xref: /aosp_15_r20/external/e2fsprogs/lib/e2p/mntopts.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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