Remove unnecessary status bitfield conversions.
[tinc] / src / tincctl.c
1 /*
2     tincctl.c -- Controlling a running tincd
3     Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "system.h"
21
22 #include <getopt.h>
23
24 #ifdef HAVE_READLINE
25 #include "readline/readline.h"
26 #include "readline/history.h"
27 #endif
28
29 #include "xalloc.h"
30 #include "protocol.h"
31 #include "control_common.h"
32 #include "crypto.h"
33 #include "ecdsagen.h"
34 #include "fsck.h"
35 #include "info.h"
36 #include "invitation.h"
37 #include "names.h"
38 #include "rsagen.h"
39 #include "utils.h"
40 #include "tincctl.h"
41 #include "top.h"
42 #include "version.h"
43 #include "subnet.h"
44 #include "keys.h"
45
46 #ifndef MSG_NOSIGNAL
47 #define MSG_NOSIGNAL 0
48 #endif
49
50 static char **orig_argv;
51
52 /* If nonzero, display usage information and exit. */
53 static bool show_help = false;
54
55 /* If nonzero, print the version on standard output and exit.  */
56 static bool show_version = false;
57
58 static char *name = NULL;
59 static char controlcookie[1025];
60 char *tinc_conf = NULL;
61 char *hosts_dir = NULL;
62 struct timeval now;
63
64 // Horrible global variables...
65 static int pid = 0;
66 int fd = -1;
67 char line[4096];
68 static int code;
69 static int req;
70 static int result;
71 bool force = false;
72 bool tty = true;
73 bool confbasegiven = false;
74 char *scriptinterpreter = NULL;
75 static char defaultextension[] = "";
76 char *scriptextension = defaultextension;
77 static char *prompt;
78 char *device = NULL;
79 char *iface = NULL;
80 int debug_level = -1;
81
82 static struct option const long_options[] = {
83         {"batch", no_argument, NULL, 'b'},
84         {"config", required_argument, NULL, 'c'},
85         {"net", required_argument, NULL, 'n'},
86         {"help", no_argument, NULL, 1},
87         {"version", no_argument, NULL, 2},
88         {"pidfile", required_argument, NULL, 3},
89         {"force", no_argument, NULL, 4},
90         {NULL, 0, NULL, 0}
91 };
92
93 static void version(void) {
94         static const char *message =
95                 "%s version %s (built %s %s, protocol %d.%d)\n"
96                 "Features:"
97 #ifdef HAVE_READLINE
98                 " readline"
99 #endif
100 #ifdef HAVE_CURSES
101                 " curses"
102 #endif
103 #ifndef DISABLE_LEGACY
104                 " legacy_protocol"
105 #endif
106                 "\n\n"
107                 "Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
108                 "See the AUTHORS file for a complete list.\n"
109                 "\n"
110                 "tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
111                 "and you are welcome to redistribute it under certain conditions;\n"
112                 "see the file COPYING for details.\n";
113
114         printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
115 }
116
117 static void usage(bool status) {
118         if(status) {
119                 fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
120         } else {
121                 static const char *message =
122                         "Usage: %s [options] command\n"
123                         "\n"
124                         "Valid options are:\n"
125                         "  -b, --batch             Don't ask for anything (non-interactive mode).\n"
126                         "  -c, --config=DIR        Read configuration options from DIR.\n"
127                         "  -n, --net=NETNAME       Connect to net NETNAME.\n"
128                         "      --pidfile=FILENAME  Read control cookie from FILENAME.\n"
129                         "      --force             Force some commands to work despite warnings.\n"
130                         "      --help              Display this help and exit.\n"
131                         "      --version           Output version information and exit.\n"
132                         "\n"
133                         "Valid commands are:\n"
134                         "  init [name]                Create initial configuration files.\n"
135                         "  get VARIABLE               Print current value of VARIABLE\n"
136                         "  set VARIABLE VALUE         Set VARIABLE to VALUE\n"
137                         "  add VARIABLE VALUE         Add VARIABLE with the given VALUE\n"
138                         "  del VARIABLE [VALUE]       Remove VARIABLE [only ones with watching VALUE]\n"
139                         "  start [tincd options]      Start tincd.\n"
140                         "  stop                       Stop tincd.\n"
141                         "  restart [tincd options]    Restart tincd.\n"
142                         "  reload                     Partially reload configuration of running tincd.\n"
143                         "  pid                        Show PID of currently running tincd.\n"
144 #ifdef DISABLE_LEGACY
145                         "  generate-keys              Generate a new Ed25519 public/private key pair.\n"
146 #else
147                         "  generate-keys [bits]       Generate new RSA and Ed25519 public/private key pairs.\n"
148                         "  generate-rsa-keys [bits]   Generate a new RSA public/private key pair.\n"
149 #endif
150                         "  generate-ed25519-keys      Generate a new Ed25519 public/private key pair.\n"
151                         "  dump                       Dump a list of one of the following things:\n"
152                         "    [reachable] nodes        - all known nodes in the VPN\n"
153                         "    edges                    - all known connections in the VPN\n"
154                         "    subnets                  - all known subnets in the VPN\n"
155                         "    connections              - all meta connections with ourself\n"
156                         "    [di]graph                - graph of the VPN in dotty format\n"
157                         "    invitations              - outstanding invitations\n"
158                         "  info NODE|SUBNET|ADDRESS   Give information about a particular NODE, SUBNET or ADDRESS.\n"
159                         "  purge                      Purge unreachable nodes\n"
160                         "  debug N                    Set debug level\n"
161                         "  retry                      Retry all outgoing connections\n"
162                         "  disconnect NODE            Close meta connection with NODE\n"
163 #ifdef HAVE_CURSES
164                         "  top                        Show real-time statistics\n"
165 #endif
166                         "  pcap [snaplen]             Dump traffic in pcap format [up to snaplen bytes per packet]\n"
167                         "  log [level]                Dump log output [up to the specified level]\n"
168                         "  export                     Export host configuration of local node to standard output\n"
169                         "  export-all                 Export all host configuration files to standard output\n"
170                         "  import                     Import host configuration file(s) from standard input\n"
171                         "  exchange                   Same as export followed by import\n"
172                         "  exchange-all               Same as export-all followed by import\n"
173                         "  invite NODE [...]          Generate an invitation for NODE\n"
174                         "  join INVITATION            Join a VPN using an INVITATION\n"
175                         "  network [NETNAME]          List all known networks, or switch to the one named NETNAME.\n"
176                         "  fsck                       Check the configuration files for problems.\n"
177                         "  sign [FILE]                Generate a signed version of a file.\n"
178                         "  verify NODE [FILE]         Verify that a file was signed by the given NODE.\n"
179                         "\n"
180                         "Report bugs to tinc@tinc-vpn.org.\n";
181
182                 printf(message, program_name);
183         }
184 }
185
186 static bool parse_options(int argc, char **argv) {
187         int r;
188         int option_index = 0;
189
190         while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) {
191                 switch(r) {
192                 case 0:   /* long option */
193                         break;
194
195                 case 'b':
196                         tty = false;
197                         break;
198
199                 case 'c': /* config file */
200                         free(confbase);
201                         confbase = xstrdup(optarg);
202                         confbasegiven = true;
203                         break;
204
205                 case 'n': /* net name given */
206                         free(netname);
207                         netname = xstrdup(optarg);
208                         break;
209
210                 case 1:   /* show help */
211                         show_help = true;
212                         break;
213
214                 case 2:   /* show version */
215                         show_version = true;
216                         break;
217
218                 case 3:   /* open control socket here */
219                         free(pidfilename);
220                         pidfilename = xstrdup(optarg);
221                         break;
222
223                 case 4:   /* force */
224                         force = true;
225                         break;
226
227                 case '?': /* wrong options */
228                         usage(true);
229                         free_names();
230                         return false;
231
232                 default:
233                         break;
234                 }
235         }
236
237         if(!netname && (netname = getenv("NETNAME"))) {
238                 netname = xstrdup(netname);
239         }
240
241         /* netname "." is special: a "top-level name" */
242
243         if(netname && (!*netname || !strcmp(netname, "."))) {
244                 free(netname);
245                 netname = NULL;
246         }
247
248         if(netname && (strpbrk(netname, "\\/") || *netname == '.')) {
249                 fprintf(stderr, "Invalid character in netname!\n");
250                 free_names();
251                 return false;
252         }
253
254         return true;
255 }
256
257 static FILE *ask_and_open(const char *filename, const char *what, const char *mode, bool ask, mode_t perms) {
258         FILE *r;
259         char directory[PATH_MAX] = ".";
260         char buf[PATH_MAX];
261         char buf2[PATH_MAX];
262
263 ask_filename:
264
265         /* Check stdin and stdout */
266         if(ask && tty) {
267                 /* Ask for a file and/or directory name. */
268                 fprintf(stderr, "Please enter a file to save %s to [%s]: ", what, filename);
269
270                 if(fgets(buf, sizeof(buf), stdin) == NULL) {
271                         fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
272                         return NULL;
273                 }
274
275                 size_t len = strlen(buf);
276
277                 if(len) {
278                         buf[--len] = 0;
279                 }
280
281                 if(len) {
282                         filename = buf;
283                 }
284         }
285
286 #ifdef HAVE_MINGW
287
288         if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) {
289 #else
290
291         if(filename[0] != '/') {
292 #endif
293
294                 /* The directory is a relative path or a filename. */
295                 if(!getcwd(directory, sizeof(directory))) {
296                         fprintf(stderr, "Could not get current directory: %s\n", strerror(errno));
297                         return NULL;
298                 }
299
300                 if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) {
301                         fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename);
302
303                         if(ask && tty) {
304                                 goto ask_filename;
305                         } else {
306                                 return NULL;
307                         }
308                 }
309
310                 filename = buf2;
311         }
312
313         disable_old_keys(filename, what);
314
315         /* Open it first to keep the inode busy */
316
317         r = fopenmask(filename, mode, perms);
318
319         if(!r) {
320                 fprintf(stderr, "Error opening file `%s': %s\n", filename, strerror(errno));
321                 return NULL;
322         }
323
324         return r;
325 }
326
327 /*
328   Generate a public/private Ed25519 key pair, and ask for a file to store
329   them in.
330 */
331 static bool ed25519_keygen(bool ask) {
332         ecdsa_t *key;
333         FILE *f;
334         char fname[PATH_MAX];
335
336         fprintf(stderr, "Generating Ed25519 key pair:\n");
337
338         if(!(key = ecdsa_generate())) {
339                 fprintf(stderr, "Error during key generation!\n");
340                 return false;
341         } else {
342                 fprintf(stderr, "Done.\n");
343         }
344
345         snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase);
346         f = ask_and_open(fname, "private Ed25519 key", "a", ask, 0600);
347
348         if(!f) {
349                 goto error;
350         }
351
352         if(!ecdsa_write_pem_private_key(key, f)) {
353                 fprintf(stderr, "Error writing private key!\n");
354                 goto error;
355         }
356
357         fclose(f);
358
359         if(name) {
360                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
361         } else {
362                 snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.pub", confbase);
363         }
364
365         f = ask_and_open(fname, "public Ed25519 key", "a", ask, 0666);
366
367         if(!f) {
368                 return false;
369         }
370
371         char *pubkey = ecdsa_get_base64_public_key(key);
372         fprintf(f, "Ed25519PublicKey = %s\n", pubkey);
373         free(pubkey);
374
375         fclose(f);
376         ecdsa_free(key);
377
378         return true;
379
380 error:
381
382         if(f) {
383                 fclose(f);
384         }
385
386         ecdsa_free(key);
387         return false;
388 }
389
390 #ifndef DISABLE_LEGACY
391 /*
392   Generate a public/private RSA key pair, and ask for a file to store
393   them in.
394 */
395 static bool rsa_keygen(int bits, bool ask) {
396         rsa_t *key;
397         FILE *f;
398         char fname[PATH_MAX];
399
400         // Make sure the key size is a multiple of 8 bits.
401         bits &= ~0x7;
402
403         // Make sure that a valid key size is used.
404         if(bits < 1024 || bits > 8192) {
405                 fprintf(stderr, "Invalid key size %d specified! It should be between 1024 and 8192 bits.\n", bits);
406                 return false;
407         } else if(bits < 2048) {
408                 fprintf(stderr, "WARNING: generating a weak %d bits RSA key! 2048 or more bits are recommended.\n", bits);
409         }
410
411         fprintf(stderr, "Generating %d bits keys:\n", bits);
412
413         if(!(key = rsa_generate(bits, 0x10001))) {
414                 fprintf(stderr, "Error during key generation!\n");
415                 return false;
416         } else {
417                 fprintf(stderr, "Done.\n");
418         }
419
420         snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.priv", confbase);
421         f = ask_and_open(fname, "private RSA key", "a", ask, 0600);
422
423         if(!f) {
424                 goto error;
425         }
426
427         if(!rsa_write_pem_private_key(key, f)) {
428                 fprintf(stderr, "Error writing private key!\n");
429                 goto error;
430         }
431
432         fclose(f);
433
434         if(name) {
435                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
436         } else {
437                 snprintf(fname, sizeof(fname), "%s" SLASH "rsa_key.pub", confbase);
438         }
439
440         f = ask_and_open(fname, "public RSA key", "a", ask, 0666);
441
442         if(!f) {
443                 goto error;
444         }
445
446         if(!rsa_write_pem_public_key(key, f)) {
447                 fprintf(stderr, "Error writing public key!\n");
448                 goto error;
449         }
450
451         fclose(f);
452         rsa_free(key);
453
454         return true;
455
456 error:
457
458         if(f) {
459                 fclose(f);
460         }
461
462         rsa_free(key);
463         return false;
464 }
465 #endif
466
467 char buffer[4096];
468 size_t blen = 0;
469
470 bool recvline(int fd, char *line, size_t len) {
471         char *newline = NULL;
472
473         if(!fd) {
474                 return false;
475         }
476
477         while(!(newline = memchr(buffer, '\n', blen))) {
478                 ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
479
480                 if(nrecv == -1 && sockerrno == EINTR) {
481                         continue;
482                 } else if(nrecv <= 0) {
483                         return false;
484                 }
485
486                 blen += nrecv;
487         }
488
489         if((size_t)(newline - buffer) >= len) {
490                 return false;
491         }
492
493         len = newline - buffer;
494
495         memcpy(line, buffer, len);
496         line[len] = 0;
497         memmove(buffer, newline + 1, blen - len - 1);
498         blen -= len + 1;
499
500         return true;
501 }
502
503 static bool recvdata(int fd, char *data, size_t len) {
504         while(blen < len) {
505                 ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
506
507                 if(nrecv == -1 && sockerrno == EINTR) {
508                         continue;
509                 } else if(nrecv <= 0) {
510                         return false;
511                 }
512
513                 blen += nrecv;
514         }
515
516         memcpy(data, buffer, len);
517         memmove(buffer, buffer + len, blen - len);
518         blen -= len;
519
520         return true;
521 }
522
523 bool sendline(int fd, const char *format, ...) {
524         static char buffer[4096];
525         char *p = buffer;
526         ssize_t blen;
527         va_list ap;
528
529         va_start(ap, format);
530         blen = vsnprintf(buffer, sizeof(buffer), format, ap);
531         buffer[sizeof(buffer) - 1] = 0;
532         va_end(ap);
533
534         if(blen < 1 || (size_t)blen >= sizeof(buffer)) {
535                 return false;
536         }
537
538         buffer[blen] = '\n';
539         blen++;
540
541         while(blen) {
542                 ssize_t nsend = send(fd, p, blen, MSG_NOSIGNAL);
543
544                 if(nsend == -1 && sockerrno == EINTR) {
545                         continue;
546                 } else if(nsend <= 0) {
547                         return false;
548                 }
549
550                 p += nsend;
551                 blen -= nsend;
552         }
553
554         return true;
555 }
556
557 static void pcap(int fd, FILE *out, uint32_t snaplen) {
558         sendline(fd, "%d %d %d", CONTROL, REQ_PCAP, snaplen);
559         char data[9018];
560
561         struct {
562                 uint32_t magic;
563                 uint16_t major;
564                 uint16_t minor;
565                 uint32_t tz_offset;
566                 uint32_t tz_accuracy;
567                 uint32_t snaplen;
568                 uint32_t ll_type;
569         } header = {
570                 0xa1b2c3d4,
571                 2, 4,
572                 0, 0,
573                 snaplen ? snaplen : sizeof(data),
574                 1,
575         };
576
577         struct {
578                 uint32_t tv_sec;
579                 uint32_t tv_usec;
580                 uint32_t len;
581                 uint32_t origlen;
582         } packet;
583
584         struct timeval tv;
585
586         fwrite(&header, sizeof(header), 1, out);
587         fflush(out);
588
589         char line[32];
590
591         while(recvline(fd, line, sizeof(line))) {
592                 int code, req;
593                 unsigned long len;
594                 int n = sscanf(line, "%d %d %lu", &code, &req, &len);
595                 gettimeofday(&tv, NULL);
596
597                 if(n != 3 || code != CONTROL || req != REQ_PCAP || len > sizeof(data)) {
598                         break;
599                 }
600
601                 if(!recvdata(fd, data, len)) {
602                         break;
603                 }
604
605                 packet.tv_sec = tv.tv_sec;
606                 packet.tv_usec = tv.tv_usec;
607                 packet.len = len;
608                 packet.origlen = len;
609                 fwrite(&packet, sizeof(packet), 1, out);
610                 fwrite(data, len, 1, out);
611                 fflush(out);
612         }
613 }
614
615 static void logcontrol(int fd, FILE *out, int level) {
616         sendline(fd, "%d %d %d", CONTROL, REQ_LOG, level);
617         char data[1024];
618         char line[32];
619
620         while(recvline(fd, line, sizeof(line))) {
621                 int code, req, len;
622                 int n = sscanf(line, "%d %d %d", &code, &req, &len);
623
624                 if(n != 3 || code != CONTROL || req != REQ_LOG || len < 0 || (size_t)len > sizeof(data)) {
625                         break;
626                 }
627
628                 if(!recvdata(fd, data, len)) {
629                         break;
630                 }
631
632                 fwrite(data, len, 1, out);
633                 fputc('\n', out);
634                 fflush(out);
635         }
636 }
637
638 static bool stop_tincd(void) {
639         if(!connect_tincd(true)) {
640                 return false;
641         }
642
643         sendline(fd, "%d %d", CONTROL, REQ_STOP);
644
645         while(recvline(fd, line, sizeof(line))) {
646                 // wait for tincd to close the connection...
647         }
648
649         close(fd);
650         pid = 0;
651         fd = -1;
652
653         return true;
654 }
655
656 #ifdef HAVE_MINGW
657 static bool remove_service(void) {
658         SC_HANDLE manager = NULL;
659         SC_HANDLE service = NULL;
660         SERVICE_STATUS status = {0};
661         bool success = false;
662
663         manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
664
665         if(!manager) {
666                 fprintf(stderr, "Could not open service manager: %s\n", winerror(GetLastError()));
667                 goto exit;
668         }
669
670         service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
671
672         if(!service) {
673                 if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
674                         success = stop_tincd();
675                 } else {
676                         fprintf(stderr, "Could not open %s service: %s\n", identname, winerror(GetLastError()));
677                 }
678
679                 goto exit;
680         }
681
682         if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
683                 fprintf(stderr, "Could not stop %s service: %s\n", identname, winerror(GetLastError()));
684         } else {
685                 fprintf(stderr, "%s service stopped\n", identname);
686         }
687
688         if(!DeleteService(service)) {
689                 fprintf(stderr, "Could not remove %s service: %s\n", identname, winerror(GetLastError()));
690                 goto exit;
691         }
692
693         success = true;
694
695 exit:
696
697         if(service) {
698                 CloseServiceHandle(service);
699         }
700
701         if(manager) {
702                 CloseServiceHandle(manager);
703         }
704
705         if(success) {
706                 fprintf(stderr, "%s service removed\n", identname);
707         }
708
709         return success;
710 }
711 #endif
712
713 bool connect_tincd(bool verbose) {
714         if(fd >= 0) {
715                 fd_set r;
716                 FD_ZERO(&r);
717                 FD_SET(fd, &r);
718                 struct timeval tv = {0, 0};
719
720                 if(select(fd + 1, &r, NULL, NULL, &tv)) {
721                         fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n");
722                         close(fd);
723                         fd = -1;
724                 } else {
725                         return true;
726                 }
727         }
728
729         FILE *f = fopen(pidfilename, "r");
730
731         if(!f) {
732                 if(verbose) {
733                         fprintf(stderr, "Could not open pid file %s: %s\n", pidfilename, strerror(errno));
734                 }
735
736                 return false;
737         }
738
739         char host[129];
740         char port[129];
741
742         if(fscanf(f, "%20d %1024s %128s port %128s", &pid, controlcookie, host, port) != 4) {
743                 if(verbose) {
744                         fprintf(stderr, "Could not parse pid file %s\n", pidfilename);
745                 }
746
747                 fclose(f);
748                 return false;
749         }
750
751         fclose(f);
752
753 #ifndef HAVE_MINGW
754
755         if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
756                 fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
757                 /* clean up the stale socket and pid file */
758                 unlink(pidfilename);
759                 unlink(unixsocketname);
760                 return false;
761         }
762
763         struct sockaddr_un sa = {
764                 .sun_family = AF_UNIX,
765         };
766
767         if(strlen(unixsocketname) >= sizeof(sa.sun_path)) {
768                 fprintf(stderr, "UNIX socket filename %s is too long!", unixsocketname);
769                 return false;
770         }
771
772         strncpy(sa.sun_path, unixsocketname, sizeof(sa.sun_path));
773
774         fd = socket(AF_UNIX, SOCK_STREAM, 0);
775
776         if(fd < 0) {
777                 if(verbose) {
778                         fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno));
779                 }
780
781                 return false;
782         }
783
784         if(connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
785                 if(verbose) {
786                         fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
787                 }
788
789                 close(fd);
790                 fd = -1;
791                 return false;
792         }
793
794 #else
795         struct addrinfo hints = {
796                 .ai_family = AF_UNSPEC,
797                 .ai_socktype = SOCK_STREAM,
798                 .ai_protocol = IPPROTO_TCP,
799                 .ai_flags = 0,
800         };
801
802         struct addrinfo *res = NULL;
803
804         if(getaddrinfo(host, port, &hints, &res) || !res) {
805                 if(verbose) {
806                         fprintf(stderr, "Cannot resolve %s port %s: %s\n", host, port, sockstrerror(sockerrno));
807                 }
808
809                 return false;
810         }
811
812         fd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP);
813
814         if(fd < 0) {
815                 if(verbose) {
816                         fprintf(stderr, "Cannot create TCP socket: %s\n", sockstrerror(sockerrno));
817                 }
818
819                 return false;
820         }
821
822         unsigned long arg = 0;
823
824         if(ioctlsocket(fd, FIONBIO, &arg) != 0) {
825                 if(verbose) {
826                         fprintf(stderr, "System call `%s' failed: %s\n", "ioctlsocket", sockstrerror(sockerrno));
827                 }
828         }
829
830         if(connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
831                 if(verbose) {
832                         fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
833                 }
834
835                 close(fd);
836                 fd = -1;
837                 return false;
838         }
839
840         freeaddrinfo(res);
841 #endif
842
843 #ifdef SO_NOSIGPIPE
844         static const int one = 1;
845         setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof(one));
846 #endif
847
848         sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT);
849
850         char data[4096];
851         int version;
852
853         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %4095s %d", &code, data, &version) != 3 || code != 0) {
854                 if(verbose) {
855                         fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
856                 }
857
858                 close(fd);
859                 fd = -1;
860                 return false;
861         }
862
863         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
864                 if(verbose) {
865                         fprintf(stderr, "Could not fully establish control socket connection\n");
866                 }
867
868                 close(fd);
869                 fd = -1;
870                 return false;
871         }
872
873         return true;
874 }
875
876
877 static int cmd_start(int argc, char *argv[]) {
878         if(connect_tincd(false)) {
879                 if(netname) {
880                         fprintf(stderr, "A tincd is already running for net `%s' with pid %d.\n", netname, pid);
881                 } else {
882                         fprintf(stderr, "A tincd is already running with pid %d.\n", pid);
883                 }
884
885                 return 0;
886         }
887
888         char *c;
889         char *slash = strrchr(program_name, '/');
890
891 #ifdef HAVE_MINGW
892
893         if((c = strrchr(program_name, '\\')) > slash) {
894                 slash = c;
895         }
896
897 #endif
898
899         if(slash++) {
900                 xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name);
901         } else {
902                 c = xstrdup("tincd");
903         }
904
905         int nargc = 0;
906         char **nargv = xzalloc((optind + argc) * sizeof(*nargv));
907
908         char *arg0 = c;
909 #ifdef HAVE_MINGW
910         /*
911            Windows has no real concept of an "argv array". A command line is just one string.
912            The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention)
913            it uses quotes to handle spaces in arguments.
914            Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN).
915            If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed
916            into the next arguments when the spawned process' CRT parses its command line, resulting in chaos.
917         */
918         xasprintf(&arg0, "\"%s\"", arg0);
919 #endif
920         nargv[nargc++] = arg0;
921
922         for(int i = 1; i < optind; i++) {
923                 nargv[nargc++] = orig_argv[i];
924         }
925
926         for(int i = 1; i < argc; i++) {
927                 nargv[nargc++] = argv[i];
928         }
929
930 #ifdef HAVE_MINGW
931         int status = spawnvp(_P_WAIT, c, nargv);
932
933         free(nargv);
934         free(c);
935
936         if(status == -1) {
937                 fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno));
938                 return 1;
939         }
940
941         return status;
942 #else
943         int pfd[2] = {-1, -1};
944
945         if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) {
946                 fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno));
947                 free(nargv);
948                 free(c);
949                 return 1;
950         }
951
952         pid_t pid = fork();
953
954         if(pid == -1) {
955                 fprintf(stderr, "Could not fork: %s\n", strerror(errno));
956                 free(nargv);
957                 free(c);
958                 return 1;
959         }
960
961         if(!pid) {
962                 close(pfd[0]);
963                 char buf[100];
964                 snprintf(buf, sizeof(buf), "%d", pfd[1]);
965                 setenv("TINC_UMBILICAL", buf, true);
966                 exit(execvp(c, nargv));
967         } else {
968                 close(pfd[1]);
969         }
970
971         free(nargv);
972
973 #ifdef SIGINT
974         signal(SIGINT, SIG_IGN);
975 #endif
976
977         // Pass all log messages from the umbilical to stderr.
978         // A nul-byte right before closure means tincd started successfully.
979         bool failure = true;
980         uint8_t buf[1024];
981         ssize_t len;
982
983         while((len = read(pfd[0], buf, sizeof(buf))) > 0) {
984                 failure = buf[len - 1];
985
986                 if(!failure) {
987                         len--;
988                 }
989
990                 if(write(2, buf, len) != len) {
991                         // Nothing we can do about it.
992                 }
993         }
994
995         if(len) {
996                 failure = true;
997         }
998
999         close(pfd[0]);
1000
1001         // Make sure the child process is really gone.
1002         int status = -1;
1003         pid_t result = waitpid(pid, &status, 0);
1004
1005 #ifdef SIGINT
1006         signal(SIGINT, SIG_DFL);
1007 #endif
1008
1009         bool failed = failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status);
1010
1011         if(failed) {
1012                 fprintf(stderr, "Error starting %s\n", c);
1013         }
1014
1015         free(c);
1016
1017         return failed ? EXIT_FAILURE : EXIT_SUCCESS;
1018 #endif
1019 }
1020
1021 static int cmd_stop(int argc, char *argv[]) {
1022         (void)argv;
1023
1024         if(argc > 1) {
1025                 fprintf(stderr, "Too many arguments!\n");
1026                 return 1;
1027         }
1028
1029 #ifdef HAVE_MINGW
1030         return remove_service() ? EXIT_SUCCESS : EXIT_FAILURE;
1031 #else
1032
1033         if(!stop_tincd()) {
1034                 if(pid) {
1035                         if(kill(pid, SIGTERM)) {
1036                                 fprintf(stderr, "Could not send TERM signal to process with PID %d: %s\n", pid, strerror(errno));
1037                                 return 1;
1038                         }
1039
1040                         fprintf(stderr, "Sent TERM signal to process with PID %d.\n", pid);
1041                         waitpid(pid, NULL, 0);
1042                         return 0;
1043                 }
1044
1045                 return 1;
1046         }
1047
1048         return 0;
1049 #endif
1050 }
1051
1052 static int cmd_restart(int argc, char *argv[]) {
1053         cmd_stop(1, argv);
1054         return cmd_start(argc, argv);
1055 }
1056
1057 static int cmd_reload(int argc, char *argv[]) {
1058         (void)argv;
1059
1060         if(argc > 1) {
1061                 fprintf(stderr, "Too many arguments!\n");
1062                 return 1;
1063         }
1064
1065         if(!connect_tincd(true)) {
1066                 return 1;
1067         }
1068
1069         sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
1070
1071         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) {
1072                 fprintf(stderr, "Could not reload configuration.\n");
1073                 return 1;
1074         }
1075
1076         return 0;
1077
1078 }
1079
1080 static int dump_invitations(void) {
1081         char dname[PATH_MAX];
1082         snprintf(dname, sizeof(dname), "%s" SLASH "invitations", confbase);
1083         DIR *dir = opendir(dname);
1084
1085         if(!dir) {
1086                 if(errno == ENOENT) {
1087                         fprintf(stderr, "No outstanding invitations.\n");
1088                         return 0;
1089                 }
1090
1091                 fprintf(stderr, "Cannot not read directory %s: %s\n", dname, strerror(errno));
1092                 return 1;
1093         }
1094
1095         struct dirent *ent;
1096
1097         bool found = false;
1098
1099         while((ent = readdir(dir))) {
1100                 char buf[MAX_STRING_SIZE];
1101
1102                 if(b64decode_tinc(ent->d_name, buf, 24) != 18) {
1103                         continue;
1104                 }
1105
1106                 char fname[PATH_MAX];
1107
1108                 if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ent->d_name) >= sizeof(fname)) {
1109                         fprintf(stderr, "Filename too long: %s" SLASH "%s\n", dname, ent->d_name);
1110                         continue;
1111                 }
1112
1113                 FILE *f = fopen(fname, "r");
1114
1115                 if(!f) {
1116                         fprintf(stderr, "Cannot open %s: %s\n", fname, strerror(errno));
1117                         continue;
1118                 }
1119
1120                 buf[0] = 0;
1121
1122                 if(!fgets(buf, sizeof(buf), f)) {
1123                         fprintf(stderr, "Invalid invitation file %s\n", fname);
1124                         fclose(f);
1125                         continue;
1126                 }
1127
1128                 fclose(f);
1129
1130                 char *eol = buf + strlen(buf);
1131
1132                 while(strchr("\t \r\n", *--eol)) {
1133                         *eol = 0;
1134                 }
1135
1136                 if(strncmp(buf, "Name = ", 7) || !check_id(buf + 7)) {
1137                         fprintf(stderr, "Invalid invitation file %s\n", fname);
1138                         continue;
1139                 }
1140
1141                 found = true;
1142                 printf("%s %s\n", ent->d_name, buf + 7);
1143         }
1144
1145         closedir(dir);
1146
1147         if(!found) {
1148                 fprintf(stderr, "No outstanding invitations.\n");
1149         }
1150
1151         return 0;
1152 }
1153
1154 static int cmd_dump(int argc, char *argv[]) {
1155         bool only_reachable = false;
1156
1157         if(argc > 2 && !strcasecmp(argv[1], "reachable")) {
1158                 if(strcasecmp(argv[2], "nodes")) {
1159                         fprintf(stderr, "`reachable' only supported for nodes.\n");
1160                         usage(true);
1161                         return 1;
1162                 }
1163
1164                 only_reachable = true;
1165                 argv++;
1166                 argc--;
1167         }
1168
1169         if(argc != 2) {
1170                 fprintf(stderr, "Invalid number of arguments.\n");
1171                 usage(true);
1172                 return 1;
1173         }
1174
1175         if(!strcasecmp(argv[1], "invitations")) {
1176                 return dump_invitations();
1177         }
1178
1179         if(!connect_tincd(true)) {
1180                 return 1;
1181         }
1182
1183         int do_graph = 0;
1184
1185         if(!strcasecmp(argv[1], "nodes")) {
1186                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1187         } else if(!strcasecmp(argv[1], "edges")) {
1188                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1189         } else if(!strcasecmp(argv[1], "subnets")) {
1190                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
1191         } else if(!strcasecmp(argv[1], "connections")) {
1192                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
1193         } else if(!strcasecmp(argv[1], "graph")) {
1194                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1195                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1196                 do_graph = 1;
1197         } else if(!strcasecmp(argv[1], "digraph")) {
1198                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
1199                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
1200                 do_graph = 2;
1201         } else {
1202                 fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]);
1203                 usage(true);
1204                 return 1;
1205         }
1206
1207         if(do_graph == 1) {
1208                 printf("graph {\n");
1209         } else if(do_graph == 2) {
1210                 printf("digraph {\n");
1211         }
1212
1213         while(recvline(fd, line, sizeof(line))) {
1214                 char node1[4096], node2[4096];
1215                 int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, node1, node2);
1216
1217                 if(n == 2) {
1218                         if(do_graph && req == REQ_DUMP_NODES) {
1219                                 continue;
1220                         } else {
1221                                 if(do_graph) {
1222                                         printf("}\n");
1223                                 }
1224
1225                                 return 0;
1226                         }
1227                 }
1228
1229                 if(n < 2) {
1230                         break;
1231                 }
1232
1233                 char node[4096];
1234                 char id[4096];
1235                 char from[4096];
1236                 char to[4096];
1237                 char subnet[4096];
1238                 char host[4096];
1239                 char port[4096];
1240                 char local_host[4096];
1241                 char local_port[4096];
1242                 char via[4096];
1243                 char nexthop[4096];
1244                 int cipher, digest, maclength, compression, distance, socket, weight;
1245                 short int pmtu, minmtu, maxmtu;
1246                 unsigned int options;
1247                 node_status_t status;
1248                 long int last_state_change;
1249                 int udp_ping_rtt;
1250                 uint64_t in_packets, in_bytes, out_packets, out_bytes;
1251
1252                 switch(req) {
1253                 case REQ_DUMP_NODES: {
1254                         int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status.value, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes);
1255
1256                         if(n != 22) {
1257                                 fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
1258                                 return 1;
1259                         }
1260
1261                         if(do_graph) {
1262                                 const char *color = "black";
1263
1264                                 if(!strcmp(host, "MYSELF")) {
1265                                         color = "green";
1266                                 } else if(!status.reachable) {
1267                                         color = "red";
1268                                 } else if(strcmp(via, node)) {
1269                                         color = "orange";
1270                                 } else if(!status.validkey) {
1271                                         color = "black";
1272                                 } else if(minmtu > 0) {
1273                                         color = "green";
1274                                 }
1275
1276                                 printf(" \"%s\" [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
1277                         } else {
1278                                 if(only_reachable && !status.reachable) {
1279                                         continue;
1280                                 }
1281
1282                                 printf("%s id %s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %d (min %d max %d) rx %"PRIu64" %"PRIu64" tx %"PRIu64" %"PRIu64,
1283                                        node, id, host, port, cipher, digest, maclength, compression, options, status.value, nexthop, via, distance, pmtu, minmtu, maxmtu, in_packets, in_bytes, out_packets, out_bytes);
1284
1285                                 if(udp_ping_rtt != -1) {
1286                                         printf(" rtt %d.%03d", udp_ping_rtt / 1000, udp_ping_rtt % 1000);
1287                                 }
1288
1289                                 printf("\n");
1290                         }
1291                 }
1292                 break;
1293
1294                 case REQ_DUMP_EDGES: {
1295                         int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %4095s port %4095s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
1296
1297                         if(n != 8) {
1298                                 fprintf(stderr, "Unable to parse edge dump from tincd.\n");
1299                                 return 1;
1300                         }
1301
1302                         if(do_graph) {
1303                                 float w = 1.0f + 65536.0f / (float)weight;
1304
1305                                 if(do_graph == 1 && strcmp(node1, node2) > 0) {
1306                                         printf(" \"%s\" -- \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
1307                                 } else if(do_graph == 2) {
1308                                         printf(" \"%s\" -> \"%s\" [w = %f, weight = %f];\n", node1, node2, w, w);
1309                                 }
1310                         } else {
1311                                 printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight);
1312                         }
1313                 }
1314                 break;
1315
1316                 case REQ_DUMP_SUBNETS: {
1317                         int n = sscanf(line, "%*d %*d %4095s %4095s", subnet, node);
1318
1319                         if(n != 2) {
1320                                 fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
1321                                 return 1;
1322                         }
1323
1324                         printf("%s owner %s\n", strip_weight(subnet), node);
1325                 }
1326                 break;
1327
1328                 case REQ_DUMP_CONNECTIONS: {
1329                         int n = sscanf(line, "%*d %*d %4095s %4095s port %4095s %x %d %x", node, host, port, &options, &socket, &status.value);
1330
1331                         if(n != 6) {
1332                                 fprintf(stderr, "Unable to parse connection dump from tincd.\n");
1333                                 return 1;
1334                         }
1335
1336                         printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status.value);
1337                 }
1338                 break;
1339
1340                 default:
1341                         fprintf(stderr, "Unable to parse dump from tincd.\n");
1342                         return 1;
1343                 }
1344         }
1345
1346         fprintf(stderr, "Error receiving dump.\n");
1347         return 1;
1348 }
1349
1350 static int cmd_purge(int argc, char *argv[]) {
1351         (void)argv;
1352
1353         if(argc > 1) {
1354                 fprintf(stderr, "Too many arguments!\n");
1355                 return 1;
1356         }
1357
1358         if(!connect_tincd(true)) {
1359                 return 1;
1360         }
1361
1362         sendline(fd, "%d %d", CONTROL, REQ_PURGE);
1363
1364         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_PURGE || result) {
1365                 fprintf(stderr, "Could not purge old information.\n");
1366                 return 1;
1367         }
1368
1369         return 0;
1370 }
1371
1372 static int cmd_debug(int argc, char *argv[]) {
1373         if(argc != 2) {
1374                 fprintf(stderr, "Invalid number of arguments.\n");
1375                 return 1;
1376         }
1377
1378         if(!connect_tincd(true)) {
1379                 return 1;
1380         }
1381
1382         int debuglevel = atoi(argv[1]);
1383         int origlevel;
1384
1385         sendline(fd, "%d %d %d", CONTROL, REQ_SET_DEBUG, debuglevel);
1386
1387         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &origlevel) != 3 || code != CONTROL || req != REQ_SET_DEBUG) {
1388                 fprintf(stderr, "Could not set debug level.\n");
1389                 return 1;
1390         }
1391
1392         fprintf(stderr, "Old level %d, new level %d.\n", origlevel, debuglevel);
1393         return 0;
1394 }
1395
1396 static int cmd_retry(int argc, char *argv[]) {
1397         (void)argv;
1398
1399         if(argc > 1) {
1400                 fprintf(stderr, "Too many arguments!\n");
1401                 return 1;
1402         }
1403
1404         if(!connect_tincd(true)) {
1405                 return 1;
1406         }
1407
1408         sendline(fd, "%d %d", CONTROL, REQ_RETRY);
1409
1410         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) {
1411                 fprintf(stderr, "Could not retry outgoing connections.\n");
1412                 return 1;
1413         }
1414
1415         return 0;
1416 }
1417
1418 static int cmd_connect(int argc, char *argv[]) {
1419         if(argc != 2) {
1420                 fprintf(stderr, "Invalid number of arguments.\n");
1421                 return 1;
1422         }
1423
1424         if(!check_id(argv[1])) {
1425                 fprintf(stderr, "Invalid name for node.\n");
1426                 return 1;
1427         }
1428
1429         if(!connect_tincd(true)) {
1430                 return 1;
1431         }
1432
1433         sendline(fd, "%d %d %s", CONTROL, REQ_CONNECT, argv[1]);
1434
1435         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_CONNECT || result) {
1436                 fprintf(stderr, "Could not connect to %s.\n", argv[1]);
1437                 return 1;
1438         }
1439
1440         return 0;
1441 }
1442
1443 static int cmd_disconnect(int argc, char *argv[]) {
1444         if(argc != 2) {
1445                 fprintf(stderr, "Invalid number of arguments.\n");
1446                 return 1;
1447         }
1448
1449         if(!check_id(argv[1])) {
1450                 fprintf(stderr, "Invalid name for node.\n");
1451                 return 1;
1452         }
1453
1454         if(!connect_tincd(true)) {
1455                 return 1;
1456         }
1457
1458         sendline(fd, "%d %d %s", CONTROL, REQ_DISCONNECT, argv[1]);
1459
1460         if(!recvline(fd, line, sizeof(line)) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_DISCONNECT || result) {
1461                 fprintf(stderr, "Could not disconnect %s.\n", argv[1]);
1462                 return 1;
1463         }
1464
1465         return 0;
1466 }
1467
1468 static int cmd_top(int argc, char *argv[]) {
1469         (void)argv;
1470
1471         if(argc > 1) {
1472                 fprintf(stderr, "Too many arguments!\n");
1473                 return 1;
1474         }
1475
1476 #ifdef HAVE_CURSES
1477
1478         if(!connect_tincd(true)) {
1479                 return 1;
1480         }
1481
1482         top(fd);
1483         return 0;
1484 #else
1485         fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n");
1486         return 1;
1487 #endif
1488 }
1489
1490 static int cmd_pcap(int argc, char *argv[]) {
1491         if(argc > 2) {
1492                 fprintf(stderr, "Too many arguments!\n");
1493                 return 1;
1494         }
1495
1496         if(!connect_tincd(true)) {
1497                 return 1;
1498         }
1499
1500         pcap(fd, stdout, argc > 1 ? atoi(argv[1]) : 0);
1501         return 0;
1502 }
1503
1504 #ifdef SIGINT
1505 static void sigint_handler(int sig) {
1506         (void)sig;
1507
1508         fprintf(stderr, "\n");
1509         shutdown(fd, SHUT_RDWR);
1510 }
1511 #endif
1512
1513 static int cmd_log(int argc, char *argv[]) {
1514         if(argc > 2) {
1515                 fprintf(stderr, "Too many arguments!\n");
1516                 return 1;
1517         }
1518
1519         if(!connect_tincd(true)) {
1520                 return 1;
1521         }
1522
1523 #ifdef SIGINT
1524         signal(SIGINT, sigint_handler);
1525 #endif
1526
1527         logcontrol(fd, stdout, argc > 1 ? atoi(argv[1]) : -1);
1528
1529 #ifdef SIGINT
1530         signal(SIGINT, SIG_DFL);
1531 #endif
1532
1533         close(fd);
1534         fd = -1;
1535         return 0;
1536 }
1537
1538 static int cmd_pid(int argc, char *argv[]) {
1539         (void)argv;
1540
1541         if(argc > 1) {
1542                 fprintf(stderr, "Too many arguments!\n");
1543                 return 1;
1544         }
1545
1546         if(!connect_tincd(true) || !pid) {
1547                 return 1;
1548         }
1549
1550         printf("%d\n", pid);
1551         return 0;
1552 }
1553
1554 size_t rstrip(char *value) {
1555         size_t len = strlen(value);
1556
1557         while(len && strchr("\t\r\n ", value[len - 1])) {
1558                 value[--len] = 0;
1559         }
1560
1561         return len;
1562 }
1563
1564 char *get_my_name(bool verbose) {
1565         FILE *f = fopen(tinc_conf, "r");
1566
1567         if(!f) {
1568                 if(verbose) {
1569                         fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno));
1570                 }
1571
1572                 return NULL;
1573         }
1574
1575         char buf[4096];
1576         char *value;
1577
1578         while(fgets(buf, sizeof(buf), f)) {
1579                 size_t len = strcspn(buf, "\t =");
1580                 value = buf + len;
1581                 value += strspn(value, "\t ");
1582
1583                 if(*value == '=') {
1584                         value++;
1585                         value += strspn(value, "\t ");
1586                 }
1587
1588                 if(!rstrip(value)) {
1589                         continue;
1590                 }
1591
1592                 buf[len] = 0;
1593
1594                 if(strcasecmp(buf, "Name")) {
1595                         continue;
1596                 }
1597
1598                 if(*value) {
1599                         fclose(f);
1600                         return replace_name(value);
1601                 }
1602         }
1603
1604         fclose(f);
1605
1606         if(verbose) {
1607                 fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
1608         }
1609
1610         return NULL;
1611 }
1612
1613 ecdsa_t *get_pubkey(FILE *f) {
1614         char buf[4096];
1615         char *value;
1616
1617         while(fgets(buf, sizeof(buf), f)) {
1618                 size_t len = strcspn(buf, "\t =");
1619                 value = buf + len;
1620                 value += strspn(value, "\t ");
1621
1622                 if(*value == '=') {
1623                         value++;
1624                         value += strspn(value, "\t ");
1625                 }
1626
1627                 if(!rstrip(value)) {
1628                         continue;
1629                 }
1630
1631                 buf[len] = 0;
1632
1633                 if(strcasecmp(buf, "Ed25519PublicKey")) {
1634                         continue;
1635                 }
1636
1637                 if(*value) {
1638                         return ecdsa_set_base64_public_key(value);
1639                 }
1640         }
1641
1642         return NULL;
1643 }
1644
1645 const var_t variables[] = {
1646         /* Server configuration */
1647         {"AddressFamily", VAR_SERVER | VAR_SAFE},
1648         {"AutoConnect", VAR_SERVER | VAR_SAFE},
1649         {"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
1650         {"BindToInterface", VAR_SERVER},
1651         {"Broadcast", VAR_SERVER | VAR_SAFE},
1652         {"BroadcastSubnet", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1653         {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
1654         {"DecrementTTL", VAR_SERVER | VAR_SAFE},
1655         {"Device", VAR_SERVER},
1656         {"DeviceStandby", VAR_SERVER},
1657         {"DeviceType", VAR_SERVER},
1658         {"DirectOnly", VAR_SERVER | VAR_SAFE},
1659         {"Ed25519PrivateKeyFile", VAR_SERVER},
1660         {"ExperimentalProtocol", VAR_SERVER},
1661         {"Forwarding", VAR_SERVER},
1662         {"FWMark", VAR_SERVER},
1663         {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE},
1664         {"Hostnames", VAR_SERVER},
1665         {"IffOneQueue", VAR_SERVER},
1666         {"Interface", VAR_SERVER},
1667         {"InvitationExpire", VAR_SERVER},
1668         {"KeyExpire", VAR_SERVER | VAR_SAFE},
1669         {"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
1670         {"LocalDiscovery", VAR_SERVER | VAR_SAFE},
1671         {"LogLevel", VAR_SERVER},
1672         {"MACExpire", VAR_SERVER | VAR_SAFE},
1673         {"MaxConnectionBurst", VAR_SERVER | VAR_SAFE},
1674         {"MaxOutputBufferSize", VAR_SERVER | VAR_SAFE},
1675         {"MaxTimeout", VAR_SERVER | VAR_SAFE},
1676         {"Mode", VAR_SERVER | VAR_SAFE},
1677         {"Name", VAR_SERVER},
1678         {"PingInterval", VAR_SERVER | VAR_SAFE},
1679         {"PingTimeout", VAR_SERVER | VAR_SAFE},
1680         {"PriorityInheritance", VAR_SERVER},
1681         {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
1682         {"PrivateKeyFile", VAR_SERVER},
1683         {"ProcessPriority", VAR_SERVER},
1684         {"Proxy", VAR_SERVER},
1685         {"ReplayWindow", VAR_SERVER | VAR_SAFE},
1686         {"ScriptsExtension", VAR_SERVER},
1687         {"ScriptsInterpreter", VAR_SERVER},
1688         {"StrictSubnets", VAR_SERVER | VAR_SAFE},
1689         {"TunnelServer", VAR_SERVER | VAR_SAFE},
1690         {"UDPDiscovery", VAR_SERVER | VAR_SAFE},
1691         {"UDPDiscoveryKeepaliveInterval", VAR_SERVER | VAR_SAFE},
1692         {"UDPDiscoveryInterval", VAR_SERVER | VAR_SAFE},
1693         {"UDPDiscoveryTimeout", VAR_SERVER | VAR_SAFE},
1694         {"MTUInfoInterval", VAR_SERVER | VAR_SAFE},
1695         {"UDPInfoInterval", VAR_SERVER | VAR_SAFE},
1696         {"UDPRcvBuf", VAR_SERVER},
1697         {"UDPSndBuf", VAR_SERVER},
1698         {"UPnP", VAR_SERVER},
1699         {"UPnPDiscoverWait", VAR_SERVER},
1700         {"UPnPRefreshPeriod", VAR_SERVER},
1701         {"VDEGroup", VAR_SERVER},
1702         {"VDEPort", VAR_SERVER},
1703         /* Host configuration */
1704         {"Address", VAR_HOST | VAR_MULTIPLE},
1705         {"Cipher", VAR_SERVER | VAR_HOST},
1706         {"ClampMSS", VAR_SERVER | VAR_HOST | VAR_SAFE},
1707         {"Compression", VAR_SERVER | VAR_HOST | VAR_SAFE},
1708         {"Digest", VAR_SERVER | VAR_HOST},
1709         {"Ed25519PublicKey", VAR_HOST},
1710         {"Ed25519PublicKeyFile", VAR_SERVER | VAR_HOST},
1711         {"IndirectData", VAR_SERVER | VAR_HOST | VAR_SAFE},
1712         {"MACLength", VAR_SERVER | VAR_HOST},
1713         {"PMTU", VAR_SERVER | VAR_HOST},
1714         {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
1715         {"Port", VAR_HOST},
1716         {"PublicKey", VAR_HOST | VAR_OBSOLETE},
1717         {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
1718         {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE},
1719         {"TCPOnly", VAR_SERVER | VAR_HOST | VAR_SAFE},
1720         {"Weight", VAR_HOST | VAR_SAFE},
1721         {NULL, 0}
1722 };
1723
1724 static int cmd_config(int argc, char *argv[]) {
1725         if(argc < 2) {
1726                 fprintf(stderr, "Invalid number of arguments.\n");
1727                 return 1;
1728         }
1729
1730         if(strcasecmp(argv[0], "config")) {
1731                 argv--, argc++;
1732         }
1733
1734         int action = -2;
1735
1736         if(!strcasecmp(argv[1], "get")) {
1737                 argv++, argc--;
1738         } else if(!strcasecmp(argv[1], "add")) {
1739                 argv++, argc--, action = 1;
1740         } else if(!strcasecmp(argv[1], "del")) {
1741                 argv++, argc--, action = -1;
1742         } else if(!strcasecmp(argv[1], "replace") || !strcasecmp(argv[1], "set") || !strcasecmp(argv[1], "change")) {
1743                 argv++, argc--, action = 0;
1744         }
1745
1746         if(argc < 2) {
1747                 fprintf(stderr, "Invalid number of arguments.\n");
1748                 return 1;
1749         }
1750
1751         // Concatenate the rest of the command line
1752         strncpy(line, argv[1], sizeof(line) - 1);
1753
1754         for(int i = 2; i < argc; i++) {
1755                 strncat(line, " ", sizeof(line) - 1 - strlen(line));
1756                 strncat(line, argv[i], sizeof(line) - 1 - strlen(line));
1757         }
1758
1759         // Liberal parsing into node name, variable name and value.
1760         char *node = NULL;
1761         char *variable;
1762         char *value;
1763         size_t len;
1764
1765         len = strcspn(line, "\t =");
1766         value = line + len;
1767         value += strspn(value, "\t ");
1768
1769         if(*value == '=') {
1770                 value++;
1771                 value += strspn(value, "\t ");
1772         }
1773
1774         line[len] = '\0';
1775         variable = strchr(line, '.');
1776
1777         if(variable) {
1778                 node = line;
1779                 *variable++ = 0;
1780         } else {
1781                 variable = line;
1782         }
1783
1784         if(!*variable) {
1785                 fprintf(stderr, "No variable given.\n");
1786                 return 1;
1787         }
1788
1789         if(action >= 0 && !*value) {
1790                 fprintf(stderr, "No value for variable given.\n");
1791                 return 1;
1792         }
1793
1794         if(action < -1 && *value) {
1795                 action = 0;
1796         }
1797
1798         /* Some simple checks. */
1799         bool found = false;
1800         bool warnonremove = false;
1801
1802         for(int i = 0; variables[i].name; i++) {
1803                 if(strcasecmp(variables[i].name, variable)) {
1804                         continue;
1805                 }
1806
1807                 found = true;
1808                 variable = (char *)variables[i].name;
1809
1810                 if(!strcasecmp(variable, "Subnet") && *value) {
1811                         subnet_t s = {0};
1812
1813                         if(!str2net(&s, value)) {
1814                                 fprintf(stderr, "Malformed subnet definition %s\n", value);
1815                                 return 1;
1816                         }
1817
1818                         if(!subnetcheck(s)) {
1819                                 fprintf(stderr, "Network address and prefix length do not match: %s\n", value);
1820                                 return 1;
1821                         }
1822                 }
1823
1824                 /* Discourage use of obsolete variables. */
1825
1826                 if(variables[i].type & VAR_OBSOLETE && action >= 0) {
1827                         if(force) {
1828                                 fprintf(stderr, "Warning: %s is an obsolete variable!\n", variable);
1829                         } else {
1830                                 fprintf(stderr, "%s is an obsolete variable! Use --force to use it anyway.\n", variable);
1831                                 return 1;
1832                         }
1833                 }
1834
1835                 /* Don't put server variables in host config files */
1836
1837                 if(node && !(variables[i].type & VAR_HOST) && action >= 0) {
1838                         if(force) {
1839                                 fprintf(stderr, "Warning: %s is not a host configuration variable!\n", variable);
1840                         } else {
1841                                 fprintf(stderr, "%s is not a host configuration variable! Use --force to use it anyway.\n", variable);
1842                                 return 1;
1843                         }
1844                 }
1845
1846                 /* Should this go into our own host config file? */
1847
1848                 if(!node && !(variables[i].type & VAR_SERVER)) {
1849                         node = get_my_name(true);
1850
1851                         if(!node) {
1852                                 return 1;
1853                         }
1854                 }
1855
1856                 /* Change "add" into "set" for variables that do not allow multiple occurrences.
1857                    Turn on warnings when it seems variables might be removed unintentionally. */
1858
1859                 if(action == 1 && !(variables[i].type & VAR_MULTIPLE)) {
1860                         warnonremove = true;
1861                         action = 0;
1862                 } else if(action == 0 && (variables[i].type & VAR_MULTIPLE)) {
1863                         warnonremove = true;
1864                 }
1865
1866                 break;
1867         }
1868
1869         if(node && !check_id(node)) {
1870                 fprintf(stderr, "Invalid name for node.\n");
1871
1872                 if(node != line) {
1873                         free(node);
1874                 }
1875
1876                 return 1;
1877         }
1878
1879         if(!found) {
1880                 if(force || action < 0) {
1881                         fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable);
1882                 } else {
1883                         fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable);
1884
1885                         if(node && node != line) {
1886                                 free(node);
1887                         }
1888
1889                         return 1;
1890                 }
1891         }
1892
1893         // Open the right configuration file.
1894         char filename[PATH_MAX];
1895
1896         if(node) {
1897                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node);
1898
1899                 if(node != line) {
1900                         free(node);
1901                         node = NULL;
1902                 }
1903         } else {
1904                 snprintf(filename, sizeof(filename), "%s", tinc_conf);
1905         }
1906
1907         FILE *f = fopen(filename, "r");
1908
1909         if(!f) {
1910                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
1911                 return 1;
1912         }
1913
1914         char tmpfile[PATH_MAX];
1915         FILE *tf = NULL;
1916
1917         if(action >= -1) {
1918                 if((size_t)snprintf(tmpfile, sizeof(tmpfile), "%s.config.tmp", filename) >= sizeof(tmpfile)) {
1919                         fprintf(stderr, "Filename too long: %s.config.tmp\n", filename);
1920                         return 1;
1921                 }
1922
1923                 tf = fopen(tmpfile, "w");
1924
1925                 if(!tf) {
1926                         fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno));
1927                         fclose(f);
1928                         return 1;
1929                 }
1930         }
1931
1932         // Copy the file, making modifications on the fly, unless we are just getting a value.
1933         char buf1[4096];
1934         char buf2[4096];
1935         bool set = false;
1936         bool removed = false;
1937         found = false;
1938
1939         while(fgets(buf1, sizeof(buf1), f)) {
1940                 buf1[sizeof(buf1) - 1] = 0;
1941                 strncpy(buf2, buf1, sizeof(buf2));
1942
1943                 // Parse line in a simple way
1944                 char *bvalue;
1945
1946                 size_t len = strcspn(buf2, "\t =");
1947                 bvalue = buf2 + len;
1948                 bvalue += strspn(bvalue, "\t ");
1949
1950                 if(*bvalue == '=') {
1951                         bvalue++;
1952                         bvalue += strspn(bvalue, "\t ");
1953                 }
1954
1955                 rstrip(bvalue);
1956                 buf2[len] = '\0';
1957
1958                 // Did it match?
1959                 if(!strcasecmp(buf2, variable)) {
1960                         // Get
1961                         if(action < -1) {
1962                                 found = true;
1963                                 printf("%s\n", bvalue);
1964                                 // Del
1965                         } else if(action == -1) {
1966                                 if(!*value || !strcasecmp(bvalue, value)) {
1967                                         removed = true;
1968                                         continue;
1969                                 }
1970
1971                                 // Set
1972                         } else if(action == 0) {
1973                                 // Warn if "set" was used for variables that can occur multiple times
1974                                 if(warnonremove && strcasecmp(bvalue, value)) {
1975                                         fprintf(stderr, "Warning: removing %s = %s\n", variable, bvalue);
1976                                 }
1977
1978                                 // Already set? Delete the rest...
1979                                 if(set) {
1980                                         continue;
1981                                 }
1982
1983                                 // Otherwise, replace.
1984                                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
1985                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
1986                                         return 1;
1987                                 }
1988
1989                                 set = true;
1990                                 continue;
1991                                 // Add
1992                         } else if(action > 0) {
1993                                 // Check if we've already seen this variable with the same value
1994                                 if(!strcasecmp(bvalue, value)) {
1995                                         found = true;
1996                                 }
1997                         }
1998                 }
1999
2000                 if(action >= -1) {
2001                         // Copy original line...
2002                         if(fputs(buf1, tf) < 0) {
2003                                 fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2004                                 return 1;
2005                         }
2006
2007                         // Add newline if it is missing...
2008                         if(*buf1 && buf1[strlen(buf1) - 1] != '\n') {
2009                                 if(fputc('\n', tf) < 0) {
2010                                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2011                                         return 1;
2012                                 }
2013                         }
2014                 }
2015         }
2016
2017         // Make sure we read everything...
2018         if(ferror(f) || !feof(f)) {
2019                 fprintf(stderr, "Error while reading from configuration file %s: %s\n", filename, strerror(errno));
2020                 return 1;
2021         }
2022
2023         if(fclose(f)) {
2024                 fprintf(stderr, "Error closing configuration file %s: %s\n", filename, strerror(errno));
2025                 return 1;
2026         }
2027
2028         // Add new variable if necessary.
2029         if((action > 0 && !found) || (action == 0 && !set)) {
2030                 if(fprintf(tf, "%s = %s\n", variable, value) < 0) {
2031                         fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
2032                         return 1;
2033                 }
2034         }
2035
2036         if(action < -1) {
2037                 if(found) {
2038                         return 0;
2039                 } else {
2040                         fprintf(stderr, "No matching configuration variables found.\n");
2041                         return 1;
2042                 }
2043         }
2044
2045         // Make sure we wrote everything...
2046         if(fclose(tf)) {
2047                 fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno));
2048                 return 1;
2049         }
2050
2051         // Could we find what we had to remove?
2052         if(action < 0 && !removed) {
2053                 remove(tmpfile);
2054                 fprintf(stderr, "No configuration variables deleted.\n");
2055                 return 1;
2056         }
2057
2058         // Replace the configuration file with the new one
2059 #ifdef HAVE_MINGW
2060
2061         if(remove(filename)) {
2062                 fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno));
2063                 return 1;
2064         }
2065
2066 #endif
2067
2068         if(rename(tmpfile, filename)) {
2069                 fprintf(stderr, "Error renaming temporary file %s to configuration file %s: %s\n", tmpfile, filename, strerror(errno));
2070                 return 1;
2071         }
2072
2073         // Silently try notifying a running tincd of changes.
2074         if(connect_tincd(false)) {
2075                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2076         }
2077
2078         return 0;
2079 }
2080
2081 static bool try_bind(int port) {
2082         struct addrinfo *ai = NULL, *aip;
2083         struct addrinfo hint = {
2084                 .ai_flags = AI_PASSIVE,
2085                 .ai_family = AF_UNSPEC,
2086                 .ai_socktype = SOCK_STREAM,
2087                 .ai_protocol = IPPROTO_TCP,
2088         };
2089
2090         bool success = true;
2091         char portstr[16];
2092         snprintf(portstr, sizeof(portstr), "%d", port);
2093
2094         if(getaddrinfo(NULL, portstr, &hint, &ai) || !ai) {
2095                 return false;
2096         }
2097
2098         for(aip = ai; aip; aip = aip->ai_next) {
2099                 int fd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
2100
2101                 if(!fd) {
2102                         success = false;
2103                         break;
2104                 }
2105
2106                 int result = bind(fd, ai->ai_addr, ai->ai_addrlen);
2107                 closesocket(fd);
2108
2109                 if(result) {
2110                         success = false;
2111                         break;
2112                 }
2113         }
2114
2115         freeaddrinfo(ai);
2116         return success;
2117 }
2118
2119 int check_port(const char *name) {
2120         if(try_bind(655)) {
2121                 return 655;
2122         }
2123
2124         fprintf(stderr, "Warning: could not bind to port 655. ");
2125
2126         for(int i = 0; i < 100; i++) {
2127                 uint16_t port = 0x1000 + prng(0x8000);
2128
2129                 if(try_bind(port)) {
2130                         char filename[PATH_MAX];
2131                         snprintf(filename, sizeof(filename), "%s" SLASH "hosts" SLASH "%s", confbase, name);
2132                         FILE *f = fopen(filename, "a");
2133
2134                         if(!f) {
2135                                 fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
2136                                 fprintf(stderr, "Please change tinc's Port manually.\n");
2137                                 return 0;
2138                         }
2139
2140                         fprintf(f, "Port = %d\n", port);
2141                         fclose(f);
2142                         fprintf(stderr, "Tinc will instead listen on port %d.\n", port);
2143                         return port;
2144                 }
2145         }
2146
2147         fprintf(stderr, "Please change tinc's Port manually.\n");
2148         return 0;
2149 }
2150
2151 static int cmd_init(int argc, char *argv[]) {
2152         if(!access(tinc_conf, F_OK)) {
2153                 fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf);
2154                 return 1;
2155         }
2156
2157         if(argc > 2) {
2158                 fprintf(stderr, "Too many arguments!\n");
2159                 return 1;
2160         } else if(argc < 2) {
2161                 if(tty) {
2162                         char buf[1024];
2163                         fprintf(stderr, "Enter the Name you want your tinc node to have: ");
2164
2165                         if(!fgets(buf, sizeof(buf), stdin)) {
2166                                 fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
2167                                 return 1;
2168                         }
2169
2170                         size_t len = rstrip(buf);
2171
2172                         if(!len) {
2173                                 fprintf(stderr, "No name given!\n");
2174                                 return 1;
2175                         }
2176
2177                         name = strdup(buf);
2178                 } else {
2179                         fprintf(stderr, "No Name given!\n");
2180                         return 1;
2181                 }
2182         } else {
2183                 name = strdup(argv[1]);
2184
2185                 if(!*name) {
2186                         fprintf(stderr, "No Name given!\n");
2187                         return 1;
2188                 }
2189         }
2190
2191         if(!check_id(name)) {
2192                 fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n");
2193                 return 1;
2194         }
2195
2196         if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
2197                 fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
2198                 return 1;
2199         }
2200
2201         if(mkdir(confbase, 0777) && errno != EEXIST) {
2202                 fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
2203                 return 1;
2204         }
2205
2206         if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
2207                 fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
2208                 return 1;
2209         }
2210
2211         FILE *f = fopen(tinc_conf, "w");
2212
2213         if(!f) {
2214                 fprintf(stderr, "Could not create file %s: %s\n", tinc_conf, strerror(errno));
2215                 return 1;
2216         }
2217
2218         fprintf(f, "Name = %s\n", name);
2219         fclose(f);
2220
2221 #ifndef DISABLE_LEGACY
2222
2223         if(!rsa_keygen(2048, false)) {
2224                 return 1;
2225         }
2226
2227 #endif
2228
2229         if(!ed25519_keygen(false)) {
2230                 return 1;
2231         }
2232
2233         check_port(name);
2234
2235 #ifndef HAVE_MINGW
2236         char filename[PATH_MAX];
2237         snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase);
2238
2239         if(access(filename, F_OK)) {
2240                 FILE *f = fopenmask(filename, "w", 0777);
2241
2242                 if(!f) {
2243                         fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
2244                         return 1;
2245                 }
2246
2247                 fprintf(f, "#!/bin/sh\n\necho 'Unconfigured tinc-up script, please edit '$0'!'\n\n#ifconfig $INTERFACE <your vpn IP address> netmask <netmask of whole VPN>\n");
2248                 fclose(f);
2249         }
2250
2251 #endif
2252
2253         return 0;
2254
2255 }
2256
2257 static int cmd_generate_keys(int argc, char *argv[]) {
2258 #ifdef DISABLE_LEGACY
2259         (void)argv;
2260
2261         if(argc > 1) {
2262 #else
2263
2264         if(argc > 2) {
2265 #endif
2266                 fprintf(stderr, "Too many arguments!\n");
2267                 return 1;
2268         }
2269
2270         if(!name) {
2271                 name = get_my_name(false);
2272         }
2273
2274 #ifndef DISABLE_LEGACY
2275
2276         if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true)) {
2277                 return 1;
2278         }
2279
2280 #endif
2281
2282         if(!ed25519_keygen(true)) {
2283                 return 1;
2284         }
2285
2286         return 0;
2287 }
2288
2289 #ifndef DISABLE_LEGACY
2290 static int cmd_generate_rsa_keys(int argc, char *argv[]) {
2291         if(argc > 2) {
2292                 fprintf(stderr, "Too many arguments!\n");
2293                 return 1;
2294         }
2295
2296         if(!name) {
2297                 name = get_my_name(false);
2298         }
2299
2300         return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true);
2301 }
2302 #endif
2303
2304 static int cmd_generate_ed25519_keys(int argc, char *argv[]) {
2305         (void)argv;
2306
2307         if(argc > 1) {
2308                 fprintf(stderr, "Too many arguments!\n");
2309                 return 1;
2310         }
2311
2312         if(!name) {
2313                 name = get_my_name(false);
2314         }
2315
2316         return !ed25519_keygen(true);
2317 }
2318
2319 static int cmd_help(int argc, char *argv[]) {
2320         (void)argc;
2321         (void)argv;
2322
2323         usage(false);
2324         return 0;
2325 }
2326
2327 static int cmd_version(int argc, char *argv[]) {
2328         (void)argv;
2329
2330         if(argc > 1) {
2331                 fprintf(stderr, "Too many arguments!\n");
2332                 return 1;
2333         }
2334
2335         version();
2336         return 0;
2337 }
2338
2339 static int cmd_info(int argc, char *argv[]) {
2340         if(argc != 2) {
2341                 fprintf(stderr, "Invalid number of arguments.\n");
2342                 return 1;
2343         }
2344
2345         if(!connect_tincd(true)) {
2346                 return 1;
2347         }
2348
2349         return info(fd, argv[1]);
2350 }
2351
2352 static const char *conffiles[] = {
2353         "tinc.conf",
2354         "tinc-up",
2355         "tinc-down",
2356         "subnet-up",
2357         "subnet-down",
2358         "host-up",
2359         "host-down",
2360         NULL,
2361 };
2362
2363 static int cmd_edit(int argc, char *argv[]) {
2364         if(argc != 2) {
2365                 fprintf(stderr, "Invalid number of arguments.\n");
2366                 return 1;
2367         }
2368
2369         char filename[PATH_MAX] = "";
2370
2371         if(strncmp(argv[1], "hosts" SLASH, 6)) {
2372                 for(int i = 0; conffiles[i]; i++) {
2373                         if(!strcmp(argv[1], conffiles[i])) {
2374                                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", confbase, argv[1]);
2375                                 break;
2376                         }
2377                 }
2378         } else {
2379                 argv[1] += 6;
2380         }
2381
2382         if(!*filename) {
2383                 snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, argv[1]);
2384                 char *dash = strchr(argv[1], '-');
2385
2386                 if(dash) {
2387                         *dash++ = 0;
2388
2389                         if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) {
2390                                 fprintf(stderr, "Invalid configuration filename.\n");
2391                                 return 1;
2392                         }
2393                 }
2394         }
2395
2396         char *command;
2397 #ifndef HAVE_MINGW
2398         const char *editor = getenv("VISUAL");
2399
2400         if(!editor) {
2401                 editor = getenv("EDITOR");
2402         }
2403
2404         if(!editor) {
2405                 editor = "vi";
2406         }
2407
2408         xasprintf(&command, "\"%s\" \"%s\"", editor, filename);
2409 #else
2410         xasprintf(&command, "edit \"%s\"", filename);
2411 #endif
2412         int result = system(command);
2413         free(command);
2414
2415         if(result) {
2416                 return result;
2417         }
2418
2419         // Silently try notifying a running tincd of changes.
2420         if(connect_tincd(false)) {
2421                 sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
2422         }
2423
2424         return 0;
2425 }
2426
2427 static int export(const char *name, FILE *out) {
2428         char filename[PATH_MAX];
2429         snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name);
2430         FILE *in = fopen(filename, "r");
2431
2432         if(!in) {
2433                 fprintf(stderr, "Could not open configuration file %s: %s\n", filename, strerror(errno));
2434                 return 1;
2435         }
2436
2437         fprintf(out, "Name = %s\n", name);
2438         char buf[4096];
2439
2440         while(fgets(buf, sizeof(buf), in)) {
2441                 if(strcspn(buf, "\t =") != 4 || strncasecmp(buf, "Name", 4)) {
2442                         fputs(buf, out);
2443                 }
2444         }
2445
2446         if(ferror(in)) {
2447                 fprintf(stderr, "Error while reading configuration file %s: %s\n", filename, strerror(errno));
2448                 fclose(in);
2449                 return 1;
2450         }
2451
2452         fclose(in);
2453         return 0;
2454 }
2455
2456 static int cmd_export(int argc, char *argv[]) {
2457         (void)argv;
2458
2459         if(argc > 1) {
2460                 fprintf(stderr, "Too many arguments!\n");
2461                 return 1;
2462         }
2463
2464         char *name = get_my_name(true);
2465
2466         if(!name) {
2467                 return 1;
2468         }
2469
2470         int result = export(name, stdout);
2471
2472         if(!tty) {
2473                 fclose(stdout);
2474         }
2475
2476         free(name);
2477         return result;
2478 }
2479
2480 static int cmd_export_all(int argc, char *argv[]) {
2481         (void)argv;
2482
2483         if(argc > 1) {
2484                 fprintf(stderr, "Too many arguments!\n");
2485                 return 1;
2486         }
2487
2488         DIR *dir = opendir(hosts_dir);
2489
2490         if(!dir) {
2491                 fprintf(stderr, "Could not open host configuration directory %s: %s\n", hosts_dir, strerror(errno));
2492                 return 1;
2493         }
2494
2495         bool first = true;
2496         int result = 0;
2497         struct dirent *ent;
2498
2499         while((ent = readdir(dir))) {
2500                 if(!check_id(ent->d_name)) {
2501                         continue;
2502                 }
2503
2504                 if(first) {
2505                         first = false;
2506                 } else {
2507                         printf("#---------------------------------------------------------------#\n");
2508                 }
2509
2510                 result |= export(ent->d_name, stdout);
2511         }
2512
2513         closedir(dir);
2514
2515         if(!tty) {
2516                 fclose(stdout);
2517         }
2518
2519         return result;
2520 }
2521
2522 static int cmd_import(int argc, char *argv[]) {
2523         (void)argv;
2524
2525         if(argc > 1) {
2526                 fprintf(stderr, "Too many arguments!\n");
2527                 return 1;
2528         }
2529
2530         FILE *in = stdin;
2531         FILE *out = NULL;
2532
2533         char buf[4096];
2534         char name[4096];
2535         char filename[PATH_MAX] = "";
2536         int count = 0;
2537         bool firstline = true;
2538
2539         while(fgets(buf, sizeof(buf), in)) {
2540                 if(sscanf(buf, "Name = %4095s", name) == 1) {
2541                         firstline = false;
2542
2543                         if(!check_id(name)) {
2544                                 fprintf(stderr, "Invalid Name in input!\n");
2545                                 return 1;
2546                         }
2547
2548                         if(out) {
2549                                 fclose(out);
2550                         }
2551
2552                         if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, name) >= sizeof(filename)) {
2553                                 fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, name);
2554                                 return 1;
2555                         }
2556
2557                         if(!force && !access(filename, F_OK)) {
2558                                 fprintf(stderr, "Host configuration file %s already exists, skipping.\n", filename);
2559                                 out = NULL;
2560                                 continue;
2561                         }
2562
2563                         out = fopen(filename, "w");
2564
2565                         if(!out) {
2566                                 fprintf(stderr, "Error creating configuration file %s: %s\n", filename, strerror(errno));
2567                                 return 1;
2568                         }
2569
2570                         count++;
2571                         continue;
2572                 } else if(firstline) {
2573                         fprintf(stderr, "Junk at the beginning of the input, ignoring.\n");
2574                         firstline = false;
2575                 }
2576
2577
2578                 if(!strcmp(buf, "#---------------------------------------------------------------#\n")) {
2579                         continue;
2580                 }
2581
2582                 if(out) {
2583                         if(fputs(buf, out) < 0) {
2584                                 fprintf(stderr, "Error writing to host configuration file %s: %s\n", filename, strerror(errno));
2585                                 return 1;
2586                         }
2587                 }
2588         }
2589
2590         if(out) {
2591                 fclose(out);
2592         }
2593
2594         if(count) {
2595                 fprintf(stderr, "Imported %d host configuration files.\n", count);
2596                 return 0;
2597         } else {
2598                 fprintf(stderr, "No host configuration files imported.\n");
2599                 return 1;
2600         }
2601 }
2602
2603 static int cmd_exchange(int argc, char *argv[]) {
2604         return cmd_export(argc, argv) ? 1 : cmd_import(argc, argv);
2605 }
2606
2607 static int cmd_exchange_all(int argc, char *argv[]) {
2608         return cmd_export_all(argc, argv) ? 1 : cmd_import(argc, argv);
2609 }
2610
2611 static int switch_network(char *name) {
2612         if(strcmp(name, ".")) {
2613                 if(!check_netname(name, false)) {
2614                         fprintf(stderr, "Invalid character in netname!\n");
2615                         return 1;
2616                 }
2617
2618                 if(!check_netname(name, true)) {
2619                         fprintf(stderr, "Warning: unsafe character in netname!\n");
2620                 }
2621         }
2622
2623         if(fd >= 0) {
2624                 close(fd);
2625                 fd = -1;
2626         }
2627
2628         free_names();
2629         netname = strcmp(name, ".") ? xstrdup(name) : NULL;
2630         make_names(false);
2631
2632         free(tinc_conf);
2633         free(hosts_dir);
2634         free(prompt);
2635
2636         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
2637         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
2638         xasprintf(&prompt, "%s> ", identname);
2639
2640         return 0;
2641 }
2642
2643 static int cmd_network(int argc, char *argv[]) {
2644         if(argc > 2) {
2645                 fprintf(stderr, "Too many arguments!\n");
2646                 return 1;
2647         }
2648
2649         if(argc == 2) {
2650                 return switch_network(argv[1]);
2651         }
2652
2653         DIR *dir = opendir(confdir);
2654
2655         if(!dir) {
2656                 fprintf(stderr, "Could not read directory %s: %s\n", confdir, strerror(errno));
2657                 return 1;
2658         }
2659
2660         struct dirent *ent;
2661
2662         while((ent = readdir(dir))) {
2663                 if(*ent->d_name == '.') {
2664                         continue;
2665                 }
2666
2667                 if(!strcmp(ent->d_name, "tinc.conf")) {
2668                         printf(".\n");
2669                         continue;
2670                 }
2671
2672                 char fname[PATH_MAX];
2673                 snprintf(fname, sizeof(fname), "%s/%s/tinc.conf", confdir, ent->d_name);
2674
2675                 if(!access(fname, R_OK)) {
2676                         printf("%s\n", ent->d_name);
2677                 }
2678         }
2679
2680         closedir(dir);
2681
2682         return 0;
2683 }
2684
2685 static int cmd_fsck(int argc, char *argv[]) {
2686         (void)argv;
2687
2688         if(argc > 1) {
2689                 fprintf(stderr, "Too many arguments!\n");
2690                 return 1;
2691         }
2692
2693         return fsck(orig_argv[0]);
2694 }
2695
2696 static void *readfile(FILE *in, size_t *len) {
2697         size_t count = 0;
2698         size_t bufsize = 4096;
2699         char *buf = xmalloc(bufsize);
2700
2701         while(!feof(in)) {
2702                 size_t read = fread(buf + count, 1, bufsize - count, in);
2703
2704                 if(!read) {
2705                         break;
2706                 }
2707
2708                 count += read;
2709
2710                 if(count >= bufsize) {
2711                         bufsize *= 2;
2712                         buf = xrealloc(buf, bufsize);
2713                 }
2714         }
2715
2716         if(len) {
2717                 *len = count;
2718         }
2719
2720         return buf;
2721 }
2722
2723 static int cmd_sign(int argc, char *argv[]) {
2724         if(argc > 2) {
2725                 fprintf(stderr, "Too many arguments!\n");
2726                 return 1;
2727         }
2728
2729         if(!name) {
2730                 name = get_my_name(true);
2731
2732                 if(!name) {
2733                         return 1;
2734                 }
2735         }
2736
2737         char fname[PATH_MAX];
2738         snprintf(fname, sizeof(fname), "%s" SLASH "ed25519_key.priv", confbase);
2739         FILE *fp = fopen(fname, "r");
2740
2741         if(!fp) {
2742                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2743                 return 1;
2744         }
2745
2746         ecdsa_t *key = ecdsa_read_pem_private_key(fp);
2747
2748         if(!key) {
2749                 fprintf(stderr, "Could not read private key from %s\n", fname);
2750                 fclose(fp);
2751                 return 1;
2752         }
2753
2754         fclose(fp);
2755
2756         FILE *in;
2757
2758         if(argc == 2) {
2759                 in = fopen(argv[1], "rb");
2760
2761                 if(!in) {
2762                         fprintf(stderr, "Could not open %s: %s\n", argv[1], strerror(errno));
2763                         ecdsa_free(key);
2764                         return 1;
2765                 }
2766         } else {
2767                 in = stdin;
2768         }
2769
2770         size_t len;
2771         char *data = readfile(in, &len);
2772
2773         if(in != stdin) {
2774                 fclose(in);
2775         }
2776
2777         if(!data) {
2778                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2779                 ecdsa_free(key);
2780                 return 1;
2781         }
2782
2783         // Ensure we sign our name and current time as well
2784         long t = time(NULL);
2785         char *trailer;
2786         xasprintf(&trailer, " %s %ld", name, t);
2787         size_t trailer_len = strlen(trailer);
2788
2789         data = xrealloc(data, len + trailer_len);
2790         memcpy(data + len, trailer, trailer_len);
2791         free(trailer);
2792
2793         char sig[87];
2794
2795         if(!ecdsa_sign(key, data, len + trailer_len, sig)) {
2796                 fprintf(stderr, "Error generating signature\n");
2797                 free(data);
2798                 ecdsa_free(key);
2799                 return 1;
2800         }
2801
2802         b64encode_tinc(sig, sig, 64);
2803         ecdsa_free(key);
2804
2805         fprintf(stdout, "Signature = %s %ld %s\n", name, t, sig);
2806         fwrite(data, len, 1, stdout);
2807
2808         free(data);
2809         return 0;
2810 }
2811
2812 static int cmd_verify(int argc, char *argv[]) {
2813         if(argc < 2) {
2814                 fprintf(stderr, "Not enough arguments!\n");
2815                 return 1;
2816         }
2817
2818         if(argc > 3) {
2819                 fprintf(stderr, "Too many arguments!\n");
2820                 return 1;
2821         }
2822
2823         char *node = argv[1];
2824
2825         if(!strcmp(node, ".")) {
2826                 if(!name) {
2827                         name = get_my_name(true);
2828
2829                         if(!name) {
2830                                 return 1;
2831                         }
2832                 }
2833
2834                 node = name;
2835         } else if(!strcmp(node, "*")) {
2836                 node = NULL;
2837         } else {
2838                 if(!check_id(node)) {
2839                         fprintf(stderr, "Invalid node name\n");
2840                         return 1;
2841                 }
2842         }
2843
2844         FILE *in;
2845
2846         if(argc == 3) {
2847                 in = fopen(argv[2], "rb");
2848
2849                 if(!in) {
2850                         fprintf(stderr, "Could not open %s: %s\n", argv[2], strerror(errno));
2851                         return 1;
2852                 }
2853         } else {
2854                 in = stdin;
2855         }
2856
2857         size_t len;
2858         char *data = readfile(in, &len);
2859
2860         if(in != stdin) {
2861                 fclose(in);
2862         }
2863
2864         if(!data) {
2865                 fprintf(stderr, "Error reading %s: %s\n", argv[1], strerror(errno));
2866                 return 1;
2867         }
2868
2869         char *newline = memchr(data, '\n', len);
2870
2871         if(!newline || (newline - data > MAX_STRING_SIZE - 1)) {
2872                 fprintf(stderr, "Invalid input\n");
2873                 free(data);
2874                 return 1;
2875         }
2876
2877         *newline++ = '\0';
2878         size_t skip = newline - data;
2879
2880         char signer[MAX_STRING_SIZE] = "";
2881         char sig[MAX_STRING_SIZE] = "";
2882         long t = 0;
2883
2884         if(sscanf(data, "Signature = %s %ld %s", signer, &t, sig) != 3 || strlen(sig) != 86 || !t || !check_id(signer)) {
2885                 fprintf(stderr, "Invalid input\n");
2886                 free(data);
2887                 return 1;
2888         }
2889
2890         if(node && strcmp(node, signer)) {
2891                 fprintf(stderr, "Signature is not made by %s\n", node);
2892                 free(data);
2893                 return 1;
2894         }
2895
2896         if(!node) {
2897                 node = signer;
2898         }
2899
2900         char *trailer;
2901         xasprintf(&trailer, " %s %ld", signer, t);
2902         size_t trailer_len = strlen(trailer);
2903
2904         data = xrealloc(data, len + trailer_len);
2905         memcpy(data + len, trailer, trailer_len);
2906         free(trailer);
2907
2908         newline = data + skip;
2909
2910         char fname[PATH_MAX];
2911         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, node);
2912         FILE *fp = fopen(fname, "r");
2913
2914         if(!fp) {
2915                 fprintf(stderr, "Could not open %s: %s\n", fname, strerror(errno));
2916                 free(data);
2917                 return 1;
2918         }
2919
2920         ecdsa_t *key = get_pubkey(fp);
2921
2922         if(!key) {
2923                 rewind(fp);
2924                 key = ecdsa_read_pem_public_key(fp);
2925         }
2926
2927         if(!key) {
2928                 fprintf(stderr, "Could not read public key from %s\n", fname);
2929                 fclose(fp);
2930                 free(data);
2931                 return 1;
2932         }
2933
2934         fclose(fp);
2935
2936         if(b64decode_tinc(sig, sig, 86) != 64 || !ecdsa_verify(key, newline, len + trailer_len - (newline - data), sig)) {
2937                 fprintf(stderr, "Invalid signature\n");
2938                 free(data);
2939                 ecdsa_free(key);
2940                 return 1;
2941         }
2942
2943         ecdsa_free(key);
2944
2945         fwrite(newline, len - (newline - data), 1, stdout);
2946
2947         free(data);
2948         return 0;
2949 }
2950
2951 static const struct {
2952         const char *command;
2953         int (*function)(int argc, char *argv[]);
2954         bool hidden;
2955 } commands[] = {
2956         {"start", cmd_start, false},
2957         {"stop", cmd_stop, false},
2958         {"restart", cmd_restart, false},
2959         {"reload", cmd_reload, false},
2960         {"dump", cmd_dump, false},
2961         {"list", cmd_dump, false},
2962         {"purge", cmd_purge, false},
2963         {"debug", cmd_debug, false},
2964         {"retry", cmd_retry, false},
2965         {"connect", cmd_connect, false},
2966         {"disconnect", cmd_disconnect, false},
2967         {"top", cmd_top, false},
2968         {"pcap", cmd_pcap, false},
2969         {"log", cmd_log, false},
2970         {"pid", cmd_pid, false},
2971         {"config", cmd_config, true},
2972         {"add", cmd_config, false},
2973         {"del", cmd_config, false},
2974         {"get", cmd_config, false},
2975         {"set", cmd_config, false},
2976         {"init", cmd_init, false},
2977         {"generate-keys", cmd_generate_keys, false},
2978 #ifndef DISABLE_LEGACY
2979         {"generate-rsa-keys", cmd_generate_rsa_keys, false},
2980 #endif
2981         {"generate-ed25519-keys", cmd_generate_ed25519_keys, false},
2982         {"help", cmd_help, false},
2983         {"version", cmd_version, false},
2984         {"info", cmd_info, false},
2985         {"edit", cmd_edit, false},
2986         {"export", cmd_export, false},
2987         {"export-all", cmd_export_all, false},
2988         {"import", cmd_import, false},
2989         {"exchange", cmd_exchange, false},
2990         {"exchange-all", cmd_exchange_all, false},
2991         {"invite", cmd_invite, false},
2992         {"join", cmd_join, false},
2993         {"network", cmd_network, false},
2994         {"fsck", cmd_fsck, false},
2995         {"sign", cmd_sign, false},
2996         {"verify", cmd_verify, false},
2997         {NULL, NULL, false},
2998 };
2999
3000 #ifdef HAVE_READLINE
3001 static char *complete_command(const char *text, int state) {
3002         static int i;
3003
3004         if(!state) {
3005                 i = 0;
3006         } else {
3007                 i++;
3008         }
3009
3010         while(commands[i].command) {
3011                 if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) {
3012                         return xstrdup(commands[i].command);
3013                 }
3014
3015                 i++;
3016         }
3017
3018         return NULL;
3019 }
3020
3021 static char *complete_dump(const char *text, int state) {
3022         const char *matches[] = {"reachable", "nodes", "edges", "subnets", "connections", "graph", NULL};
3023         static int i;
3024
3025         if(!state) {
3026                 i = 0;
3027         } else {
3028                 i++;
3029         }
3030
3031         while(matches[i]) {
3032                 if(!strncasecmp(matches[i], text, strlen(text))) {
3033                         return xstrdup(matches[i]);
3034                 }
3035
3036                 i++;
3037         }
3038
3039         return NULL;
3040 }
3041
3042 static char *complete_config(const char *text, int state) {
3043         static int i;
3044
3045         if(!state) {
3046                 i = 0;
3047         } else {
3048                 i++;
3049         }
3050
3051         while(variables[i].name) {
3052                 char *dot = strchr(text, '.');
3053
3054                 if(dot) {
3055                         if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) {
3056                                 char *match;
3057                                 xasprintf(&match, "%.*s.%s", (int)(dot - text), text, variables[i].name);
3058                                 return match;
3059                         }
3060                 } else {
3061                         if(!strncasecmp(variables[i].name, text, strlen(text))) {
3062                                 return xstrdup(variables[i].name);
3063                         }
3064                 }
3065
3066                 i++;
3067         }
3068
3069         return NULL;
3070 }
3071
3072 static char *complete_info(const char *text, int state) {
3073         static int i;
3074
3075         if(!state) {
3076                 i = 0;
3077
3078                 if(!connect_tincd(false)) {
3079                         return NULL;
3080                 }
3081
3082                 // Check the list of nodes
3083                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
3084                 sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
3085         }
3086
3087         while(recvline(fd, line, sizeof(line))) {
3088                 char item[4096];
3089                 int n = sscanf(line, "%d %d %4095s", &code, &req, item);
3090
3091                 if(n == 2) {
3092                         i++;
3093
3094                         if(i >= 2) {
3095                                 break;
3096                         } else {
3097                                 continue;
3098                         }
3099                 }
3100
3101                 if(n != 3) {
3102                         fprintf(stderr, "Unable to parse dump from tincd, n = %d, i = %d.\n", n, i);
3103                         break;
3104                 }
3105
3106                 if(!strncmp(item, text, strlen(text))) {
3107                         return xstrdup(strip_weight(item));
3108                 }
3109         }
3110
3111         return NULL;
3112 }
3113
3114 static char *complete_nothing(const char *text, int state) {
3115         (void)text;
3116         (void)state;
3117         return NULL;
3118 }
3119
3120 static char **completion(const char *text, int start, int end) {
3121         (void)end;
3122         char **matches = NULL;
3123
3124         if(!start) {
3125                 matches = rl_completion_matches(text, complete_command);
3126         } else if(!strncasecmp(rl_line_buffer, "dump ", 5)) {
3127                 matches = rl_completion_matches(text, complete_dump);
3128         } else if(!strncasecmp(rl_line_buffer, "add ", 4)) {
3129                 matches = rl_completion_matches(text, complete_config);
3130         } else if(!strncasecmp(rl_line_buffer, "del ", 4)) {
3131                 matches = rl_completion_matches(text, complete_config);
3132         } else if(!strncasecmp(rl_line_buffer, "get ", 4)) {
3133                 matches = rl_completion_matches(text, complete_config);
3134         } else if(!strncasecmp(rl_line_buffer, "set ", 4)) {
3135                 matches = rl_completion_matches(text, complete_config);
3136         } else if(!strncasecmp(rl_line_buffer, "info ", 5)) {
3137                 matches = rl_completion_matches(text, complete_info);
3138         }
3139
3140         return matches;
3141 }
3142 #endif
3143
3144 static int cmd_shell(int argc, char *argv[]) {
3145         xasprintf(&prompt, "%s> ", identname);
3146         int result = 0;
3147         char buf[4096];
3148         char *line = NULL;
3149         int maxargs = argc + 16;
3150         char **nargv = xmalloc(maxargs * sizeof(*nargv));
3151
3152         for(int i = 0; i < argc; i++) {
3153                 nargv[i] = argv[i];
3154         }
3155
3156 #ifdef HAVE_READLINE
3157         rl_readline_name = "tinc";
3158         rl_basic_word_break_characters = "\t\n ";
3159         rl_completion_entry_function = complete_nothing;
3160         rl_attempted_completion_function = completion;
3161         rl_filename_completion_desired = 0;
3162         char *copy = NULL;
3163 #endif
3164
3165         while(true) {
3166 #ifdef HAVE_READLINE
3167
3168                 if(tty) {
3169                         free(copy);
3170                         free(line);
3171                         line = readline(prompt);
3172                         copy = line ? xstrdup(line) : NULL;
3173                 } else {
3174                         line = fgets(buf, sizeof(buf), stdin);
3175                 }
3176
3177 #else
3178
3179                 if(tty) {
3180                         fputs(prompt, stdout);
3181                 }
3182
3183                 line = fgets(buf, sizeof(buf), stdin);
3184 #endif
3185
3186                 if(!line) {
3187                         break;
3188                 }
3189
3190                 /* Ignore comments */
3191
3192                 if(*line == '#') {
3193                         continue;
3194                 }
3195
3196                 /* Split */
3197
3198                 int nargc = argc;
3199                 char *p = line + strspn(line, " \t\n");
3200                 char *next = strtok(p, " \t\n");
3201
3202                 while(p && *p) {
3203                         if(nargc >= maxargs) {
3204                                 maxargs *= 2;
3205                                 nargv = xrealloc(nargv, maxargs * sizeof(*nargv));
3206                         }
3207
3208                         nargv[nargc++] = p;
3209                         p = next;
3210                         next = strtok(NULL, " \t\n");
3211                 }
3212
3213                 if(nargc == argc) {
3214                         continue;
3215                 }
3216
3217                 if(!strcasecmp(nargv[argc], "exit") || !strcasecmp(nargv[argc], "quit")) {
3218 #ifdef HAVE_READLINE
3219                         free(copy);
3220 #endif
3221                         free(nargv);
3222                         return result;
3223                 }
3224
3225                 bool found = false;
3226
3227                 for(int i = 0; commands[i].command; i++) {
3228                         if(!strcasecmp(nargv[argc], commands[i].command)) {
3229                                 result |= commands[i].function(nargc - argc - 1, nargv + argc + 1);
3230                                 found = true;
3231                                 break;
3232                         }
3233                 }
3234
3235 #ifdef HAVE_READLINE
3236
3237                 if(tty && found) {
3238                         add_history(copy);
3239                 }
3240
3241 #endif
3242
3243                 if(!found) {
3244                         fprintf(stderr, "Unknown command `%s'.\n", nargv[argc]);
3245                         result |= 1;
3246                 }
3247         }
3248
3249 #ifdef HAVE_READLINE
3250         free(copy);
3251 #endif
3252         free(nargv);
3253
3254         if(tty) {
3255                 printf("\n");
3256         }
3257
3258         return result;
3259 }
3260
3261 static void cleanup(void) {
3262         free(tinc_conf);
3263         free(hosts_dir);
3264         free_names();
3265 }
3266
3267 int main(int argc, char *argv[]) {
3268         program_name = argv[0];
3269         orig_argv = argv;
3270         tty = isatty(0) && isatty(1);
3271
3272         if(!parse_options(argc, argv)) {
3273                 return 1;
3274         }
3275
3276         make_names(false);
3277         xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase);
3278         xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);
3279         atexit(cleanup);
3280
3281         if(show_version) {
3282                 version();
3283                 return 0;
3284         }
3285
3286         if(show_help) {
3287                 usage(false);
3288                 return 0;
3289         }
3290
3291 #ifdef HAVE_MINGW
3292         static struct WSAData wsa_state;
3293
3294         if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
3295                 fprintf(stderr, "System call `%s' failed: %s\n", "WSAStartup", winerror(GetLastError()));
3296                 return false;
3297         }
3298
3299 #endif
3300
3301         gettimeofday(&now, NULL);
3302         crypto_init();
3303         prng_init();
3304
3305         if(optind >= argc) {
3306                 return cmd_shell(argc, argv);
3307         }
3308
3309         for(int i = 0; commands[i].command; i++) {
3310                 if(!strcasecmp(argv[optind], commands[i].command)) {
3311                         return commands[i].function(argc - optind, argv + optind);
3312                 }
3313         }
3314
3315         fprintf(stderr, "Unknown command `%s'.\n", argv[optind]);
3316         usage(true);
3317         return 1;
3318 }