xref: /dragonfly/sbin/jscan/subs.c (revision 4a9a2afb7b2d86ea674d59e2680245a8c92fbd6a)
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
jf_warn(struct jfile * jf,const char * ctl,...)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 *
type_to_name(int16_t rectype)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
stringout(FILE * fp,char c,int exact)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
jattr_reset(struct jattr * jattr)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
buf_to_int64(const void * buf,int bytes)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 *
dupdatastr(const void * buf,int bytes)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 *
dupdatapath(const void * buf,int bytes)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
get_transid_from_file(const char * path,int64_t * transid,int flags)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