1dea673e9SRodney W. Grimes /* 2dea673e9SRodney W. Grimes * Copyright (c) 1983, 1993 3dea673e9SRodney W. Grimes * The Regents of the University of California. All rights reserved. 4dea673e9SRodney W. Grimes * 5dea673e9SRodney W. Grimes * 6dea673e9SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 7dea673e9SRodney W. Grimes * modification, are permitted provided that the following conditions 8dea673e9SRodney W. Grimes * are met: 9dea673e9SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 10dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 11dea673e9SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 12dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 13dea673e9SRodney W. Grimes * documentation and/or other materials provided with the distribution. 14dea673e9SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 15dea673e9SRodney W. Grimes * must display the following acknowledgement: 16dea673e9SRodney W. Grimes * This product includes software developed by the University of 17dea673e9SRodney W. Grimes * California, Berkeley and its contributors. 18dea673e9SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19dea673e9SRodney W. Grimes * may be used to endorse or promote products derived from this software 20dea673e9SRodney W. Grimes * without specific prior written permission. 21dea673e9SRodney W. Grimes * 22dea673e9SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23dea673e9SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24dea673e9SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25dea673e9SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26dea673e9SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27dea673e9SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28dea673e9SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29dea673e9SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30dea673e9SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31dea673e9SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32dea673e9SRodney W. Grimes * SUCH DAMAGE. 33dea673e9SRodney W. Grimes */ 34dea673e9SRodney W. Grimes 35dea673e9SRodney W. Grimes #ifndef lint 36dea673e9SRodney W. Grimes static char copyright[] = 37dea673e9SRodney W. Grimes "@(#) Copyright (c) 1983, 1993\n\ 38dea673e9SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 39dea673e9SRodney W. Grimes #endif /* not lint */ 40dea673e9SRodney W. Grimes 41dea673e9SRodney W. Grimes #ifndef lint 425458e2f4SJoerg Wunsch static char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/28/95"; 43dea673e9SRodney W. Grimes #endif /* not lint */ 44dea673e9SRodney W. Grimes 45dea673e9SRodney W. Grimes /* 46dea673e9SRodney W. Grimes * lpc -- line printer control program -- commands: 47dea673e9SRodney W. Grimes */ 48dea673e9SRodney W. Grimes 49dea673e9SRodney W. Grimes #include <sys/param.h> 50dea673e9SRodney W. Grimes #include <sys/time.h> 51dea673e9SRodney W. Grimes #include <sys/stat.h> 525458e2f4SJoerg Wunsch #include <sys/file.h> 53dea673e9SRodney W. Grimes 54dea673e9SRodney W. Grimes #include <signal.h> 55dea673e9SRodney W. Grimes #include <fcntl.h> 56dea673e9SRodney W. Grimes #include <errno.h> 57dea673e9SRodney W. Grimes #include <dirent.h> 58dea673e9SRodney W. Grimes #include <unistd.h> 59dea673e9SRodney W. Grimes #include <stdlib.h> 60dea673e9SRodney W. Grimes #include <stdio.h> 61dea673e9SRodney W. Grimes #include <ctype.h> 62dea673e9SRodney W. Grimes #include <string.h> 63dea673e9SRodney W. Grimes #include "lp.h" 64dea673e9SRodney W. Grimes #include "lp.local.h" 65dea673e9SRodney W. Grimes #include "lpc.h" 66dea673e9SRodney W. Grimes #include "extern.h" 67dea673e9SRodney W. Grimes #include "pathnames.h" 68dea673e9SRodney W. Grimes 69360d4ad5SWarner Losh extern uid_t uid, euid; 70360d4ad5SWarner Losh 71dea673e9SRodney W. Grimes static void abortpr __P((int)); 72dea673e9SRodney W. Grimes static void cleanpr __P((void)); 73dea673e9SRodney W. Grimes static void disablepr __P((void)); 74dea673e9SRodney W. Grimes static int doarg __P((char *)); 75dea673e9SRodney W. Grimes static int doselect __P((struct dirent *)); 76dea673e9SRodney W. Grimes static void enablepr __P((void)); 77dea673e9SRodney W. Grimes static void prstat __P((void)); 78dea673e9SRodney W. Grimes static void putmsg __P((int, char **)); 79dea673e9SRodney W. Grimes static int sortq __P((const void *, const void *)); 80dea673e9SRodney W. Grimes static void startpr __P((int)); 81dea673e9SRodney W. Grimes static void stoppr __P((void)); 82dea673e9SRodney W. Grimes static int touch __P((struct queue *)); 83dea673e9SRodney W. Grimes static void unlinkf __P((char *)); 84dea673e9SRodney W. Grimes static void upstat __P((char *)); 85dea673e9SRodney W. Grimes 86dea673e9SRodney W. Grimes /* 87dea673e9SRodney W. Grimes * kill an existing daemon and disable printing. 88dea673e9SRodney W. Grimes */ 89dea673e9SRodney W. Grimes void 90dea673e9SRodney W. Grimes doabort(argc, argv) 91dea673e9SRodney W. Grimes int argc; 92dea673e9SRodney W. Grimes char *argv[]; 93dea673e9SRodney W. Grimes { 94dea673e9SRodney W. Grimes register int c, status; 95dea673e9SRodney W. Grimes register char *cp1, *cp2; 96dea673e9SRodney W. Grimes char prbuf[100]; 97dea673e9SRodney W. Grimes 98dea673e9SRodney W. Grimes if (argc == 1) { 99dea673e9SRodney W. Grimes printf("Usage: abort {all | printer ...}\n"); 100dea673e9SRodney W. Grimes return; 101dea673e9SRodney W. Grimes } 102dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 103dea673e9SRodney W. Grimes printer = prbuf; 104dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 105dea673e9SRodney W. Grimes cp1 = prbuf; 106dea673e9SRodney W. Grimes cp2 = bp; 107360d4ad5SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 108360d4ad5SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 109dea673e9SRodney W. Grimes *cp1++ = c; 110dea673e9SRodney W. Grimes *cp1 = '\0'; 111dea673e9SRodney W. Grimes abortpr(1); 112dea673e9SRodney W. Grimes } 113dea673e9SRodney W. Grimes return; 114dea673e9SRodney W. Grimes } 115dea673e9SRodney W. Grimes while (--argc) { 116dea673e9SRodney W. Grimes printer = *++argv; 117dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 118dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 119dea673e9SRodney W. Grimes continue; 120dea673e9SRodney W. Grimes } else if (status == -1) { 121dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 122dea673e9SRodney W. Grimes continue; 123dea673e9SRodney W. Grimes } else if (status == -3) 124dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 125dea673e9SRodney W. Grimes abortpr(1); 126dea673e9SRodney W. Grimes } 127dea673e9SRodney W. Grimes } 128dea673e9SRodney W. Grimes 129dea673e9SRodney W. Grimes static void 130dea673e9SRodney W. Grimes abortpr(dis) 131dea673e9SRodney W. Grimes int dis; 132dea673e9SRodney W. Grimes { 133dea673e9SRodney W. Grimes register FILE *fp; 134dea673e9SRodney W. Grimes struct stat stbuf; 135dea673e9SRodney W. Grimes int pid, fd; 136dea673e9SRodney W. Grimes 137dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 138dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 139dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 140dea673e9SRodney W. Grimes LO = DEFLOCK; 141360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 142dea673e9SRodney W. Grimes printf("%s:\n", printer); 143dea673e9SRodney W. Grimes 144dea673e9SRodney W. Grimes /* 145dea673e9SRodney W. Grimes * Turn on the owner execute bit of the lock file to disable printing. 146dea673e9SRodney W. Grimes */ 147dea673e9SRodney W. Grimes if (dis) { 148360d4ad5SWarner Losh seteuid(euid); 149dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 150dea673e9SRodney W. Grimes if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 151dea673e9SRodney W. Grimes printf("\tcannot disable printing\n"); 152dea673e9SRodney W. Grimes else { 153dea673e9SRodney W. Grimes upstat("printing disabled\n"); 154dea673e9SRodney W. Grimes printf("\tprinting disabled\n"); 155dea673e9SRodney W. Grimes } 156dea673e9SRodney W. Grimes } else if (errno == ENOENT) { 157dea673e9SRodney W. Grimes if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 158dea673e9SRodney W. Grimes printf("\tcannot create lock file\n"); 159dea673e9SRodney W. Grimes else { 160dea673e9SRodney W. Grimes (void) close(fd); 161dea673e9SRodney W. Grimes upstat("printing disabled\n"); 162dea673e9SRodney W. Grimes printf("\tprinting disabled\n"); 163dea673e9SRodney W. Grimes printf("\tno daemon to abort\n"); 164dea673e9SRodney W. Grimes } 165360d4ad5SWarner Losh goto out; 166dea673e9SRodney W. Grimes } else { 167dea673e9SRodney W. Grimes printf("\tcannot stat lock file\n"); 168360d4ad5SWarner Losh goto out; 169dea673e9SRodney W. Grimes } 170dea673e9SRodney W. Grimes } 171dea673e9SRodney W. Grimes /* 172dea673e9SRodney W. Grimes * Kill the current daemon to stop printing now. 173dea673e9SRodney W. Grimes */ 174dea673e9SRodney W. Grimes if ((fp = fopen(line, "r")) == NULL) { 175dea673e9SRodney W. Grimes printf("\tcannot open lock file\n"); 176360d4ad5SWarner Losh goto out; 177dea673e9SRodney W. Grimes } 178dea673e9SRodney W. Grimes if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { 179dea673e9SRodney W. Grimes (void) fclose(fp); /* unlocks as well */ 180dea673e9SRodney W. Grimes printf("\tno daemon to abort\n"); 181360d4ad5SWarner Losh goto out; 182dea673e9SRodney W. Grimes } 183dea673e9SRodney W. Grimes (void) fclose(fp); 184360d4ad5SWarner Losh if (kill(pid = atoi(line), SIGTERM) < 0) { 185360d4ad5SWarner Losh if (errno == ESRCH) 186360d4ad5SWarner Losh printf("\tno daemon to abort\n"); 187dea673e9SRodney W. Grimes else 188360d4ad5SWarner Losh printf("\tWarning: daemon (pid %d) not killed\n", pid); 189360d4ad5SWarner Losh } else 190dea673e9SRodney W. Grimes printf("\tdaemon (pid %d) killed\n", pid); 191360d4ad5SWarner Losh out: 192360d4ad5SWarner Losh seteuid(uid); 193dea673e9SRodney W. Grimes } 194dea673e9SRodney W. Grimes 195dea673e9SRodney W. Grimes /* 196dea673e9SRodney W. Grimes * Write a message into the status file. 197dea673e9SRodney W. Grimes */ 198dea673e9SRodney W. Grimes static void 199dea673e9SRodney W. Grimes upstat(msg) 200dea673e9SRodney W. Grimes char *msg; 201dea673e9SRodney W. Grimes { 202dea673e9SRodney W. Grimes register int fd; 2035f87a7b6SWarner Losh char statfile[MAXPATHLEN]; 204dea673e9SRodney W. Grimes 205dea673e9SRodney W. Grimes if (cgetstr(bp, "st", &ST) == -1) 206dea673e9SRodney W. Grimes ST = DEFSTAT; 2075f87a7b6SWarner Losh (void) snprintf(statfile, sizeof(statfile), "%s/%s", SD, ST); 208dea673e9SRodney W. Grimes umask(0); 209dea673e9SRodney W. Grimes fd = open(statfile, O_WRONLY|O_CREAT, 0664); 210dea673e9SRodney W. Grimes if (fd < 0 || flock(fd, LOCK_EX) < 0) { 211dea673e9SRodney W. Grimes printf("\tcannot create status file\n"); 212dea673e9SRodney W. Grimes return; 213dea673e9SRodney W. Grimes } 214dea673e9SRodney W. Grimes (void) ftruncate(fd, 0); 215dea673e9SRodney W. Grimes if (msg == (char *)NULL) 216dea673e9SRodney W. Grimes (void) write(fd, "\n", 1); 217dea673e9SRodney W. Grimes else 218dea673e9SRodney W. Grimes (void) write(fd, msg, strlen(msg)); 219dea673e9SRodney W. Grimes (void) close(fd); 220dea673e9SRodney W. Grimes } 221dea673e9SRodney W. Grimes 222dea673e9SRodney W. Grimes /* 223dea673e9SRodney W. Grimes * Remove all spool files and temporaries from the spooling area. 224dea673e9SRodney W. Grimes */ 225dea673e9SRodney W. Grimes void 226dea673e9SRodney W. Grimes clean(argc, argv) 227dea673e9SRodney W. Grimes int argc; 228dea673e9SRodney W. Grimes char *argv[]; 229dea673e9SRodney W. Grimes { 230dea673e9SRodney W. Grimes register int c, status; 231dea673e9SRodney W. Grimes register char *cp1, *cp2; 232dea673e9SRodney W. Grimes char prbuf[100]; 233dea673e9SRodney W. Grimes 234dea673e9SRodney W. Grimes if (argc == 1) { 235dea673e9SRodney W. Grimes printf("Usage: clean {all | printer ...}\n"); 236dea673e9SRodney W. Grimes return; 237dea673e9SRodney W. Grimes } 238dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 239dea673e9SRodney W. Grimes printer = prbuf; 240dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 241dea673e9SRodney W. Grimes cp1 = prbuf; 242dea673e9SRodney W. Grimes cp2 = bp; 2435f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 2445f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 245dea673e9SRodney W. Grimes *cp1++ = c; 246dea673e9SRodney W. Grimes *cp1 = '\0'; 247dea673e9SRodney W. Grimes cleanpr(); 248dea673e9SRodney W. Grimes } 249dea673e9SRodney W. Grimes return; 250dea673e9SRodney W. Grimes } 251dea673e9SRodney W. Grimes while (--argc) { 252dea673e9SRodney W. Grimes printer = *++argv; 253dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 254dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 255dea673e9SRodney W. Grimes continue; 256dea673e9SRodney W. Grimes } else if (status == -1) { 257dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 258dea673e9SRodney W. Grimes continue; 259dea673e9SRodney W. Grimes } else if (status == -3) 260dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 261dea673e9SRodney W. Grimes 262dea673e9SRodney W. Grimes cleanpr(); 263dea673e9SRodney W. Grimes } 264dea673e9SRodney W. Grimes } 265dea673e9SRodney W. Grimes 266dea673e9SRodney W. Grimes static int 267dea673e9SRodney W. Grimes doselect(d) 268dea673e9SRodney W. Grimes struct dirent *d; 269dea673e9SRodney W. Grimes { 270dea673e9SRodney W. Grimes int c = d->d_name[0]; 271dea673e9SRodney W. Grimes 272dea673e9SRodney W. Grimes if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') 273dea673e9SRodney W. Grimes return(1); 274dea673e9SRodney W. Grimes return(0); 275dea673e9SRodney W. Grimes } 276dea673e9SRodney W. Grimes 277dea673e9SRodney W. Grimes /* 278dea673e9SRodney W. Grimes * Comparison routine for scandir. Sort by job number and machine, then 279dea673e9SRodney W. Grimes * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. 280dea673e9SRodney W. Grimes */ 281dea673e9SRodney W. Grimes static int 282dea673e9SRodney W. Grimes sortq(a, b) 283dea673e9SRodney W. Grimes const void *a, *b; 284dea673e9SRodney W. Grimes { 285dea673e9SRodney W. Grimes struct dirent **d1, **d2; 286dea673e9SRodney W. Grimes int c1, c2; 287dea673e9SRodney W. Grimes 288dea673e9SRodney W. Grimes d1 = (struct dirent **)a; 289dea673e9SRodney W. Grimes d2 = (struct dirent **)b; 290bc407914SWarner Losh if ((c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))) 291dea673e9SRodney W. Grimes return(c1); 292dea673e9SRodney W. Grimes c1 = (*d1)->d_name[0]; 293dea673e9SRodney W. Grimes c2 = (*d2)->d_name[0]; 294dea673e9SRodney W. Grimes if (c1 == c2) 295dea673e9SRodney W. Grimes return((*d1)->d_name[2] - (*d2)->d_name[2]); 296dea673e9SRodney W. Grimes if (c1 == 'c') 297dea673e9SRodney W. Grimes return(-1); 298dea673e9SRodney W. Grimes if (c1 == 'd' || c2 == 'c') 299dea673e9SRodney W. Grimes return(1); 300dea673e9SRodney W. Grimes return(-1); 301dea673e9SRodney W. Grimes } 302dea673e9SRodney W. Grimes 303dea673e9SRodney W. Grimes /* 304dea673e9SRodney W. Grimes * Remove incomplete jobs from spooling area. 305dea673e9SRodney W. Grimes */ 306dea673e9SRodney W. Grimes static void 307dea673e9SRodney W. Grimes cleanpr() 308dea673e9SRodney W. Grimes { 309dea673e9SRodney W. Grimes register int i, n; 310dea673e9SRodney W. Grimes register char *cp, *cp1, *lp; 311dea673e9SRodney W. Grimes struct dirent **queue; 312dea673e9SRodney W. Grimes int nitems; 313dea673e9SRodney W. Grimes 314dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 315dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 316dea673e9SRodney W. Grimes printf("%s:\n", printer); 317dea673e9SRodney W. Grimes 318360d4ad5SWarner Losh for (lp = line, cp = SD; (lp - line) < sizeof(line) && (*lp++ = *cp++);) 319dea673e9SRodney W. Grimes ; 320dea673e9SRodney W. Grimes lp[-1] = '/'; 321dea673e9SRodney W. Grimes 322360d4ad5SWarner Losh seteuid(euid); 323dea673e9SRodney W. Grimes nitems = scandir(SD, &queue, doselect, sortq); 324360d4ad5SWarner Losh seteuid(uid); 325dea673e9SRodney W. Grimes if (nitems < 0) { 326dea673e9SRodney W. Grimes printf("\tcannot examine spool directory\n"); 327dea673e9SRodney W. Grimes return; 328dea673e9SRodney W. Grimes } 329dea673e9SRodney W. Grimes if (nitems == 0) 330dea673e9SRodney W. Grimes return; 331dea673e9SRodney W. Grimes i = 0; 332dea673e9SRodney W. Grimes do { 333dea673e9SRodney W. Grimes cp = queue[i]->d_name; 334dea673e9SRodney W. Grimes if (*cp == 'c') { 335dea673e9SRodney W. Grimes n = 0; 336dea673e9SRodney W. Grimes while (i + 1 < nitems) { 337dea673e9SRodney W. Grimes cp1 = queue[i + 1]->d_name; 338dea673e9SRodney W. Grimes if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) 339dea673e9SRodney W. Grimes break; 340dea673e9SRodney W. Grimes i++; 341dea673e9SRodney W. Grimes n++; 342dea673e9SRodney W. Grimes } 343dea673e9SRodney W. Grimes if (n == 0) { 34487751a84SWarner Losh strncpy(lp, cp, sizeof(line) - strlen(line) - 1); 34587751a84SWarner Losh line[sizeof(line) - 1] = '\0'; 346dea673e9SRodney W. Grimes unlinkf(line); 347dea673e9SRodney W. Grimes } 348dea673e9SRodney W. Grimes } else { 349dea673e9SRodney W. Grimes /* 350dea673e9SRodney W. Grimes * Must be a df with no cf (otherwise, it would have 351dea673e9SRodney W. Grimes * been skipped above) or a tf file (which can always 352dea673e9SRodney W. Grimes * be removed). 353dea673e9SRodney W. Grimes */ 35487751a84SWarner Losh strncpy(lp, cp, sizeof(line) - strlen(line) - 1); 35587751a84SWarner Losh line[sizeof(line) - 1] = '\0'; 356dea673e9SRodney W. Grimes unlinkf(line); 357dea673e9SRodney W. Grimes } 358dea673e9SRodney W. Grimes } while (++i < nitems); 359dea673e9SRodney W. Grimes } 360dea673e9SRodney W. Grimes 361dea673e9SRodney W. Grimes static void 362dea673e9SRodney W. Grimes unlinkf(name) 363dea673e9SRodney W. Grimes char *name; 364dea673e9SRodney W. Grimes { 365360d4ad5SWarner Losh seteuid(euid); 366dea673e9SRodney W. Grimes if (unlink(name) < 0) 367dea673e9SRodney W. Grimes printf("\tcannot remove %s\n", name); 368dea673e9SRodney W. Grimes else 369dea673e9SRodney W. Grimes printf("\tremoved %s\n", name); 370360d4ad5SWarner Losh seteuid(uid); 371dea673e9SRodney W. Grimes } 372dea673e9SRodney W. Grimes 373dea673e9SRodney W. Grimes /* 374dea673e9SRodney W. Grimes * Enable queuing to the printer (allow lpr's). 375dea673e9SRodney W. Grimes */ 376dea673e9SRodney W. Grimes void 377dea673e9SRodney W. Grimes enable(argc, argv) 378dea673e9SRodney W. Grimes int argc; 379dea673e9SRodney W. Grimes char *argv[]; 380dea673e9SRodney W. Grimes { 381dea673e9SRodney W. Grimes register int c, status; 382dea673e9SRodney W. Grimes register char *cp1, *cp2; 383dea673e9SRodney W. Grimes char prbuf[100]; 384dea673e9SRodney W. Grimes 385dea673e9SRodney W. Grimes if (argc == 1) { 386dea673e9SRodney W. Grimes printf("Usage: enable {all | printer ...}\n"); 387dea673e9SRodney W. Grimes return; 388dea673e9SRodney W. Grimes } 389dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 390dea673e9SRodney W. Grimes printer = prbuf; 391dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 392dea673e9SRodney W. Grimes cp1 = prbuf; 393dea673e9SRodney W. Grimes cp2 = bp; 3945f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 3955f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 396dea673e9SRodney W. Grimes *cp1++ = c; 397dea673e9SRodney W. Grimes *cp1 = '\0'; 398dea673e9SRodney W. Grimes enablepr(); 399dea673e9SRodney W. Grimes } 400dea673e9SRodney W. Grimes return; 401dea673e9SRodney W. Grimes } 402dea673e9SRodney W. Grimes while (--argc) { 403dea673e9SRodney W. Grimes printer = *++argv; 404dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 405dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 406dea673e9SRodney W. Grimes continue; 407dea673e9SRodney W. Grimes } else if (status == -1) { 408dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 409dea673e9SRodney W. Grimes continue; 410dea673e9SRodney W. Grimes } else if (status == -3) 411dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 412dea673e9SRodney W. Grimes 413dea673e9SRodney W. Grimes enablepr(); 414dea673e9SRodney W. Grimes } 415dea673e9SRodney W. Grimes } 416dea673e9SRodney W. Grimes 417dea673e9SRodney W. Grimes static void 418dea673e9SRodney W. Grimes enablepr() 419dea673e9SRodney W. Grimes { 420dea673e9SRodney W. Grimes struct stat stbuf; 421dea673e9SRodney W. Grimes 422dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 423dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 424dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 425dea673e9SRodney W. Grimes LO = DEFLOCK; 426360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 427dea673e9SRodney W. Grimes printf("%s:\n", printer); 428dea673e9SRodney W. Grimes 429dea673e9SRodney W. Grimes /* 430dea673e9SRodney W. Grimes * Turn off the group execute bit of the lock file to enable queuing. 431dea673e9SRodney W. Grimes */ 432360d4ad5SWarner Losh seteuid(euid); 433dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 434dea673e9SRodney W. Grimes if (chmod(line, stbuf.st_mode & 0767) < 0) 435dea673e9SRodney W. Grimes printf("\tcannot enable queuing\n"); 436dea673e9SRodney W. Grimes else 437dea673e9SRodney W. Grimes printf("\tqueuing enabled\n"); 438dea673e9SRodney W. Grimes } 439360d4ad5SWarner Losh seteuid(uid); 440dea673e9SRodney W. Grimes } 441dea673e9SRodney W. Grimes 442dea673e9SRodney W. Grimes /* 443dea673e9SRodney W. Grimes * Disable queuing. 444dea673e9SRodney W. Grimes */ 445dea673e9SRodney W. Grimes void 446dea673e9SRodney W. Grimes disable(argc, argv) 447dea673e9SRodney W. Grimes int argc; 448dea673e9SRodney W. Grimes char *argv[]; 449dea673e9SRodney W. Grimes { 450dea673e9SRodney W. Grimes register int c, status; 451dea673e9SRodney W. Grimes register char *cp1, *cp2; 452dea673e9SRodney W. Grimes char prbuf[100]; 453dea673e9SRodney W. Grimes 454dea673e9SRodney W. Grimes if (argc == 1) { 455dea673e9SRodney W. Grimes printf("Usage: disable {all | printer ...}\n"); 456dea673e9SRodney W. Grimes return; 457dea673e9SRodney W. Grimes } 458dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 459dea673e9SRodney W. Grimes printer = prbuf; 460dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 461dea673e9SRodney W. Grimes cp1 = prbuf; 462dea673e9SRodney W. Grimes cp2 = bp; 4635f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 4645f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 465dea673e9SRodney W. Grimes *cp1++ = c; 466dea673e9SRodney W. Grimes *cp1 = '\0'; 467dea673e9SRodney W. Grimes disablepr(); 468dea673e9SRodney W. Grimes } 469dea673e9SRodney W. Grimes return; 470dea673e9SRodney W. Grimes } 471dea673e9SRodney W. Grimes while (--argc) { 472dea673e9SRodney W. Grimes printer = *++argv; 473dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 474dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 475dea673e9SRodney W. Grimes continue; 476dea673e9SRodney W. Grimes } else if (status == -1) { 477dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 478dea673e9SRodney W. Grimes continue; 479dea673e9SRodney W. Grimes } else if (status == -3) 480dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 481dea673e9SRodney W. Grimes 482dea673e9SRodney W. Grimes disablepr(); 483dea673e9SRodney W. Grimes } 484dea673e9SRodney W. Grimes } 485dea673e9SRodney W. Grimes 486dea673e9SRodney W. Grimes static void 487dea673e9SRodney W. Grimes disablepr() 488dea673e9SRodney W. Grimes { 489dea673e9SRodney W. Grimes register int fd; 490dea673e9SRodney W. Grimes struct stat stbuf; 491dea673e9SRodney W. Grimes 492dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 493dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 494dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 495dea673e9SRodney W. Grimes LO = DEFLOCK; 496360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 497dea673e9SRodney W. Grimes printf("%s:\n", printer); 498dea673e9SRodney W. Grimes /* 499dea673e9SRodney W. Grimes * Turn on the group execute bit of the lock file to disable queuing. 500dea673e9SRodney W. Grimes */ 501360d4ad5SWarner Losh seteuid(euid); 502dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 503dea673e9SRodney W. Grimes if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0) 504dea673e9SRodney W. Grimes printf("\tcannot disable queuing\n"); 505dea673e9SRodney W. Grimes else 506dea673e9SRodney W. Grimes printf("\tqueuing disabled\n"); 507dea673e9SRodney W. Grimes } else if (errno == ENOENT) { 508dea673e9SRodney W. Grimes if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) 509dea673e9SRodney W. Grimes printf("\tcannot create lock file\n"); 510dea673e9SRodney W. Grimes else { 511dea673e9SRodney W. Grimes (void) close(fd); 512dea673e9SRodney W. Grimes printf("\tqueuing disabled\n"); 513dea673e9SRodney W. Grimes } 514dea673e9SRodney W. Grimes } else 515dea673e9SRodney W. Grimes printf("\tcannot stat lock file\n"); 516360d4ad5SWarner Losh seteuid(uid); 517dea673e9SRodney W. Grimes } 518dea673e9SRodney W. Grimes 519dea673e9SRodney W. Grimes /* 520dea673e9SRodney W. Grimes * Disable queuing and printing and put a message into the status file 521dea673e9SRodney W. Grimes * (reason for being down). 522dea673e9SRodney W. Grimes */ 523dea673e9SRodney W. Grimes void 524dea673e9SRodney W. Grimes down(argc, argv) 525dea673e9SRodney W. Grimes int argc; 526dea673e9SRodney W. Grimes char *argv[]; 527dea673e9SRodney W. Grimes { 528dea673e9SRodney W. Grimes register int c, status; 529dea673e9SRodney W. Grimes register char *cp1, *cp2; 530dea673e9SRodney W. Grimes char prbuf[100]; 531dea673e9SRodney W. Grimes 532dea673e9SRodney W. Grimes if (argc == 1) { 533dea673e9SRodney W. Grimes printf("Usage: down {all | printer} [message ...]\n"); 534dea673e9SRodney W. Grimes return; 535dea673e9SRodney W. Grimes } 536dea673e9SRodney W. Grimes if (!strcmp(argv[1], "all")) { 537dea673e9SRodney W. Grimes printer = prbuf; 538dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 539dea673e9SRodney W. Grimes cp1 = prbuf; 540dea673e9SRodney W. Grimes cp2 = bp; 5415f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 5425f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 543dea673e9SRodney W. Grimes *cp1++ = c; 544dea673e9SRodney W. Grimes *cp1 = '\0'; 545dea673e9SRodney W. Grimes putmsg(argc - 2, argv + 2); 546dea673e9SRodney W. Grimes } 547dea673e9SRodney W. Grimes return; 548dea673e9SRodney W. Grimes } 549dea673e9SRodney W. Grimes printer = argv[1]; 550dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 551dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 552dea673e9SRodney W. Grimes return; 553dea673e9SRodney W. Grimes } else if (status == -1) { 554dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 555dea673e9SRodney W. Grimes return; 556dea673e9SRodney W. Grimes } else if (status == -3) 557dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 558dea673e9SRodney W. Grimes 559dea673e9SRodney W. Grimes putmsg(argc - 2, argv + 2); 560dea673e9SRodney W. Grimes } 561dea673e9SRodney W. Grimes 562dea673e9SRodney W. Grimes static void 563dea673e9SRodney W. Grimes putmsg(argc, argv) 564dea673e9SRodney W. Grimes int argc; 565dea673e9SRodney W. Grimes char **argv; 566dea673e9SRodney W. Grimes { 567dea673e9SRodney W. Grimes register int fd; 568dea673e9SRodney W. Grimes register char *cp1, *cp2; 569dea673e9SRodney W. Grimes char buf[1024]; 570dea673e9SRodney W. Grimes struct stat stbuf; 571dea673e9SRodney W. Grimes 572dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 573dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 574dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 575dea673e9SRodney W. Grimes LO = DEFLOCK; 576dea673e9SRodney W. Grimes if (cgetstr(bp, "st", &ST) == -1) 577dea673e9SRodney W. Grimes ST = DEFSTAT; 578dea673e9SRodney W. Grimes printf("%s:\n", printer); 579dea673e9SRodney W. Grimes /* 580dea673e9SRodney W. Grimes * Turn on the group execute bit of the lock file to disable queuing and 581dea673e9SRodney W. Grimes * turn on the owner execute bit of the lock file to disable printing. 582dea673e9SRodney W. Grimes */ 583360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 584360d4ad5SWarner Losh seteuid(euid); 585dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 586dea673e9SRodney W. Grimes if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) 587dea673e9SRodney W. Grimes printf("\tcannot disable queuing\n"); 588dea673e9SRodney W. Grimes else 589dea673e9SRodney W. Grimes printf("\tprinter and queuing disabled\n"); 590dea673e9SRodney W. Grimes } else if (errno == ENOENT) { 591dea673e9SRodney W. Grimes if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) 592dea673e9SRodney W. Grimes printf("\tcannot create lock file\n"); 593dea673e9SRodney W. Grimes else { 594dea673e9SRodney W. Grimes (void) close(fd); 595dea673e9SRodney W. Grimes printf("\tprinter and queuing disabled\n"); 596dea673e9SRodney W. Grimes } 597360d4ad5SWarner Losh seteuid(uid); 598dea673e9SRodney W. Grimes return; 599dea673e9SRodney W. Grimes } else 600dea673e9SRodney W. Grimes printf("\tcannot stat lock file\n"); 601dea673e9SRodney W. Grimes /* 602dea673e9SRodney W. Grimes * Write the message into the status file. 603dea673e9SRodney W. Grimes */ 604360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, ST); 605dea673e9SRodney W. Grimes fd = open(line, O_WRONLY|O_CREAT, 0664); 606dea673e9SRodney W. Grimes if (fd < 0 || flock(fd, LOCK_EX) < 0) { 607dea673e9SRodney W. Grimes printf("\tcannot create status file\n"); 608360d4ad5SWarner Losh seteuid(uid); 609dea673e9SRodney W. Grimes return; 610dea673e9SRodney W. Grimes } 611360d4ad5SWarner Losh seteuid(uid); 612dea673e9SRodney W. Grimes (void) ftruncate(fd, 0); 613dea673e9SRodney W. Grimes if (argc <= 0) { 614dea673e9SRodney W. Grimes (void) write(fd, "\n", 1); 615dea673e9SRodney W. Grimes (void) close(fd); 616dea673e9SRodney W. Grimes return; 617dea673e9SRodney W. Grimes } 618dea673e9SRodney W. Grimes cp1 = buf; 619dea673e9SRodney W. Grimes while (--argc >= 0) { 620dea673e9SRodney W. Grimes cp2 = *argv++; 6215f87a7b6SWarner Losh while ((cp1 - buf) < sizeof(buf) && (*cp1++ = *cp2++)) 622dea673e9SRodney W. Grimes ; 623dea673e9SRodney W. Grimes cp1[-1] = ' '; 624dea673e9SRodney W. Grimes } 625dea673e9SRodney W. Grimes cp1[-1] = '\n'; 626dea673e9SRodney W. Grimes *cp1 = '\0'; 627dea673e9SRodney W. Grimes (void) write(fd, buf, strlen(buf)); 628dea673e9SRodney W. Grimes (void) close(fd); 629dea673e9SRodney W. Grimes } 630dea673e9SRodney W. Grimes 631dea673e9SRodney W. Grimes /* 632dea673e9SRodney W. Grimes * Exit lpc 633dea673e9SRodney W. Grimes */ 634dea673e9SRodney W. Grimes void 635dea673e9SRodney W. Grimes quit(argc, argv) 636dea673e9SRodney W. Grimes int argc; 637dea673e9SRodney W. Grimes char *argv[]; 638dea673e9SRodney W. Grimes { 639dea673e9SRodney W. Grimes exit(0); 640dea673e9SRodney W. Grimes } 641dea673e9SRodney W. Grimes 642dea673e9SRodney W. Grimes /* 643dea673e9SRodney W. Grimes * Kill and restart the daemon. 644dea673e9SRodney W. Grimes */ 645dea673e9SRodney W. Grimes void 646dea673e9SRodney W. Grimes restart(argc, argv) 647dea673e9SRodney W. Grimes int argc; 648dea673e9SRodney W. Grimes char *argv[]; 649dea673e9SRodney W. Grimes { 650dea673e9SRodney W. Grimes register int c, status; 651dea673e9SRodney W. Grimes register char *cp1, *cp2; 652dea673e9SRodney W. Grimes char prbuf[100]; 653dea673e9SRodney W. Grimes 654dea673e9SRodney W. Grimes if (argc == 1) { 655dea673e9SRodney W. Grimes printf("Usage: restart {all | printer ...}\n"); 656dea673e9SRodney W. Grimes return; 657dea673e9SRodney W. Grimes } 658dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 659dea673e9SRodney W. Grimes printer = prbuf; 660dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 661dea673e9SRodney W. Grimes cp1 = prbuf; 662dea673e9SRodney W. Grimes cp2 = bp; 6635f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 6645f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 665dea673e9SRodney W. Grimes *cp1++ = c; 666dea673e9SRodney W. Grimes *cp1 = '\0'; 667dea673e9SRodney W. Grimes abortpr(0); 668dea673e9SRodney W. Grimes startpr(0); 669dea673e9SRodney W. Grimes } 670dea673e9SRodney W. Grimes return; 671dea673e9SRodney W. Grimes } 672dea673e9SRodney W. Grimes while (--argc) { 673dea673e9SRodney W. Grimes printer = *++argv; 674dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 675dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 676dea673e9SRodney W. Grimes continue; 677dea673e9SRodney W. Grimes } else if (status == -1) { 678dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 679dea673e9SRodney W. Grimes continue; 680dea673e9SRodney W. Grimes } else if (status == -3) 681dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 682dea673e9SRodney W. Grimes 683dea673e9SRodney W. Grimes abortpr(0); 684dea673e9SRodney W. Grimes startpr(0); 685dea673e9SRodney W. Grimes } 686dea673e9SRodney W. Grimes } 687dea673e9SRodney W. Grimes 688dea673e9SRodney W. Grimes /* 689dea673e9SRodney W. Grimes * Enable printing on the specified printer and startup the daemon. 690dea673e9SRodney W. Grimes */ 691dea673e9SRodney W. Grimes void 692dea673e9SRodney W. Grimes startcmd(argc, argv) 693dea673e9SRodney W. Grimes int argc; 694dea673e9SRodney W. Grimes char *argv[]; 695dea673e9SRodney W. Grimes { 696dea673e9SRodney W. Grimes register int c, status; 697dea673e9SRodney W. Grimes register char *cp1, *cp2; 698dea673e9SRodney W. Grimes char prbuf[100]; 699dea673e9SRodney W. Grimes 700dea673e9SRodney W. Grimes if (argc == 1) { 701dea673e9SRodney W. Grimes printf("Usage: start {all | printer ...}\n"); 702dea673e9SRodney W. Grimes return; 703dea673e9SRodney W. Grimes } 704dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 705dea673e9SRodney W. Grimes printer = prbuf; 706dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 707dea673e9SRodney W. Grimes cp1 = prbuf; 708dea673e9SRodney W. Grimes cp2 = bp; 7095f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 7105f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 711dea673e9SRodney W. Grimes *cp1++ = c; 712dea673e9SRodney W. Grimes *cp1 = '\0'; 713dea673e9SRodney W. Grimes startpr(1); 714dea673e9SRodney W. Grimes } 715dea673e9SRodney W. Grimes return; 716dea673e9SRodney W. Grimes } 717dea673e9SRodney W. Grimes while (--argc) { 718dea673e9SRodney W. Grimes printer = *++argv; 719dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 720dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 721dea673e9SRodney W. Grimes continue; 722dea673e9SRodney W. Grimes } else if (status == -1) { 723dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 724dea673e9SRodney W. Grimes continue; 725dea673e9SRodney W. Grimes } else if (status == -3) 726dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 727dea673e9SRodney W. Grimes 728dea673e9SRodney W. Grimes startpr(1); 729dea673e9SRodney W. Grimes } 730dea673e9SRodney W. Grimes } 731dea673e9SRodney W. Grimes 732dea673e9SRodney W. Grimes static void 733dea673e9SRodney W. Grimes startpr(enable) 734dea673e9SRodney W. Grimes int enable; 735dea673e9SRodney W. Grimes { 736dea673e9SRodney W. Grimes struct stat stbuf; 737dea673e9SRodney W. Grimes 738dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 739dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 740dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 741dea673e9SRodney W. Grimes LO = DEFLOCK; 742360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 743dea673e9SRodney W. Grimes printf("%s:\n", printer); 744dea673e9SRodney W. Grimes 745dea673e9SRodney W. Grimes /* 746dea673e9SRodney W. Grimes * Turn off the owner execute bit of the lock file to enable printing. 747dea673e9SRodney W. Grimes */ 748360d4ad5SWarner Losh seteuid(euid); 749dea673e9SRodney W. Grimes if (enable && stat(line, &stbuf) >= 0) { 750dea673e9SRodney W. Grimes if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0) 751dea673e9SRodney W. Grimes printf("\tcannot enable printing\n"); 752dea673e9SRodney W. Grimes else 753dea673e9SRodney W. Grimes printf("\tprinting enabled\n"); 754dea673e9SRodney W. Grimes } 755dea673e9SRodney W. Grimes if (!startdaemon(printer)) 756dea673e9SRodney W. Grimes printf("\tcouldn't start daemon\n"); 757dea673e9SRodney W. Grimes else 758dea673e9SRodney W. Grimes printf("\tdaemon started\n"); 759360d4ad5SWarner Losh seteuid(uid); 760dea673e9SRodney W. Grimes } 761dea673e9SRodney W. Grimes 762dea673e9SRodney W. Grimes /* 763dea673e9SRodney W. Grimes * Print the status of each queue listed or all the queues. 764dea673e9SRodney W. Grimes */ 765dea673e9SRodney W. Grimes void 766dea673e9SRodney W. Grimes status(argc, argv) 767dea673e9SRodney W. Grimes int argc; 768dea673e9SRodney W. Grimes char *argv[]; 769dea673e9SRodney W. Grimes { 770dea673e9SRodney W. Grimes register int c, status; 771dea673e9SRodney W. Grimes register char *cp1, *cp2; 772dea673e9SRodney W. Grimes char prbuf[100]; 773dea673e9SRodney W. Grimes 774dea673e9SRodney W. Grimes if (argc == 1) { 775dea673e9SRodney W. Grimes printer = prbuf; 776dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 777dea673e9SRodney W. Grimes cp1 = prbuf; 778dea673e9SRodney W. Grimes cp2 = bp; 7795f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 7805f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 781dea673e9SRodney W. Grimes *cp1++ = c; 782dea673e9SRodney W. Grimes *cp1 = '\0'; 783dea673e9SRodney W. Grimes prstat(); 784dea673e9SRodney W. Grimes } 785dea673e9SRodney W. Grimes return; 786dea673e9SRodney W. Grimes } 787dea673e9SRodney W. Grimes while (--argc) { 788dea673e9SRodney W. Grimes printer = *++argv; 789dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 790dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 791dea673e9SRodney W. Grimes continue; 792dea673e9SRodney W. Grimes } else if (status == -1) { 793dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 794dea673e9SRodney W. Grimes continue; 795dea673e9SRodney W. Grimes } else if (status == -3) 796dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 797dea673e9SRodney W. Grimes 798dea673e9SRodney W. Grimes prstat(); 799dea673e9SRodney W. Grimes } 800dea673e9SRodney W. Grimes } 801dea673e9SRodney W. Grimes 802dea673e9SRodney W. Grimes /* 803dea673e9SRodney W. Grimes * Print the status of the printer queue. 804dea673e9SRodney W. Grimes */ 805dea673e9SRodney W. Grimes static void 806dea673e9SRodney W. Grimes prstat() 807dea673e9SRodney W. Grimes { 808dea673e9SRodney W. Grimes struct stat stbuf; 809dea673e9SRodney W. Grimes register int fd, i; 810dea673e9SRodney W. Grimes register struct dirent *dp; 811dea673e9SRodney W. Grimes DIR *dirp; 812dea673e9SRodney W. Grimes 813dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 814dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 815dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 816dea673e9SRodney W. Grimes LO = DEFLOCK; 817dea673e9SRodney W. Grimes if (cgetstr(bp, "st", &ST) == -1) 818dea673e9SRodney W. Grimes ST = DEFSTAT; 819dea673e9SRodney W. Grimes printf("%s:\n", printer); 8205f87a7b6SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 821dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 822dea673e9SRodney W. Grimes printf("\tqueuing is %s\n", 823dea673e9SRodney W. Grimes (stbuf.st_mode & 010) ? "disabled" : "enabled"); 824dea673e9SRodney W. Grimes printf("\tprinting is %s\n", 825dea673e9SRodney W. Grimes (stbuf.st_mode & 0100) ? "disabled" : "enabled"); 826dea673e9SRodney W. Grimes } else { 827dea673e9SRodney W. Grimes printf("\tqueuing is enabled\n"); 828dea673e9SRodney W. Grimes printf("\tprinting is enabled\n"); 829dea673e9SRodney W. Grimes } 830dea673e9SRodney W. Grimes if ((dirp = opendir(SD)) == NULL) { 831dea673e9SRodney W. Grimes printf("\tcannot examine spool directory\n"); 832dea673e9SRodney W. Grimes return; 833dea673e9SRodney W. Grimes } 834dea673e9SRodney W. Grimes i = 0; 835dea673e9SRodney W. Grimes while ((dp = readdir(dirp)) != NULL) { 836dea673e9SRodney W. Grimes if (*dp->d_name == 'c' && dp->d_name[1] == 'f') 837dea673e9SRodney W. Grimes i++; 838dea673e9SRodney W. Grimes } 839dea673e9SRodney W. Grimes closedir(dirp); 840dea673e9SRodney W. Grimes if (i == 0) 841dea673e9SRodney W. Grimes printf("\tno entries\n"); 842dea673e9SRodney W. Grimes else if (i == 1) 843dea673e9SRodney W. Grimes printf("\t1 entry in spool area\n"); 844dea673e9SRodney W. Grimes else 845dea673e9SRodney W. Grimes printf("\t%d entries in spool area\n", i); 846dea673e9SRodney W. Grimes fd = open(line, O_RDONLY); 847dea673e9SRodney W. Grimes if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { 848dea673e9SRodney W. Grimes (void) close(fd); /* unlocks as well */ 849bc407914SWarner Losh printf("\tprinter idle\n"); 850dea673e9SRodney W. Grimes return; 851dea673e9SRodney W. Grimes } 852dea673e9SRodney W. Grimes (void) close(fd); 85336abea5dSBrian Somers /* print out the contents of the status file, if it exists */ 8545f87a7b6SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, ST); 855dea673e9SRodney W. Grimes fd = open(line, O_RDONLY); 856dea673e9SRodney W. Grimes if (fd >= 0) { 857dea673e9SRodney W. Grimes (void) flock(fd, LOCK_SH); 85836abea5dSBrian Somers (void) fstat(fd, &stbuf); 85936abea5dSBrian Somers if (stbuf.st_size > 0) { 86036abea5dSBrian Somers putchar('\t'); 861dea673e9SRodney W. Grimes while ((i = read(fd, line, sizeof(line))) > 0) 862dea673e9SRodney W. Grimes (void) fwrite(line, 1, i, stdout); 86336abea5dSBrian Somers } 864dea673e9SRodney W. Grimes (void) close(fd); /* unlocks as well */ 865dea673e9SRodney W. Grimes } 866dea673e9SRodney W. Grimes } 867dea673e9SRodney W. Grimes 868dea673e9SRodney W. Grimes /* 869dea673e9SRodney W. Grimes * Stop the specified daemon after completing the current job and disable 870dea673e9SRodney W. Grimes * printing. 871dea673e9SRodney W. Grimes */ 872dea673e9SRodney W. Grimes void 873dea673e9SRodney W. Grimes stop(argc, argv) 874dea673e9SRodney W. Grimes int argc; 875dea673e9SRodney W. Grimes char *argv[]; 876dea673e9SRodney W. Grimes { 877dea673e9SRodney W. Grimes register int c, status; 878dea673e9SRodney W. Grimes register char *cp1, *cp2; 879dea673e9SRodney W. Grimes char prbuf[100]; 880dea673e9SRodney W. Grimes 881dea673e9SRodney W. Grimes if (argc == 1) { 882dea673e9SRodney W. Grimes printf("Usage: stop {all | printer ...}\n"); 883dea673e9SRodney W. Grimes return; 884dea673e9SRodney W. Grimes } 885dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 886dea673e9SRodney W. Grimes printer = prbuf; 887dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 888dea673e9SRodney W. Grimes cp1 = prbuf; 889dea673e9SRodney W. Grimes cp2 = bp; 8905f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 8915f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 892dea673e9SRodney W. Grimes *cp1++ = c; 893dea673e9SRodney W. Grimes *cp1 = '\0'; 894dea673e9SRodney W. Grimes stoppr(); 895dea673e9SRodney W. Grimes } 896dea673e9SRodney W. Grimes return; 897dea673e9SRodney W. Grimes } 898dea673e9SRodney W. Grimes while (--argc) { 899dea673e9SRodney W. Grimes printer = *++argv; 900dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 901dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 902dea673e9SRodney W. Grimes continue; 903dea673e9SRodney W. Grimes } else if (status == -1) { 904dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 905dea673e9SRodney W. Grimes continue; 906dea673e9SRodney W. Grimes } else if (status == -3) 907dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 908dea673e9SRodney W. Grimes 909dea673e9SRodney W. Grimes stoppr(); 910dea673e9SRodney W. Grimes } 911dea673e9SRodney W. Grimes } 912dea673e9SRodney W. Grimes 913dea673e9SRodney W. Grimes static void 914dea673e9SRodney W. Grimes stoppr() 915dea673e9SRodney W. Grimes { 916dea673e9SRodney W. Grimes register int fd; 917dea673e9SRodney W. Grimes struct stat stbuf; 918dea673e9SRodney W. Grimes 919dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 920dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 921dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 922dea673e9SRodney W. Grimes LO = DEFLOCK; 923360d4ad5SWarner Losh (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); 924dea673e9SRodney W. Grimes printf("%s:\n", printer); 925dea673e9SRodney W. Grimes 926dea673e9SRodney W. Grimes /* 927dea673e9SRodney W. Grimes * Turn on the owner execute bit of the lock file to disable printing. 928dea673e9SRodney W. Grimes */ 929360d4ad5SWarner Losh seteuid(euid); 930dea673e9SRodney W. Grimes if (stat(line, &stbuf) >= 0) { 931dea673e9SRodney W. Grimes if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0) 932dea673e9SRodney W. Grimes printf("\tcannot disable printing\n"); 933dea673e9SRodney W. Grimes else { 934dea673e9SRodney W. Grimes upstat("printing disabled\n"); 935dea673e9SRodney W. Grimes printf("\tprinting disabled\n"); 936dea673e9SRodney W. Grimes } 937dea673e9SRodney W. Grimes } else if (errno == ENOENT) { 938dea673e9SRodney W. Grimes if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) 939dea673e9SRodney W. Grimes printf("\tcannot create lock file\n"); 940dea673e9SRodney W. Grimes else { 941dea673e9SRodney W. Grimes (void) close(fd); 942dea673e9SRodney W. Grimes upstat("printing disabled\n"); 943dea673e9SRodney W. Grimes printf("\tprinting disabled\n"); 944dea673e9SRodney W. Grimes } 945dea673e9SRodney W. Grimes } else 946dea673e9SRodney W. Grimes printf("\tcannot stat lock file\n"); 947360d4ad5SWarner Losh seteuid(uid); 948dea673e9SRodney W. Grimes } 949dea673e9SRodney W. Grimes 950dea673e9SRodney W. Grimes struct queue **queue; 951dea673e9SRodney W. Grimes int nitems; 952dea673e9SRodney W. Grimes time_t mtime; 953dea673e9SRodney W. Grimes 954dea673e9SRodney W. Grimes /* 955dea673e9SRodney W. Grimes * Put the specified jobs at the top of printer queue. 956dea673e9SRodney W. Grimes */ 957dea673e9SRodney W. Grimes void 958dea673e9SRodney W. Grimes topq(argc, argv) 959dea673e9SRodney W. Grimes int argc; 960dea673e9SRodney W. Grimes char *argv[]; 961dea673e9SRodney W. Grimes { 962dea673e9SRodney W. Grimes register int i; 963dea673e9SRodney W. Grimes struct stat stbuf; 964dea673e9SRodney W. Grimes int status, changed; 965dea673e9SRodney W. Grimes 966dea673e9SRodney W. Grimes if (argc < 3) { 967dea673e9SRodney W. Grimes printf("Usage: topq printer [jobnum ...] [user ...]\n"); 968dea673e9SRodney W. Grimes return; 969dea673e9SRodney W. Grimes } 970dea673e9SRodney W. Grimes 971dea673e9SRodney W. Grimes --argc; 972dea673e9SRodney W. Grimes printer = *++argv; 973dea673e9SRodney W. Grimes status = cgetent(&bp, printcapdb, printer); 974dea673e9SRodney W. Grimes if (status == -2) { 975dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 976dea673e9SRodney W. Grimes return; 977dea673e9SRodney W. Grimes } else if (status == -1) { 978dea673e9SRodney W. Grimes printf("%s: unknown printer\n", printer); 979dea673e9SRodney W. Grimes return; 980dea673e9SRodney W. Grimes } else if (status == -3) 981dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 982dea673e9SRodney W. Grimes 983dea673e9SRodney W. Grimes if (cgetstr(bp, "sd", &SD) == -1) 984dea673e9SRodney W. Grimes SD = _PATH_DEFSPOOL; 985dea673e9SRodney W. Grimes if (cgetstr(bp, "lo", &LO) == -1) 986dea673e9SRodney W. Grimes LO = DEFLOCK; 987dea673e9SRodney W. Grimes printf("%s:\n", printer); 988dea673e9SRodney W. Grimes 989360d4ad5SWarner Losh seteuid(euid); 990dea673e9SRodney W. Grimes if (chdir(SD) < 0) { 991dea673e9SRodney W. Grimes printf("\tcannot chdir to %s\n", SD); 992360d4ad5SWarner Losh goto out; 993dea673e9SRodney W. Grimes } 994360d4ad5SWarner Losh seteuid(uid); 995dea673e9SRodney W. Grimes nitems = getq(&queue); 996dea673e9SRodney W. Grimes if (nitems == 0) 997dea673e9SRodney W. Grimes return; 998dea673e9SRodney W. Grimes changed = 0; 999dea673e9SRodney W. Grimes mtime = queue[0]->q_time; 1000dea673e9SRodney W. Grimes for (i = argc; --i; ) { 1001dea673e9SRodney W. Grimes if (doarg(argv[i]) == 0) { 1002dea673e9SRodney W. Grimes printf("\tjob %s is not in the queue\n", argv[i]); 1003dea673e9SRodney W. Grimes continue; 1004dea673e9SRodney W. Grimes } else 1005dea673e9SRodney W. Grimes changed++; 1006dea673e9SRodney W. Grimes } 1007dea673e9SRodney W. Grimes for (i = 0; i < nitems; i++) 1008dea673e9SRodney W. Grimes free(queue[i]); 1009dea673e9SRodney W. Grimes free(queue); 1010dea673e9SRodney W. Grimes if (!changed) { 1011dea673e9SRodney W. Grimes printf("\tqueue order unchanged\n"); 1012dea673e9SRodney W. Grimes return; 1013dea673e9SRodney W. Grimes } 1014dea673e9SRodney W. Grimes /* 1015dea673e9SRodney W. Grimes * Turn on the public execute bit of the lock file to 1016dea673e9SRodney W. Grimes * get lpd to rebuild the queue after the current job. 1017dea673e9SRodney W. Grimes */ 1018360d4ad5SWarner Losh seteuid(euid); 1019dea673e9SRodney W. Grimes if (changed && stat(LO, &stbuf) >= 0) 1020dea673e9SRodney W. Grimes (void) chmod(LO, (stbuf.st_mode & 0777) | 01); 1021360d4ad5SWarner Losh 1022360d4ad5SWarner Losh out: 1023360d4ad5SWarner Losh seteuid(uid); 1024dea673e9SRodney W. Grimes } 1025dea673e9SRodney W. Grimes 1026dea673e9SRodney W. Grimes /* 1027dea673e9SRodney W. Grimes * Reposition the job by changing the modification time of 1028dea673e9SRodney W. Grimes * the control file. 1029dea673e9SRodney W. Grimes */ 1030dea673e9SRodney W. Grimes static int 1031dea673e9SRodney W. Grimes touch(q) 1032dea673e9SRodney W. Grimes struct queue *q; 1033dea673e9SRodney W. Grimes { 1034dea673e9SRodney W. Grimes struct timeval tvp[2]; 1035360d4ad5SWarner Losh int ret; 1036dea673e9SRodney W. Grimes 1037dea673e9SRodney W. Grimes tvp[0].tv_sec = tvp[1].tv_sec = --mtime; 1038dea673e9SRodney W. Grimes tvp[0].tv_usec = tvp[1].tv_usec = 0; 1039360d4ad5SWarner Losh seteuid(euid); 1040360d4ad5SWarner Losh ret = utimes(q->q_name, tvp); 1041360d4ad5SWarner Losh seteuid(uid); 1042360d4ad5SWarner Losh return (ret); 1043dea673e9SRodney W. Grimes } 1044dea673e9SRodney W. Grimes 1045dea673e9SRodney W. Grimes /* 1046dea673e9SRodney W. Grimes * Checks if specified job name is in the printer's queue. 1047dea673e9SRodney W. Grimes * Returns: negative (-1) if argument name is not in the queue. 1048dea673e9SRodney W. Grimes */ 1049dea673e9SRodney W. Grimes static int 1050dea673e9SRodney W. Grimes doarg(job) 1051dea673e9SRodney W. Grimes char *job; 1052dea673e9SRodney W. Grimes { 1053dea673e9SRodney W. Grimes register struct queue **qq; 1054dea673e9SRodney W. Grimes register int jobnum, n; 1055dea673e9SRodney W. Grimes register char *cp, *machine; 1056dea673e9SRodney W. Grimes int cnt = 0; 1057dea673e9SRodney W. Grimes FILE *fp; 1058dea673e9SRodney W. Grimes 1059dea673e9SRodney W. Grimes /* 1060dea673e9SRodney W. Grimes * Look for a job item consisting of system name, colon, number 1061dea673e9SRodney W. Grimes * (example: ucbarpa:114) 1062dea673e9SRodney W. Grimes */ 1063f8eb25daSWarner Losh if ((cp = strchr(job, ':')) != NULL) { 1064dea673e9SRodney W. Grimes machine = job; 1065dea673e9SRodney W. Grimes *cp++ = '\0'; 1066dea673e9SRodney W. Grimes job = cp; 1067dea673e9SRodney W. Grimes } else 1068dea673e9SRodney W. Grimes machine = NULL; 1069dea673e9SRodney W. Grimes 1070dea673e9SRodney W. Grimes /* 1071dea673e9SRodney W. Grimes * Check for job specified by number (example: 112 or 235ucbarpa). 1072dea673e9SRodney W. Grimes */ 1073dea673e9SRodney W. Grimes if (isdigit(*job)) { 1074dea673e9SRodney W. Grimes jobnum = 0; 1075dea673e9SRodney W. Grimes do 1076dea673e9SRodney W. Grimes jobnum = jobnum * 10 + (*job++ - '0'); 1077dea673e9SRodney W. Grimes while (isdigit(*job)); 1078dea673e9SRodney W. Grimes for (qq = queue + nitems; --qq >= queue; ) { 1079dea673e9SRodney W. Grimes n = 0; 1080dea673e9SRodney W. Grimes for (cp = (*qq)->q_name+3; isdigit(*cp); ) 1081dea673e9SRodney W. Grimes n = n * 10 + (*cp++ - '0'); 1082dea673e9SRodney W. Grimes if (jobnum != n) 1083dea673e9SRodney W. Grimes continue; 1084dea673e9SRodney W. Grimes if (*job && strcmp(job, cp) != 0) 1085dea673e9SRodney W. Grimes continue; 1086dea673e9SRodney W. Grimes if (machine != NULL && strcmp(machine, cp) != 0) 1087dea673e9SRodney W. Grimes continue; 1088dea673e9SRodney W. Grimes if (touch(*qq) == 0) { 1089dea673e9SRodney W. Grimes printf("\tmoved %s\n", (*qq)->q_name); 1090dea673e9SRodney W. Grimes cnt++; 1091dea673e9SRodney W. Grimes } 1092dea673e9SRodney W. Grimes } 1093dea673e9SRodney W. Grimes return(cnt); 1094dea673e9SRodney W. Grimes } 1095dea673e9SRodney W. Grimes /* 1096dea673e9SRodney W. Grimes * Process item consisting of owner's name (example: henry). 1097dea673e9SRodney W. Grimes */ 1098dea673e9SRodney W. Grimes for (qq = queue + nitems; --qq >= queue; ) { 1099360d4ad5SWarner Losh seteuid(euid); 1100360d4ad5SWarner Losh fp = fopen((*qq)->q_name, "r"); 1101360d4ad5SWarner Losh seteuid(uid); 1102360d4ad5SWarner Losh if (fp == NULL) 1103dea673e9SRodney W. Grimes continue; 1104dea673e9SRodney W. Grimes while (getline(fp) > 0) 1105dea673e9SRodney W. Grimes if (line[0] == 'P') 1106dea673e9SRodney W. Grimes break; 1107dea673e9SRodney W. Grimes (void) fclose(fp); 1108dea673e9SRodney W. Grimes if (line[0] != 'P' || strcmp(job, line+1) != 0) 1109dea673e9SRodney W. Grimes continue; 1110dea673e9SRodney W. Grimes if (touch(*qq) == 0) { 1111dea673e9SRodney W. Grimes printf("\tmoved %s\n", (*qq)->q_name); 1112dea673e9SRodney W. Grimes cnt++; 1113dea673e9SRodney W. Grimes } 1114dea673e9SRodney W. Grimes } 1115dea673e9SRodney W. Grimes return(cnt); 1116dea673e9SRodney W. Grimes } 1117dea673e9SRodney W. Grimes 1118dea673e9SRodney W. Grimes /* 1119dea673e9SRodney W. Grimes * Enable everything and start printer (undo `down'). 1120dea673e9SRodney W. Grimes */ 1121dea673e9SRodney W. Grimes void 1122dea673e9SRodney W. Grimes up(argc, argv) 1123dea673e9SRodney W. Grimes int argc; 1124dea673e9SRodney W. Grimes char *argv[]; 1125dea673e9SRodney W. Grimes { 1126dea673e9SRodney W. Grimes register int c, status; 1127dea673e9SRodney W. Grimes register char *cp1, *cp2; 1128dea673e9SRodney W. Grimes char prbuf[100]; 1129dea673e9SRodney W. Grimes 1130dea673e9SRodney W. Grimes if (argc == 1) { 1131dea673e9SRodney W. Grimes printf("Usage: up {all | printer ...}\n"); 1132dea673e9SRodney W. Grimes return; 1133dea673e9SRodney W. Grimes } 1134dea673e9SRodney W. Grimes if (argc == 2 && !strcmp(argv[1], "all")) { 1135dea673e9SRodney W. Grimes printer = prbuf; 1136dea673e9SRodney W. Grimes while (cgetnext(&bp, printcapdb) > 0) { 1137dea673e9SRodney W. Grimes cp1 = prbuf; 1138dea673e9SRodney W. Grimes cp2 = bp; 11395f87a7b6SWarner Losh while ((c = *cp2++) && c != '|' && c != ':' && 11405f87a7b6SWarner Losh (cp1 - prbuf) < sizeof(prbuf)) 1141dea673e9SRodney W. Grimes *cp1++ = c; 1142dea673e9SRodney W. Grimes *cp1 = '\0'; 1143dea673e9SRodney W. Grimes startpr(2); 1144dea673e9SRodney W. Grimes } 1145dea673e9SRodney W. Grimes return; 1146dea673e9SRodney W. Grimes } 1147dea673e9SRodney W. Grimes while (--argc) { 1148dea673e9SRodney W. Grimes printer = *++argv; 1149dea673e9SRodney W. Grimes if ((status = cgetent(&bp, printcapdb, printer)) == -2) { 1150dea673e9SRodney W. Grimes printf("cannot open printer description file\n"); 1151dea673e9SRodney W. Grimes continue; 1152dea673e9SRodney W. Grimes } else if (status == -1) { 1153dea673e9SRodney W. Grimes printf("unknown printer %s\n", printer); 1154dea673e9SRodney W. Grimes continue; 1155dea673e9SRodney W. Grimes } else if (status == -3) 1156dea673e9SRodney W. Grimes fatal("potential reference loop detected in printcap file"); 1157dea673e9SRodney W. Grimes 1158dea673e9SRodney W. Grimes startpr(2); 1159dea673e9SRodney W. Grimes } 1160dea673e9SRodney W. Grimes } 1161