Annotation of coherent/g/usr/bin/mlp/lp.c, revision 1.1.1.1

1.1       root        1: 
                      2: /******************************************************************************
                      3:    lp.   This is the Multiple-Line-Printer spooler interface to applications
                      4:          and the Coherent user.  Its job is to accept a print job and place it
                      5:    into the spool queue.  As part of this, a special filename is formed to 
                      6:    ensure that requests are printed in a prioritized-first-come-first-served
                      7:    manner.  The actual file is given a 192 byte header.  Then the text of the
                      8:    report is appended on the header.  Much of the information stored in the
                      9:    header is extracted from an environment variable called MLP_SPOOL.  If a 
                     10:    printer is not specified, then the user name is used to derive the printer
                     11:    name.  This allows users to "route" their requests to various printers
                     12:    on demmand.
                     13: 
                     14:    This program's command line interface is very similar to lp in Unix SV.
                     15: 
                     16:    One noteable difference:  Output is ALWAYS copied into the spool directory.
                     17:    This is to facilitate deferred de-spooling.
                     18: 
                     19:    Author: B.Blatchley (c) Magnetic Data Operation 1992
                     20: ******************************************************************************/
                     21: 
                     22: #include "header.h"
                     23: 
                     24: #define PRIORITY  '2'
                     25: #define LONGEVITY 'S'
                     26: 
                     27: static int  input_from_stdin = FALSE;
                     28: static char priority = PRIORITY;
                     29: static char qstatus = 'R';
                     30: static char keep_status = LONGEVITY;
                     31: static int  copies = 1;
                     32: static int  mailme = FALSE;
                     33: static int  writeme = FALSE;
                     34: static int  silent = FALSE;
                     35: static char printer[15];
                     36: static char user[15];
                     37: static char title[WORKSTR];
                     38: static char path[WORKSTR];
                     39: static char message[WORKSTR];
                     40: 
                     41: extern int  curr_formlen;
                     42: 
                     43: 
                     44: /******************************************************************************
                     45:    Return a new filename for the spool request.
                     46: ******************************************************************************/
                     47: 
                     48: char *request_filename( when, priority)
                     49: char when;
                     50: char priority;
                     51: {
                     52:    static char name[WORKSTR];
                     53:    int         seqnum;
                     54:    char        num[10];
                     55: 
                     56:    seqnum = get_seq_num();
                     57: 
                     58:    sprintf( name, "%c%c%05d", when, priority, seqnum);
                     59: 
                     60:    sprintf( num, "%d ", seqnum);  strcat( message, num);   
                     61: 
                     62:    return( name); 
                     63: }
                     64: 
                     65: 
                     66: 
                     67: 
                     68: /******************************************************************************
                     69:    Given the contents of the SPOOLER environment variable other things and 
                     70:    return a header string.  This header will precede the actual printed-output.
                     71: ******************************************************************************/
                     72: 
                     73: char *make_header()
                     74: {
                     75:    static char header[ HEADER_SIZE+1];
                     76:    char        tmp[ WORKSTR], s[30];
                     77: 
                     78:    headerval( header, H_ENTIRE, " ");
                     79: 
                     80:    if ( input_from_stdin) headerval( header, H_DESC, "Standard Input");
                     81:    if (path[0])           headerval( header, H_DESC,  path);
                     82:    if (title[0])          headerval( header, H_DESC,  title);
                     83: 
                     84:    sprintf( s, "%03d", curr_formlen);  headerval( header, H_FORMLEN, s);
                     85: 
                     86:    headerval( header, H_USER,    user);
                     87:    headerval( header, H_PRINTER, printer); 
                     88: 
                     89:    if (printer[0]) headerval( header, H_PRINTER, printer);
                     90: 
                     91:    headerval( header, H_DSTAMP,  datestamp());
                     92: 
                     93:    sprintf( tmp, "%02d", copies);     headerval( header, H_COPIES,    tmp);
                     94:    sprintf( tmp, "%c", keep_status);  headerval( header, H_LONGEVITY, tmp);
                     95: 
                     96:    if (mailme)  headerval( header, H_MAILME,  "M");
                     97:    if (writeme) headerval( header, H_WRITEME, "W");
                     98:    
                     99: 
                    100:    /* Fill from SPOOL Environment variable, if available */
                    101: 
                    102:    if (getenv(SPOOL_ENV)) { 
                    103:       strcpy( tmp, getenv( SPOOL_ENV));
                    104: 
                    105:       strncpy( s, &tmp[0],  10); headerval( header, H_TYPE,    s);
                    106:       strncpy( s, &tmp[10],  3); headerval( header, H_FORMLEN, s);
                    107:       strncpy( s, &tmp[13], 14); headerval( header, H_DBASE,   s);
                    108:       strncpy( s, &tmp[27], 14); headerval( header, H_FORMAT,  s);
                    109:       strncpy( s, &tmp[41], 43); headerval( header, H_DESC,    s);
                    110:    }
                    111: 
                    112:    return( header);
                    113: }
                    114: 
                    115: 
                    116: 
                    117: 
                    118: /******************************************************************************
                    119:    Create a spooled printout.  Count the pages as they go by and
                    120:    put this in the header for later use.
                    121: ******************************************************************************/
                    122: 
                    123: spool_output()
                    124: {
                    125:    char *qname, *header, buffer[256], tmp[WORKSTR];
                    126:    int   out, pages, n;
                    127: 
                    128: 
                    129:    qname  = request_filename( qstatus, priority);
                    130:    header = make_header();
                    131: 
                    132:    if (!strcmp(LOCAL, printer) || !strcmp(DISPLAY, printer))
                    133:       qname[0] = 'r';
                    134: 
                    135:    sprintf( buffer, "%s/%s", QUEUE_PATH, qname);
                    136: 
                    137:    if (( out = open( buffer, O_RDWR|O_CREAT|O_TRUNC, 0644))) {
                    138:       write( out, header, HEADER_SIZE);
                    139: 
                    140:       pages = writeOut( 0, out, 0, 9999, curr_formlen, FALSE);
                    141: 
                    142:       sprintf( buffer, "%04d", pages);  headerval( header, H_PAGES, buffer);
                    143: 
                    144:       lseek( out, 0L, 0);               write( out, header, HEADER_SIZE);
                    145: 
                    146:       if (!strcmp(LOCAL, printer))  {
                    147:          silent = TRUE;
                    148: 
                    149:          for ( n = 0; n < copies; n++)
                    150:             local_print( out, 0, 0);
                    151:       }
                    152: 
                    153:       close( out);
                    154: 
                    155:       if (!strcmp(DISPLAY, printer)) {
                    156:          silent = TRUE;
                    157: 
                    158:          sprintf( tmp, "review %s/%s %d -mlp; clear", QUEUE_PATH, qname, curr_formlen);
                    159:          system(tmp);
                    160:       }
                    161:    } 
                    162:    else
                    163:       fatal("Cannot write request \"%s\" into the spool queue: %s", qname,
                    164:          QUEUE_PATH);
                    165: }
                    166: 
                    167: 
                    168: 
                    169: 
                    170: 
                    171: /******************************************************************************
                    172:    Reprint a request that has already been spooled.
                    173: ******************************************************************************/
                    174: 
                    175: reprint_request( seqnum, start, end)
                    176: int seqnum;
                    177: int start;
                    178: int end;
                    179: {
                    180:    char *qname, *header, path[WORKSTR], tmp[WORKSTR], request[20];
                    181:    int   out, n;
                    182: 
                    183:    if ( start > end) {
                    184:       n = end; end = start; start = n;
                    185:    }
                    186: 
                    187:    if ( start > 0 && end == 0) end = 9999;
                    188: 
                    189:    sprintf( tmp, "%05d", seqnum);
                    190:    strcpy( request, request_name( tmp));
                    191: 
                    192:    if (*request == 0) {
                    193:       warning("Cannot open request #%05d to despool.", seqnum);
                    194:       silent = TRUE;
                    195:       return;
                    196:    }
                    197: 
                    198:    if (!strcmp(LOCAL, printer)) {
                    199:       silent = TRUE;
                    200:       sprintf( path, "%s/%s", QUEUE_PATH, request);
                    201: 
                    202:       if ( (out = open( path, O_RDWR)) != BAD) {
                    203:          lseek( out, (long) HEADER_SIZE, 0);
                    204: 
                    205:          for ( n = 0; n < copies; n++)
                    206:             local_print( out, start, end);
                    207: 
                    208:          close( out);
                    209:       }
                    210:    }
                    211:    if (!strcmp(DISPLAY, printer)) {
                    212:       silent = TRUE;
                    213:       sprintf( path, "review %s/%s %d -mlp; clear", QUEUE_PATH, request, curr_formlen);
                    214:       system( path);
                    215:    }
                    216:    else {
                    217:       qname  = request_filename( qstatus, priority);
                    218:       header = make_header();
                    219: 
                    220:       sprintf( path, "%s/%s", QUEUE_PATH, qname);
                    221: 
                    222:       if (( out = open( path, O_RDWR|O_CREAT|O_TRUNC, 0644))) {
                    223: 
                    224:          sprintf( tmp, "Reprint #%05u from page %04u to %04u", 
                    225:             seqnum, start, end);
                    226: 
                    227:          headerval( header, H_DESC, tmp);
                    228: 
                    229:          headerval( header, H_LONGEVITY, "R");
                    230: 
                    231:          write( out, header, HEADER_SIZE);
                    232: 
                    233:          close( out);
                    234:       } 
                    235:       else
                    236:          fatal("Cannot write request \"%s\" into the spool queue: %s", qname,
                    237:             QUEUE_PATH);
                    238:    }
                    239: }
                    240:    
                    241: 
                    242: 
                    243: /****************************************************************************
                    244:    Echo user's command
                    245: ****************************************************************************/
                    246: 
                    247: void echo_command()
                    248: {
                    249:    char *t, *u;
                    250: 
                    251:    if (silent) return;
                    252: 
                    253:    if (message[0]) {
                    254:       t = strtok( message, " "); u = strtok( NULL, " ");
                    255: 
                    256:       if (u != NULL)
                    257:          fprintf( stderr, "(MLP Spooled Requests: %s, %s", t, u);
                    258:       else
                    259:          fprintf( stderr, "(MLP Spooled Request: %s", t);
                    260:    
                    261:       while (t = strtok( NULL, " "))
                    262:          fprintf( stderr, ", %s", t);
                    263:    }
                    264: 
                    265:    fprintf( stderr, ")\n");
                    266: }
                    267: 
                    268: 
                    269: 
                    270: 
                    271: /******************************************************************************
                    272:    Ask the despooler to shutdown.  Remove the despooler's PID from the status  
                    273:    file.  Then wakeup the despooler (which will read the newly changed status
                    274:    file).  When the despooler sees its PID removed, it will terminate.
                    275: ******************************************************************************/
                    276: 
                    277: shutdown_despooler()
                    278: {
                    279:    int   pid;
                    280:    char *value;
                    281: 
                    282:    if (getuid() == 0) {
                    283:       value = status( DESPOOLER, "");  sscanf( value, "%d", &pid);
                    284: 
                    285:       status( DESPOOLER, " ");
                    286: 
                    287:       if ( pid > 0) kill( pid, SIGALRM);
                    288: 
                    289:       printf("MLP Despooler Shutdown.\n");
                    290:       wakeup_despooler();      
                    291:    }
                    292:    else
                    293:       printf("\007\nSorry, you must be superuser to do this.\n\n");
                    294: }
                    295: 
                    296: 
                    297: 
                    298: 
                    299: /******************************************************************************
                    300:    Find printer name "unknown" is assumed to be undefined in the route
                    301:    directory--therefore the printer for unknown users will be the system
                    302:    default.  HOWEVER, if the route file "unknown" is filled with the name of
                    303:    a printer, then these request will go to the this printer instead.  Kind
                    304:    of a freebe feature!   Get the user's login name too.
                    305: ******************************************************************************/
                    306: 
                    307: char *get_printer_and_user_name()
                    308: {
                    309:    strcpy( user,    "unknown"); 
                    310:    strcpy( printer, "unknown"); 
                    311: 
                    312:    if ( getlogin())
                    313:       strcpy( user, getlogin());
                    314: 
                    315:    strcpy( printer, route_request( user));
                    316: 
                    317:    if (!strcmp( SYSTEM, printer))
                    318:       strcpy( printer, controls(DEFAULT,""));
                    319: }
                    320: 
                    321: 
                    322: 
                    323: 
                    324: /******************************************************************************
                    325:    Check for environmental overides for the priority, form length and copies.
                    326: ******************************************************************************/
                    327: 
                    328: char *get_environment()
                    329: {
                    330:    char tmp[WORKSTR];
                    331:    int  tmpv;
                    332: 
                    333:    if (getenv(PRIORITY_ENV)) { 
                    334:       strcpy( tmp, getenv( PRIORITY_ENV));  tmp[1] = 0;
                    335: 
                    336:       if (*tmp < '0') *tmp = '0';
                    337:       if (*tmp > '9') *tmp = '9';  
                    338: 
                    339:       priority = *tmp;
                    340:    }
                    341: 
                    342:    if (getenv(LONGEVITY_ENV)) { 
                    343:       strcpy( tmp, getenv( LONGEVITY_ENV));  tmp[1] = 0;
                    344: 
                    345:       switch (*tmp) {
                    346:          case 'l':
                    347:          case 'L': keep_status = 'L'; break;
                    348:          case 't':
                    349:          case 'T': keep_status = 'T'; break;
                    350:          case 's':
                    351:          case 'S':
                    352:           default: keep_status = 'S';
                    353:       }
                    354:    }
                    355: 
                    356: 
                    357:    curr_formlen = 66;
                    358: 
                    359:    if (getenv(FORMLEN_ENV))
                    360:       if ( sscanf( getenv( FORMLEN_ENV), "%d", &tmpv))
                    361:          curr_formlen = tmpv;
                    362: 
                    363: 
                    364:    if (getenv(COPIES_ENV)) {
                    365:       copies = 66;
                    366: 
                    367:       if ( sscanf( getenv( COPIES_ENV), "%d", &tmpv))
                    368:          copies = tmpv;
                    369:    }
                    370: }
                    371: 
                    372: 
                    373: 
                    374: 
                    375: 
                    376: /******************************************************************************
                    377:    Main Driver.   Parse the arguments and spool each report named (otherwise
                    378:    spool the contents of standard input).   Then send the despooler a wakup
                    379:    call.
                    380: 
                    381:    NOTE:  This program does DIFFERENT things depending on what it is called.
                    382:              1) as "lp" it does lp kinds of things.
                    383:              2) as "lpshut" it shuts down the despooler.
                    384:              3) as "reprint" it reprints spooled requests
                    385: ******************************************************************************/
                    386: 
                    387: void main( argc, argv)
                    388: int   argc;
                    389: char *argv[];
                    390: {
                    391:    extern char *optarg;
                    392:    extern int   optind;
                    393:    extern char *progname;
                    394:    char         o;
                    395:    int          file, reprint, seqnum, start, end;
                    396: 
                    397:    reprint = FALSE;
                    398: 
                    399:    umask(FPERMS);
                    400: 
                    401:    progname = basename( argv[0]);
                    402: 
                    403:    get_printer_and_user_name();
                    404: 
                    405: 
                    406: 
                    407:    /******** As the lpshut command *************/
                    408: 
                    409:    if (!strcmp( progname, "lpshut")) {
                    410:       shutdown_despooler();
                    411: 
                    412:       log("Shutdown Scheduler Daemon");
                    413: 
                    414:       /* cancel the currently running backend processes */
                    415: 
                    416:       if (argv[1] == NULL) 
                    417:          kill_printing_request( 0, R_KILL, CLEAR_ALL);
                    418:       else
                    419:       if (strcmp( argv[1], "-d"))
                    420:          kill_printing_request( 0, R_KILL, CLEAR_ALL);
                    421:       
                    422:       exit(0);
                    423:    }
                    424: 
                    425: 
                    426:    /******** As the reprint command *************/
                    427: 
                    428:    if (!strcmp( progname, "reprint")) {
                    429:       if ( argc == 1)
                    430:          printf( "\nusage:  reprint request_num [start_page] [end_page]\n\n");
                    431:       else {
                    432:          get_environment();
                    433: 
                    434:          seqnum = 0; sscanf( argv[1], "%d", &seqnum);
                    435:          start  = 0; sscanf( argv[2], "%d", &start);
                    436:          end    = 0; sscanf( argv[3], "%d", &end);
                    437: 
                    438:          reprint_request( seqnum, start, end);
                    439:          wakeup_despooler();
                    440:       }
                    441:       exit(0);
                    442:    }
                    443: 
                    444: 
                    445:    /******** As the lp command *************/
                    446: 
                    447:    while ( (o = getopt( argc, argv, "bd:mn:t:wsSR")) != EOF) {
                    448:       switch (o) {
                    449:          case 'd': strncpy( printer, optarg, sizeof( printer));  break;
                    450:          case 't': strncpy( title,   optarg, sizeof( title));    break;
                    451:          case 'n': sscanf( optarg, "%d", &copies);               break;
                    452:          case 'm': mailme  = TRUE;                               break;
                    453:          case 's': silent  = TRUE;                               break;
                    454:          case 'w': writeme = TRUE;                               break;
                    455:          case 'R': reprint = TRUE;                               break;
                    456: 
                    457:          case 'S': shutdown_despooler();                         exit(0);
                    458:       }
                    459:    }
                    460: 
                    461:    get_environment();
                    462: 
                    463:    if ( reprint) {
                    464:       seqnum = 0; sscanf( argv[optind],   "%d", &seqnum);
                    465:       start  = 0; sscanf( argv[optind+1], "%d", &start);
                    466:       end    = 0; sscanf( argv[optind+2], "%d", &end);
                    467: 
                    468:       reprint_request( seqnum, start, end);
                    469:    }
                    470:    else {
                    471:       if ( optind < argc) {
                    472:          while (optind < argc) {
                    473: 
                    474:             if (strcmp( argv[optind], "-"))
                    475:                if ( ( file = open( argv[optind], O_RDONLY))) {
                    476:                   dup2( file, 0);
                    477:                   strncpy( path, argv[optind], strlen( argv[optind]));
                    478:                   spool_output();
                    479:                }
                    480: 
                    481:             optind++;
                    482:          }
                    483:       }
                    484:       else {
                    485:          input_from_stdin = TRUE;
                    486:          spool_output();
                    487:       }
                    488:    }
                    489: 
                    490:    echo_command();
                    491: 
                    492:    wakeup_despooler();
                    493: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.