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); 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 * 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 * 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); bool buf_assign (struct buffer *dest, const struct buffer *src);
void string_clear (char *str); 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 */ /* for dmalloc debugging */
@ -220,6 +224,7 @@ void buf_rmtail (struct buffer *buf, uint8_t remove);
* non-buffer string functions * non-buffer string functions
*/ */
void chomp (char *str); void chomp (char *str);
const char *skip_leading_whitespace (const char *str);
void string_null_terminate (char *str, int len, int capacity); 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; 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 void
openvpn_sleep (const int n) 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_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_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 */ /* convert netmasks for iproute2 */
int count_netmask_bits(const char *); 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 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) if (list->n < MAX_PLUGINS)
{ {
struct plugin_option *o = &list->plugins[list->n++]; struct plugin_option *o = &list->plugins[list->n++];
o->so_pathname = so_pathname; o->argv = make_extended_arg_array (p, gc);
o->args = args; if (o->argv[0])
o->so_pathname = o->argv[0];
return true; return true;
} }
else else
@ -145,11 +146,15 @@ void
plugin_option_list_print (const struct plugin_option_list *list, int msglevel) plugin_option_list_print (const struct plugin_option_list *list, int msglevel)
{ {
int i; int i;
struct gc_arena gc = gc_new ();
for (i = 0; i < list->n; ++i) for (i = 0; i < list->n; ++i)
{ {
const struct plugin_option *o = &list->plugins[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 #endif
@ -256,24 +261,23 @@ plugin_open_item (struct plugin *p,
if (!p->plugin_handle && init_point == p->requested_initialization_point) if (!p->plugin_handle && init_point == p->requested_initialization_point)
{ {
struct gc_arena gc = gc_new (); 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"); 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 * Call the plugin initialization
*/ */
if (p->open2) 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) 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 else
ASSERT (0); ASSERT (0);
msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s", msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s",
p->so_pathname, p->so_pathname,
o->args ? o->args : "[NULL]", print_argv (o->argv, &gc, PA_BRACKET),
plugin_mask_string (p->plugin_type_mask, &gc), plugin_mask_string (p->plugin_type_mask, &gc),
(retlist && *retlist) ? "[RETLIST]" : ""); (retlist && *retlist) ? "[RETLIST]" : "");

View File

@ -39,7 +39,7 @@
struct plugin_option { struct plugin_option {
const char *so_pathname; const char *so_pathname;
const char *args; const char **argv;
}; };
struct plugin_option_list { struct plugin_option_list {
@ -98,7 +98,7 @@ struct plugin_return
}; };
struct plugin_option_list *plugin_option_list_new (struct gc_arena *gc); 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 #ifdef ENABLE_DEBUG
void plugin_option_list_print (const struct plugin_option_list *list, int msglevel); 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 void
push_reset (struct options *o) 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 #if P2MP_SERVER
void push_option (struct options *o, const char *opt, int msglevel); 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); void push_reset (struct options *o);