1 From: "Rick Williams" <rick@charlesworth.com>
2 Date: Wed, 12 May 1999 09:16:02 +0100
4 I was asked for a copy of the programs we were using to mail
5 everybody and as they are not too big I hope you don't mind me
6 posting them here. There are two programs emailrequest.pl and
7 post_all.pl, they both require Mail.pm which I understand is
10 These programs have been completely re-written from scratch by
11 one of our programmers and work <G>. The usual disclaimers
14 emailrequest.pl generates a list of all current users from the
15 password list sorted on company, surname and firstname, this is
16 very useful for us here because our staff constantly changes. The
17 other, post_all.pl takes a message and sends it on to all users in
18 the password list as a BCC, there are certain filters in the program
19 to miss out non-human users.
21 You will need some settings in your aliases file to call these
22 programs (although rather obvious). The first setting is needed.
28 email: "|/where/you/put/it/emailrequest.pl"
31 everyone: "|/where/you/put/it/post_all.pl"
33 #If you want to send a mass message to one part of your org only
34 #and it is defined in the company setting in the password file
36 company: "|/where/you/put/it/post_all.pl \"Company Section\""
39 --Message-Boundary-12668
40 Content-description: Text from file 'emailrequest.pl'
45 # Internal EMail List Generator
49 # William F. McCaw 1999
52 # Returns an email containing a sorted list of all valid users on the
53 # system, grouped according to company.
55 # For this program to work properly, the following conditions must be met
56 # for all valid email recipients...
58 # * Their UID must be between 1000 and 60000 (inclusive).
59 # * Their Name must be defined.
60 # * Their Name must not start with a lower case 'x'.
61 # * Their Name must not be 'nobody'.
62 # * Their must be of the following format...
64 # "Forename Surname, Company"
66 # Note... The ", Company" must be present.
67 # Forename is assumed to be the first word.
68 # Surname is assumed to be everything else.
73 # Read the message from standard input
76 # Extract the required details from the message's header
77 while ( defined($Line = <STDIN>) && ($Line =~ /^[^\r\n]/) )
79 $Line =~ s/[\r\n]//gs;
80 if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i ) # First choice for sender
82 if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender ) # May be no return path
85 # Ensure we have a sender's address
86 exit(0) if ( !$MsgSender );
89 # Read the contents of the system's password file
91 open(PASS, '/etc/passwd') || exit(0);
96 # Extract the details of all valid users from the password file and batch
97 # them according to the company name associated with them.
100 foreach $User ( @Users )
102 # Separate the current user's details and determine whether to include them
103 # within the generated email list
104 ( $EMail, $Password, $UID, $GID, $Name, $Home, $Shell ) = split(/:/, $User);
105 next if ( !defined($UID) || ($UID < 1000) || ($UID > 60000) ||
106 !defined($Name) || ($Name =~ /^x/) || ($Name eq 'nobody') );
107 # Ensure the name field contains a company name
108 next if ( !($Name =~ /^(.*?)\s*\,\s*(.*?)$/) );
111 # Get the reference to the members array for this company, creating the
112 # company entry as and when required
113 if ( exists($Companies{uc($Company)}) )
114 { $Members = $Companies{uc($Company)}->[1]; }
118 $Companies{uc($Company)} = [ $Company, $Members ];
120 # Massage the user's name into the required "Surname, Forename" format
121 if ( $Name =~ /^\s*([^\s]+)\s+(.+)$/ )
122 { $Name = "$2, $1"; }
123 # Append the user to the list for the current company
124 push(@$Members, [ $Name, $EMail ]);
128 # Generate the email back to the original sender containing the full list
130 open(MAIL, "|/usr/bin/exim -t");
132 # Output the message headers and leading message body text
133 print(MAIL "From: $MsgSender\n",
135 "Subject: Requested EMail List\n\n",
136 "Internal EMail addresses as of: ", scalar(localtime()), "\n");
138 # Output the sorted list of companies, and within that, output the sorted
139 # list of individuals within that company
140 foreach $Company ( sort(keys(%Companies)) )
142 $Company = $Companies{$Company};
145 ('~' x (length($Company->[0]) + 1)), "\n");
146 foreach $Member ( sort({ uc($a->[0]) cmp uc($b->[0]) } @{$Company->[1]}) )
147 { printf(MAIL " %-34s %s\n", $Member->[0], $Member->[1]); }
150 # Output the trailing message footer
152 "Remember to received an updated email list, just send a blank message to\n",
153 "email\@charlesworth.com and you should get a reply within 30 seconds.\n\n",
154 "For more information or any queries contact sysadmin\@charlesworth.com\n\n");
162 --Message-Boundary-12668
163 Content-description: Text from file 'post_all.pl'
168 # "Everyone" EMail Exploder
172 # William F. McCaw 1999
175 # Sends body of message supplied on STDIN to all valid users listed within
176 # the computer's /etc/passwd file.
178 # * Original headers, apart from the sender and subject are discarded.
179 # * Recipients are batched with up to 60 per email.
180 # * Recipients are specified via 'Bcc:'.
184 # Function Prototypes
190 # Determine the target company for sending out the email to
192 $TargetCompany = (( defined($ARGV[0]) ) ? $ARGV[0] : '');
195 # Read the message from standard input
199 # Extract the required details from the message's header
200 while ( defined($Line = <STDIN>) && ($Line =~ /^[^\r\n]/) )
202 $Line =~ s/[\r\n]//gs;
203 if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i ) # First choice for sender
205 if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender ) # May be no return path
207 elsif ( $Line =~ /^Subject:\s*(.+)/i ) # Preserve the subject
208 { $MsgSubject = $1; }
210 # If we are missing certain information then provide some defaults
211 $MsgSubject = '*** Unknown Subject ***' if ( !$MsgSubject );
212 # Read in the message body and signature
216 # Read the contents of the system's password file
218 open(PASS, '/etc/passwd') || exit(0);
223 # Send the message to all the users within the password file
226 foreach $User ( @Users )
228 # Split the current users's details and determine whether to send the
229 # message to them or not
230 ( $EMail, $Password, $UID, $GID, $Name, $Home, $Shell ) = split(/:/, $User);
231 next if ( !defined($UID) || ($UID < 1000) || ($UID > 60000) ||
232 !defined($Name) || ($Name =~ /^x/) || ($Name eq 'nobody') );
233 next if ( $TargetCompany && !($Name =~ /\,\s*$TargetCompany/io) );
234 # If we have already reached the recipient limit for this message then
235 # dispatch it and reset the recipient list ready for the next message
236 if ( scalar(@MsgRecipients) == 60 )
241 # Append the current email address to the recipient list
242 push(@MsgRecipients, $EMail);
245 # Ensure the folk at the end of the user list receive the message
246 if ( scalar(@MsgRecipients) )
253 # Routine to send the specified message
257 open(MAIL, "|/usr/bin/exim -t");
258 print(MAIL "From: $MsgSender\n") if ( $MsgSender );
259 print(MAIL "To: Everyone <discard>\n",
260 "Subject: TO EVERYONE: $MsgSubject\n",
261 "Bcc: ", join(", ", @MsgRecipients), "\n\n",