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