home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / WNWATTCP.ZIP / APPS / LPR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-29  |  9.4 KB  |  338 lines

  1. /*
  2.  * LPR - dump job to printer
  3.  *
  4.  *
  5.  *   Copyright (C) 1991, University of Waterloo
  6.  *
  7.  *   Portions Copyright (C) 1990, National Center for Supercomputer Applications
  8.  *   and portions copyright (c) 1990, Clarkson University
  9.  *
  10.  *   This program is free software; you can redistribute it and/or modify
  11.  *   it, but you may not sell it.
  12.  *
  13.  *   This program is distributed in the hope that it will be useful,
  14.  *   but without any warranty; without even the implied warranty of
  15.  *   merchantability or fitness for a particular purpose.
  16.  *
  17.  *       Erick Engelke                   or via E-Mail
  18.  *       Faculty of Engineering
  19.  *       University of Waterloo          Erick@development.watstar.uwaterloo.ca
  20.  *       200 University Ave.,
  21.  *       Waterloo, Ont., Canada
  22.  *       N2L 3G1
  23.  *
  24.  *
  25.  * The following notes on control and data files were obtained from Clarkson's
  26.  * CUTE project.
  27.  *
  28.  *
  29.  * Control File: format is the first character in the line is a command,
  30.  * the rest of the line is the argument.  Also note lowercase letters
  31.  * denote the data file names (of various types).
  32.  *
  33.  * currently valid commands are:
  34.  *
  35.  *     J -- "job name" on banner page
  36.  *     C -- "class name" on banner page
  37.  *     L -- "literal" user's name to print on banner
  38.  *     T -- "title" for pr
  39.  *     H -- "host name" of machine where lpr was done
  40.  *     P -- "person" user's login name
  41.  *     I -- "indent" amount to indent output
  42.  *     f -- "file name" name of text file to print
  43.  *     l -- "file name" text file with control chars
  44.  *     p -- "file name" text file to print with pr(1)
  45.  *     t -- "file name" troff(1) file to print
  46.  *     n -- "file name" ditroff(1) file to print
  47.  *     d -- "file name" dvi file to print
  48.  *     g -- "file name" plot(1G) file to print
  49.  *     v -- "file name" plain raster file to print (impress)
  50.  *     c -- "file name" cifplot file to print
  51.  *     1 -- "R font file" for troff
  52.  *     2 -- "I font file" for troff
  53.  *     3 -- "B font file" for troff
  54.  *     4 -- "S font file" for troff
  55.  *     N -- "name" of file (used by lpq)
  56.  *     U -- "unlink" name of file to remove
  57.  *           (after we print it. (Pass 2 only)).
  58.  *     M -- "mail" to user when done printing
  59.  *
  60.  * Currently it looks like only a lowercase filename and U command are
  61.  * necessary.  However one should also include J, L, H, and P.
  62.  *
  63.  * In general the lpd program doesn't care what the data file looks like.
  64.  * It should however be of the type specified in the control file
  65.  * otherwise it will probably print incorrectly.
  66.  *
  67.  * The format is ?fA<number><hostname>.  ? is either c for control or d
  68.  * for data files.  Number is a 3 digit number (0 padded) used for job
  69.  * number information.  Hostname is the name of the originating host and
  70.  * had best be equal to whatever shows up in the from field when a
  71.  * connection is opened (ie probably should be the "real" hostname).
  72.  * Currently all of these must be used as the program has them compiled in
  73.  * (by stupid use of pointers).  I may change this in time but currently
  74.  * it is the law if you want everything to work (some things will work
  75.  * just fine without it, queueing a file just wants names, showing the
  76.  * queue expects a number to start in the fourth position, deleting a file
  77.  * expects the hostname to start in the 7th position and go to the end of
  78.  * the filename.
  79.  */
  80.  
  81.  
  82. #include <stdio.h>
  83. #include <io.h>
  84. #include <tcp.h>
  85.  
  86. #define SHORT_LIST 3
  87. #define LONG_LIST  4
  88.  
  89. #define LPQ_PORT 515
  90. #define LOCAL_PORT 722
  91.  
  92.  
  93.  
  94. lpr( localhostname, printer, rhostname, filename, username, servername )
  95. char *localhostname;
  96. char *printer;
  97. char *rhostname;
  98. char *filename;
  99. char *username;
  100. char *servername;
  101. {
  102.     tcp_Socket socketdata, *s;
  103.     longword filesize;
  104.     longword host;
  105.     int status = 0;
  106.     int connected = 0;
  107.     int localport;
  108.     int len;
  109.     longword curtime;
  110.  
  111.     char buffer[ 1024 ];
  112.     char remotename[ 80 ];
  113.     char cmdfile[ 1024 ];
  114.     longword remaining, found, bufsize;
  115.     FILE *f;
  116.  
  117.  
  118.  
  119.     /* */
  120.  
  121.    /* Quick and dirty arg stuff.  This needs to be done right */
  122.  
  123.  
  124.     if (!(f = fopen( filename, "rb"))) {
  125.     printf("Unable to open file '%s'\n", filename );
  126.     return( 3 );
  127.     }
  128.  
  129.    sock_init();
  130.    s = &socketdata;
  131.    if (!(host = resolve( rhostname ))) {
  132.       fprintf(stderr, "lpq: unknown host %s\n",rhostname);
  133.       return(1);
  134.    }
  135.  
  136.    localport = 255 + (MsecClock() & 255);
  137.  
  138.    if ( !tcp_open( s, localport, host, LPQ_PORT, NULL)) {
  139.       fprintf(stderr,"Unable to open socket.");
  140.       tcp_shutdown();
  141.       return(1);
  142.    }
  143.  
  144.    fprintf( stdout, "connecting...\r");
  145.    sock_wait_established( s, sock_delay, NULL, &status );
  146.    connected = 1;
  147.    fprintf(stdout,"connection established");
  148.  
  149.    /* is there an opening message - non-standard but possible */
  150.  
  151.    if (sock_dataready( s )) {
  152.        sock_fastread( s, buffer, sizeof( buffer ));
  153.        sock_tick( s, &status );    /* in case above message closed port */
  154.    }
  155.  
  156.    /* use ipnumber/time  */
  157.    time( &curtime );
  158.    sprintf(remotename,"fA.%8lx.%8lx", my_ip_addr ,curtime);
  159.    /* we are connected */
  160.    sprintf( buffer, "\2%s\n", printer );    /* select a printer */
  161.    sock_puts( s, buffer );
  162.  
  163.    /* state #2 */
  164.  
  165.    sock_wait_input( s, sock_delay, NULL, &status );
  166.  
  167.    sock_fastread( s, buffer, sizeof( buffer ));
  168.  
  169.    switch (*buffer) {
  170.        case 0 : break;
  171.        case 1 : printf("Printer '%s' is not available\n", printer);
  172.         goto close_it;
  173.        default: puts("Some unknown error encounterred");
  174.         goto close_it;
  175.    }
  176.  
  177.    /* printer is accepted, printing file */
  178.    filesize = filelength( fileno( f ));
  179.  
  180.  
  181.    sprintf( buffer, "\3%ld d%s\n", filesize, remotename );
  182.    sock_puts( s , buffer );
  183.    sock_wait_input( s, sock_delay, NULL, &status );
  184.  
  185.    /* state 3, reply from filename */
  186.    sock_fastread( s, buffer, sizeof( buffer ));
  187.  
  188.    switch (*buffer) {
  189.     case 0: break;
  190.     case 1: fprintf(stderr,"remote host complains of bad connection");
  191.         goto close_it;
  192.     case 2: puts("remote host out of storage space");
  193.         goto close_it;
  194.     }
  195.  
  196.     /* dump file */
  197.  
  198.     remaining = filesize;
  199.     bufsize = sizeof( buffer );
  200.     do {
  201.     if (remaining < bufsize ) bufsize = remaining;
  202.     if (!(found = fread( buffer, 1, sizeof(buffer), f)))
  203.         break;
  204.     sock_write( s, buffer, found );
  205.     sock_tick( s , &status );
  206.     if (sock_dataready( s )) {
  207.         puts("LPR: interrupted on transfer...");
  208.         goto close_it;
  209.         break;
  210.     }
  211.     } while ( (remaining -= found) > 0 );
  212.  
  213.  
  214.     sock_putc( s, 0 );
  215.  
  216.     /* check on status of this file */
  217.  
  218.     sock_wait_input( s, sock_delay, NULL, &status );
  219.     sock_fastread( s, buffer, sizeof(buffer));
  220.  
  221.     switch (*buffer) {
  222.     case 0: break;
  223.     default:puts("file was rejected");
  224.         goto close_it;        /* could retry */
  225.     }
  226.  
  227.     sprintf( cmdfile,   "H%s\n"  "P%s\n" "C%s\n" "G%s\n" "L%s\n"
  228.             "T%s\n" "fd%s\n" "N%s\n" "Ud%s\n" "J%s\n",
  229.     localhostname,    /* eg "maggot.watstar" */
  230.     username,    /* eg "erick", */
  231.     servername,    /* eg "development", */
  232.  
  233.         "nobody",    /* group */
  234.     username,        /* eg  "erick",    for on banner */
  235.  
  236.         "SomeJobTitle",    /* title */
  237.     remotename,    /* file processor */
  238.     "local_name",
  239.     remotename,
  240.     "Job_name"
  241.     );
  242.     remotename[1] ^= 1;
  243.  
  244.     sprintf( buffer, "\2%d c%s\n", strlen( cmdfile ), remotename );
  245.  
  246.     sock_puts( s , buffer );
  247.     sock_flush( s );
  248.  
  249.     sock_wait_input( s, sock_delay, NULL, &status );
  250.     sock_fastread( s, buffer, sizeof( buffer ));
  251.  
  252.     switch (*buffer) {
  253.     case 0: break;
  254.         case 1: puts("Bad connection");
  255.         goto close_it;
  256.         case 2: puts("Out of space on host");
  257.                 goto close_it;
  258.         default:puts("Unknown error");
  259.                 goto close_it;
  260.     }
  261.  
  262.     sock_puts( s, cmdfile );
  263.     sock_putc( s, 0 );
  264.     sock_flush( s );
  265.  
  266.     sock_wait_input( s, sock_delay, NULL, &status );
  267.     sock_fastread( s, buffer, sizeof( buffer ));
  268.  
  269.     switch (*buffer) {
  270.     case 0: puts("Complete");
  271.         sock_putc( s, 0 );
  272.         sock_flush( s );
  273.         break;
  274.         default:puts("Control file rejected");
  275.                 status = 3;
  276.                 break;
  277.     }
  278.  
  279.     /* all roads come here */
  280. close_it:
  281.     sock_tick( s, &status);    /* in case they sent reset */
  282.     sock_close( s );
  283.     sock_wait_closed( s, sock_delay, NULL, &status );
  284.  
  285. sock_err:
  286.     switch( status ) {
  287.     case 1: break;
  288.     case-1: fprintf(stderr,"Remote host reset connection\n\r");
  289.         status = 3;
  290.         break;
  291.     }
  292.     if (!connected)
  293.        fprintf( stdout, "\n\rCould not get connected.  Perhaps you were not in the /etc/hosts.lpd file!\n\r");
  294.  
  295.     return( status );
  296. }
  297.  
  298.  
  299. main(argc, argv)
  300. int argc;
  301. char **argv;
  302. {
  303.     char remotename[128];
  304.     char *filename;
  305.     char *printer;
  306.     char *userid, *server;
  307.     char *rhostname;
  308.     int status;
  309.  
  310.     userid = server = "UNKNOWN";
  311.  
  312.     puts("LPR using Waterloo TCP");
  313.     switch (argc) {
  314.     case 3:
  315.         /* no printername */
  316.         rhostname = argv[1];
  317.         filename = argv[2];
  318.         printer = "lp";
  319.         break;
  320.     case 6:
  321.         /* whole thing */
  322.         userid = argv[4];
  323.         server = argv[5];        /* and continue on below */
  324.     case 4:
  325.         /* Hostname and printer */
  326.         printer = argv[1];
  327.         rhostname = argv[2];
  328.         filename = argv[3];
  329.         break;
  330.     default:
  331.           fprintf(stdout, "Usage: LPR [printer] host filename [userid server]");
  332.           exit(1);
  333.    }
  334.    status = lpr( "maggot", printer, rhostname, filename, userid, server );
  335.  
  336.    return( status );
  337. }
  338.