/* parsing lists {{{*/ if(service) { xmlNodePtr memberships = findNode(service->children, "Memberships", 1); xmlNodePtr ms; xmlNodePtr role; xmlNodePtr members, member; xmlNodePtr pname; xmlNodePtr type; xmlNodePtr lastchange; xmlChar *content; int flag = 0; lastchange = findNode(service->children, "LastChange", 1); content = xmlNodeGetContent(lastchange); cl->lastchange = strdup((char*)content); DMSG(stderr, "Contact: lastchange = %s\n", cl->lastchange); if(!memberships) { fprintf(stderr, "NULL membership\n"); count = 0; goto cleanup; } for(ms=memberships->children;ms;ms=ms->next) { int ctype = 1; if(!ms->children) continue; role = findNode(ms->children, "MemberRole", 1); if(!role) { fprintf(stderr, "Null role\n"); count = 0; goto cleanup; } members = findNode(role, "Members", 1); if(!members) continue; if(xmlStrEqual(role->children->content, (xmlChar*)"Allow")) flag = 3; else if(xmlStrEqual(role->children->content, (xmlChar*)"Block")) flag = 4; else continue; for(member=members->children;member;member=member->next) { Contact *c; type = findNode(member->children, "Type", 1); content = xmlNodeGetContent(type); if(!content) { fprintf(stderr, "NULL Type\n"); continue; } if(xmlStrEqual(content, (xmlChar*)"Passport")) { pname = findNode(member->children, "PassportName", 1); ctype = 1; } else if(xmlStrEqual(content, (xmlChar*)"Email")) { pname = findNode(member->children, "Email", 1); ctype = 32; } else continue; xmlFree(content); if(!pname) { fprintf(stderr, "NULL PassportName or Email\n"); continue; } content = xmlNodeGetContent(pname); if(content) { char name[32]; char domain[32]; if(sscanf((char*)content, "%[^@]@%s", name, domain) != 2) { fprintf(stderr, "parse contact: malformed email: %s\n", content); continue; } c = contact_new((char*)content); c->name = strdup(name); c->type = ctype; c->status = NA; c->inlist |= flag; c->domain = NULL; /* should be filled during sort */ cl_append_contact(cl, c, name, domain); xmlFree(content); count++; } } } }/*}}}*/ DMSG(stderr, "parsed contact count: %d\n", count); cleanup: cl->flag &= ~CL_INITLIST; return count; }/*}}}*/ int _cl_do_soapreq_ab(CL *cl)/*{{{*/ { TCPClient *client; char *req = NULL; char *header; char buf[512]; int ret, len; char *ptr = NULL; client = tcpclient_new("contacts.msn.com", 80); ret = _cl_load_soapreq_ab(cl, cl->ablastchange, &req, TRUE); if(ret) { tcpclient_connect(client); header = (char*)xmalloc(strlen(ab_request_header) + 32); DMSG(stderr, "sending ab request\n"); len = sprintf(header, "%s%d\r\n\r\n", ab_request_header, ret); if(tcpclient_send(client, header, len) <= 0) goto cleanup; if(tcpclient_send(client, req, ret) <= 0) goto cleanup; len = tcpclient_recv_header(client, &ptr); /* header */ if(ptr) { HTTPHeader *header; xmlDocPtr doc; xmlParserCtxtPtr ctxt; FILE *fp; DMSG(stderr, "AB response header:\n%s", ptr); header = http_parse_header(ptr); len = header->content_length; DMSG(stderr, "Length: %d\n", len); http_header_destroy(header); memset(buf, 0, sizeof(buf)); fp = fopen("addressbook.xml", "w"); fprintf(fp, buf); len -= (ret = tcpclient_recv(client, buf, sizeof(buf)-1)); ctxt = xmlCreatePushParserCtxt(NULL, NULL, buf, ret, "addressbook.xml"); fprintf(fp, buf); if(ctxt == NULL) { fprintf(stderr, "failed to create parser context"); return 0; } while(len > 0) { memset(buf, 0, sizeof(buf)); len -= (ret=tcpclient_recv(client, buf, sizeof(buf)-1)); fprintf(fp, buf); xmlParseChunk(ctxt, buf, ret, 0); } fclose(fp); xmlParseChunk(ctxt, buf, 0, 1); tcpclient_destroy(client); client = NULL; doc = ctxt->myDoc; len = ctxt->wellFormed; xmlFreeParserCtxt(ctxt); //count += _cl_parse_contacts(cl, doc); xmlFreeDoc(doc); xmlCleanupParser(); DMSG(stderr, "addressbook xml parsing done: %s\n", len?"good":"malformed"); xfree(ptr); } else { DMSG(stderr, "ab: no header found\n\r"); } } else { fprintf(stderr, "failed to load abreq\n"); } cleanup: xfree(header); return 0; }/*}}}*/ int cl_load_contacts(CL *cl, const char* file)/*{{{*/ { int ret; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr contact; xmlNodePtr node; xmlChar *content; doc = xmlReadFile(file, NULL, 0); if (doc == NULL) { fprintf(stderr, "Failed to parse %s\n", file); return 0; } ret = 0; root = xmlDocGetRootElement(doc); contact = findNode(root->children, "contact", 3); #define READSTR(dst,elem) node = findNode(contact->children, elem, 1); \ content = xmlNodeGetContent(node); \ dst = strdup((char*)content); \ xmlFree(content) #define READINT(dst, elem) node = findNode(contact->children, elem, 1); \ content = xmlNodeGetContent(node); \ dst = atoi((char*)content); \ xmlFree(content) for(;contact;contact=contact->next) { Contact *c; node = findNode(contact->children, "nick", 1); content = xmlNodeGetContent(node); c = contact_new((char*)content); xmlFree(content); READSTR(c->name, "name"); READSTR(c->PSM, "PSM"); READINT(c->inlist, "inlist"); READINT(c->type, "type"); c->status = NA; node = findNode(contact->children, "domain", 1); content = xmlNodeGetContent(node); c->domain = NULL; /* should be filled during sort */ cl_append_contact(cl, c, c->name, (char*)content); xmlFree(content); ret++; } node = findNode(root->children, "lastchange", 3); if(node) { content = xmlNodeGetContent(node); cl->lastchange = strdup((char*)content); xmlFree(content); } xmlFreeDoc(doc); return ret; }/*}}}*/
/* delete from global list */ if(!strcmp(name, cl->list->name)) { cl->list = cl->list->g_next; } else { Contact *prev; for(prev=cl->list;prev->g_next;prev=prev->g_next) { if(!strcmp(prev->g_next->name, name)) { prev->g_next = prev->g_next->g_next; break; } } } list = (Contact*)xmlHashLookup(cl->emailtable, (xmlChar*)email); contact_destroy(list); } else { list = (Contact*)xmlHashLookup(cl->table, (xmlChar*)domain); c->d_next = list; xmlHashUpdateEntry(cl->table, (xmlChar*)domain, c, NULL); c->g_next = cl->list; cl->list = c; } xmlHashUpdateEntry(cl->emailtable, (xmlChar*)email, c, NULL); if(! cl->flag & CL_INITLIST) /* reorder when new contact added */ _cl_sort_contacts(cl); return 1; }/*}}}*/ Contact *cl_get_contact_by_email(CL *cl, const char *email)/*{{{*/ { return (Contact*)xmlHashLookup(cl->emailtable, (xmlChar*)email); }/*}}}*/ int _cl_parse_contacts(CL *cl, xmlDocPtr doc)/*{{{*/ { xmlNodePtr node; xmlNodePtr services; xmlNodePtr service; int count = 0; node = xmlDocGetRootElement(doc); services = findNode(node, "Services", 5); if(!services) { DMSG(stderr, "cannot find <Services>\n"); goto cleanup; } cl->flag |= CL_INITLIST; for(service=services->children;service;service=service->next)/*{{{*/ { xmlNodePtr type; xmlNodePtr info = findNode(service->children, "Info",1); if(!info) { fprintf(stderr, "cannot find <Info> in <Service>\n"); count = 0; goto cleanup; } type = findNode(info->children, "Type", 3); if(!type || !type->children) { fprintf(stderr, "NULL Type\n"); count = 0; goto cleanup; } if(xmlStrEqual(type->children->content, (xmlChar*)"Messenger")) break; }/*}}}*/ /* parsing lists {{{*/ if(service) { xmlNodePtr memberships = findNode(service->children, "Memberships", 1); xmlNodePtr ms; xmlNodePtr role; xmlNodePtr members, member; xmlNodePtr pname; xmlNodePtr type; xmlNodePtr lastchange; xmlChar *content; int flag = 0; lastchange = findNode(service->children, "LastChange", 1); content = xmlNodeGetContent(lastchange); cl->lastchange = strdup((char*)content); DMSG(stderr, "Contact: lastchange = %s\n", cl->lastchange); if(!memberships) { fprintf(stderr, "NULL membership\n"); count = 0; goto cleanup; } for(ms=memberships->children;ms;ms=ms->next) { int ctype = 1; if(!ms->children) continue; role = findNode(ms->children, "MemberRole", 1); if(!role) { fprintf(stderr, "Null role\n"); count = 0; goto cleanup; } members = findNode(role, "Members", 1); if(!members) continue; if(xmlStrEqual(role->children->content, (xmlChar*)"Allow")) flag = 3; else if(xmlStrEqual(role->children->content, (xmlChar*)"Block")) flag = 4; else continue; for(member=members->children;member;member=member->next) { Contact *c; type = findNode(member->children, "Type", 1); content = xmlNodeGetContent(type); if(!content) { fprintf(stderr, "NULL Type\n"); continue; } if(xmlStrEqual(content, (xmlChar*)"Passport")) { pname = findNode(member->children, "PassportName", 1); ctype = 1; } else if(xmlStrEqual(content, (xmlChar*)"Email")) { pname = findNode(member->children, "Email", 1); ctype = 32; } else continue; xmlFree(content); if(!pname) { fprintf(stderr, "NULL PassportName or Email\n"); continue; } content = xmlNodeGetContent(pname); if(content) { char name[32]; char domain[32]; if(sscanf((char*)content, "%[^@]@%s", name, domain) != 2) { fprintf(stderr, "parse contact: malformed email: %s\n", content); continue; } c = contact_new((char*)content); c->name = strdup(name); c->type = ctype; c->status = NA; c->inlist |= flag; c->domain = NULL; /* should be filled during sort */ cl_append_contact(cl, c, name, domain); xmlFree(content); count++; } } } }/*}}}*/ DMSG(stderr, "parsed contact count: %d\n", count); cleanup: cl->flag &= ~CL_INITLIST; return count; }/*}}}*/
void on_add_address_clicked(GtkButton *button,gpointer user_data) { LinphoneFriend *lf=linphone_friend_new(); contact_new(lf,gtk_widget_get_toplevel(GTK_WIDGET(button))); }