#!/usr/bin/perl -w $BackupSuffix = '~'; $Compress = 'gzip -9'; $DefaultEditor = 'jstar'; $Uncompress = 'gzip --uncompress'; $CompressionExtension = '.gz'; $TempDir = '/tmp/'; if ( defined($ENV{'EDITOR'}) ) { if ( -x $ENV{'EDITOR'} ) { $Editor = $ENV{'EDITOR'} } else { $Editor = $DefaultEditor } } else { $Editor = $DefaultEditor } if ( ! defined($ARGV[0]) ) { print(STDERR "you did not say what *$CompressionExtension file to edit with $Editor\n"); exit; } $NegativeLengthOfCompressionExtension = 0 - length($CompressionExtension); $NA = rindex($ARGV[0], '/') + 1; if ( $NA == 0 ) { $FilePath = '' } else { $FilePath = substr($ARGV[0], 0, $NA) } if ( substr($ARGV[0], $NegativeLengthOfCompressionExtension) eq $CompressionExtension ) { $FileNameBase = substr($ARGV[0], $NA, $NegativeLengthOfCompressionExtension) } else { $FileNameBase = substr($ARGV[0], $NA) } $File = $FilePath . $FileNameBase . $CompressionExtension; $FileB = $File . $BackupSuffix; $TFile = $TempDir . $FileNameBase; if ( -e $TFile ) { if ( -e "$TFile$$" ) { print(STDERR " unable to create temporary files; there are already files named $TFile and $TFile$$ "); exit; } $TFile = $TFile . $$; } $TFileB = $TFile . $BackupSuffix; if ( -e $TFileB ) { print(STDERR " unable to create temporary files; there is already a file named $TFileB "); exit; } if ( -e $File ) { # the file we want to edit already exists if ( ! -f $File ) { print(STDERR "you cannot edit $File\n", "because it is not a normal file.\n"); exit; } if ( ! -r $File ) { print(STDERR "you cannot edit $File\n", "because you do not have read permission for this file.\n"); exit; } if ( -l $File ) { print(STDERR "you cannot edit $File\n", "because it is a soft link.\n"); exit; } system("$Uncompress < $File > $TFile;$Editor $TFile"); if ( -e $TFileB ) { # the file was changed # we fork into two process: the foreground process exits # and the background process does the cleanup. Thus we get the prompt # back right away, while it compresses the file in the background. $NA = fork; if ( $NA == 0 ) { (undef,undef,$Mode,undef,$UID,$GID) = stat($File); if ( ! rename($File,$FileB) ) { print(STDERR "unable to rename $File to $FileB\n");exit } if ( system("$Compress < $TFile > $File") ) { print(STDERR "unable to $Compress < $TFile > $File\n");exit } if ( unlink($TFile,$TFileB) < 2 ) { print(STDERR "unable to delete $TFile and $TFileB\n") } if ( ! chmod($Mode,$File) ) { print(STDERR "unable to set permissions of $File\n") } if ( ! chown($UID,$GID,$File) ) { print(STDERR "unable to set owner and group of $File\n") } } } else { # the file was not changed unlink($TFile); } } else { # the file we want to edit does not exist, so edit a new file system("$Editor $TFile"); if ( -e $TFile ) { # the file was created $NA = fork; if ( $NA == 0 ) { if ( system("$Compress < $TFile > $File") ) { print(STDERR "unable to $Compress < $TFile > $File\n");exit } if ( ! unlink($TFile) ) { print(STDERR "unable to delete $TFile and $TFileB\n") } } } # else the file was not created, there is nothing to clean up. } __END__ This program makes it easy to edit compressed text files, so you can compress all your text files to save disk space, and still easily edit or view the compressed text files. It uncompresses the file to a temporary file, edits the temporary file, and then replaces the original file by compressing the temporary file. Configuration: $Editor is the name of the text file editor program you want to use, like emacs, jed, jove, joe, jstar, vi, vim, etc. This program tries to use the editor named in the environment parameter EDITOR; hopefully you have already edited /etc/profile or $HOME/.bash_profile and set EDITOR to your favorite text editor. If this program cannot use the environment parameter EDITOR, it uses $DefaultEditor, which is defined at the beginning of this program. But make sure your editor saves the previous version of the file with a backup suffix, because if this program does not find the file with the backup suffix after running the editor, it assumes that no changes were made to the file, and deletes the temporary file without replacing the original file, so that your changes are lost. Since it is possible that some user might use an editor which does not make backup copies of files, or makes backup copies with an unusual extension; maybe it would be better if we did not try to read environment parameter EDITOR and instead always use the default editor. But that would not help if a user had an rc file or environment parameter for the default editor which caused the editor to behave in an unusual way. Maybe this program should check to see which editor was being used, and check rc files, environment parameters for that editor, and maybe adding command line options or altering environment parameters for that editor. $BackupSuffix is the backup suffix used by your editor. $Compress is the compression command. It should compress standard input to standard output. $Uncompress is the uncompression command. It should uncompress standard input to standard output. $CompressionExtension is the compression extension. If you do not want a compression extension, you can use $CompressionExtension=''. $TempDir is the directory where the temporary files will be created. The last character of $TempDir should be '/'. If $TempDir is '', then the temporary files will be created in the current directory. You give the name of the file you want to edit on the command line; if the file name you give does not include the compression extension, this perl script automatically adds the compression extension. This program can not edit a file if the name does not include the compression extension. If the file does not exist it will be created. The original version of the file will be saved with the backup suffix; if you edit a file named 'foo.gz' and the backup suffix is '~', the original version will be save as 'foo.gz~'. You might want to make a bash alias so you do not have to type so many characters to run this program. You could use this program to do any kind of data conversion or reformatting instead of compression. You could convert DOS text to unix text, html to sgml, tif to gif, French to English, etc. This program does not try to prevent users from editing files they do not have permission to write. Should it? Sometimes a user may want to use an editor to read a file even though the user does not have write permission for the file; we should not try to prevent that. This program does not allow you to edit directories, devices, pipes, sockets, etc. I do not think you will ever want to do anything like that. This program also does not allow you to edit soft links. You might occaisionally want to edit a file which is actually a soft link to a file, but there are problems with doing that. If 'foo' is a soft link to 'bar', and you edit foo, should the backup file be named 'foo~' or 'bar~'? Soft links would require special handling, so it was easier to forbid it. Maybe it should uncompress the original compressed file in the background. Then we could start editing the temporary file right away, before it was fully uncompressed. Kenneth Howlett September 2000 av556@detroit.freenet.org