source: commands.c @ 228326a

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