Import luanet library
[project/luci.git] / libs / luanet / src / df.c
1 /* based on busybox code */
2 #include <stdio.h>
3 #include <string.h>
4 #include <mntent.h>
5 #include <sys/vfs.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9
10 #include <lua.h>
11 #include <lualib.h>
12 #include <lauxlib.h>
13
14 #include "helper.h"
15
16 struct mntent *find_mount_point(const char *name, const char *table)
17 {
18 struct stat s;
19 dev_t mountDevice;
20 FILE *mountTable;
21 struct mntent *mountEntry;
22
23 if (stat(name, &s) != 0)
24 return 0;
25
26 if ((s.st_mode & S_IFMT) == S_IFBLK)
27 mountDevice = s.st_rdev;
28 else
29 mountDevice = s.st_dev;
30
31
32 mountTable = setmntent(table ? table : "/etc/mtab", "r");
33 if (!mountTable)
34 return 0;
35
36 while ((mountEntry = getmntent(mountTable)) != 0) {
37 if (strcmp(name, mountEntry->mnt_dir) == 0
38 || strcmp(name, mountEntry->mnt_fsname) == 0
39 ) { /* String match. */
40 break;
41 }
42 if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */
43 break;
44 if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */
45 break;
46 }
47 endmntent(mountTable);
48 return mountEntry;
49 }
50
51 static unsigned long kscale(unsigned long b, unsigned long bs)
52 {
53 return (b * (unsigned long long) bs + 1024/2) / 1024;
54 }
55
56 int df(lua_State *L)
57 {
58 unsigned long blocks_used;
59 unsigned blocks_percent_used;
60 FILE *mount_table;
61 struct mntent *mount_entry = 0;
62 struct statfs s;
63 /* default display is kilobytes */
64 const char *disp_units_hdr = "1k-blocks";
65 int cnt = 0;
66 printf("Filesystem %-15sUsed Available Use%% Mounted on\n",
67 disp_units_hdr);
68
69 mount_table = NULL;
70 mount_table = setmntent("/etc/mtab", "r");
71 lua_newtable(L);
72 while (1) {
73 const char *device;
74 const char *mount_point;
75
76 if (mount_table) {
77 mount_entry = getmntent(mount_table);
78 if (!mount_entry) {
79 endmntent(mount_table);
80 break;
81 }
82 }
83
84 device = mount_entry->mnt_fsname;
85 mount_point = mount_entry->mnt_dir;
86
87 if (statfs(mount_point, &s) != 0) {
88 perror(mount_point);
89 continue;
90 }
91
92 if ((s.f_blocks > 0) || !mount_table)
93 {
94 blocks_used = s.f_blocks - s.f_bfree;
95 blocks_percent_used = 0;
96 if (blocks_used + s.f_bavail)
97 {
98 blocks_percent_used = (blocks_used * 100ULL + (blocks_used + s.f_bavail) / 2 )
99 / (blocks_used + s.f_bavail);
100 }
101 lua_pushinteger(L, ++cnt);
102 lua_newtable(L);
103
104 add_table_entry_int(L, "blocks", kscale(s.f_blocks, s.f_bsize));
105 add_table_entry_int(L, "used", kscale(s.f_blocks-s.f_bfree, s.f_bsize));
106 add_table_entry_int(L, "avail", kscale(s.f_bavail, s.f_bsize));
107 add_table_entry_int(L, "percent", blocks_percent_used);
108 add_table_entry(L, "device", device);
109 add_table_entry(L, "mountpoint", mount_point);
110 add_table_entry_int(L, "blocksize", s.f_bsize);
111 lua_settable(L, -3);
112
113 /*printf("\n%-20s" + 1, device)
114 printf(" %9lu %9lu %9lu %3u%% %s\n",
115 kscale(s.f_blocks, s.f_bsize),
116 kscale(s.f_blocks-s.f_bfree, s.f_bsize),
117 kscale(s.f_bavail, s.f_bsize),
118 blocks_percent_used, mount_point);*/
119 }
120 }
121 return 1;
122 }