nrelease - fix/improve livecd
[dragonfly.git] / sbin / jscan / subs.c
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