00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <sys/types.h>
00031 #include <stdint.h>
00032 #include <string.h>
00033 #include <stdio.h>
00034 #include <assert.h>
00035 #include <limits.h>
00036 #include <err.h>
00037
00038 #include "support.h"
00039 #include "kern/sfs.h"
00040
00041
00042 #ifdef HOST
00043
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include "hostcompat.h"
00047 #define SWAPL(x) ntohl(x)
00048 #define SWAPS(x) ntohs(x)
00049
00050 #else
00051
00052 #define SWAPL(x) (x)
00053 #define SWAPS(x) (x)
00054
00055 #endif
00056
00057 #include "disk.h"
00058
00059 static
00060 uint32_t
00061 dumpsb(void)
00062 {
00063 struct sfs_super sp;
00064 diskread(&sp, SFS_SB_LOCATION);
00065 if (SWAPL(sp.sp_magic) != SFS_MAGIC) {
00066 errx(1, "Not an sfs filesystem");
00067 }
00068 sp.sp_volname[sizeof(sp.sp_volname)-1] = 0;
00069 printf("Volume name: %-40s %u blocks\n", sp.sp_volname,
00070 SWAPL(sp.sp_nblocks));
00071
00072 return SWAPL(sp.sp_nblocks);
00073 }
00074
00075 static
00076 void
00077 dodirblock(uint32_t block)
00078 {
00079 struct sfs_dir sds[SFS_BLOCKSIZE/sizeof(struct sfs_dir)];
00080 int nsds = SFS_BLOCKSIZE/sizeof(struct sfs_dir);
00081 int i;
00082
00083 diskread(&sds, block);
00084
00085 printf(" [block %u]\n", block);
00086 for (i=0; i<nsds; i++) {
00087 uint32_t ino = SWAPL(sds[i].sfd_ino);
00088 if (ino==SFS_NOINO) {
00089 printf(" [free entry]\n");
00090 }
00091 else {
00092 sds[i].sfd_name[SFS_NAMELEN-1] = 0;
00093 printf(" %u %s\n", ino, sds[i].sfd_name);
00094 }
00095 }
00096 }
00097
00098 static
00099 void
00100 dumpdir(uint32_t ino)
00101 {
00102 struct sfs_inode sfi;
00103 uint32_t ib[SFS_DBPERIDB];
00104 int nentries, i;
00105 uint32_t block, nblocks=0;
00106
00107 diskread(&sfi, ino);
00108
00109 nentries = SWAPL(sfi.sfi_size) / sizeof(struct sfs_dir);
00110 if (SWAPL(sfi.sfi_size) % sizeof(struct sfs_dir) != 0) {
00111 warnx("Warning: dir size is not a multiple of dir entry size");
00112 }
00113 printf("Directory %u: %d entries\n", ino, nentries);
00114
00115 for (i=0; i<SFS_NDIRECT; i++) {
00116 block = SWAPL(sfi.sfi_direct[i]);
00117 if (block) {
00118 dodirblock(block);
00119 nblocks++;
00120 }
00121 }
00122 if (SWAPL(sfi.sfi_indirect)) {
00123 diskread(&ib, SWAPL(sfi.sfi_indirect));
00124 for (i=0; i<SFS_DBPERIDB; i++) {
00125 block = SWAPL(ib[i]);
00126 if (block) {
00127 dodirblock(block);
00128 nblocks++;
00129 }
00130 }
00131 }
00132 printf(" %u blocks in directory\n", nblocks);
00133 }
00134
00135 static
00136 void
00137 dumpbits(uint32_t fsblocks)
00138 {
00139 uint32_t nblocks = SFS_BITBLOCKS(fsblocks);
00140 uint32_t i, j;
00141 char data[SFS_BLOCKSIZE];
00142
00143 printf("Freemap: %u blocks (%u %u %u)\n", nblocks, SFS_BITMAPSIZE(fsblocks), fsblocks, SFS_BLOCKBITS);
00144
00145 for (i=0; i<nblocks; i++) {
00146 diskread(data, SFS_MAP_LOCATION+i);
00147 for (j=0; j<SFS_BLOCKSIZE; j++) {
00148 printf("%02x", (unsigned char)data[j]);
00149 if (j%32==31) {
00150 printf("\n");
00151 }
00152 }
00153 }
00154 printf("\n");
00155 }
00156
00157 int
00158 main(int argc, char **argv)
00159 {
00160 uint32_t nblocks;
00161
00162 #ifdef HOST
00163 hostcompat_init(argc, argv);
00164 #endif
00165
00166 if (argc!=2) {
00167 errx(1, "Usage: dumpsfs device/diskfile");
00168 }
00169
00170 opendisk(argv[1]);
00171 nblocks = dumpsb();
00172 dumpbits(nblocks);
00173 dumpdir(SFS_ROOT_LOCATION);
00174
00175 closedisk();
00176
00177 return 0;
00178 }