source: commands.c @ 0d17295

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