#!/usr/bin/perl # # Wiki Editor Daemon # (c) 2002 Simon Clift # Licensed under the Gnu GPL # # This is a user agent that runs as the user who wishes to edit Wiki pages # using their regular editor. The agent receives commands from the editor to # retrieve and store pages on a Wiki and puts these in a temporary directory # where they can be edited. Each instance of the daemon handles one Wiki. # # The daemon understands the following commands (see # EditDaemonWithGVimIntegration page for full documentation) # # configure wikiURL # # authenticate # edit # save # quit # # The following are written to the log file, but to implement dynamically # brings all kinds of annoying messiness about transferring files around that # might be open for editing. # # configure baseDirectory # configure pipeName # configure editDirectory # configure logFileName # # The communication is via a pipe in the $HOME/baseDirectory (by default this # base directory is .wikiEditDaemon) which is removed after the program quits. # The base directory, editing directory, wiki URL and pipe name may be # specified on the command line of the program. # # SIGHUP causes all files to be saved. # SIGQUIT and all other unknown signals cause a save then quit. # use English; use strict; use LWP::UserAgent; use Socket; use Getopt::Long; use wikiEditDaemonObject; # Set defaults for each of the parameters. my $parmHash; $parmHash->{ 'homeDirectory' } = $ENV{'HOME'}; $parmHash->{ 'baseDirectory' } = $parmHash->{ 'homeDirectory' } . '/.wikiEditDaemon'; $parmHash->{ 'editDirectory' } = 'edit'; $parmHash->{ 'pipeName' } = 'inputPipe'; $parmHash->{ 'logFileName' } = 'log'; # Check command line parameters my $result = GetOptions( "baseDirectory=s" => \$parmHash->{ 'baseDirectory' }, "editDirectory=s" => \$parmHash->{ 'editDirectory' }, "pipeName=s" => \$parmHash->{ 'pipeName' }, "logFileName=s" => \$parmHash->{ 'logFileName' }, ); # Check for existing daemons. If we are using the same parameter set then we # shall politely excuse ourself. eval { my $oldLog = $parmHash->{ 'baseDirectory' } . '/' . $parmHash->{ 'logFileName' }; if ( -e $oldLog ) { open LOG, "< " . $oldLog or die "Failed to open the old log file."; my $logText = join '', ; close LOG; # The PID of the previous server should be there from the log file my ( $otherPID, $isShutDown ); { $logText =~ /PID\s*=\s*(\d+)/gm; $otherPID = $1; }; # If the shutdown occurred properly we should see this message. { $logText =~ /(WikiEditorService has been shut down\.)/gm; $isShutDown = $1; }; if ( not defined( $isShutDown ) and defined( $otherPID ) ) { # We can check if it's still running by doing this. my $killCount = kill 0, $otherPID; if ( $killCount > 0 ) { print STDERR . "Process $otherPID is running and appears to be a wiki\n" . "editor service that uses the same parameters. Please\n" . "either shut process $otherPID down or restart this program\n" . "so that it uses another base directory " . "(-basedir parameter).\n"; exit(1); }; }; }; }; # Set up a WWW user agent object and a wikiEditDaemonObject. We'll identify # ourselves and make a fairly short time-out period. my ( $ua ); eval { $ua = new LWP::UserAgent( agent => "wikiEditService/perl", timeout => 15, ); $main::we = new wikiEditDaemonObject( $parmHash, $ua ) }; if ( $EVAL_ERROR ) { die $EVAL_ERROR . "\n" . "Unable to create a user agent and a wiki editor daemon object.\n"; }; # Set signal traps. $SIG{INT} = \&trapQuit; $SIG{QUIT} = \&trapQuit; $SIG{TERM} = \&trapQuit; $SIG{STOP} = \&trapQuit; $SIG{HUP} = \&trapSave; sub trapQuit { wikiEditDaemonObject::writeToLog( $main::we, 'INT, QUIT, TERM or STOP ' . ' Signal has been received.'); wikiEditDaemonObject::save( $main::we, [ 'ALL' ] ); wikiEditDaemonObject::quit( $main::we ); exit(0); }; sub trapSave { wikiEditDaemonObject::writeToLog( $main::we, 'HUP Signal has been received.' ); wikiEditDaemonObject::save( $main::we, [ 'ALL' ] ); }; # Fire up the main loop eval { $main::we->loop(); }; if ( $EVAL_ERROR ) { $main::we->closeInputPipe(); die $EVAL_ERROR . "\n" . "Fatal error during the main daemon loop.\n"; }; 1;