uio_Stream * res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode) { uio_Stream *fp; struct stat sb; if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode)) return ((uio_Stream *) ~0); fp = uio_fopen (dir, filename, mode); return (fp); }
uio_FileBlock * uio_openFileBlock2(uio_Handle *handle, off_t offset, size_t size) { // TODO: mmap (see uio_openFileBlock) // TODO: check if offset and size are acceptable. // Need to handle streams of which the size is unknown. #if 0 if (uio_stat(handle, &statBuf) == -1) { // errno is set return NULL; } if (statBuf.st_size > offset || (statBuf.st_size - offset > size)) { // NOT: 'if (statBuf.st_size > offset + size)', to protect // against overflow. } #endif uio_Handle_ref(handle); return uio_FileBlock_new(handle, 0, offset, size, NULL, 0, 0, 0, 0); }
static int debugCmdStat(DebugContext *debugContext, int argc, char *argv[]) { struct stat statBuf; if (argc != 2) { fprintf(debugContext->err, "Invalid number of arguments.\n"); return 1; } if (uio_stat(debugContext->cwd, argv[1], &statBuf) == -1) { // errno is set int savedErrno; savedErrno = errno; fprintf(debugContext->err, "Could not stat file: %s\n", strerror(errno)); errno = savedErrno; return 1; } fprintf(debugContext->out, "size %ld bytes\n" "uid %d gid %d mode 0%o\n", (unsigned long) statBuf.st_size, (unsigned int) statBuf.st_uid, (unsigned int) statBuf.st_gid, (unsigned int) statBuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)); // Can't do these next three in one fprintf, as ctime uses a static buffer // that is overwritten with each call. fprintf(debugContext->out, "last access: %s", ctime(&statBuf.st_atime)); fprintf(debugContext->out, "last modification: %s", ctime(&statBuf.st_mtime)); fprintf(debugContext->out, "last status change: %s", ctime(&statBuf.st_ctime)); return 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); }
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); }