libexplain
1.4.D001
|
00001 /* 00002 * libexplain - a library of system-call-specific strerror replacements 00003 * Copyright (C) 2013, 2014 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU Lesser General Public License as 00007 * published by the Free Software Foundation; either version 3 of the 00008 * License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/sys/mount.h> 00020 00021 #include <libexplain/buffer/mount_flags.h> 00022 #include <libexplain/parse_bits.h> 00023 00024 00025 static const explain_parse_bits_table_t table[] = 00026 { 00027 #ifdef MS_RDONLY 00028 { "MS_RDONLY", MS_RDONLY }, 00029 #endif 00030 #ifdef ST_RDONLY 00031 { "ST_RDONLY", MT_RDONLY }, /* POSIX */ 00032 #endif 00033 #ifdef MS_NOSUID 00034 { "MS_NOSUID", MS_NOSUID }, 00035 #endif 00036 #ifdef ST_NOSUID 00037 { "ST_NOSUID", ST_NOSUID } /* POSIX */ 00038 #endif 00039 #ifdef MS_NODEV 00040 { "MS_NODEV", MS_NODEV }, 00041 #endif 00042 #ifdef MS_NOEXEC 00043 { "MS_NOEXEC", MS_NOEXEC }, 00044 #endif 00045 #ifdef MS_SYNCHRONOUS 00046 { "MS_SYNCHRONOUS", MS_SYNCHRONOUS }, 00047 #endif 00048 #ifdef MS_SYNC 00049 { "MS_SYNC", MS_SYNCHRONOUS }, /* histortical, ambiguous */ 00050 #endif 00051 #ifdef MS_REMOUNT 00052 { "MS_REMOUNT", MS_REMOUNT }, 00053 #endif 00054 #ifdef MS_MANDLOCK 00055 { "MS_MANDLOCK", MS_MANDLOCK }, 00056 #endif 00057 #ifdef MS_DIRSYNC 00058 { "MS_DIRSYNC", MS_DIRSYNC }, 00059 #endif 00060 #ifdef MS_NOATIME 00061 { "MS_NOATIME", MS_NOATIME }, 00062 #endif 00063 #ifdef MS_NODIRATIME 00064 { "MS_NODIRATIME", MS_NODIRATIME }, 00065 #endif 00066 #ifdef MS_BIND 00067 { "MS_BIND", MS_BIND }, 00068 #endif 00069 #ifdef HAVE_SYS_MOUNT_MS_MOVE 00070 { "MS_MOVE", MS_MOVE }, 00071 #endif 00072 #ifdef MS_REC 00073 { "MS_REC", MS_REC }, 00074 #endif 00075 #ifdef MS_SILENT 00076 { "MS_SILENT", MS_SILENT }, 00077 #endif 00078 #ifdef MS_POSIXACL 00079 { "MS_POSIXACL", MS_POSIXACL }, 00080 #endif 00081 #ifdef MS_UNBINDABLE 00082 { "MS_UNBINDABLE", MS_UNBINDABLE }, 00083 #endif 00084 #ifdef MS_PRIVATE 00085 { "MS_PRIVATE", MS_PRIVATE }, 00086 #endif 00087 #ifdef MS_SLAVE 00088 { "MS_SLAVE", MS_SLAVE }, 00089 #endif 00090 #ifdef MS_SHARED 00091 { "MS_SHARED", MS_SHARED }, 00092 #endif 00093 #ifdef MS_RELATIME 00094 { "MS_RELATIME", MS_RELATIME }, 00095 #endif 00096 #ifdef MS_KERNMOUNT 00097 { "MS_KERNMOUNT", MS_KERNMOUNT }, 00098 #endif 00099 #ifdef MS_I_VERSION 00100 { "MS_I_VERSION", MS_I_VERSION }, 00101 #endif 00102 #ifdef MS_STRICTATIME 00103 { "MS_STRICTATIME", MS_STRICTATIME }, 00104 #endif 00105 #ifdef MS_NOSEC 00106 { "MS_NOSEC", MS_NOSEC }, 00107 #endif 00108 #ifdef MS_BORN 00109 { "MS_BORN", MS_BORN }, 00110 #endif 00111 #ifdef MS_ACTIVE 00112 { "MS_ACTIVE", MS_ACTIVE }, 00113 #endif 00114 #ifdef MS_NOUSER 00115 { "MS_NOUSER", MS_NOUSER }, 00116 #endif 00117 #ifdef MS_VERBOSE 00118 { "MS_VERBOSE", MS_VERBOSE }, 00119 #endif 00120 00121 #ifdef MS_MGC_VAL 00122 { "MS_MGC_VAL", MS_MGC_VAL }, 00123 #endif 00124 #ifdef MS_MGC_MSK 00125 { "MS_MGC_MSK", MS_MGC_MSK }, 00126 #endif 00127 #ifdef MS_RMT_MASK 00128 { "MS_RMT_MASK", MS_RMT_MASK }, 00129 #endif 00130 }; 00131 00132 00133 void 00134 explain_buffer_mount_flags(explain_string_buffer_t *sb, unsigned long flags) 00135 { 00136 unsigned long other; 00137 int first; 00138 00139 /* 00140 * Discard magic: 00141 * 00142 * Linux kernel 3.2 :: fs/namespace.c circa line2316 00143 * 00144 * Pre-0.97 versions of mount() didn't have a flags word. When 00145 * the flags word was introduced its top half was required to have 00146 * the magic value 0xC0ED, and this remained so until 2.4.0-test9. 00147 * Therefore, if this magic number is present, it carries no 00148 * information and must be discarded. 00149 */ 00150 first = 1; 00151 #ifdef MS_MGC_MSK 00152 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 00153 { 00154 flags &= ~MS_MGC_MSK; 00155 explain_string_buffer_puts(sb, "MS_MGC_VAL"); 00156 if (!flags) 00157 return; 00158 first = 0; 00159 } 00160 else 00161 #endif 00162 if (flags == 0) 00163 { 00164 explain_string_buffer_putc(sb, '0'); 00165 return; 00166 } 00167 00168 other = 0; 00169 for (;;) 00170 { 00171 int bit; 00172 const explain_parse_bits_table_t *tp; 00173 00174 bit = (flags & -flags); 00175 flags &= ~bit; 00176 tp = explain_parse_bits_find_by_value(bit, table, SIZEOF(table)); 00177 if (tp) 00178 { 00179 if (!first) 00180 explain_string_buffer_puts(sb, " | "); 00181 explain_string_buffer_puts(sb, tp->name); 00182 first = 0; 00183 } 00184 else 00185 other |= bit; 00186 if (!flags) 00187 break; 00188 } 00189 if (other) 00190 { 00191 /* Linux kernel sources use hex, so we will */ 00192 if (!first) 00193 explain_string_buffer_puts(sb, " | "); 00194 explain_string_buffer_printf(sb, "0x%lX", other); 00195 first = 0; 00196 } 00197 } 00198 00199 00200 unsigned long 00201 explain_parse_mount_flags_or_die(const char *text, const char *caption) 00202 { 00203 return explain_parse_bits_or_die(text, table, SIZEOF(table), caption); 00204 } 00205 00206 00207 /* vim: set ts=8 sw=4 et : */