home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
kill2.zip
/
kill2src.zip
/
kill.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-21
|
14KB
|
513 lines
/*************************************************************************/
/* Kill2 file maintenance utility copyright (c) 1992 by M. Kimes */
/* all rights reserved */
/* Free for use in non-commercial environments */
/* $10.00 for commercial use to the author */
/*************************************************************************/
#define INCL_DOS
#include <os2.h>
#include <io.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <time.h>
#include <malloc.h>
typedef struct __filelist__ {
char *filename;
struct __filelist__ *next;
} FILELIST;
#define JUSTLIST 1
#define JUSTTOUCH 2
#define RECURSE 4
int majversion = 0,minversion = 2;
int redirected;
extern void sendhelp (void);
extern int _fastcall wildcard (char *fstr,char *fcard);
extern int _fastcall oldenough (char *filename,ULONG days);
extern int _fastcall unixsetftime (int handle,time_t t);
extern struct __filelist2__ *msortl(struct __filelist2__ *p);
extern time_t _fastcall dosfile_2_unix (struct _ftime *ft,struct _fdate *fd);
FILELIST * _fastcall add_to_excemptlist (USHORT newest,FILELIST *ehead,
FILELIST *khead) {
/* add newest files to exempt list */
FILELIST *info,*nhead = ehead,*nlast;
struct __filelist2__ {
char *filename;
time_t filedate;
struct __filelist2__ *next;
} *tinfo = NULL,*tlast = NULL,*thead = NULL;
USHORT numfiles = 0;
FILEFINDBUF f;
int search_handle,num_matches;
nlast = nhead;
while(nlast) nlast = nlast->next;
while(khead) {
search_handle = -1;
num_matches = 1;
if(!DosFindFirst(khead->filename,&search_handle,0,&f,
sizeof(FILEFINDBUF),&num_matches,0L)) {
while(num_matches == 1) {
tinfo = malloc(sizeof(struct __filelist2__));
if(!tinfo) {
fprintf(stderr,"\n **Out of memory\n");
exit(6);
}
tinfo->filename = strdup(f.achName);
if(!tinfo->filename) {
free(tinfo);
fprintf(stderr,"\n **Out of memory\n");
exit(6);
}
tinfo->filedate = dosfile_2_unix(&f.ftimeLastWrite,&f.fdateLastWrite);
if(!thead) {
thead = tinfo;
}
else tlast->next = tinfo;
tlast = tinfo;
tinfo->next = NULL;
numfiles++;
if(DosFindNext(search_handle,&f,sizeof(FILEFINDBUF),&num_matches)) break;
}
DosFindClose(search_handle);
}
khead = khead->next;
}
if(numfiles > newest) {
thead = msortl(thead);
while(numfiles > newest && thead) {
tinfo = thead;
thead = thead->next;
free(tinfo->filename);
free(tinfo);
numfiles--;
}
}
fprintf(stderr,"-A%u Excluded:\n",newest);
while(thead) {
tinfo = thead;
thead = thead->next;
info = malloc(sizeof(FILELIST));
if(!info) {
fprintf(stderr,"\n **Out of memory\n");
exit(6);
}
info->filename = strdup(tinfo->filename);
if(!info->filename) {
free(info);
fprintf(stderr,"\n **Out of memory\n");
exit(6);
}
if(!nhead) {
nhead = info;
}
else nlast->next = info;
nlast = info;
info->next = NULL;
free(tinfo->filename);
free(tinfo);
fprintf(stderr," %s\n",info->filename);
}
return nhead;
}
int _fastcall wildcard_list (char *filename,FILELIST *exclude) {
FILELIST *info;
int ret = 0; /* match if no excludes */
info = exclude;
while(info) {
if(info->filename && wildcard(filename,info->filename)) {
ret = 1;
break;
}
info = info->next;
}
return ret;
}
long unlink_allf (FILELIST *exclude,ULONG days,int flags,char *string,...) {
/* wildcard delete */
FILEFINDBUF *f;
int search_handle,num_matches;
long numunlinked = 0L;
char *p,*ss,*str,*s,*filepart;
va_list ap;
time_t curtime;
curtime = time(NULL);
s = malloc(1028);
if(!s) return 0L;
va_start(ap,string);
vsprintf(s,string,ap);
va_end(ap);
if(!*s) {
free(s);
return 0L;
}
p = s;
while((p = strchr(p,'/')) != NULL) *p = '\\'; /* / = \\ */
str = strdup(s);
if(!str) {
free(s);
return 0L;
}
p = s;
p = strrchr(s,'\\'); /* strip s to just path */
if(!p) p = strrchr(s,':');
if(p) {
p++;
*p = 0;
}
else *s = 0;
filepart = str;
filepart = strrchr(str,'\\'); /* find file portion of str */
if(!filepart) filepart = strrchr(str,':');
if(filepart) {
filepart++;
}
else filepart = str;
ss = (char *)malloc(1027);
f = (FILEFINDBUF *)malloc(sizeof(FILEFINDBUF));
if(!ss || !f) {
if(ss) free(ss);
if(f) free(f);
free(str);
free(s);
return 0L;
}
search_handle = -1;
num_matches = 1;
if(!DosFindFirst(str,&search_handle,(FILE_DIRECTORY * ((flags & RECURSE) != 0)),
f,sizeof(FILEFINDBUF),&num_matches,0L)) {
strcpy(ss,s);
p = &ss[strlen(ss)];
while(num_matches == 1) {
if(f->attrFile & FILE_DIRECTORY) {
if(*f->achName != '.') {
if(stackavail() > 2048) {
fprintf(stderr," [-=> %s%s\\%s]\n",s,f->achName,filepart);
numunlinked += unlink_allf(exclude,days,flags,"%s%s\\%s",s,f->achName,filepart);
fprintf(stderr," [<=- %s%s]\n",s,filepart);
}
else fprintf(stderr," **Warning: insufficient stack for further recursion\n");
}
}
else {
if(!wildcard_list(f->achName,exclude)) {
strcpy(p,f->achName);
if(oldenough(ss,days)) {
if(!(flags & JUSTLIST) && !(flags & JUSTTOUCH)) {
unlink(ss);
fprintf(stderr," Unlinked");
}
else if(flags & JUSTTOUCH) {
int handle;
handle = sopen(ss,O_RDWR | O_BINARY,SH_DENYNO);
if(handle != -1) {
int error;
if((error = unixsetftime(handle,curtime)) == 0)
fprintf(stderr," Touched");
else
fprintf(stderr," Couldn't touch: error #%d.",error);
close(handle);
}
else
fprintf(stderr," Couldn't touch: no read/write access.");
}
fprintf(stderr," ");
printf("%s\n",ss);
if(redirected)
fprintf(stderr,"%s\n",ss);
numunlinked++;
}
}
}
if(DosFindNext(search_handle,f,sizeof(FILEFINDBUF),&num_matches)) break;
}
DosFindClose(search_handle);
}
free(f);
free(ss);
free(str);
free(s);
return numunlinked;
}
int main (int argc,char *argv[]) {
int flags = JUSTLIST,help = 0;
USHORT newest = 0;
FILE *fp;
FILELIST *ehead = NULL,*elast = NULL,*khead = NULL,*klast = NULL,*info;
ULONG days = 0L,numdead = 0L;
char s[1027];
{
USHORT info,devhead;
DosQHandType(fileno(stdout),&info,&devhead);
if(((info & 255) == 1) && (devhead & 2)) redirected = 0;
else redirected = 1;
}
fprintf(stderr,"\n");
if(argc < 2) help = 1;
while(argc > 1) {
switch(toupper(*argv[argc - 1])) {
case '-':
case '/':
switch(toupper(argv[argc - 1][1])) {
case 'E': /* file pattern to exclude */
if(argv[argc - 1][2] == '@' && argv[argc - 1][3] != '@') {
fprintf(stderr,"Loading exclude list \"%s\"\n",&argv[argc - 1][3]);
fp = fopen(&argv[argc - 1][3],"rt");
if(fp) {
while(!feof(fp) && fgets(s,1027,fp)) {
info = malloc(sizeof(FILELIST));
if(!info) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
while(s[strlen(s) - 1] == '\n' || s[strlen(s) - 1] == ' ')
s[strlen(s) - 1] = 0; /* strip lf, trailing spaces */
while(*s == ' ') memmove(s,&s[1],strlen(s)); /* leading spaces */
if(!*s) continue;
info->filename = strdup(s);
if(!info->filename) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->next = NULL;
if(!ehead) {
ehead = info;
}
else elast->next = info;
elast = info;
#ifdef DEBUG
fprintf(stderr,"EXCLUDE: \"%s\"\n",info->filename);
#endif
}
fclose(fp);
}
else {
fprintf(stderr,"\n **Couldn't load exclude files from \"%s\"!\n",&argv[argc - 1][3]);
return 5;
}
}
else {
info = malloc(sizeof(FILELIST));
if(!info) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->filename = strdup(&argv[argc - 1][2 + (argv[argc - 1][2] == '@')]);
if(!info->filename) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->next = NULL;
if(!ehead) {
ehead = info;
}
else elast->next = info;
elast = info;
#ifdef DEBUG
fprintf(stderr,"EXCLUDE: \"%s\"\n",info->filename);
#endif
}
break;
case 'L':
flags |= JUSTLIST;
#ifdef DEBUG
fprintf(stderr,"LISTing\n");
#endif
break;
case 'A':
newest = atoi(&argv[argc - 1][2]);
#ifdef DEBUG
fprintf(stderr,"NEWest %u\n",newest);
#endif
if(!newest) {
fprintf(stderr,"\n **Error in -A# argument; 0 given\n");
return 8;
}
break;
case '?':
case 'H':
help = 1;
#ifdef DEBUG
fprintf(stderr,"HELPing\n");
#endif
break;
case 'T':
flags |= JUSTTOUCH;
#ifdef DEBUG
fprintf(stderr,"TOUCHing\n");
#endif
break;
case 'K': /* KILL! */
flags &= (~(JUSTLIST | JUSTTOUCH));
#ifdef DEBUG
fprintf(stderr,"KILLing\n");
#endif
break;
case 'D':
days = atol(&argv[argc - 1][2]);
fprintf(stderr,"Processing files %lu day%s old or older\n",days,&"s"[days == 1L]);
break;
case 'R':
flags |= RECURSE;
#ifdef DEBUG
fprintf(stderr,"RECURSE\n");
#endif
break;
case '-':
memmove(argv[argc - 1],&argv[argc - 1][1],strlen(argv[argc - 1]));
goto DashInterrupt;
default:
fprintf(stderr,"\n **Unknown switch %s\n",argv[argc - 1]);
return 3;
}
break;
default: /* file pattern to kill */
DashInterrupt:
if(*argv[argc - 1] == '@' && argv[argc - 1][1] != '@') {
fprintf(stderr,"Loading kill list \"%s\"\n",&argv[argc - 1][1]);
fp = fopen(&argv[argc - 1][1],"rt");
if(fp) {
while(!feof(fp) && fgets(s,1027,fp)) {
info = malloc(sizeof(FILELIST));
if(!info) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
while(s[strlen(s) - 1] == '\n' || s[strlen(s) - 1] == ' ')
s[strlen(s) - 1] = 0; /* strip lf, trailing spaces */
while(*s == ' ') memmove(s,&s[1],strlen(s)); /* leading spaces */
if(!*s) continue;
info->filename = strdup(s);
if(!info->filename) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->next = NULL;
if(!khead) {
khead = info;
}
else klast->next = info;
klast = info;
#ifdef DEBUG
fprintf(stderr,"KILL: \"%s\"\n",info->filename);
#endif
}
fclose(fp);
}
else fprintf(stderr," **Warning: couldn't open \"%s\"\n",&argv[argc - 1][1]);
}
else {
info = malloc(sizeof(FILELIST));
if(!info) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->filename = strdup(&argv[argc - 1][(*argv[argc - 1] == '@')]);
if(!info->filename) {
fprintf(stderr,"\n **Out of memory\n");
return 2;
}
info->next = NULL;
if(!khead) {
khead = info;
}
else klast->next = info;
klast = info;
#ifdef DEBUG
fprintf(stderr,"KILL: \"%s\"\n",info->filename);
#endif
}
break;
}
argc--;
}
if(help) {
sendhelp();
return 1;
}
else {
if(newest && khead) {
flags &= (~RECURSE); /* no recursion w/ newest option */
info = add_to_excemptlist(newest,ehead,khead);
if(!ehead) ehead = info;
}
fprintf(stderr,"\nKILL2 v%d.%02d copyright (c) 1992 by M. Kimes -- all rights reserved\n",majversion,minversion);
if(!khead) {
fprintf(stderr,"\n **Nothing to do\n");
return 4;
}
info = khead;
while(info) {
fprintf(stderr," [%s]\n",info->filename);
numdead += unlink_allf(ehead,days,flags,info->filename);
info = info->next;
}
fprintf(stderr,"\nKILL2 processed %lu file%s\n",numdead,&"s"[numdead == 1L]);
}
return 0;
}