home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / planner / part01 / plan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-23  |  4.9 KB  |  209 lines

  1.  
  2. /*    THIS IS THE UNPUBLISHED SOURCE CODE OF REMBO        */
  3. /*    The copyright notice above does not evidence any       */
  4. /*    actual or intended publication of such source code.    */
  5. /*    So, use it if you like, but give me credit.        */
  6.  
  7.  
  8. /*     Usage: plan [-f file_name] program_name            */
  9.  
  10.  
  11. /*    Description:                    */
  12.  
  13. /*     This program takes the full pathname of an    */
  14. /*     executable and runs it on a fifo in the     */
  15. /*    user's home directory named .plan.  This    */
  16. /*     way, when finger is executed, the output    */
  17. /*     of the program goes to the fifo.        */
  18.     
  19. /*    Written by:  Tony Rems                 */
  20.  
  21. /*     Send bugs and flames to /dev/null or         */
  22. /*     rembo@unisoft.com                 */
  23.  
  24. /*    Modifications:                    */
  25.  
  26. /*    September 1991                    */
  27. /*           (by Geoff Loker geoff@mdms.moore.com)    */
  28. /*    Modified the program so that the path to the    */
  29. /*    .plan file is not hardcoded in.  Now any number    */
  30. /*    of users can use the program at the same time.    */
  31. /*    I also modified the program to use an optional    */
  32. /*    argument to specify which file to use.  The    */
  33. /*    default file used is still the user's .plan,    */
  34. /*    but this can now also be used to set up        */
  35. /*    .signatures or any other file the user wants.    */
  36.  
  37. /*    Even more modifications                */
  38.  
  39. /*    January 1992                    */
  40. /*          (by Karen Bruner napalm@ugcs.caltech.edu) */
  41. /*    Added pid_deal function, so people can stick    */
  42. /*     the program in their .login, and then have it    */
  43. /*    killed by their .logout.  Program will not    */
  44. /*    run if a .planpid file, the file with the PID    */
  45. /*    for plan, already exists in the user's home    */
  46. /*    directory.                    */
  47.  
  48. #include <sys/types.h>
  49. #include <sys/file.h>
  50. #include <stdio.h>
  51. #include <fcntl.h>
  52. #include <sys/stat.h>
  53. #include <signal.h>
  54. #include <string.h>
  55.  
  56. /* Defines */
  57. #define PERMS 0666
  58. #define USAGE "%s [-f file_name] program_name\n"
  59.  
  60. /* Function prototypes */
  61. void sig_handler();
  62. int pid_deal();    
  63.  
  64. main (argc, argv)
  65. int argc;
  66. char *argv[];
  67. {
  68.         int c, fflg;
  69.     char *file;
  70.         extern char *optarg;
  71.     extern int optind;
  72.     int fd;
  73.     int pid;
  74.     int status;
  75.     char *getenv(), *home, plan[256], *strcat(), *strcpy();
  76.     int pid_check;
  77.     
  78.     fflg = c = 0;
  79.     while ((c = getopt(argc, argv, "f:")) != EOF) {
  80.       file = optarg;
  81.       fflg++;
  82.     }
  83.  
  84. /* Comment out the next line if you don't want to have PID recorded
  85.    to file .planpid */
  86.  
  87.     pid_check = pid_deal(); /* check for .planpid, if none, write
  88.                    .planpid */
  89.  
  90. /* Uncomment next line if you commented out previous line */
  91.  
  92. /*  pid_check = 1; */
  93.  
  94.   if (pid_check == 1)  /* execute remaining part of program if .planpid
  95.               does not exist, i.e., no other plan process is
  96.               running */
  97.     {
  98.     if (fflg)
  99.       strcpy(plan, file);
  100.     else {
  101.       home = getenv("HOME");
  102.       strcpy(plan, home);
  103.       strcat(plan, "/.plan");
  104.     }
  105. /*    setenv("PLAN", plan, 1); */
  106.  
  107.     if ( argc != optind + 1 ) {
  108.         fprintf (stderr, USAGE, argv[0]);
  109.         exit(1);
  110.     }  /* if */
  111.  
  112. /* Catch interrupts for cleanup */
  113.     signal(SIGTERM, sig_handler);
  114.     signal(SIGINT, sig_handler);
  115.     signal(SIGHUP, sig_handler);
  116.  
  117.     unlink (plan);
  118.  
  119. /* Make the fifo */
  120.     if ((mknod(plan, S_IFIFO | PERMS, 0)) < 0 ) {
  121.         perror("mknod");
  122.         exit(2);
  123.     }  /* if */
  124.  
  125.     while (1) {
  126.         if ((fd = open(plan, O_WRONLY)) < 0 ) {
  127.             perror("open");
  128.             exit(3);
  129.         } /* if */
  130.  
  131. /* Once our open completes we know that someone else has
  132.  * opened the FIFO for reading, so we can know run our 
  133.  * program on it.  So, we fork, exec our program and
  134.  * wait for the child to complete.
  135.  */
  136.         switch (pid = fork()) {
  137.             case -1:
  138.                 perror("fork");
  139.                 exit(4);
  140.                 break;
  141.             case 0:
  142. /* If we're in the child, we copy our fifo to stdout */
  143. /* and exec the program given */
  144.                 dup2(fd, 1);
  145.                 execlp(argv[optind],argv[optind],(void *)NULL);
  146.                 perror("child returned");
  147.                 exit(5);
  148.                 break;
  149.             default:
  150. /* If we're in the parent, we close the pipe and wait */
  151.                 close(fd);
  152.                 while (wait(&status) != pid)
  153.                     ;
  154.                 break;
  155.         } /* switch */
  156.         sleep(2);
  157.         close(fd);
  158.     } /* while */
  159.     }  /* end of my if (pid_check... */
  160.  
  161.   else
  162.     printf("plan already running\n");
  163.  
  164. } /* main */
  165.  
  166. void sig_handler()  /* cleanup */
  167. {
  168.     char *plan, *getenv();
  169.     
  170.     plan = getenv("PLAN");
  171.  
  172.     unlink(plan);
  173.     exit(0);
  174. }
  175.  
  176. int pid_deal()    /* function for recording pid and making sure process
  177.            isn't already running */
  178. {
  179.   char savepid[100];    /* string for file name */
  180.   FILE *sp;
  181.   int checker;        /* return value:  0 if .planpid exists, and
  182.                program shouldn't be run, 1 if not */
  183.   char *home;
  184.  
  185.   home = getenv("HOME");        /* put save name for file */
  186.   strcpy(savepid, home);        /* in savepid */
  187.   strcat(savepid, "/.planpid");
  188.  
  189.   if ((sp = fopen(savepid, "r")) != NULL) /* test for existence of 
  190.                          .planpid by trying to open
  191.                          the file for reading */
  192.     checker = 0;     /* return a zero if read was successful, i.e.,
  193.                file already exists */
  194.     
  195.   else
  196.     checker = 1;    /* file doesn't exist, return a 1 to execute
  197.                the rest of the program */
  198.   fclose(sp);
  199.  
  200.   if (checker == 1)
  201.     {
  202.       sp = fopen(savepid, "w");
  203.       fprintf(sp, "%d", getpid());     /* puts PID for plan into file */
  204.       fclose(sp);
  205.     }
  206.  
  207.   return checker;
  208.