static rc_t cg_dump_create_output_dir( cg_dump_ctx * cg_ctx ) { rc_t rc = KDirectoryCreateDir ( cg_ctx->dir, 0775, ( kcmCreate | kcmParents ), "%s", cg_ctx->dst ); if ( rc != 0 ) { (void)PLOGERR( klogErr, ( klogErr, rc, "cannot create directory '$(dir)'", "dir=%s", cg_ctx->dst ) ); } 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; }
LIB_EXPORT rc_t CC KDatabaseVCreateDB ( KDatabase *self, KDatabase **dbp, KCreateMode cmode, const char *name, va_list args ) { rc_t rc; char path [ 256 ]; if ( dbp == NULL ) return RC ( rcDB, rcDatabase, rcCreating, rcParam, rcNull ); * dbp = NULL; if ( self == NULL ) return RC ( rcDB, rcDatabase, rcCreating, rcSelf, rcNull ); if ( self -> read_only ) return RC ( rcDB, rcDatabase, rcCreating, rcDatabase, rcReadonly ); rc = KDBVMakeSubPath ( self -> dir, path, sizeof path, "db", 2, name, args ); if ( rc == 0 ) { /* ensure that the "db" namespace directory is there */ rc = KDirectoryCreateDir ( self -> dir, 0775, kcmOpen, "db" ); if ( rc == 0 ) { rc = KDBManagerVCreateDBInt ( self -> mgr, dbp, self -> dir, cmode, path, NULL ); if ( rc == 0 ) { KDatabase *db = ( KDatabase* ) * dbp; db -> dad = self; atomic32_inc ( & self -> refcount ); } } } return rc; }
rc_t CopyDirectoryDirectories( const KDirectory *source, KDirectory *dest ) { rc_t rc; KNamelist *list; const char *name; int i; uint32_t count; uint32_t mode; uint32_t pathtype; KDirectoryList( source, &list, PathIsDir, NULL, "."); KNamelistCount(list, &count); for (i=0; i<count; i++) { KNamelistGet(list, i, &name); /* fprintf(stderr, "Creating directory %s\n", name); */ mode = DEFAULT_DIR_MODE; rc = KDirectoryAccess( source, &mode, "%s", name); if (rc != 0) { LOGERR ( klogInt, rc, name ); return rc; } pathtype = KDirectoryPathType( dest, "%s", name ); if ((pathtype & ~kptAlias) == kptNotFound) { rc = KDirectoryCreateDir( dest, mode, kcmOpen, "%s", name ); if (rc != 0) { LOGERR ( klogInt, rc, name ); return rc; } } else if ((pathtype & ~kptAlias) == kptDir) { if (clobber_protections) { KDirectorySetAccess( dest, false, mode, 0777, "%s", name); } } CopyDirectoryToExistingDirectory( source, name, dest, (char *)name); } return 0; }
/* CreateDB * VCreateDB * create a new or open an existing database * * "db" [ OUT ] - return parameter for newly opened database * * "cmode" [ IN ] - creation mode * * "path" [ IN ] - NUL terminated string in * wd-native character set giving path to database */ static rc_t KDBManagerVCreateDBInt ( KDBManager *self, KDatabase **db, KDirectory *wd, KCreateMode cmode, const char *path, va_list args ) { char dbpath [ 4096 ]; rc_t rc = KDirectoryVResolvePath ( wd, true, dbpath, sizeof dbpath, path, args ); if ( rc == 0 ) { /* we won't try accession resolution here */ int type = KDBPathType ( /*NULL,*/ wd, NULL, dbpath ); switch ( type ) { case kptNotFound: /* first good path */ break; case kptBadPath: return RC ( rcDB, rcMgr, rcCreating, rcPath, rcInvalid ); case kptDatabase: case kptDatabase | kptAlias: /* found so is not good if we want to create new and not * clear/init or open old */ if ((cmode & kcmValueMask) == kcmCreate) return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcExists ); if (KDBManagerOpenObjectBusy (self, dbpath)) return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcBusy ); /* test now for locked directory */ rc = KDBWritable ( wd, dbpath ); if (rc) { switch (GetRCState(rc)) { default: return rc; case rcLocked: return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcLocked ); case rcReadonly: return RC ( rcDB, rcMgr, rcCreating, rcDatabase, rcReadonly ); case rcNotFound: /* not found is good but probably unreachable */ break; case 0: rc = 0; break; } } /* second good path */ break; case kptTable: case kptTable | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcTable, rcExists); case kptColumn: case kptColumn | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcColumn, rcExists); case kptIndex: case kptIndex | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcIndex, rcExists); case kptMetadata: case kptMetadata | kptAlias: return RC (rcDB, rcMgr, rcCreating, rcMetadata, rcExists); case kptFile: case kptFile | kptAlias: /* if we find a file, vary the failure if it is an archive that is a database * or a non related file */ if ( KDBOpenPathTypeRead ( self, wd, dbpath, NULL, kptDatabase, NULL, false ) == 0 ) return RC ( rcDB, rcMgr, rcCreating, rcDirectory, rcUnauthorized ); /* fall through */ default: return RC ( rcDB, rcMgr, rcCreating, rcPath, rcIncorrect ); } /* [re]create directory */ rc = KDirectoryCreateDir ( wd, 0775, cmode, "%s", dbpath ); if (rc == 0) /* create tbl subdirectory as required for db */ rc = KDirectoryCreateDir ( wd, 0775, kcmOpen, "%s/tbl", dbpath ); if ( rc == 0 ) { KMD5SumFmt *md5 = NULL; if ( ( cmode & kcmMD5 ) != 0 ) { KFile * f; /* if needed create the md5 digest file */ rc = KDirectoryCreateFile ( wd, &f, true, 0664, kcmOpen, "%s/md5", dbpath ); if ( rc == 0 ) { /* create a formatter around file formatter will own "f" afterward */ rc = KMD5SumFmtMakeUpdate ( & md5, f ); /* if failed to create formatter, release "f" */ if ( rc != 0 ) KFileRelease ( f ); } } if ( rc == 0 ) rc = KDBManagerMakeDBUpdate ( self, db, wd, dbpath, md5 ); KMD5SumFmtRelease ( md5 ); } } 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; }
static rc_t CC extract_action (const KDirectory * dir, const char * path, void * _adata) { rc_t rc; extract_adata * adata; KPathType type; char link [2 * 4096]; /* we'll truncate? */ uint32_t access; rc = 0; adata = _adata; STSMSG (1, ("extract_action: %s\n", path)); type = KDirectoryPathType (dir, path); if (type & kptAlias) { rc = KDirectoryVResolveAlias (dir, false, link, sizeof (link), path, NULL); if (rc == 0) { rc = KDirectoryVAccess (dir, &access, path, NULL); if (rc == 0) { rc = KDirectoryCreateAlias (adata->dir, access, kcmCreate|kcmParents, link, path); } } } else { switch (type & ~kptAlias) { case kptNotFound: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcNotFound); KOutMsg ("%s: %s type kptNotFouns %R\n", __func__, path, rc); break; case kptBadPath: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcInvalid); break; case kptFile: rc = KDirectoryVAccess (dir, &access, path, NULL); if (rc == 0) { const KFile * fin; KFile * fout; rc = KDirectoryVCreateFile (adata->dir, &fout, false, access, kcmCreate|kcmParents, path, NULL); if (rc == 0) { rc = KDirectoryVOpenFileRead (dir, &fin, path, NULL); if (rc == 0) { #if USE_SKEY_MD5_FIX /* KLUDGE!!!! */ size_t pathz, skey_md5z; static const char skey_md5[] = "skey.md5"; pathz = string_size (path); skey_md5z = string_size(skey_md5); if ( pathz >= skey_md5z && strcmp ( & path [ pathz - skey_md5z ], skey_md5 ) == 0 ) rc = copy_file_skey_md5_kludge (fin, fout); else #endif rc = copy_file (fin, fout); KFileRelease (fin); } KFileRelease (fout); } } break; case kptDir: rc = KDirectoryVAccess (dir, &access, path, NULL); if (rc == 0) { rc = KDirectoryCreateDir (adata->dir, 0700, kcmCreate|kcmParents, path, NULL); if (rc == 0) { rc = step_through_dir (dir, path, adata->filter, adata->fdata, extract_action, adata); if (rc == 0) rc = KDirectoryVSetAccess (adata->dir, false, access, 0777, path, NULL); } } break; case kptCharDev: case kptBlockDev: case kptFIFO: /* shouldn't get here */ return 0; } } return rc; }