fixed getport() so sockets are not left open after errors.
[unix-history] / usr / src / usr.sbin / lpr / common_source / common.c
index 9703265..0f16a7c 100644 (file)
@@ -1,4 +1,4 @@
-/*     common.c        4.2     83/05/13        */
+/*     common.c        4.5     83/06/02        */
 /*
  * Routines and data common to all the line printer functions.
  */
 /*
  * Routines and data common to all the line printer functions.
  */
@@ -53,21 +53,23 @@ char        *from = host;   /* client's machine name */
  * Create a connection to the remote printer server.
  * Most of this code comes from rcmd.c.
  */
  * Create a connection to the remote printer server.
  * Most of this code comes from rcmd.c.
  */
-getport()
+getport(rhost)
+       char *rhost;
 {
        struct hostent *hp;
        struct servent *sp;
        struct sockaddr_in sin;
        int s, timo = 1, lport = IPPORT_RESERVED - 1;
 {
        struct hostent *hp;
        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.
         */
-       if (RM == NULL)
+       if (rhost == NULL)
                fatal("no remote host to connect to");
                fatal("no remote host to connect to");
-       hp = gethostbyname(RM);
+       hp = gethostbyname(rhost);
        if (hp == NULL)
        if (hp == NULL)
-               fatal("unknown host %s", RM);
+               fatal("unknown host %s", rhost);
        sp = getservbyname("printer", "tcp");
        if (sp == NULL)
                fatal("printer/tcp: unknown service");
        sp = getservbyname("printer", "tcp");
        if (sp == NULL)
                fatal("printer/tcp: unknown service");
@@ -84,13 +86,14 @@ retry:
        if (s < 0)
                return(-1);
        if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
        if (s < 0)
                return(-1);
        if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 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;
@@ -111,18 +114,15 @@ rresvport(alport)
        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s < 0)
                return(-1);
        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s < 0)
                return(-1);
-       for (;;) {
+       for (; *alport > IPPORT_RESERVED/2; (*alport)--) {
                sin.sin_port = htons((u_short) *alport);
                if (bind(s, (caddr_t)&sin, sizeof(sin), 0) >= 0)
                        return(s);
                if (errno != EADDRINUSE && errno != EADDRNOTAVAIL)
                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) {
-                       printf("%s: All ports in use\n", name);
-                       return(-1);
-               }
+                       break;
        }
        }
+       (void) close(s);
+       return(-1);
 }
 
 /*
 }
 
 /*
@@ -172,7 +172,7 @@ getq(namelist)
        if ((dirp = opendir(".")) == NULL)
                return(-1);
        if (fstat(dirp->dd_fd, &stbuf) < 0)
        if ((dirp = opendir(".")) == NULL)
                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
@@ -181,7 +181,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) {
@@ -191,7 +191,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);
                /*
@@ -202,7 +202,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;
        }
@@ -211,6 +211,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);
 }
 
 /*
 }
 
 /*
@@ -240,17 +244,3 @@ fatal(msg, a1, a2, a3)
        putchar('\n');
        exit(1);
 }
        putchar('\n');
        exit(1);
 }
-
-fatalerror(msg)
-       char *msg;
-{
-       extern int sys_nerr;
-       extern char *sys_errlist[];
-
-       printf("%s: ", name);
-       if (*msg)
-               printf("%s: ", msg);
-       fputs(errno < sys_nerr ? sys_errlist[errno] : "Unknown error" , stdout);
-       putchar('\n');
-       exit(1);
-}