home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-19 | 54.0 KB | 1,346 lines |
- Newsgroups: comp.sources.misc
- From: ram@eiffel.com (Raphael Manfredi)
- Subject: v33i101: mailagent - Rule Based Mail Filtering, Part09/17
- Message-ID: <1992Nov20.050626.14244@sparky.imd.sterling.com>
- X-Md4-Signature: 53a058f70412d3e236c9f9b061221874
- Date: Fri, 20 Nov 1992 05:06:26 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: ram@eiffel.com (Raphael Manfredi)
- Posting-number: Volume 33, Issue 101
- Archive-name: mailagent/part09
- Environment: Perl, Sendmail, UNIX
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: MANIFEST PACKLIST agent/filter/parser.c agent/pl/dbr.pl
- # agent/test/cmd/run.t
- # Wrapped by kent@sparky on Wed Nov 18 22:42:24 1992
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 9 (of 17)."'
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(11685 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- XConfigure Portability tool
- XCopying The GNU General Public Licence Version 2
- XJmakefile Description of the main Makefile
- XMANIFEST This list of files
- XMakefile.SH A makefile to run subsidiary makefiles
- XREADME Basic instructions
- Xagent/ Where mailagent support files are located
- Xagent/Jmakefile High level description of Makefile
- Xagent/Makefile.SH Makefile which builds and installs mailagent
- Xagent/README Welcome to mailagent
- Xagent/examples/ A set of files from my own environment
- Xagent/examples/README Explains what the examples are
- Xagent/examples/daemon Rules for "vacation" emulation
- Xagent/examples/mailfolders A copy of my ~/.mailfolders
- Xagent/examples/mchk Checks for new mail
- Xagent/examples/mhinc Call the MH inc command to incorporate new mail
- Xagent/examples/nocmds Message you currently get if you send me a command
- Xagent/examples/profile What I added to my onw ~/.profile
- Xagent/examples/rules The rules I am currently using
- Xagent/examples/vacation A sample vacation message
- Xagent/files/ Mailagent's configuration files
- Xagent/files/Jmakefile High level description for Makefile
- Xagent/files/Makefile.SH Makefile for subsidiary files
- Xagent/files/README Notes about files found in this directory
- Xagent/files/agenthelp Help file used by mailhelp
- Xagent/files/chkagent.sh Cron script to spot problems in the mailagent system
- Xagent/files/commands Allowed commands for mailagent
- Xagent/files/distribs Example of distribution list
- Xagent/files/filter.sh Shell script version of the mail filter
- Xagent/files/mailagent.cf Example of configuration file
- Xagent/files/proglist Example of description file
- Xagent/filter/ The C version of the mail filter
- Xagent/filter/Jmakefile Generic makefile template
- Xagent/filter/Makefile.SH Makefile for C filter
- Xagent/filter/README Introduction to filter
- Xagent/filter/environ.c Environment management routines
- Xagent/filter/environ.h Declarations for environment management routines
- Xagent/filter/hash.c Symbol table handling
- Xagent/filter/hash.h Declarations for symbol table
- Xagent/filter/io.c I/O routines
- Xagent/filter/io.h Header for I/O routines
- Xagent/filter/lock.c File locking
- Xagent/filter/lock.h Declarations for file locking routines
- Xagent/filter/logfile.c Logging facilities
- Xagent/filter/logfile.h Header for logging routines
- Xagent/filter/main.c The main entry point for filter
- Xagent/filter/misc.c Miscellaneous routines
- Xagent/filter/msg.c Handles fatal messages
- Xagent/filter/msg.h Declarations for user messages
- Xagent/filter/parser.c Parse the config file with variable substitutions
- Xagent/filter/parser.h About config file parsing
- Xagent/filter/portable.h Portable declarations
- Xagent/filter/sysexits.h Standard exit codes
- Xagent/filter/user.c To get login name from user
- Xagent/magent.SH The main processor
- Xagent/maildist.SH Mails a whole distribution
- Xagent/mailhelp.SH Mails some help
- Xagent/maillist.SH Mails a list of available distributions
- Xagent/mailpatch.SH Mails patches for a given distribution
- Xagent/man/ Manual pages for mailagent
- Xagent/man/Jmakefile Makefile description for jmake
- Xagent/man/Makefile.SH Makefile for manual pages extraction
- Xagent/man/mailagent.SH Produces a manual page for mailagent
- Xagent/man/maildist.SH Produces a manual page for maildist
- Xagent/man/mailhelp.SH Produces a manual page for mailhelp
- Xagent/man/maillist.SH Produces a manual page for maillist
- Xagent/man/mailpatch.SH Produces a manual page for mailpatch
- Xagent/mhook.SH The mail hook wrapper
- Xagent/pl/ Perl files used by mailagent scripts
- Xagent/pl/acs_rqst.pl Perl library to ask for private file access
- Xagent/pl/actions.pl Implementation of mailagent's actions
- Xagent/pl/add_log.pl Perl library to add logs to logfile
- Xagent/pl/analyze.pl Perl library analyzing the incoming mail
- Xagent/pl/builtins.pl Perl library dealing with builtins
- Xagent/pl/checklock.pl Perl library to check for long lasting locks
- Xagent/pl/context.pl Mailagent context file handling
- Xagent/pl/dbr.pl Internal database management
- Xagent/pl/distribs.pl Perl library to scan the distribs file
- Xagent/pl/emergency.pl Perl library dealing with emergencies
- Xagent/pl/eval.pl A little expression interpreter
- Xagent/pl/extern.pl Perl library to handle persistent variables
- Xagent/pl/fatal.pl Perl library to deal with fatal errors
- Xagent/pl/filter.pl Running the filtering commands
- Xagent/pl/free_file.pl Perl library to free file access
- Xagent/pl/getdate.pl Richard Ohnemus's getdate package
- Xagent/pl/header.pl Header-related routines
- Xagent/pl/history.pl Perl library to implement history mechanism
- Xagent/pl/hook.pl Mail hook wrapping functions
- Xagent/pl/interface.pl Perl interface with filter commands
- Xagent/pl/jobnum.pl Perl library to compute a job number
- Xagent/pl/lexical.pl Perl library for lexical analysis
- Xagent/pl/listqueue.pl Perl library to list the queue
- Xagent/pl/locate.pl Perl library to locate loaded patterns/addresses
- Xagent/pl/macros.pl Perl library for macros expansion
- Xagent/pl/mailhook.pl Initializing and running hooks
- Xagent/pl/makedir.pl Perl library for making a directory
- Xagent/pl/matching.pl Matching routines used by filter
- Xagent/pl/mbox.pl Getting mails from a mailbox file
- Xagent/pl/once.pl Dealing with once commands
- Xagent/pl/parse.pl Perl library to parse a mail message
- Xagent/pl/period.pl Perl library to compute periods
- Xagent/pl/plsave.pl Perl library to handle the plsave cache file
- Xagent/pl/pqueue.pl Processing the queued mails
- Xagent/pl/queue_mail.pl Queuing mails
- Xagent/pl/rangeargs.pl Perl library to expand a list of patches
- Xagent/pl/read_conf.pl Perl library to read configuration file
- Xagent/pl/rfc822.pl Perl library to parse RFC822 addresses
- Xagent/pl/rules.pl Compiles the filtering rules
- Xagent/pl/runcmd.pl Filter commands ran from here
- Xagent/pl/sendfile.pl Perl library to send files in shar / kit mode
- Xagent/pl/stats.pl Mailagent's statistics recording and printing
- Xagent/pl/unpack.pl Perl library to unpack archive files
- Xagent/test/ Regression test suite
- Xagent/test/Jmakefile Generic makefile for test suite
- Xagent/test/Makefile.SH Makefile for test suite
- Xagent/test/README About the regression tests
- Xagent/test/TEST Runs the full test suite
- Xagent/test/actions Rule file for cmd tests
- Xagent/test/basic/ Basic tests
- Xagent/test/basic/config.t Main test initialization and sanity checks
- Xagent/test/basic/filter.t Make sure C filter works
- Xagent/test/basic/mailagent.t Make sure mailagent basically works
- Xagent/test/cmd/ Tests of mailagent's filtering commands
- Xagent/test/cmd/abort.t Test ABORT command
- Xagent/test/cmd/annotate.t Test ANNOTATE command
- Xagent/test/cmd/assign.t Test ASSIGN command
- Xagent/test/cmd/back.t Test BACK command
- Xagent/test/cmd/begin.t Test BEGIN command
- Xagent/test/cmd/bounce.t Test BOUNCE command
- Xagent/test/cmd/delete.t Test DELETE command
- Xagent/test/cmd/feed.t Test FEED command
- Xagent/test/cmd/forward.t Test FORWARD command
- Xagent/test/cmd/give.t Test GIVE command
- Xagent/test/cmd/keep.t Test KEEP command
- Xagent/test/cmd/leave.t Test LEAVE command
- Xagent/test/cmd/message.t Test MESSAGE command
- Xagent/test/cmd/nop.t Test NOP command
- Xagent/test/cmd/notify.t Test NOTIFY command
- Xagent/test/cmd/once.t Test ONCE command
- Xagent/test/cmd/pass.t Test PASS command
- Xagent/test/cmd/perl.t Test PERL command
- Xagent/test/cmd/pipe.t Test PIPE command
- Xagent/test/cmd/post.t Test POST command
- Xagent/test/cmd/process.t Test PROCESS command
- Xagent/test/cmd/purify.t Test PURIFY command
- Xagent/test/cmd/queue.t Test QUEUE command
- Xagent/test/cmd/record.t Test RECORD command
- Xagent/test/cmd/reject.t Test REJECT command
- Xagent/test/cmd/restart.t Test RESTART command
- Xagent/test/cmd/resync.t Test RESYNC command
- Xagent/test/cmd/run.t Test RUN command
- Xagent/test/cmd/save.t Test SAVE command
- Xagent/test/cmd/select.t Test SELECT command
- Xagent/test/cmd/split.t Test SPLIT command
- Xagent/test/cmd/store.t Test STORE command
- Xagent/test/cmd/strip.t Test STRIP command
- Xagent/test/cmd/subst.t Test SUBST command
- Xagent/test/cmd/tr.t Test TR command
- Xagent/test/cmd/unique.t Test UNIQUE command
- Xagent/test/cmd/unknown.t Make sure unknown command defaults correctly
- Xagent/test/cmd/vacation.t Test VACATION command
- Xagent/test/cmd/write.t Test WRITE command
- Xagent/test/filter/ Testing the filtering capabilities
- Xagent/test/filter/backref.t Check backreferences
- Xagent/test/filter/case.t Normalized header case tests
- Xagent/test/filter/default.t Check default behaviour when mail not saved
- Xagent/test/filter/escape.t Escape sequences within actions
- Xagent/test/filter/group.t Selector combination tests
- Xagent/test/filter/hook.t Ensure hooks are correctly invoked
- Xagent/test/filter/list.t Check matching on lists like To and Newsgroups
- Xagent/test/filter/loop.t Check loop detection
- Xagent/test/filter/multiple.t Check multiple selectors
- Xagent/test/filter/not.t Negated pattern tests
- Xagent/test/filter/pattern.t Check patterns specification and loading
- Xagent/test/filter/status.t Action status updating tests
- Xagent/test/level Default logging level for tests
- Xagent/test/mail The mail used by testing routines
- Xagent/test/option/ Tests the options to the mailagent program
- Xagent/test/option/L.t Test -L option
- Xagent/test/option/V.t Test -V option
- Xagent/test/option/c.t Test -c option
- Xagent/test/option/d.t Test -d option
- Xagent/test/option/e.t Test -e option
- Xagent/test/option/f.t Test -f option
- Xagent/test/option/h.t Test -h option
- Xagent/test/option/i.t Test -i option
- Xagent/test/option/l.t Test -l option
- Xagent/test/option/o.t Test -o option
- Xagent/test/option/q.t Test -q option
- Xagent/test/option/r.t Test -r option
- Xagent/test/option/s.t Test -s option
- Xagent/test/option/t.t Test -t option
- Xagent/test/option/what.t Ensure good behaviour with unknown option
- Xagent/test/pl/ Perl libraries for the regression test suite
- Xagent/test/pl/cmd.pl Initializes command paths
- Xagent/test/pl/filter.pl Set up environment for filter tests
- Xagent/test/pl/init.pl Variable initializations
- Xagent/test/pl/logfile.pl Logging file checking
- Xagent/test/pl/mail.pl Modifies mail components
- Xagent/test/rules Rules used by filtering tests
- Xbin/perload The dataloading/autoloading perl translator
- Xconfig.h.SH Produces config.h
- Xinstall.SH Installation script
- Xpatchlevel.h Current version number and patch level
- END_OF_FILE
- if test 11685 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'PACKLIST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PACKLIST'\"
- else
- echo shar: Extracting \"'PACKLIST'\" \(11453 characters\)
- sed "s/^X//" >'PACKLIST' <<'END_OF_FILE'
- XAfter all the mailagent kits are run you should have the following files:
- X
- XFilename Kit Description
- X-------- --- -----------
- XConfigure 2 Portability tool
- XCopying 5 The GNU General Public Licence Version 2
- XJmakefile 14 Description of the main Makefile
- XMANIFEST 8 This list of files
- XMakefile.SH 11 A makefile to run subsidiary makefiles
- XPACKLIST 8 Which files came with which kits
- XREADME 1 Basic instructions
- Xagent/ Where mailagent support files are located
- Xagent/Jmakefile 14 High level description of Makefile
- Xagent/Makefile.SH 11 Makefile which builds and installs mailagent
- Xagent/README 1 Welcome to mailagent
- Xagent/examples/ A set of files from my own environment
- Xagent/examples/README 1 Explains what the examples are
- Xagent/examples/daemon 15 Rules for "vacation" emulation
- Xagent/examples/mailfolders 15 A copy of my ~/.mailfolders
- Xagent/examples/mchk 14 Checks for new mail
- Xagent/examples/mhinc 14 Call the MH inc command to incorporate new mail
- Xagent/examples/nocmds 14 Message you currently get if you send me a comm
- Xagent/examples/profile 14 What I added to my onw ~/.profile
- Xagent/examples/rules 1 The rules I am currently using
- Xagent/examples/vacation 14 A sample vacation message
- Xagent/files/ Mailagent's configuration files
- Xagent/files/Jmakefile 14 High level description for Makefile
- Xagent/files/Makefile.SH 12 Makefile for subsidiary files
- Xagent/files/agenthelp 10 Help file used by mailhelp
- Xagent/files/chkagent.sh 13 Cron script to spot problems in the mailagent s
- Xagent/files/commands 15 Allowed commands for mailagent
- Xagent/files/distribs 14 Example of distribution list
- Xagent/files/filter.sh 10 Shell script version of the mail filter
- Xagent/files/mailagent.cf 13 Example of configuration file
- Xagent/files/proglist 13 Example of description file
- Xagent/filter/ The C version of the mail filter
- Xagent/filter/Jmakefile 14 Generic makefile template
- Xagent/filter/Makefile.SH 11 Makefile for C filter
- Xagent/filter/README 1 Introduction to filter
- Xagent/filter/environ.c 10 Environment management routines
- Xagent/filter/environ.h 14 Declarations for environment management routine
- Xagent/filter/hash.c 9 Symbol table handling
- Xagent/filter/hash.h 13 Declarations for symbol table
- Xagent/filter/io.c 7 I/O routines
- Xagent/filter/io.h 14 Header for I/O routines
- Xagent/filter/lock.c 7 File locking
- Xagent/filter/lock.h 14 Declarations for file locking routines
- Xagent/filter/logfile.c 11 Logging facilities
- Xagent/filter/logfile.h 13 Header for logging routines
- Xagent/filter/main.c 12 The main entry point for filter
- Xagent/filter/misc.c 14 Miscellaneous routines
- Xagent/filter/msg.c 13 Handles fatal messages
- Xagent/filter/msg.h 14 Declarations for user messages
- Xagent/filter/parser.c 6 Parse the config file with variable substitutio
- Xagent/filter/parser.h 14 About config file parsing
- Xagent/filter/portable.h 13 Portable declarations
- Xagent/filter/sysexits.h 14 Standard exit codes
- Xagent/filter/user.c 13 To get login name from user
- Xagent/magent.SH 6 The main processor
- Xagent/maildist.SH 4 Mails a whole distribution
- Xagent/mailhelp.SH 13 Mails some help
- Xagent/maillist.SH 10 Mails a list of available distributions
- Xagent/mailpatch.SH 9 Mails patches for a given distribution
- Xagent/man/ Manual pages for mailagent
- Xagent/man/Jmakefile 14 Makefile description for jmake
- Xagent/man/Makefile.SH 12 Makefile for manual pages extraction
- Xagent/man/mailagent.SH 3 Produces a manual page for mailagent
- Xagent/man/maildist.SH 14 Produces a manual page for maildist
- Xagent/man/mailhelp.SH 11 Produces a manual page for mailhelp
- Xagent/man/maillist.SH 14 Produces a manual page for maillist
- Xagent/man/mailpatch.SH 14 Produces a manual page for mailpatch
- Xagent/pl/ Perl files used by mailagent scripts
- Xagent/pl/acs_rqst.pl 13 Perl library to ask for private file access
- Xagent/pl/actions.pl 4 Implementation of mailagent's actions
- Xagent/pl/add_log.pl 14 Perl library to add logs to logfile
- Xagent/pl/analyze.pl 8 Perl library analyzing the incoming mail
- Xagent/pl/builtins.pl 12 Perl library dealing with builtins
- Xagent/pl/checklock.pl 14 Perl library to check for long lasting locks
- Xagent/pl/context.pl 12 Mailagent context file handling
- Xagent/pl/dbr.pl 8 Internal database management
- Xagent/pl/distribs.pl 12 Perl library to scan the distribs file
- Xagent/pl/emergency.pl 12 Perl library dealing with emergencies
- Xagent/pl/eval.pl 11 A little expression interpreter
- Xagent/pl/fatal.pl 14 Perl library to deal with fatal errors
- Xagent/pl/filter.pl 6 Running the filtering commands
- Xagent/pl/free_file.pl 14 Perl library to free file access
- Xagent/pl/getdate.pl 1 Richard Ohnemus's getdate package
- Xagent/pl/header.pl 11 Header-related routines
- Xagent/pl/history.pl 13 Perl library to implement history mechanism
- Xagent/pl/lexical.pl 12 Perl library for lexical analysis
- Xagent/pl/listqueue.pl 11 Perl library to list the queue
- Xagent/pl/locate.pl 14 Perl library to locate loaded patterns/addresse
- Xagent/pl/macros.pl 12 Perl library for macros expansion
- Xagent/pl/makedir.pl 14 Perl library for making a directory
- Xagent/pl/matching.pl 7 Matching routines used by filter
- Xagent/pl/mbox.pl 13 Getting mails from a mailbox file
- Xagent/pl/once.pl 13 Dealing with once commands
- Xagent/pl/period.pl 13 Perl library to compute periods
- Xagent/pl/plsave.pl 11 Perl library to handle the plsave cache file
- Xagent/pl/pqueue.pl 13 Processing the queued mails
- Xagent/pl/queue_mail.pl 9 Queuing mails
- Xagent/pl/rangeargs.pl 14 Perl library to expand a list of patches
- Xagent/pl/read_conf.pl 13 Perl library to read configuration file
- Xagent/pl/rfc822.pl 13 Perl library to parse RFC822 addresses
- Xagent/pl/rules.pl 9 Compiles the filtering rules
- Xagent/pl/runcmd.pl 10 Filter commands ran from here
- Xagent/pl/sendfile.pl 9 Perl library to send files in shar / kit mode
- Xagent/pl/stats.pl 5 Mailagent's statistics recording and printing
- Xagent/pl/unpack.pl 13 Perl library to unpack archive files
- Xagent/test/ Regression test suite
- Xagent/test/Jmakefile 14 Generic makefile for test suite
- Xagent/test/Makefile.SH 12 Makefile for test suite
- Xagent/test/README 1 About the regression tests
- Xagent/test/TEST 12 Runs the full test suite
- Xagent/test/actions 12 Rule file for cmd tests
- Xagent/test/basic/ Basic tests
- Xagent/test/basic/config.t 13 Main test initialization and sanity checks
- Xagent/test/basic/filter.t 13 Make sure C filter works
- Xagent/test/basic/mailagent.t 13 Make sure mailagent basically works
- Xagent/test/cmd/ Tests of mailagent's filtering commands
- Xagent/test/cmd/abort.t 15 Test ABORT command
- Xagent/test/cmd/annotate.t 15 Test ANNOTATE command
- Xagent/test/cmd/assign.t 15 Test ASSIGN command
- Xagent/test/cmd/back.t 11 Test BACK command
- Xagent/test/cmd/begin.t 15 Test BEGIN command
- Xagent/test/cmd/bounce.t 15 Test BOUNCE command
- Xagent/test/cmd/delete.t 15 Test DELETE command
- Xagent/test/cmd/feed.t 15 Test FEED command
- Xagent/test/cmd/forward.t 7 Test FORWARD command
- Xagent/test/cmd/give.t 14 Test GIVE command
- Xagent/test/cmd/keep.t 14 Test KEEP command
- Xagent/test/cmd/leave.t 14 Test LEAVE command
- Xagent/test/cmd/message.t 15 Test MESSAGE command
- Xagent/test/cmd/nop.t 15 Test NOP command
- Xagent/test/cmd/notify.t 15 Test NOTIFY command
- Xagent/test/cmd/once.t 13 Test ONCE command
- Xagent/test/cmd/pass.t 15 Test PASS command
- Xagent/test/cmd/pipe.t 14 Test PIPE command
- Xagent/test/cmd/post.t 15 Test POST command
- Xagent/test/cmd/process.t 15 Test PROCESS command
- Xagent/test/cmd/purify.t 14 Test PURIFY command
- Xagent/test/cmd/queue.t 15 Test QUEUE command
- Xagent/test/cmd/record.t 14 Test RECORD command
- Xagent/test/cmd/reject.t 15 Test REJECT command
- Xagent/test/cmd/restart.t 15 Test RESTART command
- Xagent/test/cmd/resync.t 15 Test RESYNC command
- Xagent/test/cmd/run.t 14 Test RUN command
- Xagent/test/cmd/save.t 14 Test SAVE command
- Xagent/test/cmd/select.t 15 Test SELECT command
- Xagent/test/cmd/split.t 5 Test SPLIT command
- Xagent/test/cmd/store.t 14 Test STORE command
- Xagent/test/cmd/strip.t 14 Test STRIP command
- Xagent/test/cmd/subst.t 15 Test SUBST command
- Xagent/test/cmd/tr.t 15 Test TR command
- Xagent/test/cmd/unique.t 12 Test UNIQUE command
- Xagent/test/cmd/unknown.t 15 Make sure unknown command defaults correctly
- Xagent/test/cmd/vacation.t 4 Test VACATION command
- Xagent/test/cmd/write.t 13 Test WRITE command
- Xagent/test/filter/ Testing the filtering capabilities
- Xagent/test/filter/backref.t 15 Check backreferences
- Xagent/test/filter/default.t 14 Check default behaviour when mail not saved
- Xagent/test/filter/list.t 14 Check matching on lists like To and Newsgroups
- Xagent/test/filter/loop.t 15 Check loop detection
- Xagent/test/filter/multiple.t 14 Check multiple selectors
- Xagent/test/filter/pattern.t 15 Check patterns specification and loading
- Xagent/test/level 15 Default logging level for tests
- Xagent/test/mail 13 The mail used by testing routines
- Xagent/test/option/ Tests the options to the mailagent program
- Xagent/test/option/L.t 8 Test -L option
- Xagent/test/option/V.t 15 Test -V option
- Xagent/test/option/c.t 14 Test -c option
- Xagent/test/option/d.t 14 Test -d option
- Xagent/test/option/e.t 14 Test -e option
- Xagent/test/option/f.t 14 Test -f option
- Xagent/test/option/h.t 15 Test -h option
- Xagent/test/option/i.t 15 Test -i option
- Xagent/test/option/l.t 14 Test -l option
- Xagent/test/option/o.t 15 Test -o option
- Xagent/test/option/q.t 14 Test -q option
- Xagent/test/option/r.t 15 Test -r option
- Xagent/test/option/s.t 9 Test -s option
- Xagent/test/option/t.t 14 Test -t option
- Xagent/test/option/what.t 15 Ensure good behaviour with unknown option
- Xagent/test/pl/ Perl libraries for the regression test suite
- Xagent/test/pl/cmd.pl 15 Initializes command paths
- Xagent/test/pl/filter.pl 15 Set up environment for filter tests
- Xagent/test/pl/init.pl 15 Variable initializations
- Xagent/test/pl/logfile.pl 13 Logging file checking
- Xagent/test/pl/mail.pl 14 Modifies mail components
- Xagent/test/rules 14 Rules used by filtering tests
- Xbin/perload 7 The dataloading/autoloading perl translator
- Xconfig.h.SH 10 Produces config.h
- Xinstall.SH 10 Installation script
- Xpatchlevel.h 15 Current version number and patch level
- END_OF_FILE
- if test 11453 -ne `wc -c <'PACKLIST'`; then
- echo shar: \"'PACKLIST'\" unpacked with wrong size!
- fi
- # end of 'PACKLIST'
- fi
- if test -f 'agent/filter/parser.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/filter/parser.c'\"
- else
- echo shar: Extracting \"'agent/filter/parser.c'\" \(16295 characters\)
- sed "s/^X//" >'agent/filter/parser.c' <<'END_OF_FILE'
- X/*
- X
- X ##### ## ##### #### ###### ##### ####
- X # # # # # # # # # # # #
- X # # # # # # #### ##### # # #
- X ##### ###### ##### # # ##### ### #
- X # # # # # # # # # # ### # #
- X # # # # # #### ###### # # ### ####
- X
- X Parse a configuration file.
- X*/
- X
- X/*
- X * $Id: parser.c,v 2.9.1.2 92/11/01 15:42:10 ram Exp $
- X *
- X * Copyright (c) 1992, Raphael Manfredi
- X *
- X * You may redistribute only under the terms of the GNU General Public
- X * Licence as specified in the README file that comes with dist.
- X *
- X * $Log: parser.c,v $
- X * Revision 2.9.1.2 92/11/01 15:42:10 ram
- X * patch11: forgot inclusion of <sys/types.h> for possible pid_t
- X *
- X * Revision 2.9.1.1 92/08/12 21:31:37 ram
- X * patch6: added security checks
- X * patch6: moved logfile initialization from main.c
- X *
- X * Revision 2.9 92/07/14 16:48:36 ram
- X * 3.0 beta baseline.
- X *
- X */
- X
- X#include "config.h"
- X#include "portable.h"
- X#include "hash.h"
- X#include "msg.h"
- X#include <sys/types.h>
- X#include "logfile.h"
- X#include "environ.h"
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <pwd.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#ifdef I_STRING
- X#include <string.h>
- X#else
- X#include <strings.h>
- X#endif
- X
- X#ifndef GETHOSTNAME
- X#ifdef UNAME
- X#include <sys/utsname.h>
- X#endif
- X#endif
- X
- X#define MAX_STRING 2048 /* Maximum length for strings */
- X#define SYMBOLS 50 /* Expected number of symbols */
- X
- X/* Function declarations */
- Xpublic void read_conf(); /* Read configuration file */
- Xpublic void set_env_vars(); /* Set envrionment variables */
- Xprivate void secure(); /* Perform basic security checks on file */
- Xprivate void check_perm(); /* Check permissions on file */
- Xprivate void get_home(); /* Extract home from /etc/passwd */
- Xprivate void substitute(); /* Variable and ~ substitutions */
- Xprivate void add_home(); /* Replace ~ with home directory */
- Xprivate void add_variable(); /* Replace $var by its value */
- Xprivate void insert_value(); /* Record variable value in H table */
- Xprivate char *machine_name(); /* Return the machine name */
- Xprivate char *strip_down(); /* Strip down domain name from host name */
- Xprivate void strip_comment(); /* Strip trailing comment in config line */
- Xprivate void start_log(); /* Start up logging */
- X
- Xprivate char *home = (char *) 0; /* Location of the home directory */
- Xpublic struct htable symtab; /* Symbol table */
- X
- Xextern char *strsave(); /* Save string value in memory */
- Xextern struct passwd *getpwuid(); /* Fetch /etc/passwd entry from uid */
- Xextern char *getenv(); /* Get environment variable */
- X
- Xpublic void read_conf(file)
- Xchar *file;
- X{
- X /* Read file in the home directory and build a symbol H table on the fly.
- X * The ~ substitution and usual $var substitution occur (but not ${var}).
- X */
- X
- X char path[MAX_STRING]; /* Full path of the config file */
- X char *rules; /* Path of the rule file, if any */
- X char mailagent[MAX_STRING]; /* Path of the configuration file */
- X FILE *fd; /* File descriptor used for config file */
- X int line = 0; /* Line number */
- X
- X if (home == (char *) 0) /* Home not already artificially set */
- X get_home(); /* Get home directory via /etc/passwd */
- X
- X /* Build full path for configuration file, based on $HOME */
- X strcpy(path, home);
- X strcat(path, "/");
- X strcat(path, file);
- X strcpy(mailagent, path); /* Save configuration path for later */
- X
- X fd = fopen(path, "r");
- X if (fd == (FILE *) 0)
- X fatal("cannot open config file %s", path);
- X
- X /* Initialize the H table */
- X if (-1 == ht_create(&symtab, SYMBOLS))
- X fatal("cannot create symbol table");
- X
- X while((char *) 0 != fgets(path, MAX_STRING - 1, fd)) {
- X line ++; /* One more line */
- X substitute(path); /* Standard parameter substitutions */
- X insert_value(path, line); /* Record value in hash table */
- X }
- X fclose(fd);
- X
- X
- X /* Some security checks are in order here, or someone could set up a fake
- X * a config file for us and then let the mailagent execute arbitrary
- X * commands under our uid. These tests are performed after the parsing of
- X * the file, to allow logging of errors.
- X */
- X
- X start_log(); /* Start up loging */
- X secure(mailagent); /* Perform basic security checks */
- X
- X /* Final security check on the rule file, if provided. The constraints are
- X * the same as those for the ~/.mailagent configuration file. This is
- X * because a rule can specify a RUN command, which will start a process
- X * with the user's privileges.
- X */
- X
- X rules = ht_value(&symtab, "rules"); /* Fetch rules location */
- X if (rules == (char *) 0) /* No rule file, that's fine */
- X return;
- X
- X check_perm(rules); /* Might not exist, don't use secure() */
- X}
- X
- Xprivate void start_log()
- X{
- X /* Start up logging, if possible. Note that not defining a logging
- X * directory or a logging level is a fatal error.
- X */
- X
- X char logfile[MAX_STRING]; /* Location of logfile */
- X char *value; /* Symbol value */
- X int level = 0; /* Logging level wanted */
- X
- X value = ht_value(&symtab, "logdir"); /* Fetch logging directory */
- X if (value == (char *) 0)
- X fatal("logging directory not defined");
- X strcpy(logfile, value);
- X strcat(logfile, "/");
- X
- X value = ht_value(&symtab, "log"); /* Basename of the log file */
- X if (value == (char *) 0)
- X fatal("logfile not defined");
- X strcat(logfile, value);
- X
- X value = ht_value(&symtab, "level"); /* Fetch logging level */
- X if (value == (char *) 0)
- X fatal("no logging level defined");
- X sscanf(value, "%d", &level);
- X
- X set_loglvl(level); /* Logging level wanted */
- X if (-1 == open_log(logfile))
- X fprintf(stderr, "%s: cannot open logfile %s\n", progname, logfile);
- X}
- X
- Xprivate void secure(file)
- Xchar *file;
- X{
- X /* Make sure the file is owned by the effective uid, and that it is not
- X * world writable. Otherwise, simply abort with a fatal error.
- X * Returning from this routine implies that the security checks succeeded.
- X */
- X
- X struct stat buf; /* Statistics buffer */
- X
- X if (-1 == stat(file, &buf)) {
- X add_log(1, "SYSERR stat: %m (%e)");
- X fatal("cannot stat file %s", file);
- X }
- X
- X check_perm(file); /* Check permissions */
- X}
- X
- Xprivate void check_perm(file)
- Xchar *file;
- X{
- X /* Check basic permissions on the specified file. If cannot be world
- X * writable and must be owned by the user. If the file specified does not
- X * exist, no error is reported however.
- X */
- X
- X struct stat buf; /* Statistics buffer */
- X
- X if (-1 == stat(file, &buf))
- X return;
- X
- X#ifndef S_IWOTH
- X#define S_IWOTH 00002 /* Write permissions for other */
- X#endif
- X
- X if (buf.st_mode & S_IWOTH)
- X fatal("file %s is world writable!", file);
- X
- X if (buf.st_uid != geteuid())
- X fatal("file %s not owned by user!", file);
- X}
- X
- Xpublic char *homedir()
- X{
- X return home; /* Location of the home directory */
- X}
- X
- Xpublic void env_home()
- X{
- X home = getenv("HOME"); /* For tests only -- see main.c */
- X if (home != (char *) 0)
- X home = strsave(home); /* POSIX getenv() returns ptr to static data */
- X}
- X
- Xprivate void get_home()
- X{
- X /* Get home directory out of /etc/passwd file */
- X
- X struct passwd *pp; /* Pointer to passwd entry */
- X
- X pp = getpwuid(geteuid());
- X if (pp == (struct passwd *) 0)
- X fatal("cannot locate home directory");
- X home = strsave(pp->pw_dir);
- X if (home == (char *) 0)
- X fatal("no more memory");
- X}
- X
- Xpublic void set_env_vars(envp)
- Xchar **envp; /* The environment pointer */
- X{
- X /* Set the all environment variable correctly. If the configuration file
- X * defines a variable of the form 'p_host' where "host" is the lowercase
- X * name of the machine (domain name stripped), then that value is prepended
- X * to the current value of the PATH variable. We also set HOME and TZ if
- X * there is a 'timezone' variable in the config file.
- X */
- X
- X char *machine = machine_name(); /* The machine name */
- X char *path_val; /* Path value to append */
- X char *tz; /* Time zone value */
- X char name[MAX_STRING]; /* Built 'p_host' */
- X
- X init_env(envp); /* Built the current environment */
- X
- X /* If there is a path: entry in the ~/.mailagent, it is used to replace
- X * then current PATH value. This entry is of course not mandatory. If not
- X * present, we'll simply prepend the added path 'p_host' to the existing
- X * value provided by sendmail, cron, or whoever invoked us.
- X */
- X path_val = ht_value(&symtab, "path");
- X if (path_val != (char *) 0) {
- X if (-1 == set_env("PATH", path_val))
- X fatal("cannot initialize PATH");
- X }
- X
- X sprintf(name, "p_%s", machine); /* Name of field in ~/.mailagent */
- X path_val = ht_value(&symtab, name); /* Exists ? */
- X if (path_val != (char *) 0) { /* Yes, prepend its value */
- X add_log(19, "updating PATH with '%s' from config file", name);
- X if (-1 == prepend_env("PATH", ":"))
- X fatal("cannot set PATH variable");
- X if (-1 == prepend_env("PATH", path_val))
- X fatal("cannot set PATH variable");
- X }
- X
- X /* Also set a correct value for the home directory */
- X if (-1 == set_env("HOME", home))
- X fatal("cannot set HOME variable");
- X
- X /* If there is a 'timezone' variable, set TZ accordingly */
- X tz = ht_value(&symtab, "timezone"); /* Exists ? */
- X if (tz != (char *) 0) {
- X if (-1 == set_env("TZ", tz))
- X add_log(1, "ERROR cannot set TZ variable");
- X }
- X}
- X
- Xprivate void substitute(value)
- Xchar *value;
- X{
- X /* Run parameter and ~ substitution in-place */
- X
- X char buffer[MAX_STRING]; /* Copy on which we work */
- X char *ptr = buffer; /* To iterate over the buffer */
- X char *origin = value; /* Save origin pointer */
- X
- X strcpy(buffer, value); /* Make a copy of original line */
- X while (*value++ = *ptr) /* Line is updated in-place */
- X switch(*ptr++) {
- X case '~': /* Replace by home directory */
- X add_home(&value);
- X break;
- X case '$': /* Variable substitution */
- X add_variable(&value, &ptr);
- X break;
- X }
- X}
- X
- Xprivate void add_home(to)
- Xchar **to; /* Pointer to address in substituted text */
- X{
- X /* Add home directory at the current location. If the 'home' symbol has
- X * been found, use that instead.
- X */
- X
- X char *value = *to - 1; /* Go back to overwrite the '~' */
- X char *ptr = home; /* Where home directory string is stored */
- X char *symbol; /* Symbol entry for 'home' */
- X
- X if (strlen(home) == 0) /* As a special case, this is empty when */
- X ptr = "/"; /* referring to the root directory */
- X
- X symbol = ht_value(&symtab, "home"); /* Maybe we saw 'home' already */
- X if (symbol != (char *) 0) /* Yes, we did */
- X ptr = symbol; /* Use it for ~ substitution */
- X
- X while (*value++ = *ptr++) /* Copy string */
- X ;
- X
- X *to = value - 1; /* Update position in substituted string */
- X}
- X
- Xprivate void add_variable(to, from)
- Xchar **to; /* Pointer to address in substituted text */
- Xchar **from; /* Pointer to address in original text */
- X{
- X /* Add value of variable at the current location */
- X
- X char *value = *to - 1; /* Go back to overwrite the '$' */
- X char *ptr = *from; /* Start of variable's name */
- X char buffer[MAX_STRING]; /* To hold the name of the variable */
- X char *name = buffer; /* To advance in buffer */
- X char *dol_value; /* $value of variable */
- X
- X /* Get variable's name */
- X while (*name++ = *ptr) {
- X if (isalnum(*ptr))
- X ptr++;
- X else
- X break;
- X }
- X
- X *(name - 1) = '\0'; /* Ensure null terminated string */
- X *from = ptr; /* Update pointer in original text */
- X
- X /* Fetch value of variable recorded so far */
- X dol_value = ht_value(&symtab, buffer);
- X if (dol_value == (char *) 0)
- X return;
- X
- X /* Do the variable substitution */
- X while (*value++ = *dol_value++)
- X ;
- X
- X *to = value - 1; /* Update pointer to substituted text */
- X}
- X
- Xprivate void insert_value(path, line)
- Xchar *path; /* The whole line */
- Xint line; /* The line number, for error reports */
- X{
- X /* Analyze the line after parameter substitution and record the value of
- X * the variable in the hash table. The line has the following format:
- X * name : value # trailing comment
- X * If only spaces are encoutered or if the first non blank value is a '#',
- X * then the line is ignored. Otherwise, any error in parsing is reported.
- X */
- X
- X char name[MAX_STRING]; /* The name of the variable */
- X char *nptr = name; /* To fill in the name buffer */
- X
- X while (isspace(*path)) /* Skip leading spaces */
- X path++;
- X
- X if (*path == '#') /* A comment */
- X return; /* Ignore the whole line */
- X if (*path == '\0') /* A line full of spaces */
- X return; /* Ignore it */
- X
- X while (*nptr++ = *path) { /* Copy everything until non alphanum */
- X if (*path == '_') { /* '_' is valid in variable names */
- X path++; /* But is not an alphanumeric char */
- X continue;
- X } else if (!isalnum(*path++)) /* Reached a non-alphanumeric char */
- X break; /* We got variable name */
- X }
- X *(nptr - 1) = '\0'; /* Overwrite the ':' with '\0' */
- X path--; /* Go back on non-alphanum char */
- X while (*path) /* Now go and find the ':' */
- X if (*path++ == ':') /* Found it */
- X break;
- X
- X /* We reached the end of the string without seeing a ':' */
- X if (*path == '\0') {
- X fprintf(stderr, "syntax error in config file, line %d\n", line);
- X return;
- X }
- X
- X while (isspace(*path)) /* Skip leading spaces in value */
- X path++;
- X path[strlen(path) - 1] = '\0'; /* Chop final newline */
- X strip_comment(path); /* Remove trailing comment */
- X (void) ht_put(&symtab, name, path); /* Add value into symbol table */
- X}
- X
- Xprivate void strip_comment(line)
- Xchar *line;
- X{
- X /* Remove anything after first '#' on line (trailing comment) and also
- X * strip any trailing spaces (including those right before the '#'
- X * character).
- X */
- X
- X char *first = (char *) 0; /* First space in sequence */
- X char c; /* Character at current position */
- X
- X while (c = *line++) {
- X if (isspace(c) && first != (char *) 0)
- X continue;
- X if (c == '#') { /* This has to be a comment */
- X if (first != (char *) 0) /* Position of first preceding space */
- X *first = '\0'; /* String ends at first white space */
- X *(line - 1) = '\0'; /* Also truncate at '#' position */
- X return; /* Done */
- X }
- X if (isspace(c))
- X first = line - 1; /* Record first space position */
- X else
- X first = (char *) 0; /* Signal: no active first space */
- X }
- X
- X /* We have not found any '#' sign, so there is no comment in this line.
- X * However, there might be trailing white spaces... Trim them.
- X */
- X
- X if (first != (char *) 0)
- X *first = '\0'; /* Get rid of trailing white spaces */
- X}
- X
- Xprivate char *machine_name()
- X{
- X /* Compute the local machine name, using only lower-cased names and
- X * stipping down any domain name. The result points on a freshly allocated
- X * string. A null pointer is returned in case of error.
- X */
- X
- X#ifdef GETHOSTNAME
- X char name[MAX_STRING + 1]; /* The host name */
- X#else
- X#ifdef UNAME
- X struct utsname un; /* The internal uname structure */
- X#else
- X#ifdef PHOSTNAME
- X char *command = PHOSTNAME; /* Shell command to get hostname */
- X FILE *fd; /* File descriptor on popen() */
- X char name[MAX_STRING + 1]; /* The host name read from command */
- X char buffer[MAX_STRING + 1]; /* Input buffer */
- X#endif
- X#endif
- X#endif
- X
- X#ifdef GETHOSTNAME
- X if (-1 != gethostname(name, MAX_STRING))
- X return strip_down(name);
- X
- X add_log(1, "SYSERR gethostname: %m (%e)");
- X return (char *) 0;
- X#else
- X#ifdef UNAME
- X if (-1 != uname(&un))
- X return strip_down(un.nodename);
- X
- X add_log(1, "SYSERR uname: %m (%e)");
- X return (char *) 0;
- X#else
- X#ifdef PHOSTNAME
- X fd = popen(PHOSTNAME, "r");
- X if (fd != (FILE *) 0) {
- X fgets(buffer, MAX_STRING, fd);
- X fclose(fd);
- X sscanf(buffer, "%s", name);
- X return strip_down(name);
- X }
- X
- X add_log(1, "SYSERR cannot run %s: %m (%e)", PHOSTNAME);
- X#endif
- X return strip_down(HOSTNAME);
- X#endif
- X#endif
- X}
- X
- Xprivate char *strip_down(host)
- Xchar *host;
- X{
- X /* Return a freshly allocated string containing the host name. The string
- X * is lower-cased and the domain part is removed from the name.
- X */
- X
- X char name[MAX_STRING + 1]; /* Constructed name */
- X char *ptr = name;
- X char c;
- X
- X if (host == (char *) 0)
- X return (char *) 0;
- X
- X while (c = *host) { /* Lower-case name */
- X if (isupper(c))
- X *ptr = tolower(c);
- X else
- X *ptr = c;
- X if (c != '.') { /* Found a domain delimiter? */
- X host++; /* No, continue */
- X ptr++;
- X } else
- X break; /* Yes, we end processing there */
- X }
- X *ptr = '\0'; /* Ensure null-terminated string */
- X
- X add_log(19, "hostname is %s", name);
- X
- X return strsave(name); /* Save string in memory */
- X}
- X
- END_OF_FILE
- if test 16295 -ne `wc -c <'agent/filter/parser.c'`; then
- echo shar: \"'agent/filter/parser.c'\" unpacked with wrong size!
- fi
- # end of 'agent/filter/parser.c'
- fi
- if test -f 'agent/pl/dbr.pl' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/pl/dbr.pl'\"
- else
- echo shar: Extracting \"'agent/pl/dbr.pl'\" \(10851 characters\)
- sed "s/^X//" >'agent/pl/dbr.pl' <<'END_OF_FILE'
- X;# $Id: dbr.pl,v 2.9.1.3 92/11/10 10:13:10 ram Exp $
- X;#
- X;# Copyright (c) 1992, Raphael Manfredi
- X;#
- X;# You may redistribute only under the terms of the GNU General Public
- X;# Licence as specified in the README file that comes with dist.
- X;#
- X;# $Log: dbr.pl,v $
- X;# Revision 2.9.1.3 92/11/10 10:13:10 ram
- X;# patch12: unfortunate typo transformed all tags into UNKNOWN
- X;#
- X;# Revision 2.9.1.2 92/11/01 15:46:56 ram
- X;# patch11: now ensures correct hashed name and tags or uses defaults
- X;# patch11: (reported by Nigel Metheringham <nigelm@ohm.york.ac.uk>)
- X;#
- X;# Revision 2.9.1.1 92/08/26 13:09:51 ram
- X;# patch8: update now recognizes undef parameters
- X;# patch8: added a delete interface function
- X;#
- X;# Revision 2.9 92/07/14 16:49:45 ram
- X;# 3.0 beta baseline.
- X;#
- X;#
- X;# This is a simple database. Items are sorted by key, and have a tag
- X;# associated with it. Both are necessary to access the database. Every record
- X;# also carries a time stamp and associated values.
- X;#
- X;# The hashing is done like that: If the key is shorter than two characters,
- X;# an X is appended. Then, let 'a' and 'b' be the first and second character of
- X;# the name. Then the file 'b' is stored under directory 'a', and in 'b' there
- X;# are entries with the following format (separtion is the TAB character).
- X;#
- X;# key tag timestamp <values>
- X;#
- Xpackage dbr;
- X
- X# Compute the relative path under the once directory for a given name
- Xsub hash_path {
- X local($hname) = @_;
- X # Ensure at least 2 characters. Fill in missing chars with 'X'.
- X $hname .= "X" if (length($hname) < 2);
- X $hname .= "X" if (length($hname) < 2);
- X $hname =~ s/[^A-Za-z0-9_]/X/g; # Don't want funny chars in path name
- X # Get only the 2 first characters
- X local(@chars) = split(//, substr($hname, 0, 2));
- X '/' . join('/', @chars);
- X}
- X
- X# Fetch the entry in a dbr file and return the value of the timestamp and
- X# the line number in the file. Return (0,0) if no previous record was found
- X# for the name/tag association. An error is signaled by (-1,0). A line number
- X# different from 0, as in (0, 10), indicates that an entry was found but the
- X# selection did not succeed. Note that the timestamp returned is > 0 iff the
- X# entry was found and the selection was done completely.
- X# All the attached values are returned at the end of the list. It is possible
- X# to filter among those values by specifying a list of regular expressions, at
- X# the end of the argument list. An empty regular expression means the item is
- X# not to be filtered on (equivalent of '/.*/'). Expressions provided are
- X# taken as exact values to be matched against unless they start with '/' or '&'.
- X# A '/' denotes a regular expression to be applied, whilst '&' denotes function
- X# to be called with the actual value argument: function should return zero
- X# for rejection or any other value for selection.
- Xsub info {
- X local($hname, $tag, @what) = @_;
- X local($file); # DBR file associated with '$hname'
- X local(@values); # Attached values to the item
- X local($_);
- X ($hname, $tag) = &default($hname, $tag);
- X $file = $cf'hashdir . &hash_path($hname);
- X return (0,0) unless -f "$file";
- X unless (open(DBR, $file)) {
- X &'add_log("ERROR could not open dbr file $file: $!") if $'loglvl;
- X return (-1, 0);
- X }
- X local($linenum) = 0; # Value of line if found
- X local($timestamp) = 0; # Associated time stamp
- X &'acs_rqst($file); # Lock file (avoid concurrent updating)
- X while (<DBR>) {
- X if (s/^(\S+)\s([\w-]+)\s(\d+)\t*//) {
- X next unless $1 eq $hname;
- X next unless $2 eq $tag;
- X $linenum = $.; # Record line number
- X $timestamp = int($3); # And timestamp
- X last if &match; # Found it if matches @what filter
- X $timestamp = 0; # Not found yet
- X } else { # Invalid entry
- X &'add_log("ERROR $file corrupted, line $.") if $'loglvl;
- X $timestamp = -1; # Signals error
- X last; # Abort processing
- X }
- X }
- X &'free_file($file); # Remove lock on file
- X close DBR; # Close file
- X ($timestamp, $linenum, @values); # Return item information
- X}
- X
- X# Apply match from @what, and fill in @values as a side effect if matched.
- Xsub match {
- X local(@target) = split(/\t|\n/); # Get values from line
- X local($idx) = -1; # Index within @target
- X local($matched) = 1; # Assume selection will match
- X local($res); # Eval result
- X local($@); # Eval error report string
- X foreach $what (@what) {
- X $idx++; # Advance in @target
- X next if $what eq ''; # Skip empty selection
- X if ($what =~ m|^/|) { # Regular expression
- X $res = eval '$target[$idx] =~ ' . $what;
- X &'add_log("WARNING dbr error: $@") if $@ && $'loglvl > 5;
- X next if $@;
- X $matched = $res;
- X } elsif ($what =~ m|^&|) { # Function to apply
- X $res = eval "$what('" . $target[$idx] . "')";
- X &'add_log("WARNING dbr error: $@") if chop($@) && $'loglvl > 5;
- X next if $@;
- X $matched = $res;
- X } else { # Regular string comparaison
- X $matched = $target[$idx] eq $what;
- X }
- X last unless $matched;
- X }
- X @values = @target if $matched; # Fill in values if selection ok
- X $matched; # Return matching status
- X}
- X
- X# Update the entry ($hname, $tag) in file to hold the current timestamp. If the
- X# $linenum parameter is non-null, we know we may copy the old file until that
- X# line (excluded), then replace the current line with the new timestamp.
- X# If $linenum is null, then we may safely append the entry in the file. If
- X# the $linenum parameter is 'undef', then the user does not have it precomputed
- X# or wishes to have the line number re-computed.
- X# The new values held in @values replace the old ones for the entry. If 'undef'
- X# is given instead, then the corresponding entry is deleted from the database.
- Xsub update {
- X local($hname, $tag, $linenum, @values) = @_;
- X local($now) = time; # Current time
- X local($file); # DBR file associated with '$hname'
- X local($_);
- X ($hname, $tag) = &default($hname, $tag);
- X $file = $cf'hashdir . &hash_path($hname);
- X unless (-f "$file") {
- X local($dirname) = $file =~ m|^(.*)/.*|;
- X &'makedir($dirname);
- X }
- X $linenum = (&info($hname, $tag))[1] unless defined($linenum);
- X if ($linenum == 0) { # No entry previously recorded
- X return unless defined(@values); # Nothing to delete
- X unless(open(DBR, ">>$file")) {
- X &'add_log("ERROR cannot append in $file: $!") if $'loglvl;
- X return;
- X }
- X &'acs_rqst($file); # Lock file (avoid concurrent updating)
- X print DBR "$hname $tag $now\t"; # The name, command tag and timestamp
- X print DBR join("\t", @values); # Associated values
- X print DBR "\n";
- X close DBR;
- X &'free_file($file); # Remove lock on file
- X } else { # An entry existed already
- X unless (open(DBR, ">$file.x")) {
- X &'add_log("ERROR cannot create $file.x: $!") if $'loglvl;
- X return;
- X }
- X unless (open(OLD, "$file")) {
- X &'add_log("ERROR couldn't reopen $file: $!") if $'loglvl;
- X close DBR;
- X return;
- X }
- X &'acs_rqst($file); # Lock file (avoid concurrent updating)
- X while (<OLD>) {
- X if ($. < $linenum) { # Before line to update
- X print DBR; # Print line verbatim
- X } elsif ($. == $linenum) { # We reached line to be updated
- X next unless defined(@values);
- X print DBR "$hname $tag $now\t";
- X print DBR join("\t", @values);
- X print DBR "\n";
- X } else { # Past updating point
- X print DBR; # Print line verbatim
- X }
- X }
- X close OLD;
- X close DBR;
- X unless (rename("$file.x", "$file")) {
- X &'add_log("ERROR cannot rename $file.x to $file: $!") if $'loglvl;
- X }
- X &'free_file($file); # Remove lock on file
- X }
- X}
- X
- X# Delete entry. This is really a wrapper to the more general update routine
- X# and is provided as a convenience only.
- Xsub delete {
- X local($hname, $tag, $linenum) = @_;
- X &update($hname, $tag, defined($linenum) ? $linenum : undef, undef);
- X}
- X
- X# Make sure the hashing name and the tag are correct, or use default values.
- Xsub default {
- X local($hname, $tag) = @_;
- X $hname =~ s/^\s+//; # Leading blanks would perturb dbr
- X $hname =~ s/\s/_/g; # All other spaces replaced by _
- X $hname = 'X' unless $hname; # Hashing name cannot be empty
- X $tag =~ s/\s/_/g; # Tag has to be a single word
- X $tag = 'UNKNOWN' unless $tag; # Tag cannot be empty
- X ($hname, $tag);
- X}
- X
- X# Cleaning operation. Remove all the entries in the file whose timestamp is
- X# older than the supplied date limit.
- Xsub clean {
- X local($agemax) = @_;
- X local($limit) = time - $agemax; # Everything newer is kept
- X &recursive_clean($cf'hashdir); # Recursively scan directory
- X}
- X
- X# Recursively scan the direcroy and deal with each file
- Xsub recursive_clean {
- X local($dir) = @_; # Directory to scan
- X local(@contents); # Contents of the directory
- X unless (opendir(DIR, $dir)) {
- X &'add_log("WARNING cannot open directory $dir: $!") if $'loglvl > 5;
- X return;
- X }
- X @contents = readdir(DIR); # Slurp the whole thing
- X close DIR; # And close dir, ready for recursion
- X local($_);
- X foreach (@contents) {
- X next if $_ eq '.' || $_ eq '..';
- X if (-d "$dir/$_") {
- X &recursive_clean("$dir/$_");
- X next;
- X }
- X &clean_file("$dir/$_");
- X }
- X unless (opendir(DIR, $dir)) {
- X &'add_log("WARNING cannot re-open directory $dir: $!") if $'loglvl > 5;
- X return;
- X }
- X @contents = readdir(DIR); # Slurp the whole thing
- X close DIR;
- X unless (@contents > 2) { # Has at least . and ..
- X unless (rmdir($dir)) { # Don't leave empty directories
- X &'add_log("SYSERR rmdir: $!") if $'loglvl;
- X &'add_log("ERROR could not remove directory $file") if $'loglvl;
- X }
- X }
- X}
- X
- X# Clean single dbr file, using $limit as the oldest allowed time stamp
- Xsub clean_file {
- X local($file) = @_; # File to be cleaned
- X &'add_log("processing $file") if $'loglvl > 18;
- X unless (open(FILE, $file)) {
- X &'add_log("WARNING cannot open file $file: $!") if $'loglvl > 5;
- X return;
- X }
- X unless (open(NEW, ">$file.x")) {
- X &'add_log("ERROR cannot create $file.x: $!") if $'loglvl > 1;
- X close FILE;
- X return;
- X }
- X &'acs_rqst($file); # Lock file to prevent concurrent mods
- X local($warns) = 0; # Avoid cascade warnings
- X local($_, $.);
- X while (<FILE>) {
- X if (/^(\S+)\s([\w-]+)\s(\d+)\t*/) {
- X # Variable $limit was set in 'clean'
- X if ($3 > $limit) { # File new enough
- X next if (print NEW); # Copy line verbatim
- X &'add_log("SYSERR write: $!") if $'loglvl;
- X &'add_log("WARNING truncated $file at line $.") if $'loglvl > 5;
- X last;
- X }
- X } else {
- X # Skip bad lines, up to a maximum of 10
- X if (++$warns > 10) {
- X &'add_log("WARNING $file truncated at line $.") if $'loglvl > 5;
- X last;
- X } else {
- X &'add_log("NOTICE $file corrupted, line $.") if $'loglvl > 6;
- X next;
- X }
- X }
- X }
- X close FILE;
- X close NEW;
- X unless (rename("$file.x", $file)) {
- X &'add_log("ERROR cannot rename $file.x to $file: $!") if $'loglvl;
- X }
- X unless (-s "$file") {
- X unless (unlink($file)) { # Don't leave empty files behind
- X &'add_log("SYSERR unlink: $!") if $'loglvl;
- X &'add_log("ERROR could not remove $file") if $'loglvl;
- X }
- X }
- X &'free_file($file); # Remove lock on file
- X}
- X
- Xpackage main;
- X
- END_OF_FILE
- if test 10851 -ne `wc -c <'agent/pl/dbr.pl'`; then
- echo shar: \"'agent/pl/dbr.pl'\" unpacked with wrong size!
- fi
- # end of 'agent/pl/dbr.pl'
- fi
- if test -f 'agent/test/cmd/run.t' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'agent/test/cmd/run.t'\"
- else
- echo shar: Extracting \"'agent/test/cmd/run.t'\" \(294 characters\)
- sed "s/^X//" >'agent/test/cmd/run.t' <<'END_OF_FILE'
- X# The RUN command
- Xdo '../pl/cmd.pl';
- Xunlink 'ok';
- X
- X&add_header('X-Tag: run');
- X`$cmd`;
- X$? == 0 || print "1\n";
- X-f "$user" && print "2\n"; # Mail not saved
- X-f 'ok' || print "3\n"; # Output of /bin/echo
- X&get_log(4, 'ok');
- X&check_log('Works.', 5); # It works
- X
- Xunlink 'ok', 'mail';
- Xprint "0\n";
- END_OF_FILE
- if test 294 -ne `wc -c <'agent/test/cmd/run.t'`; then
- echo shar: \"'agent/test/cmd/run.t'\" unpacked with wrong size!
- fi
- # end of 'agent/test/cmd/run.t'
- fi
- echo shar: End of archive 9 \(of 17\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 17 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-