blob: 17c26c480b0b19d7b9d7f4fe8491022570485ee6
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * mountopts.c --- convert between default mount options and strings |
4 | * |
5 | * Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu> |
6 | * |
7 | * This file can be redistributed under the terms of the GNU Library General |
8 | * Public License |
9 | * |
10 | */ |
11 | |
12 | #include <stdio.h> |
13 | #include <stdlib.h> |
14 | #include <string.h> |
15 | #include <ctype.h> |
16 | #include <errno.h> |
17 | |
18 | #include "e2p.h" |
19 | |
20 | struct mntopt { |
21 | unsigned int mask; |
22 | const char *string; |
23 | }; |
24 | |
25 | static const struct mntopt mntopt_list[] = { |
26 | { EXT2_DEFM_DEBUG, "debug" }, |
27 | { EXT2_DEFM_BSDGROUPS, "bsdgroups" }, |
28 | { EXT2_DEFM_XATTR_USER, "user_xattr" }, |
29 | { EXT2_DEFM_ACL, "acl" }, |
30 | { EXT2_DEFM_UID16, "uid16" }, |
31 | { EXT3_DEFM_JMODE_DATA, "journal_data" }, |
32 | { EXT3_DEFM_JMODE_ORDERED, "journal_data_ordered" }, |
33 | { EXT3_DEFM_JMODE_WBACK, "journal_data_writeback" }, |
34 | { 0, 0 }, |
35 | }; |
36 | |
37 | const char *e2p_mntopt2string(unsigned int mask) |
38 | { |
39 | const struct mntopt *f; |
40 | static char buf[20]; |
41 | int fnum; |
42 | |
43 | for (f = mntopt_list; f->string; f++) { |
44 | if (mask == f->mask) |
45 | return f->string; |
46 | } |
47 | for (fnum = 0; mask >>= 1; fnum++); |
48 | sprintf(buf, "MNTOPT_%d", fnum); |
49 | return buf; |
50 | } |
51 | |
52 | int e2p_string2mntopt(char *string, unsigned int *mask) |
53 | { |
54 | const struct mntopt *f; |
55 | char *eptr; |
56 | int num; |
57 | |
58 | for (f = mntopt_list; f->string; f++) { |
59 | if (!strcasecmp(string, f->string)) { |
60 | *mask = f->mask; |
61 | return 0; |
62 | } |
63 | } |
64 | if (strncasecmp(string, "MNTOPT_", 8)) |
65 | return 1; |
66 | |
67 | if (string[8] == 0) |
68 | return 1; |
69 | num = strtol(string+8, &eptr, 10); |
70 | if (num > 32 || num < 0) |
71 | return 1; |
72 | if (*eptr) |
73 | return 1; |
74 | *mask = 1 << num; |
75 | return 0; |
76 | } |
77 | |
78 | static char *skip_over_blanks(char *cp) |
79 | { |
80 | while (*cp && isspace(*cp)) |
81 | cp++; |
82 | return cp; |
83 | } |
84 | |
85 | static char *skip_over_word(char *cp) |
86 | { |
87 | while (*cp && !isspace(*cp) && *cp != ',') |
88 | cp++; |
89 | return cp; |
90 | } |
91 | |
92 | /* |
93 | * Edit a mntopt set array as requested by the user. The ok |
94 | * parameter, if non-zero, allows the application to limit what |
95 | * mntopts the user is allowed to set or clear using this function. |
96 | */ |
97 | int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok) |
98 | { |
99 | char *cp, *buf, *next; |
100 | int neg; |
101 | unsigned int mask; |
102 | |
103 | buf = xstrdup(str); |
104 | cp = buf; |
105 | while (cp && *cp) { |
106 | neg = 0; |
107 | cp = skip_over_blanks(cp); |
108 | next = skip_over_word(cp); |
109 | if (*next == 0) |
110 | next = 0; |
111 | else |
112 | *next = 0; |
113 | switch (*cp) { |
114 | case '-': |
115 | case '^': |
116 | neg++; |
117 | case '+': |
118 | cp++; |
119 | break; |
120 | } |
121 | if (e2p_string2mntopt(cp, &mask)) |
122 | return 1; |
123 | if (ok && !(ok & mask)) |
124 | return 1; |
125 | if (mask & EXT3_DEFM_JMODE) |
126 | *mntopts &= ~EXT3_DEFM_JMODE; |
127 | if (neg) |
128 | *mntopts &= ~mask; |
129 | else |
130 | *mntopts |= mask; |
131 | cp = next ? next+1 : 0; |
132 | } |
133 | return 0; |
134 | } |
135 |