"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "tulp-4.2.1/src/lc.c" of archive tulp-4.2.1.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * TULP - Unix Mailing List manager
3 * (sub-set of FRECP's Bitnet Listserv tool)
4 *
5 * Copyright (C) 1991-2000 Kimmo Suominen, Christophe Wolfhugel
6 *
7 * Please read the files COPYRIGHT and AUTHORS for the extended
8 * copyrights refering to this file.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 1, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <limits.h>
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <signal.h>
32 #include <sys/stat.h>
33 #include <dirent.h>
34 #include <sys/times.h>
35 #include "conf.h"
36 #include "ext.h"
37 #include "l.h"
38 #include "lp.h"
39 #include "str.h"
40 #include "popen.h"
41 #include "messages.h"
42 #ifdef FAKESYSLOG
43 # include "fakesyslog.h"
44 #else
45 # include <syslog.h>
46 #endif /* FAKESYSLOG */
47
48 RCSID("@(#)lc.c,v 1.9 2000/03/07 22:16:30 kim Exp")
49
50 FILE *l;
51 char adrs[MAXLINE];
52 static char cmd[MAXLINE + 1];
53
54 struct kword {
55 char k[4];
56 void (*job) ();
57 };
58
59 void help(), list(), review(), subscribe(), signoff(), listindex(), getFile(),
60 addUser(), delUser();
61
62 struct kword kw[] = {
63 {"hel", help},
64 {"lis", list},
65 {"rev", review},
66 {"sub", subscribe},
67 {"sig", signoff},
68 {"uns", signoff},
69 {"ind", listindex},
70 {"get", getFile},
71 {"add", addUser},
72 {"del", delUser},
73 {"", NULL}
74 };
75
76 /*
77 * Spawn return message MTA
78 */
79
80 FILE *getMTA(char *recipient, char *list, int method)
81 {
82 FILE *mta;
83 char *pre = "";
84
85 #ifdef ADD_REQUEST
86 sprintf(cmd, "%s -f%s-request@%s %s", SENDMAIL, list, HOST, recipient);
87 #else
88 sprintf(cmd, "%s %s", SENDMAIL, recipient);
89 #endif
90 if ((mta = l_popen(cmd, "w")) == NULL) {
91 syslog(LOG_ERR, "getMTA - popen failed: %m");
92 exit(2);
93 }
94 switch (method) {
95 case MTA_RESEND:
96 pre = "Resent-";
97 /* Fall through */
98 case MTA_MAIL:
99 fprintf(mta, "%sFrom: listserv@%s (%s)\n", pre, HOST, vers);
100 /* Fall through */
101 case MTA_RELAY:
102 #ifdef ADD_SENDER
103 fprintf(mta, "%sSender: list-errors@%s (%s)\n", pre, HOST, vers);
104 #endif
105 break;
106 default:
107 syslog(LOG_ERR, "getMTA - unknown method: %d", method);
108 exit(2);
109 }
110 return (mta);
111 }
112
113 /*
114 * HELP
115 */
116
117 void help()
118 {
119 FILE *f, *h;
120
121 strlwr(buf);
122 syslog(LOG_INFO, "HELP to %s", From);
123 h = getMTA(adrs, "listserv", MTA_MAIL);
124 fprintf(h, TULP_HDRHELP(From));
125 f = fopen("helpfile", "r");
126 while (fgets(buf, sizeof(buf), f) != NULL)
127 fputs(buf, h);
128 fclose(f);
129 l_pclose(h);
130 }
131
132 /*
133 * LIST
134 */
135
136 void list()
137 {
138 FILE *f, *h;
139
140 syslog(LOG_INFO, "LIST to %s", From);
141 h = getMTA(adrs, "listserv", MTA_MAIL);
142 fprintf(h, TULP_HDRLIST(From));
143 f = fopen("lists", "r");
144 while (fgets(buf, sizeof(buf), f) != NULL) {
145 if (buf[0] == '#')
146 continue;
147 strtok(buf, ",");
148 fprintf(h, "%-15s * %s\n", buf, strtok(NULL, "\n"));
149 }
150 fclose(f);
151 l_pclose(h);
152 }
153
154 /*
155 * REVIEW list
156 */
157
158 void review()
159 {
160 FILE *h;
161 char *s;
162
163 s = strtok(NULL, " \t\n");
164 strlwr(s);
165 syslog(LOG_INFO, "REV '%s' to %s", s, From);
166 if (s == NULL)
167 fprintf(l, TULP_SYNTAX);
168 else if (ReadUserList(s) == -1)
169 fprintf(l, TULP_NOSUCHLIST);
170 else {
171 h = getMTA(adrs, "listserv", MTA_MAIL);
172 fprintf(h, TULP_HDRREV(From, s));
173 RewindCommentList();
174 RewindUserList();
175 while (GetComment(buf) != NULL)
176 fprintf(h, "%s\n", buf);
177 if (!IsOwner(From) && (strcasecmp(GetReview(), "owner") == 0
178 || (strcasecmp(GetReview(), "private") == 0 && !IsUser(From))))
179 fprintf(l, TULP_REVPRIVATE);
180 else
181 while (GetUser(buf) != NULL) {
182 strtok(buf, "(");
183 buf[strlen(buf) - 1] = 0;
184 fprintf(h, "%-40s %s\n", buf, strtok(NULL, ")\n"));
185 }
186 l_pclose(h);
187 }
188 CloseUserList();
189 }
190
191 /*
192 * SUBSCRIBE list first last
193 */
194
195 void subscribe()
196 {
197 FILE *f, *h;
198 char *s1, *s2;
199
200 s1 = strtok(NULL, " \n");
201 strlwr(s1);
202 s2 = strtok(NULL, "\n");
203 syslog(LOG_INFO, "SUB '%s' from %s", s1, From);
204 if (s1 == NULL || s2 == NULL)
205 fprintf(l, TULP_SYNTAX);
206 else {
207 if (ReadUserList(s1) == -1)
208 fprintf(l, TULP_NOSUCHLIST);
209 else {
210 RewindUserList();
211 RewindOwnerList();
212 if (strcasecmp(GetSubscription(), "closed") == 0)
213 fprintf(l, TULP_SUBCLOSED);
214 else if (strcasecmp(GetSubscription(), "owner") == 0) {
215 fprintf(l, TULP_SUBFORWARDED);
216 rcpt[0] = 0;
217 while (GetOwner(cmd) != NULL) {
218 strcat(rcpt, strtok(cmd, " \t\r\n"));
219 strcat(rcpt, " ");
220 }
221 sprintf(cmd, "%s %s", SENDMAIL, rcpt);
222 f = l_popen(cmd, "w");
223 fprintf(f, TULP_SUBREQUEST(adrs, s1, s2));
224 l_pclose(f);
225 } else {
226 sprintf(cmd, "%s (%s)", adrs, s2);
227 switch (AddUser(cmd)) {
228 case 0:
229 h = getMTA(adrs, "listserv", MTA_MAIL);
230 fprintf(h, TULP_HDRWELCOME(From, s1));
231 strcat(s1, ".w");
232 f = fopen(s1, "r");
233 while (fgets(buf, sizeof(buf), f) != NULL)
234 fputs(buf, h);
235 fclose(f);
236 l_pclose(h);
237 break;
238 case 1:
239 fprintf(l, TULP_SUBALREADY);
240 break;
241 }
242 WriteUserList();
243 }
244 }
245 CloseUserList();
246 }
247 }
248
249 /*
250 * SIGNOFF list
251 */
252
253 void signoff()
254 {
255 FILE *f;
256 char *s;
257
258 s = strtok(NULL, " \t\n");
259 strlwr(s);
260 syslog(LOG_INFO, "SIG '%s' from %s", s, From);
261 if (s == NULL)
262 fprintf(l, TULP_SYNTAX);
263 else if (ReadUserList(s) == -1)
264 fprintf(l, TULP_NOSUCHLIST);
265 else {
266 RewindOwnerList();
267 rcpt[0] = 0;
268 while (GetOwner(cmd) != NULL) {
269 strcat(rcpt, strtok(cmd, " "));
270 strcat(rcpt, " ");
271 }
272 sprintf(cmd, "%s %s", SENDMAIL, rcpt);
273 f = l_popen(cmd, "w");
274 if (DelUser(adrs) == -1) {
275 fprintf(f, TULP_SIGFAILED(adrs, s));
276 fprintf(l, TULP_NOTONLIST);
277 } else {
278 fprintf(f, TULP_SIGSUCCESS(adrs, s));
279 fprintf(l, TULP_SIGDONE);
280 }
281 l_pclose(f);
282 WriteUserList();
283 CloseUserList();
284 }
285 }
286
287 /*
288 * INDEX list
289 */
290
291 void listindex()
292 {
293 #define MAX_FILES 640
294 static char files[MAX_FILES][64 + 1], swp[64 + 1];
295 FILE *h;
296 char *s;
297 int i, j, noFiles;
298 DIR *dirp;
299 struct dirent *de;
300 struct stat st;
301
302 s = strtok(NULL, "\n");
303 strlwr(s);
304 syslog(LOG_INFO, "IND %s from %s", s, From);
305 if (s == NULL || s[0] == '/' || s[0] == '~' || strstr(s, "..") != NULL)
306 fprintf(l, TULP_SYNTAX);
307 else {
308 if (ReadUserList(s) != -1 && (strcasecmp(GetSend(), "public") != 0
309 || strcasecmp(GetReview(), "public") != 0)
310 && !IsUser(From) && !IsOwner(From))
311 fprintf(l, TULP_NOTONLIST);
312 else {
313 if (chdir(s) == -1)
314 fprintf(l, TULP_NONESTORED);
315 else {
316 h = getMTA(adrs, "listserv", MTA_MAIL);
317 fprintf(h, TULP_HDRINDEX(From, s));
318 dirp = opendir(".");
319 noFiles = 0;
320 while (noFiles < MAX_FILES && (de = readdir(dirp)) != NULL)
321 if (de->d_name[0] != '.')
322 strcpy(files[noFiles++], de->d_name);
323 closedir(dirp);
324 for (i = 0; i < noFiles - 1; i++) {
325 for (j = i + 1; j < noFiles; j++) {
326 if (strcmp(files[j], files[i]) < 0) {
327 strcpy(swp, files[i]);
328 strcpy(files[i], files[j]);
329 strcpy(files[j], swp);
330 }
331 }
332 }
333 for (i = 0; i < noFiles; i++) {
334 stat(files[i], &st);
335 if (st.st_mode & S_IFDIR)
336 strcat(files[i], "/");
337 fprintf(h, "%-40s %10ld %s",
338 files[i], (unsigned long) st.st_size, ctime(&st.st_mtime));
339 }
340 chdir(TULPDIR);
341 if (noFiles == 0)
342 fprintf(l, TULP_INDNOFILES);
343 l_pclose(h);
344 }
345 }
346 CloseUserList();
347 }
348 }
349
350 /*
351 * GET list file
352 */
353
354 void getFile()
355 {
356 FILE *f, *h;
357 char *s, *t;
358
359 s = strtok(NULL, " ");
360 t = strtok(NULL, " \n");
361 strlwr(s);
362 strlwr(t);
363 syslog(LOG_INFO, "GET %s %s from %s",
364 (s == NULL) ? " " : s, (t == NULL) ? " " : t, From);
365 if (ReadUserList(s) != -1 && (strcasecmp(GetSend(), "public") != 0
366 || strcasecmp(GetReview(), "public") != 0)
367 && !IsUser(From) && !IsOwner(From))
368 fprintf(l, TULP_NOTONLIST);
369 else if (strstr(s, "..") != NULL || *s == '/' || *s == '~') {
370 fprintf(l, "Cannot access group %s.\n", s);
371 syslog(LOG_NOTICE, "Attempt to access file %s in %s by %s.", t, s, From);
372 } else {
373 if (chdir(s) == -1)
374 fprintf(l, TULP_NONESTORED);
375 else {
376 if (strstr(t, "..") != NULL || *t == '/' || *t == '~')
377 *t = 0;
378 f = fopen(t, "r");
379 if (f == NULL)
380 fprintf(l, TULP_GETNOSUCHFILE);
381 else {
382 h = getMTA(adrs, "listserv", MTA_MAIL);
383 fprintf(h, TULP_HDRGET(From, s, t));
384 while (fgets(buf, sizeof(buf), f) != NULL)
385 fputs(buf, h);
386 fclose(f);
387 l_pclose(h);
388 }
389 chdir(TULPDIR);
390 }
391 }
392 CloseUserList();
393 }
394
395 /*
396 * ADD list user@host.foo.bar First Last
397 */
398
399 void addUser()
400 {
401 FILE *f, *h;
402 char *s, *t, *u;
403
404 s = strtok(NULL, " \n");
405 t = strtok(NULL, " \n");
406 u = strtok(NULL, "\n");
407 strlwr(s);
408 syslog(LOG_INFO, "ADD '%s' %s from %s", s, t, From);
409 if (s == NULL || t == NULL || u == NULL)
410 fprintf(l, TULP_SYNTAX);
411 else if (ReadUserList(s) == -1)
412 fprintf(l, TULP_NOSUCHLIST);
413 else {
414 RewindUserList();
415 RewindOwnerList();
416 if (!IsOwner(From))
417 fprintf(l, TULP_NOTOWNER);
418 else {
419 h = getMTA(t, "listserv", MTA_MAIL);
420 sprintf(cmd, "%s (%s)", t, u);
421 switch (AddUser(cmd)) {
422 case 0:
423 fprintf(h, TULP_HDRWELCOME(cmd, s));
424 fprintf(h, TULP_ADDBY(cmd, s, From));
425 strcat(s, ".w");
426 f = fopen(s, "r");
427 while (fgets(buf, sizeof(buf), f) != NULL)
428 fputs(buf, h);
429 fclose(f);
430 fprintf(l, TULP_ADDSUCCESS);
431 break;
432 case 1:
433 fprintf(h, TULP_SUBUPDATED(cmd, s, From));
434 fprintf(l, TULP_ADDALREADY);
435 break;
436 }
437 l_pclose(h);
438 }
439 WriteUserList();
440 CloseUserList();
441 }
442 }
443
444 /*
445 * DELETE list user@host.foo.bar
446 */
447
448 void delUser()
449 {
450 FILE *h;
451 char *s1, *s2;
452
453 s1 = strtok(NULL, " \n");
454 s2 = strtok(NULL, " \n");
455 strlwr(s1);
456 syslog(LOG_INFO, "DEL '%s' %s from %s", s1, s2, From);
457 if (s1 == NULL || s2 == NULL)
458 fprintf(l, TULP_SYNTAX);
459 else if (ReadUserList(s1) == -1)
460 fprintf(l, TULP_NOSUCHLIST);
461 else {
462 RewindUserList();
463 RewindOwnerList();
464 if (!IsOwner(From))
465 fprintf(l, TULP_NOTOWNER);
466 else if (!IsUser(s2))
467 fprintf(l, TULP_DELNOTONLIST);
468 else {
469 sprintf(cmd, "%s", s2);
470 switch (DelUser(cmd)) {
471 case 0:
472 h = getMTA(s2, "listserv", MTA_MAIL);
473 fprintf(h, TULP_DELREMOVED(s2, s1, From));
474 l_pclose(h);
475 fprintf(l, TULP_DELSUCCESS);
476 break;
477 case -1:
478 fprintf(l, TULP_DELINCONSISTENT);
479 break;
480 }
481 }
482 WriteUserList();
483 CloseUserList();
484 }
485 }
486
487 /*
488 * Find a command
489 */
490
491 int doCmd()
492 {
493 int i;
494 char s[4];
495
496 if (buf[0] == '\n')
497 return (0);
498 strncpy(s, strtok(buf, " "), 3);
499 s[3] = '\0';
500 strlwr(s);
501 for (i = 0; kw[i].k[0] != 0; i++)
502 if (strncmp(kw[i].k, s, 3) == 0) {
503 kw[i].job();
504 return (0);
505 }
506 return (-1);
507 }
508
509 void listservCmd(char *file)
510 {
511 int done, noCmd;
512 FILE *f;
513
514 #ifdef CPUTYPE
515 struct tms t;
516 long tt;
517
518 times(&t);
519 tt = t.tms_stime + t.tms_utime + t.tms_cstime + t.tms_cutime;
520 #endif
521
522 noCmd = 0;
523 done = 0;
524 strcpy(adrs, From);
525 strtok(adrs, " ");
526 l = getMTA(adrs, "listserv", MTA_MAIL);
527 fprintf(l, TULP_HDROUTPUT(From));
528 f = fopen(file, "r");
529 buf[0] = 0;
530 while (fgets(buf, sizeof(buf), f) != NULL && buf[0] != '\n')
531 buf[0] = 0;
532 if (buf[0] == 0)
533 fprintf(l, TULP_NOBODY);
534 else {
535 while (!done && fgets(buf, sizeof(buf) - 3, f) != NULL) {
536 if (strncasecmp(buf, "quit", 4) == 0
537 || strncasecmp(buf, "end", 3) == 0
538 || strncasecmp(buf, "stop", 4) == 0
539 || buf[0] == '-') {
540 fprintf(l, "> %s", buf);
541 fprintf(l, TULP_EXITING);
542 break;
543 }
544 #ifdef SHUTDOWN
545 if (strcmp(SHUTDOWN, buf) == 0) {
546 syslog(LOG_INFO, "Shutdown by %s", From);
547 done = 1; /* this is clean */
548 noCmd++;
549 continue;
550 }
551 #endif
552 if (buf[0] != '\n') {
553 fprintf(l, "> %s", buf);
554 if (doCmd() == -1)
555 fprintf(l, TULP_SAYWHAT);
556 else {
557 noCmd++;
558 fprintf(l, TULP_OKAY);
559 }
560 }
561 }
562 }
563 if (noCmd == 0) {
564 fprintf(l, TULP_NOCOMMANDS);
565 syslog(LOG_INFO, "No commands from %s", From);
566 mailMsg("listman", "No commands");
567 }
568 fclose(f);
569 unlink(file);
570 #ifdef CPUTYPE
571 times(&t);
572 tt = (t.tms_stime + t.tms_utime + t.tms_cstime + t.tms_cutime) - tt;
573 fprintf(l, TULP_TOTAL((float) tt / HZ, CPUTYPE));
574 #endif
575 l_pclose(l);
576 }