home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trn / part05 / rcln.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  12.7 KB  |  484 lines

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