home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume23 / trn / part11 / ngdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-22  |  8.7 KB  |  390 lines

  1. /* $Header: ngdata.c,v 4.3.3.2 91/01/16 03:18:21 davison Trn $
  2.  *
  3.  * $Log:    ngdata.c,v $
  4.  * Revision 4.3.3.2  91/01/16  03:18:21  davison
  5.  * Integrated rn patches 48-54.  Fixed bug in ZEROGLOB code.
  6.  * 
  7.  * Revision 4.3.3.1  90/07/21  20:28:27  davison
  8.  * Initial Trn Release
  9.  * 
  10.  * Revision 4.3.2.11  90/11/22  16:14:34  sob
  11.  * Added changes to accomodate picky C preprocessors
  12.  * 
  13.  * Revision 4.3.2.10  90/04/14  22:05:15  sob
  14.  * Removed redundant declaration of active_name
  15.  * 
  16.  * Revision 4.3.2.9  90/03/22  23:04:55  sob
  17.  * Fixes provided by Wayne Davison <drivax!davison>
  18.  * 
  19.  * Revision 4.3.2.8  90/03/17  20:50:51  sob
  20.  * Fixes provided by stewart@netxcom.iad-nxe.global-mis.dhl.com to handle
  21.  * flaky transfers of the active file from the server.
  22.  * 
  23.  * Revision 4.3.2.7  90/03/17  17:11:08  sob
  24.  * Added support for CNEWS active file flags.
  25.  *
  26.  * Revision 4.3.2.6  89/12/08  22:42:04  sob
  27.  * Corrected typo in an #ifdef statement pointed out by
  28.  * jik@pit-manager.mit.edu
  29.  * 
  30.  * Revision 4.3.2.5  89/11/28  01:51:14  sob
  31.  * Removed redundant #include directive.
  32.  * 
  33.  * Revision 4.3.2.4  89/11/27  01:31:07  sob
  34.  * Altered NNTP code per ideas suggested by Bela Lubkin
  35.  * <filbo@gorn.santa-cruz.ca.us>
  36.  * 
  37.  * Revision 4.3.2.3  89/11/08  02:41:40  sob
  38.  * Removed unneeded subroutine.
  39.  * 
  40.  * Revision 4.3.2.2  89/11/08  02:24:31  sob
  41.  * Integrated modifications from other RRN patches colleceted from USENET
  42.  * 
  43.  * Revision 4.3.2.1  89/11/06  00:42:43  sob
  44.  * Added RRN support from NNTP 1.5
  45.  * 
  46.  * Revision 4.3  85/05/01  11:44:38  lwall
  47.  * Baseline for release with 4.3bsd.
  48.  * 
  49.  */
  50.  
  51. #include "EXTERN.h"
  52. #include "common.h"
  53. #include "ndir.h"
  54. #include "rcstuff.h"
  55. #include "rn.h"
  56. #include "intrp.h"
  57. #include "final.h"
  58. #include "rcln.h"
  59. #include "util.h"
  60. #ifdef SERVER
  61. #include "server.h"
  62. #endif
  63. #include "INTERN.h"
  64. #include "ngdata.h"
  65.  
  66. void
  67. ngdata_init()
  68. {
  69. #ifdef SERVER
  70.     char ser_line[256];
  71.     int entries;
  72. #endif
  73.     char *cp;
  74.  
  75. /* The following is only for systems that do not zero globals properly */
  76. #ifdef ZEROGLOB
  77. # ifdef CACHEFIRST
  78.   {
  79.     int i;
  80.     for (i=0; i<MAXRCLINE; i++)
  81.     abs1st[i] = 0;
  82.   }
  83. # endif
  84. #endif    /* ZEROGLOB */
  85.  
  86.     /* open the active file */
  87.  
  88. #ifdef SERVER
  89.  
  90. #ifdef USETHREADS
  91.     if (use_threads) {
  92.     cp = filexp(ACTIVE2);
  93.     actfp = fopen(cp,"r");
  94.     if (actfp == Nullfp) {
  95.         printf(cantopen,cp) FLUSH;
  96.         finalize(1);
  97.     }
  98.     return;
  99.     }
  100. #endif
  101.  
  102.     put_server("LIST");        /* tell server we want the active file */
  103.     get_server(ser_line, sizeof(ser_line));
  104.     if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  105.     fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
  106.     finalize(1);
  107.     }
  108.  
  109.     cp = filexp("/tmp/rrnact.%$");    /* make a temporary name */
  110.     strcpy(active_name, cp);
  111.     actfp = fopen(active_name, "w+");    /* and get ready */
  112.     if (actfp == Nullfp) {
  113.     printf(cantopen,active_name) FLUSH;
  114.     finalize(1);
  115.     }
  116.  
  117.     entries = 0;
  118.     while (1) {
  119.     if (get_server(ser_line, sizeof(ser_line)) < 0) {
  120.         printf("Can't get active file from server:\ntransfer failed after %d entries\n", entries);
  121.         finalize(1);
  122.     }
  123.     if (ser_line[0] == '.')        /* while there's another line */
  124.         break;            /* get it and write it to */
  125.     entries++;
  126.     fputs(ser_line, actfp);
  127.     putc('\n', actfp);
  128.     }
  129.  
  130.     fseek(actfp,0L,0);        /* just get to the beginning */
  131.  
  132. #else /* not SERVER */
  133.  
  134. #ifdef USETHREADS
  135.     if (use_threads)
  136.     cp = filexp(ACTIVE2);
  137.     else
  138. #endif
  139.     cp = filexp(ACTIVE);
  140.     actfp = fopen(cp,"r");
  141.     if (actfp == Nullfp) {
  142.     printf(cantopen,cp) FLUSH;
  143.     finalize(1);
  144.     }
  145. #endif
  146. }
  147.  
  148. /* find the maximum article number of a newsgroup */
  149.  
  150. ART_NUM
  151. getngsize(num)
  152. register NG_NUM num;
  153. {
  154.     register int len;
  155.     register char *nam;
  156.     char tmpbuf[80];
  157.     ART_POS oldsoft;
  158.  
  159.     nam = rcline[num];
  160.     len = rcnums[num] - 1;
  161.     softtries++;
  162. #ifdef DEBUGGING
  163.     if (debug & DEB_SOFT_POINTERS)
  164.     printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
  165. #endif
  166.     oldsoft = softptr[num];
  167.     if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
  168.     if (softptr[num] != oldsoft) {
  169.         softmisses++;
  170.         writesoft = TRUE;
  171.     }
  172.     }
  173.     else {
  174.     softptr[num] = 0;
  175.     if (rcchar[num] == ':')        /* unsubscribe quietly */
  176.         rcchar[num] = NEGCHAR;
  177.     return TR_BOGUS;        /* well, not so quietly, actually */
  178.     }
  179.     
  180. #ifdef DEBUGGING
  181.     if (debug & DEB_SOFT_POINTERS) {
  182.     printf("Should be %ld\n",(long)softptr[num]) FLUSH;
  183.     }
  184. #endif
  185. #ifdef MININACT
  186.     {
  187.     register char *s, ch;
  188.     ART_NUM tmp;
  189.  
  190.     for (s=tmpbuf+len+1; isdigit(*s); s++) ;
  191.     if (tmp = atol(s))
  192. #ifdef CACHEFIRST
  193.         abs1st[num] = tmp;
  194. #else
  195.         abs1st = tmp;
  196. #endif
  197.     if (!in_ng) {
  198.         for (s++; isdigit(*s); s++) ;
  199.         while (isspace(*s)) s++;
  200.         ch = *s;
  201. #ifdef USETHREADS
  202.         if (isupper(ch)) {
  203.         ch = tolower(ch);
  204.         ThreadedGroup = FALSE;
  205.         } else
  206.         ThreadedGroup = use_threads;
  207. #endif
  208.         switch (ch) {
  209.         case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
  210.         case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
  211.         /* This shouldn't even occur.  What are we doing in a non-existent
  212.            group?  Disallow it. */
  213.         case 'x': return TR_BOGUS;
  214.         /* what should be done about refiled groups?  rn shouldn't even
  215.            be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
  216.            get the news there) */
  217.         case '=': return TR_BOGUS;
  218.         default: moderated = nullstr;
  219.         }
  220.     }
  221.     }
  222. #endif
  223.     return atol(tmpbuf+len+1);
  224. }
  225.  
  226. ACT_POS
  227. findact(outbuf,nam,len,suggestion)
  228. char *outbuf;
  229. char *nam;
  230. int len;
  231. long suggestion;
  232. {
  233.     ACT_POS retval;
  234.  
  235.     fseek(actfp,100000L,1);    /* hopefully this forces a reread */
  236.     if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
  237.       fgets(outbuf,80,actfp) == Nullch ||
  238.       outbuf[len] != ' ' ||
  239.       strnNE(outbuf,nam,len)) {
  240. #ifdef DEBUGGING
  241.     if (debug & DEB_SOFT_POINTERS)
  242.         printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
  243.           FLUSH;
  244. #endif
  245.     fseek(actfp,0L,0);
  246. #ifndef lint
  247.     retval = (ACT_POS)ftell(actfp);
  248. #else
  249.     retval = Null(ACT_POS);
  250. #endif /* lint */
  251.     while (fgets(outbuf,80,actfp) != Nullch) {
  252.         if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
  253.         return retval;
  254. #ifndef lint
  255.         retval = (ACT_POS) ftell(actfp);
  256. #endif /* lint */
  257.     }
  258.     return (ACT_POS) -1;        /* well, not so quietly, actually */
  259.     }
  260.     else
  261. #ifndef lint
  262.     return (ACT_POS) suggestion;
  263. #else
  264.     return retval;
  265. #endif /* lint */
  266.     /*NOTREACHED*/
  267. }
  268.  
  269. /* determine the absolutely first existing article number */
  270. #ifdef SERVER
  271. ART_NUM
  272. getabsfirst(ngnum,ngsize)
  273. register NG_NUM ngnum;
  274. ART_NUM ngsize;
  275. {
  276.     register ART_NUM a1st;
  277. #ifndef MININACT
  278.     char ser_line[256];
  279.     ART_NUM x,y;
  280. #endif
  281.  
  282. #ifdef CACHEFIRST
  283.     if (a1st = abs1st[ngnum])
  284.     return a1st;
  285. #endif
  286. #ifdef MININACT
  287.     getngsize(ngnum);
  288. # ifdef CACHEFIRST
  289.     return abs1st[ngnum];
  290. # else
  291.     return abs1st;
  292. # endif
  293. #else
  294.     sprintf(cp,"GROUP %s",rcline[ngnum]);
  295.     put_server(cp);
  296.     if (get_server(ser_line, sizeof(ser_line)) < 0) {
  297.     fprintf(stderr, "rrn: Unexpected close of server socket.\n");
  298.     finalize(1);
  299.     }
  300.     if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  301.     a1st = ngsize+1;        /* nothing there */
  302.     }
  303.     (void) sscanf(ser_line,"%d%d%d",&x,&y,&a1st);
  304. # ifdef CACHEFIRST
  305.     abs1st[ngnum] = a1st;
  306. # endif
  307.     return a1st;
  308. #endif
  309. }
  310. /* we already know the lowest article number with NNTP */
  311. ART_NUM
  312. getngmin(dirname,floor)
  313. char *dirname;
  314. ART_NUM floor;
  315. {
  316.     return(floor);
  317. }
  318. #else
  319. ART_NUM
  320. getabsfirst(ngnum,ngsize)
  321. register NG_NUM ngnum;
  322. ART_NUM ngsize;
  323. {
  324.     register ART_NUM a1st;
  325. #ifndef MININACT
  326.     char dirname[MAXFILENAME];
  327. #endif
  328.  
  329. #ifdef CACHEFIRST
  330.     if (a1st = abs1st[ngnum])
  331.     return a1st;
  332. #endif
  333. #ifdef MININACT
  334.     getngsize(ngnum);
  335. # ifdef CACHEFIRST
  336.     return abs1st[ngnum];
  337. # else
  338.     return abs1st;
  339. # endif
  340. #else /* not MININACT */
  341.     sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
  342.     a1st = getngmin(dirname,0L);
  343.     if (!a1st)                /* nothing there at all? */
  344.     a1st = ngsize+1;        /* aim them at end of newsgroup */
  345. # ifdef CACHEFIRST
  346.     abs1st[ngnum] = a1st;
  347. # endif
  348.     return a1st;
  349. #endif /* MININACT */
  350. }
  351.  
  352. /* scan a directory for minimum article number greater than floor */
  353.  
  354. ART_NUM
  355. getngmin(dirname,floor)
  356. char *dirname;
  357. ART_NUM floor;
  358. {
  359.     register DIR *dirp;
  360.     register struct DIRTYPE *dp;
  361.     register ART_NUM min = 1000000;
  362.     register ART_NUM maybe;
  363.     register char *p;
  364.     char tmpbuf[128];
  365.     
  366.     dirp = opendir(dirname);
  367.     if (!dirp)
  368.     return 0;
  369.     while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
  370.     if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
  371.         for (p = dp->d_name; *p; p++)
  372.         if (!isdigit(*p))
  373.             goto nope;
  374.         if (*dirname == '.' && !dirname[1])
  375.         stat(dp->d_name, &filestat);
  376.         else {
  377.         sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
  378.         stat(tmpbuf, &filestat);
  379.         }
  380.         if (! (filestat.st_mode & S_IFDIR))
  381.         min = maybe;
  382.     }
  383.       nope:
  384.     ;
  385.     }
  386.     closedir(dirp);
  387.     return min==1000000 ? 0 : min;
  388. }
  389. #endif
  390.