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

  1. /* $Id: ngdata.c,v 4.4.2.1 1991/12/01 18:05:42 sob PATCH_2 sob $
  2.  *
  3.  * $Log: ngdata.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:23:31  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 "ndir.h"
  32. #include "rcstuff.h"
  33. #include "rn.h"
  34. #include "intrp.h"
  35. #include "final.h"
  36. #include "rcln.h"
  37. #include "util.h"
  38. #ifdef SERVER
  39. #include "server.h"
  40. #endif
  41. #include "INTERN.h"
  42. #include "ngdata.h"
  43.  
  44. void
  45. ngdata_init()
  46. {
  47.     char *cp;
  48.  
  49.     /* open the active file */
  50.  
  51. #ifdef SERVER
  52.     put_server("LIST");        /* tell server we want the active file */
  53.     nntp_get(ser_line, sizeof(ser_line));
  54.     if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  55.     fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
  56.     finalize(1);
  57.     }
  58.  
  59.     cp = filexp("%P/rrnact.%$");    /* make a temporary name */
  60.     strcpy(active_name, cp);
  61.     actfp = fopen(active_name, "w+");    /* and get ready */
  62.     if (actfp == Nullfp) {
  63.     printf(cantopen,active_name) FLUSH;
  64.     finalize(1);
  65.     }
  66.  
  67.     activeitems = 0;
  68.     while (1) {
  69.     if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
  70.         printf("Can't get active file from server:\ntransfer failed after %d entries\n", activeitems);
  71.         finalize(1);
  72.     }
  73.     if (ser_line[0] == '.')        /* while there's another line */
  74.         break;            /* get it and write it to */
  75.     activeitems++;
  76.     fputs(ser_line, actfp);
  77.     putc('\n', actfp);
  78.     }
  79.  
  80.     if (ferror(actfp)) {
  81.     printf("Error writing to active file %s.\n", active_name) FLUSH;
  82.     finalize(1);
  83.     }
  84. #else /* not SERVER */
  85.  
  86.     cp = filexp(ACTIVE);
  87.     actfp = fopen(cp,"r");
  88.     if (actfp == Nullfp) {
  89.     printf(cantopen,cp) FLUSH;
  90.     finalize(1);
  91.     }
  92.     activeitems = 0;
  93.     /* count entries */
  94.     while(fgets(buf,LBUFLEN,actfp) != NULL)
  95.     activeitems++;
  96. #endif
  97.     if (fseek(actfp,0L,0) == -1) {    /* just get to the beginning */
  98.     printf("Error seeking in active file.\n") FLUSH;
  99.     finalize(1);
  100.     }
  101.  
  102.     return;
  103. }
  104.  
  105. /* find the maximum article number of a newsgroup */
  106.  
  107. ART_NUM
  108. getngsize(num)
  109. register NG_NUM num;
  110. {
  111.     register int len;
  112.     register char *nam;
  113.     char tmpbuf[80];
  114.     ART_POS oldsoft;
  115.  
  116.     nam = rcline[num];
  117.     len = rcnums[num] - 1;
  118.     softtries++;
  119. #ifdef DEBUGGING
  120.     if (debug & DEB_SOFT_POINTERS)
  121.     printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
  122. #endif
  123.     oldsoft = softptr[num];
  124.     if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
  125.     if (softptr[num] != oldsoft) {
  126.         softmisses++;
  127.         writesoft = TRUE;
  128.     }
  129.     }
  130.     else {
  131.     softptr[num] = 0;
  132. #ifdef USETHREADS
  133.     if (RCCHAR(rcchar[num]) == ':')
  134. #else
  135.     if (rcchar[num] == ':')        /* unsubscribe quietly */
  136. #endif
  137.         rcchar[num] = NEGCHAR;
  138.     return TR_BOGUS;        /* well, not so quietly, actually */
  139.     }
  140.     
  141. #ifdef DEBUGGING
  142.     if (debug & DEB_SOFT_POINTERS) {
  143.     printf("Should be %ld\n",(long)softptr[num]) FLUSH;
  144.     }
  145. #endif
  146.     {
  147.     register char *s;
  148.     ART_NUM tmp;
  149.  
  150.     for (s=tmpbuf+len+1; isdigit(*s); s++) ;
  151.     if (tmp = atol(s))
  152. #ifdef MININACT
  153. #ifdef CACHEFIRST
  154.         abs1st[num] = tmp;
  155. #else
  156.         abs1st = tmp;
  157. #endif
  158. #endif
  159.     if (!in_ng) {
  160.         for (s++; isdigit(*s); s++) ;
  161.         while (isspace(*s)) s++;
  162.         switch (*s) {
  163.         case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
  164.         case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
  165.         /* This shouldn't even occur.  What are we doing in a non-existent
  166.            group?  Disallow it. */
  167.         case 'x': return TR_BOGUS;
  168.         /* what should be done about refiled groups?  rn shouldn't even
  169.            be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
  170.            get the news there) */
  171.         case '=': return TR_BOGUS;
  172.         default: moderated = nullstr;
  173.         }
  174.     }
  175.     }
  176. #ifdef USETHREADS
  177.     {
  178.     ART_NUM last;
  179.  
  180.     last = atol(tmpbuf+len+1);
  181.     return last >= ngmax[num] ? last : ngmax[num];
  182.     }
  183. #else
  184.     return atol(tmpbuf+len+1);
  185. #endif
  186. }
  187.  
  188. ACT_POS
  189. findact(outbuf,nam,len,suggestion)
  190. char *outbuf;
  191. char *nam;
  192. int len;
  193. long suggestion;
  194. {
  195.     ACT_POS retval;
  196.  
  197.     fseek(actfp,100000L,1);    /* hopefully this forces a reread */
  198.     if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
  199.       fgets(outbuf,80,actfp) == Nullch ||
  200.       outbuf[len] != ' ' ||
  201.       strnNE(outbuf,nam,len)) {
  202. #ifdef DEBUGGING
  203.     if (debug & DEB_SOFT_POINTERS)
  204.         printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
  205.           FLUSH;
  206. #endif
  207.     fseek(actfp,0L,0);
  208. #ifndef lint
  209.     retval = (ACT_POS)ftell(actfp);
  210. #else
  211.     retval = Null(ACT_POS);
  212. #endif /* lint */
  213.     while (fgets(outbuf,80,actfp) != Nullch) {
  214.         if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
  215.         return retval;
  216. #ifndef lint
  217.         retval = (ACT_POS) ftell(actfp);
  218. #endif /* lint */
  219.         if (ferror(actfp)) {
  220.         perror("error on active file"); /* something is wrong */
  221.         sig_catcher(0);
  222.         }
  223.     }
  224.     if(ferror(actfp)) {
  225.         perror("error on active file");
  226.         sig_catcher(0);
  227.     }
  228.     return (ACT_POS) -1;
  229.     }
  230.     else
  231. #ifndef lint
  232.     return (ACT_POS) suggestion;
  233. #else
  234.     return retval;
  235. #endif /* lint */
  236.     /*NOTREACHED*/
  237. }
  238.  
  239. /* determine the absolutely first existing article number */
  240. #ifdef SERVER
  241. ART_NUM
  242. getabsfirst(ngnum,ngsize)
  243. register NG_NUM ngnum;
  244. ART_NUM ngsize;
  245. {
  246.     ART_NUM a1st;
  247.  
  248. #ifdef CACHEFIRST
  249.     if (a1st = abs1st[ngnum])
  250.     return a1st;
  251. #endif
  252. #ifdef MININACT
  253.     getngsize(ngnum);
  254. # ifdef CACHEFIRST
  255.     return abs1st[ngnum];
  256. # else
  257.     return abs1st;
  258. # endif
  259. #else
  260.     getngsize(ngnum); /* set moderated as side effect */
  261.     sprintf(ser_line,"GROUP %s",rcline[ngnum]);
  262.     put_server(ser_line);
  263.     if (nntp_get(ser_line, sizeof(ser_line)) < 0) {
  264.     fprintf(stderr, "\nrrn: Unexpected close of server socket.\n");
  265.     finalize(1);
  266.     }
  267.     if (*ser_line == CHAR_FATAL){
  268.     fprintf(stderr,"\nrrn: %s\n",ser_line);
  269.     finalize(1);
  270.     }
  271.     if (*ser_line != CHAR_OK) {        /* and then see if that's ok */
  272.     a1st = ngsize+1;        /* nothing there */
  273.     }
  274.     (void) sscanf(ser_line,"%*d%*d%d",&a1st);
  275. # ifdef CACHEFIRST
  276.     abs1st[ngnum] = a1st;
  277. # endif
  278.     return a1st;
  279. #endif
  280. }
  281. /* we already know the lowest article number with NNTP */
  282. ART_NUM
  283. getngmin(dirname,floor)
  284. char *dirname;
  285. ART_NUM floor;
  286. {
  287.     return(floor);        /* dirname not used */
  288. }
  289.  
  290. #else /*SERVER*/
  291.  
  292. ART_NUM
  293. getabsfirst(ngnum,ngsize)
  294. register NG_NUM ngnum;
  295. ART_NUM ngsize;
  296. {
  297.     register ART_NUM a1st;
  298. #ifndef MININACT
  299.     char dirname[MAXFILENAME];
  300. #endif
  301.  
  302. #ifdef CACHEFIRST
  303.     if (a1st = abs1st[ngnum])
  304.     return a1st;
  305. #endif
  306. #ifdef MININACT
  307.     getngsize(ngnum);
  308. # ifdef CACHEFIRST
  309.     return abs1st[ngnum];
  310. # else
  311.     return abs1st;
  312. # endif
  313. #else /* not MININACT */
  314.     getngsize(ngnum); /* set moderate as side effect */
  315.     sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
  316.     a1st = getngmin(dirname,0L);
  317.     if (!a1st)                /* nothing there at all? */
  318.     a1st = ngsize+1;        /* aim them at end of newsgroup */
  319. # ifdef CACHEFIRST
  320.     abs1st[ngnum] = a1st;
  321. # endif
  322.     return a1st;
  323. #endif /* MININACT */
  324. }
  325.  
  326. /* scan a directory for minimum article number greater than floor */
  327.  
  328. ART_NUM
  329. getngmin(dirname,floor)
  330. char *dirname;
  331. ART_NUM floor;
  332. {
  333.     register DIR *dirp;
  334.     register struct DIRTYPE *dp;
  335.     register ART_NUM min = 1000000;
  336.     register ART_NUM maybe;
  337.     register char *p;
  338. #ifdef notdef
  339.     char tmpbuf[128];
  340. #endif
  341.     
  342.     dirp = opendir(dirname);
  343.     if (!dirp)
  344.     return 0;
  345.     while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
  346.     if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
  347.         for (p = dp->d_name; *p; p++)
  348.         if (!isdigit(*p))
  349.             goto nope;
  350. #ifdef notdef
  351.        /* 
  352.         * If newsgroup names ever go entirely numeric, then
  353.         * this code will have to be reinserted.
  354.         * For the time being, we assume that if a numeric name is
  355.         * found, it must be an article (and not a directory).
  356.         * This will avoid two stat(2) calls for those running
  357.         * rn.
  358.         */
  359.         if (*dirname == '.' && !dirname[1])
  360.         stat(dp->d_name, &filestat);
  361.         else {
  362.         sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
  363.         stat(tmpbuf, &filestat);
  364.         }
  365.         if (! (filestat.st_mode & S_IFDIR))
  366. #endif
  367.         min = maybe;
  368.     }
  369.       nope:
  370.     ;
  371.     }
  372.     closedir(dirp);
  373.     return min==1000000 ? 0 : min;
  374. }
  375. #endif
  376.