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