1 /* 2 * MISC.C 3 */ 4 5 #include "cpdup.h" 6 7 void 8 logstd(const char *ctl, ...) 9 { 10 va_list va; 11 12 va_start(va, ctl); 13 vprintf(ctl, va); 14 va_end(va); 15 } 16 17 void 18 logerr(const char *ctl, ...) 19 { 20 va_list va; 21 22 va_start(va, ctl); 23 vfprintf(stderr, ctl, va); 24 va_end(va); 25 } 26 27 char * 28 mprintf(const char *ctl, ...) 29 { 30 char *ptr; 31 va_list va; 32 33 ptr = NULL; 34 35 va_start(va, ctl); 36 if (vasprintf(&ptr, ctl, va) < 0) 37 fatal("malloc failed"); 38 va_end(va); 39 assert(ptr != NULL); 40 return(ptr); 41 } 42 43 char * 44 fextract(FILE *fi, int n, int *pc, int skip) 45 { 46 int i; 47 int c; 48 int imax; 49 char *s; 50 51 i = 0; 52 c = *pc; 53 imax = (n < 0) ? 64 : n + 1; 54 55 s = malloc(imax); 56 if (s == NULL) 57 fatal("out of memory"); 58 59 while (c != EOF) { 60 if (n == 0 || (n < 0 && (c == ' ' || c == '\n'))) 61 break; 62 63 s[i++] = c; 64 if (i == imax) { 65 imax += 64; 66 s = realloc(s, imax); 67 if (s == NULL) 68 fatal("out of memory"); 69 } 70 if (n > 0) 71 --n; 72 c = getc(fi); 73 } 74 if (c == skip && skip != EOF) 75 c = getc(fi); 76 *pc = c; 77 s[i] = 0; 78 return(s); 79 } 80 81 int16_t 82 hc_bswap16(int16_t var) 83 { 84 return ((var & 0xff) << 8 | (var >> 8 & 0xff)); 85 } 86 87 int32_t 88 hc_bswap32(int32_t var) 89 { 90 return ((var & 0xff) << 24 | (var & 0xff00) << 8 91 | (var >> 8 & 0xff00) | (var >> 24 & 0xff)); 92 } 93 94 int64_t 95 hc_bswap64(int64_t var) 96 { 97 return (hc_bswap32(var >> 32 & 0xffffffff) 98 | (int64_t) hc_bswap32(var & 0xffffffff) << 32); 99 } 100 101 #ifdef DEBUG_MALLOC 102 103 #undef malloc 104 #undef free 105 106 struct malloc_info { 107 struct malloc_info *next; 108 struct malloc_info *prev; 109 const char *file; 110 int magic; 111 int line; 112 }; 113 114 struct malloc_info DummyInfo = { &DummyInfo, &DummyInfo, NULL, 0, 0 }; 115 struct malloc_info *InfoList = &DummyInfo; 116 117 void * 118 debug_malloc(size_t bytes, const char *file, int line) 119 { 120 struct malloc_info *info = malloc(sizeof(*info) + bytes); 121 122 info->magic = 0x5513A4C2; 123 info->file = file; 124 info->line = line; 125 126 info->next = InfoList; 127 info->prev = InfoList->prev; 128 info->next->prev = info; 129 info->prev->next = info; 130 return(info + 1); 131 } 132 133 void 134 debug_free(void *ptr) 135 { 136 struct malloc_info *info = (struct malloc_info *)ptr - 1; 137 struct malloc_info *scan; 138 static int report; 139 140 for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) { 141 if (info == scan) { 142 assert(info->magic == 0x5513A4C2); 143 info->magic = 0; 144 info->next->prev = info->prev; 145 info->prev->next = info->next; 146 free(info); 147 break; 148 } 149 } 150 if (scan == &DummyInfo) 151 free(ptr); 152 153 if ((++report & 65535) == 0) { 154 printf("--- report\n"); 155 for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) { 156 printf("%-15s %d\n", scan->file, scan->line); 157 } 158 } 159 } 160 161 #endif 162 163 void 164 fatal(const char *ctl, ...) 165 { 166 va_list va; 167 168 if (ctl == NULL) { 169 puts("cpdup [<options>] src [dest]"); 170 puts(" -C request compressed ssh link if remote operation\n" 171 " -v[vv] verbose level (-vv is typical)\n" 172 " -d print directories being traversed\n" 173 " -u use unbuffered output for -v[vv]\n" 174 " -I display performance summary\n" 175 " -f force update even if files look the same\n" 176 " -F<ssh_opt> Add <ssh_opt> to options passed to ssh\n" 177 " -i0 do NOT confirm when removing something\n" 178 " -j0 do not try to recreate CHR or BLK devices\n" 179 " -l force line-buffered stdout/stderr\n" 180 " -s0 disable safeties - allow files to overwrite directories\n" 181 " -q quiet operation\n" 182 " -o do not remove any files, just overwrite/add\n" 183 ); 184 puts( 185 " -k maintain/generate FSMID checkfile on target,\n" 186 " and compare source FSMIDs against the checkfiles\n" 187 " -K file -k+specify FSMID checkfile, else .FSMID.CHECK\n" 188 #ifndef NOMD5 189 " -m maintain/generate MD5 checkfile on source,\n" 190 " and compare with (optional) destination,\n" 191 " copying if the compare fails\n" 192 " -M file -m+specify MD5 checkfile, else .MD5_CHECKSUMS\n" 193 " copy if md5 check fails\n" 194 #endif 195 " -H path hardlink from path to target instead of copying\n" 196 " -R read-only slave mode for ssh remotes\n" 197 " source to target, if source matches path.\n" 198 " -V verify file contents even if they appear\n" 199 " to be the same.\n" 200 " -VV same as -V but ignore mtime entirely\n" 201 " -x use .cpignore as exclusion file\n" 202 " -X file specify exclusion file\n" 203 " Version 1.17 by Matt Dillon, Dima Ruban, & Oliver Fromme\n" 204 ); 205 exit(0); 206 } else { 207 va_start(va, ctl); 208 vfprintf(stderr, ctl, va); 209 va_end(va); 210 putc('\n', stderr); 211 exit(EXIT_FAILURE); 212 } 213 } 214