1/* vi: set sw=4 ts=4: */ 2/* 3 * mountopts.c --- convert between default mount options and strings 4 * 5 * Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu> 6 * 7 * This file can be redistributed under the terms of the GNU Library General 8 * Public License 9 * 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 20struct mntopt { 21 unsigned int mask; 22 const char *string; 23}; 24 25static const 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 { 0, 0 }, 35}; 36 37const char *e2p_mntopt2string(unsigned int mask) 38{ 39 const struct mntopt *f; 40 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{ 54 const struct mntopt *f; 55 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 103 buf = xstrdup(str); 104 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} 135