home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / trn / part10 / rcln.c < prev    next >
C/C++ Source or Header  |  1991-08-22  |  13KB  |  481 lines

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