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