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

unix.superglobalmegacorp.com

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