main.c revision 91400
1100616Smp/*-
259243Sobrien * Copyright (c) 1990, 1993, 1994
359243Sobrien *	The Regents of the University of California.  All rights reserved.
459243Sobrien *
559243Sobrien * This code is derived from software contributed to Berkeley by
659243Sobrien * Cimarron D. Taylor of the University of California, Berkeley.
759243Sobrien *
859243Sobrien * Redistribution and use in source and binary forms, with or without
959243Sobrien * modification, are permitted provided that the following conditions
1059243Sobrien * are met:
1159243Sobrien * 1. Redistributions of source code must retain the above copyright
1259243Sobrien *    notice, this list of conditions and the following disclaimer.
1359243Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1459243Sobrien *    notice, this list of conditions and the following disclaimer in the
1559243Sobrien *    documentation and/or other materials provided with the distribution.
1659243Sobrien * 3. All advertising materials mentioning features or use of this software
1759243Sobrien *    must display the following acknowledgement:
1859243Sobrien *	This product includes software developed by the University of
1959243Sobrien *	California, Berkeley and its contributors.
2059243Sobrien * 4. Neither the name of the University nor the names of its contributors
2159243Sobrien *    may be used to endorse or promote products derived from this software
2259243Sobrien *    without specific prior written permission.
2359243Sobrien *
2459243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25100616Smp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2659243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2759243Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2859243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2959243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3059243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3159243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3259243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3359243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3459243Sobrien * SUCH DAMAGE.
3559243Sobrien */
3659243Sobrien
3759243Sobrien#ifndef lint
3859243Sobrienchar copyright[] =
3959243Sobrien"@(#) Copyright (c) 1990, 1993, 1994\n\
4059243Sobrien	The Regents of the University of California.  All rights reserved.\n";
4159243Sobrien#endif /* not lint */
4259243Sobrien
4359243Sobrien#ifndef lint
4459243Sobrien#if 0
4559243Sobrienstatic char sccsid[] = "@(#)main.c	8.4 (Berkeley) 5/4/95";
4659243Sobrien#else
4759243Sobrienstatic const char rcsid[] =
4859243Sobrien  "$FreeBSD: head/usr.bin/find/main.c 91400 2002-02-27 17:57:00Z dwmalone $";
4959243Sobrien#endif
5059243Sobrien#endif /* not lint */
5159243Sobrien
5259243Sobrien#include <sys/types.h>
5359243Sobrien#include <sys/stat.h>
5459243Sobrien
5559243Sobrien#include <err.h>
5659243Sobrien#include <errno.h>
5759243Sobrien#include <fcntl.h>
5859243Sobrien#include <fts.h>
5959243Sobrien#include <locale.h>
6059243Sobrien#include <regex.h>
6159243Sobrien#include <stdio.h>
6259243Sobrien#include <stdlib.h>
6359243Sobrien#include <time.h>
6459243Sobrien#include <unistd.h>
6559243Sobrien
6659243Sobrien#include "find.h"
6759243Sobrien
6859243Sobrientime_t now;			/* time find was run */
6959243Sobrienint dotfd;			/* starting directory */
7059243Sobrienint ftsoptions;			/* options for the ftsopen(3) call */
7159243Sobrienint isdeprecated;		/* using deprecated syntax */
7259243Sobrienint isdepth;			/* do directories on post-order visit */
7359243Sobrienint isoutput;			/* user specified output operator */
7459243Sobrienint issort;         		/* do hierarchies in lexicographical order */
7559243Sobrienint isxargs;			/* don't permit xargs delimiting chars */
7659243Sobrienint mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
7759243Sobrienint regexp_flags = REG_BASIC;	/* use the "basic" regexp by default*/
7859243Sobrien
7959243Sobrienstatic void usage __P((void));
8059243Sobrien
8159243Sobrienint
8259243Sobrienmain(argc, argv)
8359243Sobrien	int argc;
8459243Sobrien	char *argv[];
8559243Sobrien{
8659243Sobrien	char **p, **start;
8759243Sobrien	int Hflag, Lflag, ch;
8859243Sobrien
8959243Sobrien	(void)setlocale(LC_ALL, "");
9059243Sobrien
9159243Sobrien	(void)time(&now);	/* initialize the time-of-day */
9259243Sobrien
9359243Sobrien	p = start = argv;
9459243Sobrien	Hflag = Lflag = 0;
9559243Sobrien	ftsoptions = FTS_NOSTAT | FTS_PHYSICAL;
9659243Sobrien	while ((ch = getopt(argc, argv, "EHLPXdf:sx")) != -1)
9759243Sobrien		switch (ch) {
9859243Sobrien		case 'E':
9959243Sobrien			regexp_flags |= REG_EXTENDED;
10059243Sobrien			break;
10159243Sobrien		case 'H':
10259243Sobrien			Hflag = 1;
10359243Sobrien			Lflag = 0;
10459243Sobrien			break;
10559243Sobrien		case 'L':
10659243Sobrien			Lflag = 1;
10759243Sobrien			Hflag = 0;
10859243Sobrien			break;
10959243Sobrien		case 'P':
11059243Sobrien			Hflag = Lflag = 0;
11159243Sobrien			break;
11259243Sobrien		case 'X':
11359243Sobrien			isxargs = 1;
11459243Sobrien			break;
11559243Sobrien		case 'd':
11659243Sobrien			isdepth = 1;
11759243Sobrien			break;
11859243Sobrien		case 'f':
11959243Sobrien			*p++ = optarg;
12059243Sobrien			break;
12159243Sobrien		case 's':
12259243Sobrien			issort = 1;
12359243Sobrien			break;
12459243Sobrien		case 'x':
12559243Sobrien			ftsoptions |= FTS_XDEV;
12659243Sobrien			break;
12759243Sobrien		case '?':
12859243Sobrien		default:
12959243Sobrien			break;
13059243Sobrien		}
13159243Sobrien
13259243Sobrien	argc -= optind;
13359243Sobrien	argv += optind;
13459243Sobrien
13559243Sobrien	if (Hflag)
13659243Sobrien		ftsoptions |= FTS_COMFOLLOW;
13759243Sobrien	if (Lflag) {
13859243Sobrien		ftsoptions &= ~FTS_PHYSICAL;
13959243Sobrien		ftsoptions |= FTS_LOGICAL;
14059243Sobrien	}
14159243Sobrien
14259243Sobrien	/*
14359243Sobrien	 * Find first option to delimit the file list.  The first argument
14459243Sobrien	 * that starts with a -, or is a ! or a ( must be interpreted as a
14559243Sobrien	 * part of the find expression, according to POSIX .2.
14659243Sobrien	 */
14759243Sobrien	for (; *argv != NULL; *p++ = *argv++) {
14859243Sobrien		if (argv[0][0] == '-')
14959243Sobrien			break;
15059243Sobrien		if ((argv[0][0] == '!' || argv[0][0] == '(') &&
15159243Sobrien		    argv[0][1] == '\0')
15259243Sobrien			break;
15359243Sobrien	}
15459243Sobrien
15559243Sobrien	if (p == start)
15659243Sobrien		usage();
15759243Sobrien	*p = NULL;
15859243Sobrien
15959243Sobrien	if ((dotfd = open(".", O_RDONLY, 0)) < 0)
16059243Sobrien		err(1, ".");
16159243Sobrien
16259243Sobrien	exit(find_execute(find_formplan(argv), start));
16359243Sobrien}
16459243Sobrien
16559243Sobrienstatic void
16659243Sobrienusage()
16759243Sobrien{
16859243Sobrien	(void)fprintf(stderr,
16959243Sobrien"usage: find [-H | -L | -P] [-EXdsx] [-f file] [file ...] [expression]\n");
17059243Sobrien	exit(1);
17169408Sache}
17259243Sobrien