188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/* 288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Copyright 2005 The Android Open Source Project 388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Android "cp" replacement. 588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * The GNU/Linux "cp" uses O_LARGEFILE in its open() calls, utimes() instead 788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * of utime(), and getxattr()/setxattr() instead of chmod(). These are 888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * probably "better", but are non-portable, and not necessary for our 988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * purposes. 1088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 1188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <stdlib.h> 1288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <stdio.h> 1388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <string.h> 1488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <unistd.h> 1588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <sys/types.h> 1688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <sys/stat.h> 1788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <getopt.h> 1888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <dirent.h> 1988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <fcntl.h> 2088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <utime.h> 2188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <limits.h> 2288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <errno.h> 2388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <assert.h> 2488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <host/CopyFile.h> 2588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 2688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*#define DEBUG_MSGS*/ 2788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#ifdef DEBUG_MSGS 2888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project# define DBUG(x) printf x 2988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#else 3088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project# define DBUG(x) ((void)0) 3188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#endif 3288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 3388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#define FSSEP '/' /* filename separator char */ 3488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 3588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 3688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/* 3788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Process the command-line file arguments. 3888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 3988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Returns 0 on success. 4088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 4188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectint process(int argc, char* const argv[], unsigned int options) 4288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{ 4388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int retVal = 0; 4488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int i, cc; 4588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project char* stripDest = NULL; 4688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int stripDestLen; 4788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project struct stat destStat; 4888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project bool destMustBeDir = false; 4988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project struct stat sb; 5088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 5188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project assert(argc >= 2); 5288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 5388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* 5488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Check for and trim a trailing slash on the last arg. 5588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 5688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * It's useful to be able to say "cp foo bar/" when you want to copy 5788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * a single file into a directory. If you say "cp foo bar", and "bar" 5888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * does not exist, it will create "bar", when what you really wanted 5988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * was for the cp command to fail with "directory does not exist". 6088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 6188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project stripDestLen = strlen(argv[argc-1]); 6288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project stripDest = malloc(stripDestLen+1); 6388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project memcpy(stripDest, argv[argc-1], stripDestLen+1); 6488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (stripDest[stripDestLen-1] == FSSEP) { 6588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project stripDest[--stripDestLen] = '\0'; 6688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project destMustBeDir = true; 6788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 6888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 6988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (argc > 2) 7088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project destMustBeDir = true; 7188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 7288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* 7388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Start with a quick check to ensure that, if we're expecting to copy 7488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * to a directory, the target already exists and is actually a directory. 7588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * It's okay if it's a symlink to a directory. 7688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 7788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * If it turns out to be a directory, go ahead and raise the 7888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * destMustBeDir flag so we do some path concatenation below. 7988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 8088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (stat(stripDest, &sb) < 0) { 8188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (destMustBeDir) { 8288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (errno == ENOENT) 8388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, 8488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project "acp: destination directory '%s' does not exist\n", 8588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project stripDest); 8688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project else 8788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, "acp: unable to stat dest dir\n"); 8888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project retVal = 1; 8988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project goto bail; 9088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 9188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } else { 9288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (S_ISDIR(sb.st_mode)) { 9388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project DBUG(("--- dest exists and is a dir, setting flag\n")); 9488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project destMustBeDir = true; 9588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } else if (destMustBeDir) { 9688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, 9788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project "acp: destination '%s' is not a directory\n", 9888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project stripDest); 9988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project retVal = 1; 10088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project goto bail; 10188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 10288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 10388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 10488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* 10588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Copying files. 10688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 10788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Strip trailing slashes off. They shouldn't be there, but 10888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * sometimes file completion will put them in for directories. 10988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 11088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * The observed behavior of GNU and BSD cp is that they print warnings 11188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * if something fails, but continue on. If any part fails, the command 11288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * exits with an error status. 11388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 11488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project for (i = 0; i < argc-1; i++) { 11588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project const char* srcName; 11688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project char* src; 11788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project char* dst; 11888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int copyResult; 11988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int srcLen; 12088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 12188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* make a copy of the source name, and strip trailing '/' */ 12288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project srcLen = strlen(argv[i]); 12388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project src = malloc(srcLen+1); 12488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project memcpy(src, argv[i], srcLen+1); 12588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 12688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (src[srcLen-1] == FSSEP) 12788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project src[--srcLen] = '\0'; 12888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 12988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* find just the name part */ 13088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project srcName = strrchr(src, FSSEP); 13188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (srcName == NULL) { 13288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project srcName = src; 13388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } else { 13488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project srcName++; 13588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project assert(*srcName != '\0'); 13688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 13788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 13888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (destMustBeDir) { 13988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* concatenate dest dir and src name */ 14088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int srcNameLen = strlen(srcName); 14188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 14288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project dst = malloc(stripDestLen +1 + srcNameLen +1); 14388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project memcpy(dst, stripDest, stripDestLen); 14488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project dst[stripDestLen] = FSSEP; 14588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project memcpy(dst + stripDestLen+1, srcName, srcNameLen+1); 14688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } else { 14788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* simple */ 14888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project dst = stripDest; 14988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 15088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 15188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project /* 15288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Copy the source to the destination. 15388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 15488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project copyResult = copyFile(src, dst, options); 15588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 15688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (copyResult != 0) 15788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project retVal = 1; 15888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 15988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project free(src); 16088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (dst != stripDest) 16188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project free(dst); 16288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 16388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 16488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectbail: 16588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project free(stripDest); 16688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project return retVal; 16788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project} 16888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 16988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/* 17088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Set up the options. 17188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */ 17288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectint main(int argc, char* const argv[]) 17388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{ 17488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project bool wantUsage; 17588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int ic, retVal; 17688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project int verboseLevel; 17788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project unsigned int options; 17888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 17988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project verboseLevel = 0; 18088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options = 0; 18188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project wantUsage = false; 18288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 18388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project while (1) { 18488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project ic = getopt(argc, argv, "defprtuv"); 18588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (ic < 0) 18688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 18788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 18888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project switch (ic) { 18988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'd': 19088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_NO_DEREFERENCE; 19188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 19288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'e': 19388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_TRY_EXE; 19488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 19588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'f': 19688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_FORCE; 19788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 19888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'p': 19988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_PERMISSIONS; 20088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 20188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 't': 20288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_TIMESTAMPS; 20388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 20488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'r': 20588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_RECURSIVE; 20688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 20788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'u': 20888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= COPY_UPDATE_ONLY; 20988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 21088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project case 'v': 21188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project verboseLevel++; 21288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 21388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project default: 21488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, "Unexpected arg -%c\n", ic); 21588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project wantUsage = true; 21688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 21788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 21888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 21988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (wantUsage) 22088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project break; 22188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 22288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 22388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project options |= verboseLevel & COPY_VERBOSE_MASK; 22488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 22588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (optind == argc-1) { 22688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, "acp: missing destination file\n"); 22788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project return 2; 22888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } else if (optind+2 > argc) 22988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project wantUsage = true; 23088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 23188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project if (wantUsage) { 23288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, "Usage: acp [OPTION]... SOURCE DEST\n"); 23388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " or: acp [OPTION]... SOURCE... DIRECTORY\n"); 23488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, "\nOptions:\n"); 23588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -d never follow (dereference) symbolic links\n"); 23688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -e if source file doesn't exist, try adding " 23788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project "'.exe' [Win32 only]\n"); 23888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -f use force, removing existing file if it's " 23988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project "not writeable\n"); 24088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -p preserve mode, ownership\n"); 24188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -r recursive copy\n"); 24288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -t preserve timestamps\n"); 24388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -u update only: don't copy if dest is newer\n"); 24488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project fprintf(stderr, " -v verbose output (-vv is more verbose)\n"); 24588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project return 2; 24688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project } 24788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 24888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project retVal = process(argc-optind, argv+optind, options); 24988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project DBUG(("EXIT: %d\n", retVal)); 25088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project return retVal; 25188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project} 25288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project 253