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