#!/usr/bin/perl # #NAME # Helper - helper app for text files, based on suffix. # #SYNOPSIS # Helper file # #DESCRIPTION # This script acts as a sort of "generic helper" to browsers such as # netscape, mosaic, and possibly others. The browser calls helpers # by copying the data to a /tmp/ file. We examine the file's name, # picking off any suffix, and use that to decide what application to # run for that file. # # The main reason you might want this program is: Netscape (and lynx # and mosaic and probably most browsers) actually ignore the a file # suffix (aka extension), and use only the invisible HTTP type and # subtype to decide which helper to run. Thus if a server tells your # browser that foo.bar is "Content-Type: text/plain\n\n", the .bar # suffix is irrelevant. Only one helper can exist for text/plain # files, and that same helper is run for all of them, regardless of # any suffix that they may have.. # # What this Helper program does is look at the suffix, and with the # help of instructions that you put in your .helpers file, it can # start up different programs for different file suffixes. # # This scheme is needed because the browsers generally ignore the # suffix, although they ask you for it. They only use the HTTP file # type and subtype to choose a helper. But they do seem to be nice # enough to propogate the suffix from the URL to the /tmp/ file that # they pass to helpers. So we can write a generic helper that does # the work of looking at the suffix and firing up the right program. # #SETUP # To use this as a netscape helper, you need to install it: # # 0. First, put this script somewhere in your search path, and give # it one or more names. We assume it is called "Helper" here, but # you can of course call it what you want. Also, make sure that all # the programs it may need are installed. and in the search path. # # 1. Use the Options .. General Preferences menu to bring up the # general config window. Select the "Helper" tab to get the helper # config list. # # 2. Scroll down to the "text/plain" entry and click to select it. # # 3. Press the "New..." button to get the helper edit window. # # 4. Fill in "text/plain" as the Type and "abc" as the Suffix. Fill # in the Description field with something descriptive, such as "abc # music notation". # # 5. Click the Application button to enable the input field, and # fill in "Helper %s" in the input field. # # 6. Press the OK button at the bottom. # # 7. Press the OK button at the bottom of the Helpers window. # # There, wasn't that easy? ;-) Hey, if you want to see how complex # it can be made, try figuring out how to configure Internet # Explorer to use this program. If you figure it out, let me know. # # I've also used this program as a helper for several other programs # and it's usually easy once you figure out how to get it called. It # is easiest with programs that I wrote myself ... # #DIAGNOSTICS # Out of general paranoia, we direct our output to the files # Helper.out and Helper.err.ps lead. We write them in the $TMPDIR # directory if that is defined in the environment, or in the current # working directory if not. # #FILES # We read $HOME/.helpers and expect to find lines of the forms: # prog: suff: command # suff: command # command # where the prog, suff and command field are separated by colons. If # we find a recognizable suffix, we run sprintf(command,file), so # you can use %s to represent the file name. # # The prog field should contain the name of this program, and must # start in column 1. You can install this program under several # names, and set it up as helpers for several HTTP types if you # wish. By using the different names, you can make it run different # commands for the same suffix (if the server generates different # type/subtype values for the suffixes). # # The suff is whatever comes after the last '.' in the URL. For DOS # systems, it is the last 3-char "extension". For Unix systems, of # course, it can be anything. # # The command is an arbitrary character string, terminated by a # newline. It will be run by the perl "system" command, so any shell # variables will be expanded from your environment. You can use %s # to represent the file name. # # Example: # Helper: abc: abc2gv < %s # txt: xterm -e $EDITOR %s # The first line will only work if this program is called "Helper"; # the second line will work no matter what this program is called. # This is intentional: It lets you set up several helpers for the # same suffix, by giving this program several different names. # #BUGS # Program names in .helpers must be in column 1, and comments must # be on separate lines (though they can start in any column). # # Missing programs aren't handled as well as might be hoped. # # There seems to be no way for a helper application to discover the # name of the URL that delivered the data. Sorry 'bout dat. Not much # we can do about it except to beg and plead with the browser makers # to fix the problem. # # We should read .mailcap and .mime.types if .helpers is missing. # This is probably something for a future release. # #AUTHOR # John Chambers $| = 1; $" = ' '; ($me = $0) =~ s'.*/''; # What's my name? $V = $ENV{"V_$me"} || $ENV{"T_$me"} || $ENV{"D_$me"} || 3; $D = $ENV{'TMPDIR'} || '.'; # Set up our default command: $ed = $ENV{EDITOR} || $ENV{VISUAL} || 'vi'; $dfl = 'xterm -e $ed %s'; open(STDERR,">$D/$me.err") || die "$0: Can't write $D/$me.err ($!)\n"; open(STDOUT,">$D/$me.out") || die "$0: Can't write $D/$me.out ($!)\n"; if ($V>1) {for $e (sort keys %ENV) {print "ENV{$e}=\"$ENV{$e}\"\n"}} for $i (0 .. @ARGV) { print "ARGV[$i]=\"$a\"\n" if $V>1; next if !($a = $ARGV[$i]); # This happens! if (($p,$s) = ($a =~ /(.*)\.([^.]+)$/)) { print "$me: Prefix \"$p\" Suffix \"$s\"\n" if $V>1; $path = $a; # Full path to file. $suff = $s; if (($d,$r) = ($p =~ '^(.+)/(.+)$')) { print "$me: Dir \"$d\" Root \"$r\"\n" if $V>1; } else { $d = '.'; $r = $p; print "$me: dir \"$d\" root \"$r\"\n" if $V>1; } } else { print "$me: No suffix in \"$a\"\n" if $V>1; $path = $a; } } print "$me: path=\"$path\"\n" if $V>2; $h = "$ENV{HOME}/.helpers"; if (-f $h) { if (open(H,$h)) { for $line () { chomp $line; if ($line =~ m/\s*#/) { print "$me: Ignore \"$line\" (comment)\n" if $V>5; } elsif (($nam,$suf,$app) = ($line =~ m/^(\w+)\s*:\s*(\S*)\s*:\s*(.*)$/)) { print "$me: \"$nam\": \"$suf\" => \"$app\"\n" if $V>2; if ($nam eq $me) { $App{$suf} = $app; } else { print "$me: Ignore \"$line\" (wrong program)\n" if $V>1; } } elsif (($suf,$app) = ($line =~ m/^\s*(\S*)\s*:\s*(.*)$/)) { print "$me: \"$suf\" => \"$app\"\n" if $V>2; $App{$suf} = $app; } else { ($dfl = $line) =~ s/^\s*//; print "$me: Default \"$dfl\"\n" if $V>1; } } } else { printf STDERR "$0: Can't read $h ($!)\n"; } } if ($suff) { if ($app = $App{$suff}) { print "$me: \"$suf\" is \"$app\"\n" if $V>2; $cmd = sprintf($app,$path); print "$me: cmd=\"$cmd\"\n" if $V>1; # system "$cmd & wait"; exec $cmd; exit; } else { print "$me: No helper found for \"$suff\"\n" if $V>0; } } else { print "$me: No suffix found in \"$path\"\n" if $V>0; } print "$me: Using default command \"$dfl\"\n" if $V>0; $cmd = sprintf($dfl,$path); print "$me: cmd=\"$cmd\"\n" if $V>1; #system "$cmd & wait"; exec $cmd; exit;