source: commands.c @ 3dcccba

barnowl_perlaim
Last change on this file since 3dcccba was 3dcccba, checked in by Geoffrey Thomas <geofft@mit.edu>, 16 years ago
This would probably work, except it doesn't compile.
  • Property mode set to 100644
File size: 72.8 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id$";
8
9/* fn is "char *foo(int argc, char **argv, char *buff)" */
10#define OWLCMD_ARGS(name, fn, ctx, summary, usage, description) \
11        { name, summary, usage, description, ctx, \
12          NULL, fn, NULL, NULL, NULL, NULL, NULL }
13
14/* fn is "void foo(void)" */
15#define OWLCMD_VOID(name, fn, ctx, summary, usage, description) \
16        { name, summary, usage, description, ctx, \
17          NULL, NULL, fn, NULL, NULL, NULL, NULL }
18
19/* fn is "void foo(int)" */
20#define OWLCMD_INT(name, fn, ctx, summary, usage, description) \
21        { name, summary, usage, description, ctx, \
22          NULL, NULL, NULL, fn, NULL, NULL, NULL }
23
24#define OWLCMD_ALIAS(name, actualname) \
25        { name, OWL_CMD_ALIAS_SUMMARY_PREFIX actualname, "", "", OWL_CTX_ANY, \
26          actualname, NULL, NULL, NULL, NULL, NULL, NULL }
27
28/* fn is "char *foo(void *ctx, int argc, char **argv, char *buff)" */
29#define OWLCMD_ARGS_CTX(name, fn, ctx, summary, usage, description) \
30        { name, summary, usage, description, ctx, \
31          NULL, NULL, NULL, NULL, ((char*(*)(void*,int,char**,char*))fn), NULL, NULL }
32
33/* fn is "void foo(void)" */
34#define OWLCMD_VOID_CTX(name, fn, ctx, summary, usage, description) \
35        { name, summary, usage, description, ctx, \
36          NULL, NULL, NULL, NULL, NULL, ((void(*)(void*))(fn)), NULL }
37
38/* fn is "void foo(int)" */
39#define OWLCMD_INT_CTX(name, fn, ctx, summary, usage, description) \
40        { name, summary, usage, description, ctx, \
41          NULL, NULL, NULL, NULL, NULL, NULL, ((void(*)(void*,int))fn) }
42
43
44owl_cmd commands_to_init[]
45  = {
46  OWLCMD_ARGS("zlog", owl_command_zlog, OWL_CTX_ANY,
47              "send a login or logout notification",
48              "zlog in [tty]\nzlog out",
49              "zlog in will send a login notification, zlog out will send a\n"
50              "logout notification.  By default a login notification is sent\n"
51              "when owl is started and a logout notification is sent when owl\n"
52              "is exited.  This behavior can be changed with the 'startuplogin'\n"
53              "and 'shudownlogout' variables.  If a tty is specified for zlog in\n"
54              "then the owl variable 'tty' will be set to that string, causing\n"
55              "it to be used as the zephyr location tty.\n"),
56
57  OWLCMD_VOID("quit", owl_command_quit, OWL_CTX_ANY,
58              "exit owl",
59              "",
60              "Exit owl and run any shutdown activities."),
61  OWLCMD_ALIAS("exit", "quit"),
62  OWLCMD_ALIAS("q",    "quit"),
63
64  OWLCMD_ARGS("term", owl_command_term, OWL_CTX_ANY,
65              "control the terminal",
66              "term raise\n"
67              "term deiconify\n",
68              ""),
69
70  OWLCMD_VOID("nop", owl_command_nop, OWL_CTX_ANY,
71              "do nothing",
72              "",
73              ""),
74 
75  OWLCMD_ARGS("start-command", owl_command_start_command, OWL_CTX_INTERACTIVE,
76              "prompts the user to enter a command",
77              "start-command [initial-value]",
78              "Initializes the command field to initial-value."),
79
80  OWLCMD_ARGS("start-question", owl_command_start_question, OWL_CTX_INTERACTIVE,
81              "prompts the user to enter a response to some question",
82              "start-command <question>",
83              ""),
84
85  OWLCMD_ARGS("start-password", owl_command_start_password, OWL_CTX_INTERACTIVE,
86              "prompts the user to enter a password",
87              "start-password <question>",
88              ""),
89
90  OWLCMD_ARGS("alias", owl_command_alias, OWL_CTX_ANY,
91              "creates a command alias",
92              "alias <new_command> <old_command>",
93              "Creates a command alias from new_command to old_command.\n"
94              "Any arguments passed to <new_command> will be appended to\n"
95              "<old_command> before it is executed.\n"),
96
97  OWLCMD_ARGS("bindkey", owl_command_bindkey, OWL_CTX_ANY,
98              "creates a binding in a keymap",
99              "bindkey <keymap> <keyseq> command <command>",
100              "Binds a key sequence to a command within a keymap.\n"
101              "Use 'show keymaps' to see the existing keymaps.\n"
102              "Key sequences may be things like M-C-t or NPAGE.\n"),
103
104  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
105              "send a zephyr",
106              "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
107              "Zwrite send a zephyr to the one or more users specified.\n\n"
108              "The following options are available:\n\n"
109              "-m    Specifies a message to send without prompting.\n"
110              "      Note that this does not yet log an outgoing message.\n"
111              "      This must be the last argument.\n\n"
112              "-n    Do not send a ping message.\n\n"
113              "-C    If the message is sent to more than one user include a\n"
114              "      \"cc:\" line in the text\n\n"
115              "-c class\n"
116              "      Send to the specified zephyr class\n\n"
117              "-i instance\n"
118              "      Send to the specified zephyr instance\n\n"
119              "-r realm\n"
120              "      Send to a foreign realm\n"
121              "-O opcode\n"
122              "      Send to the specified opcode\n"),
123
124  OWLCMD_ARGS("loopwrite", owl_command_loopwrite, OWL_CTX_INTERACTIVE,
125              "send a loopback message",
126              "loopwrite",
127              "Send a local message.\n"),
128
129  OWLCMD_ARGS("zcrypt", owl_command_zcrypt, OWL_CTX_INTERACTIVE,
130              "send an encrypted zephyr",
131              "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [-m <message...>]\n",
132              "Behaves like zwrite but uses encryption.  Not for use with\n"
133              "personal messages\n"),
134 
135  OWLCMD_ARGS("reply", owl_command_reply,  OWL_CTX_INTERACTIVE,
136              "reply to the current message",
137              "reply [-e] [ sender | all | zaway ]",
138              "If -e is specified, the zwrite command line is presented to\n"
139              "allow editing.\n\n"
140              "If 'sender' is specified, reply to the sender.\n\n"
141              "If 'all' or no args are specified, reply publically to the\n"
142              "same class/instance for non-personal messages and to the\n"
143              "sender for personal messages.\n\n"
144              "If 'zaway' is specified, replies with a zaway message.\n\n"),
145
146  OWLCMD_ARGS("set", owl_command_set, OWL_CTX_ANY,
147              "set a variable value",
148              "set [-q] [<variable>] [<value>]\n"
149              "set",
150              "Set the named variable to the specified value.  If no\n"
151              "arguments are given, print the value of all variables.\n"
152              "If the value is unspecified and the variable is a boolean, it will be\n"
153              "set to 'on'.  If -q is used, set is silent and does not print a\n"
154              "message.\n"),
155
156  OWLCMD_ARGS("unset", owl_command_unset, OWL_CTX_ANY,
157              "unset a boolean variable value",
158              "set [-q] <variable>\n"
159              "set",
160              "Set the named boolean variable to off.\n"
161              "If -q is specified, is silent and doesn't print a message.\n"),
162
163  OWLCMD_ARGS("print", owl_command_print, OWL_CTX_ANY,
164              "print a variable value",
165              "print <variable>\n"
166              "print",
167              "Print the value of the named variable.  If no arguments\n"
168              "are used print the value of all variables.\n"),
169
170  OWLCMD_ARGS("startup", owl_command_startup, OWL_CTX_ANY,
171              "run a command and set it to be run at every Owl startup",
172              "startup <commands> ...",
173              "Everything on the command line after the startup command\n"
174              "is executed as a normal owl command and is also placed in\n"
175              "a file so that the command is executed every time owl\n"
176              "is started"),
177
178  OWLCMD_ARGS("unstartup", owl_command_unstartup, OWL_CTX_ANY,
179              "remove a command from the list of those to be run at Owl startup",
180              "unstartup <commands> ...",
181              ""),
182
183  OWLCMD_VOID("version", owl_command_version, OWL_CTX_ANY,
184              "print the version of the running owl", "", ""),
185
186  OWLCMD_ARGS("subscribe", owl_command_subscribe, OWL_CTX_ANY,
187              "subscribe to a zephyr class, instance, recipient",
188              "subscribe [-t] <class> <instance> [recipient]",
189              "Subscribe the specified class and instance.  If the recipient\n"
190              "is not listed on the command line it defaults\n"
191              "to * (the wildcard recipient).  If the -t option is present\n"
192              "the subscription will only be temporary, i.e., it will not\n"
193              "be written to the subscription file and will therefore not\n"
194              "be present the next time owl is started.\n"),
195  OWLCMD_ALIAS("sub", "subscribe"),
196
197  OWLCMD_ARGS("unsubscribe", owl_command_unsubscribe, OWL_CTX_ANY,
198              "unsubscribe from a zephyr class, instance, recipient",
199              "unsubscribe [-t] <class> <instance> [recipient]",
200              "Unsubscribe from the specified class and instance.  If the\n"
201              "recipient is not listed on the command line it defaults\n"
202              "to * (the wildcard recipient).  If the -t option is present\n"
203              "the unsubscription will only be temporary, i.e., it will not\n"
204              "be updated in the subscription file and will therefore not\n"
205              "be in effect the next time owl is started.\n"),
206  OWLCMD_ALIAS("unsub", "unsubscribe"),
207
208  OWLCMD_VOID("unsuball", owl_command_unsuball, OWL_CTX_ANY,
209              "unsubscribe from all zephyrs", "", ""),
210 
211  OWLCMD_VOID("getsubs", owl_command_getsubs, OWL_CTX_ANY,
212              "print all current subscriptions",
213              "getsubs",
214              "getsubs retrieves the current subscriptions from the server\n"
215              "and displays them.\n"),
216
217  OWLCMD_ARGS("dump", owl_command_dump, OWL_CTX_ANY,
218              "dump messages to a file",
219              "dump <filename>",
220              "Dump messages in current view to the named file."),
221
222  OWLCMD_ARGS("source", owl_command_source, OWL_CTX_ANY,
223              "execute owl commands from a file",
224              "source <filename>",
225              "Execute the owl commands in <filename>.\n"),
226
227  OWLCMD_ARGS("addbuddy", owl_command_addbuddy, OWL_CTX_INTERACTIVE,
228              "add a buddy to a buddylist",
229              "addbuddy <protocol> <screenname>",
230              "Add the named buddy to your buddylist.  <protocol> can be zephyr\n"),
231
232  OWLCMD_ARGS("delbuddy", owl_command_delbuddy, OWL_CTX_INTERACTIVE,
233              "delete a buddy from a buddylist",
234              "delbuddy <protocol> <screenname>",
235              "Delete the named buddy from your buddylist.  <protocol> can be aim or zephyr\n"),
236
237  OWLCMD_ARGS("smartzpunt", owl_command_smartzpunt, OWL_CTX_INTERACTIVE,
238              "creates a zpunt based on the current message",
239              "smartzpunt [-i | --instance]",
240              "Starts a zpunt command based on the current message's class\n"
241              "(and instance if -i is specified).\n"),
242
243  OWLCMD_ARGS("zpunt", owl_command_zpunt, OWL_CTX_ANY,
244              "suppress a given zephyr triplet",
245              "zpunt <class> <instance> [recipient]\n"
246              "zpunt <instance>",
247              "The zpunt command will supress message to the specified\n"
248              "zephyr triplet.  In the second usage messages as supressed\n"
249              "for class MESSAGE and the named instance.\n\n"
250              "SEE ALSO:  zunpunt, show zpunts\n"),
251
252  OWLCMD_ARGS("zunpunt", owl_command_zunpunt, OWL_CTX_ANY,
253              "undo a previous zpunt",
254              "zunpunt <class> <instance> [recipient]\n"
255              "zunpunt <instance>",
256              "The zunpunt command will allow messages that were previosly\n"
257              "suppressed to be received again.\n\n"
258              "SEE ALSO:  zpunt, show zpunts\n"),
259
260  OWLCMD_ARGS("punt", owl_command_punt, OWL_CTX_ANY,
261              "suppress an arbitrary filter",
262              "punt <filter-name>",
263              "punt <filter-text (multiple words)>\n"
264              "The punt command will supress message to the specified\n"
265              "filter\n\n"
266              "SEE ALSO:  unpunt, zpunt, show zpunts\n"),
267
268  OWLCMD_ARGS("unpunt", owl_command_unpunt, OWL_CTX_ANY,
269              "remove an entry from the punt list",
270              "zpunt <filter-name>\n"
271              "zpunt <filter-text>\n"
272              "zpunt <number>\n",
273              "The unpunt command will remove an entry from the puntlist.\n"
274              "The first two forms correspond to the first two forms of the :punt\n"
275              "command. The latter allows you to remove a specific entry from the\n"
276              "the list (see :show zpunts)\n\n"
277              "SEE ALSO:  punt, zpunt, zunpunt, show zpunts\n"),
278
279  OWLCMD_VOID("info", owl_command_info, OWL_CTX_INTERACTIVE,
280              "display detailed information about the current message",
281              "", ""),
282 
283  OWLCMD_ARGS("help", owl_command_help, OWL_CTX_INTERACTIVE,
284              "display help on using owl",
285              "help [command]", ""),
286
287  OWLCMD_ARGS("zlist", owl_command_zlist, OWL_CTX_INTERACTIVE,
288              "List users logged in",
289              "znol [-f file]",
290              "Print a znol-style listing of users logged in"),
291
292  OWLCMD_ARGS("blist", owl_command_blist, OWL_CTX_INTERACTIVE,
293              "List all buddies logged in",
294              "blist",
295              "Print a listing of buddies logged in, regardless of protocol."),
296
297  OWLCMD_ARGS("toggle-oneline", owl_command_toggleoneline, OWL_CTX_INTERACTIVE,
298              "Toggle the style between oneline and the default style",
299              "toggle-oneline",
300              ""),
301
302  OWLCMD_VOID("recv:shiftleft", owl_command_shift_left, OWL_CTX_INTERACTIVE,
303              "scrolls receive window to the left", "", ""),
304
305  OWLCMD_VOID("recv:shiftright", owl_command_shift_right, OWL_CTX_INTERACTIVE,
306              "scrolls receive window to the left", "", ""),
307
308  OWLCMD_VOID("recv:pagedown", owl_function_mainwin_pagedown, 
309              OWL_CTX_INTERACTIVE,
310              "scrolls down by a page", "", ""),
311
312  OWLCMD_VOID("recv:pageup", owl_function_mainwin_pageup, OWL_CTX_INTERACTIVE,
313              "scrolls up by a page", "", ""),
314
315  OWLCMD_INT ("recv:scroll", owl_function_page_curmsg, OWL_CTX_INTERACTIVE,
316              "scrolls current message up or down", 
317              "recv:scroll <numlines>", 
318              "Scrolls the current message up or down by <numlines>.\n"
319              "Scrolls up if <numlines> is negative, else scrolls down.\n"),
320
321  OWLCMD_ARGS("next", owl_command_next, OWL_CTX_INTERACTIVE,
322              "move the pointer to the next message",
323              "recv:next [ --filter <name> ] [ --skip-deleted ] [ --last-if-none ]\n"
324              "          [ --smart-filter | --smart-filter-instance ]",
325              "Moves the pointer to the next message in the current view.\n"
326              "If --filter is specified, will only consider messages in\n"
327              "the filter <name>.\n"
328              "If --smart-filter or --smart-filter-instance is specified,\n"
329              "goes to the next message that is similar to the current message.\n"
330              "If --skip-deleted is specified, deleted messages will\n"
331              "be skipped.\n"
332              "If --last-if-none is specified, will stop at last message\n"
333              "in the view if no other suitable messages are found.\n"),
334  OWLCMD_ALIAS("recv:next", "next"),
335
336  OWLCMD_ARGS("prev", owl_command_prev, OWL_CTX_INTERACTIVE,
337              "move the pointer to the previous message",
338              "recv:prev [ --filter <name> ] [ --skip-deleted ] [ --first-if-none ]\n"
339              "          [ --smart-filter | --smart-filter-instance ]",
340              "Moves the pointer to the next message in the current view.\n"
341              "If --filter is specified, will only consider messages in\n"
342              "the filter <name>.\n"
343              "If --smart-filter or --smart-filter-instance is specified,\n"
344              "goes to the previous message that is similar to the current message.\n"
345              "If --skip-deleted is specified, deleted messages will\n"
346              "be skipped.\n"
347              "If --first-if-none is specified, will stop at first message\n"
348              "in the view if no other suitable messages are found.\n"),
349  OWLCMD_ALIAS("recv:prev", "prev"),
350
351  OWLCMD_ALIAS("recv:next-notdel", "recv:next --skip-deleted --last-if-none"),
352  OWLCMD_ALIAS("next-notdel",      "recv:next --skip-deleted --last-if-none"),
353
354  OWLCMD_ALIAS("recv:prev-notdel", "recv:prev --skip-deleted --first-if-none"),
355  OWLCMD_ALIAS("prev-notdel",      "recv:prev --skip-deleted --first-if-none"),
356
357  OWLCMD_ALIAS("recv:next-personal", "recv:next --filter personal"),
358
359  OWLCMD_ALIAS("recv:prev-personal", "recv:prev --filter personal"),
360
361  OWLCMD_VOID("first", owl_command_first, OWL_CTX_INTERACTIVE,
362              "move the pointer to the first message", "", ""),
363  OWLCMD_ALIAS("recv:first", "first"),
364
365  OWLCMD_VOID("last", owl_command_last, OWL_CTX_INTERACTIVE,
366              "move the pointer to the last message", "", 
367              "Moves the pointer to the last message in the view.\n"
368              "If we are already at the last message in the view,\n"
369              "blanks the screen and moves just past the end of the view\n"
370              "so that new messages will appear starting at the top\n"
371              "of the screen.\n"),
372  OWLCMD_ALIAS("recv:last", "last"),
373
374  OWLCMD_VOID("expunge", owl_command_expunge, OWL_CTX_INTERACTIVE,
375              "remove all messages marked for deletion", "", ""),
376
377  OWLCMD_VOID("resize", owl_command_resize, OWL_CTX_ANY,
378              "resize the window to the current screen size", "", ""),
379
380  OWLCMD_VOID("redisplay", owl_command_redisplay, OWL_CTX_ANY,
381              "redraw the entire window", "", ""),
382
383  OWLCMD_VOID("suspend", owl_command_suspend, OWL_CTX_ANY,
384              "suspend owl", "", ""),
385
386  OWLCMD_ARGS("echo", owl_command_echo, OWL_CTX_ANY,
387              "pops up a message in popup window",
388              "echo [args .. ]\n\n", ""),
389
390  OWLCMD_ARGS("exec", owl_command_exec, OWL_CTX_ANY,
391              "run a command from the shell",
392              "exec [args .. ]", ""),
393
394  OWLCMD_ARGS("aexec", owl_command_aexec, OWL_CTX_INTERACTIVE,
395              "run a command from the shell and display in an admin message",
396              "aexec [args .. ]", ""),
397
398  OWLCMD_ARGS("pexec", owl_command_pexec, OWL_CTX_INTERACTIVE,
399              "run a command from the shell and display in a popup window",
400              "pexec [args .. ]", ""),
401
402  OWLCMD_ARGS("perl", owl_command_perl, OWL_CTX_ANY,
403              "run a perl expression",
404              "perl [args .. ]", ""),
405
406  OWLCMD_ARGS("aperl", owl_command_aperl, OWL_CTX_INTERACTIVE,
407              "run a perl expression and display in an admin message",
408              "aperl [args .. ]", ""),
409
410  OWLCMD_ARGS("pperl", owl_command_pperl, OWL_CTX_INTERACTIVE,
411              "run a perl expression and display in a popup window",
412              "pperl [args .. ]", ""),
413
414  OWLCMD_ARGS("multi", owl_command_multi, OWL_CTX_ANY,
415              "runs multiple ;-separated commands",
416              "multi <command1> ( ; <command2> )*\n",
417              "Runs multiple semicolon-separated commands in order.\n"
418              "Note quoting isn't supported here yet.\n"
419              "If you want to do something fancy, use perl.\n"),
420
421  OWLCMD_ARGS("(", owl_command_multi, OWL_CTX_ANY,
422              "runs multiple ;-separated commands",
423              "'(' <command1> ( ; <command2> )* ')'\n",
424              "Runs multiple semicolon-separated commands in order.\n"
425              "You must have a space before the final ')'\n"
426              "Note quoting isn't supported here yet.\n"
427              "If you want to do something fancy, use perl.\n"),
428
429  OWLCMD_VOID("pop-message", owl_command_pop_message, OWL_CTX_RECWIN,
430              "pops up a message in a window", "", ""),
431
432  OWLCMD_VOID("openurl", owl_command_openurl, OWL_CTX_INTERACTIVE,
433              "opens up a URL from the current message",
434              "", 
435              "Uses the 'webbrowser' variable to determine\n"
436              "which browser to use.  Currently, 'netscape'\n"
437              "and 'galeon' are supported.\n"),
438
439  OWLCMD_ARGS("zaway", owl_command_zaway, OWL_CTX_INTERACTIVE,
440              "Set, enable or disable zephyr away message",
441              "zaway [ on | off | toggle ]\n"
442              "zaway <message>",
443              "Turn on or off a zaway message.  If 'message' is\n"
444              "specified turn on zaway with that message, otherwise\n"
445              "use the default.\n"),
446
447  OWLCMD_ARGS("away", owl_command_away, OWL_CTX_INTERACTIVE,
448              "Set, enable or disable both AIM and zephyr away messages",
449              "away [ on | off | toggle ]\n"
450              "away <message>",
451              "Turn on or off the AIM and zephyr away message.  If\n"
452              "'message' is specified turn them on with that message,\n"
453              "otherwise use the default.\n"
454              "\n"
455              "This command really just runs the 'aaway' and 'zaway'\n"
456              "commands together\n"
457              "\n"
458              "SEE ALSO: aaway, zaway"),
459
460  OWLCMD_ARGS("load-subs", owl_command_loadsubs, OWL_CTX_ANY,
461              "load subscriptions from a file",
462              "load-subs <file>\n", ""),
463
464  OWLCMD_ARGS("loadsubs", owl_command_loadsubs, OWL_CTX_ANY,
465              "load subscriptions from a file",
466              "loadsubs <file>\n", ""),
467
468  OWLCMD_ARGS("loadloginsubs", owl_command_loadloginsubs, OWL_CTX_ANY,
469              "load login subscriptions from a file",
470              "loadloginsubs <file>\n",
471              "The file should contain a list of usernames, one per line."),
472
473  OWLCMD_VOID("about", owl_command_about, OWL_CTX_INTERACTIVE,
474              "print information about owl", "", ""),
475
476  OWLCMD_VOID("status", owl_command_status, OWL_CTX_ANY,
477              "print status information about the running owl", "", ""),
478 
479  OWLCMD_ARGS("zlocate", owl_command_zlocate, OWL_CTX_INTERACTIVE,
480              "locate a user",
481              "zlocate [-d] <user> ...", 
482              "Performs a zlocate on one ore more users and puts the result\n"
483              "int a popwin.  If -d is specified, does not authenticate\n"
484              "the lookup request.\n"),
485 
486  OWLCMD_ARGS("filter", owl_command_filter, OWL_CTX_ANY,
487              "create a message filter",
488              "filter <name> [ -c fgcolor ] [ -b bgcolor ] [ <expression> ... ]",
489              "The filter command creates a filter with the specified name,\n"
490              "or if one already exists it is replaced.  Example filter\n"
491              "syntax would be:\n\n"
492              "     filter myfilter -c red ( class ^foobar$ ) or ( class ^quux$ and instance ^bar$ )\n\n"
493              "Valid matching fields are:\n"
494              "    sender     -  sender\n"
495              "    recipient  -  recipient\n"
496              "    class      -  zephyr class name\n"
497              "    instance   -  zephyr instance name\n"
498              "    opcode     -  zephyr opcode\n"
499              "    realm      -  zephyr realm\n"
500              "    body       -  message body\n"
501              "    hostname   -  hostname of sending host\n"
502              "    type       -  message type (zephyr, admin...)\n"
503              "    direction  -  either 'in' 'out' or 'none'\n"
504              "    login      -  either 'login' 'logout' or 'none'\n"
505              "Also you may match on the validity of another filter:\n"
506              "    filter <filtername>\n"
507              "Also you may pass the message to a perl function returning 0 or 1,\n"
508              "where 1 indicates that the function matches the filter:\n"
509              "    perl <subname>\n"
510              "Valid operators are:\n"
511              "    and\n"
512              "    or\n"
513              "    not\n"
514              "And additionally you may use the static values:\n"
515              "    true\n"
516              "    false\n"
517              "Spaces must be present before and after parenthesis.  If the\n"
518              "optional color arguments are used they specifies the colors that\n"
519              "messages matching this filter should be displayed in.\n\n"
520              "SEE ALSO: view, viewclass, viewuser\n"),
521
522  OWLCMD_ARGS("colorview", owl_command_colorview, OWL_CTX_INTERACTIVE,
523              "change the colors on the current filter",
524              "colorview <fgcolor> [<bgcolor>]",
525              "The colors of messages in the current filter will be changed\n"
526              "to <fgcolor>,<bgcolor>.  Use the 'show colors' command for a list\n"
527              "of valid colors.\n\n"
528              "SEE ALSO: 'show colors'\n"),
529
530  OWLCMD_ARGS("colorclass", owl_command_colorclass, OWL_CTX_INTERACTIVE,
531              "create a filter to color messages of the given class name",
532              "colorclass <class> <fgcolor> [<bgcolor>]",
533              "A filter will be created to color messages in <class>"
534              "in <fgcolor>,<bgcolor>.  Use the 'show colors' command for a list\n"
535              "of valid colors.\n\n"
536              "SEE ALSO: 'show colors'\n"),
537
538  OWLCMD_ARGS("view", owl_command_view, OWL_CTX_INTERACTIVE,
539              "view messages matching a filter",
540              "view [<viewname>] [-f <filter> | --home | -r ] [-s <style>]\n"
541              "view <filter>\n"
542              "view -d <expression>\n"
543              "view --home",
544              "The view command sets information associated with a particular view,\n"
545              "such as view's filter or style.  In the first general usage listed\n"
546              "above <viewname> is the name of the view to be changed.  If not\n"
547              "specified the default view 'main' will be used.  A filter can be set\n"
548              "for the view by listing a named filter after the -f argument.  If\n"
549              "the --home argument is used the filter will be set to the filter named\n"
550              "by the\n 'view_home' variable.  The style can be set by listing the\n"
551              "name style after the -s argument.\n"
552              "\n"
553              "The other usages listed above are abbreivated forms that simply set\n"
554              "the filter of the current view. The -d option allows you to write a\n"
555              "filter expression that will be dynamically created by owl and then\n"
556              "applied as the view's filter\n"
557              "SEE ALSO: filter, viewclass, viewuser\n"),
558
559  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
560              "view only messages similar to the current message",
561              "smartnarrow [-i | --instance]",
562              "If the curmsg is a personal message narrow\n"
563              "   to the conversation with that user.\n"
564              "If the curmsg is a class message, instance foo, recip *\n"
565              "   message, narrow to the class, inst.\n"
566              "If the curmsg is a class message then narrow\n"
567              "    to the class.\n"
568              "If the curmsg is a class message and '-i' is specied\n"
569              "    then narrow to the class, instance\n"),
570
571  OWLCMD_ARGS("smartfilter", owl_command_smartfilter, OWL_CTX_INTERACTIVE,
572              "returns the name of a filter based on the current message",
573              "smartfilter [-i | --instance]",
574              "If the curmsg is a personal message, the filter is\n"
575              "   the conversation with that user.\n"
576              "If the curmsg is a class message, instance foo, recip *\n"
577              "   message, the filter is the class, inst.\n"
578              "If the curmsg is a class message, the filter is that class.\n"
579              "If the curmsg is a class message and '-i' is specied\n"
580              "    the filter is that <class,instance> pair\n"),
581
582  OWLCMD_ARGS("viewclass", owl_command_viewclass, OWL_CTX_INTERACTIVE,
583              "view messages matching a particular class",
584              "viewclass <class>",
585              "The viewclass command will automatically create a filter\n"
586              "matching the specified class and switch the current view\n"
587              "to it.\n\n"
588              "SEE ALSO: filter, view, viewuser\n"),
589  OWLCMD_ALIAS("vc", "viewclass"),
590
591  OWLCMD_ARGS("viewuser", owl_command_viewuser, OWL_CTX_INTERACTIVE,
592              "view messages matching a particular user",
593              "viewuser <user>",
594              "The viewuser command will automatically create a filter\n"
595              "matching the specified user and switch the current\n"
596              "view to it.\n\n"
597              "SEE ALSO: filter, view, viewclass\n"),
598  OWLCMD_ALIAS("vu", "viewuser"),
599
600  OWLCMD_ARGS("show", owl_command_show, OWL_CTX_INTERACTIVE,
601              "show information",
602              "show colors\n"
603              "show commands\n"
604              "show command <command>\n"
605              "show errors\n"
606              "show filters\n"
607              "show filter <filter>\n"
608              "show keymaps\n"
609              "show keymap <keymap>\n"
610              "show license\n"
611              "show startup\n"
612              "show status\n"
613              "show styles\n"
614              "show subscriptions / show subs\n"
615              "show terminal\n"
616              "show variables\n"
617              "show variable <variable>\n"
618              "show version\n"
619              "show view [<view>]\n"
620              "show zpunts\n",
621
622              "Show colors will display a list of valid colors for the\n"
623              "     terminal."
624              "Show filters will list the names of all filters.\n"
625              "Show filter <filter> will show the definition of a particular\n"
626              "     filter.\n\n"
627              "Show startup will display the custom startup config\n\n"
628              "Show zpunts will show the active zpunt filters.\n\n"
629              "Show keymaps will list the names of all keymaps.\n"
630              "Show keymap <keymap> will show the key bindings in a keymap.\n\n"
631              "Show commands will list the names of all keymaps.\n"
632              "Show command <command> will provide information about a command.\n\n"
633              "Show styles will list the names of all styles available\n"
634              "for formatting messages.\n\n"
635              "Show variables will list the names of all variables.\n\n"
636              "Show errors will show a list of errors ecountered by Owl.\n\n"
637              "SEE ALSO: filter, view, alias, bindkey, help\n"),
638 
639  OWLCMD_ARGS("delete", owl_command_delete, OWL_CTX_INTERACTIVE,
640              "mark a message for deletion",
641              "delete [ -id msgid ] [ --no-move ]\n"
642              "delete view\n"
643              "delete trash",
644              "If no message id is specified the current message is marked\n"
645              "for deletion.  Otherwise the message with the given message\n"
646              "id is marked for deltion.\n"
647              "If '--no-move' is specified, don't move after deletion.\n"
648              "If 'trash' is specified, deletes all trash/auto messages\n"
649              "in the current view.\n"
650              "If 'view' is specified, deletes all messages in the\n"
651              "current view.\n"),
652  OWLCMD_ALIAS("del", "delete"),
653
654  OWLCMD_ARGS("undelete", owl_command_undelete, OWL_CTX_INTERACTIVE,
655              "unmark a message for deletion",
656              "undelete [ -id msgid ] [ --no-move ]\n"
657              "undelete view",
658              "If no message id is specified the current message is\n"
659              "unmarked for deletion.  Otherwise the message with the\n"
660              "given message id is marked for undeltion.\n"
661              "If '--no-move' is specified, don't move after deletion.\n"
662              "If 'view' is specified, undeletes all messages\n"
663              "in the current view.\n"),
664  OWLCMD_ALIAS("undel", "undelete"),
665
666  OWLCMD_VOID("beep", owl_command_beep, OWL_CTX_ANY,
667              "ring the terminal bell",
668              "beep",
669              "Beep will ring the terminal bell.\n"
670              "If the variable 'bell' has been\n"
671              "set to 'off' this command does nothing.\n"),
672
673  OWLCMD_ARGS("debug", owl_command_debug, OWL_CTX_ANY,
674              "prints a message into the debug log",
675              "debug <message>", ""),
676
677  OWLCMD_ARGS("getview", owl_command_getview, OWL_CTX_INTERACTIVE,
678              "returns the name of the filter for the current view",
679              "", ""),
680
681  OWLCMD_ARGS("getvar", owl_command_getvar, OWL_CTX_INTERACTIVE,
682              "returns the value of a variable",
683              "getvar <varname>", ""),
684
685  OWLCMD_ARGS("getstyle", owl_command_getstyle, OWL_CTX_INTERACTIVE,
686              "returns the name of the style for the current view",
687              "", ""),
688
689  OWLCMD_ARGS("search", owl_command_search, OWL_CTX_INTERACTIVE,
690              "search messages for a particular string",
691              "search [-r] [<string>]",
692              "The search command will find messages that contain the\n"
693              "specified string and move the cursor there.  If no string\n"
694              "argument is supplied then the previous one is used.  By\n"
695              "default searches are done fowards, if -r is used the search\n"
696              "is performed backwards"),
697
698  OWLCMD_ARGS("setsearch", owl_command_setsearch, OWL_CTX_INTERACTIVE,
699              "set the search highlight string without searching",
700              "setsearch <string>",
701              "The setsearch command highlights all occurences of its\n"
702          "argument and makes it the default argument for future\n"
703          "search commands, but does not move the cursor.  With\n"
704          "no argument, it makes search inactive."),
705
706  OWLCMD_ARGS("error", owl_command_error, OWL_CTX_ANY,
707              "Display an error message",
708              "error <message>",
709              ""),
710
711  OWLCMD_ARGS("message", owl_command_message, OWL_CTX_ANY,
712              "Display an informative message",
713              "message <message>",
714              ""),
715
716  OWLCMD_VOID("yes", owl_command_yes, OWL_CTX_RECV,
717              "Answer yes to a question",
718              "yes",
719              ""),
720
721  OWLCMD_VOID("no", owl_command_no, OWL_CTX_RECV,
722              "Answer no to a question",
723              "no",
724              ""),
725
726  /****************************************************************/
727  /************************* EDIT-SPECIFIC ************************/
728  /****************************************************************/
729
730  OWLCMD_VOID_CTX("edit:move-next-word", owl_editwin_move_to_nextword, 
731                  OWL_CTX_EDIT,
732                  "moves cursor forward a word",
733                  "", ""),
734
735  OWLCMD_VOID_CTX("edit:move-prev-word", owl_editwin_move_to_previousword, 
736                  OWL_CTX_EDIT,
737                  "moves cursor backwards a word",
738                  "", ""),
739
740  OWLCMD_VOID_CTX("edit:move-to-buffer-start", owl_editwin_move_to_top,
741                  OWL_CTX_EDIT,
742                  "moves cursor to the top left (start) of the buffer",
743                  "", ""),
744
745  OWLCMD_VOID_CTX("edit:move-to-buffer-end", owl_editwin_move_to_end, 
746                  OWL_CTX_EDIT,
747                  "moves cursor to the bottom right (end) of the buffer",
748                  "", ""),
749
750  OWLCMD_VOID_CTX("edit:move-to-line-end", owl_editwin_move_to_line_end, 
751                  OWL_CTX_EDIT,
752                  "moves cursor to the end of the line",
753                  "", ""),
754
755  OWLCMD_VOID_CTX("edit:move-to-line-start", owl_editwin_move_to_line_start, 
756                  OWL_CTX_EDIT,
757                  "moves cursor to the beginning of the line",
758                  "", ""),
759
760  OWLCMD_VOID_CTX("edit:move-left", owl_editwin_key_left, 
761                  OWL_CTX_EDIT,
762                  "moves the cursor left by a character",
763                  "", ""),
764
765  OWLCMD_VOID_CTX("edit:move-right", owl_editwin_key_right,
766                  OWL_CTX_EDIT,
767                  "moves the cursor right by a character",
768                  "", ""),
769
770  OWLCMD_VOID_CTX("edit:delete-next-word", owl_editwin_delete_nextword,
771                  OWL_CTX_EDIT,
772                  "deletes the word to the right of the cursor",
773                  "", ""),
774
775  OWLCMD_VOID_CTX("edit:delete-prev-word", owl_editwin_delete_previousword,
776                  OWL_CTX_EDIT,
777                  "deletes the word to the left of the cursor",
778                  "", ""),
779
780  OWLCMD_VOID_CTX("edit:delete-prev-char", owl_editwin_backspace,
781                  OWL_CTX_EDIT,
782                  "deletes the character to the left of the cursor",
783                  "", ""),
784
785  OWLCMD_VOID_CTX("edit:delete-next-char", owl_editwin_delete_char, 
786                  OWL_CTX_EDIT,
787                  "deletes the character to the right of the cursor",
788                  "", ""),
789
790  OWLCMD_VOID_CTX("edit:delete-to-line-end", owl_editwin_delete_to_endofline,
791                  OWL_CTX_EDIT,
792                  "deletes from the cursor to the end of the line",
793                  "", ""),
794
795  OWLCMD_VOID_CTX("edit:delete-all", owl_editwin_clear, 
796                  OWL_CTX_EDIT,
797                  "deletes all of the contents of the buffer",
798                  "", ""),
799
800  OWLCMD_VOID_CTX("edit:transpose-chars", owl_editwin_transpose_chars,
801                  OWL_CTX_EDIT,
802                  "Interchange characters around point, moving forward one character.",
803                  "", ""),
804
805  OWLCMD_VOID_CTX("edit:fill-paragraph", owl_editwin_fill_paragraph, 
806                  OWL_CTX_EDIT,
807                  "fills the current paragraph to line-wrap well",
808                  "", ""),
809
810  OWLCMD_VOID_CTX("edit:recenter", owl_editwin_recenter, 
811                  OWL_CTX_EDIT,
812                  "recenters the buffer",
813                  "", ""),
814
815  OWLCMD_ARGS_CTX("edit:insert-text", owl_command_edit_insert_text, 
816                  OWL_CTX_EDIT,
817                  "inserts text into the buffer",
818                  "edit:insert-text <text>", ""),
819
820  OWLCMD_VOID_CTX("edit:cancel", owl_command_edit_cancel, 
821                  OWL_CTX_EDIT,
822                  "cancels the current command",
823                  "", ""),
824
825  OWLCMD_VOID_CTX("edit:history-next", owl_command_edit_history_next, 
826                  OWL_CTX_EDIT,
827                  "replaces the text with the previous history",
828                  "", ""),
829
830  OWLCMD_VOID_CTX("edit:history-prev", owl_command_edit_history_prev, 
831                  OWL_CTX_EDIT,
832                  "replaces the text with the previous history",
833                  "", ""),
834
835  OWLCMD_VOID_CTX("editline:done", owl_command_editline_done, 
836                  OWL_CTX_EDITLINE,
837                  "completes the command (eg, executes command being composed)",
838                  "", ""),
839
840  OWLCMD_VOID_CTX("editresponse:done", owl_command_editresponse_done, 
841                  OWL_CTX_EDITRESPONSE,
842                  "completes the response to a question",
843                  "", ""),
844
845  OWLCMD_VOID_CTX("editmulti:move-up-line", owl_editwin_key_up, 
846                  OWL_CTX_EDITMULTI,
847                  "moves the cursor up one line",
848                  "", ""),
849
850  OWLCMD_VOID_CTX("editmulti:move-down-line", owl_editwin_key_down, 
851                  OWL_CTX_EDITMULTI,
852                  "moves the cursor down one line",
853                  "", ""),
854
855  OWLCMD_VOID_CTX("editmulti:done", owl_command_editmulti_done, 
856                  OWL_CTX_EDITMULTI,
857                  "completes the command (eg, sends message being composed)",
858                  "", ""),
859
860  OWLCMD_VOID_CTX("editmulti:done-or-delete", owl_command_editmulti_done_or_delete, 
861                  OWL_CTX_EDITMULTI,
862                  "completes the command, but only if at end of message",
863                  "", 
864                  "If only whitespace is to the right of the cursor,\n"
865                  "runs 'editmulti:done'.\n"\
866                  "Otherwise runs 'edit:delete-next-char'\n"),
867
868  /****************************************************************/
869  /********************** POPLESS-SPECIFIC ************************/
870  /****************************************************************/
871
872  OWLCMD_VOID_CTX("popless:scroll-down-page", owl_viewwin_pagedown, 
873                  OWL_CTX_POPLESS,
874                  "scrolls down one page",
875                  "", ""),
876
877  OWLCMD_VOID_CTX("popless:scroll-down-line", owl_viewwin_linedown, 
878                  OWL_CTX_POPLESS,
879                  "scrolls down one line",
880                  "", ""),
881
882  OWLCMD_VOID_CTX("popless:scroll-up-page", owl_viewwin_pageup, 
883                  OWL_CTX_POPLESS,
884                  "scrolls up one page",
885                  "", ""),
886
887  OWLCMD_VOID_CTX("popless:scroll-up-line", owl_viewwin_lineup, 
888                  OWL_CTX_POPLESS,
889                  "scrolls up one line",
890                  "", ""),
891
892  OWLCMD_VOID_CTX("popless:scroll-to-top", owl_viewwin_top, 
893                  OWL_CTX_POPLESS,
894                  "scrolls to the top of the buffer",
895                  "", ""),
896
897  OWLCMD_VOID_CTX("popless:scroll-to-bottom", owl_viewwin_bottom, 
898                  OWL_CTX_POPLESS,
899                  "scrolls to the bottom of the buffer",
900                  "", ""),
901
902  OWLCMD_INT_CTX ("popless:scroll-right", owl_viewwin_right, 
903                  OWL_CTX_POPLESS,
904                  "scrolls right in the buffer",
905                  "popless:scroll-right <num-chars>", ""),
906
907  OWLCMD_INT_CTX ("popless:scroll-left", owl_viewwin_left, 
908                  OWL_CTX_POPLESS,
909                  "scrolls left in the buffer",
910                  "popless:scroll-left <num-chars>", ""),
911
912  OWLCMD_VOID_CTX("popless:quit", owl_command_popless_quit, 
913                  OWL_CTX_POPLESS,
914                  "exits the popless window",
915                  "", ""),
916
917  OWLCMD_ALIAS("webzephyr", "zwrite daemon.webzephyr -c webzephyr -i"),
918
919  /* This line MUST be last! */
920  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
921
922};
923
924void owl_command_info()
925{
926  owl_function_info();
927}
928
929void owl_command_nop()
930{
931}
932
933char *owl_command_help(int argc, char **argv, char *buff)
934{
935  if (argc!=2) {
936    owl_help();
937    return NULL;
938  }
939 
940  owl_function_help_for_command(argv[1]);
941  return NULL;
942}
943
944char *owl_command_zlist(int argc, char **argv, char *buff)
945{
946  int elapsed=0, timesort=0;
947  char *file=NULL;
948
949  argc--;
950  argv++;
951  while (argc) {
952    if (!strcmp(argv[0], "-e")) {
953      elapsed=1;
954      argc--;
955      argv++;
956    } else if (!strcmp(argv[0], "-t")) {
957      timesort=1;
958      argc--;
959      argv++;
960    } else if (!strcmp(argv[0], "-f")) {
961      if (argc==1) {
962        owl_function_makemsg("zlist: -f needs an argument");
963        return(NULL);
964      }
965      file=argv[1];
966      argc-=2;
967      argv+=2;
968    } else {
969      owl_function_makemsg("zlist: unknown argument");
970      return(NULL);
971    }
972  }
973  owl_function_buddylist(0, 1, file);
974  return(NULL);
975}
976
977char *owl_command_blist()
978{
979  owl_function_buddylist(1, 1, NULL);
980  return(NULL);
981}
982
983char *owl_command_toggleoneline()
984{
985  owl_function_toggleoneline();
986  return(NULL);
987}
988
989void owl_command_about()
990{
991  owl_function_about();
992}
993
994void owl_command_version()
995{
996  char buff[1024];
997
998  sprintf(buff, "Owl version %s", OWL_VERSION_STRING);
999  owl_function_makemsg(buff);
1000}
1001
1002char *owl_command_addbuddy(int argc, char **argv, char *buff)
1003{
1004  if (argc!=3) {
1005    owl_function_makemsg("usage: addbuddy <protocol> <buddyname>");
1006    return(NULL);
1007  }
1008
1009  /* TODO add a hook for perl modules */
1010  if (!strcasecmp(argv[1], "zephyr")) {
1011    owl_zephyr_addbuddy(argv[2]);
1012    owl_function_makemsg("%s added as zephyr buddy", argv[2]);
1013  } else {
1014    owl_function_makemsg("addbuddy: currently the only supported protocol is 'zephyr'");
1015  }
1016
1017  return(NULL);
1018}
1019
1020char *owl_command_delbuddy(int argc, char **argv, char *buff)
1021{
1022  if (argc!=3) {
1023    owl_function_makemsg("usage: delbuddy <protocol> <buddyname>");
1024    return(NULL);
1025  }
1026
1027  /* TODO add a hook for perl modules */
1028  if (!strcasecmp(argv[1], "zephyr")) {
1029    owl_zephyr_delbuddy(argv[2]);
1030    owl_function_makemsg("%s deleted as zephyr buddy", argv[2]);
1031  } else {
1032    owl_function_makemsg("delbuddy: currently the only supported protocol is 'zephyr'");
1033  }
1034
1035  return(NULL);
1036}
1037
1038char *owl_command_startup(int argc, char **argv, char *buff)
1039{
1040  char *ptr;
1041
1042  if (argc<2) {
1043    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
1044    return(NULL);
1045  }
1046
1047  ptr=strchr(buff, ' ');
1048  if (!ptr) {
1049    owl_function_makemsg("Parse error finding command for startup");
1050    return(NULL);
1051  }
1052
1053  owl_function_command(ptr+1);
1054  owl_function_addstartup(ptr+1);
1055
1056  return(NULL);
1057}
1058
1059char *owl_command_unstartup(int argc, char **argv, char *buff)
1060{
1061  char *ptr;
1062
1063  if (argc<2) {
1064    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
1065    return(NULL);
1066  }
1067
1068  ptr=strchr(buff, ' ');
1069  if (!ptr) {
1070    owl_function_makemsg("Parse error finding command for unstartup");
1071    return(NULL);
1072  }
1073
1074  owl_function_delstartup(ptr+1);
1075
1076  return(NULL);
1077}
1078
1079char *owl_command_dump(int argc, char **argv, char *buff)
1080{
1081  char *filename;
1082 
1083  if (argc!=2) {
1084    owl_function_makemsg("usage: dump <filename>");
1085    return(NULL);
1086  }
1087  filename=owl_util_makepath(argv[1]);
1088  owl_function_dump(filename);
1089  owl_free(filename);
1090  return(NULL);
1091}
1092
1093char *owl_command_source(int argc, char **argv, char *buff)
1094{
1095  if (argc!=2) {
1096    owl_function_makemsg("usage: source <filename>");
1097    return(NULL);
1098  }
1099
1100  owl_function_source(argv[1]);
1101  return(NULL);
1102}
1103
1104char *owl_command_next(int argc, char **argv, char *buff)
1105{
1106  char *filter=NULL;
1107  int skip_deleted=0, last_if_none=0;
1108  while (argc>1) {
1109    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
1110      skip_deleted=1;
1111      argc-=1; argv+=1; 
1112    } else if (argc>=1 && !strcmp(argv[1], "--last-if-none")) {
1113      last_if_none=1;
1114      argc-=1; argv+=1; 
1115    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
1116      filter = owl_strdup(argv[2]);
1117      argc-=2; argv+=2; 
1118    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
1119      filter = owl_function_smartfilter(0);
1120      argc-=2; argv+=2; 
1121    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
1122      filter = owl_function_smartfilter(1);
1123      argc-=2; argv+=2; 
1124    } else {
1125      owl_function_makemsg("Invalid arguments to command 'next'.");
1126      return(NULL);
1127    }
1128  }
1129  owl_function_nextmsg_full(filter, skip_deleted, last_if_none);
1130  if (filter) owl_free(filter);
1131  return(NULL);
1132}
1133
1134char *owl_command_prev(int argc, char **argv, char *buff)
1135{
1136  char *filter=NULL;
1137  int skip_deleted=0, first_if_none=0;
1138  while (argc>1) {
1139    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
1140      skip_deleted=1;
1141      argc-=1; argv+=1; 
1142    } else if (argc>=1 && !strcmp(argv[1], "--first-if-none")) {
1143      first_if_none=1;
1144      argc-=1; argv+=1; 
1145    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
1146      filter = owl_strdup(argv[2]);
1147      argc-=2; argv+=2; 
1148    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
1149      filter = owl_function_smartfilter(0);
1150      argc-=2; argv+=2; 
1151    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
1152      filter = owl_function_smartfilter(1);
1153      argc-=2; argv+=2; 
1154   } else {
1155      owl_function_makemsg("Invalid arguments to command 'prev'.");
1156      return(NULL);
1157    }
1158  }
1159  owl_function_prevmsg_full(filter, skip_deleted, first_if_none);
1160  if (filter) owl_free(filter);
1161  return(NULL);
1162}
1163
1164char *owl_command_smartnarrow(int argc, char **argv, char *buff)
1165{
1166  char *filtname = NULL;
1167
1168  if (argc == 1) {
1169    filtname = owl_function_smartfilter(0);
1170  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
1171    filtname = owl_function_smartfilter(1);
1172  } else {
1173    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
1174  }
1175  if (filtname) {
1176    owl_function_change_currentview_filter(filtname);
1177    owl_free(filtname);
1178  }
1179  return NULL;
1180}
1181
1182char *owl_command_smartfilter(int argc, char **argv, char *buff)
1183{
1184  char *filtname = NULL;
1185
1186  if (argc == 1) {
1187    filtname = owl_function_smartfilter(0);
1188  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
1189    filtname = owl_function_smartfilter(1);
1190  } else {
1191    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
1192  }
1193  return filtname;
1194}
1195
1196void owl_command_expunge()
1197{
1198  owl_function_expunge();
1199}
1200
1201void owl_command_first()
1202{
1203  owl_global_set_rightshift(&g, 0);
1204  owl_function_firstmsg();
1205}
1206
1207void owl_command_last()
1208{
1209  owl_function_lastmsg();
1210}
1211
1212void owl_command_resize()
1213{
1214  owl_function_resize();
1215}
1216
1217void owl_command_redisplay()
1218{
1219  owl_function_full_redisplay();
1220  owl_global_set_needrefresh(&g);
1221}
1222
1223void owl_command_shift_right()
1224{
1225  owl_function_shift_right();
1226}
1227
1228void owl_command_shift_left()
1229{
1230  owl_function_shift_left();
1231}
1232
1233void owl_command_unsuball()
1234{
1235  owl_function_unsuball();
1236}
1237
1238char *owl_command_loadsubs(int argc, char **argv, char *buff)
1239{
1240  if (argc == 2) {
1241    owl_function_loadsubs(argv[1]);
1242  } else if (argc == 1) {
1243    owl_function_loadsubs(NULL);
1244  } else {
1245    owl_function_makemsg("Wrong number of arguments for load-subs.");
1246    return(NULL);
1247  }
1248  return(NULL);
1249}
1250
1251
1252char *owl_command_loadloginsubs(int argc, char **argv, char *buff)
1253{
1254  if (argc == 2) {
1255    owl_function_loadloginsubs(argv[1]);
1256  } else if (argc == 1) {
1257    owl_function_loadloginsubs(NULL);
1258  } else {
1259    owl_function_makemsg("Wrong number of arguments for load-subs.");
1260    return(NULL);
1261  }
1262  return(NULL);
1263}
1264
1265void owl_command_suspend()
1266{
1267  owl_function_suspend();
1268}
1269
1270char *owl_command_start_command(int argc, char **argv, char *buff)
1271{
1272  buff = skiptokens(buff, 1);
1273  owl_function_start_command(buff);
1274  return(NULL);
1275}
1276
1277char *owl_command_start_question(int argc, char **argv, char *buff)
1278{
1279  buff = skiptokens(buff, 1);
1280  owl_function_start_question(buff);
1281  return(NULL);
1282}
1283
1284char *owl_command_start_password(int argc, char **argv, char *buff)
1285{
1286  buff = skiptokens(buff, 1);
1287  owl_function_start_password(buff);
1288  return(NULL);
1289}
1290
1291char *owl_command_zaway(int argc, char **argv, char *buff)
1292{
1293  if ((argc==1) ||
1294      ((argc==2) && !strcmp(argv[1], "on"))) {
1295    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
1296    owl_function_zaway_on();
1297    return NULL;
1298  }
1299
1300  if (argc==2 && !strcmp(argv[1], "off")) {
1301    owl_function_zaway_off();
1302    return NULL;
1303  }
1304
1305  if (argc==2 && !strcmp(argv[1], "toggle")) {
1306    owl_function_zaway_toggle();
1307    return NULL;
1308  }
1309
1310  buff = skiptokens(buff, 1);
1311  owl_global_set_zaway_msg(&g, buff);
1312  owl_function_zaway_on();
1313  return NULL;
1314}
1315
1316
1317char *owl_command_away(int argc, char **argv, char *buff)
1318{
1319  /* TODO add a hook for perl modules */
1320  if ((argc==1) ||
1321      ((argc==2) && !strcmp(argv[1], "on"))) {
1322    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
1323    owl_function_zaway_on();
1324    return NULL;
1325  }
1326
1327  if (argc==2 && !strcmp(argv[1], "off")) {
1328    owl_function_zaway_off();
1329    return NULL;
1330  }
1331
1332  if (argc==2 && !strcmp(argv[1], "toggle")) {
1333    /* if either one is on, turn it off, otherwise toggle both (turn
1334     *  them both on)
1335     */
1336    if (!owl_global_is_zaway(&g) /* && !owl_global_is_aaway(&g) */) {
1337      owl_function_zaway_toggle();
1338      owl_function_makemsg("Away messages set.");
1339    } else {
1340      if (owl_global_is_zaway(&g)) owl_function_zaway_toggle();
1341      owl_function_makemsg("Away messages off.");
1342    }
1343    return NULL;
1344  }
1345
1346  buff = skiptokens(buff, 1);
1347  owl_global_set_zaway_msg(&g, buff);
1348  owl_function_zaway_on();
1349  owl_function_makemsg("Away messages set.");
1350  return NULL;
1351}
1352
1353char *owl_command_set(int argc, char **argv, char *buff)
1354{
1355  char *var, *val;
1356  int  silent=0;
1357  int requirebool=0;
1358
1359  if (argc == 1) {
1360    owl_function_printallvars();
1361    return NULL;
1362  } 
1363
1364  if (argc > 1 && !strcmp("-q",argv[1])) {
1365    silent = 1;
1366    argc--; argv++;
1367  }
1368
1369  if (argc == 2) {
1370    var=argv[1];
1371    val="on";
1372    requirebool=1;
1373  } else if (argc == 3) {
1374    var=argv[1];
1375    val=argv[2];
1376  } else {
1377    owl_function_makemsg("Wrong number of arguments for set command");
1378    return NULL;
1379  }
1380  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
1381  return NULL;
1382}
1383
1384char *owl_command_unset(int argc, char **argv, char *buff)
1385{
1386  char *var, *val;
1387  int  silent=0;
1388
1389  if (argc > 1 && !strcmp("-q",argv[1])) {
1390    silent = 1;
1391    argc--; argv++;
1392  }
1393  if (argc == 2) {
1394    var=argv[1];
1395    val="off";
1396  } else {
1397    owl_function_makemsg("Wrong number of arguments for unset command");
1398    return NULL;
1399  }
1400  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
1401  return NULL;
1402}
1403
1404char *owl_command_print(int argc, char **argv, char *buff)
1405{
1406  char *var;
1407  char valbuff[1024];
1408
1409  if (argc==1) {
1410    owl_function_printallvars();
1411    return NULL;
1412  } else if (argc!=2) {
1413    owl_function_makemsg("Wrong number of arguments for print command");
1414    return NULL;
1415  }
1416
1417  var=argv[1];
1418   
1419  if (0 == owl_variable_get_tostring(owl_global_get_vardict(&g), 
1420                                     var, valbuff, 1024)) {
1421    owl_function_makemsg("%s = '%s'", var, valbuff);
1422  } else {
1423    owl_function_makemsg("Unknown variable '%s'.", var);
1424  }
1425  return NULL;
1426}
1427
1428
1429char *owl_command_exec(int argc, char **argv, char *buff)
1430{
1431  return owl_function_exec(argc, argv, buff, 0);
1432}
1433
1434char *owl_command_pexec(int argc, char **argv, char *buff)
1435{
1436  return owl_function_exec(argc, argv, buff, 1);
1437}
1438
1439char *owl_command_aexec(int argc, char **argv, char *buff)
1440{
1441  return owl_function_exec(argc, argv, buff, 2);
1442}
1443
1444char *owl_command_perl(int argc, char **argv, char *buff)
1445{
1446  return owl_function_perl(argc, argv, buff, 0);
1447}
1448
1449char *owl_command_pperl(int argc, char **argv, char *buff)
1450{
1451  return owl_function_perl(argc, argv, buff, 1);
1452}
1453
1454char *owl_command_aperl(int argc, char **argv, char *buff)
1455{
1456  return owl_function_perl(argc, argv, buff, 2);
1457}
1458
1459char *owl_command_multi(int argc, char **argv, char *buff)
1460{
1461  char *lastrv = NULL, *dupbuff, *newbuff;
1462  char **commands;
1463  int  ncommands, i;
1464  if (argc < 2) {
1465    owl_function_makemsg("Invalid arguments to 'multi' command.");   
1466    return NULL;
1467  }
1468  dupbuff = owl_strdup(buff);
1469  newbuff = skiptokens(dupbuff, 1);
1470  if (!strcmp(argv[0], "(")) {
1471    for (i=strlen(newbuff)-1; i>=0; i--) {
1472      if (newbuff[i] == ')') {
1473        newbuff[i] = '\0';
1474        break;
1475      } else if (newbuff[i] != ' ') {
1476        owl_function_makemsg("Invalid arguments to 'multi' command.");   
1477        owl_free(newbuff);
1478        return NULL;
1479      }
1480    }
1481  }
1482  commands = atokenize(newbuff, ";", &ncommands);
1483  for (i=0; i<ncommands; i++) {
1484    if (lastrv) {
1485      owl_free(lastrv);
1486    }
1487    lastrv = owl_function_command(commands[i]);
1488  }
1489  owl_free(dupbuff);
1490  atokenize_free(commands, ncommands);
1491  return lastrv;
1492}
1493
1494
1495char *owl_command_alias(int argc, char **argv, char *buff)
1496{
1497  if (argc < 3) {
1498    owl_function_makemsg("Invalid arguments to 'alias' command.");
1499    return NULL;
1500  }
1501  buff = skiptokens(buff, 2);
1502  owl_function_command_alias(argv[1], buff);
1503  return (NULL);
1504}
1505
1506
1507char *owl_command_bindkey(int argc, char **argv, char *buff)
1508{
1509  owl_keymap *km;
1510  int ret;
1511
1512  if (argc < 5 || strcmp(argv[3], "command")) {
1513    owl_function_makemsg("Usage: bindkey <keymap> <binding> command <cmd>");
1514    return NULL;
1515  }
1516  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), argv[1]);
1517  if (!km) {
1518    owl_function_makemsg("No such keymap '%s'", argv[1]);
1519    return NULL;
1520  }
1521  buff = skiptokens(buff, 4);
1522  ret = owl_keymap_create_binding(km, argv[2], buff, NULL, "*user*");
1523  if (ret!=0) {
1524    owl_function_makemsg("Unable to bind '%s' in keymap '%s' to '%s'.",
1525                         argv[2], argv[1], buff);
1526    return NULL;
1527  }
1528  return NULL;
1529}
1530
1531void owl_command_quit()
1532{
1533  owl_function_quit();
1534}
1535
1536char *owl_command_debug(int argc, char **argv, char *buff)
1537{
1538  if (argc<2) {
1539    owl_function_makemsg("Need at least one argument to debug command");
1540    return(NULL);
1541  }
1542
1543  if (!owl_global_is_debug_fast(&g)) {
1544    owl_function_makemsg("Debugging is not turned on");
1545    return(NULL);
1546  }
1547
1548  owl_function_debugmsg(argv[1]);
1549  return(NULL);
1550}
1551
1552char *owl_command_term(int argc, char **argv, char *buff)
1553{
1554  if (argc<2) {
1555    owl_function_makemsg("Need at least one argument to the term command");
1556    return(NULL);
1557  }
1558
1559  if (!strcmp(argv[1], "raise")) {
1560    owl_function_xterm_raise();
1561  } else if (!strcmp(argv[1], "deiconify")) {
1562    owl_function_xterm_deiconify();
1563  } else {
1564    owl_function_makemsg("Unknown terminal subcommand");
1565  }
1566  return(NULL);
1567}
1568
1569char *owl_command_zlog(int argc, char **argv, char *buff)
1570{
1571  if ((argc<2) || (argc>3)) {
1572    owl_function_makemsg("Wrong number of arguments for zlog command");
1573    return(NULL);
1574  }
1575
1576  if (!strcmp(argv[1], "in")) {
1577    if (argc>2) {
1578      owl_global_set_tty(&g, argv[2]);
1579    }
1580    owl_zephyr_zlog_in();
1581  } else if (!strcmp(argv[1], "out")) {
1582    if (argc!=2) {
1583      owl_function_makemsg("Wrong number of arguments for zlog command");
1584      return(NULL);
1585    }
1586    owl_zephyr_zlog_out();
1587  } else {
1588    owl_function_makemsg("Invalid subcommand for zlog");
1589  }
1590  return(NULL);
1591}
1592
1593
1594void owl_command_zlog_out(void)
1595{
1596  owl_zephyr_zlog_out();
1597}
1598
1599
1600char *owl_command_subscribe(int argc, char **argv, char *buff)
1601{
1602  char *recip="";
1603  int temp=0;
1604  int ret=0;
1605 
1606  if (argc<3) {
1607    owl_function_makemsg("Not enough arguments to the subscribe command");
1608    return(NULL);
1609  }
1610  argc--;
1611  argv++;
1612
1613  if (!strcmp(argv[0], "-t")) {
1614    temp=1;
1615    argc--;
1616    argv++;
1617  }
1618  if (argc<2) {
1619    owl_function_makemsg("Not enough arguments to the subscribe command");
1620    return(NULL);
1621  }
1622
1623  if (argc>3) {
1624    owl_function_makemsg("Too many arguments to the subscribe command");
1625    return(NULL);
1626  }
1627
1628  if (argc==2) {
1629    recip="";
1630  } else if (argc==3) {
1631    recip=argv[2];
1632  }
1633
1634  ret = owl_function_subscribe(argv[0], argv[1], recip);
1635  if (!temp && !ret) {
1636    owl_zephyr_addsub(NULL, argv[0], argv[1], recip);
1637  }
1638  return(NULL);
1639}
1640
1641
1642char *owl_command_unsubscribe(int argc, char **argv, char *buff)
1643{
1644  char *recip="";
1645  int temp=0;
1646
1647  if (argc<3) {
1648    owl_function_makemsg("Not enough arguments to the unsubscribe command");
1649    return(NULL);
1650  }
1651  argc--;
1652  argv++;
1653
1654  if (!strcmp(argv[0], "-t")) {
1655    temp=1;
1656    argc--;
1657    argv++;
1658  }
1659  if (argc<2) {
1660    owl_function_makemsg("Not enough arguments to the subscribe command");
1661    return(NULL);
1662  }
1663
1664  if (argc>3) {
1665    owl_function_makemsg("Too many arguments to the unsubscribe command");
1666    return(NULL);
1667  }
1668
1669  if (argc==2) {
1670    recip="";
1671  } else if (argc==3) {
1672    recip=argv[2];
1673  }
1674
1675  owl_function_unsubscribe(argv[0], argv[1], recip);
1676  if (!temp) {
1677    owl_zephyr_delsub(NULL, argv[0], argv[1], recip);
1678  }
1679  return(NULL);
1680}
1681
1682char *owl_command_echo(int argc, char **argv, char *buff)
1683{
1684  buff = skiptokens(buff, 1);
1685  owl_function_popless_text(buff);
1686  return NULL;
1687}
1688
1689void owl_command_getsubs(void)
1690{
1691  owl_function_getsubs();
1692}
1693
1694void owl_command_status(void)
1695{
1696  owl_function_status();
1697}
1698
1699char *owl_command_zwrite(int argc, char **argv, char *buff)
1700{
1701  owl_zwrite z;
1702
1703  if (!owl_global_is_havezephyr(&g)) {
1704    owl_function_makemsg("Zephyr is not available");
1705    return(NULL);
1706  }
1707  /* check for a zwrite -m */
1708  owl_zwrite_create_from_line(&z, buff);
1709  if (owl_zwrite_is_message_set(&z)) {
1710    owl_function_zwrite(buff, NULL);
1711    owl_zwrite_free(&z);
1712    return (NULL);
1713  }
1714
1715  if (argc < 2) {
1716    owl_function_makemsg("Not enough arguments to the zwrite command.");
1717  } else {
1718    owl_function_zwrite_setup(buff);
1719  }
1720  return(NULL);
1721}
1722
1723char *owl_command_loopwrite(int argc, char **argv, char *buff)
1724{
1725  owl_function_loopwrite_setup();
1726  return(NULL);
1727}
1728
1729char *owl_command_zcrypt(int argc, char **argv, char *buff)
1730{
1731#ifdef OWL_ENABLE_ZCRYPT
1732  owl_zwrite z;
1733
1734  if (!owl_global_is_havezephyr(&g)) {
1735    owl_function_makemsg("Zephyr is not available");
1736    return(NULL);
1737  }
1738  /* check for a zcrypt -m */
1739  owl_zwrite_create_from_line(&z, buff);
1740  if (owl_zwrite_is_message_set(&z)) {
1741    owl_function_zcrypt(buff, NULL);
1742    owl_zwrite_free(&z);
1743    return (NULL);
1744  }
1745
1746  if (argc < 2) {
1747    owl_function_makemsg("Not enough arguments to the zcrypt command.");
1748  } else {
1749    owl_function_zwrite_setup(buff);
1750  }
1751  return(NULL);
1752#else
1753  owl_function_makemsg("This Owl does not support zcrypt");
1754#endif
1755}
1756
1757char *owl_command_reply(int argc, char **argv, char *buff)
1758{
1759  int edit=0;
1760 
1761  if (argc>=2 && !strcmp("-e", argv[1])) {
1762    edit=1;
1763    argv++;
1764    argc--;
1765  }
1766
1767  if ((argc==1) || (argc==2 && !strcmp(argv[1], "all"))) {   
1768    owl_function_reply(0, !edit);
1769  } else if (argc==2 && !strcmp(argv[1], "sender")) {
1770    owl_function_reply(1, !edit);
1771  } else if (argc==2 && !strcmp(argv[1], "zaway")) {
1772    owl_message *m;
1773    owl_view    *v;
1774    v = owl_global_get_current_view(&g);   
1775    m = owl_view_get_element(v, owl_global_get_curmsg(&g));
1776    if (m) owl_zephyr_zaway(m);
1777  } else {
1778    owl_function_makemsg("Invalid arguments to the reply command.");
1779  }
1780  return NULL;
1781}
1782
1783char *owl_command_filter(int argc, char **argv, char *buff)
1784{
1785  owl_function_create_filter(argc, argv);
1786  return NULL;
1787}
1788
1789char *owl_command_zlocate(int argc, char **argv, char *buff)
1790{
1791  int auth;
1792 
1793  if (argc<2) {
1794    owl_function_makemsg("Too few arguments for zlocate command");
1795    return NULL;
1796  }
1797
1798  auth=1;
1799  if (!strcmp(argv[1], "-d")) {
1800    if (argc>2) {
1801      auth=0;
1802      argc--;
1803      argv++;
1804    } else {
1805      owl_function_makemsg("Missing arguments for zlocate command");
1806      return NULL;
1807    }
1808  }
1809
1810  argc--;
1811  argv++;
1812  owl_function_zlocate(argc, argv, auth);
1813  return NULL;
1814}
1815
1816
1817/* Backwards compatability has made this kind of complicated:
1818 * view [<viewname>] [-f <filter> | -d <expression> | --home | -r ] [-s <style>]
1819 * view <filter>
1820 * view -d <expression>
1821 * view --home
1822 */
1823char *owl_command_view(int argc, char **argv, char *buff)
1824{
1825  /* First take the 'view --home' and 'view -r' cases */
1826  if (argc == 2) {
1827    if (!strcmp(argv[1], "--home")) {
1828      owl_function_change_currentview_filter(owl_global_get_view_home(&g));
1829      return(NULL);
1830    } else if (!strcmp(argv[1], "-r")) {
1831      char *foo;
1832      foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
1833      owl_function_change_currentview_filter(foo);
1834      owl_free(foo);
1835      return(NULL);
1836    }
1837  }
1838
1839  /* Now look for 'view <filter>' */
1840  if (argc==2) {
1841    owl_function_change_currentview_filter(argv[1]);
1842    return(NULL);
1843  }
1844
1845  /* Now get 'view -d <expression>' */
1846  if (argc>=3 && !strcmp(argv[1], "-d")) {
1847    char **myargv;
1848    int i;
1849
1850    myargv=owl_malloc((argc*sizeof(char *))+50);
1851    myargv[0]="";
1852    myargv[1]="owl-dynamic";
1853    for (i=2; i<argc; i++) {
1854      myargv[i]=argv[i];
1855    }
1856    owl_function_create_filter(argc, myargv);
1857    owl_function_change_currentview_filter("owl-dynamic");
1858    owl_free(myargv);
1859    return NULL;
1860  }
1861
1862  /* Finally handle the general case */
1863  if (argc<3) {
1864    owl_function_makemsg("Too few arguments to the view command.");
1865    return(NULL);
1866  }
1867  argc--;
1868  argv++;
1869  if (strcmp(argv[0], "-f") &&
1870      strcmp(argv[0], "-d") &&
1871      strcmp(argv[0], "--home") &&
1872      strcmp(argv[0], "-s") &&
1873      strcmp(argv[0], "-r")) {
1874    if (strcmp(argv[0], "main")) {
1875      owl_function_makemsg("No view named '%s'", argv[0]);
1876      return(NULL);
1877    }
1878    argc--;
1879    argv++;
1880  }
1881  while (argc) {
1882    if (!strcmp(argv[0], "-f")) {
1883      if (argc<2) {
1884        owl_function_makemsg("Too few argments to the view command");
1885        return(NULL);
1886      }
1887      owl_function_change_currentview_filter(argv[1]);
1888      argc-=2;
1889      argv+=2;
1890    } else if (!strcmp(argv[0], "--home")) {
1891      owl_function_change_currentview_filter(owl_global_get_view_home(&g));
1892      argc--;
1893      argv++;
1894    } else if (!strcmp(argv[0], "-r")) {
1895      char *foo;
1896      foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
1897      owl_function_change_currentview_filter(foo);
1898    } else if (!strcmp(argv[0], "-s")) {
1899      if (argc<2) {
1900        owl_function_makemsg("Too few argments to the view command");
1901        return(NULL);
1902      }
1903      owl_function_change_style(owl_global_get_current_view(&g), argv[1]);
1904      argc-=2;
1905      argv+=2;
1906    } else {
1907      owl_function_makemsg("Too few argments to the view command");
1908      return(NULL);
1909    }
1910   
1911  }
1912  return(NULL);
1913}
1914
1915char *owl_command_show(int argc, char **argv, char *buff)
1916{
1917  if (argc<2) {
1918    owl_function_help_for_command("show");
1919    return NULL;
1920  }
1921
1922  if (!strcmp(argv[1], "filter") || !strcmp(argv[1], "filters")) {
1923    if (argc==2) {
1924      owl_function_show_filters();
1925    } else {
1926      owl_function_show_filter(argv[2]);
1927    }
1928  } else if (argc==2 
1929             && (!strcmp(argv[1], "zpunts") || !strcmp(argv[1], "zpunted"))) {
1930    owl_function_show_zpunts();
1931  } else if (!strcmp(argv[1], "command") || !strcmp(argv[1], "commands")) {
1932    if (argc==2) {
1933      owl_function_show_commands();
1934    } else {
1935      owl_function_show_command(argv[2]);
1936    }
1937  } else if (!strcmp(argv[1], "variable") || !strcmp(argv[1], "variables")) {
1938    if (argc==2) {
1939      owl_function_show_variables();
1940    } else {
1941      owl_function_show_variable(argv[2]);
1942    }
1943  } else if (!strcmp(argv[1], "keymap") || !strcmp(argv[1], "keymaps")) {
1944    if (argc==2) {
1945      owl_function_show_keymaps();
1946    } else {
1947      owl_function_show_keymap(argv[2]);
1948    }
1949  } else if (!strcmp(argv[1], "view")) {
1950    if (argc==3) {
1951      owl_function_show_view(argv[2]);
1952    } else {
1953      owl_function_show_view(NULL);
1954    }
1955  } else if (!strcmp(argv[1], "colors")) {
1956    owl_function_show_colors();
1957  } else if (!strcmp(argv[1], "styles")) {
1958    owl_function_show_styles();
1959  } else if (!strcmp(argv[1], "subs") || !strcmp(argv[1], "subscriptions")) {
1960    owl_function_getsubs();
1961  } else if (!strcmp(argv[1], "terminal") || !strcmp(argv[1], "term")) {
1962    owl_function_show_term();
1963  } else if (!strcmp(argv[1], "version")) {
1964    owl_function_about();
1965  } else if (!strcmp(argv[1], "status")) {
1966    owl_function_status();
1967  } else if (!strcmp(argv[1], "license")) {
1968    owl_function_show_license();
1969  } else if (!strcmp(argv[1], "startup")) {
1970    char *filename;
1971   
1972    filename=owl_global_get_startupfile(&g);
1973    owl_function_popless_file(filename);
1974  } else if (!strcmp(argv[1], "errors")) {
1975    owl_function_showerrs();
1976  } else {
1977    owl_function_makemsg("Unknown subcommand for 'show' command (see 'help show' for allowed args)");
1978    return NULL;
1979  }
1980  return NULL;
1981}
1982
1983char *owl_command_viewclass(int argc, char **argv, char *buff)
1984{
1985  char *filtname;
1986  if (argc!=2) {
1987    owl_function_makemsg("Wrong number of arguments to viewclass command");
1988    return NULL;
1989  }
1990  filtname = owl_function_classinstfilt(argv[1], NULL);
1991  owl_function_change_currentview_filter(filtname);
1992  owl_free(filtname);
1993  return NULL;
1994}
1995
1996char *owl_command_viewuser(int argc, char **argv, char *buff)
1997{
1998  char *filtname;
1999  if (argc!=2) {
2000    owl_function_makemsg("Wrong number of arguments to viewuser command");
2001    return NULL;
2002  }
2003  filtname=owl_function_zuserfilt(argv[1]);
2004  owl_function_change_currentview_filter(filtname);
2005  owl_free(filtname);
2006  return NULL;
2007}
2008
2009
2010void owl_command_pop_message(void)
2011{
2012  owl_function_curmsg_to_popwin();
2013}
2014
2015void owl_command_openurl(void)
2016{
2017  owl_function_openurl();
2018}
2019
2020char *owl_command_delete(int argc, char **argv, char *buff)
2021{
2022  int move_after = 1;
2023
2024  if (argc>1 && !strcmp(argv[1], "--no-move")) {
2025    move_after = 0;
2026    argc--; 
2027    argv++;
2028  }
2029
2030  if (argc==1) {
2031    owl_function_deletecur(move_after);
2032    return NULL;
2033  }
2034
2035  if (argc==2 && !strcmp(argv[1], "view")) {
2036    owl_function_delete_curview_msgs(1);
2037    return NULL;
2038  }
2039
2040  if (argc==2 && !strcmp(argv[1], "trash")) {
2041    owl_function_delete_automsgs();
2042    return NULL;
2043  }
2044
2045  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
2046    owl_function_delete_by_id(atoi(argv[2]), 1);
2047    return NULL;
2048  }
2049
2050  owl_function_makemsg("Unknown arguments to delete command");
2051  return NULL;
2052}
2053
2054char *owl_command_undelete(int argc, char **argv, char *buff)
2055{
2056  int move_after = 1;
2057
2058  if (argc>1 && !strcmp(argv[1], "--no-move")) {
2059    move_after = 0;
2060    argc--; 
2061    argv++;
2062  }
2063
2064  if (argc==1) {
2065    owl_function_undeletecur(move_after);
2066    return NULL;
2067  }
2068
2069  if (argc==2 && !strcmp(argv[1], "view")) {
2070    owl_function_delete_curview_msgs(0);
2071    return NULL;
2072  }
2073
2074  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
2075    owl_function_delete_by_id(atoi(argv[2]), 0);
2076    return NULL;
2077  }
2078
2079  owl_function_makemsg("Unknown arguments to delete command");
2080  return NULL;
2081}
2082
2083void owl_command_beep()
2084{
2085  owl_function_beep();
2086}
2087
2088char *owl_command_colorview(int argc, char **argv, char *buff)
2089{
2090  if (argc < 2 || argc > 3) {
2091    owl_function_makemsg("Wrong number of arguments to colorview command");
2092    return NULL;
2093  }
2094  owl_function_color_current_filter(argv[1], (argc == 3 ? argv[2] : NULL));
2095  return NULL;
2096}
2097
2098char *owl_command_colorclass(int argc, char **argv, char *buff)
2099{
2100  char *filtname;
2101 
2102  if (argc < 3 || argc > 4) {
2103    owl_function_makemsg("Wrong number of arguments to colorclass command");
2104    return NULL;
2105  }
2106
2107  filtname=owl_function_classinstfilt(argv[1], NULL);
2108  (void) owl_function_color_filter(filtname, argv[2], (argc == 4 ? argv[3] : NULL));
2109  return NULL;
2110}
2111
2112char *owl_command_zpunt(int argc, char **argv, char *buff)
2113{
2114  owl_command_zpunt_and_zunpunt(argc, argv, 0);
2115  return NULL;
2116}
2117
2118char *owl_command_zunpunt(int argc, char **argv, char *buff)
2119{
2120  owl_command_zpunt_and_zunpunt(argc, argv, 1);
2121  return NULL;
2122}
2123
2124void owl_command_zpunt_and_zunpunt(int argc, char **argv, int type)
2125{
2126  /* if type==0 then zpunt
2127   * if type==1 then zunpunt
2128   */
2129  char *class, *inst, *recip;
2130
2131  class="message";
2132  inst="";
2133  recip="*";
2134
2135  if (argc==1) {
2136    /* show current punt filters */
2137    owl_function_show_zpunts();
2138    return;
2139  } else if (argc==2) {
2140    inst=argv[1];
2141  } else if (argc==3) {
2142    class=argv[1];
2143    inst=argv[2];
2144  } else if (argc==4) {
2145    class=argv[1];
2146    inst=argv[2];
2147    recip=argv[3];
2148  } else {
2149    owl_function_makemsg("Wrong number of arguments to the zpunt command");
2150    return;
2151  }
2152
2153  owl_function_zpunt(class, inst, recip, type);
2154  if (type==0) {
2155    owl_function_makemsg("<%s, %s, %s> added to punt list.", class, inst, recip);
2156  } else if (type==1) {
2157    owl_function_makemsg("<%s, %s, %s> removed from punt list.", class, inst, recip);
2158  }
2159}
2160
2161char *owl_command_smartzpunt(int argc, char **argv, char *buff)
2162{
2163  if (argc == 1) {
2164    owl_function_smartzpunt(0);
2165  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
2166    owl_function_smartzpunt(1);
2167  } else {
2168    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
2169  }
2170  return NULL;
2171}
2172
2173char *owl_command_punt(int argc, char **argv, char *buff)
2174{
2175  owl_command_punt_unpunt(argc, argv, buff, 0);
2176  return NULL;
2177}
2178
2179char *owl_command_unpunt(int argc, char **argv, char *buff)
2180{
2181  owl_command_punt_unpunt(argc, argv, buff, 1);
2182  return NULL;
2183}
2184
2185void owl_command_punt_unpunt(int argc, char ** argv, char *buff, int unpunt)
2186{
2187  owl_list * fl;
2188  owl_filter * f;
2189  char * text;
2190  int i;
2191
2192  fl = owl_global_get_puntlist(&g);
2193  if(argc == 1) {
2194    owl_function_show_zpunts();
2195  }
2196
2197  if(argc == 2) {
2198    /* Handle :unpunt <number> */
2199    if(unpunt && (i=atoi(argv[1])) !=0) {
2200      i--;      /* Accept 1-based indexing */
2201      if(i < owl_list_get_size(fl)) {
2202        f = (owl_filter*)owl_list_get_element(fl, i);
2203        owl_list_remove_element(fl, i);
2204        owl_filter_free(f);
2205        return;
2206      } else {
2207        owl_function_error("No such filter number: %d", i+1);
2208      }
2209    }
2210    text = owl_sprintf("filter %s", argv[1]);
2211  } else {
2212    text = skiptokens(buff, 1);
2213  }
2214
2215  owl_function_punt(text, unpunt);
2216}
2217
2218
2219char *owl_command_getview(int argc, char **argv, char *buff)
2220{
2221  char *filtname;
2222  if (argc != 1) {
2223    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
2224    return NULL;
2225  }
2226  filtname = owl_view_get_filtname(owl_global_get_current_view(&g));
2227  if (filtname) filtname = owl_strdup(filtname);
2228  return filtname;
2229}
2230
2231char *owl_command_getvar(int argc, char **argv, char *buff)
2232{
2233  char tmpbuff[1024];
2234  if (argc != 2) {
2235    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
2236    return NULL;
2237  }
2238  if (owl_variable_get_tostring(owl_global_get_vardict(&g), 
2239                                argv[1], tmpbuff, 1024)) {
2240    return NULL;
2241  }
2242  return owl_strdup(tmpbuff); 
2243}
2244
2245char *owl_command_search(int argc, char **argv, char *buff)
2246{
2247  int direction;
2248  char *buffstart;
2249
2250  direction=OWL_DIRECTION_DOWNWARDS;
2251  buffstart=skiptokens(buff, 1);
2252  if (argc>1 && !strcmp(argv[1], "-r")) {
2253    direction=OWL_DIRECTION_UPWARDS;
2254    buffstart=skiptokens(buff, 2);
2255  }
2256   
2257  if (argc==1 || (argc==2 && !strcmp(argv[1], "-r"))) {
2258    owl_function_search_continue(direction);
2259  } else {
2260    owl_function_search_start(buffstart, direction);
2261  }
2262 
2263  return(NULL);
2264}
2265
2266char *owl_command_setsearch(int argc, char **argv, char *buff)
2267{
2268  char *buffstart;
2269
2270  buffstart=skiptokens(buff, 1);
2271
2272  owl_global_set_search_active(&g, buffstart);
2273
2274  if (!*buffstart) {
2275    owl_global_set_search_inactive(&g);
2276  }
2277
2278  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
2279 
2280  return(NULL);
2281}
2282
2283char *owl_command_getstyle(int argc, char **argv, char *buff)
2284{
2285  char *stylename;
2286  if (argc != 1) {
2287    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
2288    return NULL;
2289  }
2290  stylename = owl_view_get_style_name(owl_global_get_current_view(&g));
2291  if (stylename) stylename = owl_strdup(stylename);
2292  return stylename;
2293}
2294
2295char *owl_command_error(int argc, char **argv, char *buff)
2296{
2297    buff = skiptokens(buff, 1);
2298    owl_function_error(buff);
2299    return NULL;
2300}
2301
2302char *owl_command_message(int argc, char **argv, char *buff)
2303{
2304    buff = skiptokens(buff, 1);
2305    owl_function_makemsg(buff);
2306    return NULL;
2307}
2308
2309void owl_command_yes(void)
2310{
2311  owl_message *m;
2312  owl_view *v;
2313  char *cmd;
2314
2315  v = owl_global_get_current_view(&g);
2316
2317  /* bail if there's no current message */
2318  if (owl_view_get_size(v) < 1) {
2319    owl_function_error("No current message.");
2320    return;
2321  }
2322
2323  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
2324  if(!owl_message_is_question(m)) {
2325    owl_function_error("That message isn't a question.");
2326    return;
2327  }
2328  if(owl_message_is_answered(m)) {
2329    owl_function_error("You already answered that question.");
2330    return;
2331  }
2332  cmd = owl_message_get_attribute_value(m, "yescommand");
2333  if(!cmd) {
2334    owl_function_error("No yes command!");
2335    return;
2336  }
2337
2338  owl_function_command_norv(cmd);
2339  owl_message_set_isanswered(m);
2340  return;
2341}
2342
2343void owl_command_no(void)
2344{
2345  owl_message *m;
2346  owl_view *v;
2347  char *cmd;
2348
2349  v = owl_global_get_current_view(&g);
2350
2351  /* bail if there's no current message */
2352  if (owl_view_get_size(v) < 1) {
2353    owl_function_error("No current message.");
2354    return;
2355  }
2356
2357  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
2358  if(!owl_message_is_question(m)) {
2359    owl_function_error("That message isn't a question.");
2360    return;
2361  }
2362  if(owl_message_is_answered(m)) {
2363    owl_function_error("You already answered that question.");
2364    return;
2365  }
2366  cmd = owl_message_get_attribute_value(m, "nocommand");
2367  if(!cmd) {
2368    owl_function_error("No no command!");
2369    return;
2370  }
2371
2372  owl_function_command_norv(cmd);
2373  owl_message_set_isanswered(m);
2374  return;
2375}
2376
2377/*********************************************************************/
2378/************************** EDIT SPECIFIC ****************************/
2379/*********************************************************************/
2380
2381void owl_command_edit_cancel(owl_editwin *e)
2382{
2383  owl_history *hist;
2384
2385  owl_function_makemsg("Command cancelled.");
2386
2387  hist=owl_editwin_get_history(e);
2388  owl_history_store(hist, owl_editwin_get_text(e));
2389  owl_history_reset(hist);
2390
2391  owl_editwin_fullclear(e);
2392  owl_global_set_needrefresh(&g);
2393  wnoutrefresh(owl_editwin_get_curswin(e));
2394  owl_global_set_typwin_inactive(&g);
2395  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
2396
2397  owl_function_activate_keymap("recv");
2398}
2399
2400void owl_command_edit_history_prev(owl_editwin *e)
2401{
2402  owl_history *hist;
2403  char *ptr;
2404
2405  hist=owl_editwin_get_history(e);
2406  if (!owl_history_is_touched(hist)) {
2407    owl_history_store(hist, owl_editwin_get_text(e));
2408    owl_history_set_partial(hist);
2409  }
2410  ptr=owl_history_get_prev(hist);
2411  if (ptr) {
2412    owl_editwin_clear(e);
2413    owl_editwin_insert_string(e, ptr);
2414    owl_editwin_redisplay(e, 0);
2415    owl_global_set_needrefresh(&g);
2416  } else {
2417    owl_function_beep();
2418  }
2419}
2420
2421void owl_command_edit_history_next(owl_editwin *e)
2422{
2423  owl_history *hist;
2424  char *ptr;
2425
2426  hist=owl_editwin_get_history(e);
2427  ptr=owl_history_get_next(hist);
2428  if (ptr) {
2429    owl_editwin_clear(e);
2430    owl_editwin_insert_string(e, ptr);
2431    owl_editwin_redisplay(e, 0);
2432    owl_global_set_needrefresh(&g);
2433  } else {
2434    owl_function_beep();
2435  }
2436}
2437
2438char *owl_command_edit_insert_text(owl_editwin *e, int argc, char **argv, char *buff)
2439{
2440  buff = skiptokens(buff, 1);
2441  owl_editwin_insert_string(e, buff);
2442  owl_editwin_redisplay(e, 0);
2443  owl_global_set_needrefresh(&g); 
2444  return NULL;
2445}
2446
2447void owl_command_editline_done(owl_editwin *e)
2448{
2449  owl_history *hist=owl_editwin_get_history(e);
2450  char *rv, *cmd;
2451
2452  owl_history_store(hist, owl_editwin_get_text(e));
2453  owl_history_reset(hist);
2454  owl_global_set_typwin_inactive(&g);
2455  cmd = owl_strdup(owl_editwin_get_text(e));
2456  owl_editwin_fullclear(e);
2457  rv = owl_function_command(cmd);
2458  owl_free(cmd);
2459
2460  wnoutrefresh(owl_editwin_get_curswin(e));
2461  owl_global_set_needrefresh(&g);
2462
2463  if (rv) {
2464    owl_function_makemsg("%s", rv);
2465    owl_free(rv);
2466  }
2467}
2468
2469
2470void owl_command_editresponse_done(owl_editwin *e)
2471{
2472  char *text = owl_strdup(owl_editwin_get_text(e));
2473  void (*callback)(void *, char *) = owl_editwin_get_callback(e);
2474  void *cbdata = owl_editwin_get_cbdata(e);
2475
2476  owl_global_set_typwin_inactive(&g);
2477  owl_editwin_fullclear(e);
2478  wnoutrefresh(owl_editwin_get_curswin(e));
2479  owl_global_set_needrefresh(&g);
2480
2481  callback(cbdata, text);
2482  owl_free(text);
2483}
2484
2485
2486void owl_command_editmulti_done(owl_editwin *e)
2487{
2488  owl_history *hist=owl_editwin_get_history(e);
2489
2490  owl_history_store(hist, owl_editwin_get_text(e));
2491  owl_history_reset(hist);
2492
2493  owl_editwin_do_callback(e);
2494  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
2495  owl_editwin_fullclear(e);
2496  owl_global_set_typwin_inactive(&g);
2497  owl_global_set_needrefresh(&g);
2498  wnoutrefresh(owl_editwin_get_curswin(e));
2499}
2500
2501void owl_command_editmulti_done_or_delete(owl_editwin *e)
2502{
2503  if (owl_editwin_is_at_end(e)) {
2504    owl_command_editmulti_done(e);
2505  } else {
2506    owl_editwin_delete_char(e);
2507  }
2508}
2509
2510
2511/*********************************************************************/
2512/*********************** POPLESS SPECIFIC ****************************/
2513/*********************************************************************/
2514
2515void owl_command_popless_quit(owl_viewwin *vw)
2516{
2517  owl_popwin_close(owl_global_get_popwin(&g));
2518  owl_viewwin_free(vw);
2519  owl_global_set_needrefresh(&g);
2520}
Note: See TracBrowser for help on using the repository browser.