Removed annoying 'i' variable from add_option.

Allow plugin and push directives to have multiple
parameters specified instead of only 1 quoted
parameter.

Allow plugin and push directives to have multi-line
parameter lists, such as:

<plugin>
  my-plugin.so
  parm1
  parm2
</plugin>


git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@785 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
james 2005-11-09 07:30:14 +00:00
parent d40f2b204b
commit eadf16a660
9 changed files with 162 additions and 229 deletions

View File

@ -398,6 +398,19 @@ buf_chomp (struct buffer *buf)
buf_null_terminate (buf);
}
const char *
skip_leading_whitespace (const char *str)
{
while (*str)
{
const char c = *str;
if (!(c == ' ' || c == '\t'))
break;
++str;
}
return str;
}
/*
* like buf_null_terminate, but operate on strings
*/
@ -474,6 +487,42 @@ string_clear (char *str)
}
}
/*
* Return the length of a string array
*/
int
string_array_len (const char **array)
{
int i = 0;
if (array)
{
while (array[i])
++i;
}
return i;
}
char *
print_argv (const char **p, struct gc_arena *gc, const unsigned int flags)
{
struct buffer out = alloc_buf_gc (256, gc);
int i = 0;
for (;;)
{
const char *cp = *p++;
if (!cp)
break;
if (i)
buf_printf (&out, " ");
if (flags & PA_BRACKET)
buf_printf (&out, "[%s]", cp);
else
buf_printf (&out, "%s", cp);
++i;
}
return BSTR (&out);
}
/*
* Allocate a string inside a buffer
*/

View File

@ -84,6 +84,10 @@ void free_buf (struct buffer *buf);
bool buf_assign (struct buffer *dest, const struct buffer *src);
void string_clear (char *str);
int string_array_len (const char **array);
#define PA_BRACKET (1<<0)
char *print_argv (const char **p, struct gc_arena *gc, const unsigned int flags);
/* for dmalloc debugging */
@ -220,6 +224,7 @@ void buf_rmtail (struct buffer *buf, uint8_t remove);
* non-buffer string functions
*/
void chomp (char *str);
const char *skip_leading_whitespace (const char *str);
void string_null_terminate (char *str, int len, int capacity);
/*

67
misc.c
View File

@ -1368,6 +1368,73 @@ make_arg_array (const char *first, const char *parms, struct gc_arena *gc)
return (const char **)ret;
}
#if ENABLE_INLINE_FILES
static const char **
make_inline_array (const char *str, struct gc_arena *gc)
{
char line[OPTION_LINE_SIZE];
struct buffer buf;
int len = 0;
char **ret = NULL;
int i = 0;
buf_set_read (&buf, str, strlen (str));
while (buf_parse (&buf, '\n', line, sizeof (line)))
++len;
/* alloc return array */
ALLOC_ARRAY_CLEAR_GC (ret, char *, len + 1, gc);
buf_set_read (&buf, str, strlen(str));
while (buf_parse (&buf, '\n', line, sizeof (line)))
{
chomp (line);
ASSERT (i < len);
ret[i] = string_alloc (skip_leading_whitespace (line), gc);
++i;
}
ASSERT (i <= len);
ret[i] = NULL;
return (const char **)ret;
}
#endif
static const char **
make_arg_copy (char **p, struct gc_arena *gc)
{
char **ret = NULL;
const int len = string_array_len ((const char **)p);
const int max_parms = len + 1;
int i;
/* alloc return array */
ALLOC_ARRAY_CLEAR_GC (ret, char *, max_parms, gc);
for (i = 0; i < len; ++i)
ret[i] = p[i];
return (const char **)ret;
}
const char **
make_extended_arg_array (char **p, struct gc_arena *gc)
{
const int argc = string_array_len ((const char **)p);
#if ENABLE_INLINE_FILES
if (!strcmp (p[0], INLINE_FILE_TAG) && argc == 2)
return make_inline_array (p[1], gc);
else
#endif
if (argc == 0)
return make_arg_array (NULL, NULL, gc);
else if (argc == 1)
return make_arg_array (p[0], NULL, gc);
else if (argc == 2)
return make_arg_array (p[0], p[1], gc);
else
return make_arg_copy (p, gc);
}
void
openvpn_sleep (const int n)
{

1
misc.h
View File

@ -180,6 +180,7 @@ void env_set_remove_from_environment (const struct env_set *es);
const char **make_env_array (const struct env_set *es, struct gc_arena *gc);
const char **make_arg_array (const char *first, const char *parms, struct gc_arena *gc);
const char **make_extended_arg_array (char **p, struct gc_arena *gc);
/* convert netmasks for iproute2 */
int count_netmask_bits(const char *);

234
options.c

File diff suppressed because it is too large Load Diff

View File

@ -127,13 +127,14 @@ plugin_option_list_new (struct gc_arena *gc)
}
bool
plugin_option_list_add (struct plugin_option_list *list, const char *so_pathname, const char *args)
plugin_option_list_add (struct plugin_option_list *list, char **p, struct gc_arena *gc)
{
if (list->n < MAX_PLUGINS)
{
struct plugin_option *o = &list->plugins[list->n++];
o->so_pathname = so_pathname;
o->args = args;
o->argv = make_extended_arg_array (p, gc);
if (o->argv[0])
o->so_pathname = o->argv[0];
return true;
}
else
@ -145,11 +146,15 @@ void
plugin_option_list_print (const struct plugin_option_list *list, int msglevel)
{
int i;
struct gc_arena gc = gc_new ();
for (i = 0; i < list->n; ++i)
{
const struct plugin_option *o = &list->plugins[i];
msg (msglevel, " plugin[%d] %s '%s'", i, o->so_pathname, o->args);
msg (msglevel, " plugin[%d] %s '%s'", i, o->so_pathname, print_argv (o->argv, &gc, PA_BRACKET));
}
gc_free (&gc);
}
#endif
@ -256,24 +261,23 @@ plugin_open_item (struct plugin *p,
if (!p->plugin_handle && init_point == p->requested_initialization_point)
{
struct gc_arena gc = gc_new ();
const char **argv = make_arg_array (o->so_pathname, o->args, &gc);
dmsg (D_PLUGIN_DEBUG, "PLUGIN_INIT: PRE");
plugin_show_args_env (D_PLUGIN_DEBUG, argv, envp);
plugin_show_args_env (D_PLUGIN_DEBUG, o->argv, envp);
/*
* Call the plugin initialization
*/
if (p->open2)
p->plugin_handle = (*p->open2)(&p->plugin_type_mask, argv, envp, retlist);
p->plugin_handle = (*p->open2)(&p->plugin_type_mask, o->argv, envp, retlist);
else if (p->open1)
p->plugin_handle = (*p->open1)(&p->plugin_type_mask, argv, envp);
p->plugin_handle = (*p->open1)(&p->plugin_type_mask, o->argv, envp);
else
ASSERT (0);
msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s",
p->so_pathname,
o->args ? o->args : "[NULL]",
print_argv (o->argv, &gc, PA_BRACKET),
plugin_mask_string (p->plugin_type_mask, &gc),
(retlist && *retlist) ? "[RETLIST]" : "");

View File

@ -39,7 +39,7 @@
struct plugin_option {
const char *so_pathname;
const char *args;
const char **argv;
};
struct plugin_option_list {
@ -98,7 +98,7 @@ struct plugin_return
};
struct plugin_option_list *plugin_option_list_new (struct gc_arena *gc);
bool plugin_option_list_add (struct plugin_option_list *list, const char *so_pathname, const char *args);
bool plugin_option_list_add (struct plugin_option_list *list, char **p, struct gc_arena *gc);
#ifdef ENABLE_DEBUG
void plugin_option_list_print (const struct plugin_option_list *list, int msglevel);

8
push.c
View File

@ -178,6 +178,14 @@ push_option (struct options *o, const char *opt, int msglevel)
}
}
void
push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc)
{
const char **argv = make_extended_arg_array (p, gc);
char *opt = print_argv (argv, gc, 0);
push_option (o, opt, msglevel);
}
void
push_reset (struct options *o)
{

1
push.h
View File

@ -51,6 +51,7 @@ void receive_auth_failed (struct context *c, const struct buffer *buffer);
#if P2MP_SERVER
void push_option (struct options *o, const char *opt, int msglevel);
void push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc);
void push_reset (struct options *o);