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 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 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 84 static char *skip_over_blanks(char *cp) 85 { 86 while (*cp && isspace(*cp)) 87 cp++; 88 return cp; 89 } 90 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 */ 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 }