xref: /dragonfly/bin/cpdup/misc.c (revision 5ca0a96d)
1 /*
2  * MISC.C
3  */
4 
5 #include "cpdup.h"
6 
7 void
logstd(const char * ctl,...)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
logerr(const char * ctl,...)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 *
mprintf(const char * ctl,...)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 *
fextract(FILE * fi,int n,int * pc,int skip)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
hc_bswap16(int16_t var)82 hc_bswap16(int16_t var)
83 {
84     return ((var & 0xff) << 8 | (var >> 8 & 0xff));
85 }
86 
87 int32_t
hc_bswap32(int32_t var)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
hc_bswap64(int64_t var)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 *
debug_malloc(size_t bytes,const char * file,int line)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
debug_free(void * ptr)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
fatal(const char * ctl,...)164 fatal(const char *ctl, ...)
165 {
166     va_list va;
167 
168     if (ctl == NULL) {
169 	puts("usage: cpdup [options] src dest");
170 	puts("\n"
171 	     "options:\n"
172 	     "    -C          request compressed ssh link if remote operation\n"
173 	     "    -d          print directories being traversed\n"
174 	     "    -f          force update even if files look the same\n"
175 	     "    -F<ssh_opt> add <ssh_opt> to options passed to ssh\n"
176 	     "    -h          show this help\n"
177 	     "    -H path     hardlink from path to target instead of copying\n"
178 	     "    -I          display performance summary\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"
182 	);
183 #ifndef NOMD5
184 	puts("    -m          maintain/generate MD5 checkfile on source,\n"
185 	     "                and compare with (optional) destination,\n"
186 	     "                copying if the compare fails\n"
187 	     "    -M file     -m+specify MD5 checkfile, else .MD5_CHECKSUMS\n"
188 	     "                copy if md5 check fails"
189 	);
190 #endif
191 	puts("    -n          do not make any real changes to the target\n"
192 	     "    -o          do not remove any files, just overwrite/add\n"
193 	     "    -q          quiet operation\n"
194 	     "    -R          read-only slave mode for ssh remotes\n"
195 	     "                source to target, if source matches path.\n"
196 	     "    -S          slave mode\n"
197 	     "    -s0         disable safeties - allow files to overwrite directories\n"
198 	     "    -u          use unbuffered output for -v[vv]\n"
199 	     "    -v[vv]      verbose level (-vv is typical)\n"
200 	     "    -V          verify file contents even if they appear\n"
201 	     "                to be the same.\n"
202 	     "    -VV         same as -V but ignore mtime entirely\n"
203 	     "    -x          use .cpignore as exclusion file\n"
204 	     "    -X file     specify exclusion file (can match full source\n"
205 	     "                path if the exclusion file is specified via\n"
206 	     "                an absolute path.\n"
207 	     "\n"
208 	     "Version " VERSION " by " AUTHORS "\n"
209 	);
210 	exit(0);
211     } else {
212 	va_start(va, ctl);
213 	vfprintf(stderr, ctl, va);
214 	va_end(va);
215 	putc('\n', stderr);
216 	exit(EXIT_FAILURE);
217     }
218 }
219