1: /* $Header: rcln.c,v 4.3.1.3 86/11/04 15:57:03 lwall Exp $
   2:  *
   3:  * $Log:	rcln.c,v $
   4:  * Revision 4.3.1.3  86/11/04  15:57:03  lwall
   5:  * realloc attempted on unalloced area.
   6:  *
   7:  * Revision 4.3.1.2  85/07/23  17:39:08  lwall
   8:  * Oops, was freeing a static buf on -c in checkexpired.
   9:  *
  10:  * Revision 4.3.1.1  85/05/10  11:37:08  lwall
  11:  * Branch for patches.
  12:  *
  13:  * Revision 4.3  85/05/01  11:45:36  lwall
  14:  * Baseline for release with 4.3bsd.
  15:  *
  16:  */
  17: 
  18: #include "EXTERN.h"
  19: #include "common.h"
  20: #include "util.h"
  21: #include "rcstuff.h"
  22: #include "ngdata.h"
  23: #include "INTERN.h"
  24: #include "rcln.h"
  25: 
  26: void
  27: rcln_init()
  28: {
  29:     ;
  30: }
  31: 
  32: #ifdef CATCHUP
  33: void
  34: catch_up(ngx)
  35: NG_NUM ngx;
  36: {
  37:     char tmpbuf[128];
  38: 
  39: #ifdef VERBOSE
  40:     IF(verbose)
  41:     printf("\nMarking %s as all read.\n",rcline[ngx]) FLUSH;
  42:     ELSE
  43: #endif
  44: #ifdef TERSE
  45:     fputs("\nMarked read\n",stdout) FLUSH;
  46: #endif
  47:     sprintf(tmpbuf,"%s: 1-%ld", rcline[ngx],(long)getngsize(ngx));
  48:     free(rcline[ngx]);
  49:     rcline[ngx] = savestr(tmpbuf);
  50:     *(rcline[ngx] + rcnums[ngx] - 1) = '\0';
  51:     write_rc();
  52: }
  53: #endif
  54: 
  55: /* add an article number to a newsgroup, if it isn't already read */
  56: 
  57: int
  58: addartnum(artnum,ngnam)
  59: ART_NUM artnum;
  60: char *ngnam;
  61: {
  62:     register NG_NUM ngnum = find_ng(ngnam);
  63:     register char *s, *t, *maxt = Nullch;
  64:     ART_NUM min = 0, max = -1, lastnum = 0;
  65:     char *mbuf;
  66:     bool morenum;
  67: 
  68:     if (!artnum)
  69:     return 0;
  70:     if (ngnum == nextrcline || !rcnums[ngnum])
  71:                     /* not found in newsrc? */
  72:     return 0;
  73: #ifdef CACHEFIRST
  74:     if (!abs1st[ngnum])
  75: #else
  76:     if (!toread[ngnum])
  77: #endif
  78:                     /* now is a good time to trim down */
  79:     set_toread(ngnum);      /* the list due to expires if we */
  80:                     /* have not yet. */
  81: #ifdef DEBUGGING
  82:     if (artnum > ngmax[ngnum] + 10  /* allow for incoming articles */
  83:        ) {
  84:     printf("\nCorrupt Xref line!!!  %ld --> %s(1..%ld)\n",
  85:         artnum,ngnam,
  86:         ngmax[ngnum]) FLUSH;
  87:     paranoid = TRUE;        /* paranoia reigns supreme */
  88:     return -1;          /* hope this was the first newsgroup */
  89:     }
  90: #endif
  91: 
  92:     if (toread[ngnum] == TR_BOGUS)
  93:     return 0;
  94: #ifdef DEBUGGING
  95:     if (debug & DEB_XREF_MARKER) {
  96:     printf("%ld->\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
  97:       rcline[ngnum] + rcnums[ngnum]) FLUSH;
  98:     }
  99: #endif
 100:     s = rcline[ngnum] + rcnums[ngnum];
 101:     while (*s == ' ') s++;      /* skip spaces */
 102:     t = s;
 103:     while (isdigit(*s) && artnum >= (min = atol(s))) {
 104:                     /* while it might have been read */
 105:     for (t = s; isdigit(*t); t++) ; /* skip number */
 106:     if (*t == '-') {        /* is it a range? */
 107:         t++;            /* skip to next number */
 108:         if (artnum <= (max = atol(t)))
 109:         return 0;       /* it is in range => already read */
 110:         lastnum = max;      /* remember it */
 111:         maxt = t;           /* remember position in case we */
 112:                     /* want to overwrite the max */
 113:         while (isdigit(*t)) t++;    /* skip second number */
 114:     }
 115:     else {
 116:         if (artnum == min)      /* explicitly a read article? */
 117:         return 0;
 118:         lastnum = min;      /* remember what the number was */
 119:         maxt = Nullch;      /* last one was not a range */
 120:     }
 121:     while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
 122:     s = t;
 123:     }
 124: 
 125:     /* we have not read it, so insert the article number before s */
 126: 
 127:     morenum = isdigit(*s);      /* will it need a comma after? */
 128:     *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
 129:     mbuf = safemalloc((MEM_SIZE)(strlen(s) + (s-rcline[ngnum]) + 8));
 130:     strcpy(mbuf,rcline[ngnum]);     /* make new rc line */
 131:     if (maxt && lastnum && artnum == lastnum+1)
 132:                         /* can we just extend last range? */
 133:     t = mbuf + (maxt-rcline[ngnum]);/* then overwrite previous max */
 134:     else {
 135:     t = mbuf + (t-rcline[ngnum]);   /* point t into new line instead */
 136:     if (lastnum) {          /* have we parsed any line? */
 137:         if (!morenum)       /* are we adding to the tail? */
 138:         *t++ = ',';     /* supply comma before */
 139:         if (!maxt && artnum == lastnum+1 && *(t-1) == ',')
 140:                     /* adjacent singletons? */
 141:         *(t-1) = '-';       /* turn them into a range */
 142:     }
 143:     }
 144:     if (morenum) {          /* is there more to life? */
 145:     if (min == artnum+1) {      /* can we consolidate further? */
 146:         bool range_before = (*(t-1) == '-');
 147:         bool range_after;
 148:         char *nextmax;
 149: 
 150:         for (nextmax = s; isdigit(*nextmax); nextmax++) ;
 151:         range_after = *nextmax++ == '-';
 152: 
 153:         if (range_before)
 154:         *t = '\0';      /* artnum is redundant */
 155:         else
 156:         sprintf(t,"%ld-",(long)artnum);/* artnum will be new min */
 157: 
 158:         if (range_after)
 159:         s = nextmax;        /* *s is redundant */
 160:     /*  else
 161: 		s = s */      /* *s is new max */
 162:     }
 163:     else
 164:         sprintf(t,"%ld,",(long)artnum); /* put the number and comma */
 165:     }
 166:     else
 167:     sprintf(t,"%ld",(long)artnum);  /* put the number there (wherever) */
 168:     strcat(t,s);            /* copy remainder of line */
 169: #ifdef DEBUGGING
 170:     if (debug & DEB_XREF_MARKER) {
 171:     printf("%s\n",mbuf) FLUSH;
 172:     }
 173: #endif
 174:     free(rcline[ngnum]);
 175:     rcline[ngnum] = mbuf;       /* pull the switcheroo */
 176:     *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
 177:                     /* wipe out : or ! */
 178:     if (toread[ngnum] > TR_NONE)    /* lest we turn unsub into bogus */
 179:     --toread[ngnum];
 180:     return 0;
 181: }
 182: 
 183: #ifdef MCHASE
 184: /* delete an article number from a newsgroup, if it is there */
 185: 
 186: void
 187: subartnum(artnum,ngnam)
 188: register ART_NUM artnum;
 189: char *ngnam;
 190: {
 191:     register NG_NUM ngnum = find_ng(ngnam);
 192:     register char *s, *t;
 193:     register ART_NUM min, max;
 194:     char *mbuf;
 195:     int curlen;
 196: 
 197:     if (!artnum)
 198:     return;
 199:     if (ngnum == nextrcline || !rcnums[ngnum])
 200:     return;             /* not found in newsrc? */
 201: #ifdef DEBUGGING
 202:     if (debug & DEB_XREF_MARKER) {
 203:     printf("%ld<-\n%s%c%s\n",(long)artnum,rcline[ngnum],rcchar[ngnum],
 204:       rcline[ngnum] + rcnums[ngnum]) FLUSH;
 205:     }
 206: #endif
 207:     s = rcline[ngnum] + rcnums[ngnum];
 208:     while (*s == ' ') s++;      /* skip spaces */
 209: 
 210:     /* a little optimization, since it is almost always the last number */
 211: 
 212:     for (t=s; *t; t++) ;        /* find end of string */
 213:     curlen = t-rcline[ngnum];
 214:     for (t--; isdigit(*t); t--) ;   /* find previous delim */
 215:     if (*t == ',' && atol(t+1) == artnum) {
 216:     *t = '\0';
 217:     if (toread[ngnum] >= TR_NONE)
 218:         ++toread[ngnum];
 219: #ifdef DEBUGGING
 220:     if (debug & DEB_XREF_MARKER)
 221:         printf("%s%c %s\n",rcline[ngnum],rcchar[ngnum],s) FLUSH;
 222: #endif
 223:     return;
 224:     }
 225: 
 226:     /* not the last number, oh well, we may need the length anyway */
 227: 
 228:     while (isdigit(*s) && artnum >= (min = atol(s))) {
 229:                     /* while it might have been read */
 230:     for (t = s; isdigit(*t); t++) ; /* skip number */
 231:     if (*t == '-') {        /* is it a range? */
 232:         t++;            /* skip to next number */
 233:         max = atol(t);
 234:         while (isdigit(*t)) t++;    /* skip second number */
 235:         if (artnum <= max) {
 236:                     /* it is in range => already read */
 237:         if (artnum == min) {
 238:             min++;
 239:             artnum = 0;
 240:         }
 241:         else if (artnum == max) {
 242:             max--;
 243:             artnum = 0;
 244:         }
 245:         *(rcline[ngnum] + rcnums[ngnum] - 1) = rcchar[ngnum];
 246:         mbuf = safemalloc((MEM_SIZE)(curlen + (artnum?15:2)));
 247:         *s = '\0';
 248:         strcpy(mbuf,rcline[ngnum]); /* make new rc line */
 249:         s = mbuf + (s-rcline[ngnum]);
 250:                     /* point s into mbuf now */
 251:         if (artnum) {       /* split into two ranges? */
 252:             prange(s,min,artnum-1);
 253:             s += strlen(s);
 254:             *s++ = ',';
 255:             prange(s,artnum+1,max);
 256:         }
 257:         else            /* only one range */
 258:             prange(s,min,max);
 259:         s += strlen(s);
 260:         strcpy(s,t);        /* copy remainder over */
 261: #ifdef DEBUGGING
 262:         if (debug & DEB_XREF_MARKER) {
 263:             printf("%s\n",mbuf) FLUSH;
 264:         }
 265: #endif
 266:         free(rcline[ngnum]);
 267:         rcline[ngnum] = mbuf;   /* pull the switcheroo */
 268:         *(rcline[ngnum] + rcnums[ngnum] - 1) = '\0';
 269:                     /* wipe out : or ! */
 270:         if (toread[ngnum] >= TR_NONE)
 271:             ++toread[ngnum];
 272:         return;
 273:         }
 274:     }
 275:     else {
 276:         if (artnum == min) {    /* explicitly a read article? */
 277:         if (*t == ',')      /* pick a comma, any comma */
 278:             t++;
 279:         else if (s[-1] == ',')
 280:             s--;
 281:         else if (s[-2] == ',')  /* (in case of space) */
 282:             s -= 2;
 283:         strcpy(s,t);        /* no need to realloc */
 284:         if (toread[ngnum] >= TR_NONE)
 285:             ++toread[ngnum];
 286: #ifdef DEBUGGING
 287:         if (debug & DEB_XREF_MARKER) {
 288:             printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
 289:               rcline[ngnum] + rcnums[ngnum]) FLUSH;
 290:         }
 291: #endif
 292:         return;
 293:         }
 294:     }
 295:     while (*t && !isdigit(*t)) t++; /* skip comma and any spaces */
 296:     s = t;
 297:     }
 298: }
 299: 
 300: void
 301: prange(where,min,max)
 302: char *where;
 303: ART_NUM min,max;
 304: {
 305:     if (min == max)
 306:     sprintf(where,"%ld",(long)min);
 307:     else
 308:     sprintf(where,"%ld-%ld",(long)min,(long)max);
 309: }
 310: #endif
 311: 
 312: /* calculate the number of unread articles for a newsgroup */
 313: 
 314: void
 315: set_toread(ngnum)
 316: register NG_NUM ngnum;
 317: {
 318:     register char *s, *c, *h;
 319:     char tmpbuf[64], *mybuf = tmpbuf;
 320:     char *nums;
 321:     int length;
 322: #ifdef CACHEFIRST
 323:     bool virgin_ng = (!abs1st[ngnum]);
 324: #endif
 325:     ART_NUM ngsize = getngsize(ngnum);
 326:     ART_NUM unread = ngsize;
 327:     ART_NUM newmax;
 328: 
 329: #ifdef DEBUGGING
 330:     ngmax[ngnum] = ngsize;      /* for checking out-of-range Xrefs */
 331: #endif
 332:     if (ngsize == TR_BOGUS) {
 333:     printf("Warning!  Bogus newsgroup: %s\n",rcline[ngnum]) FLUSH;
 334:     paranoid = TRUE;
 335:     toread[ngnum] = TR_BOGUS;
 336:     return;
 337:     }
 338: #ifdef CACHEFIRST
 339:     if (virgin_ng)
 340: #else
 341:     if (!toread[ngnum])
 342: #endif
 343:     {
 344:     sprintf(tmpbuf," 1-%ld",(long)ngsize);
 345:     if (strNE(tmpbuf,rcline[ngnum]+rcnums[ngnum]))
 346:         checkexpired(ngnum,ngsize); /* this might realloc rcline */
 347:     }
 348:     nums = rcline[ngnum]+rcnums[ngnum];
 349:     length = strlen(nums);
 350:     if (length >= 60)
 351:     mybuf = safemalloc((MEM_SIZE)(length+5));
 352:     strcpy(mybuf,nums);
 353:     mybuf[length++] = ',';
 354:     mybuf[length] = '\0';
 355:     for (s = mybuf; isspace(*s); s++)
 356:         ;
 357:     for ( ; (c = index(s,',')) != Nullch ; s = ++c) {
 358:                     /* for each range */
 359:     *c = '\0';          /* keep index from running off */
 360:     if ((h = index(s,'-')) != Nullch)   /* find - in range, if any */
 361:         unread -= (newmax = atol(h+1)) - atol(s) + 1;
 362:     else if (newmax = atol(s))
 363:         unread--;       /* recalculate length */
 364:     if (newmax > ngsize) {  /* paranoia check */
 365:         unread = -1;
 366:         break;
 367:     }
 368:     }
 369:     if (unread >= 0)        /* reasonable number? */
 370:     toread[ngnum] = (ART_UNREAD)unread;
 371:                     /* remember how many are left */
 372:     else {              /* SOMEONE RESET THE NEWSGROUP!!! */
 373:     toread[ngnum] = (ART_UNREAD)ngsize;
 374:                     /* assume nothing carried over */
 375:     printf("Warning!  Somebody reset %s--assuming nothing read.\n",
 376:         rcline[ngnum]) FLUSH;
 377:     *(rcline[ngnum] + rcnums[ngnum]) = '\0';
 378:     paranoid = TRUE;        /* enough to make a guy paranoid */
 379:     }
 380:     if (mybuf != tmpbuf)
 381:     free(mybuf);
 382:     if (rcchar[ngnum] == NEGCHAR)
 383:     toread[ngnum] = TR_UNSUB;
 384: }
 385: 
 386: /* make sure expired articles are marked as read */
 387: 
 388: void
 389: checkexpired(ngnum,ngsize)
 390: register NG_NUM ngnum;
 391: ART_NUM ngsize;
 392: {
 393:     register ART_NUM a1st = getabsfirst(ngnum,ngsize);
 394:     register char *s, *t;
 395:     register ART_NUM num, lastnum = 0;
 396:     char *mbuf, *newnum;
 397: 
 398:     if (a1st<=1)
 399:     return;
 400: #ifdef DEBUGGING
 401:     if (debug & DEB_XREF_MARKER) {
 402:     printf("1-%ld->\n%s%c%s\n",(long)(a1st-1),rcline[ngnum],rcchar[ngnum],
 403:       rcline[ngnum] + rcnums[ngnum]) FLUSH;
 404:     }
 405: #endif
 406:     for (s = rcline[ngnum] + rcnums[ngnum]; isspace(*s); s++);
 407:     while (*s && (num = atol(s)) <= a1st) {
 408:     while (isdigit(*s)) s++;
 409:     while (*s && !isdigit(*s)) s++;
 410:     lastnum = num;
 411:     }
 412:     if (*s) {
 413:     if (s[-1] == '-') {         /* landed in a range? */
 414:         if (lastnum != 1)
 415:         sprintf(rcline[ngnum]+rcnums[ngnum]," 1-%s",s);
 416:         goto ret;
 417:     }
 418:     }
 419:     /* s now points to what should follow first range */
 420:     if (s - rcline[ngnum] > rcnums[ngnum] + 10)
 421:     mbuf = rcline[ngnum];
 422:     else {
 423:     mbuf = safemalloc((MEM_SIZE)(rcnums[ngnum] + strlen(s) + 10));
 424:     strcpy(mbuf,rcline[ngnum]);
 425:     }
 426:     newnum = t = mbuf+rcnums[ngnum];
 427:     sprintf(t," 1-%ld",(long)(a1st - (lastnum != a1st)));
 428:     if (*s) {
 429:     t += strlen(t);
 430:     *t++ = ',';
 431:     strcpy(t,s);
 432:     }
 433:     if (!checkflag && mbuf == rcline[ngnum]) {
 434:     rcline[ngnum] = saferealloc(rcline[ngnum],
 435:         (MEM_SIZE)(rcnums[ngnum] + strlen(newnum) + 1));
 436:     }
 437:     else {
 438:     if (!checkflag)
 439:         free(rcline[ngnum]);
 440:     rcline[ngnum] = mbuf;
 441:     }
 442: 
 443: ret:;       /* semicolon in case DEBUGGING undefined */
 444: #ifdef DEBUGGING
 445:     if (debug & DEB_XREF_MARKER) {
 446:     printf("%s%c%s\n",rcline[ngnum],rcchar[ngnum],
 447:       rcline[ngnum] + rcnums[ngnum]) FLUSH;
 448:     }
 449: #endif
 450: }

Defined functions

addartnum defined in line 57; used 2 times
catch_up defined in line 33; used 3 times
checkexpired defined in line 388; used 2 times
prange defined in line 300; used 4 times
rcln_init defined in line 26; used 2 times
set_toread defined in line 314; used 10 times
subartnum defined in line 186; used 2 times
Last modified: 1987-03-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3829
Valid CSS Valid XHTML 1.0 Strict