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