+ identname = xstrdup("tinc");
+ }
+
+#ifdef HAVE_MINGW
+
+ if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
+ if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) {
+ if(!confbase) {
+ if(netname) {
+ xasprintf(&confbase, "%s/%s", installdir, netname);
+ } else {
+ xasprintf(&confbase, "%s", installdir);
+ }
+ }
+
+ if(!logfilename) {
+ xasprintf(&logfilename, "%s/tinc.log", confbase);
+ }
+ }
+
+ RegCloseKey(key);
+
+ if(*installdir) {
+ return;
+ }
+ }
+
+#endif
+
+ if(!pidfilename) {
+ xasprintf(&pidfilename, LOCALSTATEDIR "/run/%s.pid", identname);
+ }
+
+ if(!logfilename) {
+ xasprintf(&logfilename, LOCALSTATEDIR "/log/%s.log", identname);
+ }
+
+ if(netname) {
+ if(!confbase) {
+ xasprintf(&confbase, CONFDIR "/tinc/%s", netname);
+ } else {
+ logger(LOG_INFO, "Both netname and configuration directory given, using the latter...");
+ }
+ } else {
+ if(!confbase) {
+ xasprintf(&confbase, CONFDIR "/tinc");
+ }
+ }
+}
+
+static void free_names() {
+ if(identname) {
+ free(identname);
+ }
+
+ if(netname) {
+ free(netname);
+ }
+
+ if(pidfilename) {
+ free(pidfilename);
+ }
+
+ if(logfilename) {
+ free(logfilename);
+ }
+
+ if(confbase) {
+ free(confbase);
+ }
+}
+
+static bool drop_privs() {
+#ifdef HAVE_MINGW
+
+ if(switchuser) {
+ logger(LOG_ERR, "%s not supported on this platform", "-U");
+ return false;
+ }
+
+ if(do_chroot) {
+ logger(LOG_ERR, "%s not supported on this platform", "-R");
+ return false;
+ }
+
+#else
+ uid_t uid = 0;
+
+ if(switchuser) {
+ struct passwd *pw = getpwnam(switchuser);
+
+ if(!pw) {
+ logger(LOG_ERR, "unknown user `%s'", switchuser);
+ return false;
+ }
+
+ uid = pw->pw_uid;
+
+ if(initgroups(switchuser, pw->pw_gid) != 0 ||
+ setgid(pw->pw_gid) != 0) {
+ logger(LOG_ERR, "System call `%s' failed: %s",
+ "initgroups", strerror(errno));
+ return false;
+ }
+
+#ifndef ANDROID
+// Not supported in android NDK
+ endgrent();
+ endpwent();
+#endif
+ }
+
+ if(do_chroot) {
+ tzset(); /* for proper timestamps in logs */