source: variable.c @ 3b0edaa

release-1.6release-1.7release-1.8release-1.9
Last change on this file since 3b0edaa was 3b0edaa, checked in by Anders Kaseorg <andersk@mit.edu>, 11 years ago
Rename owl_variable_free to owl_variable_delete. Signed-off-by: Anders Kaseorg <andersk@mit.edu> Reviewed-by: Nelson Elhage <nelhage@mit.edu>
  • Property mode set to 100644
File size: 35.7 KB
RevLine 
[7d4fbcd]1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <ctype.h>
6#include "owl.h"
7
[aa2f33b3]8#define OWLVAR_BOOL(name,default,summary,description) \
9        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
[c1d9441]10        NULL, NULL, NULL, NULL, NULL, NULL }
[7d4fbcd]11
[aa2f33b3]12#define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
13        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
[c1d9441]14        validate, set, NULL, get, NULL, NULL }
[7d4fbcd]15
[aa2f33b3]16#define OWLVAR_INT(name,default,summary,description) \
17        { name, OWL_VARIABLE_INT, NULL, default, "<int>", summary,description, NULL, \
[7d4fbcd]18        NULL, NULL, NULL, NULL, NULL, NULL }
19
[aa2f33b3]20#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
21        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
[7d4fbcd]22        validate, set, NULL, get, NULL, NULL }
23
[aa2f33b3]24#define OWLVAR_PATH(name,default,summary,description) \
25        { name, OWL_VARIABLE_STRING, default, 0, "<path>", summary,description,  NULL, \
[7d4fbcd]26        NULL, NULL, NULL, NULL, NULL, NULL }
27
[aa2f33b3]28#define OWLVAR_STRING(name,default,summary,description) \
29        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
[7d4fbcd]30        NULL, NULL, NULL, NULL, NULL, NULL }
31
[c01e477]32#define OWLVAR_STRING_FULL(name,default,summary,description,validate,set,get) \
33        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
34        validate, set, NULL, get, NULL, NULL }
35
[7d4fbcd]36/* enums are really integers, but where validset is a comma-separated
37 * list of strings which can be specified.  The tokens, starting at 0,
38 * correspond to the values that may be specified. */
[aa2f33b3]39#define OWLVAR_ENUM(name,default,summary,description,validset) \
40        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
[7d4fbcd]41        owl_variable_enum_validate, \
42        NULL, owl_variable_enum_set_fromstring, \
43        NULL, owl_variable_enum_get_tostring, \
44        NULL }
45
[aa2f33b3]46#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
47        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
[217a43e]48        validate, \
49        set, owl_variable_enum_set_fromstring, \
50        get, owl_variable_enum_get_tostring, \
51        NULL }
52
[7d4fbcd]53static owl_variable variables_to_init[] = {
54
[5d365f6]55  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
[213a3eb]56                 "ring the terminal bell when personal messages are received",
[5d365f6]57                 "Can be set to 'on', 'off', or the name of a filter which\n"
58                 "messages need to match in order to ring the bell"),
[7d4fbcd]59
60  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
[aa2f33b3]61               "enable / disable the terminal bell", "" ),
[7d4fbcd]62
63  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
64                    "whether debugging is enabled",
[aa2f33b3]65                    "If set to 'on', debugging messages are logged to the\n"
66                    "file specified by the debugfile variable.\n",
[7d4fbcd]67                    NULL, owl_variable_debug_set, NULL),
68
69  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
[aa2f33b3]70               "send a login message when owl starts", "" ),
[7d4fbcd]71
72  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
[aa2f33b3]73               "send a logout message when owl exits", "" ),
[7d4fbcd]74
75  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
[aa2f33b3]76               "display received pings", "" ),
[7d4fbcd]77
78  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
[aa2f33b3]79               "send pings", "" ),
[7d4fbcd]80
[73624b4]81  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
[451db9e]82               "disable printing information in the separator bar", "" ),
[73624b4]83
[f9c43ae]84  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
85               "strip kerberos instance for reply", ""),
86
[7e3e00a]87  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
88               "strip leading and trailing newlines", ""),
89
[7d4fbcd]90  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
[aa2f33b3]91               "display outgoing messages", "" ),
[7d4fbcd]92
93  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
[aa2f33b3]94               "load logins from .anyone on startup", "" ),
[7d4fbcd]95
96  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
[aa2f33b3]97               "turn personal logging on or off", 
98               "If this is set to on, personal messages are\n"
99               "logged in the directory specified\n"
100               "by the 'logpath' variable.  The filename in that\n"
101               "directory is derived from the sender of the message.\n" ),
[7d4fbcd]102
103  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
[aa2f33b3]104               "turn class logging on or off",
105               "If this is set to on, class messages are\n"
106               "logged in the directory specified\n"
107               "by the 'classlogpath' variable.\n" 
108               "The filename in that directory is derived from\n"
109               "the name of the class to which the message was sent.\n" ),
[7d4fbcd]110
[12c35df]111  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
112               "specifices which kind of messages should be logged",
113               "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
114               "selected, only incoming messages are logged, if 'out'\n"
115               "is selected only outgoing messages are logged.  If 'both'\n"
116               "is selected both incoming and outgoing messages are\n"
117               "logged.",
118               "both,in,out"),
119
[e1c4636]120  OWLVAR_BOOL( "colorztext" /* %OwlVarStub */, 1,
[aa2f33b3]121               "allow @color() in zephyrs to change color",
122               "Note that only messages received after this variable\n"
123               "is set will be affected." ),
[e1c4636]124
[c15bbfb]125  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
126               "Use 'nice' line drawing on the terminal.",
127               "If turned off, dashes, pipes and pluses will be used\n"
128               "to draw lines on the screen.  Useful when the terminal\n"
129               "is causing problems" ),
130
[d309eb3]131  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
132               "Do automatic zcrypt processing",
133               "" ),
134
[4357be8]135  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
136                    "Enable zephyr pseudo logins",
137                    "When this is enabled, Owl will periodically check the zephyr\n"
138                    "location of users in your .anyone file.  If a user is present\n"
139                    "but sent no login message, or a user is not present that sent no\n"
[451db9e]140                    "logout message, a pseudo login or logout message wil be created\n",
[4357be8]141                    NULL, owl_variable_pseudologins_set, NULL),
[5a95b69]142
[280ddc6]143  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
144               "Enable printing of login notifications",
145               "When this is enabled, Owl will print login and logout notifications\n"
[3038d13]146               "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
147               "login or logout notifications.\n"),
[280ddc6]148
[15b34fd]149  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
150                 "name of a filter controlling which messages to log",
151
152                 "If non empty, any messages matching the given filter will be logged.\n"
153                 "This is a completely separate mechanisim from the other logging\n"
154                 "variables like logging, classlogging, loglogins, loggingdirection,\n"
155                 "etc.  If you want this variable to control all logging, make sure\n"
156                 "all other logging variables are in their default state.\n"),
157
[e22f27c]158  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
159               "Enable logging of login notifications",
160               "When this is enabled, Owl will login login and logout notifications\n"
161               "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
162               "login or logout notifications.\n"),
163
[217a43e]164  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
[aa2f33b3]165                    "don't send zephyrs on C-d",
166                    "If set to 'off', C-d won't send a zephyr from the edit\n"
167                    "window.  If set to 'on', C-d will always send a zephyr\n"
168                    "being composed in the edit window.  If set to 'middle',\n"
169                    "C-d will only ever send a zephyr if the cursor is at\n"
170                    "the end of the message being composed.\n\n"
171                    "Note that this works by changing the C-d keybinding\n"
172                    "in the editmulti keymap.\n",
173                    "off,middle,on",
[7d4fbcd]174                    NULL, owl_variable_disable_ctrl_d_set, NULL),
175
176  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
[aa2f33b3]177               "path for logging personal zephyrs", 
178               "Specifies a directory which must exist.\n"
179               "Files will be created in the directory for each sender.\n"),
[7d4fbcd]180
181  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
[aa2f33b3]182               "path for logging class zephyrs",
183               "Specifies a directory which must exist.\n"
184               "Files will be created in the directory for each class.\n"),
[7d4fbcd]185
186  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
[aa2f33b3]187               "path for logging debug messages when debugging is enabled",
188               "This file will be logged to if 'debug' is set to 'on'.\n"),
[7d4fbcd]189 
[ced25d1]190  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
[aa2f33b3]191               "name of a program to run that will generate zsigs",
192               "This program should produce a zsig on stdout when run.\n"
[81a96af]193               "Note that it is important that this program not block.\n\n"
194               "See the documentation for 'zsig' for more information about\n"
195               "how the outgoing zsig is chosen."
196               ),
[7d4fbcd]197
[700c712]198  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
199               "name of a program to run when new messages are present",
200               "The named program will be run when owl recevies new.\n"
201               "messages.  It will not be run again until the first\n"
202               "instance exits"),
203
[247cbc9]204  OWLVAR_STRING( "zsender" /* %OwlVarStub */, "",
205             "zephyr sender name",
206         "Allows you to customize the outgoing username in\n"
207         "zephyrs.  If this is unset, it will use your Kerberos\n"
208         "principal. Note that customizing the sender name will\n"
209         "cause your zephyrs to be sent unauthenticated."),
210
[de3f641]211  OWLVAR_STRING( "zsigfunc" /* %OwlVarStub */, "BarnOwl::default_zephyr_signature()",
212                 "zsig perl function",
213                 "Called every time you start a zephyrgram without an\n"
214                 "explicit zsig.  The default setting implements the policy\n"
215                 "descripted in the documentation for the 'zsig' variable.\n"),
216
[7d4fbcd]217  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
[81a96af]218                 "zephyr signature",
219                 "The zsig to get on outgoing messages. If this variable is\n"
220                 "unset, 'zsigproc' will be run to generate a zsig. If that is\n"
221                 "also unset, the 'zwrite-signature' zephyr variable will be\n"
222                 "used instead.\n"),
[7d4fbcd]223
224  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
[aa2f33b3]225                 "string to append to the end of the sepbar",
226                 "The sepbar is the bar separating the top and bottom\n"
227                 "of the owl screen.  Any string specified here will\n"
228                 "be displayed on the right of the sepbar\n"),
[7d4fbcd]229
230  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
[aa2f33b3]231               "turn zaway on or off", "" ),
[7d4fbcd]232
233  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */, 
234                 OWL_DEFAULT_ZAWAYMSG,
[aa2f33b3]235                 "zaway msg for responding to zephyrs when away", "" ),
[7d4fbcd]236
237  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */, 
238                 OWL_DEFAULT_ZAWAYMSG,
[aa2f33b3]239                 "default zaway message", "" ),
[7d4fbcd]240
[4b660cc]241  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
242                    "Set AIM away status",
243                    "",
244                    NULL, owl_variable_aaway_set, NULL),
245
246  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */, 
247                 OWL_DEFAULT_AAWAYMSG,
248                 "AIM away msg for responding when away", "" ),
249
250  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */, 
251                 OWL_DEFAULT_AAWAYMSG,
252                 "default AIM away message", "" ),
253
[7d4fbcd]254  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
[aa2f33b3]255                 "home view to switch to after 'X' and 'V'", 
256                 "SEE ALSO: view, filter\n" ),
[7d4fbcd]257
[ecd5dc5]258  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
259                 "filter on which to trigger alert actions",
260                 "" ),
261
262  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
[b278973]263                 "owl command to execute for alert actions",
[ecd5dc5]264                 "" ),
265
[c01e477]266  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "tty name for zephyr location", "",
267                      NULL, owl_variable_tty_set, NULL),
[bd3f232]268
[27c3a93]269  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "__unspecified__",
[c3ab155]270                 "name of the default formatting style",
[f1e629d]271                 "This sets the default message formatting style.\n"
272                 "Styles may be created with the 'style' command.\n"
273                 "Some built-in styles include:\n"
274                 "   default  - the default owl formatting\n"
275                 "   oneline  - one line per-message\n"
276                 "   perl     - legacy perl interface\n"
277                 "\nSEE ALSO: style, show styles, view -s <style>\n"
278                 ),
279
[c3ab155]280
[d36f2cb]281  OWLVAR_INT(    "edit:maxfillcols" /* %OwlVarStub:edit_maxfillcols */, 70,
[aa2f33b3]282                 "maximum number of columns for M-q to fill text to",
283                 "This specifies the maximum number of columns for M-q\n"
284                 "to fill text to.  If set to 0, ther will be no maximum\n"
285                 "limit.  In all cases, the current width of the screen\n"
286                 "will also be taken into account.  It will be used instead\n"
287                 "if it is narrower than the maximum, or if this\n"
288                 "is set to 0.\n" ),
[d36f2cb]289
[039213e]290  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 0,
[aa2f33b3]291                 "maximum number of columns for line-wrapping",
292                 "This specifies the maximum number of columns for\n"
293                 "auto-line-wrapping.  If set to 0, ther will be no maximum\n"
294                 "limit.  In all cases, the current width of the screen\n"
295                 "will also be taken into account.  It will be used instead\n"
296                 "if it is narrower than the maximum, or if this\n"
297                 "is set to 0.\n\n"
298                 "It is recommended that outgoing messages be no wider\n"
299                 "than 60 columns, as a courtesy to recipients.\n"),
[d36f2cb]300
[1db061d]301  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
[6a415e9]302              "number of seconds after AIM login to ignore login messages",
303              "This specifies the number of seconds to wait after an\n"
304              "AIM login before allowing the recipt of AIM login notifications.\n"
[1db061d]305              "By default this is set to 15.  If you would like to view login\n"
306              "notifications of buddies as soon as you login, set it to 0 instead."),
[6a415e9]307
308             
[7d4fbcd]309  OWLVAR_INT_FULL( "typewinsize" /* %OwlVarStub:typwin_lines */, 
310                   OWL_TYPWIN_SIZE,
[aa2f33b3]311                  "number of lines in the typing window", 
312                   "This specifies the height of the window at the\n"
313                   "bottom of the screen where commands are entered\n"
314                   "and where messages are composed.\n",
315                   "int > 0",
[7d4fbcd]316                   owl_variable_int_validate_gt0,
317                   owl_variable_typewinsize_set,
318                   NULL /* use default for get */
319                   ),
320
[da466e0]321  OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0,
322                  "number of lines to add to the typing window when in use",
323                   "On small screens you may want the typing window to\n"
324                   "auto-hide when not entering a command or message.\n"
325                   "This variable is the number of lines to add to the\n"
326           "typing window when it is in use; you can then set\n"
327           "typewinsize to 1.\n\n"
328           "This works a lot better with a non-default scrollmode;\n"
329           "try :set scrollmode pagedcenter.\n"),
330
[aa2f33b3]331  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
332               "how to scroll up and down",
333               "This controls how the screen is scrolled as the\n"
334               "cursor moves between messages being displayed.\n"
335               "The following modes are supported:\n\n"
336               "   normal      - This is the owl default.  Scrolling happens\n"
337               "                 when it needs to, and an attempt is made to\n"
338               "                 keep the current message roughly near\n"
339               "                 the middle of the screen.\n"
340               "   top         - The current message will always be the\n"
341               "                 the top message displayed.\n"
342               "   neartop     - The current message will be one down\n"
343               "                 from the top message displayed,\n"
344               "                 where possible.\n"
345               "   center      - An attempt is made to keep the current\n"
346               "                 message near the center of the screen.\n"
347               "   paged       - The top message displayed only changes\n"
348               "                 when user moves the cursor to the top\n"
349               "                 or bottom of the screen.  When it moves,\n"
350               "                 the screen will be paged up or down and\n"
351               "                 the cursor will be near the top or\n"
352               "                 the bottom.\n"
353               "   pagedcenter - The top message displayed only changes\n"
354               "                 when user moves the cursor to the top\n"
355               "                 or bottom of the screen.  When it moves,\n"
356               "                 the screen will be paged up or down and\n"
357               "                 the cursor will be near the center.\n",
358               "normal,top,neartop,center,paged,pagedcenter" ),
359
[ecd5dc5]360
[7d4fbcd]361  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
[aa2f33b3]362               "enable automatic following of the last zephyr",
363               "If the cursor is at the last message, it will\n"
364               "continue to follow the last message if this is set.\n"
365               "Note that this is currently risky as you might accidentally\n"
366               "delete a message right as it came in.\n" ),
[7d4fbcd]367
368  /* This MUST be last... */
[aa2f33b3]369  { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
370    NULL, NULL, NULL, NULL, NULL, NULL }
[7d4fbcd]371
372};
373
374/**************************************************************************/
375/*********************** SPECIFIC TO VARIABLES ****************************/
376/**************************************************************************/
377
378
379/* commonly useful */
380
[64735f0]381int owl_variable_int_validate_gt0(const owl_variable *v, const void *newval)
[4357be8]382{
[7d4fbcd]383  if (newval == NULL) return(0);
[defe4a3]384  else if (*(const int*)newval < 1) return(0);
[7d4fbcd]385  else return (1);
386}
387
[64735f0]388int owl_variable_int_validate_positive(const owl_variable *v, const void *newval)
[4357be8]389{
[7d4fbcd]390  if (newval == NULL) return(0);
[defe4a3]391  else if (*(const int*)newval < 0) return(0);
[7d4fbcd]392  else return (1);
393}
394
395/* typewinsize */
[e19eb97]396int owl_variable_typewinsize_set(owl_variable *v, const void *newval)
[4357be8]397{
[7d4fbcd]398  int rv;
399  rv = owl_variable_int_set_default(v, newval);
400  if (0 == rv) owl_function_resize();
401  return(rv);
402}
403
404/* debug (cache value in g->debug) */
[e19eb97]405int owl_variable_debug_set(owl_variable *v, const void *newval)
[4357be8]406{
[defe4a3]407  if (newval && (*(const int*)newval == 1 || *(const int*)newval == 0)) {
408    g.debug = *(const int*)newval;
[7d4fbcd]409  }
410  return owl_variable_bool_set_default(v, newval);
[4b660cc]411}
412
413/* When 'aaway' is changed, need to notify the AIM server */
[e19eb97]414int owl_variable_aaway_set(owl_variable *v, const void *newval)
[4357be8]415{
[4b660cc]416  if (newval) {
[defe4a3]417    if (*(const int*)newval == 1) {
[4b660cc]418      owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
[defe4a3]419    } else if (*(const int*)newval == 0) {
[4b660cc]420      owl_aim_set_awaymsg("");
421    }
422  }
423  return owl_variable_bool_set_default(v, newval);
[7d4fbcd]424}
425
[e19eb97]426int owl_variable_pseudologins_set(owl_variable *v, const void *newval)
[4357be8]427{
428  if (newval) {
[defe4a3]429    if (*(const int*)newval == 1) {
[4357be8]430      owl_function_zephyr_buddy_check(0);
431    }
432  }
433  return owl_variable_bool_set_default(v, newval);
434}
435
[7d4fbcd]436/* note that changing the value of this will clobber
437 * any user setting of this */
[e19eb97]438int owl_variable_disable_ctrl_d_set(owl_variable *v, const void *newval)
[4357be8]439{
[217a43e]440  if (newval && !owl_context_is_startup(owl_global_get_context(&g))) {
[defe4a3]441    if (*(const int*)newval == 2) {
[7d4fbcd]442      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
[defe4a3]443    } else if (*(const int*)newval == 1) {
[3b42640]444      owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete");
[7d4fbcd]445    } else {
[3b42640]446      owl_function_command_norv("bindkey editmulti C-d command edit:done");
[7d4fbcd]447    }
448  } 
[217a43e]449  return owl_variable_int_set_default(v, newval); 
[7d4fbcd]450}
451
[e19eb97]452int owl_variable_tty_set(owl_variable *v, const void *newval)
[4357be8]453{
[09489b89]454  owl_zephyr_set_locationinfo(owl_global_get_hostname(&g), newval);
[c01e477]455  return(owl_variable_string_set_default(v, newval));
456}
457
[7d4fbcd]458
459/**************************************************************************/
460/****************************** GENERAL ***********************************/
461/**************************************************************************/
462
463int owl_variable_dict_setup(owl_vardict *vd) {
[d536e72]464  owl_variable *var, *cur;
[7d4fbcd]465  if (owl_dict_create(vd)) return(-1);
[d536e72]466  for (var = variables_to_init; var->name != NULL; var++) {
467    cur = owl_malloc(sizeof(owl_variable));
468    memcpy(cur, var, sizeof(owl_variable));
[7d4fbcd]469    switch (cur->type) {
470    case OWL_VARIABLE_OTHER:
471      cur->set_fn(cur, cur->pval_default);
472      break;
473    case OWL_VARIABLE_STRING:
474      if (!cur->validate_fn) 
475        cur->validate_fn = owl_variable_string_validate_default;
476      if (!cur->set_fn) 
477        cur->set_fn = owl_variable_string_set_default;
478      if (!cur->set_fromstring_fn) 
479        cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
480      if (!cur->get_fn) 
481        cur->get_fn = owl_variable_get_default;
482      if (!cur->get_tostring_fn) 
483        cur->get_tostring_fn = owl_variable_string_get_tostring_default;     
484      if (!cur->free_fn) 
485        cur->free_fn = owl_variable_free_default;
486      cur->set_fn(cur, cur->pval_default);
487      break;
488    case OWL_VARIABLE_BOOL:
489      if (!cur->validate_fn) 
490        cur->validate_fn = owl_variable_bool_validate_default;
491      if (!cur->set_fn) 
492        cur->set_fn = owl_variable_bool_set_default;
493      if (!cur->set_fromstring_fn) 
494        cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
495      if (!cur->get_fn) 
496        cur->get_fn = owl_variable_get_default;
497      if (!cur->get_tostring_fn) 
498        cur->get_tostring_fn = owl_variable_bool_get_tostring_default;     
499      if (!cur->free_fn) 
500        cur->free_fn = owl_variable_free_default;
501      cur->val = owl_malloc(sizeof(int));
502      cur->set_fn(cur, &cur->ival_default);
503      break;
504    case OWL_VARIABLE_INT:
505      if (!cur->validate_fn) 
506        cur->validate_fn = owl_variable_int_validate_default;
507      if (!cur->set_fn) 
508        cur->set_fn = owl_variable_int_set_default;
509      if (!cur->set_fromstring_fn) 
510        cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
511      if (!cur->get_fn) 
512        cur->get_fn = owl_variable_get_default;
513      if (!cur->get_tostring_fn) 
514        cur->get_tostring_fn = owl_variable_int_get_tostring_default;     
515      if (!cur->free_fn) 
516        cur->free_fn = owl_variable_free_default;
517      cur->val = owl_malloc(sizeof(int));
518      cur->set_fn(cur, &cur->ival_default);
519      break;
520    default:
521      fprintf(stderr, "owl_variable_setup: invalid variable type\n");
522      return(-2);
523    }
[4d86e06]524    owl_dict_insert_element(vd, cur->name, cur, NULL);
[7d4fbcd]525  }
526  return 0;
527}
528
[a695a68]529void owl_variable_dict_add_variable(owl_vardict * vardict,
530                                    owl_variable * var) {
[3b0edaa]531  owl_dict_insert_element(vardict, var->name, var, (void (*)(void *))owl_variable_delete);
[a695a68]532}
533
[e19eb97]534owl_variable * owl_variable_newvar(const char *name, const char *summary, const char * description) {
[4d86e06]535  owl_variable * var = owl_malloc(sizeof(owl_variable));
[a695a68]536  memset(var, 0, sizeof(owl_variable));
537  var->name = owl_strdup(name);
538  var->summary = owl_strdup(summary);
539  var->description = owl_strdup(description);
540  return var;
541}
542
[e19eb97]543void owl_variable_update(owl_variable *var, const char *summary, const char *desc) {
[d536e72]544  if(var->summary) owl_free(var->summary);
545  var->summary = owl_strdup(summary);
546  if(var->description) owl_free(var->description);
547  var->description = owl_strdup(desc);
548}
549
[e19eb97]550void owl_variable_dict_newvar_string(owl_vardict * vd, const char *name, const char *summ, const char * desc, const char * initval) {
[d536e72]551  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_STRING);
552  if(old) {
553    owl_variable_update(old, summ, desc);
554    if(old->pval_default) owl_free(old->pval_default);
555    old->pval_default = owl_strdup(initval);
556  } else {
557    owl_variable * var = owl_variable_newvar(name, summ, desc);
558    var->type = OWL_VARIABLE_STRING;
559    var->pval_default = owl_strdup(initval);
560    var->set_fn = owl_variable_string_set_default;
561    var->set_fromstring_fn = owl_variable_string_set_fromstring_default;
562    var->get_fn = owl_variable_get_default;
563    var->get_tostring_fn = owl_variable_string_get_tostring_default;
564    var->free_fn = owl_variable_free_default;
565    var->set_fn(var, initval);
566    owl_variable_dict_add_variable(vd, var);
567  }
[a695a68]568}
569
[e19eb97]570void owl_variable_dict_newvar_int(owl_vardict * vd, const char *name, const char *summ, const char * desc, int initval) {
[d536e72]571  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_INT);
572  if(old) {
573    owl_variable_update(old, summ, desc);
574    old->ival_default = initval;
575  } else {
576    owl_variable * var = owl_variable_newvar(name, summ, desc);
577    var->type = OWL_VARIABLE_INT;
578    var->ival_default = initval;
579    var->validate_fn = owl_variable_int_validate_default;
580    var->set_fn = owl_variable_int_set_default;
581    var->set_fromstring_fn = owl_variable_int_set_fromstring_default;
582    var->get_fn = owl_variable_get_default;
583    var->get_tostring_fn = owl_variable_int_get_tostring_default;
584    var->free_fn = owl_variable_free_default;
585    var->val = owl_malloc(sizeof(int));
586    var->set_fn(var, &initval);
587    owl_variable_dict_add_variable(vd, var);
588  }
[a695a68]589}
590
[e19eb97]591void owl_variable_dict_newvar_bool(owl_vardict * vd, const char *name, const char *summ, const char * desc, int initval) {
[d536e72]592  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_BOOL);
593  if(old) {
594    owl_variable_update(old, summ, desc);
595    old->ival_default = initval;
596  } else {
597    owl_variable * var = owl_variable_newvar(name, summ, desc);
598    var->type = OWL_VARIABLE_BOOL;
599    var->ival_default = initval;
600    var->validate_fn = owl_variable_bool_validate_default;
601    var->set_fn = owl_variable_bool_set_default;
602    var->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
603    var->get_fn = owl_variable_get_default;
604    var->get_tostring_fn = owl_variable_bool_get_tostring_default;
605    var->free_fn = owl_variable_free_default;
606    var->val = owl_malloc(sizeof(int));
607    var->set_fn(var, &initval);
608    owl_variable_dict_add_variable(vd, var);
609  }
[a695a68]610}
611
[7d4fbcd]612void owl_variable_dict_free(owl_vardict *d) {
[3b0edaa]613  owl_dict_free_all(d, (void (*)(void *))owl_variable_delete);
[7d4fbcd]614}
615
616/* free the list with owl_variable_dict_namelist_free */
[e5c9b14a]617void owl_variable_dict_get_names(const owl_vardict *d, owl_list *l) {
[7d4fbcd]618  owl_dict_get_keys(d, l);
619}
620
621void owl_variable_dict_namelist_free(owl_list *l) {
622  owl_list_free_all(l, owl_free);
623}
624
[3b0edaa]625void owl_variable_delete(owl_variable *v)
626{
[7d4fbcd]627  if (v->free_fn) v->free_fn(v);
[d536e72]628  owl_free(v);
[7d4fbcd]629}
630
631
[64735f0]632const char *owl_variable_get_description(const owl_variable *v) {
[aa2f33b3]633  return v->description;
634}
635
[64735f0]636const char *owl_variable_get_summary(const owl_variable *v) {
[aa2f33b3]637  return v->summary;
[7d4fbcd]638}
639
[64735f0]640const char *owl_variable_get_validsettings(const owl_variable *v) {
[7d4fbcd]641  if (v->validsettings) {
642    return v->validsettings;
643  } else {
644    return "";
645  }
646}
647
648/* functions for getting and setting variable values */
649
650/* returns 0 on success, prints a status msg if msg is true */
[e19eb97]651int owl_variable_set_fromstring(owl_vardict *d, const char *name, const char *value, int msg, int requirebool) {
[7d4fbcd]652  owl_variable *v;
653  char buff2[1024];
654  if (!name) return(-1);
655  v = owl_dict_find_element(d, name);
656  if (v == NULL) {
[836ea3a3]657    if (msg) owl_function_error("Unknown variable %s", name);
[7d4fbcd]658    return -1;
659  }
660  if (!v->set_fromstring_fn) {
[836ea3a3]661    if (msg) owl_function_error("Variable %s is read-only", name);
[486688f]662    return -1;   
663  }
664  if (requirebool && v->type!=OWL_VARIABLE_BOOL) {
[836ea3a3]665    if (msg) owl_function_error("Variable %s is not a boolean", name);
[486688f]666    return -1;   
[7d4fbcd]667  }
668  if (0 != v->set_fromstring_fn(v, value)) {
[836ea3a3]669    if (msg) owl_function_error("Unable to set %s (must be %s)", name, 
[7d4fbcd]670                                  owl_variable_get_validsettings(v));
671    return -1;
672  }
673  if (msg && v->get_tostring_fn) {
674    v->get_tostring_fn(v, buff2, 1024, v->val);
675    owl_function_makemsg("%s = '%s'", name, buff2);
676  }   
677  return 0;
678}
679 
[e19eb97]680int owl_variable_set_string(owl_vardict *d, const char *name, const char *newval) {
[7d4fbcd]681  owl_variable *v;
682  if (!name) return(-1);
683  v = owl_dict_find_element(d, name);
684  if (v == NULL || !v->set_fn) return(-1);
685  if (v->type!=OWL_VARIABLE_STRING) return(-1);
[ba6c8bd]686  return v->set_fn(v, newval);
[7d4fbcd]687}
688 
[e19eb97]689int owl_variable_set_int(owl_vardict *d, const char *name, int newval) {
[7d4fbcd]690  owl_variable *v;
691  if (!name) return(-1);
692  v = owl_dict_find_element(d, name);
693  if (v == NULL || !v->set_fn) return(-1);
694  if (v->type!=OWL_VARIABLE_INT && v->type!=OWL_VARIABLE_BOOL) return(-1);
695  return v->set_fn(v, &newval);
696}
697 
[e19eb97]698int owl_variable_set_bool_on(owl_vardict *d, const char *name) {
[7d4fbcd]699  return owl_variable_set_int(d,name,1);
700}
701
[e19eb97]702int owl_variable_set_bool_off(owl_vardict *d, const char *name) {
[7d4fbcd]703  return owl_variable_set_int(d,name,0);
704}
705
[e5c9b14a]706int owl_variable_get_tostring(const owl_vardict *d, const char *name, char *buf, int bufsize) {
[7d4fbcd]707  owl_variable *v;
708  if (!name) return(-1);
709  v = owl_dict_find_element(d, name);
710  if (v == NULL || !v->get_tostring_fn) return(-1);
711  return v->get_tostring_fn(v, buf, bufsize, v->val);
712}
713
[e5c9b14a]714int owl_variable_get_default_tostring(const owl_vardict *d, const char *name, char *buf, int bufsize) {
[7d4fbcd]715  owl_variable *v;
716  if (!name) return(-1);
717  v = owl_dict_find_element(d, name);
718  if (v == NULL || !v->get_tostring_fn) return(-1);
719  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
720    return v->get_tostring_fn(v, buf, bufsize, &(v->ival_default));
721  } else {
722    return v->get_tostring_fn(v, buf, bufsize, v->pval_default);
723  }
724}
725
[e5c9b14a]726owl_variable *owl_variable_get_var(const owl_vardict *d, const char *name, int require_type) {
[7d4fbcd]727  owl_variable *v;
728  if (!name) return(NULL);
729  v = owl_dict_find_element(d, name);
730  if (v == NULL || !v->get_fn || v->type != require_type) return(NULL);
[d536e72]731  return v;
732}
733
734/* returns a reference */
[e5c9b14a]735const void *owl_variable_get(const owl_vardict *d, const char *name, int require_type) {
[d536e72]736  owl_variable *v = owl_variable_get_var(d, name, require_type);
737  if(v == NULL) return NULL;
[7d4fbcd]738  return v->get_fn(v);
739}
740
741/* returns a reference */
[e5c9b14a]742const char *owl_variable_get_string(const owl_vardict *d, const char *name) {
[4d86e06]743  return owl_variable_get(d,name, OWL_VARIABLE_STRING);
[7d4fbcd]744}
745
746/* returns a reference */
[e5c9b14a]747const void *owl_variable_get_other(const owl_vardict *d, const char *name) {
[4d86e06]748  return owl_variable_get(d,name, OWL_VARIABLE_OTHER);
[7d4fbcd]749}
750
[e5c9b14a]751int owl_variable_get_int(const owl_vardict *d, const char *name) {
[defe4a3]752  const int *pi;
[4d86e06]753  pi = owl_variable_get(d,name,OWL_VARIABLE_INT);
[7d4fbcd]754  if (!pi) return(-1);
755  return(*pi);
756}
757
[e5c9b14a]758int owl_variable_get_bool(const owl_vardict *d, const char *name) {
[defe4a3]759  const int *pi;
[4d86e06]760  pi = owl_variable_get(d,name,OWL_VARIABLE_BOOL);
[7d4fbcd]761  if (!pi) return(-1);
762  return(*pi);
763}
764
[e5c9b14a]765void owl_variable_describe(const owl_vardict *d, const char *name, owl_fmtext *fm) {
[aa2f33b3]766  char defaultbuf[50];
[7d4fbcd]767  char buf[1024];
768  int buflen = 1023;
769  owl_variable *v;
770
771  if (!name
772      || (v = owl_dict_find_element(d, name)) == NULL 
773      || !v->get_fn) {
774    snprintf(buf, buflen, "     No such variable '%s'\n", name);     
775    owl_fmtext_append_normal(fm, buf);
776    return;
777  }
778  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
[aa2f33b3]779    v->get_tostring_fn(v, defaultbuf, 50, &(v->ival_default));
[7d4fbcd]780  } else {
[aa2f33b3]781    v->get_tostring_fn(v, defaultbuf, 50, v->pval_default);
[7d4fbcd]782  }
[aa2f33b3]783  snprintf(buf, buflen, OWL_TABSTR "%-20s - %s (default: '%s')\n", 
[7d4fbcd]784                  v->name, 
[aa2f33b3]785                  owl_variable_get_summary(v), defaultbuf);
[7d4fbcd]786  owl_fmtext_append_normal(fm, buf);
787}
788
[e5c9b14a]789void owl_variable_get_help(const owl_vardict *d, const char *name, owl_fmtext *fm) {
[7d4fbcd]790  char buff[1024];
791  int bufflen = 1023;
792  owl_variable *v;
793
794  if (!name
795      || (v = owl_dict_find_element(d, name)) == NULL 
796      || !v->get_fn) {
797    owl_fmtext_append_normal(fm, "No such variable...\n");
798    return;
799  }
800
801  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
802  owl_fmtext_append_normal(fm, OWL_TABSTR);
803  owl_fmtext_append_normal(fm, name);
804  owl_fmtext_append_normal(fm, " - ");
[aa2f33b3]805  owl_fmtext_append_normal(fm, v->summary);
[7d4fbcd]806  owl_fmtext_append_normal(fm, "\n\n");
807
808  owl_fmtext_append_normal(fm, "Current:        ");
809  owl_variable_get_tostring(d, name, buff, bufflen);
810  owl_fmtext_append_normal(fm, buff);
811  owl_fmtext_append_normal(fm, "\n\n");
812
813
814  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
815    v->get_tostring_fn(v, buff, bufflen, &(v->ival_default));
816  } else {
817    v->get_tostring_fn(v, buff, bufflen, v->pval_default);
818  }
819  owl_fmtext_append_normal(fm, "Default:        ");
820  owl_fmtext_append_normal(fm, buff);
821  owl_fmtext_append_normal(fm, "\n\n");
822
823  owl_fmtext_append_normal(fm, "Valid Settings: ");
824  owl_fmtext_append_normal(fm, owl_variable_get_validsettings(v));
825  owl_fmtext_append_normal(fm, "\n\n");
[aa2f33b3]826
827  if (v->description && *v->description) {
828    owl_fmtext_append_normal(fm, "Description:\n");
829    owl_fmtext_append_normal(fm, owl_variable_get_description(v));
830    owl_fmtext_append_normal(fm, "\n\n");
831  }
[7d4fbcd]832}
833
834
835
836
837/**************************************************************************/
838/*********************** GENERAL TYPE-SPECIFIC ****************************/
839/**************************************************************************/
840
841/* default common functions */
842
[64735f0]843const void *owl_variable_get_default(const owl_variable *v) {
[7d4fbcd]844  return v->val;
845}
846
847void owl_variable_free_default(owl_variable *v) {
848  if (v->val) owl_free(v->val);
849}
850
851/* default functions for booleans */
852
[64735f0]853int owl_variable_bool_validate_default(const owl_variable *v, const void *newval) {
[7d4fbcd]854  if (newval == NULL) return(0);
[defe4a3]855  else if (*(const int*)newval==1 || *(const int*)newval==0) return(1);
[7d4fbcd]856  else return (0);
857}
858
[e19eb97]859int owl_variable_bool_set_default(owl_variable *v, const void *newval) {
[7d4fbcd]860  if (v->validate_fn) {
861    if (!v->validate_fn(v, newval)) return(-1);
862  }
[defe4a3]863  *(int*)v->val = *(const int*)newval;
[7d4fbcd]864  return(0);
865}
866
[e19eb97]867int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval) {
[7d4fbcd]868  int i;
869  if (!strcmp(newval, "on")) i=1;
870  else if (!strcmp(newval, "off")) i=0;
871  else return(-1);
872  return (v->set_fn(v, &i));
873}
874
[64735f0]875int owl_variable_bool_get_tostring_default(const owl_variable *v, char* buf, int bufsize, const void *val) {
[7d4fbcd]876  if (val == NULL) {
877    snprintf(buf, bufsize, "<null>");
878    return -1;
[defe4a3]879  } else if (*(const int*)val == 0) {
[7d4fbcd]880    snprintf(buf, bufsize, "off");
881    return 0;
[defe4a3]882  } else if (*(const int*)val == 1) {
[7d4fbcd]883    snprintf(buf, bufsize, "on");
884    return 0;
885  } else {
886    snprintf(buf, bufsize, "<invalid>");
887    return -1;
888  }
889}
890
891/* default functions for integers */
892
[64735f0]893int owl_variable_int_validate_default(const owl_variable *v, const void *newval) {
[7d4fbcd]894  if (newval == NULL) return(0);
895  else return (1);
896}
897
[e19eb97]898int owl_variable_int_set_default(owl_variable *v, const void *newval) {
[7d4fbcd]899  if (v->validate_fn) {
900    if (!v->validate_fn(v, newval)) return(-1);
901  }
[defe4a3]902  *(int*)v->val = *(const int*)newval;
[7d4fbcd]903  return(0);
904}
905
[e19eb97]906int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval) {
[7d4fbcd]907  int i;
[99525be]908  char *ep;
909  i = strtol(newval, &ep, 10);
[7d4fbcd]910  if (*ep || ep==newval) return(-1);
911  return (v->set_fn(v, &i));
912}
913
[64735f0]914int owl_variable_int_get_tostring_default(const owl_variable *v, char* buf, int bufsize, const void *val) {
[7d4fbcd]915  if (val == NULL) {
916    snprintf(buf, bufsize, "<null>");
917    return -1;
918  } else {
[defe4a3]919    snprintf(buf, bufsize, "%d", *(const int*)val);
[7d4fbcd]920    return 0;
921  } 
922}
923
924/* default functions for enums (a variant of integers) */
925
[64735f0]926int owl_variable_enum_validate(const owl_variable *v, const void *newval) { 
[7d4fbcd]927  char **enums;
928  int nenums, val;
929  if (newval == NULL) return(0);
930  enums = atokenize(v->validsettings, ",", &nenums);
931  if (enums == NULL) return(0);
[1672650]932  atokenize_delete(enums, nenums);
[defe4a3]933  val = *(const int*)newval;
[7d4fbcd]934  if (val < 0 || val >= nenums) {
935    return(0);
936  }
937  return(1);
938}
939
[e19eb97]940int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval) {
[7d4fbcd]941  char **enums;
942  int nenums, i, val=-1;
943  if (newval == NULL) return(-1);
944  enums = atokenize(v->validsettings, ",", &nenums);
945  if (enums == NULL) return(-1);
946  for (i=0; i<nenums; i++) {
947    if (0==strcmp(newval, enums[i])) {
948      val = i;
949    }
950  }
[1672650]951  atokenize_delete(enums, nenums);
[7d4fbcd]952  if (val == -1) return(-1);
953  return (v->set_fn(v, &val));
954}
955
[64735f0]956int owl_variable_enum_get_tostring(const owl_variable *v, char* buf, int bufsize, const void *val) {
[7d4fbcd]957  char **enums;
958  int nenums, i;
959
960  if (val == NULL) {
961    snprintf(buf, bufsize, "<null>");
962    return -1;
963  }
964  enums = atokenize(v->validsettings, ",", &nenums);
[defe4a3]965  i = *(const int*)val;
[7d4fbcd]966  if (i<0 || i>=nenums) {
967    snprintf(buf, bufsize, "<invalid:%d>",i);
[1672650]968    atokenize_delete(enums, nenums);
[7d4fbcd]969    return(-1);
970  }
971  snprintf(buf, bufsize, "%s", enums[i]);
[1672650]972  atokenize_delete(enums, nenums);
[7d4fbcd]973  return 0;
974}
975
976/* default functions for stringeans */
977
[64735f0]978int owl_variable_string_validate_default(const struct _owl_variable *v, const void *newval) {
[7d4fbcd]979  if (newval == NULL) return(0);
980  else return (1);
981}
982
[e19eb97]983int owl_variable_string_set_default(owl_variable *v, const void *newval) {
[7d4fbcd]984  if (v->validate_fn) {
985    if (!v->validate_fn(v, newval)) return(-1);
986  }
987  if (v->val) owl_free(v->val);
988  v->val = owl_strdup(newval);
989  return(0);
990}
991
[e19eb97]992int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval) {
[7d4fbcd]993  return (v->set_fn(v, newval));
994}
995
[64735f0]996int owl_variable_string_get_tostring_default(const owl_variable *v, char* buf, int bufsize, const void *val) {
[7d4fbcd]997  if (val == NULL) {
998    snprintf(buf, bufsize, "<null>");
999    return -1;
1000  } else {
[e19eb97]1001    snprintf(buf, bufsize, "%s", (const char*)val);
[7d4fbcd]1002    return 0;
1003  }
1004}
1005
Note: See TracBrowser for help on using the repository browser.