xref: /haiku/src/bin/df.cpp (revision 75d92dbdda188052f5f1eac96d78c285ceeff9b9)
117049c45SAxel Dörfler //	df - for Haiku
217049c45SAxel Dörfler //
317049c45SAxel Dörfler //	authors, in order of contribution:
417049c45SAxel Dörfler //	jonas.sundstrom@kirilla.com
517049c45SAxel Dörfler //	axeld@pinc-software.de
617049c45SAxel Dörfler //
717049c45SAxel Dörfler 
817049c45SAxel Dörfler 
917049c45SAxel Dörfler #include <Volume.h>
1017049c45SAxel Dörfler #include <Directory.h>
1117049c45SAxel Dörfler #include <Path.h>
1217049c45SAxel Dörfler 
1317049c45SAxel Dörfler #include <fs_info.h>
1417049c45SAxel Dörfler 
1517049c45SAxel Dörfler #include <stdio.h>
16758b1d0eSIngo Weinhold #include <stdlib.h>
1717049c45SAxel Dörfler #include <string.h>
1817049c45SAxel Dörfler #include <ctype.h>
1917049c45SAxel Dörfler #include <errno.h>
2017049c45SAxel Dörfler 
2117049c45SAxel Dörfler 
2217049c45SAxel Dörfler void
PrintFlag(uint32 deviceFlags,uint32 testFlag,char yes,char no)23*75d92dbdSAdrien Destugues PrintFlag(uint32 deviceFlags, uint32 testFlag, char yes, char no)
2417049c45SAxel Dörfler {
25*75d92dbdSAdrien Destugues 	printf("%c", deviceFlags & testFlag ? yes : no);
2617049c45SAxel Dörfler }
2717049c45SAxel Dörfler 
2817049c45SAxel Dörfler 
2917049c45SAxel Dörfler void
PrintMountPoint(dev_t device,bool verbose)3017049c45SAxel Dörfler PrintMountPoint(dev_t device, bool verbose)
3117049c45SAxel Dörfler {
3217049c45SAxel Dörfler 	char mount[B_PATH_NAME_LENGTH];
3317049c45SAxel Dörfler 	mount[0] = '\0';
3417049c45SAxel Dörfler 
3517049c45SAxel Dörfler 	BVolume	volume(device);
3617049c45SAxel Dörfler 	BDirectory root;
3717049c45SAxel Dörfler 	if (volume.GetRootDirectory(&root) == B_OK) {
3817049c45SAxel Dörfler 		BPath path(&root, NULL);
3917049c45SAxel Dörfler 		if (path.InitCheck() == B_OK)
4017049c45SAxel Dörfler 			strlcpy(mount, path.Path(), sizeof(mount));
4117049c45SAxel Dörfler 		else
4217049c45SAxel Dörfler 			strlcpy(mount, "?", sizeof(mount));
4317049c45SAxel Dörfler 	}
4417049c45SAxel Dörfler 
4517049c45SAxel Dörfler 	if (verbose)
4617049c45SAxel Dörfler 		printf("   Mounted at: %s\n", mount);
4717049c45SAxel Dörfler 	else {
48b03efd58SDariusz Knociński 		printf("%-17s ", mount);
49b03efd58SDariusz Knociński 		if (strlen(mount) > 17)
50b03efd58SDariusz Knociński 			printf("\n%17s ", "");
5117049c45SAxel Dörfler 	}
5217049c45SAxel Dörfler }
5317049c45SAxel Dörfler 
5417049c45SAxel Dörfler 
5517049c45SAxel Dörfler void
PrintType(const char * fileSystem)5617049c45SAxel Dörfler PrintType(const char *fileSystem)
5717049c45SAxel Dörfler {
58b03efd58SDariusz Knociński 	char type[16];
5917049c45SAxel Dörfler 	strlcpy(type, fileSystem, sizeof(type));
6017049c45SAxel Dörfler 
61b03efd58SDariusz Knociński 	printf("%-9s", type);
6217049c45SAxel Dörfler }
6317049c45SAxel Dörfler 
6417049c45SAxel Dörfler 
6517049c45SAxel Dörfler const char *
ByteString(int64 numBlocks,int64 blockSize)6617049c45SAxel Dörfler ByteString(int64 numBlocks, int64 blockSize)
6717049c45SAxel Dörfler {
6817049c45SAxel Dörfler 	double blocks = 1. * numBlocks * blockSize;
6917049c45SAxel Dörfler 	static char string[64];
7017049c45SAxel Dörfler 
7117049c45SAxel Dörfler 	if (blocks < 1024)
72deb9fbcbSAlexander von Gluck IV 		sprintf(string, "%" B_PRId64, numBlocks * blockSize);
7317049c45SAxel Dörfler 	else {
74b03efd58SDariusz Knociński 		const char *units[] = {"KiB", "MiB", "GiB", "TiB", "PiB", "EiB",
75b03efd58SDariusz Knociński 							   "ZiB", "YiB", NULL};
7617049c45SAxel Dörfler 		int32 i = -1;
7717049c45SAxel Dörfler 
7817049c45SAxel Dörfler 		do {
7917049c45SAxel Dörfler 			blocks /= 1024.0;
8017049c45SAxel Dörfler 			i++;
8117049c45SAxel Dörfler 		} while (blocks >= 1024 && units[i + 1]);
8217049c45SAxel Dörfler 
8317049c45SAxel Dörfler 		sprintf(string, "%.1f %s", blocks, units[i]);
8417049c45SAxel Dörfler 	}
8517049c45SAxel Dörfler 
8617049c45SAxel Dörfler 	return string;
8717049c45SAxel Dörfler }
8817049c45SAxel Dörfler 
8917049c45SAxel Dörfler 
9017049c45SAxel Dörfler void
PrintBlocks(int64 blocks,int64 blockSize,bool showBlocks)9117049c45SAxel Dörfler PrintBlocks(int64 blocks, int64 blockSize, bool showBlocks)
9217049c45SAxel Dörfler {
9317049c45SAxel Dörfler 	char temp[1024];
9417049c45SAxel Dörfler 
9517049c45SAxel Dörfler 	if (showBlocks)
96deb9fbcbSAlexander von Gluck IV 		sprintf(temp, "%" B_PRId64, blocks * (blockSize / 1024));
9717049c45SAxel Dörfler 	else
9817049c45SAxel Dörfler 		strcpy(temp, ByteString(blocks, blockSize));
9917049c45SAxel Dörfler 
10017049c45SAxel Dörfler 	printf("%10s", temp);
10117049c45SAxel Dörfler }
10217049c45SAxel Dörfler 
10317049c45SAxel Dörfler 
10417049c45SAxel Dörfler void
PrintVerbose(dev_t device)10517049c45SAxel Dörfler PrintVerbose(dev_t device)
10617049c45SAxel Dörfler {
10717049c45SAxel Dörfler 	fs_info info;
10817049c45SAxel Dörfler 	if (fs_stat_dev(device, &info) != B_OK) {
10917049c45SAxel Dörfler 		fprintf(stderr, "Could not stat fs: %s\n", strerror(errno));
11017049c45SAxel Dörfler 		return;
11117049c45SAxel Dörfler 	}
11217049c45SAxel Dörfler 
113deb9fbcbSAlexander von Gluck IV 	printf("   Device No.: %" B_PRIdDEV "\n", info.dev);
11417049c45SAxel Dörfler 	PrintMountPoint(info.dev, true);
11517049c45SAxel Dörfler 	printf("  Volume Name: \"%s\"\n", info.volume_name);
11617049c45SAxel Dörfler 	printf("  File System: %s\n", info.fsh_name);
11717049c45SAxel Dörfler 	printf("       Device: %s\n", info.device_name);
11817049c45SAxel Dörfler 
11917049c45SAxel Dörfler 	printf("        Flags: ");
120*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_QUERY, 'Q', '-');
121*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_ATTR, 'A', '-');
122*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_MIME, 'M', '-');
123*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_SHARED, 'S', '-');
124*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_PERSISTENT, 'P', '-');
125*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_REMOVABLE, 'R', '-');
126*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_READONLY, '-', 'W');
12717049c45SAxel Dörfler 
128deb9fbcbSAlexander von Gluck IV 	printf("\n     I/O Size: %10s (%" B_PRIdOFF " byte)\n",
129deb9fbcbSAlexander von Gluck IV 		ByteString(info.io_size, 1), info.io_size);
130deb9fbcbSAlexander von Gluck IV 	printf("   Block Size: %10s (%" B_PRIdOFF " byte)\n",
131deb9fbcbSAlexander von Gluck IV 		ByteString(info.block_size, 1), info.block_size);
132deb9fbcbSAlexander von Gluck IV 	printf(" Total Blocks: %10s (%" B_PRIdOFF " blocks)\n",
133deb9fbcbSAlexander von Gluck IV 		ByteString(info.total_blocks, info.block_size), info.total_blocks);
134deb9fbcbSAlexander von Gluck IV 	printf("  Free Blocks: %10s (%" B_PRIdOFF " blocks)\n",
135deb9fbcbSAlexander von Gluck IV 		ByteString(info.free_blocks, info.block_size), info.free_blocks);
136deb9fbcbSAlexander von Gluck IV 	printf("  Total Nodes: %" B_PRIdOFF "\n", info.total_nodes);
137deb9fbcbSAlexander von Gluck IV 	printf("   Free Nodes: %" B_PRIdOFF "\n", info.free_nodes);
138deb9fbcbSAlexander von Gluck IV 	printf("   Root Inode: %" B_PRIdINO "\n", info.root);
13917049c45SAxel Dörfler }
14017049c45SAxel Dörfler 
14117049c45SAxel Dörfler 
14217049c45SAxel Dörfler void
PrintCompact(dev_t device,bool showBlocks,bool all)14317049c45SAxel Dörfler PrintCompact(dev_t device, bool showBlocks, bool all)
14417049c45SAxel Dörfler {
14517049c45SAxel Dörfler 	fs_info info;
14617049c45SAxel Dörfler 	if (fs_stat_dev(device, &info) != B_OK)
14717049c45SAxel Dörfler 		return;
14817049c45SAxel Dörfler 
14917049c45SAxel Dörfler 	if (!all && (info.flags & B_FS_IS_PERSISTENT) == 0)
15017049c45SAxel Dörfler 		return;
15117049c45SAxel Dörfler 
15217049c45SAxel Dörfler 	PrintType(info.fsh_name);
15317049c45SAxel Dörfler 	PrintBlocks(info.total_blocks, info.block_size, showBlocks);
15417049c45SAxel Dörfler 	PrintBlocks(info.free_blocks, info.block_size, showBlocks);
15517049c45SAxel Dörfler 
15617049c45SAxel Dörfler 	printf(" ");
157*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_QUERY, 'Q', '-');
158*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_ATTR, 'A', '-');
159*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_HAS_MIME, 'M', '-');
160*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_SHARED, 'S', '-');
161*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_PERSISTENT, 'P', '-');
162*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_REMOVABLE, 'R', '-');
163*75d92dbdSAdrien Destugues 	PrintFlag(info.flags, B_FS_IS_READONLY, '-', 'W');
16417049c45SAxel Dörfler 
165*75d92dbdSAdrien Destugues 	printf(" %24s ", info.device_name);
166*75d92dbdSAdrien Destugues 	PrintMountPoint(info.dev, false);
167*75d92dbdSAdrien Destugues 	printf("\n");
16817049c45SAxel Dörfler }
16917049c45SAxel Dörfler 
17017049c45SAxel Dörfler 
17117049c45SAxel Dörfler void
ShowUsage(const char * programName)17217049c45SAxel Dörfler ShowUsage(const char *programName)
17317049c45SAxel Dörfler {
17417049c45SAxel Dörfler 	printf("usage: %s [--help | --blocks, -b | -all, -a] [<path-to-device>]\n"
17517049c45SAxel Dörfler 		"  -a, --all\tinclude all file systems, also those not visible from Tracker\n"
17617049c45SAxel Dörfler 		"  -b, --blocks\tshow device size in blocks of 1024 bytes\n"
17717049c45SAxel Dörfler 		"If <path-to-device> is used, detailed info for that device only will be listed.\n"
17817049c45SAxel Dörfler 		"Flags:\n"
17917049c45SAxel Dörfler 		"   Q: has query\n"
18017049c45SAxel Dörfler 		"   A: has attribute\n"
18117049c45SAxel Dörfler 		"   M: has mime\n"
18217049c45SAxel Dörfler 		"   S: is shared\n"
18317049c45SAxel Dörfler 		"   P: is persistent (visible in Tracker)\n"
18417049c45SAxel Dörfler 		"   R: is removable\n"
18517049c45SAxel Dörfler 		"   W: is writable\n", programName);
18617049c45SAxel Dörfler 	exit(0);
18717049c45SAxel Dörfler }
18817049c45SAxel Dörfler 
18917049c45SAxel Dörfler 
19017049c45SAxel Dörfler int
main(int argc,char ** argv)191f89856e5SMichael Lotz main(int argc, char **argv)
19217049c45SAxel Dörfler {
19317049c45SAxel Dörfler 	char *programName = argv[0];
19417049c45SAxel Dörfler 	if (strrchr(programName, '/'))
19517049c45SAxel Dörfler 		programName = strrchr(programName, '/') + 1;
19617049c45SAxel Dörfler 
19717049c45SAxel Dörfler 	bool showBlocks = false;
19817049c45SAxel Dörfler 	bool all = false;
19917049c45SAxel Dörfler 	dev_t device = -1;
20017049c45SAxel Dörfler 
20117049c45SAxel Dörfler 	while (*++argv) {
20217049c45SAxel Dörfler 		char *arg = *argv;
20317049c45SAxel Dörfler 		if (*arg == '-') {
20417049c45SAxel Dörfler 			while (*++arg && isalpha(*arg)) {
20517049c45SAxel Dörfler 				switch (arg[0]) {
20617049c45SAxel Dörfler 					case 'a':
20717049c45SAxel Dörfler 						all = true;
20817049c45SAxel Dörfler 						break;
20917049c45SAxel Dörfler 					case 'b':
21017049c45SAxel Dörfler 						showBlocks = true;
21117049c45SAxel Dörfler 						break;
212045af160SFrançois Revol 					case 'h':
213045af160SFrançois Revol 						// human readable units in Unix df
214045af160SFrançois Revol 						break;
21517049c45SAxel Dörfler 					default:
21617049c45SAxel Dörfler 						ShowUsage(programName);
21717049c45SAxel Dörfler 				}
21817049c45SAxel Dörfler 			}
21917049c45SAxel Dörfler 			if (arg[0] == '-') {
22017049c45SAxel Dörfler 				arg++;
22117049c45SAxel Dörfler 				if (!strcmp(arg, "all"))
22217049c45SAxel Dörfler 					all = true;
22317049c45SAxel Dörfler 				else if (!strcmp(arg, "blocks"))
22417049c45SAxel Dörfler 					showBlocks = true;
22517049c45SAxel Dörfler 				else
22617049c45SAxel Dörfler 					ShowUsage(programName);
22717049c45SAxel Dörfler 			}
22817049c45SAxel Dörfler 		} else
22917049c45SAxel Dörfler 			break;
23017049c45SAxel Dörfler 	}
23117049c45SAxel Dörfler 
23217049c45SAxel Dörfler 	// Do we already have a device? Then let's print out detailed info about that
23317049c45SAxel Dörfler 
23417049c45SAxel Dörfler 	if (argv[0] != NULL) {
23517049c45SAxel Dörfler 		PrintVerbose(dev_for_path(argv[0]));
23617049c45SAxel Dörfler 		return 0;
23717049c45SAxel Dörfler 	}
23817049c45SAxel Dörfler 
23917049c45SAxel Dörfler 	// If not, then just iterate over all devices and give a compact summary
24017049c45SAxel Dörfler 
241*75d92dbdSAdrien Destugues 	printf(" Type      Total     Free      Flags   Device                   Mounted on\n"
242b03efd58SDariusz Knociński 		   "--------- --------- --------- ------- ------------------------ -----------------\n");
24317049c45SAxel Dörfler 
24417049c45SAxel Dörfler 	int32 cookie = 0;
24517049c45SAxel Dörfler 	while ((device = next_dev(&cookie)) >= B_OK) {
24617049c45SAxel Dörfler 		PrintCompact(device, showBlocks, all);
24717049c45SAxel Dörfler 	}
24817049c45SAxel Dörfler 
24917049c45SAxel Dörfler 	return 0;
25017049c45SAxel Dörfler }
251