Exemple #1
0
/* Init
 */
static
rc_t KColumnIdx2Init ( KColumnIdx2 *self, uint64_t idx2_eof )
{
    rc_t rc;

#if 0
    memset(&self->cstorage,0,sizeof(self->cstorage));
    self->cstorage.elem_bits = sizeof(KColumnIdx2BlockCache)*8;
    self->last = 0;
#endif
    rc = KFileSize ( self -> f, & self -> eof );
    if ( rc == 0 )
    {
        if ( self -> eof < idx2_eof )
            rc = RC ( rcDB, rcColumn, rcConstructing, rcIndex, rcCorrupt );
        else
        {
            self -> eof = idx2_eof;
            return 0;
        }
    }
    
    KFileRelease ( self -> f );

    self -> f = NULL;
    return rc;
}
Exemple #2
0
/* ----------------------------------------------------------------------
 * CCNodeSraDirFileSize
 *  returns size in bytes of target file
 *
 *  "path" [ IN ] - NUL terminated string in directory-native
 *  character set denoting target file
 *
 *  "size" [ OUT ] - return parameter for file size
 * NOTE: Does not meet a design target of on stack (localized variable) allocation of single 4kb path
 */
static
rc_t CC CCNodeSraDirFilePhysicalSize (const CCNodeSraDir *self,
                                      uint64_t *size,
                                      const char *path_fmt,
                                      va_list args)
{
    char path[4096];
    int path_size;

    assert (self != NULL);
    assert (size != NULL);
    assert (path_fmt != NULL);

    path_size = args ?
        vsnprintf ( path, sizeof path, path_fmt, args ) :
        snprintf  ( path, sizeof path, "%s", path_fmt );
    if ( path_size < 0 || path_size >= (int) sizeof path )
        return RC (rcFS, rcNoTarg, rcAccessing, rcPath, rcExcessive );

    if (CCNodeSraDirLegalPath (self, path))
        return (KFileSize (self->file, size)); /* we have to assume physical and logical size are the same */

    *size = 0;
    return RC (rcFS, rcNoTarg, rcAccessing, rcPath, rcNotFound);
}
Exemple #3
0
static
rc_t CC KLoaderFile_Size(const KLoaderFile *self, uint64_t *size)
{
    if( self && self->kfile ) {
        return KFileSize(self->kfile, size);
    }
    return KDirectoryFileSize(self ? self->dir : NULL, size, "%s", self->realname);
}
Exemple #4
0
static rc_t LogFileSize_timed ( const LogFile *self, uint64_t *size )
{
    KTimeMs_t ms = KTimeMsStamp ();
    rc_t rc = KFileSize ( self -> wrapped, size );
    ms = KTimeMsStamp () - ms;
    WriteToRecorder ( self -> rec, "S\t%lu\t%lu\n", *size, ms );
    return rc;
}
Exemple #5
0
rc_t CC
TCheckFileContent ( struct KFile * file, const uint8_t* filler, size_t filler_size )
{
    rc_t rc = 0;
    
    uint64_t content_size;
    rc = KFileSize ( file, &content_size );
    if (rc != 0)
    {
        return rc;
    }
    
    if (content_size == 0)
    {
        // do nothing
        return rc;
    }
    
    const size_t buffer_size = 32*1024;
    
    uint8_t buffer[buffer_size], reference_buffer[buffer_size];
    size_t filler_sizes_in_buffer = buffer_size / filler_size;
    
    assert(buffer_size % filler_size == 0);
    assert(buffer_size / filler_size  > 0);
    
    for (size_t i = 0; i < filler_sizes_in_buffer; ++i)
    {
        memmove(reference_buffer + i*filler_size, filler, filler_size);
    }
    
    uint64_t num_read_total = 0;
    size_t num_read;
    while (num_read_total < content_size)
    {
        size_t to_read = content_size - num_read_total;
        if (to_read > buffer_size)
        {
            to_read = buffer_size;
        }
        rc = KFileReadAll ( file, num_read_total, buffer, to_read, &num_read );
        if (rc != 0)
        {
            break;
        }
        
        assert(num_read == to_read);
        
        if (memcmp(reference_buffer, buffer, num_read) != 0)
        {
            return RC( rcKrypto, rcFile, rcValidating, rcEncryption, rcCorrupt );
        }
        
        num_read_total += num_read;
    }
    
    return rc;
}
Exemple #6
0
static
rc_t copy_file (const KFile * fin, KFile *fout)
{
    rc_t rc;
    uint8_t	buff	[64 * 1024];
    size_t	num_read;
    uint64_t	inpos;
    uint64_t	outpos;
    uint64_t    fsize;

    assert (fin != NULL);
    assert (fout != NULL);

    inpos = 0;
    outpos = 0;

    rc = KFileSize (fin, &fsize);
    if (rc != 0)
        return rc;

    do
    {
        rc = KFileRead (fin, inpos, buff, sizeof (buff), &num_read);
        if (rc != 0)
        {
            PLOGERR (klogErr, (klogErr, rc,
                               "Failed to read from directory structure in creating archive at $(P)",
                               PLOG_U64(P), inpos));
            break;
        }
        else if (num_read > 0)
        {
            size_t to_write;

            inpos += (uint64_t)num_read;

            to_write = num_read;
            while (to_write > 0)
            {
                size_t num_writ;
                rc = KFileWrite (fout, outpos, buff, num_read, &num_writ);
                if (rc != 0)
                {
                    PLOGERR (klogErr, (klogErr, rc,
                                       "Failed to write to archive in creating archive at $(P)",
                                       PLOG_U64(P), outpos));
                    break;
                }
                outpos += num_writ;
                to_write -= num_writ;
            }
        }
        if (rc != 0)
            break;
    } while (num_read != 0);
    return rc;
}
Exemple #7
0
static uint64_t get_file_size( const char * path, bool remotely )
{
    uint64_t res = 0;
    const KFile * f;
    rc_t rc = ( remotely ) ? make_remote_file( &f, path ) : make_local_file( &f, path );
    if ( rc == 0 )
    {
        KFileSize ( f, &res );
        KFileRelease( f );
    }
    return res;
}
Exemple #8
0
rc_t CC
TCopyFile ( struct KFile * file_dst, struct KFile * file_src )
{
    rc_t rc = 0;
    
    uint64_t size_src;
    rc = KFileSize ( file_src, &size_src );
    if (rc != 0)
    {
        return rc;
    }
    
    if (size_src == 0)
    {
        // do nothing
        return rc;
    }
    
    const size_t buffer_size = 32*1024;
    
    uint8_t buffer[buffer_size];
   
    uint64_t num_copied_total = 0;
    size_t num_read, num_written;
    while (num_copied_total < size_src)
    {
        size_t to_copy = size_src - num_copied_total;
        if (to_copy > buffer_size)
        {
            to_copy = buffer_size;
        }
        rc = KFileReadAll ( file_src, num_copied_total, buffer, to_copy, &num_read );
        if (rc != 0)
        {
            break;
        }
        assert(num_read == to_copy);
        rc = KFileWriteAll ( file_dst, num_copied_total, buffer, to_copy, &num_written );
        if (rc != 0)
        {
            break;
        }
        assert(num_written == to_copy);
        
        num_copied_total += num_written;
    }
    
    return rc;
}
Exemple #9
0
/* ----------------------------------------------------------------------
 * Size
 *  returns size in bytes of file
 *
 *  "size" [ OUT ] - return parameter for file size
 */
static
rc_t CC KWGAEncFileSize (const KWGAEncFile *self, uint64_t *size)
{
    uint64_t esize;
    rc_t rc;
    assert (self != NULL);
    assert (self->encrypted != NULL);
    assert (size != NULL);

    *size = 0;
    rc = KFileSize (self->encrypted, &esize);
    if (rc == 0)
        *size = esize - sizeof (KWGAEncFileHeader);
    return rc;
}
Exemple #10
0
static uint64_t get_file_size( const char * path )
{
    uint64_t res = 0;
    KDirectory * dir;
    rc_t rc = KDirectoryNativeDir( &dir );
    if ( rc == 0 )
    {
        const KFile * f;
        rc = KDirectoryOpenFileRead( dir, &f, "%s", path );
        if ( rc == 0 )
        {
            KFileSize ( f, &res );
            KFileRelease( f );
        }
        KDirectoryRelease( dir );
    }
    return res;
}
Exemple #11
0
/* Init
 */
static
rc_t KColumnIdx2Init ( KColumnIdx2 *self, uint64_t idx2_eof )
{
    rc_t rc = KFileSize ( self -> f, & self -> eof );
    if ( rc == 0 )
    {
        if ( self -> eof < idx2_eof )
            rc = RC ( rcDB, rcIndex, rcConstructing, rcIndex, rcCorrupt );
        else
        {
            self -> eof = idx2_eof;
            return 0;
        }
    }

    KFileRelease ( self -> f );
    self -> f = NULL;
    return rc;
}
Exemple #12
0
/* ----------------------------------------------------------------------
 * Destroy
 *
 */
static
rc_t CC KCounterFileDestroy (KCounterFile *self)
{
    rc_t rc = 0;
    uint64_t size;

    assert (self != NULL);
    assert (self->bytecounter != NULL);

    if (self->force || ! self->size_allowed)
    {
        size_t	num_read = 0;
        uint8_t	ignored[64*1024];
        
        size = self->max_position;
        if (self->dad.read_enabled)
            do
            {
                rc = KFileRead (self->original, size,
                                ignored, sizeof ignored, &num_read);
                size += num_read;
                DBGMSG(DBG_KFS,DBG_FLAG(DBG_KFS_COUNTER),
                       ("%s: size '%lu' num_read '%lu'\n", __func__, size, num_read));
                if (rc != 0)
                    break;
                check_state (self, ignored, num_read);
            } while (num_read != 0);
    }
    else
    {
        rc = KFileSize (self->original, &size);
        DBGMSG(DBG_KFS,DBG_FLAG(DBG_KFS_COUNTER),
               ("%s: lazy way size '%lu'\n", __func__, size));
    }
    *self->bytecounter = size;
    if (rc == 0)
    {
        rc = KFileRelease (self->original);
        free (self);
    }
    return rc;
}
Exemple #13
0
static rc_t LoadHeader(char const **rslt, char const path[], char const base[])
{
    KFile const *kf;
    rc_t rc = OpenFile(&kf, path, base);
    
    *rslt = NULL;
    if (rc == 0) {
        uint64_t fsize;
        rc = KFileSize(kf, &fsize);
        if (rc == 0) {
            char *fdata = malloc(fsize+1);
            
            if (fdata) {
                size_t nread;
                rc = KFileRead(kf, 0, fdata, fsize, &nread);
                if (rc == 0) {
                    if (nread) {
                        fdata[nread] = '\0';
                        *rslt = fdata;
                    }
                    else {
                        free(fdata);
                        rc = RC(rcApp, rcArgv, rcAccessing, rcFile, rcEmpty);
                        (void)PLOGERR(klogErr, (klogErr, rc, "File '$(file)' is empty", "file=%s", path));
                    }
                }
                else {
                    (void)PLOGERR(klogErr, (klogErr, rc, "Failed to read file '$(file)'", "file=%s", path));
                }
            }
            else {
                rc = RC(rcApp, rcArgv, rcAccessing, rcMemory, rcExhausted);
                (void)PLOGERR(klogErr, (klogErr, rc, "Failed to read file '$(file)'", "file=%s", path));
            }
        }
        KFileRelease(kf);
    }
    else {
        (void)PLOGERR(klogErr, (klogErr, rc, "Failed to open file '$(file)'", "file=%s", path));
    }
    return rc;
}
Exemple #14
0
/* Init
 */
static
rc_t KColumnDataInit ( KColumnData *self, uint64_t pos, size_t pgsize )
{
    rc_t rc = KFileSize ( self -> f, & self -> eof );
    if ( rc == 0 )
    {
        if ( self -> eof < pos || pgsize == 0 || ( pos % pgsize ) != 0 )
            rc = RC ( rcDB, rcColumn, rcConstructing, rcData, rcCorrupt );
        else
        {
            self -> eof = pos;
            self -> pgsize = pgsize;
            return 0;
        }
    }

    KFileRelease ( self -> f );
    self -> f = NULL;
    return rc;
}
Exemple #15
0
/* ----------------------------------------------------------------------
 * Size
 *  returns size in bytes of file
 *
 *  "size" [ OUT ] - return parameter for file size
 */
static
rc_t CC KCounterFileSize (const KCounterFile *self, uint64_t *size)
{
    rc_t	rc;
    uint64_t	fsize;

    assert (self != NULL);
    assert (self->original != NULL);
    assert (size != NULL);

    rc = KFileSize (self->original, &fsize);

    if (rc == 0)
    {
	/* success: refreshing the value */
	*size = ((KCounterFile *)self)->max_position = fsize;
    }
    /* pass along RC value */
    return rc;
}
Exemple #16
0
static
rc_t FileInPlace (KDirectory * cwd, const char * leaf, bool try_rename)
{
    rc_t rc;
    bool is_tmp;

    STSMSG (1, ("%scrypting file in place %s",De,leaf));

    rc = 0;
    is_tmp = IsTmpFile (leaf);
    if (is_tmp)
    {
        STSMSG (1, ("%s is a vdb-decrypt/vdb-encrypt temporary file and will "
                    "be ignored", leaf));
        TmpFoundFlag = true;
        if (ForceFlag)
            ; /* LOG OVERWRITE */
        else
            ; /* LOG TMP */
    }
    if (!is_tmp || ForceFlag)
    {
        char temp [MY_MAX_PATH];


        rc = KDirectoryResolvePath (cwd, false, temp, sizeof temp, ".%s%s",
                                    leaf, TmpExt);

        if (rc)
            PLOGERR (klogErr, (klogErr, rc, "unable to resolve '.$(S)$(E)'",
                               "S=%s,E=%s",leaf,TmpExt));
        else
        {
            KPathType kpt;
            uint32_t kcm;

            kcm = kcmCreate|kcmParents;
            kpt = KDirectoryPathType (cwd, temp);
            if (kpt != kptNotFound)
            {
                /* log busy */
                if (ForceFlag)
                {
                    kcm = kcmInit|kcmParents;
                    /* log force */
                    kpt = kptNotFound;
                }
            }

            if (kpt == kptNotFound)
            {
                const KFile * infile;

                rc = KDirectoryOpenFileRead (cwd, &infile, "%s", leaf);
                if (rc)
                    PLOGERR (klogErr, (klogErr, rc, "Unable to resolve '$(F)'",
                                       "F=%s",leaf));
                else
                {
                    uint64_t fz;
                    size_t z;
                    rc_t irc;
                    uint64_t ignored;

                    rc = KFileSize (infile, &fz);
                    /* ignore rc for now? yes hack */
                    z = string_size (leaf);

                    /* vdb-decrypt and vdb-encrypt both ignore repository cache files. */
                    irc = GetCacheTruncatedSize (infile, &ignored, true);
                    if (irc == 0)
                        STSMSG (1, ("skipping cache download file %s", leaf));
                    else if ((fz == 0) &&
                             (string_cmp (leaf + (z - (sizeof (".lock")-1)), sizeof (".lock"),
                                          ".lock", sizeof (".lock") , sizeof (".lock")) == 0))
                        STSMSG (1, ("skipping cache lock download file %s", leaf));
                    else
                    {
                        EncScheme scheme;

                        rc = EncryptionTypeCheck (infile, leaf, &scheme);
                        if (rc == 0)
                        {
                            ArcScheme ascheme;
                            bool changed;
                            bool do_this_file;
                            char new_name [MY_MAX_PATH + sizeof EncExt];

                            do_this_file = DoThisFile (infile, scheme, &ascheme);
                            strcpy (new_name, leaf);
                            if (try_rename && do_this_file)
                                changed = NameFixUp (new_name);
                            else
                                changed = false;
/*                         KOutMsg ("### %d \n", changed); */

                            if (!do_this_file)
                            {
                                if (changed)
                                {
                                    STSMSG (1, ("renaming %s to %s", leaf, new_name));
                                    rc = KDirectoryRename (cwd, false, leaf, new_name);
                                }
                                else
                                    STSMSG (1, ("skipping %s",leaf));
                            }
                            else
                            {
                                KFile * outfile;

                                rc = KDirectoryCreateExclusiveAccessFile (cwd, &outfile,
                                                                          false, 0600, kcm,
                                                                          temp);
                                if (rc == 0)
                                {
                                    const KFile * Infile;
                                    KFile * Outfile;

                                    rc = CryptFile (infile, &Infile, outfile, &Outfile, scheme);

                                    if (rc == 0)
                                    {
                                        STSMSG (1, ("copying %s to %s", leaf, temp));

                                        rc = CopyFile (Infile, Outfile, leaf, temp);

                                        if (rc == 0)
                                        {
                                            uint32_t access;
                                            KTime_t date;

                                            rc = KDirectoryAccess (cwd, &access, "%s", leaf);
                                            if (rc == 0)
                                                rc = KDirectoryDate (cwd, &date, "%s", leaf);

                                            KFileRelease (infile);
                                            KFileRelease (outfile);
                                            KFileRelease (Infile);
                                            KFileRelease (Outfile);

                                            if (rc == 0)
                                            {
                                                STSMSG (1, ("renaming %s to %s", temp, new_name));

                                                rc = KDirectoryRename (cwd, true, temp, new_name);
                                                if (rc)
                                                    LOGERR (klogErr, rc, "error renaming");
                                                else
                                                {
                                                    if (changed)
                                                        KDirectoryRemove (cwd, false, "%s", leaf);

                                                    /*rc =*/
                                                    KDirectorySetAccess (cwd, false, access,
                                                                         0777, "%s", new_name);
                                                    KDirectorySetDate (cwd, false, date, "%s", new_name);
                                                    /* gonna ignore an error here I think */
                                                    return rc;
                                                }
                                            }
                                        }
                                    }
                                    KFileRelease (outfile);
                                }
                            }
                        }
                    }
                    KFileRelease (infile);
                }
            }
        }
    }
    return rc;
}
Exemple #17
0
/* EncryptionKey
 *  return any associated encryption key
 *
 *  attempts to copy NUL-terminated key into provided buffer
 *
 *  "buffer" [ OUT ] and "bsize" [ IN ] - encryption key output parameter
 *
 *  "key_size" [ OUT, NULL OKAY ] - returns the key size in
 *  bytes, excluding any NUL termination.
 */
LIB_EXPORT rc_t CC KRepositoryEncryptionKey ( const KRepository *self,
    char *buffer, size_t bsize, size_t *key_size )
{
    rc_t rc;

    if ( self == NULL )
        rc = RC ( rcKFG, rcNode, rcAccessing, rcSelf, rcNull );
    else
    {
        const KConfigNode *node;

        if ( key_size != NULL )
            * key_size = 0;

        rc = KConfigNodeOpenNodeRead ( self -> node, & node, "encryption-key" );
        if ( rc == 0 )
        {
            size_t num_read, remaining;
            rc = KConfigNodeRead ( node, 0, buffer, bsize, & num_read, & remaining );
            KConfigNodeRelease ( node );

            if ( rc == 0 )
            {
                if ( key_size != NULL )
                    * key_size = num_read + remaining;

                if ( remaining != 0 )
                    rc = RC ( rcKFG, rcNode, rcAccessing, rcBuffer, rcInsufficient );
                else if ( num_read < bsize )
                    memset ( & buffer [ num_read ], 0, bsize - num_read );
            }
        }
        else if ( GetRCState ( rc ) == rcNotFound )
        {
            char path [ 4096 ];
            rc_t rc2 = KRepositoryEncryptionKeyFile ( self, path, sizeof path, NULL );
            if ( rc2 == 0 )
            {
                KDirectory *wd;
                rc2 = KDirectoryNativeDir ( & wd );
                if ( rc2 == 0 )
                {
                    const KFile *keyFile;
                    rc2 = KDirectoryOpenFileRead ( wd, & keyFile, path );
                    KDirectoryRelease ( wd );
                    if ( rc2 == 0 )
                    {
                        size_t num_read;
                        rc = KFileReadAll ( keyFile, 0, buffer, bsize, & num_read );
                        if ( rc == 0 )
                        {
                            if ( num_read == bsize )
                            {
                                uint64_t eof;
                                rc = KFileSize ( keyFile, & eof );
                                if ( rc == 0 )
                                    num_read = ( size_t ) eof;
                                else
                                    num_read = 0;

                                rc = RC ( rcKFG, rcFile, rcReading, rcBuffer, rcInsufficient );
                                memset ( buffer, 0, bsize );
                            }
                            else if ( num_read == 0 )
                            {
                                rc = RC ( rcKFG, rcFile, rcReading, rcFile, rcEmpty );
                                memset ( buffer, 0, bsize );
                            }
                            else
                            {
                                char *eoln = string_chr ( buffer, num_read, '\n' );
                                if ( eoln != NULL )
                                {
                                    if ( eoln == buffer )
                                        num_read = 0;
                                    else if ( eoln [ -1 ] == '\r' )
                                        num_read = eoln - buffer - 1;
                                    else
                                        num_read = eoln - buffer;
                                }

                                if ( key_size != NULL )
                                    * key_size = num_read;

                                memset ( & buffer [ num_read ], 0, bsize - num_read );
                            }
                        }

                        KFileRelease ( keyFile );
                    }
                }
            }
        }
    }

    return rc;
}
Exemple #18
0
static
rc_t aws_find_nodes ( KConfigNode *aws_node, const char *aws_path )
{
    KDirectory *wd;

    rc_t rc = KDirectoryNativeDir ( &wd );
    if ( rc == 0 )
    {
        char *buffer;
        size_t num_read;
        uint64_t buf_size;

        const KFile *credentials, *config;

        rc = KDirectoryOpenFileRead ( wd, &credentials, "%s%s", aws_path, "/credentials" );
        if ( rc == 0 )
        {
            rc = KFileSize ( credentials, &buf_size );
            if ( rc == 0 )
            {
                buffer = malloc ( buf_size );
                if ( buffer != NULL )
                {
                    rc = KFileReadAll ( credentials, 0, buffer, ( size_t ) buf_size, &num_read );

                    if ( rc == 0 )
                        aws_parse_file ( credentials, aws_node, buffer, num_read, true );

                    free ( buffer );
                }

            }

            KFileRelease ( credentials );
        }

        rc = KDirectoryOpenFileRead ( wd, &config, "%s%s", aws_path, "/config" );
        if ( rc == 0 )
        {
            rc = KFileSize ( config, &buf_size );
            if ( rc == 0 )
            {
                buffer = malloc ( buf_size );
                if ( buffer != NULL )
                {
                    rc = KFileReadAll ( config, 0, buffer, ( size_t ) buf_size, &num_read );
                    
                    if ( rc == 0 )
                        aws_parse_file ( config, aws_node, buffer, num_read, false );

                    free ( buffer );
                }
            }

            KFileRelease ( config );
        }

        KDirectoryRelease ( wd );
    }            
           
    return rc;
}
Exemple #19
0
/* ----------------------------------------------------------------------
 * Size
 *  returns size in bytes of file
 *
 *  "size" [ OUT ] - return parameter for file size
 */
static
rc_t CC CCFileSize (const CCFile *self, uint64_t *size)
{
    return KFileSize (self->original, size);
}
Exemple #20
0
/* MakeWrite
 *  make a queue file for writing-behind on background thread
 *
 *  when the file is created, a background thread is started that
 *  waits for buffers to appear in the cross-thread queue. as the producer
 *  thread writes, data are accumulated into buffers which are pushed
 *  into the queue as they fill, and written in turn on the bg thread.
 *
 *  the producer 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 background 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 a permanent error, or if the
 *  queue is sealed by the producer thread.
 *
 *  when the file is collected in response to a release message,
 *  the queue will be sealed against further inserts, pending buffers
 *  will be written, the background thread will be joined, and
 *  the source file will be released.
 *
 *  the intended usage is serial writing of the file. random writes
 *  will be accepted, but may reduce the queue efficiency.
 *
 *  "qf" [ OUT ] - return parameter for queue file
 *
 *  "dst" [ IN ] - destination file for write-behind on background thread.
 *  must have write permissions.
 *
 *  "queue_bytes" [ IN ] - the write-behind limit of the producer
 *  thread, in bytes. this is the amount of data that will be queued
 *  for the background thread before the producer thread sleeps.
 *
 *  "block_size" [ IN, DEFAULT ZERO ] - optional parameter giving
 *  desired block size when writing to "dst". this may be used
 *  to tune writing for source data, e.g. 64K blocks for gzip.
 */
LIB_EXPORT rc_t CC KQueueFileMakeWrite ( KFile **qfp,
    KFile *dst, 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 ( dst == NULL )
            rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcNull );
        else if ( ! dst -> write_enabled )
        {
            if ( dst -> read_enabled )
                rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcReadonly );
            else
                rc = RC ( rcApp, rcFile, rcConstructing, rcFile, rcNoPerm );
        }
        else
        {
            KQueueFile *qf = malloc ( sizeof * qf );
            if ( qf == NULL )
                rc = RC ( rcApp, rcFile, rcConstructing, rcMemory, rcExhausted );
            else
            {
                rc = KFileInit ( & qf -> dad, ( const KFile_vt* ) & KQueueFileWrite_vt_v1, "KQueueFile", "no-name", false, true );
                if ( rc == 0 )
                {
                    qf -> f = dst;
                    rc = KFileAddRef ( dst );
                    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 ( dst, & qf -> apparent_size );

                            /* starting position not used */
                            qf -> start_pos = 0;

                            /* 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, KQueueFileRunWrite, qf );
                            if ( rc == 0 )
                            {
                                * qfp = & qf -> dad;
                                return 0;
                            }

                            KQueueRelease ( qf -> q );
                        }

                        KFileRelease ( qf -> f );
                    }
                }

                free ( qf );
            }
        }

        * qfp = NULL;
    }

    return rc;
}
static
rc_t CC KBufWriteFileSize ( const KBufWriteFile *self, uint64_t *size )
{
    return KFileSize ( self -> f, size );
}
Exemple #22
0
static rc_t CC KHttpUndyingFileSize(const KHttpUndyingFile *self,
    uint64_t *size)
{
    return KFileSize(GetUnderlyingFile(self), size);
}
Exemple #23
0
static
rc_t KCounterFileMake (KCounterFile ** pself,
		       KFile * original,
		       uint64_t * bytecounter,
		       uint64_t * linecounter,
                       bool force)
{
    uint64_t		fsize;
    rc_t		rc;
    KCounterFile *	self;

    /* -----
     * we can not accept any of the three pointer parameters as NULL
     */
    assert (pself != NULL);
    assert (original != NULL);
    assert (bytecounter != NULL);

    /* -----
     * get space for the object
     */
    self = malloc (sizeof (KCounterFile));
    if (self == NULL)	/* allocation failed */
    {
	/* fail */
	rc = RC (rcFS, rcFile, rcConstructing, rcMemory, rcExhausted);
    }
    else
    {
	rc = KFileInit (&self->dad,			/* initialize base class */
			(const KFile_vt*)&vtKCounterFile,/* VTable for KCounterFile */
			original->read_enabled,
			original->write_enabled);
	if (rc == 0)
	{
            for (;;)
            {
                if (force) /* all sizes come from actual reads */
                {
                    fsize = 0;
                    self->force = true;
                    self->size_allowed = false;
                }
                else
                {
                    rc = KFileSize(original,&fsize);
                    if (GetRCState(rc) == rcUnsupported)
                    {
                        force = true;
                        continue;
                    }
                    else if (rc)
                        break;
                    self->force = false;
                    self->size_allowed = true;
                }
                self->max_position = fsize;
                self->original = original;
                self->bytecounter = bytecounter;
                self->linecounter = linecounter;
                if (linecounter)
                {
                    self->line_state = ENOTHING;
                    *linecounter = 0;
                }
                else
                {
                    self->line_state = EBINARY;
                }
                *bytecounter = fsize;
                *pself = self;
                return 0;
            }
	}
	/* fail */
	free (self);
    }
    *pself = NULL;
    return rc;
}
Exemple #24
0
static rc_t LogFileSize ( const LogFile *self, uint64_t *size )
{
    rc_t rc = KFileSize ( self -> wrapped, size );
    WriteToRecorder ( self -> rec, "S\t%lu\n", *size );
    return rc;
}
Exemple #25
0
rc_t get_a_sequence (param_block * pb)
{
    char * eol;
    rc_t rc = 0;
    if (pb->seq == NULL)        /* first call */
    {
        const void * annoying;
        uint64_t file_pos;
        size_t map_size;
        uint64_t file_size;

        rc = KFileSize (pb->file, &file_size);
        if (rc)
            return rc;

        rc = KMMapAddrRead (pb->mmap, &annoying);
        if (rc)
            return rc;

        pb->seq = annoying;

        if (pb->seq == NULL)
            return 0;

        rc = KMMapPosition (pb->mmap, &file_pos);
        if (rc)
            return rc;

        if (file_pos != 0)
        {
            rc = RC (rcExe, rcMemMap, rcAccessing, rcOffset, rcInvalid);
            return rc;
        }

        rc = KMMapSize (pb->mmap, &map_size);
        if (rc)
            return rc;

        if (map_size != file_size)
        {
            rc = RC (rcExe, rcMemMap, rcAccessing, rcFile, rcInvalid);
            return rc;
        }
        pb->eof = pb->seq + map_size;
    }
    else
    {
        pb->seq += pb->seq_size + 1;

        if (pb->seq >= pb->eof)
        {
            pb->seq = NULL;
            return 0;
        }
    }

    eol = string_chr (pb->seq, pb->eof - pb->seq, '\n');
    if (eol == NULL)
        pb->seq_size = pb->eof - pb->seq;
    else
        pb->seq_size = eol - pb->seq;

    return rc;
}