home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part04 / setopts.c < prev   
Encoding:
C/C++ Source or Header  |  1988-04-12  |  10.7 KB  |  414 lines

  1. /* setopts.c    (c) copyright 1986 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. /* add an option indicated by "set option[=value]" or by "alias name alias" 
  6.  * function is recursive, so multilists get appended accordingly
  7.  */
  8. add_option(list, argv)
  9. register struct options **list;
  10. register char **argv;
  11. {
  12.     register struct options *tmp;
  13.     struct options *calloc();
  14.     register char *option, *value = NULL;
  15.  
  16.     if (!(option = *argv))
  17.     return 1;
  18.     /* check for one of three forms:
  19.      * option=value    option = value  option= value
  20.      * value can be in quotes to preserve whitespace
  21.      */
  22.     if (*++argv && !strcmp(*argv, "=")) {
  23.     if (value = *++argv) /* example: "set foo = " */
  24.         ++argv;
  25.     } else if (value = index(option, '=')) {
  26.     /* option=value  strip into option="option" value="value"; (quotes?) */
  27.     register char c, *p2;
  28.     *value = 0; /* option is now a null termined `option' */
  29.     if ((c = *++value) == '"' || c == '\'') {
  30.         *value++ = 0;
  31.         if (!(p2 = index(value, c))) {
  32.         print("No matching %c for %s.\n", c, option);
  33.         return 0;
  34.         } else
  35.         *p2 = 0;
  36.     } else if (!c) {  /* example: "set crt=" */
  37.         if (!*argv) {
  38.         print("No value for %s.\n", option);
  39.         return 0;
  40.         }
  41.         value = *argv++;
  42.     }
  43.     }
  44.     /* check to see if option is already set by attempting to unset it */
  45.     (void) un_set(list, option);
  46.  
  47.     /* now make a new option struct and set fields */
  48.     if (!(tmp = calloc((unsigned)1, sizeof(struct options)))) {
  49.     error("calloc");
  50.     return -1;
  51.     }
  52.     tmp->option = savestr(option);
  53.     tmp->value = savestr(value); /* strdup handles the NULL case */
  54.  
  55.     tmp->next = *list;
  56.     *list = tmp;
  57.  
  58.     /* check for options which must have values or are used frequently */
  59.     if (*list == set_options) {
  60. #if defined(CURSES) || defined(SUNTOOL)
  61.     if (!strcmp(tmp->option, "no_reverse"))
  62.         turnoff(glob_flags, REV_VIDEO);
  63.     else
  64. #endif /* CURSES || SUNTOOL */
  65.     if (!strcmp(tmp->option, "prompt"))
  66.         prompt = (tmp->value)? tmp->value : DEF_PROMPT;
  67.     else if (!strcmp(tmp->option, "mil_time"))
  68.         turnon(glob_flags, MIL_TIME);
  69.     else if (!strcmp(tmp->option, "escape"))
  70.         escape = (tmp->value)? tmp->value : DEF_ESCAPE;
  71.     else if (!strcmp(tmp->option, "hdr_format"))
  72.         hdr_format = (tmp->value)? tmp->value : DEF_HDR_FMT;
  73.     else if (!strcmp(tmp->option, "crt")) {
  74.         if (!istool)
  75.         crt = (tmp->value)? max(atoi(tmp->value), 2): 18;
  76.     } else if (!strcmp(tmp->option, "screen")) {
  77.         screen = (tmp->value)? max(atoi(tmp->value), 1): 18;
  78. #ifdef CURSES
  79.         if (iscurses && screen > LINES-2)
  80.         screen = LINES-2;
  81. #endif /* CURSES */
  82.     } else if (!strcmp(tmp->option, "history"))
  83.         init_history((value && *value)? atoi(value) : 1);
  84.     }
  85.  
  86.     if (*argv)
  87.     return add_option(list, argv);
  88.     return 1;
  89. }
  90.  
  91. /*
  92.  * If str is NULL, just print options and their values. Note that numerical
  93.  * values are not converted to int upon return.  If str is not NULL
  94.  * return the string that matched, else return NULL;
  95.  */
  96. char *
  97. do_set(list, str)
  98. register struct options *list;
  99. register char *str;
  100. {
  101.     register struct options *opts;
  102. #ifdef SUNTOOL
  103.     int x,y;
  104.  
  105.     if (istool && !str)
  106.     y = 10 + 2 * l_height(LARGE);
  107. #endif /* SUNTOOL */
  108.  
  109.     if (!str && !istool)
  110.     (void) do_pager(NULL, TRUE); /* page using internal pager */
  111.  
  112.     for (opts = list; opts; opts = opts->next)
  113.     if (!str) {
  114. #ifdef SUNTOOL
  115.         if (istool)
  116.         pw_text(msg_win, 5, y, PIX_SRC, fonts[DEFAULT], opts->option);
  117.         else
  118. #endif /* SUNTOOL */
  119.         (void) do_pager(opts->option, FALSE);
  120.         if (opts->value)
  121. #ifdef SUNTOOL
  122.         if (istool) {
  123.             x = 30*l_width(DEFAULT);
  124.             pw_text(msg_win, x,y, PIX_SRC, fonts[DEFAULT], opts->value);
  125.             pw_text(msg_win, x+1, y, PIX_SRC|PIX_DST,
  126.                  fonts[DEFAULT], opts->value);
  127.             x += strlen(opts->value)*l_width(DEFAULT);
  128.         } else
  129. #endif /* SUNTOOL */
  130.         {
  131.             (void) do_pager("     \t", FALSE);
  132.             (void) do_pager(opts->value, FALSE);
  133.         }
  134. #ifdef SUNTOOL
  135.         if (istool)
  136.         Clrtoeol(msg_win, x, y, DEFAULT), y += l_height(DEFAULT);
  137.         else
  138. #endif /* SUNTOOL */
  139.         if (do_pager("\n", FALSE) == EOF)
  140.             break;
  141.     } else {
  142.         if (strcmp(str, opts->option))
  143.         continue;
  144.         if (opts->value)
  145.         return opts->value;
  146.         else
  147.         return "";
  148.     }
  149.  
  150.     if (!str && !istool)
  151.     (void) do_pager(NULL, FALSE); /* terminate internal pager */
  152.  
  153.     /* if we still haven't matched, check for environment vars */
  154.     if (str && list == set_options) {
  155.     register int N, n;
  156.     for (N = 0; environ[N]; N++) {
  157.         char *p = index(environ[N], '=');
  158.         if (p)
  159.         *p = 0;
  160.         n = lcase_strcmp(str, environ[N]);
  161.         if (p)
  162.         *p = '=';
  163.         if (!n)
  164.         return p+1;
  165.     }
  166.     }
  167.     return NULL;
  168. }
  169.  
  170. /*
  171.  * unset the variable described by p in the list "list".
  172.  * if the variable isn't set, then return 0, else return 1.
  173.  */
  174. un_set(list, p)
  175. register struct options **list;
  176. register char *p;
  177. {
  178.     register struct options *opts = *list, *tmp;
  179.  
  180.     if (!list || !*list || !p || !*p)
  181.     return 0;
  182.     if (*list == set_options) {
  183. #if defined(CURSES) || defined(SUNTOOL)
  184.     if (!strcmp(p, "no_reverse"))
  185.         turnon(glob_flags, REV_VIDEO);
  186.     else
  187. #endif /* CURSES || SUNTOOL */
  188.     if (!strcmp(p, "prompt"))
  189.         prompt = DEF_PROMPT;
  190.     else if (!strcmp(p, "mil_time"))
  191.         turnoff(glob_flags, MIL_TIME);
  192.     else if (!strcmp(p, "escape"))
  193.         escape = DEF_ESCAPE;
  194.     else if (!strcmp(p, "hdr_format"))
  195.         hdr_format = DEF_HDR_FMT;
  196.     else if (!strcmp(p, "crt"))
  197.         crt = 18;
  198.     else if (!strcmp(p, "screen")) {
  199.         screen = 18;
  200. #ifdef CURSES
  201.         if (iscurses && screen > LINES-2)
  202.         screen = LINES-2;
  203. #endif /* CURSES */
  204.     } else if (!strcmp(p, "history"))
  205.         init_history(1);
  206.     }
  207.  
  208.     if (!strcmp(p, opts->option)) {
  209.     *list = (*list)->next;
  210.     xfree (opts->option);
  211.     if (opts->value)
  212.         xfree(opts->value);
  213.     xfree((char *)opts);
  214.     return 1;
  215.     }
  216.     for ( ; opts->next; opts = opts->next)
  217.     if (!strcmp(p, opts->next->option)) {
  218.         tmp = opts->next;
  219.         opts->next = opts->next->next;
  220.         xfree (tmp->option);
  221.         if (tmp->value)
  222.         xfree(tmp->value);
  223.         xfree ((char *)tmp);
  224.         return 1;
  225.     }
  226.     return 0;
  227. }
  228.  
  229. /* The functions below return -1 since they don't affect
  230.  * messages. This prevents piping from do_loop().
  231.  */
  232. set(n, argv)
  233. register int n;
  234. register char **argv;
  235. {
  236.     char firstchar = **argv;
  237.     register char *cmd = *argv;
  238.     register struct options **list;
  239.  
  240.     if (*cmd == 'u')
  241.     cmd += 2;
  242.     if (*++argv && !strcmp(*argv, "-?"))
  243.     return help(0, (*cmd == 'i')? "ignore": "set", cmd_help);
  244.     if (*argv && **argv == '?') {
  245.     char buf[BUFSIZ];
  246.     int incurses;
  247.     if (!strcmp(*argv, "?all")) {
  248.         if (incurses = iscurses) /* assign and compare to TRUE */
  249.         clr_bot_line(), iscurses = FALSE;
  250.         (void) do_pager(NULL, TRUE); /* start internal pager */
  251.         for (n = 0; variable_stuff(n, NULL, buf); n++)
  252.         if (do_pager(strcat(buf, "\n"), FALSE) == EOF)
  253.             break;
  254.         (void) do_pager(NULL, FALSE); /* terminate pager */
  255.         iscurses = incurses;
  256.     } else {
  257.         /* May return null if variable not set. */
  258.         (void) variable_stuff(0, (*argv)+1, buf);
  259.         print("%s\n", buf);
  260.     }
  261.     return -1;
  262.     }
  263.  
  264.     if (firstchar == 'u') {
  265.     if (!*argv)
  266.         print("%s what?\n", cmd);
  267.     else {
  268.         list = (*cmd == 'i')? &ignore_hdr : &set_options;
  269.         do  if (!strcmp(*argv, "*"))
  270.             while (*list)
  271.             (void) un_set(list, (*list)->option);
  272.         else if (!un_set(list, *argv))
  273.             print("un%s: %s not set\n",
  274.             (*cmd == 'i')? "ignore" : "set", *argv);
  275.         while (*++argv);
  276.     }
  277.     return -1;
  278.     }
  279.     if (!*argv)
  280.     (void) do_set((*cmd == 'i')? ignore_hdr: set_options, NULL);
  281.     else
  282.     (void) add_option((*cmd == 'i')? &ignore_hdr: &set_options, argv);
  283.     return -1;
  284. }
  285.  
  286. alts(argc, argv)
  287. register char **argv;
  288. {
  289.     char buf[256], buf2[256], *p;
  290.     u_long save_bang = ison(glob_flags, IGN_BANG);
  291.  
  292.     if (argc && *++argv && !strcmp(*argv, "-?"))
  293.     return help(0, "alts_help", cmd_help);
  294.     if (argc > 1) {
  295.     (void) argv_to_string(buf2, argv);
  296.     (void) sprintf(buf, "set alternates=\"%s\"",  buf2);
  297.     turnon(glob_flags, IGN_BANG);
  298.     if (argv = make_command(buf, TRPL_NULL, &argc))
  299.         (void) do_command(argc, argv, msg_list);
  300.     if (!save_bang)
  301.         turnoff(glob_flags, IGN_BANG);
  302.     } else
  303.     if (!(p = do_set(set_options, "alternates")))
  304.         print("No alternate hostnames set.\n");
  305.     else
  306.         print("Alternate hostnames: %s\n", p);
  307.     return -1;
  308. }
  309.  
  310. save_opts(cnt, argv)
  311. char **argv;
  312. {
  313.     char file[256], *tmp;
  314.     register FILE *fp;
  315.  
  316.     if (cnt && *++argv && !strcmp(*argv, "-?"))
  317.     return help(0, "source_help", cmd_help);
  318.     if (cnt && *argv)
  319.     (void) strcpy(file, *argv);
  320.     else if (tmp = getenv("MAILRC"))
  321.     (void) strcpy(file, tmp);
  322.     else {
  323.     char *home = do_set(set_options, "home");
  324.     if (!home || !*home)
  325.         home = ALTERNATE_HOME;
  326.     /* if .musrc doesn't exist, check .mailrc. If neither, force .mushrc */
  327.     if (Access(sprintf(file, "%s/%s", home, MAILRC), F_OK) &&
  328.             Access(sprintf(file, "%s/%s", home, ALTERNATE_RC), F_OK))
  329.         (void) sprintf(file, "%s/%s", home, MAILRC);
  330.     }
  331.  
  332.     cnt = 1;
  333.     tmp = getpath(file, &cnt);
  334.     if (cnt) {
  335.     if (cnt == -1)
  336.         print("%s: %s\n", file, tmp);
  337.     else
  338.         print("%s is a directory.\n", tmp);
  339.     return -1;
  340.     }
  341.     /* See if the file exists and confirm overwrite */
  342.     if (!Access(tmp, F_OK)) {
  343.     int overwrite = TRUE;
  344.     char buf[4];
  345.     print("\"%s\" exists. Overwrite? ", tmp);
  346.     if (!istool) {
  347.         if (Getstr(buf, 3, 0) <= 0 || lower(*buf) != 'y')
  348.         overwrite = FALSE;
  349.     }
  350. #ifdef SUNTOOL
  351.     else {
  352.         int c = confirm(panel_sw->ts_windowfd);
  353.         if (lower(c) != 'y' && c != MS_LEFT)
  354.         overwrite = FALSE;
  355.     }
  356. #endif /* SUNTOOL */
  357.     if (!overwrite) {
  358.         print("\"%s\" unchanged.\n", tmp);
  359.         return -1;
  360.     }
  361.     }
  362.     if (!(fp = fopen(tmp, "w"))) {
  363.     error("Can't open %s", file);
  364.     return -1;
  365.     }
  366.  
  367.     save_list("basic variable settings", set_options, "set", '=', fp);
  368.  
  369.     save_list("mail headers for outgoing mail", own_hdrs, "my_hdr", 0, fp);
  370.  
  371.     save_list("aliases", aliases, "alias", 0, fp);
  372.  
  373.     save_list("headers to ignore", ignore_hdr, "ignore", ' ', fp);
  374.  
  375.     save_list("command abbreviations", functions, "cmd", ' ', fp);
  376.  
  377.     save_list("command macros for function keys", fkeys, "fkey", ' ', fp);
  378.  
  379.     fclose(fp);
  380.     print("All variables and options saved in %s\n", tmp);
  381.     return -1;
  382. }
  383.  
  384. save_list(title, list, command, equals, fp)
  385. struct options *list;
  386. register char *command, *title, equals;
  387. register FILE *fp;
  388. {
  389.     register struct options *opts;
  390.     register char *p;
  391.  
  392.     if (!list)
  393.     return;
  394.     fprintf(fp, "#\n# %s\n#\n", title);
  395.     for (opts = list; opts; opts = opts->next) {
  396.     fprintf(fp, "%s %s", command, opts->option);
  397.     if (opts->value && *opts->value) {
  398.         register char *quote;
  399.         if (!equals)
  400.         quote = NO_STRING;
  401.         else if (p = any(opts->value, "\"'"))
  402.         if (*p == '\'') quote = "\"";
  403.         else quote = "'";
  404.         else
  405.         if (!any(opts->value, " \t;|"))
  406.             quote = NO_STRING;
  407.         else quote = "'";
  408.         fputc(equals? equals: ' ', fp);
  409.         fprintf(fp, "%s%s%s", quote, opts->value, quote);
  410.     }
  411.     fputc('\n', fp);
  412.     }
  413. }
  414.