/*
libutil -- stuff dealing with articles
Written by Cornelius Krasel <krasel@wpxx02.toxi.uni-wuerzburg.de>.
Copyright 1998, 1999.
See file COPYING for restrictions on the use of this software.
*/
#include "leafnode.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include <unistd.h>
#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
syntax highlighted by Code2HTML, v. 0.9.1