Common subdirectories: ./Tools and ../majordomo-1.94.4//Tools
diff -u ./archive2.pl ../majordomo-1.94.4//archive2.pl
--- ./archive2.pl       Thu Aug 28 16:33:40 1997
+++ ../majordomo-1.94.4//archive2.pl    Thu Aug 28 16:35:16 1997
@@ -4,8 +4,8 @@
# permission only.
#
# $Source: /sources/cvsrepos/majordomo/archive2.pl,v $
-# $Revision: 1.9 $
-# $Date: 1996/12/12 15:01:39 $
+# $Revision: 1.10 $
+# $Date: 1997/08/27 15:07:44 $
# $Author: cwilson $
# $State: Exp $
#
@@ -16,11 +16,14 @@
#      -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 <archive>.YYMMDD
+#      -D      Archive file is <archive>.YYYYMMDD
#      -m      Archive file is <archive>.YYMM
+#      -M      Archive file is <archive>.YYYYMM
#      -y      Archive file is <archive>.YY
+#      -Y      Archive file is <archive>.YYYY
# Exactly one of "-u" or "-a" must be specified.
-# At most one of "-d", "-m", or "-y" may be specified; if none is
-#   specified, archive name is simply <archive>
+# At most one of "-d", "-D", "-m", "-M", "-y", or "-Y" may be specified;
+# if none is specified, archive name is simply <archive>
#
# 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":
@@ -76,9 +79,9 @@
    $MoY{$_} = $m++;
}

-$usage = "Usage: $0 -f <file> {-u|-a} [-d|-m|-y] [file ...]";
+$usage = "Usage: $0 -f <file> {-u|-a} [-d|-D|-m|-M|-y|-Y] [file ...]";

-&Getopts("f:uadmy") || die("$usage\nStopped");
+&Getopts("f:uadDmMyY") || die("$usage\nStopped");

if (!defined($opt_f)) {
    print STDERR "'-f <list>' required\n$usage\n";
@@ -103,10 +106,13 @@
$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', '-m', or '-y' allowed\n$usage\n";
+    print STDERR "Only one of '-d', '-D', '-m', '-M', -y', or '-Y' allowed\n$usage\n";
    exit 3;
}

@@ -159,11 +165,20 @@
    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") ||
Common subdirectories: ./bin and ../majordomo-1.94.4//bin
diff -u ./config-test ../majordomo-1.94.4//config-test
--- ./config-test       Thu Aug 28 16:33:40 1997
+++ ../majordomo-1.94.4//config-test    Thu Aug 28 16:35:15 1997
@@ -1,5 +1,5 @@
#!/bin/perl
-# $Id: config-test,v 1.17 1997/03/10 17:22:05 cwilson Exp $
+# $Id: config-test,v 1.18 1997/08/27 15:17:13 cwilson Exp $
# configuration test for majordomo
# provided with majordomo, modifications by darren stalder <[email protected]>
# more mods by Vince Skahan <[email protected]>
@@ -210,10 +210,10 @@
    }
}

-if ( -r $log && -w $log) {
+if ( -f $log && -r $log && -w $log) {
    &good("logfile $log exists and is writeable.");
} else {
-    &bad("logfile $log exists, but is not writeable.");
+    &bad("logfile $log exists, but is not writeable or isn't a file.");
}

&header ("Mailers");
diff -u ./config_parse.pl ../majordomo-1.94.4//config_parse.pl
--- ./config_parse.pl   Thu Aug 28 16:33:38 1997
+++ ../majordomo-1.94.4//config_parse.pl        Thu Aug 28 16:35:14 1997
@@ -5,7 +5,7 @@
# writes into the global variable %main'config_opts
#

-# $Header: /sources/cvsrepos/majordomo/config_parse.pl,v 1.63 1997/04/20 16:06:58 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/config_parse.pl,v 1.64 1997/08/27 14:41:32 cwilson Exp $
# $Modified: Tue Dec 17 19:29:14 1996 by cwilson $

# this array holds the interesting info for use by all tools
@@ -76,6 +76,8 @@
# 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.
@@ -145,6 +147,16 @@
# 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
@@ -404,6 +416,8 @@
# 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',
@@ -458,6 +472,8 @@
# 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',
diff -u ./digest ../majordomo-1.94.4//digest
--- ./digest    Thu Aug 28 16:33:41 1997
+++ ../majordomo-1.94.4//digest Thu Aug 28 16:35:16 1997
@@ -5,12 +5,12 @@
# Heavily modified by Brent Chapman <[email protected]>

# $Source: /sources/cvsrepos/majordomo/digest,v $
-# $Revision: 1.22 $
-# $Date: 1997/03/10 17:11:25 $
+# $Revision: 1.23 $
+# $Date: 1997/08/27 14:42:52 $
# $Author: cwilson $
# $State: Exp $
#
-# $Header: /sources/cvsrepos/majordomo/digest,v 1.22 1997/03/10 17:11:25 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/digest,v 1.23 1997/08/27 14:42:52 cwilson Exp $
#
#

@@ -21,10 +21,9 @@

&init;
&readconfig;
-$TEMP = "$TMPDIR/digest.$$" || "/usr/tmp/digest.$$";
+$TEMP = (defined $TMPDIR && -d $TMPDIR) ?
+       "$TMPDIR/digest.$$" : "/usr/tmp/digest.$$";

-$sendmail_command = "/usr/lib/sendmail" if ! defined $sendmail_command ;
-
if (defined($opt_r)) {
    &receive_message;
    if (&should_be_sent(1)) {
@@ -164,17 +163,19 @@
#
sub send_digest {
    local($lastfile) = shift;
-    @files=<$V{'INCOMING'}/*>;
-    if ($#files < $[) {
-       &abort("No messages.\nStopped ");
+    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 $message (@files) {
-       print STDERR "non digest input file $message", next
-           if $message !~ m#/\d+$#;
+    foreach (@files) {
+           $message = "$V{'INCOMING'}/$_";
           open(message) || &abort("$message: $!\n");
-           #side note: "open message or die"?
           print STDERR "\tprocessing $message\n";
           push(@processed,$message);

@@ -327,6 +328,8 @@
# 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);
@@ -378,6 +381,20 @@
            } # 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 (<config>) {
               next if /^\s*$|^\s*#/;
diff -u ./majordomo ../majordomo-1.94.4//majordomo
--- ./majordomo Thu Aug 28 16:33:38 1997
+++ ../majordomo-1.94.4//majordomo      Thu Aug 28 16:35:14 1997
@@ -8,8 +8,8 @@
#   usage rights.
#
# $Source: /sources/cvsrepos/majordomo/majordomo,v $
-# $Revision: 1.87 $
-# $Date: 1997/04/20 16:11:49 $
+# $Revision: 1.88 $
+# $Date: 1997/08/27 14:55:29 $
# $Author: cwilson $
# $State: Exp $
#
@@ -457,9 +457,8 @@
               # 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\"): $!");
-               unlink("$listdir/$clean_list");
-               link("$listdir/$clean_list.new", "$listdir/$clean_list") ||
-                   &abort("link(\"$listdir/$clean_list.new\", \"$listdir/$clean_list\"): $!");
+               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";
@@ -471,11 +470,13 @@
                 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";
@@ -813,10 +814,6 @@
               &lclose(INFO);
               print REPLY "New info for list $clean_list accepted.\n";
               &log("newinfo $clean_list PASSWORD");
-               # if we read to actual end-of-file, we are done
-               if (eof) {
-                   &done();
-               }
           } else {
               &abort("Can't write $listdir/$clean_list.info: $!");
           }
@@ -829,10 +826,6 @@
                   last;
               }
           }
-           # if we read to actual end-of-file, we are done
-           if (eof) {
-               &done();
-           }
       }
    } else {
       &squawk("newinfo: unknown list '$list'.");
@@ -842,10 +835,6 @@
               last;
           }
        }
-       # if we read to actual end-of-file, we are done
-       if (eof) {
-           &done();
-       }
    }
}

@@ -924,10 +913,6 @@
               chmod(0664, "$listdir/$clean_list.intro");
               print REPLY "New intro for list $clean_list accepted.\n";
               &log("newintro $clean_list PASSWORD");
-               # if we read to actual end-of-file, we are done
-               if (eof) {
-                   &done();
-               }
           } else {
               &abort("Can't write $listdir/$clean_list.intro: $!");
           }
@@ -940,10 +925,6 @@
                   last;
               }
           }
-           # if we read to actual end-of-file, we are done
-           if (eof) {
-               &done();
-           }
       }
    } else {
       &squawk("newintro: unknown list '$list'.");
@@ -953,10 +934,6 @@
               last;
           }
        }
-       # if we read to actual end-of-file, we are done
-       if (eof) {
-           &done();
-       }
    }
}
sub do_config {
@@ -1046,10 +1023,11 @@
               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");
-                   unlink "$listdir/$clean_list.new.config";
                   return (1);
               }

@@ -1190,7 +1168,6 @@
sub do_lists {
    # Tell the requester what lists we serve
    local($list);
-    local($command_advert, $command_noadvert);
    local($reply_addr) = &ParseAddrs($reply_to);

    select((select(REPLY), $| = 1)[0]);
@@ -1212,16 +1189,14 @@
       if (    ($'config_opts{$list, 'advertise'} ne '')
            || ($'config_opts{$list, 'noadvertise'} ne '') ) {

-           local(@array) = ();
-           local($i, $command, $result) = ();
-               $reply_addr =~ s/\@/\\\@/g;
-               $result = 0;
+           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) {
-                     $command = "(q~$reply_addr~ =~ $i)";
-                     $result = 1, last if (eval $command);
+                     $result = 1, last if (eval $i); # Expects $_ = $reply_addr
                  }
                } else { $result = 1; }

@@ -1230,9 +1205,7 @@
                  @array = split(/\001/,$'config_opts{$list, 'noadvertise'});

                  foreach $i (@array) {
-                     $command = "(q~$reply_addr~ =~ $i)";
-                     print STDERR "do_lists: noadvertise execing $command\n" if $DEBUG;
-                     $result = 0, last if (eval $command);
+                     $result = 0, last if (eval $i); # Expects $_ = $reply_addr
                   }
               }

@@ -1852,6 +1825,9 @@
    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");
@@ -1925,11 +1901,15 @@
    # close (and thereby send) the welcome message to the subscriber
    close(MSG);

-    # tell the list owner of the new subscriber
+       }
+
+    # 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
diff -u ./majordomo.cf ../majordomo-1.94.4//majordomo.cf
--- ./majordomo.cf      Thu Aug 28 16:33:43 1997
+++ ../majordomo-1.94.4//majordomo.cf   Thu Aug 28 16:35:19 1997
@@ -98,7 +98,7 @@
# imbecile Internet, "open+confirm" or "auto+confirm" is a wiser
# choice for publicly available Majordomo servers.
#
-# $config'default_subscribe_policy = "open+confirm";
+$config'default_subscribe_policy = "open+confirm";

#
#  Configure X400 parsing here.  This is functional, but not well tested
@@ -220,7 +220,7 @@
# no trailing ";"
# For example:
#   $global_taboo_headers = <<'END';
-#   /^from:.*[email protected]/i
+#   /^from:.*trouble\@hassle\.net/i
#   /^subject:.*non-delivery notice/i
#   END
# NOTE! Using ' instead of " in the 'END' is VERY IMPORTANT!!!
@@ -313,4 +313,4 @@
$majordomo_dont_reply = '(mailer-daemon|uucp|listserv|majordomo|listproc)\@';

1;
-# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.33 1997/04/27 14:56:45 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.34 1997/08/27 15:00:31 cwilson Exp $
diff -u ./majordomo.pl ../majordomo-1.94.4//majordomo.pl
--- ./majordomo.pl      Thu Aug 28 16:33:39 1997
+++ ../majordomo-1.94.4//majordomo.pl   Thu Aug 28 16:35:14 1997
@@ -1,12 +1,12 @@
# General subroutines for Majordomo

# $Source: /sources/cvsrepos/majordomo/majordomo.pl,v $
-# $Revision: 1.55 $
-# $Date: 1997/04/02 14:04:14 $
+# $Revision: 1.56 $
+# $Date: 1997/08/27 14:58:53 $
# $Author: cwilson $
# $State: Exp $
#
-# $Header: /sources/cvsrepos/majordomo/majordomo.pl,v 1.55 1997/04/02 14:04:14 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/majordomo.pl,v 1.56 1997/08/27 14:58:53 cwilson Exp $
#

# The exit codes for abort.  Look in /usr/include/sysexits.h.
@@ -707,7 +707,7 @@
}

sub main'is_list_member {
-    local($subscriber, $listdir, $clean_list) = @_;
+    local($subscriber, $listdir, $clean_list, $file) = @_;
    local($matches) = 0;
    local(*LIST);
    local($_);
@@ -714,10 +714,11 @@

    print STDERR "is_list_member: enter\n" if $DEBUG;

-    $clean_list = "$listdir/$clean_list" if $listdir;
-    print STDERR "is_list_member: checking $clean_list for $subscriber\n"
+    $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, $clean_list)) {
+    if (open(LIST, $file)) {
       while (<LIST>) {
           if (&main'addr_match($subscriber, $_,
              (&main'cf_ck_bool($clean_list,"mungedomain") ? 2 : undef))) {
@@ -728,7 +729,7 @@
       close(LIST);
    }
    else {
-       &main'bitch("Can't read $clean_list: $!"); #'"";
+       &main'bitch("Can't read $file: $!"); #'"";
    }

    print STDERR "is_list_member: exit $matches\n" if $DEBUG;
@@ -796,8 +797,7 @@

    $total = 0;
    foreach $list (@lists) {
-       $list = "$listdir/$list" unless ($list =~ m|^/|);
-       $total += &main'is_list_member($subscriber, "", $list);
+       $total += &main'is_list_member($subscriber, $listdir, $clean_list, $list);
    }
    print STDERR "access_check: exit\n" if $DEBUG;
    return $total;
diff -u ./majordomo_version.pl ../majordomo-1.94.4//majordomo_version.pl
--- ./majordomo_version.pl      Thu Aug 28 16:33:39 1997
+++ ../majordomo-1.94.4//majordomo_version.pl   Thu Aug 28 16:35:14 1997
@@ -1,5 +1,5 @@
-# $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.25 1997/04/28 18:20:31 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/majordomo_version.pl,v 1.26 1997/08/27 15:56:36 cwilson Exp $

-$majordomo_version = "1.94.3";
+$majordomo_version = "1.94.4";
1;

Common subdirectories: ./man and ../majordomo-1.94.4//man
diff -u ./resend ../majordomo-1.94.4//resend
--- ./resend    Thu Aug 28 16:33:40 1997
+++ ../majordomo-1.94.4//resend Thu Aug 28 16:35:15 1997
@@ -5,8 +5,8 @@
# permission only.
#
# $Source: /sources/cvsrepos/majordomo/resend,v $
-# $Revision: 1.85 $
-# $Date: 1997/04/02 14:04:48 $
+# $Revision: 1.86 $
+# $Date: 1997/08/27 14:59:24 $
# $Author: cwilson $
# $State: Exp $
#
@@ -552,17 +552,13 @@
    local(@files) = split (/[:\s]+/, $opt_I);

    foreach $file (@files) {
-       # add $listdir if not explicitly set.
-       #
-       $file = "$listdir/$file" unless ($file =~ m|^/|);
-
       # Return a null message if the sender (from the From: or
       # Reply-To: headers) is found
       #
-       return "" if &is_list_member($from, "", $file) ||
+       return "" if &is_list_member($from, $listdir, $opt_l, $file) ||
           (defined $reply_to  &&
           $reply_to ne $from  &&
-           &is_list_member($reply_to, "", $file));
+           &is_list_member($reply_to, $listdir, $opt_l, $file));
    }

    # We only get here if nothing matches.
diff -u ./sample.cf ../majordomo-1.94.4//sample.cf
--- ./sample.cf Thu Aug 28 16:33:44 1997
+++ ../majordomo-1.94.4//sample.cf      Thu Aug 28 16:35:19 1997
@@ -98,7 +98,7 @@
# imbecile Internet, "open+confirm" or "auto+confirm" is a wiser
# choice for publicly available Majordomo servers.
#
-# $config'default_subscribe_policy = "open+confirm";
+$config'default_subscribe_policy = "open+confirm";

#
#  Configure X400 parsing here.  This is functional, but not well tested
@@ -220,7 +220,7 @@
# no trailing ";"
# For example:
#   $global_taboo_headers = <<'END';
-#   /^from:.*[email protected]/i
+#   /^from:.*trouble\@hassle\.net/i
#   /^subject:.*non-delivery notice/i
#   END
# NOTE! Using ' instead of " in the 'END' is VERY IMPORTANT!!!
@@ -313,4 +313,4 @@
$majordomo_dont_reply = '(mailer-daemon|uucp|listserv|majordomo|listproc)\@';

1;
-# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.33 1997/04/27 14:56:45 cwilson Exp $
+# $Header: /sources/cvsrepos/majordomo/sample.cf,v 1.34 1997/08/27 15:00:31 cwilson Exp $
Binary files ./wrapper and ../majordomo-1.94.4//wrapper differ