home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume12 / cake / part03 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-10-14  |  9.6 KB  |  537 lines

  1. /*
  2. **    Cake main file.
  3. */
  4.  
  5. static    char
  6. rcs_id[] = "$Header: /mip/zs/src/sys/cake/RCS/main.c,v 1.15 87/10/05 20:14:53 zs Exp $";
  7.  
  8. #include    "cake.h"
  9. #include    <pwd.h>
  10. #include    <signal.h>
  11. #include    <sys/stat.h>
  12.  
  13. typedef    struct    passwd    Pwent;
  14. typedef    struct    stat    Stat;
  15.  
  16. int    Gflag = FALSE;
  17. int    Lflag = FALSE;
  18. int    Rflag = FALSE;
  19. int    Xflag = FALSE;
  20. int    Zflag = FALSE;
  21. int    bflag = FALSE;
  22. int    cflag = FALSE;
  23. int    dflag = FALSE;
  24. int    gflag = FALSE;
  25. int    iflag = FALSE;
  26. int    kflag = TRUE;
  27. int    nflag = FALSE;
  28. int    qflag = FALSE;
  29. int    rflag = FALSE;
  30. int    sflag = FALSE;
  31. int    tflag = FALSE;
  32. int    vflag = FALSE;
  33. int    wflag = FALSE;
  34. int    xflag = FALSE;
  35. int    zflag = FALSE;
  36.  
  37. char    *cakefile  = NULL;
  38. char    *shellfile[2] = { SYSTEM_CMD, SCRIPT_CMD };
  39. char    *metachars = METACHARS;
  40. int    maxprocs   = 1;
  41. List    *active_procs;
  42. char    scratchbuf[128];
  43.  
  44. int    cakedebug    = FALSE;
  45. int    entrydebug    = FALSE;
  46. int    patdebug    = FALSE;
  47. int    lexdebug    = FALSE;
  48.  
  49. char    cakeflagbuf[MAXSIZE];
  50. char    *cppargv[MAXARGS];
  51. int    cppargc = 0;
  52.  
  53. main(argc, argv)
  54. int    argc;
  55. char    **argv;
  56. {
  57.     extern        cake_abort(), cake_finish();
  58.     extern    int    parse_args(), process_args();
  59.     extern    Node    *chase();
  60.     extern    char    *getenv();
  61.     extern    char    *dir_setup();
  62.     extern    Pwent    *getpwuid();
  63.     extern    int    geteuid();
  64.     extern    FILE    *cake_popen();
  65.     extern    FILE    *yyin;
  66.     extern    int    yydebug;
  67.     Stat        statbuf;
  68.     int        envc;
  69.     char        *envv[MAXARGS];
  70.     reg    Pwent    *pwent;
  71.     reg    char    *envstr;
  72.     reg    int    status;
  73.     reg    Node    *rootnode;
  74.  
  75.     signal(SIGINT,  cake_finish);
  76.     signal(SIGQUIT, cake_finish);
  77.     signal(SIGILL,  cake_abort);
  78.     signal(SIGTRAP, cake_abort);
  79.     signal(SIGIOT,  cake_abort);
  80.     signal(SIGEMT,  cake_abort);
  81.     signal(SIGFPE,  cake_abort);
  82.     signal(SIGBUS,  cake_abort);
  83.     signal(SIGSEGV, cake_abort);
  84.     signal(SIGSYS,  cake_abort);
  85.     signal(SIGPIPE, cake_abort);
  86.     signal(SIGALRM, cake_abort);
  87.  
  88.     yydebug = FALSE;
  89.     active_procs = makelist0();
  90.  
  91.     if (rindex(argv[0], 'f') != NULL
  92.     &&  streq(rindex(argv[0], 'f'), "fake"))
  93.         cakedebug = TRUE;
  94.  
  95.     init_sym();
  96.     cppargv[cppargc++] = new_name(CPP);
  97.     strcpy(cakeflagbuf, "-DCAKEFLAGS=");
  98.  
  99.     if ((envstr = getenv("CAKE")) != NULL)
  100.     {
  101.         envc = parse_args(envstr, envv);
  102.         process_args(envv, &envc, 0);
  103.         if (envc > 0)
  104.             fprintf(stderr, "cake: non-options in environment ignored\n");
  105.     }
  106.  
  107.     argv += process_args(argv, &argc, 1);
  108.  
  109. #ifdef    CAKEDEBUG
  110.     if (cakedebug || entrydebug || patdebug || lexdebug)
  111.         setlinebuf(stdout);
  112. #endif
  113.  
  114.     if (cakefile == NULL)
  115.     {
  116.         if (stat("cakefile", &statbuf) == 0)
  117.             cakefile = "cakefile";
  118.         or (stat("Cakefile", &statbuf) == 0)
  119.             cakefile = "Cakefile";
  120.         or (stat("recipe", &statbuf) == 0)
  121.             cakefile = "recipe";
  122.         or (stat("Recipe", &statbuf) == 0)
  123.             cakefile = "Recipe";
  124.         else
  125.         {
  126.             fprintf(stderr, "cake: cannot locate a cakefile\n");
  127.             exit(1);
  128.         }
  129.     }
  130.  
  131.     if (gflag)
  132.         cakefile = dir_setup(cakefile);
  133.  
  134.     pwent = getpwuid(geteuid());
  135.     strcpy(scratchbuf, "-I");
  136.     strcat(scratchbuf, pwent->pw_dir);
  137.     strcat(scratchbuf, ULIB);
  138.     cppargv[cppargc++] = new_name(scratchbuf);
  139.     strcpy(scratchbuf, "-I");
  140.     strcat(scratchbuf, SLIB);
  141.     cppargv[cppargc++] = new_name(scratchbuf);
  142.     cppargv[cppargc++] = cakeflagbuf;
  143.     cppargv[cppargc++] = cakefile;
  144.     cppargv[cppargc]   = NULL;
  145.  
  146.     if (cakedebug)
  147.     {
  148.         reg    int    i;
  149.  
  150.         for (i = 0; i < cppargc; i++)
  151.             printf("%s\n", cppargv[i]);
  152.     }
  153.  
  154.     if ((yyin = cake_popen(cppargv, "r")) == NULL)
  155.     {
  156.         fprintf(stderr, "cake: cannot open cpp filter\n");
  157.         exit(1);
  158.     }
  159.  
  160.     if (Zflag)
  161.     {
  162.         reg    int    c;
  163.  
  164.         while ((c = getc(yyin)) != EOF)
  165.             putchar(c);
  166.  
  167.         cake_pclose(yyin);
  168.         exit(0);
  169.     }
  170.  
  171.     yyinit();
  172.     init_entry();
  173.     if (yyparse())
  174.     {
  175.         fprintf(stderr, "cake: cannot parse %s\n", cakefile);
  176.         exit(1);
  177.     }
  178.  
  179.     shell_setup(shellfile[0], 0);
  180.     shell_setup(shellfile[1], 1);
  181.     meta_setup(metachars);
  182.  
  183.     cake_pclose(yyin);
  184.     dir_start();
  185.     prep_entries();
  186.     final_entry(argc, argv);
  187.  
  188.     rootnode = chase(CHASEROOT, 0, (Entry *) NULL);
  189.  
  190.     if (! qflag)
  191.         execute(rootnode);
  192.     
  193.     dir_finish();
  194.     cleanup();
  195. #ifdef    STATS_FILE
  196.     statistics();
  197. #endif
  198.  
  199.     status = (off_node(rootnode, nf_ERR) && is_ok(rootnode))? 0: 1;
  200.     cdebug("exit status %d\n", status);
  201.     exit(status);
  202. }
  203.  
  204. int
  205. process_args(vector, count, base)
  206. reg    char    **vector;
  207. reg    int    *count;
  208. reg    int    base;
  209. {
  210.     reg    int    i, j;
  211.  
  212.     j = 0;
  213.     cdebug("process args:");
  214.     while (*count > base && vector[base][0] == '-')
  215.     {
  216.         putflag(base, vector[base]);
  217.  
  218.         for (i = 1; vector[base][i] != '\0'; i++)
  219.         {
  220.             switch (vector[base][i])
  221.             {
  222.  
  223. #ifdef    CAKEDEBUG
  224.         when 'C':    cdebug(" -C");
  225.                 cakedebug  = ! cakedebug;
  226.         
  227.         when 'E':    cdebug(" -E");
  228.                 entrydebug = ! entrydebug;
  229.         
  230.         when 'P':    cdebug(" -P");
  231.                 patdebug   = ! patdebug;
  232.         
  233.         when 'W':    cdebug(" -W");
  234.                 lexdebug   = TRUE;
  235.         
  236.         when 'Y':    cdebug(" -Y");
  237.                 yydebug    = TRUE;
  238. #endif
  239.         when 'G':    cdebug(" -G");
  240.                 Gflag = TRUE;
  241.         
  242.         when 'L':    cdebug(" -L");
  243.                 Lflag = TRUE;
  244.         
  245.         when 'R':    cdebug(" -R");
  246.                 Rflag = TRUE;
  247.         
  248.         when 'X':    cdebug(" -X");
  249.                 Xflag = TRUE;
  250.         
  251.         when 'Z':    cdebug(" -Z");
  252.                 Zflag = TRUE;
  253.         
  254.         when 'a':    cdebug(" -a");
  255.                 kflag = FALSE;
  256.         
  257.         when 'b':    cdebug(" -b");
  258.                 bflag = TRUE;
  259.         
  260.         when 'c':    cdebug(" -c");
  261.                 cflag = TRUE;
  262.         
  263.         when 'd':    cdebug(" -d");
  264.                 dflag = TRUE;
  265.         
  266.         when 'g':    cdebug(" -g");
  267.                 gflag = TRUE;
  268.         
  269.         when 'i':    cdebug(" -i");
  270.                 iflag = TRUE;
  271.         
  272.         when 'k':    cdebug(" -k");
  273.                 kflag = TRUE;
  274.         
  275.         when 'n':    cdebug(" -n");
  276.                 nflag = TRUE;
  277.                 tflag = FALSE;
  278.                 qflag = FALSE;
  279.         
  280.         when 'q':    cdebug(" -q");
  281.                 qflag = TRUE;
  282.                 nflag = FALSE;
  283.                 tflag = FALSE;
  284.         
  285.         when 'r':    cdebug(" -r");
  286.                 rflag = TRUE;
  287.         
  288.         when 's':    cdebug(" -s");
  289.                 sflag = TRUE;
  290.         
  291.         when 't':    cdebug(" -t");
  292.                 tflag = TRUE;
  293.                 nflag = FALSE;
  294.                 qflag = FALSE;
  295.         
  296.         when 'v':    cdebug(" -v");
  297.                 vflag = TRUE;
  298.         
  299.         when 'w':    cdebug(" -w");
  300.                 wflag = TRUE;
  301.         
  302.         when 'x':    cdebug(" -x");
  303.                 xflag = TRUE;
  304.         
  305.         when 'z':    cdebug(" -z");
  306.                 zflag = TRUE;
  307.         
  308.         when 'D':
  309.         case 'I':
  310.         case 'U':    if (i != 1)
  311.                     usage();
  312.  
  313.                 cdebug(" %s", vector[base]);
  314.                 cppargv[cppargc++] = new_name(vector[base]);
  315.                 goto nextword;
  316.         
  317.         when 'N':    putflag(base, vector[base+1]);
  318.                 sscanf(vector[base+1], "%d", &maxprocs);
  319.                 if (vector[base][i+1] != '\0')
  320.                     usage();
  321.  
  322.                 cdebug(" -N %d", maxprocs);
  323.                 (*count)--;
  324.                 vector++, j++;
  325.                 goto nextword;
  326.         
  327.         when 'S':    putflag(base, vector[base+1]);
  328.                 if (vector[base][i+1] == '1')
  329.                     shellfile[0] = new_name(vector[base+1]);
  330.                 or (vector[base][i+1] == '2')
  331.                     shellfile[1] = new_name(vector[base+1]);
  332.                 else
  333.                     usage();
  334.  
  335.                 if (vector[base][i+2] != '\0')
  336.                     usage();
  337.  
  338.                 cdebug(" -S%c %s", vector[base][i+1], vector[base+1]);
  339.                 (*count)--;
  340.                 vector++, j++;
  341.                 goto nextword;
  342.         
  343.         when 'T':    putflag(base, vector[base+1]);
  344.                 metachars = new_name(vector[base+1]);
  345.                 if (vector[base][i+1] != '\0')
  346.                     usage();
  347.  
  348.                 cdebug(" -T %s", metachars);
  349.                 (*count)--;
  350.                 vector++, j++;
  351.                 goto nextword;
  352.         
  353.         when 'f':    putflag(base, vector[base+1]);
  354.                 cakefile = new_name(vector[base+1]);
  355.                 if (vector[base][i+1] != '\0')
  356.                     usage();
  357.  
  358.                 cdebug(" -f %s", cakefile);
  359.                 (*count)--;
  360.                 vector++, j++;
  361.                 goto nextword;
  362.  
  363.         otherwise:    usage();
  364.             }
  365.         }
  366.  
  367. nextword:
  368.         (*count)--;
  369.         vector++, j++;
  370.     }
  371.  
  372.     cdebug(" \n%return %d\n", j);
  373.     return j;
  374. }
  375.  
  376. /*
  377. **    Put a flag into the CAKEFLAGS definition.
  378. */
  379.  
  380. putflag(base, flag)
  381. reg    int    base;
  382. reg    char    *flag;
  383. {
  384.     if (base == 1)
  385.     {
  386.         strcat(cakeflagbuf, " ");
  387.         strcat(cakeflagbuf, flag);
  388.         if (strlen(cakeflagbuf) >= MAXSIZE)
  389.         {
  390.             fprintf(stderr, "cake: CAKEFLAGS too long\n");
  391.             exit(1);
  392.         }
  393.     }
  394. }
  395.  
  396. /*
  397. **    Tell the unfortunate user how to use cake.
  398. */
  399.  
  400. usage()
  401. {
  402.     fprintf(stderr, "Usage: cake [-abcdgiknqrstvwxzGLRXZ] [-ffile]\n");
  403.     fprintf(stderr, "       [-Ddefn] [-Idir] [-Uname] [-S shell] [-T metachars] [file ...]\n");
  404.     exit(1);
  405. }
  406.  
  407. exit_cake(needtrail)
  408. reg    int    needtrail;
  409. {
  410.     if (cakedebug && needtrail)
  411.         get_trail(stdout);
  412.     else
  413.         dir_finish();
  414.  
  415.     exit(1);
  416. }
  417.  
  418. /*
  419. **    Handle bus errors and segmentation violations.
  420. */
  421.  
  422. cake_abort()
  423. {
  424.  
  425.     signal(SIGINT,  SIG_IGN);
  426.     signal(SIGQUIT, SIG_IGN);
  427.  
  428.     printf("Abort on signal\n");
  429.     if (cakedebug)
  430.         get_trail(stdout);
  431.  
  432.     signal(SIGQUIT, SIG_DFL);
  433.     kill(getpid(), SIGQUIT);
  434. }
  435.  
  436. /*
  437. **    Handle user interrupts.
  438. */
  439.  
  440. cake_finish()
  441. {
  442.     reg    List    *ptr;
  443.     reg    Proc    *proc;
  444.  
  445.     signal(SIGINT,  SIG_IGN);
  446.     signal(SIGQUIT, SIG_IGN);
  447.  
  448.     printf("*** Interrupt\n");
  449.     fflush(stdout);
  450.     for_list (ptr, active_procs)
  451.     {
  452.         proc = (Proc *) ldata(ptr);
  453.         if (proc->pr_node != NULL)
  454.             cake_error(proc->pr_node);
  455.     }
  456.  
  457.     exit_cake(FALSE);
  458. }
  459.  
  460. #ifdef    STATS_FILE
  461. #ifdef    ATT
  462. #include    <sys/times.h>
  463.  
  464. typedef    struct    tms    Tms;
  465. #else
  466. #include    <sys/time.h>
  467. #include    <sys/resource.h>
  468.  
  469. typedef    struct    rusage    Rusage;
  470. #endif
  471.  
  472. statistics()
  473. {
  474.     extern    char    *getlogin();
  475.     extern        getpw();
  476.     extern    int    out_tried, out_found;
  477.     extern    int    stat_tried, stat_found;
  478.     FILE        *sfp;
  479.  
  480.     if ((sfp = fopen(STATS_FILE, "a")) != NULL)
  481.     {
  482. #ifdef    ATT
  483.         Tms    tbuf;
  484. #else
  485.         Rusage    s, c;
  486. #endif
  487.         long    su, ss, cu, cs;
  488.         char    *usr;
  489.  
  490.         if ((usr = getlogin()) == NULL)
  491.         {
  492.             char    buf[256];
  493.             char    *usr_end;
  494.  
  495.             if (getpw(getuid(), buf) != 0)
  496.                 usr = "NULL";
  497.             else
  498.             {
  499.                 usr = buf;
  500.                 if ((usr_end = index(usr, ':')) != NULL)
  501.                     *usr_end = '\0';
  502.                 else
  503.                     usr = "NULL";
  504.             }
  505.  
  506.             usr = new_name(usr);
  507.         }
  508.  
  509. #ifdef    ATT
  510.         if (times(&tbuf) == -1)
  511.         {
  512.             fclose(sfp);
  513.             return;
  514.         }
  515.  
  516.         su = tbuf.tms_utime*100/TIMERES;
  517.         ss = tbuf.tms_stime*100/TIMERES;
  518.         cu = tbuf.tms_cutime*100/TIMERES;
  519.         cs = tbuf.tms_cstime*100/TIMERES;
  520. #else
  521.         getrusage(RUSAGE_SELF,     &s);
  522.         getrusage(RUSAGE_CHILDREN, &c);
  523.  
  524.         su = s.ru_utime.tv_sec*100 + s.ru_utime.tv_usec/10000;
  525.         ss = s.ru_stime.tv_sec*100 + s.ru_stime.tv_usec/10000;
  526.         cu = c.ru_utime.tv_sec*100 + c.ru_utime.tv_usec/10000;
  527.         cs = c.ru_stime.tv_sec*100 + c.ru_stime.tv_usec/10000;
  528. #endif
  529.         fprintf(sfp, "%s %ld %ld %ld %ld ", usr, su, ss, cu, cs);
  530.         fprintf(sfp, "%d %d %d %d %d\n", sbrk(0),
  531.             out_tried, out_found, stat_tried, stat_found);
  532.  
  533.         fclose(sfp);
  534.     }
  535. }
  536. #endif
  537.