libexplain  1.4.D001
libexplain/buffer/stat_mode.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009-2011, 2013 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/stat.h>
00020 
00021 #include <libexplain/buffer/stat_mode.h>
00022 #include <libexplain/buffer/pointer.h>
00023 #include <libexplain/option.h>
00024 #include <libexplain/is_efault.h>
00025 #include <libexplain/parse_bits.h>
00026 #include <libexplain/sizeof.h>
00027 
00028 
00029 static const explain_parse_bits_table_t hi_table[] =
00030 {
00031     { "S_IFREG", S_IFREG },
00032     { "S_IFBLK", S_IFBLK },
00033     { "S_IFCHR", S_IFCHR },
00034     { "S_IFDIR", S_IFDIR },
00035 #ifdef S_IFCMP
00036     { "S_IFCMP", S_IFCMP },
00037 #endif
00038 #ifdef S_IFDOOR
00039     { "S_IFDOOR", S_IFDOOR },
00040 #endif
00041 #ifdef S_IFIFO
00042     { "S_IFIFO", S_IFIFO },
00043 #endif
00044 #ifdef S_IFLNK
00045     { "S_IFLNK", S_IFLNK },
00046 #endif
00047 #ifdef S_IFMPB
00048     { "S_IFMPB", S_IFMPB },
00049 #endif
00050 #ifdef S_IFMPC
00051     { "S_IFMPC", S_IFMPC },
00052 #endif
00053 #ifdef S_IFNAM
00054     { "S_IFNAM", S_IFNAM },
00055 #endif
00056 #ifdef S_IFNWK
00057     { "S_IFNWK", S_IFNWK },
00058 #endif
00059 #ifdef S_IFSOCK
00060     { "S_IFSOCK", S_IFSOCK },
00061 #endif
00062 #ifdef S_IFWHT
00063     { "S_IFWHT", S_IFWHT },
00064 #endif
00065 };
00066 
00067 static const explain_parse_bits_table_t lo_table_short[] =
00068 {
00069     { "S_ISUID", S_ISUID },
00070     { "S_ISGID", S_ISGID },
00071     { "S_ISVTX", S_ISVTX },
00072 };
00073 
00074 static const explain_parse_bits_table_t lo_table_long[] =
00075 {
00076     { "S_ISUID", S_ISUID },
00077     { "S_ISGID", S_ISGID },
00078     { "S_ISVTX", S_ISVTX },
00079     { "S_IRWXU", S_IRWXU },
00080     { "S_IRUSR", S_IRUSR },
00081     { "S_IWUSR", S_IWUSR },
00082     { "S_IXUSR", S_IXUSR },
00083     { "S_IRWXG", S_IRWXG },
00084     { "S_IRGRP", S_IRGRP },
00085     { "S_IWGRP", S_IWGRP },
00086     { "S_IXGRP", S_IXGRP },
00087     { "S_IRWXO", S_IRWXO },
00088     { "S_IROTH", S_IROTH },
00089     { "S_IWOTH", S_IWOTH },
00090     { "S_IXOTH", S_IXOTH },
00091 };
00092 
00093 
00094 void
00095 explain_buffer_stat_mode(explain_string_buffer_t *sb, mode_t mode)
00096 {
00097     const explain_parse_bits_table_t *lo_table;
00098     const explain_parse_bits_table_t *tp;
00099     int             first;
00100 
00101     if (mode == 0)
00102     {
00103         explain_string_buffer_putc(sb, '0');
00104         return;
00105     }
00106     first = 1;
00107     for (tp = hi_table; tp < ENDOF(hi_table); ++tp)
00108     {
00109         if (tp->value == (int)(mode & S_IFMT))
00110         {
00111             explain_string_buffer_puts(sb, tp->name);
00112             first = 0;
00113             mode -= tp->value;
00114             break;
00115         }
00116     }
00117 
00118     lo_table = lo_table_short;
00119     if (explain_option_symbolic_mode_bits())
00120     {
00121         lo_table = lo_table_long;
00122     }
00123     for (tp = lo_table; tp < ENDOF(lo_table); ++tp)
00124     {
00125         if (tp->value != 0 && (int)(mode & tp->value) == tp->value)
00126         {
00127             if (!first)
00128                 explain_string_buffer_puts(sb, " | ");
00129             explain_string_buffer_puts(sb, tp->name);
00130             first = 0;
00131             mode -= tp->value;
00132         }
00133     }
00134     if (mode != 0)
00135     {
00136         if (!first)
00137             explain_string_buffer_puts(sb, " | ");
00138         explain_string_buffer_printf(sb, "%#o", (int)mode);
00139     }
00140 }
00141 
00142 
00143 static const explain_parse_bits_table_t full_table[] =
00144 {
00145     { "S_IFREG", S_IFREG },
00146     { "S_IFBLK", S_IFBLK },
00147     { "S_IFCHR", S_IFCHR },
00148     { "S_IFDIR", S_IFDIR },
00149 #ifdef S_IFCMP
00150     { "S_IFCMP", S_IFCMP },
00151 #endif
00152 #ifdef S_IFDOOR
00153     { "S_IFDOOR", S_IFDOOR },
00154 #endif
00155 #ifdef S_IFIFO
00156     { "S_IFIFO", S_IFIFO },
00157 #endif
00158 #ifdef S_IFLNK
00159     { "S_IFLNK", S_IFLNK },
00160 #endif
00161 #ifdef S_IFMPB
00162     { "S_IFMPB", S_IFMPB },
00163 #endif
00164 #ifdef S_IFMPC
00165     { "S_IFMPC", S_IFMPC },
00166 #endif
00167 #ifdef S_IFNAM
00168     { "S_IFNAM", S_IFNAM },
00169 #endif
00170 #ifdef S_IFNWK
00171     { "S_IFNWK", S_IFNWK },
00172 #endif
00173 #ifdef S_IFSOCK
00174     { "S_IFSOCK", S_IFSOCK },
00175 #endif
00176 #ifdef S_IFWHT
00177     { "S_IFWHT", S_IFWHT },
00178 #endif
00179     { "S_IFMT", S_IFMT },
00180     { "S_ISUID", S_ISUID },
00181     { "S_ISGID", S_ISGID },
00182     { "S_ISVTX", S_ISVTX },
00183     { "S_IRWXU", S_IRWXU },
00184     { "S_IRUSR", S_IRUSR },
00185     { "S_IWUSR", S_IWUSR },
00186     { "S_IXUSR", S_IXUSR },
00187     { "S_IRWXG", S_IRWXG },
00188     { "S_IRGRP", S_IRGRP },
00189     { "S_IWGRP", S_IWGRP },
00190     { "S_IXGRP", S_IXGRP },
00191     { "S_IRWXO", S_IRWXO },
00192     { "S_IROTH", S_IROTH },
00193     { "S_IWOTH", S_IWOTH },
00194     { "S_IXOTH", S_IXOTH },
00195 };
00196 
00197 
00198 int
00199 explain_parse_stat_mode_or_die(const char *text, const char *caption)
00200 {
00201     return
00202         explain_parse_bits_or_die
00203         (
00204             text,
00205             full_table,
00206             SIZEOF(full_table),
00207             caption
00208         );
00209 }
00210 
00211 
00212 /* vim: set ts=8 sw=4 et : */