void ofxNetworkUtils::init(unsigned int filterFlags, unsigned int excludeFlags){
	networkInterfaces.clear(); // 
	struct ifaddrs * ifap;
	if (getifaddrs(&ifap) == 0)
	{
		struct ifaddrs * p = ifap;
		while(p)
		{
			int ifaAddr  = SockAddrToUint(p->ifa_addr);
			int maskAddr = SockAddrToUint(p->ifa_netmask);
			int dstAddr  = SockAddrToUint(p->ifa_dstaddr);
			if (ifaAddr != 0 && (p->ifa_flags & filterFlags) && (p->ifa_flags & excludeFlags) == 0)
			{
				
				networkInterface aNetworkInterface;
				
				char ifaAddrStr[32];  Inet_NtoA(ifaAddr,  ifaAddrStr);
				char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
				char dstAddrStr[32];  Inet_NtoA(dstAddr,  dstAddrStr);
				
				char logMsg[512];
				sprintf(logMsg, "Found interface: name=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, ifaAddrStr, maskAddrStr, dstAddrStr);
				
				ofLog(OF_LOG_NOTICE, logMsg);
				networkInterfaces.push_back( new networkInterface(p->ifa_name, ifaAddrStr, maskAddrStr, dstAddrStr));
				
			}
			p = p->ifa_next;
		}
		freeifaddrs(ifap);
	}
	
}
示例#2
0
文件: net_ip.c 项目: Ododo/etlegacy
/*
=============
Sys_SockaddrToString
=============
*/
static void Sys_SockaddrToString(char *dest, int destlen, struct sockaddr *input)
{
#ifdef FEATURE_IPV6
	socklen_t inputlen;

	if (input->sa_family == AF_INET6)
	{
		inputlen = sizeof(struct sockaddr_in6);
	}
	else
	{
		inputlen = sizeof(struct sockaddr_in);
	}

	if (getnameinfo(input, inputlen, dest, destlen, NULL, 0, NI_NUMERICHOST) && destlen > 0)
	{
		*dest = '\0';
	}
#else // IPV4
#ifdef __MORPHOS__
	char *addr = Inet_NtoA(((struct sockaddr_in *)input)->sin_addr.s_addr);
#else
	char *addr = inet_ntoa(((struct sockaddr_in *)input)->sin_addr);
#endif

	Q_strncpyz(dest, addr, destlen);
#endif
}
示例#3
0
// Send PORT command
int ftp_port( struct ftp_info *info, unsigned long flags, struct sockaddr_in *addr )
{
	int reply;
	int ip1, ip2, ip3, ip4, p1, p2, port;

	if (!addr)
		return 0;

	if	(!(flags & PORT_QUIET))
		*info->fi_serverr = 0;

	if (sscanf(Inet_NtoA(addr->sin_addr.s_addr), "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4)
		return 0;

	port = ntohs(addr->sin_port);
	p1 = port / 256;
	p2 = port % 256;

	reply = _ftpa( info, flags, "PORT %d,%d,%d,%d,%d,%d", ip1, ip2, ip3, ip4, p1, p2 );

	if	(!(flags & PORT_QUIET) && reply / 100 != COMPLETE)
		stccpy( info->fi_serverr, info->fi_iobuf, IOBUFSIZE + 1 );

	return reply;
}
示例#4
0
bool 
UdpSend( link_t *link, udp_hdr_t *udpHdr, ip_hdr_t *ipHdr, udp_descr_t *descr )
{
bool     success = FALSE;
u8       *frame;
static i8       UdpSendaddr[32];
i32      length;
    
    length = LinkLength(link);
    frame = (u8 *)x_malloc(length);  
    if(frame!=0) {
        if(LinkCopy(link, frame, (u16)length)) {
#ifdef XSTK_NUCNET
#ifdef XLIB_XSNMP
			plist[0].charptr = (i8 *)Inet_NtoA(ipHdr->dst);
			plist[1].intval  = udpHdr->dst;
            x_sprintf(UdpSendaddr,"udp:%s:%d"); 
#else
            sprintf(UdpSendaddr,"udp:%s:%d",Inet_NtoA(ipHdr->dst),udpHdr->dst); 
#endif
#else
#ifdef XLIB_XSNMP
			plist[0].charptr = (i8 *)Inet_NtoA(x_htonl(ipHdr->dst));
			plist[1].intval  = udpHdr->dst;
            x_sprintf(UdpSendaddr,"udp:%s:%d"); 
#else
            sprintf(UdpSendaddr,"udp:%s:%d",Inet_NtoA(x_htonl(ipHdr->dst)),udpHdr->dst); 
#endif
#endif
        
            if(NwDgSendTo(UdpSendaddr, frame, length, udpHdr->src)) {
                success = TRUE;
			} else {
			}
        }
       x_free(frame);
    }
    
    if(success) {
        udpStat.outDatagrams++;
	} else {
        udpStat.outErrors++;
	}
       
    return success;         
}
示例#5
0
int aros_getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *host, size_t hostlen,
char *serv, size_t servlen, int flags)
{
  struct sockaddr_in *sin = (struct sockaddr_in *)sa;

  if (host) {
    snprintf(host, hostlen, Inet_NtoA(sin->sin_addr.s_addr));
  }

  return 0;
}
示例#6
0
void
WUploadThread::SetUpload(const ConstSocketRef &socket, muscle::ip_address remoteIP, WFileThread * ft)
{
	String host;
	fAccept = false;
	fRemoteIP = remoteIP;
	fSocket = socket;
	fFileThread = ft;
	// Set string ip too
	muscle::ip_address _ip = GetPeerIPAddress(fSocket, true);
	host = Inet_NtoA(_ip, true);
	fStrRemoteIP = host.Cstr();
}
示例#7
0
App::App(void)
	:
	BApplication(STR_MUSCLE_DEAMON_NAME)
	, maxBytes(MUSCLE_NO_LIMIT)
	, maxNodesPerSession(MUSCLE_NO_LIMIT)
	, maxReceiveRate(MUSCLE_NO_LIMIT)
	, maxSendRate(MUSCLE_NO_LIMIT)
	, maxCombinedRate(MUSCLE_NO_LIMIT)
	, maxMessageSize(MUSCLE_NO_LIMIT)
	, maxSessions(MUSCLE_NO_LIMIT)
	, maxSessionsPerHost(MUSCLE_NO_LIMIT)
	, fprivateKeyFilePath(NULL)
	, retVal(0)
	, okay(true)
{
	CompleteSetupSystem css;

	TCHECKPOINT;

#ifdef MUSCLE_ENABLE_MEMORY_TRACKING
	printf("MUSCLE_ENABLE_MEMORY_TRACKING\n");
	// Set up memory allocation policies for our server.  These policies will make sure
	// that the server can't allocate more than a specified amount of memory, and if it tries,
	// some emergency callbacks will be called to free up cached info.
	FunctionCallback fcb(AbstractObjectRecycler::GlobalFlushAllCachedObjects);
	MemoryAllocatorRef nullRef;
	AutoCleanupProxyMemoryAllocator cleanupAllocator(nullRef);
	cleanupAllocator.GetCallbacksQueue().AddTail(GenericCallbackRef(&fcb, false));

	UsageLimitProxyMemoryAllocator usageLimitAllocator(MemoryAllocatorRef(&cleanupAllocator, false));

	SetCPlusPlusGlobalMemoryAllocator(MemoryAllocatorRef(&usageLimitAllocator, false));
	SetCPlusPlusGlobalMemoryAllocator(MemoryAllocatorRef());  // unset, so that none of our allocator objects will be used after they are gone
	
	if ((maxBytes != MUSCLE_NO_LIMIT) && (&usageLimitAllocator)) 
		usageLimitAllocator.SetMaxNumBytes(maxBytes);
#endif

	TCHECKPOINT;

	server.GetAddressRemappingTable() = tempRemaps;

	if (maxNodesPerSession != MUSCLE_NO_LIMIT) 
		server.GetCentralState().AddInt32(PR_NAME_MAX_NODES_PER_SESSION, maxNodesPerSession);
	
	for (MessageFieldNameIterator iter = tempPrivs.GetFieldNameIterator(); iter.HasData(); iter++) 
		tempPrivs.CopyName(iter.GetFieldName(), server.GetCentralState());

	// If the user asked for bandwidth limiting, create Policy objects to handle that.
	AbstractSessionIOPolicyRef inputPolicyRef, outputPolicyRef;
	if (maxCombinedRate != MUSCLE_NO_LIMIT) {
		inputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxCombinedRate));
		outputPolicyRef = inputPolicyRef;
		
		if (inputPolicyRef()) 
			LogTime(MUSCLE_LOG_INFO, "Limiting aggregate I/O bandwidth to %.02f kilobytes/second.\n", ((float)maxCombinedRate/1024.0f));
		else
		{
			WARN_OUT_OF_MEMORY;
			okay = false;
		}
	} else {
		if (maxReceiveRate != MUSCLE_NO_LIMIT) {
			inputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxReceiveRate));
			
			if (inputPolicyRef())
				LogTime(MUSCLE_LOG_INFO, "Limiting aggregate receive bandwidth to %.02f kilobytes/second.\n", ((float)maxReceiveRate/1024.0f));
			else {
				WARN_OUT_OF_MEMORY;
				okay = false;
			}
		}
		
		if (maxSendRate != MUSCLE_NO_LIMIT) {
			outputPolicyRef.SetRef(newnothrow RateLimitSessionIOPolicy(maxSendRate));
			
			if (outputPolicyRef())
				LogTime(MUSCLE_LOG_INFO, "Limiting aggregate send bandwidth to %.02f kilobytes/second.\n", ((float)maxSendRate/1024.0f)); 
			else {
				WARN_OUT_OF_MEMORY;
				okay = false; 
			}
		}
	}

	// Set up the Session Factory.  This factory object creates the new StorageReflectSessions
	// as needed when people connect, and also has a filter to keep out the riff-raff.
	StorageReflectSessionFactory factory; factory.SetMaxIncomingMessageSize(maxMessageSize);
	FilterSessionFactory filter(ReflectSessionFactoryRef(&factory, false), maxSessionsPerHost, maxSessions);
	filter.SetInputPolicy(inputPolicyRef);
	filter.SetOutputPolicy(outputPolicyRef);

	for (int b=bans.GetNumItems()-1; ((okay)&&(b>=0)); b--) 
		if (filter.PutBanPattern(bans[b]()) != B_NO_ERROR) 
			okay = false;
	
	for (int a=requires.GetNumItems()-1; ((okay)&&(a>=0)); a--) 
		if (filter.PutRequirePattern(requires[a]()) != B_NO_ERROR)
			okay = false;

#ifdef MUSCLE_ENABLE_SSL
   ByteBufferRef optCryptoBuf;
   if (fprivateKeyFilePath)
   {
      FileDataIO fdio(muscleFopen(fprivateKeyFilePath->Cstr(), "rb"));
      ByteBufferRef fileData = GetByteBufferFromPool((uint32)fdio.GetLength());
      if ((fdio.GetFile())&&(fileData())&&(fdio.ReadFully(fileData()->GetBuffer(), fileData()->GetNumBytes()) == fileData()->GetNumBytes()))
      { 
         LogTime(MUSCLE_LOG_INFO, "Using private key file [%s] to authenticate with connecting clients\n", fprivateKeyFilePath->Cstr());
         server.SetSSLPrivateKey(fileData);
      }
      else
      {
         LogTime(MUSCLE_LOG_CRITICALERROR, "Couldn't load private key file [%s] (file not found?)\n", fprivateKeyFilePath->Cstr());
         okay = false;
      }
   }
#else
   if (fprivateKeyFilePath)
   {
      LogTime(MUSCLE_LOG_CRITICALERROR, "Can't loadp private key file [%s], SSL support is not compiled in!\n", fprivateKeyFilePath->Cstr());
      okay = false;
   }
#endif

	// Set up ports.  We allow multiple ports, mostly just to show how it can be done;
	// they all get the same set of ban/require patterns (since they all do the same thing anyway).
	if (listenPorts.IsEmpty())
		listenPorts.PutWithDefault(IPAddressAndPort(invalidIP, DEFAULT_MUSCLED_PORT));
	
	for (HashtableIterator<IPAddressAndPort, Void> iter(listenPorts); iter.HasData(); iter++) {
		const IPAddressAndPort & iap = iter.GetKey();
		if (server.PutAcceptFactory(iap.GetPort(), ReflectSessionFactoryRef(&filter, false), iap.GetIPAddress()) != B_NO_ERROR) {
			if (iap.GetIPAddress() == invalidIP)
				LogTime(MUSCLE_LOG_CRITICALERROR, "Error adding port %u, aborting.\n", iap.GetPort());
			else
				LogTime(MUSCLE_LOG_CRITICALERROR, "Error adding port %u to interface %s, aborting.\n", iap.GetPort(), Inet_NtoA(iap.GetIPAddress())());
			
			okay = false;
			break;
		}
	}

	if (okay) {
		retVal = (server.ServerProcessLoop() == B_NO_ERROR) ? 0 : 10;
		
		if (retVal > 0)
			LogTime(MUSCLE_LOG_CRITICALERROR, "Server process aborted!\n");
		else 
			LogTime(MUSCLE_LOG_INFO, "Server process exiting.\n");
	} else
		LogTime(MUSCLE_LOG_CRITICALERROR, "Error occurred during setup, aborting!\n");

	server.Cleanup();
}
示例#8
0
void
App::ArgvReceived(int32 argc, char **argv)
{
	printf("ArgvReceived\n");
	
	Message args; 
	(void) ParseArgs(argc, argv, args);
	HandleStandardDaemonArgs(args);

	const char * value;
	if (args.HasName("help")) {
		Log(MUSCLE_LOG_INFO, "Usage:  muscled [port=%u] [listen=ip:port] [displaylevel=lvl] [filelevel=lvl] [logfile=filename]\n", DEFAULT_MUSCLED_PORT); 
#ifdef MUSCLE_ENABLE_MEMORY_TRACKING
		Log(MUSCLE_LOG_INFO, "					 [maxmem=megs]\n");
#endif
		Log(MUSCLE_LOG_INFO, "					 [maxnodespersession=num] [remap=oldip=newip]\n");
		Log(MUSCLE_LOG_INFO, "					 [ban=ippattern] [require=ippattern]\n");
		Log(MUSCLE_LOG_INFO, "					 [privban=ippattern] [privunban=ippattern]\n");
		Log(MUSCLE_LOG_INFO, "					 [privkick=ippattern] [privall=ippattern]\n");
		Log(MUSCLE_LOG_INFO, "					 [maxsendrate=kBps] [maxreceiverate=kBps]\n");
		Log(MUSCLE_LOG_INFO, "					 [maxcombinedrate=kBps] [maxmessagesize=k]\n");
		Log(MUSCLE_LOG_INFO, "					 [maxsessions=num] [maxsessionsperhost=num]\n");
		Log(MUSCLE_LOG_INFO, "					 [localhost=ipaddress] [daemon]\n");
		Log(MUSCLE_LOG_INFO, " - port may be any number between 1 and 65536\n");
		Log(MUSCLE_LOG_INFO, " - listen is like port, except it includes a local interface IP as well.\n");
		Log(MUSCLE_LOG_INFO, " - lvl is: none, critical, errors, warnings, info, debug, or trace.\n");
#ifdef MUSCLE_ENABLE_MEMORY_TRACKING
		Log(MUSCLE_LOG_INFO, " - maxmem is the max megabytes of memory the server may use (default=unlimited)\n");
#endif
		Log(MUSCLE_LOG_INFO, " - You may also put one or more ban=<pattern> arguments in.\n");
		Log(MUSCLE_LOG_INFO, "	Each pattern specifies one or more IP addresses to\n");
		Log(MUSCLE_LOG_INFO, "	disallow connections from, e.g. ban=192.168.*.*\n");
		Log(MUSCLE_LOG_INFO, " - You may put one or more require=<pattern> arguments in.\n");
		Log(MUSCLE_LOG_INFO, "	If any of these are present, then only IP addresses that match\n");
		Log(MUSCLE_LOG_INFO, "	at least one of them will be allowed to connect.\n");
		Log(MUSCLE_LOG_INFO, " - To assign privileges, specify one of the following:\n");
		Log(MUSCLE_LOG_INFO, "	privban=<pattern>, privunban=<pattern>,\n");
		Log(MUSCLE_LOG_INFO, "	privkick=<pattern> or privall=<pattern>.\n");
		Log(MUSCLE_LOG_INFO, "	privall assigns all privileges to the matching IP addresses.\n");
		Log(MUSCLE_LOG_INFO, " - remap tells muscled to treat connections from a given IP address\n");
		Log(MUSCLE_LOG_INFO, "	as if they are coming from another (for stupid NAT tricks, etc)\n");
		Log(MUSCLE_LOG_INFO, " - If daemon is specified, muscled will run as a background process.\n");
	}

	{
		for (int32 i = 0; (args.FindString("port", i, &value) == B_NO_ERROR); i++) {
			int16 port = atoi(value);
			
			if (port >= 0)
				listenPorts.PutWithDefault(IPAddressAndPort(invalidIP, port));
		}

		for (int32 i = 0; (args.FindString("listen", i, &value) == B_NO_ERROR); i++) {
			IPAddressAndPort iap(value, DEFAULT_MUSCLED_PORT, false);
			
			if (iap.GetPort() > 0)
				listenPorts.PutWithDefault(iap);
			else
				LogTime(MUSCLE_LOG_ERROR, "Unable to parse IP/port string [%s]\n", value);
		}
	}

	{
		for (int32 i = 0; (args.FindString("remap", i, &value) == B_NO_ERROR); i++) {
			StringTokenizer tok(value, ",=");
			const char * from = tok();
			const char * to = tok();
			ip_address fromIP = from ? Inet_AtoN(from) : 0;
			
			if ((fromIP != invalidIP)&&(to)) {
				char ipbuf[64]; Inet_NtoA(fromIP, ipbuf);
				LogTime(MUSCLE_LOG_INFO, "Will treat connections coming from [%s] as if they were from [%s].\n", ipbuf, to);
				tempRemaps.Put(fromIP, to);
			} else
				LogTime(MUSCLE_LOG_ERROR, "Error parsing remap argument (it should look something like remap=192.168.0.1,132.239.50.8).\n");
		}
	}

#ifdef MUSCLE_ENABLE_MEMORY_TRACKING
	if (args.FindString("maxmem", &value) == B_NO_ERROR) {
		int megs = muscleMax(1, atoi(value));
		LogTime(MUSCLE_LOG_INFO, "Limiting memory usage to %i megabyte%s.\n", megs, (megs==1)?"":"s");
		maxBytes = megs*1024L*1024L;
	}
#endif

	if (args.FindString("maxmessagesize", &value) == B_NO_ERROR) {
		int k = muscleMax(1, atoi(value));
		LogTime(MUSCLE_LOG_INFO, "Limiting message sizes to %i kilobyte%s.\n", k, (k==1)?"":"s");
		maxMessageSize = k*1024L;
	}

	if (args.FindString("maxsendrate", &value) == B_NO_ERROR) {
		float k = (float) atof(value);
		maxSendRate = muscleMax((uint32)0, (uint32)(k * 1024.0f));
	}

	if (args.FindString("maxreceiverate", &value) == B_NO_ERROR) {
		float k = (float) atof(value);
		maxReceiveRate = muscleMax((uint32)0, (uint32)(k * 1024.0f));
	}

	if (args.FindString("maxcombinedrate", &value) == B_NO_ERROR) {
		float k = (float) atof(value);
		maxCombinedRate = muscleMax((uint32)0, (uint32)(k * 1024.0f));
	}

	if (args.FindString("maxnodespersession", &value) == B_NO_ERROR) {
		maxNodesPerSession = atoi(value);
		LogTime(MUSCLE_LOG_INFO, "Limiting nodes-per-session to "UINT32_FORMAT_SPEC".\n", maxNodesPerSession);
	}

	if (args.FindString("maxsessions", &value) == B_NO_ERROR) {
		maxSessions = atoi(value);
		LogTime(MUSCLE_LOG_INFO, "Limiting total session count to "UINT32_FORMAT_SPEC".\n", maxSessions);
	}

	if (args.FindString("maxsessionsperhost", &value) == B_NO_ERROR) {
		maxSessionsPerHost = atoi(value);
		LogTime(MUSCLE_LOG_INFO, "Limiting session count for any given host to "UINT32_FORMAT_SPEC".\n", maxSessionsPerHost);
	}
	
	if (args.FindString("privatekey", &value) == B_NO_ERROR) {
		fprivateKeyFilePath = new String(value);	
		//const String * fprivateKeyFilePath = args.GetStringPointer("privatekey");
		//LogTime(MUSCLE_LOG_INFO, "Limiting session count for any given host to "UINT32_FORMAT_SPEC".\n", fprivateKeyFilePath);
	}

	{
		for (int32 i = 0; (args.FindString("ban", i, &value) == B_NO_ERROR); i++) {
			LogTime(MUSCLE_LOG_INFO, "Banning all clients whose IP addresses match [%s].\n", value);	
			bans.AddTail(value);
		}
	}

	{
		for (int32 i = 0; (args.FindString("require", i, &value) == B_NO_ERROR); i++) {
			LogTime(MUSCLE_LOG_INFO, "Allowing only clients whose IP addresses match [%s].\n", value);	
			requires.AddTail(value);
		}
	}
	
	{
		const char * privNames[] = {"privkick", "privban", "privunban", "privall"};
		for (int p = 0; p <= PR_NUM_PRIVILEGES; p++) {  // if (p == PR_NUM_PRIVILEGES), that means all privileges
			for (int32 q=0; (args.FindString(privNames[p], q, &value) == B_NO_ERROR); q++) {
				LogTime(MUSCLE_LOG_INFO, "Clients whose IP addresses match [%s] get %s privileges.\n", value, privNames[p]+4);
				char tt[32]; 
				muscleSprintf(tt, "priv%i", p);
				tempPrivs.AddString(tt, value);
			}
		}
	}
}
示例#9
0
void HandleStandardDaemonArgs(const Message & args)
{
   TCHECKPOINT;

#ifndef WIN32
   if (args.HasName("disablestderr"))
   {
      LogTime(MUSCLE_LOG_INFO, "Suppressing all further output to stderr!\n");
      close(STDERR_FILENO);
   }
   if (args.HasName("disablestdout"))
   {
      LogTime(MUSCLE_LOG_INFO, "Suppressing all further output to stdout!\n");
      close(STDOUT_FILENO);
   }
#endif

   // Do this first, so that the stuff below will affect the right process.
   const char * n;
   if (args.FindString("daemon", &n) == B_NO_ERROR)
   {
      LogTime(MUSCLE_LOG_INFO, "Spawning off a daemon-child...\n");
      if (BecomeDaemonProcess(NULL, n[0] ? n : "/dev/null") != B_NO_ERROR)
      {
         LogTime(MUSCLE_LOG_CRITICALERROR, "Could not spawn daemon-child process!\n");
         ExitWithoutCleanup(10);
      }
   }

#ifdef WIN32
   const String * consoleStr = args.GetStringPointer("console");
   if (consoleStr) Win32AllocateStdioConsole(consoleStr->Cstr());
#endif

#ifdef MUSCLE_ENABLE_DEADLOCK_FINDER
   {
      const char * df = args.GetCstr("deadlockfinder");
      if (df) _enableDeadlockFinderPrints = ParseBool(df, true);
   }
#endif

   const char * value;
   if (args.FindString("displaylevel", &value) == B_NO_ERROR)
   {
      int ll = ParseLogLevelKeyword(value);
      if (ll >= 0) SetConsoleLogLevel(ll);
              else LogTime(MUSCLE_LOG_INFO, "Error, unknown display log level type [%s]\n", value);
   }

   if ((args.FindString("oldlogfilespattern", &value) == B_NO_ERROR)&&(*value != '\0')) SetOldLogFilesPattern(value);

   if ((args.FindString("maxlogfiles", &value) == B_NO_ERROR)||(args.FindString("maxnumlogfiles", &value) == B_NO_ERROR))
   {
      const uint32 maxNumFiles = (uint32) atol(value);
      if (maxNumFiles > 0) SetMaxNumLogFiles(maxNumFiles);
                      else LogTime(MUSCLE_LOG_ERROR, "Please specify a maxnumlogfiles value that is greater than zero.\n");
   }

   if (args.FindString("logfile", &value) == B_NO_ERROR)
   {
      SetFileLogName(value);
      if (GetFileLogLevel() == MUSCLE_LOG_NONE) SetFileLogLevel(MUSCLE_LOG_INFO); // no sense specifying a name and then not logging anything!
   }

   if (args.FindString("filelevel", &value) == B_NO_ERROR)
   {
      const int ll = ParseLogLevelKeyword(value);
      if (ll >= 0) SetFileLogLevel(ll);
              else LogTime(MUSCLE_LOG_INFO, "Error, unknown file log level type [%s]\n", value);
   }

   if (args.FindString("maxlogfilesize", &value) == B_NO_ERROR)
   {
      const uint32 maxSizeKB = (uint32) atol(value);
      if (maxSizeKB > 0) SetFileLogMaximumSize(maxSizeKB*1024);
                    else LogTime(MUSCLE_LOG_ERROR, "Please specify a maxlogfilesize in kilobytes, that is greater than zero.\n");
   }

   if ((args.HasName("compresslogfile"))||(args.HasName("compresslogfiles"))) SetFileLogCompressionEnabled(true);

   if (args.FindString("localhost", &value) == B_NO_ERROR)
   {
      const IPAddress ip = Inet_AtoN(value);
      if (ip != invalidIP)
      {
         char ipbuf[64]; Inet_NtoA(ip, ipbuf);
         LogTime(MUSCLE_LOG_INFO, "IP address [%s] will be used as the localhost address.\n", ipbuf);
         SetLocalHostIPOverride(ip);
      }
      else LogTime(MUSCLE_LOG_ERROR, "Error parsing localhost IP address [%s]!\n", value);
   }

   if (args.FindString("dnscache", &value) == B_NO_ERROR)
   {
      const uint64 micros = ParseHumanReadableTimeIntervalString(value);
      if (micros > 0)
      {
         uint32 maxCacheSize = 1024;
         if (args.FindString("dnscachesize", &value) == B_NO_ERROR) maxCacheSize = (uint32) atol(value);
         LogTime(MUSCLE_LOG_INFO, "Setting DNS cache parameters to " UINT32_FORMAT_SPEC " entries, expiration period is %s\n", maxCacheSize, GetHumanReadableTimeIntervalString(micros)());
         SetHostNameCacheSettings(maxCacheSize, micros);
      }
      else LogTime(MUSCLE_LOG_ERROR, "Unable to parse time interval string [%s] for dnscache argument!\n", value);
   }

   if ((args.HasName("debugcrashes"))||(args.HasName("debugcrash")))
   {
#if defined(__linux__) || defined(__APPLE__)
      LogTime(MUSCLE_LOG_INFO, "Enabling stack-trace printing when a crash occurs.\n");
      signal(SIGSEGV, CrashSignalHandler);
      signal(SIGBUS,  CrashSignalHandler);
      signal(SIGILL,  CrashSignalHandler);
      signal(SIGABRT, CrashSignalHandler);
      signal(SIGFPE,  CrashSignalHandler);
#elif MUSCLE_USE_MSVC_STACKWALKER
# ifndef MUSCLE_INLINE_LOGGING
      LogTime(MUSCLE_LOG_INFO, "Enabling stack-trace printing when a crash occurs.\n");
      SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler);
# endif
#else
      LogTime(MUSCLE_LOG_ERROR, "Can't enable stack-trace printing when a crash occurs, that feature isn't supported on this platform!\n");
#endif
   }

#if defined(__linux__) || defined(__APPLE__)
   {
      const char * niceStr = NULL; (void) args.FindString("nice", &niceStr);
      const char * meanStr = NULL; (void) args.FindString("mean", &meanStr);

      const int32 niceLevel = niceStr ? ((strlen(niceStr) > 0) ? atoi(niceStr) : 5) : 0;
      const int32 meanLevel = meanStr ? ((strlen(meanStr) > 0) ? atoi(meanStr) : 5) : 0;
      const int32 effectiveLevel = niceLevel-meanLevel;

      if (effectiveLevel)
      {
         errno = 0;  // the only reliable way to check for an error here :^P
         const int ret = nice(effectiveLevel);  // I'm only looking at the return value to shut gcc 4.4.3 up
         if (errno != 0) LogTime(MUSCLE_LOG_WARNING, "Could not change process execution priority to " INT32_FORMAT_SPEC " (ret=%i).\n", effectiveLevel, ret);
                    else LogTime(MUSCLE_LOG_INFO, "Process is now %s (niceLevel=%i)\n", (effectiveLevel<0)?"mean":"nice", effectiveLevel);
      }
   }
#endif

#ifdef __linux__
   const char * priStr;
        if (args.FindString("realtime",      &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, false);
   else if (args.FindString("realtime_rr",   &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, false);
   else if (args.FindString("realtime_fifo", &priStr) == B_NO_ERROR) SetRealTimePriority(priStr, true);
#endif

#ifdef MUSCLE_CATCH_SIGNALS_BY_DEFAULT
# ifdef MUSCLE_AVOID_SIGNAL_HANDLING
#  error "MUSCLE_CATCH_SIGNALS_BY_DEFAULT and MUSCLE_AVOID_SIGNAL_HANDLING are mutually exclusive compiler flags... you can not specify both!"
# endif
   if (args.HasName("dontcatchsignals"))
   {
      _mainReflectServerCatchSignals = false;
      LogTime(MUSCLE_LOG_DEBUG, "Controlled shutdowns (via Control-C) disabled in the main thread.\n");
   }
#else
   if (args.HasName("catchsignals"))
   {
# ifdef MUSCLE_AVOID_SIGNAL_HANDLING
      LogTime(MUSCLE_LOG_ERROR, "Can not enable controlled shutdowns, MUSCLE_AVOID_SIGNAL_HANDLING was specified during compilation!\n");
# else
      _mainReflectServerCatchSignals = true;
      LogTime(MUSCLE_LOG_DEBUG, "Controlled shutdowns (via Control-C) enabled in the main thread.\n");
# endif
   }
#endif

   if (args.HasName("printnetworkinterfaces"))
   {
      Queue<NetworkInterfaceInfo> infos;
      if (GetNetworkInterfaceInfos(infos) == B_NO_ERROR)
      {
         printf("--- Network interfaces on this machine are as follows: ---\n");
         for (uint32 i=0; i<infos.GetNumItems(); i++) printf("  %s\n", infos[i].ToString()());
         printf("--- (end of list) ---\n");
      }
   }
}