void *thread_iobuf_to_queue_fct(void *args)
{
    struct s_blockinfo blkinfo;
    cdico *dico = NULL;
    u32 headertype;
    u16 fsindex;
    int sumok;
    int status;
    s64 lres;
    int res;

    inc_secthreads();    

    while ((iobuffer_get_end_of_buffer(g_iobuffer) == false))
    {
        if (((res = iobuffer_read_logichead(g_iobuffer, &headertype, &dico, &fsindex)) != FSAERR_SUCCESS) && (get_status() == STATUS_RUNNING))
        {
            dico_destroy(dico);
            msgprintf(MSG_STACK, "iobuffer_read_logichead() failed to read next logic-header\n");
            set_status(STATUS_FAILED, "iobuffer_read_logichead() failed");
            goto thread_iobuf_to_queue_cleanup;
        }

        if (headertype == FSA_HEADTYPE_BLKH) // header introduces a data block
        {
            if ((iobuffer_read_block(g_iobuffer, dico, &sumok, &blkinfo) != FSAERR_SUCCESS) && (get_status() == STATUS_RUNNING))
            {
                msgprintf(MSG_STACK, "iobuffer_read_block() failed\n");
                set_status(STATUS_FAILED, "iobuffer_read_block() failed");
                goto thread_iobuf_to_queue_cleanup;
            }

            if (g_fsbitmap[fsindex] == 1)
            {
                status = ((sumok == true) ? QITEM_STATUS_TODO : QITEM_STATUS_DONE);
                if ((lres = queue_add_block(g_queue, &blkinfo, status)) != FSAERR_SUCCESS)
                {
                    set_status(STATUS_FAILED, "queue_add_block() failed");
                    goto thread_iobuf_to_queue_cleanup;
                }
                dico_destroy(dico);
            }
        }
        else // current header does not introduce a block
        {
            // if it's a global header or a if this local header belongs to a filesystem that the main thread needs
            if ((fsindex == FSA_FILESYSID_NULL) || (g_fsbitmap[fsindex] == 1))
            {
                if ((lres = queue_add_header(g_queue, dico, headertype, fsindex)) != FSAERR_SUCCESS)
                {
                    msgprintf(MSG_STACK, "queue_add_header()=%ld=%s failed\n", (long)lres, error_int_to_string(lres));
                    set_status(STATUS_FAILED, "iobuffer_read_block() failed");
                    goto thread_iobuf_to_queue_cleanup;
                }
            }
            else // header not used: remove data strucutre in dynamic memory
            {
                dico_destroy(dico);
            }
        }
    }

thread_iobuf_to_queue_cleanup:
    queue_set_end_of_queue(g_queue, true);
    msgprintf(MSG_DEBUG1, "THREAD-ENQUEUE: exit\n");
    dec_secthreads();
    return NULL;
}
Example #2
0
void *thread_reader_fct(void *args)
{
    char magic[FSA_SIZEOF_MAGIC];
    struct s_blockinfo blkinfo;
    u32 endofarchive=false;
    carchreader *ai=NULL;
    cdico *dico=NULL;
    int skipblock;
    u16 fsid;
    int sumok;
    int status;
    u64 errors;
    s64 lres;
    int res;
    
    // init
    errors=0;
    inc_secthreads();

    if ((ai=(carchreader *)args)==NULL)
    {   errprintf("ai is NULL\n");
        goto thread_reader_fct_error;
    }
    
    // open archive file
    if (archreader_volpath(ai)!=0)
    {   errprintf("archreader_volpath() failed\n");
        goto thread_reader_fct_error;
    }
    
    if (archreader_open(ai)!=0)
    {   errprintf("archreader_open(%s) failed\n", ai->basepath);
        goto thread_reader_fct_error;
    }
    
    // read volume header
    if (archreader_read_volheader(ai)!=0)
    {   errprintf("archio_read_volheader() failed\n");
        goto thread_reader_fct_error;
    }
    
    // ---- read main archive header
    if ((res=archreader_read_header(ai, magic, &dico, false, &fsid))!=FSAERR_SUCCESS)
    {   errprintf("archreader_read_header() failed to read the archive header\n");
        goto thread_reader_fct_error; // this header is required to continue
    }
    
    if (dico_get_u32(dico, 0, MAINHEADKEY_ARCHIVEID, &ai->archid)!=0)
    {   msgprintf(3, "cannot get archive-id from main header\n");
        goto thread_reader_fct_error;
    }
    
    if ((lres=queue_add_header(&g_queue, dico, magic, fsid))!=FSAERR_SUCCESS)
    {   errprintf("queue_add_header()=%ld=%s failed to add the archive header\n", (long)lres, error_int_to_string(lres));
        goto thread_reader_fct_error;
    }
    
    // read all other data from file (filesys-header, normal objects headers, ...)
    while (endofarchive==false && get_stopfillqueue()==false)
    {
        if ((res=archreader_read_header(ai, magic, &dico, true, &fsid))!=FSAERR_SUCCESS)
        {   dico_destroy(dico);
            msgprintf(MSG_STACK, "archreader_read_header() failed to read next header\n");
            if (res==OLDERR_MINOR) // header is corrupt or not what we expected
            {   errors++;
                msgprintf(MSG_DEBUG1, "OLDERR_MINOR\n");
                continue;
            }
            else // fatal error (eg: cannot read archive from disk)
            {
                msgprintf(MSG_DEBUG1, "!OLDERR_MINOR\n");
                goto thread_reader_fct_error;
            }
        }
        
        // read header and see if it's for archive management or higher level data
        if (strncmp(magic, FSA_MAGIC_VOLF, FSA_SIZEOF_MAGIC)==0) // header is "end of volume"
        {
            archreader_close(ai);
            
            // check the "end of archive" flag in header
            if (dico_get_u32(dico, 0, VOLUMEFOOTKEY_LASTVOL, &endofarchive)!=0)
            {   errprintf("cannot get compr from block-header\n");
                goto thread_reader_fct_error;
            }
            msgprintf(MSG_VERB2, "End of volume [%s]\n", ai->volpath);
            if (endofarchive!=true)
            {
                archreader_incvolume(ai, false);
                while (regfile_exists(ai->volpath)!=true)
                {
                    // wait until the queue is empty so that the main thread does not pollute the screen
                    while (queue_count(&g_queue)>0)
                        usleep(5000);
                    fflush(stdout);
                    fflush(stderr);
                    msgprintf(MSG_FORCE, "File [%s] is not found, please type the path to volume %ld:\n", ai->volpath, (long)ai->curvol);
                    fprintf(stdout, "New path:> ");
                    res=scanf("%256s", ai->volpath);
                }
                
                msgprintf(MSG_VERB2, "New volume is [%s]\n", ai->volpath);
                if (archreader_open(ai)!=0)
                {   msgprintf(MSG_STACK, "archreader_open() failed\n");
                    goto thread_reader_fct_error;
                }
                if (archreader_read_volheader(ai)!=0)
                {      msgprintf(MSG_STACK, "archio_read_volheader() failed\n");
                    goto thread_reader_fct_error;
                }
            }
            dico_destroy(dico);
        }
        else // high-level archive (not involved in volume management)
        {
            if (strncmp(magic, FSA_MAGIC_BLKH, FSA_SIZEOF_MAGIC)==0) // header starts a data block
            {
                skipblock=(g_fsbitmap[fsid]==0);
                //errprintf("DEBUG: skipblock=%d g_fsbitmap[fsid=%d]=%d\n", skipblock, (int)fsid, (int)g_fsbitmap[fsid]);
                if (archreader_read_block(ai, dico, skipblock, &sumok, &blkinfo)!=0)
                {   msgprintf(MSG_STACK, "archreader_read_block() failed\n");
                    goto thread_reader_fct_error;
                }
                
                if (skipblock==false)
                {
                    status=((sumok==true)?QITEM_STATUS_TODO:QITEM_STATUS_DONE);
                    if ((lres=queue_add_block(&g_queue, &blkinfo, status))!=FSAERR_SUCCESS)
                    {   if (lres!=FSAERR_NOTOPEN)
                            errprintf("queue_add_block()=%ld=%s failed\n", (long)lres, error_int_to_string(lres));
                        goto thread_reader_fct_error;
                    }
                    if (sumok==false) errors++;
                    dico_destroy(dico);
                }
            }
            else // another higher level header
            {
                // if it's a global header or a if this local header belongs to a filesystem that the main thread needs
                if (fsid==FSA_FILESYSID_NULL || g_fsbitmap[fsid]==1)
                {
                    if ((lres=queue_add_header(&g_queue, dico, magic, fsid))!=FSAERR_SUCCESS)
                    {   msgprintf(MSG_STACK, "queue_add_header()=%ld=%s failed\n", (long)lres, error_int_to_string(lres));
                        goto thread_reader_fct_error;
                    }
                }
                else // header not used: remove data strucutre in dynamic memory
                {
                    dico_destroy(dico);
                }
            }
        }
    }
    
thread_reader_fct_error:
    msgprintf(MSG_DEBUG1, "THREAD-READER: queue_set_end_of_queue(&g_queue, true)\n");
    queue_set_end_of_queue(&g_queue, true); // don't wait for more data from this thread
    dec_secthreads();
    msgprintf(MSG_DEBUG1, "THREAD-READER: exit\n");
    return NULL;
}
Example #3
0
// add headers and datblock at the end of the queue
int regmulti_save_enqueue(cregmulti *m, cqueue *q, int fsid)
{
    cblockinfo blkinfo;
    char *dynblock;
    u32 offset=0;
    u64 filesize;
    int i;
    
    if (!m)
    {   errprintf("invalid param\n");
        return -1;
    }
    
    // don't do anything if block is empty
    if (m->count==0)
        return 0;
    
    for (i=0; i < m->count; i++)
    {
        if (m->objhead[i]==NULL)
        {   errprintf("error: objhead[%d]==NULL\n", i);
            return -1;
        }
        
        // get file size from header
        if (dico_get_u64(m->objhead[i], DICO_OBJ_SECTION_STDATTR, DISKITEMKEY_SIZE, &filesize)!=0)
        {   errprintf("Cannot read filesize DISKITEMKEY_SIZE from archive\n");
            return -1;
        }
        
        // the extraction function needs to know how many small-files are packed together
        if (dico_add_u32(m->objhead[i], DICO_OBJ_SECTION_STDATTR, DISKITEMKEY_MULTIFILESCOUNT, (u32)m->count)!=0)
        {   errprintf("dico_add_u32(DISKITEMKEY_MULTIFILESCOUNT) failed\n");
            return -1;
        }
        
        // the extraction function needs to know where the data for this file are in the block
        if (dico_add_u32(m->objhead[i], DICO_OBJ_SECTION_STDATTR, DISKITEMKEY_MULTIFILESOFFSET, (u32)offset)!=0)
        {   errprintf("dico_add_u32(DISKITEMKEY_MULTIFILESCOUNT) failed\n");
            return -1;
        }
        offset+=(u32)filesize;
        
        if (queue_add_header(q, m->objhead[i], FSA_MAGIC_OBJT, fsid)!=0)
        {   errprintf("queue_add_header() failed\n");
            return -1;
        }
    }
    
    // make a copy of the static block to dynamic memory
    if ((dynblock=malloc(m->usedsize)) == NULL)
    {   errprintf("malloc(%ld) failed: out of memory\n", (long)m->usedsize);
        return -1;
    }
    memcpy(dynblock, m->data, m->usedsize);
    
    memset(&blkinfo, 0, sizeof(blkinfo));
    blkinfo.blkrealsize=m->usedsize;
    blkinfo.blkdata=(char*)dynblock;
    blkinfo.blkoffset=0; // no meaning for multi-regfiles
    blkinfo.blkfsid=fsid;
    if (queue_add_block(q, &blkinfo, QITEM_STATUS_TODO)!=0)
    {   errprintf("queue_add_block() failed\n");
        return -1;
    }
    
     return 0;
}