10b561052SJoerg Wunsch /* 20b561052SJoerg Wunsch * Copyright (c) 1983, 1993 30b561052SJoerg Wunsch * The Regents of the University of California. All rights reserved. 40b561052SJoerg Wunsch * 50b561052SJoerg Wunsch * Redistribution and use in source and binary forms, with or without 60b561052SJoerg Wunsch * modification, are permitted provided that the following conditions 70b561052SJoerg Wunsch * are met: 80b561052SJoerg Wunsch * 1. Redistributions of source code must retain the above copyright 90b561052SJoerg Wunsch * notice, this list of conditions and the following disclaimer. 100b561052SJoerg Wunsch * 2. Redistributions in binary form must reproduce the above copyright 110b561052SJoerg Wunsch * notice, this list of conditions and the following disclaimer in the 120b561052SJoerg Wunsch * documentation and/or other materials provided with the distribution. 130b561052SJoerg Wunsch * 3. All advertising materials mentioning features or use of this software 140b561052SJoerg Wunsch * must display the following acknowledgement: 150b561052SJoerg Wunsch * This product includes software developed by the University of 160b561052SJoerg Wunsch * California, Berkeley and its contributors. 170b561052SJoerg Wunsch * 4. Neither the name of the University nor the names of its contributors 180b561052SJoerg Wunsch * may be used to endorse or promote products derived from this software 190b561052SJoerg Wunsch * without specific prior written permission. 200b561052SJoerg Wunsch * 210b561052SJoerg Wunsch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 220b561052SJoerg Wunsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230b561052SJoerg Wunsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240b561052SJoerg Wunsch * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 250b561052SJoerg Wunsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260b561052SJoerg Wunsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270b561052SJoerg Wunsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280b561052SJoerg Wunsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290b561052SJoerg Wunsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300b561052SJoerg Wunsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310b561052SJoerg Wunsch * SUCH DAMAGE. 320b561052SJoerg Wunsch */ 330b561052SJoerg Wunsch 341f589b47SGarance A Drosehn #if 0 35b7fd8699SGarance A Drosehn #ifndef lint 365458e2f4SJoerg Wunsch static char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95"; 37b7fd8699SGarance A Drosehn #endif /* not lint */ 381f589b47SGarance A Drosehn #endif 39b7fd8699SGarance A Drosehn 401f589b47SGarance A Drosehn #include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */ 411f589b47SGarance A Drosehn __FBSDID("$FreeBSD$"); 420b561052SJoerg Wunsch 430b561052SJoerg Wunsch #include <sys/param.h> 440b561052SJoerg Wunsch #include <sys/stat.h> 450b561052SJoerg Wunsch 464a1a0dbeSGarrett Wollman #include <ctype.h> 470b561052SJoerg Wunsch #include <dirent.h> 484a1a0dbeSGarrett Wollman #include <errno.h> 494a1a0dbeSGarrett Wollman #include <fcntl.h> 504a1a0dbeSGarrett Wollman #include <signal.h> 510b561052SJoerg Wunsch #include <stdio.h> 520b561052SJoerg Wunsch #include <stdlib.h> 530b561052SJoerg Wunsch #include <string.h> 544a1a0dbeSGarrett Wollman #define psignal foil_gcc_psignal 554a1a0dbeSGarrett Wollman #define sys_siglist foil_gcc_siglist 564a1a0dbeSGarrett Wollman #include <unistd.h> 574a1a0dbeSGarrett Wollman #undef psignal 584a1a0dbeSGarrett Wollman #undef sys_siglist 594a1a0dbeSGarrett Wollman 600b561052SJoerg Wunsch #include "lp.h" 610b561052SJoerg Wunsch #include "lp.local.h" 620b561052SJoerg Wunsch #include "pathnames.h" 630b561052SJoerg Wunsch 640b561052SJoerg Wunsch /* 650b561052SJoerg Wunsch * Routines to display the state of the queue. 660b561052SJoerg Wunsch */ 670b561052SJoerg Wunsch #define JOBCOL 40 /* column for job # in -l format */ 680b561052SJoerg Wunsch #define OWNCOL 7 /* start of Owner column in normal */ 690b561052SJoerg Wunsch #define SIZCOL 62 /* start of Size column in normal */ 700b561052SJoerg Wunsch 710b561052SJoerg Wunsch /* 720b561052SJoerg Wunsch * Stuff for handling job specifications 730b561052SJoerg Wunsch */ 74360d4ad5SWarner Losh extern uid_t uid, euid; 75360d4ad5SWarner Losh 760b561052SJoerg Wunsch static int col; /* column on screen */ 777b7fb4bbSKris Kennaway static char current[MAXNAMLEN+1]; /* current file being printed */ 787b7fb4bbSKris Kennaway static char file[MAXNAMLEN+1]; /* print file name */ 790b561052SJoerg Wunsch static int first; /* first file in ``files'' column? */ 800b561052SJoerg Wunsch static int garbage; /* # of garbage cf files */ 810b561052SJoerg Wunsch static int lflag; /* long output option */ 820b561052SJoerg Wunsch static int rank; /* order to be printed (-1=none, 0=active) */ 830b561052SJoerg Wunsch static long totsize; /* total print job size in bytes */ 840b561052SJoerg Wunsch 85ba7a1ad7SGarance A Drosehn static const char *head0 = "Rank Owner Job Files"; 86ba7a1ad7SGarance A Drosehn static const char *head1 = "Total Size\n"; 870b561052SJoerg Wunsch 88ba7a1ad7SGarance A Drosehn static void alarmhandler(int _signo); 89ba7a1ad7SGarance A Drosehn static void warn(const struct printer *_pp); 90334a9508SJoerg Wunsch 910b561052SJoerg Wunsch /* 920b561052SJoerg Wunsch * Display the current state of the queue. Format = 1 if long format. 930b561052SJoerg Wunsch */ 940b561052SJoerg Wunsch void 95ba7a1ad7SGarance A Drosehn displayq(struct printer *pp, int format) 960b561052SJoerg Wunsch { 9730b4b758SGarance A Drosehn register struct jobqueue *q; 98360d4ad5SWarner Losh register int i, nitems, fd, ret; 997b7fb4bbSKris Kennaway char *cp, *endp; 10030b4b758SGarance A Drosehn struct jobqueue **queue; 1010b561052SJoerg Wunsch struct stat statb; 1020b561052SJoerg Wunsch FILE *fp; 103334a9508SJoerg Wunsch void (*savealrm)(int); 1040b561052SJoerg Wunsch 1050b561052SJoerg Wunsch lflag = format; 1060b561052SJoerg Wunsch totsize = 0; 1070b561052SJoerg Wunsch rank = -1; 1084a1a0dbeSGarrett Wollman 1094a1a0dbeSGarrett Wollman if ((cp = checkremote(pp))) { 1100b561052SJoerg Wunsch printf("Warning: %s\n", cp); 1114a1a0dbeSGarrett Wollman free(cp); 1124a1a0dbeSGarrett Wollman } 1130b561052SJoerg Wunsch 1140b561052SJoerg Wunsch /* 1150b561052SJoerg Wunsch * Print out local queue 1160b561052SJoerg Wunsch * Find all the control files in the spooling directory 1170b561052SJoerg Wunsch */ 118360d4ad5SWarner Losh seteuid(euid); 1194a1a0dbeSGarrett Wollman if (chdir(pp->spool_dir) < 0) 1204a1a0dbeSGarrett Wollman fatal(pp, "cannot chdir to spooling directory: %s", 1214a1a0dbeSGarrett Wollman strerror(errno)); 122360d4ad5SWarner Losh seteuid(uid); 1234a1a0dbeSGarrett Wollman if ((nitems = getq(pp, &queue)) < 0) 1244a1a0dbeSGarrett Wollman fatal(pp, "cannot examine spooling area\n"); 125360d4ad5SWarner Losh seteuid(euid); 1264a1a0dbeSGarrett Wollman ret = stat(pp->lock_file, &statb); 127360d4ad5SWarner Losh seteuid(uid); 128360d4ad5SWarner Losh if (ret >= 0) { 1294a1a0dbeSGarrett Wollman if (statb.st_mode & LFM_PRINT_DIS) { 1304a1a0dbeSGarrett Wollman if (pp->remote) 131cc3fd56fSGarance A Drosehn printf("%s: ", local_host); 1324a1a0dbeSGarrett Wollman printf("Warning: %s is down: ", pp->printer); 133360d4ad5SWarner Losh seteuid(euid); 1344a1a0dbeSGarrett Wollman fd = open(pp->status_file, O_RDONLY|O_SHLOCK); 135360d4ad5SWarner Losh seteuid(uid); 1360b561052SJoerg Wunsch if (fd >= 0) { 1370b561052SJoerg Wunsch while ((i = read(fd, line, sizeof(line))) > 0) 1380b561052SJoerg Wunsch (void) fwrite(line, 1, i, stdout); 1390b561052SJoerg Wunsch (void) close(fd); /* unlocks as well */ 1400b561052SJoerg Wunsch } else 1410b561052SJoerg Wunsch putchar('\n'); 1420b561052SJoerg Wunsch } 1434a1a0dbeSGarrett Wollman if (statb.st_mode & LFM_QUEUE_DIS) { 1444a1a0dbeSGarrett Wollman if (pp->remote) 145cc3fd56fSGarance A Drosehn printf("%s: ", local_host); 1464a1a0dbeSGarrett Wollman printf("Warning: %s queue is turned off\n", 1474a1a0dbeSGarrett Wollman pp->printer); 1480b561052SJoerg Wunsch } 1490b561052SJoerg Wunsch } 1500b561052SJoerg Wunsch 1510b561052SJoerg Wunsch if (nitems) { 152360d4ad5SWarner Losh seteuid(euid); 1534a1a0dbeSGarrett Wollman fp = fopen(pp->lock_file, "r"); 154360d4ad5SWarner Losh seteuid(uid); 1550b561052SJoerg Wunsch if (fp == NULL) 1564a1a0dbeSGarrett Wollman warn(pp); 1570b561052SJoerg Wunsch else { 1580b561052SJoerg Wunsch /* get daemon pid */ 1590b561052SJoerg Wunsch cp = current; 1607b7fb4bbSKris Kennaway endp = cp + sizeof(current) - 1; 1617b7fb4bbSKris Kennaway while ((i = getc(fp)) != EOF && i != '\n') { 1627b7fb4bbSKris Kennaway if (cp < endp) 1635458e2f4SJoerg Wunsch *cp++ = i; 1647b7fb4bbSKris Kennaway } 1650b561052SJoerg Wunsch *cp = '\0'; 1660b561052SJoerg Wunsch i = atoi(current); 167360d4ad5SWarner Losh if (i <= 0) { 168360d4ad5SWarner Losh ret = -1; 169360d4ad5SWarner Losh } else { 170360d4ad5SWarner Losh seteuid(euid); 171360d4ad5SWarner Losh ret = kill(i, 0); 172360d4ad5SWarner Losh seteuid(uid); 173360d4ad5SWarner Losh } 174360d4ad5SWarner Losh if (ret < 0) { 1754a1a0dbeSGarrett Wollman warn(pp); 176360d4ad5SWarner Losh } else { 1770b561052SJoerg Wunsch /* read current file name */ 1780b561052SJoerg Wunsch cp = current; 1797b7fb4bbSKris Kennaway endp = cp + sizeof(current) - 1; 1807b7fb4bbSKris Kennaway while ((i = getc(fp)) != EOF && i != '\n') { 1817b7fb4bbSKris Kennaway if (cp < endp) 1825458e2f4SJoerg Wunsch *cp++ = i; 1837b7fb4bbSKris Kennaway } 1840b561052SJoerg Wunsch *cp = '\0'; 1850b561052SJoerg Wunsch /* 1860b561052SJoerg Wunsch * Print the status file. 1870b561052SJoerg Wunsch */ 1884a1a0dbeSGarrett Wollman if (pp->remote) 189cc3fd56fSGarance A Drosehn printf("%s: ", local_host); 190360d4ad5SWarner Losh seteuid(euid); 1914a1a0dbeSGarrett Wollman fd = open(pp->status_file, O_RDONLY|O_SHLOCK); 192360d4ad5SWarner Losh seteuid(uid); 1930b561052SJoerg Wunsch if (fd >= 0) { 1944a1a0dbeSGarrett Wollman while ((i = read(fd, line, 1954a1a0dbeSGarrett Wollman sizeof(line))) > 0) 1964a1a0dbeSGarrett Wollman fwrite(line, 1, i, stdout); 1974a1a0dbeSGarrett Wollman close(fd); /* unlocks as well */ 1980b561052SJoerg Wunsch } else 1990b561052SJoerg Wunsch putchar('\n'); 2000b561052SJoerg Wunsch } 2010b561052SJoerg Wunsch (void) fclose(fp); 2020b561052SJoerg Wunsch } 2030b561052SJoerg Wunsch /* 2040b561052SJoerg Wunsch * Now, examine the control files and print out the jobs to 2050b561052SJoerg Wunsch * be done for each user. 2060b561052SJoerg Wunsch */ 2070b561052SJoerg Wunsch if (!lflag) 2080b561052SJoerg Wunsch header(); 2090b561052SJoerg Wunsch for (i = 0; i < nitems; i++) { 2100b561052SJoerg Wunsch q = queue[i]; 21130b4b758SGarance A Drosehn inform(pp, q->job_cfname); 2120b561052SJoerg Wunsch free(q); 2130b561052SJoerg Wunsch } 2140b561052SJoerg Wunsch free(queue); 2150b561052SJoerg Wunsch } 2164a1a0dbeSGarrett Wollman if (!pp->remote) { 2170b561052SJoerg Wunsch if (nitems == 0) 2180b561052SJoerg Wunsch puts("no entries"); 2190b561052SJoerg Wunsch return; 2200b561052SJoerg Wunsch } 2210b561052SJoerg Wunsch 2220b561052SJoerg Wunsch /* 2230b561052SJoerg Wunsch * Print foreign queue 2240b561052SJoerg Wunsch * Note that a file in transit may show up in either queue. 2250b561052SJoerg Wunsch */ 2260b561052SJoerg Wunsch if (nitems) 2270b561052SJoerg Wunsch putchar('\n'); 2284a1a0dbeSGarrett Wollman (void) snprintf(line, sizeof(line), "%c%s", format ? '\4' : '\3', 2294a1a0dbeSGarrett Wollman pp->remote_queue); 2300b561052SJoerg Wunsch cp = line; 2316ee8b269SWarner Losh for (i = 0; i < requests && cp-line+10 < sizeof(line) - 1; i++) { 2320b561052SJoerg Wunsch cp += strlen(cp); 2330b561052SJoerg Wunsch (void) sprintf(cp, " %d", requ[i]); 2340b561052SJoerg Wunsch } 235d583a7c3SWarner Losh for (i = 0; i < users && cp - line + 1 + strlen(user[i]) < 2366ee8b269SWarner Losh sizeof(line) - 1; i++) { 2370b561052SJoerg Wunsch cp += strlen(cp); 2380b561052SJoerg Wunsch *cp++ = ' '; 2390b561052SJoerg Wunsch (void) strcpy(cp, user[i]); 2400b561052SJoerg Wunsch } 2410b561052SJoerg Wunsch strcat(line, "\n"); 242334a9508SJoerg Wunsch savealrm = signal(SIGALRM, alarmhandler); 2434a1a0dbeSGarrett Wollman alarm(pp->conn_timeout); 2444a1a0dbeSGarrett Wollman fd = getport(pp, pp->remote_host, 0); 2456d0727f4SJoerg Wunsch alarm(0); 246334a9508SJoerg Wunsch (void)signal(SIGALRM, savealrm); 2470b561052SJoerg Wunsch if (fd < 0) { 248cc3fd56fSGarance A Drosehn if (from_host != local_host) 249cc3fd56fSGarance A Drosehn printf("%s: ", local_host); 2504a1a0dbeSGarrett Wollman printf("connection to %s is down\n", pp->remote_host); 2510b561052SJoerg Wunsch } 2520b561052SJoerg Wunsch else { 2530b561052SJoerg Wunsch i = strlen(line); 2540b561052SJoerg Wunsch if (write(fd, line, i) != i) 2554a1a0dbeSGarrett Wollman fatal(pp, "Lost connection"); 2560b561052SJoerg Wunsch while ((i = read(fd, line, sizeof(line))) > 0) 2570b561052SJoerg Wunsch (void) fwrite(line, 1, i, stdout); 2580b561052SJoerg Wunsch (void) close(fd); 2590b561052SJoerg Wunsch } 2600b561052SJoerg Wunsch } 2610b561052SJoerg Wunsch 2620b561052SJoerg Wunsch /* 2630b561052SJoerg Wunsch * Print a warning message if there is no daemon present. 2640b561052SJoerg Wunsch */ 26536d0e2a3SJoerg Wunsch static void 266ba7a1ad7SGarance A Drosehn warn(const struct printer *pp) 2670b561052SJoerg Wunsch { 2684a1a0dbeSGarrett Wollman if (pp->remote) 269cc3fd56fSGarance A Drosehn printf("%s: ", local_host); 2700b561052SJoerg Wunsch puts("Warning: no daemon present"); 2710b561052SJoerg Wunsch current[0] = '\0'; 2720b561052SJoerg Wunsch } 2730b561052SJoerg Wunsch 2740b561052SJoerg Wunsch /* 2750b561052SJoerg Wunsch * Print the header for the short listing format 2760b561052SJoerg Wunsch */ 2770b561052SJoerg Wunsch void 278ba7a1ad7SGarance A Drosehn header(void) 2790b561052SJoerg Wunsch { 2806d39e1b7SGarance A Drosehn printf("%s", head0); 2810b561052SJoerg Wunsch col = strlen(head0)+1; 2820b561052SJoerg Wunsch blankfill(SIZCOL); 2836d39e1b7SGarance A Drosehn printf("%s", head1); 2840b561052SJoerg Wunsch } 2850b561052SJoerg Wunsch 2860b561052SJoerg Wunsch void 287ba7a1ad7SGarance A Drosehn inform(const struct printer *pp, char *cf) 2880b561052SJoerg Wunsch { 289c547dbe8SGarance A Drosehn int copycnt, jnum; 290ec6b8da5SGarance A Drosehn char savedname[MAXPATHLEN+1]; 2910b561052SJoerg Wunsch FILE *cfp; 2920b561052SJoerg Wunsch 2930b561052SJoerg Wunsch /* 2940b561052SJoerg Wunsch * There's a chance the control file has gone away 2950b561052SJoerg Wunsch * in the meantime; if this is the case just keep going 2960b561052SJoerg Wunsch */ 297360d4ad5SWarner Losh seteuid(euid); 2980b561052SJoerg Wunsch if ((cfp = fopen(cf, "r")) == NULL) 2990b561052SJoerg Wunsch return; 300360d4ad5SWarner Losh seteuid(uid); 3010b561052SJoerg Wunsch 3020b561052SJoerg Wunsch if (rank < 0) 3030b561052SJoerg Wunsch rank = 0; 3044a1a0dbeSGarrett Wollman if (pp->remote || garbage || strcmp(cf, current)) 3050b561052SJoerg Wunsch rank++; 306ec6b8da5SGarance A Drosehn 307ec6b8da5SGarance A Drosehn /* 308ec6b8da5SGarance A Drosehn * The cf-file may include commands to print more than one datafile 309ec6b8da5SGarance A Drosehn * from the user. For each datafile, the cf-file contains at least 310ec6b8da5SGarance A Drosehn * one line which starts with some format-specifier ('a'-'z'), and 311ec6b8da5SGarance A Drosehn * a second line ('N'ame) which indicates the original name the user 312ec6b8da5SGarance A Drosehn * specified for that file. There can be multiple format-spec lines 313ec6b8da5SGarance A Drosehn * for a single Name-line, if the user requested multiple copies of 314ec6b8da5SGarance A Drosehn * that file. Standard lpr puts the format-spec line(s) before the 315ec6b8da5SGarance A Drosehn * Name-line, while lprNG puts the Name-line before the format-spec 316ec6b8da5SGarance A Drosehn * line(s). This section needs to handle the lines in either order. 317ec6b8da5SGarance A Drosehn */ 318ec6b8da5SGarance A Drosehn copycnt = 0; 319ec6b8da5SGarance A Drosehn file[0] = '\0'; 320ec6b8da5SGarance A Drosehn savedname[0] = '\0'; 321c547dbe8SGarance A Drosehn jnum = calc_jobnum(cf, NULL); 3220b561052SJoerg Wunsch while (getline(cfp)) { 3230b561052SJoerg Wunsch switch (line[0]) { 3240b561052SJoerg Wunsch case 'P': /* Was this file specified in the user's list? */ 3250b561052SJoerg Wunsch if (!inlist(line+1, cf)) { 3260b561052SJoerg Wunsch fclose(cfp); 3270b561052SJoerg Wunsch return; 3280b561052SJoerg Wunsch } 3290b561052SJoerg Wunsch if (lflag) { 3300b561052SJoerg Wunsch printf("\n%s: ", line+1); 3310b561052SJoerg Wunsch col = strlen(line+1) + 2; 3320b561052SJoerg Wunsch prank(rank); 3330b561052SJoerg Wunsch blankfill(JOBCOL); 3340b561052SJoerg Wunsch printf(" [job %s]\n", cf+3); 3350b561052SJoerg Wunsch } else { 3360b561052SJoerg Wunsch col = 0; 3370b561052SJoerg Wunsch prank(rank); 3380b561052SJoerg Wunsch blankfill(OWNCOL); 339c547dbe8SGarance A Drosehn printf("%-10s %-3d ", line+1, jnum); 3400b561052SJoerg Wunsch col += 16; 3410b561052SJoerg Wunsch first = 1; 3420b561052SJoerg Wunsch } 3430b561052SJoerg Wunsch continue; 3440b561052SJoerg Wunsch default: /* some format specifer and file name? */ 3450b561052SJoerg Wunsch if (line[0] < 'a' || line[0] > 'z') 346ec6b8da5SGarance A Drosehn break; 347ec6b8da5SGarance A Drosehn if (copycnt == 0 || strcmp(file, line+1) != 0) { 3485d7321f6SGarance A Drosehn strlcpy(file, line + 1, sizeof(file)); 349d583a7c3SWarner Losh } 350ec6b8da5SGarance A Drosehn copycnt++; 351ec6b8da5SGarance A Drosehn /* 352ec6b8da5SGarance A Drosehn * deliberately 'continue' to another getline(), so 353ec6b8da5SGarance A Drosehn * all format-spec lines for this datafile are read 354ec6b8da5SGarance A Drosehn * in and counted before calling show() 355ec6b8da5SGarance A Drosehn */ 3560b561052SJoerg Wunsch continue; 3570b561052SJoerg Wunsch case 'N': 3585d7321f6SGarance A Drosehn strlcpy(savedname, line + 1, sizeof(savedname)); 359ec6b8da5SGarance A Drosehn break; 360ec6b8da5SGarance A Drosehn } 361ec6b8da5SGarance A Drosehn if ((file[0] != '\0') && (savedname[0] != '\0')) { 362ec6b8da5SGarance A Drosehn show(savedname, file, copycnt); 363ec6b8da5SGarance A Drosehn copycnt = 0; 3640b561052SJoerg Wunsch file[0] = '\0'; 365ec6b8da5SGarance A Drosehn savedname[0] = '\0'; 3660b561052SJoerg Wunsch } 3670b561052SJoerg Wunsch } 3680b561052SJoerg Wunsch fclose(cfp); 369ec6b8da5SGarance A Drosehn /* check for a file which hasn't been shown yet */ 370ec6b8da5SGarance A Drosehn if (file[0] != '\0') { 371ec6b8da5SGarance A Drosehn if (savedname[0] == '\0') { 372ec6b8da5SGarance A Drosehn /* a safeguard in case the N-ame line is missing */ 3735d7321f6SGarance A Drosehn strlcpy(savedname, file, sizeof(savedname)); 374ec6b8da5SGarance A Drosehn } 375ec6b8da5SGarance A Drosehn show(savedname, file, copycnt); 376ec6b8da5SGarance A Drosehn } 3770b561052SJoerg Wunsch if (!lflag) { 3780b561052SJoerg Wunsch blankfill(SIZCOL); 3790b561052SJoerg Wunsch printf("%ld bytes\n", totsize); 3800b561052SJoerg Wunsch totsize = 0; 3810b561052SJoerg Wunsch } 3820b561052SJoerg Wunsch } 3830b561052SJoerg Wunsch 3840b561052SJoerg Wunsch int 385ba7a1ad7SGarance A Drosehn inlist(char *uname, char *cfile) 3860b561052SJoerg Wunsch { 387c547dbe8SGarance A Drosehn int *r, jnum; 388c547dbe8SGarance A Drosehn char **u; 389c547dbe8SGarance A Drosehn const char *cfhost; 3900b561052SJoerg Wunsch 3910b561052SJoerg Wunsch if (users == 0 && requests == 0) 3920b561052SJoerg Wunsch return(1); 3930b561052SJoerg Wunsch /* 3940b561052SJoerg Wunsch * Check to see if it's in the user list 3950b561052SJoerg Wunsch */ 3960b561052SJoerg Wunsch for (u = user; u < &user[users]; u++) 397ba7a1ad7SGarance A Drosehn if (!strcmp(*u, uname)) 3980b561052SJoerg Wunsch return(1); 3990b561052SJoerg Wunsch /* 4000b561052SJoerg Wunsch * Check the request list 4010b561052SJoerg Wunsch */ 402c547dbe8SGarance A Drosehn jnum = calc_jobnum(cfile, &cfhost); 4030b561052SJoerg Wunsch for (r = requ; r < &requ[requests]; r++) 404c547dbe8SGarance A Drosehn if (*r == jnum && !strcmp(cfhost, from_host)) 4050b561052SJoerg Wunsch return(1); 4060b561052SJoerg Wunsch return(0); 4070b561052SJoerg Wunsch } 4080b561052SJoerg Wunsch 4090b561052SJoerg Wunsch void 410ba7a1ad7SGarance A Drosehn show(const char *nfile, const char *datafile, int copies) 4110b561052SJoerg Wunsch { 4120b561052SJoerg Wunsch if (strcmp(nfile, " ") == 0) 4130b561052SJoerg Wunsch nfile = "(standard input)"; 4140b561052SJoerg Wunsch if (lflag) 415ba7a1ad7SGarance A Drosehn ldump(nfile, datafile, copies); 4160b561052SJoerg Wunsch else 417ba7a1ad7SGarance A Drosehn dump(nfile, datafile, copies); 4180b561052SJoerg Wunsch } 4190b561052SJoerg Wunsch 4200b561052SJoerg Wunsch /* 4210b561052SJoerg Wunsch * Fill the line with blanks to the specified column 4220b561052SJoerg Wunsch */ 4230b561052SJoerg Wunsch void 424ba7a1ad7SGarance A Drosehn blankfill(int tocol) 4250b561052SJoerg Wunsch { 426ba7a1ad7SGarance A Drosehn while (col++ < tocol) 4270b561052SJoerg Wunsch putchar(' '); 4280b561052SJoerg Wunsch } 4290b561052SJoerg Wunsch 4300b561052SJoerg Wunsch /* 4310b561052SJoerg Wunsch * Give the abbreviated dump of the file names 4320b561052SJoerg Wunsch */ 4330b561052SJoerg Wunsch void 434ba7a1ad7SGarance A Drosehn dump(const char *nfile, const char *datafile, int copies) 4350b561052SJoerg Wunsch { 4360b561052SJoerg Wunsch struct stat lbuf; 437be794da7SGarance A Drosehn const char etctmpl[] = ", ..."; 438be794da7SGarance A Drosehn char etc[sizeof(etctmpl)]; 439be794da7SGarance A Drosehn char *lastsep; 440be794da7SGarance A Drosehn short fill, nlen; 441be794da7SGarance A Drosehn short rem, remetc; 4420b561052SJoerg Wunsch 4430b561052SJoerg Wunsch /* 444be794da7SGarance A Drosehn * Print as many filenames as will fit 445be794da7SGarance A Drosehn * (leaving room for the 'total size' field) 4460b561052SJoerg Wunsch */ 4470b561052SJoerg Wunsch fill = first ? 0 : 2; /* fill space for ``, '' */ 448be794da7SGarance A Drosehn nlen = strlen(nfile); 449be794da7SGarance A Drosehn rem = SIZCOL - 1 - col; 450be794da7SGarance A Drosehn if (nlen + fill > rem) { 451be794da7SGarance A Drosehn if (first) { 452be794da7SGarance A Drosehn /* print the right-most part of the name */ 453be794da7SGarance A Drosehn printf("...%s ", &nfile[3+nlen-rem]); 454be794da7SGarance A Drosehn col = SIZCOL; 455be794da7SGarance A Drosehn } else if (rem > 0) { 456be794da7SGarance A Drosehn /* fit as much of the etc-string as we can */ 457be794da7SGarance A Drosehn remetc = rem; 458be794da7SGarance A Drosehn if (rem > strlen(etctmpl)) 459be794da7SGarance A Drosehn remetc = strlen(etctmpl); 460be794da7SGarance A Drosehn etc[0] = '\0'; 461be794da7SGarance A Drosehn strncat(etc, etctmpl, remetc); 4626d39e1b7SGarance A Drosehn printf("%s", etc); 463be794da7SGarance A Drosehn col += remetc; 464be794da7SGarance A Drosehn rem -= remetc; 465be794da7SGarance A Drosehn /* room for the last segment of this filename? */ 466be794da7SGarance A Drosehn lastsep = strrchr(nfile, '/'); 467be794da7SGarance A Drosehn if ((lastsep != NULL) && (rem > strlen(lastsep))) { 468be794da7SGarance A Drosehn /* print the right-most part of this name */ 469be794da7SGarance A Drosehn printf("%s", lastsep); 470be794da7SGarance A Drosehn col += strlen(lastsep); 471be794da7SGarance A Drosehn } else { 472be794da7SGarance A Drosehn /* do not pack any more names in here */ 4730b561052SJoerg Wunsch blankfill(SIZCOL); 4740b561052SJoerg Wunsch } 475be794da7SGarance A Drosehn } 4760b561052SJoerg Wunsch } else { 477be794da7SGarance A Drosehn if (!first) 4780b561052SJoerg Wunsch printf(", "); 4790b561052SJoerg Wunsch printf("%s", nfile); 480be794da7SGarance A Drosehn col += nlen + fill; 4810b561052SJoerg Wunsch } 482be794da7SGarance A Drosehn first = 0; 483be794da7SGarance A Drosehn 484360d4ad5SWarner Losh seteuid(euid); 485ba7a1ad7SGarance A Drosehn if (*datafile && !stat(datafile, &lbuf)) 4860b561052SJoerg Wunsch totsize += copies * lbuf.st_size; 487360d4ad5SWarner Losh seteuid(uid); 4880b561052SJoerg Wunsch } 4890b561052SJoerg Wunsch 4900b561052SJoerg Wunsch /* 4910b561052SJoerg Wunsch * Print the long info about the file 4920b561052SJoerg Wunsch */ 4930b561052SJoerg Wunsch void 494ba7a1ad7SGarance A Drosehn ldump(const char *nfile, const char *datafile, int copies) 4950b561052SJoerg Wunsch { 4960b561052SJoerg Wunsch struct stat lbuf; 4970b561052SJoerg Wunsch 4980b561052SJoerg Wunsch putchar('\t'); 4990b561052SJoerg Wunsch if (copies > 1) 5000b561052SJoerg Wunsch printf("%-2d copies of %-19s", copies, nfile); 5010b561052SJoerg Wunsch else 5020b561052SJoerg Wunsch printf("%-32s", nfile); 503ba7a1ad7SGarance A Drosehn if (*datafile && !stat(datafile, &lbuf)) 504ef1c4c53SJohn Birrell printf(" %qd bytes", (long long) lbuf.st_size); 5050b561052SJoerg Wunsch else 5060b561052SJoerg Wunsch printf(" ??? bytes"); 5070b561052SJoerg Wunsch putchar('\n'); 5080b561052SJoerg Wunsch } 5090b561052SJoerg Wunsch 5100b561052SJoerg Wunsch /* 5110b561052SJoerg Wunsch * Print the job's rank in the queue, 5120b561052SJoerg Wunsch * update col for screen management 5130b561052SJoerg Wunsch */ 5140b561052SJoerg Wunsch void 515ba7a1ad7SGarance A Drosehn prank(int n) 5160b561052SJoerg Wunsch { 5170b561052SJoerg Wunsch char rline[100]; 518ba7a1ad7SGarance A Drosehn static const char *r[] = { 5190b561052SJoerg Wunsch "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" 5200b561052SJoerg Wunsch }; 5210b561052SJoerg Wunsch 5220b561052SJoerg Wunsch if (n == 0) { 5230b561052SJoerg Wunsch printf("active"); 5240b561052SJoerg Wunsch col += 6; 5250b561052SJoerg Wunsch return; 5260b561052SJoerg Wunsch } 5270b561052SJoerg Wunsch if ((n/10)%10 == 1) 5280b561052SJoerg Wunsch (void)snprintf(rline, sizeof(rline), "%dth", n); 5290b561052SJoerg Wunsch else 5300b561052SJoerg Wunsch (void)snprintf(rline, sizeof(rline), "%d%s", n, r[n%10]); 5310b561052SJoerg Wunsch col += strlen(rline); 5320b561052SJoerg Wunsch printf("%s", rline); 5330b561052SJoerg Wunsch } 534334a9508SJoerg Wunsch 535334a9508SJoerg Wunsch void 536ba7a1ad7SGarance A Drosehn alarmhandler(int signo __unused) 537334a9508SJoerg Wunsch { 538ba7a1ad7SGarance A Drosehn /* the signal is ignored */ 539ba7a1ad7SGarance A Drosehn /* (the '__unused' is just to avoid a compile-time warning) */ 540334a9508SJoerg Wunsch } 541