# 2.11BSD#431 - /usr/src/usr.bin/at/atq.c

##### Functions

    countfiles        X
    creation          X
    filewanted        X
    get_mth_day       X
    getid             X
    isowner           X
    main              X
    plastrun          X
    powner            X
    printdate         X
    printjobname      X
    printqueue        X
    usage             X

##### Variables

    copyright         X
    namewanted        X
    nullentry         X
    numentries        X
    queue             X

##### Macros

    ATDIR             X
    LASTFILE          X

       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,"%ld", &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: }

#### Defined functions

countfiles defined in line 160; used 3 times

- in line 74, 145-148(2)

creation defined in line 534; used 2 times

- in line 70, 118

filewanted defined in line 519; used 2 times

- in line 72, 118

get_mth_day defined in line 425; used 2 times

- in line 399, 408

getid defined in line 317; used 1 times

- in line 206

isowner defined in line 258; used 2 times

- in line 181, 239

main defined in line 61; never used
plastrun defined in line 333; used 2 times

- in line 202, 215

powner defined in line 285; used 2 times

- in line 204, 248

printdate defined in line 389; used 1 times

- in line 247

printjobname defined in line 465; used 1 times

- in line 250

printqueue defined in line 195; used 2 times

- in line 73, 153

printrank defined in line 372; used 2 times

- in line 201, 246

usage defined in line 551; used 2 times

- in line 69, 94

#### Defined variables

copyright defined in line 8; never used
mthnames defined in line 49; used 2 times

- in line 364, 413

namewanted defined in line 56; used 4 times

- in line 105, 145-148(2), 234

nullentry defined in line 54; used 1 times

- in line 76

numentries defined in line 55; used 5 times

- in line 118, 140-145(2), 176, 230

queue defined in line 58; used 7 times

- in line 118, 181, 231, 239, 247-250(3)

sccsid defined in line 14; never used

#### Defined macros

ATDIR defined in line 42; used 3 times

- in line 114-120(3)

LASTFILE defined in line 43; used 2 times

- in line 349-350(2)

Last modified: 1987-03-12 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1647 |