xref: /csrg-svn/usr.bin/uucp/uuclean/uuclean.c (revision 13675)
1*13675Ssam #ifndef lint
2*13675Ssam static char sccsid[] = "@(#)uuclean.c	5.1 (Berkeley) 07/02/83";
3*13675Ssam #endif
4*13675Ssam 
5*13675Ssam #include "uucp.h"
6*13675Ssam #include <signal.h>
7*13675Ssam #include <pwd.h>
8*13675Ssam #include <sys/types.h>
9*13675Ssam #include <sys/stat.h>
10*13675Ssam #ifdef	NDIR
11*13675Ssam #include "ndir.h"
12*13675Ssam #else
13*13675Ssam #include <dir.h>
14*13675Ssam #endif
15*13675Ssam 
16*13675Ssam extern time_t time();
17*13675Ssam 
18*13675Ssam 
19*13675Ssam /*******
20*13675Ssam  *
21*13675Ssam  *	uuclean  -  this program will search through the spool
22*13675Ssam  *	directory (Spool) and delete all files with a requested
23*13675Ssam  *	prefix which are older than (nomtime) seconds.
24*13675Ssam  *	If the -m option is set, the program will try to
25*13675Ssam  *	send mail to the usid of the file.
26*13675Ssam  *
27*13675Ssam  *	options:
28*13675Ssam  *		-m  -  send mail for deleted file
29*13675Ssam  *		-d  -  directory to clean
30*13675Ssam  *		-n  -  time to age files before delete (in hours)
31*13675Ssam  *		-p  -  prefix for search
32*13675Ssam  *		-x  -  turn on debug outputs
33*13675Ssam  *	exit status:
34*13675Ssam  *		0  -  normal return
35*13675Ssam  *		1  -  can not read directory
36*13675Ssam  */
37*13675Ssam 
38*13675Ssam #define DPREFIX "U"
39*13675Ssam #define NOMTIME 72	/* hours to age files before deletion */
40*13675Ssam 
41*13675Ssam main(argc, argv)
42*13675Ssam char *argv[];
43*13675Ssam {
44*13675Ssam 	DIR *dirp;
45*13675Ssam 	char file[NAMESIZE];
46*13675Ssam 	time_t nomtime, ptime;
47*13675Ssam 	struct stat stbuf;
48*13675Ssam 	int mflg=0;
49*13675Ssam 	int orig_uid = getuid();
50*13675Ssam 
51*13675Ssam 	strcpy(Progname, "uuclean");
52*13675Ssam 	uucpname(Myname);
53*13675Ssam 	nomtime = NOMTIME * (time_t)3600;
54*13675Ssam 
55*13675Ssam 	while (argc>1 && argv[1][0] == '-') {
56*13675Ssam 		switch (argv[1][1]) {
57*13675Ssam 		case 'd':
58*13675Ssam 			Spool = &argv[1][2];
59*13675Ssam 			break;
60*13675Ssam 		case 'm':
61*13675Ssam 			mflg = 1;
62*13675Ssam 			break;
63*13675Ssam 		case 'n':
64*13675Ssam 			nomtime = atoi(&argv[1][2]) * (time_t)3600;
65*13675Ssam 			break;
66*13675Ssam 		case 'p':
67*13675Ssam 			if (&argv[1][2] != '\0')
68*13675Ssam 				stpre(&argv[1][2]);
69*13675Ssam 			break;
70*13675Ssam 		case 'x':
71*13675Ssam 			chkdebug(orig_uid);
72*13675Ssam 			Debug = atoi(&argv[1][2]);
73*13675Ssam 			if (Debug <= 0)
74*13675Ssam 				Debug = 1;
75*13675Ssam 			break;
76*13675Ssam 		default:
77*13675Ssam 			printf("unknown flag %s\n", argv[1]); break;
78*13675Ssam 		}
79*13675Ssam 		--argc;  argv++;
80*13675Ssam 	}
81*13675Ssam 
82*13675Ssam 	DEBUG(4, "DEBUG# %s\n", "START");
83*13675Ssam 	chdir(Spool);	/* NO subdirs in uuclean!  rti!trt */
84*13675Ssam 
85*13675Ssam 	if ((dirp = opendir(Spool)) == NULL) {
86*13675Ssam 		printf("%s directory unreadable\n", Spool);
87*13675Ssam 		exit(1);
88*13675Ssam 	}
89*13675Ssam 
90*13675Ssam 	time(&ptime);
91*13675Ssam 	while (gnamef(dirp, file)) {
92*13675Ssam 		if (!chkpre(file))
93*13675Ssam 			continue;
94*13675Ssam 
95*13675Ssam 		if (stat(file, &stbuf) == -1) {	/* NO subdirs in uuclean! */
96*13675Ssam 		DEBUG(4, "stat on %s failed\n", file);
97*13675Ssam 			continue;
98*13675Ssam 		}
99*13675Ssam 
100*13675Ssam 
101*13675Ssam 		if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
102*13675Ssam 			continue;
103*13675Ssam /*
104*13675Ssam  * teklabs.1518, Terry Laskodi, +2s/ctime/mtime/
105*13675Ssam  * so mv-ing files about does not defeat uuclean
106*13675Ssam  */
107*13675Ssam 		if ((ptime - stbuf.st_mtime) < nomtime)
108*13675Ssam 			continue;
109*13675Ssam 		if (file[0] == CMDPRE)
110*13675Ssam 			notfyuser(file);
111*13675Ssam 		DEBUG(4, "unlink file %s\n", file);
112*13675Ssam 		unlink(file);
113*13675Ssam 		if (mflg) sdmail(file, stbuf.st_uid);
114*13675Ssam 	}
115*13675Ssam 
116*13675Ssam 	closedir(dirp);
117*13675Ssam 	exit(0);
118*13675Ssam }
119*13675Ssam 
120*13675Ssam 
121*13675Ssam #define MAXPRE 10
122*13675Ssam char Pre[MAXPRE][NAMESIZE];
123*13675Ssam int Npre = 0;
124*13675Ssam /***
125*13675Ssam  *	chkpre(file)	check for prefix
126*13675Ssam  *	char *file;
127*13675Ssam  *
128*13675Ssam  *	return codes:
129*13675Ssam  *		0  -  not prefix
130*13675Ssam  *		1  -  is prefix
131*13675Ssam  */
132*13675Ssam 
133*13675Ssam chkpre(file)
134*13675Ssam char *file;
135*13675Ssam {
136*13675Ssam 	int i;
137*13675Ssam 
138*13675Ssam 	for (i = 0; i < Npre; i++) {
139*13675Ssam 		if (prefix(Pre[i], file))
140*13675Ssam 			return(1);
141*13675Ssam 		}
142*13675Ssam 	return(0);
143*13675Ssam }
144*13675Ssam 
145*13675Ssam /***
146*13675Ssam  *	stpre(p)	store prefix
147*13675Ssam  *	char *p;
148*13675Ssam  *
149*13675Ssam  *	return codes:  none
150*13675Ssam  */
151*13675Ssam 
152*13675Ssam stpre(p)
153*13675Ssam char *p;
154*13675Ssam {
155*13675Ssam 	if (Npre < MAXPRE - 2)
156*13675Ssam 		strcpy(Pre[Npre++], p);
157*13675Ssam 	return;
158*13675Ssam }
159*13675Ssam 
160*13675Ssam /***
161*13675Ssam  *	notfyuser(file)	- notfiy requestor of deleted requres
162*13675Ssam  *
163*13675Ssam  *	return code - none
164*13675Ssam  */
165*13675Ssam 
166*13675Ssam notfyuser(file)
167*13675Ssam char *file;
168*13675Ssam {
169*13675Ssam 	FILE *fp;
170*13675Ssam 	int numrq;
171*13675Ssam 	char frqst[100], lrqst[100];
172*13675Ssam 	char msg[BUFSIZ];
173*13675Ssam 	char *args[10];
174*13675Ssam 
175*13675Ssam 	if ((fp = fopen(file, "r")) == NULL)
176*13675Ssam 		return;
177*13675Ssam 	if (fgets(frqst, 100, fp) == NULL) {
178*13675Ssam 		fclose(fp);
179*13675Ssam 		return;
180*13675Ssam 	}
181*13675Ssam 	numrq = 1;
182*13675Ssam 	while (fgets(lrqst, 100, fp))
183*13675Ssam 		numrq++;
184*13675Ssam 	fclose(fp);
185*13675Ssam 	sprintf(msg,
186*13675Ssam 	  "File %s delete. \nCould not contact remote. \n%d requests deleted.\n", file, numrq);
187*13675Ssam 	if (numrq == 1) {
188*13675Ssam 		strcat(msg, "REQUEST: ");
189*13675Ssam 		strcat(msg, frqst);
190*13675Ssam 	}
191*13675Ssam 	else {
192*13675Ssam 		strcat(msg, "FIRST REQUEST: ");
193*13675Ssam 		strcat(msg, frqst);
194*13675Ssam 		strcat(msg, "\nLAST REQUEST: ");
195*13675Ssam 		strcat(msg, lrqst);
196*13675Ssam 	}
197*13675Ssam 	getargs(frqst, args);
198*13675Ssam 	mailst(args[3], msg, "");
199*13675Ssam 	return;
200*13675Ssam }
201*13675Ssam 
202*13675Ssam 
203*13675Ssam /***
204*13675Ssam  *	sdmail(file, uid)
205*13675Ssam  *
206*13675Ssam  *	sdmail  -  this routine will determine the owner
207*13675Ssam  *	of the file (file), create a message string and
208*13675Ssam  *	call "mailst" to send the cleanup message.
209*13675Ssam  *	This is only implemented for local system
210*13675Ssam  *	mail at this time.
211*13675Ssam  */
212*13675Ssam 
213*13675Ssam sdmail(file, uid)
214*13675Ssam char *file;
215*13675Ssam {
216*13675Ssam 	static struct passwd *pwd;
217*13675Ssam 	struct passwd *getpwuid();
218*13675Ssam 	char mstr[40];
219*13675Ssam 
220*13675Ssam 	sprintf(mstr, "uuclean deleted file %s\n", file);
221*13675Ssam 	if (pwd->pw_uid == uid) {
222*13675Ssam 		mailst(pwd->pw_name, mstr, "");
223*13675Ssam 	return(0);
224*13675Ssam 	}
225*13675Ssam 
226*13675Ssam 	setpwent();
227*13675Ssam 	if ((pwd = getpwuid(uid)) != NULL) {
228*13675Ssam 		mailst(pwd->pw_name, mstr, "");
229*13675Ssam 	}
230*13675Ssam 	return(0);
231*13675Ssam }
232*13675Ssam 
233*13675Ssam cleanup(code)
234*13675Ssam int code;
235*13675Ssam {
236*13675Ssam 	exit(code);
237*13675Ssam }
238