Merge branch 'vendor/GDB'
[dragonfly.git] / bin / cpdup / misc.c
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 }