blob: 17c26c480b0b19d7b9d7f4fe8491022570485ee6 [file] [log] [blame]
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00001/* vi: set sw=4 ts=4: */
Mike Frysingerd89e6292005-04-24 05:07:59 +00002/*
3 * mountopts.c --- convert between default mount options and strings
Tim Rikerc1ef7bd2006-01-25 00:08:53 +00004 *
Mike Frysingerd89e6292005-04-24 05:07:59 +00005 * Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu>
Tim Rikerc1ef7bd2006-01-25 00:08:53 +00006 *
Mike Frysingerd89e6292005-04-24 05:07:59 +00007 * This file can be redistributed under the terms of the GNU Library General
8 * Public License
Tim Rikerc1ef7bd2006-01-25 00:08:53 +00009 *
Mike Frysingerd89e6292005-04-24 05:07:59 +000010 */
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
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +000025static const struct mntopt mntopt_list[] = {
Mike Frysingerd89e6292005-04-24 05:07:59 +000026 { 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{
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +000039 const struct mntopt *f;
Mike Frysingerd89e6292005-04-24 05:07:59 +000040 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{
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +000054 const struct mntopt *f;
Mike Frysingerd89e6292005-04-24 05:07:59 +000055 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
Rob Landleyd921b2e2006-08-03 15:41:12 +0000103 buf = xstrdup(str);
Mike Frysingerd89e6292005-04-24 05:07:59 +0000104 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}