home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / daemons / lprm_fix.z / lprm_fix / lpr / common_source / common.c next >
Encoding:
C/C++ Source or Header  |  1993-05-04  |  8.5 KB  |  310 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[] = "@(#)common.c    5.7 (Berkeley) 3/2/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * Routines and data common to all the line printer functions.
  40.  */
  41.  
  42. #include "lp.h"
  43.  
  44. int    DU;        /* daeomon user-id */
  45. int    MX;        /* maximum number of blocks to copy */
  46. int    MC;        /* maximum number of copies allowed */
  47. char    *LP;        /* line printer device name */
  48. char    *RM;        /* remote machine name */
  49. char    *RP;        /* remote printer name */
  50. char    *LO;        /* lock file name */
  51. char    *ST;        /* status file name */
  52. char    *SD;        /* spool directory */
  53. char    *AF;        /* accounting file */
  54. char    *LF;        /* log file for error messages */
  55. char    *OF;        /* name of output filter (created once) */
  56. char    *IF;        /* name of input filter (created per job) */
  57. char    *RF;        /* name of fortran text filter (per job) */
  58. char    *TF;        /* name of troff filter (per job) */
  59. char    *NF;        /* name of ditroff filter (per job) */
  60. char    *DF;        /* name of tex filter (per job) */
  61. char    *GF;        /* name of graph(1G) filter (per job) */
  62. char    *VF;        /* name of vplot filter (per job) */
  63. char    *CF;        /* name of cifplot filter (per job) */
  64. char    *PF;        /* name of vrast filter (per job) */
  65. char    *FF;        /* form feed string */
  66. char    *TR;        /* trailer string to be output when Q empties */
  67. short    SC;        /* suppress multiple copies */
  68. short    SF;        /* suppress FF on each print job */
  69. short    SH;        /* suppress header page */
  70. short    SB;        /* short banner instead of normal header */
  71. short    HL;        /* print header last */
  72. short    RW;        /* open LP for reading and writing */
  73. short    PW;        /* page width */
  74. short    PL;        /* page length */
  75. short    PX;        /* page width in pixels */
  76. short    PY;        /* page length in pixels */
  77. short    BR;        /* baud rate if lp is a tty */
  78. int    FC;        /* flags to clear if lp is a tty */
  79. int    FS;        /* flags to set if lp is a tty */
  80. int    XC;        /* flags to clear for local mode */
  81. int    XS;        /* flags to set for local mode */
  82. short    RS;        /* restricted to those with local accounts */
  83.  
  84. char    line[BUFSIZ];
  85. char    pbuf[BUFSIZ/2];    /* buffer for printcap strings */
  86. char    *bp = pbuf;    /* pointer into pbuf for pgetent() */
  87. char    *name;        /* program name */
  88. char    *printer;    /* printer name */
  89. char    host[32];    /* host machine name */
  90. char    *from = host;    /* client's machine name */
  91. int    sendtorem;    /* are we sending to a remote? */
  92.  
  93. /*
  94.  * Create a connection to the remote printer server.
  95.  * Most of this code comes from rcmd.c.
  96.  */
  97. getport(rhost)
  98.     char *rhost;
  99. {
  100.     struct hostent *hp;
  101.     struct servent *sp;
  102.     struct sockaddr_in sin;
  103.     int s, timo = 1, lport = IPPORT_RESERVED - 1;
  104.     int err;
  105.  
  106.     /*
  107.      * Get the host address and port number to connect to.
  108.      */
  109.     if (rhost == NULL)
  110.         fatal("no remote host to connect to");
  111.     hp = gethostbyname(rhost);
  112.     if (hp == NULL)
  113.         fatal("unknown host %s", rhost);
  114.     sp = getservbyname("printer", "tcp");
  115.     if (sp == NULL)
  116.         fatal("printer/tcp: unknown service");
  117.     bzero((char *)&sin, sizeof(sin));
  118.     bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
  119.     sin.sin_family = hp->h_addrtype;
  120.     sin.sin_port = sp->s_port;
  121.  
  122.     /*
  123.      * Try connecting to the server.
  124.      */
  125. retry:
  126.     s = rresvport(&lport);
  127.     if (s < 0)
  128.         return(-1);
  129.     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
  130.         err = errno;
  131.         (void) close(s);
  132.         errno = err;
  133.         if (errno == EADDRINUSE) {
  134.             lport--;
  135.             goto retry;
  136.         }
  137.         if (errno == ECONNREFUSED && timo <= 16) {
  138.             sleep(timo);
  139.             timo *= 2;
  140.             goto retry;
  141.         }
  142.         return(-1);
  143.     }
  144.     return(s);
  145. }
  146.  
  147. /*
  148.  * Getline reads a line from the control file cfp, removes tabs, converts
  149.  *  new-line to null and leaves it in line.
  150.  * Returns 0 at EOF or the number of characters read.
  151.  */
  152. getline(cfp)
  153.     FILE *cfp;
  154. {
  155.     register int linel = 0;
  156.     register char *lp = line;
  157.     register c;
  158.  
  159.     while ((c = getc(cfp)) != '\n') {
  160.         if (c == EOF)
  161.             return(0);
  162.         if (c == '\t') {
  163.             do {
  164.                 *lp++ = ' ';
  165.                 linel++;
  166.             } while ((linel & 07) != 0);
  167.             continue;
  168.         }
  169.         *lp++ = c;
  170.         linel++;
  171.     }
  172.     *lp++ = '\0';
  173.     return(linel);
  174. }
  175.  
  176. /*
  177.  * Scan the current directory and make a list of daemon files sorted by
  178.  * creation time.
  179.  * Return the number of entries and a pointer to the list.
  180.  */
  181. getq(namelist)
  182.     struct queue *(*namelist[]);
  183. {
  184.     register struct direct *d;
  185.     register struct queue *q, **queue;
  186.     register int nitems;
  187.     struct stat stbuf;
  188.     DIR *dirp;
  189.     int arraysz;
  190.     static int compar();
  191.  
  192.     if ((dirp = opendir(SD)) == NULL)
  193.         return(-1);
  194.     if (fstat(dirp->dd_fd, &stbuf) < 0)
  195.         goto errdone;
  196.  
  197.     /*
  198.      * Estimate the array size by taking the size of the directory file
  199.      * and dividing it by a multiple of the minimum size entry. 
  200.      */
  201.     arraysz = (stbuf.st_size / 24);
  202.     queue = (struct queue **)malloc(arraysz * sizeof(struct queue *));
  203.     if (queue == NULL)
  204.         goto errdone;
  205.  
  206.     nitems = 0;
  207.     while ((d = readdir(dirp)) != NULL) {
  208.         if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
  209.             continue;    /* daemon control files only */
  210.         if (stat(d->d_name, &stbuf) < 0)
  211.             continue;    /* Doesn't exist */
  212.         q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1);
  213.         if (q == NULL)
  214.             goto errdone;
  215.         q->q_time = stbuf.st_mtime;
  216.         strcpy(q->q_name, d->d_name);
  217.         /*
  218.          * Check to make sure the array has space left and
  219.          * realloc the maximum size.
  220.          */
  221.         if (++nitems > arraysz) {
  222.             queue = (struct queue **)realloc((char *)queue,
  223.                 (stbuf.st_size/12) * sizeof(struct queue *));
  224.             if (queue == NULL)
  225.                 goto errdone;
  226.         }
  227.         queue[nitems-1] = q;
  228.     }
  229.     closedir(dirp);
  230.     if (nitems)
  231.         qsort(queue, nitems, sizeof(struct queue *), compar);
  232.     *namelist = queue;
  233.     return(nitems);
  234.  
  235. errdone:
  236.     closedir(dirp);
  237.     return(-1);
  238. }
  239.  
  240. /*
  241.  * Compare modification times.
  242.  */
  243. static
  244. compar(p1, p2)
  245.     register struct queue **p1, **p2;
  246. {
  247.     if ((*p1)->q_time < (*p2)->q_time)
  248.         return(-1);
  249.     if ((*p1)->q_time > (*p2)->q_time)
  250.         return(1);
  251.     return(0);
  252. }
  253.  
  254. /*
  255.  * Figure out whether the local machine is the same
  256.  * as the remote machine (RM) entry (if it exists).
  257.  */
  258. char *
  259. checkremote()
  260. {
  261.     char name[MAXHOSTNAMELEN];
  262.     register struct hostent *hp;
  263.     static char errbuf[128];
  264.  
  265.     sendtorem = 0;    /* assume printer is local */
  266.     if (RM != (char *)NULL) {
  267.         /* get the official name of the local host */
  268.         gethostname(name, sizeof(name));
  269.         name[sizeof(name)-1] = '\0';
  270.         hp = gethostbyname(name);
  271.         if (hp == (struct hostent *) NULL) {
  272.             (void) sprintf(errbuf,
  273.             "unable to get official name for local machine %s",
  274.             name);
  275.             return errbuf;
  276.         } else (void) strcpy(name, hp->h_name);
  277.  
  278.         /* get the official name of RM */
  279.         hp = gethostbyname(RM);
  280.         if (hp == (struct hostent *) NULL) {
  281.             (void) sprintf(errbuf,
  282.             "unable to get official name for remote machine %s",
  283.             RM);
  284.             return errbuf;
  285.         }
  286.  
  287.         /*
  288.          * if the two hosts are not the same,
  289.          * then the printer must be remote.
  290.          */
  291.         if (strcmp(name, hp->h_name) != 0)
  292.             sendtorem = 1;
  293.     }
  294.     return (char *)0;
  295. }
  296.  
  297. /*VARARGS1*/
  298. fatal(msg, a1, a2, a3)
  299.     char *msg;
  300. {
  301.     if (from != host)
  302.         printf("%s: ", host);
  303.     printf("%s: ", name);
  304.     if (printer)
  305.         printf("%s: ", printer);
  306.     printf(msg, a1, a2, a3);
  307.     putchar('\n');
  308.     exit(1);
  309. }
  310.