home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum5.lzh
/
SPRACHEN
/
C
/
FIND
/
find.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-04-13
|
9KB
|
314 lines
/* find.c
*
* 'find' sucht rekursiv nach Files mit bestimmten Eigenschaften und
* fuehrt dann Operationen auf diese gefundenen Files aus
*
* Uwe Simon April 1988
*
* Dieses Programm ist PD-Software !!!!!!
* Es basiert auf du.c von Tom Leitner, Graz
*
*/
/* system includes */
#include <stdio.h>
#include <dir.h>
#include <modes.h>
#include <direct.h>
#include <time.h>
/* constants & macros */
#define RBF (1) /* random block file found opened */
#define PIPE (2) /* pipe file opened */
#define NET (4) /* network file opened */
#define TRUE 1 /* logical true */
#define FALSE 0 /* logical false */
#define KB(x) (x+1023L)/1024 /* formula to calculate kB from bytes */
#define SECT(x) (x+255L)/256 /* formula to calc. sectors from bytes */
#define MAXPATH 256 /* max. # of characters for path name */
#define EQ 0
#define LESS 1
#define MORE 2
/* global variables */
char path[MAXPATH] = ""; /* string to store the path */
char *root; /* root directory to start from */
int max_level=1000; /* max level to go in filesystem */
int print_flag=FALSE;
char *f_name=NULL; /* filename to look for */
char *exec_str=NULL; /* command to execute */
int ask=0; /* ask for command flag */
int user=0,group=0,perm=0,size=-1,t_f=1;
int user_q=1,group_q=1,name_q=1,size_q=0,perm_q;
/*-------------------------------- M A I N ----------------------------------*/
main(argc, argv)
int argc;
char *argv[];
{
get_parms(argc, argv);
findfile(0,root);
}
/*-------------------- parses command line for parameters --------------------*/
get_parms(argc,argv)
int argc;
char *argv[];
{
char *s;
int pc = 0;
while (--argc>0) {
if ((*++argv)[0] == '-') {
if(strlen(argv[0])>1) {
if(argv[0][2]=='=') s=&argv[0][3];
else s=&argv[0][2];
} else s=NULL;
switch(toupper(argv[0][1])) {
case '~':
case '!':
t_f=FALSE;
break;
case 'O':
print_flag = TRUE;
break;
case 'U':
if(s[0]=='-') { user_q=0; s++;}
user=atoi(s);
break;
case 'G':
if(s[0]=='-') { group_q=0; s++;}
group=atoi(s);
break;
case 'S':
switch(s[0]) {
case '+': size_q=LESS; s++; break;
case '-': size_q=MORE; s++; break;
default: size_q=EQ;
}
size=atoi(s);
break;
case 'P':
perm=0;
while(*s) {
perm= (perm<<3)+*s++-'0';
}
break;
case 'A': ask=1;
case 'E':
exec_str=s;
break;
case 'N':
if(s[0]=='-') { name_q=0; s++;}
f_name=s;
break;
case 'L':
max_level=atoi(s);
break;
case '?':
usage();
exit(0);
default:
_errmsg(0,"unknown option '%c'\n",argv[0][1]);
exit(1);
}
}
else if (pc == 0) {
root = argv[0];
pc++;
} else exit(_errmsg(1,"only one parameter allowed"));
}
if (pc == 0) root = ".";
}
/*------------------------- print usage explanations -------------------------*/
#define E(txt) fprintf(stderr, txt)
usage()
{
E("Syntax: find {<opts>} [<path>]\n");
E("Function: finds files in Filesystem\n");
E("Options :\n");
E("\t-o output the found pathnames\n");
E("\t-~ only non matching files\n");
E("\t-n=[-]<string> files with name <string> (wildcards allowed)\n");
E("\t-p=<num> files with permissions <num> (<num> is octal)\n");
E("\t-u=[-]<num> files which belong to user <num>\n");
E("\t-g=[-]<num> files which belong to group <num>\n");
E("\t-s=[+|-]<num> files are <num> blocks long (256 Byte/Block)\n");
E("\t-e=<string> execute <string> on matching files\n");
E("\t-a=<string> ask for executing <string> on matching files\n");
E("\t-l=<num> recursive search to depth <num>\n");
}
#undef E(txt)
/*------------------------------ main algorithm ------------------------------*/
findfile(level, filename )
char *filename;
{
unsigned long size=0L;
int fd, pl, dfiles;
DIR *dirp;
struct direct *dirrec;
static struct fildes stat;
/* setup the cumulative path name */
if(level>=max_level) return;
pl = strlen(path);
if (pl) strncat(path, "/", MAXPATH);
strncat(path, filename, MAXPATH);
/* try to open the file */
if( ((fd=open(filename,S_IREAD)) < 0) && /* regular file ? */
((fd=open(filename,S_IFDIR|S_IREAD)) < 0) ) /* directory ? */
fprintf(stderr,"Cannot open '%s'\n", filename);
/* successfully opened. check if it's on the right device */
else {
if(_gs_gfd(fd, &stat,sizeof(struct fildes))!=-1) {
/* now test if it is the file we want */
test_file(filename,stat,fd);
/* ok. we're on a valid device : now check if we hit a directory file */
if( stat.fd_att & S_IFDIR ) {
/* yes. we hit a directory file. close the FD and CHD into it. */
close(fd);
if(level==max_level-1) {
path[pl] = (char) NULL;
return;
}
if( (dirp = opendir( filename )) && !chdir( filename) ) {
/* skip the "." and the ".." entries */
readdir(dirp); readdir( dirp );
/* get file sizes of all files in this directory */
while (dirrec = readdir (dirp))
if (dirrec->d_addr) {
findfile(level+1,dirrec->d_name);
}
/* end of directory : close it and print the results */
closedir( dirp );
chdir("..");
}
/* ERROR occurred : can't CHD into this directory. */
else
fprintf(stderr, "Cannot chdir '%s'\n", filename);
/* the given filename was no directory. it's a normal file so just get its
size and increment the file count */
} else close( fd );
}
/* the given file name is not on a valid device */
else
fprintf(stderr,"Cannot read file - not a block special device\n");
}
/* reset the cumulative PATH string */
path[pl] = (char) NULL;
return( size );
}
/*-------------------------- print one table entry ---------------------------*/
test_file(name,pfd,f)
char *name;
struct fildes pfd;
int f;
{
int match,h_size;
match=1;
if(f_name) match=match&& ((_cmpnam(name,f_name,strlen(f_name))==0)==name_q);
if(user) match=match&& ((user==pfd.fd_own[1])==user_q);
if(group) match=match&& ((group==pfd.fd_own[0])==group_q);
if(perm) match=match&&((perm&pfd.fd_att)==perm);
if(size>=0) {
h_size=(_gs_size(f)+255)/256;
switch(size_q) {
case EQ: match=match&&(size==h_size); break;
case MORE: match=match&&(size>=h_size); break;
case LESS: match=match&&(size<=h_size); break;
}
}
if(match==t_f) do_command(name);
}
char *replace(str,s1,s2)
char *str,*s1,*s2; /* relace first place from s1 in str with s2 */
{
char sh[256],*pa;
int pos;
if((pos=findstr(1,str,s1))==NULL) return(NULL);
else {
pa=&str[pos-1+strlen(s1)];
strncpy(sh,str,pos-1);
sh[pos-1]='\0';
strcat(sh,s2);
strcat(sh,pa);
}
strcpy(str,sh); /* copy back new string */
return(&str[pos-1]);
}
do_command(name)
char *name;
{
char str[256],h[5],*pa;
int pos,ok;
ok=0;
if(print_flag) printf("%s\n",path);
if(exec_str) {
strcpy(str,exec_str);
for(;replace(str,"{}",name);); /* replace all {} with filename */
if(ask) {
fprintf(stderr,"Pathname: %s\n",path);
fprintf(stderr,"execute: %s\n",str);
do {
fgets(h,4,stdin);
switch(toupper(h[0])) {
case 'Y': ok=1; break;
case 'N': return; break;
case 'C': exit(0);
default: printf("\nY(es, N(o or C(ancel\n");
}
} while(!ok);
}
system(str);
}
}
/* E O F */