Blame lib/master_parse.y

Packit 8480eb
%{
Packit 8480eb
/* ----------------------------------------------------------------------- *
Packit 8480eb
 *   
Packit 8480eb
 *  master_parser.y - master map buffer parser.
Packit 8480eb
 *
Packit 8480eb
 *   Copyright 2006 Ian Kent <raven@themaw.net>
Packit 8480eb
 *
Packit 8480eb
 *   This program is free software; you can redistribute it and/or modify
Packit 8480eb
 *   it under the terms of the GNU General Public License as published by
Packit 8480eb
 *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
Packit 8480eb
 *   USA; either version 2 of the License, or (at your option) any later
Packit 8480eb
 *   version.
Packit 8480eb
 *   
Packit 8480eb
 *   This program is distributed in the hope that it will be useful,
Packit 8480eb
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8480eb
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8480eb
 *   GNU General Public License for more details.
Packit 8480eb
 *
Packit 8480eb
 * ----------------------------------------------------------------------- */
Packit 8480eb
Packit 8480eb
#include <stdio.h>
Packit 8480eb
#include <string.h>
Packit 8480eb
#include <stdlib.h>
Packit 8480eb
#include <stdarg.h>
Packit 8480eb
#include <ctype.h>
Packit 8480eb
#include <sys/ioctl.h>
Packit 8480eb
Packit 8480eb
#include "automount.h"
Packit 8480eb
#include "master.h"
Packit 8480eb
Packit 8480eb
#define MAX_ERR_LEN	512
Packit 8480eb
Packit 8480eb
extern struct master *master_list;
Packit 8480eb
Packit 8480eb
char **add_argv(int, char **, char *);
Packit 8480eb
const char **copy_argv(int, const char **);
Packit 8480eb
int free_argv(int, const char **);
Packit 8480eb
Packit 8480eb
extern FILE *master_in;
Packit 8480eb
extern char *master_text;
Packit 8480eb
extern int master_lex(void);
Packit 8480eb
extern int master_lineno;
Packit 8480eb
extern void master_set_scan_buffer(const char *);
Packit 8480eb
Packit 8480eb
static char *master_strdup(char *);
Packit 8480eb
static void local_init_vars(void);
Packit 8480eb
static void local_free_vars(void);
Packit 8480eb
static void trim_maptype(char *);
Packit 8480eb
static int add_multi_mapstr(void);
Packit 8480eb
Packit 8480eb
static int master_error(const char *s);
Packit 8480eb
static int master_notify(const char *s);
Packit 8480eb
static int master_msg(const char *s);
Packit 8480eb
 
Packit 8480eb
static char *path;
Packit 8480eb
static char *type;
Packit 8480eb
static char *format;
Packit 8480eb
static long timeout;
Packit 8480eb
static long negative_timeout;
Packit 8480eb
static unsigned symlnk;
Packit 8480eb
static unsigned nobind;
Packit 8480eb
static unsigned ghost;
Packit 8480eb
extern unsigned global_selection_options;
Packit 8480eb
static unsigned random_selection;
Packit 8480eb
static unsigned use_weight;
Packit 8480eb
static unsigned long mode;
Packit 8480eb
static char **tmp_argv;
Packit 8480eb
static int tmp_argc;
Packit 8480eb
static char **local_argv;
Packit 8480eb
static int local_argc;
Packit 8480eb
Packit 8480eb
static char errstr[MAX_ERR_LEN];
Packit 8480eb
Packit 8480eb
static unsigned int verbose;
Packit 8480eb
static unsigned int debug;
Packit 8480eb
Packit 8480eb
static int lineno;
Packit 8480eb
Packit 8480eb
#define YYDEBUG 0
Packit 8480eb
Packit 8480eb
#ifndef YYENABLE_NLS
Packit 8480eb
#define YYENABLE_NLS 0
Packit 8480eb
#endif
Packit 8480eb
#ifndef YYLTYPE_IS_TRIVIAL
Packit 8480eb
#define YYLTYPE_IS_TRIVIAL 0
Packit 8480eb
#endif
Packit 8480eb
Packit 8480eb
#if YYDEBUG
Packit 8480eb
static int master_fprintf(FILE *, char *, ...);
Packit 8480eb
#undef YYFPRINTF
Packit 8480eb
#define YYFPRINTF master_fprintf
Packit 8480eb
#endif
Packit 8480eb
Packit 8480eb
%}
Packit 8480eb
Packit 8480eb
%union {
Packit 8480eb
	char strtype[2048];
Packit 8480eb
	int inttype;
Packit 8480eb
	long longtype;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
%token COMMENT
Packit 8480eb
%token MAP
Packit 8480eb
%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
Packit 8480eb
%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE
Packit 8480eb
%token COLON COMMA NL DDASH
Packit 8480eb
%type <strtype> map
Packit 8480eb
%type <strtype> options
Packit 8480eb
%type <strtype> dn
Packit 8480eb
%type <strtype> dnattrs
Packit 8480eb
%type <strtype> dnattr
Packit 8480eb
%type <strtype> option
Packit 8480eb
%type <strtype> daemon_option
Packit 8480eb
%type <strtype> mount_option
Packit 8480eb
%token <strtype> PATH
Packit 8480eb
%token <strtype> QUOTE
Packit 8480eb
%token <strtype> NILL
Packit 8480eb
%token <strtype> SPACE
Packit 8480eb
%token <strtype> EQUAL
Packit 8480eb
%token <strtype> MULTITYPE
Packit 8480eb
%token <strtype> MAPTYPE
Packit 8480eb
%token <strtype> DNSERVER
Packit 8480eb
%token <strtype> DNATTR
Packit 8480eb
%token <strtype> DNNAME
Packit 8480eb
%token <strtype> MAPHOSTS
Packit 8480eb
%token <strtype> MAPNULL
Packit 8480eb
%token <strtype> MAPXFN
Packit 8480eb
%token <strtype> MAPNAME
Packit 8480eb
%token <longtype> NUMBER
Packit 8480eb
%token <longtype> OCTALNUMBER
Packit 8480eb
%token <strtype> OPTION
Packit 8480eb
Packit 8480eb
%start file
Packit 8480eb
Packit 8480eb
%%
Packit 8480eb
Packit 8480eb
file: {
Packit 8480eb
		master_lineno = 0;
Packit 8480eb
#if YYDEBUG != 0
Packit 8480eb
		master_debug = YYDEBUG;
Packit 8480eb
#endif
Packit 8480eb
	} line
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
line:
Packit 8480eb
	| PATH mapspec
Packit 8480eb
	{
Packit 8480eb
		path = master_strdup($1);
Packit 8480eb
		if (!path) {
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| PATH MULTITYPE maplist
Packit 8480eb
	{
Packit 8480eb
		char *tmp = NULL;
Packit 8480eb
Packit 8480eb
		trim_maptype($2);
Packit 8480eb
Packit 8480eb
		path = master_strdup($1);
Packit 8480eb
		if (!path) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
Packit 8480eb
		if ((tmp = strchr($2, ',')))
Packit 8480eb
			*tmp++ = '\0';
Packit Service 71cd40
Packit 8480eb
		type = master_strdup($2);
Packit 8480eb
		if (!type) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (tmp) {
Packit 8480eb
			format = master_strdup(tmp);
Packit 8480eb
			if (!format) {
Packit 8480eb
				master_error("memory allocation error");
Packit 8480eb
				local_free_vars();
Packit 8480eb
				YYABORT;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| PATH COLON { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPTION { master_notify($2); YYABORT; }
Packit 8480eb
	| PATH NILL { master_notify($2); YYABORT; }
Packit 8480eb
	| PATH OPT_RANDOM { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_DEBUG { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_SYMLINK { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_NOBIND { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_GHOST { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_NOGHOST { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_VERBOSE { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH OPT_MODE { master_notify($1); YYABORT; }
Packit 8480eb
	| PATH { master_notify($1); YYABORT; }
Packit 8480eb
	| QUOTE { master_notify($1); YYABORT; }
Packit 8480eb
	| OPTION { master_notify($1); YYABORT; }
Packit 8480eb
	| NILL { master_notify($1); YYABORT; }
Packit 8480eb
	| COMMENT { YYABORT; }
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
mapspec: map
Packit 8480eb
	{
Packit 8480eb
		local_argc = tmp_argc;
Packit 8480eb
		local_argv = tmp_argv;
Packit 8480eb
		tmp_argc = 0;
Packit 8480eb
		tmp_argv = NULL;
Packit 8480eb
	}
Packit 8480eb
	| map options
Packit 8480eb
	{
Packit 8480eb
		local_argc = tmp_argc;
Packit 8480eb
		local_argv = tmp_argv;
Packit 8480eb
		tmp_argc = 0;
Packit 8480eb
		tmp_argv = NULL;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
maplist: map
Packit 8480eb
	{
Packit 8480eb
		if (!add_multi_mapstr()) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| map options
Packit 8480eb
	{
Packit 8480eb
		if (!add_multi_mapstr()) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| maplist DDASH map
Packit 8480eb
	{
Packit 8480eb
		local_argc++;
Packit 8480eb
		local_argv = add_argv(local_argc, local_argv, "--");
Packit 8480eb
		if (!local_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (!add_multi_mapstr()) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| maplist DDASH map options
Packit 8480eb
	{
Packit 8480eb
		local_argc++;
Packit 8480eb
		local_argv = add_argv(local_argc, local_argv, "--");
Packit 8480eb
		if (!local_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (!add_multi_mapstr()) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
map:	PATH
Packit 8480eb
	{
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPNAME
Packit 8480eb
	{
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPHOSTS
Packit 8480eb
	{
Packit 8480eb
		type = master_strdup($1 + 1);
Packit 8480eb
		if (!type) {
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPXFN
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		master_msg("X/Open Federated Naming service not supported");
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	| MAPNULL
Packit 8480eb
	{
Packit 8480eb
		type = master_strdup($1 + 1);
Packit 8480eb
		if (!type) {
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| dnattrs
Packit 8480eb
	{
Packit 8480eb
		type = master_strdup("ldap");
Packit 8480eb
		if (!type) {
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPTYPE PATH
Packit 8480eb
	{
Packit 8480eb
		char *tmp = NULL;
Packit 8480eb
Packit 8480eb
		trim_maptype($1);
Packit 8480eb
Packit 8480eb
		if ((tmp = strchr($1, ',')))
Packit 8480eb
			*tmp++ = '\0';
Packit Service 71cd40
Packit 8480eb
		if (strcmp($1, "exec"))
Packit 8480eb
			type = master_strdup($1);
Packit 8480eb
		else
Packit 8480eb
			type = master_strdup("program");
Packit 8480eb
		if (!type) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (tmp) {
Packit 8480eb
			format = master_strdup(tmp);
Packit 8480eb
			if (!format) {
Packit 8480eb
				master_error("memory allocation error");
Packit 8480eb
				local_free_vars();
Packit 8480eb
				YYABORT;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPTYPE MAPNAME
Packit 8480eb
	{
Packit 8480eb
		char *tmp = NULL;
Packit 8480eb
Packit 8480eb
		trim_maptype($1);
Packit 8480eb
Packit 8480eb
		if ((tmp = strchr($1, ',')))
Packit 8480eb
			*tmp++ = '\0';
Packit 8480eb
Packit 8480eb
		if (strcmp($1, "exec"))
Packit 8480eb
			type = master_strdup($1);
Packit 8480eb
		else
Packit 8480eb
			type = master_strdup("program");
Packit 8480eb
		if (!type) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (tmp) {
Packit 8480eb
			format = master_strdup(tmp);
Packit 8480eb
			if (!format) {
Packit 8480eb
				master_error("memory allocation error");
Packit 8480eb
				local_free_vars();
Packit 8480eb
				YYABORT;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	| MAPTYPE dn
Packit 8480eb
	{
Packit 8480eb
		char *tmp = NULL;
Packit 8480eb
Packit 8480eb
		trim_maptype($1);
Packit 8480eb
Packit 8480eb
		if ((tmp = strchr($1, ',')))
Packit 8480eb
			*tmp++ = '\0';
Packit 8480eb
Packit 8480eb
		if (strcmp($1, "exec"))
Packit 8480eb
			type = master_strdup($1);
Packit 8480eb
		else
Packit 8480eb
			type = master_strdup("program");
Packit 8480eb
		if (!type) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		if (tmp) {
Packit 8480eb
			format = master_strdup(tmp);
Packit 8480eb
			if (!format) {
Packit 8480eb
				master_error("memory allocation error");
Packit 8480eb
				local_free_vars();
Packit 8480eb
				YYABORT;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $2);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		/* Add back the type for lookup_ldap.c to handle ldaps */
Packit 8480eb
		if (*tmp_argv[0]) {
Packit 8480eb
			tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2);
Packit 8480eb
			if (!tmp) {
Packit 8480eb
				master_error("memory allocation error");
Packit 8480eb
				local_free_vars();
Packit 8480eb
				YYABORT;
Packit 8480eb
			}
Packit 8480eb
			strcpy(tmp, type);
Packit 8480eb
			strcat(tmp, ":");
Packit 8480eb
			strcat(tmp, tmp_argv[0]);
Packit 8480eb
			free(tmp_argv[0]);
Packit 8480eb
			tmp_argv[0] = tmp;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
dn:	DNSERVER dnattrs
Packit 8480eb
	{
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
		strcat($$, $2);
Packit 8480eb
	}
Packit 8480eb
	| dnattrs
Packit 8480eb
	{
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
	}
Packit 8480eb
	|
Packit 8480eb
	{
Packit 8480eb
		master_notify("syntax error in dn");
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
dnattrs: DNATTR EQUAL DNNAME
Packit 8480eb
	{
Packit 8480eb
		if (strcasecmp($1, "cn") &&
Packit 8480eb
		    strcasecmp($1, "ou") &&
Packit 8480eb
		    strcasecmp($1, "automountMapName") &&
Packit 8480eb
		    strcasecmp($1, "nisMapName")) {
Packit 8480eb
			strcpy(errstr, $1);
Packit 8480eb
			strcat(errstr, "=");
Packit 8480eb
			strcat(errstr, $3);
Packit 8480eb
			master_notify(errstr);
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
		strcat($$, "=");
Packit 8480eb
		strcat($$, $3);
Packit 8480eb
	}
Packit 8480eb
	| DNATTR EQUAL DNNAME COMMA dnattr
Packit 8480eb
	{
Packit 8480eb
		if (strcasecmp($1, "cn") &&
Packit 8480eb
		    strcasecmp($1, "ou") &&
Packit 8480eb
		    strcasecmp($1, "automountMapName") &&
Packit 8480eb
		    strcasecmp($1, "nisMapName")) {
Packit 8480eb
			strcpy(errstr, $1);
Packit 8480eb
			strcat(errstr, "=");
Packit 8480eb
			strcat(errstr, $3);
Packit 8480eb
			master_notify(errstr);
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
		strcat($$, "=");
Packit 8480eb
		strcat($$, $3);
Packit 8480eb
		strcat($$, ",");
Packit 8480eb
		strcat($$, $5);
Packit 8480eb
	}
Packit 8480eb
	| DNNAME
Packit 8480eb
	{
Packit 8480eb
		/* Matches map in old style syntax ldap:server:map */
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
	}
Packit 8480eb
	| DNATTR
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
dnattr: DNATTR EQUAL DNNAME
Packit 8480eb
	{
Packit 8480eb
		if (!strcasecmp($1, "automountMapName") ||
Packit 8480eb
		    !strcasecmp($1, "nisMapName")) {
Packit 8480eb
			strcpy(errstr, $1);
Packit 8480eb
			strcat(errstr, "=");
Packit 8480eb
			strcat(errstr, $3);
Packit 8480eb
			master_notify(errstr);
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
		strcat($$, "=");
Packit 8480eb
		strcat($$, $3);
Packit 8480eb
	}
Packit 8480eb
	| DNATTR EQUAL DNNAME COMMA dnattr
Packit 8480eb
	{
Packit 8480eb
		if (!strcasecmp($1, "automountMapName") ||
Packit 8480eb
		    !strcasecmp($1, "nisMapName")) {
Packit 8480eb
			strcpy(errstr, $1);
Packit 8480eb
			strcat(errstr, "=");
Packit 8480eb
			strcat(errstr, $3);
Packit 8480eb
			master_notify(errstr);
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
		strcpy($$, $1);
Packit 8480eb
		strcat($$, "=");
Packit 8480eb
		strcat($$, $3);
Packit 8480eb
		strcat($$, ",");
Packit 8480eb
		strcat($$, $5);
Packit 8480eb
	}
Packit 8480eb
	| DNATTR
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	| DNNAME
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
options: option {}
Packit 8480eb
	| options COMMA option {}
Packit 8480eb
	| options option {}
Packit 8480eb
	| options COMMA COMMA option
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	| options EQUAL
Packit 8480eb
	{
Packit 8480eb
		master_notify($1);
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
option: daemon_option
Packit 8480eb
	| mount_option {}
Packit 8480eb
	| error
Packit 8480eb
	{
Packit 8480eb
		master_notify("bogus option");
Packit 8480eb
		YYABORT;
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
Packit 8480eb
	| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
Packit 8480eb
	| OPT_SYMLINK	{ symlnk = 1; }
Packit 8480eb
	| OPT_NOBIND	{ nobind = 1; }
Packit 8480eb
	| OPT_NOGHOST	{ ghost = 0; }
Packit 8480eb
	| OPT_GHOST	{ ghost = 1; }
Packit 8480eb
	| OPT_VERBOSE	{ verbose = 1; }
Packit 8480eb
	| OPT_DEBUG	{ debug = 1; }
Packit 8480eb
	| OPT_RANDOM	{ random_selection = 1; }
Packit 8480eb
	| OPT_USE_WEIGHT { use_weight = 1; }
Packit 8480eb
	| OPT_MODE OCTALNUMBER { mode = $2; }
Packit 8480eb
	;
Packit 8480eb
Packit 8480eb
mount_option: OPTION
Packit 8480eb
	{
Packit 8480eb
		tmp_argc++;
Packit 8480eb
		tmp_argv = add_argv(tmp_argc, tmp_argv, $1);
Packit 8480eb
		if (!tmp_argv) {
Packit 8480eb
			master_error("memory allocation error");
Packit 8480eb
			local_free_vars();
Packit 8480eb
			YYABORT;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	;
Packit 8480eb
%%
Packit 8480eb
Packit 8480eb
#if YYDEBUG
Packit 8480eb
static int master_fprintf(FILE *f, char *msg, ...)
Packit 8480eb
{
Packit 8480eb
	va_list ap;
Packit 8480eb
	va_start(ap, msg);
Packit 8480eb
	vsyslog(LOG_DEBUG, msg, ap);
Packit 8480eb
	va_end(ap);
Packit 8480eb
	return 1;
Packit 8480eb
}
Packit 8480eb
#endif
Packit 8480eb
Packit 8480eb
static char *master_strdup(char *str)
Packit 8480eb
{
Packit 8480eb
	char *tmp;
Packit 8480eb
Packit 8480eb
	tmp = strdup(str);
Packit 8480eb
	if (!tmp)
Packit 8480eb
		master_error("memory allocation error");
Packit 8480eb
	return tmp;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static int master_error(const char *s)
Packit 8480eb
{
Packit 8480eb
	logmsg("%s while parsing map.", s);
Packit 8480eb
	return 0;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static int master_notify(const char *s)
Packit 8480eb
{
Packit 8480eb
	logmsg("syntax error in map near [ %s ]", s);
Packit 8480eb
	return(0);
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static int master_msg(const char *s)
Packit 8480eb
{
Packit 8480eb
	logmsg("%s", s);
Packit 8480eb
	return 0;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void local_init_vars(void)
Packit 8480eb
{
Packit 8480eb
	path = NULL;
Packit 8480eb
	type = NULL;
Packit 8480eb
	format = NULL;
Packit 8480eb
	verbose = 0;
Packit 8480eb
	debug = 0;
Packit 8480eb
	timeout = -1;
Packit 8480eb
	negative_timeout = 0;
Packit 8480eb
	symlnk = 0;
Packit 8480eb
	nobind = 0;
Packit 8480eb
	ghost = defaults_get_browse_mode();
Packit 8480eb
	random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
Packit 8480eb
	use_weight = 0;
Packit 8480eb
	mode = 0;
Packit 8480eb
	tmp_argv = NULL;
Packit 8480eb
	tmp_argc = 0;
Packit 8480eb
	local_argv = NULL;
Packit 8480eb
	local_argc = 0;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void local_free_vars(void)
Packit 8480eb
{
Packit 8480eb
	if (path)
Packit 8480eb
		free(path);
Packit 8480eb
Packit 8480eb
	if (type)
Packit 8480eb
		free(type);
Packit 8480eb
Packit 8480eb
	if (format)
Packit 8480eb
		free(format);
Packit 8480eb
Packit 8480eb
	if (local_argv) {
Packit 8480eb
		free_argv(local_argc, (const char **) local_argv);
Packit 8480eb
		local_argv = NULL;
Packit 8480eb
		local_argc = 0;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (tmp_argv) {
Packit 8480eb
		free_argv(tmp_argc, (const char **) tmp_argv);
Packit 8480eb
		tmp_argv = NULL;
Packit 8480eb
		tmp_argc = 0;
Packit 8480eb
	}
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static void trim_maptype(char *type)
Packit 8480eb
{
Packit 8480eb
	char *tmp;
Packit 8480eb
Packit 8480eb
	tmp = strchr(type, ':');
Packit 8480eb
	if (tmp)
Packit 8480eb
		*tmp = '\0';
Packit 8480eb
	else {
Packit 8480eb
		int len = strlen(type);
Packit 8480eb
		while (len-- && isblank(type[len]))
Packit 8480eb
			type[len] = '\0';
Packit 8480eb
	}
Packit 8480eb
	return;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
static int add_multi_mapstr(void)
Packit 8480eb
{
Packit 8480eb
	if (type) {
Packit 8480eb
		/* If type given and format is non-null add it back */
Packit 8480eb
		if (format) {
Packit 8480eb
			int len = strlen(type) + strlen(format) + 2;
Packit 8480eb
			char *tmp = realloc(type, len);
Packit 8480eb
			if (!tmp)
Packit 8480eb
				return 0;
Packit 8480eb
			type = tmp;
Packit 8480eb
			strcat(type, ",");
Packit 8480eb
			strcat(type, format);
Packit 8480eb
			free(format);
Packit 8480eb
			format = NULL;
Packit 8480eb
		}
Packit 8480eb
Packit 8480eb
		local_argc++;
Packit 8480eb
		local_argv = add_argv(local_argc, local_argv, type);
Packit 8480eb
		if (!local_argv) {
Packit 8480eb
			free(type);
Packit 8480eb
			type = NULL;
Packit 8480eb
			return 0;
Packit 8480eb
		}
Packit 8480eb
Packit 8480eb
		free(type);
Packit 8480eb
		type = NULL;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv);
Packit 8480eb
	if (!local_argv) {
Packit 8480eb
		free(type);
Packit 8480eb
		type = NULL;
Packit 8480eb
		return 0;
Packit 8480eb
	}
Packit 8480eb
	local_argc += tmp_argc;
Packit 8480eb
Packit 8480eb
	tmp_argc = 0;
Packit 8480eb
	tmp_argv = NULL;
Packit 8480eb
Packit 8480eb
	return 1;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
void master_init_scan(void)
Packit 8480eb
{
Packit 8480eb
	lineno = 0;
Packit 8480eb
}
Packit 8480eb
Packit 8480eb
int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigned int logging, time_t age)
Packit 8480eb
{
Packit 8480eb
	struct master *master = master_list;
Packit 8480eb
	struct mapent_cache *nc;
Packit 8480eb
	struct master_mapent *entry, *new;
Packit 8480eb
	struct map_source *source;
Packit 8480eb
	unsigned int logopt = logging;
Packit 8480eb
	unsigned int m_logopt = master->logopt;
Packit 8480eb
	int ret;
Packit 8480eb
Packit 8480eb
	local_init_vars();
Packit 8480eb
Packit 8480eb
	lineno++;
Packit 8480eb
Packit 8480eb
	master_set_scan_buffer(buffer);
Packit 8480eb
Packit 8480eb
	ret = master_parse();
Packit 8480eb
	if (ret != 0) {
Packit 8480eb
		local_free_vars();
Packit 8480eb
		return 0;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	nc = master->nc;
Packit 8480eb
Packit 8480eb
	/* Add null map entries to the null map cache */
Packit 8480eb
	if (type && !strcmp(type, "null")) {
Packit 8480eb
		cache_update(nc, NULL, path, NULL, lineno);
Packit 8480eb
		local_free_vars();
Packit 8480eb
		return 1;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	/* Ignore all subsequent matching nulled entries */
Packit 8480eb
	if (cache_lookup_distinct(nc, path)) {
Packit 8480eb
		local_free_vars();
Packit 8480eb
		return 1;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (debug || verbose) {
Packit 8480eb
		logopt = (debug ? LOGOPT_DEBUG : 0);
Packit 8480eb
		logopt |= (verbose ? LOGOPT_VERBOSE : 0);
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	new = NULL;
Packit 8480eb
	entry = master_find_mapent(master, path);
Packit 8480eb
	if (!entry) {
Packit 8480eb
		new = master_new_mapent(master, path, age);
Packit 8480eb
		if (!new) {
Packit 8480eb
			local_free_vars();
Packit 8480eb
			return 0;
Packit 8480eb
		}
Packit 8480eb
		entry = new;
Packit 8480eb
	} else {
Packit 8480eb
		if (entry->age && entry->age == age) {
Packit 8480eb
			if (strcmp(path, "/-")) {
Packit 8480eb
				info(m_logopt,
Packit 8480eb
				    "ignoring duplicate indirect mount %s",
Packit 8480eb
				     path);
Packit 8480eb
				local_free_vars();
Packit 8480eb
				return 0;
Packit 8480eb
			}
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (!format) {
Packit 8480eb
		if (conf_amd_mount_section_exists(path))
Packit 8480eb
			format = strdup("amd");
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (format && !strcmp(format, "amd")) {
Packit 8480eb
		unsigned int loglevel = conf_amd_get_log_options();
Packit 8480eb
		unsigned int flags = conf_amd_get_flags(path);
Packit 8480eb
Packit 8480eb
		if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO)
Packit 8480eb
			logopt = LOGOPT_DEBUG;
Packit 8480eb
		else if (loglevel <= LOG_INFO && loglevel > LOG_ERR)
Packit 8480eb
			logopt = LOGOPT_VERBOSE;
Packit 8480eb
Packit 8480eb
		/* It isn't possible to provide the fullybrowsable amd
Packit 8480eb
		 * browsing functionality within the autofs framework.
Packit 8480eb
		 * This flag will not be set if browsable_dirs = full
Packit 8480eb
		 * in the configuration or fullybrowsable is present as
Packit 8480eb
		 * an option.
Packit 8480eb
		 */
Packit 8480eb
		if (flags & CONF_BROWSABLE_DIRS)
Packit 8480eb
			ghost = 1;
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
Packit 8480eb
	if (!entry->ap) {
Packit 8480eb
		ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0);
Packit 8480eb
		if (!ret) {
Packit 8480eb
			error(m_logopt, "failed to add autofs_point");
Packit 8480eb
			if (new)
Packit 8480eb
				master_free_mapent(new);
Packit 8480eb
			local_free_vars();
Packit 8480eb
			return 0;
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
	if (random_selection)
Packit 8480eb
		entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
Packit 8480eb
	if (use_weight)
Packit 8480eb
		entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
Packit 8480eb
	if (symlnk)
Packit 8480eb
		entry->ap->flags |= MOUNT_FLAG_SYMLINK;
Packit 8480eb
	if (negative_timeout)
Packit 8480eb
		entry->ap->negative_timeout = negative_timeout;
Packit 8480eb
	if (mode && mode < LONG_MAX)
Packit 8480eb
		entry->ap->mode = mode;
Packit 8480eb
Packit 8480eb
	if (timeout < 0) {
Packit 8480eb
		/*
Packit 8480eb
		 * If no timeout is given get the timout from the
Packit 8480eb
		 * autofs point, or the first map, or the config
Packit 8480eb
		 * for amd maps.
Packit 8480eb
		 */
Packit 8480eb
		if (format && !strcmp(format, "amd"))
Packit 8480eb
			timeout = conf_amd_get_dismount_interval(path);
Packit 8480eb
		else
Packit 8480eb
			timeout = get_exp_timeout(entry->ap, entry->maps);
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
	if (format && !strcmp(format, "amd")) {
Packit 8480eb
		char *opts = conf_amd_get_map_options(path);
Packit 8480eb
		if (opts) {
Packit 8480eb
			/* autofs uses the equivalent of cache:=inc,sync
Packit 8480eb
			 * (except for file maps which use cache:=all,sync)
Packit 8480eb
			 * but if the map is large then it may be necessary
Packit 8480eb
			 * to read the whole map at startup even if browsing
Packit 8480eb
			 * is is not enabled, so look for cache:=all in the
Packit 8480eb
			 * map_options configuration entry.
Packit 8480eb
			 */
Packit 8480eb
			if (strstr(opts, "cache:=all"))
Packit 8480eb
				entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL;
Packit 8480eb
			free(opts);
Packit 8480eb
		}
Packit 8480eb
	}
Packit 8480eb
Packit 8480eb
/*
Packit 8480eb
	source = master_find_map_source(entry, type, format,
Packit 8480eb
					local_argc, (const char **) local_argv); 
Packit 8480eb
	if (!source)
Packit 8480eb
		source = master_add_map_source(entry, type, format, age, 
Packit 8480eb
					local_argc, (const char **) local_argv);
Packit 8480eb
	else
Packit 8480eb
		source->age = age;
Packit 8480eb
*/
Packit 8480eb
	source = master_add_map_source(entry, type, format, age, 
Packit 8480eb
					local_argc, (const char **) local_argv);
Packit 8480eb
	if (!source) {
Packit 8480eb
		error(m_logopt, "failed to add source");
Packit 8480eb
		if (new)
Packit 8480eb
			master_free_mapent(new);
Packit 8480eb
		local_free_vars();
Packit 8480eb
		return 0;
Packit 8480eb
	}
Packit 8480eb
	set_exp_timeout(entry->ap, source, timeout);
Packit 8480eb
	source->master_line = lineno;
Packit 8480eb
Packit 8480eb
	entry->age = age;
Packit 8480eb
	entry->current = NULL;
Packit 8480eb
Packit 8480eb
	if (new)
Packit 8480eb
		master_add_mapent(master, entry);
Packit 8480eb
Packit 8480eb
	local_free_vars();
Packit 8480eb
Packit 8480eb
	return 1;
Packit 8480eb
}
Packit 8480eb