summaryrefslogtreecommitdiffhomepage
path: root/libs/luanet/src/df.c
blob: be582f6efb0ed61b879cb81219e17a1977043c4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* based on busybox code */
#include <stdio.h>
#include <string.h>
#include <mntent.h>
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

#include "helper.h"

struct mntent *find_mount_point(const char *name, const char *table)
{
	struct stat s;
	dev_t mountDevice;
	FILE *mountTable;
	struct mntent *mountEntry;

	if (stat(name, &s) != 0)
		return 0;

	if ((s.st_mode & S_IFMT) == S_IFBLK)
		mountDevice = s.st_rdev;
	else
		mountDevice = s.st_dev;


	mountTable = setmntent(table ? table : "/etc/mtab", "r");
	if (!mountTable)
		return 0;

	while ((mountEntry = getmntent(mountTable)) != 0) {
		if (strcmp(name, mountEntry->mnt_dir) == 0
			|| strcmp(name, mountEntry->mnt_fsname) == 0
			) { /* String match. */
			break;
			}
		if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)  /* Match the device. */
			break;
		if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice)  /* Match the directory's mount point. */
			break;
	}
	endmntent(mountTable);
	return mountEntry;
}

static unsigned long kscale(unsigned long b, unsigned long bs)
{
	return (b * (unsigned long long) bs + 1024/2) / 1024;
}

int df(lua_State *L)
{
	unsigned long blocks_used;
	unsigned blocks_percent_used;
	FILE *mount_table;
	struct mntent *mount_entry = 0;
	struct statfs s;
	/* default display is kilobytes */
	const char *disp_units_hdr = "1k-blocks";
	int cnt = 0;
	printf("Filesystem           %-15sUsed Available Use%% Mounted on\n",
			disp_units_hdr);

	mount_table = NULL;
	mount_table = setmntent("/etc/mtab", "r");
	lua_newtable(L);
	while (1) {
		const char *device;
		const char *mount_point;

		if (mount_table) {
			mount_entry = getmntent(mount_table);
			if (!mount_entry) {
				endmntent(mount_table);
				break;
			}
		}

		device = mount_entry->mnt_fsname;
		mount_point = mount_entry->mnt_dir;

		if (statfs(mount_point, &s) != 0) {
			perror(mount_point);
			continue;
		}

		if ((s.f_blocks > 0) || !mount_table)
		{
			blocks_used = s.f_blocks - s.f_bfree;
			blocks_percent_used = 0;
			if (blocks_used + s.f_bavail)
			{
				blocks_percent_used = (blocks_used * 100ULL	+ (blocks_used + s.f_bavail) / 2 )
					/ (blocks_used + s.f_bavail);
			}
			lua_pushinteger(L, ++cnt);
	        lua_newtable(L);

			add_table_entry_int(L, "blocks", kscale(s.f_blocks, s.f_bsize));
			add_table_entry_int(L, "used", kscale(s.f_blocks-s.f_bfree, s.f_bsize));
			add_table_entry_int(L, "avail", kscale(s.f_bavail, s.f_bsize));
			add_table_entry_int(L, "percent", blocks_percent_used);
			add_table_entry(L, "device", device);
			add_table_entry(L, "mountpoint", mount_point);
			add_table_entry_int(L, "blocksize",  s.f_bsize);
			lua_settable(L, -3);

			/*printf("\n%-20s" + 1, device)
			printf(" %9lu %9lu %9lu %3u%% %s\n",
				kscale(s.f_blocks, s.f_bsize),
				kscale(s.f_blocks-s.f_bfree, s.f_bsize),
				kscale(s.f_bavail, s.f_bsize),
				blocks_percent_used, mount_point);*/
		}
	}
	return 1;
}