BSD 4_3_Reno release
[unix-history] / usr / src / usr.sbin / lpr / common_source / common.c
index 52f8baa..a11510c 100644 (file)
@@ -1,4 +1,26 @@
-/*     common.c        4.4     83/05/27        */
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that: (1) source distributions retain this entire copyright notice and
+ * comment, and (2) distributions including binaries display the following
+ * acknowledgement:  ``This product includes software developed by the
+ * University of California, Berkeley and its contributors'' in the
+ * documentation or other materials provided with the distribution and in
+ * all advertising materials mentioning features or use of this software.
+ * Neither the name of the University nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)common.c   5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
 /*
  * Routines and data common to all the line printer functions.
  */
 /*
  * Routines and data common to all the line printer functions.
  */
@@ -7,6 +29,7 @@
 
 int    DU;             /* daeomon user-id */
 int    MX;             /* maximum number of blocks to copy */
 
 int    DU;             /* daeomon user-id */
 int    MX;             /* maximum number of blocks to copy */
+int    MC;             /* maximum number of copies allowed */
 char   *LP;            /* line printer device name */
 char   *RM;            /* remote machine name */
 char   *RP;            /* remote printer name */
 char   *LP;            /* line printer device name */
 char   *RM;            /* remote machine name */
 char   *RP;            /* remote printer name */
@@ -19,6 +42,7 @@ char  *OF;            /* name of output filter (created once) */
 char   *IF;            /* name of input filter (created per job) */
 char   *RF;            /* name of fortran text filter (per job) */
 char   *TF;            /* name of troff filter (per job) */
 char   *IF;            /* name of input filter (created per job) */
 char   *RF;            /* name of fortran text filter (per job) */
 char   *TF;            /* name of troff filter (per job) */
+char   *NF;            /* name of ditroff filter (per job) */
 char   *DF;            /* name of tex filter (per job) */
 char   *GF;            /* name of graph(1G) filter (per job) */
 char   *VF;            /* name of vplot filter (per job) */
 char   *DF;            /* name of tex filter (per job) */
 char   *GF;            /* name of graph(1G) filter (per job) */
 char   *VF;            /* name of vplot filter (per job) */
@@ -26,19 +50,21 @@ char        *CF;            /* name of cifplot filter (per job) */
 char   *PF;            /* name of vrast filter (per job) */
 char   *FF;            /* form feed string */
 char   *TR;            /* trailer string to be output when Q empties */
 char   *PF;            /* name of vrast filter (per job) */
 char   *FF;            /* form feed string */
 char   *TR;            /* trailer string to be output when Q empties */
+short  SC;             /* suppress multiple copies */
 short  SF;             /* suppress FF on each print job */
 short  SH;             /* suppress header page */
 short  SB;             /* short banner instead of normal header */
 short  SF;             /* suppress FF on each print job */
 short  SH;             /* suppress header page */
 short  SB;             /* short banner instead of normal header */
+short  HL;             /* print header last */
 short  RW;             /* open LP for reading and writing */
 short  PW;             /* page width */
 short  PL;             /* page length */
 short  PX;             /* page width in pixels */
 short  PY;             /* page length in pixels */
 short  BR;             /* baud rate if lp is a tty */
 short  RW;             /* open LP for reading and writing */
 short  PW;             /* page width */
 short  PL;             /* page length */
 short  PX;             /* page width in pixels */
 short  PY;             /* page length in pixels */
 short  BR;             /* baud rate if lp is a tty */
-short  FC;             /* flags to clear if lp is a tty */
-short  FS;             /* flags to set if lp is a tty */
-short  XC;             /* flags to clear for local mode */
-short  XS;             /* flags to set for local mode */
+int    FC;             /* flags to clear if lp is a tty */
+int    FS;             /* flags to set if lp is a tty */
+int    XC;             /* flags to clear for local mode */
+int    XS;             /* flags to set for local mode */
 short  RS;             /* restricted to those with local accounts */
 
 char   line[BUFSIZ];
 short  RS;             /* restricted to those with local accounts */
 
 char   line[BUFSIZ];
@@ -48,6 +74,7 @@ char  *name;          /* program name */
 char   *printer;       /* printer name */
 char   host[32];       /* host machine name */
 char   *from = host;   /* client's machine name */
 char   *printer;       /* printer name */
 char   host[32];       /* host machine name */
 char   *from = host;   /* client's machine name */
+int    sendtorem;      /* are we sending to a remote? */
 
 /*
  * Create a connection to the remote printer server.
 
 /*
  * Create a connection to the remote printer server.
@@ -60,6 +87,7 @@ getport(rhost)
        struct servent *sp;
        struct sockaddr_in sin;
        int s, timo = 1, lport = IPPORT_RESERVED - 1;
        struct servent *sp;
        struct sockaddr_in sin;
        int s, timo = 1, lport = IPPORT_RESERVED - 1;
+       int err;
 
        /*
         * Get the host address and port number to connect to.
 
        /*
         * Get the host address and port number to connect to.
@@ -84,14 +112,15 @@ retry:
        s = rresvport(&lport);
        if (s < 0)
                return(-1);
        s = rresvport(&lport);
        if (s < 0)
                return(-1);
-       if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
+       if (connect(s, (caddr_t)&sin, sizeof(sin)) < 0) {
+               err = errno;
+               (void) close(s);
+               errno = err;
                if (errno == EADDRINUSE) {
                if (errno == EADDRINUSE) {
-                       close(s);
                        lport--;
                        goto retry;
                }
                if (errno == ECONNREFUSED && timo <= 16) {
                        lport--;
                        goto retry;
                }
                if (errno == ECONNREFUSED && timo <= 16) {
-                       (void) close(s);
                        sleep(timo);
                        timo *= 2;
                        goto retry;
                        sleep(timo);
                        timo *= 2;
                        goto retry;
@@ -101,29 +130,6 @@ retry:
        return(s);
 }
 
        return(s);
 }
 
-rresvport(alport)
-       int *alport;
-{
-       struct sockaddr_in sin;
-       int s;
-
-       sin.sin_family = AF_INET;
-       sin.sin_addr.s_addr = 0;
-       s = socket(AF_INET, SOCK_STREAM, 0);
-       if (s < 0)
-               return(-1);
-       for (;;) {
-               sin.sin_port = htons((u_short) *alport);
-               if (bind(s, (caddr_t)&sin, sizeof(sin), 0) >= 0)
-                       return(s);
-               if (errno != EADDRINUSE && errno != EADDRNOTAVAIL)
-                       return(-1);
-               (*alport)--;
-               if (*alport == IPPORT_RESERVED/2)
-                       return(-1);
-       }
-}
-
 /*
  * Getline reads a line from the control file cfp, removes tabs, converts
  *  new-line to null and leaves it in line.
 /*
  * Getline reads a line from the control file cfp, removes tabs, converts
  *  new-line to null and leaves it in line.
@@ -168,10 +174,10 @@ getq(namelist)
        int arraysz, compar();
        DIR *dirp;
 
        int arraysz, compar();
        DIR *dirp;
 
-       if ((dirp = opendir(".")) == NULL)
+       if ((dirp = opendir(SD)) == NULL)
                return(-1);
        if (fstat(dirp->dd_fd, &stbuf) < 0)
                return(-1);
        if (fstat(dirp->dd_fd, &stbuf) < 0)
-               return(-1);
+               goto errdone;
 
        /*
         * Estimate the array size by taking the size of the directory file
 
        /*
         * Estimate the array size by taking the size of the directory file
@@ -180,7 +186,7 @@ getq(namelist)
        arraysz = (stbuf.st_size / 24);
        queue = (struct queue **)malloc(arraysz * sizeof(struct queue *));
        if (queue == NULL)
        arraysz = (stbuf.st_size / 24);
        queue = (struct queue **)malloc(arraysz * sizeof(struct queue *));
        if (queue == NULL)
-               return(-1);
+               goto errdone;
 
        nitems = 0;
        while ((d = readdir(dirp)) != NULL) {
 
        nitems = 0;
        while ((d = readdir(dirp)) != NULL) {
@@ -190,7 +196,7 @@ getq(namelist)
                        continue;       /* Doesn't exist */
                q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1);
                if (q == NULL)
                        continue;       /* Doesn't exist */
                q = (struct queue *)malloc(sizeof(time_t)+strlen(d->d_name)+1);
                if (q == NULL)
-                       return(-1);
+                       goto errdone;
                q->q_time = stbuf.st_mtime;
                strcpy(q->q_name, d->d_name);
                /*
                q->q_time = stbuf.st_mtime;
                strcpy(q->q_name, d->d_name);
                /*
@@ -201,7 +207,7 @@ getq(namelist)
                        queue = (struct queue **)realloc((char *)queue,
                                (stbuf.st_size/12) * sizeof(struct queue *));
                        if (queue == NULL)
                        queue = (struct queue **)realloc((char *)queue,
                                (stbuf.st_size/12) * sizeof(struct queue *));
                        if (queue == NULL)
-                               return(-1);
+                               goto errdone;
                }
                queue[nitems-1] = q;
        }
                }
                queue[nitems-1] = q;
        }
@@ -210,6 +216,10 @@ getq(namelist)
                qsort(queue, nitems, sizeof(struct queue *), compar);
        *namelist = queue;
        return(nitems);
                qsort(queue, nitems, sizeof(struct queue *), compar);
        *namelist = queue;
        return(nitems);
+
+errdone:
+       closedir(dirp);
+       return(-1);
 }
 
 /*
 }
 
 /*
@@ -226,6 +236,49 @@ compar(p1, p2)
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * Figure out whether the local machine is the same
+ * as the remote machine (RM) entry (if it exists).
+ */
+char *
+checkremote()
+{
+       char name[MAXHOSTNAMELEN];
+       register struct hostent *hp;
+       static char errbuf[128];
+
+       sendtorem = 0;  /* assume printer is local */
+       if (RM != (char *)NULL) {
+               /* get the official name of the local host */
+               gethostname(name, sizeof(name));
+               name[sizeof(name)-1] = '\0';
+               hp = gethostbyname(name);
+               if (hp == (struct hostent *) NULL) {
+                   (void) sprintf(errbuf,
+                       "unable to get official name for local machine %s",
+                       name);
+                   return errbuf;
+               } else (void) strcpy(name, hp->h_name);
+
+               /* get the official name of RM */
+               hp = gethostbyname(RM);
+               if (hp == (struct hostent *) NULL) {
+                   (void) sprintf(errbuf,
+                       "unable to get official name for remote machine %s",
+                       RM);
+                   return errbuf;
+               }
+
+               /*
+                * if the two hosts are not the same,
+                * then the printer must be remote.
+                */
+               if (strcmp(name, hp->h_name) != 0)
+                       sendtorem = 1;
+       }
+       return (char *)0;
+}
+
 /*VARARGS1*/
 fatal(msg, a1, a2, a3)
        char *msg;
 /*VARARGS1*/
 fatal(msg, a1, a2, a3)
        char *msg;