Example #1
0
int KDBPathType ( const KDirectory *dir, bool *pHasZombies, const char *path )
{
    const char *leaf, *parent;


    rc_t rc;
    int type = KDirectoryPathType ( dir, "%s", path );
    
    if (pHasZombies)
        *pHasZombies = false;

    switch ( type )
    {
    case kptDir:
    case kptDir | kptAlias:
        type = KDBPathTypeDir (dir, type, pHasZombies, path);
        break;

    case kptFile:
    case kptFile | kptAlias:
    {
        /* if we hit a file first try it as an archive */
        const KDirectory * ldir;

        rc = KDirectoryOpenSraArchiveRead_silent ( dir, &ldir, false, "%s", path );
#if SUPPORT_KDB_TAR
        if ( rc != 0 )
            rc = KDirectoryOpenTarArchiveRead_silent ( dir, &ldir, false, "%s", path );
#endif
        /* it was an archive so recur */
        if ( rc == 0 )
        {
            /* recheck this newly opened directory for KDB/KFS type */
            int type2;

            type2 = KDBPathType ( ldir, NULL, "." );
            if ((type2 != kptDir) || (type != (kptDir|kptAlias)))
                type = type2;

            KDirectoryRelease (ldir);
        }
        /* it was not an archive so see if it it's an idx file */
        else
        {
            leaf = strrchr ( path, '/' );
            if ( leaf != NULL )
            {
                parent = string_rchr ( path, leaf - path, '/' );
                if ( parent ++ == NULL )
                    parent = path;
                if ( memcmp ( parent, "idx/", 4 ) == 0 )
                    type += kptIndex - kptFile;
            }
        }
        break;
    }
    }
    return type;
}
Example #2
0
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;
}
Example #3
0
LIB_EXPORT int CC KDBManagerVPathType ( const KDBManager * self, const char *path, va_list args )
{
    if ( self != NULL )
    {
        char full [ 4096 ];
        rc_t rc = KDirectoryVResolvePath ( self -> wd, false, full, sizeof full, path, args );
        if ( rc == 0 )
            return KDBPathType ( /*self,*/ self -> wd, NULL, full );
    }
    return kptBadPath;
}
Example #4
0
LIB_EXPORT rc_t CC KDBManagerVPathOpenRemoteDBRead ( struct KDBManager const * self,
    struct KDatabase const ** p_db, struct VPath const * remote, struct VPath const * cache )
{
    if ( self == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcSelf, rcNull );
    if ( p_db == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcParam, rcNull );
    if ( remote == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcParam, rcNull );
    /* cache == NULL is OK */    
    
    {   
        /*  vpath has already been resolved and is known to be a remote URL. 
            Open it if it is a database; use the provided cache; avoid an additional round of resolution */
        const KDirectory *dir;
        rc_t rc = VFSManagerOpenDirectoryReadDecryptRemote( self -> vfsmgr, &dir, remote, cache );
        if ( rc == 0 )
        {
            if ( ( (~kptAlias) & KDBPathType ( dir, NULL, "." ) ) != kptDatabase )
            {
                rc = RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcIncorrect );
            }
            else
            {
                KDatabase *db;

                /* allocate a new guy */
                rc = KDatabaseMakeVPath ( & db, dir, remote, NULL, true );
                if ( rc == 0 )
                {
                    rc = KDBManagerInsertDatabase ( ( KDBManager* ) self, db );
                    if ( rc == 0 )
                    {
                        * p_db = db;
                        return 0;
                    }
                    free (db);
                }
            }

            KDirectoryRelease ( dir );
        }
        return rc;
    }
}
Example #5
0
LIB_EXPORT rc_t CC KDBManagerVPathOpenLocalDBRead ( struct KDBManager const * self,
    struct KDatabase const ** p_db, struct VPath const * vpath )
{
    if ( self == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcSelf, rcNull );
    if ( p_db == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcParam, rcNull );
    if ( vpath == NULL )
        return RC ( rcDB, rcDatabase, rcAccessing, rcParam, rcNull );
        
    {   
        /* vpath has already been resolved and is known to be a local path. 
           open it if it is a database; avoid an additional round of resolution */
        const KDirectory *dir;
        rc_t rc = VFSManagerOpenDirectoryReadDirectoryRelativeDecrypt ( self -> vfsmgr, self -> wd, &dir, vpath );
        if ( rc == 0 )
        {
            if ( ( (~kptAlias) & KDBPathType ( dir, NULL, "." ) ) != kptDatabase )
            {
                rc = RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcIncorrect );
            }
            else
            {
                KDatabase *db;

                rc = KDatabaseMakeVPath ( & db, dir, vpath, NULL, true );
                if ( rc == 0 )
                {
                    rc = KDBManagerInsertDatabase ( ( KDBManager* ) self, db );
                    if ( rc == 0 )
                    {
                        * p_db = db;
                        return 0;
                    }
                    free (db);
                }
            }

            KDirectoryRelease ( dir );
        }
        return rc;
    }
} 
Example #6
0
/* Writable
 *  returns 0 if object is writable
 *  or a reason why if not
 *
 *  "path" [ IN ] - NUL terminated path
 *
 * TBD: Better reasons for non local paths
 */
static
rc_t KDBManagerWritableInt ( const KDirectory * dir, const char * path )
{
    rc_t rc;

    int type = KDBPathType ( /*NULL,*/ dir, NULL, path ) & ~ kptAlias;
    switch ( type )
    {
    case kptDatabase:
    case kptTable:
    case kptPrereleaseTbl:
    case kptColumn:
        rc = KDBWritable ( dir, path );
        break;

    case kptIndex:
    case kptMetadata:
        /* a wrong database type */
        rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcIncorrect );
        break;
#if 0
        /*TBD - eventually we need to check for an archive here */
    case kptFile: 
        /* check if this is an archive .tar or .sra and return rcReadonly if it is */
#endif
    case kptNotFound:
        rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcNotFound );
        break;
    case kptBadPath:
        rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcInvalid );
        break;
    default:
        rc = RC ( rcDB, rcMgr, rcAccessing, rcPath, rcIncorrect );
    }

    return rc;
}
Example #7
0
/* OpenDBUpdate
 * VOpenDBUpdate
 *  open a database for read/write
 *
 *  "db" [ OUT ] - return parameter for newly opened database
 *
 *  "path" [ IN ] - NUL terminated string in
 *  wd-native character set giving path to database
 */
static
rc_t KDBManagerVOpenDBUpdateInt ( KDBManager *self,
    KDatabase **db, KDirectory *wd, const char *path, va_list args )
{
    char dbpath [ 4096 ];
    rc_t rc = KDirectoryVResolvePath ( wd, true,
        dbpath, sizeof dbpath, path, args );
    if ( rc == 0 )
    {
        KSymbol * sym;
        KFile *f;
        KMD5SumFmt * md5 = NULL;

        /* if already open, refuse */
        sym = KDBManagerOpenObjectFind (self, dbpath);
        if (sym != NULL)
        {
            rc_t obj;
            switch (sym->type)
            {
            default:
                obj = rcPath;
                break;
            case kptDatabase:
                obj = rcDatabase;
                break;
            case kptTable:
                obj = rcTable;
                break;
            case kptColumn:
                obj = rcColumn;
                break;
            case kptIndex:
                obj = rcIndex;
                break;
            case kptMetadata:
                obj = rcMetadata;
                break;
            }
            return RC ( rcDB, rcMgr, rcOpening, obj, rcBusy );
        }
        /* only open existing dbs */
        switch (KDBPathType ( /*self,*/ wd, NULL, dbpath ) )
        {
        case kptNotFound:
            return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcNotFound );
        case kptBadPath:
            return RC ( rcDB, rcMgr, rcOpening, rcPath, rcInvalid );
	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, rcOpening, rcDirectory, rcUnauthorized );
	    /* fall through */
        default:
            return RC ( rcDB, rcMgr, rcOpening, rcPath, rcIncorrect );
        case kptDatabase:
        case kptDatabase | kptAlias:
            break;
        }

        /* test now for locked directory */
        rc = KDBWritable (wd, dbpath);
        switch (GetRCState (rc))
        {
        default:
#if 0
            return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcNoPerm ); /* TBD: better state? */
#endif

        case rcLocked:
            return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcLocked );

        case rcReadonly:
            return RC ( rcDB, rcMgr, rcOpening, rcDatabase, rcReadonly );


        case 0:
            rc = 0;
            break;
        }

        rc = KDirectoryOpenFileWrite ( wd, &f, true, "%s/md5", dbpath );
        if ( rc == 0 )
        {
            rc = KMD5SumFmtMakeUpdate ( & md5, f );
            if ( rc != 0 )
                KFileRelease ( f );
        }
        else if ( GetRCState ( rc ) == rcNotFound )
            rc = 0;

        if ( rc == 0 )
            rc = KDBManagerMakeDBUpdate ( self, db, wd, dbpath, md5 );

        KMD5SumFmtRelease ( md5 );
    }

    return rc;
}
Example #8
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;
}