Пример #1
0
int archwriter_write_volheader(carchwriter *ai)
{
    struct s_writebuf *wb=NULL;
    cdico *voldico;
    
    assert(ai);
    
    if ((wb=writebuf_alloc())==NULL)
    {   msgprintf(MSG_STACK, "writebuf_alloc() failed\n");
        return -1;
    }
    
    if ((voldico=dico_alloc())==NULL)
    {   msgprintf(MSG_STACK, "voldico=dico_alloc() failed\n");
        return -1;
    }
    
    // prepare header
    dico_add_u32(voldico, 0, VOLUMEHEADKEY_VOLNUM, ai->curvol);
    dico_add_u32(voldico, 0, VOLUMEHEADKEY_ARCHID, ai->archid);
    dico_add_string(voldico, 0, VOLUMEHEADKEY_FILEFORMATVER, FSA_FILEFORMAT);
    dico_add_string(voldico, 0, VOLUMEHEADKEY_PROGVERCREAT, FSA_VERSION);
    
    // write header to buffer
    if (writebuf_add_header(wb, voldico, FSA_MAGIC_VOLH, ai->archid, FSA_FILESYSID_NULL)!=0)
    {   errprintf("archio_write_header() failed\n");
        return -1;
    }
    
    // write header to file
    if (archwriter_write_buffer(ai, wb)!=0)
    {   errprintf("archwriter_write_buffer() failed\n");
        return -1;
    }
    
    dico_destroy(voldico);
    writebuf_destroy(wb);
    
    return 0;
}
Пример #2
0
int archwriter_write_volfooter(carchwriter *ai, bool lastvol)
{
    struct s_writebuf *wb=NULL;
    cdico *voldico;
    
    assert(ai);
    
    if ((wb=writebuf_alloc())==NULL)
    {   errprintf("writebuf_alloc() failed\n");
        return -1;
    }
    
    if ((voldico=dico_alloc())==NULL)
    {   errprintf("voldico=dico_alloc() failed\n");
        return -1;
    }
    
    // prepare header
    dico_add_u32(voldico, 0, VOLUMEFOOTKEY_VOLNUM, ai->curvol);
    dico_add_u32(voldico, 0, VOLUMEFOOTKEY_ARCHID, ai->archid);
    dico_add_u32(voldico, 0, VOLUMEFOOTKEY_LASTVOL, lastvol);
    
    // write header to buffer
    if (writebuf_add_header(wb, voldico, FSA_MAGIC_VOLF, ai->archid, FSA_FILESYSID_NULL)!=0)
    {   msgprintf(MSG_STACK, "archio_write_header() failed\n");
        return -1;
    }
    
    // write header to file
    if (archwriter_write_buffer(ai, wb)!=0)
    {   msgprintf(MSG_STACK, "archwriter_write_data(size=%ld) failed\n", (long)wb->size);
        return -1;
    }
    
    dico_destroy(voldico);
    writebuf_destroy(wb);
    
    return 0;
}
Пример #3
0
int archreader_read_header(carchreader *ai, char *magic, cdico **d, bool allowseek, u16 *fsid)
{
    s64 curpos;
    u16 temp16;
    u32 temp32;
    u32 archid;
    int res;
    
    assert(ai);
    assert(d);
    assert(fsid);
    
    // init
    memset(magic, 0, FSA_SIZEOF_MAGIC);
    *fsid=FSA_FILESYSID_NULL;
    *d=NULL;
    
    if ((*d=dico_alloc())==NULL)
    {   errprintf("dico_alloc() failed\n");
        return OLDERR_FATAL;
    }
    
    // search for next read header marker and magic (it may be further if corruption in archive)
    if ((curpos=lseek64(ai->archfd, 0, SEEK_CUR))<0)
    {   sysprintf("lseek64() failed to get the current position in archive\n");
        return OLDERR_FATAL;
    }
    
    if ((res=archreader_read_data(ai, magic, FSA_SIZEOF_MAGIC))!=FSAERR_SUCCESS)
    {   msgprintf(MSG_STACK, "cannot read header magic: res=%d\n", res);
        return OLDERR_FATAL;
    }
    
    // we don't want to search for the magic if it's a volume header
    if (is_magic_valid(magic)!=true && allowseek!=true)
    {   errprintf("cannot read header magic: this is not a valid fsarchiver file, or it has been created with a different version.\n");
        return OLDERR_FATAL;
    }
    
    while (is_magic_valid(magic)!=true)
    {
        if (lseek64(ai->archfd, curpos++, SEEK_SET)<0)
        {   sysprintf("lseek64(pos=%lld, SEEK_SET) failed\n", (long long)curpos);
            return OLDERR_FATAL;
        }
        if ((res=archreader_read_data(ai, magic, FSA_SIZEOF_MAGIC))!=FSAERR_SUCCESS)
        {   msgprintf(MSG_STACK, "cannot read header magic: res=%d\n", res);
            return OLDERR_FATAL;
        }
    }
    
    // read the archive id
    if ((res=archreader_read_data(ai, &temp32, sizeof(temp32)))!=FSAERR_SUCCESS)
    {   msgprintf(MSG_STACK, "cannot read archive-id in header: res=%d\n", res);
        return OLDERR_FATAL;
    }
    archid=le32_to_cpu(temp32);
    if (ai->archid) // only check archive-id if it's known (when main header has been read)
    {
        if (archid!=ai->archid)
        {   errprintf("archive-id in header does not match: archid=[%.8x], expected=[%.8x]\n", archid, ai->archid);
            return OLDERR_MINOR;
        }
    }
    
    // read the filesystem id
    if ((res=archreader_read_data(ai, &temp16, sizeof(temp16)))!=FSAERR_SUCCESS)
    {   msgprintf(MSG_STACK, "cannot read filesystem-id in header: res=%d\n", res);
        return OLDERR_FATAL;
    }
    *fsid=le16_to_cpu(temp16);
    
    // read the dico of the header
    if ((res=archreader_read_dico(ai, *d))!=FSAERR_SUCCESS)
    {   msgprintf(MSG_STACK, "imgdisk_read_dico() failed\n");
        return res;
    }
    
    return FSAERR_SUCCESS;
}