home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / 3bnet / part02 < prev    next >
Encoding:
Text File  |  1987-08-27  |  43.0 KB  |  1,762 lines

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v11i026:  3BNet utilities and printer spooler, Part02/02
  5. Message-ID: <1250@uunet.UU.NET>
  6. Date: 28 Aug 87 13:23:20 GMT
  7. Sender: Unknown@uunet.UU.NET
  8. Organization: UUNET Communications Services, Arlington, VA
  9. Lines: 1750
  10. Approved: rs@uunet.UU.NET
  11.  
  12. Submitted-by: hayes%wizard@sdcsvax.ucsd.edu (James Hayes)
  13. Posting-number: Volume 11, Issue 26
  14. Archive-name: 3bnet/Part02
  15.  
  16. # This is a shell archive.  Remove anything before this line,
  17. # then unpack it by saving it in a file and typing "sh file".
  18.  
  19. echo x - Makefile
  20. sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
  21. all:    census
  22.  
  23. census:    census.o
  24.     cc census.o -o census -ltermlib
  25. @//E*O*F Makefile//
  26. chmod u=rw,g=r,o= Makefile
  27.  
  28. echo x - census.c
  29. sed 's/^@//' > "census.c" <<'@//E*O*F census.c//'
  30. #include "census.h"
  31. #include <ctype.h>
  32. #include <curses.h>
  33. #include <signal.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <sys/utsname.h>
  37.  
  38. char *them;
  39. char us[9];
  40. char thetab[MAXNODES][9];
  41. char node[9];
  42. char temp[150];
  43.  
  44. static char *statmsg[] = {" UP ","DOWN",
  45.                 "?   "," ?  ","  ? ","   ?"};
  46.  
  47. suicide()
  48. {
  49.     nl();
  50.     echo();
  51.     nocbreak();
  52.     noraw();
  53.     refresh();
  54.     endwin();
  55.     printf("\nCleaning up...\n");
  56.     exit(0);
  57. }
  58.  
  59. main(argc,argv)
  60. int argc;
  61. char **argv;
  62. {
  63.     int i, numentries, minutes;
  64.     struct utsname name;
  65.  
  66.     them= MS(strlen(TMPDIR)+9);
  67.  
  68.     if (argc>1) {
  69.         minutes=atoi(argv[1]);
  70.  
  71.         if ((minutes<0)||(minutes>200)) {
  72.             fprintf(stderr,"Usage: %s [minutes]\n",argv[0]);
  73.             fprintf(stderr,"       (where minutes is 0 to 200)\n");
  74.             exit(1);
  75.         }    
  76.     }
  77.     else minutes=15;
  78.  
  79.     setup();
  80.  
  81.     uname(&name);
  82.     strcpy(us,name.sysname);
  83.  
  84.     do {
  85.         numentries=gettable(argv);
  86.  
  87.         for (i=0;i<numentries;i++)
  88.             if ( (talk_to(i))==0 )
  89.                 statdisp(0,i+1);
  90.             else {
  91.                 statdisp(1,i+1);
  92.                 system(KILLCMD);
  93.             }
  94.         stall(minutes);
  95.     } while (1);
  96. }
  97.  
  98. int talk_to(i)
  99. int i;
  100. {
  101.     int limit;
  102.     int counter;
  103.  
  104.     limit=MAXTIMEOUT;
  105.     counter=0;
  106.     
  107.     sprintf(them,TMPDIR,thetab[i]);
  108.     sprintf(temp,RTOUCHCMD,thetab[i],us,them);
  109.     unlink(them);
  110.     system(temp);
  111.  
  112.     statdisp(2,i+1);
  113.     
  114.     do {
  115.         sleep(2);
  116.         limit-=2;
  117.         statdisp(counter+2,i+1);
  118.         counter=(counter+1)%4;
  119.         if ( (access(them,0))==0) break;
  120.     } while (limit>0);
  121.  
  122.     if ( (access(them,0))!=0) return(1);
  123.         else {
  124.             unlink(them);
  125.             return(0);
  126.         }
  127. }
  128.  
  129.  
  130. setup()
  131. {
  132.     int i;
  133.  
  134.     signal(SIGINT,SIG_IGN);
  135.     signal(SIGHUP,SIG_IGN);
  136.     signal(SIGQUIT,SIG_IGN);
  137.  
  138.     initscr();
  139.  
  140.     nonl();
  141.     cbreak();
  142.     raw();
  143.     noecho();
  144.     clear();
  145.     refresh();
  146.     nodelay(stdscr,1);
  147.     
  148.     attrset(A_REVERSE);
  149.     mvaddstr(1,1,
  150. "                                                                              "
  151. );
  152.     mvaddstr(22,1,
  153. "                                                                              "
  154. );
  155.     attrset(A_NORMAL);
  156.     mvaddstr(0,2,"Network status report:");
  157.     MYrefresh;
  158. }
  159.  
  160. int gettable(argv)
  161. char **argv;
  162. {
  163.     static char node[9];
  164.     FILE *table;
  165.     int i;
  166.  
  167.     move(23,1); 
  168.     clrtoeol();
  169.     mvaddstr(23,1,"Gathering table data.");
  170.     MYrefresh;    
  171.  
  172.     if ( (access(TABLECMD,1))!=0) {
  173.         fprintf(stderr,"%s: ",argv[0]);
  174.         perror(TABLECMD);
  175.         suicide();
  176.     }
  177.  
  178.         table=popen(TABLECMD,"r");
  179.         for (i=0; i<6 ; i++) fgets(temp,81,table);
  180.  
  181.         i=0;
  182.         do {
  183.             if ( (fgets(temp,81,table))!=NULL) {
  184.                 if (strlen(temp) > 3) {
  185.                     awk_node(node,temp);
  186.                     if (strcmp(node,us)!=0)  {
  187.                         strcpy(thetab[i++],node);
  188.                         nodedisp(node,i);
  189.                     }
  190.                 }
  191.             }
  192.             else break;
  193.         } while (1);
  194.     move(23,1); 
  195.     clrtoeol();
  196.     mvaddstr(23,1,"Hit any key to exit.");
  197.     MYrefresh;
  198.     pclose (table);
  199. return(i);
  200. }
  201.  
  202. awk_node(node,temp)
  203. char *node;
  204. char *temp;
  205. {
  206.     int i;
  207.     strncpy(node,temp,8);
  208.     for(i=8; i>0; i--) if (isalnum(temp[i])) break;
  209.                         else node[i]='\0';
  210. }
  211.  
  212. stall(yawn)
  213. int yawn;
  214. {
  215.     int i,j;
  216.  
  217.     move(23,1);
  218.     clrtoeol();
  219.     mvaddstr(23,1,"   minutes till next update (Hit any key to exit)");
  220.     
  221.     for (i=yawn;i>0;i--) {
  222.         if (i==1) mvaddstr(23,2,
  223.             "   minute till next update (Hit any key to exit)  ");
  224.         mvprintw(23,1,"%2d",i);    
  225.         MYrefresh;
  226.         for (j=0;j<60;j++) {
  227.             if (getch()!= (-1)) suicide();
  228.             sleep(1);
  229.         }
  230.     }
  231. }
  232.  
  233. nodedisp(name,where)
  234. char *name;
  235. int where;
  236. {
  237.     int x,y;
  238.  
  239.     x=(where-1)%ROWS+3;
  240.     y=(where-1)/ROWS*COLWIDTH;
  241.  
  242.     mvaddstr(x, y+1 ,name);
  243.     mvaddch(x, y+11,'[');
  244.     mvaddch(x, y+16,']');
  245. }
  246.  
  247. statdisp(status,where)
  248. int status;
  249. int where;
  250. {
  251.     int x,y;
  252.  
  253.     x=(where-1)%ROWS+3;
  254.     y=(where-1)/ROWS*COLWIDTH;
  255.  
  256.     if (getch()!= (-1)) suicide();
  257.     switch(status) {
  258.     case 1: attrset(A_BLINK);
  259.             mvaddch( x, y+18, '*');
  260.             break;
  261.     case 2:
  262.     case 3:
  263.     case 4:
  264.     case 5: attrset(A_DIM|A_REVERSE);
  265.             break;
  266.     }
  267.  
  268.     move(0,0);
  269.     mvaddstr( x, y+12,statmsg[status]);
  270.     attrset(A_NORMAL);
  271.     MYrefresh;
  272. }
  273. @//E*O*F census.c//
  274. chmod u=rw,g=r,o= census.c
  275.  
  276. echo x - census.h
  277. sed 's/^@//' > "census.h" <<'@//E*O*F census.h//'
  278. #define TABLECMD    "/usr/bin/nitable"
  279. #define RTOUCHCMD    "/usr/bin/nisend -e -s -d%s -!\042nisend -e -s -d%s \
  280. -f%s /etc/fstab\042"
  281. #define KILLCMD        "/usr/bin/nisend -s -e -k all"
  282. #define TMPDIR        "/usr/tmp/%s" 
  283. #define MAXTIMEOUT    60
  284.  
  285. #define MAXNODES    100
  286. #define ROWS        18
  287. #define COLWIDTH    20
  288.  
  289. #define MYrefresh move(12,78); refresh()
  290. #define MS(x) (char *)malloc(x)
  291. @//E*O*F census.h//
  292. chmod u=rw,g=r,o=r census.h
  293.  
  294. echo x - census.man
  295. sed 's/^@//' > "census.man" <<'@//E*O*F census.man//'
  296. @.TH CENSUS 1 Local
  297. @.AT 5 2.0
  298. @.SH NAME
  299. census - who's alive on 3bnet
  300. @.sp
  301. @.SH SYNOPSIS
  302. @.PP
  303. census [timeout]
  304. @.sp
  305. @.SH DESCRIPTION
  306. @.I Census
  307. allows you to `poll' the 3bnet Ethernet for active machines.
  308. Although
  309. @.I official
  310. AT&T documentation states that the network configuration
  311. table will automatically keep track of UP/DOWN nodes, this was not
  312. proven to be truthful.  Hence
  313. @.IR census .
  314. @.sp
  315. The 
  316. @.I census
  317. program lives happily in the /usr/3bnet/bin directory.  When
  318. activated with no options, 
  319. @.I census 
  320. sends commands to all the machines on the network asking them to
  321. report back.
  322. @.I census
  323. will spend one minute waiting for each reply and updating the display
  324. in real time using
  325. @.IR curses (3X).
  326. When all the nodes have been checked,
  327. @.I census
  328. stops and informs you that 3bnet is indeed (for lack of a better
  329. word) sane and sleeps for [timeout] minutes (default 15) before trying again.
  330. @.sp
  331. @.SH SEE ALSO
  332. @.IR curses (3X),
  333. @.IR nisend (1).
  334. @.SH AUTHOR
  335. James Hayes, University of California at San Diego
  336. @.br
  337. (ARPA: hayes@sdcsvax.ucsd.edu)
  338. @//E*O*F census.man//
  339. chmod u=rw,g=r,o= census.man
  340.  
  341. echo x - sysprint.man
  342. sed 's/^@//' > "sysprint.man" <<'@//E*O*F sysprint.man//'
  343. @.TH SYSPRINT 7 Local 
  344. @.AT 5 2.0
  345. @.SH NAME
  346. /etc/sysprint - printer name database.
  347. @.SH DESCRIPTION
  348. @.PP
  349. The file 
  350. @.B /etc/sysprint
  351. is the 
  352. @.I 3bnet
  353. networked printer database.
  354. The file contains information on the English name of a printer,
  355. the name of the
  356. @.I 3bnet
  357. node on which the printer resides, and a flag
  358. that indicates restricted use.  If the user has the login name
  359. "student", he/she may not use printers marked as restricted.
  360. @.br
  361. @.SH FORMAT
  362. @.PP
  363. The general format of the file is similar to many UNIX databases.  A
  364. line beginning with "#" is treated as a comment and blank lines are
  365. ignored.  The information is to be formatted in this manner:
  366. @.sp
  367. @.B NAME
  368. (whitespace)
  369. @.B RESTRICTION 
  370. (whitespace)
  371. @.B NODE_NAME
  372. @.sp 2
  373. For Example:
  374. @.sp
  375. # This is comment, the blank line will be ignored...
  376. @.br
  377. {This is a blank line.}
  378. @.br
  379. gumby        A    3bsw2
  380. @.br
  381. pokey        R    print32
  382. @.br
  383. # This line is the last line.
  384. @.br
  385. @.sp
  386. @.SH NAME
  387. @.PP
  388. This is the English name the user would specify to refer to the
  389. printer connected to
  390. @.B NODE_NAME.
  391. 15 characters maximum length.
  392. @.sp
  393. @.SH RESTRICTION
  394. @.PP
  395. The restriction flag consists of one
  396. @.I CAPITAL
  397. letter.  The letter may be an "R" for
  398. @.B restricted
  399. use, or an "A" for use by
  400. @.BR anyone .
  401. @.sp
  402. @.SH NODE_NAME
  403. @.PP
  404. If it isn't obvious... This is the
  405. @.I 3bnet
  406. node name of the machine the printer is physically connected to.
  407. @.sp
  408. @.SH SEE ALSO
  409. @.IR spool (1)
  410. @.br
  411. @//E*O*F sysprint.man//
  412. chmod u=rwx,g=r,o= sysprint.man
  413.  
  414. exit 0
  415. Newsgroups: net.sources
  416. Subject: 3Bnet utilities/Remote Print Spooling (Part 1 of 2)
  417. Summary: 
  418. Expires: 
  419. Sender: 
  420. Reply-To: hayes@wizard.UUCP (James Hayes)
  421. Followup-To: comp.sys.att
  422. Distribution: net
  423. Organization: UC San Diego Computer Science/Engineering Department.
  424.  
  425. Ok folks, here it is.  Part 1 of 2.  Containing:
  426.  
  427. spool.c spool.h Makefile (for the network spool program)
  428. sysprint (the printer database)
  429. spool.man (the '-man' page)
  430. spool.doc.ms (discussion of network security)
  431.  
  432. These have only been tested on a 3b2/310 running SVR2.0x and I don't make
  433. any guarantees otherwise.  (Besides the guarantee that it is really bad
  434.                                     code... Commented, but bad.)
  435.  
  436. As usual, complain if something doesn't work... I'll try to help as much
  437. as possible, but I can't circumvent acts of god.
  438.  
  439. Jim Hayes, University of California at San Diego.
  440.  
  441. BITNET: hayes%sdcsvax@WISCVM.BITNET
  442. ARPA:    hayes@sdcsvax.ucsd.edu
  443. UUCP:   {pick one close to berkeley}!sdcsvax!hayes
  444.  
  445. ------------------SNIPPITY-------------------
  446. # This is a shell archive.  Remove anything before this line,
  447. # then unpack it by saving it in a file and typing "sh file".
  448. #
  449. # Wrapped by wizard!hayes on Wed May 13 20:12:02 PDT 1987
  450. # Contents:  Makefile spool.c spool.doc.ms spool.h spool.man sysprint
  451. #    sysprint.man
  452.  
  453. echo x - Makefile
  454. sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
  455. #
  456. #
  457. CFLAGS = -g
  458. #
  459. all:    spool 
  460.  
  461. spool:    spool.o spool.defs
  462.     cc spool.o -o spool
  463.  
  464. clean:    
  465.     rm *.o core
  466. @//E*O*F Makefile//
  467. chmod u=rw,g=r,o=r Makefile
  468.  
  469. echo x - spool.c
  470. sed 's/^@//' > "spool.c" <<'@//E*O*F spool.c//'
  471. #include <stdio.h>
  472. #include <sys/utsname.h>          /* System naming fetching library */
  473. #include <string.h>            /* Until Jim can learn strings... */
  474. #include <signal.h>
  475. #include "spool.h"            /* spool.c #defines. */
  476.  
  477. /* **************************************************************
  478. print:
  479.   spool -pprinter_name -b[banner] {files}
  480.  
  481. query:
  482.   spool -pprinter_name -q {<--query.}
  483.  
  484. list available printer:
  485.   spool -l
  486.  
  487. (A -d may be added to turn debugging on.)
  488.  
  489. Author:  James Hayes.  (hayes@sdcsvax.ucsd.edu)
  490. Log: 
  491.         Version 1.5 (Added option for banner.)        13-Feb-86 
  492.     Version 1.6 (Fixed things/cleaned up the code.)    19-Feb-86
  493.     Version 2.0 (Frozen Revision)            03-Mar-86
  494.  
  495. **************************************************************** */
  496.  
  497.    char *printer_name[20],    /* The printer name known to eecs70 students.*/
  498.         *printer_node[20],    /* The node name of the receiving printer. */
  499.     *restriction[2];    /* The restriction flag. */
  500.  
  501.     int validate_printer(),     /* Verify printer exists. */
  502.     list_printers(),    /* List available printers */
  503.     printer_status(),    /* Request remote printer status */
  504.     timeout(),        /* Wait for file to arrive. */
  505.     student,        /* Non-zero if "student" logged in */
  506.     debug;            /* Non-zero if debugging enabled. */
  507.  
  508. /* ********************************************************************** */ 
  509.  
  510. main(argc,argv)
  511. int argc;
  512. char *argv[];
  513.  
  514. {
  515.    FILE *infd, *outfd, *fopen();
  516.  
  517.    extern int errno,        /* What else? */
  518.       optind,            /* For use with getopt (2) */
  519.     opterr,            /* Ditto */
  520.     debug,            /* debug flag */
  521.         student,        /* Non zero if student running program. */
  522.     list_printers(),
  523.     validate_printer();
  524.  
  525.  
  526.    extern char *optarg,        /* Getopt option target string */
  527.     *printer_name[20],    /* The printer name known to ee70 students.*/  
  528.         *printer_node[20],    /* The node name of the receiving printer. */
  529.     *restriction[2];    /* The restriction flag. */
  530.  
  531.    char *mktemp(),        /* MaKe a TeMPorary unique file name */
  532.     *outname,        /* The temporary name itself. */
  533.     *template[150],        /* The template used to create the temp name.*/
  534.     *remote_command[255],   /* The remote command holder to the remote machine */
  535.     *requested_printer,     /* The printer requested by the student.*/
  536.     *banner,        /* The truncated (10chars) banner name. */
  537.     *login_name[20];    /* Login name of calling user. */
  538.        
  539.    int in_char,            /* Current stream input character */
  540.        current_opt,        /* Pointer the next argv[] option. getopt(2) */
  541.        error,            /* Non zero if command line errors found.*/
  542.        prflag,            /* Non zero if a printer was specified */
  543.        list_available,        /* Non zero if a printer list was asked for */
  544.        query,            /* Non zero if printer status requested    */
  545.        banflag,            /* Non zero if a banner was specified */
  546.        exec_status,        /* Exit status of the system call 'system()' */
  547.        i; 
  548.  
  549.    struct utsname name;        /* Structure for the uname() system call */
  550.  
  551.    list_available=        /* Initialize everything. */
  552.    debug=
  553.    query=
  554.    error=
  555.    prflag=
  556.    student=
  557.    banflag=0;   
  558.  
  559.    uname(&name);                    /* Get the system name. */
  560.    sprintf(template,DEFAULT_DIR,name.sysname);        /* Make the temporary file templaye. */
  561.  
  562.    cuserid(login_name);                    /* Get the login name of the user */
  563.    if ( (strcmp(login_name,"student"))==0 ) student++;  /* If student, set the student flag */
  564.  
  565.    if ( (strcmp(argv[3],"@"))==0 ) return_state(argv[1],argv[2]);   /* Invoke the return mode of spool ? */
  566.  
  567.    /* Loop through all possible options and set flags according to what
  568.       is chosen.  If an erronious command line option is choosen, then
  569.       error is set to non-zero and the spooling stops.   */
  570.  
  571.    while  ((current_opt=getopt(argc,argv,"p:b:sld")) !=EOF)
  572.          switch (current_opt)
  573.           {
  574.            case 'p':        /* Printer? */
  575.             prflag++;
  576.             requested_printer=optarg;
  577.             break;
  578.             case 'b':        /* Banner name? */
  579.             banflag++;
  580.             banner=optarg;
  581.             break;
  582.            case 's':         /* Query printer? */
  583.             query++;
  584.             break;
  585.            case 'd':        /* Debug flag? */
  586.             debug++;
  587.             break;
  588.            case 'l':        /* List printers? */
  589.             list_available++;
  590.             break;
  591.            case '?':        /* Bad option? */
  592.             error++;
  593.             break;
  594.           }
  595.  
  596.  
  597. DEBUG Template for making files %s\n",template);
  598. DEBUG Student UID=%d, student flag=%d\n",getuid(),student);
  599.  
  600.       if ( (query) && (prflag))                        /* Got -s and a printer name? */
  601.       if ( (validate_printer(requested_printer))==0 )          /* Valid name? */
  602.         {
  603.           fprintf(stderr,"spool: printer %s does not exist.\n", requested_printer);
  604.           fprintf(stderr, "       To see supported printers, use: spool -l\n"); 
  605.               exit(1);
  606.         }
  607.       else                                /* Everything O.K... Do query. */
  608.         {
  609.           query_request(printer_node);
  610.           exit(0);
  611.          }
  612.  
  613.       if (query)    /*Since -s is a strange option, be polite. */
  614.     {
  615.       fprintf(stderr,"spool: Please request a printer\n");
  616.       exit(2);
  617.     }
  618.  
  619.       if (list_available)         /* List available printers?  */
  620.     {
  621.       DEBUG Listing printers: \n");
  622.       list_printers();
  623.       exit(0);
  624.         }
  625.  
  626.       /********************************************************************
  627.        * Bad flag combinations, ie. Banner and no printer, printer and no
  628.        * banner, no banner and printer, are not allowed.
  629.        ********************************************************************
  630.        */
  631.  
  632.       if ((prflag==NULL) && (banflag)) error++;
  633.       if ((banflag==NULL) && (prflag)) error++;
  634.       if ((banflag==NULL) && (prflag==NULL)) error++;
  635.  
  636.       if (error==0)            /* No errors? Check printer name. */
  637.  
  638.       if ( (validate_printer(requested_printer))==0 )
  639.         {
  640.          fprintf(stderr, "spool: Incorrect printer choice\n");
  641.          error++;
  642.         }
  643.       if (error)
  644.        {
  645.      fprintf(stderr,USAGE);        /* If there was an error, print the */
  646.      list_printers();        /* command usage, and list the */
  647.      exit(3);            /* Available printers. */
  648.        }
  649.  
  650. DEBUG Your printer: node: %s Res: %s Name: %s\n\n", printer_node,restriction, printer_name);
  651.  
  652.        i=optind;              /* Save pointer to beginning of file names in the argv. */
  653.  
  654. /*******************************************************************************************************
  655.  * Scan through each name specified to see if it is readable...  (As usual, complain if not, and exit.)
  656.  *******************************************************************************************************
  657.  */
  658.  
  659.      for (;optind<argc;optind++)
  660.        if (access(argv[i],4) !=NULL)               /* Check for read permissions */
  661.          {
  662.            fprintf(stderr,"spool: error opening %s for transmission.\n", argv[optind]);
  663.            exit(4);
  664.          }
  665.  
  666.     infd=stdin;            /* Default input is stdin. */
  667.     outname=mktemp(template);      /* Form unique filename. */
  668.       outfd=fopen(outname,"w");     /* Open it for writing. */
  669.     if (outfd==NULL)        /* Error? */
  670.        {
  671.         fprintf(stderr,"spool: panic: error opening tempfile %s\n",outname);
  672.         exit(5);    
  673.       }
  674.  
  675.     optind=i;    /* Restore saved argv pointer */
  676.  
  677.     do           /* Copy each file into the transmission file. */
  678.       {
  679.           if (optind < argc)
  680.            {
  681.              infd=fopen(argv[i],"r");   /* Open for reading */
  682.              if (infd==NULL)
  683.               {
  684.             fprintf(stderr,"spool: File %s was deleted, spool attempt aborted.\n",argv[i]);
  685.             exit(6);
  686.               }
  687.            }
  688.            while ( (in_char=getc(infd)) !=EOF) putc(in_char,outfd); 
  689.            if (infd!=stdin) fclose(infd);                /* Don't try and close stdin. */
  690.       } while (++i < argc);                         /* Until all files are done. */
  691.  
  692.       fclose(outfd);                             /* Ready to transmit. */
  693.  
  694.       errno=0;  /* Just in case... */
  695.  
  696.       sprintf(banner,"%.10s",banner);               /* Truncate the banner. */
  697.  
  698.       if ( (strcmp(name.sysname,printer_node))==0)        /* Are we on the same node we are trying to send to? */
  699.         sprintf(remote_command,LOCAL_LP,LOCAL_LP_ARGS);         /* If so, use the local command. */
  700.       else 
  701.         sprintf(remote_command,COMMAND,ARGUMENTS);          /* Otherwise, use the network command. */
  702.  
  703.       DEBUG Remote command:\n%s\n",remote_command);
  704.  
  705.       if (debug==0)
  706.       {
  707.         exec_status=system(remote_command);             /* Execute the command. */
  708.  
  709.         if (exec_status == ERR)                 /* Was there a problem? */
  710.       {
  711.        fprintf(stderr,"spool: can't execute transmit program, spool attempt aborted with\n");
  712.        fprintf(stderr,"       system() erorr %d.\n",errno);
  713.        unlink(outname);
  714.        exit(7);
  715.       }
  716.        }
  717.  
  718. DEBUG Unlinking work file %s.\n",outname);
  719.  
  720.     if (unlink(outname) != NULL)
  721.       {
  722.         fprintf(stderr,"panic: spool could not delete the temporary workfile %s. File(s) did transmit.\n",outname);
  723.         exit(8);
  724.       }
  725.  
  726.   if ( (strcmp(name.sysname,printer_node))!=0)
  727.   list_response(name.sysname);                        /* Wait for status file to come back. & printit. */
  728.  
  729. DEBUG EXIT.\n");
  730. }
  731.  
  732. /****************************************************************************
  733.  * validate (requested_printer);
  734.  *
  735.  *        return code:  0=not found.
  736.  *            non-zero, found.
  737.  *
  738.  *       If found, the node_name of the printer is returned in printer_node,
  739.  *     along with it's restriction in restriction.
  740.  ****************************************************************************
  741.  */
  742.  
  743. validate_printer(requested_printer)
  744. char *requested_printer;
  745. {
  746.   FILE *infd;
  747.  
  748. extern char *printer_name[20],    /* The printer name known to ee70 students.*/  
  749.         *printer_node[20],    /* The node name of the receiving printer. */
  750.     *restriction[2];    /* The restriction flag. */
  751.  
  752. extern int student;
  753.  
  754.   int    in_char,        /* Current stream input char. */
  755.     found,            /* found requested printer in SYS_PRINTERS file if non-zero. */
  756.     scan_OK;        /* Result of fscanf. -1=EOF. */
  757.     
  758.   found=0;
  759.   if ((infd=fopen(SYS_PRINTERS,"r"))==NULL)
  760.   {
  761.     printf(stderr,"spool: Network printer database could not be located.\n");
  762.     exit(10);
  763.   }
  764.   else
  765.   {
  766.    scan_OK=0;
  767.    do
  768.    {
  769.      in_char=getc(infd);            /* Get first character */
  770.      if (in_char==EOL)                 /* Blank line? */
  771.       {
  772.        do in_char=getc(infd) ;          /* Skip any extra newlines. */
  773.        while (in_char==EOL);
  774.       }
  775.      if (in_char==SCRATCH)              /* Was it a beginning of a comment? */
  776.      do in_char=getc(infd) ;
  777.      while ( (in_char!=EOL) && (in_char!=EOF) ) ;
  778.              
  779.      if (in_char==EOF) scan_OK=-1;          /* End of file? God forbid! */
  780.  
  781.      if ((scan_OK==-1) || (in_char==SCRATCH) || (in_char==EOL)) ;
  782.      else
  783.        {
  784.     ungetc(in_char,infd);    /* Put the first character back. */
  785.     scan_OK=fscanf(infd,"%s%s%s",printer_name,restriction, printer_node);
  786.  
  787.        if ( (strcmp(printer_name,requested_printer))==0 ) /* Found? */
  788.          {
  789.              scan_OK=EOF;               /* Found? YES!, so artificially end the file. */
  790.          found++;
  791.          DEBUG Found printer name %s, restriction=%s.\n",printer_name, restriction);
  792.          DEBUG Student flag=%d\n",student);
  793.  
  794.              if ( ((strcmp(restriction,"R"))==0)  && (student>0) )
  795.                {
  796.              fprintf(stderr, "spool: You are not allowed to use printer %s.\n", requested_printer);
  797.              exit(13);
  798.                }
  799.          }
  800.        }
  801.    } while (scan_OK!=EOF);        /* Keep going until EOF */
  802.      fclose(infd);
  803.   }
  804.    return found;
  805. }
  806.  
  807. /****************************************************************************
  808.  * List available printers from SYS_PRINTERS.
  809.  * (and print them out of course!)
  810.  ****************************************************************************
  811.  */
  812.  
  813. list_printers()
  814. {
  815.   FILE *infd;
  816.  
  817. extern char *printer_name[20],    /* The printer name known to ee70 students.*/  
  818.         *printer_node[20],    /* The node name of the receiving printer. */
  819.     *restriction[2];    /* The restriction flag. */
  820.  
  821. extern int debug;
  822.  
  823. int     in_char,
  824.     scan_OK;
  825.  
  826.   if ((infd=fopen(SYS_PRINTERS,"r"))==NULL)
  827.   {
  828.     printf(stderr,"spool: Network printer database could not be located.\n");
  829.     exit(10);
  830.   }
  831.   else
  832.   {
  833.     fprintf(stdout,"\n   %-15s| %-30s\n","Printer Name:", "Restriction: (A=Anyone, R=Restricted)");
  834.     fprintf(stdout,"   ---------------+--------------------------------------\n");
  835.     scan_OK=0;
  836.     do
  837.      {
  838.        in_char=getc(infd);  /* See above for the comments for this mess. */
  839.        if (in_char==EOL) 
  840.           do in_char=getc(infd); while (in_char==EOL);
  841.  
  842.        if (in_char==SCRATCH)
  843.      do in_char=getc(infd); while ( (in_char!=EOL) && (in_char!=EOF) );
  844.              
  845.        if (in_char==EOF) scan_OK=-1;
  846.        if ((scan_OK==-1) || (in_char==SCRATCH) || (in_char==EOL)) ;
  847.        else
  848.         {
  849.       ungetc(in_char,infd);
  850.       scan_OK=fscanf(infd,"%s%s%s",printer_name,restriction, printer_node);
  851.       fprintf(stdout,"   %-15s|%2s\n",printer_name,restriction);
  852.         }
  853.    } while (scan_OK!=EOF) ;
  854.   }
  855.    fclose(infd);
  856.    fprintf(stdout,"\n");
  857.    return;
  858. }
  859.  
  860. /****************************************************************************
  861.  * List response sent by remote system.  If it hasn't arrived yet, wait
  862.  * until it does.  (Up to 40 seconds.)
  863.  ****************************************************************************
  864.  */
  865. list_response(system_name)            /* Name of this system. (Used to build correct file name.) */
  866. char *system_name;
  867. {
  868.    FILE *infd;
  869.    int in_char;
  870.    char *filename[30];
  871.  
  872.    sprintf(filename,STATUS_TEMPLATE,system_name);
  873.    wait_file(TIMEOUT,filename);            /* Wait for TIMEOUT seconds for file 'filename' to arrive. */
  874.  
  875.    if ( (infd=fopen(filename,"r"))==NULL )
  876.       {
  877.     fprintf(stderr,"spool: Status file \'%s\' is missing. Hmm.\n", system_name);
  878.     exit(11);
  879.       }
  880.     else
  881.       {
  882.     fprintf(stdout,"\n");
  883.         while ( (in_char=getc(infd)) !=EOF) putc(in_char,stdout);     /* List the file. */
  884.     fprintf(stdout,"\n");
  885.     close(infd);
  886.     if ( (unlink(filename)) !=NULL )
  887.         fprintf(stderr,"Can't remove status file %s. Tell proctor.\n", filename);
  888.     exit(8);
  889.       }
  890. }
  891.  
  892. /****************************************************************************
  893.  * query_request(printer_node);
  894.  * Line printer query request for printer 'printer_node'.
  895.  ****************************************************************************
  896.  */
  897.  
  898. query_request(printer_node)
  899. char *printer_node;
  900. {
  901.    extern int errno,
  902.     debug;
  903.  
  904.    int exec_status,
  905.        in_char; 
  906.  
  907.    char *mktemp(),
  908.     *outname,
  909.     *template[150],
  910.     *remote_command[255];  
  911.  
  912.    struct utsname name;        /* System name fetching structure */
  913.  
  914.    uname(&name);         /* Fetch our system name. */
  915.  
  916.    errno=0;
  917.  
  918.    if ( (strcmp(name.sysname,printer_node))==0)       /* Requesting from same machine as printer? */
  919.      sprintf(remote_command,LOCAL_LPSTAT);          /* Issue local lpstat command. */
  920.    else
  921.      sprintf(remote_command,QUERY_COMMAND,QUERY_ARGUMENTS);   /* Otherwise, use remote command. */
  922.  
  923.    DEBUG Remote command: %s\n",remote_command);
  924.  
  925.   if (debug==0)
  926.    {
  927.    exec_status=system(remote_command);
  928.  
  929.       if (exec_status == ERR)
  930.       {
  931.        fprintf(stderr,"spool: Can't execute request program, request attempt aborted with\n");
  932.        fprintf(stderr,"       system() error %d.\n",errno);
  933.        exit(9);
  934.       }
  935.    }
  936.    if ( (strcmp(name.sysname,printer_node))!=0)        /* If requesting from remote machine, wait for results. */
  937.    list_response(name.sysname);
  938. }
  939.  
  940. /****************************************************************************
  941.  * wait_file(seconds,filename);
  942.  * wait 'seconds' for file 'filename'
  943.  * NOTE:  THE FILE BEING WAITED FOR IS UNLINKED, JUST IN CASE AN OLDER 
  944.  *        VERSION OF IT MIGHT BE AROUND.    YOU HAVE BEEN WARNED....
  945.  * 
  946.  * If no file arrives after 'seconds', print error and exit(12) 
  947.  ****************************************************************************
  948.  */
  949. wait_file(seconds,filename)
  950. int seconds;
  951. char *filename;
  952. {
  953.    DEBUG Filename: %s\n",filename);
  954.    unlink(filename);            /* Just in case a leftover exists. */
  955.  
  956.    signal(SIGALRM,timeout);         /* Set the alarm to point to the time out routine. */
  957.    alarm(seconds);            /* Allow seconds timeout. */
  958.    fprintf(stdout,"One moment please, your request is being processed.");
  959.    fflush(stdout);
  960.    
  961.    do 
  962.      {
  963.        fprintf(stdout,".");        /* Print little dots every few seconds to let the user know what's goin on. */
  964.        fflush(stdout);
  965.        sleep(2);
  966.      }
  967.       while ((access(filename,4))!=NULL );    /* Keep doing it until the time runs out, or the file arrives. */
  968.  
  969.   signal(SIGALRM, SIG_IGN);
  970. }
  971.  
  972. timeout()
  973. {
  974.   signal(SIGALRM, SIG_IGN);
  975.   printf("\nSorry, the remote machine is not answering. Please make sure the\n");
  976.   printf("printer/remote machine is operating properly.\n");
  977.   exit(12);
  978. }
  979.  
  980. /****************************************************************************
  981.  * This is the return server for the spool program. It is invoked with
  982.  * spool machine_making_request request_type @
  983.  ****************************************************************************
  984.  */
  985. return_state(sysname,command)
  986. char *sysname,
  987.      *command;
  988. {
  989.  int exec_status; 
  990.  char *remote_command[255];
  991.  
  992.  printf("Command: %s, Sysname: %s\n",command,sysname);
  993.  
  994.   if (strcmp(command,"S")==0)                    /* Status request */
  995.     sprintf(remote_command,STAT_COMMAND,STAT_ARGUMENTS);
  996.  
  997.   if (strcmp(command,"R")==0)                    /* Return lp command status */
  998.     sprintf(remote_command,LP_COMMAND,LP_ARGUMENTS);
  999.  
  1000.   printf("Remote command: %s\n",remote_command);
  1001.  
  1002.   exec_status=system(remote_command);
  1003.  
  1004.   exit(0);
  1005. }
  1006.  
  1007. @//E*O*F spool.c//
  1008. chmod u=rw,g=r,o=r spool.c
  1009.  
  1010. echo x - spool.doc.ms
  1011. sed 's/^@//' > "spool.doc.ms" <<'@//E*O*F spool.doc.ms//'
  1012. @.ST
  1013. @.nr VS 18
  1014. @.ds LH "EECS 70
  1015. @.ds RH %
  1016. @.ds CH "Project Report
  1017. @.ds CF
  1018. @.sp 2i
  1019. @.LG
  1020. @.ce
  1021. \fBReport of activities\fI
  1022. @.sp
  1023. @.ce
  1024. \fBPrinter Spooling Over 3bnet\fR
  1025. @.sp 2
  1026. @.ce
  1027. @.SM
  1028. @.nr VS 15
  1029. James A. Hayes
  1030. @.br
  1031. @.ce
  1032. University of California,
  1033. @.br
  1034. @.ce
  1035. San Diego
  1036. @.br
  1037. @.sp 3
  1038. @.ce
  1039. @.LG
  1040. @.I ABSTRACT
  1041. @.sp
  1042. @.QP
  1043. @.LG
  1044. @.nr VS 18
  1045. The goal of the
  1046. @.I spool
  1047. implementation is to allow students to send information to printers
  1048. not physically
  1049. connected to their machine.  This design replaces the current method of
  1050. having to physically login to the printer's host.  This document
  1051. will provide an outline of the 
  1052. @.I spool
  1053. implementation.
  1054. @.sp 3
  1055. @.nr VS 14
  1056. @.LP
  1057. March, 1986
  1058. @.br
  1059. @.nr PS 12
  1060. @.bp
  1061. @.SH
  1062. Introduction
  1063. @.PP
  1064. While the concept of a remote printer spooling system is easy to
  1065. understand, the actual implementation is at best, complicated.  If you have
  1066. not already done so, please read the
  1067. @.I spool
  1068. manual page which will explain the \fIspool\fR command syntax.
  1069. This document will try to explain the
  1070. @.I spool
  1071. implementation in three stages.  An explanation of network
  1072. security, a description of the
  1073. @.I nisend
  1074. command,  and finally,
  1075. a nuts-and-bolts description of the spooling software.
  1076. @.sp
  1077. @.SH
  1078. 1. Network Security
  1079. @.PP
  1080. The AT&T 3B2 computer is capable of running an Ethernet network 
  1081. communications
  1082. system.  While the software provided with the Ethernet hardware is complete, 
  1083. a major problem arises when trying to use it in an educational environment.
  1084. The network commands are not protected from subversive
  1085. application.  That is
  1086. to say, it is dangerous when
  1087. @.I anyone
  1088. is given permission to use the network
  1089. commands.  This means that a student on machine A can
  1090. @.I copy
  1091. or knowingly
  1092. @.I damage
  1093. homework files from a student on machine B.
  1094. @.PP
  1095. The means for securing
  1096. the crucial network command (\fInisend\fR)
  1097. is borne from built-in UNIX\(dg
  1098. @.FS
  1099. \(dg.
  1100. UNIX is a trademark of AT&T Bell Laboratories.
  1101. @.FE
  1102. execution privileges.
  1103. @.PP
  1104. The network command
  1105. @.I nisend
  1106. is owned by
  1107. @.B bin
  1108. and is a member of the newly
  1109. created group
  1110. \fBnisecure\fR.  It has  only the owner and group execute
  1111. permissions set.  This will not allow anyone but
  1112. @.B root
  1113. or a member of the
  1114. group
  1115. @.B nisecure
  1116. to execute the
  1117. @.I nisend
  1118. program.  The print spooler (\fIspool\fR) is
  1119. also a member of the group
  1120. @.B nisecure
  1121. and sets its group identification (sgid) on
  1122. execution.  The execute permissions for
  1123. @.I spool
  1124. allow it to be run by anyone.
  1125. @.PP
  1126. Since the group ID of
  1127. @.I spool
  1128. is the same as \fInisend\fR,
  1129. @.I spool
  1130. is allowed to call
  1131. \fInisend\fR.  So far, 
  1132. @.I spool
  1133. is the only program that is allowed to call \fInisend\fR.
  1134. @.PP
  1135. The access permissions (as seen by \fIls\fR)
  1136. look like this:
  1137. @.KS
  1138. @.sp
  1139. @.ce
  1140. /usr/bin/nisend /usr/bin/spool
  1141. @.TS
  1142. center;
  1143. l l l l l l.
  1144. -rwxr-s---    bin    nisecure    xx/xx/86    12:00    nisend
  1145. -rwxr-xr-x    root    nisecure    xx/xx/86    12:00    spool
  1146. @.TE
  1147. @.KE
  1148. @.sp
  1149. @.SH
  1150. 2. The `nisend' Program
  1151. @.PP
  1152. The
  1153. @.I nisend
  1154. program is provided by AT&T as a front-end file transfer and
  1155. remote command execution system to be used by programs at the
  1156. shell and applications
  1157. level.  It is complete, but does have a few problems that are worth
  1158. mentioning.
  1159. @.PP
  1160. @.I Nisend
  1161. sends mail to its users after every request, transfer, command
  1162. execution, error and hiccup.  The default file access mode is set to 
  1163. 600 (owner read/write).  The directory where the file will be saved (once
  1164. transmitted) is not the same directory it was taken from.  The default
  1165. receiving directory is ~/rje/\fIname\fR.  The
  1166. local file to be transmitted must
  1167. be the last item on the command line.  The one line \*Q3bnet job xxxxyyy
  1168. submitted\*U is always printed.
  1169. @.PP
  1170. The  above problems may be circumvented by command line options.  To
  1171. stop mail, use the
  1172. @.I undocumented
  1173. -e option.  To set
  1174. the access permissions of
  1175. the remote files, use the -a\fImode\fR option.  To specify
  1176. what directory the
  1177. file is to be saved in, use the -f\fIpath\fR option.  The
  1178. \*Q3bnet...\*U message may be silenced by the -s option.
  1179. @.PP
  1180. The spool program uses a standard form of the
  1181. @.I nisend
  1182. command that avoids all the above problems. It looks like this:
  1183. @.LP
  1184. @.in +.5i
  1185. @.ti -.5i
  1186. @.na
  1187. nisend -s -e -d\fIremote_machine\fR -a0666
  1188. -f/usr/tmp/\fIremote_name\fR
  1189. -!\*Q\fIremote_command\fR\*U /usr/tmp/\fIlocal_file\fR
  1190. @.ad b
  1191. @.in -.5i
  1192. @.sp
  1193. @.SH
  1194. 3. The `spool' Program, an Overview
  1195. @.PP
  1196. The
  1197. @.I spool
  1198. program is not a server, although it performs the function of
  1199. a server because it is executed on the sending machine as well
  1200. as the receiving machine when a request is submitted.
  1201. @.PP
  1202. The sending machine is responsible for collecting the files, sending
  1203. them, submitting them for printing, and waiting for confirmation from the
  1204. @.I spool
  1205. program on the receiving end.  The 
  1206. @.I spool
  1207. program on the receiving end
  1208. takes the confirmation from
  1209. @.I lp
  1210. or status from
  1211. @.I lpstat
  1212. and returns it to the
  1213. waiting machine on the sending end.
  1214. @.sp
  1215. @.SH
  1216. 3.1. Spooling a File for Remote Printing
  1217. @.sp
  1218. \fRCOMMAND: spool -p room10 -bJones foo.c
  1219. @.sp
  1220. ACTIONS:
  1221. @.PP
  1222. Validate the command options and verify that the specified file(s) and
  1223. printer (via \fI/etc/sysprint\fR) exist.
  1224. Read the file(s) (via stdin or file name(s)
  1225. on command line), concatenate them, and put them in a temporary file
  1226. /usr/tmp/sp.\fInode\fR.\fIXXXXX\fR, where
  1227. @.I node
  1228. is the
  1229. @.B 3bnet
  1230. node name of the user's
  1231. machine making the request, and
  1232. @.I XXXXX
  1233. is the process ID of the
  1234. @.I spool
  1235. program.  The above actions insure that the temporary file will have a
  1236. unique name on the remote machine when it is arrives there.
  1237. @.PP
  1238. Send the file to the remote system, execute
  1239. @.I lp
  1240. on the
  1241. remote system, store the standard output and standard error of
  1242. @.I lp
  1243. in another temporary file /usr/tmp/\fInode\fR.stat,
  1244. send it back to the user, display it
  1245. and exit.
  1246. @.KS
  1247. @.LP
  1248. For example: (See also \fIFigure 1\fR)
  1249. @.IP \fBUSER:\fR 10
  1250. $ pr *.s | spool -pX -bSharon  (executed on machine A, for printer X
  1251. on machine B, with PID=5427.)
  1252. @.sp
  1253. @.KE
  1254. @.LP
  1255. @.B SPOOL:
  1256. (SENDING END)
  1257. @.IP 1.
  1258. Collect standard input (or specified files) and save in
  1259. /usr/tmp/sp.A.a5427
  1260. @.IP 2.
  1261. Execute
  1262. @.I nisend
  1263. (via the
  1264. @.I system()
  1265. call).
  1266. @.QP
  1267. @.na
  1268. /usr/bin/nisend -s -e -dB -a0666 -f/usr/tmp/sp.A.a5427 -!\*Q\fBSee
  1269. remote command below\fR\*U /usr/tmp/sp.A.a5427
  1270. @.ad b
  1271. @.IP 3.
  1272. Remove /usr/tmp/sp.A.a5427
  1273. @.IP 4.
  1274. Wait for the response /usr/tmp/A.stat to arrive, (contains the output
  1275. of the
  1276. @.I lp
  1277. command.) give it 40 seconds to show up, and if it doesn't
  1278. arrive after that, give up and tell the user what happened. If it
  1279. does arrive in the allotted time, print it out.
  1280. @.IP 5.
  1281. Remove /usr/tmp/A.stat (If it arrived from the remote machine.)
  1282. @.sp
  1283. @.LP
  1284. \fBRemotely executed command (broken down into steps):\fR
  1285. [Please note that the
  1286. @.I lp
  1287. command is executed on the printing system by
  1288. @.I spool
  1289. on the requesting system and not by
  1290. @.I spool
  1291. on the printing system.  This saves about 3 seconds that would
  1292. normally be wasted waiting for
  1293. @.I spool
  1294. to fork() and exec(), then waiting for
  1295. @.I lp
  1296. to echo the request ID.  Now, the result of
  1297. @.I lp
  1298. can be sent back the moment it is available.  This is quirk of the
  1299. @.I nisend
  1300. command.]
  1301. @.sp
  1302. @.in +.5i
  1303. @.IP A.
  1304. submit the job to lp and capture its output:
  1305. @.QP
  1306. @.na
  1307. usr/bin/lp -tSharon -c /usr/tmp/sp.A.a5427 > /usr/tmp/A.stat 2>&1
  1308. @.ad b
  1309. @.IP B.
  1310. Remove the temporary file:
  1311. rm /usr/tmp/sp.A.a5427
  1312. @.IP C.
  1313. Return the captured output of
  1314. @.I lp
  1315. to the calling spool by executing
  1316. spool on the receiving end:
  1317. @.in +.5i
  1318. /usr/bin/spool A R @  (A=Name to send back to, R=\fIlp\fR report,
  1319. @@=Receiver mode.)
  1320. @.in -.5i
  1321. @.IP D.
  1322. Remove the captured output of lp and return.
  1323. @.QP
  1324. rm /usr/tmp/A.stat
  1325. @.in -.5i
  1326. @.sp 1
  1327. @.SH
  1328. 3.2. Requesting a Status Report on the Remote Printer
  1329. @.sp
  1330. \fRCOMMAND: spool -s -p room10
  1331. @.sp
  1332. ACTIONS:
  1333. @.PP
  1334. Validate the command options and verify that the specified printer (via
  1335. \fI/etc/sysprint\fR) exists.
  1336. @.PP
  1337. Execute the
  1338. @.I lpstat
  1339. program on the remote system, store the standard output
  1340. and standard error of
  1341. @.I lpstat
  1342. in a temporary file /usr/tmp/\fInode\fR.stat, send it back to
  1343. the user, display it and exit. (\fINode\fR is the requesting
  1344. @.B 3bnet
  1345. node name.)
  1346. @.KS
  1347. @.LP
  1348. For example: (see also \fIFigure 2\fR)
  1349. @.IP \fBUSER:\fR 10
  1350. $ spool -s -pX (executed on machine A, for printer X on machine B)
  1351. @.br
  1352. @.KE
  1353. @.LP
  1354. @.B SPOOL:
  1355. (SENDING END)
  1356. @.IP 1.
  1357. Execute
  1358. @.I nisend
  1359. (via the
  1360. @.I system()
  1361. call):
  1362. @.QP
  1363. @.na
  1364. /usr/bin/nisend -s -e -dB -a0666
  1365. -!\*Q\fBSee remote command below\fR\*U
  1366. @.ad b
  1367. @.IP 2.
  1368. Wait for the response /usr/tmp/A.stat to arrive, (contains the output of
  1369. the
  1370. @.I lpstat
  1371. command.) give it 40 seconds to show up, and if it
  1372. doesn't arrive after that, give up and tell the user what
  1373. happened. If it does arrive in the allotted time, print it out.
  1374. @.IP 3.
  1375. Remove /usr/tmp/A.stat (If it arrived from the remote machine.)
  1376. @.sp
  1377. @.LP
  1378. \fBRemotely executed command (broken down into steps):\fR
  1379. @.in +.5i
  1380. @.IP A.
  1381. Fire-up
  1382. @.I spool
  1383. on the receiving end. There it will execute
  1384. @.I lpstat
  1385. and return the output back to the user:
  1386. @.in +.5i
  1387. /usr/bin/spool A S @  (A=Machine name to send back to, S=lp status
  1388. report, @=Receiver mode.)
  1389. @.in -.5i
  1390. @.IP B.
  1391. Remove the captured output of
  1392. @.I lpstat
  1393. and exit.
  1394. @.in +.5i
  1395. rm /usr/tmp/A.stat
  1396. @.in -1i
  1397. @.sp 2
  1398. @.SH
  1399. Conclusion/Comments
  1400. @.PP
  1401. It is not the most efficient, but it works.  Possible future
  1402. improvements might involve an actual spool daemon.  This would make
  1403. handshaking more reliable, instead of using 
  1404. @.I nisend
  1405. which is very slow and very sensitive to system load.
  1406. @.sp
  1407. @//E*O*F spool.doc.ms//
  1408. chmod u=rwx,g=r,o= spool.doc.ms
  1409.  
  1410. echo x - spool.h
  1411. sed 's/^@//' > "spool.h" <<'@//E*O*F spool.h//'
  1412. #define SYS_PRINTERS "/etc/sysprint"    /* Location of printer info. */
  1413. #define DEFAULT_DIR "/usr/tmp/%sXXXXXX"      /* Place for temp files,
  1414.     where %s and XXXXXX will be replaced by the machine name and
  1415.     process I.D. */
  1416. #define TIMEOUT 50            /* Seconds to wait for response */
  1417. /* ***************************************************************************
  1418. COMMAND is what is sent to the remote system.  Various arguments in the
  1419. command (%s strings) are specified in the ARGUMENTS portion.  The arguments
  1420. are declared in the order they appear in the command.
  1421. ************************************************************************** */
  1422.  
  1423. #define COMMAND "/usr/bin/nisend -e -d%s -a0666 -s -c -f%s -!\042\
  1424. /usr/bin/lp -c -t%s %s>/usr/tmp/%s.stat 2>&1; rm %s;\
  1425. /usr/local/spool %s R @; rm /usr/tmp/%s.stat\042 %s"
  1426.  
  1427.  
  1428. #define ARGUMENTS printer_node,outname,banner,outname,name.sysname,outname,\
  1429.     name.sysname,name.sysname,outname
  1430.  
  1431. /* **************************************************************************
  1432. QUERY_COMMAND is what gets sent to the remote printer to get its status
  1433. sent back. QUERY_ARGUEMENTS are stuffed into the QUERY_COMMAND.
  1434. ************************************************************************** */
  1435. #define QUERY_COMMAND "/usr/bin/nisend -e -s -d%s -!\
  1436. \042/usr/local/spool %s S @; rm /usr/tmp/%s.stat\042"
  1437.  
  1438. #define QUERY_ARGUMENTS printer_node,name.sysname,name.sysname
  1439.  
  1440. #define USAGE "print:  spool -p {printer} -b {banner}\n\
  1441. status: spool -p {printer} -s\n\
  1442. list supported network printers: spool -l\n"
  1443.  
  1444. #define STAT_COMMAND "lpstat -a -r -u -p>/usr/tmp/%s.stat;\
  1445. /usr/bin/nisend -c -e -d%s -a0666 -f/usr/tmp/%s.stat \
  1446. /usr/tmp/%s.stat"
  1447.  
  1448. #define STAT_ARGUMENTS sysname,sysname,sysname,sysname
  1449.  
  1450. #define LP_COMMAND "/usr/bin/nisend -s -e -c -d%s -a0666 -f /usr/tmp/%s.stat \
  1451. /usr/tmp/%s.stat"
  1452.  
  1453. #define LP_ARGUMENTS sysname,sysname,sysname 
  1454.  
  1455. /* We use these commands in the case that the person spooling to a remote
  1456.     printer, isn't.  (Meaning: When they are on the same machine as
  1457.     the printer, and no network activity needs to take place.
  1458. /*
  1459. #define LOCAL_LP "/usr/bin/lp -c -t%s %s"
  1460. #define LOCAL_LP_ARGS banner,outname
  1461.  
  1462. #define LOCAL_LPSTAT "/usr/bin/lpstat -a -r -u -p"
  1463. #define STATUS_TEMPLATE "/usr/tmp/%s.stat"
  1464.  
  1465. #define ERR -1
  1466. #define DEBUG if (debug) fprintf(stderr,"Debug>
  1467. #define EOL 10
  1468. #define SCRATCH 35
  1469.  
  1470. @//E*O*F spool.h//
  1471. chmod u=rw,g=r,o=r spool.h
  1472.  
  1473. echo x - spool.man
  1474. sed 's/^@//' > "spool.man" <<'@//E*O*F spool.man//'
  1475. @.TH SPOOL 1 Local
  1476. @.AT 5 2.0
  1477. @.SH NAME
  1478. spool - spool files to remote printer.
  1479. @.sp
  1480. @.SH SYNOPSIS
  1481. @.PP
  1482. spool -s 
  1483. @.RI -p printer
  1484. @.br
  1485. spool
  1486. @.RI -p printer
  1487. @.RI -b banner
  1488. [files]
  1489. @.br
  1490. spool -l
  1491. @.br
  1492. spool
  1493. @.I node_name
  1494. R|S @
  1495. @.B (see below)
  1496. @.sp
  1497. @.SH DESCRIPTION
  1498. @.PP
  1499. @.I Spool
  1500. allows the printing of files on a remote machine.
  1501. After sending the request,
  1502. @.I spool
  1503. waits for (and displays) confirmation of the printing or status request.
  1504. @.PP            
  1505. The command line options:
  1506. @.TP
  1507. @.B -p
  1508. This option is used to specify the remote
  1509. printer name for the printing or status request. (Required)
  1510. @.TP
  1511. @.B -s
  1512. Requests a queue and status report from the remote printer.
  1513. This must be used in conjunction with the
  1514. @.B -p
  1515. flag.
  1516. (See above.)
  1517. @.TP
  1518. @.B -l
  1519. Lists the printers that can be reached from the network, along with
  1520. information regarding restricted use.
  1521. @.TP
  1522. @.B -b
  1523. The
  1524. @.BI -b banner
  1525. option is required for all printing
  1526. requests.
  1527. @.I Banner
  1528. will appear on the printout in large letters 
  1529. below the login name of the requestor.
  1530. There is a ten character maximum, with no spaces.
  1531. @.TP
  1532. @.B -d
  1533. Turns on a myriad of sometimes useful debugging
  1534. information, but does not actually execute the
  1535. remote commands.
  1536. @.PP
  1537. The last
  1538. @.I spool
  1539. command invokes the ``return'' mode of the
  1540. @.I spool
  1541. program.  When a
  1542. @.I spool
  1543. request is submitted, the
  1544. @.I spool
  1545. program on the remote printer is invoked with the
  1546. name of the calling machine, an R for ``return 
  1547. @.I spool
  1548. request
  1549. number'' or an S for ``return
  1550. @.I lp
  1551. queue status'' and then an
  1552. @@ sign.  The @ sign is introduced to make it very unlikely
  1553. for a user to type ``spool Mach7 R @'' from the console. (See
  1554. reference below.)
  1555. @.br
  1556. @.sp
  1557. @.SH EXAMPLES
  1558. pr foo.s | spool -pgumby -bJohn
  1559. @.br
  1560. @.PP
  1561. @.in +.5i
  1562. Formats the file foo.s and feeds it to
  1563. @.I spool
  1564. for printing on the remote printer
  1565. @.B gumby.
  1566. The name on the printout will be John.
  1567. @.in -.5i
  1568. @.br
  1569. @.sp
  1570. spool -ppokey -bJones hexdump.c
  1571. @.PP
  1572. @.in +.5i
  1573. Prints the file hexdump.c on the remote printer 
  1574. @.B pokey
  1575. with the name Jones on the printout.
  1576. @.in -.5i
  1577. @.br
  1578. @.sp
  1579. spool -s -psluggo
  1580. @.PP
  1581. @.in +.5i
  1582. Requests status information about printer \fBsluggo\fR.  This
  1583. command will list the printer status, pending and
  1584. currently printing files, and other tidbits of
  1585. knowledge.
  1586. @.in -.5i
  1587. @.br
  1588. @.sp
  1589. spool -l
  1590. @.PP
  1591. @.in +.5i
  1592. Lists the reachable printers physically connected to
  1593. the network.  This list is taken from 
  1594. @.B ``etc/sysprint.''
  1595. [See \fBsysprint(7)\fR]
  1596. @.in -.5i
  1597. @.br
  1598. @.sp
  1599. @.SH NOTES
  1600. @.PP
  1601. The '-' options may be specified in any order.
  1602. Options may be combined, and spaces between options
  1603. and arguments are allowed.  For example:
  1604. \fIspool -s -p room10\fR is the same as \fIspool -sproom10\fR.
  1605. [See \fBgetopt(3C)\fR]
  1606. @.PP
  1607. Restricted use of printers is determined by login name through
  1608. \fIcuserid\fR. Currently, the
  1609. `student' login is not allowed to use restricted printers.
  1610. @.br
  1611. @.SH FILES
  1612. @.br
  1613. @.B /etc/sysprint
  1614. @.SH DIAGNOSTICS
  1615. @.br
  1616. Exit codes and messages:
  1617. @.sp
  1618. @.TP
  1619. 1
  1620. Printer xxxx does not exist
  1621. @.TP
  1622. 2
  1623. Please request a printer
  1624. @.TP
  1625. 3
  1626. General usage error
  1627. @.TP
  1628. 4
  1629. Error opening xxxx for transmission
  1630. @.TP
  1631. 5
  1632. Panic: Error opening temporary file
  1633. @.TP
  1634. 6
  1635. File disappeared
  1636. @.TP
  1637. 7
  1638. Can't execute transmit program. (Nisend failed)
  1639. @.TP
  1640. 8
  1641. Panic: Could not delete temporary file
  1642. @.TP
  1643. 9
  1644. Can't execute request program. (Nisend failed)
  1645. @.TP
  1646. 10
  1647. Network printer database is missing.
  1648. @.TP
  1649. 11
  1650. Status file is missing. Hmm.
  1651. @.TP
  1652. 12
  1653. Sorry, remote machine is not answering...
  1654. @.TP
  1655. 13
  1656. Not allowed to use printer xxxx
  1657. @.br
  1658. @.sp
  1659. @.SH REFERENCE
  1660. @.LP
  1661. ``\fBProject Report: Printer Spooling Over 3bnet\fR'' by James A.
  1662. Hayes, March, 1986.
  1663. @.SH SEE ALSO
  1664. @.LP
  1665. \fIsysprint(7)\fR, \fIgetopt(3C)\fR, \fIcuserid(2)\fR.
  1666. @.br
  1667. @//E*O*F spool.man//
  1668. chmod u=rwx,g=r,o= spool.man
  1669.  
  1670. echo x - sysprint
  1671. sed 's/^@//' > "sysprint" <<'@//E*O*F sysprint//'
  1672. # system printer database.
  1673. #
  1674. #  Name   Restriction   Node   
  1675.     5414    A    3bp5414
  1676.     5426    A    3bp5426
  1677. #
  1678. # done
  1679. #
  1680. @//E*O*F sysprint//
  1681. chmod u=rw,g=r,o= sysprint
  1682.  
  1683. echo x - sysprint.man
  1684. sed 's/^@//' > "sysprint.man" <<'@//E*O*F sysprint.man//'
  1685. @.TH SYSPRINT 7 Local 
  1686. @.AT 5 2.0
  1687. @.SH NAME
  1688. /etc/sysprint - printer name database.
  1689. @.SH DESCRIPTION
  1690. @.PP
  1691. The file 
  1692. @.B /etc/sysprint
  1693. is the 
  1694. @.I 3bnet
  1695. networked printer database.
  1696. The file contains information on the English name of a printer,
  1697. the name of the
  1698. @.I 3bnet
  1699. node on which the printer resides, and a flag
  1700. that indicates restricted use.  If the user has the login name
  1701. "student", he/she may not use printers marked as restricted.
  1702. @.br
  1703. @.SH FORMAT
  1704. @.PP
  1705. The general format of the file is similar to many UNIX databases.  A
  1706. line beginning with "#" is treated as a comment and blank lines are
  1707. ignored.  The information is to be formatted in this manner:
  1708. @.sp
  1709. @.B NAME
  1710. (whitespace)
  1711. @.B RESTRICTION 
  1712. (whitespace)
  1713. @.B NODE_NAME
  1714. @.sp 2
  1715. For Example:
  1716. @.sp
  1717. # This is comment, the blank line will be ignored...
  1718. @.br
  1719. {This is a blank line.}
  1720. @.br
  1721. gumby        A    3bsw2
  1722. @.br
  1723. pokey        R    print32
  1724. @.br
  1725. # This line is the last line.
  1726. @.br
  1727. @.sp
  1728. @.SH NAME
  1729. @.PP
  1730. This is the English name the user would specify to refer to the
  1731. printer connected to
  1732. @.B NODE_NAME.
  1733. 15 characters maximum length.
  1734. @.sp
  1735. @.SH RESTRICTION
  1736. @.PP
  1737. The restriction flag consists of one
  1738. @.I CAPITAL
  1739. letter.  The letter may be an "R" for
  1740. @.B restricted
  1741. use, or an "A" for use by
  1742. @.BR anyone .
  1743. @.sp
  1744. @.SH NODE_NAME
  1745. @.PP
  1746. If it isn't obvious... This is the
  1747. @.I 3bnet
  1748. node name of the machine the printer is physically connected to.
  1749. @.sp
  1750. @.SH SEE ALSO
  1751. @.IR spool (1)
  1752. @.br
  1753. @//E*O*F sysprint.man//
  1754. chmod u=rwx,g=r,o= sysprint.man
  1755.  
  1756. exit 0
  1757. -- 
  1758.  
  1759. Rich $alz
  1760. Cronus Project, BBN Labs            rsalz@bbn.com
  1761. Moderator, comp.sources.unix            sources@uunet.uu.net
  1762.