home *** CD-ROM | disk | FTP | other *** search
- /*
- ** TRIMNEWS.C
- **
- ** TRIMNEWS
- **
- ** This program scans UULIB:NewsGroups then chdir's into each news group's
- ** directory. The second field specifies the number of days old any numerical
- ** file (filename beginning with 0-9) is allowed to be before it is deleted.
- **
- ** If the second field does not exist for a given line in the NewsGroups file,
- ** 7 days is automatically assumed. The number of days is referenced from
- ** when the file was created, NOT the Date: field in the article.
- **
- ** -all may be passed as a parameter, and trimnews will delete all files,
- ** not just those a certain number of days (hours) old. This overrides any
- ** and all parameters specified in UULib:Newsgroups as well as a -h param.
- **
- ** -h <hours> may be passed as a parameter, is used if a UULib:Newsgroups
- ** for a newsgroup does not exists. It indicates that all files over <hours>
- ** old should be deleted.
- **
- ** The program is meant to be run daily from a cron entry to clear out old
- ** news.
- **
- ** On AmigaDOS 3.0 and above, the program waits 2 seconds between each
- ** newsgroup to ensure that the filesystem buffers are flushed to disk.
- **
- ** If "-d" is set when executed, some very extensive debugging information
- ** is printed on stdout, for AmigaDOS 2.0 and above.
- */
-
- #define VERBOSE
-
- #include <string.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
-
- #include "config.h"
- #include "version.h"
- #include "log.h"
- #include "OwnDevUnit.h"
-
- #undef NULL
- #define NULL 0
-
- #include <exec/memory.h>
- #include <exec/libraries.h>
- #include <clib/exec_protos.h>
-
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/exall.h>
- #include <clib/dos_protos.h>
-
- IDENT (".10");
-
- extern struct DosLibrary
- *DOSBase;
- struct Library
- *OwnDevUnitBase = NULL;
- char
- TmpBuf [256];
- int
- countfiles = 0, /* how many files deleted */
- countbytes = 0, /* how many bytes in the files deleted */
- allfiles = 0, /* delete ALL files, not just date-ranges */
- hours = 0, /* delete 'x' hours instead of days */
- broken = 0, /* ctrl-C has happened */
- debug = 0, /* display debug information */
- dos3_0 = 0, /* running on 3.0 or above */
- dos2_0 = 0, /* running on 2.04 or above */
- nodelay = 0; /* do not delay between dirs on 3.0+ */
- struct DateStamp
- *ds = NULL;
- struct ExAllControl
- *eac = NULL;
-
- struct MyExAllBuf {
- ULONG
- meb_Entries;
- struct ExAllData
- meb_Data [100];
- } *ead1 = NULL, *ead2 = NULL;
-
- const char
- *FMT_Final = "Deleted %ld files containing %ld bytes";
-
- void ScanDirectoryDeleteFiles (char *path, int days);
- void SetupExAll (void);
- void CleanupExAll (void);
- long dstot (long *date);
- void ProcessExAllBuffer (const char *path, const struct MyExAllBuf *edata,
- const long tnow);
- void rm_file (const char *path, const char *name);
-
- int
- brk (void)
- {
- broken = 1;
- return 0;
- }
-
- int
- main (int argc, char **argv)
- {
- FILE *fi;
- char *path;
- char newsgrp [128];
- int days;
- char *dir = GetConfigDir (UUNEWS);
-
- LogProgram = "TrimNews";
-
- if ((OwnDevUnitBase = OpenLibrary ((UBYTE *) ODU_NAME, 0)) == NULL) {
- fprintf (stderr, "Couldn't open lock library\n");
- exit (20);
- }
-
- onbreak (brk);
-
- if (argc > 1) {
- int inx = 1;
- char *p;
-
- while (inx <= argc) {
- p = argv [inx++];
- if (p && *p == '-') {
- p++;
- if (strcmp (p, "all") == 0)
- allfiles = 1;
- else
- if (strcmp (p, "h") == 0) {
- hours = atoi (argv [inx++]);
- }
- else
- if (strcmp (p, "d") == 0) {
- debug = 1;
- }
- else
- if (strcmp (p, "n") == 0) {
- nodelay = 1;
- }
- else {
- fprintf (stderr, "%s: don't know option '%s'\n", argv [0], p);
- exit (30);
- }
- }
- }
- }
-
- dos3_0 = DOSBase->dl_lib.lib_Version >= 39 ? 1 : 0;
- dos2_0 = DOSBase->dl_lib.lib_Version >= 37 ? 1 : 0;
- if (dos2_0)
- SetupExAll ();
-
- fi = openlib ("NewsGroups");
- if (!fi) {
- fprintf (stderr, "Unable to open NewsGroups file\n");
- exit (20);
- }
-
- while (fgets (TmpBuf, sizeof (TmpBuf), fi) && !broken) {
- switch (sscanf (TmpBuf, "%s %d", newsgrp, &days)) {
- case 1:
- if (!hours)
- days = 7;
- else
- days = 0;
- case 2:
- if (!days && !allfiles && !hours)
- continue;
- if (path = HandleHeirarchy (dir, newsgrp, 1)) {
- ScanDirectoryDeleteFiles (path, days);
- free (path);
- }
- }
- }
- fclose (fi);
-
- if (dos2_0)
- CleanupExAll ();
-
- ulog (-1, FMT_Final, countfiles, countbytes);
- printf ("%s: ", LogProgram);
- printf (FMT_Final, countfiles, countbytes);
- printf ("\n");
-
- if (OwnDevUnitBase) {
- CloseLibrary (OwnDevUnitBase);
- OwnDevUnitBase = NULL;
- }
-
- return 0;
- }
-
- void
- ScanDirectoryDeleteFiles (char *path, int days)
- {
- BPTR lock = NULL;
- BPTR oldlock = NULL;
- struct FileInfoBlock *fib = NULL;
- long delete_ds [3];
- long tnow;
- int more;
- struct MyExAllBuf *eadata, *ead;
-
- DateStamp ((struct DateStamp *) delete_ds);
- tnow = dstot (delete_ds);
- if (days)
- tnow -= (days * (1440 * 60));
- else
- if (hours)
- tnow -= (hours * 60);
-
- lock = Lock ((UBYTE *) path, ACCESS_READ);
- if (!lock)
- goto done;
-
- oldlock = CurrentDir (lock);
-
- if (dos2_0) {
- eac->eac_LastKey = 0;
- eac->eac_Entries = 0;
- eac->eac_MatchString = NULL;
- eac->eac_MatchFunc = NULL;
-
- ead1->meb_Entries = 0;
- ead2->meb_Entries = 0;
-
- ead = ead2; /* next buffer to be filled */
- eadata = ead1; /* buffer to be deleted */
-
- do {
- more = ExAll (lock, &ead->meb_Data[0], sizeof (ead->meb_Data), ED_DATE, eac);
- if (!more) {
- if (IoErr () != ERROR_NO_MORE_ENTRIES) {
- fprintf (stderr, "ExAll() error %ld\n", IoErr ());
- break;
- }
- }
-
- ead->meb_Entries = eac->eac_Entries;
-
- ProcessExAllBuffer (path, eadata, tnow);
-
- if (eadata == ead1) {
- eadata = ead2;
- ead = ead1;
- }
- else {
- eadata = ead1;
- ead = ead2;
- }
-
- } while (more);
-
- ProcessExAllBuffer (path, eadata, tnow); /* get last buffer */
-
- if (dos3_0 && nodelay == 0)
- Delay (100); /* wait 2 seconds to flush buffers */
- }
- else { /* dos 1.3 or below */
- fib = malloc (sizeof (struct FileInfoBlock));
- if (!fib)
- goto done;
-
- if (!Examine (lock, fib))
- goto done;
-
- while (ExNext (lock, fib)) {
- if (isdigit ((unsigned char) fib->fib_FileName [0])) {
- if (allfiles || tnow > dstot ((long *) &fib->fib_Date)) {
- rm_file (path, fib->fib_FileName);
- countbytes += fib->fib_Size;
- countfiles += 1;
- }
- }
- }
- }
-
- done:
- if (fib)
- free (fib);
- if (lock) {
- lock = CurrentDir (oldlock);
- UnLock (lock);
- }
-
- return;
- }
-
- long
- dstot (long *date) /* days, mins, ticks */
- {
- return ((date [0] * 1440 * 60) + (date [1] * 60) + (date [2] / 50));
- }
-
- void
- ProcessExAllBuffer (const char *path, const struct MyExAllBuf *edata,
- const long tnow)
- {
- struct ExAllData *exdata;
-
- if (debug)
- fprintf (stderr, "PEB enter: entries %ld, path = '%s', allfiles = %ld, tnow = %ld\n", edata->meb_Entries, path, allfiles, tnow);
-
- if (edata->meb_Entries) {
- exdata = &edata->meb_Data[0];
-
- while (exdata) {
- if (debug)
- fprintf (stderr, "PEB: exdata = 0x%lx, next = 0x%lx, name = '%s', type %ld, size %ld,\n prot 0x%lx, days %ld, mins %ld, ticks %ld\n",
- exdata, exdata->ed_Next, exdata->ed_Name, exdata->ed_Type, exdata->ed_Size, exdata->ed_Prot, exdata->ed_Days, exdata->ed_Mins, exdata->ed_Ticks);
- if (exdata->ed_Type == ST_FILE || exdata->ed_Type == ST_LINKFILE) {
-
- ds = (struct DateStamp *) &exdata->ed_Days;
- if (isdigit (*exdata->ed_Name) &&
- (allfiles || tnow > dstot ((long *) ds))) {
-
- rm_file (path, (const char *) exdata->ed_Name);
- countbytes += exdata->ed_Size;
- countfiles += 1;
- }
- }
-
- exdata = exdata->ed_Next;
- }
- }
-
- if (debug)
- fprintf (stderr, "PEB: exit\n");
- return;
- }
-
- void
- rm_file (const char *path, const char *name)
- {
- if (debug)
- fprintf (stderr, "delete %s/%s\n", path, name);
-
- if (!DeleteFile ((UBYTE *) name)) { /* we are assumed to already be in directory "path" */
- fprintf (stderr, "DeleteFile() error %ld\n", IoErr ());
- }
-
- return;
- }
-
- void
- SetupExAll (void)
- {
- eac = AllocDosObject (DOS_EXALLCONTROL, NULL);
- if (!eac) {
- fprintf (stderr, "Cannot allocate ExAllControl, error %ld\n", IoErr ());
- exit (30);
- }
- ead1 = AllocVec (sizeof (struct MyExAllBuf) + 200, MEMF_CLEAR); /* +200 per Randell Jesup */
- if (!ead1) {
- FreeDosObject (DOS_EXALLCONTROL, eac);
- fprintf (stderr, "Can't get memory for ExAllData\n");
- exit (30);
- }
- ead2 = AllocVec (sizeof (struct MyExAllBuf) + 200, MEMF_CLEAR); /* +200 per Randell Jesup */
- if (!ead2) {
- FreeVec (ead1);
- FreeDosObject (DOS_EXALLCONTROL, eac);
- fprintf (stderr, "Can't get memory for ExAllData 2\n");
- exit (30);
- }
-
- return;
- }
-
- void
- CleanupExAll (void)
- {
- if (eac) {
- FreeDosObject (DOS_EXALLCONTROL, eac);
- eac = NULL;
- }
- if (ead1) {
- FreeVec (ead1);
- ead1 = NULL;
- }
- if (ead2) {
- FreeVec (ead2);
- ead2 = NULL;
- }
-
- return;
- }
-