mirror of
https://github.com/OpenVPN/openvpn.git
synced 2025-05-09 21:51:05 +08:00
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:
parent
d40f2b204b
commit
eadf16a660
49
buffer.c
49
buffer.c
@ -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
|
||||||
*/
|
*/
|
||||||
|
5
buffer.h
5
buffer.h
@ -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
67
misc.c
@ -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
1
misc.h
@ -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 *);
|
||||||
|
22
plugin.c
22
plugin.c
@ -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]" : "");
|
||||||
|
|
||||||
|
4
plugin.h
4
plugin.h
@ -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
8
push.c
@ -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
1
push.h
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user