Voder-Vocoder

The Log of Hal Canary

Navigation: Home | THE LOG | Log Archives | Resume | Contact Info | Public Key | SSL | Math Applets | Site Map | WP Backend | RSS2 | Atom

Archive for the “Computers & Code” Category

« Previous Entries Next Entries »

~/bin/longest-filename

#!/bin/sh
#DTPD#
# ~/bin/longest-filename
# How long is the longest filename
# in these directories?
{ for x in "$@" ; do
find "$x" -exec basename {} \;
done } | wc -L

Hal Canary | Computers & Code | 2008-06-07 18:10:57 EDT
Permanent Link | Comments Off

Random password generator

#!/usr/bin/env python

# Randoms - Copyright 2008 Hal Canary
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the 'Software'), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

import Tkinter
import os
import base64

def genrandint():
    'Generates a random integer between 0 and (2^32)-1'
    x = 0
    for i in range(4):
        x = (x << 8)+ord(os.urandom(1))
    return x

def randstring():
    'generate a 142-bit password consisting of A-Za-z0-9'
    return base64.b64encode(os.urandom(18),'Zz')

def genrand128int():
    'Generates a random integer between 0 and (2^128)-1'
    x = 0
    for i in range(16):
        x = (x << 8)+ord(os.urandom(1))
    return x

def generaterandletts():
    'generate a 131-bit password consisting of a-z'
    s = ''
    for i in range(28):
        x = ''
        while x == '' :
            y = ord(os.urandom(1)) # 0-255
            if y < (256//26*26):
                x = chr((y % 26) + 97)
        s = s + x
        if i%4 == 3:
            s = s + ' '
    return s

class Application(Tkinter.Frame):
    'a window that displays text'
    def __init__(self, master=None):
        Tkinter.Frame.__init__(self, master)
        self.grid()
        self.createWidgets()
        self.winfo_toplevel().resizable(width=False, height=False)

    def createWidgets(self):
        self.textBox = Tkinter.Text(self,height=4,padx=5, pady=5)
        self.textBox.grid()
        self.textBox.configure(state='disabled')
        self.quitButton = Tkinter.Button(self, text="Quit", command=self.quit)
        self.quitButton.grid()        

    def addText(self, pos, string):
        self.textBox.configure(state='normal')
        self.textBox.insert (pos, string)
        self.textBox.configure(state='disabled')        

app = Application()
app.master.title('Randomness')
app.addText('1.0', 'Integer: %d\n' % genrandint())
app.addText('2.0', 'Integer: %d\n' % genrand128int())
app.addText('3.0', 'String: %s\n' % randstring())
app.addText('4.0', 'String: %s' % generaterandletts())
app.mainloop()

Compiled version for windows

Hal Canary | Computers & Code | 2008-02-03 23:56:27 EST
Permanent Link | Comments Off

zipme.py

#!/usr/bin/env python

# zipme.py - Copyright 2008 Hal Canary
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

# To use me:
#   >>> from zipme import zipme
#   >>> zipme('directoryname')

import zipfile
import os
import os.path
def zipdir(z,x):
    if os.path.isfile(x):
        z.write(x)
        print 'wrote %s' % x
    elif os.path.isdir(x):
        for y in os.listdir(x):
            zipdir(z,x + os.sep + y)
    else:
        print 'ERROR: %s' % x

def zipme(d):
    z = zipfile.ZipFile(d+'.zip','w',zipfile.ZIP_DEFLATED)
    zipdir(z,d)
    z.close()

if __name__ == "__main__":
    zipme('Randoms')

Hal Canary | Computers & Code | 2008-01-28 21:49:48 EST
Permanent Link | Comments Off

genpasswd.py

#!/usr/bin/env python
# ~/bin/genpasswd.py
#   Generate a random password with about
#   142 bits of randomness, making use of
#   /dev/urandom.
# Note:
#   Most online services have somewhat
#   arbitrary rules about what characters
#   can be included in a password. So we
#   limit ourselves to A-Za-z0-9.
# Copyright 2007-2008 Hal Canary
# Dedicated to the Public Domain.
import os, base64
print base64.b64encode(os.urandom(18),'Zz')

Hal Canary | Computers & Code | 2008-01-27 15:54:05 EST
Permanent Link | Comments Off

Email2

== Email2 ==

Here’s a proposal for new e-mail protocols to completely replace existing SMTP/MIME/IMAP/POP protocols. There would be a phase-in period, lasting about 5-10 years, during which two systems would exist in paralel and servers would fall back to old protocols where the new ones aren’t availible yet.

The name of the new protocols would be Email2. It would contain the following protocols:

Email2 E-Mail Client Protocol
	* client-server connections
	* replaces SMTP, IMAP, POP
	* Specifies how the client sends and
	  recieves messages from the server.
	* Client configuration is simplified:
	  user ONLY specifies e-mail address
	  and password.  No seperate inbound
	  and outbound configurations.
	* Use of TLS strongly recommended.
Email2 E-Mail Server Protocol
	* server-server connections
	* replaces SMTP
	* meant to discourage spam
	* Use of TLS strongly recommended.
	* servers must verfy dns records of
	  sending server before accepting e-mail.
Email2 E-Mail File Format
	* replaces MIME
	* 8-bit
	* unicode (UTF-8) for all text,
	  including headers
	* mesage is compressed with DEFLATE
	  algorithm
Email2 E-Mail Storage Protocol
	* replaces maildir, mbox, et cetera
	* Can be used by all major OSes
	* similar to maildir
	* allows user to switch clients seamlessly

== Email2 E-Mail File Format ==

First of all, we need to get rid of 7-bit and linelength limitations that are part of SMTP.

The message is composed of three parts:

Head
Body
Attachments

Specifically, we would have the following:

Magic number representing this file format.
0x0a
UTF-8 data (the head) with each field
	seperated by a single unix-style endline.
0x0a0a (two endlines to specify the end of the head)
a gziped file containing the body
the attachemnts, somehow.

The head is similar to SMTP headers, but is encoded in UTF-8. There are more restrictions on what can be in the headers, for instance “From:” must be identical to the email sending the message, or it will not be accepted. Mailing lists have their own specific headers.

Since the body may be long and the server won’t need to read it (except for spam filtering), it will be compressed.

The body should *not* be HTML, since that introduces several security & spam risks. I suggest UTF-8 text with a minimal markup syntax to allow for “slightly rich” text. The text of the body may have long lines intended to be wrapped to whatever screen is availible. It is not assumed that this plain text is monospaced or wrapped at 70 characters.

All printable Unicode characters are acceptable in the body.

Because plain text is so unacceptable to most people, we allow text to be transformed to italics, bold, monospaced, subscript, superscript, strikethrough, and underline.

Whole paragraphs (seperated by newlines) can be modified with indention, center, and rightjustify.

The minimal markup syntax would use the “\” backslash character as an escape character. The following codes would be used for text modifications:

\{ec} = escape character, a literal "\"
\{bi} = begin italics
\{ei} = end italics
\{bb} = begin bold
\{eb} = end bold
\{bm} = begin monospaced
\{em} = end monospaced
\{bp} = begin subscriPt
\{ep} = end subscriPt
\{bt} = begin superscripT
\{et} = end superscripT
\{bs} = begin strikethrough
\{es} = end strikethrough
\{bu} = begin underline
\{eu} = end underline
\{bi} = begin indentation (this one *stacks*)
\{ei} = end indentation (only end one level)
\{cj} = begin center justification on this line
\{lj} = go back to left justification on this line
\{rj} = begin right justification on this line

The backslash character *must* be followed by one of those two-character escape codes to be a conforming document.

All conforming email clients should display this markup to the user in a consistant way and not expose the underlying escape characters.

Maformed escape syntax should always throw up an error. No conforming client can ever produce malfomerd syntax, so this might be spam.

Quoting previous email would always use the indentation markup, like a HTML blockquote element.

Additionally, whitespace characters like spaces, tabs, and newlines would be rendered just like they would in a plain-text document. One newline standard (such as CRLF or LF) would be chosen and all conforming clients would use it.
Tabs would be rendered in a consistant way—for example one could put a tab-stop every 8 ems. (1 em is the width of a single “m” glyph.) Or base the tabs off of the width of the client’s monospaced font.

Note that the following things are *banned* from this markup language: specifying fonts, specifying font types (other than monospace), specifying font size, specifying font color, specifying background color, blinking text, scrolling text, tables, embedded scripts, embedded images, or embedded documents. If you want any of that, you must attach an attachment.

Additionally, all conforming mail clinets *must* recognize IANA-registered URI schemes and make them into clickable (or otherwise selectable) links. But those links will look like URIs, to keep the process *transparent* to the user. URI’s can be imbedded in the text in the form “[whitespace]URI[whitespace]”, “(URI)”, “[URI]”, “{URI}”, or “<URI>”. This should be recognizable by the client since URIs generally do not contain whitespace characters or <[({})]>.

The header has none of this markup.

For the N attachemtns, the Internet media type, the preferred document name, whether it is compressed, a checksum or cryptographic hash, and file length is specified. For security purposes, the client mut not open these attachments automatically and should call a virus scanner before opening them. It is recommended that all email clients attempt to compress the attachements with DEFLATE before attaching them. If the compression results are good, then they will be attached like that. (For example, the ZIP file format can include files either compressed or uncompressed.) a checksum for each attachment would be included in the email file format. The exact format would be part of the standard, but I don’t have an opinion on how it should work.

== Email2 E-Mail Storage Protocol ==

The new standard would specify a standard way of storing email in a filesystem, similar to Maildir. This way, a user can *always* switch email clients seamlessly. Furthermore, a default place to store email would be used, specifed for each operating system. For example, under Windows it would be something like

	%HOMEDRIVE%%HOMEPATH%\Application Data\email\

and *NIX would use

	$HOME/.email/

== Email2 E-Mail Client Protocol & Server Protocol ==

Email2 is a Client-Server-Server-Client protocol. No more forwarding email through a chain of servers. No more faking addresses.

Suppose bannana@orange.com wants to email mango@plum.com.

Bannana’s client must connect to mail.orange.com directly, using a TLS encrypted session and verfying his creditions with a password (or optionally some other identifer, like a PKE key).

The connection is *not* SMTP, since we are throwing that protocol out the window. we’ll call it a “client-server” connection.

mail.orange.com verifies that the e-mail is well-formed and that the “From” address matches the address that Bannana used to log in with.

mail.orange.com then connects directly to mail.plum.com using a TLS-encrypted “server-server” connection and identifies itself as mail.orange.com. mail.plum.com *MUST* verify that mail.orange.com is who they say they are through checking (1) dns entries AND (2) TLS encryption keys. mail.orange.com has already verified mail.plum.com.

mail.orange.com then hands over the e-mail to mango@plum.com. Before terminating the session, mail.plum.com (1) checks to see that the e-mail is from an address at @orange.com (2) tells mail.orange.com whether there is a mango@ this address (3) checks to see if the message is well-formed. If not, then orange knows that the e-mail is undeliverable and will tell the sending client that. (There is an undeliverable folder on the server just for that purpose.)

Next, (this is an optional step that awesome mail servers will be able to do) mail.plum.com consults a series of rules that Mango specified earlier and sorts the mail into a subfolder of the Inbox folder. For example, if the subject contains a specific keyword, it might go in a subfolder for that keyword. The server might run Spamasasain on the message and sort it into a Inbox/Spam folder. Why does the server do this and not the client? Becasue whe user might use two clients on two different machines to connect to the server and doesn’t wat to repeat a bunch of rules!

Ideally, the rule format will be specified in the protocol.

Later, mango@plum.com creates a client-server connection with mail.plum.com This is a TLS-encrypted, fully authenticated connection. The first thing mango’s client does is check the Inbox folder and all it’s subfolders for new messages. It retrieves a few headers for each message (From, Subject, Date, Number of attachments, message length).

The client could be configured several different ways. If it is POP-style, it will immediately download all the messages and delete them off the server. If it is configured IMAP-style, it will leave messages on the server unless they are specifially deleted by ther user. It could also be configured mirror-style where it leaves a copy on the server but also mirrors each email lcoally. IMAP-style should be the default.

The user will see a heirarchy of folders:

plum.com/
	Inbox/
		Spam/
		Knitting_Circle/
	Old/
		Bannana/
		Apple/
		Nectarine/
	Sent/
	Undeliverable/
	Outbox/
	Drafts/
	Trash/
Local Folders/
	Drafts
	Outbox/
	Trash/
	Bannana/
	Apple/
	Nectarine/

The user could drag-and-drop the new email from Bannana from plum.com/Inbox/ to plum.com/Old/Bannana . This would be an atomic operation that the server could perform without copying the email, just moving some pointers around.

I am no human-interface guru, so this could probably use some refining.

The client also has a way of changing the delivery rules on the server in some standard way.

== Mailing Lists ===

Client-Server-Server-Server-Client Proticol would exist for mailing lists.

Suppose that bannana@orange.com wants to send a email to the Fruits mailing list, which has an email address of fruits%pear.com. mango@plum.com is on that list.

First of all, notice that mailing list addresses have a different syntax, replaceing the “@” with a “%”. the “%” is supposed to too like mutliple “@”s. [Is that going to be a problem with URI syntax? maybe we should use fruits#pear.com.]

For the first server-server connection, mail.orange.com connects to mail.pear.com, using the same authentication system. mail.pear.com then checks to see if there is a fruits mailing list and (this is important) if bannana@orange.com is authorized to email that list. mail.pear.com might be configured to reject anyone that is not on the list, or to reject anyone who isn’t a list owner, or to allow anyone to post to the list (which is a *BAD* idea).

mail.pear.com looks through the mailing list and sorts it by domain name, then connects sequentially all the domains to deliver the email. These connections are again authenticated both ways. When mango@plum.com gets the message it looks like this:

From: Bannana <bannana@orange.com>
To: Fruits <fruits%pear.com>
Delivered To: mango <mango@plum.com>

The “Delivered To” header was inserted by mail.plum.com (mail software are allowed to insert but not delete headers, but in general do less of this than the current generation of clients)

(*) A note about BCC (blind carbon copy). Assume that Bannana BCCed Mango on an email to Apple. Then Mango would see a header that says that.

From: Bannana <bannana@orange.com>
To: Apple <apple@pear.com>
BCC: mango <mango@plum.com>

If one BCC’s a mailing list then:

From: Bannana <bannana@orange.com>
To: Apple <apple@pear.com>
BCC: Fruits <fruits%pear.com>
Delivered To: mango <mango@plum.com>

is what Mango would see. Everyone on that list knows what list was BCCed. Apple, however, is in the dark.

There is no way to see who is on a mailing list unless you are an owner of that list. Of course the owner might make that information availible some other way.

== Timestamps ==

All timestamps in the email header should use ISO 8601 in the following way: 2007-12-21 17:47:01-05:00. Clients can convert to local timezone if they wish. Clients may diplay dates using local conventions as well.

There are multiple timestamps in the header

Date = when the client started to transmit
DateS = when the Sending server recieved the message
DateL = when the listsrev recieved the messafe
DateR = when the recieving server recieved the message
DateC = when the recieving client first noticed it

Client machines often have incorrect clocks. Servers are encouraged to use NTP to keep thier clocks up to date, so maybe a client could be configured to use DateS to timestamp the real message.

== Dead addresses ==

Since mail can no longer be forwarded, what happens when you get a new email address?

All email servers should keep a list of no-longer active email addresses and give an apropriate error code for undeliverable mail.

Delivery status:

Deliverable
Undeliverable - no such address
Undeliverable - account closed 

When a mail account is closed, the user or administrator can add a 1kb plain text (UTF-8) message explaining why it is closed and maybe another address to try.

This message should get back to the sender somehow, but not in the form of another email.

== Problems with this approach ==

A lot of coding. But most of it is really simple stuff.

Clients will need to be able to connect to both kinds of email servers for the interum.

Mail-sorting rules might be difficult to stadardize.

The standard needs to specify EVERYTHING, so that various implementations are fully compatable.

The NSA will find it much more difficlt to spy on your email. Servers could be designed with a wiretap mode where all emails to and from a particular address are automatically forwarded to the apropriate law enforcement.

It will be much simpler to fight spam: simply delete the offending dns entries.

This gives too much power to the DNS servers and the certificate authorities.

What about servers that aren’t connected to the internet 99+% of the time (most are)?

Hal Canary | Computers & Code | 2008-01-25 14:34:12 EST
Permanent Link | Comments Off

My XO-1 has gotten me interested in hacking in python again, since that is the XO’s primary programming environment.

I quickly hacked out an ftp script in python since the default install lacked an ftp client. “My next project will be to finally write version 1.0 of my fcp (FTP copy) program — a ftp client that uses rcp/scp syntax.

Here’s the first script:

#!/usr/bin/env python2.5
import ftplib
import os
import getpass
host="hostname"
user="hal"
pas=getpass.getpass(user+"@"+host+"'s password: ")
# local file with path
localfile="ftpcp"
# directory  on sever
dir="/www/pub"
# filrnaame on server
filename="ftpcp.txt"
# login to FTP
f=ftplib.FTP(host)
f.login(user, pas)
f.set_pasv(True)
f.cwd(dir)
f.storbinary("STOR " + filename, open(localfile, 'rb'))
f.quit()

Next I’ve got to write some very savy code that can parse complex command-line options.

Then I’ve got to learn how to do everything else in python.


Update: a function!

import ftplib
import os
import getpass
def ftpputfiles(host, direct, *files, **kwds):
    'user defaults to $USERNAME if blank'
    # does little error checking.  this is bad!
    user, password = ('', '')
    if kwds.has_key('user'):
        user = kwds['user']
    if user == '':
        user = os.environ['USERNAME']

    if kwds.has_key('password'):
        password = kwds['password']
    if password == '':
        querystring = '%s@%s's password: ' % (user,host)
        password = getpass.getpass(querystring)

    f = ftplib.FTP(host)
    f.login(user, password)
    f.set_pasv(True)
    f.cwd(direct)
    for localfile in files :
        filename = os.path.basename(localfile)
        fl = open(localfile, 'rb')
        f.storbinary('STOR %s' % filename, fl)
        fl.close()
    f.quit()

Hal Canary | Computers & Code | 2008-01-13 00:05:28 EST
Permanent Link | Comments Off

Downsample

I can’t tell the difference between a 32KBps and 224KBps mp3 file. Can you?

So I’m down-sampling all my mp3s to fit on my new mp3 player. I should be able to fit around 3 days of music onto my 1GB player this way.

Here’s a script to do that—a work in progress

#!/bin/sh

## Compressmp3s - Copyright 2007 Hal Canary
## Dedicated to the Public Domain.

## Arguments: a list of directories to search for mp3s
## This script will use lame to create a 32kbps version
## of those mp3 and save it in a subdirectory of $TARGETDIR

if [ "$#" -lt 1 ] ; then
    echo "Give me an argument!"
    exit 1
fi

TARGETDIR="$HOME/tmp/CompressedAudio"
mkdir -p "$TARGETDIR" || {
    echo "Use a directory you have permissions for.";
    exit 1 ; }

## for FILE in "$@" ; do
find "$@" -name '*.mp3' | while read FILE; do
    IN="$FILE"
    OUT="${TARGETDIR}/$FILE"
    ## Grab the id3 info for later use
    artist=`id3info "$IN" | grep TPE1 | \
        awk -F ': ' '{print $2}'`
    album=`id3info "$IN" | grep TALB | \
        awk -F ': ' '{print $2}'`
    track=`id3info "$IN" | grep TRCK | \
        awk -F ': ' '{print $2}'`
    song=`id3info "$IN" | grep TIT2 | \
        awk -F ': ' '{print $2}'`
    echo "$OUT"
    ## refuse to clobber a file
    if [ ! -f "$OUT" ] ; then
        echo "  artist=$artist"
        echo "  album=$album"
        echo "  track=$track"
        echo "  song=$song"
        echo ""
        DIRECTORY=`dirname "$OUT"`
        mkdir -p "$DIRECTORY" || { echo "permission error" ;
            exit 1 ; }
        lame -b 32 "$IN" "$OUT" \
            --ta "$artist" --tl "$album" \
            --tn "$track" --tt "$song" \
            --add-id3v2
    else
        echo "  already exists!"
    fi
done

Okay, on some files, I *can* tell the difference.

* * *

Compare: 032kbps mp3 versus 128kbps mp3.

Hal Canary | Computers & Code | 2007-12-12 12:40:06 EST
Permanent Link | Comments Off

new music player

My second-generation ipod died this year. It was five years old. I have now replaced it with a $40 1GB flash-based thing (an Insignia Kix from Best Buy). It has %10 of the memory, but is 10 times as easy to use. Just copy files onto it, no messing around with a separate program to create playlists and update databases.

Of course, next year they’ll have a 4GB product for the same price.

Hal Canary | Computers & Code | 2007-12-02 23:17:33 EST
Permanent Link | Comments Off

number reform

Well, if we were really starting from scratch, I would go with a base 16 numbering system (already in use by programmers everywhere).

One would have to throw out SI units, which would cease to make sense. It would also give us an opportunity to throw out the base 360/60/60 system (degrees/minutes/seconds) and 24/60/60 (hours/minutes/seconds) that the Babylonians saddled us with.

The proposal: The sixteen digits 0123456789abcdef. Integers would be written

dd,dddd,dddd

with four digit groups (16 bits each). Mixed numbers would be witten

dd,dddd,dddd.ddd

and a decimal separating fractions. Floating-point numbers (or numbers in scientific notation) would always be written

d.dddPdd

or

d.dddP-dd

where “xPy” means “x × 16y” (P for exPonent.)

The new minute would be 1/256 th of an average day. (5.625 old-minutes) The new second would be 1/65536 th of a day (1.318 old-seconds).

The new standard length would be around 9.202 centimeters. that would make the speed of light equal to an even 16^8 (new standard lengths/new seconds)

The new degree would simply be 1/256th of a circle.

Translating to and from binary would of course be trivial.

One would have to come up with new prefixes which mean “256 times”, “1/256 times”, “1/65536 times”, and “65536 times”—like “kilo” means “1000 times”.

Hal Canary | Computers & Code | 2007-10-31 13:46:45 EDT
Permanent Link | Comments Off

Excessively long URLs.

I hate unnecessarily long URLs. One of the things I always try to figure out how to leave out is the file name extension. As Tim Berners-Lee says:

"cgi", even ".html" is something which will change. You may not be using HTML for that page in 20 years time, but you might want today’s links to it to still be valid. The canonical way of making links to the W3C site doesn’t use the extension

Here are two ways of doing this with Apache.

1) Insert this line into your ".htaccess" file:

DefaultType text/html

Then when you create any new html pages, call them "foobar" instead of "foobar.html" and then your URL will be:

http://example.com/directory/foobar

and not

http://example.com/directory/foobar.html

Which makes more sense. Now you can at some later point in time change the default to .shtml or .php

2) Put this in your ".htaccess" file:

Options All MultiViews

Then put a file called "foobar.html" in the directory "directory/" and the URL:

http://example.com/directory/foobar

will automagically work.


Other options:

3) Here’s a third way:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME}.html  -f
RewriteRule ^(.*)$           $1.html

Hal Canary | Computers & Code | 2007-06-28 10:14:14 EDT
Permanent Link | Comments Off

Firefox Addons

Favorite Firefox Addons:

Go Up

Lets you go "up" a level in the current website via the provided toolbar button, or by pressing Alt+Up arrow. The "up" is determined by trimming the last section of the URL, e.g. example.org/foo/somepage.html becomes example.org/foo/

I don’t use this much, but it does come in handy every so often.

Flashblock

Flashblock is an extension for the Mozilla, Firefox, and Netscape browsers that takes a pessimistic approach to dealing with Macromedia Flash content on a webpage and blocks ALL Flash content from loading. It then leaves placeholders on the webpage that allow you to click to download and then view the Flash content.

This is a lifesaver. Try moving your mouse cursor over a piece of flash, then hitting the page-down key. Nothing happens, unless the flash is blocked.

MM3-ProxySwitch

In the Firefox Browser (and other Mozilla programs) you can per default configure only the setting for one internet connection. With the MM3-ProxySwitch you can manage different configurations and simply switch over between these.

I use this one on my laptop for managing proxies.

FullerScreen

This extension enhances the Full Screen mode into a really full screen mode, hiding the remaining toolbars and statusbar and making them visible again when the mouse pointer hits an edge of the screen.

It also offers a slideshow mode, enabling @projection CSS rules in a document when full screen mode is turned on. Navigation between slides in implemented in the extension and a slide manager showing thumbnails for the slides is available through shift-F11.

I’m still trying this out, but it seems like a good idea.

Hal Canary | Computers & Code | 2007-06-25 09:17:51 EDT
Permanent Link | 1 Comment

Unix Utility Scripts

This page collects several of the scripts I’ve written for Linux over the years.

Maybe someone else will find them useful.

Hal Canary | Computers & Code | 2007-06-12 10:26:46 EDT
Permanent Link | Comments Off

« Previous Entries Next Entries »

Copyright 1997-2007 by Hal Canary.
mailto: h3 at halcanary dot org
xmpp:halcanary@jabber.org
aim:halwcanary
http://halcanary.org