1 /* 2 * mountopts.c --- convert between default mount options and strings 3 * 4 * Copyright (C) 2002 Theodore Ts'o <tytso (at) 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 <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <ctype.h> 16 #include <errno.h> 17 18 #include "e2p.h" 19 20 struct mntopt { 21 unsigned int mask; 22 const char *string; 23 }; 24 25 static 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 { EXT4_DEFM_NOBARRIER, "nobarrier" }, 35 { EXT4_DEFM_BLOCK_VALIDITY, "block_validity" }, 36 { EXT4_DEFM_DISCARD, "discard"}, 37 { EXT4_DEFM_NODELALLOC, "nodelalloc"}, 38 { 0, 0 }, 39 }; 40 41 const char *e2p_mntopt2string(unsigned int mask) 42 { 43 struct mntopt *f; 44 static char buf[20]; 45 int fnum; 46 47 for (f = mntopt_list; f->string; f++) { 48 if (mask == f->mask) 49 return f->string; 50 } 51 for (fnum = 0; mask >>= 1; fnum++); 52 sprintf(buf, "MNTOPT_%d", fnum); 53 return buf; 54 } 55 56 int e2p_string2mntopt(char *string, unsigned int *mask) 57 { 58 struct mntopt *f; 59 char *eptr; 60 int num; 61 62 for (f = mntopt_list; f->string; f++) { 63 if (!strcasecmp(string, f->string)) { 64 *mask = f->mask; 65 return 0; 66 } 67 } 68 if (strncasecmp(string, "MNTOPT_", 8)) 69 return 1; 70 71 if (string[8] == 0) 72 return 1; 73 num = strtol(string+8, &eptr, 10); 74 if (num > 32 || num < 0) 75 return 1; 76 if (*eptr) 77 return 1; 78 *mask = 1 << num; 79 return 0; 80 } 81 82 static char *skip_over_blanks(char *cp) 83 { 84 while (*cp && isspace(*cp)) 85 cp++; 86 return cp; 87 } 88 89 static char *skip_over_word(char *cp) 90 { 91 while (*cp && !isspace(*cp) && *cp != ',') 92 cp++; 93 return cp; 94 } 95 96 /* 97 * Edit a mntopt set array as requested by the user. The ok 98 * parameter, if non-zero, allows the application to limit what 99 * mntopts the user is allowed to set or clear using this function. 100 */ 101 int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok) 102 { 103 char *cp, *buf, *next; 104 int neg; 105 unsigned int mask; 106 int rc = 0; 107 108 buf = malloc(strlen(str)+1); 109 if (!buf) 110 return 1; 111 strcpy(buf, str); 112 cp = buf; 113 while (cp && *cp) { 114 neg = 0; 115 cp = skip_over_blanks(cp); 116 next = skip_over_word(cp); 117 if (*next == 0) 118 next = 0; 119 else 120 *next = 0; 121 switch (*cp) { 122 case '-': 123 case '^': 124 neg++; 125 case '+': 126 cp++; 127 break; 128 } 129 if (e2p_string2mntopt(cp, &mask)) { 130 rc = 1; 131 break; 132 } 133 if (ok && !(ok & mask)) { 134 rc = 1; 135 break; 136 } 137 if (mask & EXT3_DEFM_JMODE) 138 *mntopts &= ~EXT3_DEFM_JMODE; 139 if (neg) 140 *mntopts &= ~mask; 141 else 142 *mntopts |= mask; 143 cp = next ? next+1 : 0; 144 } 145 free(buf); 146 return rc; 147 } 148