home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / UUPC11XT.ZIP / RN / RCLN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-21  |  16.1 KB  |  579 lines

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