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