Annotation of 43BSDReno/usr.bin/at/atq/atq.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)atq.c      5.6 (Berkeley) 5/11/89";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  *
        !            19:  *     Synopsis:  atq [ -c ] [ -n ] [ name ... ]
        !            20:  *
        !            21:  *
        !            22:  *     Print the queue of files waiting to be executed. These files 
        !            23:  *     were created by using the "at" command and are located in the 
        !            24:  *     directory "/usr/spool/at".
        !            25:  *
        !            26:  *
        !            27:  *     Author: Steve Wall
        !            28:  *             Computer Systems Research Group
        !            29:  *             University of California @ Berkeley
        !            30:  *
        !            31:  */
        !            32: 
        !            33: # include <stdio.h>
        !            34: # include <sys/types.h>
        !            35: # include <sys/file.h>
        !            36: # include <sys/dir.h>
        !            37: # include <sys/stat.h>
        !            38: # include <sys/time.h>
        !            39: # include <pwd.h>
        !            40: # include <ctype.h>
        !            41: # include "pathnames.h"
        !            42: 
        !            43: /*
        !            44:  * Months of the year
        !            45:  */
        !            46: static char *mthnames[12] = {
        !            47:        "Jan","Feb","Mar","Apr","May","Jun","Jul",
        !            48:        "Aug","Sep","Oct","Nov","Dec",
        !            49: };
        !            50: 
        !            51: char *nullentry = NULL;                        /* avoid 'namelist' NULL ptr problems */
        !            52: int numentries;                                /* number of entries in spooling area */
        !            53: int namewanted = 0;                    /* only print jobs belonging to a 
        !            54:                                           certain person */
        !            55: struct direct **queue;                 /* the queue itself */
        !            56: 
        !            57: 
        !            58: main(argc,argv)
        !            59: int argc;
        !            60: char **argv;
        !            61: {
        !            62: 
        !            63:        int cflag = 0;                  /* print in order of creation time */
        !            64:        int nflag = 0;                  /* just print the number of jobs in 
        !            65:                                           queue */
        !            66:        int usage();                    /* print usage info and exit */
        !            67:        int creation();                 /* sort jobs by date of creation */
        !            68:        int alphasort();                /* sort jobs by date of execution */
        !            69:        int filewanted();               /* should a file be included in queue?*/
        !            70:        int printqueue();               /* print the queue */
        !            71:        int countfiles();               /* count the number of files in queue
        !            72:                                           for a given person */
        !            73:        char **namelist = &nullentry;   /* array of specific name(s) requested*/
        !            74: 
        !            75: 
        !            76:        --argc, ++argv;
        !            77: 
        !            78:        /*
        !            79:         * Interpret command line flags if they exist.
        !            80:         */
        !            81:        while (argc > 0 && **argv == '-') {
        !            82:                (*argv)++;
        !            83:                while (**argv) switch (*(*argv)++) {
        !            84: 
        !            85:                        case 'c' :      cflag++; 
        !            86:                                        break;
        !            87: 
        !            88:                        case 'n' :      nflag++; 
        !            89:                                        break;
        !            90: 
        !            91:                        default  :      usage();
        !            92: 
        !            93:                }
        !            94:                --argc, ++argv;
        !            95:        }
        !            96: 
        !            97:        /*
        !            98:         * If a certain name (or names) is requested, set a pointer to the
        !            99:         * beginning of the list.
        !           100:         */
        !           101:        if (argc > 0) {
        !           102:                ++namewanted;
        !           103:                namelist = argv;
        !           104:        }
        !           105: 
        !           106:        /*
        !           107:         * Move to the spooling area and scan the directory, placing the
        !           108:         * files in the queue structure. The queue comes back sorted by
        !           109:         * execution time or creation time.
        !           110:         */
        !           111:        if (chdir(_PATH_ATDIR) == -1) {
        !           112:                perror(_PATH_ATDIR);
        !           113:                exit(1);
        !           114:        }
        !           115:        if ((numentries = scandir(".",&queue,filewanted, (cflag) ? creation : 
        !           116:                                alphasort)) < 0) {
        !           117:                perror(_PATH_ATDIR);
        !           118:                exit(1);
        !           119:        }
        !           120: 
        !           121:        /*
        !           122:         * Either print a message stating:
        !           123:         *
        !           124:         *      1) that the spooling area is empty.
        !           125:         *      2) the number of jobs in the spooling area.
        !           126:         *      3) the number of jobs in the spooling area belonging to 
        !           127:         *         a certain person.
        !           128:         *      4) that the person requested doesn't have any files in the
        !           129:         *         spooling area.
        !           130:         *
        !           131:         * or send the queue off to "printqueue" for printing.
        !           132:         *
        !           133:         * This whole process might seem a bit elaborate, but it's worthwhile
        !           134:         * to print some informative messages for the user.
        !           135:         *
        !           136:         */
        !           137:        if ((numentries == 0) && (!nflag)) {
        !           138:                printf("no files in queue.\n");
        !           139:                exit(0);
        !           140:        }
        !           141:        if (nflag) {
        !           142:                printf("%d\n",(namewanted) ? countfiles(namelist) : numentries);
        !           143:                exit(0);
        !           144:        }
        !           145:        if ((namewanted) && (countfiles(namelist) == 0)) {
        !           146:                printf("no files for %s.\n", (argc == 1) ?
        !           147:                                        *argv : "specified users");
        !           148:                exit(0);
        !           149:        }
        !           150:        printqueue(namelist);
        !           151:        exit(0);
        !           152: }
        !           153: 
        !           154: /*
        !           155:  * Count the number of jobs in the spooling area owned by a certain person(s).
        !           156:  */
        !           157: countfiles(namelist)
        !           158: char **namelist;
        !           159: {
        !           160:        int i;                                  /* for loop index */
        !           161:        int entryfound;                         /* found file owned by user(s)*/
        !           162:        int numfiles = 0;                       /* number of files owned by a
        !           163:                                                   certain person(s) */
        !           164:        char **ptr;                             /* scratch pointer */
        !           165: 
        !           166: 
        !           167:        /*
        !           168:         * For each file in the queue, see if the user(s) own the file. We
        !           169:         * have to use "entryfound" (rather than simply incrementing "numfiles")
        !           170:         * so that if a person's name appears twice on the command line we 
        !           171:         * don't double the number of files owned by him/her.
        !           172:         */
        !           173:        for (i = 0; i < numentries ; i++) {
        !           174:                ptr = namelist;
        !           175:                entryfound = 0;
        !           176: 
        !           177:                while (*ptr) {
        !           178:                        if (isowner(*ptr,queue[i]->d_name))
        !           179:                                ++entryfound;
        !           180:                        ++ptr;
        !           181:                }
        !           182:                if (entryfound)
        !           183:                        ++numfiles;
        !           184:        }
        !           185:        return(numfiles);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * Print the queue. If only jobs belonging to a certain person(s) are requested,
        !           190:  * only print jobs that belong to that person(s).
        !           191:  */
        !           192: printqueue(namelist)
        !           193: char **namelist;
        !           194: {
        !           195:        int i;                                  /* for loop index */
        !           196:        int rank = 1;                           /* rank of a job */
        !           197:        int entryfound;                         /* found file owned by user(s)*/
        !           198:        int printrank();                        /* print the rank of a job */
        !           199:        int plastrun();                         /* print the last time the 
        !           200:                                                   spooling area was updated */
        !           201:        int powner();                           /* print the name of the owner
        !           202:                                                   of the job */
        !           203:        char **ptr;                             /* scratch pointer */
        !           204:        struct stat stbuf;                      /* buffer for file stats */
        !           205: 
        !           206: 
        !           207:        /*
        !           208:         * Print the time the spooling area was last modified and the header
        !           209:         * for the queue.
        !           210:         */
        !           211:        plastrun();
        !           212:        printf(" Rank     Execution Date     Owner     Job #   Job Name\n");
        !           213: 
        !           214:        /*
        !           215:         * Print the queue. If a certain name(s) was requested, print only jobs
        !           216:         * belonging to that person(s), otherwise print the entire queue.
        !           217:         * Once again, we have to use "entryfound" (rather than simply 
        !           218:         * comparing each command line argument) so that if a person's name 
        !           219:         * appears twice we don't print each file owned by him/her twice.
        !           220:         *
        !           221:         *
        !           222:         * "printrank", "printdate", and "printjobname" all take existing 
        !           223:         * data and display it in a friendly manner.
        !           224:         *
        !           225:         */
        !           226:        for (i = 0; i < numentries; i++) {
        !           227:                if ((stat(queue[i]->d_name, &stbuf)) < 0) {
        !           228:                        continue;
        !           229:                }
        !           230:                if (namewanted) {
        !           231:                        ptr = namelist;
        !           232:                        entryfound = 0;
        !           233: 
        !           234:                        while (*ptr) {
        !           235:                                if (isowner(*ptr,queue[i]->d_name))
        !           236:                                        ++entryfound;
        !           237:                                ++ptr;
        !           238:                        }
        !           239:                        if (!entryfound)
        !           240:                                continue;
        !           241:                }
        !           242:                printrank(rank++);
        !           243:                printdate(queue[i]->d_name);
        !           244:                powner(queue[i]->d_name);
        !           245:                printf("%5d",stbuf.st_ino);
        !           246:                printjobname(queue[i]->d_name);
        !           247:        }
        !           248:        ++ptr;
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * See if "name" owns "job".
        !           253:  */
        !           254: isowner(name,job)
        !           255: char *name;
        !           256: char *job;
        !           257: {
        !           258:        char buf[128];                  /* buffer for 1st line of spoolfile 
        !           259:                                           header */
        !           260:        FILE *infile;                   /* I/O stream to spoolfile */
        !           261: 
        !           262:        if ((infile = fopen(job,"r")) == NULL) {
        !           263:                fprintf(stderr,"Couldn't open spoolfile ");
        !           264:                perror(job);
        !           265:                return(0);
        !           266:        }
        !           267: 
        !           268:        if (fscanf(infile,"# owner: %127s%*[^\n]\n",buf) != 1) {
        !           269:                fclose(infile);
        !           270:                return(0);
        !           271:        }
        !           272: 
        !           273:        fclose(infile);
        !           274:        return((strcmp(name,buf) == 0) ? 1 : 0);
        !           275: }
        !           276: 
        !           277: /*
        !           278:  * Print the owner of the job. This is stored on the first line of the
        !           279:  * spoolfile. If we run into trouble getting the name, we'll just print "???".
        !           280:  */
        !           281: powner(file)
        !           282: char *file;
        !           283: {
        !           284:        char owner[10];                         /* the owner */
        !           285:        FILE *infile;                           /* I/O stream to spoolfile */
        !           286: 
        !           287:        /*
        !           288:         * Open the job file and grab the first line.
        !           289:         */
        !           290: 
        !           291:        if ((infile = fopen(file,"r")) == NULL) {
        !           292:                printf("%-10.9s","???");
        !           293:                perror(file);
        !           294:                return;
        !           295:        }
        !           296: 
        !           297:        if (fscanf(infile,"# owner: %9s%*[^\n]\n",owner) != 1) {
        !           298:                printf("%-10.9s","???");
        !           299:                fclose(infile);
        !           300:                return;
        !           301:        }
        !           302: 
        !           303:        fclose(infile);
        !           304:        printf("%-10.9s",owner);
        !           305: 
        !           306: }
        !           307:        
        !           308: /*
        !           309:  * Print the time the spooling area was updated.
        !           310:  */
        !           311: plastrun()
        !           312: {
        !           313:        struct timeval now;                     /* time it is right now */
        !           314:        struct timezone zone;                   /* NOT USED */
        !           315:        struct tm *loc;                         /* detail of time it is right */
        !           316:        u_long lasttime;                        /* last update time in seconds
        !           317:                                                   since 1/1/70 */
        !           318:        FILE *last;                             /* file where last update hour
        !           319:                                                   is stored */
        !           320: 
        !           321: 
        !           322:        /*
        !           323:         * Open the file where the last update time is stored, and grab the
        !           324:         * last update hour. The update time is measured in seconds since
        !           325:         * 1/1/70.
        !           326:         */
        !           327:        if ((last = fopen(_PATH_LASTFILE,"r")) == NULL) {
        !           328:                perror(_PATH_LASTFILE);
        !           329:                exit(1);
        !           330:        }
        !           331:        fscanf(last,"%lu",&lasttime);
        !           332:        fclose(last);
        !           333: 
        !           334:        /*
        !           335:         * Get a broken down representation of the last update time.
        !           336:         */
        !           337:        loc = localtime(&lasttime);
        !           338: 
        !           339:        /*
        !           340:         * Print the time that the spooling area was last updated.
        !           341:         */
        !           342:        printf("\n LAST EXECUTION TIME: %s ",mthnames[loc->tm_mon]);
        !           343:        printf("%d, 19%d ",loc->tm_mday,loc->tm_year);
        !           344:        printf("at %d:%02d\n\n",loc->tm_hour,loc->tm_min);
        !           345: }
        !           346: 
        !           347: /*
        !           348:  * Print the rank of a job. (I've got to admit it, I stole it from "lpq")
        !           349:  */
        !           350: static 
        !           351: printrank(n)
        !           352: {
        !           353:        static char *r[] = {
        !           354:                "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
        !           355:        };
        !           356: 
        !           357:        if ((n/10) == 1)
        !           358:                 printf("%3d%-5s", n,"th");
        !           359:        else
        !           360:                 printf("%3d%-5s", n, r[n%10]);
        !           361: }
        !           362: 
        !           363: /*
        !           364:  * Print the date that a job is to be executed. This takes some manipulation 
        !           365:  * of the file name.
        !           366:  */
        !           367: printdate(filename)
        !           368: char *filename;
        !           369: {
        !           370:        int yday  =  0;                         /* day of year file will be 
        !           371:                                                   executed */
        !           372:        int min   =  0;                         /* min. file will be executed */
        !           373:        int hour  =  0;                         /* hour file will be executed */
        !           374:        int day   =  0;                         /* day file will be executed */
        !           375:        int month =  0;                         /* month file will be executed*/
        !           376:        int year  =  0;                         /* year file will be executed */
        !           377:        int get_mth_day();                      /* convert a day of year to a
        !           378:                                                   month and day of month */
        !           379:        char date[19];                          /* reformatted execution date */
        !           380: 
        !           381:        /*
        !           382:         * Pick off the necessary info from the file name and convert the day
        !           383:         * of year to a month and day of month.
        !           384:         */
        !           385:        sscanf(filename,"%2d.%3d.%2d%2d",&year,&yday,&hour,&min);
        !           386:        get_mth_day(year,yday,&month,&day);
        !           387: 
        !           388:        /*
        !           389:         * Format the execution date of a job.
        !           390:         */
        !           391:        sprintf(date,"%3s %2d, 19%2d %02d:%02d",mthnames[month],
        !           392:                                                    day, year,hour,min);
        !           393: 
        !           394:        /*
        !           395:         * Print the date the job will be executed.
        !           396:         */
        !           397:        printf("%-21.18s",date);
        !           398: }
        !           399: 
        !           400: /*
        !           401:  * Given a day of the year, calculate the month and day of month.
        !           402:  */
        !           403: get_mth_day(year,dayofyear,month,day)
        !           404: int year, dayofyear, *month, *day;
        !           405: 
        !           406: {
        !           407: 
        !           408:        int i = 1;                              /* for loop index */
        !           409:        int leap;                               /* are we dealing with a leap
        !           410:                                                   year? */
        !           411:                                                /* Table of the number of days 
        !           412:                                                   in each month of the year.
        !           413: 
        !           414:                                                     dofy_tab[1] -- regular year
        !           415:                                                     dofy_tab[2] -- leap year 
        !           416:                                                                              */
        !           417: 
        !           418:        static int dofy_tab[2][13] = {
        !           419:                { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        !           420:                { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        !           421:        };
        !           422: 
        !           423:        /*
        !           424:         * Are we dealing with a leap year?
        !           425:         */
        !           426:        leap = ((year%4 == 0 && year%100 != 0) || year%100 == 0);
        !           427: 
        !           428:        /*
        !           429:         * Calculate the month of the year and day of the month.
        !           430:         */
        !           431:        while (dayofyear >= dofy_tab[leap][i]) {
        !           432:                dayofyear -= dofy_tab[leap][i++];
        !           433:                ++(*month);
        !           434:        }
        !           435:        *day = (dayofyear + 1);
        !           436: }
        !           437:        
        !           438: /*
        !           439:  * Print a job name. If the old "at" has been used to create the spoolfile,
        !           440:  * the three line header that the new version of "at" puts in the spoolfile.
        !           441:  * Thus, we just print "???".
        !           442:  */
        !           443: printjobname(file)
        !           444: char *file;
        !           445: {
        !           446:        char *ptr;                              /* scratch pointer */
        !           447:        char jobname[28];                       /* the job name */
        !           448:        FILE *filename;                         /* job file in spooling area */
        !           449: 
        !           450:        /*
        !           451:         * Open the job file and grab the second line.
        !           452:         */
        !           453:        printf("   ");
        !           454: 
        !           455:        if ((filename = fopen(file,"r")) == NULL) {
        !           456:                printf("%.27s\n", "???");
        !           457:                perror(file);
        !           458:                return;
        !           459:        }
        !           460:        /*
        !           461:         * Skip over the first line.
        !           462:         */
        !           463:        fscanf(filename,"%*[^\n]\n");
        !           464: 
        !           465:        /*
        !           466:         * Now get the job name.
        !           467:         */
        !           468:        if (fscanf(filename,"# jobname: %27s%*[^\n]\n",jobname) != 1) {
        !           469:                printf("%.27s\n", "???");
        !           470:                fclose(filename);
        !           471:                return;
        !           472:        }
        !           473:        fclose(filename);
        !           474: 
        !           475:        /*
        !           476:         * Put a pointer at the begining of the line and remove the basename
        !           477:         * from the job file.
        !           478:         */
        !           479:        ptr = jobname;
        !           480:        if ((ptr = (char *)rindex(jobname,'/')) != 0)
        !           481:                ++ptr;
        !           482:        else 
        !           483:                ptr = jobname;
        !           484: 
        !           485:        if (strlen(ptr) > 23)
        !           486:                printf("%.23s ...\n",ptr);
        !           487:        else
        !           488:                printf("%.27s\n",ptr);
        !           489: }
        !           490: 
        !           491: /*
        !           492:  * Do we want to include a file in the queue? (used by "scandir") We are looking
        !           493:  * for files with following syntax: yy.ddd.hhhh. so the test is made to see if 
        !           494:  * the file name has three dots in it. This test will suffice since the only
        !           495:  * other files in /usr/spool/at don't have any dots in their name.
        !           496:  */
        !           497: filewanted(direntry)
        !           498: struct direct *direntry;
        !           499: {
        !           500:        int numdot = 0;
        !           501:        char *filename;
        !           502: 
        !           503:        filename = direntry->d_name;
        !           504:        while (*filename)
        !           505:                numdot += (*(filename++) == '.');
        !           506:        return(numdot == 3);
        !           507: }
        !           508: 
        !           509: /*
        !           510:  * Sort files by time of creation. (used by "scandir")
        !           511:  */
        !           512: creation(d1, d2)
        !           513: struct direct **d1, **d2;
        !           514: {
        !           515:        struct stat stbuf1, stbuf2;
        !           516: 
        !           517:        if (stat((*d1)->d_name,&stbuf1) < 0)
        !           518:                return(1);
        !           519: 
        !           520:        if (stat((*d2)->d_name,&stbuf2) < 0)
        !           521:                return(1);
        !           522: 
        !           523:        return(stbuf1.st_ctime < stbuf2.st_ctime);
        !           524: }
        !           525:        
        !           526: /*
        !           527:  * Print usage info and exit.
        !           528:  */
        !           529: usage() 
        !           530: {
        !           531:        fprintf(stderr,"usage:  atq [-c] [-n] [name ...]\n");
        !           532:        exit(1);
        !           533: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.