libexplain  1.4.D001
libexplain/buffer/erofs.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2008-2010, 2013 Peter Miller
00004  * Written by Peter Miller <pmiller@opensource.org.au>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as
00008  * published by the Free Software Foundation; either version 3 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <libexplain/ac/sys/types.h> /* must be first */
00021 #include <libexplain/ac/linux/cdrom.h>
00022 #include <libexplain/ac/linux/fd.h>
00023 #include <libexplain/ac/linux/major.h>
00024 #include <libexplain/ac/linux/kdev_t.h>
00025 #include <libexplain/ac/sys/ioctl.h>
00026 #include <libexplain/ac/sys/mtio.h>
00027 #include <libexplain/ac/unistd.h> /* for ioctl() on Solaris */
00028 
00029 #include <libexplain/buffer/erofs.h>
00030 #include <libexplain/buffer/gettext.h>
00031 #include <libexplain/buffer/mount_point.h>
00032 
00033 
00034 static void
00035 explain_buffer_erofs_generic(explain_string_buffer_t *sb, const char *caption)
00036 {
00037     explain_string_buffer_printf_gettext
00038     (
00039         sb,
00040         /*
00041          * xgettext:  This error message is ised to explain an EROFS error,
00042          * usually from an open(2) system call.
00043          *
00044          * %1$s => The name of the offending system call argument
00045          */
00046         i18n("write access was requested and %s refers to a file on a "
00047             "read-only file system"),
00048         caption
00049     );
00050 }
00051 
00052 
00053 static void
00054 explain_buffer_erofs_generic_dev(explain_string_buffer_t *sb,
00055     const char *caption)
00056 {
00057     explain_string_buffer_printf_gettext
00058     (
00059         sb,
00060         /*
00061          * xgettext:  This error message is ised to explain an EROFS error,
00062          * usually from an open(2) system call, in the case where write access
00063          * was requested for a read-only device.
00064          *
00065          * %1$s => The name of the offending system call argument
00066          */
00067         i18n("write access was requested and %s refers to a read-only "
00068             "device"),
00069         caption
00070     );
00071 }
00072 
00073 
00074 void
00075 explain_buffer_erofs(explain_string_buffer_t *sb, const char *pathname,
00076     const char *caption)
00077 {
00078     struct stat     st;
00079 
00080     if (stat(pathname, &st) >= 0)
00081     {
00082         switch (st.st_mode & S_IFMT)
00083         {
00084         case S_IFBLK:
00085         case S_IFCHR:
00086             explain_buffer_erofs_generic_dev(sb, caption);
00087             return;
00088 
00089         default:
00090             break;
00091         }
00092     }
00093 
00094     explain_buffer_erofs_generic(sb, caption);
00095     if (explain_buffer_mount_point(sb, pathname) < 0)
00096         explain_buffer_mount_point_dirname(sb, pathname);
00097 }
00098 
00099 
00100 void
00101 explain_buffer_erofs_fildes(explain_string_buffer_t *sb, int fildes,
00102     const char *caption)
00103 {
00104 #ifdef CDROM_GET_CAPABILITY
00105     {
00106         int             cap;
00107 
00108         cap = 0;
00109         if (ioctl(fildes, CDROM_GET_CAPABILITY, &cap) >= 0)
00110         {
00111             /*
00112              * Device is a CD-ROM drive, or similar.
00113              *
00114              * Remember: in English it's is a "disc" with-a-C when it's
00115              * a CD or a DVD (blame the French, it started out as their
00116              * standard), and it's a "disk" with-a-K in every other case.
00117              */
00118             explain_buffer_gettext
00119             (
00120                 sb,
00121                 /*
00122                  * xgettext:  This error message is issued to explain an
00123                  * EROFS error, in the case of a CD-ROM disc (or similar).
00124                  */
00125                 i18n("the disc cannot be written to")
00126             );
00127             return;
00128         }
00129     }
00130 #endif
00131 
00132 #ifdef FDGETDRVTYP
00133     {
00134         floppy_drive_name fdt;
00135 
00136         if (ioctl(fildes, FDGETDRVTYP, &fdt) >= 0)
00137         {
00138             explain_buffer_gettext
00139             (
00140                 sb,
00141                 /*
00142                  * xgettext:  This error message is issued to explain an EROFS
00143                  * error, in the case of a floppy disk (or similar).
00144                  */
00145                 i18n("the disk has the write-protect tab set")
00146             );
00147             return;
00148         }
00149     }
00150 #endif
00151 
00152 #ifdef MTIOCGET
00153     {
00154         struct mtget    status;
00155 
00156         if (ioctl(fildes, MTIOCGET, &status) >= 0)
00157         {
00158             explain_buffer_gettext
00159             (
00160                 sb,
00161                 /*
00162                  * xgettext:  This error message is issued to explain an EROFS
00163                  * error, in the case of a magnetic tape (or similar).
00164                  */
00165                 i18n("the tape has the write-protect tab set")
00166             );
00167             return;
00168         }
00169     }
00170 #endif
00171 
00172     /* check for devices */
00173     {
00174         struct stat     st;
00175 
00176         if (fstat(fildes, &st) >= 0)
00177         {
00178             switch (st.st_mode & S_IFMT)
00179             {
00180             case S_IFBLK:
00181 #ifdef MMC_BLOCK_MAJOR
00182                 /*
00183                  * Somewhat bizarrely, SD/MMC driver defines *no* ioctls.
00184                  */
00185                 if (MAJOR(st.st_rdev) == MMC_BLOCK_MAJOR)
00186                 {
00187                     explain_buffer_gettext
00188                     (
00189                         sb,
00190                         /*
00191                          * xgettext:  This error message is issued to explain
00192                          * an EROFS error, in the case of a Secure Disk /
00193                          * Multimedia Card.
00194                          */
00195                         i18n("the SD/MMC card has the write-protect tab set")
00196                     );
00197                     return;
00198                 }
00199 #endif
00200                 /* fall through... */
00201 
00202             case S_IFCHR:
00203                 explain_buffer_erofs_generic_dev(sb, caption);
00204                 return;
00205 
00206             default:
00207                 break;
00208             }
00209         }
00210     }
00211 
00212     explain_buffer_erofs_generic(sb, caption);
00213     explain_buffer_mount_point_fd(sb, fildes);
00214 }
00215 
00216 
00217 /* vim: set ts=8 sw=4 et : */