comparison mcabber/src/server.c @ 24:e88b15cbf2de

[/trunk] Changeset 40 by mikael * Change structure -> src directory for mcabber source code...
author mikael
date Sun, 27 Mar 2005 20:16:02 +0000
parents
children 8588f5a4b638
comparison
equal deleted inserted replaced
23:d7107507424b 24:e88b15cbf2de
1 #include <arpa/inet.h>
2 #include <netdb.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/poll.h>
7
8 #include "list.h"
9 #include "parsecfg.h"
10 #include "screen.h"
11 #include "socket.h"
12 #include "utf8.h"
13 #include "server.h"
14 #include "harddefines.h"
15 #include "utils.h"
16 #include "buddies.h"
17
18 #define JABBERPORT 5222
19
20
21 /* Desc: poll data from server
22 *
23 * In : socket
24 * Out : pending buffer (or NULL if no incoming data)
25 *
26 * Note: it is up to the caller to free the returned string
27 */
28 char *srv_poll(int sock)
29 {
30 struct pollfd sock_p;
31 sock_p.fd = sock;
32 sock_p.events = POLLIN | POLLPRI;
33 sock_p.revents = 0;
34 poll(&sock_p, 1, 0);
35
36 if (sock_p.revents) {
37 return sk_recv(sock);
38 }
39
40 return NULL;
41 }
42
43
44 /* Desc: resolve host
45 *
46 * In : hostname
47 * Out : 32bit address (or 0 if error)
48 *
49 * Note: -
50 */
51 static u_long srv_resolve(const char *host)
52 {
53 long i;
54 struct hostent *he;
55
56 if ((i = inet_addr(host)) == -1) {
57 if (!(he = gethostbyname(host)))
58 return 0;
59 else
60 return (*(u_long *) he->h_addr);
61 }
62
63 return i;
64 }
65
66
67 /* Desc: connect to jabber server
68 *
69 * In : config
70 * Out : socket (or -1 on error)
71 *
72 * Note: if port is -1, the default Jabber port will be used
73 */
74 int srv_connect(const char *server, unsigned int port)
75 {
76 struct sockaddr_in name;
77 int sock;
78
79 if (server == NULL) {
80 fprintf(stderr, "You must supply a server name\n\r");
81 return -1;
82 }
83
84 if (port == -1U) {
85 port = JABBERPORT;
86 }
87
88 name.sin_family = AF_INET;
89 name.sin_port = htons(port);
90
91 if (!(name.sin_addr.s_addr = srv_resolve(server))) {
92 fprintf(stderr, "Cant resolve \"%s\"\n", server);
93 return -1;
94 }
95
96 if ((sock = sk_conn((struct sockaddr *) &name)) < 0) {
97 fprintf(stderr, "Can't connect to \"%s:%u\"\n", server, port);
98 return -1;
99 }
100
101 return sock;
102 }
103
104
105 /* Desc: login into jabber server
106 *
107 * In : socket, servername, user, password, resource
108 * Out : idsession
109 *
110 * Note: it is up to the caller to free the returned string
111 */
112 char *srv_login(int sock, const char *server, const char *user,
113 const char *pass, const char *resource)
114 {
115 char *stringtosend = malloc(2048);
116 char *response, *aux;
117 char *idsession = malloc(128);
118 int pos = 0;
119
120 memset(stringtosend, 0, 2048);
121 strcpy(stringtosend, "<?xml version='1.0' encoding='UTF-8' ?>");
122 strcat(stringtosend, "<stream:stream to='");
123 strcat(stringtosend, server);
124 strcat(stringtosend, "' xmlns='jabber:client' xmlns:stream='");
125 strcat(stringtosend, "http://etherx.jabber.org/streams'>\n");
126
127 if (!sk_send(sock, stringtosend)) {
128 perror("senddata (server.c:132)");
129 return NULL;
130 }
131 response = sk_recv(sock);
132 if (strstr(response, "error")) {
133 /* fprintf(stderr, "Response not valid:\n%s\n\n", response); */
134 scr_CreatePopup("Error",
135 "Bad answer from the server", 60, 0, NULL);
136 return NULL;
137 }
138 aux = response;
139 while (strncmp(aux, "id", 2))
140 aux++;
141 pos = 0;
142 aux += 4;
143 while (strncmp(aux, "'", 1)) {
144 aux++;
145 pos++;
146 }
147 aux -= pos;
148 strncpy(idsession, aux, pos);
149
150 free(response);
151
152 strcpy(stringtosend, "<iq type='set' id='1000'>");
153 strcat(stringtosend, "<query xmlns='jabber:iq:auth'>");
154 strcat(stringtosend, "<username>");
155 strcat(stringtosend, user);
156 strcat(stringtosend, "</username><password>");
157 strcat(stringtosend, pass);
158 strcat(stringtosend, "</password><resource>");
159 strcat(stringtosend, resource);
160 strcat(stringtosend, "</resource></query></iq>\n");
161 if (!sk_send(sock, stringtosend)) {
162 perror("senddata (server.c:167)");
163 return NULL;
164 }
165 response = sk_recv(sock);
166 if (strstr(response, "error")) {
167 /* fprintf(stderr, "Response not valid:\n%s\n\n", response);*/
168 scr_CreatePopup("Error",
169 "Account doesn't exist, or bad password", 60, 0,
170 NULL);
171
172 /*
173 scr_CreatePopup("Info", "Trying to create the account...", 60, 0, NULL);
174
175 strcpy(stringtosend, "<iq type='set' id='reg' to='");
176 strcat(stringtosend, server);
177 strcat(stringtosend, "'>");
178 strcat(stringtosend, "<query xmlns='jabber:iq:register'>");
179 strcat(stringtosend, "<username>");
180 strcat(stringtosend, user);
181 strcat(stringtosend, "</username><password>");
182 strcat(stringtosend, pass);
183 strcat(stringtosend, "</password>");
184 strcat(stringtosend, "</query></iq>\n");
185 if (!sk_send(sock, stringtosend)) {
186 perror("senddata (server.c:167)");
187 return NULL;
188 }
189
190 response = sk_recv(sock);
191 */
192 scr_TerminateCurses();
193 printf("Reinicie cabber!\n\n");
194 return NULL;
195 }
196 free(response);
197 free(stringtosend);
198
199 return idsession;
200 }
201
202
203 /* Desc: broadcast presence
204 *
205 * In : socket, presence string
206 * Out : ?
207 *
208 * Note: see `sk_send' for output values
209 */
210 int srv_setpresence(int sock, const char *type)
211 {
212 int rv;
213 char *str = malloc(1024);
214
215 sprintf(str, "<presence><status>%s</status></presence>", type);
216 if (!(rv = sk_send(sock, str))) {
217 perror("senddata (server.c:199)");
218 }
219 free(str);
220
221 return rv;
222 }
223
224
225 /* Desc: request roster
226 *
227 * In : socket
228 * Out : roster string
229 *
230 * Note: it is up to the caller to free the returned string
231 */
232 char *srv_getroster(int sock)
233 {
234 char *str = malloc(1024);
235
236 strcpy(str, "<iq type='get' id='1001'><query xmlns='");
237 strcat(str, "jabber:iq:roster'/></iq>\n");
238 if (!sk_send(sock, str)) {
239 perror("senddata (server.c:222)");
240 return NULL;
241 }
242 free(str);
243
244 return sk_recv(sock);
245 }
246
247
248 /* Desc: send text to buddy
249 *
250 * In : socket, destination jid, text, source jid
251 * Out : 0 = ok
252 *
253 * Note: -
254 */
255 int
256 srv_sendtext(int sock, const char *to, const char *text, const char *from)
257 {
258 char *stringtosend = malloc(2048);
259 char *utf8inputline = utf8_encode(text);
260
261 sprintf(stringtosend,
262 "<message from='%s' to='%s' type='chat'><body>%s</body></message>",
263 from, to, utf8inputline);
264 if (!sk_send(sock, stringtosend)) {
265 perror("senddata (server.c:247)");
266 return -1;
267 }
268
269 free(stringtosend);
270 free(utf8inputline);
271 return 0;
272 }
273
274 int check_io(int fd1, int fd2)
275 {
276 int n = 0, i;
277 fd_set fds;
278 int io_pending = 0;
279
280 i = fd1;
281 if (fd2 > fd1)
282 i = fd2;
283
284 FD_ZERO(&fds);
285 if (fd1 >= 0)
286 FD_SET(fd1, &fds);
287 else
288 fd1 = 0;
289 if (fd2 >= 0)
290 FD_SET(fd2, &fds);
291 else
292 fd2 = 0;
293
294 if (fd2 == 0 && io_pending)
295 n = 2;
296 else if (select(i + 1, &fds, NULL, NULL, NULL) > 0)
297 n = 1 * (FD_ISSET(fd1, &fds) > 0) + 2 * (FD_ISSET(fd2, &fds) > 0);
298
299 return (n);
300 }
301
302 /* Desc: read data from server
303 *
304 * In : socket
305 * Out : ptr to newly allocated srv_msg struct
306 *
307 * Note: returns NULL if no input from server
308 */
309 srv_msg *readserver(int sock)
310 {
311 char *buffer = sk_recv(sock);
312
313 if (buffer != NULL) {
314 srv_msg *msg = calloc(1, sizeof(srv_msg));
315 char *to = getattr(buffer, "to='");
316 char *from = getattr(buffer, "from='");
317 char *id = getattr(buffer, "id='");
318 char *type = getattr(buffer, "type='");
319 char *body = gettag(buffer, "body");
320 char *status = gettag(buffer, "status");
321 char *show = gettag(buffer, "show");
322 char *line = (char *) malloc(1024);
323 memset(line, 0, 1024);
324
325 /* scan for buffer */
326 if (!strncmp(buffer, "<message", 8)) { /* manage messages */
327 msg->m = SM_MESSAGE;
328 } else if (!strncmp(buffer, "<presence", 9)) { /* manage presences */
329 msg->m = SM_PRESENCE;
330 if (!strncmp(type, "UNK", 3)) { /* assume online */
331 msg->connected = FLAG_BUDDY_CONNECTED;
332 } else if (!strncmp(type, "unavailable", 11)) { /* offline */
333 msg->connected = 0;
334 }
335 } else {
336 msg->m = SM_UNHANDLED;
337 }
338
339 /* write the parsed buffer */
340 switch (msg->m) {
341 case SM_MESSAGE:
342 {
343 char *aux = strstr(from, "/");
344 if (aux)
345 *aux = '\0';
346 msg->from = from;
347 msg->body = utf8_decode(body);
348 ut_WriteLog("+OK [%s]\n", buffer);
349 }
350 break;
351
352 case SM_PRESENCE:
353 {
354 char *aux = strstr(from, "/");
355 if (aux)
356 *aux = '\0';
357 msg->from = from;
358 }
359 break;
360
361 case SM_UNHANDLED:
362 ut_WriteLog("BAD [%s]\n", buffer);
363 break;
364
365 }
366 free(line);
367 if (strncmp(to, "UNK", 3))
368 free(to);
369 if (strncmp(from, "UNK", 3) && (msg->m != SM_MESSAGE)
370 && (msg->m != SM_PRESENCE))
371 free(from);
372 if (strncmp(id, "UNK", 3))
373 free(id);
374 if (strncmp(type, "UNK", 3))
375 free(type);
376 if (strncmp(body, "UNK", 3))
377 free(body);
378 if (strncmp(status, "UNK", 3))
379 free(status);
380 if (strncmp(show, "UNK", 3))
381 free(show);
382 free(buffer);
383
384 return msg;
385 }
386
387 return NULL;
388 }
389
390 void srv_AddBuddy(int sock, char *jidname)
391 {
392 char *buffer = (char *) malloc(1024);
393 char *p, *str;
394 int i;
395
396 memset(buffer, 0, 1024);
397 strcpy(buffer, "<iq type='set'>");
398 strcat(buffer, " <query xmlns='jabber:iq:roster'>");
399 strcat(buffer, " <item");
400 strcat(buffer, " jid='");
401 strcat(buffer, jidname);
402 strcat(buffer, "' name='");
403
404 str = strdup(jidname);
405 p = strstr(str, "@");
406 if (p)
407 *p = '\0';
408 strcat(buffer, str);
409 strcat(buffer, "'/></query></iq>");
410 sk_send(sock, buffer);
411 free(buffer);
412
413 for (i = 0; i < 2; i++) {
414 buffer = sk_recv(sock);
415 ut_WriteLog("[Subscription]: %s\n", buffer);
416 free(buffer);
417 }
418
419 buffer = (char *) malloc(1024);
420 memset(buffer, 0, 1024);
421 strcpy(buffer, "<presence to='");
422 strcat(buffer, jidname);
423 strcat(buffer, "' type='subscribe'>");
424 strcat(buffer, "<status>I would like to add you!</status></presence>");
425 sk_send(sock, buffer);
426 free(buffer);
427
428 buffer = sk_recv(sock);
429 ut_WriteLog("[Subscription]: %s\n", buffer);
430 free(buffer);
431
432 buffer = (char *) malloc(1024);
433 memset(buffer, 0, 1024);
434 strcpy(buffer, "<presence to='");
435 strcat(buffer, jidname);
436 strcat(buffer, "' type='subscribed'/>");
437 sk_send(sock, buffer);
438 free(buffer);
439
440 buffer = sk_recv(sock);
441 ut_WriteLog("[Subscription]: %s\n", buffer);
442 free(buffer);
443 }
444
445 void srv_DelBuddy(int sock, char *jidname)
446 {
447 char *buffer = (char *) malloc(1024);
448
449 strcpy(buffer, "<iq type='set'><query xmlns='jabber:iq:roster'>");
450 strcat(buffer, "<item jid='");
451 strcat(buffer, jidname);
452 strcat(buffer, "' subscription='remove'/></query></iq>");
453
454 sk_send(sock, buffer);
455 free(buffer);
456
457 buffer = sk_recv(sock);
458 ut_WriteLog("[SubscriptionRemove]: %s\n", buffer);
459 free(buffer);
460 }