source: commands.c @ 2fc8397

release-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 2fc8397 was 2fc8397, checked in by Nelson Elhage <nelhage@mit.edu>, 15 years ago
Implement {forward,backward}-paragraph
  • Property mode set to 100644
File size: 81.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id$";
8
9/* fn is "char *foo(int argc, char **argv, char *buff)" */
10#define OWLCMD_ARGS(name, fn, ctx, summary, usage, description) \
11        { name, summary, usage, description, ctx, \
12          NULL, fn, NULL, NULL, NULL, NULL, NULL }
13
14/* fn is "void foo(void)" */
15#define OWLCMD_VOID(name, fn, ctx, summary, usage, description) \
16        { name, summary, usage, description, ctx, \
17          NULL, NULL, fn, NULL, NULL, NULL, NULL }
18
19/* fn is "void foo(int)" */
20#define OWLCMD_INT(name, fn, ctx, summary, usage, description) \
21        { name, summary, usage, description, ctx, \
22          NULL, NULL, NULL, fn, NULL, NULL, NULL }
23
24#define OWLCMD_ALIAS(name, actualname) \
25        { name, OWL_CMD_ALIAS_SUMMARY_PREFIX actualname, "", "", OWL_CTX_ANY, \
26          actualname, NULL, NULL, NULL, NULL, NULL, NULL }
27
28/* fn is "char *foo(void *ctx, int argc, char **argv, char *buff)" */
29#define OWLCMD_ARGS_CTX(name, fn, ctx, summary, usage, description) \
30        { name, summary, usage, description, ctx, \
31          NULL, NULL, NULL, NULL, ((char*(*)(void*,int,char**,char*))fn), NULL, NULL }
32
33/* fn is "void foo(void)" */
34#define OWLCMD_VOID_CTX(name, fn, ctx, summary, usage, description) \
35        { name, summary, usage, description, ctx, \
36          NULL, NULL, NULL, NULL, NULL, ((void(*)(void*))(fn)), NULL }
37
38/* fn is "void foo(int)" */
39#define OWLCMD_INT_CTX(name, fn, ctx, summary, usage, description) \
40        { name, summary, usage, description, ctx, \
41          NULL, NULL, NULL, NULL, NULL, NULL, ((void(*)(void*,int))fn) }
42
43
44owl_cmd commands_to_init[]
45  = {
46  OWLCMD_ARGS("zlog", owl_command_zlog, OWL_CTX_ANY,
47              "send a login or logout notification",
48              "zlog in [tty]\nzlog out",
49              "zlog in will send a login notification, zlog out will send a\n"
50              "logout notification.  By default a login notification is sent\n"
51              "when owl is started and a logout notification is sent when owl\n"
52              "is exited.  This behavior can be changed with the 'startuplogin'\n"
53              "and 'shutdownlogout' variables.  If a tty is specified for zlog in\n"
54              "then the owl variable 'tty' will be set to that string, causing\n"
55              "it to be used as the zephyr location tty.\n"),
56
57  OWLCMD_VOID("quit", owl_command_quit, OWL_CTX_ANY,
58              "exit owl",
59              "",
60              "Exit owl and run any shutdown activities."),
61  OWLCMD_ALIAS("exit", "quit"),
62  OWLCMD_ALIAS("q",    "quit"),
63
64  OWLCMD_ARGS("term", owl_command_term, OWL_CTX_ANY,
65              "control the terminal",
66              "term raise\n"
67              "term deiconify\n",
68              ""),
69
70  OWLCMD_VOID("nop", owl_command_nop, OWL_CTX_ANY,
71              "do nothing",
72              "",
73              ""),
74 
75  OWLCMD_ARGS("start-command", owl_command_start_command, OWL_CTX_INTERACTIVE,
76              "prompts the user to enter a command",
77              "start-command [initial-value]",
78              "Initializes the command field to initial-value."),
79
80  OWLCMD_ARGS("start-question", owl_command_start_question, OWL_CTX_INTERACTIVE,
81              "prompts the user to enter a response to some question",
82              "start-command <question>",
83              ""),
84
85  OWLCMD_ARGS("start-password", owl_command_start_password, OWL_CTX_INTERACTIVE,
86              "prompts the user to enter a password",
87              "start-password <question>",
88              ""),
89
90  OWLCMD_ARGS("alias", owl_command_alias, OWL_CTX_ANY,
91              "creates a command alias",
92              "alias <new_command> <old_command>",
93              "Creates a command alias from new_command to old_command.\n"
94              "Any arguments passed to <new_command> will be appended to\n"
95              "<old_command> before it is executed.\n"),
96
97  OWLCMD_ARGS("bindkey", owl_command_bindkey, OWL_CTX_ANY,
98              "creates a binding in a keymap",
99              "bindkey <keymap> <keyseq> command <command>",
100              "Binds a key sequence to a command within a keymap.\n"
101              "Use 'show keymaps' to see the existing keymaps.\n"
102              "Key sequences may be things like M-C-t or NPAGE.\n"),
103
104  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
105              "send a zephyr",
106              "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
107              "Zwrite send a zephyr to the one or more users specified.\n\n"
108              "The following options are available:\n\n"
109              "-m    Specifies a message to send without prompting.\n"
110              "      Note that this does not yet log an outgoing message.\n"
111              "      This must be the last argument.\n\n"
112              "-n    Do not send a ping message.\n\n"
113              "-C    If the message is sent to more than one user include a\n"
114              "      \"cc:\" line in the text\n\n"
115              "-c class\n"
116              "      Send to the specified zephyr class\n\n"
117              "-i instance\n"
118              "      Send to the specified zephyr instance\n\n"
119              "-r realm\n"
120              "      Send to a foreign realm\n"
121              "-O opcode\n"
122              "      Send to the specified opcode\n"),
123
124  OWLCMD_ARGS("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              "set [-q] <variable>\n"
166              "set",
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_ARGS("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_ARGS("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_ARGS("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_VOID("recv:shiftleft", owl_command_shift_left, OWL_CTX_INTERACTIVE,
327              "scrolls receive window to the left", "", ""),
328
329  OWLCMD_VOID("recv:shiftright", owl_command_shift_right, OWL_CTX_INTERACTIVE,
330              "scrolls receive window to the left", "", ""),
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 previous 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_VOID_CTX("editresponse:done", owl_command_editresponse_done, 
914                  OWL_CTX_EDITRESPONSE,
915                  "completes the response to a question",
916                  "", ""),
917
918  OWLCMD_VOID_CTX("editmulti:move-up-line", owl_editwin_key_up, 
919                  OWL_CTX_EDITMULTI,
920                  "moves the cursor up one line",
921                  "", ""),
922
923  OWLCMD_VOID_CTX("editmulti:move-down-line", owl_editwin_key_down, 
924                  OWL_CTX_EDITMULTI,
925                  "moves the cursor down one line",
926                  "", ""),
927
928  OWLCMD_VOID_CTX("editmulti:done", owl_command_editmulti_done, 
929                  OWL_CTX_EDITMULTI,
930                  "completes the command (eg, sends message being composed)",
931                  "", ""),
932
933  OWLCMD_VOID_CTX("editmulti:done-or-delete", owl_command_editmulti_done_or_delete, 
934                  OWL_CTX_EDITMULTI,
935                  "completes the command, but only if at end of message",
936                  "", 
937                  "If only whitespace is to the right of the cursor,\n"
938                  "runs 'editmulti:done'.\n"\
939                  "Otherwise runs 'edit:delete-next-char'\n"),
940
941  OWLCMD_VOID_CTX("editmulti:forward-paragraph", owl_editwin_forward_paragraph,
942                  OWL_CTX_EDITMULTI,
943                  "Move forward to end of paragraph.",
944                  "",
945                  "Move the point to the end of the current paragraph"),
946
947  OWLCMD_VOID_CTX("editmulti:backward-paragraph", owl_editwin_backward_paragraph,
948                  OWL_CTX_EDITMULTI,
949                  "Move backward to the start of paragraph.",
950                  "",
951                  "Move the point to the start of the current paragraph"),
952
953  /****************************************************************/
954  /********************** POPLESS-SPECIFIC ************************/
955  /****************************************************************/
956
957  OWLCMD_VOID_CTX("popless:scroll-down-page", owl_viewwin_pagedown, 
958                  OWL_CTX_POPLESS,
959                  "scrolls down one page",
960                  "", ""),
961
962  OWLCMD_VOID_CTX("popless:scroll-down-line", owl_viewwin_linedown, 
963                  OWL_CTX_POPLESS,
964                  "scrolls down one line",
965                  "", ""),
966
967  OWLCMD_VOID_CTX("popless:scroll-up-page", owl_viewwin_pageup, 
968                  OWL_CTX_POPLESS,
969                  "scrolls up one page",
970                  "", ""),
971
972  OWLCMD_VOID_CTX("popless:scroll-up-line", owl_viewwin_lineup, 
973                  OWL_CTX_POPLESS,
974                  "scrolls up one line",
975                  "", ""),
976
977  OWLCMD_VOID_CTX("popless:scroll-to-top", owl_viewwin_top, 
978                  OWL_CTX_POPLESS,
979                  "scrolls to the top of the buffer",
980                  "", ""),
981
982  OWLCMD_VOID_CTX("popless:scroll-to-bottom", owl_viewwin_bottom, 
983                  OWL_CTX_POPLESS,
984                  "scrolls to the bottom of the buffer",
985                  "", ""),
986
987  OWLCMD_INT_CTX ("popless:scroll-right", owl_viewwin_right, 
988                  OWL_CTX_POPLESS,
989                  "scrolls right in the buffer",
990                  "popless:scroll-right <num-chars>", ""),
991
992  OWLCMD_INT_CTX ("popless:scroll-left", owl_viewwin_left, 
993                  OWL_CTX_POPLESS,
994                  "scrolls left in the buffer",
995                  "popless:scroll-left <num-chars>", ""),
996
997  OWLCMD_VOID_CTX("popless:quit", owl_command_popless_quit, 
998                  OWL_CTX_POPLESS,
999                  "exits the popless window",
1000                  "", ""),
1001
1002  OWLCMD_ALIAS("webzephyr", "zwrite daemon.webzephyr -c webzephyr -i"),
1003
1004  /* This line MUST be last! */
1005  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
1006
1007};
1008
1009void owl_command_info()
1010{
1011  owl_function_info();
1012}
1013
1014void owl_command_nop()
1015{
1016}
1017
1018char *owl_command_help(int argc, char **argv, char *buff)
1019{
1020  if (argc!=2) {
1021    owl_help();
1022    return NULL;
1023  }
1024 
1025  owl_function_help_for_command(argv[1]);
1026  return NULL;
1027}
1028
1029char *owl_command_zlist(int argc, char **argv, char *buff)
1030{
1031  int elapsed=0, timesort=0;
1032  char *file=NULL;
1033
1034  argc--;
1035  argv++;
1036  while (argc) {
1037    if (!strcmp(argv[0], "-e")) {
1038      elapsed=1;
1039      argc--;
1040      argv++;
1041    } else if (!strcmp(argv[0], "-t")) {
1042      timesort=1;
1043      argc--;
1044      argv++;
1045    } else if (!strcmp(argv[0], "-f")) {
1046      if (argc==1) {
1047        owl_function_makemsg("zlist: -f needs an argument");
1048        return(NULL);
1049      }
1050      file=argv[1];
1051      argc-=2;
1052      argv+=2;
1053    } else {
1054      owl_function_makemsg("zlist: unknown argument");
1055      return(NULL);
1056    }
1057  }
1058  owl_function_buddylist(0, 1, file);
1059  return(NULL);
1060}
1061
1062char *owl_command_alist()
1063{
1064  owl_function_buddylist(1, 0, NULL);
1065  return(NULL);
1066}
1067
1068char *owl_command_blist()
1069{
1070  owl_function_buddylist(1, 1, NULL);
1071  return(NULL);
1072}
1073
1074char *owl_command_toggleoneline()
1075{
1076  owl_function_toggleoneline();
1077  return(NULL);
1078}
1079
1080void owl_command_about()
1081{
1082  owl_function_about();
1083}
1084
1085void owl_command_version()
1086{
1087  owl_function_makemsg("BarnOwl version %s", OWL_VERSION_STRING);
1088}
1089
1090char *owl_command_aim(int argc, char **argv, char *buff)
1091{
1092  if (argc<2) {
1093    owl_function_makemsg("not enough arguments to aim command");
1094    return(NULL);
1095  }
1096
1097  if (!strcmp(argv[1], "search")) {
1098    if (argc!=3) {
1099      owl_function_makemsg("not enough arguments to aim search command");
1100      return(NULL);
1101    }
1102    owl_aim_search(argv[2]);
1103  } else {
1104    owl_function_makemsg("unknown subcommand '%s' for aim command", argv[1]);
1105    return(NULL);
1106  }
1107  return(NULL);
1108}
1109
1110char *owl_command_addbuddy(int argc, char **argv, char *buff)
1111{
1112  if (argc!=3) {
1113    owl_function_makemsg("usage: addbuddy <protocol> <buddyname>");
1114    return(NULL);
1115  }
1116
1117  if (!strcasecmp(argv[1], "aim")) {
1118    if (!owl_global_is_aimloggedin(&g)) {
1119      owl_function_makemsg("addbuddy: You must be logged into aim to use this command.");
1120      return(NULL);
1121    }
1122    /*
1123    owl_function_makemsg("This function is not yet operational.  Stay tuned.");
1124    return(NULL);
1125    */
1126    owl_aim_addbuddy(argv[2]);
1127    owl_function_makemsg("%s added as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
1128  } else if (!strcasecmp(argv[1], "zephyr")) {
1129    owl_zephyr_addbuddy(argv[2]);
1130    owl_function_makemsg("%s added as zephyr buddy", argv[2]);
1131  } else {
1132    owl_function_makemsg("addbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
1133  }
1134
1135  return(NULL);
1136}
1137
1138char *owl_command_delbuddy(int argc, char **argv, char *buff)
1139{
1140  if (argc!=3) {
1141    owl_function_makemsg("usage: delbuddy <protocol> <buddyname>");
1142    return(NULL);
1143  }
1144
1145  if (!strcasecmp(argv[1], "aim")) {
1146    if (!owl_global_is_aimloggedin(&g)) {
1147      owl_function_makemsg("delbuddy: You must be logged into aim to use this command.");
1148      return(NULL);
1149    }
1150    owl_aim_delbuddy(argv[2]);
1151    owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
1152  } else if (!strcasecmp(argv[1], "zephyr")) {
1153    owl_zephyr_delbuddy(argv[2]);
1154    owl_function_makemsg("%s deleted as zephyr buddy", argv[2]);
1155  } else {
1156    owl_function_makemsg("delbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
1157  }
1158
1159  return(NULL);
1160}
1161
1162char *owl_command_join(int argc, char **argv, char *buff)
1163{
1164  if (argc!=3 && argc!=4) {
1165    owl_function_makemsg("usage: join <protocol> <buddyname> [exchange]");
1166    return(NULL);
1167  }
1168
1169  if (!strcasecmp(argv[1], "aim")) {
1170    if (!owl_global_is_aimloggedin(&g)) {
1171      owl_function_makemsg("join aim: You must be logged into aim to use this command.");
1172      return(NULL);
1173    }
1174    if (argc==3) {
1175      owl_aim_chat_join(argv[2], 4);
1176    } else {
1177      owl_aim_chat_join(argv[2], atoi(argv[3]));
1178    }
1179    /* owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g)); */
1180  } else {
1181    owl_function_makemsg("join: currently the only supported protocol is 'aim'");
1182  }
1183  return(NULL);
1184}
1185
1186char *owl_command_startup(int argc, char **argv, char *buff)
1187{
1188  char *ptr;
1189
1190  if (argc<2) {
1191    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
1192    return(NULL);
1193  }
1194
1195  ptr=strchr(buff, ' ');
1196  if (!ptr) {
1197    owl_function_makemsg("Parse error finding command for startup");
1198    return(NULL);
1199  }
1200
1201  owl_function_command(ptr+1);
1202  owl_function_addstartup(ptr+1);
1203
1204  return(NULL);
1205}
1206
1207char *owl_command_unstartup(int argc, char **argv, char *buff)
1208{
1209  char *ptr;
1210
1211  if (argc<2) {
1212    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
1213    return(NULL);
1214  }
1215
1216  ptr=strchr(buff, ' ');
1217  if (!ptr) {
1218    owl_function_makemsg("Parse error finding command for unstartup");
1219    return(NULL);
1220  }
1221
1222  owl_function_delstartup(ptr+1);
1223
1224  return(NULL);
1225}
1226
1227char *owl_command_dump(int argc, char **argv, char *buff)
1228{
1229  char *filename;
1230 
1231  if (argc!=2) {
1232    owl_function_makemsg("usage: dump <filename>");
1233    return(NULL);
1234  }
1235  filename=owl_util_makepath(argv[1]);
1236  owl_function_dump(filename);
1237  owl_free(filename);
1238  return(NULL);
1239}
1240
1241char *owl_command_source(int argc, char **argv, char *buff)
1242{
1243  if (argc!=2) {
1244    owl_function_makemsg("usage: source <filename>");
1245    return(NULL);
1246  }
1247
1248  owl_function_source(argv[1]);
1249  return(NULL);
1250}
1251
1252char *owl_command_next(int argc, char **argv, char *buff)
1253{
1254  char *filter=NULL;
1255  int skip_deleted=0, last_if_none=0;
1256  while (argc>1) {
1257    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
1258      skip_deleted=1;
1259      argc-=1; argv+=1; 
1260    } else if (argc>=1 && !strcmp(argv[1], "--last-if-none")) {
1261      last_if_none=1;
1262      argc-=1; argv+=1; 
1263    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
1264      filter = owl_strdup(argv[2]);
1265      argc-=2; argv+=2; 
1266    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
1267      filter = owl_function_smartfilter(0);
1268      argc-=2; argv+=2; 
1269    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
1270      filter = owl_function_smartfilter(1);
1271      argc-=2; argv+=2; 
1272    } else {
1273      owl_function_makemsg("Invalid arguments to command 'next'.");
1274      return(NULL);
1275    }
1276  }
1277  owl_function_nextmsg_full(filter, skip_deleted, last_if_none);
1278  if (filter) owl_free(filter);
1279  return(NULL);
1280}
1281
1282char *owl_command_prev(int argc, char **argv, char *buff)
1283{
1284  char *filter=NULL;
1285  int skip_deleted=0, first_if_none=0;
1286  while (argc>1) {
1287    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
1288      skip_deleted=1;
1289      argc-=1; argv+=1; 
1290    } else if (argc>=1 && !strcmp(argv[1], "--first-if-none")) {
1291      first_if_none=1;
1292      argc-=1; argv+=1; 
1293    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
1294      filter = owl_strdup(argv[2]);
1295      argc-=2; argv+=2; 
1296    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
1297      filter = owl_function_smartfilter(0);
1298      argc-=2; argv+=2; 
1299    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
1300      filter = owl_function_smartfilter(1);
1301      argc-=2; argv+=2; 
1302   } else {
1303      owl_function_makemsg("Invalid arguments to command 'prev'.");
1304      return(NULL);
1305    }
1306  }
1307  owl_function_prevmsg_full(filter, skip_deleted, first_if_none);
1308  if (filter) owl_free(filter);
1309  return(NULL);
1310}
1311
1312char *owl_command_smartnarrow(int argc, char **argv, char *buff)
1313{
1314  char *filtname = NULL;
1315
1316  if (argc == 1) {
1317    filtname = owl_function_smartfilter(0);
1318  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
1319    filtname = owl_function_smartfilter(1);
1320  } else {
1321    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
1322  }
1323  if (filtname) {
1324    owl_function_change_currentview_filter(filtname);
1325    owl_free(filtname);
1326  }
1327  return NULL;
1328}
1329
1330char *owl_command_smartfilter(int argc, char **argv, char *buff)
1331{
1332  char *filtname = NULL;
1333
1334  if (argc == 1) {
1335    filtname = owl_function_smartfilter(0);
1336  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
1337    filtname = owl_function_smartfilter(1);
1338  } else {
1339    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);   
1340  }
1341  return filtname;
1342}
1343
1344void owl_command_expunge()
1345{
1346  owl_function_expunge();
1347}
1348
1349void owl_command_first()
1350{
1351  owl_global_set_rightshift(&g, 0);
1352  owl_function_firstmsg();
1353}
1354
1355void owl_command_last()
1356{
1357  owl_function_lastmsg();
1358}
1359
1360void owl_command_resize()
1361{
1362  owl_function_resize();
1363}
1364
1365void owl_command_redisplay()
1366{
1367  owl_function_full_redisplay();
1368  owl_global_set_needrefresh(&g);
1369}
1370
1371void owl_command_shift_right()
1372{
1373  owl_function_shift_right();
1374}
1375
1376void owl_command_shift_left()
1377{
1378  owl_function_shift_left();
1379}
1380
1381void owl_command_unsuball()
1382{
1383  owl_function_unsuball();
1384}
1385
1386char *owl_command_loadsubs(int argc, char **argv, char *buff)
1387{
1388  if (argc == 2) {
1389    owl_function_loadsubs(argv[1]);
1390  } else if (argc == 1) {
1391    owl_function_loadsubs(NULL);
1392  } else {
1393    owl_function_makemsg("Wrong number of arguments for load-subs.");
1394    return(NULL);
1395  }
1396  return(NULL);
1397}
1398
1399
1400char *owl_command_loadloginsubs(int argc, char **argv, char *buff)
1401{
1402  if (argc == 2) {
1403    owl_function_loadloginsubs(argv[1]);
1404  } else if (argc == 1) {
1405    owl_function_loadloginsubs(NULL);
1406  } else {
1407    owl_function_makemsg("Wrong number of arguments for load-subs.");
1408    return(NULL);
1409  }
1410  return(NULL);
1411}
1412
1413void owl_command_suspend()
1414{
1415  owl_function_suspend();
1416}
1417
1418char *owl_command_start_command(int argc, char **argv, char *buff)
1419{
1420  buff = skiptokens(buff, 1);
1421  owl_function_start_command(buff);
1422  return(NULL);
1423}
1424
1425char *owl_command_start_question(int argc, char **argv, char *buff)
1426{
1427  buff = skiptokens(buff, 1);
1428  owl_function_start_question(buff);
1429  return(NULL);
1430}
1431
1432char *owl_command_start_password(int argc, char **argv, char *buff)
1433{
1434  buff = skiptokens(buff, 1);
1435  owl_function_start_password(buff);
1436  return(NULL);
1437}
1438
1439char *owl_command_zaway(int argc, char **argv, char *buff)
1440{
1441  if ((argc==1) ||
1442      ((argc==2) && !strcmp(argv[1], "on"))) {
1443    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
1444    owl_function_zaway_on();
1445    return NULL;
1446  }
1447
1448  if (argc==2 && !strcmp(argv[1], "off")) {
1449    owl_function_zaway_off();
1450    return NULL;
1451  }
1452
1453  if (argc==2 && !strcmp(argv[1], "toggle")) {
1454    owl_function_zaway_toggle();
1455    return NULL;
1456  }
1457
1458  buff = skiptokens(buff, 1);
1459  owl_global_set_zaway_msg(&g, buff);
1460  owl_function_zaway_on();
1461  return NULL;
1462}
1463
1464
1465char *owl_command_aaway(int argc, char **argv, char *buff)
1466{
1467  if ((argc==1) ||
1468      ((argc==2) && !strcmp(argv[1], "on"))) {
1469    owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
1470    owl_function_aaway_on();
1471    return NULL;
1472  }
1473
1474  if (argc==2 && !strcmp(argv[1], "off")) {
1475    owl_function_aaway_off();
1476    return NULL;
1477  }
1478
1479  if (argc==2 && !strcmp(argv[1], "toggle")) {
1480    owl_function_aaway_toggle();
1481    return NULL;
1482  }
1483
1484  buff = skiptokens(buff, 1);
1485  owl_global_set_aaway_msg(&g, buff);
1486  owl_function_aaway_on();
1487  return NULL;
1488}
1489
1490
1491char *owl_command_away(int argc, char **argv, char *buff)
1492{
1493  if ((argc==1) ||
1494      ((argc==2) && !strcmp(argv[1], "on"))) {
1495    owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
1496    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
1497    owl_function_aaway_on();
1498    owl_function_zaway_on();
1499    owl_function_makemsg("Away messages set.");
1500    return NULL;
1501  }
1502
1503  if (argc==2 && !strcmp(argv[1], "off")) {
1504    owl_function_aaway_off();
1505    owl_function_zaway_off();
1506    return NULL;
1507  }
1508
1509  if (argc==2 && !strcmp(argv[1], "toggle")) {
1510    /* if either one is on, turn it off, otherwise toggle both (turn
1511     *  them both on)
1512     */
1513    if (!owl_global_is_zaway(&g) && !owl_global_is_aaway(&g)) {
1514      owl_function_aaway_toggle();
1515      owl_function_zaway_toggle();
1516      owl_function_makemsg("Away messages set.");
1517    } else {
1518      if (owl_global_is_zaway(&g)) owl_function_zaway_toggle();
1519      if (owl_global_is_aaway(&g)) owl_function_aaway_toggle();
1520      owl_function_makemsg("Away messages off.");
1521    }
1522    return NULL;
1523  }
1524
1525  buff = skiptokens(buff, 1);
1526  owl_global_set_aaway_msg(&g, buff);
1527  owl_global_set_zaway_msg(&g, buff);
1528  owl_function_aaway_on();
1529  owl_function_zaway_on();
1530  owl_function_makemsg("Away messages set.");
1531  return NULL;
1532}
1533
1534char *owl_command_set(int argc, char **argv, char *buff)
1535{
1536  char *var, *val;
1537  int  silent=0;
1538  int requirebool=0;
1539
1540  if (argc == 1) {
1541    owl_function_printallvars();
1542    return NULL;
1543  } 
1544
1545  if (argc > 1 && !strcmp("-q",argv[1])) {
1546    silent = 1;
1547    argc--; argv++;
1548  }
1549
1550  if (argc == 2) {
1551    var=argv[1];
1552    val="on";
1553    requirebool=1;
1554  } else if (argc == 3) {
1555    var=argv[1];
1556    val=argv[2];
1557  } else {
1558    owl_function_makemsg("Wrong number of arguments for set command");
1559    return NULL;
1560  }
1561  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
1562  return NULL;
1563}
1564
1565char *owl_command_unset(int argc, char **argv, char *buff)
1566{
1567  char *var, *val;
1568  int  silent=0;
1569
1570  if (argc > 1 && !strcmp("-q",argv[1])) {
1571    silent = 1;
1572    argc--; argv++;
1573  }
1574  if (argc == 2) {
1575    var=argv[1];
1576    val="off";
1577  } else {
1578    owl_function_makemsg("Wrong number of arguments for unset command");
1579    return NULL;
1580  }
1581  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
1582  return NULL;
1583}
1584
1585char *owl_command_print(int argc, char **argv, char *buff)
1586{
1587  char *var;
1588  char valbuff[1024];
1589
1590  if (argc==1) {
1591    owl_function_printallvars();
1592    return NULL;
1593  } else if (argc!=2) {
1594    owl_function_makemsg("Wrong number of arguments for print command");
1595    return NULL;
1596  }
1597
1598  var=argv[1];
1599   
1600  if (0 == owl_variable_get_tostring(owl_global_get_vardict(&g), 
1601                                     var, valbuff, 1024)) {
1602    owl_function_makemsg("%s = '%s'", var, valbuff);
1603  } else {
1604    owl_function_makemsg("Unknown variable '%s'.", var);
1605  }
1606  return NULL;
1607}
1608
1609
1610char *owl_command_exec(int argc, char **argv, char *buff)
1611{
1612  return owl_function_exec(argc, argv, buff, 0);
1613}
1614
1615char *owl_command_pexec(int argc, char **argv, char *buff)
1616{
1617  return owl_function_exec(argc, argv, buff, 1);
1618}
1619
1620char *owl_command_aexec(int argc, char **argv, char *buff)
1621{
1622  return owl_function_exec(argc, argv, buff, 2);
1623}
1624
1625char *owl_command_perl(int argc, char **argv, char *buff)
1626{
1627  return owl_function_perl(argc, argv, buff, 0);
1628}
1629
1630char *owl_command_pperl(int argc, char **argv, char *buff)
1631{
1632  return owl_function_perl(argc, argv, buff, 1);
1633}
1634
1635char *owl_command_aperl(int argc, char **argv, char *buff)
1636{
1637  return owl_function_perl(argc, argv, buff, 2);
1638}
1639
1640char *owl_command_multi(int argc, char **argv, char *buff)
1641{
1642  char *lastrv = NULL, *dupbuff, *newbuff;
1643  char **commands;
1644  int  ncommands, i;
1645  if (argc < 2) {
1646    owl_function_makemsg("Invalid arguments to 'multi' command.");   
1647    return NULL;
1648  }
1649  dupbuff = owl_strdup(buff);
1650  newbuff = skiptokens(dupbuff, 1);
1651  if (!strcmp(argv[0], "(")) {
1652    for (i=strlen(newbuff)-1; i>=0; i--) {
1653      if (newbuff[i] == ')') {
1654        newbuff[i] = '\0';
1655        break;
1656      } else if (newbuff[i] != ' ') {
1657        owl_function_makemsg("Invalid arguments to 'multi' command.");   
1658        owl_free(newbuff);
1659        return NULL;
1660      }
1661    }
1662  }
1663  commands = atokenize(newbuff, ";", &ncommands);
1664  for (i=0; i<ncommands; i++) {
1665    if (lastrv) {
1666      owl_free(lastrv);
1667    }
1668    lastrv = owl_function_command(commands[i]);
1669  }
1670  owl_free(dupbuff);
1671  atokenize_free(commands, ncommands);
1672  return lastrv;
1673}
1674
1675
1676char *owl_command_alias(int argc, char **argv, char *buff)
1677{
1678  if (argc < 3) {
1679    owl_function_makemsg("Invalid arguments to 'alias' command.");
1680    return NULL;
1681  }
1682  buff = skiptokens(buff, 2);
1683  owl_function_command_alias(argv[1], buff);
1684  return (NULL);
1685}
1686
1687
1688char *owl_command_bindkey(int argc, char **argv, char *buff)
1689{
1690  owl_keymap *km;
1691  int ret;
1692
1693  if (argc < 5 || strcmp(argv[3], "command")) {
1694    owl_function_makemsg("Usage: bindkey <keymap> <binding> command <cmd>");
1695    return NULL;
1696  }
1697  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), argv[1]);
1698  if (!km) {
1699    owl_function_makemsg("No such keymap '%s'", argv[1]);
1700    return NULL;
1701  }
1702  buff = skiptokens(buff, 4);
1703  ret = owl_keymap_create_binding(km, argv[2], buff, NULL, "*user*");
1704  if (ret!=0) {
1705    owl_function_makemsg("Unable to bind '%s' in keymap '%s' to '%s'.",
1706                         argv[2], argv[1], buff);
1707    return NULL;
1708  }
1709  return NULL;
1710}
1711
1712void owl_command_quit()
1713{
1714  owl_function_quit();
1715}
1716
1717char *owl_command_debug(int argc, char **argv, char *buff)
1718{
1719  if (argc<2) {
1720    owl_function_makemsg("Need at least one argument to debug command");
1721    return(NULL);
1722  }
1723
1724  if (!owl_global_is_debug_fast(&g)) {
1725    owl_function_makemsg("Debugging is not turned on");
1726    return(NULL);
1727  }
1728
1729  owl_function_debugmsg("%s", argv[1]);
1730  return(NULL);
1731}
1732
1733char *owl_command_term(int argc, char **argv, char *buff)
1734{
1735  if (argc<2) {
1736    owl_function_makemsg("Need at least one argument to the term command");
1737    return(NULL);
1738  }
1739
1740  if (!strcmp(argv[1], "raise")) {
1741    owl_function_xterm_raise();
1742  } else if (!strcmp(argv[1], "deiconify")) {
1743    owl_function_xterm_deiconify();
1744  } else {
1745    owl_function_makemsg("Unknown terminal subcommand");
1746  }
1747  return(NULL);
1748}
1749
1750char *owl_command_zlog(int argc, char **argv, char *buff)
1751{
1752  if ((argc<2) || (argc>3)) {
1753    owl_function_makemsg("Wrong number of arguments for zlog command");
1754    return(NULL);
1755  }
1756
1757  if (!strcmp(argv[1], "in")) {
1758    if (argc>2) {
1759      owl_global_set_tty(&g, argv[2]);
1760    }
1761    owl_zephyr_zlog_in();
1762  } else if (!strcmp(argv[1], "out")) {
1763    if (argc!=2) {
1764      owl_function_makemsg("Wrong number of arguments for zlog command");
1765      return(NULL);
1766    }
1767    owl_zephyr_zlog_out();
1768  } else {
1769    owl_function_makemsg("Invalid subcommand for zlog");
1770  }
1771  return(NULL);
1772}
1773
1774char *owl_command_subscribe(int argc, char **argv, char *buff)
1775{
1776  char *class, *instance, *recip="";
1777  int temp=0;
1778  int ret=0;
1779
1780  if (argc < 2) {
1781    owl_function_makemsg("Not enough arguments to the subscribe command");
1782    return(NULL);
1783  }
1784  argc--;
1785  argv++;
1786
1787  if (!strcmp(argv[0], "-t")) {
1788    temp=1;
1789    argc--;
1790    argv++;
1791  }
1792  if (argc < 1) {
1793    owl_function_makemsg("Not enough arguments to the subscribe command");
1794    return(NULL);
1795  }
1796
1797  if (argc > 3) {
1798    owl_function_makemsg("Too many arguments to the subscribe command");
1799    return(NULL);
1800  }
1801
1802  class = argv[0];
1803
1804  if (argc == 1) {
1805    instance = "*";
1806  } else {
1807    instance = argv[1];
1808  }
1809
1810  if (argc <= 2) {
1811    recip="";
1812  } else if (argc==3) {
1813    recip=argv[2];
1814  }
1815
1816  ret = owl_function_subscribe(class, instance, recip);
1817  if (!temp && !ret) {
1818    owl_zephyr_addsub(NULL, class, instance, recip);
1819  }
1820  return(NULL);
1821}
1822
1823
1824char *owl_command_unsubscribe(int argc, char **argv, char *buff)
1825{
1826  char *class, *instance, *recip="";
1827  int temp=0;
1828
1829  if (argc < 2) {
1830    owl_function_makemsg("Not enough arguments to the unsubscribe command");
1831    return(NULL);
1832  }
1833  argc--;
1834  argv++;
1835
1836  if (!strcmp(argv[0], "-t")) {
1837    temp=1;
1838    argc--;
1839    argv++;
1840  }
1841  if (argc < 1) {
1842    owl_function_makemsg("Not enough arguments to the unsubscribe command");
1843    return(NULL);
1844  }
1845
1846  if (argc > 3) {
1847    owl_function_makemsg("Too many arguments to the unsubscribe command");
1848    return(NULL);
1849  }
1850
1851  class = argv[0];
1852
1853  if (argc == 1) {
1854    instance = "*";
1855  } else {
1856    instance = argv[1];
1857  }
1858
1859  if (argc <= 2) {
1860    recip="";
1861  } else if (argc==3) {
1862    recip=argv[2];
1863  }
1864
1865  owl_function_unsubscribe(class, instance, recip);
1866  if (!temp) {
1867    owl_zephyr_delsub(NULL, class, instance, recip);
1868  }
1869  return(NULL);
1870}
1871
1872char *owl_command_echo(int argc, char **argv, char *buff)
1873{
1874  buff = skiptokens(buff, 1);
1875  owl_function_popless_text(buff);
1876  return NULL;
1877}
1878
1879void owl_command_getsubs(void)
1880{
1881  owl_function_getsubs();
1882}
1883
1884void owl_command_status(void)
1885{
1886  owl_function_status();
1887}
1888
1889char *owl_command_zwrite(int argc, char **argv, char *buff)
1890{
1891  owl_zwrite z;
1892
1893  if (!owl_global_is_havezephyr(&g)) {
1894    owl_function_makemsg("Zephyr is not available");
1895    return(NULL);
1896  }
1897  /* check for a zwrite -m */
1898  owl_zwrite_create_from_line(&z, buff);
1899  if (owl_zwrite_is_message_set(&z)) {
1900    owl_function_zwrite(buff, NULL);
1901    owl_zwrite_free(&z);
1902    return (NULL);
1903  }
1904
1905  if (argc < 2) {
1906    owl_function_makemsg("Not enough arguments to the zwrite command.");
1907  } else {
1908    owl_function_zwrite_setup(buff);
1909  }
1910  return(NULL);
1911}
1912
1913char *owl_command_aimwrite(int argc, char **argv, char *buff)
1914{
1915  char *newbuff, *recip, **myargv;
1916  int i, j, myargc;
1917  owl_message *m;
1918 
1919  if (!owl_global_is_aimloggedin(&g)) {
1920    owl_function_makemsg("You are not logged in to AIM.");
1921    return(NULL);
1922  }
1923
1924  if (argc < 2) {
1925    owl_function_makemsg("Not enough arguments to the aimwrite command.");
1926    return(NULL);
1927  }
1928
1929  myargv=argv;
1930  if (argc<0) {
1931    owl_function_error("Unbalanced quotes in aimwrite");
1932    return(NULL);
1933  }
1934  myargc=argc;
1935  if (myargc && *(myargv[0])!='-') {
1936    myargc--;
1937    myargv++;
1938  }
1939  while (myargc) {
1940    if (!strcmp(myargv[0], "-m")) {
1941      if (myargc<2) {
1942        break;
1943      }
1944
1945      /* Once we have -m, gobble up everything else on the line */
1946      myargv++;
1947      myargc--;
1948      newbuff=owl_malloc(1);
1949      newbuff=owl_strdup("");
1950      while (myargc) {
1951        newbuff=realloc(newbuff, strlen(newbuff)+strlen(myargv[0])+5);
1952        strcat(newbuff, myargv[0]);
1953        strcat(newbuff, " ");
1954        myargc--;
1955        myargv++;
1956      }
1957      newbuff[strlen(newbuff)-1]='\0'; /* remove last space */
1958
1959      recip=owl_malloc(strlen(argv[0])+5);
1960      sprintf(recip, "%s ", argv[1]);
1961      owl_aim_send_im(recip, newbuff);
1962      m=owl_function_make_outgoing_aim(newbuff, recip);
1963      if (m) { 
1964          owl_global_messagequeue_addmsg(&g, m);
1965      } else {
1966          owl_function_error("Could not create outgoing AIM message");
1967      }
1968
1969      owl_free(recip);
1970      owl_free(newbuff);
1971      return(NULL);
1972    } else {
1973      /* we don't care */
1974      myargv++;
1975      myargc--;
1976    }
1977  }
1978
1979  /* squish arguments together to make one screenname w/o spaces for now */
1980  newbuff=owl_malloc(strlen(buff)+5);
1981  sprintf(newbuff, "%s ", argv[0]);
1982  j=argc-1;
1983  for (i=0; i<j; i++) {
1984    strcat(newbuff, argv[i+1]);
1985  }
1986   
1987  owl_function_aimwrite_setup(newbuff);
1988  owl_free(newbuff);
1989  return(NULL);
1990}
1991
1992char *owl_command_loopwrite(int argc, char **argv, char *buff)
1993{
1994  owl_function_loopwrite_setup();
1995  return(NULL);
1996}
1997
1998char *owl_command_zcrypt(int argc, char **argv, char *buff)
1999{
2000#ifdef OWL_ENABLE_ZCRYPT
2001  owl_zwrite z;
2002
2003  if (!owl_global_is_havezephyr(&g)) {
2004    owl_function_makemsg("Zephyr is not available");
2005    return(NULL);
2006  }
2007  /* check for a zcrypt -m */
2008  owl_zwrite_create_from_line(&z, buff);
2009  if (owl_zwrite_is_message_set(&z)) {
2010    owl_function_zcrypt(buff, NULL);
2011    owl_zwrite_free(&z);
2012    return (NULL);
2013  }
2014
2015  if (argc < 2) {
2016    owl_function_makemsg("Not enough arguments to the zcrypt command.");
2017  } else {
2018    owl_function_zwrite_setup(buff);
2019  }
2020  return(NULL);
2021#else
2022  owl_function_makemsg("This Owl does not support zcrypt");
2023#endif
2024}
2025
2026char *owl_command_reply(int argc, char **argv, 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    owl_message *m;
2042    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, char **argv, char *buff)
2053{
2054  owl_function_create_filter(argc, argv);
2055  return NULL;
2056}
2057
2058char *owl_command_zlocate(int argc, char **argv, 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, char **argv, 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    char **myargv;
2117    int i;
2118
2119    myargv=owl_malloc((argc*sizeof(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      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, char **argv, 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    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, char **argv, 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, char **argv, 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, char **argv, 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, char **argv, 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()
2350{
2351  owl_function_beep();
2352}
2353
2354char *owl_command_colorview(int argc, char **argv, 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, char **argv, char *buff)
2365{
2366  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, char **argv, char *buff)
2379{
2380  owl_command_zpunt_and_zunpunt(argc, argv, 0);
2381  return NULL;
2382}
2383
2384char *owl_command_zunpunt(int argc, char **argv, 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, char **argv, int type)
2391{
2392  /* if type==0 then zpunt
2393   * if type==1 then zunpunt
2394   */
2395  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, char **argv, 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, char **argv, char *buff)
2440{
2441  owl_command_punt_unpunt(argc, argv, buff, 0);
2442  return NULL;
2443}
2444
2445char *owl_command_unpunt(int argc, char **argv, char *buff)
2446{
2447  owl_command_punt_unpunt(argc, argv, buff, 1);
2448  return NULL;
2449}
2450
2451void owl_command_punt_unpunt(int argc, char ** argv, 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_filter*)owl_list_get_element(fl, i);
2469        owl_list_remove_element(fl, i);
2470        owl_filter_free(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  } else {
2478    text = skiptokens(buff, 1);
2479  }
2480
2481  owl_function_punt(text, unpunt);
2482}
2483
2484
2485char *owl_command_getview(int argc, char **argv, char *buff)
2486{
2487  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) filtname = owl_strdup(filtname);
2494  return filtname;
2495}
2496
2497char *owl_command_getvar(int argc, char **argv, 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, char **argv, char *buf)
2512{
2513  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, char **argv, char *buff)
2526{
2527  int direction;
2528  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, char **argv, char *buff)
2547{
2548  char *buffstart;
2549
2550  buffstart=skiptokens(buff, 1);
2551
2552  owl_global_set_search_active(&g, buffstart);
2553
2554  if (!*buffstart) {
2555    owl_global_set_search_inactive(&g);
2556  }
2557
2558  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
2559 
2560  return(NULL);
2561}
2562
2563char *owl_command_aimlogin(int argc, char **argv, char *buff)
2564{
2565  if ((argc<2) || (argc>3)) {
2566    owl_function_makemsg("Wrong number of arguments to aimlogin command");
2567    return(NULL);
2568  }
2569
2570  /* if we get two arguments, ask for the password */
2571  if (argc==2) {
2572    owl_global_set_buffercommand(&g, argv[1]);
2573    owl_global_set_buffercallback(&g, &owl_callback_aimlogin);
2574    owl_function_start_password("AIM Password: ");
2575    return(NULL);
2576  } else {
2577    owl_function_aimlogin(argv[1], argv[2]);
2578  }
2579
2580  /* this is a test */
2581  return(NULL);
2582}
2583
2584char *owl_command_aimlogout(int argc, char **argv, char *buff)
2585{
2586  /* clear the buddylist */
2587  owl_buddylist_clear(owl_global_get_buddylist(&g));
2588
2589  owl_aim_logout();
2590  return(NULL);
2591}
2592
2593char *owl_command_getstyle(int argc, char **argv, char *buff)
2594{
2595  char *stylename;
2596  if (argc != 1) {
2597    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
2598    return NULL;
2599  }
2600  stylename = owl_view_get_style_name(owl_global_get_current_view(&g));
2601  if (stylename) stylename = owl_strdup(stylename);
2602  return stylename;
2603}
2604
2605char *owl_command_error(int argc, char **argv, char *buff)
2606{
2607    buff = skiptokens(buff, 1);
2608    owl_function_error("%s", buff);
2609    return NULL;
2610}
2611
2612char *owl_command_message(int argc, char **argv, char *buff)
2613{
2614    buff = skiptokens(buff, 1);
2615    owl_function_makemsg("%s", buff);
2616    return NULL;
2617}
2618
2619void owl_command_yes(void)
2620{
2621  owl_message *m;
2622  owl_view *v;
2623  char *cmd;
2624
2625  v = owl_global_get_current_view(&g);
2626
2627  /* bail if there's no current message */
2628  if (owl_view_get_size(v) < 1) {
2629    owl_function_error("No current message.");
2630    return;
2631  }
2632
2633  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
2634  if(!owl_message_is_question(m)) {
2635    owl_function_error("That message isn't a question.");
2636    return;
2637  }
2638  if(owl_message_is_answered(m)) {
2639    owl_function_error("You already answered that question.");
2640    return;
2641  }
2642  cmd = owl_message_get_attribute_value(m, "yescommand");
2643  if(!cmd) {
2644    owl_function_error("No 'yes' command!");
2645    return;
2646  }
2647
2648  owl_function_command_norv(cmd);
2649  owl_message_set_isanswered(m);
2650  return;
2651}
2652
2653void owl_command_no(void)
2654{
2655  owl_message *m;
2656  owl_view *v;
2657  char *cmd;
2658
2659  v = owl_global_get_current_view(&g);
2660
2661  /* bail if there's no current message */
2662  if (owl_view_get_size(v) < 1) {
2663    owl_function_error("No current message.");
2664    return;
2665  }
2666
2667  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
2668  if(!owl_message_is_question(m)) {
2669    owl_function_error("That message isn't a question.");
2670    return;
2671  }
2672  if(owl_message_is_answered(m)) {
2673    owl_function_error("You already answered that question.");
2674    return;
2675  }
2676  cmd = owl_message_get_attribute_value(m, "nocommand");
2677  if(!cmd) {
2678    owl_function_error("No 'no' command!");
2679    return;
2680  }
2681
2682  owl_function_command_norv(cmd);
2683  owl_message_set_isanswered(m);
2684  return;
2685}
2686
2687/*********************************************************************/
2688/************************** EDIT SPECIFIC ****************************/
2689/*********************************************************************/
2690
2691void owl_command_edit_cancel(owl_editwin *e)
2692{
2693  owl_history *hist;
2694
2695  owl_function_makemsg("Command cancelled.");
2696
2697  if(owl_editwin_get_echochar(e) == 0) {
2698    hist=owl_editwin_get_history(e);
2699    owl_history_store(hist, owl_editwin_get_text(e));
2700    owl_history_reset(hist);
2701  }
2702
2703  owl_editwin_fullclear(e);
2704  owl_global_set_needrefresh(&g);
2705  wnoutrefresh(owl_editwin_get_curswin(e));
2706  owl_global_set_typwin_inactive(&g);
2707  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
2708
2709  owl_function_activate_keymap("recv");
2710}
2711
2712void owl_command_edit_history_prev(owl_editwin *e)
2713{
2714  owl_history *hist;
2715  char *ptr;
2716
2717  hist=owl_editwin_get_history(e);
2718  if (!owl_history_is_touched(hist)) {
2719    owl_history_store(hist, owl_editwin_get_text(e));
2720    owl_history_set_partial(hist);
2721  }
2722  ptr=owl_history_get_prev(hist);
2723  if (ptr) {
2724    owl_editwin_clear(e);
2725    owl_editwin_insert_string(e, ptr);
2726    owl_editwin_redisplay(e, 0);
2727    owl_global_set_needrefresh(&g);
2728  } else {
2729    owl_function_beep();
2730  }
2731}
2732
2733void owl_command_edit_history_next(owl_editwin *e)
2734{
2735  owl_history *hist;
2736  char *ptr;
2737
2738  hist=owl_editwin_get_history(e);
2739  ptr=owl_history_get_next(hist);
2740  if (ptr) {
2741    owl_editwin_clear(e);
2742    owl_editwin_insert_string(e, ptr);
2743    owl_editwin_redisplay(e, 0);
2744    owl_global_set_needrefresh(&g);
2745  } else {
2746    owl_function_beep();
2747  }
2748}
2749
2750char *owl_command_edit_insert_text(owl_editwin *e, int argc, char **argv, char *buff)
2751{
2752  buff = skiptokens(buff, 1);
2753  owl_editwin_insert_string(e, buff);
2754  owl_editwin_redisplay(e, 0);
2755  owl_global_set_needrefresh(&g); 
2756  return NULL;
2757}
2758
2759void owl_command_editline_done(owl_editwin *e)
2760{
2761  owl_history *hist=owl_editwin_get_history(e);
2762  char *rv, *cmd;
2763
2764  owl_history_store(hist, owl_editwin_get_text(e));
2765  owl_history_reset(hist);
2766  owl_global_set_typwin_inactive(&g);
2767  cmd = owl_strdup(owl_editwin_get_text(e));
2768  owl_editwin_fullclear(e);
2769  rv = owl_function_command(cmd);
2770  owl_free(cmd);
2771
2772  wnoutrefresh(owl_editwin_get_curswin(e));
2773  owl_global_set_needrefresh(&g);
2774
2775  if (rv) {
2776    owl_function_makemsg("%s", rv);
2777    owl_free(rv);
2778  }
2779}
2780
2781
2782void owl_command_editresponse_done(owl_editwin *e)
2783{
2784  owl_function_run_buffercommand();
2785
2786  owl_global_set_typwin_inactive(&g);
2787  owl_editwin_fullclear(e);
2788  wnoutrefresh(owl_editwin_get_curswin(e));
2789  owl_global_set_needrefresh(&g);
2790}
2791
2792
2793void owl_command_editmulti_done(owl_editwin *e)
2794{
2795  owl_history *hist=owl_editwin_get_history(e);
2796
2797  owl_history_store(hist, owl_editwin_get_text(e));
2798  owl_history_reset(hist);
2799
2800  owl_function_run_buffercommand();
2801  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
2802  owl_editwin_fullclear(e);
2803  owl_global_set_typwin_inactive(&g);
2804  owl_global_set_needrefresh(&g);
2805  wnoutrefresh(owl_editwin_get_curswin(e));
2806}
2807
2808void owl_command_editmulti_done_or_delete(owl_editwin *e)
2809{
2810  if (owl_editwin_is_at_end(e)) {
2811    owl_command_editmulti_done(e);
2812  } else {
2813    owl_editwin_delete_char(e);
2814  }
2815}
2816
2817
2818/*********************************************************************/
2819/*********************** POPLESS SPECIFIC ****************************/
2820/*********************************************************************/
2821
2822void owl_command_popless_quit(owl_viewwin *vw)
2823{
2824  owl_popwin_close(owl_global_get_popwin(&g));
2825  owl_viewwin_free(vw);
2826  owl_global_set_needrefresh(&g);
2827}
Note: See TracBrowser for help on using the repository browser.