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

Defined functions

chk defined in line 170; used 2 times
chkremote defined in line 241; used 1 times
  • in line 94
iscf defined in line 286; used 2 times
isowner defined in line 224; used 3 times
lockchk defined in line 108; used 1 times
  • in line 83
process defined in line 143; used 1 times
  • in line 92
rmjob defined in line 33; used 2 times

Defined variables

all defined in line 27; used 4 times
cur_daemon defined in line 28; used 3 times
current defined in line 29; used 5 times
root defined in line 26; used 2 times
sccsid defined in line 8; never used
Last modified: 1987-02-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3906
Valid CSS Valid XHTML 1.0 Strict