home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / mush5.7 / part11 / setopts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-19  |  10.0 KB  |  393 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, "escape"))
  68.         escape = (tmp->value)? tmp->value : DEF_ESCAPE;
  69.     else if (!strcmp(tmp->option, "pager"))
  70.         pager = (tmp->value)? tmp->value : DEF_PAGER;
  71.     else if (!strcmp(tmp->option, "editor"))
  72.         editor = (tmp->value)? tmp->value : DEF_EDITOR;
  73.     else if (!strcmp(tmp->option, "hdr_format"))
  74.         hdr_format = (tmp->value)? tmp->value : DEF_HDR_FMT;
  75.     else if (!strcmp(tmp->option, "visual"))
  76.         visual = (tmp->value)? tmp->value : DEF_EDITOR;
  77.     else if (!strcmp(tmp->option, "crt")) {
  78.         if (!istool)
  79.         crt = (tmp->value)? max(atoi(tmp->value), 1): 18;
  80.     } else if (!strcmp(tmp->option, "screen")) {
  81.         screen = (tmp->value)? max(atoi(tmp->value), 1): 18;
  82. #ifdef CURSES
  83.         if (iscurses && screen > LINES-2)
  84.         screen = LINES-2;
  85. #endif CURSES
  86.     } else if (!strcmp(tmp->option, "history"))
  87.         init_history((value && *value)? atoi(value) : 1);
  88.     }
  89.  
  90.     if (*argv)
  91.     return add_option(list, argv);
  92.     return 1;
  93. }
  94.  
  95. /*
  96.  * If str is NULL, just print options and their values. Note that numerical
  97.  * values are not converted to int upon return.  If str is not NULL
  98.  * return the string that matched, else return NULL;
  99.  */
  100. char *
  101. do_set(list, str)
  102. register struct options *list;
  103. register char *str;
  104. {
  105.     register struct options *opts;
  106. #ifdef SUNTOOL
  107.     int x,y;
  108.  
  109.     if (istool && !str)
  110.     y = 10 + 2 * l_height(LARGE);
  111. #endif SUNTOOL
  112.  
  113.     for (opts = list; opts; opts = opts->next)
  114.     if (!str) {
  115. #ifdef SUNTOOL
  116.         if (istool)
  117.         pw_text(msg_win, 5, y, PIX_SRC, fonts[DEFAULT], opts->option);
  118.         else
  119. #endif SUNTOOL
  120.         fputs(opts->option, stdout);
  121.         if (opts->value)
  122. #ifdef SUNTOOL
  123.         if (istool) {
  124.             x = 30*l_width(DEFAULT);
  125.             pw_text(msg_win, x,y, PIX_SRC, fonts[DEFAULT], opts->value);
  126.             pw_text(msg_win, x+1, y, PIX_SRC|PIX_DST,
  127.                  fonts[DEFAULT], opts->value);
  128.             x += strlen(opts->value)*l_width(DEFAULT);
  129.         } else
  130. #endif SUNTOOL
  131.             printf("     \t%s", opts->value);
  132. #ifdef SUNTOOL
  133.         if (istool)
  134.         Clrtoeol(msg_win, x, y, DEFAULT), y += l_height(DEFAULT);
  135.         else
  136. #endif SUNTOOL
  137.         putchar('\n');
  138.     } else {
  139.         if (strcmp(str, opts->option))
  140.         continue;
  141.         if (opts->value)
  142.         return opts->value;
  143.         else
  144.         return "";
  145.     }
  146.     /* if we still haven't matched, check for environment vars */
  147.     if (str && list == set_options) {
  148.     register int N, n;
  149.     for (N = 0; environ[N]; N++) {
  150.         char *p = index(environ[N], '=');
  151.         if (p)
  152.         *p = 0;
  153.         n = strcmp(str, environ[N]);
  154.         if (p)
  155.         *p = '=';
  156.         if (!n)
  157.         return p+1;
  158.     }
  159.     }
  160.     return NULL;
  161. }
  162.  
  163. /*
  164.  * unset the variable described by p in the list "list".
  165.  * if the variable isn't set, then return 0, else return 1.
  166.  */
  167. un_set(list, p)
  168. register struct options **list;
  169. register char *p;
  170. {
  171.     register struct options *opts = *list, *tmp;
  172.  
  173.     if (!list || !*list || !p || !*p)
  174.     return 0;
  175.     if (*list == set_options) {
  176. #if defined(CURSES) || defined(SUNTOOL)
  177.     if (!strcmp(p, "no_reverse"))
  178.         turnon(glob_flags, REV_VIDEO);
  179.     else
  180. #endif /* CURSES || SUNTOOL */
  181.     if (!strcmp(p, "prompt"))
  182.         prompt = DEF_PROMPT;
  183.     else if (!strcmp(p, "escape"))
  184.         escape = DEF_ESCAPE;
  185.     else if (!strcmp(p, "pager"))
  186.         pager = DEF_PAGER;
  187.     else if (!strcmp(p, "editor"))
  188.         editor = DEF_EDITOR;
  189.     else if (!strcmp(p, "visual"))
  190.         visual = DEF_EDITOR;
  191.     else if (!strcmp(p, "hdr_format"))
  192.         hdr_format = DEF_HDR_FMT;
  193.     else if (!strcmp(p, "crt"))
  194.         crt = 18;
  195.     else if (!strcmp(p, "screen")) {
  196.         screen = 18;
  197. #ifdef CURSES
  198.         if (iscurses && screen > LINES-2)
  199.         screen = LINES-2;
  200. #endif CURSES
  201.     } else if (!strcmp(p, "history"))
  202.         init_history(1);
  203.     }
  204.  
  205.     if (!strcmp(p, opts->option)) {
  206.     *list = (*list)->next;
  207.     xfree (opts->option);
  208.     if (opts->value)
  209.         xfree(opts->value);
  210.     xfree((char *)opts);
  211.     return 1;
  212.     }
  213.     for ( ; opts->next; opts = opts->next)
  214.     if (!strcmp(p, opts->next->option)) {
  215.         tmp = opts->next;
  216.         opts->next = opts->next->next;
  217.         xfree (tmp->option);
  218.         if (tmp->value)
  219.         xfree(tmp->value);
  220.         xfree ((char *)tmp);
  221.         return 1;
  222.     }
  223.     return 0;
  224. }
  225.  
  226. /* The functions below return -1 since they don't affect
  227.  * messages. This prevents piping from do_loop().
  228.  */
  229. set(n, argv)
  230. register int n;
  231. register char **argv;
  232. {
  233.     char firstchar = **argv;
  234.     register char *cmd = *argv;
  235.     register struct options **list;
  236.  
  237.     if (*cmd == 'u')
  238.     cmd += 2;
  239.     if (*++argv && !strcmp(*argv, "-?"))
  240.     return help(0, (*cmd == 'i')? "ignore": "set", cmd_help);
  241.     if (*argv && **argv == '?') {
  242.     char buf[BUFSIZ];
  243.     if (!strcmp(*argv, "?all")) {
  244.         FILE *pp = NULL_FILE;
  245.         turnon(glob_flags, IGN_SIGS);
  246.         echo_on();
  247.         if (!istool && !(pp = popen(pager, "w")))
  248.         error(pager);
  249.         for (n = 0; variable_stuff(n, NULL, buf); n++)
  250.         if (pp)
  251.             fprintf(pp, "%s\n", buf);
  252.         else
  253.             print("%s\n", buf);
  254.         if (pp)
  255.         pclose(pp);
  256.         echo_off();
  257.         turnoff(glob_flags, IGN_SIGS);
  258.     } else {
  259.         (void) variable_stuff(0, (*argv)+1, buf);
  260.         wprint("%s\n", buf);
  261.     }
  262.     return -1;
  263.     }
  264.  
  265.     if (firstchar == 'u') {
  266.     if (!*argv)
  267.         print("%s what?\n", cmd);
  268.     else {
  269.         list = (*cmd == 'i')? &ignore_hdr : &set_options;
  270.         do  if (!strcmp(*argv, "*"))
  271.             while (*list)
  272.             (void) un_set(list, (*list)->option);
  273.         else if (!un_set(list, *argv))
  274.             print("un%s: %s not set\n",
  275.             (*cmd == 'i')? "ignore" : "set", *argv);
  276.         while (*++argv);
  277.     }
  278.     return -1;
  279.     }
  280.     if (!*argv)
  281.     (void) do_set((*cmd == 'i')? ignore_hdr: set_options, NULL);
  282.     else
  283.     (void) add_option((*cmd == 'i')? &ignore_hdr: &set_options, argv);
  284.     return -1;
  285. }
  286.  
  287. alts(argc, argv)
  288. register char **argv;
  289. {
  290.     char buf[256], buf2[256], *p;
  291.     long save_bang = ison(glob_flags, IGN_BANG);
  292.  
  293.     if (argc && *++argv && !strcmp(*argv, "-?"))
  294.     return help(0, "alts_help", cmd_help);
  295.     if (argc > 1) {
  296.     (void) argv_to_string(buf2, argv);
  297.     (void) sprintf(buf, "set alternates=\"%s\"",  buf2);
  298.     turnon(glob_flags, IGN_BANG);
  299.     if (argv = make_command(buf, TRPL_NULL, &argc))
  300.         (void) do_command(argc, argv, msg_list);
  301.     if (!save_bang)
  302.         turnoff(glob_flags, IGN_BANG);
  303.     } else
  304.     if (!(p = do_set(set_options, "alternates")))
  305.         print("No alternate hostnames set.\n");
  306.     else
  307.         print("Alternate hostnames: %s\n", p);
  308.     return -1;
  309. }
  310.  
  311. save_opts(cnt, argv)
  312. char **argv;
  313. {
  314.     char file[50], *tmp;
  315.     register FILE *fp;
  316.  
  317.     if (cnt && *++argv && !strcmp(*argv, "-?"))
  318.     return help(0, "source_help", cmd_help);
  319.     if (cnt && *argv)
  320.     (void) strcpy(file, *argv);
  321.     else if (tmp = getenv("MAILRC"))
  322.     (void) strcpy(file, tmp);
  323.     else {
  324.     char *home = do_set(set_options, "home");
  325.     if (!home || !*home)
  326.         home = ALTERNATE_HOME;
  327.     if (access(sprintf(file, "%s/%s", home, MAILRC), R_OK)
  328.           && access(sprintf(file, "%s/%s", home, ALTERNATE_RC), R_OK))
  329.     (void) strcpy(file, DEFAULT_RC);
  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.     if (!(fp = fopen(tmp, "w"))) {
  342.     error("Can't open %s", file);
  343.     return -1;
  344.     }
  345.  
  346.     save_list("basic variable settings", set_options, "set", '=', fp);
  347.  
  348.     save_list("mail headers for outgoing mail", own_hdrs, "my_hdr", 0, fp);
  349.  
  350.     save_list("aliases", aliases, "alias", 0, fp);
  351.  
  352.     save_list("headers to ignore", ignore_hdr, "ignore", ' ', fp);
  353.  
  354.     save_list("command abbreviations", functions, "cmd", ' ', fp);
  355.  
  356.     save_list("command macros for function keys", fkeys, "fkey", ' ', fp);
  357.  
  358.     fclose(fp);
  359.     print("All variables and options saved in %s\n", tmp);
  360.     return -1;
  361. }
  362.  
  363. save_list(title, list, command, equals, fp)
  364. struct options *list;
  365. register char *command, *title, equals;
  366. register FILE *fp;
  367. {
  368.     register struct options *opts;
  369.     register char *p;
  370.  
  371.     if (!list)
  372.     return;
  373.     fprintf(fp, "#\n# %s\n#\n", title);
  374.     for (opts = list; opts; opts = opts->next) {
  375.     fprintf(fp, "%s %s", command, opts->option);
  376.     if (opts->value && *opts->value) {
  377.         register char *quote;
  378.         if (!equals)
  379.         quote = NO_STRING;
  380.         else if (p = any(opts->value, "\"'"))
  381.         if (*p == '\'') quote = "\"";
  382.         else quote = "'";
  383.         else
  384.         if (!any(opts->value, " \t;|"))
  385.             quote = NO_STRING;
  386.         else quote = "'";
  387.         fputc(equals? equals: ' ', fp);
  388.         fprintf(fp, "%s%s%s", quote, opts->value, quote);
  389.     }
  390.     fputc('\n', fp);
  391.     }
  392. }
  393.