]> err.no Git - util-linux/commitdiff
libmount: add mnt_entry
authorKarel Zak <kzak@redhat.com>
Tue, 12 Jan 2010 12:43:07 +0000 (13:43 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 3 Jun 2010 13:20:10 +0000 (15:20 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/Makefile.am
shlibs/mount/src/fs.c [new file with mode: 0644]
shlibs/mount/src/mount.h.in
shlibs/mount/src/mountP.h

index 5cba0da9d46b695d95cfa613baa41f5e68b5734e..de265c9d57f1d03aac2ccc614d87153bd191f129 100644 (file)
@@ -13,6 +13,7 @@ libmount_la_SOURCES = $(mountinc_HEADERS)
 
 nodist_libmount_la_SOURCES = mount.h version.c utils.c test.c init.c cache.c \
                        optstr.c optmap.c optent.c optls.c iter.c list.h lock.c \
+                       fs.c \
                        $(top_srcdir)/lib/canonicalize.c
 
 libmount_la_LIBADD = $(ul_libblkid_la)
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c
new file mode 100644 (file)
index 0000000..0e12052
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ * The mnt_fs is representation of one line in a fstab / mtab / mountinfo.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <blkid/blkid.h>
+
+#include "nls.h"
+#include "mountP.h"
+
+/**
+ * mnt_new_fs:
+ *
+ * Returns newly allocated mnt_file fs.
+ */
+mnt_fs *mnt_new_fs(void)
+{
+       mnt_fs *fs = calloc(1, sizeof(struct _mnt_fs));
+       if (!fs)
+               return NULL;
+
+       INIT_LIST_HEAD(&fs->ents);
+       return fs;
+}
+
+/**
+ * mnt_free_fs:
+ * @fs: fs pointer
+ *
+ * Deallocates the fs.
+ */
+void mnt_free_fs(mnt_fs *fs)
+{
+       if (!fs)
+               return;
+       list_del(&fs->ents);
+
+       free(fs->source);
+       free(fs->tagname);
+       free(fs->tagval);
+       free(fs->mntroot);
+       free(fs->target);
+       free(fs->fstype);
+       free(fs->optstr);
+       free(fs->vfs_optstr);
+       free(fs->fs_optstr);
+
+       free(fs);
+}
+
+/**
+ * mnt_fs_get_srcpath:
+ * @fs: mnt_file (fstab/mtab/mountinfo) fs
+ *
+ * The mount "source path" is:
+ *     - a directory for 'bind' mounts (in fstab or mtab only)
+ *     - a device name for standard mounts
+ *     - NULL when path is not set (for example when TAG
+ *       (LABEL/UUID) is defined)
+ *
+ * See also mnt_fs_get_tag() and mnt_fs_get_source().
+ *
+ * Returns mount "source" path or NULL in case of error or when the path
+ * is not defined.
+ *
+ */
+const char *mnt_fs_get_srcpath(mnt_fs *fs)
+{
+       assert(fs);
+       if (!fs)
+               return NULL;
+
+       /* fstab-like fs */
+       if (fs->tagname)
+               return NULL;    /* the source contains a "NAME=value" */
+       return fs->source;
+}
+
+/**
+ * @fs: mnt_file (fstab/mtab/mountinfo) fs
+ *
+ * Returns mount "source". Note that the source could be unparsed TAG
+ * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
+ */
+const char *mnt_fs_get_source(mnt_fs *fs)
+{
+       return fs ? fs->source : NULL;
+}
+
+/* Used by parser mnt_file ONLY (@source has to be allocated) */
+int __mnt_fs_set_source(mnt_fs *fs, char *source)
+{
+       assert(fs);
+
+       if (!source)
+               return -1;
+
+       if (strchr(source, '=')) {
+               char *name, *val;
+
+               if (blkid_parse_tag_string(source, &name, &val) != 0)
+                       return -1;
+
+               fs->tagval = val;
+               fs->tagname = name;
+       }
+
+       fs->source = source;
+       return 0;
+}
+
+/**
+ * mnt_fs_set_source:
+ * @fs: fstab/mtab/mountinfo entry
+ * @source: new source
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_source(mnt_fs *fs, const char *source)
+{
+       char *p;
+
+       if (!fs && !source)
+               return -1;
+
+       p = strdup(source);
+       if (!p)
+               return -1;
+
+       free(fs->tagval);
+       free(fs->tagname);
+       free(fs->source);
+       fs->tagval = fs->tagname = fs->source = NULL;
+
+       return __mnt_fs_set_source(fs, p);
+}
+
+/**
+ * mnt_fs_get_tag:
+ * @fs: fs
+ * @name: returns pointer to NAME string
+ * @value: returns pointer to VALUE string
+ *
+ * "TAG" is NAME=VALUE (e.g. LABEL=foo)
+ *
+ * The TAG is the first column in the fstab file. The TAG
+ * or "srcpath" has to be always set for all entries.
+ *
+ * See also mnt_fs_get_source().
+ *
+ * Example:
+ *     char *src;
+ *     mnt_fs *fs = mnt_file_find_target(mf, "/home");
+ *
+ *     if (!fs)
+ *             goto err;
+ *
+ *     src = mnt_fs_get_srcpath(fs);
+ *     if (!src) {
+ *             char *tag, *val;
+ *             if (mnt_fs_get_tag(fs, &tag, &val) == 0)
+ *                     printf("%s: %s\n", tag, val);   // LABEL or UUID
+ *     } else
+ *             printf("device: %s\n", src);            // device or bind path
+ *
+ * Returns 0 on success or -1 in case that a TAG is not defined.
+ */
+int mnt_fs_get_tag(mnt_fs *fs, const char **name, const char **value)
+{
+       if (fs == NULL || !fs->tagname)
+               return -1;
+       if (name)
+               *name = fs->tagname;
+       if (value)
+               *value = fs->tagval;
+       return 0;
+}
+
+/**
+ * mnt_fs_get_target:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to mountpoint path or NULL
+ */
+const char *mnt_fs_get_target(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->target : NULL;
+}
+
+/**
+ * mnt_fs_set_target:
+ * @fs: fstab/mtab/mountinfo entry
+ * @target: mountpoint
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_target(mnt_fs *fs, const char *target)
+{
+       char *p;
+
+       assert(fs);
+
+       if (!fs || !target)
+               return -1;
+
+       p = strdup(target);
+       if (!p)
+               return -1;
+       free(fs->target);
+       fs->target = p;
+
+       return 0;
+}
+
+/**
+ * mnt_fs_get_fstype:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to filesystem type.
+ */
+const char *mnt_fs_get_fstype(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->fstype : NULL;
+}
+
+/* Used by mnt_file parser only */
+int __mnt_fs_set_fstype(mnt_fs *fs, char *fstype)
+{
+       assert(fs);
+
+       if (!fstype)
+               return -1;
+
+       fs->fstype = fstype;
+       fs->flags &= ~MNT_FS_PSEUDO;
+       fs->flags &= ~MNT_FS_NET;
+
+       /* save info about pseudo filesystems */
+       if (mnt_fstype_is_pseudofs(fs->fstype))
+               fs->flags |= MNT_FS_PSEUDO;
+       else if (mnt_fstype_is_netfs(fs->fstype))
+               fs->flags |= MNT_FS_NET;
+
+       return 0;
+}
+
+/**
+ * mnt_fs_set_fstype:
+ * @fs: fstab/mtab/mountinfo entry
+ * @fstype: filesystem type
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_fstype(mnt_fs *fs, const char *fstype)
+{
+       char *p;
+
+       if (!fs || !fstype)
+               return -1;
+
+       p = strdup(fstype);
+       if (!p)
+               return -1;
+       free(fs->fstype);
+
+       return __mnt_fs_set_fstype(fs, p);
+}
+
+/**
+ * mnt_fs_get_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to mount option string with all options (FS and VFS)
+ */
+const char *mnt_fs_get_optstr(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_optstr:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_optstr(mnt_fs *fs, const char *optstr)
+{
+       assert(fs);
+
+       if (!fs || !optstr)
+               return -1;
+       free(fs->optstr);
+       free(fs->fs_optstr);
+       free(fs->vfs_optstr);
+       fs->fs_optstr = fs->vfs_optstr = NULL;
+
+       fs->optstr = strdup(optstr);
+
+       return fs->optstr ? 0 : -1;
+}
+
+/**
+ * mnt_fs_get_fs_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * This function works for "mountinfo" files only.
+ *
+ * Returns pointer to superblock (fs-depend) mount option string or NULL.
+ */
+const char *mnt_fs_get_fs_optstr(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->fs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_get_vfs_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * This function works for "mountinfo" files only.
+ *
+ * Returns pointer to fs-independent (VFS) mount option string or NULL.
+ */
+const char *mnt_fs_get_vfs_optstr(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->vfs_optstr : NULL;
+}
+
+
+/**
+ * mnt_fs_get_freq:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns "dump frequency in days".
+ */
+int mnt_fs_get_freq(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->freq : 0;
+}
+
+/**
+ * mnt_fs_set_freq:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @freq: dump frequency in days
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_freq(mnt_fs *fs, int freq)
+{
+       assert(fs);
+
+       if (!fs)
+               return -1;
+       fs->freq = freq;
+       return 0;
+}
+
+/**
+ * mnt_fs_get_passno:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns "pass number on parallel fsck".
+ */
+int mnt_fs_get_passno(mnt_fs *fs)
+{
+       assert(fs);
+       return fs ? fs->passno: 0;
+}
+
+/**
+ * mnt_fs_set_passno:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @passno: pass number
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_passno(mnt_fs *fs, int passno)
+{
+       assert(fs);
+
+       if (!fs)
+               return -1;
+       fs->passno = passno;
+       return 0;
+}
+
+/**
+ * mnt_fs_get_option:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @name: option name
+ * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
+ * @valsz: returns size of options value or 0
+ *
+ * Returns 0 on success, 1 when not found the @name or -1 in case of error.
+ */
+int mnt_fs_get_option(mnt_fs *fs, const char *name,
+               char **value, size_t *valsz)
+{
+       char *optstr = (char *) mnt_fs_get_optstr(fs);
+       return optstr ? mnt_optstr_get_option(optstr, name, value, valsz) : 1;
+}
+
+
+/* Unfortunately the classical Unix /etc/mtab and /etc/fstab
+   do not handle directory names containing spaces.
+   Here we mangle them, replacing a space by \040.
+   What do other Unices do? */
+
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static char *mangle(const char *s)
+{
+       char *ss, *sp;
+       int n;
+
+       n = strlen(s);
+       ss = sp = malloc(4*n+1);
+       if (!sp)
+               return NULL;
+       while(1) {
+               for (n = 0; n < sizeof(need_escaping); n++) {
+                       if (*s == need_escaping[n]) {
+                               *sp++ = '\\';
+                               *sp++ = '0' + ((*s & 0300) >> 6);
+                               *sp++ = '0' + ((*s & 070) >> 3);
+                               *sp++ = '0' + (*s & 07);
+                               goto next;
+                       }
+               }
+               *sp++ = *s;
+               if (*s == 0)
+                       break;
+       next:
+               s++;
+       }
+       return ss;
+}
+
+/**
+ * mnt_fprintf_line:
+ * @f: FILE
+ * @fmt: printf-like format string (see MNT_MFILE_PRINTFMT)
+ * @source: (spec) device name or tag=value
+ * @target: mountpoint
+ * @fstype: filesystem type
+ * @options: mount options
+ * @freq: dump frequency in days
+ * @passno: pass number on parallel fsck
+ *
+ * Returns return value from fprintf().
+ */
+int mnt_fprintf_line(  FILE *f,
+                       const char *fmt,
+                       const char *source,
+                       const char *target,
+                       const char *fstype,
+                       const char *options,
+                       int freq,
+                       int passno)
+{
+       char *m1 = NULL, *m2 = NULL, *m3 = NULL, *m4 = NULL;
+       int rc = -1;
+
+       if (!f || !fmt || !source || !target || !fstype || !options)
+               return -1;
+
+       m1 = mangle(source);
+       m2 = mangle(target);
+       m3 = mangle(fstype);
+       m4 = mangle(options);
+
+       if (!m1 || !m2 || !m3 || !m4)
+               goto done;
+
+       rc = fprintf(f, fmt, m1, m2, m3, m4, freq, passno);
+done:
+       free(m1);
+       free(m2);
+       free(m3);
+       free(m4);
+
+       return rc;
+}
+
+/**
+ * mnt_fs_fprintf:
+ * @fs: fstab/mtab/mountinfo entry
+ * @f: FILE
+ * @fmt: printf-like format string (see MNT_MFILE_PRINTFMT)
+ *
+ * Returns return value from fprintf().
+ */
+int mnt_fs_fprintf(mnt_fs *fs, FILE *f, const char *fmt)
+{
+       assert(fs);
+       assert(f);
+       assert(fmt);
+
+       if (!fs || !f)
+               return -1;
+
+       return mnt_fprintf_line(f, fmt,
+                       mnt_fs_get_source(fs),
+                       mnt_fs_get_target(fs),
+                       mnt_fs_get_fstype(fs),
+                       mnt_fs_get_optstr(fs),
+                       mnt_fs_get_freq(fs),
+                       mnt_fs_get_passno(fs));
+}
+
+/**
+ * mnt_fs_print_debug
+ * @fs: fstab/mtab/mountinfo entry
+ * @file: output
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
+{
+       if (!fs)
+               return -1;
+       fprintf(file, "------ fs: %p\n", fs);
+       fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
+       fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
+       fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs));
+       fprintf(file, "optstr: %s\n", mnt_fs_get_optstr(fs));
+       fprintf(file, "freq:   %d\n", mnt_fs_get_freq(fs));
+       fprintf(file, "pass:   %d\n", mnt_fs_get_passno(fs));
+
+       return 0;
+}
index 05912e1123e3018ba473dbedef7caf2321345a42..0c3f80bfb7ec5ab8872d0523f8bf609ee2ff6de8 100644 (file)
@@ -88,6 +88,14 @@ struct mnt_optmap
 #define MNT_INVERT     (1 << 3) /* invert the mountflag */
 #define MNT_NOMTAB     (1 << 4) /* skip in the mtab option string */
 
+/**
+ * mnt_fs:
+ *
+ * Parsed fstab/mtab/mountinfo entry
+ */
+typedef struct _mnt_fs mnt_fs;
+
+
 /* version.c */
 extern int mnt_parse_version_string(const char *ver_string);
 extern int mnt_get_library_version(const char **ver_string);
@@ -191,6 +199,43 @@ extern const char *mnt_lock_get_linkfile(mnt_lock *ml);
 extern void mnt_unlock_file(mnt_lock *ml);
 extern int mnt_lock_file(mnt_lock *ml);
 
+/* fs.c */
+extern mnt_fs *mnt_new_fs(void);
+extern void mnt_free_fs(mnt_fs *ent);
+extern const char *mnt_fs_get_source(mnt_fs *ent);
+extern int mnt_fs_set_source(mnt_fs *ent, const char *source);
+extern const char *mnt_fs_get_srcpath(mnt_fs *ent);
+extern int mnt_fs_get_tag(mnt_fs *ent, const char **name, const char **value);
+extern const char *mnt_fs_get_target(mnt_fs *ent);
+extern int mnt_fs_set_target(mnt_fs *ent, const char *target);
+extern const char *mnt_fs_get_fstype(mnt_fs *ent);
+extern int mnt_fs_set_fstype(mnt_fs *ent, const char *fstype);
+extern const char *mnt_fs_get_optstr(mnt_fs *ent);
+extern int mnt_fs_set_optstr(mnt_fs *ent, const char *optstr);
+extern const char *mnt_fs_get_optfs(mnt_fs *ent);
+extern const char *mnt_fs_get_optvfs(mnt_fs *ent);
+extern int mnt_fs_get_freq(mnt_fs *ent);
+extern int mnt_fs_set_freq(mnt_fs *ent, int freq);
+extern int mnt_fs_get_passno(mnt_fs *ent);
+extern int mnt_fs_set_passno(mnt_fs *ent, int passno);
+extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
+                               char **value, size_t *valsz);
+
+/* mtab/fstab line */
+#define MNT_MFILE_PRINTFMT     "%s %s %s %s %d %d\n"
+
+extern int mnt_fprintf_line(
+                        FILE *f,
+                        const char *fmt,
+                        const char *source,
+                        const char *target,
+                        const char *fstype,
+                        const char *options,
+                        int freq,
+                        int passno);
+
+extern int mnt_fs_fprintf(mnt_fs *ent, FILE *f, const char *fmt);
+extern int mnt_fs_print_debug(mnt_fs *ent, FILE *file);
 
 /*
  * mount(8) userspace options masks (MNT_MAP_USERSPACE map)
index 82c557b4e9655a9889097b2d48b9c4a6f1155d86..b6eb8cd3432116fb0e31f9638cec2b864c3ff95d 100644 (file)
@@ -126,6 +126,42 @@ struct _mnt_optls {
        struct list_head        opts;   /* list of options */
 };
 
+/*
+ * This struct represents one entry in mtab/fstab/mountinfo file.
+ */
+struct _mnt_fs {
+       struct list_head ents;
+
+       int             id;             /* mountinfo[1]: ID */
+       int             parent;         /* moutninfo[2]: parent */
+
+       char            *source;        /* fstab[1]: mountinfo[10]:
+                                         * source dev, file, dir or TAG */
+       char            *tagname;       /* fstab[1]: tag name - "LABEL", "UUID", ..*/
+       char            *tagval;        /*           tag value */
+
+       char            *mntroot;       /* mountinfo[4]: root of the mount within the FS */
+       char            *target;        /* mountinfo[5], fstab[2]: mountpoint */
+       char            *fstype;        /* mountinfo[9], fstab[3]: filesystem type */
+
+       char            *optstr;        /* mountinfo[6,11], fstab[4]: option string */
+       char            *vfs_optstr;    /* mountinfo[6]: fs-independent (VFS) options */
+       char            *fs_optstr;     /* mountinfo[11]: fs-depend options */
+
+       int             freq;           /* fstab[5]:  dump frequency in days */
+       int             passno;         /* fstab[6]: pass number on parallel fsck */
+
+       int             flags;          /* MNT_ENTRY_* flags */
+       int             lineno;         /* line number in the parental file */
+};
+
+/*
+ * fs flags
+ */
+#define MNT_FS_ERROR   (1 << 1) /* broken entry */
+#define MNT_FS_PSEUDO  (1 << 2) /* pseudo filesystem */
+#define MNT_FS_NET     (1 << 3) /* network filesystem */
+
 /* optmap.c */
 extern const struct mnt_optmap *mnt_optmap_get_entry(struct mnt_optmap const **maps,
                              int nmaps, const char *name,
@@ -149,5 +185,8 @@ extern mnt_optent *mnt_new_optent_from_optstr(char **optstr,
 extern int mnt_optent_assign_map(mnt_optent *op,
                                struct mnt_optmap const **maps, int nmaps);
 
+/* fs.c */
+extern int __mnt_fs_set_source(mnt_fs *fs, char *source);
+extern int __mnt_fs_set_fstype(mnt_fs *fs, char *fstype);
 
 #endif /* _LIBMOUNT_PRIVATE_H */