+ char buf[4096];
+ char *value;
+ while(fgets(buf, sizeof buf, f)) {
+ int len = strcspn(buf, "\t =");
+ value = buf + len;
+ value += strspn(value, "\t ");
+ if(*value == '=') {
+ value++;
+ value += strspn(value, "\t ");
+ }
+ if(!rstrip(value))
+ continue;
+ buf[len] = 0;
+ if(strcasecmp(buf, "Name"))
+ continue;
+ if(*value) {
+ fclose(f);
+ return strdup(value);
+ }
+ }
+
+ fclose(f);
+ fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
+ return NULL;
+}
+
+#define VAR_SERVER 1 /* Should be in tinc.conf */
+#define VAR_HOST 2 /* Can be in host config file */
+#define VAR_MULTIPLE 4 /* Multiple statements allowed */
+#define VAR_OBSOLETE 8 /* Should not be used anymore */
+
+static struct {
+ const char *name;
+ int type;
+} const variables[] = {
+ /* Server configuration */
+ {"AddressFamily", VAR_SERVER},
+ {"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
+ {"BindToInterface", VAR_SERVER},
+ {"Broadcast", VAR_SERVER},
+ {"ConnectTo", VAR_SERVER | VAR_MULTIPLE},
+ {"DecrementTTL", VAR_SERVER},
+ {"Device", VAR_SERVER},
+ {"DeviceType", VAR_SERVER},
+ {"DirectOnly", VAR_SERVER},
+ {"ECDSAPrivateKeyFile", VAR_SERVER},
+ {"ExperimentalProtocol", VAR_SERVER},
+ {"Forwarding", VAR_SERVER},
+ {"GraphDumpFile", VAR_SERVER},
+ {"Hostnames", VAR_SERVER},
+ {"IffOneQueue", VAR_SERVER},
+ {"Interface", VAR_SERVER},
+ {"KeyExpire", VAR_SERVER},
+ {"LocalDiscovery", VAR_SERVER},
+ {"MACExpire", VAR_SERVER},
+ {"MaxTimeout", VAR_SERVER},
+ {"Mode", VAR_SERVER},
+ {"Name", VAR_SERVER},
+ {"PingInterval", VAR_SERVER},
+ {"PingTimeout", VAR_SERVER},
+ {"PriorityInheritance", VAR_SERVER},
+ {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
+ {"PrivateKeyFile", VAR_SERVER},
+ {"ProcessPriority", VAR_SERVER},
+ {"ReplayWindow", VAR_SERVER},
+ {"StrictSubnets", VAR_SERVER},
+ {"TunnelServer", VAR_SERVER},
+ {"UDPRcvBuf", VAR_SERVER},
+ {"UDPSndBuf", VAR_SERVER},
+ /* Host configuration */
+ {"Address", VAR_HOST | VAR_MULTIPLE},
+ {"Cipher", VAR_SERVER | VAR_HOST},
+ {"ClampMSS", VAR_SERVER | VAR_HOST},
+ {"Compression", VAR_SERVER | VAR_HOST},
+ {"Digest", VAR_SERVER | VAR_HOST},
+ {"IndirectData", VAR_SERVER | VAR_HOST},
+ {"MACLength", VAR_SERVER | VAR_HOST},
+ {"PMTU", VAR_SERVER | VAR_HOST},
+ {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
+ {"Port", VAR_HOST},
+ {"PublicKey", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
+ {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
+ {"Subnet", VAR_HOST | VAR_MULTIPLE},
+ {"TCPOnly", VAR_SERVER | VAR_HOST},
+ {NULL, 0}
+};
+
+static int cmd_config(int argc, char *argv[]) {
+ if(argc < 2) {
+ fprintf(stderr, "Invalid number of arguments.\n");