rsalz@bbn.com (Rich Salz) (03/02/88)
Submitted-by: Roger Southwick <dadla.TEK.COM!rogers> Posting-number: Volume 13, Issue 75 Archive-name: atl [ Short program that fills a gap nicely. --r$ ] Upon getting 4.3BSD, we found the Berkeley had come up with a nice new version of 'at', which allowed listing the queue and job removal. One thing was missing, a way for the user to examine their job in the queue. Well here it is. I call it 'atl'. -Roger (rogers@dadla.tek.com) # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # Makefile atl.1 atl.c echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' BINDIR = /usr/local MANDIR = /usr/manl/man1 atl : atl.c cc -O -s -o atl atl.c install : $(BINDIR)/atl $(MANDIR)/atl.1 $(BINDIR)/atl : atl install -c -o daemon -g daemon -m 4711 atl $(BINDIR) $(MANDIR)/atl.1 : atl.1 install -c -o daemon -g daemon -m 0644 atl.1 $(MANDIR) clean : rm -f atl //E*O*F Makefile// echo x - atl.1 cat > "atl.1" << '//E*O*F atl.1//' .TH ATL 1 "Local" .SH NAME atl - list a job waiting to be run .SH SYNOPSIS .B "atl job# [ job# ... ] .SH DESCRIPTION .I Atl lists on stdout the contents of the .I job# which is waiting to be run at a later date. These jobs were created with the .IR at (1) command. To obtain the needed .I job#, the user should use the .IR atq (1) command. .PP Only the job's owner (or root) may list the contents of the job. .SH BUGS To be discovered. .SH FILES /usr/spool/at spool area .SH AUTHOR Roger Southwick (rogers@dadla.TEK.COM) .SH "SEE ALSO" at(1), atq(1), atrm(1), cron(8) //E*O*F atl.1// echo x - atl.c cat > "atl.c" << '//E*O*F atl.c//' /*------------------------------------------------------------- The atl program By: Roger S. Southwick April 21, 1986 This program lists the jobs in the /usr/spool/at directory which belong to him. usage: atl job# [job#....] The job# is the job number reported by atq. (This turns out to be the inode number of the file, but we don't tell the user that!) --------------------------------------------------------------- * * MODIFICATION HISTORY: * * $Log: atl.c,v $ * Revision 1.2 86/04/21 16:45:36 rogers * Fixed so that the user may be su'ed to * the file's owner. (Definable). * * Revision 1.1 86/04/21 15:15:21 rogers * Initial revision * * -------------------------------------------------------------*/ #ifndef lint static char *RCSid = "$Header: atl.c,v 1.2 86/04/21 16:45:36 rogers Exp $"; #endif #define ATDIR "/usr/spool/at" /* * Define STRICT if you require the user to be logged in * Without this, being su'ed will work. */ /* #define STRICT /* Strict login required */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> #include <pwd.h> #include <ctype.h> extern char *sys_errlist[]; extern int errno; #define ERROR sys_errlist[errno] char *myname = NULL; FILE *fp = NULL; main(argc, argv) int argc; char *argv[]; { DIR *opendir(); struct direct *readdir(); int chdir(), stat(), sscanf(); register DIR *dirp; register struct direct *dp; register int i; int job; struct stat stb; if(chdir(ATDIR) == -1){ (void)fprintf(stderr,"atl: could not chdir %s - %s\n", ATDIR, ERROR); exit(1); } if(argc < 2){ (void)fprintf(stderr, "usage: atl job# [job#....]\n"); exit(1); } whoami(); if((dirp = opendir(".")) == NULL){ (void)fprintf(stderr,"atl: could not opendir(%s)\n", ATDIR); exit(1); } for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)){ if(dp->d_ino == 0) continue; if(strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0) continue; if(!isdigit(dp->d_name[0])) continue; if(stat(dp->d_name, &stb) == -1){ (void)fprintf(stderr,"atl: could not stat %s/%s - %s\n", ATDIR, dp->d_name, ERROR); exit(1); } if((stb.st_mode & S_IFMT) != S_IFREG) continue; for(i = 1; i < argc; i++){ if(sscanf(argv[i], "%d", &job) != 1){ (void)fprintf(stderr,"atl: job number (%s) must be numeric\n", argv[i]); continue; } if(job < 0){ (void)fprintf(stderr,"atl: job number (%d) must be positive\n", job); continue; } if(job != stb.st_ino) continue; if(notowner(dp->d_name)){ (void)fprintf(stderr, "atl: must be job's owner\n"); continue; } if(argc > 2) (void)printf("\n>>>>>> Job # %d <<<<<<\n", job); output(); } } exit(0); } int myuid; whoami() { #ifdef STRICT char *getlogin(); #endif int getuid(); struct passwd *getpwuid(); register struct passwd *pwd; extern char *myname; extern int myuid; myuid = getuid(); #ifdef STRICT if((myname = getlogin()) == NULL){ if((pwd = getpwuid(myuid)) == NULL){ (void)fprintf(stderr, "atl: Say, who are you, anyway?\n"); exit(1); } myname = pwd->pw_name; } #else if((pwd = getpwuid(myuid)) == NULL){ (void)fprintf(stderr, "atl: Say, who are you, anyway?\n"); exit(1); } myname = pwd->pw_name; #endif } char owner[80]; int notowner(name) register char *name; { FILE *fopen(); int fscanf(); extern char *myname; extern FILE *fp; extern char owner[]; extern myuid; if((fp = fopen(name, "r")) == NULL){ (void)fprintf(stderr,"atl: could not open %s/%s for read\n", ATDIR, name); exit(1); } if(fscanf(fp, "# owner: %s\n", owner) != 1){ (void)fprintf(stderr,"atl: unknown owner %s/%s\n", ATDIR, name); return(1); } if(myuid == 0) return(0); if(strcmp(owner, myname) != 0){ (void)fclose(fp); fp = NULL; return(1); } return(0); } output() { char *fgets(); extern FILE *fp; extern int myuid; extern char owner[]; char buf[BUFSIZ]; if(myuid == 0) (void)printf("# owner: %s\n", owner); while(fgets(buf, BUFSIZ, fp) != NULL) (void)fputs(buf, stdout); (void)fclose(fp); } //E*O*F atl.c// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 17 50 298 Makefile 32 108 573 atl.1 222 526 4262 atl.c 271 684 5133 total !!! wc Makefile atl.1 atl.c | sed 's=[^ ]*/==' | diff -b $temp - exit 0 -- For comp.sources.unix stuff, mail to rsalz@uunet.uu.net.