home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / rn_4_3_blars.lzh / rcln.c < prev    next >
Text File  |  1990-08-22  |  12KB  |  464 lines

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