X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/2ec489f7e0a1eb4174d7ba52dfda48999e389647..42da2a58637902f3bba731a83538804e57e340bf:/admin.c diff --git a/admin.c b/admin.c index 57d9ccfa..24d86c64 100644 --- a/admin.c +++ b/admin.c @@ -78,23 +78,6 @@ static void a_unlock(admin */*a*/); /*----- Output functions --------------------------------------------------*/ -/* --- @mystrieq@ --- * - * - * Arguments: @const char *x, *y@ = two strings - * - * Returns: True if @x@ and @y are equal, up to case. - */ - -static int mystrieq(const char *x, const char *y) -{ - for (;;) { - if (!*x && !*y) return (1); - if (tolower((unsigned char)*x) != tolower((unsigned char)*y)) - return (0); - x++; y++; - } -} - /* --- @trywrite@ --- * * * Arguments: @admin *a@ = pointer to an admin block @@ -433,6 +416,10 @@ void a_notify(const char *fmt, ...) void a_quit(void) { + peer *p; + + while ((p = p_first()) != 0) + p_destroy(p); close(sock.fd); unlink(sockname); exit(0); @@ -506,7 +493,7 @@ static void a_resolve(struct hostent *h, void *v) a_fail(a, "peer-exists %s", a->pname); else { memcpy(&a->peer.sin.sin_addr, h->h_addr, sizeof(struct in_addr)); - if (!p_create(a->pname, &a->peer.sa, a->sasz)) + if (!p_create(a->pname, a->tops, &a->peer.sa, a->sasz)) a_fail(a, "peer-create-fail %s", a->pname); else a_ok(a); @@ -558,7 +545,8 @@ static void acmd_add(admin *a, unsigned ac, char *av[]) { unsigned long pt; struct timeval tv; - unsigned i; + unsigned i, j; + const tunnel_ops *tops = tun_default; char *p; /* --- Make sure someone's not got there already --- */ @@ -568,13 +556,40 @@ static void acmd_add(admin *a, unsigned ac, char *av[]) return; } + /* --- Parse options --- */ + + i = 1; + for (;;) { + if (!av[i]) + goto bad_syntax; + if (mystrieq(av[i], "-tunnel")) { + i++; + if (!av[i]) + goto bad_syntax; + for (j = 0;; j++) { + if (!tunnels[j]) { + a_fail(a, "unknown-tunnel %s", av[i]); + return; + } + if (mystrieq(av[i], tunnels[j]->name)) { + tops = tunnels[j]; + break; + } + } + i++; + } else if (mystrieq(av[i], "--")) { + i++; + break; + } else + break; + } + /* --- Fill in the easy bits of address --- */ BURN(a->peer); - i = 1; if (mystrieq(av[i], "inet")) i++; if (ac - i != 2) { - a_fail(a, "bad-syntax -- add PEER [inet] ADDRESS PORT"); + a_fail(a, "bad-syntax -- add PEER [-tunnel TUN] [inet] ADDRESS PORT"); return; } a->peer.sin.sin_family = AF_INET; @@ -597,7 +612,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[]) /* --- If the name is numeric, do it the easy way --- */ if (inet_aton(av[i], &a->peer.sin.sin_addr)) { - if (!p_create(av[0], &a->peer.sa, a->sasz)) + if (!p_create(av[0], tops, &a->peer.sa, a->sasz)) a_fail(a, "peer-create-fail %s", a->pname); else a_ok(a); @@ -613,6 +628,7 @@ static void acmd_add(admin *a, unsigned ac, char *av[]) a->pname = xstrdup(av[0]); a->paddr = xstrdup(av[i]); + a->tops = tops; selbuf_disable(&a->b); gettimeofday(&tv, 0); tv.tv_sec += T_RESOLVE; @@ -620,6 +636,11 @@ static void acmd_add(admin *a, unsigned ac, char *av[]) bres_byname(&a->r, a->paddr, a_resolve, a); T( trace(T_ADMIN, "admin: %u resolving hostname `%s'", a->seq, a->paddr); ) + return; + +bad_syntax: + a_fail(a, "bad-syntax -- add PEER [-tunnel TUN] ADDR ..."); + return; } /*----- Administration commands -------------------------------------------*/ @@ -848,6 +869,14 @@ static void acmd_version(admin *a, unsigned ac, char *av[]) a_ok(a); } +static void acmd_tunnels(admin *a, unsigned ac, char *av[]) +{ + int i; + for (i = 0; tunnels[i]; i++) + a_info(a, "%s", tunnels[i]->name); + a_ok(a); +} + /* --- The command table and help --- */ typedef struct acmd { @@ -875,7 +904,9 @@ static const acmd acmdtab[] = { { "addr", "addr PEER", 1, 1, acmd_addr }, { "stats", "stats PEER", 1, 1, acmd_stats }, { "kill", "kill PEER", 1, 1, acmd_kill }, - { "add", "add PEER ADDR ...", 2, 0xffff, acmd_add }, + { "add", "add PEER [-tunnel TUN] ADDR ...", + 2, 0xffff, acmd_add }, + { "tunnels", "tunnels", 0, 0, acmd_tunnels }, { "quit", "quit", 0, 0, acmd_quit }, { 0, 0, 0, 0, 0 } };