FreeNOS
LinnDump.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <Types.h>
19 #include "LinnSuperBlock.h"
20 #include "LinnGroup.h"
21 #include "LinnInode.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <time.h>
27 
29 {
30  char *buff = (char *) malloc(128);
32  struct tm *tm;
33 
34  // Check for zero timestamps.
35  if (!timestamp)
36  {
37  return strdup("Never");
38  }
39  // Fill in the time struct.
40  tm = gmtime(&timeval);
41 
42  // Format time.
43  if (!strftime(buff, 128, "%F %T", tm))
44  {
45  return strdup("???");
46  }
47  // Done.
48  else
49  return buff;
50 }
51 
52 void usage(char *prog)
53 {
54  printf("usage: %s FILE [OPTIONS...]\r\n"
55  "Displays information of a Linnenbank Filesystem\r\n"
56  "\r\n"
57  "-h Show this help message.\r\n",
58  prog);
59 }
60 
61 int main(int argc, char **argv)
62 {
63  LinnSuperBlock super;
64  LinnGroup group;
65  float percentFreeBlocks = 0, percentFreeInodes = 0, megabytes = 0;
66  FILE *fp;
67 
68  // Verify command-line arguments.
69  if (argc < 2)
70  {
71  usage(argv[0]);
72  return EXIT_FAILURE;
73  }
74  // Process command-line options.
75  for (int i = 0; i < argc - 2; i++)
76  {
77  // Show help.
78  if (!strcmp(argv[i + 2], "-h"))
79  {
80  usage(argv[0]);
81  return EXIT_SUCCESS;
82  }
83  // Unknown argument.
84  else
85  printf("%s: unknown option `%s'\r\n",
86  argv[0], argv[i + 2]);
87  }
88  // Attempt to open the given file.
89  if ((fp = fopen(argv[1], "r")) == NULL)
90  {
91  printf("%s: failed to fopen() `%s': %s\n",
92  argv[0], argv[1], strerror(errno));
93  return EXIT_FAILURE;
94  }
95  // Seek to correct offset.
96  if (fseek(fp, LINN_SUPER_OFFSET, SEEK_SET) == -1)
97  {
98  printf("%s: failed to fseek() to %x in `%s': %s\n",
99  argv[0], LINN_SUPER_OFFSET, argv[1], strerror(errno));
100  return EXIT_FAILURE;
101  }
102  // Read the superblock.
103  if (fread(&super, sizeof(super), 1, fp) != 1)
104  {
105  printf("%s: failed to fread() superblock from `%s': %s\n",
106  argv[0], argv[1], ferror(fp) ? strerror(errno) : "End of file");
107  return EXIT_FAILURE;
108  }
109  // Verify magic.
110  if (super.magic0 != LINN_SUPER_MAGIC0 ||
111  super.magic1 != LINN_SUPER_MAGIC1)
112  {
113  printf("%s: `%s' is not a LinnFS filesystem (magic mismatch)\n",
114  argv[0], argv[1]);
115  return EXIT_FAILURE;
116  }
117  // Calculate the percentage of free blocks.
118  if (super.blocksCount)
119  percentFreeBlocks = ((float) super.freeBlocksCount /
120  (float) super.blocksCount) * 100.0;
121 
122  // Percentage of free inodes.
123  if (super.inodesCount)
124  percentFreeInodes = ((float) super.freeInodesCount /
125  (float) super.inodesCount) * 100.0;
126 
127  // Maximum number of megabytes the filesystem can manage.
128  megabytes = (float) super.blocksCount * (float) super.blockSize /
129  (1024.0 * 1024.0);
130 
131  // Dump superblock information.
132  printf( "LinnSuperBlock\n"
133  "[\n"
134  " magic0 = %x\n"
135  " magic1 = %x\n"
136  " majorRevision = %u\n"
137  " minorRevision = %u\n"
138  " state = %x\n"
139  " blockSize = %u\n"
140  " blocksPerGroup = %u\n"
141  " inodesPerGroup = %u\n"
142  " inodesCount = %u\n"
143  " blocksCount = %u (%.2fMB)\n"
144  " freeBlocksCount = %u (%.2f%%)\n"
145  " freeInodesCount = %u (%.2f%%)\n"
146  " creationTime = %s\n"
147  " mountTime = %s\n"
148  " mountCount = %u\n"
149  " lastCheck = %s\n"
150  " groupsTable = %u\n"
151  "]\n",
152  super.magic0, super.magic1,
153  super.majorRevision, super.minorRevision,
154  super.state, super.blockSize,
155  super.blocksPerGroup, super.inodesPerGroup, super.inodesCount,
156  super.blocksCount, megabytes,
157  super.freeBlocksCount, percentFreeBlocks,
158  super.freeInodesCount, percentFreeInodes,
159  timeString(super.creationTime),
160  timeString(super.mountTime), super.mountCount,
161  timeString(super.lastCheck), super.groupsTable);
162 
163  // Seek to the group table.
164  if (fseek(fp, super.groupsTable * super.blockSize, SEEK_SET) == -1)
165  {
166  printf("%s: failed to seek to LinnGroup table in `%s': %s\n",
167  argv[0], argv[1], strerror(errno));
168  return EXIT_FAILURE;
169  }
170  // Dump group information.
171  for (Size i = 0; i < LINN_GROUP_COUNT(&super); i++)
172  {
173  // Read the LinnGroup.
174  if (fread(&group, sizeof(group), 1, fp) != 1)
175  {
176  printf("%s: failed to fread() group from `%s': %s\n",
177  argv[0], argv[1], ferror(fp) ? strerror(errno) : "End of file");
178  return EXIT_FAILURE;
179  }
180  // Dump group.
181  printf( "LinnGroup #%u (blocks %u - %u)\n"
182  "[\n"
183  " freeBlocksCount = %u\n"
184  " freeInodesCount = %u\n"
185  " blockMap = %u - %lu\n"
186  " inodeMap = %u - %lu\n"
187  " inodeTable = %u - %lu\n"
188  "]\n",
189  i,
190  i * super.blocksPerGroup,
191  (i + 1) * super.blocksPerGroup - 1,
192  group.freeBlocksCount,
193  group.freeInodesCount,
194  group.blockMap,
195  (ulong) group.blockMap + LINN_GROUP_NUM_BLOCKMAP(&super),
196  group.inodeMap,
197  (ulong) group.inodeMap + LINN_GROUP_NUM_INODEMAP(&super),
198  group.inodeTable,
199  (ulong) group.inodeTable + LINN_GROUP_NUM_INODETAB(&super));
200  }
201  // Cleanup and terminate.
202  fclose(fp);
203  return EXIT_FAILURE;
204 }
EXIT_FAILURE
#define EXIT_FAILURE
Unsuccessful termination.
Definition: stdlib.h:36
LinnSuperBlock::state
le16 state
Describes the current status.
Definition: LinnSuperBlock.h:119
LinnSuperBlock::lastCheck
le32 lastCheck
Timestamp of the last check.
Definition: LinnSuperBlock.h:133
LinnSuperBlock::freeInodesCount
le32 freeInodesCount
Free inodes remaining.
Definition: LinnSuperBlock.h:128
LINN_GROUP_NUM_INODETAB
#define LINN_GROUP_NUM_INODETAB(sb)
Calculate the number of blocks needed for the inodes table.
Definition: LinnGroup.h:97
LinnSuperBlock::majorRevision
le16 majorRevision
Filesystem major revision level.
Definition: LinnSuperBlock.h:117
LINN_GROUP_NUM_BLOCKMAP
#define LINN_GROUP_NUM_BLOCKMAP(sb)
Calculate the number of blocks needed for the blocks bitmap.
Definition: LinnGroup.h:75
ulong
unsigned long ulong
Unsigned long number.
Definition: Types.h:47
Types.h
errno
C int errno
The lvalue errno is used by many functions to return error values.
LinnSuperBlock::magic0
le32 magic0
Allows detection of valid superblocks.
Definition: LinnSuperBlock.h:115
fopen
FILE * fopen(const char *filename, const char *mode)
Open a stream.
Definition: fopen.cpp:24
string.h
timestamp
u64 timestamp()
Reads the CPU's timestamp counter.
Definition: IntelCore.h:41
LinnGroup.h
LinnSuperBlock::magic1
le32 magic1
Allows detection of valid superblocks.
Definition: LinnSuperBlock.h:116
LinnSuperBlock::mountTime
le32 mountTime
Last time we where mounted (seconds since 1970).
Definition: LinnSuperBlock.h:131
LinnGroup
Structure of a group descriptor.
Definition: LinnGroup.h:129
LinnSuperBlock::inodesCount
le32 inodesCount
Total number of inodes.
Definition: LinnSuperBlock.h:125
LinnSuperBlock::blocksPerGroup
le32 blocksPerGroup
Number of blocks per group.
Definition: LinnSuperBlock.h:122
LinnGroup::blockMap
le32 blockMap
Block bitmap.
Definition: LinnGroup.h:138
malloc
C void * malloc(size_t size)
A memory allocator.
Definition: malloc.cpp:22
LINN_GROUP_NUM_INODEMAP
#define LINN_GROUP_NUM_INODEMAP(sb)
Calculate the number of blocks needed for the inodes bitmap.
Definition: LinnGroup.h:86
main
int main(int argc, char **argv)
Program entry point.
Definition: LinnDump.cpp:61
LinnGroup::inodeTable
le32 inodeTable
Inode table contains pre-allocated inodes.
Definition: LinnGroup.h:144
time_t
u64 time_t
Used for time in seconds.
Definition: types.h:68
LinnSuperBlock::freeBlocksCount
le32 freeBlocksCount
Number of free data blocks.
Definition: LinnSuperBlock.h:127
strdup
char * strdup(const char *str)
Duplicate a string.
Definition: strdup.cpp:37
LinnGroup::freeBlocksCount
le32 freeBlocksCount
The number of free blocks in this group.
Definition: LinnGroup.h:132
printf
int printf(const char *format,...)
Output a formatted string to standard output.
Definition: printf.cpp:22
LINN_SUPER_OFFSET
#define LINN_SUPER_OFFSET
Fixed offset in storage of the superblock.
Definition: LinnSuperBlock.h:85
LinnSuperBlock
Linnenbank Filesystem (LinnFS) super block.
Definition: LinnSuperBlock.h:113
LinnInode.h
LINN_SUPER_MAGIC1
#define LINN_SUPER_MAGIC1
Second magic number (randomly chosen bytes).
Definition: LinnSuperBlock.h:40
usage
void usage(char *prog)
Definition: LinnDump.cpp:52
LINN_SUPER_MAGIC0
#define LINN_SUPER_MAGIC0
First magic number ('Linn').
Definition: LinnSuperBlock.h:37
strcmp
int strcmp(const char *dest, const char *src)
Compare two strings.
Definition: strcmp.cpp:20
stdio.h
strerror
char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition: strerror.cpp:20
NULL
#define NULL
NULL means zero.
Definition: Macros.h:39
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
LinnSuperBlock::groupsTable
le32 groupsTable
Block address of the LinnGroup table.
Definition: LinnSuperBlock.h:135
LINN_GROUP_COUNT
#define LINN_GROUP_COUNT(sb)
Calculate the number of LinnGroups in a filesystem.
Definition: LinnGroup.h:64
LinnSuperBlock::creationTime
le32 creationTime
Time when the filesystem was created.
Definition: LinnSuperBlock.h:130
EXIT_SUCCESS
#define EXIT_SUCCESS
Successful termination.
Definition: stdlib.h:33
timeval
Time value information.
Definition: time.h:35
SEEK_SET
#define SEEK_SET
Seek relative to start-of-file.
Definition: stdio.h:46
LinnGroup::freeInodesCount
le32 freeInodesCount
Number of free inodes in this group.
Definition: LinnGroup.h:135
timeString
char * timeString(u32 timestamp)
Definition: LinnDump.cpp:28
LinnSuperBlock::blocksCount
le32 blocksCount
Total number of data blocks.
Definition: LinnSuperBlock.h:126
LinnSuperBlock::blockSize
le32 blockSize
Size of each data block.
Definition: LinnSuperBlock.h:121
LinnSuperBlock::mountCount
le16 mountCount
Number of times we where mounted.
Definition: LinnSuperBlock.h:132
LinnSuperBlock::minorRevision
le16 minorRevision
Filesystem minor revision level.
Definition: LinnSuperBlock.h:118
fread
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream)
Binary input.
Definition: fread.cpp:24
FILE
A structure containing information about a file.
Definition: stdio.h:60
stdlib.h
fclose
int fclose(FILE *stream)
Close a stream.
Definition: fclose.cpp:23
LinnGroup::inodeMap
le32 inodeMap
Inode bitmap.
Definition: LinnGroup.h:141
LinnSuperBlock::inodesPerGroup
le32 inodesPerGroup
Number of inodes per group.
Definition: LinnSuperBlock.h:123
errno.h
LinnSuperBlock.h