home *** CD-ROM | disk | FTP | other *** search
- /* $Id: ngdata.c,v 4.4.3.1 1992/02/01 03:09:32 sob PATCH_3 sob $
- *
- * $Log: ngdata.c,v $
- * Revision 4.4.3.1 1992/02/01 03:09:32 sob
- * Release 4.4 Patchlevel 3
- *
- * Revision 4.4.2.1 1991/12/01 18:05:42 sob
- * Patchlevel 2 changes
- *
- * Revision 4.4.1.1 1991/09/25 19:38:08 sob
- * Some adaptions for CNEWS
- *
- * Revision 4.4 1991/09/09 20:23:31 sob
- * release 4.4
- *
- *
- *
- */
- /* This software is Copyright 1991 by Stan Barber.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- * use this software as long as: there is no monetary profit gained
- * specifically from the use or reproduction of this software, it is not
- * sold, rented, traded or otherwise marketed, and this copyright notice is
- * included prominently in any copy made.
- *
- * The author make no claims as to the fitness or correctness of this software
- * for any use whatsoever, and it is provided as is. Any use of this software
- * is at the user's own risk.
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "ndir.h"
- #include "rcstuff.h"
- #include "rn.h"
- #include "ng.h"
- #include "intrp.h"
- #include "final.h"
- #include "rcln.h"
- #include "util.h"
- #ifdef SERVER
- #include "server.h"
- #endif
- #include "INTERN.h"
- #include "ngdata.h"
-
- void
- ngdata_init()
- {
- char *cp;
-
- /* open the active file */
-
- #ifdef SERVER
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf(">LIST\n") ; FLUSH;
- #endif
- put_server("LIST"); /* tell server we want the active file */
- nntp_get(ser_line, sizeof(ser_line));
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf("<%s\n", ser_line) ; FLUSH;
- #endif
- if (*ser_line != CHAR_OK) { /* and then see if that's ok */
- fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
- finalize(1);
- }
- time(&lastactfetch);
-
- cp = filexp("%P/rrnact.%$"); /* make a temporary name */
- strcpy(active_name, cp);
- actfp = fos2open(active_name, "w+"); /* and get ready */
- if (actfp == Nullfp) {
- printf(cantopen,active_name) ; FLUSH;
- finalize(1);
- }
-
- activeitems = 0;
- while (1) {
- if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
- printf("Can't get active file from server:\n\
- transfer failed after %d entries\n", activeitems);
- finalize(1);
- }
- if (ser_line[0] == '.') /* while there's another line */
- break; /* get it and write it to */
- activeitems++;
- fputs(ser_line, actfp);
- putc('\n', actfp);
- }
-
- if (ferror(actfp)) {
- printf("Error writing to active file %s.\n", active_name) ; FLUSH;
- finalize(1);
- }
- #else /* not SERVER */
-
- /*** OS2: because we get settings out of uupc-rc-files,
- we don't use filexp to expand the filename ***/
- /* cp = filexp(ACTIVE); */
- /* cp = ACTIVE; */
- /* actfp = fos2open(cp,"r"); */
- /* if (actfp == Nullfp) { */
- /* cp = ACTIVE_OPT; */
- /* actfp = fos2open(cp,"r"); */
- /* bla if (actfp == Nullfp) { */
- /* printf(cantopen,cp) ; FLUSH; */
- /* finalize(1); */
- /* } */
- /* } */
- /* activeitems = 0; */
- /* count entries */
- /* while(fgets(buf,LBUFLEN,actfp) != NULL) */
- /* activeitems++; */
- ngdatansrv_init();
- #endif
- if (fseek(actfp,0L,0) == -1) { /* just get to the beginning */
- printf("Error seeking in active file.\n") ; FLUSH;
- finalize(1);
- }
-
- return;
- }
-
- /* find the maximum article number of a newsgroup */
-
- ART_NUM
- getngsize(num)
- register NG_NUM num;
- {
- register int len;
- register char *nam;
- char tmpbuf[80];
- ART_POS oldsoft;
- long last;
-
- nam = rcline[num];
- len = rcnums[num] - 1;
- softtries++;
- #ifdef DEBUGGING
- if (debug & DEB_SOFT_POINTERS)
- printf("Softptr = %ld\n",(long)softptr[num]) ; FLUSH;
- #endif
- oldsoft = softptr[num];
- fseek(actfp,100000L,1); /* hopefully this forces a reread */
- if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
- if (softptr[num] != oldsoft) {
- softmisses++;
- writesoft = TRUE;
- }
- }
- else {
- softptr[num] = 0;
- #ifdef USETHREADS
- if (RCCHAR(rcchar[num]) == ':')
- #else
- if (rcchar[num] == ':') /* unsubscribe quietly */
- #endif
- rcchar[num] = NEGCHAR;
- return TR_BOGUS; /* well, not so quietly, actually */
- }
-
- #ifdef DEBUGGING
- if (debug & DEB_SOFT_POINTERS) {
- printf("Should be %ld\n",(long)softptr[num]) ; FLUSH;
- }
- #endif
- {
- register char *s;
- ART_NUM tmp;
-
- for (s=tmpbuf+len+1; isdigit(*s); s++) ;
- if (tmp = atol(s))
- #ifdef MININACT
- #ifdef CACHEFIRST
- abs1st[num] = tmp;
- #else
- abs1st = tmp;
- #endif
- #endif
- if (!in_ng) {
- for (s++; isdigit(*s); s++) ;
- while (isspace(*s)) s++;
- switch (*s) {
- case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
- case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
- /* This shouldn't even occur. What are we doing in a non-existent
- group? Disallow it. */
- case 'x': return TR_BOGUS;
- /* what should be done about refiled groups? rn shouldn't even
- be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
- get the news there) */
- case '=': return TR_BOGUS;
- default: moderated = nullstr;
- }
- }
- }
- last = atol(tmpbuf+len+1);
- if (last < ngmax[num]) {
- #ifdef SERVER
- if (time(Null(time_t*)) - lastactfetch > MINFETCHTIME) {
- fclose(actfp);
- ngdata_init(); /* re-grab the active file */
- }
- #endif
- return ngmax[num];
- }
- return (ART_NUM)last;
- }
-
- /* determine the absolutely first existing article number */
- #ifdef SERVER
- ART_NUM
- getabsfirst(ngnum,ngsize)
- register NG_NUM ngnum;
- ART_NUM ngsize;
- {
- long a1st, last;
-
- #ifdef CACHEFIRST
- if (a1st = abs1st[ngnum])
- return (ART_NUM)a1st;
- #endif
- #ifdef MININACT
- getngsize(ngnum);
- # ifdef CACHEFIRST
- return abs1st[ngnum];
- # else
- return abs1st;
- # endif
- #else
- getngsize(ngnum); /* set moderated as side effect */
- sprintf(ser_line,"GROUP %s",rcline[ngnum]);
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf(">%s\n", ser_line) ; FLUSH;
- #endif
- put_server(ser_line);
- if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
- fprintf(stderr, "\nrrn: Unexpected close of server socket.\n");
- finalize(1);
- }
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf("<%s\n", ser_line) ; FLUSH;
- #endif
- if (*ser_line == CHAR_FATAL){
- fprintf(stderr,"\nrrn: %s\n",ser_line);
- finalize(1);
- }
- if (*ser_line != CHAR_OK) /* and then see if that's ok */
- a1st = ngsize+1; /* nothing there */
- else {
- (void) sscanf(ser_line,"%*d%*d%ld%ld",&a1st,&last);
- ngmax[ngnum] = last;
- }
- # ifdef CACHEFIRST
- abs1st[ngnum] = (ART_NUM)a1st;
- # endif
- return (ART_NUM)a1st;
- #endif
- }
- /* we already know the lowest article number with NNTP */
- ART_NUM
- getngmin(dirname,floor)
- char *dirname;
- ART_NUM floor;
- {
- return(floor); /* dirname not used */
- }
-
- #else /*SERVER*/
-
- ART_NUM
- getabsfirst(ngnum,ngsize)
- register NG_NUM ngnum;
- ART_NUM ngsize;
- {
- register ART_NUM a1st;
- #ifndef MININACT
- char dirname[MAXFILENAME];
- #endif
-
- #ifdef CACHEFIRST
- if (a1st = abs1st[ngnum])
- return a1st;
- #endif
- #ifdef MININACT
- getngsize(ngnum);
- # ifdef CACHEFIRST
- return abs1st[ngnum];
- # else
- return abs1st;
- # endif
- #else /* not MININACT */
- getngsize(ngnum); /* set moderate as side effect */
- sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
- a1st = getngmin(dirname,0L);
- if (!a1st) /* nothing there at all? */
- a1st = ngsize+1; /* aim them at end of newsgroup */
- # ifdef CACHEFIRST
- abs1st[ngnum] = a1st;
- # endif
- return a1st;
- #endif /* MININACT */
- }
-
- /* scan a directory for minimum article number greater than floor */
-
- ART_NUM
- getngmin(dirname,floor)
- char *dirname;
- ART_NUM floor;
- {
- register DIR *dirp;
- register struct DIRTYPE *dp;
- register ART_NUM min = 0;
- register ART_NUM maybe;
- register char *p;
- #ifdef notdef
- char tmpbuf[128];
- #endif
-
- change_bsl2sl(dirname);
- dirp = opendir(dirname);
- if (!dirp)
- return 0;
- while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
- if (((maybe = atol(dp->d_name)) < min || !min) && maybe > floor) {
- for (p = dp->d_name; *p; p++)
- if (!isdigit(*p))
- goto nope;
- #ifdef notdef
- /*
- * If newsgroup names ever go entirely numeric, then
- * this code will have to be reinserted.
- * For the time being, we assume that if a numeric name is
- * found, it must be an article (and not a directory).
- * This will avoid two stat(2) calls for those running
- * rn.
- */
- if (*dirname == '.' && !dirname[1])
- stat(dp->d_name, &filestat);
- else {
- sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
- stat(tmpbuf, &filestat);
- }
- if (! (filestat.st_mode & S_IFDIR))
- #endif
- min = maybe;
- }
- nope:
- ;
- }
- closedir(dirp);
- return min;
- }
- #endif
-