• 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  * 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 
e2p_mntopt2string(unsigned int mask)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 
e2p_string2mntopt(char * string,unsigned int * mask)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 
skip_over_blanks(char * cp)77 static char *skip_over_blanks(char *cp)
78 {
79 	while (*cp && isspace(*cp))
80 		cp++;
81 	return cp;
82 }
83 
skip_over_word(char * cp)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  */
e2p_edit_mntopts(const char * str,__u32 * mntopts,__u32 ok)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 }
143