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