recv.c (21834B)
1 /* 2 * Copy me if you can. 3 * by 20h 4 */ 5 6 #include <u.h> 7 #include <libc.h> 8 #include "xmlpull.h" 9 #include "jacc.h" 10 #include "dat.h" 11 #include "roster.h" 12 13 int doignore; 14 15 int 16 recvjacc(int sock, jabberc *me, char *pass) 17 { 18 xmlpull *x, *b; 19 char *id, *to, *from, *tmstmp, st, *type, *va, *xm; 20 rostern *ac, *p; 21 22 type = nil; 23 id = nil; 24 from = nil; 25 to = nil; 26 xm = nil; 27 va = nil; 28 st = NONE; 29 ac = me->rost; 30 31 if(xmljacc(sock) < 0) 32 return -1; 33 if(loginjacc(sock, me->serv) < 0) 34 return -1; 35 36 x = openxmlpull(sock); 37 while((b = nextxmlpull(x)) != nil && st != END){ 38 tmstmp = mktmstmp('(', ')'); 39 if(x->na != nil) 40 x->na = filterzur(x->na); 41 if(x->va != nil) 42 x->va = filterzur(x->va); 43 switch(b->ev){ 44 case START_DOCUMENT: 45 if(me->debug) 46 print("Start.\n"); 47 st = NONE; 48 break; 49 case START_TAG: 50 if(me->debug) 51 print("Tag: %s\n", x->na); 52 if(!strcmp(x->na, "stream:stream")){ 53 st = STREAM; 54 break; 55 } 56 if(!strcmp(x->na, "stream:error")){ 57 st = ERROR; 58 break; 59 } 60 if(st == ERROR){ 61 if(strcmp(x->na, "text")) 62 fprint(2, "%serror: %s\n", tmstmp, x->na); 63 break; 64 } 65 if(!strcmp(x->na, "message")){ 66 st = MESSAGE; 67 break; 68 } 69 if(!strcmp(x->na, "presence")){ 70 id = nil; 71 st = PRESENCE; 72 break; 73 } 74 if(!strcmp(x->na, "iq")){ 75 st = IQ; 76 break; 77 } 78 if(!strcmp(x->na, "vCard") && st == IQ){ 79 st = IQ_VCARD; 80 break; 81 } 82 if(!strcmp(x->na, "error") && st == IQ){ 83 st = IQ_ERROR; 84 break; 85 } 86 if(!strcmp(x->na, "body") && st == MESSAGE){ 87 st = MESSAGE_INNER; 88 break; 89 } 90 if(!strcmp(x->na, "html") && st == MESSAGE){ 91 st = MESSAGE_HTML; 92 break; 93 } 94 if(!strcmp(x->na, "status") && (st == PRESENCE || st == PRESENCE_SET)){ 95 st = PRESENCE_STATUS; 96 break; 97 } 98 if(!strcmp(x->na, "show") && (st == PRESENCE || st == PRESENCE_SET)){ 99 st = PRESENCE_SHOW; 100 break; 101 } 102 if(!strcmp(x->na, "error") && (st == PRESENCE || st == PRESENCE_SET)){ 103 st = PRESENCE_ERROR; 104 break; 105 } 106 if(!strcmp(x->na, "x") && st == PRESENCE){ 107 st = PRESENCE_X; 108 break; 109 } 110 if(!strcmp(x->na, "item") && st == ROSTER){ 111 if(me->rost == nil){ 112 me->rost = mkrostern(); 113 ac = mkrostern(); 114 me->rost->n = ac; 115 me->rost->p = nil; 116 me->rost->name = strdup(me->name); 117 me->rost->jid = strdup(me->jid); 118 me->rost->status = strdup(me->stat); 119 me->rost->show = strdup(me->show); 120 me->rost->subsc = strdup("self"); 121 me->rost->group = strdup("self"); 122 } else { 123 ac->n = mkrostern(); 124 ac->n->p = ac; 125 ac = ac->n; 126 ac->n = nil; 127 } 128 129 st = ROSTER_INNER; 130 break; 131 } 132 if(!strcmp(x->na, "query") && st == IQ){ 133 st = IQ_INNER; 134 break; 135 } 136 if(!strcmp(x->na, "item") && st == IQ_INNER){ 137 st = IQ_ITEM; 138 ac = mkrostern(); 139 break; 140 } 141 if(!strcmp(x->na, "group") && st == IQ_ITEM){ 142 st = IQ_GROUP; 143 break; 144 } 145 if(!strcmp(x->na, "group") && st == ROSTER_INNER){ 146 st = ROSTER_GROUP; 147 break; 148 } 149 if(!strcmp(x->na, "utc") && st == IQ_TIME){ 150 st = IQ_TIME_UTC; 151 break; 152 } 153 if(!strcmp(x->na, "tz") && st == IQ_TIME){ 154 st = IQ_TIME_TZ; 155 break; 156 } 157 if(!strcmp(x->na, "display") && st == IQ_TIME){ 158 st = IQ_TIME_DISPLAY; 159 break; 160 } 161 if(!strcmp(x->na, "item") && st == IQ_DISCO){ 162 st = IQ_DISCO_ITEM; 163 break; 164 } 165 if(!strcmp(x->na, "identity") && st == IQ_DISCO){ 166 print("%sserver identity:\n", tmstmp); 167 st = IQ_DISCO_IDENT; 168 break; 169 } 170 if(!strcmp(x->na, "feature") && st == IQ_DISCO){ 171 st = IQ_DISCO_FEATU; 172 break; 173 } 174 if(!strcmp(x->na, "empty") && st == IQ_DISCO){ 175 st = IQ_DISCO_EMPTY; 176 break; 177 } 178 if(!strcmp(x->na, "version") && st == IQ_VERSION){ 179 st = IQ_VERSION_VER; 180 break; 181 } 182 if(!strcmp(x->na, "os") && st == IQ_VERSION){ 183 st = IQ_VERSION_OS; 184 break; 185 } 186 if(!strcmp(x->na, "name") && st == IQ_VERSION){ 187 st = IQ_VERSION_NAME; 188 break; 189 } 190 if(!strcmp(x->na, "agent") && st == IQ_AGENTS){ 191 st = IQ_AGENTS_AGENT; 192 break; 193 } 194 if(!strcmp(x->na, "name") && st == IQ_AGENTS_AGENT){ 195 st = IQ_AGENTS_NAME; 196 break; 197 } 198 if(!strcmp(x->na, "description") && st == IQ_AGENTS_AGENT){ 199 st = IQ_AGENTS_DESC; 200 break; 201 } 202 if(!strcmp(x->na, "transport") && st == IQ_AGENTS_AGENT){ 203 print("%s This is a transport.\n", tmstmp); 204 break; 205 } 206 if(!strcmp(x->na, "groupchat") && st == IQ_AGENTS_AGENT){ 207 print("%s You can groupchat here.\n", tmstmp); 208 break; 209 } 210 if(!strcmp(x->na, "service") && st == IQ_AGENTS_AGENT){ 211 st = IQ_AGENTS_SERV; 212 break; 213 } 214 if(!strcmp(x->na, "register") && st == IQ_AGENTS_AGENT){ 215 print("%s You can register here.\n", tmstmp); 216 break; 217 } 218 if(!strcmp(x->na, "search") && st == IQ_AGENTS_AGENT){ 219 print("%s You can search here.\n", tmstmp); 220 break; 221 } 222 if(st == IQ_VCARD){ 223 if(!strcmp(x->na, "FN")) 224 goto is_vcard_inner; 225 if(!strcmp(x->na, "GIVEN")) 226 goto is_vcard_inner; 227 if(!strcmp(x->na, "FAMILY")) 228 goto is_vcard_inner; 229 if(!strcmp(x->na, "MIDDLE")) 230 goto is_vcard_inner; 231 if(!strcmp(x->na, "PREFIX")) 232 goto is_vcard_inner; 233 if(!strcmp(x->na, "SUFFIX")) 234 goto is_vcard_inner; 235 if(!strcmp(x->na, "VERSION")) 236 goto is_vcard_inner; 237 if(!strcmp(x->na, "NICKNAME")) 238 goto is_vcard_inner; 239 if(!strcmp(x->na, "PHOTO")) 240 goto is_vcard_inner; 241 if(!strcmp(x->na, "BDAY")) 242 goto is_vcard_inner; 243 if(!strcmp(x->na, "POBOX")) 244 goto is_vcard_inner; 245 if(!strcmp(x->na, "EXTADR")) 246 goto is_vcard_inner; 247 if(!strcmp(x->na, "STREET")) 248 goto is_vcard_inner; 249 if(!strcmp(x->na, "LOCALITY")) 250 goto is_vcard_inner; 251 if(!strcmp(x->na, "REGION")) 252 goto is_vcard_inner; 253 if(!strcmp(x->na, "PCODE")) 254 goto is_vcard_inner; 255 if(!strcmp(x->na, "CTRY")) 256 goto is_vcard_inner; 257 if(!strcmp(x->na, "NUMBER")) 258 goto is_vcard_inner; 259 if(!strcmp(x->na, "USERID")) 260 goto is_vcard_inner; 261 if(!strcmp(x->na, "JABBERID")) 262 goto is_vcard_inner; 263 if(!strcmp(x->na, "MAILER")) 264 goto is_vcard_inner; 265 if(!strcmp(x->na, "LAT")) 266 goto is_vcard_inner; 267 if(!strcmp(x->na, "LON")) 268 goto is_vcard_inner; 269 if(!strcmp(x->na, "TITLE")) 270 goto is_vcard_inner; 271 if(!strcmp(x->na, "ROLE")) 272 goto is_vcard_inner; 273 if(!strcmp(x->na, "AGENT")) 274 goto is_vcard_inner; 275 if(!strcmp(x->na, "ORGNAME")) 276 goto is_vcard_inner; 277 if(!strcmp(x->na, "ORGUNIT")) 278 goto is_vcard_inner; 279 if(!strcmp(x->na, "NOTE")) 280 goto is_vcard_inner; 281 if(!strcmp(x->na, "PRODID")) 282 goto is_vcard_inner; 283 if(!strcmp(x->na, "REV")) 284 goto is_vcard_inner; 285 if(!strcmp(x->na, "PHONETIC")) 286 goto is_vcard_inner; 287 if(!strcmp(x->na, "DESC")) 288 goto is_vcard_inner; 289 if(!strcmp(x->na, "CRED")) 290 goto is_vcard_inner; 291 if(!strcmp(x->na, "HOME")) 292 goto is_vcard_end; 293 if(!strcmp(x->na, "WORK")) 294 goto is_vcard_end; 295 if(!strcmp(x->na, "POSTAL")) 296 goto is_vcard_end; 297 if(!strcmp(x->na, "PARCEL")) 298 goto is_vcard_end; 299 if(!strcmp(x->na, "DOM")) 300 goto is_vcard_end; 301 if(!strcmp(x->na, "INTL")) 302 goto is_vcard_end; 303 if(!strcmp(x->na, "PREF")) 304 goto is_vcard_end; 305 if(!strcmp(x->na, "VOICE")) 306 goto is_vcard_end; 307 if(!strcmp(x->na, "FAX")) 308 goto is_vcard_end; 309 if(!strcmp(x->na, "PAGER")) 310 goto is_vcard_end; 311 if(!strcmp(x->na, "MSG")) 312 goto is_vcard_end; 313 if(!strcmp(x->na, "CELL")) 314 goto is_vcard_end; 315 if(!strcmp(x->na, "VIDEO")) 316 goto is_vcard_end; 317 if(!strcmp(x->na, "BBS")) 318 goto is_vcard_end; 319 if(!strcmp(x->na, "MODEM")) 320 goto is_vcard_end; 321 if(!strcmp(x->na, "ISDN")) 322 goto is_vcard_end; 323 if(!strcmp(x->na, "PCS")) 324 goto is_vcard_end; 325 if(!strcmp(x->na, "INTERNET")) 326 goto is_vcard_end; 327 if(!strcmp(x->na, "X400")) 328 goto is_vcard_end; 329 break; 330 is_vcard_end: 331 print("%s%s\n", tmstmp, x->na); 332 break; 333 is_vcard_inner: 334 print("%s%s = ", tmstmp, x->na); 335 st = IQ_VCARD_INNER; 336 break; 337 } 338 break; 339 case START_END_TAG: 340 if(me->debug) 341 print("Startend: %s\n", x->na); 342 if(!strcmp(x->na, "empty") && st == IQ_DISCO){ 343 print("%s <empty>\n", tmstmp); 344 break; 345 } 346 if(!strcmp(x->na, "transport") && st == IQ_AGENTS_AGENT){ 347 print("%s This is a transport.\n", tmstmp); 348 break; 349 } 350 if(!strcmp(x->na, "groupchat") && st == IQ_AGENTS_AGENT){ 351 print("%s You can groupchat here.\n", tmstmp); 352 break; 353 } 354 if(!strcmp(x->na, "register") && st == IQ_AGENTS_AGENT){ 355 print("%s You can register here.\n", tmstmp); 356 break; 357 } 358 if(!strcmp(x->na, "search") && st == IQ_AGENTS_AGENT){ 359 print("%s You can search here.\n", tmstmp); 360 break; 361 } 362 if(st == ERROR || st == PRESENCE_ERROR || st == IQ_ERROR){ 363 fprint(2, "%serror: %s\n", tmstmp, x->na); 364 break; 365 } 366 break; 367 case TEXT: 368 if(me->debug) 369 print("Text: %s\n", x->na); 370 switch(st){ 371 case MESSAGE_INNER: 372 type = strdup(x->na); 373 break; 374 case PRESENCE_SHOW: 375 if(type == nil || (type != nil && strcmp(type, "error"))) 376 if(statusrostern(me->rost, from, from, nil, x->na) != nil) 377 print("%s%s> %s\n", tmstmp, namerostern(me->rost, from, nil), x->na); 378 break; 379 case PRESENCE_STATUS: 380 if(type == nil || (type != nil && strcmp(type, "error"))) 381 if(statusrostern(me->rost, from, from, x->na, nil) != nil) 382 print("%s%s> %s\n", tmstmp, namerostern(me->rost, from, nil), x->na); 383 break; 384 case PRESENCE_ERROR: 385 print("%s%s# %s\n", tmstmp, namerostern(me->rost, from, nil), x->na); 386 free(type); 387 type = strdup("isdone"); 388 break; 389 case ROSTER_GROUP: 390 if(ac->group == nil) 391 ac->group = strdup(x->na); 392 break; 393 case IQ_GROUP: 394 if(ac->group == nil) 395 ac->group = strdup(x->na); 396 break; 397 case IQ_ERROR: 398 print("%sIQ-Error: %s\n", tmstmp, x->na); 399 break; 400 case IQ_VCARD_INNER: 401 print("%s\n", x->na); 402 break; 403 case IQ_VERSION_OS: 404 print("%s os = %s\n", tmstmp, x->na); 405 break; 406 case IQ_VERSION_NAME: 407 print("%s name = %s\n", tmstmp, x->na); 408 break; 409 case IQ_VERSION_VER: 410 print("%s version = %s\n", tmstmp, x->na); 411 break; 412 case IQ_TIME_UTC: 413 print("%sutc = %s\n", tmstmp, x->na); 414 break; 415 case IQ_TIME_TZ: 416 print("%stz = %s\n", tmstmp, x->na); 417 break; 418 case IQ_TIME_DISPLAY: 419 print("%sdisplay = %s\n", tmstmp, x->na); 420 break; 421 case IQ_AGENTS_NAME: 422 print("%s name = %s\n", tmstmp, x->na); 423 break; 424 case IQ_AGENTS_DESC: 425 print("%s description = %s\n", tmstmp, x->na); 426 break; 427 case IQ_AGENTS_SERV: 428 print("%s service = %s\n", tmstmp, x->na); 429 break; 430 default: 431 break; 432 } 433 break; 434 case ATTR: 435 if(me->debug) 436 print("Attr: %s = %s\n", x->na, x->va); 437 switch(st){ 438 case STREAM: 439 if(!strcmp(x->na, "id")){ 440 st = NONE; 441 if(me->reg){ 442 registerjacc(sock, me->serv, me->name, pass); 443 break; 444 } 445 if(userjacc(sock, me->name, pass, me->reso) < 0) { 446 memset(pass, 0, strlen(pass)); 447 st = AUTH; 448 break; 449 } 450 } 451 break; 452 case MESSAGE: 453 if(!strcmp(x->na, "from")) 454 from = strdup(x->va); 455 if(!strcmp(x->na, "to")) 456 to = strdup(x->va); 457 if(!strcmp(x->na, "type")) 458 type = strdup(x->va); 459 break; 460 case PRESENCE: 461 if(!strcmp(x->na, "from")) 462 from = strdup(x->va); 463 if(!strcmp(x->na, "type")) 464 type = strdup(x->va); 465 break; 466 case IQ: 467 if(!strcmp(x->na, "id")){ 468 if(!strcmp(x->va, "auth_1")) 469 rosterjacc(sock); 470 if(!strcmp(x->va, "auth_2")) 471 st = ROSTER; 472 if(!strcmp(x->va, "disco0")) 473 st = IQ_DISCO; 474 if(!strcmp(x->va, "time0")) 475 st = IQ_TIME; 476 if(!strcmp(x->va, "agents0")) 477 st = IQ_AGENTS; 478 if(!strcmp(x->va, "last0")) 479 st = IQ_LAST; 480 if(!strcmp(x->va, "version0")) 481 st = IQ_VERSION; 482 id = strdup(x->va); 483 } 484 if(!strcmp(x->na, "from")) 485 from = strdup(x->va); 486 if(!strcmp(x->na, "to")) 487 to = strdup(x->va); 488 if(!strcmp(x->na, "type")) 489 type = strdup(x->va); 490 break; 491 case ROSTER_INNER: 492 if(!strcmp(x->na, "name")){ 493 ac->name = strdup(x->va); 494 break; 495 } 496 if(!strcmp(x->na, "jid")){ 497 ac->jid = strdup(x->va); 498 break; 499 } 500 break; 501 case IQ_INNER: 502 if(!strcmp(x->na, "xmlns")){ 503 if(xm != nil) 504 free(xm); 505 xm = strdup(x->va); 506 } 507 if(!strcmp(x->na, "name")){ 508 if(va != nil) 509 free(va); 510 va = strdup(x->va); 511 } 512 break; 513 case IQ_ITEM: 514 if(!strcmp(x->na, "subscription")){ 515 ac->subsc = strdup(x->va); 516 break; 517 } 518 if(!strcmp(x->na, "jid")){ 519 ac->jid = strdup(x->va); 520 break; 521 } 522 if(!strcmp(x->na, "name")){ 523 ac->name = strdup(x->va); 524 break; 525 } 526 break; 527 case IQ_DISCO_IDENT: 528 print("%s%s = %s\n", tmstmp, x->na, x->va); 529 break; 530 case IQ_DISCO_FEATU: 531 print("%s %s\n", tmstmp, x->va); 532 break; 533 case IQ_DISCO_ITEM: 534 if(!strcmp(x->na, "name")){ 535 if(id != nil) 536 free(id); 537 id = strdup(x->va); 538 } 539 if(!strcmp(x->na, "jid")){ 540 if(to != nil) 541 free(to); 542 to = strdup(x->va); 543 } 544 break; 545 case IQ_AGENTS_AGENT: 546 if(!strcmp(x->na, "jid")) 547 print("%s%s:\n", tmstmp, x->va); 548 break; 549 case IQ_LAST: 550 if(!strcmp(x->na, "seconds")) 551 print("%s%s> %ss away\n", tmstmp, namerostern(me->rost, nil, from), x->va); 552 break; 553 default: 554 break; 555 } 556 break; 557 case END_TAG: 558 if(me->debug) 559 print("Endtag: %s\n", x->na); 560 if(!strcmp(x->na, "stream:stream")){ 561 st = END; 562 break; 563 } 564 if(!strcmp(x->na, "stream:error") && st == ERROR){ 565 st = NONE; 566 break; 567 } 568 if(st == ERROR) 569 break; 570 if(!strcmp(x->na, "message") && st == MESSAGE){ 571 if(type != nil) { 572 print("%s(%s-%s)%% %s\n", tmstmp, 573 (from != nil) ? namerostern(me->rost, from, nil) : "<nil>", 574 (to != nil) ? namerostern(me->rost, to, nil) : "<nil>", 575 type); 576 playmp3("jacc_gotmessage.mp3"); 577 } 578 if(from != nil) 579 free(from); 580 if(to != nil) 581 free(to); 582 if(type != nil) 583 free(type); 584 from = nil; 585 to = nil; 586 type = nil; 587 st = NONE; 588 break; 589 } 590 if(!strcmp(x->na, "presence") && st == PRESENCE_SET){ 591 if(type != nil) 592 free(type); 593 if(from != nil) 594 free(from); 595 type = nil; 596 from = nil; 597 st = NONE; 598 break; 599 } 600 if(!strcmp(x->na, "presence") && st == PRESENCE){ 601 if(type != nil && from != nil){ 602 if(!strcmp(type, "unavailable") || !strcmp(type, "error")){ 603 if(statusrostern(me->rost, from, from, nil, "Offline") != nil) 604 print("%s%s> Offline\n", tmstmp, namerostern(me->rost, from, nil)); 605 goto presence_strcmp; 606 } 607 if(!strcmp(type, "probe")){ 608 presencejacc(sock, me->stat, me->show, me->jid, from); 609 goto presence_strcmp; 610 } 611 if(!strcmp(type, "subscribe")){ 612 statusrostern(me->rost, from, from, nil, "Online"); 613 print("%s%s wants to subscribe\n", tmstmp, namerostern(me->rost, from, nil)); 614 goto presence_strcmp; 615 } 616 if(!strcmp(type, "unsubscribe")){ 617 if(statusrostern(me->rost, from, from, nil, "Offline") != nil) 618 print("%s%s wants to unsubscribe\n", tmstmp, namerostern(me->rost, from, nil)); 619 goto presence_strcmp; 620 } 621 if(!strcmp(type, "subscribed")){ 622 print("%s%s has accepted the subscription request\n", tmstmp, namerostern(me->rost, from, nil)); 623 goto presence_strcmp; 624 } 625 if(!strcmp(type, "isdone")) 626 goto presence_strcmp; 627 } 628 if(from != nil) { 629 statusrostern(me->rost, from, from, nil, "Online"); 630 print("%s%s> Online\n", tmstmp, namerostern(me->rost, from, nil)); 631 } 632 presence_strcmp: 633 if(type != nil) 634 free(type); 635 if(from != nil) 636 free(from); 637 type = nil; 638 from = nil; 639 640 st = NONE; 641 break; 642 } 643 if(!strcmp(x->na, "iq") && (st == IQ || st == IQ_DISCO)){ 644 if(from != nil) 645 free(from); 646 if(to != nil) 647 free(to); 648 if(type != nil) 649 free(type); 650 if(id != nil) 651 free(id); 652 if(va != nil) 653 free(va); 654 if(xm != nil) 655 free(xm); 656 from = nil; 657 to = nil; 658 id = nil; 659 type = nil; 660 va = nil; 661 xm = nil; 662 st = NONE; 663 break; 664 } 665 if(!strcmp(x->na, "iq") && st == ROSTER){ 666 if(from != nil) 667 free(from); 668 if(to != nil) 669 free(to); 670 if(type != nil) 671 free(type); 672 if(id != nil) 673 free(id); 674 from = nil; 675 to = nil; 676 id = nil; 677 type = nil; 678 presencejacc(sock, me->stat, me->show, nil, nil); 679 st = NONE; 680 break; 681 } 682 if(!strcmp(x->na, "vCard") && st == IQ_VCARD){ 683 st = IQ; 684 break; 685 } 686 if(!strcmp(x->na, "error") && st == IQ_ERROR){ 687 st = IQ; 688 break; 689 } 690 if(!strcmp(x->na, "body") && st == MESSAGE_INNER){ 691 st = MESSAGE; 692 break; 693 } 694 if(!strcmp(x->na, "html") && st == MESSAGE_HTML){ 695 st = MESSAGE; 696 break; 697 } 698 if(!strcmp(x->na, "status") && st == PRESENCE_STATUS){ 699 st = PRESENCE_SET; 700 break; 701 } 702 if(!strcmp(x->na, "show") && st == PRESENCE_SHOW){ 703 st = PRESENCE_SET; 704 break; 705 } 706 if(!strcmp(x->na, "x") && st == PRESENCE_X){ 707 st = PRESENCE; 708 break; 709 } 710 if(!strcmp(x->na, "error") && st == PRESENCE_ERROR){ 711 st = PRESENCE; 712 break; 713 } 714 if(!strcmp(x->na, "item") && st == ROSTER_INNER){ 715 if(!doignore) 716 print("%sAdded user: %s/%s/%s\n", tmstmp, ac->name, ac->jid, ac->group); 717 st = ROSTER; 718 break; 719 } 720 if(!strcmp(x->na, "query") && (st == IQ_INNER || st == IQ_VERSION || st == IQ_TIME || st == IQ_LAST || st == IQ_AGENTS)){ 721 if(st == IQ_INNER && xm != nil){ 722 if(!strcmp(xm, "jabber:iq:version")){ 723 if(strcmp(to, me->jid)) 724 break; 725 else 726 versionjacc(sock, me->jid, from, id); 727 break; 728 } 729 if(!strcmp(xm, "jabber:iq:last")) 730 if(!strcmp(me->jid, to)) 731 lastjacc(sock, to, from, id, time(0) - me->last); 732 if(!strcmp(xm, "http://jabber.org/protocol/disco#info")) 733 if(!strcmp(me->jid, to)) 734 if(id != nil && strcmp(id, "http://jabber.org/protocol/muc#rooms")) 735 featuresjacc(sock, to, from, id); 736 if(!strcmp(xm, "jabber:iq:time")) 737 if(!strcmp(me->jid, to)) 738 timejacc(sock, to, from, id); 739 } 740 st = IQ; 741 break; 742 } 743 if(!strcmp(x->na, "item") && st == IQ_ITEM){ 744 st = IQ_INNER; 745 if(ac != nil && ac->subsc != nil){ 746 if(!strcmp(ac->subsc, "remove")){ 747 me->rost = delname(me->rost, ac->name, ac->jid); 748 print("%sremoved: %s\n", tmstmp, ac->jid); 749 freerostern(ac); 750 break; 751 } 752 if(!strcmp(ac->subsc, "both") || !strcmp(ac->subsc, "to") || 753 !strcmp(ac->subsc, "from") || !strcmp(ac->subsc, "none") || 754 !strcmp(ac->subsc, "ask")){ 755 if(!strcmp(ac->subsc, "ask")) 756 print("%s%s asks for authorisation.\n", tmstmp, ac->jid); 757 if((p = searchrostern(me->rost, ac->name, ac->jid)) == nil){ 758 ac->subsc = strdup(ac->subsc); 759 addrostern(me->rost, ac); 760 if(strcmp(ac->subsc, "ask")) 761 print("%sadded: %s\n", tmstmp, ac->jid); 762 } else { 763 if(p->jid != nil) 764 free(p->jid); 765 if(ac->jid != nil) 766 p->jid = strdup(ac->jid); 767 else 768 p->jid = nil; 769 770 if(p->name != nil) 771 free(p->name); 772 if(ac->name != nil) 773 p->name = strdup(ac->name); 774 else 775 p->name = nil; 776 777 if(p->subsc != nil) 778 free(p->subsc); 779 if(ac->subsc != nil) 780 p->subsc = strdup(ac->subsc); 781 else 782 p->subsc = nil; 783 784 print("%supdate: %s/%s\n", tmstmp, (ac->name == nil) ? "<nil>" : ac->name 785 , (ac->jid == nil) ? "<nil>" : ac->jid); 786 freerostern(ac); 787 } 788 } 789 } 790 ac = nil; 791 break; 792 } 793 if(!strcmp(x->na, "group") && st == IQ_GROUP){ 794 st = IQ_ITEM; 795 break; 796 } 797 if(!strcmp(x->na, "group") && st == ROSTER_GROUP){ 798 st = ROSTER_INNER; 799 break; 800 } 801 if(!strcmp(x->na, "item") && st == IQ_DISCO_ITEM){ 802 print("%s %s | %s\n", tmstmp, to, id); 803 st = IQ_DISCO; 804 break; 805 } 806 if(!strcmp(x->na, "identity") && st == IQ_DISCO_IDENT){ 807 print("%sfeatures:\n", tmstmp); 808 st = IQ_DISCO; 809 break; 810 } 811 if(!strcmp(x->na, "feature") && st == IQ_DISCO_FEATU){ 812 st = IQ_DISCO; 813 break; 814 } 815 if(!strcmp(x->na, "empty") && st == IQ_DISCO_EMPTY){ 816 st = IQ_DISCO; 817 break; 818 } 819 if(!strcmp(x->na, "utc") && st == IQ_TIME_UTC){ 820 st = IQ_TIME; 821 break; 822 } 823 if(!strcmp(x->na, "tz") && st == IQ_TIME_TZ){ 824 st = IQ_TIME; 825 break; 826 } 827 if(!strcmp(x->na, "display") && st == IQ_TIME_DISPLAY){ 828 st = IQ_TIME; 829 break; 830 } 831 if(!strcmp(x->na, "version") && st == IQ_VERSION_VER){ 832 st = IQ_VERSION; 833 break; 834 } 835 if(!strcmp(x->na, "name") && st == IQ_VERSION_NAME){ 836 st = IQ_VERSION; 837 break; 838 } 839 if(!strcmp(x->na, "os") && st == IQ_VERSION_OS){ 840 st = IQ_VERSION; 841 break; 842 } 843 if(!strcmp(x->na, "agent") && st == IQ_AGENTS_AGENT){ 844 st = IQ_AGENTS; 845 print("%s\n", tmstmp); 846 break; 847 } 848 if(!strcmp(x->na, "name") && st == IQ_AGENTS_NAME){ 849 st = IQ_AGENTS_AGENT; 850 break; 851 } 852 if(!strcmp(x->na, "description") && st == IQ_AGENTS_DESC){ 853 st = IQ_AGENTS_AGENT; 854 break; 855 } 856 if((!strcmp(x->na, "transport") || !strcmp(x->na, "groupchat") 857 || !strcmp(x->na, "register") || !strcmp(x->na, "search")) && 858 st == IQ_AGENTS_AGENT) 859 break; 860 if(!strcmp(x->na, "service") && st == IQ_AGENTS_SERV){ 861 st = IQ_AGENTS_AGENT; 862 break; 863 } 864 if(st == IQ_VCARD_INNER){ 865 st = IQ_VCARD; 866 break; 867 } 868 break; 869 case END_DOCUMENT: 870 if(me->debug) 871 print("Documentend.\n"); 872 st = END; 873 break; 874 default: 875 print("Please contact the xmlpull author about this. %x\n", b->ev); 876 st = END; 877 break; 878 } 879 free(tmstmp); 880 } 881 882 if(id != nil) 883 free(id); 884 freexmlpull(x); 885 886 return 0; 887 }