13a42736dSMatthew Dillon /*
23a42736dSMatthew Dillon * MISC.C
33a42736dSMatthew Dillon */
43a42736dSMatthew Dillon
53a42736dSMatthew Dillon #include "cpdup.h"
63a42736dSMatthew Dillon
73a42736dSMatthew Dillon void
logstd(const char * ctl,...)83a42736dSMatthew Dillon logstd(const char *ctl, ...)
93a42736dSMatthew Dillon {
103a42736dSMatthew Dillon va_list va;
113a42736dSMatthew Dillon
123a42736dSMatthew Dillon va_start(va, ctl);
133a42736dSMatthew Dillon vprintf(ctl, va);
143a42736dSMatthew Dillon va_end(va);
153a42736dSMatthew Dillon }
163a42736dSMatthew Dillon
173a42736dSMatthew Dillon void
logerr(const char * ctl,...)183a42736dSMatthew Dillon logerr(const char *ctl, ...)
193a42736dSMatthew Dillon {
203a42736dSMatthew Dillon va_list va;
213a42736dSMatthew Dillon
223a42736dSMatthew Dillon va_start(va, ctl);
233a42736dSMatthew Dillon vfprintf(stderr, ctl, va);
243a42736dSMatthew Dillon va_end(va);
253a42736dSMatthew Dillon }
263a42736dSMatthew Dillon
273a42736dSMatthew Dillon char *
mprintf(const char * ctl,...)283a42736dSMatthew Dillon mprintf(const char *ctl, ...)
293a42736dSMatthew Dillon {
3058860d7dSMatthew Dillon char *ptr;
313a42736dSMatthew Dillon va_list va;
323a42736dSMatthew Dillon
3358860d7dSMatthew Dillon ptr = NULL;
3458860d7dSMatthew Dillon
353a42736dSMatthew Dillon va_start(va, ctl);
363a42736dSMatthew Dillon if (vasprintf(&ptr, ctl, va) < 0)
373a42736dSMatthew Dillon fatal("malloc failed");
383a42736dSMatthew Dillon va_end(va);
393a42736dSMatthew Dillon assert(ptr != NULL);
403a42736dSMatthew Dillon return(ptr);
413a42736dSMatthew Dillon }
423a42736dSMatthew Dillon
43577109eaSMatthew Dillon char *
fextract(FILE * fi,int n,int * pc,int skip)44577109eaSMatthew Dillon fextract(FILE *fi, int n, int *pc, int skip)
45577109eaSMatthew Dillon {
46577109eaSMatthew Dillon int i;
47577109eaSMatthew Dillon int c;
48577109eaSMatthew Dillon int imax;
49577109eaSMatthew Dillon char *s;
50577109eaSMatthew Dillon
51577109eaSMatthew Dillon i = 0;
52577109eaSMatthew Dillon c = *pc;
53577109eaSMatthew Dillon imax = (n < 0) ? 64 : n + 1;
54577109eaSMatthew Dillon
55577109eaSMatthew Dillon s = malloc(imax);
56c0538630SMatthew Dillon if (s == NULL)
57c0538630SMatthew Dillon fatal("out of memory");
58577109eaSMatthew Dillon
59577109eaSMatthew Dillon while (c != EOF) {
60577109eaSMatthew Dillon if (n == 0 || (n < 0 && (c == ' ' || c == '\n')))
61577109eaSMatthew Dillon break;
62577109eaSMatthew Dillon
63577109eaSMatthew Dillon s[i++] = c;
64577109eaSMatthew Dillon if (i == imax) {
65577109eaSMatthew Dillon imax += 64;
66577109eaSMatthew Dillon s = realloc(s, imax);
67c0538630SMatthew Dillon if (s == NULL)
68c0538630SMatthew Dillon fatal("out of memory");
69577109eaSMatthew Dillon }
70577109eaSMatthew Dillon if (n > 0)
71577109eaSMatthew Dillon --n;
72577109eaSMatthew Dillon c = getc(fi);
73577109eaSMatthew Dillon }
74577109eaSMatthew Dillon if (c == skip && skip != EOF)
75577109eaSMatthew Dillon c = getc(fi);
76577109eaSMatthew Dillon *pc = c;
77577109eaSMatthew Dillon s[i] = 0;
78577109eaSMatthew Dillon return(s);
79577109eaSMatthew Dillon }
80577109eaSMatthew Dillon
81c0538630SMatthew Dillon int16_t
hc_bswap16(int16_t var)82c0538630SMatthew Dillon hc_bswap16(int16_t var)
83c0538630SMatthew Dillon {
84c0538630SMatthew Dillon return ((var & 0xff) << 8 | (var >> 8 & 0xff));
85c0538630SMatthew Dillon }
86c0538630SMatthew Dillon
87c0538630SMatthew Dillon int32_t
hc_bswap32(int32_t var)88c0538630SMatthew Dillon hc_bswap32(int32_t var)
89c0538630SMatthew Dillon {
90c0538630SMatthew Dillon return ((var & 0xff) << 24 | (var & 0xff00) << 8
91c0538630SMatthew Dillon | (var >> 8 & 0xff00) | (var >> 24 & 0xff));
92c0538630SMatthew Dillon }
93c0538630SMatthew Dillon
94c0538630SMatthew Dillon int64_t
hc_bswap64(int64_t var)95c0538630SMatthew Dillon hc_bswap64(int64_t var)
96c0538630SMatthew Dillon {
97c0538630SMatthew Dillon return (hc_bswap32(var >> 32 & 0xffffffff)
98c0538630SMatthew Dillon | (int64_t) hc_bswap32(var & 0xffffffff) << 32);
99c0538630SMatthew Dillon }
100c0538630SMatthew Dillon
101975200d7SMatthew Dillon #ifdef DEBUG_MALLOC
102975200d7SMatthew Dillon
103975200d7SMatthew Dillon #undef malloc
104975200d7SMatthew Dillon #undef free
105975200d7SMatthew Dillon
106975200d7SMatthew Dillon struct malloc_info {
107975200d7SMatthew Dillon struct malloc_info *next;
108975200d7SMatthew Dillon struct malloc_info *prev;
109975200d7SMatthew Dillon const char *file;
110975200d7SMatthew Dillon int magic;
111975200d7SMatthew Dillon int line;
112975200d7SMatthew Dillon };
113975200d7SMatthew Dillon
114975200d7SMatthew Dillon struct malloc_info DummyInfo = { &DummyInfo, &DummyInfo, NULL, 0, 0 };
115975200d7SMatthew Dillon struct malloc_info *InfoList = &DummyInfo;
116975200d7SMatthew Dillon
117975200d7SMatthew Dillon void *
debug_malloc(size_t bytes,const char * file,int line)118975200d7SMatthew Dillon debug_malloc(size_t bytes, const char *file, int line)
119975200d7SMatthew Dillon {
120975200d7SMatthew Dillon struct malloc_info *info = malloc(sizeof(*info) + bytes);
121975200d7SMatthew Dillon
122975200d7SMatthew Dillon info->magic = 0x5513A4C2;
123975200d7SMatthew Dillon info->file = file;
124975200d7SMatthew Dillon info->line = line;
125975200d7SMatthew Dillon
126975200d7SMatthew Dillon info->next = InfoList;
127975200d7SMatthew Dillon info->prev = InfoList->prev;
128975200d7SMatthew Dillon info->next->prev = info;
129975200d7SMatthew Dillon info->prev->next = info;
130975200d7SMatthew Dillon return(info + 1);
131975200d7SMatthew Dillon }
132975200d7SMatthew Dillon
133975200d7SMatthew Dillon void
debug_free(void * ptr)134975200d7SMatthew Dillon debug_free(void *ptr)
135975200d7SMatthew Dillon {
136975200d7SMatthew Dillon struct malloc_info *info = (struct malloc_info *)ptr - 1;
137975200d7SMatthew Dillon struct malloc_info *scan;
138975200d7SMatthew Dillon static int report;
139975200d7SMatthew Dillon
140975200d7SMatthew Dillon for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) {
141975200d7SMatthew Dillon if (info == scan) {
142975200d7SMatthew Dillon assert(info->magic == 0x5513A4C2);
143975200d7SMatthew Dillon info->magic = 0;
144975200d7SMatthew Dillon info->next->prev = info->prev;
145975200d7SMatthew Dillon info->prev->next = info->next;
146975200d7SMatthew Dillon free(info);
147975200d7SMatthew Dillon break;
148975200d7SMatthew Dillon }
149975200d7SMatthew Dillon }
150975200d7SMatthew Dillon if (scan == &DummyInfo)
151975200d7SMatthew Dillon free(ptr);
152975200d7SMatthew Dillon
153975200d7SMatthew Dillon if ((++report & 65535) == 0) {
154975200d7SMatthew Dillon printf("--- report\n");
155975200d7SMatthew Dillon for (scan = DummyInfo.next; scan != &DummyInfo; scan = scan->next) {
156975200d7SMatthew Dillon printf("%-15s %d\n", scan->file, scan->line);
157975200d7SMatthew Dillon }
158975200d7SMatthew Dillon }
159975200d7SMatthew Dillon }
160975200d7SMatthew Dillon
161975200d7SMatthew Dillon #endif
162975200d7SMatthew Dillon
1633a42736dSMatthew Dillon void
fatal(const char * ctl,...)1643a42736dSMatthew Dillon fatal(const char *ctl, ...)
1653a42736dSMatthew Dillon {
1663a42736dSMatthew Dillon va_list va;
1673a42736dSMatthew Dillon
1683a42736dSMatthew Dillon if (ctl == NULL) {
169bfb6f159SAaron LI puts("usage: cpdup [options] src dest");
170bfb6f159SAaron LI puts("\n"
171bfb6f159SAaron LI "options:\n"
172bfb6f159SAaron LI " -C request compressed ssh link if remote operation\n"
173293141b7SMatthew Dillon " -d print directories being traversed\n"
1743a42736dSMatthew Dillon " -f force update even if files look the same\n"
1757651dbc3SAaron LI " -F<ssh_opt> add <ssh_opt> to options passed to ssh\n"
1767651dbc3SAaron LI " -h show this help\n"
1777651dbc3SAaron LI " -H path hardlink from path to target instead of copying\n"
1787651dbc3SAaron LI " -I display performance summary\n"
1793a42736dSMatthew Dillon " -i0 do NOT confirm when removing something\n"
180293141b7SMatthew Dillon " -j0 do not try to recreate CHR or BLK devices\n"
1817651dbc3SAaron LI " -l force line-buffered stdout/stderr"
182bfb6f159SAaron LI );
1834d858d58SMatthew Dillon #ifndef NOMD5
184bfb6f159SAaron LI puts(" -m maintain/generate MD5 checkfile on source,\n"
1853a42736dSMatthew Dillon " and compare with (optional) destination,\n"
1863a42736dSMatthew Dillon " copying if the compare fails\n"
1873a42736dSMatthew Dillon " -M file -m+specify MD5 checkfile, else .MD5_CHECKSUMS\n"
188bfb6f159SAaron LI " copy if md5 check fails"
189bfb6f159SAaron LI );
1901bcaecdaSMatthew Dillon #endif
1917651dbc3SAaron LI puts(" -n do not make any real changes to the target\n"
1927651dbc3SAaron LI " -o do not remove any files, just overwrite/add\n"
1937651dbc3SAaron LI " -q quiet operation\n"
194ca097fa5SMatthew Dillon " -R read-only slave mode for ssh remotes\n"
195d5fdcd00SMatthew Dillon " source to target, if source matches path.\n"
1967651dbc3SAaron LI " -S slave mode\n"
1977651dbc3SAaron LI " -s0 disable safeties - allow files to overwrite directories\n"
1987651dbc3SAaron LI " -u use unbuffered output for -v[vv]\n"
1997651dbc3SAaron LI " -v[vv] verbose level (-vv is typical)\n"
200d5fdcd00SMatthew Dillon " -V verify file contents even if they appear\n"
201d5fdcd00SMatthew Dillon " to be the same.\n"
2021bcaecdaSMatthew Dillon " -VV same as -V but ignore mtime entirely\n"
2033a42736dSMatthew Dillon " -x use .cpignore as exclusion file\n"
204110def69SAaron LI " -X file specify exclusion file (can match full source\n"
205*34d72c0eSMatthew Dillon " path if the exclusion file is specified via\n"
206560e4370SMatthew Dillon " an absolute path.\n"
207bfb6f159SAaron LI "\n"
20866641ee9SAaron LI "Version " VERSION " by " AUTHORS "\n"
2093a42736dSMatthew Dillon );
2103a42736dSMatthew Dillon exit(0);
2113a42736dSMatthew Dillon } else {
2123a42736dSMatthew Dillon va_start(va, ctl);
213c0538630SMatthew Dillon vfprintf(stderr, ctl, va);
2143a42736dSMatthew Dillon va_end(va);
215c0538630SMatthew Dillon putc('\n', stderr);
216c0538630SMatthew Dillon exit(EXIT_FAILURE);
2173a42736dSMatthew Dillon }
2183a42736dSMatthew Dillon }
219