From: "Rick Williams" Date: Wed, 12 May 1999 09:16:02 +0100 I was asked for a copy of the programs we were using to mail everybody and as they are not too big I hope you don't mind me posting them here. There are two programs emailrequest.pl and post_all.pl, they both require Mail.pm which I understand is generally available. These programs have been completely re-written from scratch by one of our programmers and work . The usual disclaimers apply. emailrequest.pl generates a list of all current users from the password list sorted on company, surname and firstname, this is very useful for us here because our staff constantly changes. The other, post_all.pl takes a message and sends it on to all users in the password list as a BCC, there are certain filters in the program to miss out non-human users. You will need some settings in your aliases file to call these programs (although rather obvious). The first setting is needed. ### Alias File ### discard: :blackhole: #email list request email: "|/where/you/put/it/emailrequest.pl" #mail to everyone everyone: "|/where/you/put/it/post_all.pl" #If you want to send a mass message to one part of your org only #and it is defined in the company setting in the password file #then use company: "|/where/you/put/it/post_all.pl \"Company Section\"" --Message-Boundary-12668 Content-description: Text from file 'emailrequest.pl' #!/usr/bin/perl # # # Internal EMail List Generator # # Version 2.0 # # William F. McCaw 1999 # # # Returns an email containing a sorted list of all valid users on the # system, grouped according to company. # # For this program to work properly, the following conditions must be met # for all valid email recipients... # # * Their UID must be between 1000 and 60000 (inclusive). # * Their Name must be defined. # * Their Name must not start with a lower case 'x'. # * Their Name must not be 'nobody'. # * Their must be of the following format... # # "Forename Surname, Company" # # Note... The ", Company" must be present. # Forename is assumed to be the first word. # Surname is assumed to be everything else. # # # Read the message from standard input # $MsgSender = ''; # Extract the required details from the message's header while ( defined($Line = ) && ($Line =~ /^[^\r\n]/) ) { $Line =~ s/[\r\n]//gs; if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i ) # First choice for sender { $MsgSender = $1; } if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender ) # May be no return path { $MsgSender = $1; } } # Ensure we have a sender's address exit(0) if ( !$MsgSender ); # # Read the contents of the system's password file # open(PASS, '/etc/passwd') || exit(0); @Users = ; close(PASS); # # Extract the details of all valid users from the password file and batch # them according to the company name associated with them. # %Companies = (); foreach $User ( @Users ) { # Separate the current user's details and determine whether to include them # within the generated email list ( $EMail, $Password, $UID, $GID, $Name, $Home, $Shell ) = split(/:/, $User); next if ( !defined($UID) || ($UID < 1000) || ($UID > 60000) || !defined($Name) || ($Name =~ /^x/) || ($Name eq 'nobody') ); # Ensure the name field contains a company name next if ( !($Name =~ /^(.*?)\s*\,\s*(.*?)$/) ); $Name = $1; $Company = $2; # Get the reference to the members array for this company, creating the # company entry as and when required if ( exists($Companies{uc($Company)}) ) { $Members = $Companies{uc($Company)}->[1]; } else { $Members = []; $Companies{uc($Company)} = [ $Company, $Members ]; } # Massage the user's name into the required "Surname, Forename" format if ( $Name =~ /^\s*([^\s]+)\s+(.+)$/ ) { $Name = "$2, $1"; } # Append the user to the list for the current company push(@$Members, [ $Name, $EMail ]); } # # Generate the email back to the original sender containing the full list # open(MAIL, "|/usr/bin/exim -t"); # # Output the message headers and leading message body text print(MAIL "From: $MsgSender\n", "To: $MsgSender\n", "Subject: Requested EMail List\n\n", "Internal EMail addresses as of: ", scalar(localtime()), "\n"); # # Output the sorted list of companies, and within that, output the sorted # list of individuals within that company foreach $Company ( sort(keys(%Companies)) ) { $Company = $Companies{$Company}; print(MAIL "\n", $Company->[0], "\n", ('~' x (length($Company->[0]) + 1)), "\n"); foreach $Member ( sort({ uc($a->[0]) cmp uc($b->[0]) } @{$Company->[1]}) ) { printf(MAIL " %-34s %s\n", $Member->[0], $Member->[1]); } } # # Output the trailing message footer print(MAIL "\n", "Remember to received an updated email list, just send a blank message to\n", "email\@charlesworth.com and you should get a reply within 30 seconds.\n\n", "For more information or any queries contact sysadmin\@charlesworth.com\n\n"); close(MAIL); # # End of File # --Message-Boundary-12668 Content-description: Text from file 'post_all.pl' #!/usr/bin/perl # # # "Everyone" EMail Exploder # # Version 2.0 # # William F. McCaw 1999 # # # Sends body of message supplied on STDIN to all valid users listed within # the computer's /etc/passwd file. # # * Original headers, apart from the sender and subject are discarded. # * Recipients are batched with up to 60 per email. # * Recipients are specified via 'Bcc:'. # # # Function Prototypes # sub SendMessage(); # # Determine the target company for sending out the email to # $TargetCompany = (( defined($ARGV[0]) ) ? $ARGV[0] : ''); # # Read the message from standard input # $MsgSender = ''; $MsgSubject = ''; # Extract the required details from the message's header while ( defined($Line = ) && ($Line =~ /^[^\r\n]/) ) { $Line =~ s/[\r\n]//gs; if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i ) # First choice for sender { $MsgSender = $1; } if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender ) # May be no return path { $MsgSender = $1; } elsif ( $Line =~ /^Subject:\s*(.+)/i ) # Preserve the subject { $MsgSubject = $1; } } # If we are missing certain information then provide some defaults $MsgSubject = '*** Unknown Subject ***' if ( !$MsgSubject ); # Read in the message body and signature @MsgBody = ; # # Read the contents of the system's password file # open(PASS, '/etc/passwd') || exit(0); @Users = ; close(PASS); # # Send the message to all the users within the password file # @MsgRecipients = (); foreach $User ( @Users ) { # Split the current users's details and determine whether to send the # message to them or not ( $EMail, $Password, $UID, $GID, $Name, $Home, $Shell ) = split(/:/, $User); next if ( !defined($UID) || ($UID < 1000) || ($UID > 60000) || !defined($Name) || ($Name =~ /^x/) || ($Name eq 'nobody') ); next if ( $TargetCompany && !($Name =~ /\,\s*$TargetCompany/io) ); # If we have already reached the recipient limit for this message then # dispatch it and reset the recipient list ready for the next message if ( scalar(@MsgRecipients) == 60 ) { SendMessage(); @MsgRecipients = (); } # Append the current email address to the recipient list push(@MsgRecipients, $EMail); } # # Ensure the folk at the end of the user list receive the message if ( scalar(@MsgRecipients) ) { SendMessage(); } # # # Routine to send the specified message # sub SendMessage() { open(MAIL, "|/usr/bin/exim -t"); print(MAIL "From: $MsgSender\n") if ( $MsgSender ); print(MAIL "To: Everyone \n", "Subject: TO EVERYONE: $MsgSubject\n", "Bcc: ", join(", ", @MsgRecipients), "\n\n", @MsgBody, "\n"); close(MAIL); } # # End of File #