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