Beispiel #1
0
BOOLEAN
loadAddon (const char *addon)
{
	uio_DirHandle *addonsDir, *addonDir;
	int numLoaded;

	addonsDir = uio_openDirRelative (contentDir, "addons", 0);
	if (addonsDir == NULL)
	{
		// No addon dir found.
		log_add (log_Warning, "Warning: There's no 'addons' "
				"directory in the 'content' directory;\n\t'--addon' "
				"options are ignored.");
		return FALSE;
	}
	addonDir = uio_openDirRelative (addonsDir, addon, 0);
	if (addonDir == NULL)
	{
		log_add (log_Warning, "Warning: Addon '%s' not found", addon);
		uio_closeDir (addonsDir);
		return FALSE;
	}

	numLoaded = loadIndices (addonDir);

	uio_closeDir (addonDir);
	uio_closeDir (addonsDir);
	
	return (numLoaded > 0);
}
Beispiel #2
0
void
prepareShadowAddons (const char **addons)
{
	uio_DirHandle *addonsDir;
	const char *shadowDirName = "shadow-content";

	addonsDir = uio_openDirRelative (contentDir, "addons", 0);
	// If anything fails here, it will fail again later, so
	// we'll just keep quiet about it for now
	if (addonsDir == NULL)
		return;

	for (; *addons != NULL; addons++)
	{
		const char *addon = *addons;
		uio_DirHandle *addonDir;
		uio_DirHandle *shadowDir;

		addonDir = uio_openDirRelative (addonsDir, addon, 0);
		if (addonDir == NULL)
			continue;

		// Mount addon's "shadow-content" on top of "/"
		shadowDir = uio_openDirRelative (addonDir, shadowDirName, 0);
		if (shadowDir)
		{
			log_add (log_Debug, "Mounting shadow content of '%s' addon", addon);
			mountDirZips (shadowDir, "/", uio_MOUNT_ABOVE, contentMountHandle);
			uio_closeDir (shadowDir);
		}
		uio_closeDir (addonDir);
	}

	uio_closeDir (addonsDir);
}
Beispiel #3
0
void
prepareMeleeDir (void) {
	char buf[PATH_MAX];
	const char *meleeDirName;

	meleeDirName = getenv("UQM_MELEE_DIR");
	if (meleeDirName == NULL)
		meleeDirName = MELEEDIR;
	
	if (expandPath (buf, PATH_MAX - 13, meleeDirName, EP_ALL_SYSTEM) == -1)
	{
		// Doesn't have to be fatal, but might mess up things when saving
		// config files.
		log_add (log_Fatal, "Fatal error: Invalid path to config files.");
		exit (EXIT_FAILURE);
	}

	meleeDirName = buf;
	setenv("UQM_MELEE_DIR", meleeDirName, 1);

	// Create the path upto the save dir, if not already existing.
	if (mkdirhier (meleeDirName) == -1)
		exit (EXIT_FAILURE);

	meleeDir = uio_openDirRelative (configDir, "teams", 0);
			// TODO: this doesn't work if the save dir is not
			//       "teams" in the config dir.
	if (meleeDir == NULL)
	{
		log_add (log_Fatal, "Fatal error: Could not open melee teams dir: %s",
				strerror (errno));
		exit (EXIT_FAILURE);
	}
}
Beispiel #4
0
static int
debugCmdCd(DebugContext *debugContext, int argc, char *argv[]) {
    uio_DirHandle *newWd;

    if (argc != 2) {
        fprintf(debugContext->err, "Invalid number of arguments.\n");
        return 1;
    }
    newWd = uio_openDirRelative(debugContext->cwd, argv[1], 0);
    if (newWd == NULL) {
        fprintf(debugContext->err, "Could not access new dir: %s\n",
                strerror(errno));
        return 1;
    }
    uio_closeDir(debugContext->cwd);
    debugContext->cwd = newWd;
    return 0;
}
Beispiel #5
0
static void
mountAddonDir (uio_Repository *repository, uio_MountHandle *contentMountHandle,
		const char *addonDirName)
{
	uio_DirHandle *addonsDir;
	static uio_AutoMount *autoMount[] = { NULL };
	uio_MountHandle *mountHandle;
	uio_DirList *availableAddons;

	if (addonDirName != NULL)
	{
		mountHandle = uio_mountDir (repository, "addons",
				uio_FSTYPE_STDIO, NULL, NULL, addonDirName, autoMount,
				uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL);
		if (mountHandle == NULL)
		{
			log_add (log_Warning, "Warning: Could not mount addon directory: %s"
					";\n\t'--addon' options are ignored.", strerror (errno));
			return;
		}
	}
	else
	{
		mountHandle = contentMountHandle;
	}

	// NB: note the difference between addonsDir and addonDir.
	//     the former is the dir 'addons', the latter a directory
	//     in that dir.
	addonsDir = uio_openDirRelative (contentDir, "addons", 0);
	if (addonsDir == NULL)
	{	// No addon dir found.
		log_add (log_Warning, "Warning: There's no 'addons' "
				"directory in the 'content' directory;\n\t'--addon' "
				"options are ignored.");
		return;
	}

	mountDirZips (addonsDir, "addons", uio_MOUNT_BELOW, mountHandle);
			
	availableAddons = uio_getDirList (addonsDir, "", "", match_MATCH_PREFIX);
	if (availableAddons != NULL)
	{
		int i, count;
		
		// count the actual addon dirs
		count = 0;
		for (i = 0; i < availableAddons->numNames; ++i)
		{
			struct stat sb;

			if (availableAddons->names[i][0] == '.' ||
					uio_stat (addonsDir, availableAddons->names[i], &sb) == -1
					|| !S_ISDIR (sb.st_mode))
			{	// this dir entry ignored
				availableAddons->names[i] = NULL;
				continue;
			}
			++count;
		}
		log_add (log_Info, "%d available addon pack%s.", count,
				count == 1 ? "" : "s");

		count = 0;
		for (i = 0; i < availableAddons->numNames; ++i)
		{
			static char mountname[128];
			uio_DirHandle *addonDir;
			const char *addon = availableAddons->names[i];
			
			if (!addon)
				continue;

			++count;
			log_add (log_Info, "    %d. %s", count, addon);
		
			snprintf(mountname, 128, "addons/%s", addon);
			mountname[127]=0;

			addonDir = uio_openDirRelative (addonsDir, addon, 0);
			if (addonDir == NULL)
			{
				log_add (log_Warning, "Warning: directory 'addons/%s' "
					 "not found; addon skipped.", addon);
				continue;
			}
			mountDirZips (addonDir, mountname, uio_MOUNT_BELOW, mountHandle);
			uio_closeDir (addonDir);
		}
	}
	else
	{
		log_add (log_Info, "0 available addon packs.");
	}

	uio_DirList_free (availableAddons);
	uio_closeDir (addonsDir);
}
Beispiel #6
0
void *
_GetFontData (uio_Stream *fp, DWORD length)
{
	COUNT numDirEntries;
	DIRENTRY fontDir = NULL;
	BuildCharDesc *bcds = NULL;
	size_t numBCDs = 0;
	int dirEntryI;
	uio_DirHandle *fontDirHandle = NULL;
	uio_MountHandle *fontMount = NULL;
	FONT fontPtr = NULL;

	if (_cur_resfile_name == 0)
		goto err;

	if (fp != (uio_Stream*)~0)
	{
		// font is zipped instead of being in a directory

		char *s1, *s2;
		int n;
		const char *fontZipName;
		char fontDirName[PATH_MAX];

		if ((((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0)
						&& (s2 = strrchr (_cur_resfile_name, '\\')) == 0))
		{
			strcpy(fontDirName, ".");
			fontZipName = _cur_resfile_name;
		}
		else
		{
			if (s2 > s1)
				s1 = s2;
			n = s1 - _cur_resfile_name + 1;
			strncpy (fontDirName, _cur_resfile_name, n - 1);
			fontDirName[n - 1] = 0;
			fontZipName = _cur_resfile_name + n;
		}

		fontDirHandle = uio_openDir (repository, fontDirName, 0);
		fontMount = uio_mountDir (repository, _cur_resfile_name, uio_FSTYPE_ZIP,
						fontDirHandle, fontZipName, "/", autoMount,
						uio_MOUNT_RDONLY | uio_MOUNT_TOP,
						NULL);
		uio_closeDir (fontDirHandle);
	}

	fontDir = CaptureDirEntryTable (LoadDirEntryTable (contentDir,
			_cur_resfile_name, ".", match_MATCH_SUBSTRING));
	if (fontDir == 0)
		goto err;
	numDirEntries = GetDirEntryTableCount (fontDir);

	fontDirHandle = uio_openDirRelative (contentDir, _cur_resfile_name, 0);
	if (fontDirHandle == NULL)
		goto err;
		
	bcds = HMalloc (numDirEntries * sizeof (BuildCharDesc));
	if (bcds == NULL)
		goto err;

	// Load the surfaces for all dir Entries
	for (dirEntryI = 0; dirEntryI < numDirEntries; dirEntryI++)
	{
		char *char_name;
		unsigned int charIndex;
		TFB_Canvas canvas;
		EXTENT size;

		char_name = GetDirEntryAddress (SetAbsDirEntryTableIndex (
				fontDir, dirEntryI));
		if (sscanf (char_name, "%x.", &charIndex) != 1)
			continue;
			
		if (charIndex > 0xffff)
			continue;

		canvas = TFB_DrawCanvas_LoadFromFile (fontDirHandle, char_name);
		if (canvas == NULL)
			continue;

		TFB_DrawCanvas_GetExtent (canvas, &size);
		if (size.width == 0 || size.height == 0)
		{
			TFB_DrawCanvas_Delete (canvas);
			continue;
		}

		bcds[numBCDs].canvas = canvas;
		bcds[numBCDs].index = charIndex;
		numBCDs++;
	}
	uio_closeDir (fontDirHandle);
	DestroyDirEntryTable (ReleaseDirEntryTable (fontDir));
	if (fontMount != 0)
		uio_unmountDir(fontMount);

#if 0
	if (numBCDs == 0)
		goto err;
#endif

	// sort on the character index
	qsort (bcds, numBCDs, sizeof (BuildCharDesc), compareBCDIndex);

	fontPtr = AllocFont (0);
	if (fontPtr == NULL)
		goto err;
	
	fontPtr->Leading = 0;
	fontPtr->LeadingWidth = 0;

	{
		size_t startBCD = 0;
		UniChar pageStart;
		FONT_PAGE **pageEndPtr = &fontPtr->fontPages;
		while (startBCD < numBCDs)
		{
			// Process one character page.
			size_t endBCD;
			pageStart = bcds[startBCD].index & CHARACTER_PAGE_MASK;

			endBCD = startBCD;
			while (endBCD < numBCDs &&
					(bcds[endBCD].index & CHARACTER_PAGE_MASK) == pageStart)
				endBCD++;

			{
				size_t bcdI;
				int numChars = bcds[endBCD - 1].index + 1
						- bcds[startBCD].index;
				FONT_PAGE *page = AllocFontPage (numChars);
				page->pageStart = pageStart;
				page->firstChar = bcds[startBCD].index;
				page->numChars = numChars;
				*pageEndPtr = page;
				pageEndPtr = &page->next;

				for (bcdI = startBCD; bcdI < endBCD; bcdI++)
				{
					// Process one character.
					BuildCharDesc *bcd = &bcds[bcdI];
					TFB_Char *destChar =
							&page->charDesc[bcd->index - page->firstChar];
				
					if (destChar->data != NULL)
					{
						// There's already an image for this character.
						log_add (log_Debug, "Duplicate image for character %d "
								"for font %s.", (int) bcd->index,
								_cur_resfile_name);
						TFB_DrawCanvas_Delete (bcd->canvas);
						continue;
					}
					
					processFontChar (destChar, bcd->canvas);
					TFB_DrawCanvas_Delete (bcd->canvas);

					if (destChar->disp.height > fontPtr->Leading)
						fontPtr->Leading = destChar->disp.height;
					if (destChar->disp.width > fontPtr->LeadingWidth)
						fontPtr->LeadingWidth = destChar->disp.width;
				}
			}

			startBCD = endBCD;
		}
		*pageEndPtr = NULL;
	}

	fontPtr->Leading++;

	HFree (bcds);

	(void) fp;  /* Satisfying compiler (unused parameter) */
	(void) length;  /* Satisfying compiler (unused parameter) */
	return fontPtr;

err:
	if (fontPtr != 0)
		HFree (fontPtr);
	
	if (bcds != NULL)
	{
		size_t bcdI;
		for (bcdI = 0; bcdI < numBCDs; bcdI++)
			TFB_DrawCanvas_Delete (bcds[bcdI].canvas);
		HFree (bcds);
	}
	
	if (fontDirHandle != NULL)
		uio_closeDir (fontDirHandle);
	
	if (fontDir != 0)
		DestroyDirEntryTable (ReleaseDirEntryTable (fontDir));

	if (fontMount != 0)
		uio_unmountDir(fontMount);

	return 0;
}
Beispiel #7
0
uio_StdioAccessHandle *
uio_getStdioAccess(uio_DirHandle *dir, const char *path, int flags,
		uio_DirHandle *tempDir) {
	int res;
	uio_MountHandle *mountHandle;
	const char *name;
	char *newPath;
	char *tempDirName;
	uio_DirHandle *newDir;
	uio_FileSystemID fsID;

	res = uio_getFileLocation(dir, path, flags, &mountHandle, &newPath);
	if (res == -1) {
		// errno is set
		return NULL;
	}
	
	fsID = uio_getMountFileSystemType(mountHandle);
	if (fsID == uio_FSTYPE_STDIO) {
		// Current location is usable.
		return uio_StdioAccessHandle_new(NULL, NULL, NULL, NULL, newPath);
	}
	uio_free(newPath);

	{
		uio_uint32 dirNum;
		int i;

		// Current location is not usable. Create a directory with a
		// generated name, as a temporary location to store a copy of
		// the file.
		dirNum = (uio_uint32) time(NULL);
		tempDirName = uio_malloc(sizeof "01234567");
		for (i = 0; ; i++) {
#ifdef NUM_TEMP_RETRIES
			if (i >= NUM_TEMP_RETRIES) {
				// Using ENOSPC to report that we couldn't create a
				// temporary dir, getting EEXIST.
				uio_free(tempDirName);
				errno = ENOSPC;
				return NULL;
			}
#endif
			
			sprintf(tempDirName, "%08lx", (unsigned long) dirNum + i);
			
			res = uio_mkdir(tempDir, tempDirName, 0700);
			if (res == -1) {
				int savedErrno;
				if (errno == EEXIST)
					continue;
				savedErrno = errno;
#ifdef DEBUG
				fprintf(stderr, "Error: Could not create temporary dir: %s\n",
						strerror(errno));
#endif
				uio_free(tempDirName);
				errno = savedErrno;
				return NULL;
			}
			break;
		}

		newDir = uio_openDirRelative(tempDir, tempDirName, 0);
		if (newDir == NULL) {
#ifdef DEBUG
			fprintf(stderr, "Error: Could not open temporary dir: %s\n",
					strerror(errno));
#endif
			res = uio_rmdir(tempDir, tempDirName);
#ifdef DEBUG
			if (res == -1)
				fprintf(stderr, "Warning: Could not remove temporary dir: "
						"%s.\n", strerror(errno));
#endif
			uio_free(tempDirName);
			errno = EIO;
			return NULL;
		}

		// Get the last component of path. This should be the file to
		// access.
		name = strrchr(path, '/');
		if (name == NULL)
			name = path;

		// Copy the file
		res = uio_copyFile(dir, path, newDir, name);
		if (res == -1) {
			int savedErrno = errno;
#ifdef DEBUG
			fprintf(stderr, "Error: Could not copy file to temporary dir: "
					"%s\n", strerror(errno));
#endif
			uio_closeDir(newDir);
			uio_free(tempDirName);
			errno = savedErrno;
			return NULL;
		}
	}

	res = uio_getFileLocation(newDir, name, flags, &mountHandle, &newPath);
	if (res == -1) {
		int savedErrno = errno;
		fprintf(stderr, "Error: uio_getStdioAccess: Could not get location "
				"of temporary dir: %s.\n", strerror(errno));
		uio_closeDir(newDir);
		uio_free(tempDirName);
		errno = savedErrno;
		return NULL;
	}
	
	fsID = uio_getMountFileSystemType(mountHandle);
	if (fsID != uio_FSTYPE_STDIO) {
		// Temp dir isn't on a stdio fs either.
		fprintf(stderr, "Error: uio_getStdioAccess: Temporary file location "
				"isn't on a stdio filesystem.\n");
		uio_closeDir(newDir);
		uio_free(tempDirName);
		uio_free(newPath);
//		errno = EXDEV;
		errno = EINVAL;
		return NULL;
	}

	uio_DirHandle_ref(tempDir);
	return uio_StdioAccessHandle_new(tempDir, tempDirName, newDir, 
			uio_strdup(name), newPath);
}
Beispiel #8
0
static int
debugCmdExec(DebugContext *debugContext, int argc, char *argv[]) {
    int i;
    const char **newArgs;
    int errCode = 0;
    uio_StdioAccessHandle **handles;
    uio_DirHandle *tempDir;

    if (argc < 2) {
        fprintf(debugContext->err, "Invalid number of arguments.\n");
        return 1;
    }

    tempDir = uio_openDirRelative(debugContext->cwd, "/tmp", 0);
    if (tempDir == 0) {
        fprintf(debugContext->err, "Could not open temp dir: %s.\n",
                strerror(errno));
        return 1;
    }

    newArgs = uio_malloc(argc * sizeof (char *));
    newArgs[0] = argv[1];
    handles = uio_malloc(argc * sizeof (uio_StdioAccessHandle *));
    handles[0] = NULL;

    for (i = 2; i < argc; i++) {
#if 0
        if (argv[i][0] == '-') {
            // Don't try to parse arguments that start with '-'.
            // They are probably option flags.
            newArgs[i - 1] = argv[i];
        }
#endif
        handles[i - 1] = uio_getStdioAccess(debugContext->cwd, argv[i],
                                            O_RDONLY, tempDir);
        if (handles[i - 1] == NULL) {
            if (errno == ENOENT) {
                // No match; we keep what's typed literally.
                newArgs[i - 1] = argv[i];
                continue;
            }

            // error
            fprintf(debugContext->err,
                    "Cannot execute: Cannot get stdio access to %s: %s.\n",
                    argv[i], strerror(errno));
            errCode = 1;
            argc = i + 1;
            goto err;
        }

        newArgs[i - 1] = uio_StdioAccessHandle_getPath(handles[i - 1]);
    }
    newArgs[argc - 1] = NULL;

    fprintf(debugContext->err, "Executing: %s", newArgs[0]);
    for (i = 1; i < argc - 1; i++)
        fprintf(debugContext->err, " %s", newArgs[i]);
    fprintf(debugContext->err, "\n");

#if defined(__unix__) && !defined(_WIN32_WCE)
    {
        pid_t pid;

        pid = fork();
        switch (pid) {
        case -1:
            fprintf(debugContext->err, "Error: fork() failed: %s.\n",
                    strerror(errno));
            break;
        case 0:
            // child
            execvp(newArgs[0], (char * const *) newArgs);
            fprintf(debugContext->err, "Error: execvp() failed: %s.\n",
                    strerror(errno));
            _exit(EXIT_FAILURE);
            break;
        default: {
            // parent
            int status;
            pid_t retVal;

            while (1) {
                retVal = waitpid(pid, &status, 0);
                if (retVal != -1)
                    break;
                if (errno != EINTR) {
                    fprintf(debugContext->err, "Error: waitpid() "
                            "failed: %s\n", strerror(errno));
                    break;
                }
            }
            if (retVal == -1)
                break;

            if (WIFEXITED(status)) {
                fprintf(debugContext->err, "Exit status: %d\n",
                        WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                fprintf(debugContext->err, "Terminated on signal %d.\n",
                        WTERMSIG(status));
            } else {
                fprintf(debugContext->err, "Error: weird exit status.\n");
            }
            break;
        }
        }
    }
#else
    fprintf(debugContext->err, "Cannot execute: not supported on this "
            "platform.\n");
#endif

err:
    for (i = 1; i < argc - 1; i++) {
        if (handles[i] != NULL)
            uio_releaseStdioAccess(handles[i]);
    }
    uio_free(handles);
    uio_free((void *) newArgs);
    uio_closeDir(tempDir);

    return errCode;
}
Beispiel #9
0
DIRENTRY_REF
LoadDirEntryTable (uio_DirHandle *dirHandle, const char *path,
		const char *pattern, match_MatchType matchType, PCOUNT pnum_entries)
{
	uio_DirList *dirList;
	COUNT num_entries, length;
	COUNT i;
	COUNT slen;
	uio_DirHandle *dir;
	STRING_TABLE StringTable;
	STRING_TABLEPTR lpST;
	PSTR lpStr;
	PDWORD lpLastOffs;

	dir = uio_openDirRelative (dirHandle, path, 0);
	assert(dir != NULL);
	dirList = uio_getDirList (dir, "", pattern, matchType);
	assert(dirList != NULL);
	num_entries = 0;
	length = 0;

	// First, count the amount of space needed
	for (i = 0; i < dirList->numNames; i++)
	{
		struct stat sb;

		if (dirList->names[i][0] == '.')
		{
			dirList->names[i] = NULL;
			continue;
		}
		if (uio_stat (dir, dirList->names[i], &sb) == -1)
		{
			dirList->names[i] = NULL;
			continue;
		}
		if (!S_ISREG (sb.st_mode))
		{
			dirList->names[i] = NULL;
			continue;
		}
		length += strlen (dirList->names[i]) + 1;
		num_entries++;
	}
	uio_closeDir (dir);

	if (num_entries == 0) {
		uio_DirList_free(dirList);
		*pnum_entries = 0;
		return ((DIRENTRY_REF) 0);
	}

	slen = sizeof (STRING_TABLE_DESC)
			+ (num_entries * sizeof (DWORD));
	StringTable = AllocResourceData (slen + length, 0);
	LockStringTable (StringTable, &lpST);
	if (lpST == 0)
	{
		FreeStringTable (StringTable);
		uio_DirList_free(dirList);
		*pnum_entries = 0;
		return ((DIRENTRY_REF) 0);
	}
	lpST->StringCount = num_entries;
	lpLastOffs = &lpST->StringOffsets[0];
	*lpLastOffs = slen;
	lpStr = (PSTR)lpST + slen;

	for (i = 0; i < dirList->numNames; i++)
	{
		int size;
		if (dirList->names[i] == NULL)
			continue;
		size = strlen (dirList->names[i]) + 1;
		memcpy (lpStr, dirList->names[i], size);
		lpLastOffs[1] = lpLastOffs[0] + size;
		lpLastOffs++;
		lpStr += size;
	}
	
	uio_DirList_free(dirList);
	*pnum_entries = num_entries;
	UnlockStringTable (StringTable);
	return ((DIRENTRY_REF) StringTable);
}