Metropoli BBS
VIEWER: misc.c MODE: TEXT (ASCII)
/*
 * This OS/2 port was hacked by Harald Kipp from the
 *
 *      Network News Transfer Protocol server
 *
 *      Phil Lapsley
 *      University of California, Berkeley
 *      Stan Barber
 *      Baylor College of Medicine
 *
 * Bug reports related to THIS modified version should be sent to
 *
 *  harald@os2point.ping.de
 *  harald@sesam.com
 *  Fido: 2:2448/434
 *
 */

#define OS2
#include <os2.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <tcpconn.h>
#include <history.h>
#include <chanlib.h>

#include <dbgheap.h>

#include "nntp.h"
#include "config.h"
#include "globals.h"
#include "changi.h"


/* forward declarations */
void get_id(FILE * art_fp, char *id);


/*
 * open_valid_art -- determine if a given article name is valid;
 *              if it is, return a file pointer to the open article,
 *              along with a unique id of the article.
 *
 *      Parameters:     "artname" is a string containing the
 *                      name of the article.
 *                      "id" is space for us to put the article
 *                      id in.
 *
 *      Returns:        File pointer to the open article if the
 *                      article is valid; NULL otherwise
 *
 *      Side effects:   None.
 */

FILE *open_valid_art(PNEWSCLIENT pnc, char *artname, char *id)
{
    char path[_MAX_PATH];

    if (pnc -> art_fp != NULL) {
        if (pnc -> art_num == atol(artname)) {
	    if (fseek(pnc -> art_fp, 0L, SEEK_SET) < 0) {
		fclose(pnc -> art_fp);
		pnc -> art_fp = NULL;
	    }
	    else {
		strcpy(id, pnc -> art_id);
		return (pnc -> art_fp);
	    }
	}
	else {
	    fclose(pnc -> art_fp);
	    pnc -> art_fp = NULL;
	}
    }

    strcpy(path, pnc->mydir);
    strcat(path, "\\");
    strcat(path, artname);
    pnc -> art_fp = xopen(path, "r");

    if (pnc -> art_fp == NULL)
	return (NULL);

    get_id(pnc -> art_fp, id);
    strcpy(pnc -> art_id, id);
    pnc -> art_num = atol(artname);
    return (pnc -> art_fp);
}


/*
 * openartbyid -- open an article by message-id.
 *
 *      Arguments:      "msg_id" is the message-id of the article
 *                      to open.
 *
 *      Returns:        File pointer to opened article, or NULL if
 *                      the article was not in the history file or
 *                      could not be opened.
 *
 *      Side effects:   Opens article.
 */

FILE *openartbyid(char *msg_id)
{
    char path[_MAX_PATH];

    strcpy(path, cfg.newsdir);
    if (gethistart(cfg.historyfile, msg_id, path))
        return (xopen(path, "rt"));
    else
	return (NULL);
}


/*
 * check_ngperm -- check to see if they're allowed to see this
 * article by matching Newsgroups: and Distribution: line.
 *
 *      Parameters:     "fp" is the file pointer of this article.
 *
 *      Returns:        0 if they're not allowed to see it.
 *                      1 if they are.
 *
 *      Side effects:   None.
 */

int check_ngperm(FILE *fp, char **ngpermlist, int ngpermcount)
{
    int result = 1;
    char buf[MAXBUFLEN];
    register char *cp;
    register int i;
    char **ngarray = NULL;
    int ngcount = 0;

    if (ngpermcount) {
        while (fgets(buf, sizeof(buf), fp) != NULL) {
            if (buf[0] == '\n')
                /* End of header */
                break;
            if (buf[0] != 'N' && buf[0] != 'n')
                continue;
            if((cp = strchr(buf, '\n')) != NULL)
                *cp = '\0';
            if((cp = strchr(buf, ':')) == NULL)
                continue;
            *cp = '\0';
            if (!stricmp(buf, "newsgroups")) {
                ngcount = get_nglist(&ngarray, cp + 2);
                break;
            }
        }
    }

    rewind(fp);

    if (ngcount)
        result = ngmatch(s1strneql, 1, ngpermlist, ngpermcount, ngarray, ngcount);

    if (ngarray) {
        for (i = 0; ngarray[i]; i++)
            free(ngarray[i]);
        free(ngarray);
    }
    return (result);
}


/*
 * spew -- spew out the contents of a file to stdout, doing
 * the necessary cr-lf additions at the end.  Finish with
 * a "." on a line by itself, and an fflush(stdout).
 *
 *      Parameters:     "how" tells what part of the file we
 *                      want spewed:
 *                              ARTICLE   The entire thing.
 *                              HEAD      Just the first part.
 *                              BODY      Just the second part.
 *                      "fp" is the open file to spew from.
 *
 *      Returns:        Nothing.
 *
 *      Side effects:   Changes current position in file.
 */

void spew(int s, FILE * fp, int how)
{
    char line[NNTP_STRLEN];
    register char *cp;

    if (how == STAT)
	return;

    while (fgets(line, sizeof(line) - 6, fp) != NULL && *line != '\n') {
	if (how == BODY)		/* We need to skip this anyway */
	    continue;
	cp = strchr(line, '\n');
	if (cp != NULL)
	    *cp = '\0';
	if (*line == '.')
            if (so_puts(s, ".") == -1)
		return;
        if (so_puts(s, line) == -1)
	    return;
        if (so_puts(s, "\r\n") == -1)
	    return;
	if (cp == NULL) {
	    for (;;) {
		if ((fgets(line, sizeof(line) - 6, fp) == NULL)
			|| (strchr(line, '\n') != NULL))
		    break;
	    }
	}
    }

    if (how == HEAD) {
        so_puts(s, ".\r\n");
	return;
    }
    else if (how == ARTICLE) {
        if (so_puts(s, "\r\n") == -1)
	    return;
    }

    while (fgets(line, sizeof(line) - 6, fp) != NULL) {
	cp = strchr(line, '\n');
	if (cp != NULL)
	    *cp = '\0';
	if (*line == '.')
            if (so_puts(s, ".") == -1)
		return;
        if (so_puts(s, line) == -1)
	    return;
        if (so_puts(s, "\r\n") == -1)
	    return;

	if (cp == NULL) {
	    for (;;) {
		if ((fgets(line, sizeof(line) - 6, fp) == NULL)
			|| (strchr(line, '\n') != NULL))
		    break;
	    }
	}
    }
    so_puts(s, ".\r\n");
}


/*
 * get_id -- get the message id of the current article.
 *
 *      Parameters:     "art_fp" is a pointer to the open file.
 *                      "id" is space for the message ID.
 *
 *      Returns:        Nothing.
 *
 *      Side effects:   Seeks and rewinds on "art_fp".
 *                      Changes space pointed to by "id".
 */

void get_id(FILE * art_fp, char *id)
{
    char line[MAXBUFLEN];
    char *cp;

    while (fgets(line, sizeof(line), art_fp) != NULL) {
	if (*line == '\n')
	    break;
	if (*line == 'M' || *line == 'm') {	/* "Message-ID" */
	    if ((cp = strchr(line, ' ')) != NULL) {
		*cp = '\0';
		if (!stricmp(line, "Message-ID:")) {
		    strcpy(id, cp + 1);
		    if ((cp = strchr(id, '\n')) != NULL)
			*cp = '\0';
		    rewind(art_fp);
		    return;
		}
	    }
	}
    }
    rewind(art_fp);
    strcpy(id, "<0>");
}


/*
 * findart -- find an article number in the article array.
 *
 *      Parameters:     "artname" is a string containing
 *                      the name of the article.
 *
 *      Returns:        An index into "pnc->art_array",
 *                      or -1 if "artname" isn't in "art_array".
 *
 *      Side effects:   None.
 *
 *      Improvement:    Replace this linear search with a binary one.
 */

int findart(char *artname, long art_array[], int num_arts)
{
    register int i;
    long artnum;

    artnum = atol(artname);

    for (i = 0; i < num_arts; ++i)
	if (art_array[i] == artnum)
	    return (i);

    return (-1);
}


/*
 * get_distlist -- return a nicely set up array of distribution groups
 * along with a count, when given an NNTP-spec distribution list
 * in the form <dist1,dist2,...,distn>.
 *
 *      Parameters:             "array" is storage for our array,
 *                              set to point at some static data.
 *                              "list" is the NNTP distribution list.
 *
 *      Returns:                Number of distributions found.
 *                              -1 on error.
 *
 *      Side effects:           Changes static data area.
 */

int get_distlist(char ***array, char *list)
{
    char *cp;

    if (list[0] != '<')
	return (-1);

    cp = strchr(list + 1, '>');
    if (cp != NULL)
	*cp = '\0';
    else
	return (-1);

    for (cp = list + 1; *cp != '\0'; ++cp)
	if (*cp == ',')
	    *cp = ' ';
    return(parsit(list + 1, array));
}
[ RETURN TO DIRECTORY ]