home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / lp-onionskin / lp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-24  |  2.3 KB  |  127 lines

  1. #ifndef LINT
  2. static char SccsId[] = "@(#)lp.c    1.2 U of T Physics 12/16/87";
  3. #endif
  4.  
  5. /*
  6.  * This is an onionskin around the lp spooler.
  7.  * The problem is that the standard lp(1) uses lockfiles, with
  8.  * the well-known window of vulnerability between testing for
  9.  * the existence of the file and trying to create it.
  10.  * Thus, we have moved the standard lp command to "real_lp",
  11.  * and this program becomes "lp".
  12.  * It uses a semaphore to lock and unlock jobs sent to lp.
  13.  *        David Harrison - Dec/87
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <signal.h>
  18.  
  19. char *real_lp_cmd = "real_lp";
  20.  
  21. char *progname;
  22.  
  23. main(argc, argv)
  24. int argc;
  25. char *argv[];
  26. {
  27.     void _exit(), perror();
  28.     char *emalloc();
  29.     char *strcpy(), *strcat();
  30.     char **exec_argv;
  31.     int pid, w, status;
  32.     int (*istat)(), (*qstat)();
  33.     int i;
  34.  
  35.     progname = argv[0];
  36.  
  37.     /*
  38.      * put arguments from argv into exec_argv, terminating
  39.      * with a null.
  40.      *
  41.      * First malloc the array size needed ( with one for the NULL
  42.      * and the end).
  43.      */
  44.     exec_argv = 
  45.         (char **) emalloc( (unsigned) ((argc + 1) * sizeof (char *) ));
  46.     /*
  47.      * Put real_lp_cmd in argv[0]
  48.      */
  49.     exec_argv[0] = emalloc( (unsigned) (strlen(real_lp_cmd) + 1) );
  50.     (void) strcpy(exec_argv[0], real_lp_cmd);
  51.     /*
  52.      * Now the other argements
  53.      */
  54.     if( argc > 1) {
  55.         for(i = 1; i < argc; i++) {
  56.             exec_argv[i] = emalloc( (unsigned) (strlen(argv[i]) + 1 ));
  57.             (void) strcpy(exec_argv[i], argv[i]);
  58.         }
  59.     }
  60.     /*
  61.      * Terminate with a NULL
  62.      */
  63.     exec_argv[argc] = NULL;
  64.  
  65.     lockproc();
  66.  
  67.     switch( (pid = fork()) ) {
  68.  
  69.         case -1:
  70.             unlockproc();
  71.             Sys_Error("Can't fork\n");
  72.             break;
  73.  
  74.         case 0:
  75.             execvp( real_lp_cmd , exec_argv );
  76.             unlockproc();
  77.             fprintf(stderr,"%s: can't exec %s\n", 
  78.                 progname, real_lp_cmd );
  79.             perror("exec");
  80.             _exit(127);
  81.  
  82.         default:
  83.             break;
  84.             
  85.     }
  86.  
  87.     /*
  88.      * Trap signals and wait for child to finish.
  89.      */
  90.     istat = signal(SIGINT, SIG_IGN);
  91.     qstat = signal(SIGQUIT, SIG_IGN);
  92.     while( (w = wait(&status)) != pid && w != -1)
  93.         ;
  94.     if( w == -1)
  95.         status = -1;
  96.     signal(SIGINT, istat);
  97.     signal(SIGQUIT, qstat);
  98.  
  99.     unlockproc();
  100.             
  101.     return status;
  102.  
  103. }
  104.  
  105. char *
  106. emalloc(n)
  107. unsigned n;
  108. {
  109.     char *p, *malloc();
  110.  
  111.     p = malloc(n);
  112.     if ( p == 0)
  113.         Sys_Error("Out of memory");
  114.     return p;
  115. }
  116.  
  117. Sys_Error(s)
  118. char *s;
  119. {
  120.     void exit(), perror();
  121.  
  122.     fprintf(stderr,"%s: %s\n",progname, s);
  123.     perror("terminating");
  124.     exit(1);
  125.  
  126. }
  127.