1 /* $Id: sys2nf.c 7741 2008-04-06 09:51:47Z iulius $
3 ** Read a C news "sys" file and split it up into a set of INN
4 ** newsfeeds entries. Also works with B news.
6 ** Once done, edit all files that have HELP or all in them.
7 ** Review all files, anyway.
16 #include "inn/innconf.h"
20 #define TEMPFILE ":tmp"
25 ** Fill in the Groups array with the names of all active newsgroups.
36 /* Open file, count lines. */
37 if ((F = fopen(act, "r")) == NULL) {
41 for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
43 Groups = xmalloc((i + 2) * sizeof(char *));
45 /* Fill in each word. */
47 for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++) {
48 if ((p = strchr(buff, ' ')) != NULL)
50 Groups[i] = xstrdup(buff);
58 ** Read in the sys file and turn it into an array of strings, one
59 ** per continued line.
72 /* Read in the file, get rough count. */
73 if ((data = ReadInFile(sys, (struct stat *)NULL)) == NULL) {
77 for (p = data, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
80 /* Scan the file, glue all multi-line entries. */
81 for (strings = xmalloc((i + 1) * sizeof(char *)), i = 0, to = p = data; *p; ) {
82 for (site = to; *p; ) {
88 if (*p == '\\' && p[1] == '\n')
89 while (*++p && CTYPE(isspace, *p))
97 strings[i++] = xstrdup(site);
106 ** Is this the name of a top-level group? We want a simple name, "foo",
107 ** and should find a "foo." in the group list.
117 if (strchr(p, '.') != NULL)
119 for (i = strlen(p) - 1, gp = Groups; (g = *gp++) != NULL; )
120 if (strncmp(p, g, i) == 0 && g[i + 1] == '.')
127 ** Do we have a name that's a prefix for more then one newsgroup?
128 ** For "foo.bar", we must find more then one "foo.bar" or "foo.bar."
139 if (strchr(p, '.') == NULL)
141 for (i = strlen(p), count = 0, gp = Groups; (g = *gp++) != NULL; )
142 if (strcmp(p, g) == 0 || (strncmp(p, g, i) == 0 && g[i] == '.'))
149 ** Step through the old subscription list, try to update each one in
163 /* Distributions, not newsgroups. */
164 static const char * const distributions[] = {
165 "world", "na", "usa", "inet", "mod", "net", "local"
168 /* Newsgroup hierarchies. */
169 static const char * const hierarchies[] = {
170 "comp", "misc", "news", "rec", "sci", "soc", "talk", "alt", "bionet",
171 "bit", "biz", "clari", "ddn", "gnu", "ieee", "k12", "pubnet", "trial",
174 "ba", "ca", "dc", "ne", "ny", "tx",
176 "info", "mail", "opinions", "uunet"
179 if ((s = strtok(p, ",")) == NULL)
185 for (matched = false, i = 0; i < ARRAY_SIZE(distributions); i++)
186 if (strcmp(s, distributions[i]) == 0) {
193 if (innconf->mergetogroups)
194 if (strcmp(s, "!to") == 0 || strncmp(s, "to.", 3) == 0)
200 if (len + strlen(s) + 3 > 72) {
201 fprintf(F,"\\\n\t ");
212 SawAll = (strcmp(s, "all") == 0);
214 s = SawBang ? "*" : "*,!control,!control.*";
221 for (matched = false, i = 0; i < ARRAY_SIZE(distributions); i++)
222 if (strcmp(s, hierarchies[i]) == 0) {
230 } else if (GroupPrefix(s)) {
235 } while ((s = strtok((char *)NULL, ",")) != NULL);
259 if (!innconf_read(NULL))
262 act = "/usr/local/lib/newslib/active";
265 while ((i = getopt(ac, av, "a:s:d:")) != EOF)
270 case 'a': act = optarg; break;
271 case 'd': dir = optarg; break;
272 case 's': sys = optarg; break;
275 sites = ReadSys(sys);
277 if (mkdir(dir, 0777) < 0 && errno != EEXIST)
278 perror(dir), exit(1);
280 perror("chdir"), exit(1);
282 /* Get next non-comment ilne. */
283 if ((p = *sites++) == NULL)
285 for (F = fopen(TEMPFILE, "w"); p && *p == '#'; p = *sites++)
286 fprintf(F, "%s\n", p);
292 if ((f2 = strchr(site, ':')) == NULL)
296 if ((f3 = strchr(f2, ':')) == NULL)
300 if ((f4 = strchr(f3, ':')) == NULL)
305 /* Write the fields. */
306 fprintf(F, "%s\\\n", site);
310 if (strcmp(f3, "n") == 0)
311 fprintf(F, "\t:Tf,Wnm\\\n", f3);
313 fprintf(F, "\t:HELP%s\\\n", f3);
314 fprintf(F, "\t:%s\n", f4);
315 if (ferror(F) || fclose(F) == EOF)
316 perror(TEMPFILE), exit(1);
320 /* Find the sitename. */
321 for (q = p; *q && *q != '/' && *q != ':'; q++)
325 /* Append temp file to site file. */
326 if ((F = fopen(TEMPFILE, "r")) == NULL)
327 perror(TEMPFILE), exit(1);
328 if ((out = xfopena(p)) == NULL)
330 while ((i = fread(buff, 1, sizeof buff, F)) > 0)
331 if (fwrite(buff, 1, i, out) != i)
334 if (fclose(out) == EOF)
337 if (unlink(TEMPFILE) < 0)
338 perror("can't unlink temp file");