home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / AnnR09.lha / src / fixactive.c
Encoding:
C/C++ Source or Header  |  1992-06-19  |  9.9 KB  |  402 lines

  1. /*
  2.  * $Id: fixactive.c,v 1.15 92/06/09 15:58:31 wasp Exp Locker: wasp $
  3.  *
  4.  * fixactive - quick hack from Walter Mildenberger, put in the public domain.
  5.  *
  6.  * Purpose: updates (or creates) an active-file containing all newsgroups
  7.  *    and the highest and lowest article-number currently available.
  8.  *
  9.  *    you can do what you want with this file, but please don't discard the
  10.  * author's name ('cuz that's me :-) )
  11.  * The author [that's still me :-) ] is not responsible for any damage
  12.  * and/or malefunction this program might or might not cause.
  13.  * But if you have enhancements you want to tell me, you can reach me via
  14.  * email at wasp@chumly.ka.sub.org !
  15.  *
  16.  * $Log:    fixactive.c,v $
  17.  * Revision 1.15  92/06/09  15:58:31  wasp
  18.  * AUISG-conforming $VER:-String
  19.  * min and max-field now uses 10 digits instead of 5.
  20.  * 
  21.  * Revision 1.14  92/04/26  21:22:23  wasp
  22.  * C= - compatible Version-string added
  23.  * 
  24.  * Revision 1.13  92/04/26  20:35:30  wasp
  25.  * removed CNEWS-default, now has to be specified as a compile
  26.  * option (-dCNEWS )
  27.  * 
  28.  * Revision 1.12  92/03/20  22:53:38  wasp
  29.  * Linking with cres made the program worthless: the global variables
  30.  * didn't have the proper values :-(
  31.  * 
  32.  * Revision 1.11  92/03/11  17:13:05  wasp
  33.  * unix-defaults nor for SysV R _4_ (/var/ vs. /usr/)
  34.  * Layout modified
  35.  * more comments
  36.  * no freopen(stdin), now uses old-fashoned fopen()/fclose() :-)
  37.  * ptr2 in name-extraction now assert()ed
  38.  * activenew/old slightly modified
  39.  * 
  40.  * Revision 1.10  92/01/14  18:55:08  wasp
  41.  * minptr() now called with __regargs
  42.  * 
  43.  * Revision 1.9  91/12/13  18:42:11  wasp
  44.  * ▄bernimmt jetzt ab dem Status-flag wiueder die ganze Zeile, sodass =<groupname>
  45.  * m÷glich ist.
  46.  * 
  47.  * Revision 1.8  91/12/07  19:05:22  wasp
  48.  * Default von Hirachical wieder unabhΣngig von Compileroptionen auf FALSE
  49.  * gesetzt, um Verwirrung zu vermeiden.
  50.  * 
  51.  * Revision 1.7  91/08/17  17:28:40  wasp
  52.  * Put some unix stuff in there, moved every(?) amiga specific stuff into
  53.  * handy defines.
  54.  * 
  55.  * Revision 1.6  91/08/11  16:03:28  wasp
  56.  * Bugfix in -f Option.
  57.  * 
  58.  * Revision 1.5  91/08/05  00:43:13  wasp
  59.  * New Verbose-Flag.
  60.  * 
  61.  * Revision 1.4  91/08/03  23:23:37  wasp
  62.  * Fixed Bug: argv[1] should really be fn !
  63.  * 
  64.  * Revision 1.3  91/07/07  18:27:14  wasp
  65.  * Log-Header added
  66.  * 
  67.  */
  68.  
  69. /* define as appropriate : */
  70.  
  71. /* #define AMIGA    /* is defined by my compiler */
  72. /* #define UNIX    /* should be defined by your compiler */
  73.  
  74. /* #define CNEWS    /* for Frank Edward's CNews-Port */
  75. /* #define AUCPP  /* for Feulner's AmigaUUCP-Plus Package */
  76. /* #define DUUCP    /* for Dillon's UUCP Package, please note that the silly   */
  77.                    /* roll-over of the article-numbering is NOT implemented ! */
  78.  
  79. #include <stdlib.h>
  80. #include <stdio.h>
  81. #include <string.h>
  82. #include <assert.h>
  83. #include <sys/types.h>
  84. #include <sys/dir.h>
  85.  
  86. #define CHAR   char
  87. #define UBYTE  unsigned char
  88. #define LONG    long
  89. #define ULONG    unsigned long
  90.  
  91. #ifdef AMIGA
  92. # ifdef CNEWS
  93. #  define NEWSDIR    "NewsArts:"
  94. #  define DEFAULT "NewsCtl:active"
  95. # else
  96. #  ifdef AUCPP
  97. #   define NEWSDIR "UUNEWS:"
  98. #   define DEFAULT "UULIB:news/active"
  99. #  else
  100. #   define NEWSDIR "UUNEWS:"
  101. #   define DEFAULT "UULIB:active"
  102. #  endif
  103. # endif
  104.  
  105. #ifdef UNIX
  106. # define NEWSDIR "/var/spool/news/"
  107. # define DEFAULT "/var/lib/news/active"
  108. #endif
  109.  
  110. UBYTE *Version ="$VER: FixActive $Revision: 1.15 $ (" __DATE__ ";" __TIME__ ")";
  111.  
  112. UBYTE hierarchicalNDT = 0;
  113. /* hierarchicalNDT ; N)ewsD)irT)ype; Dillon's UUCP creates the silly
  114.     UUNEWS:comp.lang.c/<article>, which in fact should be
  115.     UUNEWS:comp/lang/c/<articlenr> ! */
  116.  
  117. #ifdef DEBUG
  118.  UBYTE verbose = 1;
  119. #else
  120.  UBYTE verbose = 0;
  121. #endif
  122.  
  123. enum working_mode {update,create,fastupdate};
  124.  
  125. UBYTE
  126.     ok = 0,
  127.     use_stdin = 0;
  128.  
  129. CHAR
  130.     tmpfilename[1024],
  131.     groupname[512],
  132.     buffer[256],
  133.     Flag[256],
  134.     *ptr1,
  135.     *ptr2,
  136.     *activefilename = NULL;
  137.  
  138. DIR
  139.     *dirdescr;
  140.  
  141. struct direct
  142.     *dirptr;
  143.  
  144. int
  145.     filenumber;
  146.  
  147. FILE
  148.     *fin,
  149.     *fout;
  150.  
  151.  
  152. void * __regargs minptr(void *ptr1, void *ptr2)
  153. /* returns the smaller of two pointers, but not NULL (unless both pointers */
  154. /* are NULL) */
  155. {    if(ptr1 && ptr2)
  156.         return( (((ULONG)ptr1) > ((ULONG)ptr2)) ? ptr2 : ptr1 );
  157.     else
  158.         return(ptr1 ? ptr1 : ptr2);
  159. }
  160.  
  161. main(LONG argc, CHAR *argv[])
  162. {    long oldest,newest,activeold,activenew;
  163.     int i;
  164.     int mode = update;
  165.  
  166.   /*
  167.     * parse the arguments, set flags accordingly
  168.     *
  169.     */
  170.     for(i = 1; i < argc; i++)
  171.     {    if(argv[i][0] == '-')
  172.         {    switch(argv[i][1]) {
  173.                 case 'H' : case 'h' : hierarchicalNDT = ! hierarchicalNDT; break;
  174.                 case 'V' : case 'v' : verbose = 1; break;
  175.                 case 'C' : case 'c' : mode = create; break;
  176.                 case 'U' : case 'u' : mode = update; break;
  177.                 case 'F' : case 'f' : mode = fastupdate; break;
  178.                 case '\0':                 use_stdin = 1;
  179.             }/* End of case */
  180.         }
  181.         else
  182.             activefilename = argv[i];
  183.     }
  184.  
  185.   /*
  186.     * handle arguments...
  187.     *
  188.     */
  189.     if(! activefilename)
  190.         activefilename = DEFAULT ;
  191.     if(use_stdin)
  192.         fin = stdin;
  193.     else
  194.         fin = fopen(activefilename,"r");
  195.  
  196.   /*
  197.     * now let's begin the work...
  198.     *
  199.     */
  200.     if(fin)
  201.     {    strcpy(buffer,activefilename);
  202.         strcat(buffer,".TMP");
  203.         if(fout = fopen(buffer,"w"))
  204.         {
  205.           /*
  206.             * well, files are open now, so we can work trough
  207.             * the whole file...
  208.             *
  209.             */
  210.             while(!(feof(fin) || ferror(fin) || ferror(fout)))
  211.             {    fgets(groupname,sizeof(groupname),fin); /* get groupname-line ... */
  212.  
  213.               /*
  214.                 * this is only for checkgroups-messages: !group means, this group
  215.                 * doesn't exist anymore. So I ignore the group silently...
  216.                 *
  217.                 */
  218.                 if(*groupname == '!')
  219.                     continue;
  220.  
  221.               /*
  222.                 * Now extract the groupname;
  223.                 * the code is a little bit cruel, but should work.
  224.                 *
  225.                 */
  226.                 ptr2 = NULL;
  227.                 if(ptr1 = strchr(groupname,' '))
  228.                     ptr2 = ptr1;
  229.                 if(ptr1 = strchr(groupname,'\t'))
  230.                     ptr2 = minptr(ptr2,ptr1);
  231.                 if(ptr1 = strchr(groupname,'\n'))
  232.                     ptr2 = minptr(ptr2,ptr1);
  233.                 if(ptr1 = strchr(groupname,'!'))
  234.                     ptr2 = minptr(ptr2,ptr1);
  235.  
  236.               /*
  237.                 * now check if it was a good hit
  238.                 *
  239.                 */
  240.                 if(!ptr2)
  241.                     continue;
  242.  
  243.               /*
  244.                 * ok, ptr2 was a good ptr, so I can terminate the groupname there
  245.                 *
  246.                 */
  247.  
  248.                 *ptr2 = 0;
  249.  
  250.                 if(strlen(groupname)==0)
  251.               /*
  252.                 * Nah, it was NOT a good hit => ignore this damn line...
  253.                 *
  254.                 */
  255.                     continue;
  256.  
  257.               /* set the defaults */
  258.                 activeold = activenew = 0;
  259.                 oldest = newest = 0;
  260.                 /* strcpy(Flag,"y"); */
  261.                 Flag[0] = 'y', Flag[1] = '\0';
  262.  
  263.                 ptr2++;
  264.               /*
  265.                 * ptr2 now points to the character immediately following
  266.                 * the termination-character; this is in a real active-file
  267.                 * the beginning of the max-field
  268.                 *
  269.                 * now set active{new,old} to the values found in active-file, if
  270.                 * the mode is update or fastupdate, which assume a valid
  271.                 * active-file
  272.                 *
  273.                 */
  274.                 if((mode == update) || (mode == fastupdate))
  275.                 {
  276.                     ptr2 = stpblk(ptr2);
  277.                     activenew = strtol(ptr2,NULL,10);
  278.  
  279.                     ptr1 = ptr2;
  280.                     ptr2 = strchr(ptr1,' ');
  281.                     if(!ptr2)
  282.                         ptr2 = strchr(ptr1,'\t');
  283.                     if(ptr2)
  284.                     {    ptr1 = stpblk(ptr2);
  285.                         activeold = strtol(ptr1,NULL,10);
  286.                         if(ptr1 = strchr(ptr1,' '))
  287.                             strcpy(Flag,ptr1+1);
  288.                     }
  289.                 }
  290.  
  291.               /*
  292.                 * now construct a directoryname out of the groupname
  293.                 *
  294.                 */
  295.                 strcpy(tmpfilename,NEWSDIR);
  296.                 strcat(tmpfilename,groupname);
  297.                 if(hierarchicalNDT)
  298.                 {    ptr1 = strchr(tmpfilename,'.');
  299.                     while(ptr1)
  300.                     {    *ptr1 = '/';
  301.                         ptr1 = strchr(tmpfilename,'.');
  302.                     }
  303.                 } /* End of hirarchical NewsDir */
  304.  
  305.               /*
  306.                 * mode-fastupdate doesn't scan the directory, but grabs the
  307.                 * ".next"-file immediately, see below
  308.                 *
  309.                 */
  310.                 if(mode != fastupdate)
  311.                 {
  312.                     if(dirdescr = opendir(tmpfilename))
  313.                     {    /* opening of directory succeeded */
  314.                         while((dirptr = readdir(dirdescr)) != NULL)
  315.                         {    /* readdir(), until there are no more files left... */
  316.                             if(stcd_i(dirptr->d_name,&filenumber))
  317.                             { /*
  318.                                 * only count real articles, wich have a len of
  319.                                 * parsed chars > 0
  320.                                 *
  321.                                 */
  322.                                 if(newest==0) /* ==0 means first article found, so */
  323.                                 {    /* set min = max = first-found-article */
  324.                                     oldest = newest = filenumber;
  325.                                 }
  326.                                 else /* the simple min-max-problem */
  327.                                 {    if(filenumber > newest)
  328.                                     {
  329.                                         newest = filenumber;
  330.                                     }
  331.                                     else
  332.                                     {    if(filenumber < oldest)
  333.                                         {
  334.                                             oldest = filenumber;
  335.                                         }
  336.                                     }
  337.                                 }
  338.                             }
  339.                         }/* End of while */
  340.                         closedir(dirdescr);
  341.                     } /* End of opendir succeded */
  342.                 }
  343.                 else /* FAST-Update, assumes dillon-uucp with ".next"-files */
  344.                 {    register FILE *nextfile;
  345.                     strcat(tmpfilename,"/.next");
  346.                     if(nextfile = fopen(tmpfilename,"r"))
  347.                     {    fgets(buffer,sizeof(buffer),nextfile);
  348.                         fclose(nextfile);
  349.                         newest = atol(buffer)-1;
  350.                     }
  351.                 }
  352.                 if(verbose)
  353.                 {    if(oldest > activeold)
  354.                         printf("setting oldest article in %s to %ld\n",groupname,oldest);
  355.                     else
  356.                         oldest = activeold;
  357.                     if(newest > activenew)
  358.                         printf("setting newest article in %s to %ld\n",groupname,newest);
  359.                     else
  360.                         newest = activenew;
  361.                 }
  362.  
  363.                 /* suppress double '\n' */
  364.                 if(Flag[strlen(Flag)-1] == '\n')
  365.                     Flag[strlen(Flag)-1] = '\0';
  366.  
  367.               /*
  368.                 * now we have everything done for the group, so
  369.                 * let's write the line...
  370.                 *
  371.                 */
  372.                 fprintf(fout,"%s %010lu %010lu %s\n",groupname,newest,oldest,Flag);
  373.  
  374.             }/* End of while */
  375.  
  376.             ok = 1; /* everything worked fine so far */
  377.             fclose(fout);
  378.         }
  379.         if(ok)
  380.         { /* if everything worked so far, we can delete the old backup,
  381.             * backup (rename) the current active-file, and set the new generated
  382.             * active-file as the current one !
  383.             *
  384.             */
  385.             strcpy(buffer,activefilename);
  386.             strcat(buffer,".o");
  387.             unlink(buffer); /* delete old backup */
  388.             rename(activefilename,buffer); /* create new one */
  389.             strcpy(buffer,activefilename); /* set computed active-file as the current one */
  390.             strcat(buffer,".TMP");
  391.             rename(buffer,activefilename);
  392.         }
  393.         else
  394.             fprintf(stderr,"an error occured, a temorary file (%s.TMP) was probably left !\n",activefilename);
  395.  
  396.         if(!use_stdin)
  397.             fclose(fin);
  398.     }
  399.    else
  400.       fputs("not done, can't open input-file!\n",stderr);
  401. }
  402.