/**/
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct listwhatinfo {
const char *name;
void (*call)(const struct listwhatinfo *lwi, const char *cachename);
- int mustall;
+ int mustall; /* -2 means ->call() must also print response and final . */
const char *what;
int einfo;
};
}
static void lwc_fixed(const struct listwhatinfo *lwi, const char *cachename) {
- char *pathname;
- pathname=
- FILE *f= fopen(
- char *p, tc;
- struct disdone { struct disdone *next; char *name; } *done, *search, *tmp;
- struct serverinfo *si;
- char fnbuf[250];
- char linebuf[MAX_RESPONSE+3];
- FILE *file;
-
- done= 0;
- for (si= servers; si; si= si->next) {
- if (!si->searchthis) continue;
- sprintf(fnbuf,"%.100s:%.100s",si->nickname,cachename);
- file= fopen(fnbuf,"r");
- if (!file) continue;
- while (fgets(linebuf,MAX_RESPONSE+3,file)) {
- p= linebuf; while (*p && !isspace(*p)) p++;
- tc= *p; *p= 0;
- for (search= done;
- search && strcasecmp(linebuf,search->name);
- search= search->next);
- if (search) continue;
- tmp= xmalloc(sizeof(struct disdone));
- tmp->name= xstrdup(linebuf);
- tmp->next= done;
- done= tmp;
- *p= tc;
- fputs(linebuf,stdout);
+ char *pathname=0;
+ int r= asprintf(&pathname, "/etc/news/nntp-merge/%s", lwi->name);
+ if (r<0) die("allocate for lwc fixed path");
+ FILE *file= fopen(pathname, "r");
+ if (!file) {
+ if (errno == ENOENT) {
+ printf("503 %s not available\r\n",lwi->what);
+ goto x;
}
- if (ferror(file)) die("read error on list file");
- fclose(file);
+ die("open a list file");
}
- for (search= done; search; search= tmp) {
- tmp= search->next; free(search->name); free(search);
- }
- return;
+
+ printf("215 %s (as configured) follows:\r\n",lwi->what);
+ int c;
+ int linestart= 1; /* -1 means comment */
+ while ((c= getc(file)) != EOF) {
+ if (linestart < 0) {
+ if (c=='\n') linestart= 1;
+ continue;
+ }
+ if (linestart) {
+ if (c=='#') { linestart= -1; continue; }
+ if (c=='.') putchar('.');
+ linestart= 0;
+ }
+ if (c=='\n') { putchar('\r'); linestart=1; }
+ putchar(c);
+ }
+ if (ferror(file))
+ die("error reading list");
+ assert(feof(file));
+ fputs(".\r\n",stdout);
+ x:
+ if (file) fclose(file);
+ free(pathname);
}
static void lwc_overview(const struct listwhatinfo *lwi, const char *cachename) {
}
static const struct listwhatinfo listwhatinfos[]= {
- { "", lwc_bynewsgroup, 1, "active file", 1 },
- { "active", lwc_bynewsgroup, 1, "active file", 1 },
- { "active.times", lwc_bynewsgroup, 1, "newsgroups' creation info", 0 },
- { "newsgroups", lwc_bynewsgroup, 0, "newsgroup titles", 0 },
- { "subscriptions", lwc_bynewsgroup, 0, "default subscription list", 0 },
- { "distributions", lwc_distributions, 0, "distributions available" },
- { "overview.fmt", lwc_overview, -1, "field list" },
- { 0 }
+ { "", lwc_bynewsgroup, 1, "active file", 1 },
+ { "active", lwc_bynewsgroup, 1, "active file", 1 },
+ { "active.times", lwc_bynewsgroup, 1, "newsgroups' creation info", 0 },
+ { "newsgroups", lwc_bynewsgroup, 0, "newsgroup titles", 0 },
+ { "subscriptions", lwc_bynewsgroup, 0, "default subscription list", 0 },
+ { "distributions", lwc_fixed, -2, "distributions available" },
+ { "distrib.pats", lwc_fixed, -2, "default distribution patterns" },
+ { "overview.fmt", lwc_overview, -1, "field list" },
+ { 0 }
};
static int copydatanodot(struct serverinfo *si, FILE *file) {
return;
}
}
- printf("215 %s follows:\r\n",lwi->what);
+ if (lwi->mustall>=-1)
+ printf("215 %s follows:\r\n",lwi->what);
lwi->call(lwi,cachename);
- printf(".\r\n");
+ if (lwi->mustall>=-1)
+ printf(".\r\n");
}
static int unadjustnumber(char *appendto, char *from, int offset) {