|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)rmjob.c 5.3 (Berkeley) 6/30/88"; ! 20: #endif /* not lint */ ! 21: ! 22: /* ! 23: * rmjob - remove the specified jobs from the queue. ! 24: */ ! 25: ! 26: #include "lp.h" ! 27: ! 28: /* ! 29: * Stuff for handling lprm specifications ! 30: */ ! 31: extern char *user[]; /* users to process */ ! 32: extern int users; /* # of users in user array */ ! 33: extern int requ[]; /* job number of spool entries */ ! 34: extern int requests; /* # of spool requests */ ! 35: extern char *person; /* name of person doing lprm */ ! 36: ! 37: char root[] = "root"; ! 38: int all = 0; /* eliminate all files (root only) */ ! 39: int cur_daemon; /* daemon's pid */ ! 40: char current[40]; /* active control file name */ ! 41: ! 42: int iscf(); ! 43: ! 44: rmjob() ! 45: { ! 46: register int i, nitems; ! 47: int assasinated = 0; ! 48: struct direct **files; ! 49: ! 50: if ((i = pgetent(line, printer)) < 0) ! 51: fatal("cannot open printer description file"); ! 52: else if (i == 0) ! 53: fatal("unknown printer"); ! 54: if ((SD = pgetstr("sd", &bp)) == NULL) ! 55: SD = DEFSPOOL; ! 56: if ((LO = pgetstr("lo", &bp)) == NULL) ! 57: LO = DEFLOCK; ! 58: if ((LP = pgetstr("lp", &bp)) == NULL) ! 59: LP = DEFDEVLP; ! 60: if ((RP = pgetstr("rp", &bp)) == NULL) ! 61: RP = DEFLP; ! 62: RM = pgetstr("rm", &bp); ! 63: ! 64: /* ! 65: * If the format was `lprm -' and the user isn't the super-user, ! 66: * then fake things to look like he said `lprm user'. ! 67: */ ! 68: if (users < 0) { ! 69: if (getuid() == 0) ! 70: all = 1; /* all files in local queue */ ! 71: else { ! 72: user[0] = person; ! 73: users = 1; ! 74: } ! 75: } ! 76: if (!strcmp(person, "-all")) { ! 77: if (from == host) ! 78: fatal("The login name \"-all\" is reserved"); ! 79: all = 1; /* all those from 'from' */ ! 80: person = root; ! 81: } ! 82: ! 83: if (chdir(SD) < 0) ! 84: fatal("cannot chdir to spool directory"); ! 85: if ((nitems = scandir(".", &files, iscf, NULL)) < 0) ! 86: fatal("cannot access spool directory"); ! 87: ! 88: if (nitems) { ! 89: /* ! 90: * Check for an active printer daemon (in which case we ! 91: * kill it if it is reading our file) then remove stuff ! 92: * (after which we have to restart the daemon). ! 93: */ ! 94: if (lockchk(LO) && chk(current)) { ! 95: assasinated = kill(cur_daemon, SIGINT) == 0; ! 96: if (!assasinated) ! 97: fatal("cannot kill printer daemon"); ! 98: } ! 99: /* ! 100: * process the files ! 101: */ ! 102: for (i = 0; i < nitems; i++) ! 103: process(files[i]->d_name); ! 104: } ! 105: chkremote(); ! 106: /* ! 107: * Restart the printer daemon if it was killed ! 108: */ ! 109: if (assasinated && !startdaemon(printer)) ! 110: fatal("cannot restart printer daemon\n"); ! 111: exit(0); ! 112: } ! 113: ! 114: /* ! 115: * Process a lock file: collect the pid of the active ! 116: * daemon and the file name of the active spool entry. ! 117: * Return boolean indicating existence of a lock file. ! 118: */ ! 119: lockchk(s) ! 120: char *s; ! 121: { ! 122: register FILE *fp; ! 123: register int i, n; ! 124: ! 125: if ((fp = fopen(s, "r")) == NULL) ! 126: if (errno == EACCES) ! 127: fatal("can't access lock file"); ! 128: else ! 129: return(0); ! 130: if (!getline(fp)) { ! 131: (void) fclose(fp); ! 132: return(0); /* no daemon present */ ! 133: } ! 134: cur_daemon = atoi(line); ! 135: if (kill(cur_daemon, 0) < 0) { ! 136: (void) fclose(fp); ! 137: return(0); /* no daemon present */ ! 138: } ! 139: for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) { ! 140: if (i > 5) { ! 141: n = 1; ! 142: break; ! 143: } ! 144: sleep(i); ! 145: } ! 146: current[n-1] = '\0'; ! 147: (void) fclose(fp); ! 148: return(1); ! 149: } ! 150: ! 151: /* ! 152: * Process a control file. ! 153: */ ! 154: process(file) ! 155: char *file; ! 156: { ! 157: FILE *cfp; ! 158: ! 159: if (!chk(file)) ! 160: return; ! 161: if ((cfp = fopen(file, "r")) == NULL) ! 162: fatal("cannot open %s", file); ! 163: while (getline(cfp)) { ! 164: switch (line[0]) { ! 165: case 'U': /* unlink associated files */ ! 166: if (from != host) ! 167: printf("%s: ", host); ! 168: printf(unlink(line+1) ? "cannot dequeue %s\n" : ! 169: "%s dequeued\n", line+1); ! 170: } ! 171: } ! 172: (void) fclose(cfp); ! 173: if (from != host) ! 174: printf("%s: ", host); ! 175: printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file); ! 176: } ! 177: ! 178: /* ! 179: * Do the dirty work in checking ! 180: */ ! 181: chk(file) ! 182: char *file; ! 183: { ! 184: register int *r, n; ! 185: register char **u, *cp; ! 186: FILE *cfp; ! 187: ! 188: /* ! 189: * Check for valid cf file name (mostly checking current). ! 190: */ ! 191: if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f') ! 192: return(0); ! 193: ! 194: if (all && (from == host || !strcmp(from, file+6))) ! 195: return(1); ! 196: ! 197: /* ! 198: * get the owner's name from the control file. ! 199: */ ! 200: if ((cfp = fopen(file, "r")) == NULL) ! 201: return(0); ! 202: while (getline(cfp)) { ! 203: if (line[0] == 'P') ! 204: break; ! 205: } ! 206: (void) fclose(cfp); ! 207: if (line[0] != 'P') ! 208: return(0); ! 209: ! 210: if (users == 0 && requests == 0) ! 211: return(!strcmp(file, current) && isowner(line+1, file)); ! 212: /* ! 213: * Check the request list ! 214: */ ! 215: for (n = 0, cp = file+3; isdigit(*cp); ) ! 216: n = n * 10 + (*cp++ - '0'); ! 217: for (r = requ; r < &requ[requests]; r++) ! 218: if (*r == n && isowner(line+1, file)) ! 219: return(1); ! 220: /* ! 221: * Check to see if it's in the user list ! 222: */ ! 223: for (u = user; u < &user[users]; u++) ! 224: if (!strcmp(*u, line+1) && isowner(line+1, file)) ! 225: return(1); ! 226: return(0); ! 227: } ! 228: ! 229: /* ! 230: * If root is removing a file on the local machine, allow it. ! 231: * If root is removing a file from a remote machine, only allow ! 232: * files sent from the remote machine to be removed. ! 233: * Normal users can only remove the file from where it was sent. ! 234: */ ! 235: isowner(owner, file) ! 236: char *owner, *file; ! 237: { ! 238: if (!strcmp(person, root) && (from == host || !strcmp(from, file+6))) ! 239: return(1); ! 240: if (!strcmp(person, owner) && !strcmp(from, file+6)) ! 241: return(1); ! 242: if (from != host) ! 243: printf("%s: ", host); ! 244: printf("%s: Permission denied\n", file); ! 245: return(0); ! 246: } ! 247: ! 248: /* ! 249: * Check to see if we are sending files to a remote machine. If we are, ! 250: * then try removing files on the remote machine. ! 251: */ ! 252: chkremote() ! 253: { ! 254: register char *cp; ! 255: register int i, rem; ! 256: char buf[BUFSIZ]; ! 257: ! 258: if (*LP || RM == NULL) ! 259: return; /* not sending to a remote machine */ ! 260: ! 261: /* ! 262: * Flush stdout so the user can see what has been deleted ! 263: * while we wait (possibly) for the connection. ! 264: */ ! 265: fflush(stdout); ! 266: ! 267: sprintf(buf, "\5%s %s", RP, all ? "-all" : person); ! 268: cp = buf; ! 269: for (i = 0; i < users; i++) { ! 270: cp += strlen(cp); ! 271: *cp++ = ' '; ! 272: strcpy(cp, user[i]); ! 273: } ! 274: for (i = 0; i < requests; i++) { ! 275: cp += strlen(cp); ! 276: (void) sprintf(cp, " %d", requ[i]); ! 277: } ! 278: strcat(cp, "\n"); ! 279: rem = getport(RM); ! 280: if (rem < 0) { ! 281: if (from != host) ! 282: printf("%s: ", host); ! 283: printf("connection to %s is down\n", RM); ! 284: } else { ! 285: i = strlen(buf); ! 286: if (write(rem, buf, i) != i) ! 287: fatal("Lost connection"); ! 288: while ((i = read(rem, buf, sizeof(buf))) > 0) ! 289: (void) fwrite(buf, 1, i, stdout); ! 290: (void) close(rem); ! 291: } ! 292: } ! 293: ! 294: /* ! 295: * Return 1 if the filename begins with 'cf' ! 296: */ ! 297: iscf(d) ! 298: struct direct *d; ! 299: { ! 300: return(d->d_name[0] == 'c' && d->d_name[1] == 'f'); ! 301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.