Version updated for 4.66 - record breaking speed of update (for once)
[exim-website.git] / config.samples / C020
1 From: "Rick Williams" <rick@charlesworth.com>
2 Date: Wed, 12 May 1999 09:16:02 +0100
3
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 
8 generally available.
9
10 These programs have been completely re-written from scratch by 
11 one of our programmers and work <G>. The usual disclaimers 
12 apply. 
13
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.
20
21 You will need some settings in your aliases file to call these 
22 programs (although rather obvious). The first setting is needed.
23
24 ### Alias File ###
25 discard:        :blackhole:
26
27 #email list request
28 email:          "|/where/you/put/it/emailrequest.pl"
29
30 #mail to everyone
31 everyone:       "|/where/you/put/it/post_all.pl"
32
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
35 #then use
36 company:        "|/where/you/put/it/post_all.pl \"Company Section\""
37
38
39 --Message-Boundary-12668
40 Content-description: Text from file 'emailrequest.pl'
41
42 #!/usr/bin/perl
43 #
44 #
45 #  Internal EMail List Generator
46 #
47 #  Version 2.0
48 #
49 #  William F. McCaw  1999
50 #
51 #
52 #  Returns an email containing a sorted list of all valid users on the
53 #  system, grouped according to company.
54 #
55 #  For this program to work properly, the following conditions must be met
56 #  for all valid email recipients...
57 #
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...
63 #
64 #       "Forename Surname, Company"
65 #
66 #    Note... The ", Company" must be present.
67 #            Forename is assumed to be the first word.
68 #            Surname is assumed to be everything else.
69 #
70
71
72 #
73 # Read the message from standard input
74 #
75 $MsgSender = '';
76 # Extract the required details from the message's header
77 while ( defined($Line = <STDIN>) && ($Line =~ /^[^\r\n]/) )
78    {
79    $Line =~ s/[\r\n]//gs;
80    if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i )     # First choice for sender
81       { $MsgSender = $1; }
82    if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender )  # May be no return path
83       { $MsgSender = $1; }
84    }
85 # Ensure we have a sender's address
86 exit(0) if ( !$MsgSender );
87
88 #
89 # Read the contents of the system's password file
90 #
91 open(PASS, '/etc/passwd') || exit(0);
92 @Users = <PASS>;
93 close(PASS);
94
95 #
96 # Extract the details of all valid users from the password file and batch
97 # them according to the company name associated with them.
98 #
99 %Companies = ();
100 foreach $User ( @Users )
101    {
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*(.*?)$/) );
109    $Name = $1;
110    $Company = $2;
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]; }
115    else
116       {
117       $Members = [];
118       $Companies{uc($Company)} = [ $Company, $Members ];
119       }
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 ]);
125    }
126
127 #
128 # Generate the email back to the original sender containing the full list
129 #
130 open(MAIL, "|/usr/bin/exim -t");
131 #
132 # Output the message headers and leading message body text
133 print(MAIL "From: $MsgSender\n",
134            "To: $MsgSender\n",
135            "Subject: Requested EMail List\n\n",
136            "Internal EMail addresses as of: ", scalar(localtime()), "\n");
137 #
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)) )
141    {
142    $Company = $Companies{$Company};
143    print(MAIL "\n", 
144               $Company->[0], "\n",
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]); }
148    }
149 #
150 # Output the trailing message footer
151 print(MAIL "\n",
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");
155 close(MAIL);
156
157
158 #
159 #  End of File
160 #
161
162 --Message-Boundary-12668
163 Content-description: Text from file 'post_all.pl'
164
165 #!/usr/bin/perl
166 #
167 #
168 #  "Everyone" EMail Exploder
169 #
170 #  Version 2.0
171 #
172 #  William F. McCaw  1999
173 #
174 #
175 #  Sends body of message supplied on STDIN to all valid users listed within
176 #  the computer's /etc/passwd file.
177 #
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:'.
181 #
182
183 #
184 # Function Prototypes
185 #
186 sub SendMessage();
187
188
189 #
190 # Determine the target company for sending out the email to
191 #
192 $TargetCompany = (( defined($ARGV[0]) ) ? $ARGV[0] : '');
193
194 #
195 # Read the message from standard input
196 #
197 $MsgSender = '';
198 $MsgSubject = '';
199 # Extract the required details from the message's header
200 while ( defined($Line = <STDIN>) && ($Line =~ /^[^\r\n]/) )
201    {
202    $Line =~ s/[\r\n]//gs;
203    if ( $Line =~ /^Return-Path:\s*<([^>]+)>/i )     # First choice for sender
204       { $MsgSender = $1; }
205    if ( $Line =~ /^From:\s*(.*)/i && !$MsgSender )  # May be no return path
206       { $MsgSender = $1; }
207    elsif ( $Line =~ /^Subject:\s*(.+)/i )           # Preserve the subject
208       { $MsgSubject = $1; }
209    }
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
213 @MsgBody = <STDIN>;
214
215 #
216 # Read the contents of the system's password file
217 #
218 open(PASS, '/etc/passwd') || exit(0);
219 @Users = <PASS>;
220 close(PASS);
221
222 #
223 # Send the message to all the users within the password file
224 #
225 @MsgRecipients = ();
226 foreach $User ( @Users )
227    {
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 )
237       {
238       SendMessage();
239       @MsgRecipients = ();
240       }
241 # Append the current email address to the recipient list
242    push(@MsgRecipients, $EMail);
243    }
244 #
245 # Ensure the folk at the end of the user list receive the message
246 if ( scalar(@MsgRecipients) )
247    { SendMessage(); }
248
249
250
251 #
252 #
253 #  Routine to send the specified message
254 #
255 sub SendMessage()
256    {
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",
262               @MsgBody,
263               "\n");
264    close(MAIL);
265    }
266
267
268 #
269 #  End of File
270 #