home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part05 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-12  |  10.9 KB  |  426 lines

  1. /* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. static char *usage_str =
  6. #ifdef SUNTOOL 
  7.     "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-t] [-s subject] [users]\n";
  8. #else
  9. #ifdef CURSES
  10.     "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  11. #else
  12.     "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
  13. #endif /* CURSES */
  14. #endif /* SUNTOOL */
  15.  
  16. #if defined(sun) && defined(M_DEBUG)
  17. cpu()
  18. {
  19.     print("CPU time limit exceeded!\n");
  20. }
  21. #endif /* sun && DEBUG */
  22.  
  23. /*ARGSUSED*/   /* we ignore envp */
  24. main(argc, argv)
  25. char **argv;
  26. {
  27.     u_long         flg = NO_FLG;
  28.     int            n, source_rc = TRUE;
  29.     char         f_flags[10], buf[256], *Cc = NULL, *Subj = NULL;
  30.     register char  *p;
  31.     char      **args;
  32.  
  33.     if (prog_name = rindex(*argv, '/'))
  34.     prog_name++;
  35.     else
  36.     prog_name = *argv;
  37.  
  38.     (void) signal(SIGBUS,  bus_n_seg);
  39.     (void) signal(SIGSEGV, bus_n_seg);
  40.  
  41.     f_flags[0] = 0;
  42.     mailfile = "";
  43.  
  44. #if defined(sun) && defined(M_DEBUG)
  45.     (void) signal(SIGXCPU, cpu);
  46.  
  47.     if (p = getenv("MALLOC_DEBUG"))
  48.     malloc_debug(atoi(p));
  49.     else
  50.     malloc_debug(0);
  51. #endif /* sun && debug */
  52.  
  53.     if (!isatty(0))
  54.     turnon(glob_flags, REDIRECT);
  55.     f_flags[0] = '\0';
  56.  
  57.     n = 0; /* don't ignore no such file or directory */
  58.     p = getpath(COMMAND_HELP, &n);
  59.  
  60.     if (n) {
  61.     fprintf(stderr, "Warning: can't read %s: %s\n", COMMAND_HELP, p);
  62.     cmd_help = "cmd_help";
  63.     } else
  64.     strdup(cmd_help, p);
  65.  
  66.     init(); /* must be done before checking mail since "login" is set here */
  67.     strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  68.  
  69.     n = FALSE;
  70. #ifdef SUNTOOL
  71.     if (n = istool = strlen(prog_name) > 3 &&
  72.          !strcmp(prog_name+strlen(prog_name)-4, "tool"))
  73.     turnon(glob_flags, DO_SHELL);
  74. #endif /* SUNTOOL */
  75.  
  76.     /*
  77.      * preparse the command line to determine whether or not we're going
  78.      * to bail out after checking that the user has no mail.  Also, check
  79.      * to see if we're going to run a tool because it must be built first.
  80.      */
  81.     if (!istool && argc > 1) {
  82.     for (args = argv+1; *args && args[0][0] == '-'; args++)
  83.         switch (args[0][1]) {
  84. #ifdef SUNTOOL
  85.         case 'T' :
  86.             if (args[1])
  87.             args++;
  88.         case 't' :
  89.             istool = 1;
  90.             n = TRUE;
  91.             turnon(glob_flags, DO_SHELL);
  92.             break;
  93. #endif /* SUNTOOL */
  94.         case 'S' : turnon(glob_flags, DO_SHELL);
  95.         case 'f' :
  96.         case 'u' :
  97.             if (args[1])
  98.             args++;
  99.             n = TRUE;
  100.             break;
  101.         case 'c' :
  102.         case 's' :
  103.         case '1' :
  104.         case '2' :
  105.             if (args[1])
  106.             args++;
  107.         default : ;
  108.         }
  109.     if (*args) {  /* unused args indicates sending mail to someone */
  110.         n = TRUE;
  111.         if (!istool)
  112.         turnon(glob_flags, IS_SENDING);
  113.     }
  114.     }
  115.  
  116. #ifdef SUNTOOL
  117.     /* even if not running tool mode parse all potential suntools args out */
  118.     args = DUBL_NULL;
  119.     tool_parse_all(&argc, argv, &args, prog_name);
  120. #endif /* SUNTOOL */
  121.  
  122.     /* check for any mail at all and exit if we're not continuing */
  123.     if (!n) {
  124.     struct stat statb;
  125.     if (stat(spoolfile, &statb) || statb.st_size == 0) {
  126.         printf("No mail for %s.\n", login);
  127.         exit(0);
  128.     }
  129.     }
  130.  
  131.     for (++argv; *argv && **argv == '-'; argv++)
  132.     switch (argv[0][1]) {
  133.         case 'e':
  134.         /*
  135.          * don't set tty modes -- e.g. echo and cbreak modes aren't
  136.          * changed.
  137.          */
  138.         turnon(glob_flags, ECHO_FLAG);
  139. #ifdef CURSES
  140.         when 'C':
  141.         /* don't init curses -- don't even set iscurses.   */
  142.         if (istool) {
  143.             puts("-C: You are already running in tool mode");
  144.             turnoff(glob_flags, PRE_CURSES);
  145.         } else if (hdrs_only)
  146.             puts("headers only: ignoring -C flag");
  147.         else
  148.             turnon(glob_flags, PRE_CURSES);
  149. #endif /* CURSES */
  150.         when 'N':
  151.         (void) strcat(f_flags, "-N ");
  152.         when 'r':
  153.         (void) strcat(f_flags, "-r "); /* folder() argument */
  154.         when 'H':
  155.         if (istool) {
  156.             puts("running in tool-mode; -H option ignored.");
  157.             break;
  158.         }
  159.         turnoff(glob_flags, PRE_CURSES);
  160.         if (*(hdrs_only = (*argv)+2) != ':')
  161.             hdrs_only = ":a";
  162.         (void) strcat(f_flags, "-N -r "); /* read only cuz no updates */
  163.         when 'i':
  164.         /* force interactive even if !isatty(0) */
  165.         turnoff(glob_flags, REDIRECT);
  166.         when 'u': /* specify a user's mailbox */
  167.         if (*mailfile)
  168.             puts("You can't specify more than one mailbox"), exit(1);
  169.         strdup(mailfile, sprintf(buf, "%s/%s",
  170.                    MAILDIR, (argv[1])? argv[1] : "root"));
  171.         if (argv[1])
  172.             ++argv;
  173.         when 'f':
  174.         if (*mailfile)
  175.             puts("You can't specify more than one mailbox"), exit(1);
  176.         if (argv[1])
  177.             strdup(mailfile, *++argv);
  178.         else
  179.             strdup(mailfile, "&");
  180.         when '1':
  181.         if (argv[1])
  182.             strdup(cmd_help, *++argv);
  183.         else
  184.             puts("-1 \"filename\""), exit(1);
  185. #ifdef SUNTOOL
  186.         when '2':
  187.         if (argv[1])
  188.             strdup(tool_help, *++argv);
  189.         else
  190.             puts("-2 \"filename\""), exit(1);
  191. #endif /* SUNTOOL */
  192.         when 's':
  193.         if (istool)
  194.             puts("bad option when run as a tool"), exit(1);
  195.         else if (argv[1])
  196.             Subj = *++argv;
  197.         else
  198.             puts("-s \"subject\""), exit(1);
  199.         when 'c':
  200.         if (istool)
  201.             puts("bad option when run as a tool"), exit(1);
  202.         else if (argv[1])
  203.             Cc = *++argv;
  204.         else
  205.             puts("-c \"cc list\""), exit(1);
  206.         break;
  207. #ifdef VERBOSE_ARG
  208.         case 'v':
  209.         if (istool)
  210.             puts("bad option when run as a tool"), exit(1);
  211.         turnon(flg, VERBOSE);
  212.         break;
  213. #endif /* VERBOSE_ARG */
  214. #ifdef SUNTOOL
  215.             case 'T':
  216.         if ((time_out = atoi(*argv)) <= 29)
  217.             time_out = 30;
  218.         /* -T implies -t */
  219.         case 't': istool = 1;
  220. #endif /* SUNTOOL */
  221.         case 'S': turnon(glob_flags, DO_SHELL);
  222.         when 'n': source_rc = FALSE;
  223.         when 'd': debug = 1;
  224.         otherwise:
  225.         print("%s: unknown option: `%c'\n", prog_name,
  226.             argv[0][1]? argv[0][1] : '-');
  227.         print(usage_str, prog_name);
  228.     }
  229.  
  230.     if (source_rc) {
  231.     (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  232.     (void) source(0, DUBL_NULL);
  233.     }
  234.  
  235.     set_cwd();  /* call _after_ sourcing files */
  236.  
  237. #ifdef SUNTOOL
  238.     if (istool)
  239.     if (ison(glob_flags, REDIRECT))
  240.         puts("You can't redirect input to a tool."), exit(1);
  241.     else
  242.         make_tool(args), turnon(glob_flags, DO_SHELL);
  243. #endif /* SUNTOOL */
  244.  
  245.     /* now we're ready for I/O */
  246.     if (isoff(glob_flags, REDIRECT)) {
  247.     /* make sure we can always recover from no echo mode */
  248.     (void) signal(SIGINT, catch);
  249.     (void) signal(SIGQUIT, catch);
  250.     if (istool)
  251.         turnon(glob_flags, ECHO_FLAG);
  252.     savetty();
  253. #ifdef TIOCGLTC
  254.     if (isatty(0) && ioctl(0, TIOCGLTC, <chars))
  255.         error("TIOCGLTC");
  256. #endif /* TIOCGLTC */
  257. #ifdef SIGCONT
  258.     (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  259. #endif /* SIGCONT */
  260.     /* echo_off() checks to see if echo_flg is set, so don't worry */
  261.     echo_off();
  262.     }
  263.  
  264.     if (!istool && *argv) { /* we could check IS_SENDING */
  265.     char recipients[BUFSIZ];
  266.     (void) argv_to_string(recipients, argv);
  267.     fix_up_addr(recipients);
  268.     if (Cc && *Cc)
  269.         fix_up_addr(Cc);
  270.     /* prompt for subject and Cc list, but not "To: "
  271.      * mail_someone() already takes care of redirection.
  272.      * if -s or -c options are given, they will be passed.
  273.      */
  274.     if (do_set(set_options, "ask"))
  275.         turnon(flg, NEW_SUBJECT);
  276.     if (do_set(set_options, "autosign"))
  277.         turnon(flg, SIGN);
  278.     if (do_set(set_options, "autoedit"))
  279.         turnon(flg, EDIT);
  280.     if (do_set(set_options, "verbose"))
  281.         turnon(flg, VERBOSE);
  282.     if (do_set(set_options, "fortune"))
  283.         turnon(flg, DO_FORTUNE);
  284.     /* set now in case user is not running shell, but is running debug */
  285.     (void) signal(SIGCHLD, sigchldcatcher);
  286.     if (!setjmp(jmpbuf))
  287.         (void) mail_someone(recipients, Subj, Cc, flg, NULL);
  288.     /* do shell set from above: "mush -S user" perhaps */
  289.     if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  290.         if (isoff(glob_flags, REDIRECT))
  291.         echo_on();
  292.         exit(0);
  293.     }
  294.     }
  295.     turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  296.  
  297.     if (ison(glob_flags, REDIRECT)) {
  298.     puts("You can't redirect input unless you're sending mail.");
  299.     puts("If you want to run a shell with redirection, use \"-i\"");
  300.     cleanup(0);
  301.     }
  302.     if (!*mailfile) {
  303.     strdup(mailfile, spoolfile);
  304.     if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  305.         /* we know it's not the spool file here */
  306.         printf("No mail in %s.\n", mailfile);
  307.         echo_on(), exit(0);
  308.     }
  309.     }
  310.  
  311.     if (!hdrs_only) {
  312.     /* catch will test DO_SHELL and try to longjmp if set.  this is a
  313.      * transition state from no-shell to do-shell to ignore sigs to
  314.      * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  315.      */
  316.     turnon(glob_flags, IGN_SIGS);
  317. #ifdef CURSES
  318.     if (ison(glob_flags, PRE_CURSES))
  319.         (void) curses_init(0, DUBL_NULL);
  320.     turnoff(glob_flags, PRE_CURSES);
  321. #endif /* CURSES */
  322.     }
  323.  
  324.     /* find a free tmpfile */
  325.     if (!(p = do_set(set_options, "home")) || !*p)
  326. alted:
  327.     p = ALTERNATE_HOME;
  328.     flg = getpid();
  329.     while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, flg++), F_OK))
  330.     ;
  331.     /* just create the file, make sure it's empty.  It'll close later and
  332.      * be reopened for reading only.
  333.      */
  334.     {
  335.     int omask = umask(077);
  336.     tmpf = fopen(tempfile, "w");
  337.     (void) umask(omask);
  338.     if (!tmpf) {
  339.         if (p != ALTERNATE_HOME)
  340.         goto alted;
  341.         error("Can't create tempfile %s", tempfile);
  342.         cleanup(0);
  343.     }
  344.     }
  345.  
  346.     /* do pseudo-intelligent stuff with certain signals */
  347.     (void) signal(SIGINT,  catch);
  348.     (void) signal(SIGQUIT, catch);
  349.     (void) signal(SIGHUP,  catch);
  350.  
  351.     if (!hdrs_only && !istool && !do_set(set_options, "quiet"))
  352.     printf("%s: Type '?' for help.\n", VERSION);
  353.  
  354.     (void) sprintf(buf, "folder %s %s", f_flags, mailfile);
  355.     if (argv = make_command(buf, TRPL_NULL, &argc)) {
  356.     if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL))
  357.         turnoff(glob_flags, IGN_SIGS), cleanup(0);
  358.     free_vec(argv);
  359.     }
  360.  
  361.     if (hdrs_only) {
  362.     (void) sprintf(buf, "headers %s", hdrs_only);
  363.     if (argv = make_command(buf, TRPL_NULL, &argc))
  364.         (void) do_hdrs(argc, argv, NULL);
  365.     cleanup(0);
  366.     }
  367.  
  368.     turnon(glob_flags, DO_SHELL);
  369.     if (istool && msg_cnt)
  370.     set_isread(current_msg);
  371.  
  372. #ifdef SUNTOOL
  373.     if (istool) {
  374.     n = 0;
  375.     p = getpath(TOOL_HELP, &n);
  376.     if (n) {
  377.         fprintf(stderr, "Warning: can't read %s: %s\n", TOOL_HELP, p);
  378.         tool_help = "tool_help";
  379.     } else
  380.         strdup(tool_help, p);
  381.     if (time_out < 30)
  382.         time_out = 60;
  383.     turnoff(glob_flags, IGN_SIGS);
  384.     (void) do_hdrs(0, DUBL_NULL, NULL);
  385.     timerclear(&(mail_timer.it_interval));
  386.     timerclear(&(mail_timer.it_value));
  387.     mail_timer.it_value.tv_sec = time_out;
  388.     setitimer(ITIMER_REAL, &mail_timer, NULL);
  389.     (void) signal(SIGALRM, check_new_mail);
  390.     unlock_cursors();
  391.     while (!(tool->tl_flags & TOOL_DONE))
  392.         tool_select(tool, 1);
  393.     cleanup(0);
  394.     }
  395. #endif /* SUNTOOL */
  396.     do_loop();
  397. }
  398.  
  399. do_version()
  400. {
  401.     print("%s\n", VERSION);
  402.     return -1;
  403. }
  404.  
  405. /* set the current working directory */
  406. set_cwd()
  407. {
  408.     char buf[MAXPATHLEN], cwd[MAXPATHLEN];
  409. #ifndef SYSV
  410.     extern char *getwd();
  411. #else /* SYSV */
  412.     extern char *getcwd();
  413. #endif /* SYSV */
  414.  
  415. #ifndef SYSV
  416.     if (getwd(cwd) == NULL)
  417. #else
  418.     if (getcwd(cwd, MAXPATHLEN) == NULL)
  419. #endif /* SYSV */
  420.     {
  421.     error("getcwd: %s", cwd);
  422.     (void) un_set(&set_options, "cwd");
  423.     } else
  424.     (void) cmd_line(sprintf(buf, "set cwd=\"%s\"", cwd), msg_list);
  425. }
  426.