src/newnews.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. free_newnews_cfg
  2. 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;
}

/* [<][>][^][v][top][bottom][index][help] */