--- delme/coreutils-7.4/src/install.c 2009-04-24 08:59:06.000000000 -0400 +++ src/install.c 2009-07-01 15:58:33.000000000 -0400 @@ -126,6 +126,9 @@ /* If true, install a directory instead of a regular file. */ static bool dir_arg; +/* If true, prefix destination directory with value of DESTDIR */ +static char *destdir; + /* Program used to strip binaries, "strip" is default */ static char const *strip_program = "strip"; @@ -158,6 +161,7 @@ {"suffix", required_argument, NULL, 'S'}, {"target-directory", required_argument, NULL, 't'}, {"verbose", no_argument, NULL, 'v'}, + {"destdir", optional_argument, NULL, 'P'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -420,6 +424,24 @@ : EXIT_FAILURE); } +/* point dst new a new filename prefixed with pre */ +void +add_prefix(char *pre, char **dst){ + char new[PATH_MAX]; + if(!pre) + return; + size_t len = strlen(pre); + strncpy(new, pre, PATH_MAX - 1); + if(**dst != '/'){ + getcwd(new + len, PATH_MAX - len); + len = strlen(new); + new[len] = '/'; + len++; + } + strncpy(new + len, *dst, PATH_MAX - len - 1); + *dst = new; +} + int main (int argc, char **argv) { @@ -460,7 +482,7 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pP::t:TvS:Z:", long_options, NULL)) != -1) { switch (optc) @@ -507,6 +529,18 @@ case 'p': x.preserve_timestamps = true; break; + case 'P': + if(destdir){ + error (EXIT_FAILURE, 0, + _("multiple destdir options specified")); + }else if(optarg){ + destdir = optarg; + }else{ + char *env_destdir = getenv("DESTDIR"); + if(env_destdir) + destdir = xstrdup(env_destdir); + } + break; case 'S': make_backups = true; backup_suffix_string = optarg; @@ -516,15 +550,7 @@ error (EXIT_FAILURE, 0, _("multiple target directories specified")); else - { - struct stat st; - if (stat (optarg, &st) != 0) - error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); - if (! S_ISDIR (st.st_mode)) - error (EXIT_FAILURE, 0, _("target %s is not a directory"), - quote (optarg)); - } - target_directory = optarg; + target_directory = optarg; break; case 'T': no_target_directory = true; @@ -582,6 +608,16 @@ version_control_string) : no_backups); + if(target_directory){ + add_prefix(destdir, &target_directory); + struct stat st; + if (stat (target_directory, &st) != 0) + error (EXIT_FAILURE, errno, _("accessing %s"), quote (target_directory)); + if (! S_ISDIR (st.st_mode)) + error (EXIT_FAILURE, 0, _("target %s is not a directory"), + quote (target_directory)); + } + if (scontext && setfscreatecon (scontext) < 0) error (EXIT_FAILURE, errno, _("failed to set default file creation context to %s"), @@ -614,8 +650,10 @@ } else if (! (dir_arg || target_directory)) { - if (2 <= n_files && target_directory_operand (file[n_files - 1])) + if (2 <= n_files && target_directory_operand (file[n_files - 1])){ target_directory = file[--n_files]; + add_prefix(destdir, &target_directory); + } else if (2 < n_files) error (EXIT_FAILURE, 0, _("target %s is not a directory"), quote (file[n_files - 1])); @@ -656,7 +694,11 @@ get_ids (); if (dir_arg) - exit_status = savewd_process_files (n_files, file, process_dir, &x); + { + for(size_t i = 0; i < n_files; i++) + add_prefix(destdir, file + i); + exit_status = savewd_process_files (n_files, file, process_dir, &x); + } else { /* FIXME: it's a little gross that this initialization is @@ -665,9 +707,11 @@ if (!target_directory) { + char *target_file = file[1]; + add_prefix(destdir, &target_file); if (! (mkdir_and_install - ? install_file_in_file_parents (file[0], file[1], &x) - : install_file_in_file (file[0], file[1], &x))) + ? install_file_in_file_parents (file[0], target_file, &x) + : install_file_in_file (file[0], target_file, &x))) exit_status = EXIT_FAILURE; } else @@ -977,6 +1021,8 @@ fputs (_("\ -p, --preserve-timestamps apply access/modification times of SOURCE files\n\ to corresponding destination files\n\ + -P, --destdir[=DESTDIR] prefix destination with the DESTDIR option or,\n\ + if not specified, the DESTDIR environment variable\n\ -s, --strip strip symbol tables\n\ --strip-program=PROGRAM program used to strip binaries\n\ -S, --suffix=SUFFIX override the usual backup suffix\n\