libexplain  1.4.D001
libexplain/buffer/mount_flags.c
Go to the documentation of this file.
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 : */