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