Home | History | Annotate | Download | only in cron
      1    523    basabi /*
      2  11115  Nobutomo  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
      3    523    basabi  * Use is subject to license terms.
      4    523    basabi  */
      5    523    basabi 
      6      0    stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
      7      0    stevel /*	  All Rights Reserved  	*/
      8      0    stevel 
      9      0    stevel 
     10      0    stevel /*
     11      0    stevel  * Copyright (c) 1983 Regents of the University of California.
     12      0    stevel  * All rights reserved.  The Berkeley software License Agreement
     13      0    stevel  * specifies the terms and conditions for redistribution.
     14      0    stevel  */
     15      0    stevel 
     16      0    stevel /*
     17      0    stevel  *
     18      0    stevel  *	Synopsis:  atq [ -c ] [ -n ] [ name ... ]
     19      0    stevel  *
     20      0    stevel  *
     21      0    stevel  *	Print the queue of files waiting to be executed. These files
     22      0    stevel  *	were created by using the "at" command and are located in the
     23      0    stevel  *	directory defined by ATDIR.
     24      0    stevel  */
     25      0    stevel 
     26      0    stevel #include <stdio.h>
     27      0    stevel #include <sys/types.h>
     28      0    stevel #include <sys/file.h>
     29      0    stevel #include <dirent.h>
     30      0    stevel #include <sys/stat.h>
     31      0    stevel #include <time.h>
     32      0    stevel #include <pwd.h>
     33      0    stevel #include <ctype.h>
     34      0    stevel #include <unistd.h>
     35      0    stevel #include <locale.h>
     36      0    stevel #include <errno.h>
     37   4774  as145665 #include <stdlib.h>
     38   4774  as145665 #include <string.h>
     39      0    stevel #include "cron.h"
     40      0    stevel 
     41      0    stevel extern char	*errmsg();
     42      0    stevel extern char	*strchr();
     43      0    stevel 
     44      0    stevel /*
     45      0    stevel  * Months of the year
     46      0    stevel  */
     47      0    stevel static char *mthnames[12] = {
     48      0    stevel 	"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
     49      0    stevel 	"Aug", "Sep", "Oct", "Nov", "Dec",
     50      0    stevel };
     51      0    stevel 
     52      0    stevel int numentries;				/* number of entries in spooling area */
     53      0    stevel int namewanted = 0;			/* print jobs for a certain person */
     54      0    stevel struct dirent **queue;			/* the queue itself */
     55      0    stevel 
     56      0    stevel #define	INVALIDUSER	"you are not a valid user (no entry in /etc/passwd)"
     57      0    stevel #define	NOTALLOWED	"you are not authorized to use at.  Sorry."
     58      0    stevel 
     59    523    basabi static void atabortperror(char *msg);
     60    523    basabi static void atabort(char *msg);
     61    523    basabi static void aterror(char *msg);
     62    523    basabi static void atperror(char *msg);
     63    523    basabi static void usage(void);
     64    523    basabi static void printjobname(char *file);
     65    523    basabi static void printdate(char *filename);
     66    523    basabi static void printrank(int n);
     67    523    basabi static void printqueue(uid_t *uidlist, int nuids);
     68      0    stevel 
     69    523    basabi int
     70    523    basabi main(int argc, char **argv)
     71      0    stevel {
     72      0    stevel 
     73    523    basabi 	struct passwd *pp;	/* password file entry pointer */
     74      0    stevel 	struct passwd pr;
     75    523    basabi 	int i;
     76      0    stevel 	int cflag = 0;			/* print in order of creation time */
     77      0    stevel 	int nflag = 0;			/* just print the number of jobs in */
     78      0    stevel 					/* queue */
     79      0    stevel 	extern int creation();		/* sort jobs by date of creation */
     80      0    stevel 	extern int execution();		/* sort jobs by date of execution */
     81      0    stevel 	int filewanted();		/* should file be included in queue? */
     82      0    stevel 	int countfiles();		/* count the number of files in queue */
     83      0    stevel 					/* for a given person */
     84      0    stevel 	uid_t *uidlist = NULL;		/* array of spec. owner ID(s) requ. */
     85      0    stevel 	int argnum = 0;			/* number of names passed as arg't */
     86      0    stevel 	int badarg = 0;
     87      0    stevel 	char *c;
     88      0    stevel 
     89      0    stevel 
     90      0    stevel 	--argc, ++argv;
     91      0    stevel 
     92      0    stevel 	(void) setlocale(LC_ALL, "");
     93      0    stevel 	pp = getpwuid(getuid());
     94      0    stevel 	pr.pw_uid = pp->pw_uid;
     95      0    stevel 	pr.pw_name = pp->pw_name;
     96      0    stevel 
     97      0    stevel 	if (pp == NULL)
     98      0    stevel 		atabort(INVALIDUSER);
     99      0    stevel 	if (!allowed(pp->pw_name, ATALLOW, ATDENY))
    100      0    stevel 		atabort(NOTALLOWED);
    101      0    stevel 
    102      0    stevel 	/*
    103      0    stevel 	 * Interpret command line flags if they exist.
    104      0    stevel 	 */
    105      0    stevel 	while (argc > 0 && **argv == '-') {
    106      0    stevel 		(*argv)++;
    107      0    stevel 		while (**argv) {
    108      0    stevel 			switch (*(*argv)++) {
    109      0    stevel 
    110      0    stevel 			case 'c' :	cflag++;
    111      0    stevel 					break;
    112      0    stevel 
    113      0    stevel 			case 'n' :	nflag++;
    114      0    stevel 					break;
    115      0    stevel 
    116      0    stevel 			default	 :	usage();
    117      0    stevel 
    118      0    stevel 			}
    119      0    stevel 		}
    120      0    stevel 		--argc, ++argv;
    121      0    stevel 	}
    122      0    stevel 
    123      0    stevel 	/*
    124      0    stevel 	 * If a certain name (or names) is requested, set a pointer to the
    125      0    stevel 	 * beginning of the list.
    126      0    stevel 	 */
    127      0    stevel 	if (argc > 0) {
    128      0    stevel 		++namewanted;
    129      0    stevel 		uidlist = (uid_t *)malloc(argc * sizeof (uid_t));
    130      0    stevel 		if (uidlist == NULL)
    131      0    stevel 			atabortperror("can't allocate list of users");
    132      0    stevel 		for (i = 0; i < argc; i++) {
    133  11115  Nobutomo 			if (cron_admin(pr.pw_name) ||
    134   4774  as145665 			    strcmp(pr.pw_name, argv[i]) == 0) {
    135      0    stevel 				if ((pp = getpwnam(argv[i])) == NULL) {
    136      0    stevel 					(void) fprintf(stderr,
    137      0    stevel 					    "atq: No such user %s\n", argv[i]);
    138      0    stevel 					exit(1);
    139      0    stevel 				}
    140      0    stevel 				uidlist[argnum] = pp->pw_uid;
    141      0    stevel 				argnum++;
    142      0    stevel 			}
    143      0    stevel 			else
    144      0    stevel 				badarg++;
    145      0    stevel 		}
    146      0    stevel 		if (badarg)
    147      0    stevel 			if (argnum)
    148      0    stevel 				printf("Printing queue information only "
    149      0    stevel 				    "for %s:\n", pr.pw_name);
    150      0    stevel 			else {
    151      0    stevel 				printf("atq: Non-priviledged user cannot "
    152      0    stevel 				    "request information regarding other "
    153      0    stevel 				    "users\n");
    154      0    stevel 				exit(1);
    155      0    stevel 			}
    156  11115  Nobutomo 	} else if (!cron_admin(pr.pw_name)) {
    157      0    stevel 		/* no argument specified and the invoker is not root */
    158      0    stevel 		++namewanted;
    159      0    stevel 		argnum = 1;
    160      0    stevel 		if ((uidlist = (uid_t *)malloc(sizeof (uid_t))) == NULL)
    161      0    stevel 			atabortperror("can't allocate list of users");
    162      0    stevel 		*uidlist = pr.pw_uid;
    163      0    stevel 	}
    164      0    stevel 
    165      0    stevel 	/*
    166      0    stevel 	 * Move to the spooling area and scan the directory, placing the
    167      0    stevel 	 * files in the queue structure. The queue comes back sorted by
    168      0    stevel 	 * execution time or creation time.
    169      0    stevel 	 */
    170      0    stevel 	if (chdir(ATDIR) == -1)
    171      0    stevel 		atabortperror(ATDIR);
    172   6628  jk217608 	if ((numentries = scandir(".", &queue, filewanted,
    173      0    stevel 	    (cflag) ? creation : execution)) < 0)
    174      0    stevel 		atabortperror(ATDIR);
    175      0    stevel 
    176      0    stevel 
    177      0    stevel 	/*
    178      0    stevel 	 * Either print a message stating:
    179      0    stevel 	 *
    180      0    stevel 	 *	1) that the spooling area is empty.
    181      0    stevel 	 *	2) the number of jobs in the spooling area.
    182      0    stevel 	 *	3) the number of jobs in the spooling area belonging to
    183      0    stevel 	 *	   a certain person.
    184      0    stevel 	 *	4) that the person requested doesn't have any files in the
    185      0    stevel 	 *	   spooling area.
    186      0    stevel 	 *
    187      0    stevel 	 * or send the queue off to "printqueue" for printing.
    188      0    stevel 	 *
    189      0    stevel 	 * This whole process might seem a bit elaborate, but it's worthwhile
    190      0    stevel 	 * to print some informative messages for the user.
    191      0    stevel 	 *
    192      0    stevel 	 */
    193      0    stevel 	if ((numentries == 0) && (!nflag)) {
    194      0    stevel 		printf("no files in queue.\n");
    195      0    stevel 		exit(0);
    196      0    stevel 	}
    197      0    stevel 	if (nflag) {
    198      0    stevel 		printf("%d\n", (namewanted) ?
    199      0    stevel 		    countfiles(uidlist, argnum) : numentries);
    200      0    stevel 		exit(0);
    201      0    stevel 	}
    202      0    stevel 	if ((namewanted) && (countfiles(uidlist, argnum) == 0)) {
    203      0    stevel 		if (argnum == 1)
    204      0    stevel 			if (argnum != argc) c = pr.pw_name;
    205      0    stevel 			else c = *argv;
    206      0    stevel 		printf("no files for %s.\n", (argnum == 1) ?
    207   4774  as145665 		    c : "specified users");
    208      0    stevel 		exit(0);
    209      0    stevel 	}
    210      0    stevel 	printqueue(uidlist, argnum);
    211    523    basabi 	return (0);
    212      0    stevel }
    213      0    stevel 
    214      0    stevel /*
    215      0    stevel  * Count the number of jobs in the spooling area owned by a certain person(s).
    216      0    stevel  */
    217    523    basabi int
    218    523    basabi countfiles(uid_t *uidlist, int nuids)
    219      0    stevel {
    220    523    basabi 	int i, j;			/* for loop indices */
    221      0    stevel 	int entryfound;				/* found file owned by users */
    222      0    stevel 	int numfiles = 0;			/* number of files owned by a */
    223      0    stevel 						/* certain person(s) */
    224    523    basabi 	uid_t *ptr;			/* scratch pointer */
    225      0    stevel 	struct stat stbuf;			/* buffer for file stats */
    226      0    stevel 
    227      0    stevel 
    228      0    stevel 	/*
    229      0    stevel 	 * For each file in the queue, see if the user(s) own the file. We
    230      0    stevel 	 * have to use "entryfound" (rather than simply incrementing "numfiles")
    231      0    stevel 	 * so that if a person's name appears twice on the command line we
    232      0    stevel 	 * don't double the number of files owned by him/her.
    233      0    stevel 	 */
    234      0    stevel 	for (i = 0; i < numentries; i++) {
    235      0    stevel 		if ((stat(queue[i]->d_name, &stbuf)) < 0) {
    236      0    stevel 			continue;
    237      0    stevel 		}
    238      0    stevel 		ptr = uidlist;
    239      0    stevel 		entryfound = 0;
    240      0    stevel 
    241      0    stevel 		for (j = 0; j < nuids; j++) {
    242      0    stevel 			if (*ptr == stbuf.st_uid)
    243      0    stevel 				++entryfound;
    244      0    stevel 			++ptr;
    245      0    stevel 		}
    246      0    stevel 		if (entryfound)
    247      0    stevel 			++numfiles;
    248      0    stevel 	}
    249      0    stevel 	return (numfiles);
    250      0    stevel }
    251      0    stevel 
    252      0    stevel /*
    253      0    stevel  * Print the queue. If only jobs belonging to a certain person(s) are requested,
    254      0    stevel  * only print jobs that belong to that person(s).
    255      0    stevel  */
    256    523    basabi static void
    257    523    basabi printqueue(uid_t *uidlist, int nuids)
    258      0    stevel {
    259    523    basabi 	int i, j;			/* for loop indices */
    260      0    stevel 	int rank;				/* rank of a job */
    261      0    stevel 	int entryfound;				/* found file owned by users */
    262      0    stevel 	char *getname();
    263    523    basabi 	uid_t *ptr;			/* scratch pointer */
    264      0    stevel 	struct stat stbuf;			/* buffer for file stats */
    265      0    stevel 	char curqueue;				/* queue of current job */
    266      0    stevel 	char lastqueue;				/* queue of previous job */
    267      0    stevel 
    268      0    stevel 	/*
    269      0    stevel 	 * Print the header for the queue.
    270      0    stevel 	 */
    271      0    stevel 	printf(" Rank	  Execution Date     Owner      Job            "
    272      0    stevel 	    "Queue   Job Name\n");
    273      0    stevel 
    274      0    stevel 	/*
    275      0    stevel 	 * Print the queue. If a certain name(s) was requested, print only jobs
    276      0    stevel 	 * belonging to that person(s), otherwise print the entire queue.
    277      0    stevel 	 * Once again, we have to use "entryfound" (rather than simply
    278      0    stevel 	 * comparing each command line argument) so that if a person's name
    279      0    stevel 	 * appears twice we don't print each file owned by him/her twice.
    280      0    stevel 	 *
    281      0    stevel 	 *
    282      0    stevel 	 * "printrank", "printdate", and "printjobname" all take existing
    283      0    stevel 	 * data and display it in a friendly manner.
    284      0    stevel 	 *
    285      0    stevel 	 */
    286      0    stevel 	lastqueue = '\0';
    287      0    stevel 	for (i = 0; i < numentries; i++) {
    288      0    stevel 		if ((stat(queue[i]->d_name, &stbuf)) < 0) {
    289      0    stevel 			continue;
    290      0    stevel 		}
    291      0    stevel 		curqueue = *(strchr(queue[i]->d_name, '.') + 1);
    292      0    stevel 		if (curqueue != lastqueue) {
    293      0    stevel 			rank = 1;
    294      0    stevel 			lastqueue = curqueue;
    295      0    stevel 		}
    296      0    stevel 		if (namewanted) {
    297      0    stevel 			ptr = uidlist;
    298      0    stevel 			entryfound = 0;
    299      0    stevel 
    300      0    stevel 			for (j = 0; j < nuids; j++) {
    301      0    stevel 				if (*ptr == stbuf.st_uid)
    302      0    stevel 					++entryfound;
    303      0    stevel 				++ptr;
    304      0    stevel 			}
    305      0    stevel 			if (!entryfound)
    306      0    stevel 				continue;
    307      0    stevel 		}
    308      0    stevel 		printrank(rank++);
    309      0    stevel 		printdate(queue[i]->d_name);
    310      0    stevel 		printf("%-10s ", getname(stbuf.st_uid));
    311      0    stevel 		printf("%-14s ", queue[i]->d_name);
    312      0    stevel 		printf("  %c", curqueue);
    313      0    stevel 		printjobname(queue[i]->d_name);
    314      0    stevel 	}
    315      0    stevel 	++ptr;
    316      0    stevel }
    317      0    stevel 
    318      0    stevel /*
    319      0    stevel  * Get the uid of a person using his/her login name. Return -1 if no
    320      0    stevel  * such account name exists.
    321      0    stevel  */
    322      0    stevel uid_t
    323    523    basabi getid(char *name)
    324      0    stevel {
    325      0    stevel 
    326      0    stevel 	struct passwd *pwdinfo;			/* password info structure */
    327      0    stevel 
    328      0    stevel 
    329      0    stevel 	if ((pwdinfo = getpwnam(name)) == 0)
    330      0    stevel 		return ((uid_t)-1);
    331      0    stevel 
    332      0    stevel 	return (pwdinfo->pw_uid);
    333      0    stevel }
    334      0    stevel 
    335      0    stevel /*
    336      0    stevel  * Get the full login name of a person using his/her user id.
    337      0    stevel  */
    338      0    stevel char *
    339    523    basabi getname(uid_t uid)
    340      0    stevel {
    341    523    basabi 	struct passwd *pwdinfo;	/* password info structure */
    342      0    stevel 
    343      0    stevel 
    344      0    stevel 	if ((pwdinfo = getpwuid(uid)) == 0)
    345      0    stevel 		return ("???");
    346      0    stevel 	return (pwdinfo->pw_name);
    347      0    stevel }
    348      0    stevel 
    349      0    stevel /*
    350      0    stevel  * Print the rank of a job. (I've got to admit it, I stole it from "lpq")
    351      0    stevel  */
    352    523    basabi static void
    353    523    basabi printrank(int n)
    354      0    stevel {
    355      0    stevel 	static char *r[] = {
    356      0    stevel 		"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
    357      0    stevel 	};
    358      0    stevel 
    359      0    stevel 	if ((n/10) == 1)
    360      0    stevel 		printf("%3d%-5s", n, "th");
    361      0    stevel 	else
    362      0    stevel 		printf("%3d%-5s", n, r[n%10]);
    363      0    stevel }
    364      0    stevel 
    365      0    stevel /*
    366      0    stevel  * Print the date that a job is to be executed. This takes some manipulation
    367      0    stevel  * of the file name.
    368      0    stevel  */
    369    523    basabi static void
    370    523    basabi printdate(char *filename)
    371      0    stevel {
    372      0    stevel 	time_t	jobdate;
    373    523    basabi 	struct tm *unpackeddate;
    374      0    stevel 	char date[18];				/* reformatted execution date */
    375      0    stevel 
    376      0    stevel 	/*
    377      0    stevel 	 * Convert the file name to a date.
    378      0    stevel 	 */
    379      0    stevel 	jobdate = num(&filename);
    380      0    stevel 	unpackeddate = localtime(&jobdate);
    381      0    stevel 
    382      0    stevel 	/* years since 1900 + base century 1900 */
    383      0    stevel 	unpackeddate->tm_year += 1900;
    384      0    stevel 	/*
    385      0    stevel 	 * Format the execution date of a job.
    386      0    stevel 	 */
    387      0    stevel 	sprintf(date, "%3s %2d, %4d %02d:%02d", mthnames[unpackeddate->tm_mon],
    388      0    stevel 	    unpackeddate->tm_mday, unpackeddate->tm_year,
    389      0    stevel 	    unpackeddate->tm_hour, unpackeddate->tm_min);
    390      0    stevel 
    391      0    stevel 	/*
    392      0    stevel 	 * Print the date the job will be executed.
    393      0    stevel 	 */
    394      0    stevel 	printf("%-21.18s", date);
    395      0    stevel }
    396      0    stevel 
    397      0    stevel /*
    398      0    stevel  * Print a job name. If the old "at" has been used to create the spoolfile,
    399      0    stevel  * the three line header that the new version of "at" puts in the spoolfile.
    400      0    stevel  * Thus, we just print "???".
    401      0    stevel  */
    402    523    basabi static void
    403    523    basabi printjobname(char *file)
    404      0    stevel {
    405      0    stevel 	char *ptr;				/* scratch pointer */
    406      0    stevel 	char jobname[28];			/* the job name */
    407      0    stevel 	FILE *filename;				/* job file in spooling area */
    408      0    stevel 
    409      0    stevel 	/*
    410      0    stevel 	 * Open the job file and grab the third line.
    411      0    stevel 	 */
    412      0    stevel 	printf("     ");
    413      0    stevel 
    414      0    stevel 	if ((filename = fopen(file, "r")) == NULL) {
    415      0    stevel 		printf("%.27s\n", "???");
    416      0    stevel 		(void) fprintf(stderr, "atq: Can't open job file %s: %s\n",
    417      0    stevel 		    file, errmsg(errno));
    418      0    stevel 		return;
    419      0    stevel 	}
    420      0    stevel 	/*
    421      0    stevel 	 * Skip over the first and second lines.
    422      0    stevel 	 */
    423      0    stevel 	fscanf(filename, "%*[^\n]\n");
    424      0    stevel 
    425      0    stevel 	/*
    426      0    stevel 	 * Now get the job name.
    427      0    stevel 	 */
    428      0    stevel 	if (fscanf(filename, ": jobname: %27s%*[^\n]\n", jobname) != 1) {
    429      0    stevel 		printf("%.27s\n", "???");
    430      0    stevel 		fclose(filename);
    431      0    stevel 		return;
    432      0    stevel 	}
    433      0    stevel 	fclose(filename);
    434      0    stevel 
    435      0    stevel 	/*
    436      0    stevel 	 * Put a pointer at the begining of the line and remove the basename
    437      0    stevel 	 * from the job file.
    438      0    stevel 	 */
    439      0    stevel 	ptr = jobname;
    440      0    stevel 	if ((ptr = (char *)strrchr(jobname, '/')) != 0)
    441      0    stevel 		++ptr;
    442      0    stevel 	else
    443      0    stevel 		ptr = jobname;
    444      0    stevel 
    445      0    stevel 	if (strlen(ptr) > 23)
    446      0    stevel 		printf("%.23s ...\n", ptr);
    447      0    stevel 	else
    448      0    stevel 		printf("%.27s\n", ptr);
    449      0    stevel }
    450      0    stevel 
    451      0    stevel 
    452      0    stevel 
    453      0    stevel /*
    454   6628  jk217608  * Sort files by queue, time of creation, and sequence. (used by "scandir")
    455      0    stevel  */
    456    523    basabi int
    457    523    basabi creation(struct dirent **d1, struct dirent **d2)
    458      0    stevel {
    459    523    basabi 	char *p1, *p2;
    460    523    basabi 	int i;
    461      0    stevel 	struct stat stbuf1, stbuf2;
    462    523    basabi 	int seq1, seq2;
    463      0    stevel 
    464      0    stevel 	if ((p1 = strchr((*d1)->d_name, '.')) == NULL)
    465      0    stevel 		return (0);
    466      0    stevel 	if ((p2 = strchr((*d2)->d_name, '.')) == NULL)
    467      0    stevel 		return (0);
    468      0    stevel 	p1++;
    469      0    stevel 	p2++;
    470      0    stevel 	if ((i = *p1++ - *p2++) != 0)
    471      0    stevel 		return (i);
    472      0    stevel 
    473      0    stevel 	if (stat((*d1)->d_name, &stbuf1) < 0)
    474      0    stevel 		return (0);
    475      0    stevel 
    476      0    stevel 	if (stat((*d2)->d_name, &stbuf2) < 0)
    477      0    stevel 		return (0);
    478      0    stevel 
    479      0    stevel 	if (stbuf1.st_ctime < stbuf2.st_ctime)
    480      0    stevel 		return (-1);
    481      0    stevel 	else if (stbuf1.st_ctime > stbuf2.st_ctime)
    482      0    stevel 		return (1);
    483      0    stevel 	p1++;
    484      0    stevel 	p2++;
    485      0    stevel 	seq1 = atoi(p1);
    486      0    stevel 	seq2 = atoi(p2);
    487      0    stevel 	return (seq1 - seq2);
    488      0    stevel }
    489      0    stevel 
    490      0    stevel /*
    491   6628  jk217608  * Sort files by queue, time of execution, and sequence. (used by "scandir")
    492      0    stevel  */
    493    523    basabi int
    494    523    basabi execution(struct dirent **d1, struct dirent **d2)
    495      0    stevel {
    496    523    basabi 	char *p1, *p2;
    497    523    basabi 	int i;
    498      0    stevel 	char *name1, *name2;
    499    523    basabi 	time_t time1, time2;
    500    523    basabi 	int seq1, seq2;
    501      0    stevel 
    502      0    stevel 	name1 = (*d1)->d_name;
    503      0    stevel 	name2 = (*d2)->d_name;
    504      0    stevel 	if ((p1 = strchr(name1, '.')) == NULL)
    505      0    stevel 		return (1);
    506      0    stevel 	if ((p2 = strchr(name2, '.')) == NULL)
    507      0    stevel 		return (1);
    508      0    stevel 	p1++;
    509      0    stevel 	p2++;
    510      0    stevel 	if ((i = *p1++ - *p2++) != 0)
    511      0    stevel 		return (i);
    512      0    stevel 
    513      0    stevel 	time1 = num(&name1);
    514      0    stevel 	time2 = num(&name2);
    515      0    stevel 
    516      0    stevel 	if (time1 < time2)
    517      0    stevel 		return (-1);
    518      0    stevel 	else if (time1 > time2)
    519      0    stevel 		return (1);
    520      0    stevel 	p1++;
    521      0    stevel 	p2++;
    522      0    stevel 	seq1 = atoi(p1);
    523      0    stevel 	seq2 = atoi(p2);
    524      0    stevel 	return (seq1 - seq2);
    525      0    stevel }
    526      0    stevel 
    527      0    stevel 
    528      0    stevel /*
    529      0    stevel  * Print usage info and exit.
    530      0    stevel  */
    531    523    basabi static void
    532    523    basabi usage(void)
    533      0    stevel {
    534      0    stevel 	fprintf(stderr, "usage:	atq [-c] [-n] [name ...]\n");
    535      0    stevel 	exit(1);
    536      0    stevel }
    537      0    stevel 
    538    523    basabi static void
    539    523    basabi aterror(char *msg)
    540      0    stevel {
    541      0    stevel 	fprintf(stderr, "atq: %s\n", msg);
    542      0    stevel }
    543      0    stevel 
    544    523    basabi static void
    545    523    basabi atperror(char *msg)
    546      0    stevel {
    547      0    stevel 	fprintf(stderr, "atq: %s: %s\n", msg, errmsg(errno));
    548      0    stevel }
    549      0    stevel 
    550    523    basabi static void
    551    523    basabi atabort(char *msg)
    552      0    stevel {
    553      0    stevel 	aterror(msg);
    554      0    stevel 	exit(1);
    555      0    stevel }
    556      0    stevel 
    557    523    basabi static void
    558    523    basabi atabortperror(char *msg)
    559      0    stevel {
    560      0    stevel 	atperror(msg);
    561      0    stevel 	exit(1);
    562      0    stevel }
    563