Switch to side-by-side view

--- a/upmpd/upmpd.cxx
+++ b/upmpd/upmpd.cxx
@@ -18,6 +18,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
 
 #include <string>
 #include <iostream>
@@ -1190,12 +1192,14 @@
 {
 	string mpdhost("localhost");
 	int mpdport = 6600;
-//	string upnplogfilename("/tmp/upmpd_libupnp.log");
+	// string upnplogfilename("/tmp/upmpd_libupnp.log");
 	string logfilename;
 	int loglevel(upnppdebug::Logger::LLINF);
 	string configfile;
 	string friendlyname(dfltFriendlyName);
 	bool ownqueue = true;
+	string upmpdcliuser("upmpdcli");
+	string pidfilename("/var/run/upmpdcli.run");
 
 	const char *cp;
 	if ((cp = getenv("UPMPD_HOST")))
@@ -1267,11 +1271,42 @@
 	}
 	upnppdebug::Logger::getTheLog("")->setLogLevel(upnppdebug::Logger::LogLevel(loglevel));
 
+    Pidfile pidfile(pidfilename);
+
+	// If started by root, do the pidfile + change uid thing
+	uid_t runas(0);
+	if (geteuid() == 0) {
+		struct passwd *pass = getpwnam(upmpdcliuser.c_str());
+		if (pass == 0) {
+			LOGFAT("upmpdcli won't run as root and user " << upmpdcliuser << 
+				   " does not exist " << endl);
+			return 1;
+		}
+		runas = pass->pw_uid;
+
+		pid_t pid;
+		if ((pid = pidfile.open()) != 0) {
+			LOGFAT("Can't open pidfile: " << pidfile.getreason() << 
+				   ". Return (other pid?): " << pid << endl);
+			return 1;
+		}
+		if (pidfile.write_pid() != 0) {
+			LOGFAT("Can't write pidfile: " << pidfile.getreason() << endl);
+			return 1;
+		}
+	}
+
 	if ((op_flags & OPT_D)) {
 		if (daemon(1, 0)) {
 			LOGFAT("Daemon failed: errno " << errno << endl);
 			return 1;
 		}
+	}
+
+	if (geteuid() == 0) {
+		// Need to rewrite pid, it may have changed with the daemon call
+		pidfile.write_pid();
+		setuid(runas);
 	}
 
 	// Initialize libupnpp, and check health