home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / trn-3.3 / part04 / rcln.c < prev    next >
C/C++ Source or Header  |  1993-11-27  |  12KB  |  449 lines

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