xref: /dragonfly/bin/cpdup/misc.c (revision 19fe1c42)
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 	fprintf(stderr, "out of memory\n");
60 	exit(EXIT_FAILURE);
61     }
62 
63     while (c != EOF) {
64 	if (n == 0 || (n < 0 && (c == ' ' || c == '\n')))
65 	    break;
66 
67 	s[i++] = c;
68 	if (i == imax) {
69 	    imax += 64;
70 	    s = realloc(s, imax);
71     	    if (s == NULL) {
72                 fprintf(stderr, "out of memory\n");
73   	        exit(EXIT_FAILURE);
74  	    }
75 	}
76 	if (n > 0)
77 	    --n;
78 	c = getc(fi);
79     }
80     if (c == skip && skip != EOF)
81 	c = getc(fi);
82     *pc = c;
83     s[i] = 0;
84     return(s);
85 }
86 
87 #ifdef DEBUG_MALLOC
88 
89 #undef malloc
90 #undef free
91 
92 struct malloc_info {
93 	struct malloc_info *next;
94 	struct malloc_info *prev;
95 	const char *file;
96 	int magic;
97 	int line;
98 };
99 
100 struct malloc_info DummyInfo = { &DummyInfo, &DummyInfo, NULL, 0, 0 };
101 struct malloc_info *InfoList = &DummyInfo;
102 
103 void *
104 debug_malloc(size_t bytes, const char *file, int line)
105 {
106 	struct malloc_info *info = malloc(sizeof(*info) + bytes);
107 
108 	info->magic = 0x5513A4C2;
109 	info->file = file;
110 	info->line = line;
111 
112 	info->next = InfoList;
113 	info->prev = InfoList->prev;
114 	info->next->prev = info;
115 	info->prev->next = info;
116 	return(info + 1);
117 }
118 
119 void
120 debug_free(void *ptr)
121 {
122 	struct malloc_info *info = (struct malloc_info *)ptr - 1;
123 	struct malloc_info *scan;
124 	static int report;
125 
126 	for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) {
127 		if (info == scan) {
128 			assert(info->magic == 0x5513A4C2);
129 			info->magic = 0;
130 			info->next->prev = info->prev;
131 			info->prev->next = info->next;
132 			free(info);
133 			break;
134 		}
135 	}
136 	if (scan == &DummyInfo)
137 		free(ptr);
138 
139 	if ((++report & 65535) == 0) {
140 		printf("--- report\n");
141 		for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) {
142 			printf("%-15s %d\n", scan->file, scan->line);
143 		}
144 	}
145 }
146 
147 #endif
148 
149 void
150 fatal(const char *ctl, ...)
151 {
152     va_list va;
153 
154     if (ctl == NULL) {
155 	puts("cpdup [<options>] src [dest]");
156 	puts("    -C          request compressed ssh link if remote operation\n"
157 	     "    -v[vv]      verbose level (-vv is typical)\n"
158 	     "    -u          use unbuffered output for -v[vv]\n"
159 	     "    -I          display performance summary\n"
160 	     "    -f          force update even if files look the same\n"
161 	     "    -i0         do NOT confirm when removing something\n"
162 	     "    -l          force line-buffered stdout/stderr\n"
163 	     "    -pN         N parallel transactions for for remote\n"
164 	     "                source or destination\n"
165 	     "    -s0         disable safeties - allow files to overwrite directories\n"
166 	     "    -q          quiet operation\n"
167 	     "    -o          do not remove any files, just overwrite/add\n"
168 	);
169 	puts(
170 #ifndef NOMD5
171 	     "    -m          maintain/generate MD5 checkfile on source,\n"
172 	     "                and compare with (optional) destination,\n"
173 	     "                copying if the compare fails\n"
174 	     "    -M file     -m+specify MD5 checkfile, else .MD5_CHECKSUMS\n"
175 	     "                copy if md5 check fails\n"
176 	     "    -H path     hardlink from path to target instead of copying\n"
177 	     "                source to target, if source matches path.\n"
178 	     "    -V          verify file contents even if they appear\n"
179 	     "                to be the same.\n"
180 #endif
181 	     "    -x          use .cpignore as exclusion file\n"
182 	     "    -X file     specify exclusion file\n"
183 	     " Version 1.11 by Matt Dillon and Dima Ruban\n"
184 	);
185 	exit(0);
186     } else {
187 	va_start(va, ctl);
188 	vprintf(ctl, va);
189 	va_end(va);
190 	puts("");
191 	exit(1);
192     }
193 }
194