From: Thomas Debesse <dev@illwieckz.net>
Date: Thu, 18 Feb 2016 11:46:25 +0000 (+0100)
Subject: fix undocumented unexpected LokiInitPaths
X-Git-Tag: xonotic-v0.8.2~8^2
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=25e4f9e8cf6aa80de16ba5f25cfc9b3da7c2c368;p=xonotic%2Fnetradiant.git

fix undocumented unexpected LokiInitPaths
---

diff --git a/tools/quake3/q3map2/path_init.c b/tools/quake3/q3map2/path_init.c
index 16758c6d..be28c203 100644
--- a/tools/quake3/q3map2/path_init.c
+++ b/tools/quake3/q3map2/path_init.c
@@ -122,7 +122,6 @@ void LokiInitPaths( char *argv0 ){
 	strcpy( installPath, "../" );
 	#else
 	char temp[ MAX_OS_PATH ];
-	char last0[ 2 ];
 	char        *path;
 	char        *last;
 	qboolean found;
@@ -136,6 +135,25 @@ void LokiInitPaths( char *argv0 ){
 		argv0 = strrchr( argv0, '/' ) + 1;
 	}
 	else if ( path ) {
+
+		/*
+		   This code has a special behavior when q3map2 is a symbolic link.
+
+		   For each dir in ${PATH} (example: "/usr/bin", "/usr/local/bin" if ${PATH} == "/usr/bin:/usr/local/bin"),
+		   it looks for "${dir}/q3map2" (file exists and is executable),
+		   then it uses "dirname(realpath("${dir}/q3map2"))/../" as installPath.
+
+		   So, if "/usr/bin/q3map2" is a symbolic link to "/opt/radiant/tools/q3map2",
+		   it will find the installPath "/usr/share/radiant/",
+		   so q3map2 will look for "/opt/radiant/baseq3" to find paks.
+
+		   More precisely, it looks for "${dir}/${argv[0]}",
+		   so if "/usr/bin/q3map2" is a symbolic link to "/opt/radiant/tools/q3map2",
+		   and if "/opt/radiant/tools/q3ma2" is a symbolic link to "/opt/radiant/tools/q3map2.x86_64",
+		   it will use "dirname("/opt/radiant/tools/q3map2.x86_64")/../" as path,
+		   so it will use "/opt/radiant/" as installPath, which will be expanded later to "/opt/radiant/baseq3" to find paks.
+		*/
+
 		found = qfalse;
 		last = path;
 
@@ -157,17 +175,20 @@ void LokiInitPaths( char *argv0 ){
 				path++;
 			}
 
+
 			/* concatenate */
 			if ( last > ( path + 1 ) ) {
-				Q_strncat( temp, sizeof( temp ), path, ( last - path ) );
+				// +1 hack: Q_strncat calls Q_strncpyz that expects a len including '\0'
+				// so that extraneous char will be rewritten by '\0', so it's ok.
+				// Also, in this case this extraneous char is always ':' or '\0', so it's ok.
+				Q_strncat( temp, sizeof( temp ), path, ( last - path + 1) );
 				Q_strcat( temp, sizeof( temp ), "/" );
 			}
-			Q_strcat( temp, sizeof( temp ), "./" );
 			Q_strcat( temp, sizeof( temp ), argv0 );
 
 			/* verify the path */
 			if ( access( temp, X_OK ) == 0 ) {
-				found++;
+				found = qtrue;
 			}
 			path = last + 1;
 		}
@@ -175,9 +196,12 @@ void LokiInitPaths( char *argv0 ){
 
 	/* flake */
 	if ( realpath( temp, installPath ) ) {
-		/* q3map is in "tools/" */
+		/*
+		   if "q3map2" is "/opt/radiant/tools/q3map2",
+		   installPath is "/opt/radiant"
+		*/
+		*( strrchr( installPath, '/' ) ) = '\0';
 		*( strrchr( installPath, '/' ) ) = '\0';
-		*( strrchr( installPath, '/' ) + 1 ) = '\0';
 	}
 	#endif
 }