static DEFAULT ExeFD() /* execute an FD command */ { DBGFEN(1,"ExeFD",NULL); /* * The command m,nFD is illegal: the user should use m,nFB */ if (CmdMod & MARGIS) { /* if it's m,nFD */ ErrStr(ERR_ILL, "m,nFD"); /* illegal command "m,nFD" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (CmdMod & DCOLON) { /* if it's ::FD */ ErrStr(ERR_ILL, "::FD"); /* illegal command "::FD" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } SrcTyp = S_SEARCH; if (Search(FALSE) == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (Matchd) { /* if successful search */ GapBeg += RefLen; /* delete found string */ } CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"SUCCESS"); return SUCCESS; }
static DEFAULT ExeFUn() /* execute an F_ command */ { DBGFEN(1,"ExeFUn",NULL); /* * The command m,nF_ is illegal: the user should use m,nFC */ if (CmdMod & MARGIS) { /* if it's m,nF_ */ ErrStr(ERR_ILL, "m,nF_"); /* illegal command "m,nF_" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (CmdMod & DCOLON) { /* if it's ::F_ */ ErrStr(ERR_ILL, "::F_"); /* illegal command "::F_" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } SrcTyp = U_SEARCH; if (Replac() == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"SUCCESS"); return SUCCESS; }
static DEFAULT ExeFS() /* execute an FS command */ { DBGFEN(1,"ExeFS",NULL); /* * The command m,nFS is illegal: the user should use m,nFC */ if (CmdMod & MARGIS) { /* if it's m,nFS */ ErrStr(ERR_ILL, "m,nFS"); /* illegal command "m,nFS" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } /* * If it's ::FStext$, it's a compare, not a search. The text argument is * compared to the characters immediately following the character pointer. * It returns -1 if the strings match, else 0. A ::FStext$ command is * equivalent to a .,.+1:FCtext$ command, so that's the way it's implemented. */ if (CmdMod & DCOLON) { /* if it's ::FS */ if (CmdMod & MARGIS) { /* if it's m,n::FS */ ErrStr(ERR_ILL, "m,n::FS"); DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (EStTop > EStBot) { /* if it's n::FS */ ErrStr(ERR_ILL, "n::FS"); DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (GapEnd == EBfEnd) { /* if nothing to search */ CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"PushEx(0)"); return PushEx(0L,OPERAND); } CmdMod &= ~DCOLON; /* clear double-colon bit */ CmdMod |= COLON; /* set colon bit */ CmdMod |= MARGIS; /* set m defined bit */ MArgmt = GapBeg - EBfBeg; /* set m */ if (PushEx((LONG)((GapBeg-EBfBeg)+1),OPERAND) == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE, PushEx() failed"); return FAILURE; } DBGFEX(1,DbgFNm,"ExeFC()"); return ExeFC(); /* execute FC command */ } SrcTyp = S_SEARCH; if (Replac() == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE, Replac() failed"); return FAILURE; } CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"SUCCESS"); return SUCCESS; }
static DEFAULT ExeFK() /* execute an FK command */ { DBGFEN(1,"ExeFK",NULL); if (CmdMod & MARGIS) { /* if it's m,nFK */ ErrStr(ERR_ILL, "m,nFK"); /* illegal command "m,nFK" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } if (CmdMod & DCOLON) { /* if it's ::FK */ ErrStr(ERR_ILL, "::FK"); /* illegal command "::FK" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } SrcTyp = FK_SEARCH; if (Search(FALSE) == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"SUCCESS"); return SUCCESS; }
DEFAULT GetAra() /* get m,n addresses */ { LONG TmpLng; #if DEBUGGING static char *DbgFNm = "GetAra"; sprintf(DbgSBf,"MArgmt = %ld, NArgmt = %ld", MArgmt, NArgmt); DbgFEn(4,DbgFNm,DbgSBf); #endif if (MArgmt < 0) { /* if negative m */ ErrMsg(ERR_NCA); /* negative argument to , */ DBGFEX(4,DbgFNm,"FAILURE, negative m"); return FAILURE; } if (NArgmt < 0) { /* if negative n */ ErrStr(ERR_POP, ErrTxt); /* POP = pointer off page */ DBGFEX(4,DbgFNm,"FAILURE, negative n"); return FAILURE; } if (MArgmt > NArgmt) { /* if wrong order */ TmpLng = NArgmt; NArgmt = MArgmt; MArgmt = TmpLng; } AraBeg = EBfBeg + MArgmt; /* compute area beginning */ if (AraBeg > GapBeg-1) { /* if past start of gap */ AraBeg += (GapEnd-GapBeg) + 1; /* correct for gap */ } AraEnd = (EBfBeg + NArgmt) - 1; /* compute area end */ if (AraEnd > GapBeg-1) { /* if before end of gap */ AraEnd += (GapEnd-GapBeg) + 1; /* correct for gap */ } if ((AraBeg > EBfEnd) || /* if m or n too large */ (AraEnd > EBfEnd)) { ErrStr(ERR_POP, ErrTxt); /* POP = pointer off page */ DBGFEX(4,DbgFNm,"FAILURE"); return FAILURE; } #if DEBUGGING sprintf(DbgSBf,"SUCCESS, AraBeg = %ld, AraEnd = %ld", Zcp2ul(AraBeg), Zcp2ul(AraEnd)); DbgFEx(4,DbgFNm,DbgSBf); #endif return SUCCESS; }
PulseSignalHeader & PulseClusterer::getNth(int idx) { if (!isComplete()) Fatal(666); if (idx < 0 || idx > (int) clusterList.size()) { ErrStr(idx, "index"); ErrStr(clusterList.size(), "pd clusters"); ErrStr(parent->getCount(), "supercluster count"); Fatal(666); } return *clusterList[idx]; }
std::ostream & operator << (std::ostream & os, const BlError & bl) { os << ErrStr (bl.err); const BlLineNumber line= bl.getpos ().getnum (); if (line != LineDirectCommand) os << " in " << line; //os << '\n'; return os; }
static DEFAULT ExeFC() /* execute an FC command */ { DBGFEN(1,"ExeFC",NULL); if (CmdMod & DCOLON) { /* if it's ::FC */ ErrStr(ERR_ILL, "::FC"); /* illegal command "::FC" */ DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } SrcTyp = FB_SEARCH; if (Replac() == FAILURE) { DBGFEX(1,DbgFNm,"FAILURE"); return FAILURE; } CmdMod = '\0'; /* clear modifiers flags */ DBGFEX(1,DbgFNm,"SUCCESS"); return SUCCESS; }
/******************************************************************************************** > HRESULT Error::GetRalphError() Author: Chris_Snook (Xara Group Ltd) <*****@*****.**> Created: 23/05/94 Purpose: ERROR1 - No local reporting -pass the mapped Error code to the harness ERROR2 - Report the Error locally - don't pass to handler ERROR3 - Report as ERROR2's - won't occur in retails - ********************************************************************************************/ HRESULT Error::GetRalphError() { UINT32 Err = Error::GetRalphErrorNumber(); wxString ErrStr( Error::GetErrorString() ); HRESULT hr = S_OK; // ERROR2's 3's if(Err==0) { if(!ErrStr.IsEmpty()) { #if defined(_DEBUG) && defined(__WXMSW__) MessageBox(NULL,ErrStr,_T("Error"),MB_OK); #endif // make sure we clear ERROR2's 'cause we report them now Error::ClearError(); } } //ERROR1 if(Err!=0) { // Do Mapping hr = ErrIDToHRESULT(Err); } // ERROR 2's 3's if(Err==0) { if(!ErrStr.IsEmpty()) hr = RALPH_E_INTERNAL; } return hr; }
// // routine: receive and send on incoming messages // // Notes: // No analysis of the message is performed - that is left // to the command processor task. Instead, the local copy // of the header // is demarshalled to determined whether or not there // is associated data; if there is, space is allocated to // contain it. void * SseInputTask::routine() { extractArgs(); Timer timer; if (cmdArgs->noSSE()) { processIpFromFile(); while (1) timer.sleep(3000); }; // run forever, waiting for messages from the SSE bool stopIssued = false; bool done = false; uint32_t lastCode = MESSAGE_CODE_UNINIT; int32_t lastLen = 0; uint32_t lastTime = 0; while (!done) { // if there's no connection, request that it be // established, then wait for that to happen if (!sse->isConnected()) { requestConnection(); while (!sse->isConnected()) timer.sleep(3000); } stopIssued = false; // got a connection - wait for data to come in SseInterfaceHeader hdr; Error err = sse->recv((void *) &hdr, sizeof(hdr)); if (err) { switch (err) { case EAGAIN: case EINTR: case ENOTCONN: case ECONNRESET: stopAllActivities(stopIssued); continue; default: Fatal(err); break; } } // demarshall the header hdr.demarshall(); if (cmdArgs->logSseMessages()) { LogWarning(ERR_NE, hdr.activityId, "bad msg from Sse, code = %d, len = %d", hdr.code, hdr.dataLength); } // allocate a message to hold the incoming message Msg *msg = msgList->alloc(); msg->setHeader(hdr); msg->setUnit((sonata_lib::Unit) UnitSse); // if there's data associated with the message, // allocate space and retrieve it, demarshall it // based on the message type, // then send it on to the command processor void *data = 0; int32_t len = hdr.dataLength; timeval tv; gettimeofday(&tv, NULL); if (len > 10000) { LogWarning(ERR_NE, hdr.activityId, "msg code = %d, len = %d, t = %u, last msg = %d, last len = %d, last t = %u", hdr.code, len, tv.tv_sec, lastCode, lastLen, lastTime); Timer t; t.sleep(100); } else { lastCode = hdr.code; lastLen = len; lastTime = tv.tv_sec; } if (len) { MemBlk *blk = partitionSet->alloc(len); Assert(blk); if (!blk) Fatal(ERR_MAF); data = blk->getData(); err = sse->recv(data, len); if (err) { switch (err) { case EAGAIN: case EINTR: case ENOTCONN: case ECONNRESET: blk->free(); Assert(msgList->free(msg)); stopAllActivities(stopIssued); continue; default: Fatal(err); break; } } msg->setData(data, len, blk); } // demarshall the data of the message depending on // the message type switch (hdr.code) { case REQUEST_INTRINSICS: break; case CONFIGURE_DX: (static_cast<DxConfiguration *> (data))->demarshall(); break; case PERM_RFI_MASK: case BIRDIE_MASK: case RCVR_BIRDIE_MASK: case TEST_SIGNAL_MASK: demarshallFrequencyMask(data); break; case RECENT_RFI_MASK: demarshallRecentRFIMask(data); break; case REQUEST_DX_STATUS: break; case SEND_DX_ACTIVITY_PARAMETERS: (static_cast<DxActivityParameters *> (data))->demarshall(); break; case DX_SCIENCE_DATA_REQUEST: (static_cast<DxScienceDataRequest *> (data))->demarshall(); break; #ifdef notdef case SEND_DOPPLER_PARAMETERS: (static_cast<DopplerParameters *> (data))->demarshall(); break; #endif case BEGIN_SENDING_FOLLOW_UP_SIGNALS: (static_cast<Count *> (data))->demarshall(); break; case SEND_FOLLOW_UP_CW_SIGNAL: (static_cast<FollowUpCwSignal *> (data))->demarshall(); break; case SEND_FOLLOW_UP_PULSE_SIGNAL: (static_cast<FollowUpPulseSignal *> (data))->demarshall(); break; case DONE_SENDING_FOLLOW_UP_SIGNALS: break; case START_TIME: (static_cast<StartActivity *> (data))->demarshall(); break; case BEGIN_SENDING_CANDIDATES: (static_cast<Count *> (data))->demarshall(); break; case SEND_CANDIDATE_CW_POWER_SIGNAL: (static_cast<CwPowerSignal *> (data))->demarshall(); break; case SEND_CANDIDATE_PULSE_SIGNAL: demarshallPulseSignal(data); break; case DONE_SENDING_CANDIDATES: break; case BEGIN_SENDING_CW_COHERENT_SIGNALS: break; case SEND_CW_COHERENT_SIGNAL: (static_cast<CwCoherentSignal *> (data))->demarshall(); break; case DONE_SENDING_CW_COHERENT_SIGNALS: break; case REQUEST_ARCHIVE_DATA: (static_cast<ArchiveRequest *> (data))->demarshall(); break; case DISCARD_ARCHIVE_DATA: (static_cast<ArchiveRequest *> (data))->demarshall(); break; // the following commands arrive with no data case STOP_DX_ACTIVITY: case SHUTDOWN_DX: case RESTART_DX: Debug(DEBUG_CONTROL, hdr.activityId, "STOP_DX_ACTIVITY, act"); break; default: LogError(ERR_IMT, hdr.activityId, "activity %d, type %d", hdr.activityId, hdr.code); Err(ERR_IMT); ErrStr(hdr.code, "msg code"); Assert(msgList->free(msg)); continue; } // at this point, the entire marshalled message is in // a generic Msg; send the message on for processing, // then go back to waiting cmdQ->send(msg); } return (0); }
// program entry point int main(int argc, char *argv[]) { is_daemonised = false; bool nodaemon = false; bool needreset = false; std::string configfile(__CONFFILE); srand(time(NULL)); int rc; openlog("dansguardian", LOG_PID | LOG_CONS, LOG_USER); #ifdef DGDEBUG std::cout << "Running in debug mode..." << std::endl; #endif #ifdef __BENCHMARK char benchmark = '\0'; #endif for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (unsigned int j = 1; j < strlen(argv[i]); j++) { char option = argv[i][j]; bool dobreak = false; switch (option) { case 'q': read_config(configfile.c_str(), 0); return sysv_kill(o.pid_filename); case 'Q': read_config(configfile.c_str(), 0); sysv_kill(o.pid_filename, false); // give the old process time to die while(sysv_amirunning(o.pid_filename)) sleep(1); unlink(o.pid_filename.c_str()); unlink(o.ipc_filename.c_str()); unlink(o.urlipc_filename.c_str()); // remember to reset config before continuing needreset = true; break; case 's': read_config(configfile.c_str(), 0); return sysv_showpid(o.pid_filename); case 'r': read_config(configfile.c_str(), 0); return sysv_hup(o.pid_filename); case 'g': read_config(configfile.c_str(), 0); return sysv_usr1(o.pid_filename); case 'v': std::cout << "DansGuardian " << PACKAGE_VERSION << std::endl << std::endl << "Built with: " << DG_CONFIGURE_OPTIONS << std::endl; return 0; case 'N': nodaemon = true; break; case 'c': if ((i+1) < argc) { configfile = argv[i+1]; dobreak = true; // broken-ness of this option reported by Jason Gauthier 2006-03-09 } else { std::cerr << "No config file specified!" << std::endl; return 1; } break; case 'h': std::cout << "Usage: " << argv[0] << " [{-c ConfigFileName|-v|-P|-h|-N|-q|-s|-r|-g}]" << std::endl; std::cout << " -v gives the version number and build options." << std::endl; std::cout << " -h gives this message." << std::endl; std::cout << " -c allows you to specify a different configuration file location." << std::endl; std::cout << " -N Do not go into the background." << std::endl; std::cout << " -q causes DansGuardian to kill any running copy." << std::endl; std::cout << " -Q kill any running copy AND start a new one with current options." << std::endl; std::cout << " -s shows the parent process PID and exits." << std::endl; std::cout << " -r closes all connections and reloads config files by issuing a HUP," << std::endl; std::cout << " but this does not reset the maxchildren option (amongst others)." << std::endl; std::cout << " -g gently restarts by not closing all current connections; only reloads" << std::endl << " filter group config files. (Issues a USR1)" << std::endl; #ifdef __BENCHMARK std::cout << " --bs benchmark searching filter group 1's bannedsitelist" << std::endl; std::cout << " --bu benchmark searching filter group 1's bannedurllist" << std::endl; std::cout << " --bp benchmark searching filter group 1's phrase lists" << std::endl; std::cout << " --bn benchmark filter group 1's NaughtyFilter in its entirety" << std::endl; #endif return 0; #ifdef __BENCHMARK case '-': if (strlen(argv[i]) != 4) { std::cerr << "Invalid benchmark option" << std::endl; return 1; } benchmark = argv[i][3]; dobreak = true; break; #endif } if (dobreak) break; // skip to the next argument } } } // Set current locale for proper character conversion setlocale(LC_ALL, ""); if (needreset) { o.reset(); } read_config(configfile.c_str(), 2); #ifdef __BENCHMARK // run benchmarks instead of starting the daemon if (benchmark) { std::string results; char* found; struct tms then, now; std::string line; std::deque<String*> lines; while (!std::cin.eof()) { std::getline(std::cin, line); String* strline = new String(line); lines.push_back(strline); } String* strline = NULL; times(&then); switch (benchmark) { case 's': // bannedsitelist while (!lines.empty()) { strline = lines.back(); lines.pop_back(); if ((found = o.fg[0]->inBannedSiteList(*strline))) { results += found; results += '\n'; } delete strline; } break; case 'u': // bannedurllist while (!lines.empty()) { strline = lines.back(); lines.pop_back(); if ((found = o.fg[0]->inBannedURLList(*strline))) { results += found; results += '\n'; } delete strline; } break; case 'p': { // phraselists std::deque<unsigned int> found; std::string file; while (!lines.empty()) { strline = lines.back(); lines.pop_back(); file += strline->toCharArray(); delete strline; } char cfile[file.length() + 129]; memcpy(cfile, file.c_str(), sizeof(char)*file.length()); o.lm.l[o.fg[0]->banned_phrase_list]->graphSearch(found, cfile, file.length()); for (std::deque<unsigned int>::iterator i = found.begin(); i != found.end(); i++) { results += o.lm.l[o.fg[0]->banned_phrase_list]->getItemAtInt(*i); results += '\n'; } } break; case 'n': { // NaughtyFilter std::string file; NaughtyFilter n; while (!lines.empty()) { strline = lines.back(); lines.pop_back(); file += strline->toCharArray(); delete strline; } DataBuffer d(file.c_str(), file.length()); String f; n.checkme(&d, f, f); std::cout << n.isItNaughty << std::endl << n.whatIsNaughty << std::endl << n.whatIsNaughtyLog << std::endl << n.whatIsNaughtyCategories << std::endl; } break; default: std::cerr << "Invalid benchmark option" << std::endl; return 1; } times(&now); std::cout << results << std::endl << "time: " << now.tms_utime - then.tms_utime << std::endl; return 0; } #endif if (sysv_amirunning(o.pid_filename)) { syslog(LOG_ERR, "%s", "I seem to be running already!"); std::cerr << "I seem to be running already!" << std::endl; return 1; // can't have two copies running!! } if (nodaemon) { o.no_daemon = 1; } if ((o.max_children + 6) > FD_SETSIZE) { syslog(LOG_ERR, "%s", "maxchildren option in dansguardian.conf has a value too high."); std::cerr << "maxchildren option in dansguardian.conf has a value too high." << std::endl; std::cerr << "Dammit Jim, I'm a filtering proxy, not a rabbit." << std::endl; return 1; // we can't have rampant proccesses can we? } unsigned int rootuid; // prepare a struct for use later rootuid = geteuid(); o.root_user = rootuid; struct passwd *st; // prepare a struct struct group *sg; // "daemongroup" option exists, but never used to be honoured. this is now // an important feature, however, because we need to be able to create temp // files with suitable permissions for scanning by AV daemons - we do this // by becoming a member of a specified AV group and setting group read perms if ((sg = getgrnam(o.daemon_group_name.c_str())) != 0) { o.proxy_group = sg->gr_gid; } else { syslog(LOG_ERR, "Unable to getgrnam(): %s", ErrStr().c_str()); std::cerr << "Unable to getgrnam(): " << ErrStr() << std::endl; return 1; } if ((st = getpwnam(o.daemon_user_name.c_str())) != 0) { // find uid for proxy user o.proxy_user = st->pw_uid; rc = setgid(o.proxy_group); // change to rights of proxy user group // i.e. low - for security if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to setgid()"); std::cerr << "Unable to setgid()" << std::endl; return 1; // setgid failed for some reason so exit with error } #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, st->pw_uid); #else rc = seteuid(o.proxy_user); // need to be euid so can su back // (yes it negates but no choice) #endif if (rc == -1) { syslog(LOG_ERR, "Unable to seteuid()"); std::cerr << "Unable to seteuid()" << std::endl; return 1; // seteuid failed for some reason so exit with error } } else { syslog(LOG_ERR, "Unable to getpwnam() - does the proxy user exist?"); std::cerr << "Unable to getpwnam() - does the proxy user exist?" << std::endl; std::cerr << "Proxy user looking for is '" << o.daemon_user_name << "'" << std::endl; return 1; // was unable to lockup the user id from passwd // for some reason, so exit with error } if (!o.no_logger && !o.log_syslog) { std::ofstream logfiletest(o.log_location.c_str(), std::ios::app); if (logfiletest.fail()) { syslog(LOG_ERR, "Error opening/creating log file. (check ownership and access rights)."); std::cout << "Error opening/creating log file. (check ownership and access rights)." << std::endl; std::cout << "I am running as " << o.daemon_user_name << " and I am trying to open " << o.log_location << std::endl; return 1; // opening the log file for writing failed } logfiletest.close(); } urldecode_re.comp("%[0-9a-fA-F][0-9a-fA-F]"); // regexp for url decoding #ifdef HAVE_PCRE // todo: these only work with PCRE enabled (non-greedy matching). // change them, or make them a feature for which you need PCRE? absurl_re.comp("[\"'](http|ftp)://.*?[\"']"); // find absolute URLs in quotes relurl_re.comp("(href|src)\\s*=\\s*[\"'].*?[\"']"); // find relative URLs in quotes #endif // this is no longer a class, but the comment has been retained for historical reasons. PRA 03-10-2005 //FatController f; // Thomas The Tank Engine while (true) { rc = fc_controlit(); // its a little messy, but I wanted to split // all the ground work and non-daemon stuff // away from the daemon class // However the line is not so fine. if (rc == 2) { // In order to re-read the conf files and create cache files // we need to become root user again #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, rootuid); #else rc = seteuid(rootuid); #endif if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to seteuid() to read conf files."); #ifdef DGDEBUG std::cerr << "Unable to seteuid() to read conf files." << std::endl; #endif return 1; } #ifdef DGDEBUG std::cout << "About to re-read conf file." << std::endl; #endif o.reset(); if (!o.read(configfile.c_str(), 2)) { syslog(LOG_ERR, "%s", "Error re-parsing the dansguardian.conf file or other DansGuardian configuration files"); #ifdef DGDEBUG std::cerr << "Error re-parsing the dansguardian.conf file or other DansGuardian configuration files" << std::endl; #endif return 1; // OptionContainer class had an error reading the conf or // other files so exit with error } #ifdef DGDEBUG std::cout << "conf file read." << std::endl; #endif if (nodaemon) { o.no_daemon = 1; } while (waitpid(-1, NULL, WNOHANG) > 0) { } // mop up defunts #ifdef HAVE_SETREUID rc = setreuid((uid_t) - 1, st->pw_uid); #else rc = seteuid(st->pw_uid); // become low priv again #endif if (rc == -1) { syslog(LOG_ERR, "%s", "Unable to re-seteuid()"); #ifdef DGDEBUG std::cerr << "Unable to re-seteuid()" << std::endl; #endif return 1; // seteuid failed for some reason so exit with error } continue; } if (rc > 0) { if (!is_daemonised) { std::cerr << "Exiting with error" << std::endl; } syslog(LOG_ERR, "%s", "Exiting with error"); return rc; // exit returning the error number } return 0; // exit without error } }