diff options
| -rw-r--r-- | booster/src/Makefile.am | 2 | ||||
| -rw-r--r-- | booster/src/booster.c | 109 | ||||
| -rw-r--r-- | booster/src/booster_fstab.c | 415 | ||||
| -rw-r--r-- | booster/src/booster_fstab.h (renamed from libglusterfs/src/glusterfs_fstab.h) | 33 | ||||
| -rw-r--r-- | libglusterfs/src/Makefile.am | 4 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs_fstab.c | 309 | 
6 files changed, 436 insertions, 436 deletions
diff --git a/booster/src/Makefile.am b/booster/src/Makefile.am index 1b3be737e..50aaa6681 100644 --- a/booster/src/Makefile.am +++ b/booster/src/Makefile.am @@ -2,7 +2,7 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance  ldpreload_PROGRAMS = glusterfs-booster.so  ldpreloaddir = $(libdir)/glusterfs/ -glusterfs_booster_so_SOURCES = booster.c booster_stat.c +glusterfs_booster_so_SOURCES = booster.c booster_stat.c booster_fstab.c  glusterfs_booster_so_CFLAGS = -I$(top_srcdir)/libglusterfsclient/src/ -D_GNU_SOURCE -D$(GF_HOST_OS) -fPIC -Wall \  	-pthread $(GF_BOOSTER_CFLAGS)  glusterfs_booster_so_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE  \ diff --git a/booster/src/booster.c b/booster/src/booster.c index aeb4caa42..264d6772b 100644 --- a/booster/src/booster.c +++ b/booster/src/booster.c @@ -42,7 +42,6 @@  #include <dirent.h>  #include <sys/statfs.h>  #include <sys/statvfs.h> -#include <glusterfs_fstab.h>  #ifndef GF_UNIT_KB  #define GF_UNIT_KB 1024 @@ -224,6 +223,7 @@ typedef struct booster_mount_table booster_mount_table_t;  static fdtable_t *booster_glfs_fdtable = NULL;  static booster_mount_table_t *booster_mount_table = NULL; +extern int booster_configure (char *confpath);  /* This is dup'ed every time VMP open/creat wants a new fd.   * This is needed so we occupy an entry in the process' file   * table. @@ -239,113 +239,6 @@ booster_get_process_fd ()  #define DEFAULT_BOOSTER_CONF    CONFDIR"/booster.conf"  #define BOOSTER_CONF_ENV_VAR    "GLUSTERFS_BOOSTER_FSTAB" -void -clean_init_params (glusterfs_init_params_t *ipars) -{ -        if (!ipars) -                return; - -        if (ipars->volume_name) -                free (ipars->volume_name); - -        if (ipars->specfile) -                free (ipars->specfile); - -        if (ipars->logfile) -                free (ipars->logfile); - -        if (ipars->loglevel) -                free (ipars->loglevel); - -        return; -} - -char * -get_option_value (char *opt) -{ -        char *val = NULL; -        char *saveptr = NULL; -        char *copy_opt = NULL; -        char *retval = NULL; - -        copy_opt = strdup (opt); - -        /* Get the = before the value of the option. */ -        val = index (copy_opt, '='); -        if (val) { -                /* Move to start of option */ -                ++val; - -                /* Now, to create a '\0' delimited string out of the -                 * options string, first get the position where the -                 * next option starts, that would be the next ','. -                 */ -                saveptr = index (val, ','); -                if (saveptr) -                        *saveptr = '\0'; -                retval = strdup (val); -        } - -        free (copy_opt); - -        return retval; -} - -void -booster_mount (struct glusterfs_mntent *ent) -{ -        char                    *opt = NULL; -        glusterfs_init_params_t ipars; - -        if (!ent) -                return; - -        if ((strcmp (ent->mnt_type, "glusterfs") != 0)) -                return; - -        memset (&ipars, 0, sizeof (glusterfs_init_params_t)); -        if (ent->mnt_fsname) -                ipars.specfile = strdup (ent->mnt_fsname); - -        opt = glusterfs_fstab_hasoption (ent, "subvolume"); -        if (opt) -                ipars.volume_name = get_option_value (opt); - -        opt = glusterfs_fstab_hasoption (ent, "logfile"); -        if (opt) -                ipars.logfile = get_option_value (opt); - -        opt = glusterfs_fstab_hasoption (ent, "loglevel"); -        if (opt) -                ipars.loglevel = get_option_value (opt); - -        glusterfs_mount (ent->mnt_dir, &ipars); -        clean_init_params (&ipars); -} - -int -booster_configure (char *confpath) -{ -        int                     ret = -1; -        glusterfs_fstab_t       *handle = NULL; -        struct glusterfs_mntent *ent = NULL; - -        if (!confpath) -                goto out; - -        handle = glusterfs_fstab_init (confpath, "r"); -        if (!handle) -                goto out; - -        while ((ent = glusterfs_fstab_getent (handle)) != NULL) -                booster_mount (ent); - -        glusterfs_fstab_close (handle); -        ret = 0; -out: -        return ret; -} -  static int32_t   booster_put_handle (booster_mount_table_t *table,                      dev_t st_dev, diff --git a/booster/src/booster_fstab.c b/booster/src/booster_fstab.c new file mode 100644 index 000000000..dba785b5b --- /dev/null +++ b/booster/src/booster_fstab.c @@ -0,0 +1,415 @@ +/* Utilities for reading/writing fstab, mtab, etc. +   Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 +   Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <alloca.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include "booster_fstab.h" +#include <stdlib.h> +#include <libglusterfsclient.h> + +/* Prepare to begin reading and/or writing mount table entries from the +   beginning of FILE.  MODE is as for `fopen'.  */ +glusterfs_fstab_t * +glusterfs_fstab_init (const char *file, const char *mode) +{ +        glusterfs_fstab_t *handle = NULL; +        handle = calloc (1, sizeof (glusterfs_fstab_t)); +        if (!handle) +                goto out; + +        FILE *result = fopen (file,mode); +        if (result != NULL) { +                handle->fp = result; +        } else { +                free (handle); +                handle = NULL; +        } + +out: + +        return handle; +} + +int +glusterfs_fstab_close (glusterfs_fstab_t *h) +{ +        if (!h) +                return -1; + +        if (h->fp) +                fclose (h->fp); + +        return 0; +} + +/* Since the values in a line are separated by spaces, a name cannot +   contain a space.  Therefore some programs encode spaces in names +   by the strings "\040".  We undo the encoding when reading an entry. +   The decoding happens in place.  */ +static char * +decode_name (char *buf) +{ +        char *rp = buf; +        char *wp = buf; + +        do +                if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' +                                && rp[3] == '0') +                { +                        /* \040 is a SPACE.  */ +                        *wp++ = ' '; +                        rp += 3; +                } +                else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' +                                && rp[3] == '1') +                { +                        /* \011 is a TAB.  */ +                        *wp++ = '\t'; +                        rp += 3; +                } +                else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' +                                && rp[3] == '2') +                { +                        /* \012 is a NEWLINE.  */ +                        *wp++ = '\n'; +                        rp += 3; +                } +                else if (rp[0] == '\\' && rp[1] == '\\') +                { +                        /* We have to escape \\ to be able to represent all +                         * characters.  */ +                        *wp++ = '\\'; +                        rp += 1; +                } +                else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' +                                && rp[3] == '4') +                { +                        /* \134 is also \\.  */ +                        *wp++ = '\\'; +                        rp += 3; +                } +                else +                        *wp++ = *rp; +        while (*rp++ != '\0'); + +        return buf; +} + + +/* Read one mount table entry from STREAM.  Returns a pointer to storage +   reused on the next call, or null for EOF or error (use feof/ferror to +   check).  */ +struct glusterfs_mntent * +__glusterfs_fstab_getent (FILE *stream, struct glusterfs_mntent *mp, +                          char *buffer, int bufsiz) +{ +        char *cp; +        char *head; + +        do +        { +                char *end_ptr; + +                if (fgets (buffer, bufsiz, stream) == NULL) +                { +                        return NULL; +                } + +                end_ptr = strchr (buffer, '\n'); +                if (end_ptr != NULL)	/* chop newline */ +                        *end_ptr = '\0'; +                else +                { +                        /* Not the whole line was read.  Do it now but forget +                         * it.  */ +                        char tmp[1024]; +                        while (fgets (tmp, sizeof tmp, stream) != NULL) +                                if (strchr (tmp, '\n') != NULL) +                                        break; +                } + +                head = buffer + strspn (buffer, " \t"); +                /* skip empty lines and comment lines:  */ +        } +        while (head[0] == '\0' || head[0] == '#'); + +        cp = strsep (&head, " \t"); +        mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) ""; +        if (head) +                head += strspn (head, " \t"); +        cp = strsep (&head, " \t"); +        mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) ""; +        if (head) +                head += strspn (head, " \t"); +        cp = strsep (&head, " \t"); +        mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) ""; +        if (head) +                head += strspn (head, " \t"); +        cp = strsep (&head, " \t"); +        mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) ""; +        switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, +                               &mp->mnt_passno) : 0) +        { +                case 0: +                        mp->mnt_freq = 0; +                case 1: +                        mp->mnt_passno = 0; +                case 2: +                        break; +        } + +        return mp; +} + +struct glusterfs_mntent * +glusterfs_fstab_getent (glusterfs_fstab_t *h) +{ +        if (!h) +                return NULL; + +        if (!h->fp) +                return NULL; + +        return __glusterfs_fstab_getent (h->fp, &h->tmpent, h->buf, +                                         GF_MNTENT_BUFSIZE); +} + +/* We have to use an encoding for names if they contain spaces or tabs. +   To be able to represent all characters we also have to escape the +   backslash itself.  This "function" must be a macro since we use +   `alloca'.  */ +#define encode_name(name)                                               \ +        do {                                                            \ +                const char *rp = name;		                        \ +                                                                        \ +                while (*rp != '\0')     	                        \ +                        if (*rp == ' ' || *rp == '\t' || *rp == '\\')   \ +                                break;                                  \ +                        else	                                        \ +                                ++rp;                                   \ +                                                                        \ +                if (*rp != '\0')                                        \ +                {                                               \ +                /* In the worst case the length of the string   \ +                 * can increase to four times the current       \ +                 * length.  */				        \ +                        char *wp;				\ +                                                                \ +                        rp = name;				\ +                        name = wp = (char *) alloca (strlen (name) * 4 + 1);                                                                 \ +                                                                \ +                        do {                            \ +                                if (*rp == ' ')		\ +                                {       		\ +                                        *wp++ = '\\';   \ +                                        *wp++ = '0';	\ +                                        *wp++ = '4';	\ +                                        *wp++ = '0';    \ +                                }			\ +                                else if (*rp == '\t')	\ +                                {			\ +                                        *wp++ = '\\';	\ +                                        *wp++ = '0';	\ +                                        *wp++ = '1';	\ +                                        *wp++ = '1';	\ +                                }			\ +                                else if (*rp == '\n')	\ +                                {	                \ +                                        *wp++ = '\\';	\ +                                        *wp++ = '0';	\ +                                        *wp++ = '1';	\ +                                        *wp++ = '2';	\ +                                }	                \ +                                else if (*rp == '\\')	\ +                                {                       \ +                                        *wp++ = '\\';	\ +                                        *wp++ = '\\';	\ +                                }                       \ +                                else	                \ +                                        *wp++ = *rp;	\ +                        } while (*rp++ != '\0');	\ +                }                                       \ +        } while (0)                                     \ + + +int +glusterfs_fstab_addent (glusterfs_fstab_t *h, +                const struct glusterfs_mntent *mnt) +{ +        struct glusterfs_mntent mntcopy = *mnt; +        if (!h) +                return -1; + +        if (!h->fp) +                return -1; + +        if (fseek (h->fp, 0, SEEK_END)) +                return -1; + +        /* Encode spaces and tabs in the names.  */ +        encode_name (mntcopy.mnt_fsname); +        encode_name (mntcopy.mnt_dir); +        encode_name (mntcopy.mnt_type); +        encode_name (mntcopy.mnt_opts); + +        return (fprintf (h->fp, "%s %s %s %s %d %d\n", +                                mntcopy.mnt_fsname, +                                mntcopy.mnt_dir, +                                mntcopy.mnt_type, +                                mntcopy.mnt_opts, +                                mntcopy.mnt_freq, +                                mntcopy.mnt_passno) +                        < 0 ? 1 : 0); +} + + +/* Search MNT->mnt_opts for an option matching OPT. +   Returns the address of the substring, or null if none found.  */ +char * +glusterfs_fstab_hasoption (const struct glusterfs_mntent *mnt, const char *opt) +{ +        const size_t optlen = strlen (opt); +        char *rest = mnt->mnt_opts, *p; + +        while ((p = strstr (rest, opt)) != NULL) +        { +                if ((p == rest || p[-1] == ',') +                                && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) +                        return p; + +                rest = strchr (p, ','); +                if (rest == NULL) +                        break; +                ++rest; +        } + +        return NULL; +} + +void +clean_init_params (glusterfs_init_params_t *ipars) +{ +        if (!ipars) +                return; + +        if (ipars->volume_name) +                free (ipars->volume_name); + +        if (ipars->specfile) +                free (ipars->specfile); + +        if (ipars->logfile) +                free (ipars->logfile); + +        if (ipars->loglevel) +                free (ipars->loglevel); + +        return; +} + +char * +get_option_value (char *opt) +{ +        char *val = NULL; +        char *saveptr = NULL; +        char *copy_opt = NULL; +        char *retval = NULL; + +        copy_opt = strdup (opt); + +        /* Get the = before the value of the option. */ +        val = index (copy_opt, '='); +        if (val) { +                /* Move to start of option */ +                ++val; + +                /* Now, to create a '\0' delimited string out of the +                 * options string, first get the position where the +                 * next option starts, that would be the next ','. +                 */ +                saveptr = index (val, ','); +                if (saveptr) +                        *saveptr = '\0'; +                retval = strdup (val); +        } + +        free (copy_opt); + +        return retval; +} + +void +booster_mount (struct glusterfs_mntent *ent) +{ +        char                    *opt = NULL; +        glusterfs_init_params_t ipars; + +        if (!ent) +                return; + +        if ((strcmp (ent->mnt_type, "glusterfs") != 0)) +                return; + +        memset (&ipars, 0, sizeof (glusterfs_init_params_t)); +        if (ent->mnt_fsname) +                ipars.specfile = strdup (ent->mnt_fsname); + +        opt = glusterfs_fstab_hasoption (ent, "subvolume"); +        if (opt) +                ipars.volume_name = get_option_value (opt); + +        opt = glusterfs_fstab_hasoption (ent, "logfile"); +        if (opt) +                ipars.logfile = get_option_value (opt); + +        opt = glusterfs_fstab_hasoption (ent, "loglevel"); +        if (opt) +                ipars.loglevel = get_option_value (opt); + +        glusterfs_mount (ent->mnt_dir, &ipars); +        clean_init_params (&ipars); +} + +int +booster_configure (char *confpath) +{ +        int                     ret = -1; +        glusterfs_fstab_t       *handle = NULL; +        struct glusterfs_mntent *ent = NULL; + +        if (!confpath) +                goto out; + +        handle = glusterfs_fstab_init (confpath, "r"); +        if (!handle) +                goto out; + +        while ((ent = glusterfs_fstab_getent (handle)) != NULL) +                booster_mount (ent); + +        glusterfs_fstab_close (handle); +        ret = 0; +out: +        return ret; +} + + diff --git a/libglusterfs/src/glusterfs_fstab.h b/booster/src/booster_fstab.h index 5d6c6a77f..9bab04c5a 100644 --- a/libglusterfs/src/glusterfs_fstab.h +++ b/booster/src/booster_fstab.h @@ -19,11 +19,12 @@  #ifndef	GLUSTERFS_FSTAB_MNTENT_H  #define	GLUSTERFS_FSTAB_MNTENT_H	1 - -#include <features.h> -#include <stdio.h> -#include <paths.h> - +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif +  +#include "compat.h"  /* General filesystem types.  */  #define GF_MNTTYPE_IGNORE	"ignore"	/* Ignore this entry.  */ @@ -42,14 +43,14 @@  /* Structure describing a mount table entry.  */  struct glusterfs_mntent -  { -    char *mnt_fsname;		/* Device or server for filesystem.  */ -    char *mnt_dir;		/* Directory mounted on.  */ -    char *mnt_type;		/* Type of filesystem: ufs, nfs, etc.  */ -    char *mnt_opts;		/* Comma-separated options for fs.  */ -    int mnt_freq;		/* Dump frequency (in days).  */ -    int mnt_passno;		/* Pass number for `fsck'.  */ -  }; +{ +        char *mnt_fsname;		/* Device or server for filesystem.  */ +        char *mnt_dir;		/* Directory mounted on.  */ +        char *mnt_type;		/* Type of filesystem: ufs, nfs, etc.  */ +        char *mnt_opts;		/* Comma-separated options for fs.  */ +        int mnt_freq;		/* Dump frequency (in days).  */ +        int mnt_passno;		/* Pass number for `fsck'.  */ +};  #define GF_MNTENT_BUFSIZE       1024  typedef struct glusterfs_fstab_handle { @@ -62,14 +63,14 @@ typedef struct glusterfs_fstab_handle {  /* Prepare to begin reading and/or writing mount table entries from the     beginning of FILE.  MODE is as for `fopen'.  */  extern glusterfs_fstab_t *glusterfs_fstab_init (const char *file, -                                                const char *mode); +                const char *mode);  extern struct glusterfs_mntent *glusterfs_fstab_getent (glusterfs_fstab_t *h);  /* Write the mount table entry described by MNT to STREAM.     Return zero on success, nonzero on failure.  */  extern int glusterfs_fstab_addent (glusterfs_fstab_t *h, -		                   const struct glusterfs_mntent *mnt); +                const struct glusterfs_mntent *mnt);  /* Close a stream opened with `glusterfs_fstab_init'.  */  extern int glusterfs_fstab_close (glusterfs_fstab_t *h); @@ -77,6 +78,6 @@ extern int glusterfs_fstab_close (glusterfs_fstab_t *h);  /* Search MNT->mnt_opts for an option matching OPT.     Returns the address of the substring, or null if none found.  */  extern char *glusterfs_fstab_hasoption (const struct glusterfs_mntent *mnt, -                                        const char *opt); +                const char *opt);  #endif diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 2863c755c..8ff35fbb2 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -6,9 +6,9 @@ libglusterfs_la_LIBADD = @LEXLIB@  lib_LTLIBRARIES = libglusterfs.la -libglusterfs_la_SOURCES = dict.c spec.lex.c y.tab.c xlator.c logging.c  hashfn.c defaults.c scheduler.c common-utils.c transport.c timer.c inode.c call-stub.c compat.c authenticate.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c glusterfs_fstab.c +libglusterfs_la_SOURCES = dict.c spec.lex.c y.tab.c xlator.c logging.c  hashfn.c defaults.c scheduler.c common-utils.c transport.c timer.c inode.c call-stub.c compat.c authenticate.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c -noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h protocol.h scheduler.h xlator.h transport.h stack.h timer.h list.h inode.h call-stub.h compat.h authenticate.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h glusterfs_fstab.h +noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h protocol.h scheduler.h xlator.h transport.h stack.h timer.h list.h inode.h call-stub.h compat.h authenticate.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h  EXTRA_DIST = spec.l spec.y diff --git a/libglusterfs/src/glusterfs_fstab.c b/libglusterfs/src/glusterfs_fstab.c deleted file mode 100644 index b21197b1d..000000000 --- a/libglusterfs/src/glusterfs_fstab.c +++ /dev/null @@ -1,309 +0,0 @@ -/* Utilities for reading/writing fstab, mtab, etc. -   Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 -   Free Software Foundation, Inc. -   This file is part of the GNU C Library. - -   The GNU C Library is free software; you can redistribute it and/or -   modify it under the terms of the GNU Lesser General Public -   License as published by the Free Software Foundation; either -   version 2.1 of the License, or (at your option) any later version. - -   The GNU C Library is distributed in the hope that it will be useful, -   but WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -   Lesser General Public License for more details. - -   You should have received a copy of the GNU Lesser General Public -   License along with the GNU C Library; if not, write to the Free -   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -   02111-1307 USA.  */ - -#include <alloca.h> -#include <stdio.h> -#include <stdio_ext.h> -#include <string.h> -#include <sys/types.h> -#include "glusterfs_fstab.h" -#include <stdlib.h> - -/* Prepare to begin reading and/or writing mount table entries from the -   beginning of FILE.  MODE is as for `fopen'.  */ -glusterfs_fstab_t * -glusterfs_fstab_init (const char *file, const char *mode) -{ -  glusterfs_fstab_t *handle = NULL; -  /* Extend the mode parameter with "c" to disable cancellation in the -     I/O functions.  */ -  size_t modelen = strlen (mode); -  char newmode[modelen + 2]; -  memcpy (mempcpy (newmode, mode, modelen), "c", 2); - -  handle = calloc (1, sizeof (glusterfs_fstab_t)); -  if (!handle) -          goto out; - -  FILE *result = fopen (file, newmode); -  if (result != NULL) { -    /* We do the locking ourselves.  */ -    __fsetlocking (result, FSETLOCKING_BYCALLER); -    handle->fp = result; -  } else { -          free (handle); -          handle = NULL; -  } - -out: - -  return handle; -} - -int -glusterfs_fstab_close (glusterfs_fstab_t *h) -{ -  if (!h) -    return -1; - -  if (h->fp) -    fclose (h->fp); - -  return 0; -} - -/* Since the values in a line are separated by spaces, a name cannot -   contain a space.  Therefore some programs encode spaces in names -   by the strings "\040".  We undo the encoding when reading an entry. -   The decoding happens in place.  */ -static char * -decode_name (char *buf) -{ -  char *rp = buf; -  char *wp = buf; - -  do -    if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0') -      { -	/* \040 is a SPACE.  */ -	*wp++ = ' '; -	rp += 3; -      } -    else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '1') -      { -	/* \011 is a TAB.  */ -	*wp++ = '\t'; -	rp += 3; -      } -    else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2') -      { -	/* \012 is a NEWLINE.  */ -	*wp++ = '\n'; -	rp += 3; -      } -    else if (rp[0] == '\\' && rp[1] == '\\') -      { -	/* We have to escape \\ to be able to represent all characters.  */ -	*wp++ = '\\'; -	rp += 1; -      } -    else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' && rp[3] == '4') -      { -	/* \134 is also \\.  */ -	*wp++ = '\\'; -	rp += 3; -      } -    else -      *wp++ = *rp; -  while (*rp++ != '\0'); - -  return buf; -} - - -/* Read one mount table entry from STREAM.  Returns a pointer to storage -   reused on the next call, or null for EOF or error (use feof/ferror to -   check).  */ -struct glusterfs_mntent * -__glusterfs_fstab_getent (FILE *stream, struct glusterfs_mntent *mp, -                          char *buffer, int bufsiz) -{ -  char *cp; -  char *head; - -  flockfile (stream); -  do -    { -      char *end_ptr; - -      if (fgets_unlocked (buffer, bufsiz, stream) == NULL) -	{ -	  funlockfile (stream); -	  return NULL; -	} - -      end_ptr = strchr (buffer, '\n'); -      if (end_ptr != NULL)	/* chop newline */ -	*end_ptr = '\0'; -      else -	{ -	  /* Not the whole line was read.  Do it now but forget it.  */ -	  char tmp[1024]; -	  while (fgets_unlocked (tmp, sizeof tmp, stream) != NULL) -	    if (strchr (tmp, '\n') != NULL) -	      break; -	} - -      head = buffer + strspn (buffer, " \t"); -      /* skip empty lines and comment lines:  */ -    } -  while (head[0] == '\0' || head[0] == '#'); - -  cp = strsep (&head, " \t"); -  mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) ""; -  if (head) -    head += strspn (head, " \t"); -  cp = strsep (&head, " \t"); -  mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) ""; -  if (head) -    head += strspn (head, " \t"); -  cp = strsep (&head, " \t"); -  mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) ""; -  if (head) -    head += strspn (head, " \t"); -  cp = strsep (&head, " \t"); -  mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) ""; -  switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0) -    { -    case 0: -      mp->mnt_freq = 0; -    case 1: -      mp->mnt_passno = 0; -    case 2: -      break; -    } -  funlockfile (stream); - -  return mp; -} - -struct glusterfs_mntent * -glusterfs_fstab_getent (glusterfs_fstab_t *h) -{ -  if (!h) -    return NULL; - -  if (!h->fp) -    return NULL; - -  return __glusterfs_fstab_getent (h->fp, &h->tmpent, h->buf, -                                   GF_MNTENT_BUFSIZE); -} - -/* We have to use an encoding for names if they contain spaces or tabs. -   To be able to represent all characters we also have to escape the -   backslash itself.  This "function" must be a macro since we use -   `alloca'.  */ -#define encode_name(name) \ -  do {									      \ -    const char *rp = name;						      \ -									      \ -    while (*rp != '\0')							      \ -      if (*rp == ' ' || *rp == '\t' || *rp == '\\')			      \ -	break;								      \ -      else								      \ -	++rp;								      \ -									      \ -    if (*rp != '\0')							      \ -      {									      \ -	/* In the worst case the length of the string can increase to	      \ -	   founr times the current length.  */				      \ -	char *wp;							      \ -									      \ -	rp = name;							      \ -	name = wp = (char *) alloca (strlen (name) * 4 + 1);		      \ -									      \ -	do								      \ -	  if (*rp == ' ')						      \ -	    {								      \ -	      *wp++ = '\\';						      \ -	      *wp++ = '0';						      \ -	      *wp++ = '4';						      \ -	      *wp++ = '0';						      \ -	    }								      \ -	  else if (*rp == '\t')						      \ -	    {								      \ -	      *wp++ = '\\';						      \ -	      *wp++ = '0';						      \ -	      *wp++ = '1';						      \ -	      *wp++ = '1';						      \ -	    }								      \ -	  else if (*rp == '\n')						      \ -	    {								      \ -	      *wp++ = '\\';						      \ -	      *wp++ = '0';						      \ -	      *wp++ = '1';						      \ -	      *wp++ = '2';						      \ -	    }								      \ -	  else if (*rp == '\\')						      \ -	    {								      \ -	      *wp++ = '\\';						      \ -	      *wp++ = '\\';						      \ -	    }								      \ -	  else								      \ -	    *wp++ = *rp;						      \ -	while (*rp++ != '\0');						      \ -      }									      \ -  } while (0) - - -int -glusterfs_fstab_addent (glusterfs_fstab_t *h, -                        const struct glusterfs_mntent *mnt) -{ -  struct glusterfs_mntent mntcopy = *mnt; -  if (!h) -    return -1; - -  if (!h->fp) -    return -1; - -  if (fseek (h->fp, 0, SEEK_END)) -    return -1; - -  /* Encode spaces and tabs in the names.  */ -  encode_name (mntcopy.mnt_fsname); -  encode_name (mntcopy.mnt_dir); -  encode_name (mntcopy.mnt_type); -  encode_name (mntcopy.mnt_opts); - -  return (fprintf (h->fp, "%s %s %s %s %d %d\n", -		   mntcopy.mnt_fsname, -		   mntcopy.mnt_dir, -		   mntcopy.mnt_type, -		   mntcopy.mnt_opts, -		   mntcopy.mnt_freq, -		   mntcopy.mnt_passno) -	  < 0 ? 1 : 0); -} - - -/* Search MNT->mnt_opts for an option matching OPT. -   Returns the address of the substring, or null if none found.  */ -char * -glusterfs_fstab_hasoption (const struct glusterfs_mntent *mnt, const char *opt) -{ -  const size_t optlen = strlen (opt); -  char *rest = mnt->mnt_opts, *p; - -  while ((p = strstr (rest, opt)) != NULL) -    { -      if ((p == rest || p[-1] == ',') -	  && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) -	return p; - -      rest = strchr (p, ','); -      if (rest == NULL) -	break; -      ++rest; -    } - -  return NULL; -}  | 
