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 / lpd / recvjob.c,v < prev    next >
Encoding:
Text File  |  1994-05-23  |  7.2 KB  |  330 lines

  1. head    1.1;
  2. access;
  3. symbols;
  4. locks
  5.     rzsfl:1.1; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.1
  10. date    94.05.23.09.05.00;    author rzsfl;    state Exp;
  11. branches;
  12. next    ;
  13.  
  14.  
  15. desc
  16. @Original
  17. @
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/*
  26.  * Copyright (c) 1983 Regents of the University of California.
  27.  * All rights reserved.
  28.  *
  29.  * Redistribution and use in source and binary forms, with or without
  30.  * modification, are permitted provided that the following conditions
  31.  * are met:
  32.  * 1. Redistributions of source code must retain the above copyright
  33.  *    notice, this list of conditions and the following disclaimer.
  34.  * 2. Redistributions in binary form must reproduce the above copyright
  35.  *    notice, this list of conditions and the following disclaimer in the
  36.  *    documentation and/or other materials provided with the distribution.
  37.  * 3. All advertising materials mentioning features or use of this software
  38.  *    must display the following acknowledgement:
  39.  *    This product includes software developed by the University of
  40.  *    California, Berkeley and its contributors.
  41.  * 4. Neither the name of the University nor the names of its contributors
  42.  *    may be used to endorse or promote products derived from this software
  43.  *    without specific prior written permission.
  44.  *
  45.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  46.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  47.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  48.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  49.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  50.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  51.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  52.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  53.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  54.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  55.  * SUCH DAMAGE.
  56.  */
  57.  
  58. #ifndef lint
  59. /*static char sccsid[] = "from: @@(#)recvjob.c    5.15 (Berkeley) 5/4/91";*/
  60. static char rcsid[] = "$Id: recvjob.c,v 1.2 1993/08/01 17:58:49 mycroft Exp $";
  61. #endif /* not lint */
  62.  
  63. /*
  64.  * Receive printer jobs from the network, queue them and
  65.  * start the printer daemon.
  66.  */
  67.  
  68. #include "lp.h"
  69. #include "pathnames.h"
  70. #include <sys/mount.h>
  71.  
  72. char    *sp = "";
  73. #define ack()    (void) write(1, sp, 1);
  74.  
  75. char    tfname[40];        /* tmp copy of cf before linking */
  76. char    dfname[40];        /* data files */
  77. int    minfree;        /* keep at least minfree blocks available */
  78.  
  79. void    rcleanup();
  80.  
  81. recvjob()
  82. {
  83.     struct stat stb;
  84.     char *bp = pbuf;
  85.     int status;
  86.  
  87.     /*
  88.      * Perform lookup for printer name or abbreviation
  89.      */
  90.     if ((status = pgetent(line, printer)) < 0)
  91.         frecverr("cannot open printer description file");
  92.     else if (status == 0)
  93.         frecverr("unknown printer %s", printer);
  94.     if ((LF = pgetstr("lf", &bp)) == NULL)
  95.         LF = _PATH_CONSOLE;
  96.     if ((SD = pgetstr("sd", &bp)) == NULL)
  97.         SD = _PATH_DEFSPOOL;
  98.     if ((LO = pgetstr("lo", &bp)) == NULL)
  99.         LO = DEFLOCK;
  100.  
  101.     (void) close(2);            /* set up log file */
  102.     if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) {
  103.         syslog(LOG_ERR, "%s: %m", LF);
  104.         (void) open(_PATH_DEVNULL, O_WRONLY);
  105.     }
  106.  
  107.     if (chdir(SD) < 0)
  108.         frecverr("%s: %s: %m", printer, SD);
  109.     if (stat(LO, &stb) == 0) {
  110.         if (stb.st_mode & 010) {
  111.             /* queue is disabled */
  112.             putchar('\1');        /* return error code */
  113.             exit(1);
  114.         }
  115.     } else if (stat(SD, &stb) < 0)
  116.         frecverr("%s: %s: %m", printer, SD);
  117.     minfree = 2 * read_number("minfree");    /* scale KB to 512 blocks */
  118.     signal(SIGTERM, rcleanup);
  119.     signal(SIGPIPE, rcleanup);
  120.  
  121.     if (readjob())
  122.         printjob();
  123. }
  124.  
  125. /*
  126.  * Read printer jobs sent by lpd and copy them to the spooling directory.
  127.  * Return the number of jobs successfully transfered.
  128.  */
  129. readjob()
  130. {
  131.     register int size, nfiles;
  132.     register char *cp;
  133.  
  134.     ack();
  135.     nfiles = 0;
  136.     for (;;) {
  137.         /*
  138.          * Read a command to tell us what to do
  139.          */
  140.         cp = line;
  141.         do {
  142.             if ((size = read(1, cp, 1)) != 1) {
  143.                 if (size < 0)
  144.                     frecverr("%s: Lost connection",printer);
  145.                 return(nfiles);
  146.             }
  147.         } while (*cp++ != '\n');
  148.         *--cp = '\0';
  149.         cp = line;
  150.         switch (*cp++) {
  151.         case '\1':    /* cleanup because data sent was bad */
  152.             rcleanup();
  153.             continue;
  154.  
  155.         case '\2':    /* read cf file */
  156.             size = 0;
  157.             while (*cp >= '0' && *cp <= '9')
  158.                 size = size * 10 + (*cp++ - '0');
  159.             if (*cp++ != ' ')
  160.                 break;
  161.             /*
  162.              * host name has been authenticated, we use our
  163.              * view of the host name since we may be passed
  164.              * something different than what gethostbyaddr()
  165.              * returns
  166.              */
  167.             strcpy(cp + 6, from);
  168.             strcpy(tfname, cp);
  169.             tfname[0] = 't';
  170.             if (!chksize(size)) {
  171.                 (void) write(1, "\2", 1);
  172.                 continue;
  173.             }
  174.             if (!readfile(tfname, size)) {
  175.                 rcleanup();
  176.                 continue;
  177.             }
  178.             if (link(tfname, cp) < 0)
  179.                 frecverr("%s: %m", tfname);
  180.             (void) unlink(tfname);
  181.             tfname[0] = '\0';
  182.             nfiles++;
  183.             continue;
  184.  
  185.         case '\3':    /* read df file */
  186.             size = 0;
  187.             while (*cp >= '0' && *cp <= '9')
  188.                 size = size * 10 + (*cp++ - '0');
  189.             if (*cp++ != ' ')
  190.                 break;
  191.             if (!chksize(size)) {
  192.                 (void) write(1, "\2", 1);
  193.                 continue;
  194.             }
  195.             (void) strcpy(dfname, cp);
  196.             if (index(dfname, '/'))
  197.                 frecverr("readjob: %s: illegal path name",
  198.                     dfname);
  199.             (void) readfile(dfname, size);
  200.             continue;
  201.         }
  202.         frecverr("protocol screwup");
  203.     }
  204. }
  205.  
  206. /*
  207.  * Read files send by lpd and copy them to the spooling directory.
  208.  */
  209. readfile(file, size)
  210.     char *file;
  211.     int size;
  212. {
  213.     register char *cp;
  214.     char buf[BUFSIZ];
  215.     register int i, j, amt;
  216.     int fd, err;
  217.  
  218.     fd = open(file, O_CREAT|O_EXCL|O_WRONLY, FILMOD);
  219.     if (fd < 0)
  220.         frecverr("readfile: %s: illegal path name: %m", file);
  221.     ack();
  222.     err = 0;
  223.     for (i = 0; i < size; i += BUFSIZ) {
  224.         amt = BUFSIZ;
  225.         cp = buf;
  226.         if (i + amt > size)
  227.             amt = size - i;
  228.         do {
  229.             j = read(1, cp, amt);
  230.             if (j <= 0)
  231.                 frecverr("Lost connection");
  232.             amt -= j;
  233.             cp += j;
  234.         } while (amt > 0);
  235.         amt = BUFSIZ;
  236.         if (i + amt > size)
  237.             amt = size - i;
  238.         if (write(fd, buf, amt) != amt) {
  239.             err++;
  240.             break;
  241.         }
  242.     }
  243.     (void) close(fd);
  244.     if (err)
  245.         frecverr("%s: write error", file);
  246.     if (noresponse()) {        /* file sent had bad data in it */
  247.         (void) unlink(file);
  248.         return(0);
  249.     }
  250.     ack();
  251.     return(1);
  252. }
  253.  
  254. noresponse()
  255. {
  256.     char resp;
  257.  
  258.     if (read(1, &resp, 1) != 1)
  259.         frecverr("Lost connection");
  260.     if (resp == '\0')
  261.         return(0);
  262.     return(1);
  263. }
  264.  
  265. /*
  266.  * Check to see if there is enough space on the disk for size bytes.
  267.  * 1 == OK, 0 == Not OK.
  268.  */
  269. chksize(size)
  270.     int size;
  271. {
  272.     int spacefree;
  273.     struct statfs sfb;
  274.  
  275.     if (statfs(".", &sfb) < 0) {
  276.         syslog(LOG_ERR, "%s: %m", "statfs(\".\")");
  277.         return (1);
  278.     }
  279.     spacefree = sfb.f_bavail * (sfb.f_fsize / 512);
  280.     size = (size + 511) / 512;
  281.     if (minfree + size > spacefree)
  282.         return(0);
  283.     return(1);
  284. }
  285.  
  286. read_number(fn)
  287.     char *fn;
  288. {
  289.     char lin[80];
  290.     register FILE *fp;
  291.  
  292.     if ((fp = fopen(fn, "r")) == NULL)
  293.         return (0);
  294.     if (fgets(lin, 80, fp) == NULL) {
  295.         fclose(fp);
  296.         return (0);
  297.     }
  298.     fclose(fp);
  299.     return (atoi(lin));
  300. }
  301.  
  302. /*
  303.  * Remove all the files associated with the current job being transfered.
  304.  */
  305. void
  306. rcleanup()
  307. {
  308.  
  309.     if (tfname[0])
  310.         (void) unlink(tfname);
  311.     if (dfname[0])
  312.         do {
  313.             do
  314.                 (void) unlink(dfname);
  315.             while (dfname[2]-- != 'A');
  316.             dfname[2] = 'z';
  317.         } while (dfname[0]-- != 'd');
  318.     dfname[0] = '\0';
  319. }
  320.  
  321. frecverr(msg, a1, a2)
  322.     char *msg;
  323. {
  324.     rcleanup();
  325.     syslog(LOG_ERR, msg, a1, a2);
  326.     putchar('\1');        /* return error code */
  327.     exit(1);
  328. }
  329. @
  330.