blob: 5db363e29ac76112f83d399a48da6d3aeb41fe50 [file] [log] [blame]
Theodore Ts'oa0c3fd52002-10-15 17:43:43 -04001/*
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
19struct mntopt {
20 unsigned int mask;
21 const char *string;
22};
23
24static 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 { 0, 0 },
31};
32
33const char *e2p_mntopt2string(int compat, unsigned int mask)
34{
35 struct mntopt *f;
36 static char buf[20];
37 int fnum;
38
39 for (f = mntopt_list; f->string; f++) {
40 if (mask == f->mask)
41 return f->string;
42 }
43 for (fnum = 0; mask >>= 1; fnum++);
44 sprintf(buf, "MNTOPT_%d", fnum);
45 return buf;
46}
47
48int e2p_string2mntopt(char *string, unsigned int *mask)
49{
50 struct mntopt *f;
51 char *eptr;
52 int num;
53
54 for (f = mntopt_list; f->string; f++) {
55 if (!strcasecmp(string, f->string)) {
56 *mask = f->mask;
57 return 0;
58 }
59 }
60 if (strncasecmp(string, "MNTOPT_", 8))
61 return 1;
62
63 if (string[8] == 0)
64 return 1;
65 num = strtol(string+8, &eptr, 10);
66 if (num > 32 || num < 0)
67 return 1;
68 if (*eptr)
69 return 1;
70 *mask = 1 << num;
71 return 0;
72}
73
74static char *skip_over_blanks(char *cp)
75{
76 while (*cp && isspace(*cp))
77 cp++;
78 return cp;
79}
80
81static char *skip_over_word(char *cp)
82{
83 while (*cp && !isspace(*cp) && *cp != ',')
84 cp++;
85 return cp;
86}
87
88/*
89 * Edit a mntopt set array as requested by the user. The ok
90 * parameter, if non-zero, allows the application to limit what
91 * mntopts the user is allowed to set or clear using this function.
92 */
93int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok)
94{
95 char *cp, *buf, *next;
96 int neg;
97 unsigned int mask;
98
99 buf = malloc(strlen(str)+1);
100 if (!buf)
101 return 1;
102 strcpy(buf, str);
103 cp = buf;
104 while (cp && *cp) {
105 neg = 0;
106 cp = skip_over_blanks(cp);
107 next = skip_over_word(cp);
108 if (*next == 0)
109 next = 0;
110 else
111 *next = 0;
112 switch (*cp) {
113 case '-':
114 case '^':
115 neg++;
116 case '+':
117 cp++;
118 break;
119 }
120 if (e2p_string2mntopt(cp, &mask))
121 return 1;
122 if (ok && !(ok & mask))
123 return 1;
124 if (neg)
125 *mntopts &= ~mask;
126 else
127 *mntopts |= mask;
128 cp = next ? next+1 : 0;
129 }
130 return 0;
131}