Whamcloud - gitweb
libe2p, libext2fs: Update file copyright permission states to match COPYING
[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 <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 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         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         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         int     rc = 0;
103
104         buf = malloc(strlen(str)+1);
105         if (!buf)
106                 return 1;
107         strcpy(buf, str);
108         cp = buf;
109         while (cp && *cp) {
110                 neg = 0;
111                 cp = skip_over_blanks(cp);
112                 next = skip_over_word(cp);
113                 if (*next == 0)
114                         next = 0;
115                 else
116                         *next = 0;
117                 switch (*cp) {
118                 case '-':
119                 case '^':
120                         neg++;
121                 case '+':
122                         cp++;
123                         break;
124                 }
125                 if (e2p_string2mntopt(cp, &mask)) {
126                         rc = 1;
127                         break;
128                 }
129                 if (ok && !(ok & mask)) {
130                         rc = 1;
131                         break;
132                 }
133                 if (mask & EXT3_DEFM_JMODE)
134                         *mntopts &= ~EXT3_DEFM_JMODE;
135                 if (neg)
136                         *mntopts &= ~mask;
137                 else
138                         *mntopts |= mask;
139                 cp = next ? next+1 : 0;
140         }
141         free(buf);
142         return rc;
143 }