home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
ms_dos
/
sfind105
/
sfind.c
< prev
next >
Wrap
Text File
|
1980-01-02
|
8KB
|
403 lines
/**
SFIND : Same File Find Utility
Ver 1.00 90/10/03 Creation
Ver 1.01 90/10/24 Bug at -e Process
Ver 1.02 90/10/26 Bug at Previous Stack & Drive Check
Ver 1.03 90/11/13 Module Size Compaction
Ver 1.04 90/12/29 Bug at Perfect Match File
Ver 1.05 91/01/02 -T Support
**/
#define TITLE "Same File Find Utility Ver 1.05 (c)masuo 1990,1991.\n\n"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#if !LATTICE
#include <conio.h>
#include <dir.h>
#endif
typedef unsigned int uint;
extern int toupper(int);
#define isdigit(c) ('0'<=c && c<='9')
#define EOS '\0'
#define ESC '\x1b'
#define CR '\r'
#define ERROR (-1)
#if LATTICE
#define FALSE 0
#define TRUE 1
#define OFF 0
#define ON 1
#define NO 0
#define YES 1
#define FA_RDONLY 0x01 /* Read only attribute */
#define FA_HIDDEN 0x02 /* Hidden file */
#define FA_SYSTEM 0x04 /* System file */
#define FA_DIREC 0x10 /* Directory */
#define ff_attrib attr
#define ff_name name
#define setdta(a) chgdta(a)
#define findfirst(a,b,c) dfind(b,a,c)
#define findnext(a) dnext(a)
#define getdisk() getdsk()
#define setdisk(d) chgdsk(d)
#else
typedef unsigned char byte;
typedef enum {FALSE, TRUE} boolean;
typedef enum {OFF, ON} sw;
typedef enum {NO, YES} FLAG;
#endif
struct FBUF {
struct FBUF *after;
char *dirptr;
long size;
union {
struct {
uint time;
uint date;
} t;
long ltime;
}d;
char attr;
char name[13];
};
struct FBUF *fbftop=NULL;
struct FBUF *filebuf;
byte filechk=OFF;
byte permatch=OFF;
byte timesame=OFF;
void dispfile(int, struct FBUF *);
int u_strcmp(char *, char *);
void u_strcat(char *, char *);
int buf_scan(struct FBUF *);
void get_dir(char *);
int select(void);
int yesno(void);
void dispfile(num, files)
int num;
struct FBUF *files;
{
int year, mon, day, hour, min, sec;
sec =(files->d.t.time&0x001f)*2;
min =(files->d.t.time&0x7ff)/0x20;
hour= files->d.t.time/0x0800;
day = files->d.t.date&0x001f;
mon =(files->d.t.date&0x01ff)/0x20;
year= files->d.t.date/0x200+1980;
fprintf(stdout,"\x1b[33m%2d\x1b[37m %-14s%8ld %04d-%02d-%02d %02d:%02d:%02d %s\x1b[m\n",
num, files->name, files->size, year, mon, day, hour, min, sec,
files->dirptr);
}
u_strcmp(p, q)
char *p, *q;
{
while(1){
if((!*p && !*q) || (filechk && *p=='.' && *q=='.'))
break;
if(*p!=*q)
return TRUE;
p++, q++;
}
return FALSE;
}
void u_strcat(d, s)
char *d, *s;
{
char *t=d;
while(*t)
t++;
while(*s){
if(!strrchr(d,*s)){
*t++=*s;
*t=EOS;
}
s++;
}
}
int buf_scan(buf)
struct FBUF *buf;
{
int cnt=0;
struct FBUF *a;
for(a=buf->after; a; a=a->after){
if(!timesame)
if(u_strcmp(a->name, buf->name))
break;
if(timesame || permatch)
if(a->d.ltime!=buf->d.ltime||a->size!=buf->size)
break;
cnt++;
}
return cnt;
}
void get_dir(path)
char *path;
{
#if LATTICE
struct FILEINFO info;
#else
struct ffblk info;
#endif
char *dirbuf;
char *lastp=path+strlen(path);
#if !LATTICE
long *tt;
#endif
int chk;
struct FBUF *tmp, *prev;
if(*(lastp-1)!='\\')
strcpy(lastp++,"\\");
dirbuf=malloc(strlen(path)+1);
if(!dirbuf){
fprintf(stderr, "malloc error(dirbuf)\n");
exit(2);
}
strcpy(dirbuf, path);
strcpy(lastp,"*.*");
setdta((char *)&info);
if(!findfirst(path, &info, 0x37)){
do{
if(info.ff_attrib & FA_DIREC){
if(info.ff_name[0]!='.'){
strcpy(lastp, info.ff_name);
get_dir(path);
setdta((char *)&info);
}
}else if(!(info.ff_attrib & (FA_SYSTEM|FA_HIDDEN|FA_RDONLY))){
filebuf=(struct FBUF *)malloc(sizeof(*filebuf));
if(!filebuf){
fprintf(stderr, "malloc error(filebuf)\n");
exit(2);
}
for(tmp=fbftop; tmp; prev=tmp, tmp=tmp->after){
if(!timesame){
chk=strcmp(info.ff_name, tmp->name);
if(chk<0)
break;
}
if(timesame||(permatch && !chk)){
#if LATTICE
if(info.time<tmp->d.ltime)
break;
else if(info.time==tmp->d.ltime && info.size<tmp->size)
break;
#else
tt=(long *)&info.ff_ftime;
if(*tt<tmp->d.ltime)
break;
else if(*tt==tmp->d.ltime && info.ff_fsize<tmp->size)
break;
#endif
}
}
filebuf->after=tmp;
if(tmp==fbftop)
fbftop=filebuf;
else
prev->after=filebuf;
filebuf->dirptr=dirbuf;
filebuf->attr=info.ff_attrib;
#if LATTICE
filebuf->d.ltime=info.time;
filebuf->size=info.size;
#else
filebuf->d.t.time=info.ff_ftime;
filebuf->d.t.date=info.ff_fdate;
filebuf->size=info.ff_fsize;
#endif
strcpy(filebuf->name, info.ff_name);
}
}while(!findnext(&info));
}
}
int select(void)
{
int ch;
while(1){
ch=getch();
if(ch=='D' || ch=='d' || ch==CR || ch==ESC)
break;
}
return ch;
}
int yesno(void)
{
while(1){
switch(toupper(getch())){
case 'Y':
return YES;
case 'N':
case ESC:
return NO;
}
}
}
void main(argc, argv)
int argc;
char *argv[];
{
struct FBUF *filebuf, *tmp;
int i, j, cnt, ch;
int curdrv=getdisk();
char drvs[128], work[128];
static char *usage[]={
"usage: ",""," [opt] drives...\n",
"option: -e=Extent Nocheck\n",
" -p=Perfect Same\n",
" -t=Time & Date & Size Same\n",
" -?=This Message\n",
NULL
};
fprintf(stderr,TITLE);
usage[1]=strrchr(*argv,'\\')+1;
drvs[0]=EOS;
if(--argc){
while(argc--){
if(**++argv=='-' || **argv=='/'){
switch(toupper(*(*argv+1))){
case 'E':
filechk=ON;
break;
case 'P':
permatch=ON;
break;
case 'T':
timesame=ON;
break;
default:
{
char **usg;
*strrchr(usage[1],'.')=EOS;
for(usg=usage; *usg; usg++)
fprintf(stderr,*usg);
}
exit(1);
}
}else{
u_strcat(drvs, *argv);
}
}
}
if(permatch)
timesame=OFF;
if(!drvs[0]){
drvs[0]=curdrv+'A';
drvs[1]=EOS;
}
for(i=0; drvs[i]; i++){
ch=toupper(drvs[i]);
setdisk(ch-'A');
if(getdisk()!=ch-'A'){
fprintf(stderr, "Invalid Drive specification: %c:\n",ch);
}else{
setdisk(curdrv);
work[0]=ch;
work[1]=':';
work[2]='\\';
work[3]=EOS;
get_dir(work);
}
}
for(filebuf=fbftop; filebuf; filebuf=filebuf->after){
scan: cnt=buf_scan(filebuf);
if(cnt){
for(i=0, tmp=filebuf; i<=cnt; i++,tmp=tmp->after)
dispfile(i+1, tmp);
fprintf(stderr,"[1..%d/ESC/CR]",++cnt);
retry: ch=getch();
#if !LATTICE
if(ch==0x03){
fprintf(stderr,"^C\n");
break;
}
#endif
if(isdigit(ch)){
i=ch-'0';
fprintf(stderr,"%c",ch);
if(i && i<=cnt/10 && cnt>9){
ch=getch();
if(ch!=CR){
if(!isdigit(ch)){
ch=ESC; goto errexit;
}
i=i*10+(ch-'0');
}
}
if((!i) || (i>cnt)){
ch=ESC;
}else{
for(j=1, tmp=filebuf; j<i; j++)
tmp=tmp->after;
strcpy(work, tmp->dirptr);
strcat(work, tmp->name);
fprintf(stderr, "\x1b[80D\x1b[7;31m%s\x1b[m ==> What Process [Del/CR/ESC]",work);
switch(toupper(ch=select())){
case CR:
if(strlen(tmp->dirptr)>3)
tmp->dirptr[strlen(tmp->dirptr)-1]=EOS;
setdisk(tmp->dirptr[0]-'A');
chdir(tmp->dirptr);
fprintf(stderr, "\x1b[80D\x1b[K\n\x1b[7m%s\x1b[m",
tmp->dirptr);
exit(0);
case 'D':
fprintf(stderr, "\x1b[25DDelete OK (Y/N)\x1b[K");
if(yesno()){
unlink(work);
fprintf(stderr, "\x1b[9Dd.\x1b[K\n");
if(cnt>2){
if(i==1){
filebuf=filebuf->after;
}else{
for(j=2, tmp=filebuf; j<i; j++)
tmp=tmp->after;
tmp->after=tmp->after->after;
}
goto scan;
}
}
break;
}
ch=CR;
}
}
if(ch!=CR && ch!=ESC)
goto retry;
errexit: fprintf(stderr,"\x1b[80D\x1b[K\n");
if(ch==ESC)
break;
while(filebuf->after){
if(!timesame)
if(u_strcmp(filebuf->name, filebuf->after->name))
break;
if(timesame || permatch)
if(filebuf->d.ltime!=filebuf->after->d.ltime
||filebuf->size !=filebuf->after->size)
break;
filebuf=filebuf->after;
}
}
}
exit(0);
}