2 * Dolda Connect - Modular multiuser Direct Connect-style client
3 * Copyright (C) 2007 Fredrik Tolf <fredrik@dolda2000.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <doldaconnect/utils.h>
25 /* "Programming with libxml2 is like the thrilling embrace of an
28 #include <libxml/parser.h>
29 #include <libxml/tree.h>
37 static xmlNodePtr findnode(xmlNodePtr node, char *name)
39 for(; node != NULL; node = node->next)
41 if(!strcmp((char *)node->name, name))
47 static int checkvalid(xmlNodePtr n)
52 name = (char *)xmlGetProp(n, (xmlChar *)"Name");
53 descr = (char *)xmlGetProp(n, (xmlChar *)"Description");
54 match = validhub(name, descr, NULL);
61 int pubhubxmlhandler(int op, char *buf, size_t len)
63 static xmlParserCtxtPtr ctxt = NULL;
65 xmlNodePtr dr, r, cr, c, n;
66 int numcols, *cols, sortcol;
68 char **names, *name, *stype, *attr;
81 ctxt = xmlCreatePushParserCtxt(NULL, NULL, buf, len, NULL);
85 xmlParseChunk(ctxt, buf, len, 0);
91 msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("A hub list could not be read from the server"));
94 xmlParseChunk(ctxt, NULL, 0, 1);
97 msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("The hub list is not valid"));
101 dr = xmlDocGetRootElement(ctxt->myDoc);
103 r = findnode(dr->children, "Hubs");
105 cr = findnode(r->children, "Columns");
108 msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("The hub list cannot be understood"));
111 for(c = findnode(cr->children, "Column"); c != NULL; c = findnode(c->next, "Column"))
113 name = (char *)xmlGetProp(c, (xmlChar *)"Name");
114 stype = (char *)xmlGetProp(c, (xmlChar *)"Type");
115 type = G_TYPE_INVALID;
118 if(!strcmp(stype, "string"))
119 type = G_TYPE_STRING;
120 else if(!strcmp(stype, "int"))
122 else if(!strcmp(stype, "percent"))
124 else if(!strcmp(stype, "bytes"))
127 if((name != NULL) && (type != G_TYPE_INVALID))
129 names = srealloc(names, (numcols + 1) * sizeof(*names));
130 types = srealloc(types, (numcols + 1) * sizeof(*names));
131 names[numcols] = sstrdup(name);
132 types[numcols] = type;
142 msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("The hub list did not contain any columns"));
145 for(i = 0; i < numcols; i++)
147 if(!strcasecmp(names[i], "Address"))
149 for(o = i; o > 0; o--) {
152 names[o] = names[o - 1];
153 types[o] = types[o - 1];
162 msgbox(GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("The hub list did not contain the address to any hubs"));
165 model = gtk_list_store_newv(numcols, types);
166 for(n = findnode(r->children, "Hub"); n != NULL; n = findnode(n->next, "Hub"))
168 if(!xmlHasProp(n, (xmlChar *)"Address") || !xmlHasProp(n, (xmlChar *)"Name"))
172 gtk_list_store_append(model, &iter);
173 for(i = 0; i < numcols; i++)
175 attr = (char *)xmlGetProp(n, (xmlChar *)names[i]);
178 if(!strcmp(names[i], "Address")) {
179 if(!strncmp(attr, "dchub://", 8))
180 gtk_list_store_set(model, &iter, i, attr + 8, -1);
182 gtk_list_store_set(model, &iter, i, attr, -1);
183 } else if(types[i] == G_TYPE_STRING) {
184 gtk_list_store_set(model, &iter, i, attr, -1);
185 } else if(types[i] == G_TYPE_INT) {
186 gtk_list_store_set(model, &iter, i, atoi(attr), -1);
187 } else if(types[i] == G_TYPE_INT64) {
188 gtk_list_store_set(model, &iter, i, strtoll(attr, NULL, 0), -1);
194 cols = smalloc((numcols - 1) * sizeof(*cols));
195 for(i = 1; i < numcols; i++)
198 for(i = 0; i < numcols; i++)
200 if(!strcmp(names[i], "Users"))
203 setpubhubmodel(GTK_TREE_MODEL(model), sortcol, numcols - 1, cols, names + 1);
205 g_object_unref(model);
210 if(ctxt->myDoc != NULL)
211 xmlFreeDoc(ctxt->myDoc);
212 xmlFreeParserCtxt(ctxt);
219 for(i = 0; i < numcols; i++)