xref: /dragonfly/sbin/jscan/subs.c (revision c03f08f3)
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  *
34  * $DragonFly: src/sbin/jscan/subs.c,v 1.8 2005/09/07 19:10:09 dillon Exp $
35  */
36 
37 #include "jscan.h"
38 
39 void
40 jf_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 
51 const char *
52 type_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_REDO:
73 	str = "REDO";
74 	break;
75     case JTYPE_AUDIT:
76 	str = "AUDIT";
77 	break;
78     case JTYPE_SETATTR:
79 	str = "SETATTR";
80 	break;
81     case JTYPE_WRITE:
82 	str = "WRITE";
83 	break;
84     case JTYPE_PUTPAGES:
85 	str = "PUTPAGES";
86 	break;
87     case JTYPE_SETACL:
88 	str = "SETACL";
89 	break;
90     case JTYPE_SETEXTATTR:
91 	str = "SETEXTATTR";
92 	break;
93     case JTYPE_CREATE:
94 	str = "CREATE";
95 	break;
96     case JTYPE_MKNOD:
97 	str = "MKNOD";
98 	break;
99     case JTYPE_LINK:
100 	str = "LINK";
101 	break;
102     case JTYPE_SYMLINK:
103 	str = "SYMLINK";
104 	break;
105     case JTYPE_WHITEOUT:
106 	str = "WHITEOUT";
107 	break;
108     case JTYPE_REMOVE:
109 	str = "REMOVE";
110 	break;
111     case JTYPE_MKDIR:
112 	str = "MKDIR";
113 	break;
114     case JTYPE_RMDIR:
115 	str = "RMDIR";
116 	break;
117     case JTYPE_RENAME:
118 	str = "RENAME";
119 	break;
120     case JTYPE_VATTR:
121 	str = "vattr";
122 	break;
123     case JTYPE_CRED:
124 	str = "cred";
125 	break;
126     case JLEAF_FILEDATA:
127 	str = "filedata";
128 	break;
129     case JLEAF_PATH1:
130 	str = "path1";
131 	break;
132     case JLEAF_PATH2:
133 	str = "path2";
134 	break;
135     case JLEAF_PATH3:
136 	str = "path3";
137 	break;
138     case JLEAF_PATH4:
139 	str = "path4";
140 	break;
141     case JLEAF_UID:
142 	str = "uid";
143 	break;
144     case JLEAF_GID:
145 	str = "gid";
146 	break;
147     case JLEAF_VTYPE:
148 	str = "vtype";
149 	break;
150     case JLEAF_MODES:
151 	str = "modes";
152 	break;
153     case JLEAF_FFLAGS:
154 	str = "fflags";
155 	break;
156     case JLEAF_PID:
157 	str = "pid";
158 	break;
159     case JLEAF_PPID:
160 	str = "ppid";
161 	break;
162     case JLEAF_COMM:
163 	str = "comm";
164 	break;
165     case JLEAF_ATTRNAME:
166 	str = "attrname";
167 	break;
168     case JLEAF_PATH_REF:
169 	str = "path_ref";
170 	break;
171     case JLEAF_RESERVED_0F:
172 	str = "?";
173 	break;
174     case JLEAF_SYMLINKDATA:
175 	str = "symlinkdata";
176 	break;
177     case JLEAF_SEEKPOS:
178 	str = "seekpos";
179 	break;
180     case JLEAF_INUM:
181 	str = "inum";
182 	break;
183     case JLEAF_NLINK:
184 	str = "nlink";
185 	break;
186     case JLEAF_FSID:
187 	str = "fsid";
188 	break;
189     case JLEAF_SIZE:
190 	str = "size";
191 	break;
192     case JLEAF_ATIME:
193 	str = "atime";
194 	break;
195     case JLEAF_MTIME:
196 	str = "mtime";
197 	break;
198     case JLEAF_CTIME:
199 	str = "ctime";
200 	break;
201     case JLEAF_GEN:
202 	str = "gen";
203 	break;
204     case JLEAF_FLAGS:
205 	str = "flags";
206 	break;
207     case JLEAF_UDEV:
208 	str = "udev";
209 	break;
210     case JLEAF_FILEREV:
211 	str = "filerev";
212 	break;
213     default:
214 	str = "?";
215 	break;
216     }
217     return (str);
218 }
219 
220 void
221 stringout(FILE *fp, char c, int exact)
222 {
223     if ((c >= 'a' && c <= 'z') ||
224 	(c >= 'A' && c <= 'Z') ||
225 	(c >= '0' && c <= '9')
226     ) {
227 	putc(c, fp);
228     } else if (isprint((unsigned char)c) && c != '\\' && c != '\"') {
229 	putc(c, fp);
230     } else if (exact == 0) {
231 	putc('.', fp);
232     } else if (c == 0) {
233 	fprintf(fp, "\\0");
234     } else if (c == '\n') {
235 	fprintf(fp, "\\n");
236     } else {
237 	fprintf(fp, "\\x%02x", (int)(unsigned char)c);
238     }
239 }
240 
241 void
242 jattr_reset(struct jattr *jattr)
243 {
244     struct jattr *undo;
245     struct jattr_data *data;
246 
247     if (jattr->path1)
248 	free(jattr->path1);
249     if (jattr->path2)
250 	free(jattr->path2);
251     if (jattr->path3)
252 	free(jattr->path3);
253     if (jattr->path4)
254 	free(jattr->path4);
255     if (jattr->comm)
256 	free(jattr->comm);
257     if (jattr->attrname)
258 	free(jattr->attrname);
259     if (jattr->pathref)
260 	free(jattr->pathref);
261     if (jattr->symlinkdata)
262 	free(jattr->symlinkdata);
263     while ((data = jattr->data.next) != NULL) {
264 	jattr->data.next = data->next;
265 	free(data);
266     }
267     if ((undo = jattr->undo) != NULL)
268 	jattr_reset(jattr->undo);
269     bzero(jattr, sizeof(*jattr));
270     jattr->undo = undo;
271     jattr->uid = (uid_t)-1;
272     jattr->gid = (gid_t)-1;
273     jattr->size = (off_t)-1;
274     jattr->modes = -1;
275     jattr->flags = -1;
276     jattr->seekpos = -1;
277 }
278 
279 int64_t
280 buf_to_int64(const void *buf, int bytes)
281 {
282     int64_t v;
283 
284     switch(bytes) {
285     case 1:
286 	v = (int64_t)*(const u_int8_t *)buf;
287 	break;
288     case 2:
289 	v = (int64_t)*(const u_int16_t *)buf;
290 	break;
291     case 4:
292 	v = (int64_t)*(const u_int32_t *)buf;
293 	break;
294     case 8:
295 	v = *(const int64_t *)buf;
296 	break;
297     default:
298 	v = 0;
299     }
300     return(v);
301 }
302 
303 void *
304 dupdata(const void *buf, int bytes)
305 {
306     void *res;
307 
308     res = malloc(bytes);
309     bcopy(buf, res, bytes);
310 
311     return(res);
312 }
313 
314 char *
315 dupdatastr(const void *buf, int bytes)
316 {
317     char *res;
318 
319     res = malloc(bytes + 1);
320     bcopy(buf, res, bytes);
321     res[bytes] = 0;
322 
323     return(res);
324 }
325 
326 /*
327  * Similar to dupdatastr() but contains sanity checks.
328  */
329 char *
330 dupdatapath(const void *buf, int bytes)
331 {
332     char *res;
333     char *scan;
334 
335     res = malloc(bytes + 1);
336     bcopy(buf, res, bytes);
337     res[bytes] = 0;
338 
339     if (res[0] == '/') {
340 	fprintf(stderr, "Bad path: %s\n", res);
341 	free(res);
342 	return(NULL);
343     }
344     scan = res;
345     for (;;) {
346 	if (scan[0] == '.' && scan[1] == '.' &&
347 	    (scan[2] == 0 || scan[2] == '/')
348 	) {
349 	    fprintf(stderr, "Bad path: %s\n", res);
350 	    free(res);
351 	    return(NULL);
352 	}
353 	if ((scan = strchr(scan, '/')) == NULL)
354 	    break;
355 	++scan;
356     }
357     return(res);
358 }
359 
360 void
361 get_transid_from_file(const char *path, int64_t *transid, int flags)
362 {
363     int n;
364     int fd;
365     char buf[32];
366 
367     *transid = 0;
368     if ((fd = open(path, O_RDONLY)) >= 0) {
369 	n = read(fd, buf, sizeof(buf) - 1);
370 	if (n >= 0)
371 	    buf[n] = 0;
372 	*transid = strtoull(buf, NULL, 16);
373 	jmodes |= flags;
374 	close(fd);
375     }
376 }
377 
378