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