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