/*
* 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));
}