Exemplo n.º 1
0
static int cp_parseArgs( int argc, char *argv[] )
{
        int c;
        while( ( c = getopt( argc, argv, "t:H:P:hv" ) ) != -1 ) {
                switch ( c ) {
                case 't':
                        if( !strcasecmp( optarg, "remote" )
                            || ( !strcasecmp( optarg, "local" ) ) )
                                setenv( "axi_ttype", optarg, 1 );
                        break;
                case 'H':
                        setenv( "axi_host", optarg, 1 );
                        break;
                case 'P':
                        setenv( "axi_port", optarg, 1 );
                        break;
                case 'h':
                        cp_usage(  );
                case 'v':
                        break;
                }
        }
        return TRUE;
}
Exemplo n.º 2
0
int
cp_main(int argc, char *argv[])
{
	struct stat to_stat, tmp_stat;
	enum op type;
	int ch, fts_options, r, have_trailing_slash;
	char *target, **src;

#ifndef ANDROID
	setprogname(argv[0]);
#endif
	(void)setlocale(LC_ALL, "");

	Hflag = Lflag = Pflag = Rflag = 0;
	while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1)
		switch (ch) {
		case 'H':
			Hflag = 1;
			Lflag = Pflag = 0;
			break;
		case 'L':
			Lflag = 1;
			Hflag = Pflag = 0;
			break;
		case 'N':
			Nflag = 1;
			break;
		case 'P':
			Pflag = 1;
			Hflag = Lflag = 0;
			break;
		case 'R':
			Rflag = 1;
			break;
		case 'a':
			Pflag = 1;
			pflag = 1;
			Rflag = 1;
			Hflag = Lflag = 0;
			break;
		case 'f':
			fflag = 1;
			iflag = 0;
			break;
		case 'i':
			iflag = isatty(fileno(stdin));
			fflag = 0;
			break;
		case 'l':
			lflag = 1;
			break;
		case 'p':
			pflag = 1;
			break;
		case 'r':
			rflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
		case '?':
		default:
			cp_usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

	if (argc < 2)
		cp_usage();

	fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
	if (rflag) {
		if (Rflag) {
			errx(EXIT_FAILURE,
		    "the -R and -r options may not be specified together.");
			/* NOTREACHED */
		}
		if (Hflag || Lflag || Pflag) {
			errx(EXIT_FAILURE,
	"the -H, -L, and -P options may not be specified with the -r option.");
			/* NOTREACHED */
		}
		fts_options &= ~FTS_PHYSICAL;
		fts_options |= FTS_LOGICAL;
	}

	if (Rflag) {
		if (Hflag)
			fts_options |= FTS_COMFOLLOW;
		if (Lflag) {
			fts_options &= ~FTS_PHYSICAL;
			fts_options |= FTS_LOGICAL;
		}
	} else if (!Pflag) {
		fts_options &= ~FTS_PHYSICAL;
		fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
	}

	myuid = getuid();

	/* Copy the umask for explicit mode setting. */
	myumask = umask(0);
	(void)umask(myumask);

	/* Save the target base in "to". */
	target = argv[--argc];
	if (strlcpy(to.p_path, target, sizeof(to.p_path)) >= sizeof(to.p_path))
		errx(EXIT_FAILURE, "%s: name too long", target);
	to.p_end = to.p_path + strlen(to.p_path);
	have_trailing_slash = (to.p_end[-1] == '/');
	if (have_trailing_slash)
		STRIP_TRAILING_SLASH(to);
	to.target_end = to.p_end;

	/* Set end of argument list for fts(3). */
	argv[argc] = NULL;

#ifndef ANDROID
	(void)signal(SIGINFO, progress);
#endif

	/*
	 * Cp has two distinct cases:
	 *
	 * cp [-R] source target
	 * cp [-R] source1 ... sourceN directory
	 *
	 * In both cases, source can be either a file or a directory.
	 *
	 * In (1), the target becomes a copy of the source. That is, if the
	 * source is a file, the target will be a file, and likewise for
	 * directories.
	 *
	 * In (2), the real target is not directory, but "directory/source".
	 */
	if (Pflag)
		r = lstat(to.p_path, &to_stat);
	else
		r = stat(to.p_path, &to_stat);
	if (r == -1 && errno != ENOENT) {
		err(EXIT_FAILURE, "%s", to.p_path);
		/* NOTREACHED */
	}
	if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
		/*
		 * Case (1).  Target is not a directory.
		 */
		if (argc > 1)
			cp_usage();
		/*
		 * Need to detect the case:
		 *	cp -R dir foo
		 * Where dir is a directory and foo does not exist, where
		 * we want pathname concatenations turned on but not for
		 * the initial mkdir().
		 */
		if (r == -1) {
			if (rflag || (Rflag && (Lflag || Hflag)))
				r = stat(*argv, &tmp_stat);
			else
				r = lstat(*argv, &tmp_stat);
			if (r == -1) {
				err(EXIT_FAILURE, "%s", *argv);
				/* NOTREACHED */
			}

			if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
				type = DIR_TO_DNE;
			else
				type = FILE_TO_FILE;
		} else
			type = FILE_TO_FILE;

		if (have_trailing_slash && type == FILE_TO_FILE) {
			if (r == -1)
				errx(1, "directory %s does not exist",
				     to.p_path);
			else
				errx(1, "%s is not a directory", to.p_path);
		}
	} else {
		/*
		 * Case (2).  Target is a directory.
		 */
		type = FILE_TO_DIR;
	}

	/*
	 * make "cp -rp src/ dst" behave like "cp -rp src dst" not
	 * like "cp -rp src/. dst"
	 */
	for (src = argv; *src; src++) {
		size_t len = strlen(*src);
		while (len-- > 1 && (*src)[len] == '/')
			(*src)[len] = '\0';
	}

	exit(copy(argv, type, fts_options));
	/* NOTREACHED */
}