/* * Copy me if you can. * by 20h */ #include #include #include "xmlpull.h" #include "jacs.h" #include "dat.h" #include "roster.h" char * getline(void) { char *ret; int l; l = -1; ret = reallocj(nil, 1025, 2); while(read(0, &ret[++l], 1) && l < 1024) if(ret[l] == '\n') break; ret[l] = '\0'; return ret; } void askanswers(ilist *i, char *tmstmp) { ilist *ac; char *val; ac = i; while(ac != nil){ print("%s%s[%s] = ", tmstmp, ac->name, (ac->val != nil) ? ac->val : ""); val = getline(); if(ac->val == nil) ac->val = val; else { if(*val != '\0'){ free(ac->val); ac->val = val; } else free(val); } ac = ac->n; } return; } int recvjacc(int sock, jabberc *me, char *pass) { xmlpull *x, *b; char *id, *to, *from, *tmstmp, st, *type; ilist *ac; type = nil; id = nil; from = nil; to = nil; st = NONE; ac = nil; if(xmljacc(sock) < 0) return -1; if(loginjacc(sock, me->serv) < 0) return -1; x = openxmlpull(sock); while((b = nextxmlpull(x)) != nil && st != END){ tmstmp = mktmstmp('(', ')'); switch(b->ev){ case START_DOCUMENT: if(me->debug) print("Start.\n"); st = NONE; break; case START_TAG: if(me->debug) print("Tag: %s\n", x->na); if(!strcmp(x->na, "stream:stream")){ st = STREAM; break; } if(!strcmp(x->na, "stream:error")){ st = ERROR; break; } if(st == ERROR){ if(strcmp(x->na, "text")) fprint(2, "%serror: %s\n", tmstmp, x->na); break; } if(!strcmp(x->na, "iq")){ st = IQ; break; } if(!strcmp(x->na, "error") && st == IQ){ st = IQ_ERROR; break; } if(st == IQ_ERROR){ print("IQ-Error: %s\n", x->na); break; } if(!strcmp(x->na, "query") && st == IQ){ st = IQ_INNER; break; } if(!strcmp(x->na, "instructions") && st == IQ_REGISTER){ st = IQ_REGISTER_INST; break; } if(!strcmp(x->na, "query") && st == IQ_REGISTER) break; if(st == IQ_REGISTER){ st = IQ_REGISTER_INNE; me->list = addilist(me->list, x->na, nil); ac = lastilist(me->list); break; } break; case START_END_TAG: if(me->debug) print("Startend: %s\n", x->na); if(st == IQ_REGISTER){ if(!strcmp(x->na, "registered")){ print("%sAlready registerd.\n", tmstmp); break; } if(strcmp(x->na, "remove")) me->list = addilist(me->list, x->na, nil); break; } if(st == ERROR){ fprint(2, "%serror: %s\n", tmstmp, x->na); break; } break; case TEXT: if(me->debug) print("Text: %s\n", x->na); switch(st){ case IQ_REGISTER_INST: print("%s %s\n", tmstmp, x->na); break; case IQ_REGISTER_INNE: ac->val = strdup(x->na); break; default: break; } break; case ATTR: if(me->debug) print("Attr: %s = %s\n", x->na, x->va); switch(st){ case STREAM: if(!strcmp(x->na, "id")){ st = NONE; if(userjacc(sock, me->name, pass, me->reso) < 0) { memset(pass, 0, strlen(pass)); st = AUTH; break; } } break; case IQ: if(!strcmp(x->na, "id")){ if(!strcmp(x->va, "auth_1")) { presencejacc(sock, me->stat, me->show, me->jid, nil); if(me->unreg) xmlnsnegjacc(sock, me->dest, "jabber:iq:register", "service_1"); else xmlnsjacc(sock, me->dest, "jabber:iq:register", "service_0"); } if(!strcmp(x->va, "service_0")) st = IQ_REGISTER; id = strdup(x->va); } if(!strcmp(x->na, "from")) from = strdup(x->va); if(!strcmp(x->na, "to")) to = strdup(x->va); if(!strcmp(x->na, "type")) type = strdup(x->va); break; case IQ_INNER: if(!strcmp(x->na, "xmlns")){ if(!strcmp(x->va, "jabber:iq:version")) { if(!strcmp(to, me->jid)){ print("%s%s:\n", tmstmp, from); break; } else versionjacc(sock, me->jid, from, id); break; } if(!strcmp(x->va, "http://jabber.org/protocol/disco#info")) if(!strcmp(me->jid, to)) featuresjacc(sock, to, from, id); } break; default: break; } break; case END_TAG: if(me->debug) print("Endtag: %s\n", x->na); if(!strcmp(x->na, "stream:stream")){ st = END; break; } if(!strcmp(x->na, "stream:error") && st == ERROR){ st = NONE; break; } if(st == ERROR) break; if(!strcmp(x->na, "iq") && (st == IQ || st == IQ_REGISTER)){ st = NONE; if(type != nil){ if(!strcmp(type, "result") && !strcmp(id, "service_1")){ print("%sSuccess.\n", tmstmp); st = END; } free(type); } if(from != nil) free(from); if(to != nil) free(to); if(id != nil) free(id); from = nil; to = nil; id = nil; type = nil; break; } if(!strcmp(x->na, "error") && st == IQ_ERROR){ st = IQ; break; } if(!strcmp(x->na, "query") && st == IQ_INNER){ st = IQ; break; } if(!strcmp(x->na, "query") && st == IQ_REGISTER){ st = IQ; if(me->list != nil){ askanswers(me->list, tmstmp); answersjacc(sock, me->dest, "jabber:iq:register", "service_1", me->list); freeilist(me->list); me->list = nil; } break; } if(!strcmp(x->na, "instructions") && st == IQ_REGISTER_INST){ st = IQ_REGISTER; break; } if(st == IQ_REGISTER_INNE){ st = IQ_REGISTER; break; } break; case END_DOCUMENT: if(me->debug) print("Documentend.\n"); st = END; break; default: print("Please contact the xmlpull author about this. %x\n", b->ev); st = END; break; } free(tmstmp); } if(id != nil) free(id); freexmlpull(x); return 0; }