|
|
306fa1 |
autofs-5.0.9 - amd lookup add parse_amd.c
|
|
|
306fa1 |
|
|
|
306fa1 |
From: Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
|
|
|
306fa1 |
Add a yacc parser and an autofs parser module for amd format
|
|
|
306fa1 |
maps.
|
|
|
306fa1 |
---
|
|
|
306fa1 |
include/automount.h | 1
|
|
|
306fa1 |
include/mounts.h | 6
|
|
|
306fa1 |
include/parse_amd.h | 54 ++
|
|
|
306fa1 |
lib/mounts.c | 81 +++
|
|
|
306fa1 |
modules/Makefile | 21 -
|
|
|
306fa1 |
modules/amd_parse.y | 511 ++++++++++++++++++++++++
|
|
|
306fa1 |
modules/amd_tok.l | 316 +++++++++++++++
|
|
|
306fa1 |
modules/parse_amd.c | 1081 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
306fa1 |
8 files changed, 2069 insertions(+), 2 deletions(-)
|
|
|
306fa1 |
create mode 100644 include/parse_amd.h
|
|
|
306fa1 |
create mode 100644 modules/amd_parse.y
|
|
|
306fa1 |
create mode 100644 modules/amd_tok.l
|
|
|
306fa1 |
create mode 100644 modules/parse_amd.c
|
|
|
306fa1 |
|
|
|
306fa1 |
--- autofs-5.0.7.orig/include/automount.h
|
|
|
306fa1 |
+++ autofs-5.0.7/include/automount.h
|
|
|
306fa1 |
@@ -34,6 +34,7 @@
|
|
|
306fa1 |
#include "parse_subs.h"
|
|
|
306fa1 |
#include "mounts.h"
|
|
|
306fa1 |
#include "dev-ioctl-lib.h"
|
|
|
306fa1 |
+#include "parse_amd.h"
|
|
|
306fa1 |
|
|
|
306fa1 |
#ifdef WITH_DMALLOC
|
|
|
306fa1 |
#include <dmalloc.h>
|
|
|
306fa1 |
--- autofs-5.0.7.orig/include/mounts.h
|
|
|
306fa1 |
+++ autofs-5.0.7/include/mounts.h
|
|
|
306fa1 |
@@ -85,10 +85,16 @@ unsigned int linux_version_code(void);
|
|
|
306fa1 |
int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
|
|
|
306fa1 |
extern unsigned int nfs_mount_uses_string_options;
|
|
|
306fa1 |
|
|
|
306fa1 |
+struct amd_entry;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
struct substvar *addstdenv(struct substvar *sv);
|
|
|
306fa1 |
struct substvar *removestdenv(struct substvar *sv);
|
|
|
306fa1 |
void add_std_amd_vars(struct substvar *sv);
|
|
|
306fa1 |
void remove_std_amd_vars(void);
|
|
|
306fa1 |
+struct amd_entry *new_amd_entry(const struct substvar *sv);
|
|
|
306fa1 |
+void clear_amd_entry(struct amd_entry *entry);
|
|
|
306fa1 |
+void free_amd_entry(struct amd_entry *entry);
|
|
|
306fa1 |
+void free_amd_entry_list(struct list_head *entries);
|
|
|
306fa1 |
|
|
|
306fa1 |
unsigned int query_kproto_ver(void);
|
|
|
306fa1 |
unsigned int get_kver_major(void);
|
|
|
306fa1 |
--- /dev/null
|
|
|
306fa1 |
+++ autofs-5.0.7/include/parse_amd.h
|
|
|
306fa1 |
@@ -0,0 +1,54 @@
|
|
|
306fa1 |
+/* ----------------------------------------------------------------------- *
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * Copyright 2004-2006 Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
+ * Copyright 2013 Red Hat, Inc.
|
|
|
306fa1 |
+ * All rights reserved.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
306fa1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
306fa1 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
|
306fa1 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
|
306fa1 |
+ * version; incorporated herein by reference.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * ----------------------------------------------------------------------- */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifndef PARSE_AMD_H
|
|
|
306fa1 |
+#define PARSE_AMD_H
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_NONE 0x00000000
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_AUTO 0x00000001
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_NFS 0x00000002
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_LINK 0x00000004
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_HOST 0x00000008
|
|
|
306fa1 |
+#define AMD_MOUNT_TYPE_MASK 0x0000ffff
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define AMD_ENTRY_CUT 0x00010000
|
|
|
306fa1 |
+#define AMD_ENTRY_MASK 0x00ff0000
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define AMD_DEFAULTS_MERGE 0x01000000
|
|
|
306fa1 |
+#define AMD_DEFAULTS_RESET 0x02000000
|
|
|
306fa1 |
+#define AMD_DEFAULTS_MASK 0xff000000
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+struct amd_entry {
|
|
|
306fa1 |
+ char *path;
|
|
|
306fa1 |
+ unsigned long flags;
|
|
|
306fa1 |
+ char *type;
|
|
|
306fa1 |
+ char *map_type;
|
|
|
306fa1 |
+ char *pref;
|
|
|
306fa1 |
+ char *fs;
|
|
|
306fa1 |
+ char *rhost;
|
|
|
306fa1 |
+ char *rfs;
|
|
|
306fa1 |
+ char *opts;
|
|
|
306fa1 |
+ char *addopts;
|
|
|
306fa1 |
+ char *remopts;
|
|
|
306fa1 |
+ char *sublink;
|
|
|
306fa1 |
+ struct selector *selector;
|
|
|
306fa1 |
+ struct list_head list;
|
|
|
306fa1 |
+ struct list_head entries;
|
|
|
306fa1 |
+ struct list_head ext_mount;
|
|
|
306fa1 |
+};
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int amd_parse_list(struct autofs_point *,
|
|
|
306fa1 |
+ const char *, struct list_head *, struct substvar **);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
--- autofs-5.0.7.orig/lib/mounts.c
|
|
|
306fa1 |
+++ autofs-5.0.7/lib/mounts.c
|
|
|
306fa1 |
@@ -442,6 +442,87 @@ void remove_std_amd_vars(void)
|
|
|
306fa1 |
return;
|
|
|
306fa1 |
}
|
|
|
306fa1 |
|
|
|
306fa1 |
+struct amd_entry *new_amd_entry(const struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct amd_entry *new;
|
|
|
306fa1 |
+ const struct substvar *v;
|
|
|
306fa1 |
+ char *path;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ v = macro_findvar(sv, "path", 4);
|
|
|
306fa1 |
+ if (!v)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ path = strdup(v->val);
|
|
|
306fa1 |
+ if (!path)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ new = malloc(sizeof(struct amd_entry));
|
|
|
306fa1 |
+ if (!new) {
|
|
|
306fa1 |
+ free(path);
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ memset(new, 0, sizeof(*new));
|
|
|
306fa1 |
+ new->path = path;
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&new->list);
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&new->entries);
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&new->ext_mount);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return new;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void clear_amd_entry(struct amd_entry *entry)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ if (!entry)
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+ if (entry->path)
|
|
|
306fa1 |
+ free(entry->path);
|
|
|
306fa1 |
+ if (entry->map_type)
|
|
|
306fa1 |
+ free(entry->map_type);
|
|
|
306fa1 |
+ if (entry->pref)
|
|
|
306fa1 |
+ free(entry->pref);
|
|
|
306fa1 |
+ if (entry->fs)
|
|
|
306fa1 |
+ free(entry->fs);
|
|
|
306fa1 |
+ if (entry->rhost)
|
|
|
306fa1 |
+ free(entry->rhost);
|
|
|
306fa1 |
+ if (entry->rfs)
|
|
|
306fa1 |
+ free(entry->rfs);
|
|
|
306fa1 |
+ if (entry->opts)
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ if (entry->addopts)
|
|
|
306fa1 |
+ free(entry->addopts);
|
|
|
306fa1 |
+ if (entry->remopts)
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ if (entry->sublink)
|
|
|
306fa1 |
+ free(entry->sublink);
|
|
|
306fa1 |
+ if (entry->selector)
|
|
|
306fa1 |
+ free_selector(entry->selector);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void free_amd_entry(struct amd_entry *entry)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ clear_amd_entry(entry);
|
|
|
306fa1 |
+ free(entry);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void free_amd_entry_list(struct list_head *entries)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ if (!list_empty(entries)) {
|
|
|
306fa1 |
+ struct list_head *head = entries;
|
|
|
306fa1 |
+ struct amd_entry *this;
|
|
|
306fa1 |
+ struct list_head *p;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ p = head->next;
|
|
|
306fa1 |
+ while (p != head) {
|
|
|
306fa1 |
+ this = list_entry(p, struct amd_entry, list);
|
|
|
306fa1 |
+ p = p->next;
|
|
|
306fa1 |
+ free_amd_entry(this);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
/*
|
|
|
306fa1 |
* Make common autofs mount options string
|
|
|
306fa1 |
*/
|
|
|
306fa1 |
--- autofs-5.0.7.orig/modules/Makefile
|
|
|
306fa1 |
+++ autofs-5.0.7/modules/Makefile
|
|
|
306fa1 |
@@ -7,16 +7,18 @@ include ../Makefile.rules
|
|
|
306fa1 |
|
|
|
306fa1 |
SRCS := lookup_file.c lookup_program.c lookup_userhome.c \
|
|
|
306fa1 |
lookup_multi.c lookup_hosts.c lookup_dir.c \
|
|
|
306fa1 |
- parse_sun.c \
|
|
|
306fa1 |
+ parse_sun.c parse_amd.c \
|
|
|
306fa1 |
mount_generic.c mount_nfs.c mount_afs.c mount_autofs.c \
|
|
|
306fa1 |
mount_changer.c mount_bind.c
|
|
|
306fa1 |
|
|
|
306fa1 |
MODS := lookup_file.so lookup_program.so lookup_userhome.so \
|
|
|
306fa1 |
lookup_multi.so lookup_hosts.so lookup_dir.so \
|
|
|
306fa1 |
- parse_sun.so \
|
|
|
306fa1 |
+ parse_sun.so parse_amd.so \
|
|
|
306fa1 |
mount_generic.so mount_nfs.so mount_afs.so mount_autofs.so \
|
|
|
306fa1 |
mount_changer.so mount_bind.so
|
|
|
306fa1 |
|
|
|
306fa1 |
+YACCSRC = amd_tok.c amd_parse.tab.c amd_parse.tab.h \
|
|
|
306fa1 |
+
|
|
|
306fa1 |
ifeq ($(EXT2FS), 1)
|
|
|
306fa1 |
SRCS += mount_ext2.c
|
|
|
306fa1 |
MODS += mount_ext2.so
|
|
|
306fa1 |
@@ -94,6 +96,21 @@ else ifeq ($(EXT4FS), 1)
|
|
|
306fa1 |
mv $(INSTALLROOT)$(autofslibdir)/mount_ext2.so $(INSTALLROOT)$(autofslibdir)/mount_ext4.so
|
|
|
306fa1 |
endif
|
|
|
306fa1 |
|
|
|
306fa1 |
+amd_tok.c: amd_tok.l
|
|
|
306fa1 |
+ $(LEX) -o$@ -Pamd_ $?
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+amd_tok.o: amd_tok.c amd_parse.tab.h
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+amd_parse.tab.c amd_parse.tab.h: amd_parse.y
|
|
|
306fa1 |
+ $(YACC) -v -d -p amd_ -b amd_parse $?
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+amd_parse.tab.o: amd_parse.tab.c amd_parse.tab.h
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+parse_amd.so: parse_amd.c amd_parse.tab.o amd_tok.o
|
|
|
306fa1 |
+ $(CC) $(LDFLAGS) $(SOLDFLAGS) $(CFLAGS) -o parse_amd.so \
|
|
|
306fa1 |
+ parse_amd.c amd_parse.tab.o amd_tok.o $(AUTOFS_LIB) $(LIBS)
|
|
|
306fa1 |
+ $(STRIP) parse_amd.so
|
|
|
306fa1 |
+
|
|
|
306fa1 |
#
|
|
|
306fa1 |
# Ad hoc compilation rules for modules which need auxilliary libraries
|
|
|
306fa1 |
#
|
|
|
306fa1 |
--- /dev/null
|
|
|
306fa1 |
+++ autofs-5.0.7/modules/amd_parse.y
|
|
|
306fa1 |
@@ -0,0 +1,511 @@
|
|
|
306fa1 |
+%{
|
|
|
306fa1 |
+/* ----------------------------------------------------------------------- *
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * Copyright 2013 Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
+ * Copyright 2013 Red Hat, Inc.
|
|
|
306fa1 |
+ * All rights reserved.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
306fa1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
306fa1 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
|
306fa1 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
|
306fa1 |
+ * version.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
306fa1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
306fa1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
306fa1 |
+ * GNU General Public License for more details.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * ----------------------------------------------------------------------- */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#include <stdio.h>
|
|
|
306fa1 |
+#include <string.h>
|
|
|
306fa1 |
+#include <stdlib.h>
|
|
|
306fa1 |
+#include <stdarg.h>
|
|
|
306fa1 |
+#include <ctype.h>
|
|
|
306fa1 |
+#include <sys/ioctl.h>
|
|
|
306fa1 |
+#include <syslog.h>
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#include "automount.h"
|
|
|
306fa1 |
+#include "parse_amd.h"
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define MAX_OPTS_LEN 1024
|
|
|
306fa1 |
+#define MAX_ERR_LEN 512
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static pthread_mutex_t parse_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+extern FILE *amd_in;
|
|
|
306fa1 |
+extern char *amd_text;
|
|
|
306fa1 |
+extern int amd_lex(void);
|
|
|
306fa1 |
+extern void amd_set_scan_buffer(const char *);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static char *amd_strdup(char *);
|
|
|
306fa1 |
+static void local_init_vars(void);
|
|
|
306fa1 |
+static void local_free_vars(void);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int amd_error(const char *s);
|
|
|
306fa1 |
+static int amd_notify(const char *s);
|
|
|
306fa1 |
+static int amd_msg(const char *s);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int add_location(void);
|
|
|
306fa1 |
+static int make_selector(char *name,
|
|
|
306fa1 |
+ char *value1, char *value2,
|
|
|
306fa1 |
+ unsigned int compare);
|
|
|
306fa1 |
+static void add_selector(struct selector *selector);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct amd_entry entry;
|
|
|
306fa1 |
+static struct list_head *entries;
|
|
|
306fa1 |
+static struct autofs_point *pap;
|
|
|
306fa1 |
+struct substvar *psv;
|
|
|
306fa1 |
+static char opts[MAX_OPTS_LEN];
|
|
|
306fa1 |
+static void prepend_opt(char *, char *);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define YYDEBUG 0
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifndef YYENABLE_NLS
|
|
|
306fa1 |
+#define YYENABLE_NLS 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+#ifndef YYLTYPE_IS_TRIVIAL
|
|
|
306fa1 |
+#define YYLTYPE_IS_TRIVIAL 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#if YYDEBUG
|
|
|
306fa1 |
+static int amd_fprintf(FILE *, char *, ...);
|
|
|
306fa1 |
+#undef YYFPRINTF
|
|
|
306fa1 |
+#define YYFPRINTF amd_fprintf
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%union {
|
|
|
306fa1 |
+ char strtype[2048];
|
|
|
306fa1 |
+ int inttype;
|
|
|
306fa1 |
+ long longtype;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%token COMMENT
|
|
|
306fa1 |
+%token SEPERATOR
|
|
|
306fa1 |
+%token SPACE
|
|
|
306fa1 |
+%token HYPHEN
|
|
|
306fa1 |
+%token IS_EQUAL
|
|
|
306fa1 |
+%token CUT
|
|
|
306fa1 |
+%token NOT_EQUAL
|
|
|
306fa1 |
+%token COMMA
|
|
|
306fa1 |
+%token OPTION_ASSIGN
|
|
|
306fa1 |
+%token NILL
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%token <strtype> MAP_OPTION
|
|
|
306fa1 |
+%token <strtype> MAP_TYPE
|
|
|
306fa1 |
+%token <strtype> FS_TYPE
|
|
|
306fa1 |
+%token <strtype> FS_OPTION
|
|
|
306fa1 |
+%token <strtype> FS_OPT_VALUE
|
|
|
306fa1 |
+%token <strtype> MNT_OPTION
|
|
|
306fa1 |
+%token <strtype> SELECTOR
|
|
|
306fa1 |
+%token <strtype> SELECTOR_VALUE
|
|
|
306fa1 |
+%token <strtype> OPTION
|
|
|
306fa1 |
+%token <strtype> MACRO
|
|
|
306fa1 |
+%token <strtype> OTHER
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%type <strtype> options
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%start file
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%%
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+file: {
|
|
|
306fa1 |
+#if YYDEBUG != 0
|
|
|
306fa1 |
+ amd_debug = YYDEBUG;
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+ } line
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+line:
|
|
|
306fa1 |
+ | location_selection_list
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+location_selection_list: location
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!add_location()) {
|
|
|
306fa1 |
+ amd_msg("failed to allocate new location");
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | location_selection_list SPACE location
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!add_location()) {
|
|
|
306fa1 |
+ amd_msg("failed to allocate new location");
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | location_selection_list SPACE CUT SPACE location
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ entry.flags |= AMD_ENTRY_CUT;
|
|
|
306fa1 |
+ if (!add_location()) {
|
|
|
306fa1 |
+ amd_msg("failed to allocate new location");
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+location: location_entry
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | HYPHEN location_entry
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ entry.flags |= AMD_DEFAULTS_MERGE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | HYPHEN
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ entry.flags |= AMD_DEFAULTS_RESET;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+location_entry: selector_or_option
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | location_entry SEPERATOR selector_or_option
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | location_entry SEPERATOR
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+selector_or_option: selection
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | option_assignment
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | OTHER
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+selection: SELECTOR IS_EQUAL SELECTOR_VALUE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!make_selector($1, $3, NULL, SEL_TYPE_EQUAL)) {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | SELECTOR NOT_EQUAL SELECTOR_VALUE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!make_selector($1, $3, NULL, SEL_TYPE_NOTEQUAL)) {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!strcmp($3, "auto")) {
|
|
|
306fa1 |
+ entry.flags |= AMD_MOUNT_TYPE_AUTO;
|
|
|
306fa1 |
+ entry.type = amd_strdup($3);
|
|
|
306fa1 |
+ } else if (!strcmp($3, "nfs") ||
|
|
|
306fa1 |
+ !strcmp($3, "nfs4")) {
|
|
|
306fa1 |
+ entry.flags |= AMD_MOUNT_TYPE_NFS;
|
|
|
306fa1 |
+ entry.type = amd_strdup($3);
|
|
|
306fa1 |
+ } else if (!strcmp($3, "link")) {
|
|
|
306fa1 |
+ entry.flags |= AMD_MOUNT_TYPE_LINK;
|
|
|
306fa1 |
+ entry.type = amd_strdup($3);
|
|
|
306fa1 |
+ } else if (!strcmp($3, "host")) {
|
|
|
306fa1 |
+ entry.flags |= AMD_MOUNT_TYPE_HOST;
|
|
|
306fa1 |
+ entry.type = amd_strdup($3);
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | MAP_OPTION OPTION_ASSIGN MAP_TYPE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!strcmp($3, "file") ||
|
|
|
306fa1 |
+ !strcmp($3, "nis") ||
|
|
|
306fa1 |
+ !strcmp($3, "nisplus") ||
|
|
|
306fa1 |
+ !strcmp($3, "ldap") ||
|
|
|
306fa1 |
+ !strcmp($3, "hesiod"))
|
|
|
306fa1 |
+ entry.map_type = amd_strdup($3);
|
|
|
306fa1 |
+ else if (!strcmp($3, "exec"))
|
|
|
306fa1 |
+ /* autofs uses "program" for "exec" map type */
|
|
|
306fa1 |
+ entry.map_type = amd_strdup("program");
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | MAP_OPTION OPTION_ASSIGN FS_OPT_VALUE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!strcmp($1, "fs"))
|
|
|
306fa1 |
+ entry.fs = amd_strdup($3);
|
|
|
306fa1 |
+ else if (!strcmp($1, "sublink"))
|
|
|
306fa1 |
+ entry.sublink = amd_strdup($3);
|
|
|
306fa1 |
+ else if (!strcmp($1, "pref")) {
|
|
|
306fa1 |
+ if (!strcmp($3, "null"))
|
|
|
306fa1 |
+ entry.pref = amd_strdup("");
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ entry.pref = amd_strdup($3);
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | FS_OPTION OPTION_ASSIGN FS_OPT_VALUE
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!strcmp($1, "rhost"))
|
|
|
306fa1 |
+ entry.rhost = amd_strdup($3);
|
|
|
306fa1 |
+ else if (!strcmp($1, "rfs"))
|
|
|
306fa1 |
+ entry.rfs = amd_strdup($3);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | MNT_OPTION OPTION_ASSIGN options
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ if (!strcmp($1, "opts")) {
|
|
|
306fa1 |
+ entry.opts = amd_strdup(opts);
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+ } else if (!strcmp($1, "addopts")) {
|
|
|
306fa1 |
+ entry.addopts = amd_strdup(opts);
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+ } else if (!strcmp($1, "remopts")) {
|
|
|
306fa1 |
+ entry.remopts = amd_strdup(opts);
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+ amd_notify($1);
|
|
|
306fa1 |
+ YYABORT;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+options: OPTION
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ prepend_opt(opts, $1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ | OPTION COMMA options
|
|
|
306fa1 |
+ {
|
|
|
306fa1 |
+ prepend_opt(opts, $1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ ;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%%
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void prepend_opt(char *dest, char *opt)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char new[MAX_OPTS_LEN];
|
|
|
306fa1 |
+ strcpy(new, opt);
|
|
|
306fa1 |
+ if (*dest != '\0') {
|
|
|
306fa1 |
+ strcat(new, ",");
|
|
|
306fa1 |
+ strcat(new, dest);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ memmove(dest, new, strlen(new));
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#if YYDEBUG
|
|
|
306fa1 |
+static int amd_fprintf(FILE *f, char *msg, ...)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ va_list ap;
|
|
|
306fa1 |
+ va_start(ap, msg);
|
|
|
306fa1 |
+ vsyslog(LOG_DEBUG, msg, ap);
|
|
|
306fa1 |
+ va_end(ap);
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static char *amd_strdup(char *str)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ tmp = strdup(str);
|
|
|
306fa1 |
+ if (!tmp)
|
|
|
306fa1 |
+ amd_error("memory allocation error");
|
|
|
306fa1 |
+ return tmp;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int amd_error(const char *s)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ if (strcmp(s, "syntax"))
|
|
|
306fa1 |
+ logmsg("syntax error in location near [ %s ]\n", amd_text);
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ logmsg("%s while parsing location.\n", s);
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int amd_notify(const char *s)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ logmsg("syntax error in location near [ %s ]\n", s);
|
|
|
306fa1 |
+ return(0);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int amd_msg(const char *s)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ logmsg("%s\n", s);
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void local_init_vars(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ memset(&entry, 0, sizeof(entry));
|
|
|
306fa1 |
+ memset(opts, 0, sizeof(opts));
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void local_free_vars(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ clear_amd_entry(&entry);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void add_selector(struct selector *selector)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct selector *s = entry.selector;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!s) {
|
|
|
306fa1 |
+ entry.selector = selector;
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ while (s->next)
|
|
|
306fa1 |
+ s = s->next;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ selector->next = s;
|
|
|
306fa1 |
+ entry.selector = selector;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int make_selector(char *name,
|
|
|
306fa1 |
+ char *value1, char *value2,
|
|
|
306fa1 |
+ unsigned int compare)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct selector *s;
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!sel_lookup(name))
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!value1)
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ s = get_selector(name);
|
|
|
306fa1 |
+ if (!s)
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (s->sel->flags & SEL_FLAG_MACRO) {
|
|
|
306fa1 |
+ tmp = amd_strdup(value1);
|
|
|
306fa1 |
+ if (!tmp)
|
|
|
306fa1 |
+ goto error;
|
|
|
306fa1 |
+ s->comp.value = tmp;
|
|
|
306fa1 |
+ } else if (s->sel->flags & SEL_FLAG_FUNC1) {
|
|
|
306fa1 |
+ char *tmp = amd_strdup(value1);
|
|
|
306fa1 |
+ if (!tmp)
|
|
|
306fa1 |
+ goto error;
|
|
|
306fa1 |
+ s->func.arg1 = tmp;
|
|
|
306fa1 |
+ } else if (s->sel->flags & SEL_FLAG_FUNC2) {
|
|
|
306fa1 |
+ char *tmp = amd_strdup(value1);
|
|
|
306fa1 |
+ if (!tmp)
|
|
|
306fa1 |
+ goto error;
|
|
|
306fa1 |
+ s->func.arg1 = tmp;
|
|
|
306fa1 |
+ if (value2) {
|
|
|
306fa1 |
+ tmp = amd_strdup(value2);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ s->func.arg2 = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ s->compare = compare;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ add_selector(s);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+error:
|
|
|
306fa1 |
+ free_selector(s);
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void amd_init_scan(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void parse_mutex_lock(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int status = pthread_mutex_lock(&parse_mutex);
|
|
|
306fa1 |
+ if (status)
|
|
|
306fa1 |
+ fatal(status);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void parse_mutex_unlock(void *arg)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int status = pthread_mutex_unlock(&parse_mutex);
|
|
|
306fa1 |
+ if (status)
|
|
|
306fa1 |
+ fatal(status);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int add_location(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct amd_entry *new;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ new = new_amd_entry(psv);
|
|
|
306fa1 |
+ if (!new)
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry.path) {
|
|
|
306fa1 |
+ free(new->path);
|
|
|
306fa1 |
+ new->path = entry.path;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ new->flags = entry.flags;
|
|
|
306fa1 |
+ new->type = entry.type;
|
|
|
306fa1 |
+ new->map_type = entry.map_type;
|
|
|
306fa1 |
+ new->pref = entry.pref;
|
|
|
306fa1 |
+ new->fs = entry.fs;
|
|
|
306fa1 |
+ new->rhost = entry.rhost;
|
|
|
306fa1 |
+ new->rfs = entry.rfs;
|
|
|
306fa1 |
+ new->dev = entry.dev;
|
|
|
306fa1 |
+ new->opts = entry.opts;
|
|
|
306fa1 |
+ new->addopts = entry.addopts;
|
|
|
306fa1 |
+ new->remopts = entry.remopts;
|
|
|
306fa1 |
+ new->sublink = entry.sublink;
|
|
|
306fa1 |
+ new->selector = entry.selector;
|
|
|
306fa1 |
+ list_add_tail(&new->list, entries);
|
|
|
306fa1 |
+ memset(&entry, 0, sizeof(struct amd_entry));
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int amd_parse_list(struct autofs_point *ap,
|
|
|
306fa1 |
+ const char *buffer, struct list_head *list,
|
|
|
306fa1 |
+ struct substvar **sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *buf;
|
|
|
306fa1 |
+ size_t len;
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ len = strlen(buffer) + 2;
|
|
|
306fa1 |
+ buf = malloc(len);
|
|
|
306fa1 |
+ if (!buf)
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+ strcpy(buf, buffer);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ parse_mutex_lock();
|
|
|
306fa1 |
+ pthread_cleanup_push(parse_mutex_unlock, NULL);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ pap = ap;
|
|
|
306fa1 |
+ psv = *sv;
|
|
|
306fa1 |
+ entries = list;
|
|
|
306fa1 |
+ amd_set_scan_buffer(buf);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ local_init_vars();
|
|
|
306fa1 |
+ ret = amd_parse();
|
|
|
306fa1 |
+ local_free_vars();
|
|
|
306fa1 |
+ *sv = psv;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ pthread_cleanup_pop(1);
|
|
|
306fa1 |
+ free(buf);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
--- /dev/null
|
|
|
306fa1 |
+++ autofs-5.0.7/modules/amd_tok.l
|
|
|
306fa1 |
@@ -0,0 +1,316 @@
|
|
|
306fa1 |
+%{
|
|
|
306fa1 |
+/* ----------------------------------------------------------------------- *
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * Copyright 2013 Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
+ * Copyright 2013 Red Hat, Inc.
|
|
|
306fa1 |
+ * All rights reserved.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
306fa1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
306fa1 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
|
306fa1 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
|
306fa1 |
+ * version.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
306fa1 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
306fa1 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
306fa1 |
+ * GNU General Public License for more details.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * ----------------------------------------------------------------------- */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifdef ECHO
|
|
|
306fa1 |
+# undef ECHO
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+static void amd_echo(void); /* forward definition */
|
|
|
306fa1 |
+#define ECHO amd_echo()
|
|
|
306fa1 |
+int amd_wrap(void);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#include <stdio.h>
|
|
|
306fa1 |
+#include <stdlib.h>
|
|
|
306fa1 |
+#include <string.h>
|
|
|
306fa1 |
+#include <ctype.h>
|
|
|
306fa1 |
+#include "amd_parse.tab.h"
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int amd_lex(void);
|
|
|
306fa1 |
+int mad_wrap(void);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define YY_SKIP_YYWRAP
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifndef YY_STACK_USED
|
|
|
306fa1 |
+#define YY_STACK_USED 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+#ifndef YY_ALWAYS_INTERACTIVE
|
|
|
306fa1 |
+#define YY_ALWAYS_INTERACTIVE 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+#ifndef YY_NEVER_INTERACTIVE
|
|
|
306fa1 |
+#define YY_NEVER_INTERACTIVE 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+#ifndef YY_MAIN
|
|
|
306fa1 |
+#define YY_MAIN 0
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void amd_set_scan_buffer(const char *);
|
|
|
306fa1 |
+static const char *line = NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifdef FLEX_SCANNER
|
|
|
306fa1 |
+static const char *line_pos = NULL;
|
|
|
306fa1 |
+static const char *line_lim = NULL;
|
|
|
306fa1 |
+int amd_yyinput(char *, int);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#undef YY_INPUT
|
|
|
306fa1 |
+#define YY_INPUT(b, r, ms) (r = amd_yyinput(b, ms))
|
|
|
306fa1 |
+#else
|
|
|
306fa1 |
+#undef input
|
|
|
306fa1 |
+#undef unput
|
|
|
306fa1 |
+#define input() (*(char *) line++)
|
|
|
306fa1 |
+#define unput(c) (*(char *) --line = c)
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%option nounput
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%x MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+NL \r?\n
|
|
|
306fa1 |
+OPTWS [[:blank:]]*
|
|
|
306fa1 |
+OTHR [^!;:=/|\- \t\r\n#]*
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+MACRO (\$\{([[:alpha:]_/]([[:alnum:]_\-])([[:alnum:]_\-/])*)\})
|
|
|
306fa1 |
+QSTR (\"([^"\\]|\\.)*\")
|
|
|
306fa1 |
+OSTR ([[:alpha:]]([[:alnum:]_\-])+)
|
|
|
306fa1 |
+FSTR ([[:alnum:]_/\.]([[:alnum:]_\-/\.]|(\\.))*)
|
|
|
306fa1 |
+VSTR (([[:alnum:]_\-\:/\.])+)
|
|
|
306fa1 |
+SSTR ([[:alpha:]]([[:alnum:]\-\.])+)
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+FOPT (({QSTR}|{FSTR}|{MACRO})+)
|
|
|
306fa1 |
+OPTS ({OSTR}(=({VSTR}|{QSTR}|{MACRO})+)?)
|
|
|
306fa1 |
+SOPT (({SSTR}|{QSTR}|{MACRO})+)
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+MAPOPT (fs|type|maptype|pref|sublink|delay)
|
|
|
306fa1 |
+MNTOPT (opts|addopts|remopts)
|
|
|
306fa1 |
+FSOPTS (rhost|rfs|dev|cachedir)
|
|
|
306fa1 |
+MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union)
|
|
|
306fa1 |
+FSTYPE (auto|nfs|link|host|nfsx|ufs|xfs|efs)
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+OSSEL (arch|karch|os|osver|full_os|vendor)
|
|
|
306fa1 |
+HSTSEL (host|hostd|xhost|domain|byte|cluster)
|
|
|
306fa1 |
+NETSEL (netnumber|network|wire|netgrp|netgrpd|in_network)
|
|
|
306fa1 |
+USRSEL (uid|gid)
|
|
|
306fa1 |
+MAPSEL (key|map|path)
|
|
|
306fa1 |
+OTRSEL (exists|autodir|dollar)
|
|
|
306fa1 |
+BOLSEL (true|false)
|
|
|
306fa1 |
+SELOPT ({OSSEL}|{HSTSEL}|{NETSEL}|{BOLSEL}|{USRSEL}|{MAPSEL}|{OTRSEL})
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+CUTSEP (\|\||\/)
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%%
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+<INITIAL>{
|
|
|
306fa1 |
+ {NL} |
|
|
|
306fa1 |
+ \x00 { }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {MAPOPT} {
|
|
|
306fa1 |
+ BEGIN(MAPOPTVAL);
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return MAP_OPTION;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {FSOPTS} {
|
|
|
306fa1 |
+ BEGIN(FSOPTVAL);
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return FS_OPTION;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {MNTOPT} {
|
|
|
306fa1 |
+ BEGIN(MNTOPTVAL);
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return MNT_OPTION;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {SELOPT} {
|
|
|
306fa1 |
+ BEGIN(SELOPTVAL);
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return SELECTOR;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {CUTSEP} { return CUT; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ "-" { return HYPHEN; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTWS} { return SPACE; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ #.* { return COMMENT; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OTHR} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return OTHER;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+<MAPOPTVAL>{
|
|
|
306fa1 |
+ {NL} |
|
|
|
306fa1 |
+ \x00 {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ yyless(1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ";" {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SEPERATOR;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTWS} {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SPACE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ":=" { return OPTION_ASSIGN; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {FSTYPE} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return FS_TYPE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {MAPTYPE} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return MAP_TYPE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {FOPT} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return FS_OPT_VALUE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+<FSOPTVAL>{
|
|
|
306fa1 |
+ {NL} |
|
|
|
306fa1 |
+ \x00 {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ yyless(1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ";" {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SEPERATOR;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTWS} {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SPACE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ":=" { return OPTION_ASSIGN; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {FOPT} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return FS_OPT_VALUE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+<MNTOPTVAL>{
|
|
|
306fa1 |
+ {NL} |
|
|
|
306fa1 |
+ \x00 {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ yyless(1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ";" {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SEPERATOR;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTWS} {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SPACE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ":=" { return OPTION_ASSIGN; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ "," { return COMMA; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTS} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return OPTION;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+<SELOPTVAL>{
|
|
|
306fa1 |
+ {NL} |
|
|
|
306fa1 |
+ \x00 {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ yyless(1);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ";" {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SEPERATOR;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {OPTWS} {
|
|
|
306fa1 |
+ BEGIN(INITIAL);
|
|
|
306fa1 |
+ return SPACE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ "==" { return IS_EQUAL; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ "!=" { return NOT_EQUAL; }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ {SOPT} {
|
|
|
306fa1 |
+ strcpy(amd_lval.strtype, amd_text);
|
|
|
306fa1 |
+ return SELECTOR_VALUE;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+%%
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#include "automount.h"
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int amd_wrap(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void amd_echo(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ logmsg("%s\n", amd_text);
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#ifdef FLEX_SCANNER
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void amd_set_scan_buffer(const char *buffer)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ line = buffer;
|
|
|
306fa1 |
+ line_pos = &line[0];
|
|
|
306fa1 |
+ /*
|
|
|
306fa1 |
+ * Ensure buffer is 1 greater than string and is zeroed before
|
|
|
306fa1 |
+ * the parse so we can fit the extra NULL which allows us to
|
|
|
306fa1 |
+ * explicitly match an end of line within the buffer (ie. the
|
|
|
306fa1 |
+ * need for 2 NULLS when parsing in memeory buffers).
|
|
|
306fa1 |
+ */
|
|
|
306fa1 |
+ line_lim = line + strlen(buffer) + 1;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define amd_min(a,b) (((a) < (b)) ? (a) : (b))
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int amd_yyinput(char *buffer, int max_size)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int n = amd_min(max_size, line_lim - line_pos);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (n > 0) {
|
|
|
306fa1 |
+ memcpy(buffer, line_pos, n);
|
|
|
306fa1 |
+ line_pos += n;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ return n;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#else
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void amd_set_scan_buffer(const char *buffer)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ line = buffer;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#endif
|
|
|
306fa1 |
--- /dev/null
|
|
|
306fa1 |
+++ autofs-5.0.7/modules/parse_amd.c
|
|
|
306fa1 |
@@ -0,0 +1,1081 @@
|
|
|
306fa1 |
+/* ----------------------------------------------------------------------- *
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * Copyright 2013 Ian Kent <raven@themaw.net>
|
|
|
306fa1 |
+ * Copyright 2013 Red Hat, Inc.
|
|
|
306fa1 |
+ * All rights reserved.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
306fa1 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
306fa1 |
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
|
306fa1 |
+ * USA; either version 2 of the License, or (at your option) any later
|
|
|
306fa1 |
+ * version; incorporated herein by reference.
|
|
|
306fa1 |
+ *
|
|
|
306fa1 |
+ * ----------------------------------------------------------------------- */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#include <stdio.h>
|
|
|
306fa1 |
+#include <malloc.h>
|
|
|
306fa1 |
+#include <netdb.h>
|
|
|
306fa1 |
+#include <stdlib.h>
|
|
|
306fa1 |
+#include <string.h>
|
|
|
306fa1 |
+#include <ctype.h>
|
|
|
306fa1 |
+#include <limits.h>
|
|
|
306fa1 |
+#include <sys/param.h>
|
|
|
306fa1 |
+#include <sys/socket.h>
|
|
|
306fa1 |
+#include <sys/types.h>
|
|
|
306fa1 |
+#include <sys/stat.h>
|
|
|
306fa1 |
+#include <sys/vfs.h>
|
|
|
306fa1 |
+#include <sys/utsname.h>
|
|
|
306fa1 |
+#include <netinet/in.h>
|
|
|
306fa1 |
+#include <sys/mount.h>
|
|
|
306fa1 |
+#include <linux/fs.h>
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define MODULE_PARSE
|
|
|
306fa1 |
+#include "automount.h"
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+#define MODPREFIX "parse(amd): "
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int parse_version = AUTOFS_PARSE_VERSION; /* Required by protocol */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct mount_mod *mount_nfs = NULL;
|
|
|
306fa1 |
+static int init_ctr = 0;
|
|
|
306fa1 |
+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void instance_mutex_lock(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int status = pthread_mutex_lock(&instance_mutex);
|
|
|
306fa1 |
+ if (status)
|
|
|
306fa1 |
+ fatal(status);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void instance_mutex_unlock(void)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int status = pthread_mutex_unlock(&instance_mutex);
|
|
|
306fa1 |
+ if (status)
|
|
|
306fa1 |
+ fatal(status);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+extern const char *global_options;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+struct parse_context {
|
|
|
306fa1 |
+ char *optstr; /* Mount options */
|
|
|
306fa1 |
+ char *macros; /* Map wide macro defines */
|
|
|
306fa1 |
+ struct substvar *subst; /* $-substitutions */
|
|
|
306fa1 |
+};
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+struct multi_mnt {
|
|
|
306fa1 |
+ char *path;
|
|
|
306fa1 |
+ char *options;
|
|
|
306fa1 |
+ char *location;
|
|
|
306fa1 |
+ struct multi_mnt *next;
|
|
|
306fa1 |
+};
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+/* Default context */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct parse_context default_context = {
|
|
|
306fa1 |
+ NULL, /* No mount options */
|
|
|
306fa1 |
+ NULL, /* No map wide macros */
|
|
|
306fa1 |
+ NULL /* The substvar local vars table */
|
|
|
306fa1 |
+};
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+/* Free all storage associated with this context */
|
|
|
306fa1 |
+static void kill_context(struct parse_context *ctxt)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ macro_lock();
|
|
|
306fa1 |
+ macro_free_table(ctxt->subst);
|
|
|
306fa1 |
+ macro_unlock();
|
|
|
306fa1 |
+ if (ctxt->optstr)
|
|
|
306fa1 |
+ free(ctxt->optstr);
|
|
|
306fa1 |
+ if (ctxt->macros)
|
|
|
306fa1 |
+ free(ctxt->macros);
|
|
|
306fa1 |
+ free(ctxt);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int parse_init(int argc, const char *const *argv, void **context)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct parse_context *ctxt;
|
|
|
306fa1 |
+ char buf[MAX_ERR_BUF];
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ sel_hash_init();
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Set up context and escape chain */
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) {
|
|
|
306fa1 |
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
|
306fa1 |
+ logerr(MODPREFIX "malloc: %s", estr);
|
|
|
306fa1 |
+ *context = NULL;
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ *context = (void *) ctxt;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ *ctxt = default_context;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* We only need this once. NFS mounts are so common that we cache
|
|
|
306fa1 |
+ this module. */
|
|
|
306fa1 |
+ instance_mutex_lock();
|
|
|
306fa1 |
+ if (mount_nfs)
|
|
|
306fa1 |
+ init_ctr++;
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ if ((mount_nfs = open_mount("nfs", MODPREFIX))) {
|
|
|
306fa1 |
+ init_ctr++;
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ kill_context(ctxt);
|
|
|
306fa1 |
+ *context = NULL;
|
|
|
306fa1 |
+ instance_mutex_unlock();
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ instance_mutex_unlock();
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return 0;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void update_with_defaults(struct amd_entry *defaults,
|
|
|
306fa1 |
+ struct amd_entry *entry,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ const struct substvar *v;
|
|
|
306fa1 |
+ unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK;
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (fstype == AMD_MOUNT_TYPE_NONE) {
|
|
|
306fa1 |
+ unsigned long deftype = defaults->flags & AMD_MOUNT_TYPE_MASK;
|
|
|
306fa1 |
+ if (deftype != AMD_MOUNT_TYPE_NONE)
|
|
|
306fa1 |
+ entry->flags |= (defaults->flags & AMD_MOUNT_TYPE_MASK);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ entry->flags = AMD_MOUNT_TYPE_NFS;
|
|
|
306fa1 |
+ tmp = strdup("nfs");
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->type = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->type && defaults->type) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->type);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->type = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->map_type && defaults->map_type) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->map_type);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->map_type = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->pref && defaults->pref) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->pref);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->pref = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->fs && defaults->fs) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->fs);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->fs = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->rfs && defaults->rfs) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->rfs);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->rfs = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->rhost && defaults->rhost) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->rhost);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->rhost = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->opts && defaults->opts) {
|
|
|
306fa1 |
+ tmp = merge_options(defaults->opts, entry->opts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->addopts && defaults->addopts) {
|
|
|
306fa1 |
+ tmp = merge_options(defaults->addopts, entry->addopts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->addopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->remopts && defaults->remopts) {
|
|
|
306fa1 |
+ tmp = merge_options(defaults->remopts, entry->remopts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static char *normalize_hostname(unsigned int logopt, const char *host,
|
|
|
306fa1 |
+ unsigned int flags, struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct addrinfo hints, *ni;
|
|
|
306fa1 |
+ char *name;
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!(flags & CONF_NORMALIZE_HOSTNAMES))
|
|
|
306fa1 |
+ name = strdup(host);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ memset(&hints, 0, sizeof(hints));
|
|
|
306fa1 |
+ hints.ai_flags = AI_CANONNAME;
|
|
|
306fa1 |
+ hints.ai_family = AF_UNSPEC;
|
|
|
306fa1 |
+ hints.ai_socktype = SOCK_DGRAM;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ret = getaddrinfo(host, NULL, &hints, &ni);
|
|
|
306fa1 |
+ if (ret) {
|
|
|
306fa1 |
+ error(logopt, "hostname lookup failed: %s", gai_strerror(ret));
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ name = strdup(ni->ai_canonname);
|
|
|
306fa1 |
+ freeaddrinfo(ni);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!name)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (flags & CONF_DOMAIN_STRIP) {
|
|
|
306fa1 |
+ const struct substvar *v = macro_findvar(sv, "hostd", 5);
|
|
|
306fa1 |
+ if (v) {
|
|
|
306fa1 |
+ char *d1 = strchr(name, '.');
|
|
|
306fa1 |
+ if (d1) {
|
|
|
306fa1 |
+ char *d2 = strchr(v->val, '.');
|
|
|
306fa1 |
+ if (d2 && !strcmp(d1, d2))
|
|
|
306fa1 |
+ *d1 = '\0';
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return name;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct substvar *expand_entry(struct autofs_point *ap,
|
|
|
306fa1 |
+ struct amd_entry *entry,
|
|
|
306fa1 |
+ unsigned int flags,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ unsigned int logopt = ap->logopt;
|
|
|
306fa1 |
+ char *expand;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->rhost) {
|
|
|
306fa1 |
+ char *host = strdup(entry->rhost);
|
|
|
306fa1 |
+ char *nn;
|
|
|
306fa1 |
+ if (!host) {
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "failed to allocate storage for rhost");
|
|
|
306fa1 |
+ goto next;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ if (expand_selectors(ap, host, &expand, sv)) {
|
|
|
306fa1 |
+ free(host);
|
|
|
306fa1 |
+ host = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ nn = normalize_hostname(ap->logopt, host, flags, sv);
|
|
|
306fa1 |
+ if (!nn)
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "rhost", 5, host);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "rhost", 5, nn);
|
|
|
306fa1 |
+ free(host);
|
|
|
306fa1 |
+ host = nn;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "rhost expand(\"%s\") -> %s", entry->rhost, host);
|
|
|
306fa1 |
+ free(entry->rhost);
|
|
|
306fa1 |
+ entry->rhost = host;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+next:
|
|
|
306fa1 |
+ if (entry->sublink) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->sublink, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "sublink expand(\"%s\") -> %s",
|
|
|
306fa1 |
+ entry->sublink, expand);
|
|
|
306fa1 |
+ free(entry->sublink);
|
|
|
306fa1 |
+ entry->sublink = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "sublink", 7, entry->sublink);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->rfs) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->rfs, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "rfs expand(\"%s\") -> %s", entry->rfs, expand);
|
|
|
306fa1 |
+ free(entry->rfs);
|
|
|
306fa1 |
+ entry->rfs = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "rfs", 3, entry->rfs);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->fs) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->fs, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "fs expand(\"%s\") -> %s", entry->fs, expand);
|
|
|
306fa1 |
+ free(entry->fs);
|
|
|
306fa1 |
+ entry->fs = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "fs", 2, entry->fs);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->opts) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->opts, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "ops expand(\"%s\") -> %s", entry->opts, expand);
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ entry->opts = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "opts", 4, entry->opts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->addopts) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->addopts, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "addopts expand(\"%s\") -> %s",
|
|
|
306fa1 |
+ entry->addopts, expand);
|
|
|
306fa1 |
+ free(entry->addopts);
|
|
|
306fa1 |
+ entry->addopts = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "addopts", 7, entry->addopts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->remopts) {
|
|
|
306fa1 |
+ if (expand_selectors(ap, entry->remopts, &expand, sv)) {
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "remopts expand(\"%s\") -> %s",
|
|
|
306fa1 |
+ entry->remopts, expand);
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ entry->remopts = expand;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "remopts", 7, entry->remopts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return sv;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void expand_merge_options(struct autofs_point *ap,
|
|
|
306fa1 |
+ struct amd_entry *entry,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->opts) {
|
|
|
306fa1 |
+ if (!expand_selectors(ap, entry->opts, &tmp, sv))
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "failed to expand opts");
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->addopts) {
|
|
|
306fa1 |
+ if (!expand_selectors(ap, entry->addopts, &tmp, sv))
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "failed to expand addopts");
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ free(entry->addopts);
|
|
|
306fa1 |
+ entry->addopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->remopts) {
|
|
|
306fa1 |
+ if (!expand_selectors(ap, entry->remopts, &tmp, sv))
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "failed to expand remopts");
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct substvar *merge_entry_options(struct autofs_point *ap,
|
|
|
306fa1 |
+ struct amd_entry *entry,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->addopts)
|
|
|
306fa1 |
+ return sv;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->opts && entry->remopts &&
|
|
|
306fa1 |
+ !strcmp(entry->opts, entry->remopts)) {
|
|
|
306fa1 |
+ expand_merge_options(ap, entry, sv);
|
|
|
306fa1 |
+ tmp = merge_options(entry->opts, entry->addopts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ info(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "merge remopts \"%s\" addopts \"%s\" => \"%s\"",
|
|
|
306fa1 |
+ entry->opts, entry->addopts, tmp);
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "opts", 4, entry->opts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ tmp = strdup(entry->opts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "remopts", 7, entry->remopts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ return sv;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ expand_merge_options(ap, entry, sv);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->opts && entry->addopts) {
|
|
|
306fa1 |
+ tmp = merge_options(entry->opts, entry->addopts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ info(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "merge opts \"%s\" addopts \"%s\" => \"%s\"",
|
|
|
306fa1 |
+ entry->opts, entry->addopts, tmp);
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "opts", 4, entry->opts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ } else if (entry->addopts) {
|
|
|
306fa1 |
+ tmp = strdup(entry->addopts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ info(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "opts add addopts \"%s\" => \"%s\"", entry->addopts, tmp);
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "opts", 4, entry->opts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ expand_merge_options(ap, entry, sv);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->remopts && entry->addopts) {
|
|
|
306fa1 |
+ tmp = merge_options(entry->remopts, entry->addopts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ info(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "merge remopts \"%s\" addopts \"%s\" => \"%s\"",
|
|
|
306fa1 |
+ entry->remopts, entry->addopts, tmp);
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "remopts", 7, entry->remopts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ } else if (entry->addopts) {
|
|
|
306fa1 |
+ tmp = strdup(entry->addopts);
|
|
|
306fa1 |
+ if (tmp) {
|
|
|
306fa1 |
+ info(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "remopts add addopts \"%s\" => \"%s\"",
|
|
|
306fa1 |
+ entry->addopts, tmp);
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ sv = macro_addvar(sv, "remopts", 7, entry->remopts);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return sv;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int do_auto_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ struct amd_entry *entry, unsigned int flags)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char target[PATH_MAX + 1];
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->map_type)
|
|
|
306fa1 |
+ strcpy(target, entry->fs);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ strcpy(target, entry->map_type);
|
|
|
306fa1 |
+ strcat(target, ",amd:");
|
|
|
306fa1 |
+ strcat(target, entry->fs);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ret = do_mount(ap, ap->path,
|
|
|
306fa1 |
+ name, strlen(name), target, "autofs", NULL);
|
|
|
306fa1 |
+ if (!ret) {
|
|
|
306fa1 |
+ struct autofs_point *sm;
|
|
|
306fa1 |
+ sm = master_find_submount(ap, entry->path);
|
|
|
306fa1 |
+ if (sm) {
|
|
|
306fa1 |
+ sm->pref = entry->pref;
|
|
|
306fa1 |
+ entry->pref = NULL;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int do_link_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ struct amd_entry *entry, unsigned int flags)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char target[PATH_MAX + 1];
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->sublink)
|
|
|
306fa1 |
+ strcpy(target, entry->sublink);
|
|
|
306fa1 |
+ else
|
|
|
306fa1 |
+ strcpy(target, entry->fs);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!(flags & CONF_AUTOFS_USE_LOFS))
|
|
|
306fa1 |
+ goto symlink;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* For a sublink this might cause an external mount */
|
|
|
306fa1 |
+ ret = do_mount(ap, ap->path,
|
|
|
306fa1 |
+ name, strlen(name), target, "bind", entry->opts);
|
|
|
306fa1 |
+ if (!ret)
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ debug(ap->logopt, MODPREFIX "bind mount failed, symlinking");
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+symlink:
|
|
|
306fa1 |
+ ret = do_mount(ap, ap->path,
|
|
|
306fa1 |
+ name, strlen(name), target, "bind", "symlink");
|
|
|
306fa1 |
+ if (!ret)
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "failed to symlink %s to %s", entry->path, target);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->sublink) {
|
|
|
306fa1 |
+ /* failed to complete sublink mount */
|
|
|
306fa1 |
+ if (ext_mount_remove(&entry->ext_mount, entry->fs))
|
|
|
306fa1 |
+ umount_ent(ap, entry->fs);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+out:
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int do_nfs_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ struct amd_entry *entry, unsigned int flags)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char target[PATH_MAX + 1];
|
|
|
306fa1 |
+ int ret = 0;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ strcpy(target, entry->rhost);
|
|
|
306fa1 |
+ strcat(target, ":");
|
|
|
306fa1 |
+ strcat(target, entry->rfs);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!entry->sublink) {
|
|
|
306fa1 |
+ ret = mount_nfs->mount_mount(ap, ap->path, name, strlen(name),
|
|
|
306fa1 |
+ target, entry->type, entry->opts,
|
|
|
306fa1 |
+ mount_nfs->context);
|
|
|
306fa1 |
+ } else {
|
|
|
306fa1 |
+ if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) {
|
|
|
306fa1 |
+ ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1,
|
|
|
306fa1 |
+ target, entry->type, entry->opts,
|
|
|
306fa1 |
+ mount_nfs->context);
|
|
|
306fa1 |
+ if (ret)
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ /* We might be using an external mount */
|
|
|
306fa1 |
+ ext_mount_add(&entry->ext_mount, entry->fs);
|
|
|
306fa1 |
+ ret = do_link_mount(ap, name, entry, flags);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+out:
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int do_host_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ struct amd_entry *entry, struct map_source *source,
|
|
|
306fa1 |
+ unsigned int flags)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct lookup_mod *lookup;
|
|
|
306fa1 |
+ struct mapent *me;
|
|
|
306fa1 |
+ const char *argv[2];
|
|
|
306fa1 |
+ int ret = 1;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ argv[0] = entry->opts;
|
|
|
306fa1 |
+ argv[1] = NULL;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ lookup = open_lookup("hosts", MODPREFIX, NULL, 1, argv);
|
|
|
306fa1 |
+ if (!lookup) {
|
|
|
306fa1 |
+ debug(ap->logopt, "open lookup module hosts failed");
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ me = cache_lookup_distinct(source->mc, name);
|
|
|
306fa1 |
+ if (me)
|
|
|
306fa1 |
+ cache_push_mapent(me, NULL);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ master_source_current_wait(ap->entry);
|
|
|
306fa1 |
+ ap->entry->current = source;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ close_lookup(lookup);
|
|
|
306fa1 |
+out:
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static int amd_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ struct amd_entry *entry, struct map_source *source,
|
|
|
306fa1 |
+ struct substvar *sv, unsigned int flags,
|
|
|
306fa1 |
+ struct parse_context *ctxt)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK;
|
|
|
306fa1 |
+ int ret = 1;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ switch (fstype) {
|
|
|
306fa1 |
+ case AMD_MOUNT_TYPE_AUTO:
|
|
|
306fa1 |
+ ret = do_auto_mount(ap, name, entry, flags);
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case AMD_MOUNT_TYPE_NFS:
|
|
|
306fa1 |
+ ret = do_nfs_mount(ap, name, entry, flags);
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case AMD_MOUNT_TYPE_LINK:
|
|
|
306fa1 |
+ ret = do_link_mount(ap, name, entry, flags);
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ case AMD_MOUNT_TYPE_HOST:
|
|
|
306fa1 |
+ ret = do_host_mount(ap, name, entry, source, flags);
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ default:
|
|
|
306fa1 |
+ info(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "unkown file system type %x", fstype);
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return ret;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+void dequote_entry(struct autofs_point *ap, struct amd_entry *entry)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *res;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->pref) {
|
|
|
306fa1 |
+ res = dequote(entry->pref, strlen(entry->pref), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "pref dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->pref), entry->pref, res);
|
|
|
306fa1 |
+ free(entry->pref);
|
|
|
306fa1 |
+ entry->pref = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->sublink) {
|
|
|
306fa1 |
+ res = dequote(entry->sublink, strlen(entry->sublink), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "sublink dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->sublink), entry->sublink, res);
|
|
|
306fa1 |
+ free(entry->sublink);
|
|
|
306fa1 |
+ entry->sublink = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->fs) {
|
|
|
306fa1 |
+ res = dequote(entry->fs, strlen(entry->fs), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "fs dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->fs), entry->fs, res);
|
|
|
306fa1 |
+ free(entry->fs);
|
|
|
306fa1 |
+ entry->fs = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->rfs) {
|
|
|
306fa1 |
+ res = dequote(entry->rfs, strlen(entry->rfs), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "rfs dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->rfs), entry->rfs, res);
|
|
|
306fa1 |
+ free(entry->rfs);
|
|
|
306fa1 |
+ entry->rfs = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->opts) {
|
|
|
306fa1 |
+ res = dequote(entry->opts, strlen(entry->opts), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "ops dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->opts), entry->opts, res);
|
|
|
306fa1 |
+ free(entry->opts);
|
|
|
306fa1 |
+ entry->opts = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->remopts) {
|
|
|
306fa1 |
+ res = dequote(entry->remopts, strlen(entry->remopts), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "remopts dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->remopts), entry->remopts, res);
|
|
|
306fa1 |
+ free(entry->remopts);
|
|
|
306fa1 |
+ entry->remopts = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->addopts) {
|
|
|
306fa1 |
+ res = dequote(entry->addopts, strlen(entry->addopts), ap->logopt);
|
|
|
306fa1 |
+ if (res) {
|
|
|
306fa1 |
+ debug(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "addopts dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->addopts), entry->addopts, res);
|
|
|
306fa1 |
+ free(entry->addopts);
|
|
|
306fa1 |
+ entry->addopts = res;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static void normalize_sublink(unsigned int logopt,
|
|
|
306fa1 |
+ struct amd_entry *entry, struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *new;
|
|
|
306fa1 |
+ size_t len;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (entry->sublink && *entry->sublink != '/') {
|
|
|
306fa1 |
+ len = strlen(entry->fs) + strlen(entry->sublink) + 2;
|
|
|
306fa1 |
+ new = malloc(len);
|
|
|
306fa1 |
+ if (!new) {
|
|
|
306fa1 |
+ error(logopt, MODPREFIX
|
|
|
306fa1 |
+ "error: couldn't allocate storage for sublink");
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ strcpy(new, entry->fs);
|
|
|
306fa1 |
+ strcat(new, "/");
|
|
|
306fa1 |
+ strcat(new, entry->sublink);
|
|
|
306fa1 |
+ debug(logopt, MODPREFIX
|
|
|
306fa1 |
+ "rfs dequote(\"%.*s\") -> %s",
|
|
|
306fa1 |
+ strlen(entry->sublink), entry->sublink, new);
|
|
|
306fa1 |
+ free(entry->sublink);
|
|
|
306fa1 |
+ entry->sublink = new;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ return;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct amd_entry *dup_defaults_entry(struct amd_entry *defaults)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct amd_entry *entry;
|
|
|
306fa1 |
+ char *tmp;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ entry = malloc(sizeof(struct amd_entry));
|
|
|
306fa1 |
+ if (!entry)
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+ memset(entry, 0, sizeof(struct amd_entry));
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ entry->flags = defaults->flags;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->type) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->type);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->type = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->map_type) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->map_type);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->map_type = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->pref) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->pref);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->pref = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->fs) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->fs);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->fs = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->rfs) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->rfs);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->rfs = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->rhost) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->rhost);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->rhost = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->opts) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->opts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->opts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->addopts) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->addopts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->addopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (defaults->remopts) {
|
|
|
306fa1 |
+ tmp = strdup(defaults->remopts);
|
|
|
306fa1 |
+ if (tmp)
|
|
|
306fa1 |
+ entry->remopts = tmp;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&entry->list);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return entry;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+struct amd_entry *make_default_entry(struct autofs_point *ap,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ char *defaults = "opts:=rw,defaults";
|
|
|
306fa1 |
+ struct amd_entry *defaults_entry;
|
|
|
306fa1 |
+ struct list_head dflts;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&dflts);
|
|
|
306fa1 |
+ if (amd_parse_list(ap, defaults, &dflts, &sv))
|
|
|
306fa1 |
+ return NULL;
|
|
|
306fa1 |
+ defaults_entry = list_entry(dflts.next, struct amd_entry, list);
|
|
|
306fa1 |
+ list_del_init(&defaults_entry->list);
|
|
|
306fa1 |
+ /* The list should now be empty .... */
|
|
|
306fa1 |
+ free_amd_entry_list(&dflts);
|
|
|
306fa1 |
+ return defaults_entry;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct amd_entry *select_default_entry(struct autofs_point *ap,
|
|
|
306fa1 |
+ struct list_head *entries,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ unsigned long flags = conf_amd_get_flags(ap->path);
|
|
|
306fa1 |
+ struct amd_entry *defaults_entry = NULL;
|
|
|
306fa1 |
+ struct amd_entry *entry_default = NULL;
|
|
|
306fa1 |
+ struct list_head *p, *head;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!(flags & CONF_SELECTORS_IN_DEFAULTS))
|
|
|
306fa1 |
+ goto no_sel;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ head = entries;
|
|
|
306fa1 |
+ p = head->next;
|
|
|
306fa1 |
+ while (p != head) {
|
|
|
306fa1 |
+ struct amd_entry *this = list_entry(p, struct amd_entry, list);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ p = p->next;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (this->flags & AMD_DEFAULTS_MERGE) {
|
|
|
306fa1 |
+ if (entry_default)
|
|
|
306fa1 |
+ free_amd_entry(entry_default);
|
|
|
306fa1 |
+ list_del_init(&this->list);
|
|
|
306fa1 |
+ entry_default = this;
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
+ } else if (this->flags & AMD_DEFAULTS_RESET) {
|
|
|
306fa1 |
+ struct amd_entry *new;
|
|
|
306fa1 |
+ new = dup_defaults_entry(defaults_entry);
|
|
|
306fa1 |
+ if (new) {
|
|
|
306fa1 |
+ free_amd_entry(entry_default);
|
|
|
306fa1 |
+ entry_default = new;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ list_del_init(&this->list);
|
|
|
306fa1 |
+ free_amd_entry(this);
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ /* Not strickly amd semantics but ... */
|
|
|
306fa1 |
+ if (!defaults_entry && entry_default) {
|
|
|
306fa1 |
+ defaults_entry = entry_default;
|
|
|
306fa1 |
+ goto done;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!defaults_entry) {
|
|
|
306fa1 |
+ debug(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "no matching selector(s) found in defaults, "
|
|
|
306fa1 |
+ "using internal defaults");
|
|
|
306fa1 |
+ goto ret_default;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ goto done;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+no_sel:
|
|
|
306fa1 |
+ if (list_empty(entries))
|
|
|
306fa1 |
+ goto ret_default;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ defaults_entry = list_entry(entries->next, struct amd_entry, list);
|
|
|
306fa1 |
+ list_del_init(&defaults_entry->list);
|
|
|
306fa1 |
+ if (!list_empty(entries)) {
|
|
|
306fa1 |
+ free_amd_entry(defaults_entry);
|
|
|
306fa1 |
+ goto ret_default;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+done:
|
|
|
306fa1 |
+ /*merge_entry_options(ap, defaults_entry, sv);*/
|
|
|
306fa1 |
+ /*normalize_sublink(ap->logopt, defaults_entry, sv);*/
|
|
|
306fa1 |
+ return defaults_entry;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ret_default:
|
|
|
306fa1 |
+ return make_default_entry(ap, sv);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+static struct amd_entry *get_defaults_entry(struct autofs_point *ap,
|
|
|
306fa1 |
+ const char *defaults,
|
|
|
306fa1 |
+ struct substvar *sv)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct amd_entry *entry;
|
|
|
306fa1 |
+ struct list_head dflts;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&dflts);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ entry = NULL;
|
|
|
306fa1 |
+ if (!defaults)
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ char *expand;
|
|
|
306fa1 |
+ if (!expand_selectors(ap, defaults, &expand, sv))
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ if (amd_parse_list(ap, expand, &dflts, &sv))
|
|
|
306fa1 |
+ goto out;
|
|
|
306fa1 |
+ entry = select_default_entry(ap, &dflts, sv);
|
|
|
306fa1 |
+ free(expand);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return entry;
|
|
|
306fa1 |
+out:
|
|
|
306fa1 |
+ return make_default_entry(ap, sv);
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int parse_mount(struct autofs_point *ap, const char *name,
|
|
|
306fa1 |
+ int name_len, const char *mapent, void *context)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ struct parse_context *ctxt = (struct parse_context *) context;
|
|
|
306fa1 |
+ unsigned int flags = conf_amd_get_flags(ap->path);
|
|
|
306fa1 |
+ struct substvar *sv = NULL;
|
|
|
306fa1 |
+ struct map_source *source;
|
|
|
306fa1 |
+ struct mapent_cache *mc;
|
|
|
306fa1 |
+ struct mapent *me;
|
|
|
306fa1 |
+ struct list_head entries, *p, *head;
|
|
|
306fa1 |
+ struct amd_entry *defaults_entry;
|
|
|
306fa1 |
+ struct amd_entry *cur_defaults;
|
|
|
306fa1 |
+ char *defaults;
|
|
|
306fa1 |
+ char *pmapent;
|
|
|
306fa1 |
+ int len, rv = 1;
|
|
|
306fa1 |
+ int cur_state;
|
|
|
306fa1 |
+ int ret;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ source = ap->entry->current;
|
|
|
306fa1 |
+ ap->entry->current = NULL;
|
|
|
306fa1 |
+ master_source_current_signal(ap->entry);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ mc = source->mc;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (!mapent) {
|
|
|
306fa1 |
+ warn(ap->logopt, MODPREFIX "error: empty map entry");
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ len = expand_selectors(ap, mapent, &pmapent, sv);
|
|
|
306fa1 |
+ if (!len) {
|
|
|
306fa1 |
+ macro_free_table(sv);
|
|
|
306fa1 |
+ pthread_setcancelstate(cur_state, NULL);
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ pthread_setcancelstate(cur_state, NULL);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ debug(ap->logopt, MODPREFIX "expanded mapent: %s", pmapent);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ defaults = conf_amd_get_map_defaults(ap->path);
|
|
|
306fa1 |
+ if (defaults) {
|
|
|
306fa1 |
+ debug(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "using map_defaults %s for %s", defaults, ap->path);
|
|
|
306fa1 |
+ } else if ((me = cache_lookup_distinct(mc, "/defaults"))) {
|
|
|
306fa1 |
+ defaults = strdup(me->mapent);
|
|
|
306fa1 |
+ if (defaults)
|
|
|
306fa1 |
+ debug(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "using /defaults %s from map", defaults);
|
|
|
306fa1 |
+ else {
|
|
|
306fa1 |
+ char buf[MAX_ERR_BUF];
|
|
|
306fa1 |
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ defaults_entry = get_defaults_entry(ap, defaults, sv);
|
|
|
306fa1 |
+ if (!defaults_entry) {
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "failed to get a defaults entry");
|
|
|
306fa1 |
+ if (defaults)
|
|
|
306fa1 |
+ free(defaults);
|
|
|
306fa1 |
+ free(pmapent);
|
|
|
306fa1 |
+ macro_free_table(sv);
|
|
|
306fa1 |
+ return 1;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ if (defaults)
|
|
|
306fa1 |
+ free(defaults);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ INIT_LIST_HEAD(&entries);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ ret = amd_parse_list(ap, pmapent, &entries, &sv;;
|
|
|
306fa1 |
+ if (ret) {
|
|
|
306fa1 |
+ error(ap->logopt,
|
|
|
306fa1 |
+ MODPREFIX "failed to parse entry: %s", pmapent);
|
|
|
306fa1 |
+ free(pmapent);
|
|
|
306fa1 |
+ goto done;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ free(pmapent);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (list_empty(&entries)) {
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX "no location found after parse");
|
|
|
306fa1 |
+ goto done;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ cur_defaults = dup_defaults_entry(defaults_entry);
|
|
|
306fa1 |
+ if (!cur_defaults) {
|
|
|
306fa1 |
+ error(ap->logopt, MODPREFIX
|
|
|
306fa1 |
+ "failed to duplicate defaults entry");
|
|
|
306fa1 |
+ goto done;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ head = &entries;
|
|
|
306fa1 |
+ p = head->next;
|
|
|
306fa1 |
+ while (p != head) {
|
|
|
306fa1 |
+ struct amd_entry *this = list_entry(p, struct amd_entry, list);
|
|
|
306fa1 |
+ p = p->next;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (this->flags & AMD_DEFAULTS_MERGE) {
|
|
|
306fa1 |
+ free_amd_entry(cur_defaults);
|
|
|
306fa1 |
+ list_del_init(&this->list);
|
|
|
306fa1 |
+ cur_defaults = this;
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
+ } else if (this->flags & AMD_DEFAULTS_RESET) {
|
|
|
306fa1 |
+ struct amd_entry *new;
|
|
|
306fa1 |
+ new = dup_defaults_entry(defaults_entry);
|
|
|
306fa1 |
+ if (new) {
|
|
|
306fa1 |
+ free_amd_entry(cur_defaults);
|
|
|
306fa1 |
+ cur_defaults = new;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ list_del_init(&this->list);
|
|
|
306fa1 |
+ free_amd_entry(this);
|
|
|
306fa1 |
+ continue;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ update_with_defaults(cur_defaults, this, sv);
|
|
|
306fa1 |
+ sv = expand_entry(ap, this, flags, sv);
|
|
|
306fa1 |
+ sv = merge_entry_options(ap, this, sv);
|
|
|
306fa1 |
+ normalize_sublink(ap->logopt, this, sv);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ dequote_entry(ap, this);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ rv = amd_mount(ap, name, this, source, sv, flags, ctxt);
|
|
|
306fa1 |
+ if (!rv)
|
|
|
306fa1 |
+ break;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ free_amd_entry(cur_defaults);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ if (rv)
|
|
|
306fa1 |
+ debug(ap->logopt, "no more locations to try, returning fail");
|
|
|
306fa1 |
+done:
|
|
|
306fa1 |
+ free_amd_entry_list(&entries);
|
|
|
306fa1 |
+ free_amd_entry(defaults_entry);
|
|
|
306fa1 |
+ macro_free_table(sv);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return rv;
|
|
|
306fa1 |
+}
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+int parse_done(void *context)
|
|
|
306fa1 |
+{
|
|
|
306fa1 |
+ int rv = 0;
|
|
|
306fa1 |
+ struct parse_context *ctxt = (struct parse_context *) context;
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ instance_mutex_lock();
|
|
|
306fa1 |
+ if (--init_ctr == 0) {
|
|
|
306fa1 |
+ rv = close_mount(mount_nfs);
|
|
|
306fa1 |
+ mount_nfs = NULL;
|
|
|
306fa1 |
+ }
|
|
|
306fa1 |
+ instance_mutex_unlock();
|
|
|
306fa1 |
+ if (ctxt)
|
|
|
306fa1 |
+ kill_context(ctxt);
|
|
|
306fa1 |
+
|
|
|
306fa1 |
+ return rv;
|
|
|
306fa1 |
+}
|