recv.c - jacc - Jabber/XMPP client for Plan 9
git clone git://r-36.net/jacc
Log
Files
Refs
LICENSE
---
recv.c (5680B)
---
     1 /*
     2  * Copy me if you can.
     3  * by 20h
     4  */
     5 
     6 #include 
     7 #include 
     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 }