Пример #1
0
char *Bgetappdir(void)
{
    char *dir = NULL;

#ifdef _WIN32
	TCHAR appdir[MAX_PATH];

	if (GetModuleFileName(NULL, appdir, MAX_PATH) > 0) {
		// trim off the filename
		char *slash = Bstrrchr(appdir, '\\');
		if (slash) slash[0] = 0;
		dir = Bstrdup(appdir);
    }

#elif defined EDUKE32_OSX
    dir = osx_getappdir();
#elif defined __FreeBSD__
    // the sysctl should also work when /proc/ is not mounted (which seems to
    // be common on FreeBSD), so use it..
    char buf[PATH_MAX] = {0};
    int name[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
    size_t len = sizeof(buf)-1;
    int ret = sysctl(name, sizeof(name)/sizeof(name[0]), buf, &len, NULL, 0);
    if(ret == 0 && buf[0] != '\0') {
        // again, remove executable name with dirname()
        // on FreeBSD dirname() seems to use some internal buffer
        dir = strdup(dirname(buf));
    }
#elif defined __linux || defined EDUKE32_BSD
    char buf[PATH_MAX] = {0};
    char buf2[PATH_MAX] = {0};
#  ifdef __linux
    Bsnprintf(buf, sizeof(buf), "/proc/%d/exe", getpid());
#  else // the BSDs.. except for FreeBSD which has a sysctl
    Bsnprintf(buf, sizeof(buf), "/proc/%d/file", getpid());
#  endif
    int len = readlink(buf, buf2, sizeof(buf2));
    if (len != -1) {
        // remove executable name with dirname(3)
        // on Linux, dirname() will modify buf2 (cutting off executable name) and return it
        // on FreeBSD it seems to use some internal buffer instead.. anyway, just strdup()
        dir = Bstrdup(dirname(buf2));
    }
#endif

    return dir;
}
Пример #2
0
int32_t Bcanonicalisefilename(char *filename, int32_t removefn)
{
    char cwd[BMAX_PATH];
    char *fnp = filename;

#ifdef _WIN32
    int drv = 0;

    if (filename[0] && filename[1] == ':')
    {
        // filename is prefixed with a drive
        drv = toupper(filename[0]) - 'A' + 1;
        fnp += 2;
    }

    if (!_getdcwd(drv, cwd, sizeof(cwd)))
        return -1;

    for (char *p = cwd; *p; p++)
        if (*p == '\\')
            *p = '/';
#else
    if (!getcwd(cwd, sizeof(cwd)))
        return -1;
#endif

    char *p = Bstrrchr(cwd, '/');
    if (!p || p[1])
        Bstrcat(cwd, "/");

    char fn[BMAX_PATH];
    Bstrcpy(fn, fnp);

#ifdef _WIN32
    for (p = fn; *p; p++)
        if (*p == '\\')
            *p = '/';
#endif

    if (fn[0] != '/')
    {
        // we are dealing with a path relative to the current directory
        Bstrcpy(filename, cwd);
        Bstrcat(filename, fn);
    }
    else
    {
#ifdef _WIN32
        filename[0] = cwd[0];
        filename[1] = ':';
        filename[2] = 0;
        Bstrcat(filename, fn);
#else
        Bstrcpy(filename, fn);
#endif
    }
    fnp = filename;
#ifdef _WIN32
    fnp += 2;  // skip the drive
#endif
    UNREFERENCED_PARAMETER(removefn);  // change the call below to use removefn instead of 1?
    return Bcorrectfilename(fnp, 1);
}
Пример #3
0
int Bcorrectfilename(char *filename, int removefn)
{
#ifdef _WIN32
	int r, trailslash=0;
#endif
	char path[256]="", fn[64]="", scratch[256], *ptr, *ptr2, ch;
	char cwd[256], *cwdp = cwd;
	char *tokarr[64];
	int ntok=0, i, j;

	int grpmode = 0;
	
	if (!Bstrncasecmp(filename,"GRP:",4)) {
		grpmode = 1;
		for (ptr=filename; *ptr; ptr++) if (*ptr == '\\') *ptr = '/';
	}
#ifdef _WIN32
	if (!grpmode) {
		// Windows uses backslashes so translate all unix-like forwardslashes
		for (ptr=filename; *ptr; ptr++) if (*ptr == '/') *ptr = '\\';
		if (*(ptr-1) == '\\') trailslash = 1;

		r = GetFullPathName(filename, 256, path, &ptr);
		if (r > 256) return -1;
		if (r == 0) return -1;
		if (!trailslash && removefn && ptr) *ptr=0;
		if (trailslash) {
			if (path[ strlen(path) - 1 ] != '\\')
				strcat(path, "\\");
		}

		for (ptr=path; *ptr; ptr++) if (*ptr == '\\') *ptr = '/';
	
		strcpy(filename,path);
	} else {
#endif
	
#ifndef _WIN32
		if (!grpmode) {
			Bgetcwd(cwd, 256);
			Bstrcat(cwd, "/");
		} else {
#endif
		cwd[0] = '/';
		cwd[1] = 0;
#ifndef _WIN32
		}
#endif

		ptr2 = filename;
		if (grpmode) {
			ptr2 += 3;
			if (ptr2[1] != '/')
				*ptr2 = '/';
			else ptr2++;
		}

		if (removefn) {
			ptr = Bstrrchr(ptr2, '/');
			if (ptr) ptr[1] = 0;
			else if (!grpmode) ptr2[0] = 0;
		}

		// now we have all the bits and pieces, clean it all up
		scratch[0] = 0;

		if (ptr2[0] != '/') {
			// relative path, which means prepend the current dir to the path
			Bstrcat(scratch, cwdp);
		}

		Bstrcat(scratch, ptr2);

		ptr2 = scratch;
		while ((ptr = Bstrtoken(ptr2==scratch?scratch:NULL,"/",&ptr2,1)) != NULL) {
			if (!Bstrcmp(ptr,".")) continue;
			else if (!Bstrcmp(ptr,"..")) {
				if (ntok>0) ntok--;
			} else {
				tokarr[ntok++] = ptr;
			}
		}

		ptr2 = filename;
		if (grpmode) {
			Bstrcpy(filename,"GRP:");
			ptr2 += 4;
		} else filename[0] = 0;
		*(ptr2++) = '/';
		for (i=0; i<ntok; i++) {
			ptr = tokarr[i];
			if (i>0) *(ptr2++) = '/';
			while (*ptr) *(ptr2++) = *(ptr++);
		}
		if (removefn) if (*(ptr2-1) != '/') *(ptr2++) = '/';
		*(ptr2) = 0;

#ifdef _WIN32
	}
#endif

	return 0;
}