📄 dumplfs.c
字号:
/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1991, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)dumplfs.c 8.1 (Berkeley) 6/5/93";#endif /* not lint */#include <sys/param.h>#include <sys/ucred.h>#include <sys/mount.h>#include <sys/time.h>#include <ufs/ufs/dinode.h>#include <ufs/lfs/lfs.h>#include <fcntl.h>#include <fstab.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "extern.h"static void addseg __P((char *));static void dump_cleaner_info __P((struct lfs *, void *));static void dump_dinode __P((struct dinode *));static void dump_ifile __P((int, struct lfs *, int));static int dump_ipage_ifile __P((int, IFILE *, int));static int dump_ipage_segusage __P((struct lfs *, int, IFILE *, int));static void dump_segment __P((int, int, daddr_t, struct lfs *, int));static int dump_sum __P((int, struct lfs *, SEGSUM *, int, daddr_t));static void dump_super __P((struct lfs *));static void usage __P((void));typedef struct seglist SEGLIST;struct seglist { SEGLIST *next; int num;};SEGLIST *seglist;int daddr_shift;char *special;/* Segment Usage formats */#define print_suheader \ (void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n")#define print_suentry(i, sp) \ (void)printf("%d\t%c%c%c\t%d\t%d\t%d\t%s", i, \ (((sp)->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), \ (((sp)->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), \ (((sp)->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' '), \ (sp)->su_nbytes, (sp)->su_ninos, (sp)->su_nsums, \ ctime((time_t *)&(sp)->su_lastmod))/* Ifile formats */#define print_iheader \ (void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n")#define print_ientry(i, ip) \ if (ip->if_daddr == LFS_UNUSED_DADDR) \ (void)printf("%d\tFREE\t%d\t \t\t%d\n", \ i, ip->if_version, ip->if_nextfree); \ else \ (void)printf("%d\tINUSE\t%d\t%8X \n", \ i, ip->if_version, ip->if_daddr)intmain(argc, argv) int argc; char *argv[];{ struct lfs lfs_sb1, lfs_sb2, *lfs_master; daddr_t seg_addr; int ch, do_allsb, do_ientries, fd, segnum; do_allsb = 0; do_ientries = 0; while ((ch = getopt(argc, argv, "ais:")) != EOF) switch(ch) { case 'a': /* Dump all superblocks */ do_allsb = 1; break; case 'i': /* Dump ifile entries */ do_ientries = 1; break; case 's': /* Dump out these segments */ addseg(optarg); break; default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); special = argv[0]; if ((fd = open(special, O_RDONLY, 0)) < 0) err("%s: %s", special, strerror(errno)); /* Read the first superblock */ get(fd, LFS_LABELPAD, &lfs_sb1, sizeof(struct lfs)); daddr_shift = lfs_sb1.lfs_bshift - lfs_sb1.lfs_fsbtodb; /* * Read the second superblock and figure out which check point is * most up to date. */ get(fd, lfs_sb1.lfs_sboffs[1] << daddr_shift, &lfs_sb2, sizeof(struct lfs)); lfs_master = &lfs_sb1; if (lfs_sb1.lfs_tstamp < lfs_sb2.lfs_tstamp) lfs_master = &lfs_sb2; (void)printf("Master Superblock:\n"); dump_super(lfs_master); dump_ifile(fd, lfs_master, do_ientries); if (seglist != NULL) for (; seglist != NULL; seglist = seglist->next) { seg_addr = lfs_master->lfs_sboffs[0] + seglist->num * (lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb); dump_segment(fd, seglist->num, seg_addr, lfs_master, do_allsb); } else for (segnum = 0, seg_addr = lfs_master->lfs_sboffs[0]; segnum < lfs_master->lfs_nseg; segnum++, seg_addr += lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb) dump_segment(fd, segnum, seg_addr, lfs_master, do_allsb); (void)close(fd); exit(0);}/* * We are reading all the blocks of an inode and dumping out the ifile table. * This code could be tighter, but this is a first pass at getting the stuff * printed out rather than making this code incredibly efficient. */static voiddump_ifile(fd, lfsp, do_ientries) int fd; struct lfs *lfsp; int do_ientries;{ IFILE *ipage; struct dinode *dip, *dpage; daddr_t addr, *addrp, *dindir, *iaddrp, *indir; int block_limit, i, inum, j, nblocks, nsupb, psize; psize = lfsp->lfs_bsize; addr = lfsp->lfs_idaddr; if (!(dpage = malloc(psize))) err("%s", strerror(errno)); get(fd, addr << daddr_shift, dpage, psize); for (dip = dpage + INOPB(lfsp) - 1; dip >= dpage; --dip) if (dip->di_inumber == LFS_IFILE_INUM) break; if (dip < dpage) err("unable to locate ifile inode"); (void)printf("\nIFILE inode\n"); dump_dinode(dip); (void)printf("\nIFILE contents\n"); nblocks = dip->di_size >> lfsp->lfs_bshift; block_limit = MIN(nblocks, NDADDR); /* Get the direct block */ if ((ipage = malloc(psize)) == NULL) err("%s", strerror(errno)); for (inum = 0, addrp = dip->di_db, i = 0; i < block_limit; i++, addrp++) { get(fd, *addrp << daddr_shift, ipage, psize); if (i < lfsp->lfs_cleansz) { dump_cleaner_info(lfsp, ipage); print_suheader; continue; } if (i < (lfsp->lfs_segtabsz + lfsp->lfs_cleansz)) { inum = dump_ipage_segusage(lfsp, inum, ipage, lfsp->lfs_sepb); if (!inum) if(!do_ientries) goto e0; else print_iheader; } else inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb); } if (nblocks <= NDADDR) goto e0; /* Dump out blocks off of single indirect block */ if (!(indir = malloc(psize))) err("%s", strerror(errno)); get(fd, dip->di_ib[0] << daddr_shift, indir, psize); block_limit = MIN(i + lfsp->lfs_nindir, nblocks); for (addrp = indir; i < block_limit; i++, addrp++) { if (*addrp == LFS_UNUSED_DADDR) break; get(fd, *addrp << daddr_shift,ipage, psize); if (i < lfsp->lfs_cleansz) { dump_cleaner_info(lfsp, ipage); continue; } else i -= lfsp->lfs_cleansz; if (i < lfsp->lfs_segtabsz) { inum = dump_ipage_segusage(lfsp, inum, ipage, lfsp->lfs_sepb); if (!inum) if(!do_ientries) goto e1; else print_iheader; } else inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb); } if (nblocks <= lfsp->lfs_nindir * lfsp->lfs_ifpb) goto e1; /* Get the double indirect block */ if (!(dindir = malloc(psize))) err("%s", strerror(errno)); get(fd, dip->di_ib[1] << daddr_shift, dindir, psize); for (iaddrp = dindir, j = 0; j < lfsp->lfs_nindir; j++, iaddrp++) { if (*iaddrp == LFS_UNUSED_DADDR) break; get(fd, *iaddrp << daddr_shift, indir, psize); block_limit = MIN(i + lfsp->lfs_nindir, nblocks); for (addrp = indir; i < block_limit; i++, addrp++) { if (*addrp == LFS_UNUSED_DADDR) break; get(fd, *addrp << daddr_shift, ipage, psize); if (i < lfsp->lfs_cleansz) { dump_cleaner_info(lfsp, ipage); continue; } else i -= lfsp->lfs_cleansz; if (i < lfsp->lfs_segtabsz) { inum = dump_ipage_segusage(lfsp, inum, ipage, lfsp->lfs_sepb); if (!inum) if(!do_ientries) goto e2; else print_iheader; } else inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb); } }e2: free(dindir);e1: free(indir);e0: free(dpage); free(ipage);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -