1#
2# Copyright (C) Stanislaw Adaszewski, 2020
3# License: GNU General Public License v3.0
4# URL: https://github.com/sadaszewski/focker
5# URL: https://adared.ch/focker
6#
7
8from ctypes import Structure, \
9    c_uint32, \
10    c_uint64, \
11    c_int64, \
12    c_int, \
13    c_char, \
14    CDLL, \
15    POINTER, \
16    ARRAY, \
17    byref
18from ctypes.util import find_library
19import re
20
21with open('/usr/include/sys/mount.h', 'r') as f:
22    rx = re.compile('[ \t]')
23    lines = f.read().split('\n')
24    lines = [ a.strip() for a in lines \
25        if list(filter(lambda b: b, rx.split(a))) [:2] == \
26            [ '#define', 'MNAMELEN'] ]
27    MNAMELEN = int(rx.split(lines[0])[2])
28    # print('MNAMELEN:', MNAMELEN)
29    #line = list(filter(lambda a: \
30    #    list(filter(lambda b: b, rx.split(a), a)[:2]) == \
31    #        ['#define', 'MNAMELEN'], f.read().split('\n')))
32    #line[0]
33
34MFSNAMELEN = 16
35# MNAMELEN = 1024
36
37
38class statfs(Structure):
39    pass
40
41
42statfs._fields_ = [
43    ('f_version', c_uint32),
44    ('f_type', c_uint32),
45    ('f_flags', c_uint64),
46    ('f_bsize', c_uint64),
47    ('f_iosize', c_uint64),
48    ('f_blocks', c_uint64),
49    ('f_bfree', c_uint64),
50    ('f_bavail', c_int64),
51    ('f_files', c_uint64),
52    ('f_ffree', c_int64),
53    ('f_syncwrites', c_uint64),
54    ('f_asyncwrites', c_uint64),
55    ('f_syncreads', c_uint64),
56    ('f_asyncreads', c_uint64),
57    ('f_spare', ARRAY(c_uint64, 10)),
58    ('f_namemax', c_uint32),
59    ('f_owner', c_uint32),
60    ('f_fsid', ARRAY(c_uint32, 2)),
61    ('f_charspare', ARRAY(c_char, 80)),
62    ('f_fstypename', ARRAY(c_char, MFSNAMELEN)),
63    ('f_mntfromname', ARRAY(c_char, MNAMELEN)),
64    ('f_mntonname', ARRAY(c_char, MNAMELEN))
65]
66
67libc = CDLL(find_library('c'))
68
69def getdict(struct):
70    return dict((field, getattr(struct, field)) for field, _ in struct._fields_)
71
72_getmntinfo = libc.getmntinfo
73_getmntinfo.argtypes = [ POINTER(POINTER(statfs)), c_int ]
74
75def getmntinfo():
76    p = POINTER(statfs)()
77    n = _getmntinfo(byref(p), c_int(1))
78    res = [ getdict(p[i]) for i in range(n) ]
79    return res
80