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
52void 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
61int 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,
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}
u64 fp
Definition ARM64Control.h:3
char * timeString(u32 timestamp)
Definition LinnDump.cpp:28
void usage(char *prog)
Definition LinnDump.cpp:52
#define timestamp()
Reads the CPU's timestamp counter.
Definition ARMCore.h:97
C char * strdup(const char *str)
Duplicate a string.
Definition strdup.cpp:37
#define SEEK_SET
Seek relative to start-of-file.
Definition stdio.h:46
C char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition strerror.cpp:20
C int errno
The lvalue errno is used by many functions to return error values.
#define EXIT_SUCCESS
Successful termination.
Definition stdlib.h:33
C int strcmp(const char *dest, const char *src)
Compare two strings.
Definition strcmp.cpp:20
#define EXIT_FAILURE
Unsuccessful termination.
Definition stdlib.h:36
C int printf(const char *format,...)
Output a formatted string to standard output.
Definition printf.cpp:22
u64 time_t
Used for time in seconds.
Definition types.h:68
C int fclose(FILE *stream)
Close a stream.
Definition fclose.cpp:23
C void * malloc(size_t size)
A memory allocator.
Definition malloc.cpp:22
C size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream)
Binary input.
Definition fread.cpp:24
C FILE * fopen(const char *filename, const char *mode)
Open a stream.
Definition fopen.cpp:24
int main(int argc, char **argv)
Program entry point.
Definition LinnDump.cpp:61
#define NULL
NULL means zero.
Definition Macros.h:39
unsigned int u32
Unsigned 32-bit number.
Definition Types.h:53
unsigned long ulong
Unsigned long number.
Definition Types.h:47
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define LINN_SUPER_MAGIC1
Second magic number (randomly chosen bytes).
#define LINN_SUPER_MAGIC0
First magic number ('Linn').
#define LINN_GROUP_NUM_BLOCKMAP(sb)
Calculate the number of blocks needed for the blocks bitmap.
Definition LinnGroup.h:75
#define LINN_GROUP_COUNT(sb)
Calculate the number of LinnGroups in a filesystem.
Definition LinnGroup.h:64
#define LINN_GROUP_NUM_INODEMAP(sb)
Calculate the number of blocks needed for the inodes bitmap.
Definition LinnGroup.h:86
#define LINN_SUPER_OFFSET
Fixed offset in storage of the superblock.
#define LINN_GROUP_NUM_INODETAB(sb)
Calculate the number of blocks needed for the inodes table.
Definition LinnGroup.h:97
A structure containing information about a file.
Definition stdio.h:61
Structure of a group descriptor.
Definition LinnGroup.h:130
le32 inodeMap
Inode bitmap.
Definition LinnGroup.h:141
le32 freeBlocksCount
The number of free blocks in this group.
Definition LinnGroup.h:132
le32 inodeTable
Inode table contains pre-allocated inodes.
Definition LinnGroup.h:144
le32 freeInodesCount
Number of free inodes in this group.
Definition LinnGroup.h:135
le32 blockMap
Block bitmap.
Definition LinnGroup.h:138
Linnenbank Filesystem (LinnFS) super block.
le16 mountCount
Number of times we where mounted.
le32 creationTime
Time when the filesystem was created.
le32 groupsTable
Block address of the LinnGroup table.
le32 inodesCount
Total number of inodes.
le32 magic0
Allows detection of valid superblocks.
le32 freeInodesCount
Free inodes remaining.
le32 blockSize
Size of each data block.
le32 mountTime
Last time we where mounted (seconds since 1970).
le32 magic1
Allows detection of valid superblocks.
le16 minorRevision
Filesystem minor revision level.
le16 majorRevision
Filesystem major revision level.
le32 inodesPerGroup
Number of inodes per group.
le32 lastCheck
Timestamp of the last check.
le32 blocksCount
Total number of data blocks.
le32 freeBlocksCount
Number of free data blocks.
le32 blocksPerGroup
Number of blocks per group.
le16 state
Describes the current status.
Time value information.
Definition time.h:36