home *** CD-ROM | disk | FTP | other *** search
/ ftp.freefriends.org / ftp.freefriends.org.tar / ftp.freefriends.org / arnold / Source / mush.rstevens.tar.gz / mush.tar / viewopts.c < prev    next >
C/C++ Source or Header  |  1990-12-06  |  19KB  |  586 lines

  1. /* @(#)viewopts.c    (c) copyright    10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. struct viewopts {
  6.     char *v_opt;
  7.     char *v_prompt;
  8.     char *v_description;
  9. #ifdef SUNTOOL
  10.     Panel_item v_choice;
  11.     Panel_item v_text;
  12. #endif /* SUNTOOL */
  13. };
  14.  
  15. #ifdef SUNTOOL
  16. short dat_cycle_cursor[] = {
  17.     0x07C0, 0x0FE0, 0x1834, 0x301C, 0x601C, 0x203C, 0x0000, 0x0000,
  18.     0x7808, 0x700C, 0x7018, 0x5830, 0x0FE0, 0x07C0, 0x0000, 0x0000
  19.  
  20. };
  21. mpr_static(cycle,           16, 16, 1, dat_cycle_cursor);
  22. #endif /* SUNTOOL */
  23.  
  24. /*
  25.  * struct contains the option, a prompt if it has a string value, whether
  26.  * or not it applies to non suntools, line mode, or both, and a
  27.  * string describing what the option does. If the prompt string starts
  28.  * with a minus sign, then the value can be set without a value. This
  29.  * is there to indicate to option_line to print a toggle (cycle) pixrect
  30.  * and to print TRUE/FALSE telling whether the value is on or off regardless
  31.  * of it's "string" value.
  32.  */
  33. struct viewopts viewopts[] = {
  34.     { "alwaysignore", NULL,
  35.     "Always ignore the message headers on the 'ignored' list." },
  36.     { "ask", NULL,
  37.     "Prompts for a subject on outgoing mail." },
  38.     { "askcc", NULL,
  39.     "Ask for list of Carbon Copy recipients whenever sending mail." },
  40.     { "autodelete", NULL,
  41.     "Automatically delete ALL READ messages whenever you update mail." },
  42.     { "autoedit", NULL,
  43.     "Automatically enter editor for REPLIES only (not toolmode)." },
  44.     { "autoinclude", NULL,
  45.     "Include a copy of author's message each time you reply to mail." },
  46.     { "autoprint", NULL,
  47.     "Display the next message on the list when you delete a message." },
  48.     { "auto_route", "-Host/Path:",
  49.     "Remove redundant uucp addresses when replying to messages." },
  50.     { "autosign", "-Filename:",
  51.     "Add file (~/.signature if set but no value) at end of all letters." },
  52.     { "autosign2", "Addr:File:",
  53.     "Signature to use for specific addresses. \"addr, ... : <signature>\""},
  54.     { "cdpath", "Path:",
  55.     "Path to search for directories when the \"cd\" command is issued." },
  56.     { "cmd_help", "Path:",
  57.     "Location of the general help file for line and curses modes." },
  58.     { "complete", "Character:",
  59.     "The character typed to cause a word completion to occur." },
  60.     { "compose_icon", "-Filename:",
  61.     "Alternate pixmap to use when compose window is closed to an icon." },
  62.     { "crt", "Lines:",
  63.     "The number of lines a message must have for 'pager' to be invoked." },
  64.     { "crt_win", "Lines:",
  65.     "Lines in the tool mode text subwindow for paging messages." },
  66.     { "curses_help", "-Commands:",
  67.     "List of curses commands whose bindings appear in the help display." },
  68.     { "date_received", NULL,
  69.     "Time displayed for message headers shows date received (or sent)." },
  70.     { "dead", "Filename:",
  71.     "The name of the file to store dead mail (default = ~/dead.letter)." },
  72.     { "domain_route", "-Host/Path:",
  73.     "Cause short-circuiting of domain addresses when auto-routing." },
  74.     { "dot", NULL,
  75.     "Allow \".\" on a line by itself to send letter." },
  76.     { "edit_hdrs", NULL,
  77.     "Allow headers of messages to be edited using your editor." },
  78.     { "editor", "Editor:",
  79.     "Editor for message editing (default = env EDITOR or \"vi\")." },
  80.     { "escape", "Character:",
  81.     "Escape character for extended editing commands (default = ~)." },
  82.     { "fignore", "Patterns:",
  83.     "Filename extensions or patterns ignored in completions." },
  84.     { "folder", "Pathname:",
  85.     "Full pathname to the directory where personal folders are kept." },
  86.     { "fortune", "-Flag:",
  87.     "Add fortune to end of letters.  Flag to \"fortune\" is optional." },
  88.     { "fortunates", "Users:",
  89.     "Those who will receive fortunes if fortune is set (default: All)." },
  90.     { "hdr_format", "Format:",
  91.     "Formatting string for headers.  \"headers -?\" or help hdr_format." },
  92.     { "history", "Number:",
  93.     "How many commands to remember (like csh)." },
  94.     { "hold", NULL,
  95.     "Read but not deleted messages are saved in spool -- not mbox." },
  96.     { "home", "Directory:",
  97.     "The user's home directory." },
  98.     { "hostname", "Hostname:",
  99.     "User-definable name for the name of your machine." },
  100.     { "ignore_bang", NULL,
  101.     "Ignore '!' as a history reference.  Otherwise, escape by: \\!" },
  102.     { "ignoreeof", "-Command:",
  103.     "Ignores ^D as exit, or (if set), execute \"command\"." },
  104.     { "indent_str", "String:",
  105.     "String to offset included messages within your letters." },
  106.     { "in_reply_to", "-String:",
  107.     "When responding to mail, add In-Reply-To: to message headers." },
  108.     { "keepsave", NULL,
  109.     "Prevents messages from being marked as `deleted' when you `save'." },
  110.     { "known_hosts", "Host list:",
  111.     "List of hosts that your site is known to uucp mail to." },
  112.     { "logfile", "Filename:",
  113.     "Log outgoing mail headers only.  Message text not logged." },
  114.     { "mail_icon", "Filename:",
  115.     "Alternate pixmap to use when tool is closed to an icon." },
  116.     { "mbox", "Filename:",
  117.     "Filename to use instead of ~/mbox for default mailbox." },
  118.     { "metoo", NULL,
  119.     "When replying to mail, metoo preserves your name on mailing list." },
  120.     { "mil_time", NULL,
  121.     "24-hour military time format is used whenever a time is printed." },
  122.     { "msg_win", "Lines:",
  123.     "Number of lines in the message composition window for tool mode." },
  124.     { "newline", "-Command:",
  125.     "Ignore RETURN.  If set to a command, execute that command." },
  126.     { "newmail_icon", "Filename:",
  127.     "Alternate icon shown when new mail is available." },
  128.     { "no_expand", NULL,
  129.     "Prevents expansion of Mush aliases in outgoing mail headers." },
  130.     { "no_hdrs", NULL,
  131.     "If set, personalized headers are NOT inserted to outgoing mail." },
  132.     { "no_reverse", NULL,
  133.     "Disables reverse video in curses mode -- uses \"bold\" in tool mode."},
  134.     { "nonobang", NULL,
  135.     "Suppresses errors from unsuccessful history references." },
  136.     { "nosave", NULL,
  137.     "Prevents aborted mail from being saved in $dead." },
  138.     { "output", NULL,
  139.     "The message list produced as output of the last command." },
  140.     { "pager", "Program:",
  141.     "Program name to be used as a pager for messages longer than crt." },
  142.     { "pre_indent_str", "String:",
  143.     "String to precede message text interpolated into message body." },
  144.     { "post_indent_str", "String:",
  145.     "String to succeed message text interpolated into message body." },
  146.     { "print_cmd", "Program:",
  147.     "Alternate program to use to send messages to the printer." },
  148.     { "printer", "Printer:",
  149.     "Printer to send messages to (default = environment PRINTER)." },
  150.     { "prompt", "String:",
  151.     "Your prompt.  \"help prompt\" for more information." },
  152.     { "quiet", "-Conditions:",
  153.     "Turn off verbose messages and error bells in various conditions." },
  154.     { "realname", "Name:",
  155.     "Your real name." },
  156.     { "record", "Filename:",
  157.     "Save all outgoing mail in specified filename." },
  158.     { "reply_to_hdr", "Headers:",
  159.     "List of headers use to construct reply addresses from a message." },
  160.     { "save_empty", NULL,
  161.     "Folders which have all messages deleted are NOT removed on updates." },
  162.     { "screen", "# of Headers:",
  163.     "Number of headers to print in non-suntools (text) mode." },
  164.     { "screen_win", "# of Headers:",
  165.     "Set the size of the header window for the tool mode only." },
  166.     { "show_deleted", NULL,
  167.     "Show deleted messages in headers listings (unused in curses mode)." },
  168.     { "show_hdrs", "Headers:",
  169.     "When displaying a message, show list of \"headers\" only." },
  170.     { "sendmail", "Program:",
  171.     "Program to use to deliver mail instead of using the default."},
  172.     { "sort", "-Option:",
  173.     "Pre-sorting of messages on mush startup (set to valid sort option)." },
  174.     { "squeeze", NULL,
  175.     "When reading messages, squeeze all blank lines into one." },
  176.     { "status", NULL,
  177.     "The success or failure status of the most recent command." },
  178.     { "thisfolder", "Folder:",
  179.     "This read-only variable gives the current folder name." },
  180.     { "tool_help", "Path:",
  181.     "Location of the help file for tool mode."  },
  182.     { "toplines", "Lines:",
  183.     "Number of lines to print of a message for the 'top' command."  },
  184.     { "tmpdir", "Directory:",
  185.     "Directory to use for temporary files used by Mush." },
  186.     { "unix", NULL,
  187.     "Non-mush commands are considered to be UNIX commands." },
  188.     { "verify", NULL,
  189.     "Verify before acting in various situations, such as sending mail." },
  190.     { "visual", "Visual editor:",
  191.     "Visual editor for messages (default = $editor or env VISUAL)."},
  192.     { "warning", NULL,
  193.     "Print warning messages for non-fatal errors." },
  194.     { "wrap", NULL,
  195.     "After referencing last message, message pointer wraps to start." },
  196.     { "wrapcolumn", "-Column to wrap [78]:",
  197.     "Column at which to wrap lines when composing messages." },
  198. };
  199.  
  200. #ifdef SUNTOOL
  201.  
  202. #define OPTIONS_PANEL_WIDTH    550
  203.  
  204. int set_value(), toggle_value(), help_opt();
  205.  
  206. Frame opts_frame;
  207. Panel opts_panel;
  208. Panel_item desc_msg;
  209. Panel_item file_text_item;
  210.  
  211. static void
  212. frame_done()
  213. {
  214. #ifdef SUN_4_0 /* SunOS 4.0+ */
  215.     window_set(opts_frame, WIN_SHOW, FALSE, NULL);
  216. #else /* SUN_4_0 */
  217.     /* not enough fd's to keep it lying around for SunOS 3.X */
  218.     window_destroy(opts_frame);
  219.     opts_frame = (Frame) 0;
  220. #endif /* SUN_4_0 */
  221. }
  222.  
  223. static void
  224. opts_help()
  225. {
  226.     help(0, "options", tool_help);
  227. }
  228.  
  229. static void
  230. opts_save_load(item)
  231. Panel_item item;
  232. {
  233.     int (*func)() = (int (*)())panel_get(item, PANEL_CLIENT_DATA);
  234.     int result;
  235.     char buf[MAXPATHLEN];
  236.     char *argv[3], *file = panel_get_value(file_text_item);
  237.  
  238.     if (!*file) {
  239.     result = (*func)(0, DUBL_NULL);
  240.     file = ".mushrc";
  241.     } else {
  242.     argv[1] = file;
  243.     argv[2] = NULL;
  244.     result = (*func)(2, argv);
  245.     }
  246.     switch (result) {
  247.     case 0:
  248.         sprintf(buf, "%s %s",
  249.         (func == source)? "Loaded options from" : "Saved options to",
  250.         file);
  251.     when -1:
  252.         sprintf(buf, "%s: %s", file, sys_errlist[errno]);
  253.     when -2:
  254.         sprintf(buf, "%s is a directory.", file);
  255.     when -3:
  256.         /* save_opts() returns -3 if user doesn't confirm overwrite */
  257.         strcpy(buf, "Save operation aborted.");
  258.     }
  259.     panel_set(desc_msg, PANEL_LABEL_STRING, buf, NULL);
  260. }
  261.  
  262. static void
  263. unset_opts()
  264. {
  265.     cmd_line("unset *", NULL);
  266. }
  267.  
  268. static void
  269. reset_opts()
  270. {
  271.     source(0, DUBL_NULL);
  272. }
  273.  
  274. /*
  275.  * Public routine which creates a subframe which contains two panels.
  276.  * The first contains options for loading and saving options from a
  277.  * file (text item) and so on... the second panel contains all the items
  278.  * which correspond to each mush variable that exists.
  279.  */
  280. void
  281. view_options()
  282. {
  283.     extern Notify_value fkey_interposer();
  284.     register char *p;
  285.     int count;
  286.  
  287.     if (opts_frame) {
  288.     window_set(opts_frame, WIN_SHOW, TRUE, NULL);
  289.     opts_panel_item(NULL);
  290.     return;
  291.     }
  292. #ifdef SUN_3_5
  293.     if (nopenfiles(0) < 3) {
  294.     ok_box("Too many frames; close one first!\n");
  295.     return;
  296.     }
  297. #endif /* SUN_3_5 */
  298.  
  299.     opts_frame = window_create(tool, FRAME,
  300.     FRAME_DONE_PROC,    frame_done,
  301.     FRAME_LABEL,        "Mush Options",
  302.     FRAME_NO_CONFIRM,    TRUE,
  303.     FRAME_SHOW_LABEL,    TRUE,
  304.     WIN_WIDTH,        OPTIONS_PANEL_WIDTH,
  305.     NULL);
  306.  
  307.     opts_panel = window_create(opts_frame, PANEL,
  308.     WIN_WIDTH,        OPTIONS_PANEL_WIDTH,
  309.     NULL);
  310.     (void) notify_interpose_event_func(opts_panel,
  311.     fkey_interposer, NOTIFY_SAFE);
  312.     panel_create_item(opts_panel, PANEL_BUTTON,
  313.     PANEL_LABEL_IMAGE,
  314.         panel_button_image(opts_panel, "Done", 4, mush_font),
  315.     PANEL_NOTIFY_PROC,    frame_done,
  316.     NULL);
  317.     panel_create_item(opts_panel, PANEL_BUTTON,
  318.     PANEL_LABEL_IMAGE,
  319.         panel_button_image(opts_panel, "Help", 4, mush_font),
  320.     PANEL_NOTIFY_PROC,    opts_help,
  321.     NULL);
  322.     panel_create_item(opts_panel, PANEL_BUTTON,
  323.     PANEL_LABEL_IMAGE,
  324.         panel_button_image(opts_panel, "Save", 4, mush_font),
  325.     PANEL_NOTIFY_PROC,    opts_save_load,
  326.     PANEL_CLIENT_DATA,    save_opts,
  327.     NULL);
  328.     panel_create_item(opts_panel, PANEL_BUTTON,
  329.     PANEL_LABEL_IMAGE,
  330.         panel_button_image(opts_panel, "Load", 4, mush_font),
  331.     PANEL_NOTIFY_PROC,    opts_save_load,
  332.     PANEL_CLIENT_DATA,    source,
  333.     NULL);
  334.     panel_create_item(opts_panel, PANEL_BUTTON,
  335.     PANEL_LABEL_IMAGE,
  336.         panel_button_image(opts_panel, "Clear", 5, mush_font),
  337.     PANEL_NOTIFY_PROC,    unset_opts,
  338.     NULL);
  339.     panel_create_item(opts_panel, PANEL_BUTTON,
  340.     PANEL_LABEL_IMAGE,
  341.         panel_button_image(opts_panel, "Restart", 7, mush_font),
  342.     PANEL_NOTIFY_PROC,    reset_opts,
  343.     NULL);
  344.     file_text_item = panel_create_item(opts_panel, PANEL_TEXT,
  345.     PANEL_LABEL_STRING,    "Save/Load File:",
  346.     PANEL_VALUE_DISPLAY_LENGTH, 30,
  347.     NULL);
  348.     desc_msg = panel_create_item(opts_panel, PANEL_MESSAGE,
  349.     PANEL_LABEL_STRING,    "Help Descriptions -- Click on Variable Name",
  350.     NULL);
  351.     window_fit_height(opts_panel);
  352.  
  353.     /* reuse opts_panel -- we don't need the other one */
  354.     opts_panel = window_create(opts_frame, PANEL,
  355.     WIN_BELOW,            opts_panel,
  356.     WIN_X,                0,
  357.     WIN_COLUMN_GAP,            120,
  358.     WIN_TOP_MARGIN,            10,
  359.     WIN_LEFT_MARGIN,        10,
  360.     WIN_WIDTH,            OPTIONS_PANEL_WIDTH,
  361.     PANEL_VERTICAL_SCROLLBAR,    scrollbar_create(NULL),
  362.     NULL);
  363.     (void) notify_interpose_event_func(opts_panel,
  364.     fkey_interposer, NOTIFY_SAFE);
  365.  
  366.     for (count = 0; count < ArraySize(viewopts); count++) {
  367.     panel_create_item(opts_panel, PANEL_MESSAGE,
  368.         PANEL_ITEM_X,    ATTR_COL(0),
  369.         PANEL_ITEM_Y,    ATTR_ROW(count),
  370.         PANEL_LABEL_STRING,    viewopts[count].v_opt,
  371.         PANEL_NOTIFY_PROC,    help_opt,
  372.         PANEL_CLIENT_DATA,    count,
  373.         NULL);
  374.  
  375.     if (!(p = viewopts[count].v_prompt) || *p == '-') {
  376.         if (p && *p)
  377.         p++;
  378.         viewopts[count].v_choice = panel_create_item(opts_panel,
  379.         PANEL_CHOICE,
  380.         PANEL_LABEL_IMAGE,    &cycle,
  381.         PANEL_LAYOUT,        PANEL_HORIZONTAL,
  382.         PANEL_CHOICE_STRINGS,    "False", "True", NULL,
  383.         PANEL_DISPLAY_LEVEL,    PANEL_CURRENT,
  384.         PANEL_ITEM_X,        ATTR_COL(1),
  385.         PANEL_ITEM_Y,        ATTR_ROW(count),
  386.         PANEL_NOTIFY_PROC,    toggle_value,
  387.         PANEL_CLIENT_DATA,    count,
  388.         NULL);
  389.     }
  390.     if (p) {
  391.         viewopts[count].v_text = panel_create_item(opts_panel, PANEL_TEXT,
  392.         PANEL_VALUE_DISPLAY_LENGTH,    10,
  393.         PANEL_VALUE_UNDERLINED,        TRUE,
  394.         PANEL_LABEL_STRING,        p,
  395.         PANEL_ITEM_X,            ATTR_COL(2),
  396.         PANEL_ITEM_Y,            ATTR_ROW(count),
  397.         PANEL_NOTIFY_PROC,        set_value,
  398.         PANEL_CLIENT_DATA,        count,
  399.         NULL);
  400.     }
  401.     }
  402.     /* set the panel items' values */
  403.     opts_panel_item(NULL);
  404.  
  405.     window_set(opts_panel,
  406.     WIN_HEIGHT,    400,
  407.     WIN_FIT_HEIGHT,    0,
  408.     NULL);
  409.     window_set(opts_frame, WIN_SHOW, TRUE, NULL);
  410. }
  411.  
  412. /*
  413.  * Sets the items in the panels to reflect that variable's value.
  414.  * If "var" is NULL, do it for all the items.
  415.  */
  416. void
  417. opts_panel_item(var)
  418. char *var;
  419. {
  420.     int count;
  421.     char *value;
  422.  
  423.     if (!opts_frame)
  424.     return;
  425.  
  426.     for (count = 0; count < ArraySize(viewopts); count++) {
  427.     if (var && strcmp(var, viewopts[count].v_opt))
  428.         continue;
  429.     value = do_set(set_options, viewopts[count].v_opt);
  430.  
  431.     if (!viewopts[count].v_prompt || *viewopts[count].v_prompt == '-')
  432.         panel_set_value(viewopts[count].v_choice, value != NULL);
  433.     if (viewopts[count].v_prompt)
  434.         panel_set_value(viewopts[count].v_text, value? value : "");
  435.     if (var)
  436.         break;
  437.     }
  438. }
  439.  
  440. /*
  441.  * Callback for choice items -- for variables that have boolean settings.
  442.  * CLIENT_DATA is the index in the viewopts array.
  443.  */
  444. static
  445. toggle_value(item, value)
  446. Panel_item item;
  447. int value;
  448. {
  449.     int count = (int) panel_get(item, PANEL_CLIENT_DATA);
  450.     char *p, *argv[4];
  451.     char *text_value = NULL;
  452.  
  453.     if (check_internal(viewopts[count].v_opt)) {
  454.     panel_set(desc_msg, PANEL_LABEL_STRING,
  455.         "This is an internal variable which cannot be changed.",
  456.         NULL);
  457.     /* can't change it - restore previous setting */
  458.     panel_set_value(viewopts[count].v_choice, !value);
  459.     return -1;
  460.     }
  461.  
  462.     if (p = viewopts[count].v_prompt) /* set equal */
  463.     text_value = panel_get_value(viewopts[count].v_text);
  464.  
  465.     if (!value) {
  466.     if (un_set(&set_options, viewopts[count].v_opt) == -1) {
  467.         /* can't change it - restore previous setting */
  468.         panel_set_value(viewopts[count].v_choice, !value);
  469.         return -1;
  470.     }
  471.     } else {
  472.     /* Turn it on if it's entirely boolean or bool/str, but no str value */
  473.     if (!p || text_value && !*text_value) {
  474.         argv[0] = viewopts[count].v_opt; /* it's a boolean */
  475.         argv[1] = NULL;
  476.     } else {
  477.         /* string value -- determine the text from the typed in value */
  478.         argv[0] = viewopts[count].v_opt;
  479.         argv[1] = "=";
  480.         argv[2] = text_value;
  481.         argv[3] = NULL;
  482.     }
  483.     if (add_option(&set_options, argv) != 1) {
  484.         /* can't change it - restore previous setting */
  485.         panel_set_value(viewopts[count].v_choice, !value);
  486.         return -1;
  487.     }
  488.     }
  489.  
  490.     if (!strcmp(viewopts[count].v_opt, "no_reverse") ||
  491.     !strcmp(viewopts[count].v_opt, "show_deleted"))
  492.     do_hdrs(0, DUBL_NULL, NULL);
  493.  
  494.     return 0;
  495. }
  496.  
  497. /* callback for text items -- set vars to the string typed. */
  498. static
  499. set_value(item, event)
  500. Panel_item item;
  501. Event *event;
  502. {
  503.     int count = (int)panel_get(item, PANEL_CLIENT_DATA);
  504.     char *p, *argv[4], *value;
  505.  
  506.     if (event_id(event) == '\t')
  507.     return (int) PANEL_NEXT;
  508.  
  509.     p = viewopts[count].v_prompt;
  510.     value = panel_get_value(item);
  511.  
  512.     if (check_internal(viewopts[count].v_opt)) {
  513.     panel_set(desc_msg, PANEL_LABEL_STRING,
  514.         "This is an internal variable which cannot be changed.",
  515.         NULL);
  516.     return (int) PANEL_NONE;
  517.     }
  518.  
  519.     /*
  520.      * You can "unset" string-only values by entering a blank string.
  521.      * If the "prompt" starts with a -, then you can only "unset" the
  522.      * variable by setting the associated choice item to false.
  523.      */
  524.     if (*p != '-' && !*value) {
  525.     (void) un_set(&set_options, viewopts[count].v_opt);
  526.     return (int) PANEL_NONE; /* do not advance caret */
  527.     }
  528.     /* Turn it on, but not to a value */
  529.     if (!*value) {
  530.     argv[0] = viewopts[count].v_opt; /* it's a boolean */
  531.     argv[1] = NULL;
  532.     } else {
  533.     /* string value -- determine the text from the typed in value */
  534.     argv[0] = viewopts[count].v_opt;
  535.     argv[1] = "=";
  536.     argv[2] = value;
  537.     argv[3] = NULL;
  538.     }
  539.  
  540.     if (add_option(&set_options, argv) == 1 && p && *p == '-')
  541.     panel_set_value(viewopts[count].v_choice, TRUE);
  542.  
  543.     return (int) PANEL_NONE;
  544. }
  545.  
  546. /* when user clicks on variable label itself */
  547. static
  548. help_opt(item, event)
  549. Panel_item item;
  550. Event *event;
  551. {
  552.     int count = (int)panel_get(item, PANEL_CLIENT_DATA);
  553.  
  554.     panel_set(desc_msg,
  555.     PANEL_LABEL_STRING, viewopts[count].v_description,
  556.     NULL);
  557.     return 0;
  558. }
  559.  
  560. #endif /* SUNTOOL */
  561.  
  562. /*
  563.  * return a string describing a variable.
  564.  * parameters: count, str, buf.
  565.  * If str != NULL, check str against ALL variables
  566.  * in viewopts array.  The one that matches, set count to it and 
  567.  * print up all the stuff from the viewopts[count] into the buffer
  568.  * space in "buf" and return it.
  569.  */
  570. char *
  571. variable_stuff(count, str, buf)
  572. register char *str, *buf;
  573. {
  574.     if (str)
  575.     for (count = 0; count < ArraySize(viewopts); count++)
  576.         if (!strcmp(str, viewopts[count].v_opt))
  577.         break;
  578.     if (count >= ArraySize(viewopts)) {
  579.     (void) sprintf(buf, "%s: Not a default %s variable.",
  580.                str? str : itoa(count), prog_name);
  581.     return NULL;
  582.     }
  583.     return sprintf(buf, "%s: %s",
  584.     viewopts[count].v_opt, viewopts[count].v_description);
  585. }
  586.