Mercurial > pidgin
annotate src/protocols/gg/lib/pubdir.c @ 12141:dcd2bcad2f3d
[gaim-migrate @ 14442]
These strings have been bothering me for quite some time. Flame me if you object to the changes. I also changed the default pounce action to 'pop up notification'. This isn't a big deal, as the action(s) you choose are saved as the default for the next time.
committer: Tailor Script <tailor@pidgin.im>
| author | Richard Laager <rlaager@wiktel.com> |
|---|---|
| date | Fri, 18 Nov 2005 23:35:26 +0000 |
| parents | 3c536224f0d0 |
| children |
| rev | line source |
|---|---|
|
11546
3c536224f0d0
[gaim-migrate @ 13801]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11360
diff
changeset
|
1 /* $Id: pubdir.c 13801 2005-09-14 19:10:39Z datallah $ */ |
| 11360 | 2 |
| 3 /* | |
| 4 * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl> | |
| 5 * Dawid Jarosz <dawjar@poczta.onet.pl> | |
| 6 * | |
| 7 * This program is free software; you can redistribute it and/or modify | |
| 8 * it under the terms of the GNU Lesser General Public License Version | |
| 9 * 2.1 as published by the Free Software Foundation. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU Lesser General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU Lesser General Public | |
| 17 * License along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, | |
| 19 * USA. | |
| 20 */ | |
| 21 | |
| 22 #include <ctype.h> | |
| 23 #include <errno.h> | |
| 24 #include <stdarg.h> | |
| 25 #include <stdio.h> | |
| 26 #include <stdlib.h> | |
| 27 #include <string.h> | |
| 28 #include <unistd.h> | |
| 29 | |
| 30 #include "libgadu.h" | |
| 31 | |
| 32 /* | |
| 33 * gg_register3() | |
| 34 * | |
| 35 * rozpoczyna rejestrację użytkownika protokołem GG 6.0. wymaga wcześniejszego | |
| 36 * pobrania tokenu za pomocą funkcji gg_token(). | |
| 37 * | |
| 38 * - email - adres e-mail klienta | |
| 39 * - password - hasło klienta | |
| 40 * - tokenid - identyfikator tokenu | |
| 41 * - tokenval - wartość tokenu | |
| 42 * - async - połączenie asynchroniczne | |
| 43 * | |
| 44 * zaalokowana struct gg_http, którą poźniej należy zwolnić | |
| 45 * funkcją gg_register_free(), albo NULL jeśli wystąpił błąd. | |
| 46 */ | |
| 47 struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async) | |
| 48 { | |
| 49 struct gg_http *h; | |
| 50 char *__pwd, *__email, *__tokenid, *__tokenval, *form, *query; | |
| 51 | |
| 52 if (!email || !password || !tokenid || !tokenval) { | |
| 53 gg_debug(GG_DEBUG_MISC, "=> register, NULL parameter\n"); | |
| 54 errno = EFAULT; | |
| 55 return NULL; | |
| 56 } | |
| 57 | |
| 58 __pwd = gg_urlencode(password); | |
| 59 __email = gg_urlencode(email); | |
| 60 __tokenid = gg_urlencode(tokenid); | |
| 61 __tokenval = gg_urlencode(tokenval); | |
| 62 | |
| 63 if (!__pwd || !__email || !__tokenid || !__tokenval) { | |
| 64 gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form fields\n"); | |
| 65 free(__pwd); | |
| 66 free(__email); | |
| 67 free(__tokenid); | |
| 68 free(__tokenval); | |
| 69 return NULL; | |
| 70 } | |
| 71 | |
| 72 form = gg_saprintf("pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", | |
| 73 __pwd, __email, __tokenid, __tokenval, | |
| 74 gg_http_hash("ss", email, password)); | |
| 75 | |
| 76 free(__pwd); | |
| 77 free(__email); | |
| 78 free(__tokenid); | |
| 79 free(__tokenval); | |
| 80 | |
| 81 if (!form) { | |
| 82 gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n"); | |
| 83 return NULL; | |
| 84 } | |
| 85 | |
| 86 gg_debug(GG_DEBUG_MISC, "=> register, %s\n", form); | |
| 87 | |
| 88 query = gg_saprintf( | |
| 89 "Host: " GG_REGISTER_HOST "\r\n" | |
| 90 "Content-Type: application/x-www-form-urlencoded\r\n" | |
| 91 "User-Agent: " GG_HTTP_USERAGENT "\r\n" | |
| 92 "Content-Length: %d\r\n" | |
| 93 "Pragma: no-cache\r\n" | |
| 94 "\r\n" | |
| 95 "%s", | |
| 96 (int) strlen(form), form); | |
| 97 | |
| 98 free(form); | |
| 99 | |
| 100 if (!query) { | |
| 101 gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for query\n"); | |
| 102 return NULL; | |
| 103 } | |
| 104 | |
| 105 if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { | |
| 106 gg_debug(GG_DEBUG_MISC, "=> register, gg_http_connect() failed mysteriously\n"); | |
| 107 free(query); | |
| 108 return NULL; | |
| 109 } | |
| 110 | |
| 111 h->type = GG_SESSION_REGISTER; | |
| 112 | |
| 113 free(query); | |
| 114 | |
| 115 h->callback = gg_pubdir_watch_fd; | |
| 116 h->destroy = gg_pubdir_free; | |
| 117 | |
| 118 if (!async) | |
| 119 gg_pubdir_watch_fd(h); | |
| 120 | |
| 121 return h; | |
| 122 } | |
| 123 | |
| 124 /* | |
| 125 * gg_unregister3() | |
| 126 * | |
| 127 * usuwa konto użytkownika z serwera protokołem GG 6.0 | |
| 128 * | |
| 129 * - uin - numerek GG | |
| 130 * - password - hasło klienta | |
| 131 * - tokenid - identyfikator tokenu | |
| 132 * - tokenval - wartość tokenu | |
| 133 * - async - połączenie asynchroniczne | |
| 134 * | |
| 135 * zaalokowana struct gg_http, którą poźniej należy zwolnić | |
| 136 * funkcją gg_unregister_free(), albo NULL jeśli wystąpił błąd. | |
| 137 */ | |
| 138 struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async) | |
| 139 { | |
| 140 struct gg_http *h; | |
| 141 char *__fmpwd, *__pwd, *__tokenid, *__tokenval, *form, *query; | |
| 142 | |
| 143 if (!password || !tokenid || !tokenval) { | |
| 144 gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n"); | |
| 145 errno = EFAULT; | |
| 146 return NULL; | |
| 147 } | |
|
11546
3c536224f0d0
[gaim-migrate @ 13801]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11360
diff
changeset
|
148 |
| 11360 | 149 __pwd = gg_saprintf("%ld", random()); |
| 150 __fmpwd = gg_urlencode(password); | |
| 151 __tokenid = gg_urlencode(tokenid); | |
| 152 __tokenval = gg_urlencode(tokenval); | |
| 153 | |
| 154 if (!__fmpwd || !__pwd || !__tokenid || !__tokenval) { | |
| 155 gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form fields\n"); | |
| 156 free(__pwd); | |
| 157 free(__fmpwd); | |
| 158 free(__tokenid); | |
| 159 free(__tokenval); | |
| 160 return NULL; | |
| 161 } | |
| 162 | |
| 163 form = gg_saprintf("fmnumber=%d&fmpwd=%s&delete=1&pwd=%s&email=deletedaccount@gadu-gadu.pl&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __tokenid, __tokenval, gg_http_hash("ss", "deletedaccount@gadu-gadu.pl", __pwd)); | |
| 164 | |
| 165 free(__fmpwd); | |
| 166 free(__pwd); | |
| 167 free(__tokenid); | |
| 168 free(__tokenval); | |
| 169 | |
| 170 if (!form) { | |
| 171 gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n"); | |
| 172 return NULL; | |
| 173 } | |
| 174 | |
| 175 gg_debug(GG_DEBUG_MISC, "=> unregister, %s\n", form); | |
| 176 | |
| 177 query = gg_saprintf( | |
| 178 "Host: " GG_REGISTER_HOST "\r\n" | |
| 179 "Content-Type: application/x-www-form-urlencoded\r\n" | |
| 180 "User-Agent: " GG_HTTP_USERAGENT "\r\n" | |
| 181 "Content-Length: %d\r\n" | |
| 182 "Pragma: no-cache\r\n" | |
| 183 "\r\n" | |
| 184 "%s", | |
| 185 (int) strlen(form), form); | |
| 186 | |
| 187 free(form); | |
| 188 | |
| 189 if (!query) { | |
| 190 gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for query\n"); | |
| 191 return NULL; | |
| 192 } | |
| 193 | |
| 194 if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { | |
| 195 gg_debug(GG_DEBUG_MISC, "=> unregister, gg_http_connect() failed mysteriously\n"); | |
| 196 free(query); | |
| 197 return NULL; | |
| 198 } | |
| 199 | |
| 200 h->type = GG_SESSION_UNREGISTER; | |
| 201 | |
| 202 free(query); | |
| 203 | |
| 204 h->callback = gg_pubdir_watch_fd; | |
| 205 h->destroy = gg_pubdir_free; | |
| 206 | |
| 207 if (!async) | |
| 208 gg_pubdir_watch_fd(h); | |
| 209 | |
| 210 return h; | |
| 211 } | |
| 212 | |
| 213 /* | |
| 214 * gg_change_passwd4() | |
| 215 * | |
| 216 * wysyła żądanie zmiany hasła zgodnie z protokołem GG 6.0. wymaga | |
| 217 * wcześniejszego pobrania tokenu za pomocą funkcji gg_token(). | |
| 218 * | |
| 219 * - uin - numer | |
| 220 * - email - adres e-mail | |
| 221 * - passwd - stare hasło | |
| 222 * - newpasswd - nowe hasło | |
| 223 * - tokenid - identyfikator tokenu | |
| 224 * - tokenval - wartość tokenu | |
| 225 * - async - połączenie asynchroniczne | |
| 226 * | |
| 227 * zaalokowana struct gg_http, którą poźniej należy zwolnić | |
| 228 * funkcją gg_change_passwd_free(), albo NULL jeśli wystąpił błąd. | |
| 229 */ | |
| 230 struct gg_http *gg_change_passwd4(uin_t uin, const char *email, const char *passwd, const char *newpasswd, const char *tokenid, const char *tokenval, int async) | |
| 231 { | |
| 232 struct gg_http *h; | |
| 233 char *form, *query, *__email, *__fmpwd, *__pwd, *__tokenid, *__tokenval; | |
| 234 | |
| 235 if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) { | |
| 236 gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n"); | |
| 237 errno = EFAULT; | |
| 238 return NULL; | |
| 239 } | |
| 240 | |
| 241 __fmpwd = gg_urlencode(passwd); | |
| 242 __pwd = gg_urlencode(newpasswd); | |
| 243 __email = gg_urlencode(email); | |
| 244 __tokenid = gg_urlencode(tokenid); | |
| 245 __tokenval = gg_urlencode(tokenval); | |
| 246 | |
| 247 if (!__fmpwd || !__pwd || !__email || !__tokenid || !__tokenval) { | |
| 248 gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n"); | |
| 249 free(__fmpwd); | |
| 250 free(__pwd); | |
| 251 free(__email); | |
| 252 free(__tokenid); | |
| 253 free(__tokenval); | |
| 254 return NULL; | |
| 255 } | |
| 256 | |
| 257 if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, newpasswd)))) { | |
| 258 gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n"); | |
| 259 free(__fmpwd); | |
| 260 free(__pwd); | |
| 261 free(__email); | |
| 262 free(__tokenid); | |
| 263 free(__tokenval); | |
| 264 | |
| 265 return NULL; | |
| 266 } | |
| 267 | |
| 268 free(__fmpwd); | |
| 269 free(__pwd); | |
| 270 free(__email); | |
| 271 free(__tokenid); | |
| 272 free(__tokenval); | |
| 273 | |
| 274 gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form); | |
| 275 | |
| 276 query = gg_saprintf( | |
| 277 "Host: " GG_REGISTER_HOST "\r\n" | |
| 278 "Content-Type: application/x-www-form-urlencoded\r\n" | |
| 279 "User-Agent: " GG_HTTP_USERAGENT "\r\n" | |
| 280 "Content-Length: %d\r\n" | |
| 281 "Pragma: no-cache\r\n" | |
| 282 "\r\n" | |
| 283 "%s", | |
| 284 (int) strlen(form), form); | |
| 285 | |
| 286 free(form); | |
| 287 | |
| 288 if (!query) { | |
| 289 gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for query\n"); | |
| 290 return NULL; | |
| 291 } | |
| 292 | |
| 293 if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { | |
| 294 gg_debug(GG_DEBUG_MISC, "=> change, gg_http_connect() failed mysteriously\n"); | |
| 295 free(query); | |
| 296 return NULL; | |
| 297 } | |
| 298 | |
| 299 h->type = GG_SESSION_PASSWD; | |
| 300 | |
| 301 free(query); | |
| 302 | |
| 303 h->callback = gg_pubdir_watch_fd; | |
| 304 h->destroy = gg_pubdir_free; | |
| 305 | |
| 306 if (!async) | |
| 307 gg_pubdir_watch_fd(h); | |
| 308 | |
| 309 return h; | |
| 310 } | |
| 311 | |
| 312 /* | |
| 313 * gg_remind_passwd3() | |
| 314 * | |
| 315 * wysyła żądanie przypomnienia hasła e-mailem. | |
| 316 * | |
| 317 * - uin - numer | |
| 318 * - email - adres e-mail taki, jak ten zapisany na serwerze | |
| 319 * - async - połączenie asynchroniczne | |
| 320 * - tokenid - identyfikator tokenu | |
| 321 * - tokenval - wartość tokenu | |
| 322 * | |
| 323 * zaalokowana struct gg_http, którą poźniej należy zwolnić | |
| 324 * funkcją gg_remind_passwd_free(), albo NULL jeśli wystąpił błąd. | |
| 325 */ | |
| 326 struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async) | |
| 327 { | |
| 328 struct gg_http *h; | |
| 329 char *form, *query, *__tokenid, *__tokenval, *__email; | |
| 330 | |
| 331 if (!tokenid || !tokenval || !email) { | |
| 332 gg_debug(GG_DEBUG_MISC, "=> remind, NULL parameter\n"); | |
| 333 errno = EFAULT; | |
| 334 return NULL; | |
| 335 } | |
| 336 | |
| 337 __tokenid = gg_urlencode(tokenid); | |
| 338 __tokenval = gg_urlencode(tokenval); | |
| 339 __email = gg_urlencode(email); | |
| 340 | |
| 341 if (!__tokenid || !__tokenval || !__email) { | |
| 342 gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n"); | |
| 343 free(__tokenid); | |
| 344 free(__tokenval); | |
| 345 free(__email); | |
| 346 return NULL; | |
| 347 } | |
| 348 | |
| 349 if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s&email=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval, __email))) { | |
| 350 gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n"); | |
| 351 free(__tokenid); | |
| 352 free(__tokenval); | |
| 353 free(__email); | |
| 354 return NULL; | |
| 355 } | |
| 356 | |
| 357 free(__tokenid); | |
| 358 free(__tokenval); | |
| 359 free(__email); | |
| 360 | |
| 361 gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form); | |
| 362 | |
| 363 query = gg_saprintf( | |
| 364 "Host: " GG_REMIND_HOST "\r\n" | |
| 365 "Content-Type: application/x-www-form-urlencoded\r\n" | |
| 366 "User-Agent: " GG_HTTP_USERAGENT "\r\n" | |
| 367 "Content-Length: %d\r\n" | |
| 368 "Pragma: no-cache\r\n" | |
| 369 "\r\n" | |
| 370 "%s", | |
| 371 (int) strlen(form), form); | |
| 372 | |
| 373 free(form); | |
| 374 | |
| 375 if (!query) { | |
| 376 gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for query\n"); | |
| 377 return NULL; | |
| 378 } | |
| 379 | |
| 380 if (!(h = gg_http_connect(GG_REMIND_HOST, GG_REMIND_PORT, async, "POST", "/appsvc/fmsendpwd3.asp", query))) { | |
| 381 gg_debug(GG_DEBUG_MISC, "=> remind, gg_http_connect() failed mysteriously\n"); | |
| 382 free(query); | |
| 383 return NULL; | |
| 384 } | |
| 385 | |
| 386 h->type = GG_SESSION_REMIND; | |
| 387 | |
| 388 free(query); | |
| 389 | |
| 390 h->callback = gg_pubdir_watch_fd; | |
| 391 h->destroy = gg_pubdir_free; | |
| 392 | |
| 393 if (!async) | |
| 394 gg_pubdir_watch_fd(h); | |
| 395 | |
| 396 return h; | |
| 397 } | |
| 398 | |
| 399 /* | |
| 400 * gg_pubdir_watch_fd() | |
| 401 * | |
| 402 * przy asynchronicznych operacjach na katalogu publicznym należy wywoływać | |
| 403 * tę funkcję przy zmianach na obserwowanym deskryptorze. | |
| 404 * | |
| 405 * - h - struktura opisująca połączenie | |
| 406 * | |
| 407 * jeśli wszystko poszło dobrze to 0, inaczej -1. operacja będzie | |
| 408 * zakończona, jeśli h->state == GG_STATE_DONE. jeśli wystąpi jakiś | |
| 409 * błąd, to będzie tam GG_STATE_ERROR i odpowiedni kod błędu w h->error. | |
| 410 */ | |
| 411 int gg_pubdir_watch_fd(struct gg_http *h) | |
| 412 { | |
| 413 struct gg_pubdir *p; | |
| 414 char *tmp; | |
| 415 | |
| 416 if (!h) { | |
| 417 errno = EFAULT; | |
| 418 return -1; | |
| 419 } | |
| 420 | |
| 421 if (h->state == GG_STATE_ERROR) { | |
| 422 gg_debug(GG_DEBUG_MISC, "=> pubdir, watch_fd issued on failed session\n"); | |
| 423 errno = EINVAL; | |
| 424 return -1; | |
| 425 } | |
| 426 | |
| 427 if (h->state != GG_STATE_PARSING) { | |
| 428 if (gg_http_watch_fd(h) == -1) { | |
| 429 gg_debug(GG_DEBUG_MISC, "=> pubdir, http failure\n"); | |
| 430 errno = EINVAL; | |
| 431 return -1; | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 if (h->state != GG_STATE_PARSING) | |
| 436 return 0; | |
| 437 | |
| 438 h->state = GG_STATE_DONE; | |
| 439 | |
| 440 if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) { | |
| 441 gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n"); | |
| 442 return -1; | |
| 443 } | |
| 444 | |
| 445 p->success = 0; | |
| 446 p->uin = 0; | |
| 447 | |
| 448 gg_debug(GG_DEBUG_MISC, "=> pubdir, let's parse \"%s\"\n", h->body); | |
| 449 | |
| 450 if ((tmp = strstr(h->body, "success")) || (tmp = strstr(h->body, "results"))) { | |
| 451 p->success = 1; | |
| 452 if (tmp[7] == ':') | |
| 453 p->uin = strtol(tmp + 8, NULL, 0); | |
| 454 gg_debug(GG_DEBUG_MISC, "=> pubdir, success (uin=%d)\n", p->uin); | |
| 455 } else | |
| 456 gg_debug(GG_DEBUG_MISC, "=> pubdir, error.\n"); | |
| 457 | |
| 458 return 0; | |
| 459 } | |
| 460 | |
| 461 /* | |
| 462 * gg_pubdir_free() | |
| 463 * | |
| 464 * zwalnia pamięć po efektach operacji na katalogu publicznym. | |
| 465 * | |
| 466 * - h - zwalniana struktura | |
| 467 */ | |
| 468 void gg_pubdir_free(struct gg_http *h) | |
| 469 { | |
| 470 if (!h) | |
| 471 return; | |
| 472 | |
| 473 free(h->data); | |
| 474 gg_http_free(h); | |
| 475 } | |
| 476 | |
| 477 /* | |
| 478 * gg_token() | |
| 479 * | |
| 480 * pobiera z serwera token do autoryzacji zakładania konta, usuwania | |
| 481 * konta i zmiany hasła. | |
| 482 * | |
| 483 * zaalokowana struct gg_http, którą poźniej należy zwolnić | |
| 484 * funkcją gg_token_free(), albo NULL jeśli wystąpił błąd. | |
| 485 */ | |
| 486 struct gg_http *gg_token(int async) | |
| 487 { | |
| 488 struct gg_http *h; | |
| 489 const char *query; | |
| 490 | |
| 491 query = "Host: " GG_REGISTER_HOST "\r\n" | |
| 492 "Content-Type: application/x-www-form-urlencoded\r\n" | |
| 493 "User-Agent: " GG_HTTP_USERAGENT "\r\n" | |
| 494 "Content-Length: 0\r\n" | |
| 495 "Pragma: no-cache\r\n" | |
| 496 "\r\n"; | |
| 497 | |
| 498 if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) { | |
| 499 gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); | |
| 500 return NULL; | |
| 501 } | |
| 502 | |
| 503 h->type = GG_SESSION_TOKEN; | |
| 504 | |
| 505 h->callback = gg_token_watch_fd; | |
| 506 h->destroy = gg_token_free; | |
| 507 | |
| 508 if (!async) | |
| 509 gg_token_watch_fd(h); | |
| 510 | |
| 511 return h; | |
| 512 } | |
| 513 | |
| 514 /* | |
| 515 * gg_token_watch_fd() | |
| 516 * | |
| 517 * przy asynchronicznych operacjach związanych z tokenem należy wywoływać | |
| 518 * tę funkcję przy zmianach na obserwowanym deskryptorze. | |
| 519 * | |
| 520 * - h - struktura opisująca połączenie | |
| 521 * | |
| 522 * jeśli wszystko poszło dobrze to 0, inaczej -1. operacja będzie | |
| 523 * zakończona, jeśli h->state == GG_STATE_DONE. jeśli wystąpi jakiś | |
| 524 * błąd, to będzie tam GG_STATE_ERROR i odpowiedni kod błędu w h->error. | |
| 525 */ | |
| 526 int gg_token_watch_fd(struct gg_http *h) | |
| 527 { | |
| 528 if (!h) { | |
| 529 errno = EFAULT; | |
| 530 return -1; | |
| 531 } | |
| 532 | |
| 533 if (h->state == GG_STATE_ERROR) { | |
| 534 gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n"); | |
| 535 errno = EINVAL; | |
| 536 return -1; | |
| 537 } | |
| 538 | |
| 539 if (h->state != GG_STATE_PARSING) { | |
| 540 if (gg_http_watch_fd(h) == -1) { | |
| 541 gg_debug(GG_DEBUG_MISC, "=> token, http failure\n"); | |
| 542 errno = EINVAL; | |
| 543 return -1; | |
| 544 } | |
| 545 } | |
| 546 | |
| 547 if (h->state != GG_STATE_PARSING) | |
| 548 return 0; | |
| 549 | |
| 550 /* jeśli h->data jest puste, to ściągaliśmy tokenid i url do niego, | |
| 551 * ale jeśli coś tam jest, to znaczy, że mamy drugi etap polegający | |
| 552 * na pobieraniu tokenu. */ | |
| 553 if (!h->data) { | |
| 554 int width, height, length; | |
| 555 char *url = NULL, *tokenid = NULL, *path, *headers; | |
| 556 const char *host; | |
| 557 struct gg_http *h2; | |
| 558 struct gg_token *t; | |
| 559 | |
| 560 gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body); | |
| 561 | |
| 562 if (h->body && (!(url = malloc(strlen(h->body))) || !(tokenid = malloc(strlen(h->body))))) { | |
| 563 gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n"); | |
| 564 free(url); | |
| 565 return -1; | |
| 566 } | |
| 567 | |
| 568 if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) { | |
| 569 gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n"); | |
| 570 free(url); | |
| 571 free(tokenid); | |
| 572 errno = EINVAL; | |
| 573 return -1; | |
| 574 } | |
| 575 | |
| 576 /* dostaliśmy tokenid i wszystkie niezbędne informacje, | |
| 577 * więc pobierzmy obrazek z tokenem */ | |
| 578 | |
| 579 if (strncmp(url, "http://", 7)) { | |
| 580 path = gg_saprintf("%s?tokenid=%s", url, tokenid); | |
| 581 host = GG_REGISTER_HOST; | |
| 582 } else { | |
| 583 char *slash = strchr(url + 7, '/'); | |
| 584 | |
| 585 if (slash) { | |
| 586 path = gg_saprintf("%s?tokenid=%s", slash, tokenid); | |
| 587 *slash = 0; | |
| 588 host = url + 7; | |
| 589 } else { | |
| 590 gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n"); | |
| 591 free(url); | |
| 592 free(tokenid); | |
| 593 errno = EINVAL; | |
| 594 return -1; | |
| 595 } | |
| 596 } | |
| 597 | |
| 598 if (!path) { | |
| 599 gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n"); | |
| 600 free(url); | |
| 601 free(tokenid); | |
| 602 return -1; | |
| 603 } | |
| 604 | |
| 605 if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) { | |
| 606 gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n"); | |
| 607 free(path); | |
| 608 free(url); | |
| 609 free(tokenid); | |
| 610 return -1; | |
| 611 } | |
| 612 | |
| 613 if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) { | |
| 614 gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); | |
| 615 free(headers); | |
| 616 free(url); | |
| 617 free(path); | |
| 618 free(tokenid); | |
| 619 return -1; | |
| 620 } | |
| 621 | |
| 622 free(headers); | |
| 623 free(path); | |
| 624 free(url); | |
| 625 | |
| 626 memcpy(h, h2, sizeof(struct gg_http)); | |
| 627 free(h2); | |
| 628 | |
| 629 h->type = GG_SESSION_TOKEN; | |
| 630 | |
| 631 h->callback = gg_token_watch_fd; | |
| 632 h->destroy = gg_token_free; | |
| 633 | |
| 634 if (!h->async) | |
| 635 gg_token_watch_fd(h); | |
| 636 | |
| 637 if (!(h->data = t = malloc(sizeof(struct gg_token)))) { | |
| 638 gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n"); | |
| 639 free(tokenid); | |
| 640 return -1; | |
| 641 } | |
| 642 | |
| 643 t->width = width; | |
| 644 t->height = height; | |
| 645 t->length = length; | |
| 646 t->tokenid = tokenid; | |
| 647 } else { | |
| 648 /* obrazek mamy w h->body */ | |
| 649 h->state = GG_STATE_DONE; | |
| 650 } | |
| 651 | |
| 652 return 0; | |
| 653 } | |
| 654 | |
| 655 /* | |
| 656 * gg_token_free() | |
| 657 * | |
| 658 * zwalnia pamięć po efektach pobierania tokenu. | |
| 659 * | |
| 660 * - h - zwalniana struktura | |
| 661 */ | |
| 662 void gg_token_free(struct gg_http *h) | |
| 663 { | |
| 664 struct gg_token *t; | |
| 665 | |
| 666 if (!h) | |
| 667 return; | |
| 668 | |
| 669 if ((t = h->data)) | |
| 670 free(t->tokenid); | |
| 671 | |
| 672 free(h->data); | |
| 673 gg_http_free(h); | |
| 674 } | |
| 675 | |
| 676 /* | |
| 677 * Local variables: | |
| 678 * c-indentation-style: k&r | |
| 679 * c-basic-offset: 8 | |
| 680 * indent-tabs-mode: notnil | |
| 681 * End: | |
| 682 * | |
| 683 * vim: shiftwidth=8: | |
| 684 */ |
