#include <stdio.h> #include <hash.h> #include <hdbm.h> #include <newsoverview.h> novartdir(dir) char *dir; struct novgroup *novopen(grp) char *grp; struct novgroup *novstream(stream) FILE *stream; struct novart *novall(gp) struct novgroup *gp; struct novart *novnext(gp) struct novgroup *gp; novthread(gp) struct novgroup *gp; novclose(gp) struct novgroup *gp;
Novartdir may be called to set the news spool directory to dir rather than the default of /usr/spool/news. Novopen opens the overview data for newsgroup grp, and returns a pointer to a structure of type struct novgroup containing at least these members:
HASHTABLE *g_msgids; HASHTABLE *g_roots;
Novall returns a pointer to the first structure of a linked list of structures of type struct novart containing at least these members:
char *a_num; char *a_subj; char *a_from; char *a_date; char *a_msgid; char *a_refs; char *a_bytes; char *a_lines; /* a waste of bits */ char *a_others; /* these members are message-ids, filled in by novthread() */ char *a_parent; char *a_child1; /* first child of a chain */ char *a_sibling; /* next sibling in this chain */ /* end message-ids */ struct novart *a_nxtnum; /* next in numeric order */
A_parent is the message-id of this article's parent article, if the parent article is described by the overview data for this group; a_child1 the message-id of this article's first child article, if any; a_sibling the message-id of this article's next sibling in a chain, if any. Any of the three members may be NULL if no article applies, and all three will be NULL until novthread is run on the group this article belongs to.
Novnext returns a pointer to the numerically-next (possibly first) article summary structure, or NULL if the group is exhausted. (Numerical order in the database is assumed and not checked.) Novthread constructs a hash table in gp->g_roots of the roots of the trees formed by following References: headers backward. This forest can be walked by traversing these roots using hashwalk (see hash(3)) and looking up the message-ids a_parent, a_child1, and a_sibling in gp->g_msgids (a hash table of all articles in gp). Novclose destroys gp and its substructure.
rootvisit(key, data, hook) char *key, *data, *hook; { prtree((struct novgroup *)hook, ((struct novart *)data)->a_msgid, 1); } process(in, inname) FILE *in; char *inname; { register struct novgroup *gp; gp = novopen(inname); if (gp == NULL) error("can't open overview file for group `%s'", inname); novthread(gp); if (gp->g_roots != NULL) hashwalk(gp->g_roots, rootvisit, (char *)gp); novclose(gp); } prtree(gp, msgid, level) register struct novgroup *gp; register char *msgid; register int level; { register int i; register struct novart *art; if (gp == NULL || gp->g_msgids == NULL || msgid == NULL) return; art = (struct novart *)hashfetch(gp->g_msgids, msgid); if (art == NULL) return; for (i = 1; i < level; i++) (void) putchar('\t'); (void) printf("%s\t%s", art->a_from, msgid); if (level == 1) (void) printf("\t%s", art->a_subj); (void) putchar('\n'); prtree(gp, art->a_child1, level + 1); prtree(gp, art->a_sibling, level); /* next sibling */ }