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