xref: /csrg-svn/usr.bin/uucp/uuclean/uuclean.c (revision 13702)
113675Ssam #ifndef lint
2*13702Ssam static char sccsid[] = "@(#)uuclean.c	5.2 (Berkeley) 07/02/83";
313675Ssam #endif
413675Ssam 
513675Ssam #include "uucp.h"
613675Ssam #include <signal.h>
713675Ssam #include <pwd.h>
813675Ssam #include <sys/types.h>
913675Ssam #include <sys/stat.h>
1013675Ssam #ifdef	NDIR
1113675Ssam #include "ndir.h"
1213675Ssam #else
13*13702Ssam #include <sys/dir.h>
1413675Ssam #endif
1513675Ssam 
1613675Ssam extern time_t time();
1713675Ssam 
1813675Ssam 
1913675Ssam /*******
2013675Ssam  *
2113675Ssam  *	uuclean  -  this program will search through the spool
2213675Ssam  *	directory (Spool) and delete all files with a requested
2313675Ssam  *	prefix which are older than (nomtime) seconds.
2413675Ssam  *	If the -m option is set, the program will try to
2513675Ssam  *	send mail to the usid of the file.
2613675Ssam  *
2713675Ssam  *	options:
2813675Ssam  *		-m  -  send mail for deleted file
2913675Ssam  *		-d  -  directory to clean
3013675Ssam  *		-n  -  time to age files before delete (in hours)
3113675Ssam  *		-p  -  prefix for search
3213675Ssam  *		-x  -  turn on debug outputs
3313675Ssam  *	exit status:
3413675Ssam  *		0  -  normal return
3513675Ssam  *		1  -  can not read directory
3613675Ssam  */
3713675Ssam 
3813675Ssam #define DPREFIX "U"
3913675Ssam #define NOMTIME 72	/* hours to age files before deletion */
4013675Ssam 
4113675Ssam main(argc, argv)
4213675Ssam char *argv[];
4313675Ssam {
4413675Ssam 	DIR *dirp;
4513675Ssam 	char file[NAMESIZE];
4613675Ssam 	time_t nomtime, ptime;
4713675Ssam 	struct stat stbuf;
4813675Ssam 	int mflg=0;
4913675Ssam 	int orig_uid = getuid();
5013675Ssam 
5113675Ssam 	strcpy(Progname, "uuclean");
5213675Ssam 	uucpname(Myname);
5313675Ssam 	nomtime = NOMTIME * (time_t)3600;
5413675Ssam 
5513675Ssam 	while (argc>1 && argv[1][0] == '-') {
5613675Ssam 		switch (argv[1][1]) {
5713675Ssam 		case 'd':
5813675Ssam 			Spool = &argv[1][2];
5913675Ssam 			break;
6013675Ssam 		case 'm':
6113675Ssam 			mflg = 1;
6213675Ssam 			break;
6313675Ssam 		case 'n':
6413675Ssam 			nomtime = atoi(&argv[1][2]) * (time_t)3600;
6513675Ssam 			break;
6613675Ssam 		case 'p':
6713675Ssam 			if (&argv[1][2] != '\0')
6813675Ssam 				stpre(&argv[1][2]);
6913675Ssam 			break;
7013675Ssam 		case 'x':
7113675Ssam 			chkdebug(orig_uid);
7213675Ssam 			Debug = atoi(&argv[1][2]);
7313675Ssam 			if (Debug <= 0)
7413675Ssam 				Debug = 1;
7513675Ssam 			break;
7613675Ssam 		default:
7713675Ssam 			printf("unknown flag %s\n", argv[1]); break;
7813675Ssam 		}
7913675Ssam 		--argc;  argv++;
8013675Ssam 	}
8113675Ssam 
8213675Ssam 	DEBUG(4, "DEBUG# %s\n", "START");
8313675Ssam 	chdir(Spool);	/* NO subdirs in uuclean!  rti!trt */
8413675Ssam 
8513675Ssam 	if ((dirp = opendir(Spool)) == NULL) {
8613675Ssam 		printf("%s directory unreadable\n", Spool);
8713675Ssam 		exit(1);
8813675Ssam 	}
8913675Ssam 
9013675Ssam 	time(&ptime);
9113675Ssam 	while (gnamef(dirp, file)) {
9213675Ssam 		if (!chkpre(file))
9313675Ssam 			continue;
9413675Ssam 
9513675Ssam 		if (stat(file, &stbuf) == -1) {	/* NO subdirs in uuclean! */
9613675Ssam 		DEBUG(4, "stat on %s failed\n", file);
9713675Ssam 			continue;
9813675Ssam 		}
9913675Ssam 
10013675Ssam 
10113675Ssam 		if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
10213675Ssam 			continue;
10313675Ssam /*
10413675Ssam  * teklabs.1518, Terry Laskodi, +2s/ctime/mtime/
10513675Ssam  * so mv-ing files about does not defeat uuclean
10613675Ssam  */
10713675Ssam 		if ((ptime - stbuf.st_mtime) < nomtime)
10813675Ssam 			continue;
10913675Ssam 		if (file[0] == CMDPRE)
11013675Ssam 			notfyuser(file);
11113675Ssam 		DEBUG(4, "unlink file %s\n", file);
11213675Ssam 		unlink(file);
11313675Ssam 		if (mflg) sdmail(file, stbuf.st_uid);
11413675Ssam 	}
11513675Ssam 
11613675Ssam 	closedir(dirp);
11713675Ssam 	exit(0);
11813675Ssam }
11913675Ssam 
12013675Ssam 
12113675Ssam #define MAXPRE 10
12213675Ssam char Pre[MAXPRE][NAMESIZE];
12313675Ssam int Npre = 0;
12413675Ssam /***
12513675Ssam  *	chkpre(file)	check for prefix
12613675Ssam  *	char *file;
12713675Ssam  *
12813675Ssam  *	return codes:
12913675Ssam  *		0  -  not prefix
13013675Ssam  *		1  -  is prefix
13113675Ssam  */
13213675Ssam 
13313675Ssam chkpre(file)
13413675Ssam char *file;
13513675Ssam {
13613675Ssam 	int i;
13713675Ssam 
13813675Ssam 	for (i = 0; i < Npre; i++) {
13913675Ssam 		if (prefix(Pre[i], file))
14013675Ssam 			return(1);
14113675Ssam 		}
14213675Ssam 	return(0);
14313675Ssam }
14413675Ssam 
14513675Ssam /***
14613675Ssam  *	stpre(p)	store prefix
14713675Ssam  *	char *p;
14813675Ssam  *
14913675Ssam  *	return codes:  none
15013675Ssam  */
15113675Ssam 
15213675Ssam stpre(p)
15313675Ssam char *p;
15413675Ssam {
15513675Ssam 	if (Npre < MAXPRE - 2)
15613675Ssam 		strcpy(Pre[Npre++], p);
15713675Ssam 	return;
15813675Ssam }
15913675Ssam 
16013675Ssam /***
16113675Ssam  *	notfyuser(file)	- notfiy requestor of deleted requres
16213675Ssam  *
16313675Ssam  *	return code - none
16413675Ssam  */
16513675Ssam 
16613675Ssam notfyuser(file)
16713675Ssam char *file;
16813675Ssam {
16913675Ssam 	FILE *fp;
17013675Ssam 	int numrq;
17113675Ssam 	char frqst[100], lrqst[100];
17213675Ssam 	char msg[BUFSIZ];
17313675Ssam 	char *args[10];
17413675Ssam 
17513675Ssam 	if ((fp = fopen(file, "r")) == NULL)
17613675Ssam 		return;
17713675Ssam 	if (fgets(frqst, 100, fp) == NULL) {
17813675Ssam 		fclose(fp);
17913675Ssam 		return;
18013675Ssam 	}
18113675Ssam 	numrq = 1;
18213675Ssam 	while (fgets(lrqst, 100, fp))
18313675Ssam 		numrq++;
18413675Ssam 	fclose(fp);
18513675Ssam 	sprintf(msg,
18613675Ssam 	  "File %s delete. \nCould not contact remote. \n%d requests deleted.\n", file, numrq);
18713675Ssam 	if (numrq == 1) {
18813675Ssam 		strcat(msg, "REQUEST: ");
18913675Ssam 		strcat(msg, frqst);
19013675Ssam 	}
19113675Ssam 	else {
19213675Ssam 		strcat(msg, "FIRST REQUEST: ");
19313675Ssam 		strcat(msg, frqst);
19413675Ssam 		strcat(msg, "\nLAST REQUEST: ");
19513675Ssam 		strcat(msg, lrqst);
19613675Ssam 	}
19713675Ssam 	getargs(frqst, args);
19813675Ssam 	mailst(args[3], msg, "");
19913675Ssam 	return;
20013675Ssam }
20113675Ssam 
20213675Ssam 
20313675Ssam /***
20413675Ssam  *	sdmail(file, uid)
20513675Ssam  *
20613675Ssam  *	sdmail  -  this routine will determine the owner
20713675Ssam  *	of the file (file), create a message string and
20813675Ssam  *	call "mailst" to send the cleanup message.
20913675Ssam  *	This is only implemented for local system
21013675Ssam  *	mail at this time.
21113675Ssam  */
21213675Ssam 
21313675Ssam sdmail(file, uid)
21413675Ssam char *file;
21513675Ssam {
21613675Ssam 	static struct passwd *pwd;
21713675Ssam 	struct passwd *getpwuid();
21813675Ssam 	char mstr[40];
21913675Ssam 
22013675Ssam 	sprintf(mstr, "uuclean deleted file %s\n", file);
22113675Ssam 	if (pwd->pw_uid == uid) {
22213675Ssam 		mailst(pwd->pw_name, mstr, "");
22313675Ssam 	return(0);
22413675Ssam 	}
22513675Ssam 
22613675Ssam 	setpwent();
22713675Ssam 	if ((pwd = getpwuid(uid)) != NULL) {
22813675Ssam 		mailst(pwd->pw_name, mstr, "");
22913675Ssam 	}
23013675Ssam 	return(0);
23113675Ssam }
23213675Ssam 
23313675Ssam cleanup(code)
23413675Ssam int code;
23513675Ssam {
23613675Ssam 	exit(code);
23713675Ssam }
238