1: /* $Header: ngdata.c,v 4.3 85/05/01 11:44:38 lwall Exp $ 2: * 3: * $Log: ngdata.c,v $ 4: * Revision 4.3 85/05/01 11:44:38 lwall 5: * Baseline for release with 4.3bsd. 6: * 7: */ 8: 9: #include "EXTERN.h" 10: #include "common.h" 11: #include "ndir.h" 12: #include "rcstuff.h" 13: #include "rn.h" 14: #include "intrp.h" 15: #include "final.h" 16: #include "rcln.h" 17: #include "server.h" 18: #include "INTERN.h" 19: #include "ngdata.h" 20: 21: #ifdef SERVER 22: char active_name[256]; 23: #endif SERVER 24: 25: void 26: ngdata_init() 27: { 28: #ifdef SERVER 29: char ser_line[256]; 30: char *cp; 31: #endif 32: /* The following is only for systems that do not zero globals properly */ 33: #ifdef ZEROGLOB 34: # ifdef CACHEFIRST 35: for (i=0; i<MAXRCLINE; i++) 36: abs1st[i] = 0; 37: # endif 38: #endif /* ZEROGLOB */ 39: 40: /* open the active file */ 41: 42: #ifdef SERVER 43: 44: put_server("LIST"); /* tell server we want the active file */ 45: (void) get_server(ser_line, sizeof(ser_line)); 46: if (*ser_line != CHAR_OK) { /* and then see if that's ok */ 47: fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line); 48: finalize(1); 49: } 50: 51: cp = filexp("/tmp/rrnact.%$"); /* make a temporary name */ 52: strcpy(active_name, cp); 53: actfp = fopen(active_name, "w+"); /* and get ready */ 54: if (actfp == Nullfp) { 55: printf(cantopen,filexp(ACTIVE)) FLUSH; 56: finalize(1); 57: } 58: 59: while (get_server(ser_line, sizeof(ser_line)) >= 0) { /* while */ 60: if (ser_line[0] == '.') /* there's another line */ 61: break; /* get it and write it to */ 62: fputs(ser_line, actfp); 63: putc('\n', actfp); 64: } 65: 66: fseek(actfp,0L,0); /* just get to the beginning */ 67: 68: #else not SERVER 69: 70: actfp = fopen(filexp(ACTIVE),"r"); 71: 72: #endif SERVER 73: 74: if (actfp == Nullfp) { 75: printf(cantopen,filexp(ACTIVE)) FLUSH; 76: finalize(1); 77: } 78: } 79: 80: /* find the maximum article number of a newsgroup */ 81: 82: ART_NUM 83: getngsize(num) 84: register NG_NUM num; 85: { 86: register int len; 87: register char *nam; 88: char tmpbuf[80]; 89: ART_POS oldsoft; 90: 91: nam = rcline[num]; 92: len = rcnums[num] - 1; 93: softtries++; 94: #ifdef DEBUGGING 95: if (debug & DEB_SOFT_POINTERS) 96: printf("Softptr = %ld\n",(long)softptr[num]) FLUSH; 97: #endif 98: oldsoft = softptr[num]; 99: if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) { 100: if (softptr[num] != oldsoft) { 101: softmisses++; 102: writesoft = TRUE; 103: } 104: } 105: else { 106: softptr[num] = 0; 107: if (rcchar[num] == ':') /* unsubscribe quietly */ 108: rcchar[num] = NEGCHAR; 109: return TR_BOGUS; /* well, not so quietly, actually */ 110: } 111: 112: #ifdef DEBUGGING 113: if (debug & DEB_SOFT_POINTERS) { 114: printf("Should be %ld\n",(long)softptr[num]) FLUSH; 115: } 116: #endif 117: #ifdef MININACT 118: { 119: register char *s; 120: char *getval(); 121: ART_NUM tmp; 122: 123: for (s=tmpbuf+len+1; isdigit(*s); s++) ; 124: if (tmp = atol(s)) 125: #ifdef CACHEFIRST 126: abs1st[num] = tmp; 127: #else 128: abs1st = tmp; 129: #endif 130: if (!in_ng) { 131: for (s++; isdigit(*s); s++) ; 132: while (isspace(*s)) s++; 133: switch (*s) { 134: case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break; 135: case 'm': moderated = getval("MODSTRING", " (moderated)"); break; 136: /* This shouldn't even occur. What are we doing in a non-existent 137: group? Disallow it. */ 138: case 'x': return TR_BOGUS; 139: /* what should be done about refiled groups? rn shouldn't even 140: be in them (ie, if sci.aquaria is refiled to rec.aquaria, then 141: get the news there) */ 142: case '=': return TR_BOGUS; 143: default: moderated = nullstr; 144: } 145: } 146: } 147: #endif 148: return atol(tmpbuf+len+1); 149: } 150: 151: ACT_POS 152: findact(outbuf,nam,len,suggestion) 153: char *outbuf; 154: char *nam; 155: int len; 156: long suggestion; 157: { 158: ACT_POS retval; 159: 160: fseek(actfp,100000L,1); /* hopefully this forces a reread */ 161: if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 || 162: fgets(outbuf,80,actfp) == Nullch || 163: outbuf[len] != ' ' || 164: strnNE(outbuf,nam,len)) { 165: #ifdef DEBUGGING 166: if (debug & DEB_SOFT_POINTERS) 167: printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len) 168: FLUSH; 169: #endif 170: fseek(actfp,0L,0); 171: #ifndef lint 172: retval = (ACT_POS)ftell(actfp); 173: #else 174: retval = Null(ACT_POS); 175: #endif lint 176: while (fgets(outbuf,80,actfp) != Nullch) { 177: if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len)) 178: return retval; 179: #ifndef lint 180: retval = (ACT_POS) ftell(actfp); 181: #endif lint 182: } 183: return (ACT_POS) -1; /* well, not so quietly, actually */ 184: } 185: else 186: #ifndef lint 187: return (ACT_POS) suggestion; 188: #else 189: return retval; 190: #endif lint 191: /*NOTREACHED*/ 192: } 193: 194: /* determine the absolutely first existing article number */ 195: 196: ART_NUM 197: getabsfirst(ngnum,ngsize) 198: register NG_NUM ngnum; 199: ART_NUM ngsize; 200: { 201: register ART_NUM a1st; 202: #ifndef MININACT 203: char dirname[MAXFILENAME]; 204: #endif 205: 206: #ifdef CACHEFIRST 207: if (a1st = abs1st[ngnum]) 208: return a1st; 209: #endif 210: #ifdef MININACT 211: getngsize(ngnum); 212: # ifdef CACHEFIRST 213: return abs1st[ngnum]; 214: # else 215: return abs1st; 216: # endif 217: #else not MININACT 218: sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum])); 219: a1st = getngmin(dirname,0L); 220: if (!a1st) /* nothing there at all? */ 221: a1st = ngsize+1; /* aim them at end of newsgroup */ 222: # ifdef CACHEFIRST 223: abs1st[ngnum] = a1st; 224: # endif 225: return a1st; 226: #endif MININACT 227: } 228: 229: /* scan a directory for minimum article number greater than floor */ 230: 231: ART_NUM 232: getngmin(dirname,floor) 233: char *dirname; 234: ART_NUM floor; 235: { 236: register DIR *dirp; 237: register struct direct *dp; 238: register ART_NUM min = 1000000; 239: register ART_NUM maybe; 240: register char *p; 241: char tmpbuf[128]; 242: 243: dirp = opendir(dirname); 244: if (!dirp) 245: return 0; 246: while ((dp = readdir(dirp)) != Null(struct direct *)) { 247: if ((maybe = atol(dp->d_name)) < min && maybe > floor) { 248: for (p = dp->d_name; *p; p++) 249: if (!isdigit(*p)) 250: goto nope; 251: if (*dirname == '.' && !dirname[1]) 252: stat(dp->d_name, &filestat); 253: else { 254: sprintf(tmpbuf,"%s/%s",dirname,dp->d_name); 255: stat(tmpbuf, &filestat); 256: } 257: if (! (filestat.st_mode & S_IFDIR)) 258: min = maybe; 259: } 260: nope: 261: ; 262: } 263: closedir(dirp); 264: return min==1000000 ? 0 : min; 265: }