1852e9da9Sdist /* 2852e9da9Sdist * Copyright (c) 1983 Regents of the University of California. 3852e9da9Sdist * All rights reserved. The Berkeley software License Agreement 4852e9da9Sdist * specifies the terms and conditions for redistribution. 5852e9da9Sdist */ 6852e9da9Sdist 795d7ed8eSwall #ifndef lint 8852e9da9Sdist char copyright[] = 9852e9da9Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10852e9da9Sdist All rights reserved.\n"; 11852e9da9Sdist #endif not lint 12852e9da9Sdist 13852e9da9Sdist #ifndef lint 14*c7338628Sbostic static char sccsid[] = "@(#)atq.c 5.4 (Berkeley) 04/06/87"; 152d68a685Smckusick #endif not lint 1695d7ed8eSwall 1795d7ed8eSwall /* 1895d7ed8eSwall * 1995d7ed8eSwall * Synopsis: atq [ -c ] [ -n ] [ name ... ] 2095d7ed8eSwall * 2195d7ed8eSwall * 2295d7ed8eSwall * Print the queue of files waiting to be executed. These files 2395d7ed8eSwall * were created by using the "at" command and are located in the 2495d7ed8eSwall * directory "/usr/spool/at". 2595d7ed8eSwall * 2695d7ed8eSwall * 2795d7ed8eSwall * Author: Steve Wall 2895d7ed8eSwall * Computer Systems Research Group 2995d7ed8eSwall * University of California @ Berkeley 3095d7ed8eSwall * 3195d7ed8eSwall */ 3295d7ed8eSwall 3395d7ed8eSwall # include <stdio.h> 3495d7ed8eSwall # include <sys/types.h> 3595d7ed8eSwall # include <sys/file.h> 3695d7ed8eSwall # include <sys/dir.h> 3795d7ed8eSwall # include <sys/stat.h> 3895d7ed8eSwall # include <sys/time.h> 3995d7ed8eSwall # include <pwd.h> 4095d7ed8eSwall # include <ctype.h> 4195d7ed8eSwall 4295d7ed8eSwall # define ATDIR "/usr/spool/at" /* spooling area */ 4395d7ed8eSwall # define LASTFILE "/usr/spool/at/lasttimedone" /* update time record 4495d7ed8eSwall file */ 4595d7ed8eSwall 4695d7ed8eSwall /* 4795d7ed8eSwall * Months of the year 4895d7ed8eSwall */ 4995d7ed8eSwall static char *mthnames[12] = { 5095d7ed8eSwall "Jan","Feb","Mar","Apr","May","Jun","Jul", 5195d7ed8eSwall "Aug","Sep","Oct","Nov","Dec", 5295d7ed8eSwall }; 5395d7ed8eSwall 541ed914fbSmckusick char *nullentry = NULL; /* avoid 'namelist' NULL ptr problems */ 5595d7ed8eSwall int numentries; /* number of entries in spooling area */ 5695d7ed8eSwall int namewanted = 0; /* only print jobs belonging to a 5795d7ed8eSwall certain person */ 5895d7ed8eSwall struct direct **queue; /* the queue itself */ 5995d7ed8eSwall 6095d7ed8eSwall 6195d7ed8eSwall main(argc,argv) 6295d7ed8eSwall int argc; 6395d7ed8eSwall char **argv; 6495d7ed8eSwall { 6595d7ed8eSwall 6695d7ed8eSwall int cflag = 0; /* print in order of creation time */ 6795d7ed8eSwall int nflag = 0; /* just print the number of jobs in 6895d7ed8eSwall queue */ 6995d7ed8eSwall int usage(); /* print usage info and exit */ 7095d7ed8eSwall int creation(); /* sort jobs by date of creation */ 7195d7ed8eSwall int alphasort(); /* sort jobs by date of execution */ 7295d7ed8eSwall int filewanted(); /* should a file be included in queue?*/ 7395d7ed8eSwall int printqueue(); /* print the queue */ 7495d7ed8eSwall int countfiles(); /* count the number of files in queue 7595d7ed8eSwall for a given person */ 761ed914fbSmckusick char **namelist = &nullentry; /* array of specific name(s) requested*/ 7795d7ed8eSwall 7895d7ed8eSwall 7995d7ed8eSwall --argc, ++argv; 8095d7ed8eSwall 8195d7ed8eSwall /* 8295d7ed8eSwall * Interpret command line flags if they exist. 8395d7ed8eSwall */ 8495d7ed8eSwall while (argc > 0 && **argv == '-') { 8595d7ed8eSwall (*argv)++; 8695d7ed8eSwall while (**argv) switch (*(*argv)++) { 8795d7ed8eSwall 8895d7ed8eSwall case 'c' : cflag++; 8995d7ed8eSwall break; 9095d7ed8eSwall 9195d7ed8eSwall case 'n' : nflag++; 9295d7ed8eSwall break; 9395d7ed8eSwall 9495d7ed8eSwall default : usage(); 9595d7ed8eSwall 9695d7ed8eSwall } 9795d7ed8eSwall --argc, ++argv; 9895d7ed8eSwall } 9995d7ed8eSwall 10095d7ed8eSwall /* 10195d7ed8eSwall * If a certain name (or names) is requested, set a pointer to the 10295d7ed8eSwall * beginning of the list. 10395d7ed8eSwall */ 1041ed914fbSmckusick if (argc > 0) { 10595d7ed8eSwall ++namewanted; 10695d7ed8eSwall namelist = argv; 10795d7ed8eSwall } 10895d7ed8eSwall 10995d7ed8eSwall /* 11095d7ed8eSwall * Move to the spooling area and scan the directory, placing the 11195d7ed8eSwall * files in the queue structure. The queue comes back sorted by 11295d7ed8eSwall * execution time or creation time. 11395d7ed8eSwall */ 11495d7ed8eSwall if (chdir(ATDIR) == -1) { 11595d7ed8eSwall perror(ATDIR); 11695d7ed8eSwall exit(1); 11795d7ed8eSwall } 11895d7ed8eSwall if ((numentries = scandir(".",&queue,filewanted, (cflag) ? creation : 11995d7ed8eSwall alphasort)) < 0) { 12095d7ed8eSwall perror(ATDIR); 12195d7ed8eSwall exit(1); 12295d7ed8eSwall } 12395d7ed8eSwall 12495d7ed8eSwall /* 12595d7ed8eSwall * Either print a message stating: 12695d7ed8eSwall * 12795d7ed8eSwall * 1) that the spooling area is empty. 12895d7ed8eSwall * 2) the number of jobs in the spooling area. 12995d7ed8eSwall * 3) the number of jobs in the spooling area belonging to 13095d7ed8eSwall * a certain person. 13195d7ed8eSwall * 4) that the person requested doesn't have any files in the 13295d7ed8eSwall * spooling area. 13395d7ed8eSwall * 13495d7ed8eSwall * or send the queue off to "printqueue" for printing. 13595d7ed8eSwall * 13695d7ed8eSwall * This whole process might seem a bit elaborate, but it's worthwhile 13795d7ed8eSwall * to print some informative messages for the user. 13895d7ed8eSwall * 13995d7ed8eSwall */ 14095d7ed8eSwall if ((numentries == 0) && (!nflag)) { 14195d7ed8eSwall printf("no files in queue.\n"); 14295d7ed8eSwall exit(0); 14395d7ed8eSwall } 14495d7ed8eSwall if (nflag) { 14595d7ed8eSwall printf("%d\n",(namewanted) ? countfiles(namelist) : numentries); 14695d7ed8eSwall exit(0); 14795d7ed8eSwall } 14895d7ed8eSwall if ((namewanted) && (countfiles(namelist) == 0)) { 14995d7ed8eSwall printf("no files for %s.\n", (argc == 1) ? 15095d7ed8eSwall *argv : "specified users"); 15195d7ed8eSwall exit(0); 15295d7ed8eSwall } 15395d7ed8eSwall printqueue(namelist); 15495d7ed8eSwall exit(0); 15595d7ed8eSwall } 15695d7ed8eSwall 15795d7ed8eSwall /* 15895d7ed8eSwall * Count the number of jobs in the spooling area owned by a certain person(s). 15995d7ed8eSwall */ 16095d7ed8eSwall countfiles(namelist) 16195d7ed8eSwall char **namelist; 16295d7ed8eSwall { 16395d7ed8eSwall int i; /* for loop index */ 16495d7ed8eSwall int entryfound; /* found file owned by user(s)*/ 16595d7ed8eSwall int numfiles = 0; /* number of files owned by a 16695d7ed8eSwall certain person(s) */ 16795d7ed8eSwall char **ptr; /* scratch pointer */ 16895d7ed8eSwall 16995d7ed8eSwall 17095d7ed8eSwall /* 17195d7ed8eSwall * For each file in the queue, see if the user(s) own the file. We 17295d7ed8eSwall * have to use "entryfound" (rather than simply incrementing "numfiles") 17395d7ed8eSwall * so that if a person's name appears twice on the command line we 17495d7ed8eSwall * don't double the number of files owned by him/her. 17595d7ed8eSwall */ 17695d7ed8eSwall for (i = 0; i < numentries ; i++) { 17795d7ed8eSwall ptr = namelist; 17895d7ed8eSwall entryfound = 0; 17995d7ed8eSwall 18095d7ed8eSwall while (*ptr) { 181ac264888Swall if (isowner(*ptr,queue[i]->d_name)) 18295d7ed8eSwall ++entryfound; 18395d7ed8eSwall ++ptr; 18495d7ed8eSwall } 18595d7ed8eSwall if (entryfound) 18695d7ed8eSwall ++numfiles; 18795d7ed8eSwall } 18895d7ed8eSwall return(numfiles); 18995d7ed8eSwall } 19095d7ed8eSwall 19195d7ed8eSwall /* 19295d7ed8eSwall * Print the queue. If only jobs belonging to a certain person(s) are requested, 19395d7ed8eSwall * only print jobs that belong to that person(s). 19495d7ed8eSwall */ 19595d7ed8eSwall printqueue(namelist) 19695d7ed8eSwall char **namelist; 19795d7ed8eSwall { 19895d7ed8eSwall int i; /* for loop index */ 19995d7ed8eSwall int rank = 1; /* rank of a job */ 20095d7ed8eSwall int entryfound; /* found file owned by user(s)*/ 20195d7ed8eSwall int printrank(); /* print the rank of a job */ 20295d7ed8eSwall int plastrun(); /* print the last time the 20395d7ed8eSwall spooling area was updated */ 204ac264888Swall int powner(); /* print the name of the owner 205ac264888Swall of the job */ 20695d7ed8eSwall char **ptr; /* scratch pointer */ 20795d7ed8eSwall struct stat stbuf; /* buffer for file stats */ 20895d7ed8eSwall 20995d7ed8eSwall 21095d7ed8eSwall /* 21195d7ed8eSwall * Print the time the spooling area was last modified and the header 21295d7ed8eSwall * for the queue. 21395d7ed8eSwall */ 21495d7ed8eSwall plastrun(); 21595d7ed8eSwall printf(" Rank Execution Date Owner Job # Job Name\n"); 21695d7ed8eSwall 21795d7ed8eSwall /* 21895d7ed8eSwall * Print the queue. If a certain name(s) was requested, print only jobs 21995d7ed8eSwall * belonging to that person(s), otherwise print the entire queue. 22095d7ed8eSwall * Once again, we have to use "entryfound" (rather than simply 22195d7ed8eSwall * comparing each command line argument) so that if a person's name 22295d7ed8eSwall * appears twice we don't print each file owned by him/her twice. 22395d7ed8eSwall * 22495d7ed8eSwall * 22595d7ed8eSwall * "printrank", "printdate", and "printjobname" all take existing 22695d7ed8eSwall * data and display it in a friendly manner. 22795d7ed8eSwall * 22895d7ed8eSwall */ 22995d7ed8eSwall for (i = 0; i < numentries; i++) { 23095d7ed8eSwall if ((stat(queue[i]->d_name, &stbuf)) < 0) { 23195d7ed8eSwall continue; 23295d7ed8eSwall } 23395d7ed8eSwall if (namewanted) { 23495d7ed8eSwall ptr = namelist; 23595d7ed8eSwall entryfound = 0; 23695d7ed8eSwall 23795d7ed8eSwall while (*ptr) { 238ac264888Swall if (isowner(*ptr,queue[i]->d_name)) 23995d7ed8eSwall ++entryfound; 24095d7ed8eSwall ++ptr; 24195d7ed8eSwall } 24295d7ed8eSwall if (!entryfound) 24395d7ed8eSwall continue; 24495d7ed8eSwall } 24595d7ed8eSwall printrank(rank++); 24695d7ed8eSwall printdate(queue[i]->d_name); 247ac264888Swall powner(queue[i]->d_name); 24895d7ed8eSwall printf("%5d",stbuf.st_ino); 24995d7ed8eSwall printjobname(queue[i]->d_name); 25095d7ed8eSwall } 25195d7ed8eSwall ++ptr; 25295d7ed8eSwall } 25395d7ed8eSwall 25495d7ed8eSwall /* 255ac264888Swall * See if "name" owns "job". 25695d7ed8eSwall */ 257ac264888Swall isowner(name,job) 258ac264888Swall char *name; 259ac264888Swall char *job; 26095d7ed8eSwall { 2611ed914fbSmckusick char buf[128]; /* buffer for 1st line of spoolfile 262ac264888Swall header */ 263ac264888Swall FILE *infile; /* I/O stream to spoolfile */ 26495d7ed8eSwall 265ac264888Swall if ((infile = fopen(job,"r")) == NULL) { 266ac264888Swall fprintf(stderr,"Couldn't open spoolfile "); 267ac264888Swall perror(job); 268ac264888Swall return(0); 269ac264888Swall } 27095d7ed8eSwall 2711ed914fbSmckusick if (fscanf(infile,"# owner: %127s%*[^\n]\n",buf) != 1) { 272ac264888Swall fclose(infile); 273ac264888Swall return(0); 27495d7ed8eSwall } 275ac264888Swall 276ac264888Swall fclose(infile); 277ac264888Swall return((strcmp(name,buf) == 0) ? 1 : 0); 27895d7ed8eSwall } 27995d7ed8eSwall 28095d7ed8eSwall /* 281ac264888Swall * Print the owner of the job. This is stored on the first line of the 282ac264888Swall * spoolfile. If we run into trouble getting the name, we'll just print "???". 283ac264888Swall */ 284ac264888Swall powner(file) 285ac264888Swall char *file; 286ac264888Swall { 2871ed914fbSmckusick char owner[10]; /* the owner */ 288ac264888Swall FILE *infile; /* I/O stream to spoolfile */ 289ac264888Swall 290ac264888Swall /* 291ac264888Swall * Open the job file and grab the first line. 292ac264888Swall */ 293ac264888Swall 294ac264888Swall if ((infile = fopen(file,"r")) == NULL) { 295ac264888Swall printf("%-10.9s","???"); 2961ed914fbSmckusick perror(file); 297ac264888Swall return; 298ac264888Swall } 299ac264888Swall 3001ed914fbSmckusick if (fscanf(infile,"# owner: %9s%*[^\n]\n",owner) != 1) { 301ac264888Swall printf("%-10.9s","???"); 302ac264888Swall fclose(infile); 303ac264888Swall return; 304ac264888Swall } 305ac264888Swall 306ac264888Swall fclose(infile); 307ac264888Swall printf("%-10.9s",owner); 308ac264888Swall 309ac264888Swall } 310ac264888Swall 31195d7ed8eSwall /* 31295d7ed8eSwall * Print the time the spooling area was updated. 31395d7ed8eSwall */ 31495d7ed8eSwall plastrun() 31595d7ed8eSwall { 31695d7ed8eSwall struct timeval now; /* time it is right now */ 31795d7ed8eSwall struct timezone zone; /* NOT USED */ 31895d7ed8eSwall struct tm *loc; /* detail of time it is right */ 31995d7ed8eSwall u_long lasttime; /* last update time in seconds 32095d7ed8eSwall since 1/1/70 */ 32195d7ed8eSwall FILE *last; /* file where last update hour 32295d7ed8eSwall is stored */ 32395d7ed8eSwall 32495d7ed8eSwall 32595d7ed8eSwall /* 32695d7ed8eSwall * Open the file where the last update time is stored, and grab the 32795d7ed8eSwall * last update hour. The update time is measured in seconds since 32895d7ed8eSwall * 1/1/70. 32995d7ed8eSwall */ 33095d7ed8eSwall if ((last = fopen(LASTFILE,"r")) == NULL) { 33195d7ed8eSwall perror(LASTFILE); 33295d7ed8eSwall exit(1); 33395d7ed8eSwall } 334*c7338628Sbostic fscanf(last,"%lu",&lasttime); 33595d7ed8eSwall fclose(last); 33695d7ed8eSwall 33795d7ed8eSwall /* 33895d7ed8eSwall * Get a broken down representation of the last update time. 33995d7ed8eSwall */ 34095d7ed8eSwall loc = localtime(&lasttime); 34195d7ed8eSwall 34295d7ed8eSwall /* 34395d7ed8eSwall * Print the time that the spooling area was last updated. 34495d7ed8eSwall */ 34595d7ed8eSwall printf("\n LAST EXECUTION TIME: %s ",mthnames[loc->tm_mon]); 34695d7ed8eSwall printf("%d, 19%d ",loc->tm_mday,loc->tm_year); 34795d7ed8eSwall printf("at %d:%02d\n\n",loc->tm_hour,loc->tm_min); 34895d7ed8eSwall } 34995d7ed8eSwall 35095d7ed8eSwall /* 35195d7ed8eSwall * Print the rank of a job. (I've got to admit it, I stole it from "lpq") 35295d7ed8eSwall */ 35395d7ed8eSwall static 35495d7ed8eSwall printrank(n) 35595d7ed8eSwall { 35695d7ed8eSwall static char *r[] = { 35795d7ed8eSwall "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 35895d7ed8eSwall }; 35995d7ed8eSwall 36095d7ed8eSwall if ((n/10) == 1) 36195d7ed8eSwall printf("%3d%-5s", n,"th"); 36295d7ed8eSwall else 36395d7ed8eSwall printf("%3d%-5s", n, r[n%10]); 36495d7ed8eSwall } 36595d7ed8eSwall 36695d7ed8eSwall /* 36795d7ed8eSwall * Print the date that a job is to be executed. This takes some manipulation 36895d7ed8eSwall * of the file name. 36995d7ed8eSwall */ 37095d7ed8eSwall printdate(filename) 37195d7ed8eSwall char *filename; 37295d7ed8eSwall { 37395d7ed8eSwall int yday = 0; /* day of year file will be 37495d7ed8eSwall executed */ 37595d7ed8eSwall int min = 0; /* min. file will be executed */ 37695d7ed8eSwall int hour = 0; /* hour file will be executed */ 37795d7ed8eSwall int day = 0; /* day file will be executed */ 37895d7ed8eSwall int month = 0; /* month file will be executed*/ 37995d7ed8eSwall int year = 0; /* year file will be executed */ 38095d7ed8eSwall int get_mth_day(); /* convert a day of year to a 38195d7ed8eSwall month and day of month */ 38295d7ed8eSwall char date[18]; /* reformatted execution date */ 38395d7ed8eSwall 38495d7ed8eSwall /* 38595d7ed8eSwall * Pick off the necessary info from the file name and convert the day 38695d7ed8eSwall * of year to a month and day of month. 38795d7ed8eSwall */ 38895d7ed8eSwall sscanf(filename,"%2d.%3d.%2d%2d",&year,&yday,&hour,&min); 38995d7ed8eSwall get_mth_day(year,yday,&month,&day); 39095d7ed8eSwall 39195d7ed8eSwall /* 39295d7ed8eSwall * Format the execution date of a job. 39395d7ed8eSwall */ 39495d7ed8eSwall sprintf(date,"%3s %2d, 19%2d %02d:%02d",mthnames[month], 39595d7ed8eSwall day, year,hour,min); 39695d7ed8eSwall 39795d7ed8eSwall /* 39895d7ed8eSwall * Print the date the job will be executed. 39995d7ed8eSwall */ 40095d7ed8eSwall printf("%-21.18s",date); 40195d7ed8eSwall } 40295d7ed8eSwall 40395d7ed8eSwall /* 40495d7ed8eSwall * Given a day of the year, calculate the month and day of month. 40595d7ed8eSwall */ 40695d7ed8eSwall get_mth_day(year,dayofyear,month,day) 40795d7ed8eSwall int year, dayofyear, *month, *day; 40895d7ed8eSwall 40995d7ed8eSwall { 41095d7ed8eSwall 41195d7ed8eSwall int i = 1; /* for loop index */ 41295d7ed8eSwall int leap; /* are we dealing with a leap 41395d7ed8eSwall year? */ 41495d7ed8eSwall /* Table of the number of days 41595d7ed8eSwall in each month of the year. 41695d7ed8eSwall 41795d7ed8eSwall dofy_tab[1] -- regular year 41895d7ed8eSwall dofy_tab[2] -- leap year 41995d7ed8eSwall */ 42095d7ed8eSwall 42195d7ed8eSwall static int dofy_tab[2][13] = { 42295d7ed8eSwall { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 42395d7ed8eSwall { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 42495d7ed8eSwall }; 42595d7ed8eSwall 42695d7ed8eSwall /* 42795d7ed8eSwall * Are we dealing with a leap year? 42895d7ed8eSwall */ 42995d7ed8eSwall leap = ((year%4 == 0 && year%100 != 0) || year%100 == 0); 43095d7ed8eSwall 43195d7ed8eSwall /* 43295d7ed8eSwall * Calculate the month of the year and day of the month. 43395d7ed8eSwall */ 43495d7ed8eSwall while (dayofyear >= dofy_tab[leap][i]) { 43595d7ed8eSwall dayofyear -= dofy_tab[leap][i++]; 43695d7ed8eSwall ++(*month); 43795d7ed8eSwall } 43895d7ed8eSwall *day = (dayofyear + 1); 43995d7ed8eSwall } 44095d7ed8eSwall 44195d7ed8eSwall /* 44295d7ed8eSwall * Print a job name. If the old "at" has been used to create the spoolfile, 44395d7ed8eSwall * the three line header that the new version of "at" puts in the spoolfile. 44495d7ed8eSwall * Thus, we just print "???". 44595d7ed8eSwall */ 44695d7ed8eSwall printjobname(file) 44795d7ed8eSwall char *file; 44895d7ed8eSwall { 449ac264888Swall char *ptr; /* scratch pointer */ 4501ed914fbSmckusick char jobname[28]; /* the job name */ 45195d7ed8eSwall FILE *filename; /* job file in spooling area */ 45295d7ed8eSwall 45395d7ed8eSwall /* 454ac264888Swall * Open the job file and grab the second line. 45595d7ed8eSwall */ 45695d7ed8eSwall printf(" "); 45795d7ed8eSwall 45895d7ed8eSwall if ((filename = fopen(file,"r")) == NULL) { 45995d7ed8eSwall printf("%.27s\n", "???"); 4601ed914fbSmckusick perror(file); 46195d7ed8eSwall return; 46295d7ed8eSwall } 463ac264888Swall /* 4641ed914fbSmckusick * Skip over the first line. 465ac264888Swall */ 4661ed914fbSmckusick fscanf(filename,"%*[^\n]\n"); 467ac264888Swall 468ac264888Swall /* 469ac264888Swall * Now get the job name. 470ac264888Swall */ 4711ed914fbSmckusick if (fscanf(filename,"# jobname: %27s%*[^\n]\n",jobname) != 1) { 47295d7ed8eSwall printf("%.27s\n", "???"); 47395d7ed8eSwall fclose(filename); 47495d7ed8eSwall return; 47595d7ed8eSwall } 47695d7ed8eSwall fclose(filename); 47795d7ed8eSwall 47895d7ed8eSwall /* 47995d7ed8eSwall * Put a pointer at the begining of the line and remove the basename 48095d7ed8eSwall * from the job file. 48195d7ed8eSwall */ 482ac264888Swall ptr = jobname; 483ac264888Swall if ((ptr = (char *)rindex(jobname,'/')) != 0) 484ac264888Swall ++ptr; 48595d7ed8eSwall else 486ac264888Swall ptr = jobname; 48795d7ed8eSwall 488ac264888Swall if (strlen(ptr) > 23) 489ac264888Swall printf("%.23s ...\n",ptr); 490ac264888Swall else 491ac264888Swall printf("%.27s\n",ptr); 49295d7ed8eSwall } 49395d7ed8eSwall 49495d7ed8eSwall /* 49595d7ed8eSwall * Do we want to include a file in the queue? (used by "scandir") We are looking 49695d7ed8eSwall * for files with following syntax: yy.ddd.hhhh. so the test is made to see if 49795d7ed8eSwall * the file name has three dots in it. This test will suffice since the only 49895d7ed8eSwall * other files in /usr/spool/at don't have any dots in their name. 49995d7ed8eSwall */ 50095d7ed8eSwall filewanted(direntry) 50195d7ed8eSwall struct direct *direntry; 50295d7ed8eSwall { 50395d7ed8eSwall int numdot = 0; 50495d7ed8eSwall char *filename; 50595d7ed8eSwall 50695d7ed8eSwall filename = direntry->d_name; 50795d7ed8eSwall while (*filename) 50895d7ed8eSwall numdot += (*(filename++) == '.'); 50995d7ed8eSwall return(numdot == 3); 51095d7ed8eSwall } 51195d7ed8eSwall 51295d7ed8eSwall /* 51395d7ed8eSwall * Sort files by time of creation. (used by "scandir") 51495d7ed8eSwall */ 51595d7ed8eSwall creation(d1, d2) 51695d7ed8eSwall struct direct **d1, **d2; 51795d7ed8eSwall { 51895d7ed8eSwall struct stat stbuf1, stbuf2; 51995d7ed8eSwall 52095d7ed8eSwall if (stat((*d1)->d_name,&stbuf1) < 0) 52195d7ed8eSwall return(1); 52295d7ed8eSwall 52395d7ed8eSwall if (stat((*d2)->d_name,&stbuf2) < 0) 52495d7ed8eSwall return(1); 52595d7ed8eSwall 52695d7ed8eSwall return(stbuf1.st_ctime < stbuf2.st_ctime); 52795d7ed8eSwall } 52895d7ed8eSwall 52995d7ed8eSwall /* 53095d7ed8eSwall * Print usage info and exit. 53195d7ed8eSwall */ 53295d7ed8eSwall usage() 53395d7ed8eSwall { 53495d7ed8eSwall fprintf(stderr,"usage: atq [-c] [-n] [name ...]\n"); 53595d7ed8eSwall exit(1); 53695d7ed8eSwall } 537