OSDN Git Service

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