find.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski/***********************************************************************
0095c7efbddd0ffeed6aaf8ec015346be161d819Till Mossakowski* This software is part of the ast package *
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski* Copyright (c) 1989-2012 AT&T Intellectual Property *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* and is licensed under the *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* Eclipse Public License, Version 1.0 *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* by AT&T Intellectual Property *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* A copy of the License is available at *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* http://www.eclipse.org/org/documents/epl-v10.html *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* Information and Software Systems Research *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* AT&T Research *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* Florham Park NJ *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski* Glenn Fowler <gsf@research.att.com> *
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski***********************************************************************/
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * Glenn Fowler
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * AT&T Research
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * rewrite of find program to use fts*() and optget()
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * this implementation should have all your favorite
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * find options plus these extensions:
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * -fast pattern
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * traverses the fast find database (updatedb(1))
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * under the dirs specified on the command line
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * for paths that contain pattern; all other
be408ef9713fbbbaf7bde82618f7d3f204fe806cTill Mossakowski * expression operators apply to matching paths
da955132262baab309a50fdffe228c9efe68251dCui Jian * -magic pattern
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * matches pattern agains the file(1) magic description
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * matches type/subtype against the file mime type
7474388b4c2236f8ab2327289555000268c7901aTill Mossakowski * -ignorecase
7474388b4c2236f8ab2327289555000268c7901aTill Mossakowski * case ingnored in path pattern matching
7474388b4c2236f8ab2327289555000268c7901aTill Mossakowski * -xargs command ... \;
7474388b4c2236f8ab2327289555000268c7901aTill Mossakowski * like -exec except that command will be invoked
7474388b4c2236f8ab2327289555000268c7901aTill Mossakowski * with as many file arguments as the system
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * allows per command
da955132262baab309a50fdffe228c9efe68251dCui Jian * -test now
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski * set the current time to now for testing
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowskistatic const char usage1[] =
e687bd70d6e6c98d82b239e01fef4a60de6739f4Till Mossakowski"[-1p1?@(#)$Id: find (AT&T Research) 2012-04-11 $\n]"
static const char usage2[] =
#include <ast.h>
#include <ls.h>
#include <modex.h>
#include <find.h>
#include <fts.h>
#include <dirent.h>
#include <error.h>
#include <proc.h>
#include <tm.h>
#include <ctype.h>
#include <magic.h>
#include <mime.h>
#include <regex.h>
#include <vmalloc.h>
#include "cmdarg.h"
enum Command
struct Node_s;
struct State_s;
typedef struct Args_s
const char* name;
int type;
int primary;
const char* arg;
const char* values;
const char* help;
} Args_t;
typedef union Value_u
} Value_t;
typedef struct Fmt_s
} Fmt_t;
typedef union Item_u
char* cp;
} Item_t;
struct Node_s
const char* name;
struct State_s
unsigned int minlevel;
unsigned int maxlevel;
int walkflags;
char* usage;
unsigned long now;
unsigned long day;
char* codes;
char* fast;
int icase;
int primary;
int reverse;
int silent;
static Args_t*
register int second;
word++;
if (*word)
return argp;
if (term >= 0)
value->s = s;
value->s = S_ISLNK(ent->fts_statp->st_mode) && pathgetlink(PATH(ent), fp->tmp, sizeof(fp->tmp)) > 0 ? fp->tmp : "";
value->i = 0;
stresc(s);
c = strlen(s);
} while ((c = *s++) && !isalpha(c));
c = toupper(c);
char** com;
case File:
case Num:
case AND:
case OR:
case COMMA:
case LPAREN:
np += i;
case RPAREN:
case LOGIC:
case META:
goto ignore;
case PHYS:
goto ignore;
case XDEV:
goto ignore;
case POST:
goto ignore;
case CHECK:
goto ignore;
case NOLEAF:
goto ignore;
case REVERSE:
goto ignore;
case SILENT:
goto ignore;
case CODES:
goto ignore;
case FAST:
goto ignore;
case ICASE:
goto ignore;
case LOCAL:
case ATIME:
case CTIME:
case MTIME:
case AMIN:
case CMIN:
case MMIN:
case USER:
case GROUP:
case EXEC:
case OK:
case XARGS:
if (!(k & CMD_INSERT) && streq(b, "{}") && (b = argv[opt_info.index]) && (streq(b, ";") || streq(b, "+") && !(i = 0)))
k |= CMD_INSERT;
if (k & CMD_INSERT)
case MAGIC:
case MIME:
case IREGEX:
case REGEX:
i |= REG_ICASE;
case PERM:
case SORT:
goto ignore;
case TYPE:
case XTYPE:
case CPIO:
goto common;
case NCPIO:
int fd;
if ((fd = open(b, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0)
case PRINT:
case PRINT0:
case PRINTF:
case PRINTX:
case FPRINT:
case FPRINT0:
case FPRINTF:
case FPRINTX:
case LS:
case FLS:
case NEWER:
case ANEWER:
case CNEWER:
case CHOP:
goto ignore;
case DAYSTART:
time_t t;
goto ignore;
case MINDEPTH:
goto ignore;
case MAXDEPTH:
goto ignore;
case TEST:
goto ignore;
register int val = 0;
int not = 0;
char* bp;
case FTS_DP:
case FTS_NS:
case FTS_DC:
case FTS_DNR:
case FTS_DNX:
case FTS_D:
ent->ignorecase = (state->icase || (!ent->fts_level || !ent->fts_parent->ignorecase) && strchr(astconf("PATH_ATTRIBUTES", ent->fts_name, NiL), 'c')) ? STR_ICASE : 0;
ent->ignorecase = ent->fts_level ? ent->fts_parent->ignorecase : (state->icase || strchr(astconf("PATH_ATTRIBUTES", ent->fts_name, NiL), 'c')) ? STR_ICASE : 0;
while (np)
case NOT:
case COMMA:
case LPAREN:
case OR:
return val;
case COMMA:
case OR:
if (val)
case LOCAL:
goto num;
case XTYPE:
val = ((state->walkflags & FTS_PHYSICAL) ? stat(PATH(ent), &st) : lstat(PATH(ent), &st)) ? 0 : st.st_mode;
goto type;
case TYPE:
type:
#ifdef S_ISSOCK
#ifdef S_ISCTG
#ifdef S_ISDOOR
val = 0;
case PERM:
case INUM:
goto num;
case ATIME:
goto tim;
case CTIME:
goto tim;
case MTIME:
tim:
case NEWER:
case ANEWER:
case CNEWER:
case SIZE:
goto num;
case USER:
goto num;
case NOUSER:
case GROUP:
goto num;
case NOGROUP:
case LINKS:
num:
case EXEC:
case OK:
case XARGS:
case NAME:
case INAME:
*bp = 0;
val = strgrpmatch(ent->fts_name, np->first.cp, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|(np->action == INAME ? STR_ICASE : ent->ignorecase)) != 0;
if (bp)
case LNAME:
val = S_ISLNK(ent->fts_statp->st_mode) && pathgetlink(PATH(ent), state->txt, sizeof(state->txt)) > 0 && strgrpmatch(state->txt, np->first.cp, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|ent->ignorecase);
case ILNAME:
val = S_ISLNK(ent->fts_statp->st_mode) && pathgetlink(PATH(ent), state->txt, sizeof(state->txt)) > 0 && strgrpmatch(state->txt, np->first.cp, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|STR_ICASE);
case PATH:
val = strgrpmatch(ent->fts_path, np->first.cp, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|ent->ignorecase) != 0;
case IPATH:
val = strgrpmatch(ent->fts_path, np->first.cp, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|STR_ICASE) != 0;
case MAGIC:
if (fp)
case MIME:
if (fp)
case REGEX:
val = 0;
case PRINT:
case PRINTF:
case PRINTX:
case PRUNE:
case FSTYPE:
case LS:
fmtls(state->buf, ent->fts_path, ent->fts_statp, NiL, S_ISLNK(ent->fts_statp->st_mode) && pathgetlink(PATH(ent), state->txt, sizeof(state->txt)) > 0 ? state->txt : NiL, LS_LONG|LS_INUMBER|LS_BLOCKS);
case EMPTY:
val = 0;
val = 0;
while ((dnt = readdir(dir)) && (dnt->d_name[0] == '.' && (!dnt->d_name[1] || dnt->d_name[1] == '.' && !dnt->d_name[2])));
case CFALSE:
val = 0;
case CTRUE:
case LEVEL:
goto num;
not = 0;
return val;
register long n1;
register long n2;
case ATIME:
case CTIME:
case MTIME:
case SIZE:
case NAME:
goto done;
done:
register char* cp;
register char** op;
if (!(state.vm = vmopen(Vmdcheap, Vmbest, 0)) || !(state.str = sfstropen()) || !(state.tmp = sfstropen()))
goto done;
sort = 0;
fp = 0;
goto done;
goto done;
goto done;
goto done;
argv[r] = 0;
goto done;
if (!*op)
goto done;
fp = 0;
done: