recv.c (5680B)
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 "jacs.h" 10 #include "dat.h" 11 #include "roster.h" 12 13 char * 14 getline(void) 15 { 16 char *ret; 17 int l; 18 19 l = -1; 20 ret = reallocj(nil, 1025, 2); 21 22 while(read(0, &ret[++l], 1) && l < 1024) 23 if(ret[l] == '\n') 24 break; 25 ret[l] = '\0'; 26 27 return ret; 28 } 29 30 void 31 askanswers(ilist *i, char *tmstmp) 32 { 33 ilist *ac; 34 char *val; 35 36 ac = i; 37 while(ac != nil){ 38 print("%s%s[%s] = ", tmstmp, ac->name, (ac->val != nil) ? ac->val : ""); 39 val = getline(); 40 if(ac->val == nil) 41 ac->val = val; 42 else { 43 if(*val != '\0'){ 44 free(ac->val); 45 ac->val = val; 46 } else 47 free(val); 48 } 49 ac = ac->n; 50 } 51 52 return; 53 } 54 55 int 56 recvjacc(int sock, jabberc *me, char *pass) 57 { 58 xmlpull *x, *b; 59 char *id, *to, *from, *tmstmp, st, *type; 60 ilist *ac; 61 62 type = nil; 63 id = nil; 64 from = nil; 65 to = nil; 66 st = NONE; 67 ac = nil; 68 69 if(xmljacc(sock) < 0) 70 return -1; 71 if(loginjacc(sock, me->serv) < 0) 72 return -1; 73 74 x = openxmlpull(sock); 75 while((b = nextxmlpull(x)) != nil && st != END){ 76 tmstmp = mktmstmp('(', ')'); 77 switch(b->ev){ 78 case START_DOCUMENT: 79 if(me->debug) 80 print("Start.\n"); 81 st = NONE; 82 break; 83 case START_TAG: 84 if(me->debug) 85 print("Tag: %s\n", x->na); 86 if(!strcmp(x->na, "stream:stream")){ 87 st = STREAM; 88 break; 89 } 90 if(!strcmp(x->na, "stream:error")){ 91 st = ERROR; 92 break; 93 } 94 if(st == ERROR){ 95 if(strcmp(x->na, "text")) 96 fprint(2, "%serror: %s\n", tmstmp, x->na); 97 break; 98 } 99 if(!strcmp(x->na, "iq")){ 100 st = IQ; 101 break; 102 } 103 if(!strcmp(x->na, "error") && st == IQ){ 104 st = IQ_ERROR; 105 break; 106 } 107 if(st == IQ_ERROR){ 108 print("IQ-Error: %s\n", x->na); 109 break; 110 } 111 if(!strcmp(x->na, "query") && st == IQ){ 112 st = IQ_INNER; 113 break; 114 } 115 if(!strcmp(x->na, "instructions") && st == IQ_REGISTER){ 116 st = IQ_REGISTER_INST; 117 break; 118 } 119 if(!strcmp(x->na, "query") && st == IQ_REGISTER) 120 break; 121 if(st == IQ_REGISTER){ 122 st = IQ_REGISTER_INNE; 123 me->list = addilist(me->list, x->na, nil); 124 ac = lastilist(me->list); 125 break; 126 } 127 break; 128 case START_END_TAG: 129 if(me->debug) 130 print("Startend: %s\n", x->na); 131 if(st == IQ_REGISTER){ 132 if(!strcmp(x->na, "registered")){ 133 print("%sAlready registerd.\n", tmstmp); 134 break; 135 } 136 if(strcmp(x->na, "remove")) 137 me->list = addilist(me->list, x->na, nil); 138 break; 139 } 140 if(st == ERROR){ 141 fprint(2, "%serror: %s\n", tmstmp, x->na); 142 break; 143 } 144 break; 145 case TEXT: 146 if(me->debug) 147 print("Text: %s\n", x->na); 148 switch(st){ 149 case IQ_REGISTER_INST: 150 print("%s %s\n", tmstmp, x->na); 151 break; 152 case IQ_REGISTER_INNE: 153 ac->val = strdup(x->na); 154 break; 155 default: 156 break; 157 } 158 break; 159 case ATTR: 160 if(me->debug) 161 print("Attr: %s = %s\n", x->na, x->va); 162 switch(st){ 163 case STREAM: 164 if(!strcmp(x->na, "id")){ 165 st = NONE; 166 if(userjacc(sock, me->name, pass, me->reso) < 0) { 167 memset(pass, 0, strlen(pass)); 168 st = AUTH; 169 break; 170 } 171 } 172 break; 173 case IQ: 174 if(!strcmp(x->na, "id")){ 175 if(!strcmp(x->va, "auth_1")) { 176 presencejacc(sock, me->stat, me->show, me->jid, nil); 177 if(me->unreg) 178 xmlnsnegjacc(sock, me->dest, "jabber:iq:register", "service_1"); 179 else 180 xmlnsjacc(sock, me->dest, "jabber:iq:register", "service_0"); 181 } 182 if(!strcmp(x->va, "service_0")) 183 st = IQ_REGISTER; 184 id = strdup(x->va); 185 } 186 if(!strcmp(x->na, "from")) 187 from = strdup(x->va); 188 if(!strcmp(x->na, "to")) 189 to = strdup(x->va); 190 if(!strcmp(x->na, "type")) 191 type = strdup(x->va); 192 break; 193 case IQ_INNER: 194 if(!strcmp(x->na, "xmlns")){ 195 if(!strcmp(x->va, "jabber:iq:version")) { 196 if(!strcmp(to, me->jid)){ 197 print("%s%s:\n", tmstmp, from); 198 break; 199 } else 200 versionjacc(sock, me->jid, from, id); 201 break; 202 } 203 if(!strcmp(x->va, "http://jabber.org/protocol/disco#info")) 204 if(!strcmp(me->jid, to)) 205 featuresjacc(sock, to, from, id); 206 207 } 208 break; 209 default: 210 break; 211 } 212 break; 213 case END_TAG: 214 if(me->debug) 215 print("Endtag: %s\n", x->na); 216 if(!strcmp(x->na, "stream:stream")){ 217 st = END; 218 break; 219 } 220 if(!strcmp(x->na, "stream:error") && st == ERROR){ 221 st = NONE; 222 break; 223 } 224 if(st == ERROR) 225 break; 226 if(!strcmp(x->na, "iq") && (st == IQ || st == IQ_REGISTER)){ 227 st = NONE; 228 if(type != nil){ 229 if(!strcmp(type, "result") && !strcmp(id, "service_1")){ 230 print("%sSuccess.\n", tmstmp); 231 st = END; 232 } 233 free(type); 234 } 235 if(from != nil) 236 free(from); 237 if(to != nil) 238 free(to); 239 if(id != nil) 240 free(id); 241 from = nil; 242 to = nil; 243 id = nil; 244 type = nil; 245 break; 246 } 247 if(!strcmp(x->na, "error") && st == IQ_ERROR){ 248 st = IQ; 249 break; 250 } 251 if(!strcmp(x->na, "query") && st == IQ_INNER){ 252 st = IQ; 253 break; 254 } 255 if(!strcmp(x->na, "query") && st == IQ_REGISTER){ 256 st = IQ; 257 if(me->list != nil){ 258 askanswers(me->list, tmstmp); 259 answersjacc(sock, me->dest, "jabber:iq:register", "service_1", me->list); 260 freeilist(me->list); 261 me->list = nil; 262 } 263 break; 264 } 265 if(!strcmp(x->na, "instructions") && st == IQ_REGISTER_INST){ 266 st = IQ_REGISTER; 267 break; 268 } 269 if(st == IQ_REGISTER_INNE){ 270 st = IQ_REGISTER; 271 break; 272 } 273 break; 274 case END_DOCUMENT: 275 if(me->debug) 276 print("Documentend.\n"); 277 st = END; 278 break; 279 default: 280 print("Please contact the xmlpull author about this. %x\n", b->ev); 281 st = END; 282 break; 283 } 284 free(tmstmp); 285 } 286 287 if(id != nil) 288 free(id); 289 freexmlpull(x); 290 291 return 0; 292 }