home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.3pl11 / src / init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-05  |  12.5 KB  |  454 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. extern int errno;        /* system error number on failure */
  84. extern char version_buff[];
  85.  
  86. char *error_name(), *error_description();
  87.  
  88. char *getenv(), *getlogin(), *strcpy(), *strcat(), *index();
  89. unsigned short getgid(), getuid(); 
  90. void exit();
  91. #ifndef    _POSIX_SOURCE
  92. struct passwd *getpwuid();
  93. #endif
  94. char *get_full_name();
  95.  
  96. #ifdef VOIDSIG
  97.   void
  98. #else
  99.   int
  100. #endif
  101. #ifdef SIGTSTP
  102.     sig_user_stop(), sig_return_from_user_stop(),
  103. #endif
  104.     quit_signal(), term_signal(), ill_signal(),
  105.     fpe_signal(),  bus_signal(),  segv_signal(),
  106.     alarm_signal(), pipe_signal(), hup_signal();
  107.  
  108. initialize(requestedmfile)
  109. char *requestedmfile;    /* first mail file to open, empty if the default */
  110. {
  111.     /** initialize the whole ball of wax.
  112.     **/
  113.     struct passwd *pass;
  114.     register int i, hostlen, domlen; 
  115.  
  116. #if defined(SIGVEC) & defined(SV_INTERRUPT)
  117.     struct sigvec alarm_vec;
  118. #endif
  119.     char     buffer[SLEN], *cp;
  120.  
  121.     sprintf(version_buff, "%s PL%d", VERSION, PATCHLEVEL);
  122.     Raw(ON);
  123.  
  124.     /* save original user and group ids */
  125.     userid  = getuid();
  126.     groupid = getgid();    
  127.  
  128.     /* make all newly created files private */
  129.     original_umask = umask(077);
  130.  
  131.     /* Get username (logname), home (login directory), and full_username
  132.      * (part of GCOS) field from the password entry for this user id.
  133.      * Full_username will get overridden by fullname in elmrc, if defined.
  134.      */
  135.  
  136.     if((pass = getpwuid(userid)) == NULL) {
  137.       error("You have no password entry!");
  138.       Raw(OFF);
  139.       exit(1);
  140.     }
  141.     strcpy(username, pass->pw_name);
  142.     strcpy(home, pass->pw_dir);
  143.  
  144.     if((cp = get_full_name(username)) != NULL)
  145.       strcpy(full_username, cp);
  146.     else
  147.       strcpy(full_username, username);    /* fall back on logname */
  148.  
  149. #ifdef DEBUG
  150.     if (debug) {        /* setup for dprint() statements! */
  151.       char newfname[SLEN], filename[SLEN];
  152.  
  153.       sprintf(filename, "%s/%s", home, DEBUGFILE);
  154.       if (access(filename, ACCESS_EXISTS) == 0) {    /* already one! */
  155.         sprintf(newfname,"%s/%s", home, OLDEBUG);
  156.         (void) rename(filename, newfname);
  157.       }
  158.  
  159.       /* Note what we just did up there: we always save the old
  160.          version of the debug file as OLDEBUG, so users can mail
  161.          copies of bug files without trashing 'em by starting up
  162.          the mailer.  Dumb, subtle, but easy enough to do!
  163.        */
  164.  
  165.       if ((debugfile = fopen(filename, "w")) == NULL) {
  166.         debug = 0;    /* otherwise 'leave' will try to log! */
  167.         leave(fprintf(stderr,"Could not open file %s for debug output!\n",
  168.           filename));
  169.       }
  170.       chown(filename, userid, groupid); /* file owned by user */
  171.  
  172.       fprintf(debugfile, 
  173.      "Debug output of the ELM program (at debug level %d).  Version %s\n\n",
  174.           debug, version_buff);
  175.     }
  176. #endif
  177.  
  178.     /*
  179.      * If debug level is fairly low, ignore keyboard signals
  180.      * until the screen is set up.
  181.      */
  182.     if (debug < 5) {
  183.       signal(SIGINT,  SIG_IGN);
  184.       signal(SIGQUIT, SIG_IGN);
  185.     }
  186.  
  187.     if(!check_only && !batch_only) {
  188.       if ((i = InitScreen()) < 0) {
  189.         if (i == -1) {
  190.           printf( 
  191. "Sorry, but you must specify what type of terminal you're on if you want to\n");
  192.           printf( 
  193. "run the \"elm\" program. (You need your environment variable \"TERM\" set.)\n"
  194.              );
  195.           dprint(1,(debugfile,"No $TERM variable in environment!\n"));
  196.         }
  197.         else if (i == -2) {
  198.           printf(
  199. "You need a cursor-addressable terminal to run \"elm\" and I can't find any\n");
  200.           printf(
  201. "kind of termcap entry for \"%s\" - check your \"TERM\" setting...\n",
  202.            getenv("TERM"));
  203.           dprint(1,
  204.         (debugfile,"$TERM variable is an unknown terminal type!\n"));
  205.         } else {
  206.           printf("Failed trying to initialize your terminal entry: unknown return code %d\n", i);
  207.           dprint(1, (debugfile, "Initscreen returned unknown code: %d\n",
  208.           i));
  209.         }
  210.         Raw(OFF);
  211.         exit(1);    /* all the errors share this exit statement */
  212.       }
  213.     }
  214.  
  215.     if (debug < 5) {    /* otherwise let the system trap 'em! */
  216.       signal(SIGQUIT, quit_signal);        /* Quit signal                 */
  217.       signal(SIGTERM, term_signal);     /* Terminate signal         */
  218.       signal(SIGILL,  ill_signal);        /* Illegal instruction      */
  219.       signal(SIGFPE,  fpe_signal);        /* Floating point exception */
  220.       signal(SIGBUS,  bus_signal);        /* Bus error              */
  221.       signal(SIGSEGV, segv_signal);        /* Segmentation Violation   */
  222.       signal(SIGHUP,  hup_signal);        /* HangUp (line dropped)    */
  223.     }
  224.     else {
  225.       dprint(3,(debugfile,
  226.   "\n*** Elm-Internal Signal Handlers Disabled due to debug level %d ***\n\n",
  227.             debug));
  228.     }
  229. #if defined(SIGVEC) & defined(SV_INTERRUPT)
  230.     alarm_vec.sv_handler = alarm_signal;
  231.     alarm_vec.sv_flags = SV_INTERRUPT;
  232.     sigvec (SIGALRM, &alarm_vec, (struct sigvec *)0);    /* Process Timer Alarm        */
  233. #else
  234.     signal(SIGALRM, alarm_signal);        /* Process Timer Alarm      */
  235. #endif
  236.     signal(SIGPIPE, pipe_signal);        /* Illegal Pipe Operation   */
  237. #ifdef SIGTSTP
  238.     signal(SIGTSTP, sig_user_stop);        /* Suspend signal from tty  */
  239.     signal(SIGCONT, sig_return_from_user_stop);    /* Continue Process */
  240. #endif
  241.  
  242.     get_term_chars();
  243.  
  244.     /*
  245.      * Get the host name as per configured behavior.
  246.      */
  247. #ifdef HOSTCOMPILED
  248.     strncpy(hostname, HOSTNAME, sizeof(hostname) - 1);
  249.     hostname[sizeof(hostname) - 1] = '\0';
  250. #else
  251.     gethostname(hostname, sizeof(hostname));
  252. #endif
  253.  
  254.     /*
  255.      * now get the domain name, used to build the full name
  256.      */
  257.     gethostdomain(hostdomain, sizeof(hostdomain));
  258.  
  259.     /*
  260.      * now the tough part:
  261.      *    we need to make three variables out of this stuff:
  262.      *    hostname = just the hostname, as in bangpaths,
  263.      *        this is whatever the user gave us so far,
  264.      *        we wont change this one
  265.      *    hostdomain = this is the domain considered local to this
  266.      *        machine, and should be what we got above.
  267.      *    hostfullname = this is the full FQDN of this machine,
  268.      *        and is a strange combination of the first two.
  269.      *    if tail(hostname) == hostdomain
  270.      *        then hostfullname = hostname
  271.      *            ie: node.ld.domain.type, ld.domain.type -> node.ld.domain.type
  272.      *    else if hostname == hostdomain + 1
  273.      *        then hostfullname = hostname
  274.      *            ie: domain.type, .domain.type -> domain.type
  275.      *    
  276.      *    else hostfullname = hostname + hostdomain
  277.      *            ie: host, .domain.type -> host.domain.type
  278.      * lost yet?
  279.      */
  280.     hostlen = strlen(hostname);
  281.     domlen = strlen(hostdomain);
  282.     if (hostlen >= domlen) {
  283.       if (istrcmp(&hostname[hostlen - domlen], hostdomain) == 0)
  284.         strcpy(hostfullname, hostname);
  285.       else {
  286.         strcpy(hostfullname, hostname);
  287.         strcat(hostfullname, hostdomain);
  288.       }
  289.     } else {
  290.       if (istrcmp(hostname, hostdomain + 1) == 0)
  291.         strcpy(hostfullname, hostname);
  292.       else {
  293.         strcpy(hostfullname, hostname);
  294.         strcat(hostfullname, hostdomain);
  295.       }
  296.     }
  297.  
  298.     /* Determine the default mail file name.
  299.      * 
  300.      * First look for an environment variable MAIL, then
  301.      * use then mailhome if it is not found
  302.      */
  303.     if ((cp = getenv("MAIL")) == NULL)
  304.         sprintf(defaultfile, "%s%s", mailhome, username);
  305.     else
  306.         strcpy(defaultfile, cp);
  307.  
  308.     /* Determine options that might be set in the .elm/elmrc */
  309.     read_rc_file();
  310.  
  311.     /* Determine the mail file to read */
  312.     if (*requestedmfile == '\0')
  313.       strcpy(requestedmfile, defaultfile);
  314.     else if(!expand_filename(requestedmfile, FALSE)) {
  315.         Raw(OFF);
  316.         exit(0);
  317.         }
  318.     if (check_size)
  319.       if(check_mailfile_size(requestedmfile) != 0) {
  320.           Raw(OFF);
  321.           exit(0);
  322.       }
  323.  
  324.     /* check for permissions only if not send only mode file */
  325.     if (! mail_only) {
  326.       if ((errno = can_access(requestedmfile, READ_ACCESS)) != 0) {
  327.         if (strcmp(requestedmfile, defaultfile) != 0 || errno != ENOENT) {
  328.           dprint(1, (debugfile,
  329.             "Error: given file %s as folder - unreadable (%s)!\n", 
  330.             requestedmfile, error_name(errno)));
  331.           fprintf(stderr,"Can't open folder '%s' for reading!\n",
  332.             requestedmfile);
  333.           Raw(OFF);
  334.           exit(1);
  335.         }
  336.       }
  337.     }
  338.  
  339.     /** check to see if the user has defined a LINES or COLUMNS
  340.         value different to that in the termcap entry (for
  341.         windowing systems, of course!) **/
  342.  
  343.     ScreenSize(&LINES, &COLUMNS);
  344.  
  345.     if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
  346.       sscanf(cp, "%d", &LINES);
  347.       LINES -= 1;    /* kludge for HP Window system? ... */
  348.     }
  349.  
  350.     if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
  351.       sscanf(cp, "%d", &COLUMNS);
  352.  
  353.     /** fix the shell if needed **/
  354.  
  355.     if (shell[0] != '/') {
  356.        sprintf(buffer, "/bin/%s", shell);
  357.        strcpy(shell, buffer);
  358.     }
  359.  
  360.     if (! mail_only && ! check_only) {
  361.  
  362.       /* get the cursor control keys... */
  363.  
  364.       cursor_control = FALSE;
  365.  
  366.       if ((cp = return_value_of("ku")) != NULL) {
  367.         strcpy(up, cp);
  368.         if ((cp = return_value_of("kd")) != NULL) {
  369.           strcpy(down, cp);
  370.           if ((cp = return_value_of("kl")) != NULL) {
  371.         strcpy(left, cp);
  372.         if ((cp = return_value_of("kr")) != NULL) {
  373.           strcpy(right, cp);
  374.           cursor_control = TRUE;
  375.           transmit_functions(ON);
  376.         }
  377.           }
  378.         }
  379.       }
  380.       if (!arrow_cursor)     /* try to use inverse bar instead */
  381.         if (return_value_of("so") != NULL && return_value_of("se") != NULL)
  382.             has_highlighting = TRUE;
  383.     }
  384.  
  385.     /** clear the screen **/
  386.     if(!check_only && !batch_only)
  387.       ClearScreen();
  388.  
  389.     if (! mail_only && ! check_only) {
  390.       if (mini_menu)
  391.         headers_per_page = LINES - 13;
  392.       else
  393.         headers_per_page = LINES -  8;    /* 5 more headers! */
  394.  
  395.       newmbox(requestedmfile, FALSE);    /* read in the folder! */
  396.     }
  397.  
  398. #ifdef DEBUG
  399.     if (debug >= 2 && debug < 10) {
  400.       fprintf(debugfile,
  401. "hostname = %-20s \tusername = %-20s \tfullname = %-20s\n",
  402.              hostname, username, full_username);
  403.  
  404.       fprintf(debugfile,
  405. "home     = %-20s \teditor   = %-20s \trecvd_mail  = %-20s\n",
  406.          home, editor, recvd_mail);
  407.  
  408.       fprintf(debugfile,
  409. "cur_folder   = %-20s \tfolders  = %-20s \tprintout = %-20s\n",
  410.          cur_folder, folders, printout);
  411.     
  412.       fprintf(debugfile,
  413. "sent_mail = %-20s \tprefix   = %-20s \tshell    = %-20s\n\n",
  414.         sent_mail, prefixchars, shell);
  415.     
  416.       if (local_signature[0])
  417.         fprintf(debugfile, "local_signature = \"%s\"\n",
  418.             local_signature);
  419.       if (remote_signature[0])
  420.         fprintf(debugfile, "remote_signature = \"%s\"\n",
  421.             remote_signature);
  422.       if (local_signature[0] || remote_signature[0])
  423.         fprintf(debugfile, "\n");
  424.     }
  425. #endif
  426. }
  427.  
  428. get_term_chars()
  429. {
  430.     /** This routine sucks out the special terminal characters
  431.         ERASE and KILL for use in the input routine.  The meaning 
  432.             of the characters are (dare I say it?) fairly obvious... **/
  433.  
  434.     term_buff term_buffer;
  435.  
  436.     if (tcgetattr(STANDARD_INPUT,&term_buffer) == -1) {
  437.       dprint(1, (debugfile,
  438.            "Error: %s encountered on ioctl call (get_term_chars)\n", 
  439.            error_name(errno)));
  440.       /* set to defaults for terminal driver */
  441.       backspace = BACKSPACE;
  442.       kill_line = ctrl('U');
  443.     }
  444.     else {
  445. #if defined(TERMIO) || defined(TERMIOS)
  446.       backspace = term_buffer.c_cc[VERASE];
  447.       kill_line = term_buffer.c_cc[VKILL];
  448. #else
  449.       backspace = term_buffer.sg_erase;
  450.       kill_line = term_buffer.sg_kill;
  451. #endif
  452.     }
  453. }
  454.