Put script environment creation/deletion in functions.
This makes environment handling safer, and also has a single place where we can add new environment variables that should be present for all scripts.
This commit is contained in:
parent
3e643d5d7e
commit
5cbef90620
12 changed files with 134 additions and 94 deletions
23
src/graph.c
23
src/graph.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
graph.c -- graph algorithms
|
||||
Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2001-2017 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2001-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -247,28 +247,23 @@ static void check_reachability(void) {
|
|||
char *name;
|
||||
char *address;
|
||||
char *port;
|
||||
char *envp[8] = {NULL};
|
||||
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NODE=%s", n->name);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", n->name);
|
||||
sockaddr2str(&n->address, &address, &port);
|
||||
xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[5], "REMOTEPORT=%s", port);
|
||||
xasprintf(&envp[6], "NAME=%s", myself->name);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "REMOTEPORT=%s", port);
|
||||
|
||||
execute_script(n->status.reachable ? "host-up" : "host-down", envp);
|
||||
execute_script(n->status.reachable ? "host-up" : "host-down", &env);
|
||||
|
||||
xasprintf(&name, n->status.reachable ? "hosts/%s-up" : "hosts/%s-down", n->name);
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
|
||||
free(name);
|
||||
free(address);
|
||||
free(port);
|
||||
|
||||
for(int i = 0; i < 7; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
|
||||
subnet_update(n, NULL, n->status.reachable);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
invitation.c -- Create and accept invitations
|
||||
Copyright (C) 2013-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2013-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -239,7 +239,7 @@ int cmd_invite(int argc, char *argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
char *myname = get_my_name(true);
|
||||
myname = get_my_name(true);
|
||||
if(!myname)
|
||||
return 1;
|
||||
|
||||
|
@ -425,15 +425,13 @@ int cmd_invite(int argc, char *argv[]) {
|
|||
xasprintf(&url, "%s/%s%s", address, hash, cookie);
|
||||
|
||||
// Call the inviation-created script
|
||||
char *envp[6] = {};
|
||||
xasprintf(&envp[0], "NAME=%s", myname);
|
||||
xasprintf(&envp[1], "NETNAME=%s", netname);
|
||||
xasprintf(&envp[2], "NODE=%s", argv[1]);
|
||||
xasprintf(&envp[3], "INVITATION_FILE=%s", filename);
|
||||
xasprintf(&envp[4], "INVITATION_URL=%s", url);
|
||||
execute_script("invitation-created", envp);
|
||||
for(int i = 0; i < 6 && envp[i]; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", argv[1]);
|
||||
environment_add(&env, "INVITATION_FILE=%s", filename);
|
||||
environment_add(&env, "INVITATION_URL=%s", url);
|
||||
execute_script("invitation-created", &env);
|
||||
environment_exit(&env);
|
||||
|
||||
puts(url);
|
||||
free(url);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
logger.c -- logging code
|
||||
Copyright (C) 2004-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
Copyright (C) 2004-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2004-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "process.h"
|
||||
#include "sptps.h"
|
||||
|
||||
debug_t debug_level = DEBUG_NOTHING;
|
||||
int debug_level = DEBUG_NOTHING;
|
||||
static logmode_t logmode = LOGMODE_STDERR;
|
||||
static pid_t logpid;
|
||||
static FILE *logfile = NULL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
logger.h -- header file for logger.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -67,7 +67,7 @@ enum {
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
extern debug_t debug_level;
|
||||
extern int debug_level;
|
||||
extern bool logcontrol;
|
||||
extern int umbilical;
|
||||
extern void openlogger(const char *, logmode_t);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
names.c -- generate commonly used (file)names
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
char *netname = NULL;
|
||||
char *myname = NULL;
|
||||
char *confdir = NULL; /* base configuration directory */
|
||||
char *confbase = NULL; /* base configuration directory for this instance of tinc */
|
||||
bool confbase_given;
|
||||
|
@ -137,6 +138,7 @@ void free_names(void) {
|
|||
free(logfilename);
|
||||
free(confbase);
|
||||
free(confdir);
|
||||
free(myname);
|
||||
|
||||
identname = NULL;
|
||||
netname = NULL;
|
||||
|
@ -145,4 +147,5 @@ void free_names(void) {
|
|||
logfilename = NULL;
|
||||
confbase = NULL;
|
||||
confdir = NULL;
|
||||
myname = NULL;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
names.h -- header for names.c
|
||||
Copyright (C) 1998-2005 Ivo Timmermans
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,6 +25,7 @@ extern char *confdir;
|
|||
extern char *confbase;
|
||||
extern bool confbase_given;
|
||||
extern char *netname;
|
||||
extern char *myname;
|
||||
extern char *identname;
|
||||
extern char *unixsocketname;
|
||||
extern char *logfilename;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_setup.c -- Setup.
|
||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2006 Scott Lamb <slamb@slamb.org>
|
||||
2010 Brandon Black <blblack@gmail.com>
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
|||
#endif
|
||||
|
||||
char *myport;
|
||||
static char *myname;
|
||||
static io_t device_io;
|
||||
devops_t devops;
|
||||
bool device_standby = false;
|
||||
|
@ -705,29 +704,17 @@ void device_enable(void) {
|
|||
|
||||
/* Run tinc-up script to further initialize the tap interface */
|
||||
|
||||
char *envp[5] = {NULL};
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NAME=%s", myname);
|
||||
|
||||
execute_script("tinc-up", envp);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
execute_script("tinc-up", &env);
|
||||
environment_exit(&env);
|
||||
}
|
||||
|
||||
void device_disable(void) {
|
||||
char *envp[5] = {NULL};
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NAME=%s", myname);
|
||||
|
||||
execute_script("tinc-down", envp);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
execute_script("tinc-down", &env);
|
||||
environment_exit(&env);
|
||||
|
||||
if (devops.disable)
|
||||
devops.disable();
|
||||
|
@ -1150,7 +1137,6 @@ void close_network_connections(void) {
|
|||
|
||||
exit_control();
|
||||
|
||||
free(myname);
|
||||
free(scriptextension);
|
||||
free(scriptinterpreter);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_auth.c -- handle the meta-protocol, authentication
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -180,21 +180,18 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
|
|||
logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname);
|
||||
|
||||
// Call invitation-accepted script
|
||||
char *envp[7] = {NULL};
|
||||
environment_t env;
|
||||
char *address, *port;
|
||||
|
||||
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[3], "NODE=%s", c->name);
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", c->name);
|
||||
sockaddr2str(&c->address, &address, &port);
|
||||
xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[5], "NAME=%s", myself->name);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "NAME=%s", myself->name);
|
||||
|
||||
execute_script("invitation-accepted", envp);
|
||||
execute_script("invitation-accepted", &env);
|
||||
|
||||
for(int i = 0; envp[i] && i < 7; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
|
||||
sptps_send_record(&c->sptps, 2, data, 0);
|
||||
return true;
|
||||
|
|
62
src/script.c
62
src/script.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
script.c -- call an external script
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2015 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include "system.h"
|
||||
|
||||
#include "conf.h"
|
||||
#include "device.h"
|
||||
#include "logger.h"
|
||||
#include "names.h"
|
||||
#include "script.h"
|
||||
|
@ -63,7 +64,56 @@ static void putenv(const char *p) {}
|
|||
static void unputenv(const char *p) {}
|
||||
#endif
|
||||
|
||||
bool execute_script(const char *name, char **envp) {
|
||||
static const int min_env_size;
|
||||
|
||||
int environment_add(environment_t *env, const char *format, ...) {
|
||||
if(env->n >= env->size) {
|
||||
env->size = env->n ? env->n * 2 : min_env_size;
|
||||
env->entries = xrealloc(env->entries, env->size * sizeof *env->entries);
|
||||
}
|
||||
|
||||
if(format) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vasprintf(&env->entries[env->n], format, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
env->entries[env->n] = NULL;
|
||||
}
|
||||
|
||||
return env->n++;
|
||||
}
|
||||
|
||||
void environment_update(environment_t *env, int pos, const char *format, ...) {
|
||||
free(env->entries[pos]);
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vasprintf(&env->entries[pos], format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void environment_init(environment_t *env) {
|
||||
env->n = 0;
|
||||
env->size = min_env_size;
|
||||
env->entries = 0; //xzalloc(env->size * sizeof *env->entries);
|
||||
|
||||
if(netname)
|
||||
environment_add(env, "NETNAME=%s", netname);
|
||||
if(myname)
|
||||
environment_add(env, "NAME=%s", myname);
|
||||
if(device)
|
||||
environment_add(env, "DEVICE=%s", device);
|
||||
if(iface)
|
||||
environment_add(env, "INTERFACE=%s", iface);
|
||||
}
|
||||
|
||||
void environment_exit(environment_t *env) {
|
||||
for(int i = 0; i < env->n; i++)
|
||||
free(env->entries[i]);
|
||||
free(env->entries);
|
||||
}
|
||||
|
||||
bool execute_script(const char *name, environment_t *env) {
|
||||
char scriptname[PATH_MAX];
|
||||
char *command;
|
||||
|
||||
|
@ -107,8 +157,8 @@ bool execute_script(const char *name, char **envp) {
|
|||
|
||||
/* Set environment */
|
||||
|
||||
for(int i = 0; envp[i]; i++)
|
||||
putenv(envp[i]);
|
||||
for(int i = 0; i < env->n; i++)
|
||||
putenv(env->entries[i]);
|
||||
|
||||
if(scriptinterpreter)
|
||||
xasprintf(&command, "%s \"%s\"", scriptinterpreter, scriptname);
|
||||
|
@ -121,8 +171,8 @@ bool execute_script(const char *name, char **envp) {
|
|||
|
||||
/* Unset environment */
|
||||
|
||||
for(int i = 0; envp[i]; i++)
|
||||
unputenv(envp[i]);
|
||||
for(int i = 0; i < env->n; i++)
|
||||
unputenv(env->entries[i]);
|
||||
|
||||
if(status != -1) {
|
||||
#ifdef WEXITSTATUS
|
||||
|
|
16
src/script.h
16
src/script.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
script.h -- header file for script.c
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,6 +21,18 @@
|
|||
#ifndef __TINC_SCRIPT_H__
|
||||
#define __TINC_SCRIPT_H__
|
||||
|
||||
extern bool execute_script(const char *, char **);
|
||||
typedef struct environment {
|
||||
int n;
|
||||
int size;
|
||||
char **entries;
|
||||
} environment_t;
|
||||
|
||||
extern int environment_add(environment_t *env, const char *format, ...);
|
||||
extern int environment_placeholder(environment_t *env);
|
||||
extern void environment_update(environment_t *env, int pos, const char *format, ...);
|
||||
extern void environment_init(environment_t *env);
|
||||
extern void environment_exit(environment_t *env);
|
||||
|
||||
extern bool execute_script(const char *name, environment_t *env);
|
||||
|
||||
#endif /* __TINC_SCRIPT_H__ */
|
||||
|
|
35
src/subnet.c
35
src/subnet.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
subnet.c -- handle subnet lookups and lists
|
||||
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
Copyright (C) 2000-2017 Guus Sliepen <guus@tinc-vpn.org>,
|
||||
2000-2005 Ivo Timmermans
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -206,22 +206,20 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
|
||||
// Prepare environment variables to be passed to the script
|
||||
|
||||
char *envp[10] = {NULL};
|
||||
int n = 0;
|
||||
xasprintf(&envp[n++], "NETNAME=%s", netname ? : "");
|
||||
xasprintf(&envp[n++], "DEVICE=%s", device ? : "");
|
||||
xasprintf(&envp[n++], "INTERFACE=%s", iface ? : "");
|
||||
xasprintf(&envp[n++], "NODE=%s", owner->name);
|
||||
environment_t env;
|
||||
environment_init(&env);
|
||||
environment_add(&env, "NODE=%s", owner->name);
|
||||
|
||||
if(owner != myself) {
|
||||
sockaddr2str(&owner->address, &address, &port);
|
||||
xasprintf(&envp[n++], "REMOTEADDRESS=%s", address);
|
||||
xasprintf(&envp[n++], "REMOTEPORT=%s", port);
|
||||
environment_add(&env, "REMOTEADDRESS=%s", address);
|
||||
environment_add(&env, "REMOTEPORT=%s", port);
|
||||
free(port);
|
||||
free(address);
|
||||
}
|
||||
|
||||
xasprintf(&envp[n++], "NAME=%s", myself->name);
|
||||
int env_subnet = environment_add(&env, NULL);
|
||||
int env_weight = environment_add(&env, NULL);
|
||||
|
||||
name = up ? "subnet-up" : "subnet-down";
|
||||
|
||||
|
@ -238,12 +236,10 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
weight = empty;
|
||||
|
||||
// Prepare the SUBNET and WEIGHT variables
|
||||
free(envp[n]);
|
||||
free(envp[n + 1]);
|
||||
xasprintf(&envp[n], "SUBNET=%s", netstr);
|
||||
xasprintf(&envp[n + 1], "WEIGHT=%s", weight);
|
||||
environment_update(&env, env_subnet, "SUBNET=%s", netstr);
|
||||
environment_update(&env, env_weight, "WEIGHT=%s", weight);
|
||||
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
}
|
||||
} else {
|
||||
if(net2str(netstr, sizeof netstr, subnet)) {
|
||||
|
@ -255,15 +251,14 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
|
|||
weight = empty;
|
||||
|
||||
// Prepare the SUBNET and WEIGHT variables
|
||||
xasprintf(&envp[n], "SUBNET=%s", netstr);
|
||||
xasprintf(&envp[n + 1], "WEIGHT=%s", weight);
|
||||
environment_update(&env, env_subnet, "SUBNET=%s", netstr);
|
||||
environment_update(&env, env_weight, "WEIGHT=%s", weight);
|
||||
|
||||
execute_script(name, envp);
|
||||
execute_script(name, &env);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; envp[i] && i < 9; i++)
|
||||
free(envp[i]);
|
||||
environment_exit(&env);
|
||||
}
|
||||
|
||||
bool dump_subnets(connection_t *c) {
|
||||
|
|
|
@ -74,6 +74,9 @@ bool netnamegiven = false;
|
|||
char *scriptinterpreter = NULL;
|
||||
char *scriptextension = "";
|
||||
static char *prompt;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
int debug_level = -1;
|
||||
|
||||
static struct option const long_options[] = {
|
||||
{"batch", no_argument, NULL, 'b'},
|
||||
|
@ -89,7 +92,7 @@ static struct option const long_options[] = {
|
|||
static void version(void) {
|
||||
printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
|
||||
BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
|
||||
printf("Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.\n"
|
||||
printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n"
|
||||
"See the AUTHORS file for a complete list.\n\n"
|
||||
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
|
||||
"and you are welcome to redistribute it under certain conditions;\n"
|
||||
|
|
Loading…
Reference in a new issue