home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / plp / part06 < prev    next >
Text File  |  1988-09-14  |  56KB  |  1,924 lines

  1. Subject:  v16i019:  Public lineprinter spooler package, Part06/16
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: papowell@julius.cs.umn.edu
  7. Posting-number: Volume 16, Issue 19
  8. Archive-name: plp/part06
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 6 (of 16)."
  17. # Contents:  filters/pf_main.c src/checkperm.c src/displayq.c src/lpc.c
  18. #   src/lpq.c src/lpr_job.c
  19. # Wrapped by papowell@attila on Wed Aug 10 10:44:55 1988
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'filters/pf_main.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'filters/pf_main.c'\"
  23. else
  24. echo shar: Extracting \"'filters/pf_main.c'\" \(8221 characters\)
  25. sed "s/^X//" >'filters/pf_main.c' <<'END_OF_FILE'
  26. X/***************************************************************************
  27. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  28. X ***************************************************************************
  29. X * MODULE: pf_main.c for prefilters
  30. X ***************************************************************************
  31. X * Revision History: Created Fri Mar  4 19:45:03 CST 1988
  32. X * $Log:    pf_main.c,v $
  33. X * Revision 2.1  88/05/09  10:12:12  papowell
  34. X * *** empty log message ***
  35. X * 
  36. X ***************************************************************************/
  37. X#ifndef lint
  38. static char id_str1[] =
  39. X    "$Header: pf_main.c,v 2.1 88/05/09 10:12:12 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  40. X#endif lint
  41. X/***************************************************************************
  42. X *  UMN-LPR prefilter template and frontend.
  43. X *
  44. X *    A prefilter is invoked with the following parameters,
  45. X *  which can be in any order, and perhaps some missing.
  46. X *
  47. X *  filtername arguments \   <- from PRINTCAP entry
  48. X *      -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \
  49. X *        [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost  \
  50. X *      -Fformat -Ddebug files
  51. X * 
  52. X *  1. Parameters can be in different order than the above.
  53. X *  2. Optional parameters can be missing
  54. X *  3. Values specified for the width, length, etc., are from PRINTCAP
  55. X *     or from the overridding user specified options.
  56. X *
  57. X *  This program provides a common front end for most of the necessary
  58. X *  grunt work.  This falls into the following classes:
  59. X * 1. Parameter extraction.
  60. X * 2. Picking off files.
  61. X *  The front end will extract parameters,  then call the prefilter(file)
  62. X *  routine,  which is responsible for carrying out the required prefilter
  63. X *  actions.
  64. X *
  65. X *  The prefilter() routine should return 0 (success), 1 (retry) or 2 (abort).
  66. X *
  67. X * Parameter Extraction
  68. X *    The main() routine will extract parameters
  69. X *  whose values are placed in the appropriate variables.  This is done
  70. X *  by using the ParmTable[], which has entries for each valid letter
  71. X *  parmeter, such as the letter flag, the type of variable,
  72. X *  and the address of the variable.
  73. X *  The following variables are provided as a default set.
  74. X *      -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \
  75. X *        [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost  \
  76. X *      -Fformat files
  77. X * VARIABLE  FLAG          TYPE    PURPOSE / PRINTCAP ENTRTY
  78. X * name     name of filter char*    argv[0], program identification
  79. X * width    -wwidth           int      PW, width in chars
  80. X * length   -llength       int      PL, length in lines
  81. X * xwidth   -xwidth        int      PX, width in pixels
  82. X * xlength  -xlength       int      PY, length in pixels
  83. X * literal  -c               int      if set, ignore control chars
  84. X * indent   -iindent       int      indent amount (depends on device)
  85. X * zopts    -Zoptions      char*    extra options for printer
  86. X * class    -Cclass        char*    classname
  87. X * job      -Jjob          char*    jobname
  88. X * accntname -Raccntname   char*    account for billing purposes
  89. X * login    -nlogin        char*    login name
  90. X * host     -hhost         char*    host name
  91. X * format   -Fformat       char*    format
  92. X * accntfile file          char*    AF, accounting file
  93. X *
  94. X * debug     - sets debug level
  95. X *
  96. X *    The functions fatal(), logerr(), and logerr_die() can be used to report
  97. X *    status. The variable errorcode can be set by the user before calling
  98. X *    these functions, and will be the exit value of the program. Its default
  99. X *    value will be 2 (abort status).
  100. X *    fatal() reports a fatal message, and terminates.
  101. X *    logerr() reports a message, appends information indicated by errno
  102. X *    (see perror(2) for details), and then returns.
  103. X *    logerr_die() will call logerr(), and then will exit with errorcode
  104. X *    status.
  105. X *    Both fatal() and logerr_die() call the cleanup() function before exit.
  106. X *
  107. X * DEBUGGING:  a simple minded debugging version can be enabled by
  108. X * compiling with the -DDEBUG option.
  109. X */
  110. X
  111. X#include <stdio.h>
  112. X#include <signal.h>
  113. X#include <sys/file.h>
  114. X
  115. int errorcode = 2;
  116. X
  117. char *name;        /* name of filter */
  118. X/* set from flags */
  119. int debug, width, length, xwidth, ylength, literal, indent;
  120. char *zopts, *class, *job, *login, *accntname, *host, *format;
  121. char *printer;
  122. int optind;
  123. X
  124. main( argc, argv )
  125. X    int argc;
  126. X    char **argv;
  127. X{
  128. X    int i;
  129. X
  130. X    getargs( argc, argv );
  131. X
  132. X    /*
  133. X     * Turn off SIGPIPE
  134. X     */
  135. X    (void)signal( SIGPIPE, SIG_IGN );
  136. X    errorcode = 0;
  137. X    for( i = optind; i < argc; ++ i ){
  138. X        errorcode = prefilter( argv[i] );
  139. X    }
  140. X    return(errorcode);
  141. X}
  142. X
  143. X/*VARARGS1*/
  144. log(msg, a1, a2, a3)
  145. X    char *msg;
  146. X{
  147. X    (void)fprintf(stderr, "%s: ", name);
  148. X    (void)fprintf(stderr, msg, a1, a2, a3);
  149. X    (void)putc('\n', stderr);
  150. X    (void)fflush(stderr);
  151. X}
  152. X
  153. X/*VARARGS1*/
  154. fatal(msg, a1, a2, a3)
  155. X    char *msg;
  156. X{
  157. X    log(msg, a1, a2, a3);
  158. X    cleanup();
  159. X    exit(errorcode);
  160. X}
  161. X
  162. X/*VARARGS1*/
  163. logerr(msg, a1, a2, a3)
  164. X    char *msg;
  165. X{
  166. X    extern int errno, sys_nerr;
  167. X    extern char *sys_errlist[];
  168. X    int err = errno;
  169. X
  170. X    (void)fprintf(stderr, "%s: ", name);
  171. X    if (msg){
  172. X        (void)fprintf(stderr, msg, a1, a2, a3);
  173. X        (void)fputs( "- ", stderr);
  174. X    }
  175. X    if( err < sys_nerr ){
  176. X        (void)fputs(sys_errlist[err]);
  177. X    } else {
  178. X        (void)fprintf(stderr, "Unknown error %d", err);
  179. X    }
  180. X    (void)putc('\n', stderr);
  181. X    (void)fflush(stderr);
  182. X}
  183. X
  184. X/*VARARGS1*/
  185. logerr_die(msg, a1, a2, a3)
  186. X    char *msg;
  187. X{
  188. X    logerr(msg, a1, a2, a3);
  189. X    cleanup();
  190. X    exit(errorcode);
  191. X}
  192. X
  193. getargs(argc, argv)
  194. X    int argc;
  195. X    char **argv;
  196. X{
  197. X    int i;        /* argument index */
  198. X    char *arg;    /* argument */
  199. X    int flag;    /* flag */
  200. X
  201. X    name = argv[0];
  202. X    for( i = 1; i < argc; ++i ){
  203. X        arg = argv[i];
  204. X        if( *arg == '-' ){ /* arg will be string */
  205. X                setvar( arg[1], &arg[2] );
  206. X        } else {
  207. X            optind = i;
  208. X            break;
  209. X        }
  210. X    }
  211. X    if( debug ){
  212. X        for( i = 0; i < argc; ++i ){
  213. X            fprintf(stdout, "%s ", argv[i] );
  214. X        }
  215. X        fprintf( stdout, "\n" );
  216. X        printf("login '%s'\n", login? login : "null" );
  217. X        printf("host '%s'\n", host? host : "null" );
  218. X        printf("class '%s'\n", class? class : "null" );
  219. X        printf("format '%s'\n", format? format : "null" );
  220. X        printf("job '%s'\n", job? job : "null" );
  221. X        printf("printer '%s'\n", printer? printer : "null" );
  222. X        printf("accntname '%s'\n", accntname? accntname : "null" );
  223. X        printf("zopts '%s'\n", zopts? zopts : "null" );
  224. X        printf("literal, %d\n", literal);
  225. X        printf("indent, %d\n", indent);
  226. X        printf("length, %d\n", length);
  227. X        printf("width, %d\n", width);
  228. X        printf("xwidth, %d\n", xwidth);
  229. X        printf("ylength, %d\n", ylength);
  230. X        for( i = 0; i < argc; ++i ){
  231. X            fprintf(stderr, "%s ", argv[i] );
  232. X        }
  233. X        fprintf( stderr, "\n" );
  234. X        fflush(stderr);
  235. X        fflush(stdout);
  236. X    }
  237. X}
  238. X            
  239. X#define INTV 0
  240. X#define STRV 1
  241. X#define FLGV 2
  242. struct parm {
  243. X    int flag;
  244. X    char **var;
  245. X    int kind;
  246. X} Parmlist[] = {
  247. X{'C', &class, STRV },
  248. X{'D', (char **)&debug, INTV },
  249. X{'F', &format, STRV },
  250. X{'J', &job, STRV },
  251. X{'P', &printer, STRV },
  252. X{'R', &accntname, STRV },
  253. X{'Z', &zopts, STRV },
  254. X{'c', (char **)&literal, FLGV },
  255. X{'h', &host, STRV },
  256. X{'i', (char **)&indent, INTV },
  257. X{'l', (char **)&length, INTV },
  258. X{'n', &login, STRV },
  259. X{'w', (char **)&width, INTV },
  260. X{'x', (char **)&xwidth, INTV },
  261. X{'y', (char **)&ylength, INTV } };
  262. X
  263. int Parmlen = sizeof(Parmlist)/sizeof(struct parm);
  264. X
  265. X/*
  266. X * setvar( int flag, char *arg )
  267. X * 1. look in table and find entry
  268. X * 2. if STRV, then set 
  269. X * 3. if INTV, then convert and set
  270. X * 4. if FLGV, then set to 1
  271. X */
  272. setvar( flag, arg )
  273. X    int flag;
  274. X    char *arg;
  275. X{
  276. X    int u, l, i, c;    /* upper, lower, i */
  277. X
  278. X    l = 0; u = Parmlen;
  279. X    while( l <= u ){
  280. X        i = (u+l)/2;
  281. X        c = flag - Parmlist[i].flag;
  282. X        if( 0 == c ){
  283. X            /* printf( "found parm %c, %d\n", flag, i ); */
  284. X            switch( Parmlist[i].kind ){
  285. X            case STRV: *Parmlist[i].var = arg; break;
  286. X            case INTV: *(int *)Parmlist[i].var = atoi(arg); break;
  287. X            case FLGV: *(int *)Parmlist[i].var = 1; break;
  288. X            }
  289. X            return;
  290. X        } else if( c < 0 ){
  291. X            /* printf( "down parm %c, %d\n", flag, i ); */
  292. X            u = i - 1 ;
  293. X        } else {
  294. X            /* printf( "up parm %c, %d\n", flag, i ); */
  295. X            l = i + 1 ;
  296. X        }
  297. X    }
  298. X    /* printf( "did not find parm %c, %d\n", flag, i ); */
  299. X    return;
  300. X}
  301. X
  302. X#ifdef DEBUG
  303. cleanup() {}
  304. X
  305. prefilter( file )
  306. X    char *file;
  307. X{
  308. X    FILE *fp;
  309. X    int c;
  310. X
  311. X    log( "file %s", file );
  312. X    if( (fp = fopen( file, "r" )) == NULL ){
  313. X        fatal( "cannot open file %s", file );
  314. X    }
  315. X    while( (c = getc(fp)) != EOF ){
  316. X        putchar(c);
  317. X    }
  318. X}
  319. X#endif DEBUG
  320. END_OF_FILE
  321. if test 8221 -ne `wc -c <'filters/pf_main.c'`; then
  322.     echo shar: \"'filters/pf_main.c'\" unpacked with wrong size!
  323. fi
  324. # end of 'filters/pf_main.c'
  325. fi
  326. if test -f 'src/checkperm.c' -a "${1}" != "-c" ; then 
  327.   echo shar: Will not clobber existing file \"'src/checkperm.c'\"
  328. else
  329. echo shar: Extracting \"'src/checkperm.c'\" \(8361 characters\)
  330. sed "s/^X//" >'src/checkperm.c' <<'END_OF_FILE'
  331. X/***************************************************************************
  332. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  333. X ***************************************************************************
  334. X * MODULE: Checkperm.c
  335. X * printer permission checking
  336. X ***************************************************************************
  337. X * Revision History: Created Sun Jan  3 19:08:26 CST 1988
  338. X * $Log:    checkperm.c,v $
  339. X * Revision 3.1  88/06/18  09:33:59  papowell
  340. X * Version 3.0- Distributed Sat Jun 18 1988
  341. X * 
  342. X * Revision 2.4  88/05/27  08:27:23  papowell
  343. X * Fixed the '~' permissions line
  344. X * 
  345. X * Revision 2.3  88/05/21  10:26:22  papowell
  346. X * Added check for '~' or always
  347. X * 
  348. X * Revision 2.2  88/05/16  09:44:32  papowell
  349. X * Modified match() to handle null strings better
  350. X * 
  351. X * Revision 2.1  88/05/09  10:07:46  papowell
  352. X * PLP: Released Version
  353. X * 
  354. X * Revision 1.3  88/04/07  09:11:14  papowell
  355. X * Modified 'while' loop; removed break
  356. X * 
  357. X * Revision 1.2  88/03/25  14:59:09  papowell
  358. X * Debugged Version:
  359. X * 1. Added the PLP control file first transfer
  360. X * 2. Checks for MX during file transfers
  361. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  362. X *     apparently they open files and then assume that they will stay
  363. X *     open.
  364. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  365. X * 
  366. X * Revision 1.1  88/03/01  11:08:18  papowell
  367. X * Initial revision
  368. X * 
  369. X ***************************************************************************/
  370. X#ifndef lint
  371. static char id_str1[] =
  372. X    "$Header: checkperm.c,v 3.1 88/06/18 09:33:59 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  373. X#endif lint
  374. X/******************************************************************************
  375. X * Checkperm - determine if a user has permissions to act on a printer queue
  376. X *
  377. X * Input:
  378. X *  permfile - name of the permissions file,
  379. X *    each line of which has the form:
  380. X *        hostname userid printer_name op pr max current
  381. X *         hostname - the host name of the invoker
  382. X *         userid - the user name of the invoker
  383. X *         printer_name - the printer queue to be checked
  384. X *        op -the maximum operation level, A is 'Highest', Z is 'lowest'
  385. X *            Note: R is for LPR, C is for LPC, * allows all
  386. X *        pr - the maximum priority level, A is 'Highest', Z is 'lowest'
  387. X *        max - max number of pages allowed
  388. X *        current - current number of pages
  389. X *
  390. X *    # -- comment
  391. X *    #hostname username printername op pr maxpages currentpages
  392. X *    attila    papowell imagen      C  A  1000     100
  393. X *  !*        cs9*     lpr         *  *
  394. X *    *         jsmith   imagen      *  *  0        0
  395. X *    *         root     *           *  *
  396. X *    
  397. X *    Note: * is the wildcard indicator and matches all characters
  398. X *    Note: if maxpages == 0, then page count is unlimited.
  399. X *  Note: if a ! is in the first column  and there is a match
  400. X *    (i.e.- we should grant permission), then permission is refused.
  401. X *    In the example above, this prevents users whose names start with
  402. X *    cs9 will be forbidden access to the lpr queue.
  403. X *
  404. X * Output:
  405. X * 0 - if userid does not have permissions to act on printer queue
  406. X * nonzero - permission granted
  407. X *
  408. X * If any of arguments is not specified (i.e.- 0 or NULL value),
  409. X * then checking is not done for the field.
  410. X *****************************************************************************/
  411. X
  412. X#include "lp.h"
  413. X
  414. int
  415. Checkperm(permfile, host, user, printerq, op, pr_level, pages)
  416. X    char    *permfile;    /* file to read for permissions */
  417. X    char    *host;        /* hostname to check for */
  418. X    char    *user;        /* username to check for */
  419. X    char    *printerq;    /* printername to check for */
  420. X    int        *op;        /* operation level to check for */
  421. X    int        *pr_level;    /* priority level to check for */
  422. X    int        pages;        /* check page limits flag */
  423. X{
  424. X    FILE    *fp;
  425. X    int        i;
  426. X    char    buf[BUFSIZ];
  427. X    char    username[MAXPARMLEN+1];
  428. X    char    hostname[MAXPARMLEN+1];
  429. X    char    printerqname[MAXPARMLEN+1];
  430. X    char    priority[MAXPARMLEN+1];
  431. X    char    operation[MAXPARMLEN+1];
  432. X    char    *str;
  433. X    int        max, current;
  434. X    int        permission = 0;
  435. X    int        invert, must, found;
  436. X
  437. X    must = 0;
  438. X    invert = 0;
  439. X    if( permfile == 0 ){
  440. X        logerr( XLOG_INFO, "Checkperm: no perm file" );
  441. X        return(permission);
  442. X    }
  443. X    if(Debug>5)log(XLOG_DEBUG,
  444. X    "Checkperm file %s,host=%s,user=%s,printerq=%s,op=%c,pr_level=%c,pages=%d",
  445. X        permfile, host?host:"NONE", user?user:"NONE", printerq?printerq:"NONE",
  446. X         op?*op:'?', pr_level?*pr_level:'?', pages);
  447. X    /*
  448. X     * open permfile for reading
  449. X     */
  450. X    if((fp = fopen_daemon(permfile,"r")) == NULL){
  451. X        logerr( XLOG_CRIT, "Checkperm: cannot open perms file %s",permfile);
  452. X        return(permission);
  453. X    }
  454. X
  455. X    /*
  456. X     * scan through the file looking for a match
  457. X     */
  458. X    found = 0;
  459. X    while( found == 0 && fgets( buf, sizeof(buf), fp ) != NULL ){
  460. X        /* read in the host name */
  461. X        /* sscanf returns number of fields converted */
  462. X        if( buf[0] == '\n' || buf[0] == '#' ){
  463. X            continue;
  464. X        }
  465. X        must = 0;
  466. X        invert = 0;
  467. X        max = current = 0;
  468. X        priority[0] = 0;
  469. X        operation[0] = 0;
  470. X        str = buf;
  471. X        switch( buf[0] ){
  472. X            case '!': invert = 1; ++str; break;
  473. X            case '~': must = 1; ++str; break;
  474. X        }
  475. X        i = sscanf(str, "%s%s%s%s%s%d%d", hostname, username,
  476. X                printerqname,operation,priority,&max,¤t);
  477. X        if( i == 0 ){
  478. X            continue;
  479. X        } else if( i < 4 ){
  480. X            log(XLOG_CRIT,
  481. X            "Error in %s, '%s'\n  Please inform system guru.", permfile, buf);
  482. X            (void)fclose(fp);
  483. X            return(permission);
  484. X        }
  485. X        if(Debug>6)log(XLOG_DEBUG,
  486. X            "host=%s,user=%s,printer=%s,oper=%s,priority=%s,max%d,current%d",
  487. X            hostname, username, printerqname,operation,priority,max,current );
  488. X
  489. X        /*
  490. X         * if the hostname field is '*', this means any host can do it
  491. X         * otherwise we should check to see if a valid host name
  492. X         */
  493. X        if( !match(host,hostname) ){
  494. X            if( must ){
  495. X                found = 1;
  496. X            }
  497. X            continue;
  498. X        }
  499. X        if(Debug>6)log(XLOG_DEBUG, "Checkperm: host ok, %s, %s",
  500. X            host?host:"<NONE>",hostname);
  501. X
  502. X        /* compare the user names */
  503. X        if( !match(user,username) ){
  504. X            if( must ){
  505. X                found = 1;
  506. X            }
  507. X            continue;
  508. X        }
  509. X        if(Debug>6)log(XLOG_DEBUG, "Checkperm: user ok, %s, %s",
  510. X            user?user:"<NONE>",username);
  511. X
  512. X        /* compare the printer queue names */
  513. X        if( !match(printerq,printerqname) ){
  514. X            if( must ){
  515. X                found = 1;
  516. X            }
  517. X            continue;
  518. X        }
  519. X        if(Debug>6)log(XLOG_DEBUG, "Checkperm: printerq ok, %s, %s",
  520. X            printerq?printerq:"<NONE>",printerqname);
  521. X
  522. X        /* compare the operations */
  523. X        if( op && operation[0] != '*' && *op < operation[0]){
  524. X            if( must ){
  525. X                found = 1;
  526. X            }
  527. X            continue;
  528. X        }
  529. X        if(Debug>6)log(XLOG_DEBUG,
  530. X            "Checkperm: OK, must %d, wanted %c(%d), have %c(%d), invert %d",
  531. X            must, op?*op:'?', op?*op:'?', operation[0], operation[0], invert);
  532. X        /*
  533. X         * Well, you had to have a match, and you did.  So this means that
  534. X         * you passed, but you do not use this entry.
  535. X         */
  536. X        if( must ){
  537. X            continue;
  538. X        }
  539. X        if(Debug>6)log(XLOG_DEBUG,
  540. X            "Checkperm: pages- %d, max %d, current %d", pages,max,current);
  541. X        found = 1;
  542. X        permission = 1;
  543. X        if( pages && max && current > max ){
  544. X            /* page limit exceeded in first matching entry: bad news */
  545. X            permission = 0;
  546. X        }
  547. X        if( pr_level && priority[0] && priority[0] != '*'){
  548. X            /* we want to check priory and there are limits */
  549. X            if( priority[0] > *pr_level ){
  550. X                /* sorry, this is too high */
  551. X                *pr_level = priority[0];
  552. X            }
  553. X        }
  554. X    }
  555. X    if( permission && invert ){
  556. X        permission = 0;
  557. X    }
  558. X    if(Debug>4)log(XLOG_DEBUG,"Checkperm %d in %s, printerq %s for %s@%s",
  559. X        permission, permfile,
  560. X        printerq?printerq:"NONE",user?user:"NONE",host?host:"NONE");
  561. X    (void)fclose(fp);
  562. X    return(permission);
  563. X}
  564. X
  565. X/*
  566. X * match( str, pattern )
  567. X *  -- str is null (match returns 1 )
  568. X *    -- pattern is <fixed>*, str is <fixed><anything> (match returns 1)
  569. X *  -- pattern is !<fixed>*, str is <fixed><anything> (match returns 0)
  570. X *    -- if not above, match returns 0
  571. X */
  572. X
  573. static int
  574. match( str, pattern)
  575. X    char *str, *pattern;
  576. X{
  577. X    int c;
  578. X
  579. X    if(Debug>8)log(XLOG_DEBUG,"match str '%s', pattern '%s'\n", str, pattern );
  580. X    if( str == 0 || pattern == 0) return(1);
  581. X    while( c = *pattern ){
  582. X        if(Debug>8)log(XLOG_DEBUG,"match partial str '%s', pattern '%s'\n",
  583. X            str, pattern );
  584. X        switch( c ){
  585. X            /*
  586. X             * match 0 or more characters in the string
  587. X             */
  588. X            case '*':
  589. X                if( match( str, pattern+1 ) ){
  590. X                    return( 1 );
  591. X                }
  592. X                if( *str && match( str+1, pattern ) ){
  593. X                    return( 1 );
  594. X                }
  595. X                return( 0 );
  596. X            case '?':
  597. X                if( *str == 0 ){
  598. X                    return( 0 );
  599. X                }
  600. X                break;
  601. X            default:
  602. X                if( c != *str ){
  603. X                    return( 0 );
  604. X                }
  605. X                break;
  606. X        }
  607. X        ++pattern; ++str;
  608. X    }
  609. X    return( *pattern == *str );
  610. X}
  611. END_OF_FILE
  612. if test 8361 -ne `wc -c <'src/checkperm.c'`; then
  613.     echo shar: \"'src/checkperm.c'\" unpacked with wrong size!
  614. fi
  615. # end of 'src/checkperm.c'
  616. fi
  617. if test -f 'src/displayq.c' -a "${1}" != "-c" ; then 
  618.   echo shar: Will not clobber existing file \"'src/displayq.c'\"
  619. else
  620. echo shar: Extracting \"'src/displayq.c'\" \(7973 characters\)
  621. sed "s/^X//" >'src/displayq.c' <<'END_OF_FILE'
  622. X/***************************************************************************
  623. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  624. X ***************************************************************************
  625. X * MODULE: displayq.c
  626. X * Display the status of a Printer queue
  627. X ***************************************************************************
  628. X * Revision History: Created Sat Jan  9 20:08:26 CST 1988
  629. X * $Log:    displayq.c,v $
  630. X * Revision 3.1  88/06/18  09:34:07  papowell
  631. X * Version 3.0- Distributed Sat Jun 18 1988
  632. X * 
  633. X * Revision 2.3  88/05/16  12:09:08  papowell
  634. X * Added a queue printing, spooling message
  635. X * 
  636. X * Revision 2.2  88/05/14  10:17:57  papowell
  637. X * Use long format for job file names;
  638. X * Added 'fd', no forward flag;
  639. X * Control file has to have hostname and origination agree.
  640. X * 
  641. X * Revision 2.1  88/05/09  10:07:58  papowell
  642. X * PLP: Released Version
  643. X * 
  644. X * Revision 1.6  88/04/06  12:13:18  papowell
  645. X * Minor updates, changes in error message formats.
  646. X * Elimination of the AF_UNIX connections, use AF_INET only.
  647. X * Better error messages.
  648. X * 
  649. X * Revision 1.5  88/03/25  14:59:21  papowell
  650. X * Debugged Version:
  651. X * 1. Added the PLP control file first transfer
  652. X * 2. Checks for MX during file transfers
  653. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  654. X *     apparently they open files and then assume that they will stay
  655. X *     open.
  656. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  657. X * 
  658. X * Revision 1.4  88/03/12  10:03:25  papowell
  659. X * *** empty log message ***
  660. X * 
  661. X * Revision 1.3  88/03/11  19:28:04  papowell
  662. X * Minor Changes, Updates
  663. X * 
  664. X * Revision 1.2  88/03/05  15:01:25  papowell
  665. X * Minor Corrections,  Lint Problems
  666. X * 
  667. X * Revision 1.1  88/03/01  11:08:21  papowell
  668. X * Initial revision
  669. X * 
  670. X ***************************************************************************/
  671. X#ifndef lint
  672. static char id_str1[] =
  673. X    "$Header: displayq.c,v 3.1 88/06/18 09:34:07 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  674. X#endif lint
  675. X
  676. X#include "lp.h"
  677. static int header;
  678. static int server;
  679. X
  680. X/***************************************************************************
  681. X * Displayq()
  682. X *  1. get the printcap entries
  683. X *  2. get the queue entries
  684. X *  3. get the active server files and see if they are in queue
  685. X *  4. print the queue status
  686. X ***************************************************************************/
  687. X
  688. Displayq()
  689. X{
  690. X    int i;                /* ACME Integers, Inc. */
  691. X    struct queue *q;    /* job entry */
  692. X    char buf[BUFSIZ];    /* status message buffer */
  693. X
  694. X    header = 0;
  695. X    /*
  696. X     * get the printcap entry
  697. X     */
  698. X    if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
  699. X        (void)fprintf(stdout, "Printer %s does not exist\n", Printer );
  700. X        (void)fflush(stdout);
  701. X        return;
  702. X    }
  703. X    if( SD == 0 || *SD == 0 ){
  704. X        if(Debug>0)log(XLOG_DEBUG,"Printer %s does not have a spool queue\n",
  705. X            Printer);
  706. X        return;
  707. X    }
  708. X    
  709. X    if(Debug>5)log(XLOG_DEBUG,"Displayq: doing %s", Printer );
  710. X    /*
  711. X     * If you are running NFS, use the remote lpr
  712. X     */
  713. X    if( RM && *RM && NW ){
  714. X        Remote_status();
  715. X        return;
  716. X    }
  717. X    /* chdir to spool directory */
  718. X    if (chdir(SD) < 0) {
  719. X        logerr_die( XLOG_NOTICE,"cannot chdir to %s", SD);
  720. X    }
  721. X    /*
  722. X     * get the numbers of jobs here
  723. X     */
  724. X    Jobcount = Getq();
  725. X    /*
  726. X     * Checkactive checks for the active jobs
  727. X     */
  728. X    server = Checkactive();
  729. X    buf[0] = 0;
  730. X    if( LO_statb.st_mode & DISABLE_QUEUE ){
  731. X        (void)strcat(buf, "no spooling" );
  732. X    }
  733. X    if( LO_statb.st_mode & DISABLE_PRINT ){
  734. X        if( buf[0] ){
  735. X            (void)strcat( buf, ", ");
  736. X        }
  737. X        (void)strcat(buf, "no printing" );
  738. X    }
  739. X
  740. X    if( Short_format ){
  741. X        if( From == Host ){
  742. X            (void)fprintf(stdout,"%s: %d jobs", Printer, Jobcount );
  743. X        } else {
  744. X            (void)fprintf(stdout,"%s@%s: %d jobs", Printer, Host, Jobcount );
  745. X        }
  746. X        if( buf[0] ){
  747. X            (void)fprintf(stdout," (%s)", buf );
  748. X        }
  749. X        (void)fprintf(stdout,"\n");
  750. X    } else {
  751. X        if( From == Host ){
  752. X            if( SV == 0 || *SV == 0 ){
  753. X                (void)fprintf(stdout, "Printer '%s' (%s):", Printer, Host );
  754. X            } else {
  755. X                (void)fprintf(stdout, "Queue '%s' (%s):", Printer, Host );
  756. X            }
  757. X            if( buf[0] ){
  758. X                (void)fprintf(stdout," (%s)", buf );
  759. X            }
  760. X            (void)fprintf(stdout,"\n");
  761. X        } else {
  762. X            if( SV == 0 || *SV == 0 ){
  763. X            (void)fprintf(stdout, "Remote printer '%s' (%s):",Printer,Host);
  764. X            } else {
  765. X            (void)fprintf(stdout, "Remote queue '%s' (%s):", Printer, Host );
  766. X            }
  767. X            if( buf[0] ){
  768. X                (void)fprintf(stdout," (%s)", buf );
  769. X            }
  770. X            (void)fprintf(stdout,"\n");
  771. X        }
  772. X        /*
  773. X         * show status files
  774. X         */
  775. X        showstatus();
  776. X    }
  777. X    (void)fflush(stdout);
  778. X    /*
  779. X     * run down list
  780. X     */
  781. X    for( i = 0; i < Jobcount; ++i ){
  782. X        q = &Queue[i];
  783. X        if( Parmcount <= 0 || Match_entry( q ) ){
  784. X            showentry(i+1, q);
  785. X        }
  786. X    }
  787. X    if( RM && *RM ){
  788. X        Remote_status();
  789. X    }
  790. X    if( From == Host ){
  791. X        putchar('\n');
  792. X    }
  793. X}
  794. X
  795. X/*****************************************************************************
  796. X * showentry( int seq, struct queue *q )
  797. X *  show status for entry
  798. X * Rank   Owner      Pr Job  Host         Files                Size
  799. X * active sutantha   Z  260  umn-cs       (stdin)              177744 bytes
  800. X * 2      powell     Z    1  attila       junk, morejunk,...   32767 bytes
  801. X *
  802. X * if you have multiple servers, the first column will contain the name
  803. X * of the server.
  804. X * Rank   Owner      Pr Job  Host         Files                Size
  805. X * sv1    sutantha   Z  260  umn-cs       (stdin)              177744 bytes
  806. X * sv2    powell     Z    1  attila       junk, morejunk,...   32767 bytes
  807. X *****************************************************************************/
  808. X
  809. static char hdr_format[] = "%6s %-11s %-2s %-3s %-11s %-20s %-6s %-s\n";
  810. static char info_format[] = "%6s %-11s %-c  %-3d %-11s %-20s %-6d %s\n";
  811. X
  812. static char *
  813. short_time( tvec )
  814. X    time_t tvec;        /* time */
  815. X{
  816. X    char *ctime();
  817. X    static char s[40];
  818. X
  819. X    /*
  820. X     *    012345678901234567890123456789
  821. X     *    Mon May 30 20:53:27 CDT 1988
  822. X     */
  823. X    (void)strcpy(s,ctime(&tvec));
  824. X    s[16] = 0;
  825. X    return( &s[4] );
  826. X}
  827. showentry( seq, q )
  828. X    int seq;
  829. X    struct queue *q;
  830. X{
  831. X    char buf[10];
  832. X    char *suffix;
  833. X    char name[BUFSIZ];
  834. X    char date[BUFSIZ];
  835. X
  836. X    if( Short_format ){
  837. X        (void)fprintf(stdout,"%d %s: %s\n", seq, q->q_name, q->q_user );
  838. X        (void)fflush(stdout);
  839. X        return;
  840. X    }
  841. X    if( header == 0 ){
  842. X        (void)fprintf(stdout, hdr_format,"Rank","Owner","Pr","Job",
  843. X            "Host","Files","Size","Date");
  844. X        header = 1;
  845. X    }
  846. X    if( q->q_daemon ){
  847. X        if( SV == 0 || *SV == 0 ){
  848. X            (void)strcpy( buf, "active" );
  849. X        } else {
  850. X            (void)strcpy( buf, q->q_server );
  851. X        }
  852. X    } else {
  853. X        switch( seq ){
  854. X        case 1: suffix = "st"; break;
  855. X        case 2: suffix = "nd"; break;
  856. X        case 3: suffix = "rd"; break;
  857. X        default: suffix = "th"; break;
  858. X        }
  859. X        (void)sprintf(buf, "%d%s", seq, suffix );
  860. X    }
  861. X    /*
  862. X     * print short name
  863. X     */
  864. X    (void)strcpy(name, &q->q_from );
  865. X    suffix = index( name, '.' );
  866. X    if( suffix ){
  867. X        *suffix = 0;
  868. X    }
  869. X    (void)fprintf(stdout, info_format, buf, q->q_user, q->q_priority, q->q_num,
  870. X        name,q->q_data, q->q_size, short_time(q->q_sp) );
  871. X    (void)fflush(stdout);
  872. X}
  873. X
  874. X/*
  875. X * show status:
  876. X * show the status files for the server devices
  877. X */
  878. showstatus()
  879. X{
  880. X    static char server_name[BUFSIZ];    /* Name of server file */
  881. X    int active, pid;
  882. X    char buf[BUFSIZ];
  883. X    char *sp, *ep;            /* ACME Pointer */
  884. X
  885. X    if( SV == 0 || *SV == 0 ){
  886. X        if( Jobcount > 0 && server == 0 ){
  887. X            (void)fprintf(stdout, "Warning: no server present\n" );
  888. X        }
  889. X        printstatus();
  890. X        return;
  891. X    }
  892. X    /*
  893. X     * check for each of the servers
  894. X     */
  895. X    (void)strcpy( server_name, SV );
  896. X    for( sp = server_name; sp; sp = ep ){
  897. X        if( ep = index( sp, ',' ) ){
  898. X            *ep = 0;
  899. X            ++ep;
  900. X        }
  901. X        /*
  902. X         * get the lock file and the status from the server
  903. X         */
  904. X        if( Set_pc_entry( sp, Server_pc_vars, Server_pc_len ) == 0 ){
  905. X            fatal( XLOG_INFO, "no server entry for %s", sp );
  906. X        }
  907. X        buf[0] = 0;
  908. X        active = Checklockfile( sp, &pid,buf,sizeof(buf),&LO_statb );
  909. X        (void)fprintf(stdout, " server- %s", sp );
  910. X        if( LO_statb.st_mode & DISABLE_PRINT ){
  911. X            (void)fprintf(stdout, " disabled");
  912. X        } else {
  913. X            (void)fprintf(stdout, " enabled");
  914. X        }
  915. X        if( active ){
  916. X            (void)fprintf(stdout, ", server %d, processing %s",pid, buf );
  917. X        }
  918. X        putchar( '\n' );
  919. X        (void)fflush( stdout );
  920. X        printstatus();
  921. X    }
  922. X}
  923. X
  924. END_OF_FILE
  925. if test 7973 -ne `wc -c <'src/displayq.c'`; then
  926.     echo shar: \"'src/displayq.c'\" unpacked with wrong size!
  927. fi
  928. # end of 'src/displayq.c'
  929. fi
  930. if test -f 'src/lpc.c' -a "${1}" != "-c" ; then 
  931.   echo shar: Will not clobber existing file \"'src/lpc.c'\"
  932. else
  933. echo shar: Extracting \"'src/lpc.c'\" \(8375 characters\)
  934. sed "s/^X//" >'src/lpc.c' <<'END_OF_FILE'
  935. X/***************************************************************************
  936. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  937. X ***************************************************************************
  938. X * MODULE: lpc.c
  939. X * lpc - control LPR queues
  940. X ***************************************************************************
  941. X * Revision History: Created Mon Jan 25 14:04:26 CST 1988
  942. X * $Log:    lpc.c,v $
  943. X * Revision 3.1  88/06/18  09:34:36  papowell
  944. X * Version 3.0- Distributed Sat Jun 18 1988
  945. X * 
  946. X * Revision 2.2  88/05/14  10:21:01  papowell
  947. X * Modified -X flag handling
  948. X * 
  949. X * Revision 2.1  88/05/09  10:08:40  papowell
  950. X * PLP: Released Version
  951. X * 
  952. X * Revision 1.7  88/04/27  18:02:54  papowell
  953. X * The SIGCHLD signal has an odd behaviour on some systems.  Modified so that
  954. X * it will not get set UNLESS processes are started;  also,  it is reset
  955. X * to SIG_DFL, not SIG_IGN.
  956. X * 
  957. X * Revision 1.6  88/04/15  13:06:23  papowell
  958. X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr)
  959. X * have valid file descriptors;  if not open, then /dev/null is used.
  960. X * 
  961. X * Revision 1.5  88/04/07  12:32:26  papowell
  962. X * Modified to use Getopt
  963. X * 
  964. X * Revision 1.4  88/04/06  12:12:17  papowell
  965. X * Minor updates, changes in error message formats.
  966. X * Elimination of the AF_UNIX connections, use AF_INET only.
  967. X * Better error messages.
  968. X * 
  969. X * Revision 1.3  88/03/25  15:00:00  papowell
  970. X * Debugged Version:
  971. X * 1. Added the PLP control file first transfer
  972. X * 2. Checks for MX during file transfers
  973. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  974. X *     apparently they open files and then assume that they will stay
  975. X *     open.
  976. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  977. X * 
  978. X * Revision 1.2  88/03/11  19:28:21  papowell
  979. X * Minor Changes, Updates
  980. X * 
  981. X * Revision 1.1  88/03/01  11:08:35  papowell
  982. X * Initial revision
  983. X * 
  984. X ***************************************************************************/
  985. X#ifndef lint
  986. static char id_str1[] =
  987. X    "$Header: lpc.c,v 3.1 88/06/18 09:34:36 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  988. X#endif lint
  989. X#include "lp.h"
  990. X
  991. X
  992. X/***************************************************************************
  993. X * SYNOPSIS
  994. X *      lpc [ -Dn ] [ -X [ command [ argument ... ] ]
  995. X * DESCRIPTION
  996. X *      Lpc  is  used  by  the  system  administrator to control the
  997. X *      operation  of the line printer system. For each line printer
  998. X *      configured in /etc/printcap, lpc may be used to:
  999. X *      + disable or enable a printer,
  1000. X *      + disable or enable a printer's spooling queue,
  1001. X *      + rearrange the order of jobs in a spooling queue,
  1002. X *      + find the status of printers, and their associated spooling
  1003. X *        queues and printer dameons.
  1004. X *      Without any arguments, lpc will prompt for commands from the
  1005. X *      standard  input.   If arguments are supplied, lpc interprets
  1006. X *      the  first argument as a command and the remaining arguments
  1007. X *      as  parameters  to  the  command.  The standard input may be
  1008. X *      redirected causing lpc to read commands from file.  Commands
  1009. X *      may  be  abreviated; the following is the list of recognized
  1010. X *      commands.
  1011. X *      ? [ command ... ]
  1012. X *      help [ command ... ]
  1013. X *      abort { all | printer ... }
  1014. X *      clean { all | printer ... }
  1015. X *      enable { all | printer ... }
  1016. X *      exit
  1017. X *      quit
  1018. X *      disable { all | printer ... }
  1019. X *      restart { all | printer ... }
  1020. X *      start { all | printer ... }
  1021. X *      kill { all | printer ... }
  1022. X *      status [ terse ] [ all ] [ printer ... ]
  1023. X *      stop { all | printer ... }
  1024. X *      remote { abort | clean | enable | disable | restart  } printer
  1025. X *      topq printer [ jobnum ... ] [ user ... ]
  1026. X *      lpq [options]
  1027. X *      lprm [options]
  1028. X *      lpd
  1029. X *
  1030. X *      -Dn  Enables  display  of  debugging  information.   The  -D
  1031. X *           selects  level  1;  -Dn  selects level n (n is a single
  1032. X *           digit).
  1033. X *      -X   Use  an  Xperimental version of LPD if the software has
  1034. X *           been  compiled  with  the  appropriate support; ignored
  1035. X *           otherwise.
  1036. X ***************************************************************************/
  1037. X/***************************************************************************
  1038. X * main(int argc, char **argv)
  1039. X * 1. get the host computer name and user name
  1040. X * 2. set up the Host and Person information
  1041. X * 3. get the parameters or set up a read from STDIN
  1042. X * 4. convert parameters and call the server routine
  1043. X ****************************************************************************/
  1044. X
  1045. extern int cleanup();
  1046. X
  1047. main(argc, argv)
  1048. X    int argc;
  1049. X    char **argv;
  1050. X{
  1051. X    struct passwd *pw_ent;        /* user entry in /etc/passwd */
  1052. X
  1053. X    /*
  1054. X     * set umask to avoid problems with user umask
  1055. X     */
  1056. X    (void)umask(0);
  1057. X    /*
  1058. X     * Set fd 0, 1, 2 to /dev/null if not open
  1059. X     */
  1060. X    Std_environ();
  1061. X#    ifdef XPERIMENT
  1062. X        Setup_test();
  1063. X#    endif XPERIMENT
  1064. X
  1065. X    /*
  1066. X     * set up the pathnames for information files
  1067. X     */
  1068. X    Tailor_names();
  1069. X    /*
  1070. X     * set the from flag
  1071. X     */
  1072. X    From = Host;
  1073. X    /*
  1074. X     * get the user name
  1075. X     */
  1076. X    if( (pw_ent = getpwuid( getuid() )) == 0 ){
  1077. X        logerr_die( XLOG_INFO, "lpc: getpwuid failed on uid %d", getuid());
  1078. X    }
  1079. X    (void)strcpy( LOGNAME, pw_ent->pw_name );
  1080. X    Person = LOGNAME;
  1081. X    if( getuid() == 0 ){
  1082. X        /* we are being invoked by root */
  1083. X        Is_root = 1;
  1084. X    }
  1085. X    /*
  1086. X     * setup parameters
  1087. X     */
  1088. X    Lpc_parms(argc, argv);
  1089. X    /*
  1090. X     * set signals
  1091. X     */
  1092. X    (void)signal(SIGPIPE, SIG_IGN);
  1093. X    (void)signal(SIGHUP, cleanup);
  1094. X    (void)signal(SIGINT, cleanup);
  1095. X    (void)signal(SIGQUIT, cleanup);
  1096. X    (void)signal(SIGTERM, cleanup);
  1097. X    if( Parmcount != 0 ){
  1098. X        (void)Control_ops();
  1099. X    } else {
  1100. X        Get_line();
  1101. X    }
  1102. X    exit( 0 );
  1103. X}
  1104. X
  1105. X/***************************************************************************
  1106. X * cleanup()
  1107. X * remove the temp files
  1108. X ***************************************************************************/
  1109. X
  1110. cleanup()
  1111. X{
  1112. X    exit( 1 );
  1113. X}
  1114. X
  1115. X/***************************************************************************
  1116. X * Lpc_parms( int arc, char **argv )
  1117. X * 1. pick off the options
  1118. X * 2. set up the parameters
  1119. X ***************************************************************************/
  1120. X
  1121. static char *optstr = "D:X";
  1122. static int Xpert;
  1123. Lpc_parms( argc, argv )
  1124. X    int argc;
  1125. X    char **argv;
  1126. X{
  1127. X    int option;
  1128. X    int i;
  1129. X
  1130. X    while( (option = Getopt(argc,argv,optstr)) != EOF ){
  1131. X        switch( option ){
  1132. X        case 'D':
  1133. X            if(Debug){
  1134. X                Diemsg("Duplicate -D option");
  1135. X            }
  1136. X            if( sscanf( Optarg, "%d", &Debug ) != 1 || Debug <= 0){
  1137. X                Diemsg("-D parameter is not positive integer" );
  1138. X            }
  1139. X            break;
  1140. X        case 'X':
  1141. X            if( Xpert ){
  1142. X                Diemsg("Duplicate -X option");
  1143. X            }
  1144. X#    ifdef DEBUG
  1145. X            Setup_test();
  1146. X            Tailor_names();
  1147. X#    else
  1148. X            Diemsg("-X is not allowed" );
  1149. X#    endif DEBUG
  1150. X            break;
  1151. X        default:
  1152. X            break;
  1153. X        }
  1154. X    }
  1155. X
  1156. X    /*
  1157. X     * set up the Parms[] array
  1158. X     */
  1159. X    for( ; Optind < argc; ++Optind ){
  1160. X        if( Parmcount < MAXPARMS ){
  1161. X            Parms[Parmcount].str = argv[Optind];
  1162. X            i = atoi( Parms[Parmcount].str );
  1163. X            if( i > 0 ){
  1164. X                Parms[Parmcount].num = i;
  1165. X            } else {
  1166. X                Parms[Parmcount].num = -1;
  1167. X            }
  1168. X            ++Parmcount;
  1169. X        } else {
  1170. X            Diemsg( "too many parameters" );
  1171. X        }
  1172. X    }
  1173. X}
  1174. X
  1175. X
  1176. X/***************************************************************************
  1177. X * Get_line()
  1178. X * Repeat:
  1179. X * 1. Get a line.
  1180. X * 2. if EOF return
  1181. X * 3. Split it up and put into Parms[]
  1182. X * 4. Call Control_ops()
  1183. X ***************************************************************************/
  1184. X
  1185. Get_line()
  1186. X{
  1187. X    char buf[BUFSIZ];    /* get a line */
  1188. X    int i;                /* ACME Integers, Inc. */
  1189. X    char *cp;            /* ACME Pointers, Inc. */
  1190. X
  1191. X    while( 1 ){
  1192. X        (void)fprintf(stdout, "lpc>");
  1193. X        (void)fflush(stdout);
  1194. X        if( fgets( buf, sizeof(buf), stdin ) == 0 ) return;
  1195. X        buf[ strlen(buf) -1 ] = 0;    /* clobber the last char */
  1196. X        /*
  1197. X         * now set up the parameters
  1198. X         */
  1199. X        Parmcount = 0;
  1200. X        for( cp = buf; *cp; ){
  1201. X            /* skip leading blanks */
  1202. X            Parms[Parmcount].str = 0;
  1203. X            Parms[Parmcount].num = -1;
  1204. X            while( *cp && isspace( *cp ) ) ++cp;
  1205. X            if( *cp ){
  1206. X                Parms[Parmcount].str = cp;
  1207. X            }
  1208. X            while( *cp && !isspace( *cp ) ) ++cp;
  1209. X            if( *cp ){
  1210. X                *cp = 0;
  1211. X                ++cp;
  1212. X            }
  1213. X            if( Parms[Parmcount].str != 0 ){
  1214. X                Parms[Parmcount].num = -1;
  1215. X                i = atoi( Parms[Parmcount].str );
  1216. X                if( i > 0 ){
  1217. X                    Parms[Parmcount].num = i;
  1218. X                }
  1219. X                ++Parmcount;
  1220. X            }
  1221. X        }
  1222. X        if( Parmcount ){
  1223. X            if(Debug>3){
  1224. X                for( i = 0; i < Parmcount; ++i ){
  1225. X                    (void)fprintf(stderr,"Parms[%d]: '%s', %d\n",i,
  1226. X                        Parms[i].str,Parms[i].num );
  1227. X                }
  1228. X            }
  1229. X            (void)Control_ops();
  1230. X        }
  1231. X    }
  1232. X    /*NOTREACHED*/
  1233. X}
  1234. END_OF_FILE
  1235. if test 8375 -ne `wc -c <'src/lpc.c'`; then
  1236.     echo shar: \"'src/lpc.c'\" unpacked with wrong size!
  1237. fi
  1238. # end of 'src/lpc.c'
  1239. fi
  1240. if test -f 'src/lpq.c' -a "${1}" != "-c" ; then 
  1241.   echo shar: Will not clobber existing file \"'src/lpq.c'\"
  1242. else
  1243. echo shar: Extracting \"'src/lpq.c'\" \(8037 characters\)
  1244. sed "s/^X//" >'src/lpq.c' <<'END_OF_FILE'
  1245. X/***************************************************************************
  1246. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1247. X ***************************************************************************
  1248. X * MODULE: lpq.c
  1249. X ***************************************************************************
  1250. X * Revision History: Created Mon Feb  1 11:34:11 CST 1988
  1251. X * $Log:    lpq.c,v $
  1252. X * Revision 3.2  88/07/01  15:44:39  papowell
  1253. X * Added multiple -P parameters
  1254. X * 
  1255. X * Revision 3.1  88/06/18  09:34:43  papowell
  1256. X * Version 3.0- Distributed Sat Jun 18 1988
  1257. X * 
  1258. X * Revision 2.2  88/05/14  10:20:56  papowell
  1259. X * Modified -X flag handling
  1260. X * 
  1261. X * Revision 2.1  88/05/09  10:08:54  papowell
  1262. X * PLP: Released Version
  1263. X * 
  1264. X * Revision 1.7  88/04/28  11:03:01  papowell
  1265. X * removed unused variables,  shuts up lint
  1266. X * 
  1267. X * Revision 1.6  88/04/27  18:02:50  papowell
  1268. X * The SIGCHLD signal has an odd behaviour on some systems.  Modified so that
  1269. X * it will not get set UNLESS processes are started;  also,  it is reset
  1270. X * to SIG_DFL, not SIG_IGN.
  1271. X * 
  1272. X * Revision 1.5  88/04/15  13:06:14  papowell
  1273. X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr)
  1274. X * have valid file descriptors;  if not open, then /dev/null is used.
  1275. X * 
  1276. X * Revision 1.4  88/04/07  12:26:49  papowell
  1277. X * modified to use Getopt
  1278. X * 
  1279. X * Revision 1.3  88/03/25  15:00:11  papowell
  1280. X * Debugged Version:
  1281. X * 1. Added the PLP control file first transfer
  1282. X * 2. Checks for MX during file transfers
  1283. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1284. X *     apparently they open files and then assume that they will stay
  1285. X *     open.
  1286. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1287. X * 
  1288. X * Revision 1.2  88/03/11  19:28:16  papowell
  1289. X * Minor Changes, Updates
  1290. X * 
  1291. X * Revision 1.1  88/03/01  11:08:39  papowell
  1292. X * Initial revision
  1293. X * 
  1294. X ***************************************************************************/
  1295. X#ifndef lint
  1296. static char id_str1[] =
  1297. X    "$Header: lpq.c,v 3.2 88/07/01 15:44:39 papowell Locked $ PLP Copyright 1988 Patrick Powell";
  1298. X#endif lint
  1299. X#include "lp.h"
  1300. X
  1301. X/***************************************************************************
  1302. X *   lpq - spool queue examination program
  1303. X *   lpq [-Pprinter ][-a][-l][+[n]][-D[n]][-X][ job # ... ][ user ... ]
  1304. X * DESCRIPTION
  1305. X *   lpq examines the spooling area used by lpd(8) for printing
  1306. X *   files on the line printer, and reports the status of the
  1307. X *   specified jobs or all jobs associated with a user. lpq
  1308. X *   invoked without any arguments reports on the printer given
  1309. X *   by the default printer (see -P option).  For each job sub-
  1310. X *   mitted (i.e. invocation of lpr(1)) lpq reports the user's
  1311. X *   name, current rank in the queue, the names of files compris-
  1312. X *   ing the job, the job identifier (a number which may be sup-
  1313. X *   plied to lprm(1) for removing a specific job), and the total
  1314. X *   size in bytes.  Job ordering is dependent on the algorithm
  1315. X *   used to scan the spooling directory and is FIFO (First in
  1316. X *   First Out), in order of priority level.  File names compris-
  1317. X *   ing a job may be unavailable (when lpr(1) is used as a sink
  1318. X *   in a pipeline) in which case the file is indicated as
  1319. X *   ``(stdin)''.  The following options are available.
  1320. X *   -P printer  spool queue name
  1321. X *   -a   All printers listed in /etc/printcap(5) file are reported.
  1322. X *   -l   aLternate display format
  1323. X *   [+[n]] redisplay the spool queue
  1324. X *   -D[n]  debug level n
  1325. X *   -X   Use an Xperimental version of LPD
  1326. X *   [ job # ... ][ user ... ]
  1327. X ***************************************************************************/
  1328. X
  1329. static int Delay;    /* time to wait */
  1330. static int Do_all_pr;        /* do all printers */
  1331. static int Xpert;            /* X flag */
  1332. static char **Printer_name;
  1333. static int Printer_count;
  1334. static int Max_printer_count;
  1335. int cleanup();
  1336. X
  1337. main( argc, argv )
  1338. X    int argc;
  1339. X    char **argv;
  1340. X{
  1341. X    struct passwd *pw_ent;        /* user entry in /etc/passwd */
  1342. X    int i;
  1343. X
  1344. X    /*
  1345. X     * set umask to avoid problems with user umask
  1346. X     */
  1347. X    (void)umask(0);
  1348. X    /*
  1349. X     * Set fd 0, 1, 2 to /dev/null if not open
  1350. X     */
  1351. X    Std_environ();
  1352. X#    ifdef XPERIMENT
  1353. X        Setup_test();
  1354. X#    endif XPERIMENT
  1355. X
  1356. X    /*
  1357. X     * set up the pathnames for information files
  1358. X     */
  1359. X    Tailor_names();
  1360. X    /*
  1361. X     * set up the from information
  1362. X     */
  1363. X    From = Host;
  1364. X    /*
  1365. X     * get the user name
  1366. X     */
  1367. X    if( (pw_ent = getpwuid( getuid() )) == 0 ){
  1368. X        logerr_die( XLOG_INFO, "getpwuid failed on uid %d", getuid());
  1369. X    }
  1370. X    (void)strcpy( LOGNAME, pw_ent->pw_name );
  1371. X    Person = LOGNAME;
  1372. X    /*
  1373. X     * get the parameters
  1374. X     */
  1375. X    Get_parms(argc, argv);
  1376. X    (void)signal(SIGPIPE, SIG_IGN);
  1377. X    (void)signal(SIGHUP, cleanup);
  1378. X    (void)signal(SIGINT, cleanup);
  1379. X    (void)signal(SIGQUIT, cleanup);
  1380. X    (void)signal(SIGTERM, cleanup);
  1381. X    do{
  1382. X        /*
  1383. X         * if we are to clear the terminal, do so
  1384. X         */
  1385. X        if( Delay ){
  1386. X            Term_clear();
  1387. X        }
  1388. X        /*
  1389. X         * if we have all printers to display, do so
  1390. X         */
  1391. X        if( Do_all_pr ){
  1392. X            Display_all();
  1393. X        } else if( Printer_count == 0 ){
  1394. X                Displayq();
  1395. X        } else {
  1396. X            for( i = 0; i < Printer_count; ++i ){
  1397. X                Printer = Printer_name[i];
  1398. X                Displayq();
  1399. X            }
  1400. X        }
  1401. X        if( Delay ){
  1402. X            sleep( (unsigned)Delay );
  1403. X        }
  1404. X    } while( Delay );
  1405. X    exit( 0 );
  1406. X}
  1407. X
  1408. X
  1409. X/***************************************************************************
  1410. X * Get_parms( argc, argv )
  1411. X * 1. set up the name routine
  1412. X * 2. extract parameters
  1413. X *  -Pprinter sets Printer to printer
  1414. X *  -Dn set Debug to n
  1415. X *  -a   sets Do_all_pr
  1416. X *  -l   set Short_format
  1417. X *  -X   sets Xpert
  1418. X *  +nn
  1419. X ***************************************************************************/
  1420. static char *optstr= "P:D:alX+?";
  1421. Get_parms( argc, argv )
  1422. X    int argc;
  1423. X    char **argv;
  1424. X{
  1425. X    int c;        /* ACME Integers, Inc. */
  1426. X    char *arg;    /* argument from list */
  1427. X
  1428. X    Opt_flag = "+";
  1429. X    while( (c = Getopt(argc,argv,optstr)) != EOF ){
  1430. X        switch( c ){
  1431. X        case 'P':
  1432. X            if( Printer_count == Max_printer_count ){
  1433. X                if( Max_printer_count == 0 ){
  1434. X                    Max_printer_count = 3;
  1435. X                    Printer_name =
  1436. X                        (char **)malloc( Max_printer_count * sizeof(char *));
  1437. X                } else {
  1438. X                    Max_printer_count += 3;
  1439. X                    Printer_name =
  1440. X                        (char **)realloc( Printer_name,
  1441. X                            Max_printer_count * sizeof(char *));
  1442. X                }
  1443. X            }
  1444. X            Printer_name[Printer_count] =  Optarg;
  1445. X            ++Printer_count;
  1446. X            break;
  1447. X        case 'D':
  1448. X            Check_already( c, &Debug );
  1449. X            if( Optarg ){
  1450. X                Debug = atoi( Optarg );
  1451. X            } else {
  1452. X                Debug = 1;
  1453. X            }
  1454. X            break;
  1455. X        case 'a':
  1456. X            Check_already( c, &Do_all_pr );
  1457. X            break;
  1458. X        case 'l':
  1459. X            Check_already( c, &Short_format );
  1460. X            break;
  1461. X        case 'X':
  1462. X            Check_already( c, &Xpert );
  1463. X#    ifdef DEBUG
  1464. X            Setup_test();
  1465. X            Tailor_names();
  1466. X#    else
  1467. X            Diemsg( "-X not allowed" );
  1468. X#    endif DEBUG
  1469. X            break;
  1470. X        case '+':
  1471. X            /**************************************
  1472. X             [+[n]] set Delay to n
  1473. X             **************************************/
  1474. X            Check_already( c, &Delay );
  1475. X            if( Optarg ){
  1476. X                Delay = atoi( Optarg );
  1477. X            }
  1478. X            if( Delay == 0 ){
  1479. X                Delay = 30;
  1480. X            }
  1481. X            break;
  1482. X        default:
  1483. X            Usemsg();
  1484. X            exit(1);
  1485. X        }
  1486. X    }
  1487. X    for(; Optind < argc; ++Optind ){
  1488. X        arg = argv[Optind];
  1489. X        Parms[Parmcount].str = arg;
  1490. X        if( isdigit( *arg ) ){
  1491. X            Parms[Parmcount].num = atoi( arg );
  1492. X        } else {
  1493. X            Parms[Parmcount].num = -1;
  1494. X        }
  1495. X        ++Parmcount;
  1496. X        if( Parmcount >= MAXPARMS ){
  1497. X            Diemsg( "Too many arguments" );
  1498. X        }
  1499. X    }
  1500. X    /*
  1501. X     * pick up the default printer name
  1502. X     */
  1503. X    Get_Printer(0);
  1504. X}
  1505. X
  1506. static
  1507. Check_already( c, v )
  1508. X    int c;
  1509. X    int *v;
  1510. X{
  1511. X    if( *v ){
  1512. X        Usemsg();
  1513. X        Diemsg( "-%c has already been specified", c);
  1514. X    }
  1515. X    *v = 1;
  1516. X}
  1517. X
  1518. Usemsg()
  1519. X{
  1520. X    (void)fprintf(stderr,
  1521. X    "use: lpq [-Pprinter] [-alX] [+[n]] [-Dn] (job# | user)*\n");
  1522. X}
  1523. X
  1524. X/***************************************************************************
  1525. X * Display_all()
  1526. X * 1. get the printer list
  1527. X * 2. for each printer in the list call Displayq
  1528. X ***************************************************************************/
  1529. X
  1530. Display_all()
  1531. X{
  1532. X    char **list;
  1533. X
  1534. X    for( list = All_printers(); *list; ++list ){
  1535. X        Printer = *list;
  1536. X        Displayq();
  1537. X    }
  1538. X}
  1539. X/***************************************************************************
  1540. X * cleanup()
  1541. X * remove the temp files
  1542. X ***************************************************************************/
  1543. X
  1544. cleanup()
  1545. X{
  1546. X    Term_finish();
  1547. X    exit( 1 );
  1548. X}
  1549. END_OF_FILE
  1550. if test 8037 -ne `wc -c <'src/lpq.c'`; then
  1551.     echo shar: \"'src/lpq.c'\" unpacked with wrong size!
  1552. fi
  1553. # end of 'src/lpq.c'
  1554. fi
  1555. if test -f 'src/lpr_job.c' -a "${1}" != "-c" ; then 
  1556.   echo shar: Will not clobber existing file \"'src/lpr_job.c'\"
  1557. else
  1558. echo shar: Extracting \"'src/lpr_job.c'\" \(9221 characters\)
  1559. sed "s/^X//" >'src/lpr_job.c' <<'END_OF_FILE'
  1560. X/***************************************************************************
  1561. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1562. X ***************************************************************************
  1563. X * MODULE: lpr_job.c
  1564. X * Submit job in the spool directory
  1565. X ***************************************************************************
  1566. X * Revision History: Created Sat Jan 30 18:11:41 CST 1988
  1567. X * $Log:    lpr_job.c,v $
  1568. X * Revision 3.2  88/06/24  17:55:45  papowell
  1569. X * MODS for VAX 4.3BSD UNIX
  1570. X * 
  1571. X * Revision 3.1  88/06/18  09:34:57  papowell
  1572. X * Version 3.0- Distributed Sat Jun 18 1988
  1573. X * 
  1574. X * Revision 2.1  88/05/09  10:09:19  papowell
  1575. X * PLP: Released Version
  1576. X * 
  1577. X * Revision 1.6  88/05/06  07:08:11  papowell
  1578. X * Modified getwd() call so that a setreuid() is done first.  This way there
  1579. X * are no problems with root perms on different systems.
  1580. X * 
  1581. X * Revision 1.5  88/05/05  20:07:24  papowell
  1582. X * Minor changes to shut up lint.
  1583. X * 
  1584. X * Revision 1.4  88/04/06  12:08:06  papowell
  1585. X * Minor change, the 'A'printer control line not put in control file.
  1586. X * This allows the existing version to send control files to older versions.
  1587. X * 
  1588. X * Revision 1.3  88/03/25  15:00:35  papowell
  1589. X * Debugged Version:
  1590. X * 1. Added the PLP control file first transfer
  1591. X * 2. Checks for MX during file transfers
  1592. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1593. X *     apparently they open files and then assume that they will stay
  1594. X *     open.
  1595. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1596. X * 
  1597. X * Revision 1.2  88/03/11  19:28:08  papowell
  1598. X * Minor Changes, Updates
  1599. X * 
  1600. X * Revision 1.1  88/03/01  11:08:49  papowell
  1601. X * Initial revision
  1602. X * 
  1603. X ***************************************************************************/
  1604. X#ifndef lint
  1605. static char id_str1[] =
  1606. X    "$Header: lpr_job.c,v 3.2 88/06/24 17:55:45 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  1607. X#endif lint
  1608. X
  1609. X#include "lpr.h"
  1610. X
  1611. char *Make_link();
  1612. char *Full_path();
  1613. extern char *getwd();
  1614. X
  1615. X
  1616. X/***************************************************************************
  1617. X * Make_job()
  1618. X * 1. Get a control file (actually a temp file)
  1619. X * 2. Write the header information into the file
  1620. X * 3. If you have a filter output, queue that
  1621. X * 4. otherwise if you have a simple file, queue that
  1622. X * 5. otherwise copy all of the files 
  1623. X ***************************************************************************/
  1624. X
  1625. Make_job()
  1626. X{
  1627. X    char *cf;            /* control file name */
  1628. X    FILE *cfp;            /* control file fp */
  1629. X    int fd;                /* data file fd */
  1630. X    int i, c;            /* ACME Integers, Inc. */
  1631. X    long j, jobsize;    /* jobsize is a long */
  1632. X    char *s;            /* ACME Pointers, Inc. */
  1633. X    struct stat f_stat, c_stat;    /* source and copy files status */
  1634. X
  1635. X    /*
  1636. X     * get the control file
  1637. X     */
  1638. X    jobsize = 0;
  1639. X    cf = Get_cf();
  1640. X    i = Open_SD( cf );
  1641. X    if( (cfp = fdopen( i, "w")) == NULL ){
  1642. X        logerr_die( XLOG_INFO, "Make_job: IMPOSSIBLE- fdopen failed %s",cf);
  1643. X    }
  1644. X    /*
  1645. X     * place in the time
  1646. X     */
  1647. X    (void)sprintf( WHENSP, "%lu", (unsigned long)time( (time_t *)0 ));
  1648. X    /*
  1649. X     * Put entries in for each character in the Parms list
  1650. X     */
  1651. X    for( i = 'A'; i <= 'Z'; ++i ){
  1652. X        s = CFparm[i-'A'];
  1653. X        if( s[0] ){
  1654. X            Entry( i, s, cfp );
  1655. X        }
  1656. X    }
  1657. X    /* set the job name to the first file if not specified */
  1658. X    if( Parmcount == 0 ){
  1659. X        Entry( 'N', "(stdin)", cfp );
  1660. X        if( JOBNAME[0] == 0 ){
  1661. X            Entry( 'J', "(stdin)", cfp );
  1662. X        }
  1663. X    } else {
  1664. X        for( i = 0; i < Parmcount; ++i ){
  1665. X            if( Parms[i].str ){
  1666. X                Entry( 'N', Parms[i].str, cfp );
  1667. X                if( JOBNAME[0] == 0 ){
  1668. X                    Entry( 'J', Parms[i].str, cfp );
  1669. X                    JOBNAME[0] = 'X';
  1670. X                }
  1671. X            }
  1672. X        }
  1673. X    }
  1674. X    /* set the class name to the priority if not specified */
  1675. X    if( CLASSNAME[0] == 0 ){
  1676. X        CLASSNAME[0] = Priority;
  1677. X        CLASSNAME[1] = 0;
  1678. X        Entry( 'C', CLASSNAME, cfp );
  1679. X    }
  1680. X    /*
  1681. X     * put out the created files or copy the ones passed
  1682. X     * First find if there are any.
  1683. X     */
  1684. X    s = Filter_out? Filter_out : Read_stdin;
  1685. X    if( s ){
  1686. X        Get_stat( SD, s, &f_stat );
  1687. X        j = (f_stat.st_size + 1023) / 1024;
  1688. X        for( c = 0; c == 0 || c < Copies; ++c ){
  1689. X            Entry( Format, s, cfp );
  1690. X            jobsize += j;
  1691. X            if( MX && jobsize > MX ){
  1692. X                Diemsg( "job too large. split up" );
  1693. X            }
  1694. X            Entry( 'U', s, cfp );
  1695. X        }
  1696. X    } else {
  1697. X        /*
  1698. X         * we create an entry for each file in the list
  1699. X         */
  1700. X        for( i = 0; i < Parmcount; ++i ){
  1701. X            if( Parms[i].str ){
  1702. X                /*
  1703. X                 * repeat the check for printability
  1704. X                 */
  1705. X                if( (fd = Is_printable( Parms[i].str, &f_stat )) < 0 ){
  1706. X                    fatal(XLOG_CRIT, "Make_job: file %s become bad, %s@%s",
  1707. X                        Parms[i].str, Person, Host );
  1708. X                }
  1709. X                if( Use_links ){
  1710. X                    /*
  1711. X                      * try to make a symbolic link to the file
  1712. X                     */
  1713. X                    s = Make_link(Parms[i].str, &c_stat );
  1714. X                } else {
  1715. X                    /*
  1716. X                      * make a copy in the spool directory
  1717. X                     */
  1718. X                    s = Copy_file( fd, Parms[i].str, &c_stat);
  1719. X                }
  1720. X                (void)strcpy(Parms[i].filename, s);
  1721. X                (void)close(fd);
  1722. X                if( f_stat.st_size != c_stat.st_size ){
  1723. X                    fatal(XLOG_CRIT,"Make_job: file %s changed, %s@%s",
  1724. X                        Parms[i].str, Person, Host );
  1725. X                }
  1726. X                Parms[i].size = (f_stat.st_size + 1023)/1024;
  1727. X                if(Debug>4)log(XLOG_DEBUG,"Make_job: %s -> %s, %d",
  1728. X                    Parms[i].str, Parms[i].filename, Parms[i].size );
  1729. X            }
  1730. X        }
  1731. X        for( c = 0; c == 0 || c < Copies; ++c ){
  1732. X            for( i = 0; i < Parmcount; ++i ){
  1733. X                if( Parms[i].str ){
  1734. X                    Entry( Format, Parms[i].filename, cfp );
  1735. X                    jobsize += Parms[i].size;
  1736. X                    if( MX && jobsize > MX ){
  1737. X                        Diemsg( "job too large (over %ldK). split up", jobsize);
  1738. X                    }
  1739. X                }
  1740. X            }
  1741. X        }
  1742. X        /*
  1743. X         * Remove the file after we have used it
  1744. X         */
  1745. X        for( i = 0; i < Parmcount; ++i ){
  1746. X            if( Parms[i].str ){
  1747. X                Entry( 'U', Parms[i].filename, cfp );
  1748. X                if( Remove && Use_links == 0 ){
  1749. X                    /* set the EUID to user */
  1750. X                    Set_uid( getuid() );
  1751. X                    if( unlink( Parms[i].str ) < 0 ){
  1752. X                        Warnmsg( "could not remove %s- %s",Parms[i].str,
  1753. X                            Errormsg(errno) );
  1754. X                    }
  1755. X                    Clear_uid();
  1756. X                }
  1757. X            }
  1758. X        }
  1759. X    }
  1760. X    /*
  1761. X     * flush the control file and rename it
  1762. X     */
  1763. X    if( fflush( cfp ) == EOF ){
  1764. X        logerr_die(XLOG_INFO, "cannot flush %s", cf );
  1765. X    }
  1766. X    if( fclose( cfp ) == EOF ){
  1767. X        logerr_die(XLOG_INFO, "cannot close %s", cf );
  1768. X    }
  1769. X    Rename_cf(cf);
  1770. X}
  1771. X
  1772. X/***************************************************************************
  1773. X * Entry( char c; char *cp; FILE *fp )
  1774. X * Prints a line out in the control file
  1775. X ***************************************************************************/
  1776. XEntry( c, cp, fp )
  1777. X    int c;
  1778. X    char *cp;
  1779. X    FILE *fp;
  1780. X{
  1781. X    int d;
  1782. X
  1783. X    d = 0;
  1784. X    if(Debug>4)log(XLOG_DEBUG,"Entry: %c '%s'", c, cp );
  1785. X    if( strlen( cp ) > MAXPARMLEN ){
  1786. X        d = cp[MAXPARMLEN];
  1787. X        cp[MAXPARMLEN] = 0;
  1788. X    }
  1789. X    if( fprintf( fp, "%c%s\n", c, cp ) == EOF ){
  1790. X        logerr_die( XLOG_INFO, "error while writing control file" );
  1791. X    }
  1792. X    if( d ){
  1793. X        cp[MAXPARMLEN] = d;
  1794. X    }
  1795. X}
  1796. X
  1797. X
  1798. X/***************************************************************************
  1799. X * Make_link( char *target, struct stat *statb )
  1800. X * makes a link to the target, and puts out entry
  1801. X ***************************************************************************/
  1802. static char *
  1803. Make_link( target, statb )
  1804. X    char *target;
  1805. X    struct stat *statb;
  1806. X{
  1807. X#ifdef NOSYMLINK
  1808. X    fatal( XLOG_INFO, "no symbolic links allowed" );
  1809. X#else  NOSYMLINK
  1810. X    char *lf;    /* link file */
  1811. X    char buf[MAXPATHLEN];
  1812. X    uid_t ruid, euid;
  1813. X
  1814. X    euid = geteuid();
  1815. X    /*
  1816. X     * get temp file name
  1817. X     */
  1818. X    lf = Get_tmp_data();
  1819. X    (void)sprintf(buf,"%s/%s", SD, lf );
  1820. X    /*
  1821. X     * generate absolute path name
  1822. X     */
  1823. X    target = Full_path( target );
  1824. X    if(Debug>3)log(XLOG_DEBUG,"Make_link: from %s to %s", buf, target );
  1825. X    Set_daemon();
  1826. X    if( symlink( target, buf ) < 0 ){
  1827. X        logerr_die( XLOG_INFO, "Make_link: symbolic link from %s to %s failed",
  1828. X            buf, target );
  1829. X    }
  1830. X    if( stat( target, statb ) < 0 ){
  1831. X        logerr_die( XLOG_INFO, "Make_link: stat failed '%s'", target );
  1832. X    }
  1833. X    Clear_uid();
  1834. X    return( lf );
  1835. X#endif NOSYMLINK
  1836. X}
  1837. X
  1838. X
  1839. X/***************************************************************************
  1840. X * Get_stat( char * dir, char *file , struct stat *statb)
  1841. X * stat the file in the specified directory
  1842. X ***************************************************************************/
  1843. X
  1844. Get_stat(dir, file, statb )
  1845. X    char *dir;
  1846. X    char *file;
  1847. X    struct stat *statb;        /* status buffer */
  1848. X{
  1849. X    static char buf[BUFSIZ];    /* for holding the pathname */
  1850. X
  1851. X    if( dir && *dir ){
  1852. X        (void)sprintf( buf, "%s/%s", dir, file );
  1853. X    } else {
  1854. X        (void)strcpy( buf, file );
  1855. X    }
  1856. X    if( stat( buf, statb ) < 0 ){
  1857. X        logerr_die( XLOG_INFO, "Get_stat: cannot stat %s", buf );
  1858. X    }
  1859. X    if(Debug>5)log(XLOG_DEBUG,"Get_stat: %s is %ld", buf, statb->st_size );
  1860. X}
  1861. X
  1862. X/***************************************************************************
  1863. X * Get_home()
  1864. X * get the current directory
  1865. X ***************************************************************************/
  1866. static char dir[MAXPATHLEN];
  1867. X
  1868. char *
  1869. Get_home()
  1870. X{
  1871. X    /*
  1872. X     * get current working directory
  1873. X     */
  1874. X    if( dir[0] == 0 ){
  1875. X        Set_uid( getuid() );
  1876. X        if( getwd(dir) == 0 ){
  1877. X            logerr_die(XLOG_INFO, "Get_home: getwd() failed" );
  1878. X        }
  1879. X        Clear_uid();
  1880. X    }
  1881. X    return( dir );
  1882. X}
  1883. X/***************************************************************************
  1884. X * Full_path( char *file )
  1885. X * return the full path name
  1886. X ***************************************************************************/
  1887. X
  1888. static char full[MAXPATHLEN];
  1889. char *
  1890. XFull_path( file )
  1891. X    char *file;
  1892. X{
  1893. X    if( file[0] == '/' ){
  1894. X        (void)strcpy( full, file );
  1895. X    } else {
  1896. X        (void)sprintf( full, "%s/%s", Get_home(), file );
  1897. X    }
  1898. X    return( full );
  1899. X}
  1900. END_OF_FILE
  1901. if test 9221 -ne `wc -c <'src/lpr_job.c'`; then
  1902.     echo shar: \"'src/lpr_job.c'\" unpacked with wrong size!
  1903. fi
  1904. # end of 'src/lpr_job.c'
  1905. fi
  1906. echo shar: End of archive 6 \(of 16\).
  1907. cp /dev/null ark6isdone
  1908. MISSING=""
  1909. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  1910.     if test ! -f ark${I}isdone ; then
  1911.     MISSING="${MISSING} ${I}"
  1912.     fi
  1913. done
  1914. if test "${MISSING}" = "" ; then
  1915.     echo You have unpacked all 16 archives.
  1916.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1917. else
  1918.     echo You still need to unpack the following archives:
  1919.     echo "        " ${MISSING}
  1920. fi
  1921. ##  End of shell archive.
  1922. exit 0
  1923.  
  1924.