home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------*/
- /* e x p i r e . c */
- /* */
- /* Expire old news articles for UUPC/extended */
- /* */
- /* Copyright (c) 1992-1993 by Kendra Electronic Wonderworks, all */
- /* rights reserved except those explicitly granted by the UUPC/ */
- /* extended license. */
- /*--------------------------------------------------------------------*/
-
- /*
- * $Id: expire.c 1.5 1993/07/13 01:13:32 ahd Exp $
- *
- * $Log: expire.c $
- * Revision 1.5 1993/07/13 01:13:32 ahd
- * Drop unused stater.h header
- *
- * Revision 1.4 1993/04/05 04:32:19 ahd
- * Add timestamp, size to information returned by directory searches
- *
- * Revision 1.3 1992/11/25 12:59:17 ahd
- * Modifiy summery messages
- *
- */
-
- /*--------------------------------------------------------------------*/
- /* System include files */
- /*--------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <limits.h>
-
- /*--------------------------------------------------------------------*/
- /* UUPC/extended include files */
- /*--------------------------------------------------------------------*/
-
- #include "lib.h"
- #include "active.h"
- #include "dater.h"
- #include "getopt.h"
- #include "hlib.h"
- #include "import.h"
- #include "importng.h"
- #include "logger.h"
- #include "uundir.h"
- #include "pushpop.h"
- #include "timestmp.h"
-
- currentfile();
-
- /*--------------------------------------------------------------------*/
- /* Global Variables */
- /*--------------------------------------------------------------------*/
-
- #define ONE_DAY (60L*60L*24L)
-
- /*--------------------------------------------------------------------*/
- /* Internal prototypes */
- /*--------------------------------------------------------------------*/
-
- static boolean numeric( char *start);
-
- static void ExpireAll( const time_t expire_date,
- const time_t archive_date );
-
- static void ExpireGroup( const char *group,
- const time_t expire_date,
- const time_t archive_date );
-
- static void ExpireOneGroup( struct grp *cur_grp,
- const time_t expire_date,
- const time_t archive_date );
-
- static void ExpireDirectory( struct grp *cur_grp,
- const time_t expire_date,
- const char *directory,
- const char *archive );
-
- static boolean numeric( char *start);
-
- static void usage( void );
-
- long total_articles_purged = 0;
- long total_articles_archived = 0;
- long total_articles_kept = 0;
- long total_bytes_purged = 0;
- long total_bytes_archived = 0;
- long total_bytes_kept = 0;
-
- /*--------------------------------------------------------------------*/
- /* m a i n */
- /* */
- /* Main program */
- /*--------------------------------------------------------------------*/
-
- void main( int argc, char **argv)
- {
- int c;
- extern char *optarg;
- extern int optind;
- char *group = NULL;
-
- time_t expire_period = 7; /* Seven days visible to users */
- time_t archive_period = 0; /* Seven days after expiring in arch */
-
- time_t expire_date;
- time_t archive_date;
-
- /*--------------------------------------------------------------------*/
- /* Report our version number and date/time compiled */
- /*--------------------------------------------------------------------*/
-
- debuglevel = 1;
- banner( argv );
-
- #if defined(__CORE__)
- copywrong = strdup(copyright);
- checkref(copywrong);
- #endif
-
- /*--------------------------------------------------------------------*/
- /* Process our arguments */
- /*--------------------------------------------------------------------*/
-
- while ((c = getopt(argc, argv, "e:a:g:x:n:")) != EOF)
- switch(c) {
-
- case 'a':
- archive_period = atoi( optarg );
- break;
-
- case 'e':
- expire_period = atoi( optarg );
- break;
-
- case 'n':
- group = optarg;
- break;
-
- case 'x':
- debuglevel = atoi( optarg );
- break;
-
- case '?':
- usage();
- exit(1);
- break;
-
- default:
- printmsg(0, "expire - invalid option -%c", c);
- usage();
- exit(2);
- break;
- }
-
- if (optind != argc) {
- fputs("Extra parameter(s) at end.\n", stderr);
- usage();
- exit(2);
- }
-
- /*--------------------------------------------------------------------*/
- /* Initialize */
- /*--------------------------------------------------------------------*/
-
- tzset(); /* Set up time zone information */
-
- if (!configure( B_NEWS ))
- exit(1); /* system configuration failed */
-
- /*--------------------------------------------------------------------*/
- /* Switch to the spooling directory */
- /*--------------------------------------------------------------------*/
-
- PushDir( E_newsdir );
- atexit( PopDir );
-
- /*--------------------------------------------------------------------*/
- /* Initialize logging file */
- /*--------------------------------------------------------------------*/
-
- openlog( NULL );
-
- /*--------------------------------------------------------------------*/
- /* Load the active file */
- /*--------------------------------------------------------------------*/
-
- get_active(); /* Get sequence numbers for groups from
- active file */
-
- /*--------------------------------------------------------------------*/
- /* Compute times for expiring files */
- /*--------------------------------------------------------------------*/
-
- time( &expire_date );
- expire_date -= (expire_period * ONE_DAY);
- archive_date = expire_date - (archive_period * ONE_DAY);
-
- printmsg(1,"%s: %sing news older than %s (%ld days)",
- argv[0],
- archive_period ? "Archiv" : "Purg",
- dater( expire_date , NULL), (long) expire_period );
-
- if ( archive_period != 0 )
- printmsg(1,"%s: Purging news older than %s",
- argv[0],
- dater( archive_date , NULL));
-
- /*--------------------------------------------------------------------*/
- /* Process one group if requested, otherwise process the entire */
- /* active file */
- /*--------------------------------------------------------------------*/
-
- if ( group != NULL )
- ExpireGroup( group, expire_date, archive_date );
- else
- ExpireAll(expire_date, archive_date );
-
- /*--------------------------------------------------------------------*/
- /* Clean up and exit */
- /*--------------------------------------------------------------------*/
-
- put_active();
-
- if ( total_articles_purged || total_articles_archived)
- printmsg(1,"%s: Purged %ld total articles (%ld bytes), "
- "archived %ld total articles (%ld bytes). " ,
- argv[0],
- total_articles_purged, total_bytes_purged,
- total_articles_archived, total_bytes_archived );
-
- printmsg(1,"%s: Left alone %ld articles (%ld bytes). "
- "Total of %ld articles now use %ld bytes." ,
- argv[0],
- total_articles_kept, total_bytes_kept,
- total_articles_kept + total_articles_archived,
- total_bytes_kept + total_bytes_archived );
-
- exit(0);
-
- } /* main */
-
- /*--------------------------------------------------------------------*/
- /* E x p i r e A l l */
- /* */
- /* Expire all defined news groups */
- /*--------------------------------------------------------------------*/
-
- static void ExpireAll( const time_t expire_date,
- const time_t archive_date )
- {
- struct grp *cur_grp = group_list;
-
- while ( cur_grp != NULL )
- {
- ExpireOneGroup( cur_grp, expire_date, archive_date );
- /* Clean up this group */
-
- cur_grp = cur_grp->grp_next; /* Then clean up the next group */
- }
- } /* Expire_All */
-
- /*--------------------------------------------------------------------*/
- /* E x p i r e G r o u p */
- /* */
- /* Clean up one group by name */
- /*--------------------------------------------------------------------*/
-
- static void ExpireGroup( const char *group,
- const time_t expire_date,
- const time_t archive_date )
- {
- struct grp *cur_grp = group_list;
- struct grp *target = NULL;
-
- /*--------------------------------------------------------------------*/
- /* Search the list of groups for the requested group */
- /*--------------------------------------------------------------------*/
-
- while ( (cur_grp != NULL) && (target == NULL))
- {
- if ( equal( cur_grp->grp_name, group ))
- target = cur_grp;
-
- cur_grp = cur_grp->grp_next; /* Then clean up the next group */
- }
-
- /*--------------------------------------------------------------------*/
- /* If we found the group, process it, otherwise report the error */
- /*--------------------------------------------------------------------*/
-
- if ( target == NULL )
- printmsg(0,"Unable to locate active group %s", group );
- else
- ExpireOneGroup( target, expire_date, archive_date );
- /* Clean up this group */
-
- } /* ExpireGroup */
-
- /*--------------------------------------------------------------------*/
- /* E x p i r e O n e G r o u p */
- /* */
- /* Clean up one group by name */
- /*--------------------------------------------------------------------*/
-
- static void ExpireOneGroup( struct grp *cur_grp,
- const time_t expire_date,
- const time_t archive_date )
- {
- char groupdir[FILENAME_MAX];
- char archdir[FILENAME_MAX];
-
- printmsg(3,"Processing news group %s", cur_grp->grp_name );
-
- /*--------------------------------------------------------------------*/
- /* Set up the directory names */
- /*--------------------------------------------------------------------*/
-
- ImportNewsGroup( groupdir, cur_grp->grp_name, 0 );
- mkfilename( archdir, E_archivedir, &groupdir[ strlen( E_newsdir) + 1] );
-
- /*--------------------------------------------------------------------*/
- /* Process the primary and archive directories */
- /*--------------------------------------------------------------------*/
-
- ExpireDirectory( cur_grp, archive_date, archdir, NULL);
- /* Purge archive first to keep
- directory smaller */
-
- ExpireDirectory( cur_grp, expire_date, groupdir,
- (archive_date < expire_date) ? archdir : NULL);
- /* Do not archive for 0 days! */
-
- } /* ExpireOneGroup */
-
- /*--------------------------------------------------------------------*/
- /* E x p i r e D i r e c t o r y */
- /* */
- /* Clean up one group by name */
- /*--------------------------------------------------------------------*/
-
- static void ExpireDirectory( struct grp *cur_grp,
- const time_t expire,
- const char *directory,
- const char *archive )
- {
- char fname[FILENAME_MAX];
-
- int articles_archived = 0;/* Count of files moved to archive */
- int articles_purged = 0;/* Count of files actually deleted */
- int articles_kept = 0;/* Count of files actually deleted */
- long bytes_purged = 0; /* Bytes freed on disk from deletions */
- long bytes_kept = 0; /* Bytes left on disk total */
- long bytes_archived = 0; /* Bytes left on disk in archive */
-
- boolean not_built = TRUE; /* Did not insure archive directory
- exists */
-
- long low = LONG_MAX; /* Oldest article number left */
-
- DIR *dirp;
- struct direct *dp;
-
- /*--------------------------------------------------------------------*/
- /* Open up the directory for processing */
- /*--------------------------------------------------------------------*/
-
- if ((dirp = opendirx(directory,"*.*")) == nil(DIR))
- {
- printmsg(3, "ExpireDirectory: couldn't opendir() %s", directory);
- cur_grp->grp_low = cur_grp->grp_high;
- return;
- } /* if */
-
- /*--------------------------------------------------------------------*/
- /* Switch to directory for processing */
- /*--------------------------------------------------------------------*/
-
- CHDIR( directory );
-
- /*--------------------------------------------------------------------*/
- /* Look for the next file in the directory */
- /*--------------------------------------------------------------------*/
-
- while((dp = readdir(dirp)) != nil(struct direct))
- {
-
- /*--------------------------------------------------------------------*/
- /* Archive/expire this file? */
- /*--------------------------------------------------------------------*/
-
- if ( numeric( dp->d_name ))/* Article format name? */
- { /* Yes --> Examine it closer */
-
- printmsg(6,"Processing file %s from %s",
- dp->d_name, dater( dp->d_modified, NULL));
-
- if ( dp->d_modified < expire ) /* Long in the tooth? */
- { /* Yes --> Move it on out */
- int not_processed = TRUE;
- /* Purge unless we archive it */
-
- if ( archive != NULL )
- {
- printmsg( 4,"Archiving file %s from %s to %s",
- dp->d_name, directory , archive);
-
- if ( not_built ) /* First pass into directory? */
- { /* Yes --> Make sure it exists */
- MKDIR( archive );
- not_built = FALSE; /* Only build it once */
- }
-
- mkfilename( fname, archive, dp->d_name);
- not_processed = rename( dp->d_name, fname );
-
- if ( not_processed )
- {
- printerr( fname );
- printmsg(0,"Rename %s to %s failed, purging file.",
- dp->d_name, fname);
- }
- else {
- articles_archived++;
- bytes_archived += dp->d_size;
- }
- } /* if ( archive != NULL ) */
-
- if ( not_processed )
- {
- printmsg( 4,"Purging file %s from %s", dp->d_name, directory );
- unlink( dp->d_name );
- articles_purged++;
- bytes_purged += dp->d_size;
- } /* if ( not_processed ) */
-
- } /* if ( dp->d_modified < expire ) */
-
- /*--------------------------------------------------------------------*/
- /* If the article is valid and still in the main news */
- /* directory, determine if it is the lowest article left */
- /*--------------------------------------------------------------------*/
-
- else {
- long article = 0;
- char *digit = dp->d_name;
-
- while( *digit )
- article = article * 10 + (*digit++ - '0');
-
- low = min( article, low );
-
- bytes_kept += dp->d_size;
- articles_kept ++;
-
- } /* else if ( archive != NULL ) */
- } /* if ( numeric( dp->d_name ) */
-
- } /* while */
-
- /*--------------------------------------------------------------------*/
- /* Update lowest article available to the users */
- /*--------------------------------------------------------------------*/
-
- if ( low == LONG_MAX )
- cur_grp->grp_low = cur_grp->grp_high;
- else
- cur_grp->grp_low = low;
-
- /*--------------------------------------------------------------------*/
- /* Close up the directory and report what we did */
- /*--------------------------------------------------------------------*/
-
- closedir(dirp);
-
- if ( articles_archived )
- printmsg(2,"%s: Purged %d articles (%ld bytes),"
- " archived %d articles (%ld bytes),"
- " left alone %d articles (%ld bytes).",
- cur_grp->grp_name,
- articles_purged, bytes_purged,
- articles_archived, bytes_archived,
- articles_kept, bytes_kept );
- else if ( articles_purged )
- printmsg(2,"%s: Purged %d articles (%ld bytes),"
- " left alone %d articles (%ld bytes).",
- cur_grp->grp_name,
- articles_purged, bytes_purged,
- articles_kept, bytes_kept );
- else if ( articles_kept )
- printmsg(2,"%s: Left alone %d articles (%ld bytes).",
- cur_grp->grp_name,
- articles_kept, bytes_kept );
-
- total_articles_archived += articles_archived;
- total_articles_kept += articles_kept;
- total_articles_purged += articles_purged;
- total_bytes_archived += bytes_archived;
- total_bytes_kept += bytes_kept;
- total_bytes_purged += bytes_purged;
-
- } /* ExpireDirectory */
-
- /*--------------------------------------------------------------------*/
- /* n u m e r i c */
- /* */
- /* Examines string, returns true if numeric with period */
- /*--------------------------------------------------------------------*/
-
- static boolean numeric( char *start)
- {
- char *number = start;
-
- while (*number != '\0')
- {
- if (!isdigit(*number) && (*number != '.'))
- return FALSE;
-
- number++;
- }
-
- return TRUE;
- } /* numeric */
-
- /*--------------------------------------------------------------------*/
- /* u s a g e */
- /* */
- /* Print usage of program */
- /*--------------------------------------------------------------------*/
-
- static void usage( void )
- {
- printf( "Usage: expire [-edays] [-adays] [-ngroup]\n");
- exit(1);
- } /* usage */
-