static rc_t CC scan_mod_dir(const KDirectory* dir, uint32_t type, const char* name, void* data) { rc_t rc = 0; const char ext[] = SHLX; assert(data); if (strlen(name) > strlen(ext) + 1 && name[strlen(name) - strlen(ext) - 1] == '.') { char buf[PATH_MAX + 1]; rc = KDirectoryResolvePath (dir, true, buf, sizeof buf, "%s/%s", data, name); while (rc == 0) { uint32_t type = KDirectoryPathType(dir, buf); if (type & kptAlias) { rc = KDirectoryResolveAlias (dir, true, buf, sizeof buf, buf); DISP_RC(rc, name); } else if (rc == 0) { if (type == kptNotFound || type == kptBadPath) { OUTMSG(("%s: %s\n", buf, type == kptNotFound ? "not found" : "bad path")); } else { OUTMSG(("%s\n", buf)); } break; } } } return rc; }
rc_t CopyDirectoryFiles( const KDirectory *source, KDirectory *dest ) { rc_t rc; KNamelist *list; const char *name; int i; uint32_t count; char resolved[1024]; rc = KDirectoryList( source, &list, PathIsFile, NULL, "."); if (rc != 0) { /* This doesn't do what I thought. */ KDirectoryResolvePath( source, false, resolved, 1024, "."); LOGERR ( klogInt, rc, resolved ); return rc; } KNamelistCount(list, &count); for (i=0; i<count; i++) { KNamelistGet(list, i, &name); if (test) { fprintf(stderr, "Will copy %s\n", name); } else { CopyFileToFile( source, name, dest, (char *)name ); } } return 0; }
LIB_EXPORT rc_t CC KLoaderFile_ResolveName(const KLoaderFile *self, char *resolved, size_t rsize) { if( self == NULL || resolved == NULL ) { return RC(rcApp, rcFile, rcAccessing, rcParam, rcNull); } return KDirectoryResolvePath(self->dir, true, resolved, rsize, "%s", self->realname); }
static rc_t ref_seq_load_main( const p_context ctx ) { KDirectory *dir; rc_t rc = KDirectoryNativeDir( &dir ); if ( rc != 0 ) { LOGERR( klogErr, rc, "ref_seq_load_main:KDirectoryNativeDir() failed" ); } else { VDBManager *mgr; rc = VDBManagerMakeUpdate ( &mgr, dir ); if ( rc != 0 ) { LOGERR( klogErr, rc, "ref_seq_load_main:VDBManagerMakeRead() failed" ); } else { rc = prepare_load( dir, ctx ); if ( rc != 0 ) { LOGERR( klogInt, rc, "ref_seq_load_main:prepare_load() failed" ); } else { char tblpath[ 4096 ]; rc = KDirectoryResolvePath( dir, true, tblpath, sizeof tblpath, ctx->dst_path ); if ( rc != 0 ) { LOGERR( klogErr, rc, "ref_seq_load_main:KDirectoryResolvePath() failed" ); } else { KPathType type = VDBManagerPathType( mgr, tblpath ); if ( type != kptNotFound ) { rc = RC( rcExe, rcDatabase, rcCreating, rcFile, rcExists ); PLOGERR( klogErr, ( klogErr, rc, "$(path)", "path=%s", tblpath ) ); } } } if ( rc == 0 ) { rc = perform_load( ctx, dir, mgr ); /* <====================== */ if ( rc != 0 ) { remove_path( dir, ctx->dst_path, ctx->quiet ); } } VDBManagerRelease( mgr ); } KDirectoryRelease( dir ); } return rc; }
/* you cannot addref to this dir object cause it's created on stack silently */ static rc_t CC DirVisitor(const KDirectory *dir, uint32_t type, const char *name, void *data) { rc_t rc = 0; DirVisit_Data* d = (DirVisit_Data*)data; if( (type & ~kptAlias) == kptFile ) { if (strcmp(&name[strlen(name) - 4], ".tsv") == 0 || strcmp(&name[strlen(name) - 8], ".tsv.bz2") == 0 || strcmp(&name[strlen(name) - 7], ".tsv.gz") == 0) { char buf[4096]; const CGLoaderFile* file; FGroupKey key; if( (rc = KDirectoryResolvePath(dir, true, buf, sizeof(buf), name)) == 0 && (rc = CGLoaderFile_Make(&file, d->dir, buf, NULL, !d->param->no_read_ahead)) == 0 && (rc = FGroupKey_Make(&key, file, d->param)) == 0 ) { FGroupMAP* found = (FGroupMAP*)BSTreeFind(d->tree, &key, FGroupMAP_Cmp); DEBUG_MSG(5, ("file %s recognized\n", name)); if( found != NULL ) { rc = FGroupMAP_Set(found, file); } else { FGroupMAP* x = calloc(1, sizeof(*x)); if( x == NULL ) { rc = RC(rcExe, rcFile, rcInserting, rcMemory, rcExhausted); } else { memcpy(&x->key, &key, sizeof(key)); if( (rc = FGroupMAP_Set(x, file)) == 0 ) { rc = BSTreeInsertUnique(d->tree, &x->dad, NULL, FGroupMAP_Sort); } } } } else if( GetRCObject(rc) == rcItem && GetRCState(rc) == rcIgnored ) { DEBUG_MSG(5, ("file %s ignored\n", name)); rc = CGLoaderFile_Release(file, true); file = NULL; } if( rc != 0 && file != NULL ) { CGLoaderFile_LOG(file, klogErr, rc, NULL, NULL); CGLoaderFile_Release(file, true); } } else if( strcmp(&name[strlen(name) - 4], ".tar") == 0 ) { const KDirectory* tmp = d->dir; if( (rc = KDirectoryOpenArcDirRead(dir, &d->dir, true, name, tocKFile, KArcParseTAR, NULL, NULL)) == 0 ) { rc = KDirectoryVisit(d->dir, true, DirVisitor, d, "."); KDirectoryRelease(d->dir); } d->dir = tmp; } } return rc; }
rc_t Initialize(unsigned int sra_sync, const char* xml_path, const char* cache_dir, const char* heart_beat_url, unsigned int xml_sync, const char* xml_root, uint32_t block_size) { rc_t rc = 0; KDirectory* dir = NULL; if( (rc = KDirectoryNativeDir(&dir)) == 0 ) { char buf[4096]; if( (rc = KDirectoryResolvePath(dir, true, buf, 4096, xml_root)) == 0 ) { /* replace /. at the end to just / */ if( strcmp(&buf[strlen(buf) - 2], "/.") == 0 ) { buf[strlen(buf) - 1] = '\0'; } /* add / to the end if missing */ if( buf[strlen(buf) - 1] != '/' ) { buf[strlen(buf) + 1] = '\0'; buf[strlen(buf)] = '/'; } if( (rc = StrDup(buf, &g_work_dir)) == 0 ) { DEBUG_MSG(8, ("Current directory set to '%s'\n", g_work_dir)); } } if ( rc == 0 ) { rc = RemoteCacheInitialize ( cache_dir ); if ( rc == 0 ) { RemoteCacheSetHttpBlockSize ( block_size ); if ( IsLocalPath ( xml_path ) ) { KDirectoryResolvePath(dir, true, buf, 4096, xml_path); rc = XML_Make(dir, g_work_dir, buf, heart_beat_url, xml_sync); } else { rc = XML_Make(dir, g_work_dir, xml_path, heart_beat_url, xml_sync); } } } ReleaseComplain(KDirectoryRelease, dir); } return rc; }
rc_t CC ReportCWD ( const ReportFuncs *f, uint32_t indent ) { KDirectory *wd; rc_t rc = KDirectoryNativeDir ( & wd ); if ( rc != 0 ) reportError(indent, rc, "KDirectoryNativeDir"); else { char cwd [ PATH_MAX + 1 ]; rc = KDirectoryResolvePath ( wd, true, cwd, sizeof cwd, "." ); KDirectoryRelease ( wd ); if ( rc != 0 ) reportError(indent, rc, "KDirectoryResolvePath"); else reportData(indent, "Cwd", cwd, 0); } return rc; }
static rc_t pacbio_extract_path( const KDirectory *dir, const char *schema_name, char * dst, size_t dst_len ) { rc_t rc = KDirectoryResolvePath ( dir, true, dst, dst_len, schema_name ); if ( rc != 0 ) PLOGERR( klogErr, ( klogErr, rc, "cannot resolve path to schema-file '$(name)'", "name=%s", schema_name )); else { char *ptr = strrchr ( dst, '/' ); if ( ptr == 0 ) { rc = RC( rcExe, rcNoTarg, rcAllocating, rcParam, rcInvalid ); PLOGERR( klogErr, ( klogErr, rc, "cannot extract the path of '$(name)'", "name=%s", schema_name )); } else *ptr = 0; } return rc; }
rc_t XML_Make(KDirectory* dir, const char* const work_dir, const char* xml_path, unsigned int sync, uint32_t xml_validate) { rc_t rc = 0; g_xml_sync = sync; if( g_xmlmgr == NULL && (rc = KXMLMgrMakeRead(&g_xmlmgr)) != 0 ) { g_xmlmgr = NULL; LOGERR(klogErr, rc, "XML manager"); } else { char buf[4096]; if( (rc = KDirectoryResolvePath(dir, true, buf, 4096, "%s", xml_path)) == 0 ) { if( (rc = StrDup(buf, &g_xml_path)) == 0 ) { DEBUG_MSG(8, ("XML path set to '%s'\n", g_xml_path)); } } g_start_dir = work_dir; g_xml_validate = xml_validate; } if( rc == 0 ) { rc = FSNode_Make((FSNode**)&g_root, "ROOT", &RootNode_vtbl); } return rc; }
static rc_t run_kar_create(const char * archive, const char * directory) { rc_t rc; const KFile * fin; KFile * fout; rc = open_out_file (archive, &fout); if (rc == 0) { char * directorystr; rc = derive_directory_name (&directorystr, archive, directory); if (rc != 0) LOGERR (klogErr, rc,"failed to derive directory name"); else { assert (directorystr != NULL); assert (directorystr[0] != '\0'); STSMSG (4, ("start creation of archive")); /* Jira ticket: SRA-1876 Date: September 13, 2013 raw usage of "directorystr" causes tests to fail within libs/kfs/arc.c */ { char full [ 4096 ]; rc = KDirectoryResolvePath ( kdir, true, full, sizeof full, "%s", directorystr ); if ( rc == 0 ) { /* string should be non-empty based upon behavior of "derive_directory_name" ( also fixed today ) */ assert ( full [ 0 ] != 0 ); /* eliminate double-slashes */ if ( full [ 1 ] != 0 ) { uint32_t i, j; /* ALLOW double slashes at the very start set starting index to 2 for that reason */ for ( i = j = 2; full [ i ] != 0; ++ i ) { if ( ( full [ j ] = full [ i ] ) != '/' || full [ j - 1 ] != '/' ) ++ j; } full [ j ] = 0; } rc = open_dir_as_archive ( full, & fin ); } } if (rc != 0) PLOGERR (klogErr, (klogErr, rc,"failed to open directory '$(D)' as archive", PLOG_S(D),directorystr)); else { assert (fin != NULL); assert (fout != NULL); STSMSG (4, ("start copy_file")); rc = copy_file (fin, fout); if (rc != 0) LOGERR (klogErr, rc, "failed copy file in create"); KFileRelease (fin); } } KFileRelease (fout); free (directorystr); if (rc) { remove_out_file (archive); } } return rc; }
rc_t KU64IndexPersist_v3(KU64Index_v3* self, bool proj, KDirectory *dir, const char *path, bool use_md5) { KU64Index_PersistData pd; char tmpname[256]; char tmpmd5name[256]; char md5path[256]; self->rc = 0; memset(&pd, 0, sizeof(KU64Index_PersistData)); self->rc = KDirectoryResolvePath(dir, false, tmpname, sizeof(tmpname), "%s.tmp", path); if( self->rc == 0 ) { self->rc = KDirectoryCreateFile(dir, &pd.file, true, 0664, kcmInit, "%s", tmpname); if(use_md5 && self->rc == 0 ) { KMD5SumFmt *km = NULL; size_t tmplen = snprintf(tmpmd5name, sizeof(tmpmd5name), "%s.md5", tmpname); KFile* kf = NULL; if( tmplen >= sizeof(tmpmd5name) ) { self->rc = RC(rcDB, rcIndex, rcPersisting, rcName, rcExcessive); } else { tmplen = snprintf(md5path, sizeof(md5path), "%s.md5", path); if( tmplen >= sizeof(md5path) ) { self->rc = RC(rcDB, rcIndex, rcPersisting, rcName, rcExcessive); } else { self->rc = KDirectoryCreateFile(dir, &kf, true, 0664, kcmInit, "%s", tmpmd5name); if( self->rc == 0 ) { self->rc = KMD5SumFmtMakeUpdate(&km, kf); if( self->rc == 0 ) { KMD5File * k5f; kf = NULL; self->rc = KMD5FileMakeWrite(&k5f, pd.file, km, path); if( self->rc == 0 ) { pd.file_md5 = k5f; pd.file = KMD5FileToKFile(k5f); } /* release pass or fail */ KMD5SumFmtRelease(km); } else { KFileRelease ( kf ); } } else { KFileRelease ( kf ); } } } if( self->rc != 0 ) { KFileRelease(pd.file); } } if( self->rc == 0 ) { struct KIndexFileHeader_v3 head; size_t writ = 0; KDBHdrInit(&head.h, 3); head.index_type = kitU64; self->rc = KFileWrite(pd.file, pd.pos, &head, sizeof(struct KIndexFileHeader_v3), &writ); if( self->rc == 0 ) { pd.pos += writ; if( use_md5 ) { KMD5FileBeginTransaction(pd.file_md5); } self->rc = BSTreePersist(&self->tree, NULL, KU64Index_WriteFunc, &pd, KU64Index_AuxFunc, &pd); } KFileRelease(pd.file); pd.file = NULL; } } if( self->rc == 0 ) { self->rc = KDirectoryRename(dir, false, tmpname, path); if( self->rc == 0 ) { if ( use_md5 ) { self->rc = KDirectoryRename(dir, false, tmpmd5name, md5path); } if( self->rc == 0 ) { /* done */ return 0; } } } /* whack temporary file */ KDirectoryRemove(dir, false, "%s", tmpname); if( use_md5 ) { KDirectoryRemove(dir, false, "%s", tmpmd5name); } return self->rc; }
static rc_t TarNode_MakeFileList(const KXMLNode* xml_node, const TarFileList** files, char* errmsg, const char* rel_path, const char* name) { rc_t rc = 0; time_t now = time(NULL); uint32_t count = 0; *files = NULL; if( (rc = KXMLNodeCountChildNodes(xml_node, &count)) == 0 ) { if( count == 0 ) { rc = RC(rcExe, rcDoc, rcValidating, rcData, rcEmpty); } else if( (rc = TarFileList_Make(files, count, name)) == 0 ) { uint32_t i = 0; while(rc == 0 && i < count) { const KXMLNode* n = NULL; const char* n_name; if( (rc = KXMLNodeGetNodeRead(xml_node, &n, i++)) == 0 && (rc = KXMLNodeElementName(n, &n_name)) == 0 ) { if( strcmp(n_name, "Item") != 0 ) { rc = RC(rcExe, rcDoc, rcValidating, rcNode, rcUnexpected); strcpy(errmsg, n_name); } else { size_t sz_read; char path[4096], name[4096]; KTime_t ts = now; uint64_t fsz = 0; bool exec = false; if( (rc = KXMLNodeReadAttrCString(n, "path", name, sizeof(name), &sz_read)) == 0 ) { if( name[0] == '\0' ) { rc = RC(rcExe, rcDoc, rcValidating, rcAttr, rcEmpty); } else if( name[0] == '/' ) { memmove(path, name, sz_read + 1); } else { KDirectory* dir = NULL; if( (rc = KDirectoryNativeDir(&dir)) == 0 && (rc = KDirectoryResolvePath(dir, true, path, sizeof(path), "%s/%s", rel_path, name)) == 0 ) { DEBUG_LINE(8, "%s/%s resolved to %s", rel_path, name, path); } KDirectoryRelease(dir); } if( rc != 0 ) { strcpy(errmsg, "TAR/Item/@path"); } } if( rc == 0 && (rc = XML_ParseTimestamp(n, "timestamp", &ts, true)) != 0 ) { strcpy(errmsg, "TAR/Item/@timestamp"); } if( rc == 0 && (rc = XML_ParseBool(n, "executable", &exec, true)) != 0 ) { strcpy(errmsg, "TAR/Item/@executable"); } if( rc == 0 && (rc = KXMLNodeReadAttrAsU64(n, "size", &fsz)) != 0 ) { strcpy(errmsg, "TAR/Item/@size"); } if( rc == 0 ) { name[0] = '\0'; rc = KXMLNodeReadAttrCString(n, "name", name, sizeof(name), &sz_read); if( (GetRCObject(rc) == (enum RCObject)rcAttr && GetRCState(rc) == rcNotFound) || name[0] == '\0' ) { char* x = strrchr(path, '/'); strcpy(name, x ? x + 1 : path); rc = 0; } else if( rc == 0 && name[0] == '/' ) { strcat(errmsg, "Item/@name cannot be absolute"); rc = RC(rcExe, rcDoc, rcValidating, rcName, rcInvalid); } else if( rc != 0 ) { strcpy(errmsg, "Item/@name"); } } if( rc == 0 ) { const KNamelist* attr = NULL; if( (rc = KXMLNodeListAttr(n, &attr)) == 0 ) { uint32_t j = 0, count = 0; if( (rc = KNamelistCount(attr, &count)) == 0 && count > 0 ) { while( rc == 0 && j < count ) { const char *attr_nm = NULL; if( (rc = KNamelistGet(attr, j++, &attr_nm)) != 0 ) { break; } if( strcmp("path", attr_nm) == 0 || strcmp("name", attr_nm) == 0 || strcmp("timestamp", attr_nm) == 0 || strcmp("size", attr_nm) == 0 || strcmp("executable", attr_nm) == 0 ) { continue; } rc = RC(rcExe, rcDoc, rcValidating, rcDirEntry, rcInvalid); strcpy(errmsg, "unknown attribute TAR/Item/@"); strcat(errmsg, attr_nm); } } ReleaseComplain(KNamelistRelease, attr); } } if( rc == 0 && (rc = TarFileList_Add(*files, path, name, fsz, ts, exec)) != 0 ) { strcpy(errmsg, "adding to TAR"); } } ReleaseComplain(KXMLNodeRelease, n); } } if( rc != 0 ) { TarFileList_Release(*files); *files = NULL; } } } return rc; }
static rc_t ReportBinary(const ReportFuncs *f, uint32_t indent, const char* argv0) { rc_t rc = 0; KDyld *dyld = NULL; assert(argv0); rc = KDyldMake(&dyld); if (rc != 0) { reportError(indent + 1, rc, "KDyldMake"); } else { const KDirectory* dir = NULL; rc = KDyldHomeDirectory(dyld, &dir, (fptr_t) ReportFinalize); if (rc != 0) { reportError(indent + 1, rc, "KDyldHomeDirectory"); } else { char binary[PATH_MAX + 1]; const char* name = strpbrk(argv0, "/\\"); const char* last_name = name; if (last_name) { ++last_name; } while (name) { name = strpbrk(last_name, "/\\"); if (name) { last_name = name; if (last_name) { ++last_name; } } } name = last_name ? last_name : argv0; rc = KDirectoryResolvePath(dir, true, binary, sizeof binary, "%s", name); if (rc != 0) { reportErrorStr(indent + 1, rc, "KDirectoryResolvePath", "origin", "KDyldHomeDirectory"); } else { bool found = false; const char tag[] = "Binary"; const char* sType = NULL; uint8_t digest[16]; uint32_t type = KDirectoryPathType(dir, "%s", binary); switch (type & ~kptAlias) { case kptFile: sType = type & kptAlias ? "alias" : "file"; found = true; break; case kptNotFound: sType = "not found"; break; default: sType = "unknown"; break; } if (found) { rc = md5(name, digest, dir); } if (type & kptAlias) { if (found && rc == 0) { reportOpen(indent, tag, 3, "path", 's', binary, "type", 's', sType, "md5", 'M', digest); } else { reportOpen(indent, tag, 2, "path", 's', binary, "type", 's', sType); } if (rc == 0 && type & kptAlias) { rc = ReportAlias(f, indent + 1, name, dir); } reportClose(indent, tag); } else { if (found && rc == 0) { report(indent, tag, 3, "path", 's', binary, "type", 's', sType, "md5", 'M', digest); } else { report(indent, tag, 2, "path", 's', binary, "type", 's', sType); } } } } RELEASE(KDirectory, dir); } RELEASE(KDyld, dyld); return rc; }
/* KMain */ rc_t CC KMain ( int argc, char *argv [] ) { Args * args; rc_t rc; rc = ArgsMakeAndHandle (&args, argc, argv, 0); if (rc) LOGERR (klogInt, rc, "failed to parse arguments"); else do { uint32_t acount; rc = ArgsParamCount (args, &acount); if (rc) { LOGERR (klogInt, rc, "failed to count parameters"); break; } if (acount == 0) { rc = MiniUsage (args); break; } else { VFSManager* mgr; rc = VFSManagerMake(&mgr); if (rc) LOGERR ( klogErr, rc, "failed to create VFSManager object" ); else { VResolver * resolver; rc = VFSManagerGetResolver (mgr, &resolver); if (rc == 0) { uint32_t ix; for ( ix = 0; ix < acount; ++ ix ) { const char * pc; rc = ArgsParamValue (args, ix, &pc ); if (rc) LOGERR (klogInt, rc, "failed to retrieve parameter value"); else { const VPath * upath = NULL; rc = VFSManagerMakePath ( mgr, (VPath**)&upath, "%s", pc); if (rc == 0) { const VPath * local; const VPath * remote; rc = VResolverQuery (resolver, eProtocolHttp, upath, &local, &remote, NULL); if (rc == 0) { const String * s; if (local != NULL) rc = VPathMakeString (local, &s); else rc = VPathMakeString (remote, &s); if (rc == 0) { OUTMSG (("%S\n", s)); free ((void*)s); } VPathRelease (local); VPathRelease (remote); } else { KDirectory * cwd; rc_t orc = VFSManagerGetCWD (mgr, &cwd); if (orc == 0) { KPathType kpt = KDirectoryPathType(cwd, "%s", pc); switch (kpt &= ~kptAlias) { case kptNotFound: STSMSG(1, ("'%s': not found while " "searching the file system", pc)); break; case kptBadPath: STSMSG(1, ("'%s': bad path while " "searching the file system", pc)); break; default: STSMSG(1, ("'%s': " "found in the file system", pc)); rc = 0; break; } } if (orc == 0 && rc == 0) { if (rc != 0) { PLOGMSG(klogErr, (klogErr, "'$(name)': not found", "name=%s", pc)); } else { char resolved[PATH_MAX] = ""; rc = KDirectoryResolvePath(cwd, true, resolved, sizeof resolved, "%s", pc); if (rc == 0) { STSMSG(1, ("'%s': found in " "the current directory at '%s'", pc, resolved)); OUTMSG (("%s\n", resolved)); } else { STSMSG(1, ("'%s': cannot resolve " "in the current directory", pc)); OUTMSG (("./%s\n", pc)); } } } KDirectoryRelease(cwd); } } RELEASE(VPath, upath); } } VResolverRelease (resolver); } VFSManagerRelease(mgr); } } ArgsWhack (args); } while (0); 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 FileInPlace (KDirectory * cwd, const char * leaf, bool try_rename) { rc_t rc; bool is_tmp; STSMSG (1, ("%scrypting file in place %s",De,leaf)); rc = 0; is_tmp = IsTmpFile (leaf); if (is_tmp) { STSMSG (1, ("%s is a vdb-decrypt/vdb-encrypt temporary file and will " "be ignored", leaf)); TmpFoundFlag = true; if (ForceFlag) ; /* LOG OVERWRITE */ else ; /* LOG TMP */ } if (!is_tmp || ForceFlag) { char temp [MY_MAX_PATH]; rc = KDirectoryResolvePath (cwd, false, temp, sizeof temp, ".%s%s", leaf, TmpExt); if (rc) PLOGERR (klogErr, (klogErr, rc, "unable to resolve '.$(S)$(E)'", "S=%s,E=%s",leaf,TmpExt)); else { KPathType kpt; uint32_t kcm; kcm = kcmCreate|kcmParents; kpt = KDirectoryPathType (cwd, temp); if (kpt != kptNotFound) { /* log busy */ if (ForceFlag) { kcm = kcmInit|kcmParents; /* log force */ kpt = kptNotFound; } } if (kpt == kptNotFound) { const KFile * infile; rc = KDirectoryOpenFileRead (cwd, &infile, "%s", leaf); if (rc) PLOGERR (klogErr, (klogErr, rc, "Unable to resolve '$(F)'", "F=%s",leaf)); else { EncScheme scheme; rc = EncryptionTypeCheck (infile, leaf, &scheme); if (rc == 0) { ArcScheme ascheme; bool changed; bool do_this_file; char new_name [MY_MAX_PATH + sizeof EncExt]; do_this_file = DoThisFile (infile, scheme, &ascheme); strcpy (new_name, leaf); if (try_rename) changed = NameFixUp (new_name); else changed = false; /* KOutMsg ("### %d \n", changed); */ if (!do_this_file) { if (changed) { STSMSG (1, ("renaming %s to %s", leaf, new_name)); rc = KDirectoryRename (cwd, false, leaf, new_name); } else STSMSG (1, ("skipping %s",leaf)); } else { KFile * outfile; rc = KDirectoryCreateExclusiveAccessFile (cwd, &outfile, false, 0600, kcm, temp); if (rc) ; else { const KFile * Infile; KFile * Outfile; rc = CryptFile (infile, &Infile, outfile, &Outfile, scheme); if (rc == 0) { STSMSG (1, ("copying %s to %s", leaf, temp)); rc = CopyFile (Infile, Outfile, leaf, temp); if (rc == 0) { uint32_t access; KTime_t date; rc = KDirectoryAccess (cwd, &access, "%s", leaf); if (rc == 0) rc = KDirectoryDate (cwd, &date, "%s", leaf); KFileRelease (infile); KFileRelease (outfile); KFileRelease (Infile); KFileRelease (Outfile); if (rc == 0) { STSMSG (1, ("renaming %s to %s", temp, new_name)); rc = KDirectoryRename (cwd, true, temp, new_name); if (rc) LOGERR (klogErr, rc, "error renaming"); else { if (changed) KDirectoryRemove (cwd, false, "%s", leaf); /*rc =*/ KDirectorySetAccess (cwd, false, access, 0777, "%s", new_name); KDirectorySetDate (cwd, false, date, "%s", new_name); /* gonna ignore an error here I think */ return rc; } } } } KFileRelease (outfile); } } } KFileRelease (infile); } } } } return rc; }
static rc_t foreach_path_obj( visit_ctx * ctx, on_path_t func ) { rc_t rc = 0; ctx->path_type = ( KDirectoryPathType ( ctx->dir, "%s", ctx->path ) & ~ kptAlias ); if ( ctx->path_type == kptDir ) { KNamelist * path_objects; rc = KDirectoryList ( ctx->dir, &path_objects, NULL, NULL, "%s", ctx->path ); if ( rc != 0 ) { PLOGERR( klogErr, ( klogErr, rc, "KDirectoryList( $(path) ) failed in $(func)", "path=%s,func=%s", ctx->path, __func__ ) ); } else { uint32_t idx, count; rc = KNamelistCount ( path_objects, &count ); if ( rc != 0 ) { PLOGERR( klogErr, ( klogErr, rc, "KNamelistCount() failed in $(func)", "func=%s", __func__ ) ); } for ( idx = 0; idx < count && rc == 0 && !ctx->terminate; ++idx ) { const char * obj_name = NULL; rc = KNamelistGet ( path_objects, idx, &obj_name ); if ( rc != 0 ) { PLOGERR( klogErr, ( klogErr, rc, "KNamelistGet( $(idx) ) failed in $(func)", "idx=%d,func=%s", idx, __func__ ) ); } else if ( obj_name != NULL ) { char obj_path[ 4096 ]; rc = KDirectoryResolvePath ( ctx->dir, true, obj_path, sizeof obj_path, "%s/%s", ctx->path, obj_name ); if ( rc != 0 ) { PLOGERR( klogErr, ( klogErr, rc, "KDirectoryResolvePath( $(path) ) failed in $(func)", "path=%s,func=%s", ctx->path, __func__ ) ); } else { visit_ctx octx; octx.dir = ctx->dir; octx.options = ctx->options; octx.path = obj_path; octx.data = ctx->data; octx.path_type = ( KDirectoryPathType ( ctx->dir, "%s", obj_path ) & ~ kptAlias ); if ( octx.path_type == kptDir ) { rc = foreach_path_obj( &octx, func ); /* recursion !!! */ } else if ( octx.path_type == kptFile ) { rc = func( &octx ); } } } } { rc_t rc2 = KNamelistRelease ( path_objects ); if ( rc2 != 0 ) { PLOGERR( klogErr, ( klogErr, rc2, "KNamelistRelease() failed in $(func)", "func=%s", __func__ ) ); } } } } if ( rc == 0 && ( ctx->path_type == kptDir || ctx->path_type == kptFile ) && !ctx->terminate ) { /* at the very end of it, call the function for the path itself */ rc = func( ctx ); } return rc; }
static rc_t run() { KDirectory * pwd; const KDirectory * xfs; const KFile * xml; rc_t rc; STSMSG (1, ("Open file system\n")); rc = KDirectoryNativeDir (&pwd); if (rc) LOGERR (klogErr, rc, "Failed to open filesystem"); else { STSMSG (1, ("Open file %s\n", XML)); rc = KDirectoryOpenFileRead (pwd, &xml, XML); if (rc) LOGERR (klogErr, rc, "failed to open xml file"); else { STSMSG (1, ("Open chrooted as XML TOC %s\n", BASE)); rc = KDirectoryOpenXTocDirRead (pwd, &xfs, true, xml, BASE); if (rc) LOGERR (klogErr, rc, "Failed to open xfs directory"); else { size_t pz; char path [8192]; rc = KDirectoryResolvePath (xfs, false, path, sizeof path, INNER_FILE1); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, false, path, sizeof path, INNER_FILE2); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, true, path, sizeof path, INNER_FILE1); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, true, path, sizeof path, INNER_FILE2); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); } } } } KDirectoryRelease (xfs); } if (rc == 0) { STSMSG (1, ("Open as XML TOC %s\n", BASE)); rc = KDirectoryOpenXTocDirRead (pwd, &xfs, false, xml, BASE); if (rc) LOGERR (klogErr, rc, "Failed to open xfs directory"); else { size_t pz; char path [8192]; rc = KDirectoryResolvePath (xfs, false, path, sizeof path, INNER_FILE1); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, false, path, sizeof path, INNER_FILE2); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, true, path, sizeof path, INNER_FILE1); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); rc = KDirectoryResolvePath (xfs, true, path, sizeof path, INNER_FILE2); if (rc == 0) { OUTMSG (("path is '%s'\n", path)); } } } } KDirectoryRelease (xfs); } } KFileRelease (xml); } KDirectoryRelease (pwd); } return rc; }
/* filter will let us add the add to and extract by name things to kar */ static rc_t step_through_dir (const KDirectory * dir, const char * path, rc_t (*action)(const KDirectory *, const char *, void *), void * adata) { rc_t rc; KNamelist * names; STSMSG (4, ("step_through_dir %s\n", path)); rc = KDirectoryList (dir, &names, NULL, NULL, "%s", path); if (rc == 0) { uint32_t limit; rc = KNamelistCount (names, &limit); if (rc == 0) { uint32_t idx; size_t pathlen; pathlen = strlen(path); for (idx = 0; (rc == 0) && (idx < limit); idx ++) { const char * name; rc = KNamelistGet (names, idx, &name); if (rc == 0) { size_t namelen = strlen (name); size_t new_pathlen = pathlen + 1 + namelen; char * new_path = malloc (new_pathlen + 1); if (new_path != NULL) { char * recur_path; if (pathlen == 0) { memmove (new_path, name, namelen); new_path[namelen] = '\0'; } else { memmove (new_path, path, pathlen); new_path[pathlen] = '/'; memmove (new_path + pathlen + 1, name, namelen); new_path[pathlen+1+namelen] = '\0'; } recur_path = malloc (pathlen + 1 + namelen + 1); if (recur_path != NULL) { rc = KDirectoryResolvePath (dir, false, recur_path, pathlen + 1 + namelen + 1, "%s", new_path); if (rc == 0) rc = action (dir, recur_path, adata); free (recur_path); } free (new_path); } } } } KNamelistRelease (names); } return rc; }