"Fossies" - the Fresh Open Source Software Archive

Member "duff-0.5.2/src/duff.c" (28 Jan 2012, 7462 Bytes) of package /linux/privat/old/duff-0.5.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * duff - Duplicate file finder
    3  * Copyright (c) 2005 Camilla Berglund <elmindreda@elmindreda.org>
    4  *
    5  * This software is provided 'as-is', without any express or implied
    6  * warranty. In no event will the authors be held liable for any
    7  * damages arising from the use of this software.
    8  *
    9  * Permission is granted to anyone to use this software for any
   10  * purpose, including commercial applications, and to alter it and
   11  * redistribute it freely, subject to the following restrictions:
   12  *
   13  *  1. The origin of this software must not be misrepresented; you
   14  *     must not claim that you wrote the original software. If you use
   15  *     this software in a product, an acknowledgment in the product
   16  *     documentation would be appreciated but is not required.
   17  *
   18  *  2. Altered source versions must be plainly marked as such, and
   19  *     must not be misrepresented as being the original software.
   20  *
   21  *  3. This notice may not be removed or altered from any source
   22  *     distribution.
   23  */
   24 
   25 #if HAVE_CONFIG_H
   26 #include "config.h"
   27 #endif
   28 
   29 #if HAVE_SYS_TYPES_H
   30 #include <sys/types.h>
   31 #endif
   32 
   33 #if HAVE_SYS_STAT_H
   34 #include <sys/stat.h>
   35 #endif
   36 
   37 #if HAVE_SYS_PARAM_H
   38 #include <sys/param.h>
   39 #endif
   40 
   41 #if HAVE_INTTYPES_H
   42 #include <inttypes.h>
   43 #elif HAVE_STDINT_H
   44 #include <stdint.h>
   45 #endif
   46 
   47 #if HAVE_ERRNO_H
   48 #include <errno.h>
   49 #endif
   50 
   51 #if HAVE_UNISTD_H
   52 #include <unistd.h>
   53 #endif
   54 
   55 #if HAVE_STDIO_H
   56 #include <stdio.h>
   57 #endif
   58 
   59 #if HAVE_STRING_H
   60 #include <string.h>
   61 #endif
   62 
   63 #if HAVE_STDLIB_H
   64 #include <stdlib.h>
   65 #endif
   66 
   67 #if HAVE_LIMITS_H
   68 #include <limits.h>
   69 #endif
   70 
   71 #if HAVE_LOCALE_H
   72 #include <locale.h>
   73 #endif
   74 
   75 #include "duffstring.h"
   76 #include "duff.h"
   77 
   78 /* Controls the handling of symlinks to directories.  The different modes are
   79  * defined in duff.h.
   80  */
   81 SymlinkMode follow_links_mode = NO_SYMLINKS;
   82 
   83 /* Whether to include dotfiles when searching recursively.
   84  */
   85 int all_files_flag = 0;
   86 
   87 /* Makes the program output verbose.
   88  */
   89 int verbose_flag = 0;
   90 
   91 /* Whether to recurse into all specified directories.
   92  */
   93 int recursive_flag = 0;
   94 
   95 /*! Whether to use null characters as delimiters instead of newlines.
   96  */
   97 int null_terminate_flag = 0;
   98 
   99 /* Makes the program not warn about skipped files.
  100  */
  101 int quiet_flag = 0;
  102 
  103 /* Makes the program not consider hard-links to be duplicate files.
  104  */
  105 int physical_flag = 0;
  106 
  107 /* For each duplicate cluster, reports all but one.  Useful for uses of
  108  * `xargs rm'.
  109  */
  110 int excess_flag = 0;
  111 
  112 /* Makes the program not rely on message digests for file equality, forcing
  113  * byte-by-byte comparisons of candidates.
  114  */
  115 int thorough_flag = 0;
  116 
  117 /* Makes the program not report files of zero size as duplicates.
  118  */
  119 int ignore_empty_flag = 0;
  120 
  121 /* Specifies the look of the cluster header.
  122  * If set to the empty string, no headers are printed.
  123  */
  124 const char* header_format = NULL;
  125 
  126 /* Whether or not the cluster header uses a digest.
  127  */
  128 int header_uses_digest = 0;
  129 
  130 /* Specifies the minimal size of files to be compared with the sampling method.
  131  */
  132 off_t sample_limit = 0;
  133 
  134 /* These functions are documented below, where they are defined.
  135  */
  136 static void version(void);
  137 static void usage(void);
  138 static void bugs(void);
  139 
  140 /* Prints version information to stdout.
  141  */
  142 static void version(void)
  143 {
  144   printf("%s\n", PACKAGE_STRING);
  145   printf(_("Copyright (c) 2005 Camilla Berglund <elmindreda@elmindreda.org>\n"));
  146   printf(_("%s contains shaX-asaddi\n"), PACKAGE_NAME);
  147   printf(_("Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>\n"));
  148 }
  149 
  150 /* Prints brief help information to stdout.
  151  * Note that it is a good idea to keep this synchronised with the actual code.
  152  * Note that it is also a good idea it keep it synchronised with the manpage.
  153  */
  154 static void usage(void)
  155 {
  156   printf(_("Usage: %s [-0HLPaepqrtz] [-d function] [-f format] [-l size] [file ...]\n"),
  157            PACKAGE_NAME);
  158 
  159   printf("       %s -h\n", PACKAGE_NAME);
  160   printf("       %s -v\n", PACKAGE_NAME);
  161 
  162   printf(_("Options:\n"));
  163   printf(_("  -0  read and write file names terminated by a null character\n"));
  164   printf(_("  -H  follow symbolic links to directories on the command line\n"));
  165   printf(_("  -L  follow all symbolic links to directories\n"));
  166   printf(_("  -P  do not follow any symbolic links (default)\n"));
  167   printf(_("  -a  include hidden files when searching recursively\n"));
  168   printf(_("  -d  the message digest function to use: sha1 sha256 sha384 sha512\n"));
  169   printf(_("  -e  excess mode; list all but one file from each cluster (no headers)\n"));
  170   printf(_("  -f  format for cluster headers\n"));
  171   printf(_("  -h  show this help\n"));
  172   printf(_("  -l  the minimum size that activates sampling\n"));
  173   printf(_("  -q  quiet; suppress warnings and error messages\n"));
  174   printf(_("  -p  physical mode; do not report multiple links as duplicates\n"));
  175   printf(_("  -r  search recursively through specified directories\n"));
  176   printf(_("  -t  thorough; force byte-by-byte comparison of files\n"));
  177   printf(_("  -v  show version information\n"));
  178   printf(_("  -z  do not report empty files\n"));
  179 }
  180 
  181 /* Prints bug report address to stdout.
  182  */
  183 static void bugs(void)
  184 {
  185   printf(_("Report bugs to <%s>\n"), PACKAGE_BUGREPORT);
  186 }
  187 
  188 /* I don't know what this function does.
  189  * I just put it in because it looks cool.
  190  */
  191 int main(int argc, char** argv)
  192 {
  193   int ch;
  194   char* temp;
  195   off_t limit;
  196 
  197   setlocale(LC_ALL, "");
  198   bindtextdomain(PACKAGE, LOCALEDIR);
  199   textdomain(PACKAGE);
  200 
  201   while ((ch = getopt(argc, argv, "0HLPad:ef:hl:pqrtvz")) != -1)
  202   {
  203     switch (ch)
  204     {
  205       case '0':
  206     null_terminate_flag = 1;
  207     break;
  208       case 'H':
  209     follow_links_mode = ARG_SYMLINKS;
  210     break;
  211       case 'L':
  212     follow_links_mode = ALL_SYMLINKS;
  213     break;
  214       case 'P':
  215     follow_links_mode = NO_SYMLINKS;
  216     break;
  217       case 'a':
  218         all_files_flag = 1;
  219         break;
  220       case 'd':
  221     if (strcasecmp(optarg, "sha1") == 0)
  222       set_digest_function(SHA_1);
  223     else if (strcasecmp(optarg, "sha256") == 0)
  224       set_digest_function(SHA_256);
  225     else if (strcasecmp(optarg, "sha384") == 0)
  226       set_digest_function(SHA_384);
  227     else if (strcasecmp(optarg, "sha512") == 0)
  228       set_digest_function(SHA_512);
  229     else
  230       error(_("%s is not a supported digest function"), optarg);
  231     break;
  232       case 'e':
  233         excess_flag = 1;
  234     break;
  235       case 'f':
  236         header_format = optarg;
  237         break;
  238       case 'h':
  239         usage();
  240         bugs();
  241         exit(EXIT_SUCCESS);
  242       case 'l':
  243         limit = (off_t) strtoull(optarg, &temp, 10);
  244     if (temp == optarg || errno == ERANGE || errno == EINVAL)
  245       warning(_("Ignoring invalid sample limit %s"), optarg);
  246     else
  247       sample_limit = limit;
  248     break;
  249       case 'p':
  250     physical_flag = 1;
  251     break;
  252       case 'q':
  253         quiet_flag = 1;
  254         break;
  255       case 'r':
  256         recursive_flag = 1;
  257         break;
  258       case 't':
  259         thorough_flag = 1;
  260         break;
  261       case 'v':
  262         version();
  263         exit(EXIT_SUCCESS);
  264       case 'z':
  265     ignore_empty_flag = 1;
  266     break;
  267       default:
  268         usage();
  269         bugs();
  270         exit(EXIT_FAILURE);
  271     }
  272   }
  273 
  274   argc -= optind;
  275   argv += optind;
  276 
  277   if (!header_format)
  278   {
  279     if (thorough_flag)
  280       header_format = _("%n files in cluster %i (%s bytes)");
  281     else
  282       header_format = _("%n files in cluster %i (%s bytes, digest %d)");
  283   }
  284 
  285   header_uses_digest = cluster_header_uses_digest(header_format);
  286 
  287   if (thorough_flag && header_uses_digest)
  288     error(_("Digest (%%d) is not calculated in thorough mode (-t)"));
  289 
  290   process_args(argc, argv);
  291 
  292   exit(EXIT_SUCCESS);
  293 }
  294