|
|
researchv10 Norman
/* @(#)uucleanup.c 1.6
* uucleanup - This is a program based on the heuristics
* by Brian Redman for cleaning up and doing something
* useful with old files left in the uucp queues.
* It also will send warning messags to users where requests are not
* going out due to failure to contact the remote system.
*
* This program knows a lot about the construction and
* contents of the C., D. and X. files. In addition, it
* thinks it knows what mail and netnews data files look like.
*
* At present, this is what is done:
* For WARNING messages:
* C. files of age given by -W option are read, looking for
* either user files to be sent or received, or
* mail to be sent. (Other remote execution that
* does not involve sending user files is not checked
* for now.) In either of the cases, the user is
* informed by mail that the request is not being
* processed due to lack of communications with the remote
* system, and the request will be deleted in the future
* if it the condition remains for several more days.
*
* For DELETIONS:
* C. files - if they reference only D. files, the C. is
* merely deleted, because the D. files are usually
* mail or news, and the later D. processing will
* take care of them.
* - if they reference files from the file system,
* a message is constructed that will contain a
* lines like
* We can't contact the remote.
*
* local!file -> remote!otherfile
*
* can't be executed.
* X. files - merely deleted at present - D.s will be taken
* care of later. Besides, some of the D.s are
* missing or else the X. wouldn't be left around.
* D. files - mail type data is sent to a local person if that
* is where it originated. If not, it is returned to the
* sender -- assumed to be from the first From line. If
* a sender can't be determing, the file is merely deleted.
* - rnews: if locally generated, just delete. If remote,
* the X. got lost, so execute rnews.
* other files - just delete them.
*
* Deletions and executions are logged in
* (CLEANUPLOG)--/usr/spool/uucp/.Admin/uucleanup
*/
#include "uucp.h"
VERSION(@(#)uucleanup.c 1.6);
#ifdef V7
#define O_RDONLY 0
#endif
#define USAGE "[-oDAYS] [-mSTRING] [-Cdays] [-Ddays] [-Wdays] [-Xdays] [-xLEVEL] [-sSYSTEM]"
extern int _age(); /* find the age of a file */
extern void oprocess(), xprocess(), cprocess();
extern void dXprocess(), dNprocess(), dMprocess(), dDprocess(), wprocess();
extern int toWho(), sendMail(), execRnews();
extern void logit();
/* need these dummys to satisy some .o files */
cleanup(){}
void systat(){}
void logent(){}
/* types of D. files */
#define D_MAIL 1
#define D_NEWS 2
#define D_XFILE 3
#define D_DATA 4
#define FULLNAME(full,dir,file) (void) sprintf(full, "%s/%s", dir, file);
int _Ddays = 7; /* D. limit */
int _Cdays = 7; /* C. limit */
int _Xdays = 2; /* X. limit */
int _Odays = 2; /* O. limit */
int _Wdays = 1; /* Warning limit for C. files */
char _ShortLocal[6]; /* 5 char or less version of local name */
char *_Undeliverable[] = {
"Subject: Undeliverable Mail\n",
"This mail message is undeliverable.\n",
"(Probably to or from system '%s')\n",
"It was sent to you or by you.\n",
"Sorry for the inconvenience.\n",
"",
};
#define CANT1 2 /* first line to fill in */
#define CANT2 3 /* second line to fill in */
char *_CantContact[] = {
"Subject: Job Killed By uucp\n",
"We can't contact machine '%s'.\n",
" ", /* uucleanup will fill in variable text here */
" ", /* fill in jobid of killed job */
"",
};
#define WARN1 2
#define WARN2 5
#define WARN3 6
char *_Warning[] = {
"Subject: Warning From uucp\n",
"We have been unable to contact machine '%s' since you queued your job.\n",
" ", /* wprocess FILLS IN THIS LINE OF TEXT */
"The job will be deleted in several days if the problem is not corrected.\n",
"If you care to kill the job, execute the following command:\n",
" ", /* wprocess FILLS IN THIS LINE WITH: uustat -kJOBid */
" ", /* FILL IN THE -m STRING IF SPECIFIED */
"",
};
main(argc, argv, envp)
char *argv[];
char **envp;
{
DIR *spooldir, *subdir;
char f[MAXFULLNAME], subf[MAXFULLNAME];
char fullname[MAXFULLNAME];
int pass = 0; /* pass counter - multi passes through directory */
char soptName[MAXFULLNAME]; /* name from -s option */
int i, value;
soptName[0] = NULLCHAR;
(void) strcpy(Logfile, CLEANUPLOGFILE);
uucpname(Myname);
(void) strncpy(_ShortLocal, Myname, 5);
_ShortLocal[5] = NULLCHAR;
(void) strcpy(Progname, "uucleanup");
while ((i = getopt(argc, argv, "C:D:W:X:m:o:s:x:")) != EOF) {
switch(i){
case 's': /* for debugging - choose system */
(void) strcpy(soptName, optarg);
break;
case 'x':
Debug = atoi(optarg);
if (Debug <= 0)
Debug = 1;
break;
case 'm':
_Warning[WARN3] = optarg;
break;
default:
(void) fprintf(stderr, "\tusage: %s %s\n",
Progname, USAGE);
exit(1);
case 'C':
case 'D':
case 'W':
case 'X':
case 'o':
value = atoi(optarg);
if (value < 1) {
fprintf(stderr," Options: CDWXo require value > 0\n");
exit(1);
}
switch(i) {
case 'C':
_Cdays = value;
break;
case 'D':
_Ddays = value;
break;
case 'W':
_Wdays = value;
break;
case 'X':
_Xdays = value;
break;
case 'o':
_Odays = value;
break;
}
break;
}
}
if (argc != optind) {
(void) fprintf(stderr, "\tusage: %s %s\n", Progname, USAGE);
exit(1);
}
DEBUG(5, "Progname (%s): STARTED\n", Progname);
DEBUG(5, "Myname (%s), ", Myname);
DEBUG(5, "_ShortLocal (%s)\n", _ShortLocal);
DEBUG(5, "Days C.(%d), ", _Cdays);
DEBUG(5, "D.(%d), ", _Ddays);
DEBUG(5, "W.(%d), ", _Wdays);
DEBUG(5, "X.(%d), ", _Xdays);
DEBUG(5, "other (%d)\n", _Odays);
if (chdir(SPOOL) != 0) {
(void) fprintf(stderr, "CAN'T CHDIR (%s): errno (%d)\n",
SPOOL, errno);
exit(1);
}
if ( (spooldir = opendir(SPOOL)) == NULL) {
(void) fprintf(stderr, "CAN'T OPEN (%s): errno (%d)\n",
SPOOL, errno);
exit(1);
}
while (gnamef(spooldir, f) == TRUE) {
if (EQUALSN("LCK..", f, 5))
continue;
if (*soptName && !EQUALS(soptName, f))
continue;
if (DIRECTORY(f)) {
(void) strcpy(Rmtname, f);
pass = 0;
/*
* pass 1 - process old C. and X. files
* pass 2 - process D.s that are going to X.
* pass 3 - processs D. mail and netnews and other D.s
* pass 4 - process other
*/
while ( (++pass < 5) && (subdir = opendir(f)) ) {
DEBUG(7, "Directory: %s\n", f);
while (gnamef(subdir, subf) == TRUE) {
DEBUG(9, "file: %s\n", subf);
FULLNAME(fullname, f, subf);
switch (pass) {
case 1:
if (EQUALSN(subf, "C.", 2)
&& _age(fullname) >=_Cdays)
cprocess(fullname);
else if (EQUALSN(subf, "C.", 2)
&& _age(fullname) ==_Wdays)
wprocess(f, subf);
else if (EQUALSN(subf, "X.", 2)
&& _age(fullname) >=_Xdays)
xprocess(fullname);
break;
case 2: /* pass 2 */
if (EQUALSN(subf, "D.", 2)
&& _age(fullname) >= _Ddays
&& dType(fullname) == D_XFILE)
dXprocess(fullname);
break;
case 3: /* pass 3 */
if (EQUALSN(subf, "D.", 2)
&& _age(fullname) >= _Ddays)
switch (dType(fullname)) {
case D_MAIL:
dMprocess(f, subf);
break;
case D_NEWS:
dNprocess(f, subf);
break;
case D_DATA:
dDprocess(fullname);
break;
default: /* do nothing */
break;
}
break;
case 4:
if ( _age(fullname) >= _Odays
&& !EQUALSN(subf, "C.", 2)
&& !EQUALSN(subf, "D.", 2)
&& !EQUALSN(subf, "X.", 2) )
oprocess(fullname);
break;
}
}
closedir(subdir);
}
}
}
exit(0);
}
/* xprocess - X. file processing -- just remove the X. for now */
void
xprocess(fullname)
char *fullname;
{
char text[BUFSIZ];
DEBUG(5, "xprocess(%s), ", fullname);
DEBUG(5, "unlink(%s)\n", fullname);
(void) sprintf(text, "xprocess: unlink(%s)", fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
/*
* cprocess - Process old C. files
*
*/
#define CMFMT "\n\t%s!%s -> %s!%s (Date %2.2d/%2.2d)\n\nCan't be executed."
#define XFMT "\n\t%s!%s (Date %2.2d/%2.2d)\n"
#define WFMT "\n\t%s!%s -> %s!%s (Date %2.2d/%2.2d)\n"
void
cprocess(fullname)
char *fullname;
{
struct stat s;
register struct tm *tp;
char buf[BUFSIZ], user[9];
char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
char text[BUFSIZ], text1[BUFSIZ], text2[BUFSIZ];
FILE *fp;
int ret;
DEBUG(5, "cprocess(%s)\n", fullname);
fp = fopen(fullname, "r");
if (fp == NULL) {
DEBUG(5, "Can't open file (%s), ", fullname);
DEBUG(5, "errno=%d -- skip it!\n", errno);
return;
}
if (fstat(fileno(fp), &s) != 0) {
/* can't happen; _age() did stat of this file and file is opened */
(void) fclose(fp);
return;
}
tp = localtime(&s.st_mtime);
if (s.st_size == 0) { /* dummy C. for polling */
DEBUG(5, "dummy C. -- unlink(%s)\n", fullname);
(void) sprintf(text, "dDprocess: dummy C. unlinked(%s)",
fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
(void) fclose(fp);
return;
}
/* Read the C. file and process it */
while (fgets(buf, BUFSIZ, fp) != NULL) {
buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
user, opt, file3) <5) {
(void) sprintf(text, "cprocess: Bad C. %s, unlink(%s)",
buf, fullname);
break;
}
*text = NULLCHAR;
ret = 0;
/* fill in line 3 of text */
(void) sprintf(text2, "Job (%s) killed!\n",
BASENAME(fullname, '/')+2);
_CantContact[CANT2] = text2;
if (*type == 'S') {
if (EQUALSN(file1, "D.", 2))
/* generated file (mail/news) I think */
/* D. processing will return it later */
continue;
/* some data was requested -- tell user */
(void) sprintf(text1, CMFMT, Myname, file1, Rmtname, file2,
tp->tm_mon + 1, tp->tm_mday);
_CantContact[CANT1] = text1;
ret = sendMail((char *) NULL, user, "", _CantContact);
}
else if (*type == 'R') {
(void) sprintf(text1, CMFMT, Rmtname, file1, Myname, file2,
tp->tm_mon + 1, tp->tm_mday);
_CantContact[CANT1] = text1;
ret = sendMail((char *) NULL, user, "", _CantContact);
}
}
if (!*text) {
(void) sprintf(text,
"cprocess: C. %s, mail returned (%d), unlink(%s)",
buf, ret, fullname);
}
DEBUG(3, "text (%s)\n", text);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
(void) fclose(fp);
return;
}
/*
* wprocess - send warning messages for C. == Wdays
*/
void
wprocess(dir, file)
char *dir, *file;
{
struct stat s;
register struct tm *tp;
char fullname[BUFSIZ], xfile[BUFSIZ], xF_file[BUFSIZ];
char buf[BUFSIZ], user[BUFSIZ];
char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
char text[BUFSIZ], text1[BUFSIZ], text2[BUFSIZ];
char *realuser, uline_m[NAMESIZE], uline_u[BUFSIZ], retaddr[BUFSIZ];
FILE *fp, *xfp;
int ret;
FULLNAME(fullname, dir, file);
DEBUG(5, "wprocess(%s)\n", fullname);
fp = fopen(fullname, "r");
if (fp == NULL) {
DEBUG(4, "Can't open file (%s), ", fullname);
DEBUG(4, "errno=%d -- skip it!\n", errno);
return;
}
if (fstat(fileno(fp), &s) != 0) {
/* can't happen; _age() did stat of this file and file is opened */
(void) fclose(fp);
return;
}
tp = localtime(&s.st_mtime);
if (s.st_size == 0) { /* dummy C. for polling */
DEBUG(5, "dummy C. -- skip(%s)\n", fullname);
(void) fclose(fp);
return;
}
/* read C. and process it */
while (fgets(buf, BUFSIZ, fp) != NULL) {
buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
user, opt, file3) <5) {
DEBUG(5, "short line (%s): ", buf);
DEBUG(5, "bad D. -- skip(%s)\n", fullname);
(void) fclose(fp);
return;
}
/* set up the 6th text line of the mail message */
(void) sprintf(text2,
"\n\tuustat -k%s\n", BASENAME(fullname, '/')+2);
_Warning[WARN2] = text2;
if (*type == 'S') { /* Send type C. file processing */
if (EQUALSN(file2, "X.", 2)) {
/* this is a uux job - tell user about it */
FULLNAME(xfile, dir, file1);
if ( (xfp = fopen(xfile, "r")) == NULL) {
/* Can't read X. file ??? - just skip */
DEBUG(3, "Can't read %s\n", xfile);
break;
}
*retaddr = *uline_u = *uline_m = *text = NULLCHAR;
while (fgets(buf, BUFSIZ, xfp) != NULL) {
buf[strlen(buf)-1] = NULLCHAR; /* remove \n */
switch(*buf) {
case 'F': /* save the file name */
FULLNAME(xF_file, dir, &buf[2]);
break;
case 'R': /* save return address */
sscanf(buf+2, "%s", retaddr);
DEBUG(7, "retaddr (%s)\n", retaddr);
break;
case 'U': /* save machine, user */
sscanf(buf+2, "%s%s", uline_u, uline_m);
break;
}
if (buf[0] != 'C')
continue;
realuser = uline_u;
if (*retaddr != NULLCHAR)
realuser = retaddr;
if (*realuser == NULLCHAR)
strcpy(realuser, user);
if (!EQUALS(uline_m, Myname))
sprintf(user, "%s!%s", uline_m, realuser);
else
strcpy(user, realuser);
(void) sprintf(text1, XFMT, Rmtname,
EQUALSN(&buf[2], "rmail", 5) ? &buf[3] : &buf[2],
tp->tm_mon + 1, tp->tm_mday);
_Warning[WARN1] = text1;
if (EQUALSN(&buf[2], "rmail", 5) )
/* this is mail; append user mail (xF_file) */
ret = sendMail((char *) NULL, user, xF_file, _Warning);
else
ret = sendMail((char *) NULL, user, "", _Warning);
break;
}
(void) fclose(xfp);
break;
}
if (EQUALSN(file1, "D.", 2))
/* generated file (mail/news) I think */
/* D. processing will return it later */
continue;
/* some data was requested -- tell user */
/* set up the 2nd text line of the mail message */
(void) sprintf(text1, WFMT, Myname, file1, Rmtname, file2,
tp->tm_mon + 1, tp->tm_mday);
_Warning[WARN1] = text1;
ret = sendMail((char *) NULL, user, "", _Warning);
}
else if (*type == 'R') { /* Receive C. file processing */
if (EQUALSN(file1, "D.", 2) && EQUALSN(file2, "D.", 2))
continue;
(void) sprintf(text1, WFMT, Rmtname, file1, Myname, file2,
tp->tm_mon + 1, tp->tm_mday);
_Warning[WARN1] = text1;
ret = sendMail((char *) NULL, user, "", _Warning);
}
} /* end while - read C. lines loop */
(void) sprintf(text,
"wprocess: %s: %s, warning message sent to %s, returned (%d)",
fullname, buf, user, ret);
DEBUG(3, "text (%s)\n", text);
logit(text, errno);
(void) fclose(fp);
return;
}
/*
* oprocess - some unknown file just remove the file
*/
void
oprocess(fullname)
char *fullname;
{
char text[BUFSIZ];
DEBUG(5, "oprocess(%s), ", fullname);
DEBUG(5, "unlink(%s)\n", fullname);
(void) sprintf(text, "oprocess: unlink(%s)", fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
/*
* dDprocess - random D. file (not mail or rnews)
*--just delete it for now
*/
void
dDprocess(fullname)
char *fullname;
{
char text[BUFSIZ];
DEBUG(5, "dDprocess(%s), ", fullname);
DEBUG(5, "unlink(%s)\n", fullname);
(void) sprintf(text, "dDprocess: unlink(%s)", fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
/*
* dXprocess - process D. files that are destined for X. on remote
* --for now just delete it
*/
void
dXprocess(fullname)
char *fullname;
{
char text[BUFSIZ];
DEBUG(5, "dXprocess(%s), ", fullname);
DEBUG(5, " unlink(%s)\n", fullname);
(void) sprintf(text, "dXprocess: unlink(%s)", fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
/*
* dMprocess - process ophan D. mail files
* There are two types: ones generated locally and
* others that are from remotes. They can be identified
* by the system name following the D.
* Local ones have the local name.
*/
void
dMprocess(dir, file)
char *dir, *file;
{
int ret;
char fullname[MAXFULLNAME];
char *toUser, *toSystem;
char text[BUFSIZ];
(void) sprintf(fullname, "%s/%s", dir, file);
DEBUG(5, "dMprocess(%s)\n", fullname);
if (PREFIX(_ShortLocal, &file[2])) {
DEBUG(5, " Local file %s: ", file);
}
else {
DEBUG(5, " Remote file %s: ", file);
}
if (toWho(fullname, &toUser, &toSystem)) {
DEBUG(5, "toUser %s, ", toUser);
DEBUG(5, "toSystem %s ", toSystem);
ret = sendMail(toSystem, toUser, fullname, _Undeliverable);
DEBUG(5, "Mail sent, unlink(%s)\n", fullname);
(void) sprintf(text,
"dMprocess: mail %s to %s!%s, returned (%d), unlink(%s)",
fullname, toSystem, toUser, ret, fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
}
/*
* dNprocess - process ophan D. netnews files
* There are two types: ones generated locally and
* others that are from remotes. They can be identified
* by the system name following the D.
* Local ones have the local name.
*/
void
dNprocess(dir, file)
char *dir, *file;
{
char fullname[MAXFULLNAME];
char text[BUFSIZ];
int ret;
(void) sprintf(fullname, "%s/%s", dir, file);
DEBUG(5, "dNprocess(%s)\n", fullname);
if (PREFIX(_ShortLocal, &file[2])) {
/* just delete it, the C. is gone */
DEBUG(5, " Local file %s, ", file);
DEBUG(5, "unlink(%s)\n", fullname);
(void) unlink(fullname);
(void) sprintf(text, "dNprocess: Local news item unlink(%s)",
fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
else {
/* execute rnews with this file - the X. is missing */
DEBUG(5, " Remote file %s, ", file);
DEBUG(5, "exec rnews(%s), ", fullname);
ret = execRnews(fullname);
DEBUG(5, "unlink(%s)\n", fullname);
(void) sprintf(text,
"dNprocess: Remote - exec rnews %s: returned (%d), unlink(%s)",
fullname, ret, fullname);
errno = 0;
(void) unlink(fullname);
logit(text, errno);
}
}
static long _sec_per_day = 86400L;
/*
* _age - find the age of "file" in days
* return:
* age of file
* 0 - if stat fails
*/
int
_age(fullname)
char *fullname;
{
static time_t ptime = 0;
time_t time();
struct stat stbuf;
if (!ptime)
(void) time(&ptime);
if (stat(fullname, &stbuf) != -1) {
return ((int)((ptime - stbuf.st_mtime)/_sec_per_day));
}
else
return(0);
}
/*
* dType - return the type of D. file
* return:
* FAIL - can't read D. file
* D_MAIL - mail message D. file
* D_NEWS - netnews D. file
* D_DATA - other kind of D. file
* D_XFILE - destined for X. on destination machine
*/
/* NLINES - number of lines of D. file to read to determine type */
#define NLINES 10
int
dType(fullname)
char *fullname;
{
char buf[BUFSIZ];
FILE *fp;
int i, type;
fp = fopen(fullname, "r");
if (fp == NULL) {
DEBUG(4, "Can't open file (%s), ", fullname);
DEBUG(4, "errno=%d -- skip it!\n", errno);
return(FAIL);
}
type = D_DATA;
/* read first NLINES lines to determine file type */
for (i=0; i<NLINES; i++) {
DEBUG(9, "buf: %s\n", buf);
if (fgets(buf, BUFSIZ, fp) == NULL)
break; /* no more lines */
if (EQUALSN(buf, "From ", 5)) {
type = D_MAIL;
break;
}
if (EQUALSN(buf, "U ", 2)) {
type = D_XFILE;
break;
}
if (EQUALSN(buf, "Newsgroups: ", 12)) {
type = D_NEWS;
break;
}
}
(void) fclose(fp);
return(type);
}
/*
* sendMail - send mail file and message to user (local or remote)
* return:
* the return from the pclose - mail exit status
*/
static char *salute[] = {
"Frankly,",
"Honestly,",
"Candidly,",
"Guilelessly,",
"Purely,",
"Scrupulously,",
"Ingenuously,",
"Innocently,",
"Childishly,",
"Artlessly,",
"Bluntly,",
"Naively,",
"Sympathetically,",
"Sufferingly,",
"Enduringly,",
"Pathetically,",
"Gustily,",
"Heartily,",
"Warmly,",
"Passionately,",
"Profoundly,",
"Wistfully,",
"Rabidly,",
"Hysterically,",
"Impetously,",
"Feverishly,",
};
sendMail(system, user, file, mtext)
char *system, *user, *file;
char *mtext[];
{
register FILE *fp, *fi;
char cmd[BUFSIZ];
static int rstart = 0;
long time();
DEBUG(5, "Mail %s to ", file);
DEBUG(5, "%s\n", user);
if (system != NULL && *system != '\0')
(void) sprintf(cmd, "%s mail %s!%s", PATH, system, user);
else
(void) sprintf(cmd, "%s mail %s", PATH, user);
DEBUG(7, "sendMail: %s\n", cmd);
if ((fp = popen(cmd, "w")) == NULL)
return(-errno);
while (*mtext[0] )
(void) fprintf(fp, *mtext++, Rmtname);
if (rstart == 0) {
srand((int)time((long *)0));
rstart = 1;
}
(void) fprintf(fp, "\n\t%s\n\t%s!uucp\n",
salute[rand()%sizeof(salute)/sizeof(salute[0])], Myname);
if (*file) {
if ((fi= fopen(file, "r")) == NULL) /* never happen;I read once */
return(pclose(fp));
(void) fprintf(fp,
"##### Data File: ############################\n");
xfappend(fi, fp);
(void) fclose(fi);
}
return(pclose(fp));
}
/*
* execRnews - execute rnews command with stdin file
* return:
* the return from the pclose - rnews exit status
*/
execRnews(file)
char *file;
{
register FILE *fp, *fi;
char cmd[BUFSIZ];
DEBUG(5, "Rnews %s\n", file);
(void) sprintf(cmd, "%s rnews ", PATH);
if ((fp = popen(cmd, "w")) == NULL)
return(-errno);
if ( (fi = fopen(file, "r")) == NULL) /* never happen - I read once */
return(pclose(fp));
xfappend(fi, fp);
(void) fclose(fi);
return(pclose(fp));
}
/*
* toWho - figure out who to send this dead mail to
* It is a guess;
* If there is a local address, send it there.
* If not, send it back where it came from.
* return:
* 0 - could not find system and user information
* 1 - found it
*/
int
toWho(file, user, system)
char *file; /* the D. mail message file */
char **system; /* pointer to the system name */
char **user; /* pointer to the user name */
{
char buf[BUFSIZ];
FILE *fp;
int i;
static char fuser[BUFSIZ], fsystem[MAXBASENAME+1]; /* from first From */
static char luser[BUFSIZ], lsystem[MAXBASENAME+1]; /* from other From */
*fuser = NULLCHAR;
DEBUG(5, "toWho(%s)\n", file);
fp = fopen(file, "r");
for (i=0; i<NLINES; i++) {
if (fgets(buf, BUFSIZ, fp) == NULL)
break; /* no more lines */
DEBUG(9, "buf: %s\n", buf);
if (!analFrom(buf, luser, lsystem))
continue;
if ( !*fuser) {
(void) strcpy(fuser, luser);
(void) strcpy(fsystem, lsystem);
}
if (EQUALS(Myname, lsystem)) {
*user = luser;
*system = lsystem;
(void) fclose(fp);
return(1);
}
}
/* could not find local user - use first line */
(void) fclose(fp);
if (!*fuser) /* didn't find all information */
return(0);
*user = fuser;
*system = fsystem;
return(1);
}
/* analFrom - analyze From line
* return:
* 0 - didn't find both from and remote from info
* 1 - found info.
*/
int
analFrom(line, user, system)
char *line, *user, *system;
{
char *s;
int i;
if (!PREFIX("From ", line) && !PREFIX(">From ", line))
return(0);
s = strchr(line, ' ') + 1;
for (i = 0; *s && *s != ' ' && *s != '\n'; i++)
user[i] = *s++;
user[i] = NULLCHAR;
/* look for "remote from" */
while (*s && ((s = strchr(s, ' ')) != NULL)) {
s++;
if (PREFIX("remote from ", s)) { /* found it */
s = s + strlen("remote from ");
for (i = 0; (i<MAXBASENAME) && *s && *s != ' ' && *s != '\n'; i++)
system[i] = *s++;
system[i] = NULLCHAR;
return(1);
}
}
return(0);
}
static FILE *_Lf = NULL;
/*
* Make log entry
* text -> ptr to text string
* status errno number
* Returns:
* none
*/
void
logit(text, status)
register char *text;
int status;
{
if (Nstat.t_pid == 0)
Nstat.t_pid = getpid();
if (_Lf == NULL) {
_Lf = fopen(Logfile, "a");
if (_Lf == NULL)
return;
setbuf(_Lf, CNULL);
}
(void) fseek(_Lf, 0L, 2);
(void) fprintf(_Lf, "%s ", Rmtname);
(void) fprintf(_Lf, "(%s,%d,%d) ", timeStamp(), Nstat.t_pid, Seqn);
(void) fprintf(_Lf, "%s (%d)\n", text, status);
return;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.