diff -urN bzflag-2.0.8.orig/src/bzfs/bzfs.cxx bzflag-2.0.8/src/bzfs/bzfs.cxx --- bzflag-2.0.8.orig/src/bzfs/bzfs.cxx 2006-05-16 13:06:45 +0400 +++ bzflag-2.0.8/src/bzfs/bzfs.cxx 2006-05-16 13:06:58 +0400 @@ -20,6 +20,12 @@ #include #include #include +#ifndef _WIN32 +#include +#include +#include +#include +#endif // implementation-specific bzflag headers #include "NetHandler.h" @@ -4545,6 +4551,78 @@ return 2; } +#ifndef _WIN32 + struct passwd *user; + struct group *group; + uid_t uid = -1; + gid_t gid = -1; + + if (clOptions->doDaemon) + { + if (( clOptions->user.length() != 0 ) && ( clOptions->group.length() != 0 )) + { + + user = getpwnam(clOptions->user.c_str()); + group = getgrnam(clOptions->group.c_str()); + + if (user) + uid = user->pw_uid; + else + std::cerr << "Couldn't find user " << clOptions->user << " in password file" << std::endl; + + if (group) + gid = group->gr_gid; + else + std::cerr << "Couldn't find group " << clOptions->group << " in groups file" << std::endl; + + } + + if(getuid()) /* root check */ + { + std::cerr << "WARNING: Cant' change user/group id unless you are root." << std::endl; + return 0; + } + + if( (int) gid != -1) + { + if(!setgid(gid)) + std::cout << "Changed groupid to " << (int) gid << std::endl; + else + { + std::cerr << "Error changing groupd: " << strerror(errno) << std::endl; + return 0; + } + } + + if( (int) uid != -1) { + if(!setuid(uid)) + std::cout << "Changed userid to " << (int) uid << std::endl; + else + { + std::cerr << "Error changing userid: " << strerror(errno) << std::endl; + return 0; + } + } + + daemon(0,0); + } +#endif + + if(clOptions->pidFileName.length() != 0) + { + unsigned int pid = 0; + FILE *fp = fopen(clOptions->pidFileName.c_str(), "wt"); + #ifndef _WIN32 + pid = getpid(); + #else + pid = _getpid(); + #endif + if (fp) + { + fprintf(fp, "%d", pid); + fclose(fp); + } + } /* MAIN SERVER RUN LOOP * diff -urN bzflag-2.0.8.orig/src/bzfs/CmdLineOptions.cxx bzflag-2.0.8/src/bzfs/CmdLineOptions.cxx --- bzflag-2.0.8.orig/src/bzfs/CmdLineOptions.cxx 2006-05-16 13:06:45 +0400 +++ bzflag-2.0.8/src/bzfs/CmdLineOptions.cxx 2006-05-16 13:17:47 +0400 @@ -73,8 +73,14 @@ "[-filterCallsigns] " "[-filterChat] " "[-filterSimple] " +#ifndef _WIN32 +"[+daemon] " +#endif "[-g] " "[-gndtex ] " +#ifndef _WIN32 +"[-group ] " +#endif "[-groupdb ] " "[-h] " "[-handicap] " @@ -134,6 +140,9 @@ "[-timemanual] " "[-tk] " "[-tkkr ] " +#ifndef _WIN32 +"[-user ] " +#endif "[-ts [micros]] " "[-userdb ] " "[-vars ] " @@ -167,8 +176,12 @@ "\t-filterCallsigns: filter callsigns to disallow inappropriate user names\n" "\t-filterChat: filter chat messages\n" "\t-filterSimple: perform simple exact matches with the bad word list\n" +#ifndef _WIN32 +"\t+daemon: daemonize server\n" +#endif "\t-g: serve one game and then exit\n" "\t-gndtex: specify ground texture\n" +"\t-group: group to start bzfs as (only with +daemon and +user)\n" "\t-groupdb: file to read for group permissions\n" "\t-h: use random building heights\n" "\t-handicap: give advantage based on relative playing ability\n" @@ -233,6 +246,7 @@ "\t-timemanual: countdown for timed games is started with /countdown\n" "\t-tk: player does not die when killing a teammate\n" "\t-tkkr: team-kills-to-wins percentage (1-100) for kicking tk-ing players\n" +"\t-user: user to start bzfs as (only with +daemon and -group)\n" "\t-ts [micros]: timestamp all console output, [micros] to include\n" "\t\tmicroseconds\n" "\t-userdb: file to read for user access permissions\n" @@ -832,18 +846,8 @@ options.password = argv[i]; memset(argv[i], ' ', options.password.size()); } else if (strcmp(argv[i], "-pidfile") == 0) { - unsigned int pid = 0; checkArgc(1, i, argc, argv[i]); - FILE *fp = fopen(argv[i], "wt"); -#ifndef _WIN32 - pid = getpid(); -#else - pid = _getpid(); -#endif - if (fp) { - fprintf(fp, "%d", pid); - fclose(fp); - } + options.pidFileName = argv[i]; } else if (strcmp(argv[i], "-pf") == 0) { // try wksPort first and if we can't open that port then // let system assign a port for us. @@ -1138,6 +1142,14 @@ checkArgc(1, i, argc, argv[i]); BZDB.set(StateDatabase::BZDB_WORLDSIZE, TextUtils::format("%d",atoi(argv[i])*2)); std::cerr << "using world size of \"" << BZDBCache::worldSize << "\"" << std::endl; + } else if (strcmp(argv[i], "+daemon") == 0 ) { + options.doDaemon = true; + } else if (strcmp(argv[i], "-user") == 0 ) { + checkArgc(1, i, argc, argv[i]); + options.user = argv[i]; + } else if (strcmp(argv[i], "-group") == 0 ) { + checkArgc(1, i, argc, argv[i]); + options.group = argv[i]; } else { std::cerr << "bad argument \"" << argv[i] << "\"" << std::endl; usage(argv[0]); diff -urN bzflag-2.0.8.orig/src/bzfs/CmdLineOptions.h bzflag-2.0.8/src/bzfs/CmdLineOptions.h --- bzflag-2.0.8.orig/src/bzfs/CmdLineOptions.h 2006-05-16 13:06:45 +0400 +++ bzflag-2.0.8/src/bzfs/CmdLineOptions.h 2006-05-16 13:07:10 +0400 @@ -78,7 +78,8 @@ filterFilename(""), filterCallsigns(false), filterChat(false), filterSimple(false), banTime(300), voteTime(60), vetoTime(2), votesRequired(2), votePercentage(50.1f), voteRepeatTime(300), - autoTeam(false), citySize(5), cacheURL(""), cacheOut("") + autoTeam(false), citySize(5), cacheURL(""), cacheOut(""), + doDaemon(false), pidFileName(""), user(""), group("") { int i; for (FlagTypeMap::iterator it = FlagType::getFlagMap().begin(); @@ -196,6 +197,19 @@ std::string cacheURL; std::string cacheOut; + + //forking or not + bool doDaemon; + + //pidfile + std::string pidFileName; + + //user + std::string user; + + //group + + std::string group; // plugins typedef struct