#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY(x)
+ extern struct conf *conf;
+ extern char *primary_config_path;
+ extern char *secondary_config_path;
+ extern char *current_working_dir;
+ extern char *stats_file;
+ extern unsigned lock_staleness_limit;
+
+ static void failed(void) ATTR_NORETURN;
+ static void ccache(int argc, char *argv[]) ATTR_NORETURN;
+
+ int ccache_main(int argc, char *argv[]);
+
static const char VERSION_TEXT[] =
- MYNAME " version %s\n"
- "\n"
- "Copyright (C) 2002-2007 Andrew Tridgell\n"
- "Copyright (C) 2009-2018 Joel Rosdahl\n"
- "\n"
- "This program is free software; you can redistribute it and/or modify it under\n"
- "the terms of the GNU General Public License as published by the Free Software\n"
- "Foundation; either version 3 of the License, or (at your option) any later\n"
- "version.\n";
+ MYNAME " version %s\n"
+ "\n"
+ "Copyright (C) 2002-2007 Andrew Tridgell\n"
+ "Copyright (C) 2009-2018 Joel Rosdahl\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or modify it under\n"
+ "the terms of the GNU General Public License as published by the Free Software\n"
+ "Foundation; either version 3 of the License, or (at your option) any later\n"
+ "version.\n";
static const char USAGE_TEXT[] =
- "Usage:\n"
- " " MYNAME " [options]\n"
- " " MYNAME " compiler [compiler options]\n"
- " compiler [compiler options] (via symbolic link)\n"
- "\n"
- "Options:\n"
- " -c, --cleanup delete old files and recalculate size counters\n"
- " (normally not needed as this is done automatically)\n"
- " -C, --clear clear the cache completely (except configuration)\n"
- " -F, --max-files=N set maximum number of files in cache to N (use 0 for\n"
- " no limit)\n"
- " -M, --max-size=SIZE set maximum size of cache to SIZE (use 0 for no\n"
- " limit); available suffixes: k, M, G, T (decimal) and\n"
- " Ki, Mi, Gi, Ti (binary); default suffix: G\n"
- " -o, --set-config=K=V set configuration key K to value V\n"
- " -p, --print-config print current configuration options\n"
- " -s, --show-stats show statistics summary\n"
- " -z, --zero-stats zero statistics counters\n"
- "\n"
- " -h, --help print this help text\n"
- " -V, --version print version and copyright information\n"
- "\n"
- "See also <https://ccache.samba.org>.\n";
+ "Usage:\n"
+ " " MYNAME " [options]\n"
+ " " MYNAME " compiler [compiler options]\n"
+ " compiler [compiler options] (via symbolic link)\n"
+ "\n"
+ "Options:\n"
+ " -c, --cleanup delete old files and recalculate size counters\n"
+ " (normally not needed as this is done automatically)\n"
+ " -C, --clear clear the cache completely (except configuration)\n"
+ " -F, --max-files=N set maximum number of files in cache to N (use 0 for\n"
+ " no limit)\n"
+ " -M, --max-size=SIZE set maximum size of cache to SIZE (use 0 for no\n"
+ " limit); available suffixes: k, M, G, T (decimal) and\n"
+ " Ki, Mi, Gi, Ti (binary); default suffix: G\n"
+ " -o, --set-config=K=V set configuration key K to value V\n"
+ " -p, --print-config print current configuration options\n"
+ " -s, --show-stats show statistics summary\n"
+ " -z, --zero-stats zero statistics counters\n"
+ "\n"
+ " -h, --help print this help text\n"
+ " -V, --version print version and copyright information\n"
+ "\n"
+ "See also <https://ccache.samba.org>.\n";
// Global configuration data.
struct conf *conf = NULL;
#include "ccache.h"
#define HASH_DELIMITER "\000cCaChE"
- mdfour_update(md, (unsigned char *)s, len);
+#define HASH_DEBUG_DELIMITER "### "
+
+// binary input, for hashing
+static char *debug_hash_bin;
+
+// text input, for debugging
+static char *debug_hash_txt;
+
+// char mapping to open files
+static FILE **debug_hash_file;
+
+void hash_debug_init(const char *bin, const char *txt)
+{
+ debug_hash_file = x_calloc(256, sizeof(FILE *));
+ static char *hash_types = "cdp"; // common, direct, cpp
+ if (bin) {
+ debug_hash_bin = x_strdup(bin);
+ assert(debug_hash_bin[strlen(debug_hash_bin)-1] == 'X');
+ for (char *p = hash_types; *p != '\0'; p++) {
+ debug_hash_bin[strlen(debug_hash_bin)-1] = *p;
+ debug_hash_file[(int) *p] = fopen(debug_hash_bin, "wb");
+ }
+ debug_hash_bin[strlen(debug_hash_bin)-1] = 'X';
+ }
+ if (txt) {
+ debug_hash_txt = x_strdup(txt);
+ debug_hash_file[(int) 't'] = fopen(debug_hash_txt, "w");
+ }
+}
+
+void hash_debug_end()
+{
+ for (int i = 0; i < 256; i++) {
+ if (debug_hash_file[i] != NULL) {
+ fclose(debug_hash_file[i]);
+ }
+ }
+}
+
+static void
+hash_binary_buffer(struct mdfour *md, const void *s, size_t len)
+{
++ mdfour_update(md, (const unsigned char *)s, len);
+ if (!md->identifier || len == 0) {
+ return;
+ }
+ if (debug_hash_bin) {
+ // log to different files, for the different hash types
+ fwrite(s, 1, len, debug_hash_file[md->identifier]);
+ }
+}
+
+static void
+hash_debug_buffer(struct mdfour *md, const void *s, size_t len)
+{
+ if (!md->identifier || len == 0) {
+ return;
+ }
+ if (debug_hash_txt) {
+ fwrite(s, 1, len, debug_hash_file['t']);
+ }
+}
void
hash_start(struct mdfour *md)