mount.c (3571B) download
1#include "mount.h"
2
3#include <stdbool.h>
4#include <string.h>
5#include <sys/mount.h>
6
7
8const mount_option_t mount_options[] = {
9 { "ro", MS_RDONLY, false }, /* read-only */
10 { "rw", MS_RDONLY, true }, /* read-write */
11 { "exec", MS_NOEXEC, true }, /* permit execution of binaries */
12 { "noexec", MS_NOEXEC, false }, /* don't execute binaries */
13 { "suid", MS_NOSUID, true }, /* honor suid executables */
14 { "nosuid", MS_NOSUID, false }, /* don't honor suid executables */
15 { "dev", MS_NODEV, true }, /* interpret device files */
16 { "nodev", MS_NODEV, false }, /* don't interpret devices */
17
18 { "sync", MS_SYNCHRONOUS, false }, /* synchronous I/O */
19 { "async", MS_SYNCHRONOUS, true }, /* asynchronous I/O */
20
21 { "dirsync", MS_DIRSYNC, false }, /* synchronous directory modifications */
22 { "remount", MS_REMOUNT, true }, /* alter flags of mounted FS */
23 { "bind", MS_BIND, false }, /* Remount part of the tree elsewhere */
24 { "rbind", MS_BIND | MS_REC, false }, /* Idem, plus mounted subtrees */
25#ifdef MS_NOSUB
26 { "sub", MS_NOSUB, MNT_INVERT }, /* allow submounts */
27 { "nosub", MS_NOSUB }, /* don't allow submounts */
28#endif
29#ifdef MS_SILENT
30 { "silent", MS_SILENT, false }, /* be quiet */
31 { "loud", MS_SILENT, true }, /* print out messages. */
32#endif
33#ifdef MS_MANDLOCK
34 { "mand", MS_MANDLOCK, false }, /* Allow mandatory locks on this FS */
35 { "nomand", MS_MANDLOCK, true }, /* Forbid mandatory locks on this FS */
36#endif
37#ifdef MS_NOATIME
38 { "atime", MS_NOATIME, true }, /* Update access time */
39 { "noatime", MS_NOATIME, false }, /* Do not update access time */
40#endif
41#ifdef MS_I_VERSION
42 { "iversion", MS_I_VERSION, false }, /* Update inode I_version time */
43 { "noiversion", MS_I_VERSION, true }, /* Don't update inode I_version time */
44#endif
45#ifdef MS_NODIRATIME
46 { "diratime", MS_NODIRATIME, true }, /* Update dir access times */
47 { "nodiratime", MS_NODIRATIME, false }, /* Do not update dir access times */
48#endif
49#ifdef MS_RELATIME
50 { "relatime", MS_RELATIME, false }, /* Update access times relative to mtime/ctime */
51 { "norelatime", MS_RELATIME, true }, /* Update access time without regard to mtime/ctime */
52#endif
53#ifdef MS_STRICTATIME
54 { "strictatime", MS_STRICTATIME, false }, /* Strict atime semantics */
55 { "nostrictatime", MS_STRICTATIME, true }, /* kernel default atime */
56#endif
57#ifdef MS_LAZYTIME
58 { "lazytime", MS_LAZYTIME, false }, /* Update {a,m,c}time on the in-memory inode only */
59 { "nolazytime", MS_LAZYTIME, true },
60#endif
61#ifdef MS_NOSYMFOLLOW
62 { "symfollow", MS_NOSYMFOLLOW, true }, /* Don't follow symlinks */
63 { "nosymfollow", MS_NOSYMFOLLOW, false },
64#endif
65 { 0 }
66};
67
68int mount_flags(const char* options, const char** dest_ptr) {
69 int flags = 0;
70
71 char option[20];
72 char dest[strlen(options) + 1];
73 int option_size = 0;
74 int dest_size = 0;
75
76 while (1) {
77 if (*options == ',' || *options == '\0') {
78 option[option_size] = '\0';
79
80 for (const mount_option_t* flg = mount_options; flg->name != NULL; flg++) {
81 if (strcmp(flg->name, option) == 0) {
82 if (flg->invert)
83 flags &= ~flg->flags;
84 else
85 flags |= flg->flags;
86 option_size = 0;
87 break;
88 }
89 }
90
91 if (option_size > 0) {
92 if (dest_size > 0)
93 dest[dest_size++] = ',';
94 memcpy(dest + dest_size, option, option_size);
95 dest_size += option_size;
96 option_size = 0;
97 }
98
99 if (*options == '\0')
100 break;
101 } else {
102 option[option_size++] = *options;
103 }
104
105 options++;
106 }
107
108 if (dest_size > 0) {
109 dest[dest_size] = '\0';
110 *dest_ptr = strdup(dest);
111 } else {
112 *dest_ptr = NULL;
113 }
114
115 return flags;
116}