recv.c - jacc - Jabber/XMPP client for Plan 9
 (HTM) git clone git://r-36.net/jacc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
       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 }