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