home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / trn_12.zip / src / rcln.c < prev    next >
C/C++ Source or Header  |  1993-12-05  |  14KB  |  491 lines

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