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