VFilePath VProcess::GetExecutableFilePath() const
{
	VFilePath filePath;

#if VERSIONMAC

	CFURLRef exeURL = ::CFBundleCopyExecutableURL( ::CFBundleGetMainBundle());
	
	if (testAssert( exeURL != NULL ))
	{
		CFStringRef cfPath = ::CFURLCopyFileSystemPath( exeURL, kCFURLHFSPathStyle);
		if (testAssert( cfPath != NULL ))
		{
			VString thepath;
			thepath.MAC_FromCFString( cfPath);
			thepath.Compose();
			filePath.FromFullPath( thepath, FPS_SYSTEM);
			::CFRelease( cfPath);
		}
		
		::CFRelease(exeURL );
	}

#elif VERSIONWIN

	// Get a path to the exe.
	UniChar path[4096];
	DWORD pathLength=0;

	path[sizeof(path)/sizeof(UniChar)-2]=0;
	pathLength = ::GetModuleFileNameW(NULL, path, sizeof(path));
	
	if (testAssert(pathLength != 0 && !path[sizeof(path)/sizeof(UniChar)-2]))
	{
		VString thepath( path);
		filePath.FromFullPath( thepath, FPS_SYSTEM);
	}

#elif VERSION_LINUX

	PathBuffer path;

	VError verr=path.InitWithExe();
	xbox_assert(verr==VE_OK);

	path.ToPath(&filePath);
	xbox_assert(verr==VE_OK);
		
#endif
	
	return filePath;
}
bool XMacSystem::SearchExecutablePath( const VString& inExecutableName, VFilePath& outPath)
{
	// first lookup in environment variables
	bool found = XBSDSystem::SearchExecutablePath( inExecutableName, outPath);
	
	// then ask launch services
	if (!found)
	{
		VString name( inExecutableName);
		
		if (!name.EndsWith( CVSTR( ".app")))
			name += CVSTR( ".app");
		
		CFURLRef cfAppUrl = NULL;
		CFStringRef cfName = name.MAC_RetainCFStringCopy();
		OSStatus status = LSFindApplicationForInfo( kLSUnknownCreator, NULL /* inBundleID */, cfName, NULL /* outFSRef */, &cfAppUrl);
		if (cfName != NULL)
			CFRelease( cfName);
			
		if (status == noErr)
		{
			if (testAssert( cfAppUrl != NULL))
			{
				CFStringRef cfPosixPath = ::CFURLCopyFileSystemPath( cfAppUrl, kCFURLPOSIXPathStyle);
				if (testAssert( cfPosixPath != NULL))
				{
					VString posixPath;
					posixPath.MAC_FromCFString( cfPosixPath);
					
					posixPath.Compose();
					
					// add an ending / because it's a bundle folder
					posixPath += "/";
					outPath.FromFullPath( posixPath, FPS_POSIX);
					
					found = true;
					::CFRelease( cfPosixPath);
				}
			}
		}

		if (cfAppUrl != NULL)
			CFRelease( cfAppUrl);
	}
	
	return found;
}
int main (int inArgc, char * const inArgv[])
{
	// set pattern matching wild char asap
	VCollator::SetDefaultWildChar( '*');	
	
	// First, create the application. So, everything is initialized and ready to use
	VRIAServerApplication application;
	VProcess::InitOptions initOptions = VProcess::Init_Default & ~VProcess::Init_WithQuickTime;

#if VERSION_LINUX
	XBOX::VString versionString;
	versionString.FromCString (STRPRODUCTVER); // 	YT 18-May-2012 - WAK0076647
    VRIAServerApplication::Get()->SetProductVersion (versionString);
#endif
	
    //jmo - We may want to quit after parsing the command line
    bool shouldQuit=false;

	if (application.Init( initOptions))
	{
		// Parse the command line argument
		VError err = VE_OK;

		// remote admin: feature development in progress
		//VRIAServerSupervisor*	srvSup = VRIAServerSupervisor::Get();

		VRIAServerStartupParameters *startupParameters = new VRIAServerStartupParameters();
		if (startupParameters != NULL)
		{
			// skip first argument (executable path)
			if (inArgc > 1)
			{
				int curArg = 1;

				while (curArg < inArgc && err == VE_OK)
				{
					VString argument( inArgv[curArg]);

					if (argument.BeginsWith( kARG_ADMINISTRATOR_PORT))
					{
						++curArg;
						argument.Remove( 1, kARG_ADMINISTRATOR_PORT.GetLength());
						if (!argument.IsEmpty() && argument.GetUniChar(1) == '=')
						{
							argument.Remove( 1, 1);
							if (!argument.IsEmpty())
							{
								sLONG port = argument.GetLong();
								if (port > 0)
									startupParameters->SetAdministratorHttpPort( port);
								else
									err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
							}
							else
							{
								err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
							}
						}
						else
						{
							err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
						}
					}
					else if (argument.BeginsWith( kARG_ADMINISTRATOR_SSL_PORT))
					{
						++curArg;
						argument.Remove( 1, kARG_ADMINISTRATOR_SSL_PORT.GetLength());
						if (!argument.IsEmpty() && argument.GetUniChar(1) == '=')
						{
							argument.Remove( 1, 1);
							if (!argument.IsEmpty())
							{
								sLONG port = argument.GetLong();
								if (port > 0)
									startupParameters->SetAdministratorSSLPort( port);
								else
									err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
							}
							else
							{
								err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
							}
						}
						else
						{
							err = VE_RIA_INVALID_COMMAND_LINE_ARGUMENTS;
						}
					}
                    else if (argument.BeginsWith( kVERSION_NUMBER))
					{
						++curArg;
						argument.Remove(1, kVERSION_NUMBER.GetLength());

						VString version;
						
						VRIAServerApplication::Get()->GetProductVersion(version);
						
						char buf[100];
						
						version.ToCString(buf, sizeof(buf));
						
                        printf("Wakanda Server %s\n", buf);

                        shouldQuit=true;
					}
					else if (argument.BeginsWith( kLOG_DUMP))
					{
						++curArg;
						argument.Remove(1, kLOG_DUMP.GetLength());
						
						startupParameters->SetNetDump(true);
					}
					else if (argument.EqualToString( kARG_DEBUG_OFF))
					{
						++curArg;
						startupParameters->SetDebuggingAuthorized( false);
					}
					else if (argument.EqualToString( kARG_SYSLOG))
					{
						++curArg;

					#if VERSIONMAC || VERSION_LINUX
						VSysLogOutput *syslogOutput = new VSysLogOutput( L"Wakanda Server");
						application.GetLogger()->AddLogListener( syslogOutput);
						syslogOutput->Release();
					#endif
					}
					else
					{
						++curArg;

						// check whether it's a solution file path
						VFilePath fullPath;
					#if VERSIONWIN
						fullPath.FromFullPath( argument, FPS_SYSTEM);
					#else // VERSIONMAC
						VURL::Decode( argument);
						fullPath.FromFullPath( argument, FPS_POSIX);
					#endif

						if (fullPath.IsValid())
						{
							VFile *file = new VFile( fullPath);
							if (file != NULL)
							{
								if (file->Exists())
								{
									if (file->ConformsTo( RIAFileKind::kSolutionFileKind) && (startupParameters->GetSolutionToLaunch() == NULL))
									{
										startupParameters->SetSolutionToLaunch( file);
									}
									else if (file->ConformsTo( L"com.netscape.javascript-source") && (startupParameters->GetJavaScriptFileToExecute() == NULL))
									{
										startupParameters->SetJavaScriptFileToExecute( file);
									}
								}
							}
							else
							{
								err = VE_MEMORY_FULL;
							}
							ReleaseRefCountable( &file);
						}
						
						// Skip unknown argument without generate an error
					}
				}
			}

			if (err == VE_OK && shouldQuit == false)
			{
				VRIAServerStartupMessage *msg = new VRIAServerStartupMessage( &application, startupParameters);
				if (msg != NULL)
				{
					msg->PostTo( VTaskMgr::Get()->GetMainTask());
					msg->Release();
				}
				ReleaseRefCountable( &startupParameters);
				
				application.Run();
			}
			else
			{
				ReleaseRefCountable( &startupParameters);
			}
		}
	}
	return 0;
}