Assorted whitespace cleanup and typo fixes.
[haiku.git] / src / bin / df.cpp
blobefb6e5583bf92420312009fd13229abf3cd69dac
1 // df - for Haiku
2 //
3 // authors, in order of contribution:
4 // jonas.sundstrom@kirilla.com
5 // axeld@pinc-software.de
6 //
9 #include <Volume.h>
10 #include <Directory.h>
11 #include <Path.h>
13 #include <fs_info.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <errno.h>
22 void
23 PrintFlag(uint32 deviceFlags, uint32 testFlag, const char *yes, const char *no)
25 printf(deviceFlags & testFlag ? yes : no);
29 void
30 PrintMountPoint(dev_t device, bool verbose)
32 char mount[B_PATH_NAME_LENGTH];
33 mount[0] = '\0';
35 BVolume volume(device);
36 BDirectory root;
37 if (volume.GetRootDirectory(&root) == B_OK) {
38 BPath path(&root, NULL);
39 if (path.InitCheck() == B_OK)
40 strlcpy(mount, path.Path(), sizeof(mount));
41 else
42 strlcpy(mount, "?", sizeof(mount));
45 if (verbose)
46 printf(" Mounted at: %s\n", mount);
47 else {
48 printf("%-15s ", mount);
49 if (strlen(mount) > 15)
50 printf("\n%15s ", "");
55 void
56 PrintType(const char *fileSystem)
58 char type[10];
59 strlcpy(type, fileSystem, sizeof(type));
61 printf("%-8s", type);
65 const char *
66 ByteString(int64 numBlocks, int64 blockSize)
68 double blocks = 1. * numBlocks * blockSize;
69 static char string[64];
71 if (blocks < 1024)
72 sprintf(string, "%" B_PRId64, numBlocks * blockSize);
73 else {
74 const char *units[] = {"K", "M", "G", NULL};
75 int32 i = -1;
77 do {
78 blocks /= 1024.0;
79 i++;
80 } while (blocks >= 1024 && units[i + 1]);
82 sprintf(string, "%.1f%s", blocks, units[i]);
85 return string;
89 void
90 PrintBlocks(int64 blocks, int64 blockSize, bool showBlocks)
92 char temp[1024];
94 if (showBlocks)
95 sprintf(temp, "%" B_PRId64, blocks * (blockSize / 1024));
96 else
97 strcpy(temp, ByteString(blocks, blockSize));
99 printf("%10s", temp);
103 void
104 PrintVerbose(dev_t device)
106 fs_info info;
107 if (fs_stat_dev(device, &info) != B_OK) {
108 fprintf(stderr, "Could not stat fs: %s\n", strerror(errno));
109 return;
112 printf(" Device No.: %" B_PRIdDEV "\n", info.dev);
113 PrintMountPoint(info.dev, true);
114 printf(" Volume Name: \"%s\"\n", info.volume_name);
115 printf(" File System: %s\n", info.fsh_name);
116 printf(" Device: %s\n", info.device_name);
118 printf(" Flags: ");
119 PrintFlag(info.flags, B_FS_HAS_QUERY, "Q", "-");
120 PrintFlag(info.flags, B_FS_HAS_ATTR, "A", "-");
121 PrintFlag(info.flags, B_FS_HAS_MIME, "M", "-");
122 PrintFlag(info.flags, B_FS_IS_SHARED, "S", "-");
123 PrintFlag(info.flags, B_FS_IS_PERSISTENT, "P", "-");
124 PrintFlag(info.flags, B_FS_IS_REMOVABLE, "R", "-");
125 PrintFlag(info.flags, B_FS_IS_READONLY, "-", "W");
127 printf("\n I/O Size: %10s (%" B_PRIdOFF " byte)\n",
128 ByteString(info.io_size, 1), info.io_size);
129 printf(" Block Size: %10s (%" B_PRIdOFF " byte)\n",
130 ByteString(info.block_size, 1), info.block_size);
131 printf(" Total Blocks: %10s (%" B_PRIdOFF " blocks)\n",
132 ByteString(info.total_blocks, info.block_size), info.total_blocks);
133 printf(" Free Blocks: %10s (%" B_PRIdOFF " blocks)\n",
134 ByteString(info.free_blocks, info.block_size), info.free_blocks);
135 printf(" Total Nodes: %" B_PRIdOFF "\n", info.total_nodes);
136 printf(" Free Nodes: %" B_PRIdOFF "\n", info.free_nodes);
137 printf(" Root Inode: %" B_PRIdINO "\n", info.root);
141 void
142 PrintCompact(dev_t device, bool showBlocks, bool all)
144 fs_info info;
145 if (fs_stat_dev(device, &info) != B_OK)
146 return;
148 if (!all && (info.flags & B_FS_IS_PERSISTENT) == 0)
149 return;
151 PrintMountPoint(info.dev, false);
152 PrintType(info.fsh_name);
153 PrintBlocks(info.total_blocks, info.block_size, showBlocks);
154 PrintBlocks(info.free_blocks, info.block_size, showBlocks);
156 printf(" ");
157 PrintFlag(info.flags, B_FS_HAS_QUERY, "Q", "-");
158 PrintFlag(info.flags, B_FS_HAS_ATTR, "A", "-");
159 PrintFlag(info.flags, B_FS_HAS_MIME, "M", "-");
160 PrintFlag(info.flags, B_FS_IS_SHARED, "S", "-");
161 PrintFlag(info.flags, B_FS_IS_PERSISTENT, "P", "-");
162 PrintFlag(info.flags, B_FS_IS_REMOVABLE, "R", "-");
163 PrintFlag(info.flags, B_FS_IS_READONLY, "-", "W");
165 printf(" %s\n", info.device_name);
169 void
170 ShowUsage(const char *programName)
172 printf("usage: %s [--help | --blocks, -b | -all, -a] [<path-to-device>]\n"
173 " -a, --all\tinclude all file systems, also those not visible from Tracker\n"
174 " -b, --blocks\tshow device size in blocks of 1024 bytes\n"
175 "If <path-to-device> is used, detailed info for that device only will be listed.\n"
176 "Flags:\n"
177 " Q: has query\n"
178 " A: has attribute\n"
179 " M: has mime\n"
180 " S: is shared\n"
181 " P: is persistent (visible in Tracker)\n"
182 " R: is removable\n"
183 " W: is writable\n", programName);
184 exit(0);
189 main(int argc, char **argv)
191 char *programName = argv[0];
192 if (strrchr(programName, '/'))
193 programName = strrchr(programName, '/') + 1;
195 bool showBlocks = false;
196 bool all = false;
197 dev_t device = -1;
199 while (*++argv) {
200 char *arg = *argv;
201 if (*arg == '-') {
202 while (*++arg && isalpha(*arg)) {
203 switch (arg[0]) {
204 case 'a':
205 all = true;
206 break;
207 case 'b':
208 showBlocks = true;
209 break;
210 default:
211 ShowUsage(programName);
214 if (arg[0] == '-') {
215 arg++;
216 if (!strcmp(arg, "all"))
217 all = true;
218 else if (!strcmp(arg, "blocks"))
219 showBlocks = true;
220 else
221 ShowUsage(programName);
223 } else
224 break;
227 // Do we already have a device? Then let's print out detailed info about that
229 if (argv[0] != NULL) {
230 PrintVerbose(dev_for_path(argv[0]));
231 return 0;
234 // If not, then just iterate over all devices and give a compact summary
236 printf("Mount Type Total Free Flags Device\n"
237 "--------------- -------- --------- --------- ------- --------------------------\n");
239 int32 cookie = 0;
240 while ((device = next_dev(&cookie)) >= B_OK) {
241 PrintCompact(device, showBlocks, all);
244 return 0;