home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / utils / elm / sources / init.c < prev    next >
C/C++ Source or Header  |  1992-05-23  |  14KB  |  472 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: init.c,v 4.1.1.4 90/12/05 14:34:08 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.4 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    init.c,v $
  17.  * Revision 4.1.1.4  90/12/05  14:34:08  syd
  18.  * fix dropping of unused vars, dropped to much
  19.  * From: Syd
  20.  *
  21.  * Revision 4.1.1.3  90/10/24  15:33:11  syd
  22.  * Remove variables no longer used
  23.  * From: W. David Higgins
  24.  *
  25.  * Revision 4.1.1.2  90/08/02  21:57:56  syd
  26.  * The newly introduced function 'stricmp' has a name conflict with a libc
  27.  * function under SunOS 4.1.  Changed name to istrcmp.
  28.  * From: scs@lokkur.dexter.mi.us (Steve Simmons)
  29.  *
  30.  * Revision 4.1.1.1  90/07/12  23:19:17  syd
  31.  * Make domain name checking case independent
  32.  * From: Syd, reported by Steven Baur
  33.  *
  34.  * Revision 4.1  90/04/28  22:43:15  syd
  35.  * checkin of Elm 2.3 as of Release PL0
  36.  *
  37.  *
  38.  ******************************************************************************/
  39.  
  40. /***** Initialize - read in all the defaults etc etc
  41. *****/
  42.  
  43. #include "headers.h"
  44. #include "patchlevel.h"
  45.  
  46. #ifdef TERMIOS
  47. #  include <termios.h>
  48.    typedef struct termios term_buff;
  49. #else
  50. # ifdef TERMIO
  51. #  include <termio.h>
  52. #  define tcgetattr(fd,buf)    ioctl((fd),TCGETA,(buf))
  53.    typedef struct termio term_buff;
  54. # else
  55. #  include <sgtty.h>
  56. #  define tcgetattr(fd,buf)    ioctl((fd),TIOCGETP,(buf))
  57.    typedef struct sgttyb term_buff;
  58. # endif
  59. #endif
  60.  
  61. #ifdef PWDINSYS
  62. #  include <sys/pwd.h>
  63. #else
  64. #  include <pwd.h>
  65. #endif
  66.  
  67. #ifdef I_TIME
  68. #  include <time.h>
  69. #endif
  70. #ifdef I_SYSTIME
  71. #  include <sys/time.h>
  72. #endif
  73.  
  74. #include <signal.h>
  75. #include <ctype.h>
  76. #include <errno.h>
  77.  
  78. #ifdef BSD
  79. #undef toupper
  80. #undef tolower
  81. #endif
  82.  
  83. #ifndef OS2
  84. extern int errno;        /* system error number on failure */
  85. #endif
  86. extern char version_buff[];
  87.  
  88. char *error_name(), *error_description();
  89.  
  90. char *getenv(), *getlogin(), *strcpy(), *strcat(), *index();
  91. unsigned short getgid(), getuid();
  92. void exit();
  93. #ifndef    _POSIX_SOURCE
  94. struct passwd *getpwuid();
  95. #endif
  96. char *get_full_name();
  97.  
  98. #ifdef VOIDSIG
  99.   void
  100. #else
  101.   int
  102. #endif
  103. #ifdef SIGTSTP
  104.     sig_user_stop(), sig_return_from_user_stop(),
  105. #endif
  106.     quit_signal(), term_signal(), ill_signal(),
  107.     fpe_signal(),  bus_signal(),  segv_signal(),
  108.     alarm_signal(), pipe_signal(), hup_signal();
  109.  
  110. initialize(requestedmfile)
  111. char *requestedmfile;    /* first mail file to open, empty if the default */
  112. {
  113.     /** initialize the whole ball of wax.
  114.     **/
  115.     struct passwd *pass;
  116.     register int i, hostlen, domlen;
  117.  
  118. #if defined(SIGVEC) & defined(SV_INTERRUPT)
  119.     struct sigvec alarm_vec;
  120. #endif
  121.     char     buffer[SLEN], *cp;
  122.  
  123.     sprintf(version_buff, "%s PL%d", VERSION, PATCHLEVEL);
  124.     Raw(ON);
  125.  
  126.     /* save original user and group ids */
  127.     userid  = getuid();
  128.     groupid = getgid();
  129.  
  130.     /* make all newly created files private */
  131.     original_umask = umask(077);
  132.  
  133.     /* Get username (logname), home (login directory), and full_username
  134.      * (part of GCOS) field from the password entry for this user id.
  135.      * Full_username will get overridden by fullname in elmrc, if defined.
  136.      */
  137.  
  138.     if((pass = getpwuid(userid)) == NULL) {
  139.       error("You have no password entry!");
  140.       Raw(OFF);
  141.       exit(1);
  142.     }
  143.     strcpy(username, pass->pw_name);
  144.     strcpy(home, pass->pw_dir);
  145.  
  146.     if((cp = get_full_name(username)) != NULL)
  147.       strcpy(full_username, cp);
  148.     else
  149.       strcpy(full_username, username);    /* fall back on logname */
  150.  
  151. #ifdef DEBUG
  152.     if (debug) {        /* setup for dprint() statements! */
  153.       char newfname[SLEN], filename[SLEN];
  154.  
  155.       sprintf(filename, "%s/%s", home, DEBUGFILE);
  156.       if (access(filename, ACCESS_EXISTS) == 0) {    /* already one! */
  157.         sprintf(newfname,"%s/%s", home, OLDEBUG);
  158.         (void) rename(filename, newfname);
  159.       }
  160.  
  161.       /* Note what we just did up there: we always save the old
  162.          version of the debug file as OLDEBUG, so users can mail
  163.          copies of bug files without trashing 'em by starting up
  164.          the mailer.  Dumb, subtle, but easy enough to do!
  165.        */
  166.  
  167.       if ((debugfile = fopen(filename, "w")) == NULL) {
  168.         debug = 0;    /* otherwise 'leave' will try to log! */
  169.         leave(fprintf(stderr,"Could not open file %s for debug output!\n",
  170.           filename));
  171.       }
  172.       chown(filename, userid, groupid); /* file owned by user */
  173.  
  174.       fprintf(debugfile,
  175.      "Debug output of the ELM program (at debug level %d).  Version %s\n\n",
  176.           debug, version_buff);
  177.     }
  178. #endif
  179.  
  180.     /*
  181.      * If debug level is fairly low, ignore keyboard signals
  182.      * until the screen is set up.
  183.      */
  184.     if (debug < 5) {
  185.       signal(SIGINT,  SIG_IGN);
  186.       signal(SIGQUIT, SIG_IGN);
  187.     }
  188.  
  189.     if(!check_only && !batch_only) {
  190.       if ((i = InitScreen()) < 0) {
  191.         if (i == -1) {
  192.           printf(
  193. "Sorry, but you must specify what type of terminal you're on if you want to\r\n");
  194.           printf(
  195. "run the \"elm\" program. (You need your environment variable \"TERM\" set.)\r\n"
  196.              );
  197.           dprint(1,(debugfile,"No $TERM variable in environment!\n"));
  198.         }
  199.         else if (i == -2) {
  200.           printf(
  201. "You need a cursor-addressable terminal to run \"elm\" and I can't find any\r\n");
  202.           printf(
  203. "kind of termcap entry for \"%s\" - check your \"TERM\" setting...\r\n",
  204.            getenv("TERM"));
  205.           printf(
  206. "Or check your TERMCAP setting or termcap database file.\r\n");
  207.           dprint(1,
  208.         (debugfile,"$TERM variable is an unknown terminal type!\n"));
  209.         } else {
  210.           printf("Failed trying to initialize your terminal entry: unknown return code %d\r\n", i);
  211.           dprint(1, (debugfile, "Initscreen returned unknown code: %d\r\n",
  212.           i));
  213.         }
  214.         Raw(OFF);
  215.         exit(1);    /* all the errors share this exit statement */
  216.       }
  217.           EndBold();
  218.           EndHalfbright();
  219.           EndInverse();
  220.     }
  221.  
  222.     if (debug < 5) {    /* otherwise let the system trap 'em! */
  223.       signal(SIGQUIT, quit_signal);        /* Quit signal                 */
  224.       signal(SIGTERM, term_signal);     /* Terminate signal         */
  225.       signal(SIGILL,  ill_signal);        /* Illegal instruction      */
  226.       signal(SIGFPE,  fpe_signal);        /* Floating point exception */
  227. #ifndef OS2
  228.       signal(SIGBUS,  bus_signal);        /* Bus error              */
  229.       signal(SIGHUP,  hup_signal);        /* HangUp (line dropped)    */
  230. #endif
  231.       signal(SIGSEGV, segv_signal);        /* Segmentation Violation   */
  232.     }
  233.     else {
  234.       dprint(3,(debugfile,
  235.   "\n*** Elm-Internal Signal Handlers Disabled due to debug level %d ***\n\n",
  236.             debug));
  237.     }
  238. #if defined(SIGVEC) & defined(SV_INTERRUPT)
  239.     alarm_vec.sv_handler = alarm_signal;
  240.     alarm_vec.sv_flags = SV_INTERRUPT;
  241.     sigvec (SIGALRM, &alarm_vec, (struct sigvec *)0);    /* Process Timer Alarm        */
  242. #else
  243.     signal(SIGALRM, alarm_signal);        /* Process Timer Alarm      */
  244. #endif
  245. #ifndef OS2
  246.     signal(SIGPIPE, pipe_signal);        /* Illegal Pipe Operation   */
  247. #endif
  248. #ifdef SIGTSTP
  249.     signal(SIGTSTP, sig_user_stop);        /* Suspend signal from tty  */
  250.     signal(SIGCONT, sig_return_from_user_stop);    /* Continue Process */
  251. #endif
  252.  
  253.     get_term_chars();
  254.  
  255.     /*
  256.      * Get the host name as per configured behavior.
  257.      */
  258. #ifdef HOSTCOMPILED
  259.     strncpy(hostname, HOSTNAME, sizeof(hostname) - 1);
  260.     hostname[sizeof(hostname) - 1] = '\0';
  261. #else
  262.     gethostname(hostname, sizeof(hostname));
  263. #endif
  264.  
  265.     /*
  266.      * now get the domain name, used to build the full name
  267.      */
  268.     gethostdomain(hostdomain, sizeof(hostdomain));
  269.  
  270.     /*
  271.      * now the tough part:
  272.      *    we need to make three variables out of this stuff:
  273.      *    hostname = just the hostname, as in bangpaths,
  274.      *        this is whatever the user gave us so far,
  275.      *        we wont change this one
  276.      *    hostdomain = this is the domain considered local to this
  277.      *        machine, and should be what we got above.
  278.      *    hostfullname = this is the full FQDN of this machine,
  279.      *        and is a strange combination of the first two.
  280.      *    if tail(hostname) == hostdomain
  281.      *        then hostfullname = hostname
  282.      *            ie: node.ld.domain.type, ld.domain.type -> node.ld.domain.type
  283.      *    else if hostname == hostdomain + 1
  284.      *        then hostfullname = hostname
  285.      *            ie: domain.type, .domain.type -> domain.type
  286.      *
  287.      *    else hostfullname = hostname + hostdomain
  288.      *            ie: host, .domain.type -> host.domain.type
  289.      * lost yet?
  290.      */
  291.     hostlen = strlen(hostname);
  292.     domlen = strlen(hostdomain);
  293.     if (hostlen >= domlen) {
  294.       if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
  295.         strcpy(hostfullname, hostname);
  296.       else {
  297.         strcpy(hostfullname, hostname);
  298.         strcat(hostfullname, hostdomain);
  299.       }
  300.     } else {
  301.       if (istrcmp(hostname, hostdomain + 1) == 0)
  302.         strcpy(hostfullname, hostname);
  303.       else {
  304.         strcpy(hostfullname, hostname);
  305.         strcat(hostfullname, hostdomain);
  306.       }
  307.     }
  308.  
  309.     /* Determine the default mail file name.
  310.      *
  311.      * First look for an environment variable MAIL, then
  312.      * use then mailhome if it is not found
  313.      */
  314.     if ((cp = getenv("MAIL")) == NULL)
  315. #ifdef OS2
  316.         if (maildir)
  317.         sprintf(defaultfile, "%s%s/newmail%s", mailhome, username, mailext);
  318.         else
  319. #endif
  320.         sprintf(defaultfile, "%s%s%s", mailhome, username, mailext);
  321.     else
  322.         strcpy(defaultfile, cp);
  323.  
  324.     /* Determine options that might be set in the .elm/elmrc */
  325.     read_rc_file();
  326.  
  327.     /* Determine the mail file to read */
  328.     if (*requestedmfile == '\0')
  329.       strcpy(requestedmfile, defaultfile);
  330.     else if(!expand_filename(requestedmfile, FALSE)) {
  331.         Raw(OFF);
  332.         exit(0);
  333.         }
  334.     if (check_size)
  335.       if(check_mailfile_size(requestedmfile) != 0) {
  336.           Raw(OFF);
  337.           exit(0);
  338.       }
  339.  
  340.     /* check for permissions only if not send only mode file */
  341.     if (! mail_only) {
  342.       if ((errno = can_access(requestedmfile, READ_ACCESS)) != 0) {
  343.         if (strcmp(requestedmfile, defaultfile) != 0 || errno != ENOENT) {
  344.           dprint(1, (debugfile,
  345.             "Error: given file %s as folder - unreadable (%s)!\n",
  346.             requestedmfile, error_name(errno)));
  347.           fprintf(stderr,"Can't open folder '%s' for reading!\n",
  348.             requestedmfile);
  349.           Raw(OFF);
  350.           exit(1);
  351.         }
  352.       }
  353.     }
  354.  
  355.     /** check to see if the user has defined a LINES or COLUMNS
  356.         value different to that in the termcap entry (for
  357.         windowing systems, of course!) **/
  358.  
  359.     ScreenSize(&LINES, &COLUMNS);
  360.  
  361.     if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
  362.       sscanf(cp, "%d", &LINES);
  363.       LINES -= 1;    /* kludge for HP Window system? ... */
  364.     }
  365.  
  366.     if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
  367.       sscanf(cp, "%d", &COLUMNS);
  368.  
  369.     /** fix the shell if needed **/
  370.  
  371. #ifndef OS2
  372.     if (shell[0] != '/') {
  373.        sprintf(buffer, "/bin/%s", shell);
  374.        strcpy(shell, buffer);
  375.     }
  376. #endif
  377.  
  378.     if (! mail_only && ! check_only) {
  379.  
  380.       /* get the cursor control keys... */
  381.  
  382.       cursor_control = FALSE;
  383.  
  384.       if ((cp = return_value_of("ku")) != NULL) {
  385.         strcpy(up, cp);
  386.         if ((cp = return_value_of("kd")) != NULL) {
  387.           strcpy(down, cp);
  388.           if ((cp = return_value_of("kl")) != NULL) {
  389.         strcpy(left, cp);
  390.         if ((cp = return_value_of("kr")) != NULL) {
  391.           strcpy(right, cp);
  392.           cursor_control = TRUE;
  393.           transmit_functions(ON);
  394.         }
  395.           }
  396.         }
  397.       }
  398.       if (!arrow_cursor)     /* try to use inverse bar instead */
  399.         if (return_value_of("so") != NULL && return_value_of("se") != NULL)
  400.             has_highlighting = TRUE;
  401.     }
  402.  
  403.     /** clear the screen **/
  404.     if(!check_only && !batch_only)
  405.       ClearScreen();
  406.  
  407.     if (! mail_only && ! check_only) {
  408.       if (mini_menu)
  409.         headers_per_page = LINES - 13;
  410.       else
  411.         headers_per_page = LINES -  8;    /* 5 more headers! */
  412.  
  413.       newmbox(requestedmfile, FALSE);    /* read in the folder! */
  414.     }
  415.  
  416. #ifdef DEBUG
  417.     if (debug >= 2 && debug < 10) {
  418.       fprintf(debugfile,
  419. "hostname = %-20s \tusername = %-20s \tfullname = %-20s\n",
  420.              hostname, username, full_username);
  421.  
  422.       fprintf(debugfile,
  423. "home     = %-20s \teditor   = %-20s \trecvd_mail  = %-20s\n",
  424.          home, editor, recvd_mail);
  425.  
  426.       fprintf(debugfile,
  427. "cur_folder   = %-20s \tfolders  = %-20s \tprintout = %-20s\n",
  428.          cur_folder, folders, printout);
  429.  
  430.       fprintf(debugfile,
  431. "sent_mail = %-20s \tprefix   = %-20s \tshell    = %-20s\n\n",
  432.         sent_mail, prefixchars, shell);
  433.  
  434.       if (local_signature[0])
  435.         fprintf(debugfile, "local_signature = \"%s\"\n",
  436.             local_signature);
  437.       if (remote_signature[0])
  438.         fprintf(debugfile, "remote_signature = \"%s\"\n",
  439.             remote_signature);
  440.       if (local_signature[0] || remote_signature[0])
  441.         fprintf(debugfile, "\n");
  442.     }
  443. #endif
  444. }
  445.  
  446. get_term_chars()
  447. {
  448.     /** This routine sucks out the special terminal characters
  449.         ERASE and KILL for use in the input routine.  The meaning
  450.             of the characters are (dare I say it?) fairly obvious... **/
  451.  
  452.     term_buff term_buffer;
  453.  
  454.     if (tcgetattr(STANDARD_INPUT,&term_buffer) == -1) {
  455.       dprint(1, (debugfile,
  456.            "Error: %s encountered on ioctl call (get_term_chars)\n",
  457.            error_name(errno)));
  458.       /* set to defaults for terminal driver */
  459.       backspace = BACKSPACE;
  460.       kill_line = ctrl('U');
  461.     }
  462.     else {
  463. #if defined(TERMIO) || defined(TERMIOS)
  464.       backspace = term_buffer.c_cc[VERASE];
  465.       kill_line = term_buffer.c_cc[VKILL];
  466. #else
  467.       backspace = term_buffer.sg_erase;
  468.       kill_line = term_buffer.sg_kill;
  469. #endif
  470.     }
  471. }
  472.