summaryrefslogtreecommitdiffstats
path: root/jacs/recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'jacs/recv.c')
-rw-r--r--jacs/recv.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/jacs/recv.c b/jacs/recv.c
new file mode 100644
index 0000000..63b1b91
--- /dev/null
+++ b/jacs/recv.c
@@ -0,0 +1,292 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#include <u.h>
+#include <libc.h>
+#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;
+}