source: commands.c @ 8240bce

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