updates.
[silc.git] / apps / silc / local_command.c
1 /*
2
3   local_command.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * $Id$
22  * $Log$
23  * Revision 1.2  2001/01/30 21:40:21  priikone
24  *      updates.
25  *
26  * Revision 1.1  2000/09/13 17:47:54  priikone
27  *      Created SILC Client Libary by moving stuff from silc/ directory.
28  *      SILC client library is SILC client without UI. Old UI still exists
29  *      in silc/ directory and uses the new client.
30  *
31  *      Bug fixes and several new functions, structures and functions
32  *      naming changes during the change was made.
33  *
34  */
35
36 #include "clientincludes.h"
37
38 /* Local commands. */
39 SilcClientCommand silc_local_command_list[] =
40 {
41   SILC_CLIENT_LCMD(help, HELP, "HELP", 0, 2),
42   SILC_CLIENT_LCMD(clear, CLEAR, "CLEAR", 0, 1),
43   SILC_CLIENT_LCMD(version, VERSION, "VERSION", 0, 1),
44   SILC_CLIENT_LCMD(server, SERVER, "SERVER", 0, 2),
45   SILC_CLIENT_LCMD(msg, MSG, "MSG", 0, 3),
46   SILC_CLIENT_LCMD(away, AWAY, "AWAY", 0, 2),
47
48   { NULL, 0, NULL, 0, 0 },
49 };
50
51 /* Finds and returns a pointer to the command list. Return NULL if the
52    command is not found. */
53
54 SilcClientCommand *silc_client_local_command_find(const char *name)
55 {
56   SilcClientCommand *cmd;
57
58   for (cmd = silc_local_command_list; cmd->name; cmd++) {
59     if (!strcmp(cmd->name, name))
60       return cmd;
61   }
62
63   return NULL;
64 }
65
66 /* HELP command. This is local command and shows help on SILC */
67
68 SILC_CLIENT_LCMD_FUNC(help)
69 {
70
71 }
72
73 /* CLEAR command. This is local command and clears current output window */
74
75 SILC_CLIENT_LCMD_FUNC(clear)
76 {
77   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
78   SilcClient client = cmd->client;
79   SilcClientInternal app = (SilcClientInternal)client->application;
80
81 #if 0
82   wclear((WINDOW *)app->screen);
83   wrefresh((WINDOW *)app->screen);
84 #endif
85
86   silc_client_command_free(cmd);
87 }
88
89 /* VERSION command. This is local command and shows version of the client */
90
91 SILC_CLIENT_LCMD_FUNC(version)
92 {
93   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
94   SilcClient client = cmd->client;
95   extern char *silc_version;
96   extern char *silc_name;
97   extern char *silc_fullname;
98
99   silc_say(client, cmd->conn,
100            "%s (%s) version %s", silc_name, silc_fullname,
101            silc_version);
102
103   silc_client_command_free(cmd);
104 }
105
106 /* Command MSG. Sends private message to user or list of users. Note that
107    private messages are not really commands, they are message packets,
108    however, on user interface it is convenient to show them as commands
109    as that is the common way of sending private messages (like in IRC). */
110 /* XXX supports only one destination */
111
112 SILC_CLIENT_LCMD_FUNC(msg)
113 {
114   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
115   SilcClientConnection conn = cmd->conn;
116   SilcClient client = cmd->client;
117   SilcClientEntry client_entry = NULL;
118   unsigned int num = 0;
119   char *nickname = NULL, *server = NULL;
120
121   if (!cmd->conn) {
122     silc_say(client, conn,
123              "You are not connected to a server, use /SERVER to connect");
124     goto out;
125   }
126
127   if (cmd->argc < 3) {
128     silc_say(client, conn, "Usage: /MSG <nickname> <message>");
129     goto out;
130   }
131
132   /* Parse the typed nickname. */
133   if (!silc_parse_nickname(cmd->argv[1], &nickname, &server, &num)) {
134     silc_say(client, conn, "Bad nickname");
135     goto out;
136   }
137
138   /* Find client entry */
139   client_entry = silc_idlist_get_client(client, conn, nickname, server, num);
140   if (!client_entry) {
141     /* Client entry not found, it was requested thus mark this to be
142        pending command. */
143     silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 0,
144                                 silc_client_local_command_msg, context);
145     return;
146   }
147
148   /* Display the message for our eyes. */
149   silc_print(client, "-> *%s* %s", cmd->argv[1], cmd->argv[2]);
150
151   /* Send the private message */
152   silc_client_packet_send_private_message(client, conn->sock, client_entry,
153                                           cmd->argv[2], cmd->argv_lens[2],
154                                           TRUE);
155
156  out:
157   silc_client_command_free(cmd);
158 }
159
160
161 /* Command SERVER. Connects to remote SILC server. This is local command. */
162
163 SILC_CLIENT_LCMD_FUNC(server)
164 {
165   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
166   SilcClient client = cmd->client;
167   SilcClientConnection conn = cmd->conn;
168   int i = 0, len, port;
169   char *hostname;
170
171   if (cmd->argc < 2) {
172     /* Show current servers */
173
174     if (!cmd->conn) {
175       silc_say(client, conn, "You are not connected to any server");
176       silc_say(client, conn, "Usage: /SERVER [<server>[:<port>]]");
177       goto out;
178     }
179
180     silc_say(client, conn, "Current server: %s on %d %s", 
181              conn->remote_host, conn->remote_port,
182              conn->remote_info ? conn->remote_info : "");
183     
184     silc_say(client, conn, "Server list:");
185     for (i = 0; i < client->conns_count; i++) {
186       silc_say(client, conn, " [%d] %s on %d %s", i + 1,
187                client->conns[i]->remote_host, 
188                client->conns[i]->remote_port,
189                client->conns[i]->remote_info ? 
190                client->conns[i]->remote_info : "");
191     }
192
193     goto out;
194   }
195
196   /* See if port is included and then extract it */
197   if (strchr(cmd->argv[1], ':')) {
198     len = strcspn(cmd->argv[1], ":");
199     hostname = silc_calloc(len + 1, sizeof(char));
200     memcpy(hostname, cmd->argv[1], len);
201     port = atoi(cmd->argv[1] + 1 + len);
202   } else {
203     hostname = cmd->argv[1];
204     port = 706;
205   }
206
207   /* Connect asynchronously to not to block user interface */
208   silc_client_connect_to_server(cmd->client, port, hostname, NULL);
209
210  out:
211   silc_client_command_free(cmd);
212 }
213
214 /* Local command AWAY. Client replies with away message to whomever sends
215    private message to the client if the away message is set. If this is
216    given without arguments the away message is removed. */
217
218 SILC_CLIENT_LCMD_FUNC(away)
219 {
220   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
221   SilcClientConnection conn = cmd->conn;
222   SilcClient client = cmd->client;
223   SilcClientInternal app = (SilcClientInternal)client->application;
224
225   if (!cmd->conn) {
226     silc_say(client, conn,
227              "You are not connected to a server, use /SERVER to connect");
228     goto out;
229   }
230
231   if (cmd->argc == 1) {
232     if (conn->away) {
233       silc_free(conn->away->away);
234       silc_free(conn->away);
235       conn->away = NULL;
236       app->screen->bottom_line->away = FALSE;
237
238       silc_say(client, conn, "Away message removed");
239       silc_screen_print_bottom_line(app->screen, 0);
240     }
241   } else {
242
243     if (conn->away)
244       silc_free(conn->away->away);
245     else
246       conn->away = silc_calloc(1, sizeof(*conn->away));
247     
248     app->screen->bottom_line->away = TRUE;
249     conn->away->away = strdup(cmd->argv[1]);
250
251     silc_say(client, conn, "Away message set: %s", conn->away->away);
252     silc_screen_print_bottom_line(app->screen, 0);
253   }
254
255  out:
256   silc_client_command_free(cmd);
257 }