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 / lpc / cmds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-23  |  21.5 KB  |  1,018 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: @(#)cmds.c    5.7 (Berkeley) 6/1/90";*/
  36. static char rcsid[] = "$Id: cmds.c,v 1.1 1994/05/23 09:04:59 rzsfl Exp rzsfl $";
  37. #endif /* not lint */
  38.  
  39. /*
  40.  * lpc -- line printer control program -- commands:
  41.  */
  42.  
  43. #include "lp.h"
  44. #include <sys/time.h>
  45. #include "pathnames.h"
  46.  
  47. /*
  48.  * kill an existing daemon and disable printing.
  49.  */
  50. xabort(argc, argv)
  51.     char *argv[];
  52. {
  53.     register int c, status;
  54.     register char *cp1, *cp2;
  55.     char prbuf[100];
  56.  
  57.     if (argc == 1) {
  58.         printf("Usage: abort {all | printer ...}\n");
  59.         return;
  60.     }
  61.     if (argc == 2 && !strcmp(argv[1], "all")) {
  62.         printer = prbuf;
  63.         while (getprent(line) > 0) {
  64.             cp1 = prbuf;
  65.             cp2 = line;
  66.             while ((c = *cp2++) && c != '|' && c != ':')
  67.                 *cp1++ = c;
  68.             *cp1 = '\0';
  69.             abortpr(1);
  70.         }
  71.         return;
  72.     }
  73.     while (--argc) {
  74.         printer = *++argv;
  75.         if ((status = pgetent(line, printer)) < 0) {
  76.             printf("cannot open printer description file\n");
  77.             continue;
  78.         } else if (status == 0) {
  79.             printf("unknown printer %s\n", printer);
  80.             continue;
  81.         }
  82.         abortpr(1);
  83.     }
  84. }
  85.  
  86. abortpr(dis)
  87. {
  88.     register FILE *fp;
  89.     struct stat stbuf;
  90.     int pid, fd;
  91.  
  92.     bp = pbuf;
  93.     if ((SD = pgetstr("sd", &bp)) == NULL)
  94.         SD = _PATH_DEFSPOOL;
  95.     if ((LO = pgetstr("lo", &bp)) == NULL)
  96.         LO = DEFLOCK;
  97.     (void) sprintf(line, "%s/%s", SD, LO);
  98.     printf("%s:\n", printer);
  99.  
  100.     /*
  101.      * Turn on the owner execute bit of the lock file to disable printing.
  102.      */
  103.     if (dis) {
  104.         if (stat(line, &stbuf) >= 0) {
  105.             if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
  106.                 printf("\tcannot disable printing\n");
  107.             else {
  108.                 upstat("printing disabled\n");
  109.                 printf("\tprinting disabled\n");
  110.             }
  111.         } else if (errno == ENOENT) {
  112.             if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
  113.                 printf("\tcannot create lock file\n");
  114.             else {
  115.                 (void) close(fd);
  116.                 upstat("printing disabled\n");
  117.                 printf("\tprinting disabled\n");
  118.                 printf("\tno daemon to abort\n");
  119.             }
  120.             return;
  121.         } else {
  122.             printf("\tcannot stat lock file\n");
  123.             return;
  124.         }
  125.     }
  126.     /*
  127.      * Kill the current daemon to stop printing now.
  128.      */
  129.     if ((fp = fopen(line, "r")) == NULL) {
  130.         printf("\tcannot open lock file\n");
  131.         return;
  132.     }
  133.     if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
  134.         (void) fclose(fp);    /* unlocks as well */
  135.         printf("\tno daemon to abort\n");
  136.         return;
  137.     }
  138.     (void) fclose(fp);
  139.     if (kill(pid = atoi(line), SIGTERM) < 0)
  140.         printf("\tWarning: daemon (pid %d) not killed\n", pid);
  141.     else
  142.         printf("\tdaemon (pid %d) killed\n", pid);
  143. }
  144.  
  145. /*
  146.  * Write a message into the status file.
  147.  */
  148. upstat(msg)
  149.     char *msg;
  150. {
  151.     register int fd;
  152.     char statfile[BUFSIZ];
  153.  
  154.     bp = pbuf;
  155.     if ((ST = pgetstr("st", &bp)) == NULL)
  156.         ST = DEFSTAT;
  157.     (void) sprintf(statfile, "%s/%s", SD, ST);
  158.     umask(0);
  159.     fd = open(statfile, O_WRONLY|O_CREAT, 0664);
  160.     if (fd < 0 || flock(fd, LOCK_EX) < 0) {
  161.         printf("\tcannot create status file\n");
  162.         return;
  163.     }
  164.     (void) ftruncate(fd, 0);
  165.     if (msg == (char *)NULL)
  166.         (void) write(fd, "\n", 1);
  167.     else
  168.         (void) write(fd, msg, strlen(msg));
  169.     (void) close(fd);
  170. }
  171.  
  172. /*
  173.  * Remove all spool files and temporaries from the spooling area.
  174.  */
  175. clean(argc, argv)
  176.     char *argv[];
  177. {
  178.     register int c, status;
  179.     register char *cp1, *cp2;
  180.     char prbuf[100];
  181.  
  182.     if (argc == 1) {
  183.         printf("Usage: clean {all | printer ...}\n");
  184.         return;
  185.     }
  186.     if (argc == 2 && !strcmp(argv[1], "all")) {
  187.         printer = prbuf;
  188.         while (getprent(line) > 0) {
  189.             cp1 = prbuf;
  190.             cp2 = line;
  191.             while ((c = *cp2++) && c != '|' && c != ':')
  192.                 *cp1++ = c;
  193.             *cp1 = '\0';
  194.             cleanpr();
  195.         }
  196.         return;
  197.     }
  198.     while (--argc) {
  199.         printer = *++argv;
  200.         if ((status = pgetent(line, printer)) < 0) {
  201.             printf("cannot open printer description file\n");
  202.             continue;
  203.         } else if (status == 0) {
  204.             printf("unknown printer %s\n", printer);
  205.             continue;
  206.         }
  207.         cleanpr();
  208.     }
  209. }
  210.  
  211. xselect(d)
  212. struct direct *d;
  213. {
  214.     int c = d->d_name[0];
  215.  
  216.     if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
  217.         return(1);
  218.     return(0);
  219. }
  220.  
  221. /*
  222.  * Comparison routine for scandir. Sort by job number and machine, then
  223.  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
  224.  */
  225. sortq(d1, d2)
  226. struct direct **d1, **d2;
  227. {
  228.     int c1, c2;
  229.  
  230.     if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
  231.         return(c1);
  232.     c1 = (*d1)->d_name[0];
  233.     c2 = (*d2)->d_name[0];
  234.     if (c1 == c2)
  235.         return((*d1)->d_name[2] - (*d2)->d_name[2]);
  236.     if (c1 == 'c')
  237.         return(-1);
  238.     if (c1 == 'd' || c2 == 'c')
  239.         return(1);
  240.     return(-1);
  241. }
  242.  
  243. /*
  244.  * Remove incomplete jobs from spooling area.
  245.  */
  246. cleanpr()
  247. {
  248.     register int i, n;
  249.     register char *cp, *cp1, *lp;
  250.     struct direct **queue;
  251.     int nitems;
  252.  
  253.     bp = pbuf;
  254.     if ((SD = pgetstr("sd", &bp)) == NULL)
  255.         SD = _PATH_DEFSPOOL;
  256.     printf("%s:\n", printer);
  257.  
  258.     for (lp = line, cp = SD; *lp++ = *cp++; )
  259.         ;
  260.     lp[-1] = '/';
  261.  
  262.     nitems = scandir(SD, &queue, xselect, sortq);
  263.     if (nitems < 0) {
  264.         printf("\tcannot examine spool directory\n");
  265.         return;
  266.     }
  267.     if (nitems == 0)
  268.         return;
  269.     i = 0;
  270.     do {
  271.         cp = queue[i]->d_name;
  272.         if (*cp == 'c') {
  273.             n = 0;
  274.             while (i + 1 < nitems) {
  275.                 cp1 = queue[i + 1]->d_name;
  276.                 if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
  277.                     break;
  278.                 i++;
  279.                 n++;
  280.             }
  281.             if (n == 0) {
  282.                 strcpy(lp, cp);
  283.                 unlinkf(line);
  284.             }
  285.         } else {
  286.             /*
  287.              * Must be a df with no cf (otherwise, it would have
  288.              * been skipped above) or a tf file (which can always
  289.              * be removed).
  290.              */
  291.             strcpy(lp, cp);
  292.             unlinkf(line);
  293.         }
  294.          } while (++i < nitems);
  295. }
  296.  
  297. unlinkf(name)
  298.     char    *name;
  299. {
  300.     if (unlink(name) < 0)
  301.         printf("\tcannot remove %s\n", name);
  302.     else
  303.         printf("\tremoved %s\n", name);
  304. }
  305.  
  306. /*
  307.  * Enable queuing to the printer (allow lpr's).
  308.  */
  309. enable(argc, argv)
  310.     char *argv[];
  311. {
  312.     register int c, status;
  313.     register char *cp1, *cp2;
  314.     char prbuf[100];
  315.  
  316.     if (argc == 1) {
  317.         printf("Usage: enable {all | printer ...}\n");
  318.         return;
  319.     }
  320.     if (argc == 2 && !strcmp(argv[1], "all")) {
  321.         printer = prbuf;
  322.         while (getprent(line) > 0) {
  323.             cp1 = prbuf;
  324.             cp2 = line;
  325.             while ((c = *cp2++) && c != '|' && c != ':')
  326.                 *cp1++ = c;
  327.             *cp1 = '\0';
  328.             enablepr();
  329.         }
  330.         return;
  331.     }
  332.     while (--argc) {
  333.         printer = *++argv;
  334.         if ((status = pgetent(line, printer)) < 0) {
  335.             printf("cannot open printer description file\n");
  336.             continue;
  337.         } else if (status == 0) {
  338.             printf("unknown printer %s\n", printer);
  339.             continue;
  340.         }
  341.         enablepr();
  342.     }
  343. }
  344.  
  345. enablepr()
  346. {
  347.     struct stat stbuf;
  348.  
  349.     bp = pbuf;
  350.     if ((SD = pgetstr("sd", &bp)) == NULL)
  351.         SD = _PATH_DEFSPOOL;
  352.     if ((LO = pgetstr("lo", &bp)) == NULL)
  353.         LO = DEFLOCK;
  354.     (void) sprintf(line, "%s/%s", SD, LO);
  355.     printf("%s:\n", printer);
  356.  
  357.     /*
  358.      * Turn off the group execute bit of the lock file to enable queuing.
  359.      */
  360.     if (stat(line, &stbuf) >= 0) {
  361.         if (chmod(line, stbuf.st_mode & 0767) < 0)
  362.             printf("\tcannot enable queuing\n");
  363.         else
  364.             printf("\tqueuing enabled\n");
  365.     }
  366. }
  367.  
  368. /*
  369.  * Disable queuing.
  370.  */
  371. disable(argc, argv)
  372.     char *argv[];
  373. {
  374.     register int c, status;
  375.     register char *cp1, *cp2;
  376.     char prbuf[100];
  377.  
  378.     if (argc == 1) {
  379.         printf("Usage: disable {all | printer ...}\n");
  380.         return;
  381.     }
  382.     if (argc == 2 && !strcmp(argv[1], "all")) {
  383.         printer = prbuf;
  384.         while (getprent(line) > 0) {
  385.             cp1 = prbuf;
  386.             cp2 = line;
  387.             while ((c = *cp2++) && c != '|' && c != ':')
  388.                 *cp1++ = c;
  389.             *cp1 = '\0';
  390.             disablepr();
  391.         }
  392.         return;
  393.     }
  394.     while (--argc) {
  395.         printer = *++argv;
  396.         if ((status = pgetent(line, printer)) < 0) {
  397.             printf("cannot open printer description file\n");
  398.             continue;
  399.         } else if (status == 0) {
  400.             printf("unknown printer %s\n", printer);
  401.             continue;
  402.         }
  403.         disablepr();
  404.     }
  405. }
  406.  
  407. disablepr()
  408. {
  409.     register int fd;
  410.     struct stat stbuf;
  411.  
  412.     bp = pbuf;
  413.     if ((SD = pgetstr("sd", &bp)) == NULL)
  414.         SD = _PATH_DEFSPOOL;
  415.     if ((LO = pgetstr("lo", &bp)) == NULL)
  416.         LO = DEFLOCK;
  417.     (void) sprintf(line, "%s/%s", SD, LO);
  418.     printf("%s:\n", printer);
  419.     /*
  420.      * Turn on the group execute bit of the lock file to disable queuing.
  421.      */
  422.     if (stat(line, &stbuf) >= 0) {
  423.         if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
  424.             printf("\tcannot disable queuing\n");
  425.         else
  426.             printf("\tqueuing disabled\n");
  427.     } else if (errno == ENOENT) {
  428.         if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
  429.             printf("\tcannot create lock file\n");
  430.         else {
  431.             (void) close(fd);
  432.             printf("\tqueuing disabled\n");
  433.         }
  434.         return;
  435.     } else
  436.         printf("\tcannot stat lock file\n");
  437. }
  438.  
  439. /*
  440.  * Disable queuing and printing and put a message into the status file
  441.  * (reason for being down).
  442.  */
  443. down(argc, argv)
  444.     char *argv[];
  445. {
  446.     register int c, status;
  447.     register char *cp1, *cp2;
  448.     char prbuf[100];
  449.  
  450.     if (argc == 1) {
  451.         printf("Usage: down {all | printer} [message ...]\n");
  452.         return;
  453.     }
  454.     if (!strcmp(argv[1], "all")) {
  455.         printer = prbuf;
  456.         while (getprent(line) > 0) {
  457.             cp1 = prbuf;
  458.             cp2 = line;
  459.             while ((c = *cp2++) && c != '|' && c != ':')
  460.                 *cp1++ = c;
  461.             *cp1 = '\0';
  462.             putmsg(argc - 2, argv + 2);
  463.         }
  464.         return;
  465.     }
  466.     printer = argv[1];
  467.     if ((status = pgetent(line, printer)) < 0) {
  468.         printf("cannot open printer description file\n");
  469.         return;
  470.     } else if (status == 0) {
  471.         printf("unknown printer %s\n", printer);
  472.         return;
  473.     }
  474.     putmsg(argc - 2, argv + 2);
  475. }
  476.  
  477. putmsg(argc, argv)
  478.     char **argv;
  479. {
  480.     register int fd;
  481.     register char *cp1, *cp2;
  482.     char buf[1024];
  483.     struct stat stbuf;
  484.  
  485.     bp = pbuf;
  486.     if ((SD = pgetstr("sd", &bp)) == NULL)
  487.         SD = _PATH_DEFSPOOL;
  488.     if ((LO = pgetstr("lo", &bp)) == NULL)
  489.         LO = DEFLOCK;
  490.     if ((ST = pgetstr("st", &bp)) == NULL)
  491.         ST = DEFSTAT;
  492.     printf("%s:\n", printer);
  493.     /*
  494.      * Turn on the group execute bit of the lock file to disable queuing and
  495.      * turn on the owner execute bit of the lock file to disable printing.
  496.      */
  497.     (void) sprintf(line, "%s/%s", SD, LO);
  498.     if (stat(line, &stbuf) >= 0) {
  499.         if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
  500.             printf("\tcannot disable queuing\n");
  501.         else
  502.             printf("\tprinter and queuing disabled\n");
  503.     } else if (errno == ENOENT) {
  504.         if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
  505.             printf("\tcannot create lock file\n");
  506.         else {
  507.             (void) close(fd);
  508.             printf("\tprinter and queuing disabled\n");
  509.         }
  510.         return;
  511.     } else
  512.         printf("\tcannot stat lock file\n");
  513.     /*
  514.      * Write the message into the status file.
  515.      */
  516.     (void) sprintf(line, "%s/%s", SD, ST);
  517.     fd = open(line, O_WRONLY|O_CREAT, 0664);
  518.     if (fd < 0 || flock(fd, LOCK_EX) < 0) {
  519.         printf("\tcannot create status file\n");
  520.         return;
  521.     }
  522.     (void) ftruncate(fd, 0);
  523.     if (argc <= 0) {
  524.         (void) write(fd, "\n", 1);
  525.         (void) close(fd);
  526.         return;
  527.     }
  528.     cp1 = buf;
  529.     while (--argc >= 0) {
  530.         cp2 = *argv++;
  531.         while (*cp1++ = *cp2++)
  532.             ;
  533.         cp1[-1] = ' ';
  534.     }
  535.     cp1[-1] = '\n';
  536.     *cp1 = '\0';
  537.     (void) write(fd, buf, strlen(buf));
  538.     (void) close(fd);
  539. }
  540.  
  541. /*
  542.  * Exit lpc
  543.  */
  544. quit(argc, argv)
  545.     char *argv[];
  546. {
  547.     exit(0);
  548. }
  549.  
  550. /*
  551.  * Kill and restart the daemon.
  552.  */
  553. restart(argc, argv)
  554.     char *argv[];
  555. {
  556.     register int c, status;
  557.     register char *cp1, *cp2;
  558.     char prbuf[100];
  559.  
  560.     if (argc == 1) {
  561.         printf("Usage: restart {all | printer ...}\n");
  562.         return;
  563.     }
  564.     if (argc == 2 && !strcmp(argv[1], "all")) {
  565.         printer = prbuf;
  566.         while (getprent(line) > 0) {
  567.             cp1 = prbuf;
  568.             cp2 = line;
  569.             while ((c = *cp2++) && c != '|' && c != ':')
  570.                 *cp1++ = c;
  571.             *cp1 = '\0';
  572.             abortpr(0);
  573.             startpr(0);
  574.         }
  575.         return;
  576.     }
  577.     while (--argc) {
  578.         printer = *++argv;
  579.         if ((status = pgetent(line, printer)) < 0) {
  580.             printf("cannot open printer description file\n");
  581.             continue;
  582.         } else if (status == 0) {
  583.             printf("unknown printer %s\n", printer);
  584.             continue;
  585.         }
  586.         abortpr(0);
  587.         startpr(0);
  588.     }
  589. }
  590.  
  591. /*
  592.  * Enable printing on the specified printer and startup the daemon.
  593.  */
  594. start(argc, argv)
  595.     char *argv[];
  596. {
  597.     register int c, status;
  598.     register char *cp1, *cp2;
  599.     char prbuf[100];
  600.  
  601.     if (argc == 1) {
  602.         printf("Usage: start {all | printer ...}\n");
  603.         return;
  604.     }
  605.     if (argc == 2 && !strcmp(argv[1], "all")) {
  606.         printer = prbuf;
  607.         while (getprent(line) > 0) {
  608.             cp1 = prbuf;
  609.             cp2 = line;
  610.             while ((c = *cp2++) && c != '|' && c != ':')
  611.                 *cp1++ = c;
  612.             *cp1 = '\0';
  613.             startpr(1);
  614.         }
  615.         return;
  616.     }
  617.     while (--argc) {
  618.         printer = *++argv;
  619.         if ((status = pgetent(line, printer)) < 0) {
  620.             printf("cannot open printer description file\n");
  621.             continue;
  622.         } else if (status == 0) {
  623.             printf("unknown printer %s\n", printer);
  624.             continue;
  625.         }
  626.         startpr(1);
  627.     }
  628. }
  629.  
  630. startpr(enable)
  631. {
  632.     struct stat stbuf;
  633.  
  634.     bp = pbuf;
  635.     if ((SD = pgetstr("sd", &bp)) == NULL)
  636.         SD = _PATH_DEFSPOOL;
  637.     if ((LO = pgetstr("lo", &bp)) == NULL)
  638.         LO = DEFLOCK;
  639.     (void) sprintf(line, "%s/%s", SD, LO);
  640.     printf("%s:\n", printer);
  641.  
  642.     /*
  643.      * Turn off the owner execute bit of the lock file to enable printing.
  644.      */
  645.     if (enable && stat(line, &stbuf) >= 0) {
  646.         if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
  647.             printf("\tcannot enable printing\n");
  648.         else
  649.             printf("\tprinting enabled\n");
  650.     }
  651.     if (!startdaemon(printer))
  652.         printf("\tcouldn't start daemon\n");
  653.     else
  654.         printf("\tdaemon started\n");
  655. }
  656.  
  657. /*
  658.  * Print the status of each queue listed or all the queues.
  659.  */
  660. status(argc, argv)
  661.     char *argv[];
  662. {
  663.     register int c, status;
  664.     register char *cp1, *cp2;
  665.     char prbuf[100];
  666.  
  667.     if (argc == 1) {
  668.         printer = prbuf;
  669.         while (getprent(line) > 0) {
  670.             cp1 = prbuf;
  671.             cp2 = line;
  672.             while ((c = *cp2++) && c != '|' && c != ':')
  673.                 *cp1++ = c;
  674.             *cp1 = '\0';
  675.             prstat();
  676.         }
  677.         return;
  678.     }
  679.     while (--argc) {
  680.         printer = *++argv;
  681.         if ((status = pgetent(line, printer)) < 0) {
  682.             printf("cannot open printer description file\n");
  683.             continue;
  684.         } else if (status == 0) {
  685.             printf("unknown printer %s\n", printer);
  686.             continue;
  687.         }
  688.         prstat();
  689.     }
  690. }
  691.  
  692. /*
  693.  * Print the status of the printer queue.
  694.  */
  695. prstat()
  696. {
  697.     struct stat stbuf;
  698.     register int fd, i;
  699.     register struct direct *dp;
  700.     DIR *dirp;
  701.  
  702.     bp = pbuf;
  703.     if ((SD = pgetstr("sd", &bp)) == NULL)
  704.         SD = _PATH_DEFSPOOL;
  705.     if ((LO = pgetstr("lo", &bp)) == NULL)
  706.         LO = DEFLOCK;
  707.     if ((ST = pgetstr("st", &bp)) == NULL)
  708.         ST = DEFSTAT;
  709.     printf("%s:\n", printer);
  710.     (void) sprintf(line, "%s/%s", SD, LO);
  711.     if (stat(line, &stbuf) >= 0) {
  712.         printf("\tqueuing is %s\n",
  713.             (stbuf.st_mode & 010) ? "disabled" : "enabled");
  714.         printf("\tprinting is %s\n",
  715.             (stbuf.st_mode & 0100) ? "disabled" : "enabled");
  716.     } else {
  717.         printf("\tqueuing is enabled\n");
  718.         printf("\tprinting is enabled\n");
  719.     }
  720.     if ((dirp = opendir(SD)) == NULL) {
  721.         printf("\tcannot examine spool directory\n");
  722.         return;
  723.     }
  724.     i = 0;
  725.     while ((dp = readdir(dirp)) != NULL) {
  726.         if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
  727.             i++;
  728.     }
  729.     closedir(dirp);
  730.     if (i == 0)
  731.         printf("\tno entries\n");
  732.     else if (i == 1)
  733.         printf("\t1 entry in spool area\n");
  734.     else
  735.         printf("\t%d entries in spool area\n", i);
  736.     fd = open(line, O_RDONLY);
  737.     if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
  738.         (void) close(fd);    /* unlocks as well */
  739.         printf("\tno daemon present\n");
  740.         return;
  741.     }
  742.     (void) close(fd);
  743.     putchar('\t');
  744.     (void) sprintf(line, "%s/%s", SD, ST);
  745.     fd = open(line, O_RDONLY);
  746.     if (fd >= 0) {
  747.         (void) flock(fd, LOCK_SH);
  748.         while ((i = read(fd, line, sizeof(line))) > 0)
  749.             (void) fwrite(line, 1, i, stdout);
  750.         (void) close(fd);    /* unlocks as well */
  751.     }
  752. }
  753.  
  754. /*
  755.  * Stop the specified daemon after completing the current job and disable
  756.  * printing.
  757.  */
  758. stop(argc, argv)
  759.     char *argv[];
  760. {
  761.     register int c, status;
  762.     register char *cp1, *cp2;
  763.     char prbuf[100];
  764.  
  765.     if (argc == 1) {
  766.         printf("Usage: stop {all | printer ...}\n");
  767.         return;
  768.     }
  769.     if (argc == 2 && !strcmp(argv[1], "all")) {
  770.         printer = prbuf;
  771.         while (getprent(line) > 0) {
  772.             cp1 = prbuf;
  773.             cp2 = line;
  774.             while ((c = *cp2++) && c != '|' && c != ':')
  775.                 *cp1++ = c;
  776.             *cp1 = '\0';
  777.             stoppr();
  778.         }
  779.         return;
  780.     }
  781.     while (--argc) {
  782.         printer = *++argv;
  783.         if ((status = pgetent(line, printer)) < 0) {
  784.             printf("cannot open printer description file\n");
  785.             continue;
  786.         } else if (status == 0) {
  787.             printf("unknown printer %s\n", printer);
  788.             continue;
  789.         }
  790.         stoppr();
  791.     }
  792. }
  793.  
  794. stoppr()
  795. {
  796.     register int fd;
  797.     struct stat stbuf;
  798.  
  799.     bp = pbuf;
  800.     if ((SD = pgetstr("sd", &bp)) == NULL)
  801.         SD = _PATH_DEFSPOOL;
  802.     if ((LO = pgetstr("lo", &bp)) == NULL)
  803.         LO = DEFLOCK;
  804.     (void) sprintf(line, "%s/%s", SD, LO);
  805.     printf("%s:\n", printer);
  806.  
  807.     /*
  808.      * Turn on the owner execute bit of the lock file to disable printing.
  809.      */
  810.     if (stat(line, &stbuf) >= 0) {
  811.         if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
  812.             printf("\tcannot disable printing\n");
  813.         else {
  814.             upstat("printing disabled\n");
  815.             printf("\tprinting disabled\n");
  816.         }
  817.     } else if (errno == ENOENT) {
  818.         if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
  819.             printf("\tcannot create lock file\n");
  820.         else {
  821.             (void) close(fd);
  822.             upstat("printing disabled\n");
  823.             printf("\tprinting disabled\n");
  824.         }
  825.     } else
  826.         printf("\tcannot stat lock file\n");
  827. }
  828.  
  829. struct    queue **queue;
  830. int    nitems;
  831. time_t    mtime;
  832.  
  833. /*
  834.  * Put the specified jobs at the top of printer queue.
  835.  */
  836. topq(argc, argv)
  837.     char *argv[];
  838. {
  839.     register int n, i;
  840.     struct stat stbuf;
  841.     register char *cfname;
  842.     int status, changed;
  843.  
  844.     if (argc < 3) {
  845.         printf("Usage: topq printer [jobnum ...] [user ...]\n");
  846.         return;
  847.     }
  848.  
  849.     --argc;
  850.     printer = *++argv;
  851.     status = pgetent(line, printer);
  852.     if (status < 0) {
  853.         printf("cannot open printer description file\n");
  854.         return;
  855.     } else if (status == 0) {
  856.         printf("%s: unknown printer\n", printer);
  857.         return;
  858.     }
  859.     bp = pbuf;
  860.     if ((SD = pgetstr("sd", &bp)) == NULL)
  861.         SD = _PATH_DEFSPOOL;
  862.     if ((LO = pgetstr("lo", &bp)) == NULL)
  863.         LO = DEFLOCK;
  864.     printf("%s:\n", printer);
  865.  
  866.     if (chdir(SD) < 0) {
  867.         printf("\tcannot chdir to %s\n", SD);
  868.         return;
  869.     }
  870.     nitems = getq(&queue);
  871.     if (nitems == 0)
  872.         return;
  873.     changed = 0;
  874.     mtime = queue[0]->q_time;
  875.     for (i = argc; --i; ) {
  876.         if (doarg(argv[i]) == 0) {
  877.             printf("\tjob %s is not in the queue\n", argv[i]);
  878.             continue;
  879.         } else
  880.             changed++;
  881.     }
  882.     for (i = 0; i < nitems; i++)
  883.         free(queue[i]);
  884.     free(queue);
  885.     if (!changed) {
  886.         printf("\tqueue order unchanged\n");
  887.         return;
  888.     }
  889.     /*
  890.      * Turn on the public execute bit of the lock file to
  891.      * get lpd to rebuild the queue after the current job.
  892.      */
  893.     if (changed && stat(LO, &stbuf) >= 0)
  894.         (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
  895.  
  896. /*
  897.  * Reposition the job by changing the modification time of
  898.  * the control file.
  899.  */
  900. touch(q)
  901.     struct queue *q;
  902. {
  903.     struct timeval tvp[2];
  904.  
  905.     tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
  906.     tvp[0].tv_usec = tvp[1].tv_usec = 0;
  907.     return(utimes(q->q_name, tvp));
  908. }
  909.  
  910. /*
  911.  * Checks if specified job name is in the printer's queue.
  912.  * Returns:  negative (-1) if argument name is not in the queue.
  913.  */
  914. doarg(job)
  915.     char *job;
  916. {
  917.     register struct queue **qq;
  918.     register int jobnum, n;
  919.     register char *cp, *machine;
  920.     int cnt = 0;
  921.     FILE *fp;
  922.  
  923.     /*
  924.      * Look for a job item consisting of system name, colon, number 
  925.      * (example: ucbarpa:114)  
  926.      */
  927.     if ((cp = index(job, ':')) != NULL) {
  928.         machine = job;
  929.         *cp++ = '\0';
  930.         job = cp;
  931.     } else
  932.         machine = NULL;
  933.  
  934.     /*
  935.      * Check for job specified by number (example: 112 or 235ucbarpa).
  936.      */
  937.     if (isdigit(*job)) {
  938.         jobnum = 0;
  939.         do
  940.             jobnum = jobnum * 10 + (*job++ - '0');
  941.         while (isdigit(*job));
  942.         for (qq = queue + nitems; --qq >= queue; ) {
  943.             n = 0;
  944.             for (cp = (*qq)->q_name+3; isdigit(*cp); )
  945.                 n = n * 10 + (*cp++ - '0');
  946.             if (jobnum != n)
  947.                 continue;
  948.             if (*job && strcmp(job, cp) != 0)
  949.                 continue;
  950.             if (machine != NULL && strcmp(machine, cp) != 0)
  951.                 continue;
  952.             if (touch(*qq) == 0) {
  953.                 printf("\tmoved %s\n", (*qq)->q_name);
  954.                 cnt++;
  955.             }
  956.         }
  957.         return(cnt);
  958.     }
  959.     /*
  960.      * Process item consisting of owner's name (example: henry).
  961.      */
  962.     for (qq = queue + nitems; --qq >= queue; ) {
  963.         if ((fp = fopen((*qq)->q_name, "r")) == NULL)
  964.             continue;
  965.         while (getline(fp) > 0)
  966.             if (line[0] == 'P')
  967.                 break;
  968.         (void) fclose(fp);
  969.         if (line[0] != 'P' || strcmp(job, line+1) != 0)
  970.             continue;
  971.         if (touch(*qq) == 0) {
  972.             printf("\tmoved %s\n", (*qq)->q_name);
  973.             cnt++;
  974.         }
  975.     }
  976.     return(cnt);
  977. }
  978.  
  979. /*
  980.  * Enable everything and start printer (undo `down').
  981.  */
  982. up(argc, argv)
  983.     char *argv[];
  984. {
  985.     register int c, status;
  986.     register char *cp1, *cp2;
  987.     char prbuf[100];
  988.  
  989.     if (argc == 1) {
  990.         printf("Usage: up {all | printer ...}\n");
  991.         return;
  992.     }
  993.     if (argc == 2 && !strcmp(argv[1], "all")) {
  994.         printer = prbuf;
  995.         while (getprent(line) > 0) {
  996.             cp1 = prbuf;
  997.             cp2 = line;
  998.             while ((c = *cp2++) && c != '|' && c != ':')
  999.                 *cp1++ = c;
  1000.             *cp1 = '\0';
  1001.             startpr(2);
  1002.         }
  1003.         return;
  1004.     }
  1005.     while (--argc) {
  1006.         printer = *++argv;
  1007.         if ((status = pgetent(line, printer)) < 0) {
  1008.             printf("cannot open printer description file\n");
  1009.             continue;
  1010.         } else if (status == 0) {
  1011.             printf("unknown printer %s\n", printer);
  1012.             continue;
  1013.         }
  1014.         startpr(2);
  1015.     }
  1016. }
  1017.