home *** CD-ROM | disk | FTP | other *** search
/ IBM Presents OS/2 Software Hits 1995 / OS-2_SW_HITS_2ND_EDITION_1995.ISO / i17 / lwp42n.exe / UNIXLPR.C < prev   
C/C++ Source or Header  |  1994-10-05  |  4KB  |  222 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <errno.h>
  6. #include <sys/stat.h>
  7. #include <netdb.h>
  8. #include <netinet/in.h>
  9. /*
  10.     A Sample LPR program for UNIX systems which currently don't support
  11. the LPR protocol. Mainly for SYS V systems.
  12.  
  13.     This is an unsupported program.
  14. */
  15.  
  16.  
  17.  
  18. char    line[132];
  19. int    pfd;
  20. #ifdef BUFSIZ
  21. #undef BUFSIZ
  22. #endif
  23. #define BUFSIZ 512
  24. /*
  25.  * Send a data file to the remote machine and spool it.
  26.  * Return positive if we should try resending.
  27.  */
  28. sendfile( file)
  29.     char *file;
  30. {
  31.     register int f, i, amt;
  32.     struct stat stb;
  33.     char buf[BUFSIZ];
  34.     int sizerr, resp;
  35.  
  36.     if (stat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0)
  37.     {
  38.         perror("hello");
  39.         return(-1);
  40.     }
  41.     /*
  42.      * Check to see if data file is a symbolic link. If so, it should
  43.      * still point to the same file or someone is trying to print something
  44.      * he shouldn't.
  45.      */
  46.     (void) sprintf(buf, "\3%ld %s\n",  stb.st_size, file);
  47.     amt = strlen(buf);
  48.     for (i = 0;  ; i++) {
  49.         if (write(pfd, buf, amt) != amt ||
  50.             (resp = response()) < 0 || resp == '\1') {
  51.             (void) close(f);
  52.             return(-2);
  53.         } else if (resp == '\0')
  54.             break;
  55.         if (i == 0)
  56.             printf("no space on remote; waiting for queue to drain");
  57.         if (i == 10)
  58.             printf("Can't send; queue full\n");
  59.         sleep(5 * 60);
  60.     }
  61.     sizerr = 0;
  62.     for (i = 0; i < stb.st_size; i += BUFSIZ) {
  63.         amt = BUFSIZ;
  64.         if (i + amt > stb.st_size)
  65.             amt = stb.st_size - i;
  66.         if (sizerr == 0 && read(f, buf, amt) != amt)
  67.             sizerr = 1;
  68.         if (write(pfd, buf, amt) != amt) {
  69.             (void) close(f);
  70.             return(-2);
  71.         }
  72.     }
  73.     (void) close(f);
  74.     if (sizerr) {
  75.         printf("%s: changed size\n", file);
  76.         /* tell recvjob to ignore this file */
  77.         (void) write(pfd, "\1", 1);
  78.         return(-1);
  79.     }
  80.     if (write(pfd, "\0", 1) != 1 || response())
  81.         return(-2);
  82.     return(0);
  83. }
  84. /*
  85.  * Check to make sure there have been no errors and that both programs
  86.  * are in sync with eachother.
  87.  * Return non-zero if the connection was lost.
  88.  */
  89. response()
  90. {
  91.     char resp;
  92.  
  93.     if (read(pfd, &resp, 1) != 1) {
  94.         fprintf(stderr,"Connection lost to queue\n");
  95.         return(-1);
  96.     }
  97.     return(resp);
  98. }
  99. /*
  100.  * Create a connection to the remote printer server.
  101.  * Most of this code comes from rcmd.c.
  102.  */
  103. getport(rhost)
  104.     char *rhost;
  105. {
  106.     struct hostent *hp;
  107.     struct servent *sp;
  108.     struct sockaddr_in sin;
  109.     int s, timo = 1, lport = IPPORT_RESERVED - 1;
  110.     int err;
  111.  
  112.     /*
  113.      * Get the host address and port number to connect to.
  114.      */
  115.     hp = gethostbyname(rhost);
  116.     if (hp == NULL)
  117.     {
  118.         fprintf(stderr,"unknown host %s\n", rhost);
  119.         exit(1);
  120.     }
  121.     bzero((char *)&sin, sizeof(sin));
  122.     bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
  123.     sin.sin_family = hp->h_addrtype;
  124.     sin.sin_port = htons(515);
  125.  
  126.     /*
  127.      * Try connecting to the server.
  128.      */
  129. retry:
  130.     s = socket(AF_INET,SOCK_STREAM,0);
  131.     if (s < 0)
  132.         return(-1);
  133.  
  134.     if (connect(s, (caddr_t)&sin, sizeof(sin), 0) < 0) {
  135.         err = errno;
  136.         (void) close(s);
  137.         errno = err;
  138.         if (errno == EADDRINUSE) {
  139.             lport--;
  140.             goto retry;
  141.         }
  142.         if (errno == ECONNREFUSED && timo <= 16) {
  143.             sleep(timo);
  144.             timo *= 2;
  145.             goto retry;
  146.         }
  147.         return(-1);
  148.     }
  149.     return(s);
  150. }
  151.  
  152. /*
  153.  * Acquire line printer or remote connection.
  154.  */
  155. openpr(RM,RP)
  156.     char *RM,*RP;
  157. {
  158.     register int i, n;
  159.     int resp;
  160.  
  161.     for (i = 1; ; i = i < 256 ? i << 1 : i) {
  162.         resp = -1;
  163.         pfd = getport(RM);
  164.         if (pfd >= 0) {
  165.             (void) sprintf(line, "\2%s\n", RP);
  166.             n = strlen(line);
  167.             if (write(pfd, line, n) == n &&
  168.                 (resp = response()) == '\0')
  169.                 break;
  170.             (void) close(pfd);
  171.         }
  172.         if (i == 1) {
  173.             if (resp < 0)
  174.                 printf("waiting for %s to come up\n", RM);
  175.             else {
  176.                 printf("waiting for queue to be enabled on %s\n", RM);
  177.                 i = 256;
  178.             }
  179.         }
  180.         sleep(i);
  181.     }
  182. }
  183.  
  184. main(argc,argv)
  185. int argc;
  186. char *argv[];
  187. {
  188.     int    i,resp;
  189.  
  190.     if ( argc != 5)
  191.     {
  192.         fprintf(stderr,"Usage: unixlpr host printer username file\n");
  193.         exit(1);
  194.     }
  195. again:
  196.     openpr(argv[1],argv[2]);
  197. reprint:
  198.     i=sendfile(argv[4]);
  199.     switch(i)
  200.     {
  201.     case 0:
  202.         sprintf(line,"\2%d cf\n",strlen(argv[3])+strlen(argv[1])+4);
  203.         if (write(pfd, line, strlen(line)) != strlen(line) ||
  204.             (resp = response()) < 0 || resp == '\1') {
  205.             goto reprint;
  206.         } else if (resp == '\0')
  207.         {
  208.             sprintf(line,"P%s\nf%s\n\0",argv[3],argv[1]);
  209.             write(pfd,line,strlen(line)+1);
  210.             resp = response();
  211.         }
  212.         close(pfd);
  213.         exit(0);
  214.     case -1:
  215.         close(pfd);
  216.         fprintf(stderr,"Error sending file.\n");
  217.         exit(1);
  218.     case -2:
  219.         goto reprint;
  220.     }
  221. }
  222.