Add support for mirroring symlinks and hardlinks.
[dragonfly.git] / sbin / jscan / subs.c
CommitLineData
ce5e5ac4
MD
1/*
2 * Copyright (c) 2004,2005 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
fa8f36eb 34 * $DragonFly: src/sbin/jscan/subs.c,v 1.5 2005/07/05 06:20:07 dillon Exp $
ce5e5ac4
MD
35 */
36
37#include "jscan.h"
38
39void
40jf_warn(struct jfile *jf, const char *ctl, ...)
41{
42 va_list va;
43
44 fprintf(stderr, "@0x%016llx ", jf->jf_pos);
45 va_start(va, ctl);
46 vfprintf(stderr, ctl, va);
47 va_end(va);
48 fprintf(stderr, "\n");
49}
50
51const char *
52type_to_name(int16_t rectype)
53{
54 const char *str;
55
56 switch((u_int16_t)rectype & ~JMASK_LAST) {
57 case JLEAF_PAD:
58 str = "PAD";
59 break;
60 case JLEAF_ABORT:
61 str = "ABORT";
62 break;
63 case JTYPE_ASSOCIATE:
64 str = "ASSOCIATE";
65 break;
66 case JTYPE_DISASSOCIATE:
67 str = "DISASSOCIATE";
68 break;
69 case JTYPE_UNDO:
70 str = "UNDO";
71 break;
72 case JTYPE_AUDIT:
73 str = "AUDIT";
74 break;
75 case JTYPE_SETATTR:
76 str = "SETATTR";
77 break;
78 case JTYPE_WRITE:
79 str = "WRITE";
80 break;
81 case JTYPE_PUTPAGES:
82 str = "PUTPAGES";
83 break;
84 case JTYPE_SETACL:
85 str = "SETACL";
86 break;
87 case JTYPE_SETEXTATTR:
88 str = "SETEXTATTR";
89 break;
90 case JTYPE_CREATE:
91 str = "CREATE";
92 break;
93 case JTYPE_MKNOD:
94 str = "MKNOD";
95 break;
96 case JTYPE_LINK:
97 str = "LINK";
98 break;
99 case JTYPE_SYMLINK:
100 str = "SYMLINK";
101 break;
102 case JTYPE_WHITEOUT:
103 str = "WHITEOUT";
104 break;
105 case JTYPE_REMOVE:
106 str = "REMOVE";
107 break;
108 case JTYPE_MKDIR:
109 str = "MKDIR";
110 break;
111 case JTYPE_RMDIR:
112 str = "RMDIR";
113 break;
114 case JTYPE_RENAME:
115 str = "RENAME";
116 break;
117 case JTYPE_VATTR:
118 str = "vattr";
119 break;
120 case JTYPE_CRED:
121 str = "cred";
122 break;
123 case JLEAF_FILEDATA:
124 str = "filedata";
125 break;
126 case JLEAF_PATH1:
127 str = "path1";
128 break;
129 case JLEAF_PATH2:
130 str = "path2";
131 break;
132 case JLEAF_PATH3:
133 str = "path3";
134 break;
135 case JLEAF_PATH4:
136 str = "path4";
137 break;
138 case JLEAF_UID:
139 str = "uid";
140 break;
141 case JLEAF_GID:
142 str = "gid";
143 break;
712e03b0
MD
144 case JLEAF_VTYPE:
145 str = "vtype";
146 break;
ce5e5ac4
MD
147 case JLEAF_MODES:
148 str = "modes";
149 break;
150 case JLEAF_FFLAGS:
151 str = "fflags";
152 break;
153 case JLEAF_PID:
154 str = "pid";
155 break;
156 case JLEAF_PPID:
157 str = "ppid";
158 break;
159 case JLEAF_COMM:
160 str = "comm";
161 break;
162 case JLEAF_ATTRNAME:
163 str = "attrname";
164 break;
165 case JLEAF_PATH_REF:
166 str = "path_ref";
167 break;
168 case JLEAF_RESERVED_0F:
169 str = "?";
170 break;
171 case JLEAF_SYMLINKDATA:
172 str = "symlinkdata";
173 break;
174 case JLEAF_SEEKPOS:
175 str = "seekpos";
176 break;
177 case JLEAF_INUM:
178 str = "inum";
179 break;
180 case JLEAF_NLINK:
181 str = "nlink";
182 break;
183 case JLEAF_FSID:
184 str = "fsid";
185 break;
186 case JLEAF_SIZE:
187 str = "size";
188 break;
189 case JLEAF_ATIME:
190 str = "atime";
191 break;
192 case JLEAF_MTIME:
193 str = "mtime";
194 break;
195 case JLEAF_CTIME:
196 str = "ctime";
197 break;
198 case JLEAF_GEN:
199 str = "gen";
200 break;
201 case JLEAF_FLAGS:
202 str = "flags";
203 break;
204 case JLEAF_UDEV:
205 str = "udev";
206 break;
207 case JLEAF_FILEREV:
208 str = "filerev";
209 break;
210 default:
211 str = "?";
212 break;
213 }
214 return (str);
215}
216
9c118cb2
MD
217void
218stringout(FILE *fp, char c, int exact)
219{
220 if (c != '\\' && c != '\"' && isprint(c)) {
221 putc(c, fp);
222 } else if (exact == 0) {
223 putc('.', fp);
224 } else if (c == 0) {
225 fprintf(fp, "\\0");
226 } else if (c == '\n') {
227 fprintf(fp, "\\n");
228 } else {
229 fprintf(fp, "\\x%02x", (int)(unsigned char)c);
230 }
231}
232
712e03b0
MD
233void
234jattr_reset(struct jattr *jattr)
235{
236 struct jattr *undo;
36d6bdee 237 struct jattr_data *data;
712e03b0
MD
238
239 if (jattr->path1)
240 free(jattr->path1);
241 if (jattr->path2)
242 free(jattr->path2);
243 if (jattr->path3)
244 free(jattr->path3);
245 if (jattr->path4)
246 free(jattr->path4);
247 if (jattr->comm)
248 free(jattr->comm);
249 if (jattr->attrname)
250 free(jattr->attrname);
251 if (jattr->pathref)
252 free(jattr->pathref);
fa8f36eb
MD
253 if (jattr->symlinkdata)
254 free(jattr->symlinkdata);
36d6bdee
MD
255 while ((data = jattr->data.next) != NULL) {
256 jattr->data.next = data->next;
257 free(data);
258 }
712e03b0
MD
259 if ((undo = jattr->undo) != NULL)
260 jattr_reset(jattr->undo);
261 bzero(jattr, sizeof(*jattr));
262 jattr->undo = undo;
263 jattr->uid = (uid_t)-1;
264 jattr->gid = (gid_t)-1;
265 jattr->size = (off_t)-1;
266 jattr->modes = -1;
267 jattr->flags = -1;
268 jattr->seekpos = -1;
269}
270
271int64_t
272buf_to_int64(const void *buf, int bytes)
273{
274 int64_t v;
275
276 switch(bytes) {
277 case 1:
278 v = (int64_t)*(const u_int8_t *)buf;
279 break;
280 case 2:
281 v = (int64_t)*(const u_int16_t *)buf;
282 break;
283 case 4:
284 v = (int64_t)*(const u_int32_t *)buf;
285 break;
286 case 8:
287 v = *(const int64_t *)buf;
288 break;
289 default:
290 v = 0;
291 }
292 return(v);
293}
294
295void *
296dupdata(const void *buf, int bytes)
297{
298 void *res;
299
300 res = malloc(bytes);
301 bcopy(buf, res, bytes);
302
303 return(res);
304}
305
306char *
307dupdatastr(const void *buf, int bytes)
308{
309 char *res;
310
311 res = malloc(bytes + 1);
312 bcopy(buf, res, bytes);
313 res[bytes] = 0;
314
315 return(res);
316}
317
318/*
319 * Similar to dupdatastr() but contains sanity checks.
320 */
321char *
322dupdatapath(const void *buf, int bytes)
323{
324 char *res;
325 char *scan;
326
327 res = malloc(bytes + 1);
328 bcopy(buf, res, bytes);
329 res[bytes] = 0;
330
331 if (res[0] == '/') {
332 fprintf(stderr, "Bad path: %s\n", res);
333 free(res);
334 return(NULL);
335 }
336 scan = res;
337 for (;;) {
338 if (scan[0] == '.' && scan[1] == '.' &&
339 (scan[2] == 0 || scan[2] == '/')
340 ) {
341 fprintf(stderr, "Bad path: %s\n", res);
342 free(res);
343 return(NULL);
344 }
345 if ((scan = strchr(scan, '/')) == NULL)
346 break;
347 ++scan;
348 }
349 return(res);
350}
ce5e5ac4 351