home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: fixactive.c,v 1.15 92/06/09 15:58:31 wasp Exp Locker: wasp $
- *
- * fixactive - quick hack from Walter Mildenberger, put in the public domain.
- *
- * Purpose: updates (or creates) an active-file containing all newsgroups
- * and the highest and lowest article-number currently available.
- *
- * you can do what you want with this file, but please don't discard the
- * author's name ('cuz that's me :-) )
- * The author [that's still me :-) ] is not responsible for any damage
- * and/or malefunction this program might or might not cause.
- * But if you have enhancements you want to tell me, you can reach me via
- * email at wasp@chumly.ka.sub.org !
- *
- * $Log: fixactive.c,v $
- * Revision 1.15 92/06/09 15:58:31 wasp
- * AUISG-conforming $VER:-String
- * min and max-field now uses 10 digits instead of 5.
- *
- * Revision 1.14 92/04/26 21:22:23 wasp
- * C= - compatible Version-string added
- *
- * Revision 1.13 92/04/26 20:35:30 wasp
- * removed CNEWS-default, now has to be specified as a compile
- * option (-dCNEWS )
- *
- * Revision 1.12 92/03/20 22:53:38 wasp
- * Linking with cres made the program worthless: the global variables
- * didn't have the proper values :-(
- *
- * Revision 1.11 92/03/11 17:13:05 wasp
- * unix-defaults nor for SysV R _4_ (/var/ vs. /usr/)
- * Layout modified
- * more comments
- * no freopen(stdin), now uses old-fashoned fopen()/fclose() :-)
- * ptr2 in name-extraction now assert()ed
- * activenew/old slightly modified
- *
- * Revision 1.10 92/01/14 18:55:08 wasp
- * minptr() now called with __regargs
- *
- * Revision 1.9 91/12/13 18:42:11 wasp
- * ▄bernimmt jetzt ab dem Status-flag wiueder die ganze Zeile, sodass =<groupname>
- * m÷glich ist.
- *
- * Revision 1.8 91/12/07 19:05:22 wasp
- * Default von Hirachical wieder unabhΣngig von Compileroptionen auf FALSE
- * gesetzt, um Verwirrung zu vermeiden.
- *
- * Revision 1.7 91/08/17 17:28:40 wasp
- * Put some unix stuff in there, moved every(?) amiga specific stuff into
- * handy defines.
- *
- * Revision 1.6 91/08/11 16:03:28 wasp
- * Bugfix in -f Option.
- *
- * Revision 1.5 91/08/05 00:43:13 wasp
- * New Verbose-Flag.
- *
- * Revision 1.4 91/08/03 23:23:37 wasp
- * Fixed Bug: argv[1] should really be fn !
- *
- * Revision 1.3 91/07/07 18:27:14 wasp
- * Log-Header added
- *
- */
-
- /* define as appropriate : */
-
- /* #define AMIGA /* is defined by my compiler */
- /* #define UNIX /* should be defined by your compiler */
-
- /* #define CNEWS /* for Frank Edward's CNews-Port */
- /* #define AUCPP /* for Feulner's AmigaUUCP-Plus Package */
- /* #define DUUCP /* for Dillon's UUCP Package, please note that the silly */
- /* roll-over of the article-numbering is NOT implemented ! */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include <sys/types.h>
- #include <sys/dir.h>
-
- #define CHAR char
- #define UBYTE unsigned char
- #define LONG long
- #define ULONG unsigned long
-
- #ifdef AMIGA
- # ifdef CNEWS
- # define NEWSDIR "NewsArts:"
- # define DEFAULT "NewsCtl:active"
- # else
- # ifdef AUCPP
- # define NEWSDIR "UUNEWS:"
- # define DEFAULT "UULIB:news/active"
- # else
- # define NEWSDIR "UUNEWS:"
- # define DEFAULT "UULIB:active"
- # endif
- # endif
-
- #ifdef UNIX
- # define NEWSDIR "/var/spool/news/"
- # define DEFAULT "/var/lib/news/active"
- #endif
-
- UBYTE *Version ="$VER: FixActive $Revision: 1.15 $ (" __DATE__ ";" __TIME__ ")";
-
- UBYTE hierarchicalNDT = 0;
- /* hierarchicalNDT ; N)ewsD)irT)ype; Dillon's UUCP creates the silly
- UUNEWS:comp.lang.c/<article>, which in fact should be
- UUNEWS:comp/lang/c/<articlenr> ! */
-
- #ifdef DEBUG
- UBYTE verbose = 1;
- #else
- UBYTE verbose = 0;
- #endif
-
- enum working_mode {update,create,fastupdate};
-
- UBYTE
- ok = 0,
- use_stdin = 0;
-
- CHAR
- tmpfilename[1024],
- groupname[512],
- buffer[256],
- Flag[256],
- *ptr1,
- *ptr2,
- *activefilename = NULL;
-
- DIR
- *dirdescr;
-
- struct direct
- *dirptr;
-
- int
- filenumber;
-
- FILE
- *fin,
- *fout;
-
-
- void * __regargs minptr(void *ptr1, void *ptr2)
- /* returns the smaller of two pointers, but not NULL (unless both pointers */
- /* are NULL) */
- { if(ptr1 && ptr2)
- return( (((ULONG)ptr1) > ((ULONG)ptr2)) ? ptr2 : ptr1 );
- else
- return(ptr1 ? ptr1 : ptr2);
- }
-
- main(LONG argc, CHAR *argv[])
- { long oldest,newest,activeold,activenew;
- int i;
- int mode = update;
-
- /*
- * parse the arguments, set flags accordingly
- *
- */
- for(i = 1; i < argc; i++)
- { if(argv[i][0] == '-')
- { switch(argv[i][1]) {
- case 'H' : case 'h' : hierarchicalNDT = ! hierarchicalNDT; break;
- case 'V' : case 'v' : verbose = 1; break;
- case 'C' : case 'c' : mode = create; break;
- case 'U' : case 'u' : mode = update; break;
- case 'F' : case 'f' : mode = fastupdate; break;
- case '\0': use_stdin = 1;
- }/* End of case */
- }
- else
- activefilename = argv[i];
- }
-
- /*
- * handle arguments...
- *
- */
- if(! activefilename)
- activefilename = DEFAULT ;
- if(use_stdin)
- fin = stdin;
- else
- fin = fopen(activefilename,"r");
-
- /*
- * now let's begin the work...
- *
- */
- if(fin)
- { strcpy(buffer,activefilename);
- strcat(buffer,".TMP");
- if(fout = fopen(buffer,"w"))
- {
- /*
- * well, files are open now, so we can work trough
- * the whole file...
- *
- */
- while(!(feof(fin) || ferror(fin) || ferror(fout)))
- { fgets(groupname,sizeof(groupname),fin); /* get groupname-line ... */
-
- /*
- * this is only for checkgroups-messages: !group means, this group
- * doesn't exist anymore. So I ignore the group silently...
- *
- */
- if(*groupname == '!')
- continue;
-
- /*
- * Now extract the groupname;
- * the code is a little bit cruel, but should work.
- *
- */
- ptr2 = NULL;
- if(ptr1 = strchr(groupname,' '))
- ptr2 = ptr1;
- if(ptr1 = strchr(groupname,'\t'))
- ptr2 = minptr(ptr2,ptr1);
- if(ptr1 = strchr(groupname,'\n'))
- ptr2 = minptr(ptr2,ptr1);
- if(ptr1 = strchr(groupname,'!'))
- ptr2 = minptr(ptr2,ptr1);
-
- /*
- * now check if it was a good hit
- *
- */
- if(!ptr2)
- continue;
-
- /*
- * ok, ptr2 was a good ptr, so I can terminate the groupname there
- *
- */
-
- *ptr2 = 0;
-
- if(strlen(groupname)==0)
- /*
- * Nah, it was NOT a good hit => ignore this damn line...
- *
- */
- continue;
-
- /* set the defaults */
- activeold = activenew = 0;
- oldest = newest = 0;
- /* strcpy(Flag,"y"); */
- Flag[0] = 'y', Flag[1] = '\0';
-
- ptr2++;
- /*
- * ptr2 now points to the character immediately following
- * the termination-character; this is in a real active-file
- * the beginning of the max-field
- *
- * now set active{new,old} to the values found in active-file, if
- * the mode is update or fastupdate, which assume a valid
- * active-file
- *
- */
- if((mode == update) || (mode == fastupdate))
- {
- ptr2 = stpblk(ptr2);
- activenew = strtol(ptr2,NULL,10);
-
- ptr1 = ptr2;
- ptr2 = strchr(ptr1,' ');
- if(!ptr2)
- ptr2 = strchr(ptr1,'\t');
- if(ptr2)
- { ptr1 = stpblk(ptr2);
- activeold = strtol(ptr1,NULL,10);
- if(ptr1 = strchr(ptr1,' '))
- strcpy(Flag,ptr1+1);
- }
- }
-
- /*
- * now construct a directoryname out of the groupname
- *
- */
- strcpy(tmpfilename,NEWSDIR);
- strcat(tmpfilename,groupname);
- if(hierarchicalNDT)
- { ptr1 = strchr(tmpfilename,'.');
- while(ptr1)
- { *ptr1 = '/';
- ptr1 = strchr(tmpfilename,'.');
- }
- } /* End of hirarchical NewsDir */
-
- /*
- * mode-fastupdate doesn't scan the directory, but grabs the
- * ".next"-file immediately, see below
- *
- */
- if(mode != fastupdate)
- {
- if(dirdescr = opendir(tmpfilename))
- { /* opening of directory succeeded */
- while((dirptr = readdir(dirdescr)) != NULL)
- { /* readdir(), until there are no more files left... */
- if(stcd_i(dirptr->d_name,&filenumber))
- { /*
- * only count real articles, wich have a len of
- * parsed chars > 0
- *
- */
- if(newest==0) /* ==0 means first article found, so */
- { /* set min = max = first-found-article */
- oldest = newest = filenumber;
- }
- else /* the simple min-max-problem */
- { if(filenumber > newest)
- {
- newest = filenumber;
- }
- else
- { if(filenumber < oldest)
- {
- oldest = filenumber;
- }
- }
- }
- }
- }/* End of while */
- closedir(dirdescr);
- } /* End of opendir succeded */
- }
- else /* FAST-Update, assumes dillon-uucp with ".next"-files */
- { register FILE *nextfile;
- strcat(tmpfilename,"/.next");
- if(nextfile = fopen(tmpfilename,"r"))
- { fgets(buffer,sizeof(buffer),nextfile);
- fclose(nextfile);
- newest = atol(buffer)-1;
- }
- }
- if(verbose)
- { if(oldest > activeold)
- printf("setting oldest article in %s to %ld\n",groupname,oldest);
- else
- oldest = activeold;
- if(newest > activenew)
- printf("setting newest article in %s to %ld\n",groupname,newest);
- else
- newest = activenew;
- }
-
- /* suppress double '\n' */
- if(Flag[strlen(Flag)-1] == '\n')
- Flag[strlen(Flag)-1] = '\0';
-
- /*
- * now we have everything done for the group, so
- * let's write the line...
- *
- */
- fprintf(fout,"%s %010lu %010lu %s\n",groupname,newest,oldest,Flag);
-
- }/* End of while */
-
- ok = 1; /* everything worked fine so far */
- fclose(fout);
- }
- if(ok)
- { /* if everything worked so far, we can delete the old backup,
- * backup (rename) the current active-file, and set the new generated
- * active-file as the current one !
- *
- */
- strcpy(buffer,activefilename);
- strcat(buffer,".o");
- unlink(buffer); /* delete old backup */
- rename(activefilename,buffer); /* create new one */
- strcpy(buffer,activefilename); /* set computed active-file as the current one */
- strcat(buffer,".TMP");
- rename(buffer,activefilename);
- }
- else
- fprintf(stderr,"an error occured, a temorary file (%s.TMP) was probably left !\n",activefilename);
-
- if(!use_stdin)
- fclose(fin);
- }
- else
- fputs("not done, can't open input-file!\n",stderr);
- }
-