home *** CD-ROM | disk | FTP | other *** search
/ ftp.freefriends.org / ftp.freefriends.org.tar / ftp.freefriends.org / arnold / Source / mush.rstevens.tar.gz / mush.tar / main.c < prev    next >
C/C++ Source or Header  |  1992-10-30  |  9KB  |  348 lines

  1. /* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #include "options.h"
  5.  
  6. #if defined(sun) && defined(M_DEBUG)
  7. cpu()
  8. {
  9.     print("CPU time limit exceeded!\n");
  10. }
  11. #endif /* sun && DEBUG */
  12.  
  13. #ifdef LCKDFLDIR
  14. extern char *lckdfldir;
  15. #endif /* LCKDFLDIR */
  16.  
  17. #ifdef DOT_LOCK
  18. int sgid;
  19. #ifdef BSD
  20. int rgid;
  21. #endif /* BSD */
  22. #endif /* DOT_LOCK */
  23.  
  24. /*ARGSUSED*/   /* we ignore envp */
  25. main(argc, argv)
  26. int argc;
  27. char *argv[];
  28. {
  29.     int              n;
  30.     char           buf[MAXPATHLEN];
  31.     register char    *p;
  32.     struct mush_flags Flags;
  33.  
  34. #ifndef INTERNAL_MALLOC
  35.     extern char *stackbottom;    /* used by xfree() */
  36.  
  37.     stackbottom = (char *) &argc;
  38. #endif /* INTERNAL_MALLOC */
  39.  
  40. #ifdef AUX
  41.     set42sig();        /* Use 4.2 BSD signal handling conventions */
  42. #endif /* AUX */
  43.  
  44. #ifdef LCKDFLDIR
  45.     lckdfldir = LCKDFLDIR;
  46. #endif /* LCKDFLDIR */
  47.     prog_name = basename(*argv);
  48.  
  49.     (void) signal(SIGBUS,  bus_n_seg);
  50.     (void) signal(SIGSEGV, bus_n_seg);
  51.     (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
  52.  
  53. #if defined(sun) && defined(M_DEBUG)
  54.     (void) signal(SIGXCPU, cpu);
  55.  
  56.     if (p = getenv("MALLOC_DEBUG"))
  57.     malloc_debug(atoi(p));
  58.     else
  59.     malloc_debug(0);
  60. #endif /* sun && debug */
  61.  
  62.     if (!isatty(0))
  63.     turnon(glob_flags, REDIRECT);
  64.     else
  65.     (void) setbuf(stdin, NULL);
  66.  
  67.     init(); /* must be done before checking mail since "login" is set here */
  68.  
  69.     n = preparse_opts(&argc,argv);
  70.  
  71.     /* check for any mail at all and exit if we're not continuing */
  72.     if (!n) {
  73.     struct stat statb;
  74. #ifdef POP3_SUPPORT
  75.     popgetmail(); /*Load mailbox with new mail, if any*/
  76. #endif /* POP3_SUPPORT*/
  77.     if (stat(spoolfile, &statb) || statb.st_size == 0) {
  78.         (void) printf("No mail for %s.\n", login);
  79.         exit(0);
  80.     }
  81.     }
  82.  
  83. #ifdef DOT_LOCK
  84.     sgid = getegid();
  85. #ifdef BSD
  86.     rgid = getgid();
  87.     setregid(sgid, rgid);
  88. #else
  89.     setgid(getgid());
  90. #endif /* BSD */
  91. #endif /* DOT_LOCK */
  92.  
  93.     parse_options(&argv, &Flags);
  94.  
  95.     (void) cmd_line(strcpy(buf, "set cmd_help"), NULL);
  96. #ifdef SUNTOOL
  97.     if (istool)
  98.     (void) cmd_line(strcpy(buf, "set tool_help"), NULL);
  99. #endif /* SUNTOOL */
  100.  
  101.     set_cwd();
  102.  
  103.     if (Flags.init_file)
  104.     (void) cmd_line(sprintf(buf, "source %s", Flags.init_file), msg_list);
  105.     if (Flags.source_rc > 0) {
  106.     /* use cmd_line() in case DEFAULT_RC has expandable chars */
  107.     (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  108.     }
  109.     if (Flags.source_rc > -1)
  110.     (void) source(0, DUBL_NULL);
  111.     mailfile = Flags.folder;
  112.  
  113.     if (*spoolfile != '/') {
  114.     n = 1;
  115.     p = getpath(spoolfile, &n);
  116.     if (n == -1)
  117.         (void) fputs(p, stderr), exit(1);
  118.     else if (n)
  119.         (void) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1);
  120.     else if (*p != '/') {
  121.         /* if it still isn't a full path, make it one */
  122.         char *wd = do_set(set_options, "cwd");
  123.         if (*wd) {
  124.         (void) sprintf(buf, "%s/%s", wd, p);
  125.         strdup(spoolfile, buf);
  126.         } else
  127.         strdup(spoolfile, p);
  128.     } else
  129.         strdup(spoolfile, p);
  130.     }
  131.  
  132. #ifdef SUNTOOL
  133.     if (istool) {
  134.     make_tool();
  135.     turnon(glob_flags, DO_SHELL);
  136.     turnoff(glob_flags, REDIRECT); /* -- SunOS-4.0 has a problem here */
  137.     }
  138. #endif /* SUNTOOL */
  139.  
  140.     /* now we're ready for I/O */
  141.     if (isoff(glob_flags, REDIRECT)) {
  142.     /* make sure we can always recover from no echo mode */
  143.     (void) signal(SIGINT, catch);
  144.     (void) signal(SIGQUIT, catch);
  145.     (void) signal(SIGHUP, catch);
  146.     if (istool || hdrs_only)
  147.         turnon(glob_flags, ECHO_FLAG);
  148.     if (!hdrs_only)
  149.         tty_settings();
  150. #ifdef SIGCONT
  151.     (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  152. #endif /* SIGCONT */
  153.     /* echo_off() checks to see if echo_flg is set, so don't worry */
  154.     echo_off();
  155.     }
  156.  
  157.     if (!istool && ison(glob_flags, IS_SENDING)) {
  158.     char recipients[BUFSIZ], *mailv[16];
  159.     (void) argv_to_string(recipients, argv);
  160.     fix_up_addr(recipients);
  161.     mailv[0] = "mail";
  162.     n = 1;
  163.     if (ison(Flags.flg, VERBOSE))
  164.         mailv[n++] = "-v";
  165.     if (Flags.Subj && *(Flags.Subj)) {
  166.         mailv[n++] = "-s";
  167.         mailv[n++] = Flags.Subj;
  168.     }
  169.     if (Flags.Cc && *(Flags.Cc)) {
  170.         fix_up_addr(Flags.Cc);
  171.         mailv[n++] = "-c";
  172.         mailv[n++] = Flags.Cc;
  173.     }
  174.     if (Flags.Bcc && *(Flags.Bcc)) {
  175.         fix_up_addr(Flags.Bcc);
  176.         mailv[n++] = "-b";
  177.         mailv[n++] = Flags.Bcc;
  178.     }
  179.     if (ison(Flags.flg, NO_SIGN))
  180.         mailv[n++] = "-u";
  181.     if (ison(Flags.flg, SEND_NOW))
  182.         mailv[n++] = "-U";
  183.     if (Flags.draft) {
  184.         if (isoff(Flags.flg, SEND_NOW))
  185.         mailv[n++] = "-E";
  186.         mailv[n++] = "-h";
  187.         mailv[n++] = Flags.draft;
  188.     }
  189.     mailv[n++] = recipients;
  190.     mailv[n] = NULL;
  191.     /* set now in case user is not running shell, but is running debug */
  192.     if (!istool)
  193.         (void) signal(SIGCHLD, sigchldcatcher);
  194.     if (!setjmp(jmpbuf))
  195.         (void) do_mail(n, mailv, msg_list);
  196.     /* do shell set from above: "mush -S user" perhaps */
  197.     if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  198.         if (isoff(glob_flags, REDIRECT))
  199.         echo_on();
  200.         exit(0);
  201.     }
  202.     }
  203.     turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  204.  
  205.     if (ison(glob_flags, REDIRECT)
  206.         && (!Flags.src_file || !Flags.src_n_exit) && !hdrs_only) {
  207.     puts("You can't redirect input unless you're sending mail.");
  208.     puts("If you want to run a shell with redirection, use \"-i\"");
  209.     cleanup(0);
  210.     }
  211.     if (!*mailfile) {
  212.     strdup(mailfile, spoolfile);
  213.     if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  214.         /* we know it's not the spool file here */
  215.         (void) printf("No mail in %s.\n", mailfile);
  216.         echo_on(), exit(0);
  217.     }
  218.     }
  219.  
  220.     if (!hdrs_only) {
  221.     /* catch will test DO_SHELL and try to longjmp if set.  this is a
  222.      * transition state from no-shell to do-shell to ignore sigs to
  223.      * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  224.      */
  225.     turnon(glob_flags, IGN_SIGS);
  226. #ifdef CURSES
  227.     if (ison(glob_flags, PRE_CURSES))
  228.         (void) curses_init(0, DUBL_NULL);
  229.     turnoff(glob_flags, PRE_CURSES);
  230. #endif /* CURSES */
  231.     }
  232.  
  233.     /* find a free tmpfile */
  234.     if (!(p = getdir(do_set(set_options, "tmpdir"))))
  235. alted:
  236.     p = ALTERNATE_HOME;
  237.     {
  238.     int pid = getpid();
  239.     while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK))
  240.     ;
  241.     }
  242.     /* just create the file, make sure it's empty.  It'll close later and
  243.      * be reopened for reading only.
  244.      */
  245.     if (!(tmpf = mask_fopen(tempfile, "w"))) {
  246.     if (strcmp(p, ALTERNATE_HOME))
  247.         goto alted;
  248.     error("Can't create tempfile %s", tempfile);
  249.     cleanup(0);
  250.     }
  251.  
  252.     /* do pseudo-intelligent stuff with certain signals */
  253.     (void) signal(SIGINT,  catch);
  254.     (void) signal(SIGQUIT, catch);
  255.     (void) signal(SIGHUP,  catch);
  256.  
  257.     if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) &&
  258.     !glob(do_set(set_options, "quiet"), "{,{,*[ \\,]}startup{,[ \\,]*}}"))
  259.     (void) printf("%s: Type '?' for help.\n", check_internal("version"));
  260.  
  261.     (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile);
  262.     if ((argv = mk_argv(buf, &argc, TRUE)) && argc > 0) {
  263.     if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) {
  264.         if (iscurses)
  265.         putchar('\n');
  266.         turnoff(glob_flags, IGN_SIGS), cleanup(0);
  267.     }
  268. #ifdef CURSES
  269.     if (iscurses)
  270.         (void) curses_help_msg(TRUE);
  271. #endif /* CURSES */
  272.     free_vec(argv);
  273.     }
  274.  
  275.     if (hdrs_only) {
  276.     (void) mail_status(0);
  277.     (void) sprintf(buf, "headers %s", hdrs_only);
  278.     if (argv = make_command(buf, TRPL_NULL, &argc))
  279.         (void) do_hdrs(argc, argv, NULL);
  280.     cleanup(0);
  281.     }
  282.  
  283.     turnon(glob_flags, DO_SHELL);
  284.  
  285.     /* finally, if the user wanted to source a file to execute, do it now */
  286.     if (Flags.src_file) {
  287.     char *s_argv[2];
  288.     s_argv[1] = Flags.src_file;
  289.     (void) source(2, s_argv);
  290.     if (!istool && Flags.src_n_exit)
  291.         cleanup(0);
  292.     }
  293.  
  294. #ifdef POP3_SUPPORT
  295.     if (time_out < MIN_TIME_OUT)
  296.     time_out = MIN_TIME_OUT;
  297. #endif /* POP3_SUPPORT */
  298. #ifdef SUNTOOL
  299.     if (istool) {
  300.     char buf[16];
  301.     n = 0;
  302. #ifndef POP3_SUPPORT
  303.     if (time_out < MIN_TIME_OUT)
  304.         time_out = MIN_TIME_OUT;
  305. #endif /* POP3_SUPPORT */
  306.     turnoff(glob_flags, IGN_SIGS);
  307.     (void) do_hdrs(0, DUBL_NULL, NULL);
  308.     timerclear(&(mail_timer.it_interval));
  309.     timerclear(&(mail_timer.it_value));
  310.  
  311.     /*  Reload time with value of timeout upon timer expiration. */
  312.     mail_timer.it_interval.tv_sec = time_out;
  313.  
  314.     mail_timer.it_value.tv_sec = time_out;
  315.     (void) notify_set_itimer_func(tool, do_check,
  316.         ITIMER_REAL, &mail_timer, (struct itimerval *) 0);
  317.     timeout_cursors(FALSE);
  318.     window_main_loop(tool);
  319.     cleanup(0);
  320.     }
  321. #endif /* SUNTOOL */
  322.     do_loop();
  323. }
  324.  
  325. do_version()
  326. {
  327.     print("%s\n", check_internal("version"));
  328.     return -1;
  329. }
  330.  
  331. /* set the current working directory */
  332. set_cwd()
  333. {
  334.     char cwd[MAXPATHLEN];
  335.  
  336.     if (GetCwd(cwd, MAXPATHLEN) == NULL) {
  337.     error("set_cwd: %s", cwd);
  338.     (void) un_set(&set_options, "cwd");
  339.     } else {
  340.     char *argv[4];
  341.     argv[0] = "cwd";
  342.     argv[1] = "=";
  343.     argv[2] = cwd;
  344.     argv[3] = NULL;
  345.     (void) add_option(&set_options, argv);
  346.     }
  347. }
  348.