⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char	*sccsid = "@(#)at.c	4.1	(ULTRIX)	7/17/90";#endif/* * at time mon day * at time wday * at time wday 'week' * at -r job... * at -l [job...] * * at.c * * Modification history * * 05 Wed Jun 06 1990, Grant W. Sullivan *	inserted "extern" in front of declaration on "environ", to match *	  execl(3) and for RISC linkages * * 04 Tue Sep 13 13:18:33 EDT 1988, Gary A. Gaudet *	-r checks for valid job id and ownership *	-l checks for valid job id * * 03 Mon Aug 15 12:08:27 EDT 1988, Gary A. Gaudet *	put suid root back in. * * 02	09-Jun-88 - Mark Parenti *	Changed signal handlers to void. * * 01	17-Feb-88 - Gary A. Gaudet *	X/OPEN *	- Added -l and -r options *	- Added at.allow and at.deny * */#include <stdio.h>#include <ctype.h>#include <errno.h>#include <pwd.h>#include <strings.h>#include <signal.h>#include <sys/file.h>#include <sys/time.h>#include <sys/types.h>#include <sys/dir.h>#include <sys/stat.h>#define HOUR 100#define HALFDAY	(12*HOUR)#define DAY	(24*HOUR)#define FALSE	0#define TRUE	1#define THISDAY		"/usr/var/spool/at"#define AT_ALLOW	"/usr/var/spool/at/at.allow"#define AT_DENY		"/usr/var/spool/at/at.deny"#define USAGE		"USAGE:\t%s time [date] [file]\n\t%s -l [job...]\n\t%s -r job...\n"char *days[] = {	"sunday",	"monday",	"tuesday",	"wednesday",	"thursday",	"friday",	"saturday",};struct monstr {	char *mname; 	int mlen;} months[] = {	{ "january", 31 },	{ "february", 28 },	{ "march", 31 },	{ "april", 30 },	{ "may", 31 },	{ "june", 30 },	{ "july", 31 },	{ "august", 31 },	{ "september", 30 },	{ "october", 31 },	{ "november", 30 },	{ "december", 31 },	{ 0, 0 },};char	fname[100];int	utime;  /* requested time in grains */int	now;	/* when is it */int	uday; /* day of year to be done */int	uyear; /* year */int	today; /* day of year today */FILE	*file;FILE	*ifile;extern	char	**environ;char	*prefix();char    *getenv();int	getopt();FILE	*popen();extern char *sys_errlist[];	/* list of error messages...see perror(3) */main(argc, argv)char **argv;{	extern int optind;	/* used by getopt(3) */	extern char *optarg;	/* used by getopt(3) */	int	lflag;		/* user wants to list job(s) */	int	rflag;		/* user wants to remove job(s) */	int	errflag;	/* user wants to try again :-) */	int	uid;		/* to check uid to job's uid */	DIR	*dirp;		/* for reading the at spool directory */	struct direct *dp;	/* for holding at spool entry */	struct stat sbuf;	/* stat(2) buffer */	extern void onintr();	register c;	char pwbuf[100];	FILE *pwfil;	int larg;	char *tmp;	rflag = lflag = errflag = 0;/* *	straight from getopt(3) manual page */	while ((c = getopt (argc, argv, "lr")) != EOF)		switch (c) {		case 'l':	/* user wants to list job(s) */			if (rflag) {				errflag++;			} else {				lflag++;			}			break;		case 'r':	/* user wants to remove job(s) */			if (lflag) {				errflag++;			} else {				rflag++;			}			break;		case '?':			errflag++;		}	if (errflag) {		(void) fprintf (stderr, USAGE, argv[0], argv[0], argv[0]);		exit (-1);	}	if (lflag) {		if (chdir (THISDAY)) {			(void) fprintf(stderr, "%s: Cannot change directory to %s\n", argv[0], THISDAY, errno);			exit (errno);		} else {			if (optind >= argc) {				dirp = opendir(THISDAY);				for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {					if (valid_job_id (dp->d_name)) {						stat (dp->d_name, &sbuf);						if (getuid() == sbuf.st_uid) {							(void) fprintf(stderr, "%s\n", dp->d_name);						}					}				}			} else {				for ( ; optind < argc; optind++) {					if (valid_job_id (argv[optind])) {						if (access (argv[optind], F_OK)) {							errflag++;							if (errno == ENOENT) {								(void) fprintf(stderr, "%s: %s: No such job\n", argv[0],										argv[optind]);							} else {								(void) fprintf(stderr, "%s: %s: Cannot access\n", argv[0],										argv[optind]);							}						} else {							(void) fprintf(stderr, "%s\n", argv[optind]);						}					} else {						errflag++;						(void) fprintf(stderr, "%s: %s: Invalid job id\n", argv[0], argv[optind]);					}				}			}		}	} else if (rflag) {		if (optind < argc) {/* *			cd to at spool directory */			if (chdir (THISDAY)) {				(void) fprintf(stderr, "%s: %s: Cannot cd to %s\n", argv[0], THISDAY, sys_errlist[errno]);				exit (errno);			} else {/* *				remove loop for each job */				for ( ; optind < argc; optind++) {/* *					check for valid job id */					if (valid_job_id (argv[optind])) {/* *						get job owner */						if (stat (argv[optind], &sbuf)) {							errflag++;							if (errno == ENOENT) {								(void) fprintf(stderr, "%s: %s: No such job\n",										argv[0], argv[optind]);							} else {								(void) fprintf(stderr, "%s: %s: Cannot stat: %s\n",										argv[0], argv[optind],										sys_errlist[errno]);							}						} else {/* *							user must be root or job owner */							if (!(uid = getuid()) || uid == sbuf.st_uid) {/* *								remove job */								if (unlink (argv[optind])) {									errflag++;									(void) fprintf(stderr,											"%s: %s: Cannot unlink: %s\n",											argv[0], argv[optind],											sys_errlist[errno]);								}							} else {								errflag++;								(void) fprintf(stderr, "%s: %s: Not owner\n", argv[0],										argv[optind]);							}						}					} else {						errflag++;						(void) fprintf(stderr, "%s: %s: Invalid job id\n", argv[0], argv[optind]);					}				}			}		} else {			(void) fprintf (stderr, USAGE, argv[0], argv[0], argv[0]);			exit (-2);		}	} else if (getuid () == 0 || allow() || (access (AT_ALLOW, F_OK) && errno == ENOENT && !deny())) {		/* argv[1] is the user's time: e.g.,  3AM */		/* argv[2] is a month name or day of week */		/* argv[3] is day of month or 'week' */		/* another argument might be an input file */		if (argc < 2) {			(void) fprintf(stderr, "at: arg count\n");			exit(-3);		}		makeutime(argv[1]);		larg = makeuday(argc,argv)+1;		if (uday==today && larg<=2 && utime<=now)			uday++;		if (uday < today)			uyear++;		c = uyear%4==0? 366: 365;		if (uday >= c) {			uday -= c;			uyear++;		}		filename(THISDAY, uyear, uday, utime);		/* Create file, then change UIDS */		close(creat(fname,0644));		chown(fname,getuid(),getgid());		setuid(getuid());		ifile = stdin;		if (argc > larg)			ifile = fopen(argv[larg], "r");		if (ifile == NULL) {			perror(argv[larg]);			exit(errno);		}		if (signal(SIGINT, SIG_IGN) != SIG_IGN)			signal(SIGINT, onintr);		file = fopen(fname, "w");		if (file == NULL) {			(void) fprintf(stderr, "at: cannot open memo file\n");			exit(errno);		}		if ((pwfil = popen("pwd", "r")) == NULL) {			(void) fprintf(stderr, "at: can't execute pwd\n");			exit(errno);		}		fgets(pwbuf, 100, pwfil);		pclose(pwfil);		(void) fprintf(file, "cd %s", pwbuf);		c = umask(0);		umask(c);		(void) fprintf(file, "umask %.1o\n", c);		if (environ) {			char **ep = environ;			while(*ep)			{				char *cp;				for (tmp = *ep, cp = "TERMCAP"; *tmp==*cp; tmp++,cp++);				if (*cp == 0 && *tmp== '=') {					ep++;					continue;				}				for(tmp = *ep ; *tmp != '=' ; tmp++) putc(*tmp,file);				putc('=', file);				putc('\'', file);				for (tmp++; *tmp; tmp++) {					if (*tmp == '\'')						fputs("'\\''", file);					else						putc(*tmp, file);				}				putc('\'', file);				(void) fprintf(file, "\nexport ");				for(tmp = *ep ; *tmp != '=' ; tmp++) putc(*tmp,file);				putc('\n',file);				ep++;			}		}		/*		 * see if the SHELL variable in the current enviroment is /bin/csh		 * and in that case, use the csh as the shell		 */		tmp = getenv("SHELL");		if (strcmp(tmp+strlen(tmp)-3, "csh") == 0)			(void) fprintf(file, "%s %s\n", tmp, "<< 'xxFUNNYxx'");		while((c = getc(ifile)) != EOF) {			putc(c, file);		}		if (strcmp(tmp+strlen(tmp)-3, "csh") == 0)			(void) fprintf(file, "%s\n", "xxFUNNYxx");		(void) fprintf(stderr, "%s\n", strrchr (fname, '/') + 1);	/* print the job number */		exit(0);	} else {		(void) fprintf(stderr, "%s: Privilege denied\n", argv[0]);		exit (-4);	}	return (errflag);	/* errflag is 0 is no errors */}/* * ALLOW - is the user allowed to use at */allow(){	struct passwd *user;	FILE *fd;	char bufr[9];	if ((fd = fopen (AT_ALLOW, "r")) != NULL) {		user = getpwuid (getuid ());		while (fscanf (fd, "%8s", bufr) != EOF) {			if (strncmp (bufr, user->pw_name, 8) == 0) {				fclose (fd);				return (1);			}		}		fclose (fd);	}	return (0);}/* * DENY - is the user denied use of at */deny(){	struct passwd *user;	FILE *fd;	char bufr[9];	if ((fd = fopen (AT_DENY, "r")) != NULL) {		user = getpwuid (getuid ());		while (fscanf (fd, "%8s", bufr) != EOF) {			if (strncmp (bufr, user->pw_name, 8) == 0) {				fclose (fd);				return (1);			}		}		fclose (fd);		return (0);	}	return (1);}makeutime(pp)char *pp; {	register val;	register char *p;	/* p points to a user time */	p = pp;	val = 0;	while(isdigit(*p)) {		val = val*10+(*p++ -'0');	}	if (p-pp < 3)		val *= HOUR;	for (;;) {		switch(*p) {		case ':':			++p;			if (isdigit(*p)) {				if (isdigit(p[1])) {					val +=(10* *p + p[1] - 11*'0');					p += 2;					continue;				}			}			(void) fprintf(stderr, "at: bad time format:\n");			exit(-5);		case 'A':		case 'a':			if (val >= HALFDAY+HOUR)				val = DAY+1;  /* illegal */			if (val >= HALFDAY && val <(HALFDAY+HOUR))				val -= HALFDAY;			break;		case 'P':		case 'p':			if (val >= HALFDAY+HOUR)				val = DAY+1;  /* illegal */			if (val < HALFDAY)				val += HALFDAY;			break;		case 'n':		case 'N':			val = HALFDAY;			break;		case 'M':		case 'm':			val = 0;			break;		case '\0':		case ' ':			/* 24 hour time */			if (val == DAY)				val -= DAY;			break;		default:			(void) fprintf(stderr, "at: bad time format\n");			exit(-6);		}		break;	}	if (val < 0 || val >= DAY) {		(void) fprintf(stderr, "at: time out of range\n");		exit(-7);	}	if (val%HOUR >= 60) {		(void) fprintf(stderr, "at: illegal minute field\n");		exit(-8);	}	utime = val;}makeuday(argc,argv)char **argv;{	/* the presumption is that argv[2], argv[3] are either	   month day OR weekday [week].  Returns either 2 or 3 as last	   argument used */	/* first of all, what's today */	long tm;	int found = -1;	char **ps;	struct tm *detail, *localtime();	struct monstr *pt;	time(&tm);	detail = localtime(&tm);	uday = today = detail->tm_yday;	uyear = detail->tm_year;	now = detail->tm_hour*100+detail->tm_min;	if (argc<=2)		return(1);	/* is the next argument a month name ? */	for (pt=months; pt->mname; pt++) {		if (prefix(argv[2], pt->mname)) {			if (found<0)				found = pt-months;			else {				(void) fprintf(stderr, "at: ambiguous month\n");				exit(-9);			}		}	}	if (found>=0) {		if (argc<=3)			return(2);		uday = atoi(argv[3]) - 1;		if (uday<0) {			(void) fprintf(stderr, "at: illegal day\n");			exit(-10);		}		while(--found>=0)			uday += months[found].mlen;		if (detail->tm_year%4==0 && uday>59)			uday += 1;		return(3);	}	/* not a month, try day of week */	found = -1;	for (ps=days; ps<days+7; ps++) {		if (prefix(argv[2], *ps)) {			if (found<0)				found = ps-days;			else {				(void) fprintf(stderr, "at: ambiguous day of week\n");				exit(-11);			}		}	}	if (found<0)		return(1);	/* find next day of this sort */	uday = found - detail->tm_wday;	if (uday<=0)		uday += 7;	uday += today;	if (argc>3 && strcmp("week", argv[3])==0) {		uday += 7;		return(3);	}	return(2);}char *prefix(begin, full)char *begin, *full;{	int c;	while (c = *begin++) {		if (isupper(c))			c = tolower(c);		if (*full != c)			return(0);		else			full++;	}	return(full);}filename(dir, y, d, t)char *dir;{	register i;	for (i=0; ; i += 53) {		(void) sprintf(fname, "%s/%02d.%03d.%04d.%02d", dir, y, d, t,		   (getpid()+i)%100);		if (access(fname, 0) == -1)			return;	}}voidonintr(){	unlink(fname);	exit(-12);}/* * VALID_JOB_ID - returns true if the string is "%02d.%03d.%04d.%02d" */intvalid_job_id (s)char *s;{	if (isdigit (*s) && isdigit (*++s) && *++s == '.' && isdigit (*++s) && isdigit (*++s) && isdigit (*++s)			&& *++s == '.' && isdigit (*++s) && isdigit (*++s) && isdigit (*++s) && isdigit (*++s)			&& *++s == '.' && isdigit (*++s) && isdigit (*++s) && *++s == NULL) {		return (TRUE);	}	return (FALSE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -