DepFixture(const char *path) : mgr(NULL) , vmgr(NULL) , resolver(NULL) , siteless(false) { rc_t rc = 0; KDirectory *wd = NULL; if (KDirectoryNativeDir(&wd)) { FAIL("failed to KDirectoryNativeDir"); } const KDirectory *dir = NULL; KConfig *cfg = NULL; if (KDirectoryOpenDirRead(wd, &dir, false, path)) { FAIL("failed to KDirectoryOpenDirRead()"); } if (KConfigMake(&cfg, dir)) { FAIL("failed to KConfigMake()"); } RELEASE(KDirectory, dir); if (VFSManagerMakeFromKfg(&vmgr, cfg)) { FAIL("failed to VFSManagerMakeFromKfg()"); } if (VFSManagerGetResolver(vmgr, &resolver)) { FAIL("failed to VFSManagerGetResolver"); } String *result = NULL; rc = KConfigReadString(cfg, "repository/site/main/tracearc/root", &result); if (rc != 0) { if (rc == SILENT_RC(rcKFG, rcNode, rcOpening, rcPath, rcNotFound)) { rc = 0; siteless = true; } else { FAIL( "failed to KConfigReadString(repository/site/main/tracearc/root)"); } } else { assert(result); KPathType t = KDirectoryPathType(wd, result->addr); if (t != kptDir) { siteless = true; } } RELEASE(String, result); RELEASE(KConfig, cfg); if (VDBManagerMakeReadWithVFSManager(&mgr, NULL, vmgr)) { FAIL("failed to VDBManagerMakeReadWithVFSManager()"); } RELEASE(KDirectory, wd); }
static rc_t KDBOpenPathTypeReadInt ( const KDBManager * mgr, const KDirectory * dir, const char * path, const KDirectory ** pdir, int * type, int pathtype, uint32_t rcobj, bool try_srapath ) { VFSManager * vmgr = mgr->vfsmgr; const KDirectory * ldir = NULL; rc_t rc = 0; /* object relative opens can be done using KFS - we hacked in VFS after all */ if (! try_srapath) { rc = KDirectoryOpenDirUpdate ((KDirectory*)dir, (KDirectory**)pdir, false, path); if ((rc) && (GetRCState(rc) != rcNotFound)) rc = KDirectoryOpenDirRead (dir, pdir, false, path); } else { VPath * vpath; /* * We've got to decide if the path coming in is a full or relative * path and if relative make it relative to dir or possibly its a srapath * accession * */ rc = VPathMakeDirectoryRelative ( &vpath, dir, path ); if ( rc == 0 ) { rc = VFSManagerOpenDirectoryReadDirectoryRelativeDecrypt ( vmgr, dir, &ldir, vpath ); if ( rc == 0 ) { *type = (~kptAlias) & KDBPathType ( ldir, NULL, "." ); /* just a directory, not a kdb type */ if ( *type == kptDir ) rc = RC (rcDB, rcMgr, rcOpening, rcPath, rcIncorrect); else if ( *type != pathtype ) { KDirectoryRelease( ldir ); rc = RC ( rcDB, rcMgr, rcOpening, rcobj, rcIncorrect ); } else { if ( pdir != NULL ) *pdir = ldir; else KDirectoryRelease( ldir ); } } VPathRelease ( vpath ); } } return rc; }
/* IsAlias * returns true if object name is an alias * returns path to fundamental name if it was aliased * * "type" [ IN ] - a KDBPathType * valid values are kptIndex and kptColumn * * "resolved" [ OUT ] and "rsize" [ IN ] - optional output buffer * for fundamenta object name if "alias" is not a fundamental name, * * "name" [ IN ] - NUL terminated object name */ LIB_EXPORT bool CC KTableIsAlias ( const KTable *self, uint32_t type, char *resolved, size_t rsize, const char *name ) { if ( self != NULL && name != NULL && name [ 0 ] != 0 ) { rc_t rc; const char *ns; char path [ 256 ]; switch ( type ) { case kptIndex: ns = "idx"; break; case kptColumn: ns = "col"; break; default: return false; } rc = KDBMakeSubPath ( self -> dir, path, sizeof path, ns, 3, name ); if ( rc == 0 ) { switch ( KDirectoryPathType ( self -> dir, "%s", path ) ) { case kptFile | kptAlias: case kptDir | kptAlias: if ( resolved != NULL && rsize != 0 ) { const KDirectory *sub; rc = KDirectoryOpenDirRead ( self -> dir, & sub, false, "%s", ns ); * resolved = 0; if ( rc != 0 ) PLOGERR ( klogWarn, ( klogWarn, rc, "failed to open subdirectory '$(sub)'", "sub=%s", ns ) ); else { rc = KDirectoryResolveAlias ( sub, false, resolved, rsize, "%s", name ); KDirectoryRelease ( sub ); if ( rc != 0 ) PLOGERR ( klogWarn, ( klogWarn, rc, "failed to resolve alias '$(alias)'", "alias=%s", name ) ); } } return true; } } } if ( resolved != NULL && rsize != 0 ) * resolved = 0; return false; }
static rc_t ShowModDir(const KDirectory* native, char* path) { rc_t rc = 0; const KDirectory* dir = NULL; assert(native && path); rc = KDirectoryOpenDirRead(native, &dir, false, path); DISP_RC(rc, path); if (rc == 0) { rc = KDirectoryVVisit(dir, false, scan_mod_dir, path, ".", NULL); } return rc; }
static rc_t open_dir_or_tar( const KDirectory *dir, const KDirectory **sub, const char * name ) { rc_t rc1, rc2; rc1 = KDirectoryOpenDirRead( dir, sub, true, name ); if ( rc1 != 0 ) { rc2 = KDirectoryOpenTarArchiveRead( dir, sub, true, name ); if ( rc2 == 0 ) rc1 = rc2; } return rc1; }
static rc_t copy2_main( Args * args ) { const char * source_path; rc_t rc = ArgsParamValue( args, 0, &source_path ); if ( rc != 0 ) LOGERR( klogInt, rc, "ArgsParamValue( 0 ) failed" ); else { const char * dest_path; rc = ArgsParamValue( args, 1, &dest_path ); if ( rc != 0 ) LOGERR( klogInt, rc, "ArgsParamValue( 1 ) failed" ); else { KDirectory *dir, *dest_dir; const KDirectory *source_dir; rc = KDirectoryNativeDir ( &dir ); if ( rc != 0 ) LOGERR( klogInt, rc, "KDirectoryNativeDir() failed" ); else { rc = KDirectoryOpenDirRead( dir, &source_dir, false, source_path ); if ( rc != 0 ) LOGERR( klogInt, rc, "KDirectoryOpenDirRead() failed" ); else { rc = KDirectoryOpenDirUpdate( dir, &dest_dir, false, dest_path ); if ( rc != 0 ) LOGERR( klogInt, rc, "KDirectoryOpenDirUpdate() failed" ); else { rc = KDirectoryCopy( source_dir, dest_dir, true, source_path, dest_path ); if ( rc != 0 ) LOGERR( klogInt, rc, "copy_dirs() failed" ); else OUTMSG(( "copy successful!\n" )); KDirectoryRelease ( dest_dir ); } KDirectoryRelease ( source_dir ); } KDirectoryRelease ( dir ); } } } return rc; }
rc_t ArchiveAndEncrypt(KDirectory* wd, const char* inpath, const char* outpath, const char* passwd) { const KDirectory* d; rc_t rc = KDirectoryOpenDirRead (wd, &d, false, "%s", inpath); if (rc == 0) { const KFile* infile; rc_t rc2; rc = KDirectoryOpenTocFileRead (d, &infile, 4, NULL, NULL, NULL); if (rc == 0) { KFile* outfile; /* if the file exists, add write access */ KDirectorySetAccess( wd, false, 0600, 0777, "%s", outpath ); rc = KDirectoryCreateFile(wd, &outfile, false, 0600, kcmCreate|kcmInit, "%s", outpath); if ( rc == 0 ) { KFile* enc_outfile; KKey key; rc = KKeyInitRead(&key, kkeyAES256, passwd, string_measure(passwd, NULL)); if ( rc == 0 ) rc = KEncFileMakeWrite(&enc_outfile, outfile, &key); if (rc == 0) rc = copy_file(infile, enc_outfile); rc2 = KFileRelease(outfile); if (rc == 0) rc = rc2; /* remove write access */ rc2 = KDirectorySetAccess( wd, false, 0400, 0777, "%s", outpath ); if (rc == 0) rc = rc2; rc2 = KFileRelease(enc_outfile); if (rc == 0) rc = rc2; } rc2 = KFileRelease(infile); if (rc == 0) rc = rc2; } rc2 = KDirectoryRelease(d); if (rc == 0) rc = rc2; } return rc; }
/* * copies top/inname (a directory) * to targettop/outname, i.e. creates outname as a copy of that directory. */ rc_t CopyDirectoryToExistingDirectory( const KDirectory *top, const char *inname, KDirectory *targettop, const char *outname ) { rc_t rc; uint32_t mode; const KDirectory *source; KDirectory *dest; rc = KDirectoryOpenDirRead(top, &source, true, "%s", (const char *)inname); if (rc != 0) { LOGERR ( klogInt, rc, "can't open input directory" ); return rc; } mode = DEFAULT_DIR_MODE; rc = KDirectoryAccess( top, &mode, "%s", inname); if (rc != 0) { LOGERR ( klogInt, rc, inname ); return rc; } rc = KDirectoryCreateDir( targettop, mode, kcmOpen, "%s", outname ); if (rc != 0) { LOGERR ( klogInt, rc, "can't create output directory" ); return rc; } if (clobber_protections) { KDirectorySetAccess( targettop, false, mode, 0777, "%s", outname); } rc = KDirectoryOpenDirUpdate(targettop, &dest, true, "%s", outname); if (rc != 0) { LOGERR ( klogInt, rc, "can't open directory for write" ); return rc; } CopyDirectoryFiles(source, dest); CopyDirectoryDirectories( source, dest ); KDirectoryRelease( dest ); KDirectoryRelease( source ); return 0; }
static rc_t CreateConfig(char* argv0) { const KFile* std_in = NULL; KDirectory* native = NULL; KDirectory* dir = NULL; rc_t rc = 0; char* location = NULL; char* mod = NULL; char* wmod = NULL; char* refseq = NULL; if (rc == 0) { rc = KDirectoryNativeDir(&native); } if (rc == 0) { const char* def = NULL; char cwd[PATH_MAX + 1] = ""; const char* home = getenv("HOME"); if (home) { def = home; } else { rc = VPathGetCWD(cwd, sizeof cwd); if (rc == 0 && cwd[0]) { def = cwd; } else { def = "."; } } while (rc == 0) { char buffer[PATH_MAX + 1]; rc = In("Specify configuration files directory", def, &location); if (rc == 0) { rc = KDirectoryOpenDirUpdate(native, &dir, false, location); if (rc == 0) { rc = KDirectoryVVisit (dir, false, scan_config_dir, buffer, ".", NULL); if (rc != 0) { if (rc == RC(rcExe, rcDirectory, rcListing, rcFile, rcExists) && buffer[0]) { PLOGERR(klogErr, (klogErr, rc, "Configuration file found: $(dir)/$(name)", "dir=%s,name=%s", location, buffer)); rc = 0; buffer[0] = '\0'; continue; } else { PLOGERR(klogErr, (klogErr, rc, "$(dir)/$(name)", "dir=%s,name=%s", location, buffer)); } } break; } else if (GetRCObject(rc) == rcPath && (GetRCState(rc) == rcIncorrect || GetRCState(rc) == rcNotFound)) { PLOGERR(klogErr, (klogErr, rc, "$(path)", "path=%s", location)); rc = 0; } else { DISP_RC(rc, location); } } } } while (rc == 0) { const KDirectory* dir = NULL; rc = In("Specify refseq installation directory", NULL, &refseq); if (rc != 0) { break; } rc = KDirectoryOpenDirRead(native, &dir, false, refseq); if (rc == 0) { RELEASE(KDirectory, dir); break; } else if (GetRCObject(rc) == rcPath && GetRCState(rc) == rcIncorrect) { PLOGERR(klogErr, (klogErr, rc, "$(path)", "path=%s", refseq)); rc = 0; } DISP_RC(rc, refseq); } if (rc == 0) { char buffer[512]; const char path[] = "vdb-config.kfg"; uint64_t pos = 0; KFile* f = NULL; rc = KDirectoryCreateFile(dir, &f, false, 0664, kcmCreate, path); DISP_RC(rc, path); if (rc == 0) { int n = snprintf(buffer, sizeof buffer, "refseq/servers = \"%s\"\n", refseq); if (n >= sizeof buffer) { rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient); } else { size_t num_writ = 0; rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ); pos += num_writ; } } if (rc == 0) { const char buffer[] = "refseq/volumes = \".\"\n"; size_t num_writ = 0; rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ); pos += num_writ; } if (rc == 0 && mod && mod[0]) { int n = snprintf(buffer, sizeof buffer, "vdb/module/paths = \"%s\"\n", mod); if (n >= sizeof buffer) { rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient); } else { size_t num_writ = 0; rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ); pos += num_writ; } } if (rc == 0 && wmod && wmod[0]) { int n = snprintf(buffer, sizeof buffer, "vdb/wmodule/paths = \"%s\"\n", wmod); if (n >= sizeof buffer) { rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient); } else { size_t num_writ = 0; rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ); pos += num_writ; } } RELEASE(KFile, f); } free(mod); free(wmod); free(refseq); free(location); RELEASE(KDirectory, dir); RELEASE(KDirectory, native); RELEASE(KFile, std_in); DestroyStdin(); return rc; }
static rc_t Start (KDirectory * cwd, const char * src, const char * dst) { KPathType dtype; KPathType stype; char dpath [MY_MAX_PATH]; char spath [MY_MAX_PATH]; rc_t rc; bool using_stdin, using_stdout, try_rename; /* limited anti oops checks */ try_rename = (dst == NULL); if (!try_rename) { /* try to prevent file to file clash */ if (strcmp (src,dst) == 0) dst = NULL; /* try to prevent file to dir clash */ else { size_t s,d; s = string_size (src); d = string_size (dst); if (s > d) { if (string_cmp (src, s, dst, d, d) == 0) { if ((strchr (src+d+1, '/') == NULL) && ((src[d] == '/') || (src[d-1] == '/'))) { try_rename = true; dst = NULL; } } } } } /* * This is a quick fix "hack" * A fully built out VFS should replace the KFS in use and eliminate this */ using_stdin = (strcmp (src, "/dev/stdin") == 0); if (using_stdin) { if (dst == NULL) { rc = RC (rcExe, rcArgv, rcParsing, rcParam, rcNull); LOGERR (klogErr, rc, "Unable to handle stdin in place"); return rc; } stype = kptFile; strcpy (spath, src); UseStdin = true; STSMSG (1, ("reading console / stdin as input")); goto stdin_shortcut; } rc = KDirectoryResolvePath (cwd, false, spath, sizeof spath, "%s", src); if (rc) { LOGERR (klogErr, rc, "can't resolve source"); return rc; } stype = KDirectoryPathType (cwd, spath); switch (stype) { case kptNotFound: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcNotFound); break; default: case kptBadPath: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcInvalid); break; case kptCharDev: case kptBlockDev: case kptFIFO: case kptZombieFile: case kptDataset: case kptDatatype: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); break; case kptFile: case kptDir: break; } if (rc) { PLOGERR (klogErr, (klogErr, rc, "can not use source '$(S)'", "S=%s", src)); return rc; } /* * In Place Operation */ if (dst == NULL) { /* * Input is a file */ if (stype == kptFile) { KDirectory * ndir; char * pc; pc = strrchr (spath, '/'); if (pc == NULL) { pc = spath; ndir = cwd; rc = KDirectoryAddRef (cwd); } else if (pc == spath) { ++pc; ndir = cwd; rc = KDirectoryAddRef (cwd); } else { *pc++ = '\0'; rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, spath); } if (rc == 0) { rc = FileInPlace (ndir, pc, try_rename); KDirectoryRelease (ndir); } } /* * Input is a directory */ else { KDirectory * ndir; rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, spath); if (rc) ; else { STSMSG (1, ("%scrypting directory %s", De, spath)); rc = DoDir (ndir, ndir); STSMSG (1, ("done with directory %s", spath)); KDirectoryRelease (ndir); } } } /* * 'Copy' Operation */ else { stdin_shortcut: using_stdout = (strcmp (dst, "/dev/stdout") == 0); if (using_stdout == true) { dtype = kptFile; strcpy (dpath, dst); UseStdout = true; STSMSG (1, ("writing console / stdout as output")); goto do_file; } rc = KDirectoryResolvePath (cwd, false, dpath, sizeof dpath, "%s", dst); if (rc) { LOGERR (klogErr, rc, "can't resolve destination"); return rc; } dtype = KDirectoryPathType (cwd, dpath); switch (dtype) { default: case kptBadPath: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcInvalid); PLOGERR (klogErr, (klogErr, rc, "can not use destination '$(S)'", "S=%s", dst)); break; case kptCharDev: case kptBlockDev: case kptFIFO: case kptZombieFile: case kptDataset: case kptDatatype: rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); PLOGERR (klogErr, (klogErr, rc, "can not use destination parameter '$(S)'", "S=%s", dst)); break; case kptNotFound: { size_t z; z = strlen (dst) - 1; if ((dst[z] == '/') || (stype == kptDir)) goto do_dir; else goto do_file; } case kptFile: if (!ForceFlag) { rc = RC (rcExe, rcArgv, rcParsing, rcFile, rcExists); PLOGERR (klogErr, (klogErr, rc, "can not over-write '$(F)' without --force", "F=%s", dpath)); break; } do_file: if (stype == kptFile) { rc = FileToFile (cwd, spath, cwd, dpath, try_rename, NULL); } else { rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); LOGERR (klogErr, rc, "Can't do directory to file"); } break; do_dir: case kptDir: /* * Input is a directory */ if (stype == kptDir) { #if DIRECTORY_TO_DIRECTORY_SUPPORTED const KDirectory * sdir; KDirectory * ddir; rc = KDirectoryOpenDirRead (cwd, &sdir, false, spath); if (rc) ; else { if (dtype == kptNotFound) { STSMSG (1, ("creating output directory %s", dpath)); rc = KDirectoryCreateDir (cwd, 0775, kcmCreate|kcmParents, "%s", dpath); } if (rc == 0) { rc = KDirectoryOpenDirUpdate (cwd, &ddir, false, dpath); if (rc) ; else { STSMSG (1, ("%scrypting directory %s to %s", De, spath, dpath)); rc = DoDir (sdir, ddir); STSMSG (1, ("done with directory %s to %s", spath, dpath)); KDirectoryRelease (ddir); } } KDirectoryRelease (sdir); } #else rc = RC (rcExe, rcArgv, rcResolving, rcPath, rcIncorrect); LOGERR (klogErr, rc, "Can't do directory to directory"); #endif } /* * Input is a file */ else { KDirectory * ndir; const char * pc; if (dtype == kptNotFound) { STSMSG (1, ("creating output directory %s", dpath)); rc = KDirectoryCreateDir (cwd, 0775, kcmCreate|kcmParents, "%s", dpath); } if (rc == 0) { STSMSG (1, ("opening output directory %s", dpath)); rc = KDirectoryOpenDirUpdate (cwd, &ndir, false, dpath); if (rc) ; else { pc = strrchr (spath, '/'); if (pc == NULL) pc = spath; else ++pc; rc = FileToFile (cwd, spath, ndir, pc, true, dpath); KDirectoryRelease (ndir); } } } break; } } return rc; }
static rc_t DoDir (const KDirectory * sd, KDirectory * dd) { KNamelist * names; rc_t rc; rc = KDirectoryList (sd, &names, NULL, NULL, "."); if (rc) ; else { uint32_t count; rc = KNamelistCount (names, &count); if (rc) ; else { uint32_t idx; for (idx = 0; idx < count; ++idx) { const char * name; rc = KNamelistGet (names, idx, &name); if (rc) ; else { const KDirectory * nsd; KDirectory * ndd; KPathType kpt; kpt = KDirectoryPathType (sd, name); switch (kpt) { default: break; case kptFile: if (sd == dd) rc = FileInPlace (dd, name, true); else rc = FileToFile (sd, name, dd, name, true, NULL); break; case kptDir: if (sd == dd) { rc = KDirectoryOpenDirUpdate (dd, &ndd, false, "%s", name); if (rc) ; else { /* RECURSION */ STSMSG (1, ("%scrypting directory %s", De, name)); rc = DoDir (ndd, ndd); STSMSG (1, ("done with directory %s", name)); KDirectoryRelease (ndd); } } else { rc = KDirectoryOpenDirRead (sd, &nsd, false, name); if (rc) ; else { rc = KDirectoryCreateDir (dd, 0600, kcmOpen, "%s", name); if (rc) ; else { rc = KDirectoryOpenDirUpdate (dd, &ndd, false, "%s", name); if (rc) ; else { /* RECURSION */ STSMSG (1, ("%scrypting directory %s", De, name)); rc = DoDir (nsd, ndd); STSMSG (1, ("done with directory %s", name)); KDirectoryRelease (ndd); } } KDirectoryRelease (nsd); } } break; } } } } KNamelistRelease (names); } return rc; }
/* HomeDirectory * returns a KDirectory where the binary for a given function is located * * "dir" [ OUT ] - return parameter for home directory ( read-only ), if found * * "func" [ IN ] - function pointer within binary to be located */ LIB_EXPORT rc_t CC KDyldHomeDirectory ( const KDyld *self, const KDirectory **dir, fptr_t func ) { rc_t rc; if ( dir == NULL ) rc = RC ( rcFS, rcDylib, rcSearching, rcParam, rcNull ); else { * dir = NULL; if ( self == NULL ) rc = RC ( rcFS, rcDylib, rcSearching, rcSelf, rcNull ); else if ( func == NULL ) rc = RC ( rcFS, rcDylib, rcSearching, rcFunction, rcNull ); else { Dl_info info; memset ( & info, 0, sizeof info ); if ( dladdr ( ( void* ) func, & info ) == 0 ) rc = RC ( rcFS, rcDylib, rcSearching, rcFunction, rcNotFound ); else { KDirectory *wd; rc = KDirectoryNativeDir ( & wd ); if ( rc == 0 ) { /* turn this into a real path */ const KSysDir *sdir = KDirectoryGetSysDir ( wd ); if ( sdir == NULL ) rc = RC ( rcFS, rcDylib, rcSearching, rcDirectory, rcIncorrect ); else { /* "dladdr" will return a simple name rather than a path when the address is within the application itself and the application was found using PATH. this is brilliant design at its best. */ char thanks_for_brilliant_APIs [ PATH_MAX ]; const char *dli_fname = info . dli_fname; /* check for a path rather than a name */ const char *last_slash = strrchr ( info . dli_fname, '/' ); if ( last_slash == NULL ) { /* simple name - get PATH */ const char *PATH = getenv ( "PATH" ); rc = RC ( rcFS, rcDylib, rcSearching, rcPath, rcNotFound ); if ( PATH != NULL ) { /* loop over PATH */ const char *path_start, *path_end; for ( path_start = PATH;; path_start = path_end + 1 ) { /* look for non-empty directory */ path_end = strchr ( path_start, ':' ); if ( path_start != path_end && path_start [ 0 ] != 0 ) { rc_t rc2; uint32_t path_type; /* handle last element in list */ if ( path_end == NULL ) last_slash = path_start + strlen ( path_start ); else for ( last_slash = path_end; last_slash > path_start; -- last_slash ) { if ( last_slash [ -1 ] != '/' ) break; } /* create possible path, using up to ':' */ rc2 = string_printf ( thanks_for_brilliant_APIs, sizeof thanks_for_brilliant_APIs, NULL, "%.*s/%s", ( int ) ( last_slash - path_start ), path_start, dli_fname ); /* if failed to create path string */ if ( rc2 != 0 ) break; /* check path against working directory */ path_type = KDirectoryPathType ( wd, thanks_for_brilliant_APIs ); if ( ( path_type & ~ kptAlias ) == kptFile ) { uint32_t access = 0; rc = KDirectoryAccess ( wd, & access, thanks_for_brilliant_APIs ); if ( rc != 0 ) break; /* try to do a quick check that the file can be executed. but it could fail to do the right guess. */ if ( access & 0100 || access & 0010 || access & 0001 ) { /* this is a file, which can be assumed to be an executable */ dli_fname = thanks_for_brilliant_APIs; last_slash = & thanks_for_brilliant_APIs [ last_slash - path_start ]; rc = 0; break; } } } /* exit if no more paths */ if ( path_end == NULL ) break; } } } if ( rc == 0 ) { char real [ PATH_MAX ]; rc = KSysDirRealPath ( sdir, real, sizeof real, "%.*s" , ( int ) ( last_slash - dli_fname ), dli_fname ); if ( rc == 0 ) rc = KDirectoryOpenDirRead ( wd, dir, false, real ); DBGMSG(DBG_KFS, DBG_FLAG(DBG_KFS_DIR), ("%s: %R path is '%s'\n", __func__, rc, real)); } } KDirectoryRelease ( wd ); } } } } return rc; }