Beispiel #1
0
/* ----------------------------------------------------------------------
 * RandomAccess
 *
 *  returns 0 if random access, error code otherwise
 */
static
rc_t CC KWGAEncFileRandomAccess (const KWGAEncFile *self)
{
    assert (self != NULL);
    assert (self->encrypted != NULL);
    return KFileRandomAccess (self->encrypted);
}
Beispiel #2
0
/* ----------------------------------------------------------------------
 * RandomAccess
 *
 *  returns 0 if random access, error code otherwise
 */
static
rc_t CC KCounterFileRandomAccess (const KCounterFile *self)
{
    assert (self != NULL);
    assert (self->original != NULL);
    return KFileRandomAccess (self->original);
}
Beispiel #3
0
/* ----------------------------------------------------------------------
 * RandomAccess
 *
 *  returns 0 if random access, error code otherwise
 *
 * Update needs to be able to seek both original and copy while read
 * only needs to be able to seek the original.
 */
static
rc_t CC KSubFileRandomAccess (const KSubFile *self)
{
    assert (self != NULL);
    return KFileRandomAccess (self->original);
}
Beispiel #4
0
static
rc_t CC KHttpUndyingFileRandomAccess(const KHttpUndyingFile *self)
{
    return KFileRandomAccess(GetUnderlyingFile(self));
}
Beispiel #5
0
static
rc_t CC KBufWriteFileRandomAccess ( const KBufWriteFile *self )
{
    return KFileRandomAccess ( self -> f );
}
Beispiel #6
0
static
rc_t CC KLoaderFile_RandomAccess(const KLoaderFile *self)
{
    return KFileRandomAccess(self ? self->kfile : NULL);
}
Beispiel #7
0
/* not KDB specific - just uses vfs/krypto/kfs objects */
static
rc_t KDBOpenFileAsDirectory (const KDirectory * dir,
                             const char * path, 
                             const KDirectory ** pdir,
                             uint32_t rcobj)
{
    const KFile * file;
    const KFile * f;
    const KDirectory * ldir;
    bool encrypted = false;

    rc_t rc;

    *pdir = NULL;

    rc = KDirectoryOpenFileRead (dir, &file, path);
    if (rc == 0)
    {
        rc = KFileRandomAccess(file);
        if (rc)
            rc = RC (rcDB, rcMgr, rcOpening, rcobj, rcUnsupported);
        else
        {
            size_t tz;
            char tbuff [4096];
            char pbuff [4096 + 1];

            rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz);
            if (rc == 0)
            {
                if (KFileIsEnc (tbuff, tz) == 0)
                {
                    encrypted = true;

                    rc = KDBOpenFileGetPassword (pbuff, sizeof (pbuff) - 1);
                    if (rc == 0)
                    {
                        KKey key;

                        rc = KKeyInitRead (&key, kkeyAES128, pbuff, string_size (pbuff));
                        if (rc == 0)
                        {
                            rc = KEncFileMakeRead (&f, file, &key);
                            if (rc == 0)
                            {
                                /* KEncFileMakeRead adds a reference */
                                KFileRelease (file);
                                file = f;
                                rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz);
                            }
                        }
                    }
                }
                else if (KFileIsWGAEnc (tbuff, tz) == 0)
                {
                    encrypted = true;

                    rc = KDBOpenFileGetPassword (pbuff, sizeof (pbuff) - 1);
                    if (rc == 0)
                    {
                        rc = KFileMakeWGAEncRead (&f, file, pbuff, string_size (pbuff));
                        if (rc == 0)
                        {
                            /* KFileMakeWGAEncRead adds a reference */
                            KFileRelease (file);
                            file = f;
                            rc = KFileReadAll (file, 0, tbuff, sizeof tbuff, &tz);
                        }
                    }
                }
                /* else not a handled encryption or unencrypted: we can't distinguish too much */

                if (rc == 0)
                {
                    if (KFileIsSRA (tbuff, tz) == 0)
                    {
                        rc = KDirectoryOpenSraArchiveReadUnbounded_silent_preopened (dir,
                                                                                     &ldir,
                                                                                     false,
                                                                                     file,
                                                                                     path);
                    }
                    else
                    {
                        rc = KDirectoryOpenTarArchiveRead_silent_preopened (dir, &ldir, false,
                                                                            file, path);
                    }

                    /* not an archive type we handle or a bad archive */
                    if (rc)
                    {
                        if (encrypted)
                            rc = RC ( rcDB, rcMgr, rcOpening, rcEncryptionKey, rcIncorrect );
                        else
                            rc = RC ( rcDB, rcMgr, rcOpening, rcPath, rcIncorrect );
                    }
                    else
                    {
                        /*
                         * release our ownership of the KFile that but archive will 
                         * keep theirs
                         */
                        KFileRelease (file);
                        *pdir = ldir;
                        return 0;
                    }
                }
            }
        }
        KFileRelease (file);
    }
    return rc;
}
Beispiel #8
0
/* MakeRead
 *  make a queue file for reading-ahead on background thread
 *
 *  when the file is created, a background thread is started
 *  that begins reading from "src" at position "pos", into
 *  buffers of size "buffer_size". each buffer is pushed into
 *  a cross-thread queue where it is consumed by the reading
 *  thread.
 *
 *  the background thread is throttled by queue capacity - determined
 *  by "queue_bytes" and "block_size", such that if the queue is full,
 *  the thread will sleep. the consumer thread is also throttled by the
 *  queue in that it will sleep if the queue is empty with pending data.
 *
 *  the background thread will exit upon reaching end of file,
 *  upon a permanent error, or if the queue is sealed by the consumer
 *  thread.
 *
 *  when the file is collected in response to a release message,
 *  the queue will be sealed against further inserts, pending buffers
 *  will be discarded, the background thread will be joined, and
 *  the source file will be released.
 *
 *  the intended usage is serial reading of the file. reads
 *  may only progress forward, i.e. backing up is not permitted.
 *
 *  "qf" [ OUT ] - return parameter for queue file
 *
 *  "pos" [ IN ] - starting position for reads from "src".
 *  NB - "src" must support being addressed at this position.
 *
 *  "src" [ IN ] - source file for read-ahead on background thread.
 *  must have read permissions.
 *
 *  "queue_bytes" [ IN ] - the read-ahead limit of the background
 *  thread, in bytes. this is the amount of data that will be queued
 *  for the consumer thread before the bg thread sleeps.
 *
 *  "block_size" [ IN, DEFAULT ZERO ] - optional parameter giving
 *  desired block size when reading from "src". this may be used
 *  to tune reading for source data, e.g. 64K blocks for gzip.
 */
LIB_EXPORT rc_t CC KQueueFileMakeRead ( const KFile **qfp, uint64_t pos,
    const KFile *src, size_t queue_bytes, size_t block_size, uint32_t timeout_ms )
{
    rc_t rc;

    if ( qfp == NULL )
        rc = RC ( rcApp, rcFile, rcConstructing, rcParam, rcNull );
    else
    {
        if ( src == NULL )
            rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcNull );
        else if ( ! src -> read_enabled )
        {
            if ( src -> write_enabled )
                rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcWriteonly );
            else
                rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcNoPerm );
        }
        else if ( pos == 0 || ( rc = KFileRandomAccess ( src ) ) == 0 )
        {
            KQueueFile *qf = malloc ( sizeof * qf );
            if ( qf == NULL )
                rc = RC ( rcApp, rcFile, rcConstructing, rcMemory, rcExhausted );
            else
            {
                rc = KFileInit ( & qf -> dad, ( const KFile_vt* ) & KQueueFileRead_vt_v1, "KQueueFile", "no-name", true, false );
                if ( rc == 0 )
                {
                    qf -> f = ( KFile* ) src;
                    rc = KFileAddRef ( src );
                    if ( rc == 0 )
                    {
                        uint32_t capacity;

                        /* zero block size means default */
                        if ( block_size == 0 )
                            block_size = DEFAULT_BLOCK_SIZE;

                        /* queue capacity is expressed in bytes originally
                           translate to buffer count */
                        capacity = ( queue_bytes + block_size - 1 ) / block_size;
                        if ( capacity == 0 )
                            capacity = 1;

                        /* actual capacity will be a power of 2 */
                        rc = KQueueMake ( & qf -> q, capacity );
                        if ( rc == 0 )
                        {
                            /* capture current size if supported */
                            qf -> rc_from_size_on_open = KFileSize ( src, & qf -> apparent_size );

                            /* starting position for read */
                            qf -> start_pos = pos;

                            /* requested buffer size */
                            qf -> b = NULL;
                            qf -> bsize = block_size;

                            /* timeout */
                            qf -> timeout_ms = timeout_ms == 0 ? DEFAULT_TIMEOUT_MS : timeout_ms;

                            /* finally, start the background thread */
                            rc = KThreadMake ( & qf -> t, KQueueFileRunRead, qf );
                            if ( rc == 0 )
                            {
                                * qfp = & qf -> dad;
                                return 0;
                            }

                            KQueueRelease ( qf -> q );
                        }

                        KFileRelease ( qf -> f );
                    }
                }

                free ( qf );
            }
        }

        * qfp = NULL;
    }

    return rc;
}