comparison mcabber/server.c @ 0:b3b2332715fb

Tailorization of /trunk Import of the upstream sources from Repository: file:///tmp/svn-mcabber Module: /trunk Revision: 15
author tailor@frmp8452
date Thu, 30 Jun 2005 21:39:31 +0000
parents
children 7eeda3a06b21
comparison
equal deleted inserted replaced
-1:000000000000 0:b3b2332715fb
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, "Cant 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 "El servidor no esta respondiendo correctamente",
136 60, 0, NULL);
137 return NULL;
138 }
139 aux = response;
140 while (strncmp(aux, "id", 2))
141 aux++;
142 pos = 0;
143 aux += 4;
144 while (strncmp(aux, "'", 1)) {
145 aux++;
146 pos++;
147 }
148 aux -= pos;
149 strncpy(idsession, aux, pos);
150
151 free(response);
152
153 strcpy(stringtosend, "<iq type='set' id='1000'>");
154 strcat(stringtosend, "<query xmlns='jabber:iq:auth'>");
155 strcat(stringtosend, "<username>");
156 strcat(stringtosend, user);
157 strcat(stringtosend, "</username><password>");
158 strcat(stringtosend, pass);
159 strcat(stringtosend, "</password><resource>");
160 strcat(stringtosend, resource);
161 strcat(stringtosend, "</resource></query></iq>\n");
162 if (!sk_send(sock, stringtosend)) {
163 perror("senddata (server.c:167)");
164 return NULL;
165 }
166 response = sk_recv(sock);
167 if (strstr(response, "error")) {
168 /* fprintf(stderr, "Response not valid:\n%s\n\n", response);*/
169 scr_CreatePopup("Error",
170 "Cuenta no creada o contraseņa incorrecta", 60, 0,
171 NULL);
172 scr_CreatePopup("Info", "Intentando crear la cuenta...", 60, 0, NULL);
173
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 scr_TerminateCurses();
192 printf("Reinicie cabber!\n\n");
193 return NULL;
194 }
195 free(response);
196 free(stringtosend);
197
198 return idsession;
199 }
200
201
202 /* Desc: broadcast presence
203 *
204 * In : socket, presence string
205 * Out : ?
206 *
207 * Note: see `sk_send' for output values
208 */
209 int srv_setpresence(int sock, const char *type)
210 {
211 int rv;
212 char *str = malloc(1024);
213
214 sprintf(str, "<presence><status>%s</status></presence>", type);
215 if (!(rv = sk_send(sock, str))) {
216 perror("senddata (server.c:199)");
217 }
218 free(str);
219
220 return rv;
221 }
222
223
224 /* Desc: request roster
225 *
226 * In : socket
227 * Out : roster string
228 *
229 * Note: it is up to the caller to free the returned string
230 */
231 char *srv_getroster(int sock)
232 {
233 char *str = malloc(1024);
234
235 strcpy(str, "<iq type='get' id='1001'><query xmlns='");
236 strcat(str, "jabber:iq:roster'/></iq>\n");
237 if (!sk_send(sock, str)) {
238 perror("senddata (server.c:222)");
239 return NULL;
240 }
241 free(str);
242
243 return sk_recv(sock);
244 }
245
246
247 /* Desc: send text to buddy
248 *
249 * In : socket, destination jid, text, source jid
250 * Out : 0 = ok
251 *
252 * Note: -
253 */
254 int
255 srv_sendtext(int sock, const char *to, const char *text, const char *from)
256 {
257 char *stringtosend = malloc(2048);
258 char *utf8inputline = utf8_encode(text);
259
260 sprintf(stringtosend,
261 "<message from='%s' to='%s' type='chat'><body>%s</body></message>",
262 from, to, utf8inputline);
263 if (!sk_send(sock, stringtosend)) {
264 perror("senddata (server.c:247)");
265 return -1;
266 }
267
268 free(stringtosend);
269 free(utf8inputline);
270 return 0;
271 }
272
273 int check_io(int fd1, int fd2)
274 {
275 int n = 0, i;
276 fd_set fds;
277 int io_pending = 0;
278
279 i = fd1;
280 if (fd2 > fd1)
281 i = fd2;
282
283 FD_ZERO(&fds);
284 if (fd1 >= 0)
285 FD_SET(fd1, &fds);
286 else
287 fd1 = 0;
288 if (fd2 >= 0)
289 FD_SET(fd2, &fds);
290 else
291 fd2 = 0;
292
293 if (fd2 == 0 && io_pending)
294 n = 2;
295 else if (select(i + 1, &fds, NULL, NULL, NULL) > 0)
296 n = 1 * (FD_ISSET(fd1, &fds) > 0) + 2 * (FD_ISSET(fd2, &fds) > 0);
297
298 return (n);
299 }
300
301 /* Desc: read data from server
302 *
303 * In : socket
304 * Out : ptr to newly allocated srv_msg struct
305 *
306 * Note: returns NULL if no input from server
307 */
308 srv_msg *readserver(int sock)
309 {
310 char *buffer = sk_recv(sock);
311
312 if (buffer != NULL) {
313 srv_msg *msg = calloc(1, sizeof(srv_msg));
314 char *to = getattr(buffer, "to='");
315 char *from = getattr(buffer, "from='");
316 char *id = getattr(buffer, "id='");
317 char *type = getattr(buffer, "type='");
318 char *body = gettag(buffer, "body");
319 char *status = gettag(buffer, "status");
320 char *show = gettag(buffer, "show");
321 char *line = (char *) malloc(1024);
322 memset(line, 0, 1024);
323
324 /* scan for buffer */
325 if (!strncmp(buffer, "<message", 8)) { /* manage messages */
326 msg->m = SM_MESSAGE;
327 } else if (!strncmp(buffer, "<presence", 9)) { /* manage presences */
328 msg->m = SM_PRESENCE;
329 if (!strncmp(type, "UNK", 3)) { /* assume online */
330 msg->connected = FLAG_BUDDY_CONNECTED;
331 } else if (!strncmp(type, "unavailable", 11)) { /* offline */
332 msg->connected = 0;
333 }
334 } else {
335 msg->m = SM_UNHANDLED;
336 }
337
338 /* write the parsed buffer */
339 switch (msg->m) {
340 case SM_MESSAGE:
341 {
342 char *aux = strstr(from, "/");
343 if (aux)
344 *aux = '\0';
345 msg->from = from;
346 msg->body = utf8_decode(body);
347 ut_WriteLog("+OK [%s]\n", buffer);
348 }
349 break;
350
351 case SM_PRESENCE:
352 {
353 char *aux = strstr(from, "/");
354 if (aux)
355 *aux = '\0';
356 msg->from = from;
357 }
358 break;
359
360 case SM_UNHANDLED:
361 ut_WriteLog("BAD [%s]\n", buffer);
362 break;
363
364 }
365 free(line);
366 if (strncmp(to, "UNK", 3))
367 free(to);
368 if (strncmp(from, "UNK", 3) && (msg->m != SM_MESSAGE)
369 && (msg->m != SM_PRESENCE))
370 free(from);
371 if (strncmp(id, "UNK", 3))
372 free(id);
373 if (strncmp(type, "UNK", 3))
374 free(type);
375 if (strncmp(body, "UNK", 3))
376 free(body);
377 if (strncmp(status, "UNK", 3))
378 free(status);
379 if (strncmp(show, "UNK", 3))
380 free(show);
381 free(buffer);
382
383 return msg;
384 }
385
386 return NULL;
387 }
388
389 void srv_AddBuddy(int sock, char *jidname)
390 {
391 char *buffer = (char *) malloc(1024);
392 char *p, *str;
393 int i;
394
395 memset(buffer, 0, 1024);
396 strcpy(buffer, "<iq type='set'>");
397 strcat(buffer, " <query xmlns='jabber:iq:roster'>");
398 strcat(buffer, " <item");
399 strcat(buffer, " jid='");
400 strcat(buffer, jidname);
401 strcat(buffer, "' name='");
402
403 str = strdup(jidname);
404 p = strstr(str, "@");
405 if (p)
406 *p = '\0';
407 strcat(buffer, str);
408 strcat(buffer, "'/></query></iq>");
409 sk_send(sock, buffer);
410 free(buffer);
411
412 for (i = 0; i < 2; i++) {
413 buffer = sk_recv(sock);
414 ut_WriteLog("[Subscription]: %s\n", buffer);
415 free(buffer);
416 }
417
418 buffer = (char *) malloc(1024);
419 memset(buffer, 0, 1024);
420 strcpy(buffer, "<presence to='");
421 strcat(buffer, jidname);
422 strcat(buffer, "' type='subscribe'>");
423 strcat(buffer, "<status>I would like to add you!</status></presence>");
424 sk_send(sock, buffer);
425 free(buffer);
426
427 buffer = sk_recv(sock);
428 ut_WriteLog("[Subscription]: %s\n", buffer);
429 free(buffer);
430
431 buffer = (char *) malloc(1024);
432 memset(buffer, 0, 1024);
433 strcpy(buffer, "<presence to='");
434 strcat(buffer, jidname);
435 strcat(buffer, "' type='subscribed'/>");
436 sk_send(sock, buffer);
437 free(buffer);
438
439 buffer = sk_recv(sock);
440 ut_WriteLog("[Subscription]: %s\n", buffer);
441 free(buffer);
442 }
443
444 void srv_DelBuddy(int sock, char *jidname)
445 {
446 char *buffer = (char *) malloc(1024);
447
448 strcpy(buffer, "<iq type='set'><query xmlns='jabber:iq:roster'>");
449 strcat(buffer, "<item jid='");
450 strcat(buffer, jidname);
451 strcat(buffer, "' subscription='remove'/></query></iq>");
452
453 sk_send(sock, buffer);
454 free(buffer);
455
456 buffer = sk_recv(sock);
457 ut_WriteLog("[SubscriptionRemove]: %s\n", buffer);
458 free(buffer);
459 }