- create LaunchInfo.txt by default
- when suggesting a command, don't add full path (since it will be found in $PATH anyway) - clean up resolve_path. Let it do path and tilde expansion and don't suggest directories in $PATH. - fix some minor memory leaks - export the variables XQF_SERVER_NAME, XQF_SERVER_MAP, XQF_SERVER_HOSTNAME and XQF_SERVER_GAME when launching a game (suggested by Ruediger Meier) git-svn-id: http://svn.code.sf.net/p/xqf/code/trunk@611 d2ac09be-c843-0410-8b1f-f8a84130e0ec
This commit is contained in:
parent
9ac88211c2
commit
f8eb8b2728
@ -1,3 +1,13 @@
|
||||
May 09, 2004: Ludwig Nussel <l-n@users.sourceforge.net>
|
||||
- create LaunchInfo.txt by default
|
||||
- when suggesting a command, don't add full path (since it will be found in
|
||||
$PATH anyway)
|
||||
- clean up resolve_path. Let it do path and tilde expansion and don't suggest
|
||||
directories in $PATH.
|
||||
- fix some minor memory leaks
|
||||
- export the variables XQF_SERVER_NAME, XQF_SERVER_MAP, XQF_SERVER_HOSTNAME and
|
||||
XQF_SERVER_GAME when launching a game (suggested by Ruediger Meier)
|
||||
|
||||
May 08, 2004: Ludwig Nussel <l-n@users.sourceforge.net>
|
||||
- support for Half-Life steam master. Nasty hack, hopefully doesn't break other stuff.
|
||||
- set anti-cheat flag for VAC (secure != 0)
|
||||
|
@ -275,8 +275,20 @@ int client_launch_exec (int forkit, char *dir, char* argv[],
|
||||
else { /* child */
|
||||
close (pipefds[0]);
|
||||
|
||||
if( s->flags & SERVER_PUNKBUSTER )
|
||||
setenv("XQF_SERVER_ANTICHEAT","1",1);
|
||||
if(s->flags & SERVER_PUNKBUSTER)
|
||||
setenv("XQF_SERVER_ANTICHEAT", "1", 1);
|
||||
|
||||
if(s->name)
|
||||
setenv("XQF_SERVER_NAME", s->name, 1);
|
||||
|
||||
if(s->map)
|
||||
setenv("XQF_SERVER_MAP", s->map, 1);
|
||||
|
||||
if(s->host->name)
|
||||
setenv("XQF_SERVER_HOSTNAME", s->host->name, 1);
|
||||
|
||||
if(s->game)
|
||||
setenv("XQF_SERVER_GAME", s->game, 1);
|
||||
|
||||
execvp (argv[0], argv);
|
||||
|
||||
|
@ -1940,9 +1940,8 @@ static GtkWidget *create_noskins_menu (int qworq2) {
|
||||
|
||||
// fill working directory with result of the directory guess function for first
|
||||
// token of command line if working directory is empty
|
||||
static void pref_guess_dir(enum server_type type)
|
||||
static void pref_guess_dir(enum server_type type, const char* cmdline, gboolean interactive)
|
||||
{
|
||||
const char *cmdline = NULL;
|
||||
const char* dir_entry = NULL;
|
||||
|
||||
dir_entry = gtk_entry_get_text (GTK_ENTRY (genprefs[type].dir_entry));
|
||||
@ -1950,7 +1949,6 @@ static void pref_guess_dir(enum server_type type)
|
||||
if(dir_entry && *dir_entry)
|
||||
return;
|
||||
|
||||
cmdline = gtk_entry_get_text (GTK_ENTRY (genprefs[type].cmd_entry));
|
||||
if (cmdline && *cmdline) // if not empty
|
||||
{
|
||||
char *guessed_dir = NULL;
|
||||
@ -1972,7 +1970,8 @@ static void pref_guess_dir(enum server_type type)
|
||||
g_strfreev(cmds);
|
||||
}
|
||||
|
||||
dialog_ok (NULL, _("You must configure a command line first"));
|
||||
if(interactive)
|
||||
dialog_ok (NULL, _("You must configure a command line first"));
|
||||
}
|
||||
|
||||
|
||||
@ -1998,7 +1997,7 @@ static void pref_suggest_command(enum server_type type)
|
||||
return;
|
||||
}
|
||||
|
||||
suggested_file = find_file_in_path(files);
|
||||
suggested_file = find_file_in_path_relative(files);
|
||||
if(!suggested_file)
|
||||
{
|
||||
dialog_ok(_("Game not found"),
|
||||
@ -2010,9 +2009,10 @@ static void pref_suggest_command(enum server_type type)
|
||||
|
||||
// gtk entry does the freeing? -- no
|
||||
gtk_entry_set_text (GTK_ENTRY (genprefs[type].cmd_entry), suggested_file);
|
||||
g_free(suggested_file);
|
||||
|
||||
pref_guess_dir (type);
|
||||
pref_guess_dir (type, suggested_file, TRUE);
|
||||
|
||||
g_free(suggested_file);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2335,10 +2335,9 @@ static GtkWidget *generic_game_frame (enum server_type type) {
|
||||
gtk_widget_show (button);
|
||||
|
||||
// translator: button for directory guess
|
||||
button = gtk_button_new_with_label (_("Guess"));
|
||||
button = gtk_button_new_with_label (_("Suggest"));
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
GTK_SIGNAL_FUNC (game_file_activate_callback), (gpointer)type);
|
||||
// GTK_SIGNAL_FUNC (pref_guess_dir), (gpointer)type);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),button , FALSE, FALSE, 0);
|
||||
gtk_tooltips_set_tip (tooltips, button, _("Tries to guess the working directory based on the command line"), NULL);
|
||||
@ -4539,6 +4538,8 @@ static void generic_prefs_free(struct generic_prefs* prefs)
|
||||
|
||||
for (i = 0; i < GAMES_TOTAL; i++)
|
||||
{
|
||||
g_free(prefs[i].pref_dir);
|
||||
g_free(prefs[i].real_dir);
|
||||
g_datalist_clear(&prefs[i].games_data);
|
||||
}
|
||||
g_free(prefs);
|
||||
@ -4725,7 +4726,7 @@ static void user_fix_defaults (void)
|
||||
{
|
||||
files = games[i].suggest_commands;
|
||||
if(!files) continue;
|
||||
suggested_file = find_file_in_path(files);
|
||||
suggested_file = find_file_in_path_relative(files);
|
||||
if(!suggested_file) continue;
|
||||
|
||||
j++;
|
||||
@ -5007,7 +5008,7 @@ int prefs_load (void) {
|
||||
|
||||
default_terminate = config_get_bool ("terminate=false");
|
||||
default_iconify = config_get_bool ("iconify=false");
|
||||
default_launchinfo = config_get_bool ("launchinfo=false");
|
||||
default_launchinfo = config_get_bool ("launchinfo=true");
|
||||
default_stopxmms = config_get_bool ("stopxmms=false");
|
||||
default_prelaunchexec = config_get_bool ("prelaunchexec=false");
|
||||
default_save_lists = config_get_bool ("save lists=true");
|
||||
@ -5089,18 +5090,19 @@ void prefs_save (void) {
|
||||
void game_file_dialog_ok_callback (GtkWidget *widget, GtkFileSelection *fs)
|
||||
{
|
||||
enum server_type type;
|
||||
char *temp = NULL;
|
||||
char *filename = NULL;
|
||||
|
||||
type = (int) gtk_object_get_user_data (GTK_OBJECT (widget));
|
||||
type = (enum server_type) gtk_object_get_user_data (GTK_OBJECT (widget));
|
||||
|
||||
if(type >= UNKNOWN_SERVER)
|
||||
return;
|
||||
|
||||
temp = g_strdup(gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
|
||||
filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
|
||||
|
||||
if (temp) {
|
||||
gtk_entry_set_text (GTK_ENTRY (genprefs[type].cmd_entry), temp);
|
||||
pref_guess_dir (type);
|
||||
if (filename) {
|
||||
gtk_entry_set_text (GTK_ENTRY (genprefs[type].cmd_entry), filename);
|
||||
pref_guess_dir (type, filename, TRUE);
|
||||
}
|
||||
if (temp)
|
||||
g_free (temp);
|
||||
}
|
||||
|
||||
void game_file_activate_callback (enum server_type type)
|
||||
@ -5108,19 +5110,11 @@ void game_file_activate_callback (enum server_type type)
|
||||
char *temp = NULL;
|
||||
char *file = NULL;
|
||||
|
||||
temp = g_strdup(gtk_entry_get_text (GTK_ENTRY (genprefs[type].cmd_entry)));
|
||||
temp = gtk_entry_get_text (GTK_ENTRY (genprefs[type].cmd_entry));
|
||||
|
||||
if (temp) {
|
||||
file = find_file_in_path(temp);
|
||||
if (file)
|
||||
gtk_entry_set_text (GTK_ENTRY (genprefs[type].cmd_entry), file);
|
||||
}
|
||||
pref_guess_dir (type, temp, TRUE);
|
||||
|
||||
pref_guess_dir (type);
|
||||
if (temp)
|
||||
g_free (temp);
|
||||
if (file)
|
||||
g_free (file);
|
||||
g_free (file);
|
||||
}
|
||||
|
||||
void game_dir_dialog_ok_callback (GtkWidget *widget, GtkFileSelection *fs)
|
||||
|
@ -19,21 +19,132 @@
|
||||
|
||||
#include "gnuconfig.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "utils.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define PRINT(fmt,rest...) \
|
||||
printf("%s: " fmt "\n", __FUNCTION__, ##rest)
|
||||
|
||||
#define ERROR(fmt,rest...) \
|
||||
PRINT(fmt ": %s", ##rest, strerror(errno))
|
||||
|
||||
typedef enum { tFile, tSymlink, tDirecory } FileType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FileType type;
|
||||
char name[PATH_MAX];
|
||||
} File;
|
||||
|
||||
enum { MaxFiles = 255 };
|
||||
static File* tempfiles[MaxFiles] = {0};
|
||||
static int currentFile = 0;
|
||||
|
||||
#define BASEDIR "/tmp/xqf_test_util/"
|
||||
|
||||
static void popFile(int nr)
|
||||
{
|
||||
for( ; nr > 0 && currentFile > 0 ; --nr)
|
||||
{
|
||||
File* entry = tempfiles[--currentFile];
|
||||
|
||||
if(!entry)
|
||||
continue;
|
||||
|
||||
switch(entry->type)
|
||||
{
|
||||
case tFile:
|
||||
case tSymlink:
|
||||
if(unlink(entry->name) == -1)
|
||||
{
|
||||
ERROR("unlink %s", entry->name);
|
||||
}
|
||||
break;
|
||||
case tDirecory:
|
||||
if(rmdir(entry->name) == -1)
|
||||
{
|
||||
ERROR("rmdir %s", entry->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
g_free(entry);
|
||||
}
|
||||
|
||||
if(currentFile < 0)
|
||||
currentFile = 0;
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
popFile(currentFile);
|
||||
}
|
||||
|
||||
static const char* newFile(FileType type, const char* name)
|
||||
{
|
||||
File* f = NULL;
|
||||
|
||||
if(currentFile >= MaxFiles)
|
||||
exit(1);
|
||||
|
||||
f = tempfiles[currentFile] = g_malloc0(sizeof(File));
|
||||
f->type = type;
|
||||
strcpy(f->name, BASEDIR);
|
||||
strcat(f->name, name);
|
||||
|
||||
++currentFile;
|
||||
|
||||
return f->name;
|
||||
}
|
||||
|
||||
|
||||
static void doMkdir(const char* dir)
|
||||
{
|
||||
dir = newFile(tDirecory, dir);
|
||||
if(mkdir(dir, 0755) == -1)
|
||||
{
|
||||
ERROR("mkdir %s", dir);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void doSymlink(const char* oldpath, const char* newpath)
|
||||
{
|
||||
newpath = newFile(tSymlink, newpath);
|
||||
if(symlink(oldpath, newpath) == -1)
|
||||
{
|
||||
ERROR("symlink %s -> %s", newpath, oldpath);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void doFile(const char* name)
|
||||
{
|
||||
int fd = -1;
|
||||
name = newFile(tFile, name);
|
||||
if((fd = open(name, O_CREAT|O_EXCL|O_RDWR, 0755)) == -1)
|
||||
{
|
||||
ERROR("open %s", name);
|
||||
exit(1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void test_find_game_dir()
|
||||
{
|
||||
const char* basedir = "/usr/local/games/quake3";
|
||||
const char* targets[] =
|
||||
{
|
||||
"westernq3",
|
||||
"WESTERNQ3",
|
||||
"triBALctf",
|
||||
"Q3UT2",
|
||||
"Q3UT3",
|
||||
"ABC",
|
||||
NULL
|
||||
};
|
||||
@ -42,12 +153,21 @@ void test_find_game_dir()
|
||||
int type = 0;
|
||||
int i = 0;
|
||||
|
||||
doMkdir("westernq3");
|
||||
doMkdir("WESTERNQ3");
|
||||
doMkdir("tribalctf");
|
||||
doMkdir("q3ut3");
|
||||
doSymlink("q3ut2", "Q3UT2");
|
||||
doSymlink("q3ut3", "Q3UT3");
|
||||
|
||||
for(; targets[i]; ++i)
|
||||
{
|
||||
result = find_game_dir(basedir, targets[i], &type);
|
||||
result = find_game_dir(BASEDIR, targets[i], &type);
|
||||
PRINT("search %s, result %s, type %d", targets[i], result, type);
|
||||
g_free(result);
|
||||
}
|
||||
|
||||
popFile(6);
|
||||
}
|
||||
|
||||
void test_file_in_dir()
|
||||
@ -75,14 +195,63 @@ void test_file_in_dir()
|
||||
}
|
||||
}
|
||||
|
||||
void test_resolve_path()
|
||||
{
|
||||
char buf[PATH_MAX] = {0};
|
||||
char* oldpath = NULL;
|
||||
const char* files[] =
|
||||
{
|
||||
"binarypath", // binary in $PATH
|
||||
"relative", // relative symlink
|
||||
"absolute", // absolute symlink
|
||||
"noexist", // not existing
|
||||
BASEDIR "bin/binarypath",
|
||||
BASEDIR "bin/relative",
|
||||
BASEDIR "bin/absolute",
|
||||
BASEDIR "bin/noexist",
|
||||
BASEDIR "game/binary",
|
||||
"~/bin/bla",
|
||||
"~/bin/q3",
|
||||
NULL
|
||||
};
|
||||
int i = 0;
|
||||
|
||||
doMkdir("game");
|
||||
doMkdir("bin");
|
||||
doFile("game/binary");
|
||||
doFile("bin/binarypath");
|
||||
doSymlink("../game/binary", "bin/relative");
|
||||
doSymlink(BASEDIR "game/binary", "bin/absolute");
|
||||
|
||||
oldpath = getenv("PATH");
|
||||
if(!oldpath)
|
||||
exit(1);
|
||||
snprintf(buf, sizeof(buf), "%s%s:%s", BASEDIR, "bin", oldpath);
|
||||
setenv("PATH", buf, 1);
|
||||
|
||||
for(; files[i]; ++i)
|
||||
{
|
||||
char* path = resolve_path(files[i]);
|
||||
PRINT("'%s' -> '%s'", files[i], path);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
setenv("PATH", oldpath, 1);
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
atexit(cleanup);
|
||||
|
||||
doMkdir("");
|
||||
|
||||
set_debug_level(0);
|
||||
|
||||
test_find_game_dir();
|
||||
test_file_in_dir();
|
||||
test_resolve_path();
|
||||
|
||||
return 0;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// vim: sw=4
|
||||
|
219
xqf/src/utils.c
219
xqf/src/utils.c
@ -36,6 +36,7 @@
|
||||
#include "debug.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static char* find_file_in_path2(const char* files, gboolean relative);
|
||||
|
||||
short strtosh (const char *str) {
|
||||
long tmp;
|
||||
@ -520,6 +521,16 @@ const char* bool2str(int i)
|
||||
* must be freed manually
|
||||
*/
|
||||
char* find_file_in_path(const char* files)
|
||||
{
|
||||
return find_file_in_path2(files, FALSE);
|
||||
}
|
||||
|
||||
char* find_file_in_path_relative(const char* files)
|
||||
{
|
||||
return find_file_in_path2(files, TRUE);
|
||||
}
|
||||
|
||||
static char* find_file_in_path2(const char* files, gboolean relative)
|
||||
{
|
||||
char** binaries = NULL;
|
||||
char* path = NULL;
|
||||
@ -548,7 +559,7 @@ char* find_file_in_path(const char* files)
|
||||
{
|
||||
// If directory name is blank, don't add a / - happens if
|
||||
// a complete path was passed
|
||||
if (strlen(directories[j]))
|
||||
if (!relative && strlen(directories[j]))
|
||||
found = g_strconcat(directories[j],"/",binaries[i],NULL);
|
||||
else
|
||||
found = g_strdup(binaries[i]);
|
||||
@ -558,6 +569,7 @@ char* find_file_in_path(const char* files)
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev(directories);
|
||||
g_strfreev(binaries);
|
||||
|
||||
return found;
|
||||
@ -692,83 +704,152 @@ GSList* slist_sort_remove_dups(GSList* list, GCompareFunc compare_func, void (*u
|
||||
return list;
|
||||
}
|
||||
|
||||
/** \brief determine directory for game binary
|
||||
*
|
||||
* Extracts the path from path using the following rules:
|
||||
* - If path is a symlink:
|
||||
* - If pointed to file contains '..', just stop, otherwise strip filename and
|
||||
* store as directory
|
||||
* - If there is no /'s in the pointed to file, use the original path instead and
|
||||
* strip filename and store as directory
|
||||
*
|
||||
* - If path is not a symlink:
|
||||
* - strip filename and store as directory
|
||||
*
|
||||
* Path can be either a file or a directory
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* path: /usr/bin/quake2 symlink to /games/quake2/quake2
|
||||
* result: /games/quake2/
|
||||
*
|
||||
* path: /usr/bin/quake symlink to ../../games/quake2/quake2
|
||||
* result: (stops - leaves as-is)
|
||||
*
|
||||
* path: /games/quake2/quake2
|
||||
* result: /games/quake2/
|
||||
*
|
||||
* path: quake2
|
||||
* result: search $PATH for binary then use above rules
|
||||
*
|
||||
* path: ~/bin/quake2
|
||||
* result: expand tilde then use above rules
|
||||
*
|
||||
* @returns game direcory or NULL. must be freed
|
||||
*/
|
||||
|
||||
char* resolve_path(const char* path)
|
||||
{
|
||||
// Extracts the path from path using the following rules:
|
||||
// - If path is a symlink:
|
||||
// - If pointed to file contains '..', just stop, otherwise strip filename and
|
||||
// store as directory
|
||||
// - If there is no /'s in the pointed to file, use the original cmd_entry instead and
|
||||
// strip filename and store as directory
|
||||
//
|
||||
// - If path is not a symlink:
|
||||
// - strip filename and store as directory
|
||||
//
|
||||
// Path can be either a file or a directory
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// cmd_entry: /usr/bin/quake2 symlink to /games/quake2/quake2
|
||||
// result dir: /games/quake2/
|
||||
//
|
||||
// cmd_entry: /usr/bin/quake symlink to ../../games/quake2/quake2
|
||||
// result dir: (stops - leaves as-is)
|
||||
//
|
||||
// cmd_entry: /games/quake2/quake2
|
||||
// result dir: /games/quake2/
|
||||
//
|
||||
// cmd_entry: quake2
|
||||
// result dir: (stops - leaves as-is)
|
||||
//
|
||||
|
||||
struct stat buf;
|
||||
struct stat statbuf;
|
||||
int length = 0;
|
||||
char buf2[256];
|
||||
char buf[256];
|
||||
char *ptr = NULL;
|
||||
char *dir = NULL;
|
||||
char* tmp = NULL;
|
||||
|
||||
if (strcmp (path, "")) {
|
||||
lstat(path, &buf);
|
||||
if ( S_ISLNK(buf.st_mode) == 1) {
|
||||
// Grab directory from sym link of cmd_entry
|
||||
|
||||
debug(2, "path is a sym link");
|
||||
if(!path || !*path)
|
||||
return NULL;
|
||||
|
||||
length = readlink (path, buf2, 255);
|
||||
|
||||
if (length){
|
||||
buf2[length]='\0';
|
||||
|
||||
if(buf2[length-1] == '/')
|
||||
buf2[length-1] = '\0';
|
||||
|
||||
ptr = strrchr(buf2, '/');
|
||||
|
||||
if (ptr) { // contains a / so pull from symlink
|
||||
if (!strstr(buf2,"..")) { // don't bother if it's got any ..'s in it
|
||||
dir = g_strndup(buf2, ptr-buf2+1);
|
||||
}
|
||||
}
|
||||
else { // no / so pull from cmd_entry instead
|
||||
ptr = strrchr(path, '/');
|
||||
if (ptr) { // contains a /
|
||||
dir = g_strndup(path, ptr-path+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Grab directory from cmd_entry
|
||||
|
||||
debug(2,"path is NOT a sym link");
|
||||
|
||||
ptr = strrchr(path, '/');
|
||||
|
||||
if (ptr) { // contains a /
|
||||
dir = g_strndup(path, ptr-path+1);
|
||||
}
|
||||
}
|
||||
if(path[0] == '~')
|
||||
{
|
||||
tmp = expand_tilde(path);
|
||||
path = tmp;
|
||||
}
|
||||
else if(path[0] != '/')
|
||||
{
|
||||
tmp = find_file_in_path(path);
|
||||
if(!tmp)
|
||||
{
|
||||
debug(3, "%s not found in $PATH", path);
|
||||
return NULL;
|
||||
}
|
||||
path = tmp;
|
||||
}
|
||||
|
||||
if(lstat(path, &statbuf) == -1)
|
||||
{
|
||||
debug(3, "lstat on %s failed", path);
|
||||
g_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( S_ISLNK(statbuf.st_mode) == 1)
|
||||
{
|
||||
// Grab directory from sym link of cmd_entry
|
||||
|
||||
debug(3, "path is a sym link");
|
||||
|
||||
length = readlink (path, buf, sizeof(buf) - 1);
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
buf[length]='\0';
|
||||
|
||||
if(buf[length-1] == '/')
|
||||
buf[length-1] = '\0';
|
||||
|
||||
ptr = strrchr(buf, '/');
|
||||
|
||||
if (ptr) { // contains a / so pull from symlink
|
||||
if (!strstr(buf,"..")) { // don't bother if it's got any ..'s in it
|
||||
dir = g_strndup(buf, ptr-buf+1);
|
||||
}
|
||||
}
|
||||
else { // no / so pull from path instead
|
||||
ptr = strrchr(path, '/');
|
||||
if (ptr) { // contains a /
|
||||
dir = g_strndup(path, ptr-path+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grab directory from cmd_entry
|
||||
|
||||
debug(3,"path is NOT a sym link");
|
||||
|
||||
ptr = strrchr(path, '/');
|
||||
|
||||
if (ptr) // contains a /
|
||||
{
|
||||
gboolean dir_is_path = FALSE;
|
||||
char* PATH = getenv("PATH");
|
||||
|
||||
// ignore direcory if it is in $PATH. It doesn't make sense to suggest
|
||||
// /usr/bin as game direcory
|
||||
if(PATH)
|
||||
{
|
||||
int i;
|
||||
char** directories = g_strsplit(PATH,":",0);
|
||||
char* basedir = g_strndup(path, ptr-path);
|
||||
|
||||
for(i=0; directories[i]; ++i)
|
||||
{
|
||||
if(!strcmp(directories[i], basedir))
|
||||
{
|
||||
dir_is_path = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev(directories);
|
||||
g_free(basedir);
|
||||
}
|
||||
|
||||
if(!dir_is_path)
|
||||
{
|
||||
dir = tmp;
|
||||
tmp = NULL;
|
||||
}
|
||||
else
|
||||
debug(3, "found directory %s in $PATH, ignoring", tmp);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(tmp);
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
@ -77,12 +77,20 @@ const char* bool2str(int i);
|
||||
int str2bool(const char* str);
|
||||
|
||||
|
||||
/** find executable file in $PATH. file is a colon seperated list of
|
||||
* executables to search for. return name of first found file, must be freed
|
||||
* manually
|
||||
/** \brief find executable file in $PATH.
|
||||
*
|
||||
* @param files colon seperated list of executables to search for
|
||||
* @returns absolute path to first found file, must be freed manually
|
||||
*/
|
||||
char* find_file_in_path(const char* files);
|
||||
|
||||
/** \brief find executable file in $PATH.
|
||||
*
|
||||
* @param files colon seperated list of executables to search for
|
||||
* @returns first found file, must be freed manually
|
||||
*/
|
||||
char* find_file_in_path_relative(const char* files);
|
||||
|
||||
/** sort list and remove duplicates
|
||||
* @param list list to sort
|
||||
* @compare_func function to use for comparing
|
||||
|
Loading…
x
Reference in New Issue
Block a user