src/newnews.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- free_newnews_cfg
- CMDnewnews
/* $Id: newnews.c,v 1.1.1.1 1998/07/29 15:14:29 proff Exp $
* $Copyright$
*/
#include "nglobal.h"
#include "acc.h"
#include "newnews.h"
struct a_newnews_cfg
{
struct a_newnews_cfg *next;
struct a_newnews_cfg *head;
struct server_cfg *server;
};
static void free_newnews_cfg(struct a_newnews_cfg *newnews_cfg)
/* [<][>][^][v][top][bottom][index][help] */
{
struct a_newnews_cfg *free_cfg;
while (newnews_cfg)
{
free_cfg = newnews_cfg;
newnews_cfg = newnews_cfg->next;
free(free_cfg);
}
}
EXPORT bool CMDnewnews(char *args)
/* [<][>][^][v][top][bottom][index][help] */
{
struct a_newnews_cfg *newnews_cfg;
struct a_newnews_cfg *newnews_head = NULL;
char newsgroups[MAX_CMD];
char etc[MAX_CMD];
char *group;
bool newnewsok = FALSE;
char *errmsg = NULL;
if (sscanf(args, "%*s %s %256[^\r\n]", newsgroups, etc) != 2)
{
emitrn (NNTP_BAD_COMMAND);
return FALSE;
}
for (newnews_cfg = NULL, group = strtok (newsgroups, ","); group; group = strtok (NULL, ","))
{
struct group_cfg *gcf;
struct server_cfg *last_cfg = NULL;
struct authent *gp;
if (group[0] == '!') /* XXX how do we fit negative groups in with our security policy? */
{
logwn (("CMDnewnews() unsupported negative form of newnews newsgroup '%s'", group));
continue;
}
gp = authorise(RemoteHosts, group); /* this is kind of dubious given possible wild */
/* cards in group, but should work 99.9% of the */
/* time */
if (!gp || !gp->read)
continue;
for (gcf = GroupList; gcf; gcf = gcf->next)
{
if (matchExp (gcf->group_pat, group, 1, 0) ||
(strcspn(group, "*[]?") > 0 && match (group, gcf->group_pat, 1, 0))) /* trick :) */
last_cfg = gcf->server_cfg;
}
if (!last_cfg)
continue;
if (!newnews_cfg)
{
newnews_cfg = newnews_head = Smalloc (sizeof *newnews_cfg);
} else
{
struct a_newnews_cfg *cf;
for (cf = newnews_head; cf; cf = cf->next)
{
if (strCaseEq(cf->server->host, last_cfg->host))
goto duplicate_server;
}
newnews_cfg->next = Smalloc (sizeof *newnews_cfg);
newnews_cfg = newnews_cfg->next;
}
newnews_cfg->server = last_cfg;
newnews_cfg->head = newnews_head;
newnews_cfg->next = NULL;
duplicate_server:
continue; /* solaris cc dumbness */
}
for (newnews_cfg = newnews_head; newnews_cfg; newnews_cfg = newnews_cfg->next)
{
char bfr[MAX_LINE];
struct server_cfg *scf, *cfg = newnews_cfg->server;
int cc;
logd (("fetching newnews from server %s", cfg->host));
if (!(scf = attachServer (cfg)))
{
logw (("couldn't fetch '%s' from %s (server down)", args, cfg->host));
cfg->share->newnews_fail++;
continue;
}
Cfemit (scf, args);
Cfflush (scf);
if (!Cfget (scf, bfr, sizeof bfr))
{
logd (("couldn't fetch all of '%s' from %s (server dropped during build)", args, cfg->host));
cfg->share->newnews_fail++;
continue;
}
if (strToi (bfr) != NNTP_NEWNEWSOK_VAL)
{
if (!newnewsok && !errmsg)
errmsg = Sstrdup(bfr);
goto dropped;
}
if (!newnewsok)
emit (bfr);
newnewsok = TRUE;
while ((cc=Cfget (scf, bfr, sizeof bfr)) && !EL(bfr))
emit (bfr);
if (!cc)
{
dropped:
strStripEOL(bfr);
logw (("couldn't fetch '%.128s' from %s (server refused)", args, cfg->host));
cfg->share->newnews_fail++;
continue;
}
cfg->share->newnews_good++;
}
if (!newnewsok)
{
if (errmsg)
emit (errmsg);
else
emitrn(NNTP_SERVERTEMPDOWN);
}
if (newnews_head)
free_newnews_cfg (newnews_head);
if (errmsg)
free (errmsg);
emitrn(".");
return TRUE;
}