Mercurial > ~mikael > mcabber > hg
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 } |