home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
usenet
/
altsrcs
/
1
/
1222
< prev
next >
Wrap
Internet Message Format
|
1990-12-28
|
6KB
From: andrewt@watnow.waterloo.edu (Andrew Thomas)
Newsgroups: alt.sources
Subject: purge - Remove old emacs backup files safely
Message-ID: <ANDREWT.90Apr23091019@watnow.waterloo.edu>
Date: 23 Apr 90 14:10:19 GMT
A couple of years ago I noticed that directories for really big
projects edited using emacs tended to get cluttered by lots of .~n~
files. I started typing things like rm *~, or rm *.~*~ to get rid
of them, and noticed that a little typo had catastrophic effects.
I wrote this program, which I called "purge", in C to do this stuff
for me. At the time I didn't know awk or perl, so there is
undoubtedly a shorter way to do it, but for what it's worth, here's my
stuff. No complaints about programming style please: I know it's a
little sloppy.
What purge does:
1) Search a directory for all files ending in .~n~ or ~
2) establish that there is a more recently NUMBERED program of the
same name, either with a .~n~ extension or with no extension.
e.g., main.c.~2~ is newer than main.c.~1~ and main.c is
newer than both of them.
Purge does not check file dates, though it really should.
3) If a newer version can be found for a particular .~n~ or ~ file,
then remove that file and report it.
4) Has the following arguments:
directory name: Purge this directory.
-c : confirm every file before erasing it.
-r : recursively purge, starting at named or current
directory.
Flags and directory names may appear anywhere. Flags are not toggles.
The thing I like about this is that it won't make stupid mistakes like
"rm *". It also tries not to delete all copies of a file. File names
with wild cards in them are not globbed.
I make no claims to this code at all. If you want to say you wrote
it, go ahead. I also take no responsibility for any of its actions.
I have been using this on a uVaxII running Ultrix 2.0, a Sun 3
running SUNOS3 and SUNOS4 and a SparcServer running SUNOS4. I have
never had it do something unexpected in two years or service. That's
more than I can say for my typing. :-)
compile with:
{g}cc -O -o purge purge.c
------------------- purge.c -------------------
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>
void Usage (s)
char* s;
{
fprintf (stderr, "Usage: %s [directory_name ...] [-c] [-r]\n", s);
fprintf (stderr, " -c = confirm before erasing files\n");
fprintf (stderr, " -r = recursively follow all subdirectories\n");
exit (1);
}
int main(argc, argv)
int argc;
char *argv[];
{
int confirm = 0, i, recurse = 0, got_one = 0;
for (i=1; i<argc; i++)
{
switch (argv[i][0])
{
case '-':
switch (argv[i][1])
{
case 'c':
confirm = 1;
break;
case 'r':
recurse = 1;
break;
default:
Usage (argv[0]);
break;
}
break;
}
}
for (i=1; i<argc; i++)
{
if (argv[i][0] != '-')
{
Do_Purge (argv[i], confirm, recurse);
got_one = 1;
}
}
if (!got_one) Do_Purge (".", confirm, recurse);
return (0);
}
char* strsav(s)
char* s;
{
char* t;
t = (char*)malloc(strlen(s)+1);
strcpy (t,s);
return (t);
}
Do_Purge (directory, confirm, recurse)
char* directory;
int confirm;
int recurse;
{
DIR *dirp;
struct direct *entry;
char *deletes[1000];
int ndels = 0, i, slash = 0;
char wholefile[160], instr[80], *this_file;
int mycompare();
if (!is_directory(directory))
{
fprintf (stderr, "File: %s - not a directory\n", directory);
return;
}
if ((dirp = opendir(directory)) == NULL)
{
fprintf (stderr, "Could not open directory: %s\n", directory);
return;
}
if (directory[strlen(directory)-1] != '/') slash = 1;
for (entry = readdir(dirp); entry != NULL; entry = readdir(dirp))
{
sprintf (wholefile, "%s%s%s",
directory,
(slash ? "/" : ""),
entry->d_name);
if (recurse && is_directory(wholefile))
{
if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
{
Do_Purge (wholefile, confirm, recurse);
}
continue;
}
if (entry->d_name[strlen(entry->d_name)-1] == '~')
{
if (Has_More_Recent(entry, dirp))
{
deletes[ndels++] = strsav(wholefile);
}
}
}
qsort (deletes, ndels, sizeof(char *), mycompare);
for (i=0; i<ndels; i++)
{
this_file = deletes[i];
if (confirm)
{
fprintf (stdout, "Delete: %s ? (y/n/q/a) ", this_file);
fscanf (stdin, "%s", instr);
instr[0] = tolower(instr[0]);
if (instr[0] == 'a')
{
confirm = 0;
instr[0] = 'y';
}
else if (instr[0] == 'q')
{
i = ndels;
}
}
else
{
fprintf (stdout, "Delete: %s\n", this_file);
instr[0] = 'y';
}
if (instr[0] == 'y') unlink (this_file);
}
closedir (dirp);
}
int mycompare(a, b)
char **a, **b;
{
return (strcmp(*a, *b));
}
Has_More_Recent (thisentry, dirp)
struct direct *thisentry;
DIR *dirp;
{
long spot;
struct direct *rentry;
char candidate[160];
int a;
char *directory;
strcpy (candidate, thisentry->d_name);
*index(candidate, '~') = '\0';
if (candidate[a=strlen(candidate)-1] == '.') candidate[a] = '\0';
spot = telldir(dirp);
rewinddir (dirp);
for (rentry = readdir(dirp); rentry != NULL; rentry = readdir(dirp))
{
if (rentry != thisentry)
{
if (!strcmp(rentry->d_name, candidate))
{
seekdir (dirp, spot);
return (1);
}
}
}
seekdir (dirp, spot);
return (0);
}
int is_directory (directory)
char* directory;
{
struct stat stats;
stat (directory, &stats);
if (stats.st_mode & S_IFDIR) return (1);
else return (0);
}
-----------------------------------------------
--
Andrew Thomas
andrewt@watnow.waterloo.edu Systems Design Eng. University of Waterloo
"If a million people do a stupid thing, it's still a stupid thing." - Opus