home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / daemons / lprm_fix.z / lprm_fix / lpr / common_source / rmjob.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-06  |  8.0 KB  |  322 lines

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