+ memmove(buf, p, *len -= p - buf);
+ }
+ break;
+ case PHO_EOF:
+ setpubhubmodel(GTK_TREE_MODEL(model), 3, 3, _("# users"), 1, _("Name"), 2, _("Description"), -1);
+ break;
+ case PHO_FINI:
+ if(model != NULL)
+ g_object_unref(model);
+ model = NULL;
+ break;
+ }
+ return(0);
+}
+
+void pubhubfdcallback(gpointer data, gint source, GdkInputCondition condition)
+{
+ static char buf[65536];
+ static size_t bufpos = 0;
+ int ret, reset;
+
+ if(!(condition & GDK_INPUT_READ))
+ return;
+ if(bufpos == sizeof(buf))
+ bufpos = 0;
+ ret = read(pubhubfd, buf + bufpos, sizeof(buf) - bufpos);
+ reset = 0;
+ if(ret <= 0)
+ {
+ if(ret < 0)
+ msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not read from public hub listing process: %s"), strerror(errno));
+ else
+ pubhubhandler(PHO_EOF, buf, &bufpos);
+ reset = 1;
+ } else {
+ bufpos += ret;
+ if(pubhubhandler(PHO_DATA, buf, &bufpos))
+ reset = 1;
+ }
+ if(reset)
+ {
+ pubhubhandler(PHO_FINI, NULL, NULL);
+ pubhubhandler = NULL;
+ gdk_input_remove(pubhubtag);
+ close(pubhubfd);
+ kill(pubhubproc, SIGINT);
+ pubhubfd = pubhubtag = -1;
+ pubhubproc = 0;
+ bufpos = 0;
+ if(filterpubhub)
+ {
+ regfree(&pubhubfilter);
+ filterpubhub = 0;