From 8b95253ff0f99b0d94b32bd663f5a54f732b0034 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 7 Dec 2010 00:09:40 +0100 Subject: [PATCH] libmount: add mntent.h compatible stuff Signed-off-by: Karel Zak --- shlibs/mount/src/fs.c | 109 +++++++++++++++++++++++++++++++----- shlibs/mount/src/mount.h.in | 4 ++ shlibs/mount/src/mount.sym | 2 + 3 files changed, 100 insertions(+), 15 deletions(-) diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c index 30dabed7..bcc53762 100644 --- a/shlibs/mount/src/fs.c +++ b/shlibs/mount/src/fs.c @@ -63,20 +63,36 @@ void mnt_free_fs(mnt_fs *fs) free(fs); } -static inline int cpy_str_item(void *new, const void *old, size_t offset) +static inline int cpy_str(char **dest, const char *src) { - char **o = (char **) (old + offset); - char **n = (char **) (new + offset); + size_t sz; + char *x; + + assert(dest); - if (!*o) + if (!src) { + free(*dest); + *dest = NULL; return 0; /* source (old) is empty */ + } - *n = strdup(*o); - if (!*n) + sz = strlen(src) + 1; + x = realloc(*dest, sz); + if (!x) return -ENOMEM; + *dest = x; + memcpy(*dest, src, sz); return 0; } +static inline int cpy_str_at_offset(void *new, const void *old, size_t offset) +{ + char **o = (char **) (old + offset); + char **n = (char **) (new + offset); + + return cpy_str(n, *o); +} + /** * mnt_copy_fs: * @fs: source FS @@ -97,23 +113,23 @@ mnt_fs *mnt_copy_fs(const mnt_fs *fs) n->parent = fs->parent; n->devno = fs->devno; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, source))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, source))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, tagname))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, tagname))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, tagval))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, tagval))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, root))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, root))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, target))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, target))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, fstype))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fstype))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, optstr))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, optstr))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, vfs_optstr))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, vfs_optstr))) goto err; - if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, fs_optstr))) + if (cpy_str_at_offset(n, fs, offsetof(struct _mnt_fs, fs_optstr))) goto err; n->freq = fs->freq; n->passno = fs->passno; @@ -922,3 +938,66 @@ int mnt_fs_print_debug(mnt_fs *fs, FILE *file) minor(mnt_fs_get_devno(fs))); return 0; } + +/** + * mnt_free_mntent: + * @mnt: mount entry + * + * Deallocates "mntent.h" mount entry. + */ +void mnt_free_mntent(struct mntent *mnt) +{ + if (mnt) { + free(mnt->mnt_fsname); + free(mnt->mnt_dir); + free(mnt->mnt_type); + free(mnt->mnt_opts); + free(mnt); + } +} + +/** + * mnt_fs_to_mntent: + * @fs: filesystem + * @mnt: mount description (as described in mntent.h) + * + * Copies information from @fs to struct mntent @mnt. If @mnt is already set + * then the struct mntent items are reallocated and updated. See also + * mnt_free_mntent(). + * + * Returns: 0 on success and negative number in case of error. + */ +int mnt_fs_to_mntent(mnt_fs *fs, struct mntent **mnt) +{ + int rc; + struct mntent *m; + + if (!fs || !mnt) + return -EINVAL; + + m = *mnt; + if (!m) { + m = calloc(1, sizeof(*m)); + if (!m) + return -ENOMEM; + } + + if ((rc = cpy_str(&m->mnt_fsname, mnt_fs_get_source(fs)))) + goto err; + if ((rc = cpy_str(&m->mnt_dir, mnt_fs_get_target(fs)))) + goto err; + if ((rc = cpy_str(&m->mnt_type, mnt_fs_get_fstype(fs)))) + goto err; + if ((rc = cpy_str(&m->mnt_opts, mnt_fs_get_optstr(fs)))) + goto err; + m->mnt_freq = mnt_fs_get_freq(fs); + m->mnt_passno = mnt_fs_get_passno(fs); + + *mnt = m; + + return 0; +err: + if (m != *mnt) + mnt_free_mntent(m); + return rc; +} diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in index 74cdf0e7..081cfe59 100644 --- a/shlibs/mount/src/mount.h.in +++ b/shlibs/mount/src/mount.h.in @@ -30,6 +30,7 @@ extern "C" { #endif #include +#include #define LIBMOUNT_VERSION "@LIBMOUNT_VERSION@" @@ -246,6 +247,9 @@ extern int mnt_fs_match_fstype(mnt_fs *fs, const char *types); extern int mnt_fs_match_options(mnt_fs *fs, const char *options); extern int mnt_fs_print_debug(mnt_fs *ent, FILE *file); +extern void mnt_free_mntent(struct mntent *mnt); +extern int mnt_fs_to_mntent(mnt_fs *fs, struct mntent **mnt); + /* tab-parse.c */ extern mnt_tab *mnt_new_tab_from_file(const char *filename); extern mnt_tab *mnt_new_tab_from_dir(const char *dirname); diff --git a/shlibs/mount/src/mount.sym b/shlibs/mount/src/mount.sym index 2db74df3..07259d27 100644 --- a/shlibs/mount/src/mount.sym +++ b/shlibs/mount/src/mount.sym @@ -130,6 +130,8 @@ global: mnt_update_set_old_target; mnt_update_get_format; mnt_update_get_filename; + mnt_fs_to_mntent; + mnt_free_mntent; local: *; }; -- 2.39.5