libexplain  1.4.D001
libexplain/ac/mntent.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/ctype.h>
00021 #include <libexplain/ac/mntent.h>
00022 #include <libexplain/ac/stdlib.h>
00023 
00024 #include <libexplain/gcc_attributes.h>
00025 
00026 
00027 #ifdef HAVE_GETMNTINFO
00028 #include <stdio.h>
00029 #include <sys/mount.h>
00030 
00031 /* FreeBSD, and probably others */
00032 
00033 static struct statfs *data;
00034 static int      data_size;
00035 static int      data_pos;
00036 
00037 
00038 FILE *
00039 setmntent(const char *filename, const char *mode)
00040 {
00041     static FILE junk;
00042 
00043     (void)filename;
00044     (void)mode;
00045     int flags = 0; /* do not hang on broken mounts */
00046     data_size = getmntinfo(&data, flags);
00047     data_pos = 0;
00048     return &junk;
00049 }
00050 
00051 
00052 struct mntent *
00053 getmntent(FILE *fp)
00054 {
00055     static struct mntent fudge;
00056     struct statfs   *p;
00057 
00058     (void)fp;
00059     if (data_pos >= data_size)
00060         return 0;
00061     p = data + data_pos++;
00062     fudge.mnt_fsname = p->f_mntfromname;
00063     fudge.mnt_dir = p->f_mntonname;
00064     fudge.mnt_type = p->f_fstypename;
00065     fudge.mnt_opts = "";
00066     fudge.mnt_freq = 0;
00067     fudge.mnt_passno = 0;
00068     return &fudge;
00069 }
00070 
00071 
00072 int
00073 endmntent(FILE *fp)
00074 {
00075     (void)fp;
00076     data = 0;
00077     data_size = 0;
00078     data_pos = 0;
00079     return 0;
00080 }
00081 
00082 #elif !defined(HAVE_SETMNTENT) && \
00083       !defined(HAVE_GETMNTENT) && \
00084       !defined(HAVE_ENDMNTENT)
00085 
00086 
00087 typedef struct bogus_t bogus_t;
00088 struct bogus_t
00089 {
00090     FILE            *fp;
00091     char            line[1000];
00092     struct mntent   data;
00093 };
00094 
00095 
00096 LIBEXPLAIN_LINKAGE_HIDDEN
00097 FILE *
00098 setmntent(const char *filename, const char *mode)
00099 {
00100     bogus_t         *bp;
00101 
00102     bp = malloc(sizeof(bogus_t));
00103     if (!bp)
00104         return 0;
00105     bp->fp = fopen(filename, mode);
00106     return (FILE *)bp;
00107 }
00108 
00109 
00110 LIBEXPLAIN_LINKAGE_HIDDEN
00111 struct mntent *
00112 getmntent(FILE *p)
00113 {
00114     bogus_t         *bp;
00115 
00116     if (!p)
00117         return 0;
00118     bp = (bogus_t *)p;
00119     if (!bp->fp)
00120         return 0;
00121 
00122     for (;;)
00123     {
00124         char            *lp;
00125         int             ac;
00126         char            *av[6];
00127 
00128         if (!fgets(bp->line, sizeof(bp->line), bp->fp))
00129             return 0;
00130         lp = bp->line;
00131         ac = 0;
00132         while (ac < 6)
00133         {
00134             if (!*lp)
00135                 break;
00136             if (isspace((unsigned char)*lp))
00137             {
00138                 ++lp;
00139                 continue;
00140             }
00141             if (*lp == '#')
00142             {
00143                 while (*lp)
00144                     ++lp;
00145                 break;
00146             }
00147             av[ac++] = lp;
00148             while (*lp && !isspace((unsigned char)*lp))
00149                 ++lp;
00150             if (!*lp)
00151                 break;
00152             *lp++ = '\0';
00153         }
00154         if (ac < 2)
00155             continue;
00156         while (ac < 6)
00157             av[ac++] = lp;
00158         bp->data.mnt_fsname = av[0];
00159 #ifdef __solaris__
00160         bp->data.mnt_dir = av[2];
00161         bp->data.mnt_type = av[3];
00162         bp->data.mnt_opts = av[4];
00163         bp->data.mnt_freq = 0;
00164         bp->data.mnt_passno = 0;
00165 #else
00166         bp->data.mnt_dir = av[1];
00167         bp->data.mnt_type = av[2];
00168         bp->data.mnt_opts = av[3];
00169         bp->data.mnt_freq = atoi(av[4]);
00170         bp->data.mnt_passno = atoi(av[5]);
00171 #endif
00172         return &bp->data;
00173     }
00174 }
00175 
00176 
00177 LIBEXPLAIN_LINKAGE_HIDDEN
00178 int
00179 endmntent(FILE *p)
00180 {
00181     if (p)
00182     {
00183         bogus_t         *bp;
00184 
00185         bp = (bogus_t *)p;
00186         if (bp->fp)
00187         {
00188             fclose(bp->fp);
00189             bp->fp = 0;
00190         }
00191         free(bp);
00192     }
00193     return 0;
00194 }
00195 
00196 #endif /* HAVE_MNTENT_H */
00197 
00198 #ifndef HAVE_HASMNTOPT
00199 
00200 #include <libexplain/ac/string.h>
00201 
00202 LIBEXPLAIN_LINKAGE_HIDDEN
00203 char *
00204 hasmntopt(const struct mntent *mnt, const char *opt)
00205 {
00206     const char      *cp;
00207     size_t          opt_len;
00208 
00209     opt_len = strlen(opt);
00210     cp = mnt->mnt_opts;
00211     for (;;)
00212     {
00213         unsigned char   c;
00214         const char      *start;
00215         const char      *end;
00216         size_t          len;
00217 
00218         c = *cp;
00219         if (!cp)
00220             return 0;
00221         if (isspace(c) || c == ',')
00222         {
00223             ++cp;
00224             continue;
00225         }
00226         start = cp;
00227         for (;;)
00228         {
00229             ++cp;
00230             c = *cp;
00231             if (!c || isspace(c) || c == ',')
00232                 break;
00233         }
00234         end = cp;
00235         len = end - start;
00236         if
00237         (
00238             opt_len < len
00239         &&
00240             start[opt_len] == '='
00241         &&
00242             0 == memcmp(opt, start, opt_len)
00243         )
00244             return (char *)start;
00245         if (opt_len == len && 0 == memcmp(opt, start, opt_len))
00246             return (char *)start;
00247     }
00248 }
00249 
00250 #endif
00251 
00252 
00253 /* vim: set ts=8 sw=4 et : */