Initial public busybox upstream commit
[busybox4maemo] / e2fsprogs / old_e2fsprogs / e2p / mntopts.c
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 }