diff -Nur coreutils-4.5.3.orig/doc/coreutils.texi coreutils-4.5.3/doc/coreutils.texi --- coreutils-4.5.3.orig/doc/coreutils.texi Sun Oct 27 22:19:34 2002 +++ coreutils-4.5.3/doc/coreutils.texi Sun Oct 27 22:48:17 2002 @@ -6188,6 +6188,11 @@ @xref{Backup options}. Make a backup of each file that would otherwise be overwritten or removed. +@item -C +@opindex -C +Install file, unless target already exists and is the same file, in which +case the modification time is not changed. + @item -c @opindex -c Ignored; for compatibility with old Unix versions of @command{install}. --- coreutils-6.10/src/install.c.orig 2008-01-05 23:59:11.000000000 +0100 +++ coreutils-6.10/src/install.c 2008-03-02 02:21:08.251625392 +0100 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,9 @@ or S_ISGID bits. */ static mode_t dir_mode_bits = CHMOD_MODE_BITS; +/* Compare files before installing (-C) */ +static int docompare=0; + /* If true, strip executable files after copying them. */ static bool strip_files; @@ -160,6 +164,82 @@ {NULL, 0, NULL, 0} }; +int compare (const char *file, const char *to) +{ + void *p, *q; + int ret=0; + size_t size; + int done=0; + struct stat file_s, to_s; + int file_fd, to_fd; + + stat(file, &file_s); + stat(to, &to_s); + + if (file_s.st_size != to_s.st_size) + return 1; + + file_fd = open(file, O_RDONLY); + if (file_fd < 0) + return 1; + + to_fd = open(to, O_RDONLY); + if (to_fd < 0) + { + close(file_fd); + return 1; + } + + size = (size_t) file_s.st_size; + if (size <= 4194309) /* Don't try to mmap() files > 4 MB */ + { + p = mmap(NULL, size, PROT_READ, MAP_SHARED, file_fd, (off_t) 0); + if (p != MAP_FAILED) + { + q = mmap(NULL, size, PROT_READ, MAP_SHARED, to_fd, (off_t) 0); + if (q == MAP_FAILED) + { + munmap(p, size); + } + else + { + ret = (memcmp(p, q, size)==0) ? 0 : 1; + munmap(p, size); + munmap(q, size); + done = 1; + } + } + } + if (!done) + { + char buf1[65536], buf2[65536]; + int n1, n2; + + lseek(file_fd, 0, SEEK_SET); + lseek(to_fd, 0, SEEK_SET); + while (ret == 0) + { + n1 = read(file_fd, buf1, sizeof(buf1)); + if (n1 == 0) + break; + else if (n1 > 0) + { + n2 = read(to_fd, buf2, n1); + if (n2 == n1) + ret = memcmp(buf1, buf2, n1); + else + ret = 1; /* ouf of sync */ + } + else + ret = 1; /* read failure */ + } + } + + close(file_fd); + close(to_fd); + return ret; +} + static void cp_option_init (struct cp_options *x) { @@ -345,7 +425,7 @@ we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pt:TvS:Z:", long_options, + while ((optc = getopt_long (argc, argv, "bCcsDdg:m:o:pt:TvS:Z:", long_options, NULL)) != -1) { switch (optc) @@ -357,6 +437,9 @@ break; case 'c': break; + case 'C': + docompare=1; + break; case 's': strip_files = true; #ifdef SIGCHLD @@ -627,6 +710,12 @@ However, since !x->recursive, the call to "copy" will fail if FROM is a directory. */ + if (docompare) + { + if(compare(from, to) == 0) /* Files are identical */ + return true; + } + return copy (from, to, false, x, ©_into_self, NULL); } @@ -805,6 +894,9 @@ --backup[=CONTROL] make a backup of each existing destination file\n\ -b like --backup but does not accept an argument\n\ -c (ignored)\n\ + -C install file, unless the target already exists and is the\n\ + same, in which case mtime will remain unchanged\n\ + (for compatibility with *BSD)\n\ -d, --directory treat all arguments as directory names; create all\n\ components of the specified directories\n\ "), stdout); --- coreutils-6.4/po/pl.po.orig 2006-10-24 22:32:17.793354500 +0200 +++ coreutils-6.4/po/pl.po 2006-10-24 22:34:53.511086250 +0200 @@ -3999,12 +3999,18 @@ " --backup[=CONTROL] make a backup of each existing destination file\n" " -b like --backup but does not accept an argument\n" " -c (ignored)\n" +" -C install file, unless the target already exists and is the\n" +" same, in which case mtime will remain unchanged\n" +" (for compatibility with *BSD)\n" " -d, --directory treat all arguments as directory names; create all\n" " components of the specified directories\n" msgstr "" " --backup[=TRYB] robienie kopii zapasowej przed zamazaniem pliku\n" " -b jak --backup, ale bez podawania argumentu\n" " -c (ignorowane)\n" +" -C instalowanie pliku, chyba że plik docelowy już istnieje\n" +" i jest taki sam - wtedy mtime pozostanie nie zmieniony\n" +" (dla kompatybilności z *BSD)\n" " -d, --directory traktowanie wszystkich argumentów jako nazw " "katalogów;\n" " tworzenie katalogów składowych podanych katalogów\n"