static rc_t open_file_as_dir (const char * path, const KDirectory ** dir) { rc_t rc; KPathType kpt; const KDirectory * d; rc = 0; kpt = KDirectoryPathType (kdir, path); switch (kpt & ~kptAlias) { case kptNotFound: rc = RC (rcExe, rcNoTarg, rcParsing, rcParam, rcNotFound); PLOGERR (klogFatal, (klogFatal, rc, "Archive [$(A)] must exist", PLOG_S(A), path)); return rc; case kptDir: default: rc = RC (rcExe, rcNoTarg, rcParsing, rcParam, rcInvalid); PLOGERR (klogFatal, (klogFatal, rc, "Archive [$(A)] must be a file", PLOG_S(A), path)); return rc; case kptFile: break; } if (rc == 0) { STSMSG (1, ("Opening %s\n", path)); rc = KDirectoryOpenArcDirRead (kdir, &d, /*chroot*/false, path, tocKFile, KArcParseSRA, /*filter*/pnamesFilter, /*filt.param*/NULL); *dir = (rc == 0) ? d : NULL; } 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; }