Exemplo n.º 1
0
/* OpenDBRead
 * VOpenDBRead
 *  open a database for read
 *
 *  "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 KDBManagerVOpenDBReadInt ( const KDBManager *self,
    const KDatabase **dbp, const KDirectory *wd,
    const char *path, va_list args )
{
    /* generate absolute path to db */
    char dbpath [ 4096 ];
    rc_t rc = KDirectoryVResolvePath ( wd, true,
        dbpath, sizeof dbpath, path, args );
    if ( rc == 0 )
    {
        KDatabase *db;
        const KDirectory *dir;

        /* open the directory if its a database */
        rc = KDBOpenPathTypeRead ( wd, dbpath, &dir, kptDatabase, NULL );
        if ( rc == 0 )
        {
            /* allocate a new guy */
            rc = KDatabaseMake ( & db, dir, dbpath );
            if ( rc == 0 )
            {
                db -> mgr = KDBManagerAttach ( self );
                * dbp = db;
                return 0;
            }

            KDirectoryRelease ( dir );
        }
    }
    
    return rc;
}
Exemplo n.º 2
0
/* CreateLockFile
 *  attempts to create a KLockFile
 *
 *  "lock" [ OUT ] - return parameter for newly created lock file
 *
 *  "path" [ IN ] - NUL terminated string in directory-native
 *  character set denoting lock file
 */
LIB_EXPORT rc_t CC KDirectoryVCreateLockFile ( KDirectory *self,
    KLockFile **lock, const char *path, va_list args )
{
    rc_t rc;

    if ( lock == NULL )
        rc = RC ( rcFS, rcFile, rcLocking, rcParam, rcNull );
    else
    {
        if ( self == NULL )
            rc = RC ( rcFS, rcFile, rcLocking, rcSelf, rcNull );
        else if ( path == NULL )
            rc = RC ( rcFS, rcFile, rcLocking, rcPath, rcNull );
        else if ( path [ 0 ] == 0 )
            rc = RC ( rcFS, rcFile, rcLocking, rcPath, rcEmpty );
        else
        {
            char full [ 4096 ];
            rc = KDirectoryVResolvePath ( self, false, full, sizeof full, path, args );
            if ( rc == 0 )
            {
                KFile *lock_file;
                rc = KDirectoryCreateFile ( self, & lock_file, false, 0600, kcmCreate | kcmParents, "%s", full );
                if ( rc == 0 )
                {
                    rc_t rc2;

                    /* no longer need the file - not going to write to it anyway */
                    KFileRelease ( lock_file );

                    /* we have the lock */
                    rc = KLockFileMake ( lock, self, full );
                    if ( rc == 0 )
                        return 0;

                    /* must unlink lockfile */
                    rc2 = KDirectoryRemove ( self, true, "%s", full );
                    if ( rc2 != 0 )
                        /* issue a report */;
                }
                else if ( GetRCState ( rc ) == rcExists )
                {
                    /* map the rc to kproc type values */
                    rc = RC ( rcFS, rcFile, rcLocking, rcLocking, rcBusy );
                }
                else
                {
                    rc = ResetRCContext ( rc, rcFS, rcFile, rcLocking );
                }
            }
        }

        * lock = NULL;
    }

    return rc;
}
Exemplo n.º 3
0
 /* ResolvePath
  *  resolves path to an absolute or directory-relative path
  *
  *  "absolute" [ IN ] - if true, always give a path starting
  *  with '/'. NB - if the directory is chroot'd, the absolute path
  *  will still be relative to directory root.
  *
  *  "resolved" [ OUT ] and "rsize" [ IN ] - buffer for
  *  NUL terminated result path in directory-native character set
  *  the resolved path will be directory relative
  *
  *  "path" [ IN ] - NUL terminated string in directory-native
  *  character set denoting target path. NB - need not exist.
 */
 inline rc_t ResolvePath ( bool absolute, char *resolved, size_t rsize,
     const char *path, ... ) const throw ()
 {
     va_list args;
     va_start ( args, path );
     rc_t rc = KDirectoryVResolvePath ( this, absolute, resolved, rsize, path, args );
     va_end ( args );
     return rc;
 }
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
rc_t CCCopyMake (CCCopy ** p, const KDirectory * in,  KDirectory * out, 
		  KDirectory * xml, bool force, KMD5SumFmt * md5,
		  CCFileFormat * ff, CCTree * tree, const char * path)
{
    rc_t rc;
    size_t pathlen;
    CCCopy * self;
    char relpath [4096];

    assert (in != NULL);
    assert (out != NULL);
    assert (xml != NULL);
    assert (path != NULL);

    rc = KDirectoryVResolvePath (in, false, relpath, sizeof relpath, path, NULL);
    if (rc != 0)
    {
	pLOGERR (klogErr, rc, "unable to resolve path $(P)", PLOG_S(P), path);
	return rc;
    }
    if ((relpath[0] == '.') && (relpath[1] == '.') && (relpath[2] == '/'))
    {
	rc = RC (rcExe, rcDirectory, rcResolving, rcPath, rcOutOfKDirectory);
	pLOGERR (klogErr, rc, "Path must resolve to current directory or subdirectories $(P)",
		 PLOG_S(P), relpath);
	return rc;
    }

    pathlen = strlen(relpath);
    self = malloc (sizeof (*self) - sizeof (*self->path) + pathlen + 1);
    if (self == NULL)
	rc = RC (rcExe, rcNoTarg, rcAllocating, rcMemory, rcExhausted);
    else
    {
	atomic32_set (&self->refcount, 1);
	KDirectoryAddRef (in);
	KDirectoryAddRef (out);
	KDirectoryAddRef (xml);
	KMD5SumFmtAddRef (md5);
	CCFileFormatAddRef (ff);
	self->in = in;
	self->out = out;
	self->xml = xml;
	self->force = force;
	self->md5 = md5;
	self->ff = ff;
	self->tree = tree;
	memcpy (self->path, relpath, pathlen+1);
	*p = self;
    }
    return rc;
}
Exemplo n.º 6
0
/* KDBVMakeSubPath
 *  adds a namespace to path spec
 */
rc_t KDBVMakeSubPath ( struct KDirectory const *dir,
    char *subpath, size_t subpath_max, const char *ns,
    uint32_t ns_size, const char *path, va_list args )
{
    rc_t rc;

    if ( ns_size > 0 )
    {
        subpath += ns_size + 1;
        subpath_max -= ns_size + 1;
    }

#if CRUFTY_USE_OF_RESOLVE_PATH
    /* because this call only builds a path instead of resolving anything
     * is is okay that we are using the wrong directory */
    rc = KDirectoryVResolvePath ( dir, false,
        subpath, subpath_max, path, args );
#else
    {
        int sz = vsnprintf ( subpath, subpath_max, path, args );
        if ( sz < 0 || ( size_t ) sz >= subpath_max )
            rc = RC ( rcDB, rcDirectory, rcResolving, rcBuffer, rcInsufficient );
        else if ( sz == 0 )
            rc = RC ( rcDB, rcDirectory, rcResolving, rcPath, rcEmpty );
        else
        {
            rc = 0;
        }
    }
#endif
    switch ( GetRCState ( rc ) )
    {
    case 0:
        assert ( subpath [ 0 ] != 0 );
        if ( subpath [ 0 ] == '.' || subpath [ 1 ] == '/' )
            return RC ( rcDB, rcDirectory, rcResolving, rcPath, rcInvalid );
        break;
    case rcInsufficient:
        return RC ( rcDB, rcDirectory, rcResolving, rcPath, rcExcessive );
    default:
        return rc;
    }

    if ( ns_size != 0 )
    {
        subpath -= ns_size + 1;
        memcpy ( subpath, ns, ns_size );
        subpath [ ns_size ] = '/';
    }
    return rc;
}
Exemplo n.º 7
0
/* Unlock
 *  remove lock
 *
 *  if object is already unlocked, the operation is idempotent
 *  and returns an rc state of rcUnlocked
 *
 *  "path" [ IN ] - NUL terminated path
 */
LIB_EXPORT rc_t CC KDBManagerVUnlock ( KDBManager *self, const char *path, va_list args )
{
    rc_t rc;
    char full [ 4096 ];

    if ( self == NULL )
        rc =  RC ( rcDB, rcMgr, rcUnlocking, rcSelf, rcNull );
    else
    {
        /* get full path to object */
        rc = KDirectoryVResolvePath ( self -> wd, true,
            full, sizeof full, path, args );
        if ( rc == 0 )
        {
            /* TBD:
               Add code to validate that this path is not in a container
               object's control.  That is the last facet in the path
               is the name of the object.  To be valid the facet before
               must not be "col", "tbl", or "db" as in those cases
               the KDBManager should not be called for this object but 
               its containing object
            */

            /* if the path is not writable because it is already locked
             * we attempt to unlock it.
             *
             * if the return is 0 from Writable than it was already 
             * unlocked so we say so and thus again the
             * the return from this will contain "rcLocked" and the 
             * caller will be forced to check for zero or RCState(rcUnlocked)
             *
             * a side effect is that if the call does not return 0 it will
             * be a wrong type to lock with the DBManager
             */
            rc = KDBManagerWritableInt ( self -> wd, path );
            if ( rc == 0 )
                rc = RC ( rcDB, rcMgr, rcUnlocking, rcLock, rcUnlocked );
            else if ( GetRCState ( rc ) == rcLocked )
            {
                rc = KDBManagerCheckOpen ( self, path );
                if ( rc == 0 )
                    rc = KDBUnlockDir ( self -> wd, path );
            }
        }

        if ( rc != 0 )
            rc = ResetRCContext ( rc, rcDB, rcMgr, rcUnlocking );
    }
    return rc;
}
Exemplo n.º 8
0
LIB_EXPORT rc_t CC KDBManagerVWritable ( const KDBManager *self, const char * path, va_list args )
{
    rc_t rc;

    if ( self == NULL )
        rc = RC ( rcDB, rcMgr, rcAccessing, rcSelf, rcNull );
    else
    {
        char dbpath [ 4096 ];

        /* get full path to object */
        rc = KDirectoryVResolvePath ( self -> wd, true, dbpath, sizeof dbpath, path, args );
        if ( rc == 0 )
            rc = KDBManagerWritableInt ( self -> wd, dbpath );
    }
    return rc;
}
Exemplo n.º 9
0
LIB_EXPORT
rc_t CC
XFS_VResolvePath (
                bool Absolute,
                char * Resolved,
                size_t ResolvedSize,
                const char * Format,
                va_list Args
)
{
    rc_t RCt;
    struct KDirectory * NatDir;

    RCt = 0;
    NatDir = NULL;

    XFS_CAN ( Resolved )
    XFS_CAN ( Format )
    XFS_CA ( ResolvedSize, 0 )

    RCt = KDirectoryNativeDir ( & NatDir );
    if ( RCt == 0 ) {
        RCt = KDirectoryVResolvePath (
                                    NatDir,
                                    Absolute,
                                    Resolved,
                                    ResolvedSize,
                                    Format,
                                    Args
                                    );
        KDirectoryRelease ( NatDir );
    }

    if ( RCt != 0 ) {
        * Resolved = 0;
    }

    return 0;
}   /* XFS_VResolvePath () */
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
/* 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,
                       bool ( CC * filter)(const KDirectory *, const char *, void *),
                       void * fdata,
                       rc_t ( CC * 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, 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; idx < limit; idx ++)
            {
                const char * name;
                rc = KNamelistGet (names, idx, &name);
                if (rc == 0)
                {
                    char * new_path;
                    size_t namelen;
                    size_t new_pathlen;
                    size_t rsize;

                    namelen = strlen (name);
                    new_pathlen = pathlen + 1 + namelen;
                    rsize = new_pathlen + 1;
                    new_path = malloc (rsize);
                    if (new_path != NULL)
                    {
                        char * recur_path;
                        if (pathlen == 0)
                        {
                            memcpy (new_path, name, namelen);
                            new_path[namelen] = '\0';
                        }
                        else
                        {
                            memcpy (new_path, path, pathlen);
                            new_path[pathlen] = '/';
                            memcpy (&new_path[pathlen+1], name, namelen);
                            new_path[new_pathlen] = '\0';
                        }
                        recur_path = malloc (rsize);
                        if (recur_path != NULL)
                        {
                            rc = KDirectoryVResolvePath (dir, false, recur_path,
                                                         rsize, new_path, NULL);

                            if (rc == 0)
                            {
                                bool use_name;
                                if (filter != NULL)
                                {
                                    use_name = filter (dir, recur_path, fdata);
                                }
                                else
                                {
                                    use_name = true;
                                }
                                if (use_name)
                                {
                                    rc = action (dir, recur_path, adata);
                                    /* 				    if (rc == 0) */
                                    /* 				    { */
                                    /* 					enum KPathType type; */
                                    /* 					type = (enum KPathType)KDirectoryPathType (dir, recur_path); */
                                    /* 					if (type == kptDir) */
                                    /*                                             rc = step_through_dir (dir, recur_path, filter, fdata, action, adata); */
                                    /* 				    } */
                                }
                            }
                            free (recur_path);
                        }
                        free (new_path);
                    }
                }
                if (rc != 0)
                    break;
            }
        }
        KNamelistRelease (names);
    }
    return rc;
}
Exemplo n.º 13
0
 inline rc_t ResolvePath ( bool absolute, char *resolved, size_t rsize,
     const char *path, va_list args ) const throw ()
 { return KDirectoryVResolvePath ( this, absolute, resolved, rsize, path, args ); }