home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part07 / init.c < prev   
Encoding:
C/C++ Source or Header  |  1989-03-12  |  15.0 KB  |  534 lines

  1. /* init.c    (c) copyright 1986 (Dan Heller) */
  2.  
  3. /* init.c -- functions and whatnot that initialize everything */
  4. #include "mush.h"
  5. #include <pwd.h>
  6.  
  7. #ifdef SUNTOOL
  8. /* mouse symbols */
  9. short dat_mouse_left[] = {
  10. #include <images/confirm_left.pr> 
  11. };
  12.  
  13. short dat_mouse_middle[] = {
  14. #include <images/confirm_middle.pr> 
  15. };
  16.  
  17. short dat_mouse_right[] = {
  18. #include <images/confirm_right.pr> 
  19. };
  20.  
  21. short dat_mail_icon_1[] = {
  22. #include "mail.icon.1"
  23. };
  24.  
  25. short dat_mail_icon_2[] = {
  26. #include "mail.icon.2"
  27. };
  28.  
  29. short dat_coffee_cup[] = {
  30. #include "coffee.cup.pr"
  31. };
  32.  
  33. short dat_read_cursor[] = {
  34. #include "glasses.pr"
  35. };
  36.  
  37. short dat_write_cursor[] = {
  38. #include "write.pr"
  39. };
  40.  
  41. short dat_up_arrow[] = {
  42. #include "up.arrow.pr"
  43. };
  44.  
  45. short dat_dn_arrow[] = {
  46. #include "dn.arrow.pr"
  47. };
  48.  
  49. short dat_envelope[] = {
  50. #include "envelope.pr"
  51. };
  52.  
  53. short dat_cycle_cursor[] = {
  54. #include "cycle.pr"
  55. };
  56.  
  57. short dat_check_cursor[] = {
  58. #include "check.pr"
  59. };
  60.  
  61. mpr_static(mail_icon_image1, 64, 64, 1, dat_mail_icon_1);
  62. mpr_static(mail_icon_image2, 64, 64, 1, dat_mail_icon_2);
  63.  
  64. mpr_static(mouse_left,      16, 16, 1, dat_mouse_left);
  65. mpr_static(mouse_middle,    16, 16, 1, dat_mouse_middle);
  66. mpr_static(mouse_right,     16, 16, 1, dat_mouse_right);
  67. mpr_static(coffee_cup,      16, 16, 1, dat_coffee_cup);
  68. mpr_static(glasses_cursor,  16, 16, 1, dat_read_cursor);
  69. mpr_static(pencil_cursor,   16, 16, 1, dat_write_cursor);
  70. mpr_static(up_arrow,        16, 16, 1, dat_up_arrow);
  71. mpr_static(dn_arrow,        16, 16, 1, dat_dn_arrow);
  72. mpr_static(envelope_cursor, 16, 16, 1, dat_envelope);
  73. mpr_static(cycle,           16, 16, 1, dat_cycle_cursor);
  74. mpr_static(check_cursor,    16, 16, 1, dat_check_cursor);
  75.  
  76. struct cursor l_cursor     = { 3, 3, PIX_SRC,         &mouse_left      };
  77. struct cursor m_cursor     = { 3, 3, PIX_SRC,         &mouse_middle    };
  78. struct cursor r_cursor     = { 3, 3, PIX_SRC,         &mouse_right     };
  79. struct cursor coffee       = { 8, 8, PIX_SRC,         &coffee_cup      };
  80. struct cursor read_cursor  = { 8, 8, PIX_SRC|PIX_DST, &glasses_cursor  };
  81. struct cursor write_cursor = { 8, 8, PIX_SRC|PIX_DST, &pencil_cursor   };
  82. struct cursor main_cursor  = { 8, 8, PIX_SRC,         &envelope_cursor };
  83. struct cursor checkmark = { 8, 8, PIX_SRC|PIX_DST, &check_cursor };
  84.  
  85. /* text and font will be set in mail_status() */
  86. struct icon mail_icon = { 64,  64, (struct pixrect *)NULL,
  87.             { 0, 0, 64, 64 }, &mail_icon_image1,
  88.             { 5, 5, 26, 12 }, NULL, (struct pixfont *)NULL, 0 };
  89.  
  90. char *font_files[] = {
  91.     "serif.r.14", "sail.r.6", "serif.r.16",
  92. };
  93.  
  94. char *alt_fonts[] = {
  95.     "gacha.r.8", "sail.r.6", "screen.r.14",
  96. };
  97.  
  98. #endif /* SUNTOOL */
  99.  
  100. #ifdef BSD
  101. #include <netdb.h>
  102. #endif /* BSD */
  103.  
  104. #ifdef SYSV
  105. #include <sys/utsname.h>
  106. #endif /* SYSV */
  107.  
  108. void
  109. init()
  110. {
  111.     char         *home, *realname, *argv[4];
  112.     extern char        *getlogin(), **calloc();
  113.     char        buf[MAXPATHLEN];
  114. #ifdef SYSV
  115.     extern struct passwd *getpwuid();  /* sys-v forgot this in pwd.h! */
  116.     struct utsname ourhost;
  117. #else
  118.     char ourhost[128];
  119. #endif /* SYSV */
  120.     register char     *p;
  121.     struct passwd     *entry;
  122.     int            cnt;
  123. #ifdef BSD
  124.     struct hostent     *hp;
  125. #endif /* BSD */
  126.  
  127.     home = getenv("HOME");
  128.     realname = getenv("NAME");
  129.     argv[1] = "=";
  130.     argv[3] = NULL;
  131.  
  132.     if (!(entry = getpwuid(getuid())))
  133.     if (p = getlogin())
  134.         strdup(login, p);
  135.     else {
  136.         login = "unknown";
  137.         print("I don't know you, but that's ok.\n");
  138.     }
  139.     else {
  140.     strdup(login, entry->pw_name);
  141.     if (!home || !*home)
  142.         home = entry->pw_dir;
  143.     if (!realname && (realname = entry->pw_gecos) &&
  144.         (p = index(realname, ',')))
  145.         *p = 0;
  146.     endpwent();
  147.     }
  148.     if (!home || !*home || Access(home, W_OK)) {
  149.     if (home && *home)
  150.         error(home);
  151.     else
  152.         print("No home!? ");
  153.     print_more("Using \"%s\" as home.\n", ALTERNATE_HOME);
  154.     } else {
  155.     argv[0] = "home";
  156.     argv[2] = home;
  157.     (void) add_option(&set_options, argv);
  158.     }
  159.     if (realname) {
  160.     if (realname == entry->pw_gecos) {
  161.         for (p = buf; *realname; realname++)
  162.         if (*realname == '&')
  163.             *p++ = upper(*login), p += Strcpy(p, login+1);
  164.         else
  165.             *p++ = *realname;
  166.         *p = 0;
  167.     } else
  168.         (void) strcpy(buf, realname);
  169.     argv[0] = "realname";
  170.     argv[2] = buf;
  171.     (void) add_option(&set_options, argv);
  172.     }
  173.     crt = 24;
  174.     screen = 18;
  175.     wrapcolumn = 0; /* Default is no wrap */
  176.     escape = DEF_ESCAPE;
  177.     prompt = DEF_PROMPT;
  178.  
  179. #ifdef BSD
  180.     (void) gethostname(ourhost, sizeof ourhost);
  181.     if (!(hp = gethostbyname(ourhost))) {
  182.     error("gethostbyname: %s", ourhost);
  183.     if (ourname = calloc((unsigned)2, sizeof (char *)))
  184.         strdup(ourname[0], ourhost);
  185.     } else {
  186.     int n = 0;
  187.     cnt = 2; /* 1 for ourhost and 1 for NULL terminator */
  188.     for (p = hp->h_name; p && *p; p = hp->h_aliases[n++])
  189.         if (strcmp(ourhost, p)) /* if host name is different */
  190.         cnt++;
  191.     if (ourname = calloc((unsigned)cnt, sizeof (char *))) {
  192.         ourname[--cnt] = NULL;
  193.         for (p = hp->h_name; p && *p && n >= 0; p = hp->h_aliases[--n])
  194.         if (strcmp(ourhost, p)) /* if host name is different */
  195.             ourname[--cnt] = savestr(p);
  196.         strdup(ourname[0], ourhost); /* cnt better be 0! */
  197.     }
  198.     }
  199.     endhostent();
  200. #endif /* BSD */
  201. #ifdef SYSV
  202.     ourname = calloc((unsigned)2, sizeof (char *));
  203.     if ((uname (&ourhost) >= 0) && (*ourhost.nodename))
  204.     ourname[0] = savestr(ourhost.nodename);
  205.     else {
  206.         /* Try to use uuname -l to get host's name if uname didn't work */
  207.         char buff[50];
  208.         char *p;
  209.         FILE *F;
  210.  
  211.         if (F = popen("exec uuname -l", "r")) {
  212.             if ((fgets(buff, sizeof buff, F) == buff) &&
  213.                 (p = strchr(buff, '\n'))) {
  214.             *p = '\0';        /* eliminate newline */
  215.         ourname[0] = savestr (buff);
  216.         }
  217.     (void)pclose(F);
  218.         }
  219.     }
  220. #endif /* SYSV */
  221.     if (ourname && ourname[0]) {
  222.     for (p = buf, cnt = 0; ourname[cnt]; cnt++) {
  223.         if (cnt)
  224.         *p++ = ' ';
  225.         p += Strcpy(p, ourname[cnt]);
  226.     }
  227.     argv[0] = "hostname";
  228.     argv[2] = buf;
  229.     (void) add_option(&set_options, argv);
  230.     }
  231.     init_bindings();
  232. }
  233.  
  234. /*
  235.  * Source a file, or just the default file.  Since sourcing files
  236.  * means reading possible aliases, don't expand the ! as history
  237.  * by setting the IGN_BANG flag.  Since a command in the sourced file
  238.  * may call source on another file, this routine may be called from
  239.  * within itself.  Continue to ignore ! chars by setting save_bang (local).
  240.  *
  241.  * Try opening the file passed to us.  If not given, check for the correct
  242.  * .rc file which is found in the user's home dir.
  243.  */
  244. source(argc, argv)
  245. char **argv;
  246. {
  247.     register char *p;
  248.     FILE      *fp;
  249.     char       file[128];
  250.     u_long      save_bang = ison(glob_flags, IGN_BANG);
  251.     int          line_no = 0;
  252.  
  253.     if (argc && *++argv && !strcmp(*argv, "-?"))
  254.     return help(0, "source", cmd_help);
  255.     if (argc && *argv)
  256.     (void) strcpy(file, *argv);
  257.     else if (p = getenv("MAILRC"))
  258.     (void) strcpy(file, p);
  259.     else {
  260.     char *home = do_set(set_options, "home");
  261.     if (!home || !*home)
  262.         home = ALTERNATE_HOME;
  263.     if (Access(sprintf(file, "%s/%s", home, MAILRC), R_OK)
  264.           && Access(sprintf(file, "%s/%s", home, ALTERNATE_RC), R_OK))
  265.     (void) strcpy(file, DEFAULT_RC);
  266.     }
  267.  
  268.     argc = 0; /* don't ignore ENOENT */
  269.     p = getpath(file, &argc);
  270.     if (argc) {
  271.     if (strcmp(file, DEFAULT_RC))
  272.         if (argc == -1)
  273.         print("%s: %s\n", file, p);
  274.         else
  275.         print("%s is a directory.\n", file);
  276.     return -1;
  277.     }
  278.     if (!(fp = fopen(p, "r"))) {
  279.     if (errno != ENOENT)
  280.         error("Can't open %s", p);
  281.     return -1;
  282.     }
  283.     turnon(glob_flags, IGN_BANG); /* ignore ! when reading record files */
  284.     (void) strcpy(file, p);
  285.     (void) src_parse(file, fp, 0, 0, &line_no);
  286.     /* if we entered the routine ignoring !, leave it that way. */
  287.     if (!save_bang)
  288.     turnoff(glob_flags, IGN_BANG);
  289.     /* Sourcing might change things, so abort pipes/macros */
  290.     return 0 - (in_pipe() || in_macro());
  291. }
  292.  
  293. /*
  294.  * Do the actual file parsing for source().  The first argument should
  295.  * be the name of the file referenced by the second argument.  The third
  296.  * argument is used for handling nested if_else_endif expressions.  The
  297.  * fourth argument is used to keep track of the recursion depth, and the
  298.  * last argument keeps track of the line number in the current file.
  299.  *
  300.  * This function calls itself recursively.  It also calls do_command(),
  301.  * which may in turn call source() recursively.
  302.  *
  303.  * If-then-else nesting algorithm:
  304.  *  On any "if" (whether parsing or not), increment if_else
  305.  *  On true "if" when parsing, evaluate by recursion
  306.  *  On false "if" when parsing, set find_else equal to if_else
  307.  *  On any "if" when not parsing, set find_endif equal to if_else
  308.  *  On "else", invert parsing only when find_else equals if_else
  309.  *  When "if" was false and there is nesting, recur for "else"
  310.  *  Skip nested "if...endif" when find_else or find_endif true
  311.  *  On "endif" or when recursion returns, decrement if_else
  312.  *  On "endif", test both find_endif and find_else against if_else:
  313.  *   when either matches, reset that one;
  314.  *   when the lesser (less nested) matches, resume parsing
  315.  *  On "endif", when if_else hits 0, continue (depth 0) or return
  316.  */
  317. src_parse(file, fp, if_else, depth, line_no)
  318. char    *file;
  319. FILE    *fp;
  320. int      if_else, depth, *line_no;
  321. {
  322.     register char *p, *p2, **newargv;
  323.     int       parsing = 1, cont_line = 0;
  324.     int          find_else = 0, find_endif = 0;
  325.     char       line[BUFSIZ];
  326.     int          argc;
  327.  
  328.     while (p = fgets(&line[cont_line], BUFSIZ - cont_line, fp)) {
  329.     (*line_no)++;
  330.     if (*(p2 = no_newln(p)) == '\\') {
  331.         cont_line = p2 - line;
  332.         continue;
  333.     } else
  334.         cont_line = 0;
  335.     /* don't consider comments (#) in lines. check if # is within quotes */
  336.         if (p = any(line, "\"'#")) {
  337.         register int balanced = 1;
  338.         while (p && (*p == '\'' || *p == '"') && balanced) {
  339.         /* first find matching quote */
  340.         register char *quote = index(p+1, *p);
  341.         if (!quote) {
  342.             print("%s: line %d: unbalanced %c.\n", file, *line_no, *p);
  343.             balanced = 0;
  344.         } else
  345.             p = any(quote+1, "'\"#");
  346.         }
  347.         if (!balanced)
  348.         continue;
  349.         if (p && *p == '#')
  350.         *p = 0; /* found a Comment: null terminate line at comment */
  351.     }
  352.     if (!*line || !parsing && !(newargv = mk_argv(line, &argc, 0))
  353.     || parsing && !(newargv = make_command(line, TRPL_NULL, &argc))) {
  354.         if (!strncmp(line, "if", 2))
  355.         find_else = ++if_else, parsing = FALSE;
  356.         continue;
  357.     }
  358.     if (!strcmp(newargv[0], "endif")) {
  359.         if (!if_else)
  360.         print("%s: line %d: endif with no \"if\".\n", file, *line_no);
  361.         else {
  362.         /* If looking for an else or endif, reset parsing */
  363.         if (find_endif && find_endif == if_else) {
  364.             if (find_endif <= find_else || !find_else)
  365.             parsing = 1, find_else = 0;
  366.             find_endif = 0;
  367.         }
  368.         /* Note: find_else never < find_endif */
  369.         if (find_else && find_else == if_else)
  370.             parsing = !parsing, find_else = 0;
  371.         /* Decrement if_else and check depth */
  372.         if (--if_else == 0)
  373.             /* Resume parsing if at the top */
  374.             if (depth == 0)
  375.             parsing = 1;
  376.             /* Return if not at the top */
  377.             else
  378.             return 1;
  379.         }
  380.         goto bad;
  381.     } else if (!strcmp(newargv[0], "else")) {
  382.         if (!if_else)
  383.         print("%s: line %d: if-less \"else\".\n", file, *line_no);
  384.         /* If inside an else, ignore nested else;
  385.          *  otherwise, recur when if_else > 1 */
  386.         else if (!find_else && !find_endif && !parsing) {
  387.         parsing = src_parse(file, fp, 1, depth + 1, line_no);
  388.         --if_else;
  389.         } else if (find_else == if_else || if_else == 1) {
  390.         find_else = 0;
  391.         parsing = !parsing;
  392.         if (!parsing)
  393.             find_endif = if_else;
  394.         }
  395.         goto bad;
  396.     } else if (!strcmp(newargv[0], "if")) {
  397.         /* if statements are of the form:
  398.          *     if expr
  399.          *     if !expr  or  if ! expr
  400.          *     if expr == expr   or   if expr != expr
  401.          */
  402.         int equals = TRUE;
  403.         register char *lhs = newargv[1], *rhs = NULL;
  404.  
  405.         if_else++;
  406.         /* If parsing, set parsing to 0 until
  407.          *  evaluating the "if" proves otherwise.
  408.          * If not parsing, skip to the "endif".
  409.          */
  410.         if (parsing)
  411.         parsing = 0;
  412.         else {
  413.         if (!find_endif)
  414.             find_endif = if_else;
  415.         goto bad;
  416.         }
  417.         if (!lhs || !*lhs) {
  418.         print("%s: line %d: if what?\n", file, *line_no);
  419.         goto bad;
  420.         }
  421.         /* "lhs" is the left hand side of the equation
  422.          * In this instance, we're doing case 2 above (check for negation).
  423.          */
  424.         if (*lhs == '!') {
  425.         if (!*++lhs && !(lhs = newargv[2])) {
  426.             print("%s: line %d: syntax error: \"if ! <what?>\"\n",
  427.             file, *line_no);
  428.             goto bad;
  429.         }
  430.         equals = FALSE;
  431.         }
  432.         if (*lhs == '-' && (lhs[1] == 'e' || lhs[1] == 'z') && !lhs[2]) {
  433.         char *path;
  434.         int n = 1; /* ignore ENOENT, I'll handle it here */
  435.         struct stat statb;
  436.  
  437.         /* check for existence or zero-length folders/files */
  438.         if (argc > 4) {
  439.             print("%s: line %d: if %s \"filename\"\n",
  440.             file, *line_no, lhs);
  441.             goto bad;
  442.         }
  443.         path = getpath(newargv[argc-1], &n);
  444.         parsing = !equals ^ (n == -1 || n == 1 && lhs[1] == 'e' ||
  445.             !stat(path, &statb) && (lhs[1] == 'e' || !statb.st_size));
  446.         } else {
  447.         if (equals && argc > 2) {
  448.             if (argc != 4) {
  449.             print("%s: %d: argument count error: %d args.\n",
  450.                 file, *line_no, argc);
  451.             goto bad;
  452.             }
  453.             /* now check newargv[1] for == or != */
  454.             if (!strcmp(newargv[2], "!="))
  455.             equals = FALSE;
  456.             else if (strcmp(newargv[2], "==")) {
  457.             print("%s: %d: use `==' or `!=' only.\n",
  458.                 file, *line_no);
  459.             goto bad;
  460.             }
  461.             rhs = newargv[3];
  462.         }
  463.         if (!strcmp(lhs, "redirect") &&
  464.               (ison(glob_flags, REDIRECT) && equals ||
  465.                isoff(glob_flags, REDIRECT) && !equals)
  466.             || !strcmp(lhs, "is_sending") &&
  467.               (ison(glob_flags, IS_SENDING) && equals ||
  468.                isoff(glob_flags, IS_SENDING) && !equals)
  469.             || !strcmp(lhs, "hdrs_only") &&
  470.               (hdrs_only && equals || !hdrs_only && !equals)
  471.             || !strcmp(lhs, "istool") &&
  472.               (istool && equals || !istool && !equals)
  473.             || !strcmp(lhs, "iscurses") &&
  474.               ((iscurses || ison(glob_flags, PRE_CURSES)) && equals
  475.               || (isoff(glob_flags, PRE_CURSES) &&
  476.                   !iscurses && !equals)))
  477.             parsing = 1;
  478.         else if (rhs) {
  479.             if (strcmp(lhs, rhs) && !equals
  480.             || !strcmp(lhs, rhs) && equals)
  481.             parsing = 1;
  482.         } else if (isdigit(*lhs))
  483.             parsing = !!(atoi(lhs) ? equals : !equals);
  484.         }
  485.         if (parsing) {
  486.         parsing = src_parse(file, fp, 1, depth + 1, line_no);
  487.         --if_else;
  488.         }
  489.         else
  490.         find_else = if_else; /* Look for a matching else */
  491. bad:
  492.         free_vec(newargv);
  493.         continue;
  494.     }
  495.     if (parsing && argc > 0)
  496.         if (!strcmp(newargv[0], "exit")) {
  497.         if_else = find_else = find_endif = 0;
  498.         break;
  499.         } else
  500.         (void) do_command(argc, newargv, msg_list);
  501.     else
  502.         free_vec(newargv);
  503.     }
  504.     if (if_else)
  505.     print("%s: missing endif\n", file);
  506.     if (depth == 0)
  507.     fclose(fp);
  508.     else
  509.     fseek(fp, 0L, 2); /* Skip ahead to the end */
  510.     return 0;
  511. }
  512.  
  513. #ifdef SUNTOOL
  514. /* open all fonts and place in fonts array. */
  515. getfonts()
  516. {
  517.     char tmp[80];
  518.     register int offset = strlen(FONTDIR) + 1;
  519.     struct pixfont *pf_open();
  520.  
  521.     (void) sprintf(tmp, "%s/", FONTDIR);
  522.     for (total_fonts = 0; total_fonts < MAX_FONTS; total_fonts++) {
  523.     (void) strcpy(&tmp[offset], font_files[total_fonts]);
  524.     if (!(fonts[total_fonts] = pf_open(tmp))) {
  525.         (void) strcpy(&tmp[offset], alt_fonts[total_fonts]);
  526.         if (!(fonts[total_fonts] = pf_open(tmp))) {
  527.         print("couldn't open font \"%s\"\n", tmp);
  528.         fonts[total_fonts] = pf_default();
  529.         }
  530.     }
  531.     }
  532. }
  533. #endif /* SUNTOOL */
  534.