home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / vcron.t.Z / vcron.t / VCRON / do_command.c < prev    next >
Text File  |  1988-11-15  |  6KB  |  234 lines

  1. /* $Source: /usr/src/local/vix/cron/do_new.c,v $
  2.  * $Revision: 1.5 $
  3.  * $Log:    do_new.c,v $
  4.  * Revision 1.5  88/04/20  21:02:00  ram
  5.  * OSK-Version. 100% rewrite
  6.  *
  7.  * Revision 1.4  87/05/02  17:33:35  paul
  8.  * baseline for mod.sources release
  9.  * 
  10.  * Revision 1.3  87/04/09  00:03:58  paul
  11.  * improved data hiding, locality of declaration/references
  12.  * fixed a rs@mirror bug by redesigning the mailto stuff completely
  13.  * 
  14.  * Revision 1.2  87/03/19  12:46:24  paul
  15.  * implemented suggestions from rs@mirror (Rich $alz):
  16.  *    MAILTO="" means no mail should be sent
  17.  *    various fixes of bugs or lint complaints
  18.  *    put a To: line in the mail message
  19.  * 
  20.  * Revision 1.1  87/01/26  23:47:00  paul
  21.  * Initial revision
  22.  */
  23.  
  24. /* Copyright 1988 by ram
  25.  * All rights reserved
  26.  *
  27.  * Distribute freely, except: don't sell it, don't remove my name from the
  28.  * source or documentation (don't take credit for my work), mark your changes
  29.  * (don't get me blamed for your possible bugs), don't alter or remove this
  30.  * notice.  Commercial redistribution is negotiable; contact me for details.
  31.  *
  32.  * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
  33.  * I'll try to keep a version up to date.  I can be reached as follows:
  34.  * Paul Vixie, Vixie Enterprises, 329 Noe Street, San Francisco, CA, 94114,
  35.  * (415) 864-7013, {ucbvax!dual,ames,ucsfmis,lll-crg,sun}!ptsfa!vixie!paul.
  36.  */
  37.  
  38. #include "cron.h"
  39. #include <signal.h>
  40. # include <modes.h>
  41. # include <types.h>
  42. # include <time.h>
  43. # include <info.h>
  44.  
  45. extern int    os9forkc(),os9exec();
  46. extern char    **environ,*getenv(),*index();
  47.  
  48. void
  49. do_command(cmd, u)
  50.     char    *cmd;
  51.     user    *u;
  52. {
  53.     REG int    child;
  54.     char    *ag[2];
  55.     extern char    *env_get();
  56.  
  57. #if DEBUGGING
  58.     Debug(DPROC, "do_command(%s, (%s,%d,%d))\n",
  59.         cmd, env_get(USERENV, u->envp), u->uid, u->gid);
  60. #endif
  61.  
  62.     setuid ((u->gid << 16) | u->uid);
  63.  
  64.     /*
  65.      * set uid of user and fork first vcron with enviroment of user.
  66.      * wait for first vcron to terminate.
  67.      */
  68.  
  69.     ag[0] = "*";    /* first child ...*/
  70.     ag[1] = cmd;    /* the command ...*/
  71.     ag[2] = NULL;
  72.     child = os9exec(os9forkc, PROGNAME, ag, u->envp, 0, 0, 0);
  73.  
  74. #if DEBUGGING
  75.     Debug(DPROC, "[%d] child process forked\n", child);
  76. #endif
  77.  
  78.     wait(0);
  79.     set_cron_uid();    /* finish, get back to work    */
  80.  
  81. #if DEBUGGING
  82.     Debug(DPROC, "[%d] main process returning to work\n", getpid());
  83. #endif
  84. }
  85.  
  86. void
  87. do_1th_child(argc,argv)
  88. int    argc;
  89. char    **argv;
  90. {
  91.  
  92.     argv[0][0] = '?';    /* 2nd child ......    */
  93.  
  94.     os9exec(os9forkc, PROGNAME, argv, environ, 0, 0, 0);
  95.  
  96.     /* no wait cause the 2.nd fork should run independly from
  97.      * master cron ! i.e. create a artificial zombie.
  98.      * return as fast as you can ...
  99.      */
  100. }
  101.  
  102. void
  103. do_2nd_child(argc,argv)
  104. int    argc;
  105. char    **argv;
  106. {
  107.     REG int    mailit;
  108.     REG char    *input;
  109.     int    need_newline = FALSE,escaped = FALSE;
  110.     char    *ag[2];
  111.     char    *shell = getenv("SHELL");
  112.     REG char    *x = shell;
  113.     unsigned int    status;
  114.     int    child;
  115.     time_t    zeit;
  116.     char    mailpath[MAX_FNAME];    /* place for exec-path to mail */
  117.  
  118.     while (*x && (!isspace (*x))) ++x;
  119.     *x = '\0';
  120.  
  121.     chdir(getenv("HOME"));
  122.     chxdir(getenv("XDIR"));
  123.  
  124.     if( argv[1][0] == '-') {    /* oops we got a mail request    */
  125.         mailit = TRUE;
  126.         argv[1]++;
  127.     } else    mailit = FALSE;
  128.  
  129.     creat("/nil", S_IREAD | S_IWRITE);
  130.     dup(0); dup(0);
  131.     if(mailit) {
  132.         /*
  133.          * we have to mail, so open an input-pipe for the mailer,
  134.          * and mail to USER. if MAILTO is defined send mail to that
  135.          * name, if fork failes, ignore mail-request.
  136.          */
  137.         close(0);
  138.         creat("/pipe", S_IREAD | S_IWRITE);
  139.         setbuf(stdin, NULL);
  140.         ag[0] = "/h0/etc/cmds/smail";    /* default mailer    */
  141.         if( info_str("smail", mailpath, MAX_FNAME)) ag[0] = mailpath;
  142.         if( !((x = getenv("MAILTO")) && *x)) x = getenv("USER");
  143.         ag[1] = x;
  144.         ag[2] = NULL;
  145.         mailit = os9exec(os9forkc, ag[0], ag, environ, 0, 0, 3);
  146.         if( mailit < 0) {
  147.             close(0); dup(1);
  148.             mailit = FALSE;
  149.         } else {
  150.             close(1); dup(0);    /* this is for the benefit */
  151.             close(0); dup(2);    /* of the next os9forkc()  */
  152.             close(2); dup(1);    /* 0 -->1,2 & 1,2 --> 0    */
  153.         }
  154.         puts("From VCron-DAEMON");
  155.         puts(MAILSUBJ);
  156.         puts("---");
  157.     }
  158.     if (input = index(argv[1], '%')) {
  159.  
  160.         /* % found.  replace with a null (remember, we're a forked
  161.          * process and the string won't be reused), and increment
  162.          * input to point at the following character.
  163.          */
  164.         *input++ = '\0';
  165.     }
  166.     if( input) {
  167.         /*
  168.          * we are creating path 0 since we were forked with no
  169.          * open pathes. open a unnamed pipe with a sufficient
  170.          * size for holding the entire input string !
  171.          * then write the input-string out and do the %-->CR
  172.          * translation.
  173.          * NOTICE: this path must be closed after (!!) forking the
  174.          *       command to signal EOF !
  175.          */
  176.         close(0);
  177.         create("/pipe", S_ISIZE | S_IREAD | S_IWRITE, S_IREAD |
  178.             S_IWRITE, strlen(input)+1);
  179.         while (*input)
  180.         {
  181.             if (!escaped && *input == '%')
  182.             {
  183.                 need_newline = FALSE;
  184.                 write( 0, "\n", 1);
  185.             }
  186.             else
  187.             {
  188.                 need_newline = TRUE;
  189.                 write( 0, input, 1);
  190.                 escaped = (*input == '\\');
  191.             }
  192.             input++;
  193.         }
  194.         if (need_newline)
  195.             write( 0, "\n", 1);
  196.         
  197.     }
  198.     ag[0] = shell;
  199.     ag[1] = argv[1];    /* do even shell-scripts    */
  200.     ag[2] = NULL;
  201.  
  202.     child = os9exec(os9forkc, shell, ag, environ,0,0,3);
  203.     close(0);    /* remember: we have to close it, to signal EOF */
  204.  
  205.     time(&zeit);
  206.     x = (char *) ctime(&zeit);
  207.     x[ strlen(x) - 1] = '\0';
  208.     /*
  209.      * we have several cases:
  210.      *    - child couldn't be forked, notifiy it to the mailer and
  211.      *      close the pipes to signal him a EOF and wait for mailer
  212.      *      to die.
  213.      *    - mailer dies first (OOPS). so close the output-pipes to
  214.      *      allow child to die and wait for it.
  215.      *    - child dies first. notify starting-ending time and return
  216.      *      status of child to mailer. that should be normal.
  217.      */
  218.     if(mailit) {
  219.         if( wait(&status) != child) {
  220.             close(1); close(2);
  221.             wait(&status);
  222.         } 
  223.         time(&zeit);
  224.         if( child >0) {
  225.             printf("\n---\ncommand[%d]: '%s'\nrunning between %s ",child,
  226.                 argv[1], x);
  227.             printf("and %sfinished with status %d.\n", ctime( &zeit), (unsigned short) status);
  228.         } else
  229.             printf("\n---\ncommand '%s'\ncouldn't be forked at %s",argv[1],x);
  230.     }
  231.     fflush(stdout);    /* flush buffers, we are finished    */
  232.     close(1); close(2);
  233. }
  234.