Annotation of coherent/g/usr/bin/mlp/lp.c, revision 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.