fsdbutil.c revision 1.18
1/* $OpenBSD: fsdbutil.c,v 1.18 2017/07/29 21:14:56 fcambus Exp $ */ 2/* $NetBSD: fsdbutil.c,v 1.5 1996/09/28 19:30:37 christos Exp $ */ 3 4/*- 5 * Copyright (c) 1996 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by John T. Kohl. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/stat.h> 34#include <sys/time.h> 35#include <sys/mount.h> 36#include <ctype.h> 37#include <err.h> 38#include <fcntl.h> 39#include <grp.h> 40#include <pwd.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <unistd.h> 45 46#include <ufs/ufs/dinode.h> 47#include <ufs/ffs/fs.h> 48 49#include "fsdb.h" 50#include "fsck.h" 51 52char ** 53crack(char *line, int *argc) 54{ 55 static char *argv[8]; 56 int i; 57 char *p, *val; 58 59 for (p = line, i = 0; p != NULL && i < 8; i++) { 60 while ((val = strsep(&p, " \t\n")) != NULL && *val == '\0') 61 /**/; 62 if (val) 63 argv[i] = val; 64 else 65 break; 66 } 67 *argc = i; 68 return argv; 69} 70 71int 72argcount(struct cmdtable *cmdp, int argc, char *argv[]) 73{ 74 if (cmdp->minargc == cmdp->maxargc) 75 warnx("command `%s' takes %u arguments", cmdp->cmd, cmdp->minargc-1); 76 else 77 warnx("command `%s' takes from %u to %u arguments", 78 cmdp->cmd, cmdp->minargc-1, cmdp->maxargc-1); 79 warnx("usage: %s: %s", cmdp->cmd, cmdp->helptxt); 80 return 1; 81} 82 83void 84printstat(const char *cp, ino_t inum, union dinode *dp) 85{ 86 struct group *grp; 87 struct passwd *pw; 88 time_t t; 89 char *p; 90 91 printf("%s: ", cp); 92 switch (DIP(dp, di_mode) & IFMT) { 93 case IFDIR: 94 puts("directory"); 95 break; 96 case IFREG: 97 puts("regular file"); 98 break; 99 case IFBLK: 100 printf("block special (%d,%d)", 101 (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev))); 102 break; 103 case IFCHR: 104 printf("character special (%d,%d)", 105 (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev))); 106 break; 107 case IFLNK: 108 fputs("symlink",stdout); 109 if (DIP(dp, di_size) > 0 && 110 DIP(dp, di_size) < sblock.fs_maxsymlinklen && 111 DIP(dp, di_blocks) == 0) { 112 char *p = sblock.fs_magic == FS_UFS1_MAGIC ? 113 (char *)dp->dp1.di_shortlink : 114 (char *)dp->dp2.di_shortlink; 115 printf(" to `%.*s'\n", (int)DIP(dp, di_size), p); 116 } else 117 putchar('\n'); 118 break; 119 case IFSOCK: 120 puts("socket"); 121 break; 122 case IFIFO: 123 puts("fifo"); 124 break; 125 } 126 127 printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum, 128 DIP(dp, di_mode), DIP(dp, di_size)); 129 t = DIP(dp, di_mtime); 130 p = ctime(&t); 131 printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], 132 DIP(dp, di_mtimensec)); 133 t = DIP(dp, di_ctime); 134 p = ctime(&t); 135 printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], 136 DIP(dp, di_ctimensec)); 137 t = DIP(dp, di_atime); 138 p = ctime(&t); 139 printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20], 140 DIP(dp, di_atimensec)); 141 142 if ((pw = getpwuid(DIP(dp, di_uid)))) 143 printf("OWNER=%s ", pw->pw_name); 144 else 145 printf("OWNUID=%u ", DIP(dp, di_uid)); 146 if ((grp = getgrgid(DIP(dp, di_gid)))) 147 printf("GRP=%s ", grp->gr_name); 148 else 149 printf("GID=%u ", DIP(dp, di_gid)); 150 151 printf("LINKCNT=%d FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink), 152 DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen)); 153} 154 155int 156checkactive(void) 157{ 158 if (!curinode) { 159 warnx("no current inode"); 160 return 0; 161 } 162 return 1; 163} 164 165int 166checkactivedir(void) 167{ 168 if (!curinode) { 169 warnx("no current inode"); 170 return 0; 171 } 172 if ((DIP(curinode, di_mode) & IFMT) != IFDIR) { 173 warnx("inode %llu not a directory", 174 (unsigned long long)curinum); 175 return 0; 176 } 177 return 1; 178} 179 180int 181printactive(void) 182{ 183 if (!checkactive()) 184 return 1; 185 switch (DIP(curinode, di_mode) & IFMT) { 186 case IFDIR: 187 case IFREG: 188 case IFBLK: 189 case IFCHR: 190 case IFLNK: 191 case IFSOCK: 192 case IFIFO: 193 printstat("current inode", curinum, curinode); 194 break; 195 case 0: 196 printf("current inode %llu: unallocated inode\n", 197 (unsigned long long)curinum); 198 break; 199 default: 200 printf("current inode %llu: screwy itype 0%o (mode 0%o)?\n", 201 (unsigned long long)curinum, DIP(curinode, di_mode) & IFMT, 202 DIP(curinode, di_mode)); 203 break; 204 } 205 return 0; 206} 207