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