source: commands.c @ c0a90c2

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