source: commands.c @ c5c5686

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