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 / crontab.c < prev    next >
C/C++ Source or Header  |  1988-11-29  |  9KB  |  459 lines

  1. /* $Source: /h0/usr/local/src/crond/crontab.c,v $
  2.  * $Revision: 1.6 $
  3.  * $Log:    crontabnew.c,v $
  4.  * Revision 1.6  88/04/20  20:00:00  ram
  5.  * OSK-version. use of group-file, added edit_cmd-option, usage of Sysinfo
  6.  *
  7.  * Revision 1.5  87/05/02  17:33:22  paul
  8.  * baseline for mod.sources release
  9.  * 
  10.  * Revision 1.4  87/03/31  13:11:48  paul
  11.  * I won't say that rs@mirror gave me this idea
  12.  *   but crontab uses getopt() now
  13.  * 
  14.  * Revision 1.3  87/03/30  23:43:48  paul
  15.  * another suggestion from rs@mirror:
  16.  *   use getpwuid(getuid)->pw_name instead of getenv("USER")
  17.  *   this is a boost to security...
  18.  * 
  19.  * Revision 1.2  87/02/11  17:40:12  paul
  20.  * changed command syntax to allow append and replace instead of append as
  21.  * default and no replace at all.
  22.  * 
  23.  * Revision 1.1  87/01/26  23:49:06  paul
  24.  * Initial revision
  25.  */
  26.  
  27. /* Copyright 1987 by Vixie Enterprises
  28.  * All rights reserved
  29.  *
  30.  * Distribute freely, except: don't sell it, don't remove my name from the
  31.  * source or documentation (don't take credit for my work), mark your changes
  32.  * (don't get me blamed for your possible bugs), don't alter or remove this
  33.  * notice.  Commercial redistribution is negotiable; contact me for details.
  34.  *
  35.  * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
  36.  * I'll try to keep a version up to date.  I can be reached as follows:
  37.  * Paul Vixie, Vixie Enterprises, 329 Noe Street, San Francisco, CA, 94114,
  38.  * (415) 864-7013, {ucbvax!dual,ames,ucsfmis,lll-crg,sun}!ptsfa!vixie!paul.
  39.  */
  40.  
  41.  
  42. #define    MAIN_PROGRAM
  43.  
  44.  
  45. #include "cron.h"
  46. #include <pwd.h>
  47. #include <grp.h>
  48. #include <errno.h>
  49. # include <modes.h>
  50. # include <types.h>
  51. # include <info.h>
  52.  
  53. extern    char    *strcpy();
  54.  
  55. static int    user_id;
  56. static char    n[MAX_FNAME];
  57.  
  58. static char    USER[MAX_UNAME];
  59. static char    FILENAME[MAX_FNAME];
  60. static int    CHECK_ERROR_COUNT;
  61. static int    OPTION;
  62. # define opt_unknown    0
  63. # define opt_list    1
  64. # define opt_delete    2
  65. # define opt_replace    3
  66. # define opt_append    4
  67. # define opt_perm    5
  68. # define opt_edit    6
  69.  
  70. #if DEBUGGING
  71. static char    *OPTIONS[] = {"???", "list", "delete", "replace", "append","show_perm"};
  72. #endif
  73.  
  74. static void
  75. usage()
  76. {
  77.     fprintf(stderr, "usage:  %s [-u<=>user] ...\n", PROGNAME);
  78.     fprintf(stderr, " ... -l     (list user's crontab)\n");
  79.     fprintf(stderr, " ... -d     (delete user's crontab)\n");
  80.     fprintf(stderr, " ... -e     (edit user's crontab)\n");
  81.     fprintf(stderr, " ... -r<=>file  (replace user's crontab)\n");
  82.     fprintf(stderr, " ... -a<=>file  (append file to user's crontab)\n");
  83.     fprintf (stderr," ... -p     (which users have the permission to install a crontab)\n");
  84.     exit(ERROR_EXIT);
  85. }
  86.  
  87.  
  88. void
  89. main(argc, argv)
  90.     int    argc;
  91.     char    *argv[];
  92. {
  93.     int    getuid();
  94.     void    parse_args(), set_cron_uid(),
  95.         list_cmd(), delete_cmd(), replace_cmd(),
  96.         show_permission (),edit_cmd();
  97.     int    append_cmd();
  98.     PROGNAME = argv[0];
  99.     user_id = getuid();
  100.  
  101.     parse_args(argc, argv);
  102.     set_cron_uid();
  103.  
  104.     if(!( info_str("CRONDIR",n, MAX_FNAME))) strcpy(n, SPOOLDIR);
  105.     strcat(n, "/");
  106.     strcat(n, USER);
  107.  
  108.     switch (OPTION)
  109.     {
  110.     case opt_list:        list_cmd();
  111.                 break;
  112.     case opt_delete:    delete_cmd();
  113.                 break;
  114.     case opt_edit:        edit_cmd();
  115.                 unlink(FILENAME);
  116.                 break;
  117.     case opt_replace:    replace_cmd();
  118.                 append_cmd();
  119.                 break;
  120.     case opt_append:    append_cmd();
  121.                 break;
  122.     case opt_perm:        show_permission ();
  123.                 break;
  124.     }
  125. }
  126.  
  127.  
  128. static void
  129. list_cmd()
  130. {
  131.     extern    errno;
  132.     FILE    *f;
  133.     int    ch;
  134.  
  135.     if (!(f = fopen(n, "r")))
  136.     {
  137.         if (errno == E_PNNF)
  138.             fprintf(stderr, "no crontab for %s\n", USER);
  139.         else
  140.             perror(n);
  141.         exit(ERROR_EXIT);
  142.     }
  143.  
  144.     /* file it open. copy to stdout, close.
  145.      */
  146.     Set_LineNum(1)
  147.     while (EOF != (ch = get_char(f)))
  148.         putchar(ch);
  149.     fclose(f);
  150. }
  151.  
  152.  
  153. static void
  154. delete_cmd()
  155. {
  156.     extern    errno;
  157.     int    unlink();
  158.     void    poke_daemon();
  159.  
  160.     if (unlink(n))
  161.     {
  162.         if (errno == E_PNNF)
  163.             fprintf(stderr, "no crontab for %s\n", USER);
  164.         else
  165.             perror(n);
  166.         exit(ERROR_EXIT);
  167.     }
  168.     poke_daemon();
  169. }
  170.  
  171.  
  172. static void
  173. replace_cmd()
  174. {
  175.     extern    errno;
  176.     extern    int    unlink();
  177.     void    poke_daemon();
  178.  
  179.     if (unlink(n))
  180.     {
  181.         if (errno != E_PNNF)
  182.         {
  183.             perror(n);
  184.             exit(ERROR_EXIT);
  185.         }
  186.     }
  187. }
  188.  
  189.  
  190. static void
  191. check_error(msg)
  192.     char    *msg;
  193. {
  194.     CHECK_ERROR_COUNT += 1;
  195.     fprintf(stderr, "\"%s\", line %d: %s\n", FILENAME, LINE_NUMBER, msg);
  196. }
  197.  
  198.  
  199. static int
  200. append_cmd()
  201. {
  202.     entry    *load_entry();
  203.     int    load_env();
  204.     void    free_entry();
  205.     void    check_error();
  206.     void    poke_daemon();
  207.  
  208.     char    envstr[MAX_TEMPSTR];
  209.     FILE    *old, *new;
  210.     int    ch;
  211.     entry    *e;
  212.     int    status;
  213.  
  214.     /* this routine is called for both 'replace' and 'append' commands
  215.      */
  216.  
  217.     /* open the new file being installed.
  218.      */
  219.     if (!(new = fopen(FILENAME, "r")))
  220.     {
  221.         perror(FILENAME);
  222.         return(ERROR_EXIT);
  223.     }
  224.  
  225.     /* check the syntax of the file being installed.
  226.      */
  227.  
  228.     /* BUG: was reporting errors after the EOF if there were any errors
  229.      * in the file proper -- kludged it by stopping after first error.
  230.      *        vix 31mar87
  231.      */
  232.     CHECK_ERROR_COUNT = 0;
  233.     while (!CHECK_ERROR_COUNT && ERR != (status = load_env(envstr, new)))
  234.     {
  235.         if (status == FALSE)
  236.         {
  237.             if ((e = load_entry(new, check_error)) != NULL)
  238.                 free((char *) e);
  239.         }
  240.     }
  241.     if (CHECK_ERROR_COUNT != 0)
  242.     {
  243.         fprintf(stderr, "errors in crontab file, can't install.\n");
  244.         fclose(new);
  245.         return(ERROR_EXIT);
  246.     }
  247.     rewind(new);
  248.  
  249.     /* open the old file for append-access.  this depends on the file
  250.      * being created if it does not exist.
  251.      */
  252.  
  253.     if (!(old = fopen(n, "a")))
  254.     {
  255.         perror(n);
  256.         fclose(new);
  257.         return(ERROR_EXIT);
  258.     }
  259.  
  260.     /* append the new to the old
  261.      */
  262.     Set_LineNum(1)
  263.     while (EOF != (ch = get_char(new)))
  264.         putc(ch, old);
  265.  
  266.     /* close them and we're done
  267.      */
  268.     fclose(old);
  269.     fclose(new);
  270.  
  271.     /* set the file to be owned by root
  272.      */
  273.     if (ERR == chown(n, ROOT_UID))
  274.     {
  275.         perror("chown");
  276.         return(ERROR_EXIT);
  277.     }
  278.  
  279.     poke_daemon();
  280.     return(0);
  281. }
  282.  
  283. void
  284. edit_cmd()
  285. {
  286.     extern char    **environ;
  287.     char    *mktemp(),*getenv();
  288.     int    os9exec(), os9forkc();
  289.     int    setuid();
  290.     void    set_cron_uid();
  291.  
  292.     register int    i,j;
  293.     int        ch;
  294.     static char    *tmp[] = { "me", 0, 0 };
  295.  
  296.     if( getenv("EDITOR")) tmp[0] = getenv("EDITOR");
  297.     mktemp(FILENAME);
  298.     tmp[1] = FILENAME;
  299.     if((i = creat(FILENAME, S_IWRITE | S_IREAD)) < 0) {
  300.         perror(FILENAME);
  301.         close(i);
  302.         exit(ERROR_EXIT);
  303.     }
  304.     if(( j = open( n, S_IREAD))  < 0)
  305.         j = creat( n, S_IREAD | S_IWRITE);
  306.     while( read(j, &ch,1) ) write(i, &ch, 1);
  307.     close(i); close(j);
  308.     if (ERR == chown(FILENAME, user_id))
  309.     {
  310.         perror("chown");
  311.         exit(ERROR_EXIT);
  312.     }
  313. again:    unlink(n);
  314.     setuid(user_id);
  315.     os9exec(os9forkc, tmp[0], tmp, environ, 0 ,0 ,3);
  316.     wait(0);
  317.     set_cron_uid();
  318.     while( append_cmd() ) {
  319.         perror("retry to edit crontab-file.");
  320.         sleep(2);
  321.         goto again;
  322.     }
  323. }
  324.  
  325. static void
  326. poke_daemon()
  327. {
  328.     if( info_signal(POKECRON) < 0 )
  329.     {
  330.         perror(POKECRON);
  331.         return;
  332.     }
  333. }
  334.     
  335.  
  336. static void
  337. parse_args(argc, argv)
  338.     int    argc;
  339.     char    *argv[];
  340. {
  341.     void        usage();
  342.     struct passwd    *getpwnam();
  343.     char    *x;
  344.     int    t;
  345.  
  346.     struct passwd    *pw;
  347.     int        argch;
  348.  
  349.     if (!(pw = getpwuid(user_id & 0xffff)))
  350.     {
  351.         fprintf(stderr, "Your UID isn't in the passwd file.\n");
  352.         perror("getpwuid");
  353.     }
  354.     strcpy(USER, pw->pw_name);
  355.     FILENAME[0] = '\0';
  356.     OPTION = opt_unknown;
  357.     for (t=1;t<argc;++t)
  358.         if (*(x = argv[t]) == '-') {
  359.             ++x;
  360.             while (*x) {
  361.                 switch (*x) {
  362.                     case 'x':
  363.                         if (*(x+1) == '=') ++x;
  364.                         if (*x) ++x;
  365.                         if (!*x) x = "ext,sch,proc,pars,misc";
  366.                         if (!set_debug_flags(x))
  367.                             usage();
  368.                         else while (*x) ++x;
  369.                         break;
  370.                     case 'u':
  371.                         if ((user_id & 0xff00) != ROOT_UID) {
  372.                             fprintf(stderr,
  373.                         "must be privileged to use -u\n"
  374.                             );
  375.                             exit(ERROR_EXIT);
  376.                         }
  377.                         if (*(x+1) == '=') ++x;
  378.                         if (*x) ++x;
  379.                         if (getpwnam(x) == (struct passwd *)NULL) {
  380.                             fprintf(stderr, "%s:  user '%s' unknown\n",
  381.                                 PROGNAME, x);
  382.                             exit(ERROR_EXIT);
  383.                         }
  384.                         (void) strcpy(USER, x);
  385.                         while (*x) ++x;
  386.                         break;
  387.                     case 'l':
  388.                         if (OPTION != opt_unknown)
  389.                             usage();
  390.                         OPTION = opt_list;
  391.                         break;
  392.                     case 'p':
  393.                         if (OPTION != opt_unknown)
  394.                             usage();
  395.                         OPTION = opt_perm;
  396.                         break;
  397.                     case 'd':
  398.                         if (OPTION != opt_unknown)
  399.                             usage();
  400.                         OPTION = opt_delete;
  401.                         break;
  402.                     case 'e':
  403.                         if (OPTION != opt_unknown)
  404.                             usage();
  405.                         OPTION = opt_edit;
  406.                         (void) strcpy(FILENAME, "/dd/tmp/crXXXXXX");
  407.                         break;
  408.                     case 'a':
  409.                         if (OPTION != opt_unknown)
  410.                             usage();
  411.                         OPTION = opt_append;
  412.                         if (*(x+1) == '=') ++x;
  413.                         if (*x) ++x;
  414.                         (void) strcpy(FILENAME, x);
  415.                         while (*x) ++x;
  416.                         break;
  417.                     case 'r':
  418.                         if (OPTION != opt_unknown)
  419.                             usage();
  420.                         OPTION = opt_replace;
  421.                         if (*(x+1) == '=') ++x;
  422.                         if (*x) ++x;
  423.                         (void) strcpy(FILENAME, x);
  424.                         while (*x) ++x;
  425.                         break;
  426.                     default:
  427.                         usage();
  428.                 }
  429.                 if (*x) ++x;
  430.             }
  431.         }
  432.     if (OPTION == opt_unknown)
  433.         usage();
  434.  
  435.     endpwent();
  436.  
  437. #if DEBUGGING
  438.     Debug(DMISC, "user=%s, file=%s, option=%s\n",
  439.                     USER, FILENAME, OPTIONS[(int)OPTION]);
  440. #endif
  441. }
  442.  
  443. static void
  444. show_permission ()
  445. {
  446.   struct group    *crongroup;
  447.   char **i;
  448.  
  449.   if(!(crongroup = getgrnam(CRON_GRP))) {
  450.     perror("no group entry for Cron-group\n");
  451.     exit(1);
  452.   }
  453.   
  454.   for( i = crongroup->gr_mem; *i ; i++ )
  455.     printf("%-10s",*i);
  456.   endgrent();
  457.   puts("\n\n");
  458. }
  459.