home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / lpr / common_source / rmjob.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-08  |  8.2 KB  |  324 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[] = "from: @(#)rmjob.c    5.7 (Berkeley) 6/1/90";*/
  36. static char rcsid[] = "$Id: rmjob.c,v 1.1 1994/05/23 09:04:58 rzsfl Exp rzsfl $";
  37. #endif /* not lint */
  38.  
  39. /*
  40.  * rmjob - remove the specified jobs from the queue.
  41.  */
  42.  
  43. #include "lp.h"
  44. #include "pathnames.h"
  45.  
  46. /*
  47.  * Stuff for handling lprm specifications
  48.  */
  49. extern char    *user[];        /* users to process */
  50. extern int    users;            /* # of users in user array */
  51. extern int    requ[];            /* job number of spool entries */
  52. extern int    requests;        /* # of spool requests */
  53. extern char    *person;        /* name of person doing lprm */
  54.  
  55. char    root[] = "root";
  56. int    all = 0;        /* eliminate all files (root only) */
  57. int    cur_daemon;        /* daemon's pid */
  58. char    current[40];        /* active control file name */
  59.  
  60. int    iscf();
  61.  
  62. rmjob()
  63. {
  64.     register int i, nitems;
  65.     int assasinated = 0;
  66.     struct direct **files;
  67.     char *cp;
  68.  
  69.     if ((i = pgetent(line, printer)) < 0)
  70.         fatal("cannot open printer description file");
  71.     else if (i == 0)
  72.         fatal("unknown printer");
  73.     if ((SD = pgetstr("sd", &bp)) == NULL)
  74.         SD = _PATH_DEFSPOOL;
  75.     if ((LO = pgetstr("lo", &bp)) == NULL)
  76.         LO = DEFLOCK;
  77.     if ((LP = pgetstr("lp", &bp)) == NULL)
  78.         LP = _PATH_DEFDEVLP;
  79.     if ((RP = pgetstr("rp", &bp)) == NULL)
  80.         RP = DEFLP;
  81.     RM = pgetstr("rm", &bp);
  82.     if (cp = checkremote())
  83.         printf("Warning: %s\n", cp);
  84.  
  85.     /*
  86.      * If the format was `lprm -' and the user isn't the super-user,
  87.      *  then fake things to look like he said `lprm user'.
  88.      */
  89.     if (users < 0) {
  90.         if (getuid() == 0)
  91.             all = 1;    /* all files in local queue */
  92.         else {
  93.             user[0] = person;
  94.             users = 1;
  95.         }
  96.     }
  97.     if (!strcmp(person, "-all")) {
  98.         if (from == host)
  99.             fatal("The login name \"-all\" is reserved");
  100.         all = 1;    /* all those from 'from' */
  101.         person = root;
  102.     }
  103.  
  104.     if (chdir(SD) < 0)
  105.         fatal("cannot chdir to spool directory");
  106.     if ((nitems = scandir(".", &files, iscf, NULL)) < 0)
  107.         fatal("cannot access spool directory");
  108.  
  109.     if (nitems) {
  110.         /*
  111.          * Check for an active printer daemon (in which case we
  112.          *  kill it if it is reading our file) then remove stuff
  113.          *  (after which we have to restart the daemon).
  114.          */
  115.         if (lockchk(LO) && chk(current)) {
  116.             assasinated = kill(cur_daemon, SIGINT) == 0;
  117.             if (!assasinated)
  118.                 fatal("cannot kill printer daemon");
  119.         }
  120.         /*
  121.          * process the files
  122.          */
  123.         for (i = 0; i < nitems; i++)
  124.             process(files[i]->d_name);
  125.     }
  126.     rmremote();
  127.     /*
  128.      * Restart the printer daemon if it was killed
  129.      */
  130.     if (assasinated && !startdaemon(printer))
  131.         fatal("cannot restart printer daemon\n");
  132.     exit(0);
  133. }
  134.  
  135. /*
  136.  * Process a lock file: collect the pid of the active
  137.  *  daemon and the file name of the active spool entry.
  138.  * Return boolean indicating existence of a lock file.
  139.  */
  140. lockchk(s)
  141.     char *s;
  142. {
  143.     register FILE *fp;
  144.     register int i, n;
  145.  
  146.     if ((fp = fopen(s, "r")) == NULL)
  147.         if (errno == EACCES)
  148.             fatal("can't access lock file");
  149.         else
  150.             return(0);
  151.     if (!getline(fp)) {
  152.         (void) fclose(fp);
  153.         return(0);        /* no daemon present */
  154.     }
  155.     cur_daemon = atoi(line);
  156.     if (kill(cur_daemon, 0) < 0) {
  157.         (void) fclose(fp);
  158.         return(0);        /* no daemon present */
  159.     }
  160.     for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) {
  161.         if (i > 5) {
  162.             n = 1;
  163.             break;
  164.         }
  165.         sleep(i);
  166.     }
  167.     current[n-1] = '\0';
  168.     (void) fclose(fp);
  169.     return(1);
  170. }
  171.  
  172. /*
  173.  * Process a control file.
  174.  */
  175. process(file)
  176.     char *file;
  177. {
  178.     FILE *cfp;
  179.  
  180.     if (!chk(file))
  181.         return;
  182.     if ((cfp = fopen(file, "r")) == NULL)
  183.         fatal("cannot open %s", file);
  184.     while (getline(cfp)) {
  185.         switch (line[0]) {
  186.         case 'U':  /* unlink associated files */
  187.             if (from != host)
  188.                 printf("%s: ", host);
  189.             printf(unlink(line+1) ? "cannot dequeue %s\n" :
  190.                 "%s dequeued\n", line+1);
  191.         }
  192.     }
  193.     (void) fclose(cfp);
  194.     if (from != host)
  195.         printf("%s: ", host);
  196.     printf(unlink(file) ? "cannot dequeue %s\n" : "%s dequeued\n", file);
  197. }
  198.  
  199. /*
  200.  * Do the dirty work in checking
  201.  */
  202. chk(file)
  203.     char *file;
  204. {
  205.     register int *r, n;
  206.     char **u, *cp, p[64], h[64];
  207.     FILE *cfp;
  208.  
  209.     /*
  210.      * Check for valid cf file name (mostly checking current).
  211.      */
  212.     if (strlen(file) < 7 || file[0] != 'c' || file[1] != 'f')
  213.         return(0);
  214.  
  215.     /*
  216.      * get the owner's name from the control file.
  217.      */
  218.     p[0] = h[0] = '\0';
  219.     if ((cfp = fopen(file, "r")) == NULL)
  220.         return(0);
  221.     while (getline(cfp)) {
  222.         if (line[0] == 'P')
  223.             strcpy(p, line+1);
  224.         else if (line[0] == 'H')
  225.             strcpy(h, line+1);
  226.     }
  227.     (void) fclose(cfp);
  228.  
  229.     if (all && (from == host || !strcmp(from, h)))
  230.         return(1);
  231.  
  232.     if (users == 0 && requests == 0)
  233.         return(!strcmp(file, current) && isowner(p, file, h));
  234.     /*
  235.      * Check the request list
  236.      */
  237.     for (n = 0, cp = file+3; isdigit(*cp); )
  238.         n = n * 10 + (*cp++ - '0');
  239.     for (r = requ; r < &requ[requests]; r++)
  240.         if (*r == n && isowner(p, file, h))
  241.             return(1);
  242.     /*
  243.      * Check to see if it's in the user list
  244.      */
  245.     for (u = user; u < &user[users]; u++)
  246.         if (!strcmp(*u, p) && isowner(p, file, h))
  247.             return(1);
  248.     return(0);
  249. }
  250.  
  251. /*
  252.  * If root is removing a file on the local machine, allow it.
  253.  * If root is removing a file from a remote machine, only allow
  254.  * files sent from the remote machine to be removed.
  255.  * Normal users can only remove the file from where it was sent.
  256.  */
  257. isowner(owner, file, h)
  258.     char *owner, *file, *h;
  259. {
  260.     if (!strcmp(person, root) && (from == host || !strcmp(from, h)))
  261.         return(1);
  262.     if (!strcmp(person, owner) && !strcmp(from, h))
  263.         return(1);
  264.     if (from != host)
  265.         printf("%s: ", host);
  266.     printf("%s: Permission denied\n", file);
  267.     return(0);
  268. }
  269.  
  270. /*
  271.  * Check to see if we are sending files to a remote machine. If we are,
  272.  * then try removing files on the remote machine.
  273.  */
  274. rmremote()
  275. {
  276.     register char *cp;
  277.     register int i, rem;
  278.     char buf[BUFSIZ];
  279.  
  280.     if (!sendtorem)
  281.         return;    /* not sending to a remote machine */
  282.  
  283.     /*
  284.      * Flush stdout so the user can see what has been deleted
  285.      * while we wait (possibly) for the connection.
  286.      */
  287.     fflush(stdout);
  288.  
  289.     sprintf(buf, "\5%s %s", RP, all ? "-all" : person);
  290.     cp = buf;
  291.     for (i = 0; i < users; i++) {
  292.         cp += strlen(cp);
  293.         *cp++ = ' ';
  294.         strcpy(cp, user[i]);
  295.     }
  296.     for (i = 0; i < requests; i++) {
  297.         cp += strlen(cp);
  298.         (void) sprintf(cp, " %d", requ[i]);
  299.     }
  300.     strcat(cp, "\n");
  301.     rem = getport(RM);
  302.     if (rem < 0) {
  303.         if (from != host)
  304.             printf("%s: ", host);
  305.         printf("connection to %s is down\n", RM);
  306.     } else {
  307.         i = strlen(buf);
  308.         if (write(rem, buf, i) != i)
  309.             fatal("Lost connection");
  310.         while ((i = read(rem, buf, sizeof(buf))) > 0)
  311.             (void) fwrite(buf, 1, i, stdout);
  312.         (void) close(rem);
  313.     }
  314. }
  315.  
  316. /*
  317.  * Return 1 if the filename begins with 'cf'
  318.  */
  319. iscf(d)
  320.     struct dirent *d;
  321. {
  322.     return(d->d_name[0] == 'c' && d->d_name[1] == 'f');
  323. }
  324.