4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * uucleanup - This is a program based on the heuristics
35 * for cleaning up and doing something
36 * useful with old files left in the uucp queues.
37 * It also will send warning messags to users where requests are not
38 * going out due to failure to contact the remote system.
40 * This program knows a lot about the construction and
41 * contents of the C., D. and X. files. In addition, it
42 * thinks it knows what mail and netnews data files look like.
44 * At present, this is what is done:
45 * For WARNING messages:
46 * C. files of age given by -W option are read, looking for
47 * either user files to be sent or received, or
48 * mail to be sent. (Other remote execution that
49 * does not involve sending user files is not checked
50 * for now.) In either of the cases, the user is
51 * informed by mail that the request is not being
52 * processed due to lack of communications with the remote
53 * system, and the request will be deleted in the future
54 * if it the condition remains for several more days.
57 * C. files - if they reference only D. files, the C. is
58 * merely deleted, because the D. files are usually
59 * mail or news, and the later D. processing will
61 * - if they reference files from the file system,
62 * a message is constructed that will contain a
64 * We can't contact the remote.
66 * local!file -> remote!otherfile
69 * X. files - merely deleted at present - D.s will be taken
70 * care of later. Besides, some of the D.s are
71 * missing or else the X. wouldn't be left around.
72 * D. files - mail type data is sent to a local person if that
73 * is where it originated. If not, it is returned to the
74 * sender -- assumed to be from the first From line. If
75 * a sender can't be determing, the file is merely deleted.
76 * - rnews: if locally generated, just delete. If remote,
77 * the X. got lost, so execute rnews.
78 * other files - just delete them.
79 * .Workspace files over a day old
81 * Deletions and executions are logged in
82 * (CLEANUPLOG)--/var/uucp/.Admin/uucleanup
91 #define USAGE "[-oDAYS] [-mSTRING] [-Cdays] [-Ddays] [-Wdays] [-Xdays] [-xLEVEL] [-sSYSTEM]"
93 extern int _age(); /* find the age of a file */
94 extern void procdtype(), oprocess(), xprocess(), cprocess();
95 extern void dXprocess(), dNprocess(), dMprocess(), dDprocess(), wprocess();
96 extern int toWho(), sendMail(), execRnews();
99 /* need these dummys to satisy some .o files */
104 static void cleanworkspace(void);
106 /* types of D. files */
111 #define FULLNAME(full,dir,file) (void) sprintf(full, "%s/%s", dir, file);
113 int _Ddays
= 7; /* D. limit */
114 int _Cdays
= 7; /* C. limit */
115 int _Xdays
= 2; /* X. limit */
116 int _Odays
= 2; /* O. limit */
117 int _Wdays
= 1; /* Warning limit for C. files */
118 char _ShortLocal
[6]; /* 5 char or less version of local name */
120 char *_Undeliverable
[] = {
121 "Subject: Undeliverable Mail\n",
122 "This mail message is undeliverable.\n",
123 "(Probably to or from system '%s')\n",
124 "It was sent to you or by you.\n",
125 "Sorry for the inconvenience.\n",
129 #define CANT1 2 /* first line to fill in */
130 #define CANT2 3 /* second line to fill in */
131 char *_CantContact
[] = {
132 "Subject: Job Killed By uucp\n",
133 "We can't contact machine '%s'.\n",
134 " ", /* uucleanup will fill in variable text here */
135 " ", /* fill in jobid of killed job */
143 "Subject: Warning From uucp\n",
144 "We have been unable to contact machine '%s' since you queued your job.\n",
145 " ", /* wprocess FILLS IN THIS LINE OF TEXT */
146 "Attempts will continue for a few more days.\n",
148 " ", /* wprocess FILLS IN THIS LINE WITH: uucp job id is JOBid. */
149 " ", /* FILL IN THE -m STRING IF SPECIFIED */
154 main(argc
, argv
, envp
)
159 DIR *jcdir
, *machdir
, *spooldir
;
160 char fullname
[MAXFULLNAME
], statfile
[MAXFULLNAME
], machname
[MAXFULLNAME
];
161 char file1
[NAMESIZE
+1], file2
[NAMESIZE
+1], file3
[NAMESIZE
+1];
162 char soptName
[MAXFULLNAME
], lockname
[MAXFULLNAME
]; /* name from -s option */
165 soptName
[0] = NULLCHAR
;
166 (void) strcpy(Logfile
, CLEANUPLOGFILE
);
168 (void) strncpy(_ShortLocal
, Myname
, 5);
169 _ShortLocal
[5] = NULLCHAR
;
170 (void) strcpy(Progname
, "uucleanup");
171 while ((i
= getopt(argc
, argv
, "C:D:W:X:m:o:s:x:")) != EOF
) {
173 case 's': /* for debugging - choose system */
174 (void) strcpy(soptName
, optarg
);
177 Debug
= atoi(optarg
);
178 if (Debug
<= 0 || Debug
>= 10) {
180 "WARNING: %s: invalid debug level %s ignored, using level 1\n",
186 "WARNING: uucleanup built with SMALL flag defined -- no debug info available\n");
190 _Warning
[WARN3
] = optarg
;
193 (void) fprintf(stderr
, "\tusage: %s %s\n",
202 value
= atoi(optarg
);
204 fprintf(stderr
," Options: CDWXo require value > 0\n");
228 if (argc
!= optind
) {
229 (void) fprintf(stderr
, "\tusage: %s %s\n", Progname
, USAGE
);
233 DEBUG(5, "Progname (%s): STARTED\n", Progname
);
234 DEBUG(5, "Myname (%s), ", Myname
);
235 DEBUG(5, "_ShortLocal (%s)\n", _ShortLocal
);
236 DEBUG(5, "Days C.(%d), ", _Cdays
);
237 DEBUG(5, "D.(%d), ", _Ddays
);
238 DEBUG(5, "W.(%d), ", _Wdays
);
239 DEBUG(5, "X.(%d), ", _Xdays
);
240 DEBUG(5, "other (%d)\n", _Odays
);
243 if (chdir(SPOOL
) != 0) {
244 (void) fprintf(stderr
, "CAN'T CHDIR (%s): errno (%d)\n",
248 if ((spooldir
= opendir(SPOOL
)) == NULL
) {
249 (void) fprintf(stderr
, "CAN'T OPEN (%s): errno (%d)\n",
254 while (gdirf(spooldir
, file1
, SPOOL
) == TRUE
) {
256 if (*soptName
&& !EQUALS(soptName
, file1
))
259 (void) strcpy(Rmtname
, file1
);
260 (void) sprintf(machname
, "%s/%s", SPOOL
, file1
);
261 if ((machdir
= opendir(machname
)) == NULL
) {
262 (void) fprintf(stderr
, "CAN'T OPEN (%s): errno (%d)\n",
269 DEBUG(7, "Directory: (%s) is open\n", file1
);
270 while (gnamef(machdir
, file2
) == TRUE
) {
272 (void) sprintf(statfile
, "%s/%s", machname
, file2
);
273 if (DIRECTORY(statfile
)) {
274 (void) sprintf(lockname
, "%s.%.*s.%s",
275 LOCKPRE
, SYSNSIZE
, file1
, file2
);
276 if (cklock(lockname
))
278 if ((jcdir
= opendir(statfile
)) == NULL
) {
279 (void) fprintf(stderr
,
280 "CAN'T OPEN (%s): errno (%d)\n",
285 DEBUG(7, "Directory: (%s) is open\n", file2
);
286 while (gnamef(jcdir
, file3
)) {
287 DEBUG(9, "file: %s\n", file3
);
288 FULLNAME(fullname
, statfile
, file3
);
289 DEBUG(9,"Fullname is (%s)\n", fullname
);
290 if (EQUALSN(file3
, "C.", 2)) {
291 if (_age(fullname
) >= _Cdays
)
293 else if(_age(fullname
) >= _Wdays
)
294 wprocess(statfile
, file3
);
296 else if (EQUALSN(file3
, "D.", 2)) {
297 if (_age(fullname
) >= _Ddays
)
298 procdtype(statfile
, file3
);
300 else if (_age(fullname
) >= _Odays
)
306 DEBUG(9, "file: %s\n", file2
);
307 DEBUG(9, "Fullname is (%s)\n", statfile
);
308 if (EQUALSN(file2
, "X.", 2)) {
309 if (_age(statfile
) >= _Xdays
)
312 else if (EQUALSN(file2
, "D.", 2)) {
313 if (_age(statfile
) >= _Ddays
)
314 procdtype(machname
, file2
);
316 else if (_age(statfile
) >= _Odays
)
325 /* procdtype - select the type of processing that a D. file should receive */
332 char fullname
[MAXFULLNAME
];
334 FULLNAME(fullname
, dir
, file
);
336 switch(dType(fullname
)) {
341 dMprocess(dir
, file
);
344 dNprocess(dir
, file
);
355 /* xprocess - X. file processing -- just remove the X. for now */
363 DEBUG(5, "xprocess(%s), ", fullname
);
364 DEBUG(5, "unlink(%s)\n", fullname
);
365 (void) sprintf(text
, "xprocess: unlink(%s)", fullname
);
367 (void) unlink(fullname
);
373 * cprocess - Process old C. files
377 #define CMFMT "\n\t%s!%s -> %s!%s (Date %2.2d/%2.2d)\n\nCan't be executed."
378 #define XFMT "\n\t%s!%s (Date %2.2d/%2.2d)\n"
379 #define XMFMT "\n\tmail %s!%s (Date %2.2d/%2.2d)\n"
380 #define WFMT "\n\t%s!%s -> %s!%s (Date %2.2d/%2.2d)\n"
387 char buf
[BUFSIZ
], user
[9];
388 char file1
[BUFSIZ
], file2
[BUFSIZ
], file3
[BUFSIZ
], type
[2], opt
[256];
389 char text
[BUFSIZ
], text1
[BUFSIZ
], text2
[BUFSIZ
];
393 DEBUG(5, "cprocess(%s)\n", fullname
);
396 fp
= fopen(fullname
, "r");
398 DEBUG(5, "Can't open file (%s), ", fullname
);
399 DEBUG(5, "errno=%d -- skip it!\n", errno
);
402 if (fstat(fileno(fp
), &s
) != 0) {
403 /* can't happen; _age() did stat of this file and file is opened */
407 tp
= localtime(&s
.st_mtime
);
409 if (s
.st_size
== 0) { /* dummy C. for polling */
410 DEBUG(5, "dummy C. -- unlink(%s)\n", fullname
);
411 (void) sprintf(text
, "dDprocess: dummy C. unlinked(%s)",
414 (void) unlink(fullname
);
420 /* Read the C. file and process it */
421 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
422 buf
[strlen(buf
)-1] = NULLCHAR
; /* remove \n */
423 if (sscanf(buf
,"%s%s%s%s%s%s", type
, file1
, file2
,
424 user
, opt
, file3
) <5) {
425 (void) sprintf(text
, "cprocess: Bad C. %s, unlink(%s)",
432 /* fill in line 3 of text */
433 (void) sprintf(text2
, "Job (%s) killed!\n",
434 BASENAME(fullname
, '/')+2);
435 _CantContact
[CANT2
] = text2
;
437 if (EQUALSN(file1
, "D.", 2))
438 /* generated file (mail/news) I think */
439 /* D. processing will return it later */
442 /* some data was requested -- tell user */
444 (void) sprintf(text1
, CMFMT
, Myname
, file1
, Rmtname
, file2
,
445 tp
->tm_mon
+ 1, tp
->tm_mday
);
446 _CantContact
[CANT1
] = text1
;
447 ret
= sendMail((char *) NULL
, user
, "", _CantContact
);
449 else if (*type
== 'R') {
450 (void) sprintf(text1
, CMFMT
, Rmtname
, file1
, Myname
, file2
,
451 tp
->tm_mon
+ 1, tp
->tm_mday
);
452 _CantContact
[CANT1
] = text1
;
453 ret
= sendMail((char *) NULL
, user
, "", _CantContact
);
459 "cprocess: C. %s, mail returned (%d), unlink(%s)",
462 DEBUG(3, "text (%s)\n", text
);
465 (void) unlink(fullname
);
473 * wprocess - send warning messages for C. == Wdays
482 char fullname
[BUFSIZ
], xfile
[BUFSIZ
], xF_file
[BUFSIZ
];
483 char buf
[BUFSIZ
], user
[BUFSIZ
];
484 char file1
[BUFSIZ
], file2
[BUFSIZ
], file3
[BUFSIZ
], type
[2], opt
[256];
485 char text
[BUFSIZ
], text1
[BUFSIZ
], text2
[BUFSIZ
];
486 char *realuser
, uline_m
[NAMESIZE
], uline_u
[BUFSIZ
], retaddr
[BUFSIZ
];
490 FULLNAME(fullname
, dir
, file
);
491 DEBUG(5, "wprocess(%s)\n", fullname
);
493 fp
= fopen(fullname
, "r");
495 DEBUG(4, "Can't open file (%s), ", fullname
);
496 DEBUG(4, "errno=%d -- skip it!\n", errno
);
500 if (fstat(fileno(fp
), &s
) != 0) {
502 /* can't happen; _age() did stat of this file and file is opened */
508 tp
= localtime(&s
.st_mtime
);
510 if (s
.st_size
== 0) { /* dummy C. for polling */
511 DEBUG(5, "dummy C. -- skip(%s)\n", fullname
);
516 /* read C. and process it */
517 while (fgets(buf
, BUFSIZ
, fp
) != NULL
) {
518 buf
[strlen(buf
)-1] = NULLCHAR
; /* remove \n */
519 if (sscanf(buf
,"%s%s%s%s%s%s", type
, file1
, file2
,
520 user
, opt
, file3
) <5) {
521 DEBUG(5, "short line (%s): ", buf
);
522 DEBUG(5, "bad D. -- skip(%s)\n", fullname
);
527 /* set up the 6th text line of the mail message */
529 (void) sprintf(text2
,
530 "\nuucp job id is %s.\n", BASENAME(fullname
, '/')+2);
532 _Warning
[WARN2
] = text2
;
534 /* if Send type then do C. file processing */
538 /* if this is a uux job - tell user about it */
540 if (EQUALSN(file2
, "X.", 2)) {
541 FULLNAME(xfile
, dir
, file1
);
543 /* if X.file can't be read then skip it */
545 if ((xfp
= fopen(xfile
, "r")) == NULL
) {
546 DEBUG(3, "Can't read %s\n", xfile
);
549 *retaddr
= *uline_u
= *uline_m
= *text
= NULLCHAR
;
550 while (fgets(buf
, BUFSIZ
, xfp
) != NULL
) {
552 /* remove \n from end of buffer */
554 buf
[strlen(buf
)-1] = NULLCHAR
;
557 /* save the file name */
560 FULLNAME(xF_file
, dir
, &buf
[2]);
563 /* save return address */
566 sscanf(buf
+2, "%s", retaddr
);
567 DEBUG(7, "retaddr (%s)\n", retaddr
);
570 /* save machine, user */
573 sscanf(buf
+2, "%s%s",
581 if (*retaddr
!= NULLCHAR
)
583 if (*realuser
== NULLCHAR
)
584 strcpy(realuser
, user
);
585 if (!EQUALS(uline_m
, Myname
))
586 sprintf(user
, "%s!%s",
589 strcpy(user
, realuser
);
591 /* give mail special handling */
592 if (EQUALSN(buf
+2, "rmail ", 6))
593 (void) sprintf(text1
, XMFMT
,
595 tp
->tm_mon
+1, tp
->tm_mday
);
597 (void) sprintf(text1
, XFMT
,
599 tp
->tm_mon
+1, tp
->tm_mday
);
601 _Warning
[WARN1
] = text1
;
602 if (EQUALSN(&buf
[2], "rmail", 5))
604 * this is mail; append
605 * user mail (xF_file).
607 ret
= sendMail((char *) NULL
,
608 user
, xF_file
, _Warning
);
610 ret
= sendMail((char *) NULL
,
618 /* if file1 is a D. file the it might be (mail/news) */
619 /* if so then D. processing will take of it later */
621 if (EQUALSN(file1
, "D.", 2))
624 /* some data was requested -- tell user */
625 /* set up the 2nd text line of the mail message */
627 (void) sprintf(text1
, WFMT
, Myname
, file1
, Rmtname
, file2
,
628 tp
->tm_mon
+ 1, tp
->tm_mday
);
629 _Warning
[WARN1
] = text1
;
630 ret
= sendMail((char *) NULL
, user
, "", _Warning
);
633 /* Receive C. file processing */
635 else if (*type
== 'R') {
636 if (EQUALSN(file1
, "D.", 2) && EQUALSN(file2
, "D.", 2))
639 (void) sprintf(text1
, WFMT
, Rmtname
, file1
, Myname
, file2
,
640 tp
->tm_mon
+ 1, tp
->tm_mday
);
641 _Warning
[WARN1
] = text1
;
642 ret
= sendMail((char *) NULL
, user
, "", _Warning
);
644 } /* end while - read C. lines loop */
647 "wprocess: %s: %s, warning message sent to %s, returned (%d)",
648 fullname
, buf
, user
, ret
);
650 DEBUG(3, "text (%s)\n", text
);
658 * oprocess - some unknown file just remove the file
666 char *p
, text
[BUFSIZ
];
668 p
= BASENAME(fullname
, '/');
669 if (EQUALSN(p
, "P.", 2) == 0)
670 if (_age(fullname
) <= _Cdays
)
672 DEBUG(5, "oprocess(%s), ", fullname
);
673 DEBUG(5, "unlink(%s)\n", fullname
);
674 (void) sprintf(text
, "oprocess: unlink(%s)", fullname
);
676 (void) unlink(fullname
);
682 * dDprocess - random D. file (not mail or rnews)
683 *--just delete it for now
692 DEBUG(5, "dDprocess(%s), ", fullname
);
693 DEBUG(5, "unlink(%s)\n", fullname
);
694 (void) sprintf(text
, "dDprocess: unlink(%s)", fullname
);
696 (void) unlink(fullname
);
702 * dXprocess - process D. files that are destined for X. on remote
703 * --for now just delete it
712 DEBUG(5, "dXprocess(%s), ", fullname
);
713 DEBUG(5, " unlink(%s)\n", fullname
);
714 (void) sprintf(text
, "dXprocess: unlink(%s)", fullname
);
716 (void) unlink(fullname
);
722 * dMprocess - process ophan D. mail files
723 * There are two types: ones generated locally and
724 * others that are from remotes. They can be identified
725 * by the system name following the D.
726 * Local ones have the local name.
734 char fullname
[MAXFULLNAME
];
735 char *toUser
, *toSystem
;
738 (void) sprintf(fullname
, "%s/%s", dir
, file
);
739 DEBUG(5, "dMprocess(%s)\n", fullname
);
742 if (PREFIX(_ShortLocal
, &file
[2])) {
743 DEBUG(5, " Local file %s: ", file
);
746 DEBUG(5, " Remote file %s: ", file
);
748 if (toWho(fullname
, &toUser
, &toSystem
)) {
749 DEBUG(5, "toUser %s, ", toUser
);
750 DEBUG(5, "toSystem %s ", toSystem
);
751 ret
= sendMail(toSystem
, toUser
, fullname
, _Undeliverable
);
752 DEBUG(5, "Mail sent, unlink(%s)\n", fullname
);
754 "dMprocess: mail %s to %s!%s, returned (%d), unlink(%s)",
755 fullname
, toSystem
, toUser
, ret
, fullname
);
757 (void) unlink(fullname
);
764 * dNprocess - process ophan D. netnews files
765 * There are two types: ones generated locally and
766 * others that are from remotes. They can be identified
767 * by the system name following the D.
768 * Local ones have the local name.
775 char fullname
[MAXFULLNAME
];
779 (void) sprintf(fullname
, "%s/%s", dir
, file
);
780 DEBUG(5, "dNprocess(%s)\n", fullname
);
783 if (PREFIX(_ShortLocal
, &file
[2])) {
784 /* just delete it, the C. is gone */
785 DEBUG(5, " Local file %s, ", file
);
786 DEBUG(5, "unlink(%s)\n", fullname
);
787 (void) unlink(fullname
);
788 (void) sprintf(text
, "dNprocess: Local news item unlink(%s)",
791 (void) unlink(fullname
);
795 /* execute rnews with this file - the X. is missing */
796 DEBUG(5, " Remote file %s, ", file
);
797 DEBUG(5, "exec rnews(%s), ", fullname
);
798 ret
= execRnews(fullname
);
799 DEBUG(5, "unlink(%s)\n", fullname
);
801 "dNprocess: Remote - exec rnews %s: returned (%d), unlink(%s)",
802 fullname
, ret
, fullname
);
804 (void) unlink(fullname
);
812 static long _sec_per_day
= 86400L;
815 * _age - find the age of "file" in days
825 static time_t ptime
= 0;
832 if (stat(fullname
, &stbuf
) != -1) {
833 return ((int)((ptime
- stbuf
.st_mtime
)/_sec_per_day
));
836 DEBUG(9, "_age: stat (%s) failed", fullname
);
837 DEBUG(9, ", errno %d\n", e
);
842 * dType - return the type of D. file
844 * FAIL - can't read D. file
845 * D_MAIL - mail message D. file
846 * D_NEWS - netnews D. file
847 * D_DATA - other kind of D. file
848 * D_XFILE - destined for X. on destination machine
851 /* NLINES - number of lines of D. file to read to determine type */
862 fp
= fopen(fullname
, "r");
864 DEBUG(4, "Can't open file (%s), ", fullname
);
865 DEBUG(4, "errno=%d -- skip it!\n", errno
);
870 /* read first NLINES lines to determine file type */
872 for (i
=0; i
<NLINES
; i
++) {
873 if (fgets(buf
, BUFSIZ
, fp
) == NULL
)
874 break; /* no more lines */
875 DEBUG(9, "buf: %s\n", buf
);
876 if (EQUALSN(buf
, "From ", 5)) {
880 if (EQUALSN(buf
, "U ", 2)) {
884 if (EQUALSN(buf
, "Newsgroups: ", 12)) {
895 * sendMail - send mail file and message to user (local or remote)
897 * the return from the pclose - mail exit status
900 sendMail(system
, user
, file
, mtext
)
901 char *system
, *user
, *file
;
908 DEBUG(5, "Mail %s to ", file
);
909 DEBUG(5, "%s\n", user
);
911 /* get rid of some stuff that could be dangerous */
912 if (system
!= NULL
&& (p
= strpbrk(system
, Shchar
)) != NULL
) {
915 if (user
!= NULL
&& (p
= strpbrk(user
, Shchar
)) != NULL
) {
918 if (system
!= NULL
&& *system
!= '\0')
919 (void) sprintf(cmd
, "%s %s '%s!%s'", PATH
, MAIL
, system
, user
);
921 (void) sprintf(cmd
, "%s %s '%s'", PATH
, MAIL
, user
);
923 DEBUG(7, "sendMail: %s\n", cmd
);
924 if ((fp
= popen(cmd
, "w")) == NULL
)
927 (void) fprintf(fp
, *mtext
++, Rmtname
);
929 (void) fprintf(fp
, "\n\tSincerely,\n\t%s!uucp\n", Myname
);
931 "\n#############################################\n");
934 /*next statement should never happen;I read once */
935 if ((fi
= fopen(file
, "r")) == NULL
)
938 "##### Data File: ############################\n");
946 * execRnews - execute rnews command with stdin file
948 * the return from the pclose - rnews exit status
957 DEBUG(5, "Rnews %s\n", file
);
959 (void) sprintf(cmd
, "%s rnews ", PATH
);
960 if ((fp
= popen(cmd
, "w")) == NULL
)
963 if ( (fi
= fopen(file
, "r")) == NULL
) /* never happen - I read once */
972 * toWho - figure out who to send this dead mail to
974 * If there is a local address, send it there.
975 * If not, send it back where it came from.
977 * 0 - could not find system and user information
982 toWho(file
, user
, system
)
983 char *file
; /* the D. mail message file */
984 char **system
; /* pointer to the system name */
985 char **user
; /* pointer to the user name */
990 static char fuser
[BUFSIZ
], fsystem
[MAXBASENAME
+1]; /* from first From */
991 static char luser
[BUFSIZ
], lsystem
[MAXBASENAME
+1]; /* from other From */
994 DEBUG(5, "toWho(%s)\n", file
);
995 fp
= fopen(file
, "r");
996 for (i
=0; i
<NLINES
; i
++) {
997 if (fgets(buf
, BUFSIZ
, fp
) == NULL
)
998 break; /* no more lines */
999 DEBUG(9, "buf: %s\n", buf
);
1000 if (!analFrom(buf
, luser
, lsystem
))
1003 (void) strcpy(fuser
, luser
);
1004 (void) strcpy(fsystem
, lsystem
);
1006 if (EQUALS(Myname
, lsystem
)) {
1014 /* could not find local user - use first line */
1016 if (!*fuser
) /* didn't find all information */
1023 /* analFrom - analyze From line
1025 * 0 - didn't find both from and remote from info
1030 analFrom(line
, user
, system
)
1031 char *line
, *user
, *system
;
1036 if (!PREFIX("From ", line
) && !PREFIX(">From ", line
))
1039 s
= strchr(line
, ' ') + 1;
1040 for (i
= 0; *s
&& *s
!= ' ' && *s
!= '\n'; i
++)
1044 /* look for "remote from" */
1045 while (*s
&& ((s
= strchr(s
, ' ')) != NULL
)) {
1047 if (PREFIX("remote from ", s
)) { /* found it */
1048 s
= s
+ strlen("remote from ");
1049 for (i
= 0; (i
<MAXBASENAME
) && *s
&& *s
!= ' ' && *s
!= '\n'; i
++)
1051 system
[i
] = NULLCHAR
;
1060 static FILE *_Lf
= NULL
;
1064 * text -> ptr to text string
1065 * status errno number
1076 if (Nstat
.t_pid
== 0)
1077 Nstat
.t_pid
= getpid();
1080 _Lf
= fopen(Logfile
, "a");
1081 (void) chmod(Logfile
, LOGFILEMODE
);
1086 (void) fseek(_Lf
, 0L, 2);
1087 (void) fprintf(_Lf
, "%s ", Rmtname
);
1088 (void) fprintf(_Lf
, "(%s,%ld,%d) ", timeStamp(), (long) Nstat
.t_pid
, Seqn
);
1089 (void) fprintf(_Lf
, "%s (%d)\n", text
, status
);
1094 cleanworkspace(void)
1097 char f
[MAXFULLNAME
];
1099 if (chdir(WORKSPACE
) != 0) {
1100 (void) fprintf(stderr
, "CAN'T CHDIR (%s): errno (%d)\n", WORKSPACE
, errno
);
1103 if ((spooldir
= opendir(WORKSPACE
)) == NULL
) {
1104 (void) fprintf(stderr
, "CAN'T OPEN (%s): errno (%d)\n", WORKSPACE
, errno
);
1108 while (gnamef(spooldir
, f
) == TRUE
)
1111 (void) fprintf(stderr
, "CAN'T UNLINK (%s): errno (%d)\n", f
, errno
);