* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)atq.c 5.1 (Berkeley) 6/6/85";
* Synopsis: atq [ -c ] [ -n ] [ name ... ]
* Print the queue of files waiting to be executed. These files
* were created by using the "at" command and are located in the
* directory "/usr/spool/at".
* Computer Systems Research Group
* University of California @ Berkeley
# define ATDIR "/usr/spool/at" /* spooling area */
# define LASTFILE "/usr/spool/at/lasttimedone" /* update time record
static char *mthnames
[12] = {
"Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec",
int numentries
; /* number of entries in spooling area */
int namewanted
= 0; /* only print jobs belonging to a
struct direct
**queue
; /* the queue itself */
int cflag
= 0; /* print in order of creation time */
int nflag
= 0; /* just print the number of jobs in
int usage(); /* print usage info and exit */
int creation(); /* sort jobs by date of creation */
int alphasort(); /* sort jobs by date of execution */
int filewanted(); /* should a file be included in queue?*/
int printqueue(); /* print the queue */
int countfiles(); /* count the number of files in queue
char **namelist
; /* array of specific name(s) requested*/
* Interpret command line flags if they exist.
while (argc
> 0 && **argv
== '-') {
while (**argv
) switch (*(*argv
)++) {
* If a certain name (or names) is requested, set a pointer to the
* Move to the spooling area and scan the directory, placing the
* files in the queue structure. The queue comes back sorted by
* execution time or creation time.
if (chdir(ATDIR
) == -1) {
if ((numentries
= scandir(".",&queue
,filewanted
, (cflag
) ? creation
:
* Either print a message stating:
* 1) that the spooling area is empty.
* 2) the number of jobs in the spooling area.
* 3) the number of jobs in the spooling area belonging to
* 4) that the person requested doesn't have any files in the
* or send the queue off to "printqueue" for printing.
* This whole process might seem a bit elaborate, but it's worthwhile
* to print some informative messages for the user.
if ((numentries
== 0) && (!nflag
)) {
printf("no files in queue.\n");
printf("%d\n",(namewanted
) ? countfiles(namelist
) : numentries
);
if ((namewanted
) && (countfiles(namelist
) == 0)) {
printf("no files for %s.\n", (argc
== 1) ?
*argv
: "specified users");
* Count the number of jobs in the spooling area owned by a certain person(s).
int i
; /* for loop index */
int entryfound
; /* found file owned by user(s)*/
int numfiles
= 0; /* number of files owned by a
char **ptr
; /* scratch pointer */
* For each file in the queue, see if the user(s) own the file. We
* have to use "entryfound" (rather than simply incrementing "numfiles")
* so that if a person's name appears twice on the command line we
* don't double the number of files owned by him/her.
for (i
= 0; i
< numentries
; i
++) {
if (isowner(*ptr
,queue
[i
]->d_name
))
* Print the queue. If only jobs belonging to a certain person(s) are requested,
* only print jobs that belong to that person(s).
int i
; /* for loop index */
int rank
= 1; /* rank of a job */
int entryfound
; /* found file owned by user(s)*/
int printrank(); /* print the rank of a job */
int plastrun(); /* print the last time the
spooling area was updated */
int powner(); /* print the name of the owner
int getid(); /* get uid of a person */
char **ptr
; /* scratch pointer */
struct stat stbuf
; /* buffer for file stats */
* Print the time the spooling area was last modified and the header
printf(" Rank Execution Date Owner Job # Job Name\n");
* Print the queue. If a certain name(s) was requested, print only jobs
* belonging to that person(s), otherwise print the entire queue.
* Once again, we have to use "entryfound" (rather than simply
* comparing each command line argument) so that if a person's name
* appears twice we don't print each file owned by him/her twice.
* "printrank", "printdate", and "printjobname" all take existing
* data and display it in a friendly manner.
for (i
= 0; i
< numentries
; i
++) {
if ((stat(queue
[i
]->d_name
, &stbuf
)) < 0) {
if (isowner(*ptr
,queue
[i
]->d_name
))
printdate(queue
[i
]->d_name
);
powner(queue
[i
]->d_name
);
printf("%5d",stbuf
.st_ino
);
printjobname(queue
[i
]->d_name
);
* See if "name" owns "job".
char buf
[30]; /* buffer for 1st line of spoolfile
FILE *infile
; /* I/O stream to spoolfile */
if ((infile
= fopen(job
,"r")) == NULL
) {
fprintf(stderr
,"Couldn't open spoolfile");
if (fscanf(infile
,"# owner: %s\n",buf
) != 1) {
return((strcmp(name
,buf
) == 0) ? 1 : 0);
* Print the owner of the job. This is stored on the first line of the
* spoolfile. If we run into trouble getting the name, we'll just print "???".
char owner
[80]; /* the owner */
FILE *infile
; /* I/O stream to spoolfile */
* Open the job file and grab the first line.
if ((infile
= fopen(file
,"r")) == NULL
) {
if (fscanf(infile
,"# owner: %s",owner
) != 1) {
* Get the uid of a person using his/her login name. Return -1 if no
* such account name exists.
struct passwd
*pwdinfo
; /* password info structure */
if ((pwdinfo
= getpwnam(name
)) == 0)
* Print the time the spooling area was updated.
struct timeval now
; /* time it is right now */
struct timezone zone
; /* NOT USED */
struct tm
*loc
; /* detail of time it is right */
u_long lasttime
; /* last update time in seconds
FILE *last
; /* file where last update hour
* Open the file where the last update time is stored, and grab the
* last update hour. The update time is measured in seconds since
if ((last
= fopen(LASTFILE
,"r")) == NULL
) {
fscanf(last
,"%d",(u_long
) &lasttime
);
* Get a broken down representation of the last update time.
loc
= localtime(&lasttime
);
* Print the time that the spooling area was last updated.
printf("\n LAST EXECUTION TIME: %s ",mthnames
[loc
->tm_mon
]);
printf("%d, 19%d ",loc
->tm_mday
,loc
->tm_year
);
printf("at %d:%02d\n\n",loc
->tm_hour
,loc
->tm_min
);
* Print the rank of a job. (I've got to admit it, I stole it from "lpq")
"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
printf("%3d%-5s", n
,"th");
printf("%3d%-5s", n
, r
[n
%10]);
* Print the date that a job is to be executed. This takes some manipulation
int yday
= 0; /* day of year file will be
int min
= 0; /* min. file will be executed */
int hour
= 0; /* hour file will be executed */
int day
= 0; /* day file will be executed */
int month
= 0; /* month file will be executed*/
int year
= 0; /* year file will be executed */
int get_mth_day(); /* convert a day of year to a
month and day of month */
char date
[18]; /* reformatted execution date */
* Pick off the necessary info from the file name and convert the day
* of year to a month and day of month.
sscanf(filename
,"%2d.%3d.%2d%2d",&year
,&yday
,&hour
,&min
);
get_mth_day(year
,yday
,&month
,&day
);
* Format the execution date of a job.
sprintf(date
,"%3s %2d, 19%2d %02d:%02d",mthnames
[month
],
* Print the date the job will be executed.
* Given a day of the year, calculate the month and day of month.
get_mth_day(year
,dayofyear
,month
,day
)
int year
, dayofyear
, *month
, *day
;
int i
= 1; /* for loop index */
int leap
; /* are we dealing with a leap
/* Table of the number of days
in each month of the year.
dofy_tab[1] -- regular year
static int dofy_tab
[2][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
* Are we dealing with a leap year?
leap
= ((year
%4 == 0 && year
%100 != 0) || year
%100 == 0);
* Calculate the month of the year and day of the month.
while (dayofyear
>= dofy_tab
[leap
][i
]) {
dayofyear
-= dofy_tab
[leap
][i
++];
* Print a job name. If the old "at" has been used to create the spoolfile,
* the three line header that the new version of "at" puts in the spoolfile.
* Thus, we just print "???".
char *ptr
; /* scratch pointer */
char jobname
[80]; /* the job name */
FILE *filename
; /* job file in spooling area */
* Open the job file and grab the second line.
if ((filename
= fopen(file
,"r")) == NULL
) {
printf("%.27s\n", "???");
* We'll yank the first line into the buffer temporarily.
fgets(jobname
,80,filename
);
if (fscanf(filename
,"# jobname: %s",jobname
) != 1) {
printf("%.27s\n", "???");
* Put a pointer at the begining of the line and remove the basename
if ((ptr
= (char *)rindex(jobname
,'/')) != 0)
printf("%.23s ...\n",ptr
);
* Do we want to include a file in the queue? (used by "scandir") We are looking
* for files with following syntax: yy.ddd.hhhh. so the test is made to see if
* the file name has three dots in it. This test will suffice since the only
* other files in /usr/spool/at don't have any dots in their name.
filename
= direntry
->d_name
;
numdot
+= (*(filename
++) == '.');
* Sort files by time of creation. (used by "scandir")
struct direct
**d1
, **d2
;
struct stat stbuf1
, stbuf2
;
if (stat((*d1
)->d_name
,&stbuf1
) < 0)
if (stat((*d2
)->d_name
,&stbuf2
) < 0)
return(stbuf1
.st_ctime
< stbuf2
.st_ctime
);
* Print usage info and exit.
fprintf(stderr
,"usage: atq [-c] [-n] [name ...]\n");