/* libutil -- stuff dealing with articles Written by Cornelius Krasel . Copyright 1998, 1999. See file COPYING for restrictions on the use of this software. */ #include "leafnode.h" #include #include #include #include #include #include #include #include "mastring.h" #include "ln_log.h" /** * find a header in an article and return it, without its name. */ char * fgetheader(FILE * f, const char *header) { char *hdr, *p; size_t hlen; if (!header || !*header || header[(hlen = strlen(header))-1] != ':') { syslog(LOG_CRIT, "internal error in %s:%d", __FILE__, __LINE__); /* RATS: ignore */ abort(); /* header must end with a colon */ } if (!f) return NULL; rewind(f); debug = 0; hdr = NULL; while ((p = getfoldedline(f, getaline)) && *p) { /* read only headers */ char *q = p; if ((strncasecmp(q, header, hlen) == 0)) { q += hlen; while (q && *q && isspace((unsigned char)*q)) q++; hdr = critstrdup(q, "fgetheader"); free(p); p = NULL; break; } free(p); p = NULL; } if (p) free(p); debug = debugmode; rewind(f); return hdr; } char * getheader(const char *filename, const char *header) { FILE *f; char *hdr; struct stat st; if ((f = fopen(filename, "r")) == NULL) return NULL; if (fstat(fileno(f), &st) || !S_ISREG(st.st_mode)) { (void)fclose(f); return NULL; } hdr = fgetheader(f, header); fclose(f); return hdr; } /* * store articles in newsgroups which are already stored in * $SPOOLDIR/message.id/ */ void store(const char *filename, FILE * filehandle, const char *newsgroups, const char *msgid) { char tmp[50]; /* RATS: ignore */ static struct newsgroup *cg; static struct newsgroup *cg_active; /* Ken Shan: we must not try to reuse the cg pointer, * it becomes invalid as the "active" pointer is realloc()ed. */ mastr *xrefincase = mastr_new(4096); const char *p; char *q; if (verbose > 2) printf(".storing %s: %s\n", msgid, newsgroups); p = newsgroups; while (p && *p) { q = strchr(p, ','); if (q) *q++ = '\0'; SKIPLWS(p); if (*p) { if (!cg || cg_active != active || strcmp(cg->name, p)) { cg = findgroup(p); cg_active = active; if (cg) { if (isinteresting(cg->name) || create_all_links) { if (!chdirgroup(p, FALSE)) cg->first = cg->last + 1; if (!chdirgroup(p, TRUE)) { ln_log(LNLOG_SERR, LNLOG_CTOP, "cannot create group directory for %s", cg->name); cg = NULL; } } else { cg = NULL; } } } /* cg may have become NULL if we don't want to store */ if (cg) { int r; if (cg->first < 1) cg->first = 1; if (cg->last < cg->first) cg->last = cg->first++; if (!chdirgroup(p, FALSE)) { /* error */ p = q; continue; } do { sprintf(tmp, "%lu", ++cg->last); errno = 0; } while ((r = link(filename, tmp)) < 0 && errno == EEXIST); if (r == 0 && verbose > 2) printf("..as article %lu in %s\n", cg->last, cg->name); if (r < 0) syslog(LOG_ERR, "error linking %s into %s: %m", filename, p); else { mastr_vcat(xrefincase, " ", cg->name, ":", tmp, NULL); } } else { if (verbose > 2) printf("..discarding unknown group %s\n", p); } } p = q; } fprintf(filehandle, "Xref: %s%s\n", fqdn, mastr_str(xrefincase)); mastr_delete(xrefincase); } #ifdef TEST int verbose = 0; int debug = 0; int main(int argc, char **argv[]) { char *t; if (argc != 3) { fprintf(stderr, "usage: %s file header:\n", argv[0]); exit(1); } t = getheader(argv[1], argv[2]); printf("header %s in %s is:\n%s\n", argv[2], argv[1], t ? t : "(NULL)"); exit(0); } #endif