Back to index

avfs  1.0.1
Classes | Defines | Typedefs | Functions | Variables
urar.c File Reference
#include "archive.h"
#include "realfile.h"
#include "prog.h"
#include "oper.h"
#include "version.h"
#include <fcntl.h>
#include <unistd.h>

Go to the source code of this file.

Classes

struct  rarnode
struct  rar_entinfo
struct  rarfile

Defines

#define DOS_DIR_SEP_CHAR   '\\'
#define LONG_HEAD_SIZE   11
#define SHORT_HEAD_SIZE   7
#define FILE_HEAD_SIZE   21
#define MARKER_HEAD_SIZE   (sizeof(good_marker_head)/sizeof(avbyte))
#define BI(ptr, i)   ((avbyte) (ptr)[i])
#define BYTE(ptr)   (BI(ptr,0))
#define DBYTE(ptr)   ((avushort)(BI(ptr,0) | (BI(ptr,1)<<8)))
#define QBYTE(ptr)
#define bh_CRC(bh)   DBYTE(bh )
#define bh_type(bh)   BYTE (bh + 2)
#define bh_flags(bh)   DBYTE(bh + 3)
#define bh_headsize(bh)   DBYTE(bh + 5)
#define bh_addsize(bh)   QBYTE(bh + 7)
#define bh_size(bh)   (bh_headsize(bh) + bh_addsize(bh))
#define fh_origsize(fh)   QBYTE(fh )
#define fh_hostos(fh)   BYTE (fh + 4)
#define fh_CRC(fh)   QBYTE(fh + 5)
#define fh_time(fh)   QBYTE(fh + 9)
#define fh_version(fh)   BYTE (fh + 13)
#define fh_method(fh)   BYTE (fh + 14)
#define fh_namelen(fh)   DBYTE(fh + 15)
#define fh_attr(fh)   QBYTE(fh + 17)
#define dos_ftsec(ft)   (int)( 2 * ((ft >> 0) & 0x1F))
#define dos_ftmin(ft)   (int)( ((ft >> 5) & 0x3F))
#define dos_fthour(ft)   (int)( ((ft >> 11) & 0x1F))
#define dos_ftday(ft)   (int)( ((ft >> 16) & 0x1F))
#define dos_ftmonth(ft)   (int)(-1 + ((ft >> 21) & 0x0F))
#define dos_ftyear(ft)   (int)(80 + ((ft >> 25) & 0x7F))
#define B_MARKER   0x72
#define B_MAIN   0x73
#define B_FILE   0x74
#define B_COMMENT   0x75
#define B_EXTRA_INFO   0x76
#define B_SUB   0x77
#define B_RECOVERY   0x78
#define FB_OUTDATED   0x4000
#define FB_WITH_BODY   0x8000
#define FA_IS_VOLUME   0x01
#define FA_WITH_COMMENT   0x02
#define FA_IS_SOLID   0x04
#define FA_WITH_AUTHENTICITY   0x20
#define FF_CONT_FROM_PREV   0x01
#define FF_CONT_IN_NEXT   0x02
#define FF_WITH_PASSWORD   0x04
#define FF_WITH_COMMENT   0x08
#define FF_IS_SOLID   0x10
#define M_STORE   0x30
#define M_FASTEST   0x31
#define M_FAST   0x32
#define M_NORMAL   0x33
#define M_GOOD   0x34
#define M_BEST   0x35
#define OS_MSDOS   0
#define OS_OS2   1
#define OS_WIN32   2
#define OS_UNIX   3
#define CRC_START   0xFFFFFFFFUL
#define CRC_INIT   0xEDB88320UL
#define CRC_TABLESIZE   256

Typedefs

typedef avbyte block_header [LONG_HEAD_SIZE]
typedef avbyte file_header [FILE_HEAD_SIZE]

Functions

static void initCRC (void)
static avuint CRC_byte (avuint crc, avbyte byte)
static avuint CRC_string (avuint crc, avbyte *buf, long size)
static int read_block_header (vfile *vf, block_header bh, int all)
static int read_marker_block (vfile *vf)
static int read_archive_header (vfile *vf)
static void conv_tolower (char *s)
static void dos2unix_path (char *path)
static avtime_t dos2unix_time (avuint dt)
static avmode_t dos2unix_attr (avuint da, avmode_t archmode)
static void rarnode_delete (struct rarnode *info)
static avmode_t rar_get_mode (struct rar_entinfo *ei, avmode_t origmode)
static void fill_rarentry (struct archive *arch, struct entry *ent, struct rar_entinfo *ei)
static void insert_rarentry (struct archive *arch, struct rar_entinfo *ei)
static int crc_additional_header (vfile *vf, struct rar_entinfo *ei, int bytes_crcd, avuint *crc)
static int read_rarentry (vfile *vf, struct rar_entinfo *ei)
static int read_rarfile (vfile *vf, struct archive *arch)
static int parse_rarfile (void *data, ventry *ve, struct archive *arch)
static int get_rar_file (ventry *ve, struct archfile *fil, int fd)
static int do_unrar (ventry *ve, struct archfile *fil)
static int rar_open (ventry *ve, struct archfile *fil)
static int rar_close (struct archfile *fil)
static avssize_t rar_read (vfile *vf, char *buf, avsize_t nbyte)
int av_init_module_urar (struct vmodule *module)

Variables

static avbyte good_marker_head []
static avuint CRC_table [CRC_TABLESIZE]

Class Documentation

struct rarnode

Definition at line 109 of file urar.c.

Class Members
avushort flags
avbyte hostos
avbyte method
avbyte packer_version
char * path
struct rar_entinfo

Definition at line 117 of file urar.c.

Class Members
block_header bh
avoff_t datastart
file_header fh
char * linkname
char * name
struct rarfile

Definition at line 125 of file urar.c.

Class Members
int fd
char * tmpfile

Define Documentation

#define B_COMMENT   0x75

Definition at line 67 of file urar.c.

#define B_EXTRA_INFO   0x76

Definition at line 68 of file urar.c.

#define B_FILE   0x74

Definition at line 66 of file urar.c.

#define B_MAIN   0x73

Definition at line 65 of file urar.c.

#define B_MARKER   0x72

Definition at line 64 of file urar.c.

#define B_RECOVERY   0x78

Definition at line 70 of file urar.c.

#define B_SUB   0x77

Definition at line 69 of file urar.c.

#define bh_addsize (   bh)    QBYTE(bh + 7)

Definition at line 44 of file urar.c.

#define bh_CRC (   bh)    DBYTE(bh )

Definition at line 40 of file urar.c.

#define bh_flags (   bh)    DBYTE(bh + 3)

Definition at line 42 of file urar.c.

#define bh_headsize (   bh)    DBYTE(bh + 5)

Definition at line 43 of file urar.c.

#define bh_size (   bh)    (bh_headsize(bh) + bh_addsize(bh))

Definition at line 45 of file urar.c.

#define bh_type (   bh)    BYTE (bh + 2)

Definition at line 41 of file urar.c.

#define BI (   ptr,
 
)    ((avbyte) (ptr)[i])

Definition at line 34 of file urar.c.

#define BYTE (   ptr)    (BI(ptr,0))

Definition at line 35 of file urar.c.

#define CRC_INIT   0xEDB88320UL

Definition at line 104 of file urar.c.

#define CRC_START   0xFFFFFFFFUL

Definition at line 103 of file urar.c.

#define CRC_TABLESIZE   256

Definition at line 106 of file urar.c.

#define DBYTE (   ptr)    ((avushort)(BI(ptr,0) | (BI(ptr,1)<<8)))

Definition at line 36 of file urar.c.

#define DOS_DIR_SEP_CHAR   '\\'

Definition at line 21 of file urar.c.

#define dos_ftday (   ft)    (int)( ((ft >> 16) & 0x1F))

Definition at line 59 of file urar.c.

#define dos_fthour (   ft)    (int)( ((ft >> 11) & 0x1F))

Definition at line 58 of file urar.c.

#define dos_ftmin (   ft)    (int)( ((ft >> 5) & 0x3F))

Definition at line 57 of file urar.c.

#define dos_ftmonth (   ft)    (int)(-1 + ((ft >> 21) & 0x0F))

Definition at line 60 of file urar.c.

#define dos_ftsec (   ft)    (int)( 2 * ((ft >> 0) & 0x1F))

Definition at line 56 of file urar.c.

#define dos_ftyear (   ft)    (int)(80 + ((ft >> 25) & 0x7F))

Definition at line 61 of file urar.c.

#define FA_IS_SOLID   0x04

Definition at line 79 of file urar.c.

#define FA_IS_VOLUME   0x01

Definition at line 77 of file urar.c.

#define FA_WITH_AUTHENTICITY   0x20

Definition at line 80 of file urar.c.

#define FA_WITH_COMMENT   0x02

Definition at line 78 of file urar.c.

#define FB_OUTDATED   0x4000

Definition at line 73 of file urar.c.

#define FB_WITH_BODY   0x8000

Definition at line 74 of file urar.c.

#define FF_CONT_FROM_PREV   0x01

Definition at line 83 of file urar.c.

#define FF_CONT_IN_NEXT   0x02

Definition at line 84 of file urar.c.

#define FF_IS_SOLID   0x10

Definition at line 87 of file urar.c.

#define FF_WITH_COMMENT   0x08

Definition at line 86 of file urar.c.

#define FF_WITH_PASSWORD   0x04

Definition at line 85 of file urar.c.

#define fh_attr (   fh)    QBYTE(fh + 17)

Definition at line 54 of file urar.c.

#define fh_CRC (   fh)    QBYTE(fh + 5)

Definition at line 49 of file urar.c.

#define fh_hostos (   fh)    BYTE (fh + 4)

Definition at line 48 of file urar.c.

#define fh_method (   fh)    BYTE (fh + 14)

Definition at line 52 of file urar.c.

#define fh_namelen (   fh)    DBYTE(fh + 15)

Definition at line 53 of file urar.c.

#define fh_origsize (   fh)    QBYTE(fh )

Definition at line 47 of file urar.c.

#define fh_time (   fh)    QBYTE(fh + 9)

Definition at line 50 of file urar.c.

#define fh_version (   fh)    BYTE (fh + 13)

Definition at line 51 of file urar.c.

#define FILE_HEAD_SIZE   21

Definition at line 28 of file urar.c.

#define LONG_HEAD_SIZE   11

Definition at line 26 of file urar.c.

#define M_BEST   0x35

Definition at line 95 of file urar.c.

#define M_FAST   0x32

Definition at line 92 of file urar.c.

#define M_FASTEST   0x31

Definition at line 91 of file urar.c.

#define M_GOOD   0x34

Definition at line 94 of file urar.c.

#define M_NORMAL   0x33

Definition at line 93 of file urar.c.

#define M_STORE   0x30

Definition at line 90 of file urar.c.

#define MARKER_HEAD_SIZE   (sizeof(good_marker_head)/sizeof(avbyte))

Definition at line 29 of file urar.c.

#define OS_MSDOS   0

Definition at line 98 of file urar.c.

#define OS_OS2   1

Definition at line 99 of file urar.c.

#define OS_UNIX   3

Definition at line 101 of file urar.c.

#define OS_WIN32   2

Definition at line 100 of file urar.c.

#define QBYTE (   ptr)
Value:
((avuint)(BI(ptr,0) | (BI(ptr,1)<<8) | \
                   (BI(ptr,2)<<16) | (BI(ptr,3)<<24)))

Definition at line 37 of file urar.c.

#define SHORT_HEAD_SIZE   7

Definition at line 27 of file urar.c.


Typedef Documentation

Definition at line 31 of file urar.c.

Definition at line 32 of file urar.c.


Function Documentation

int av_init_module_urar ( struct vmodule module)

Definition at line 672 of file urar.c.

{
    int res;
    struct avfs *avfs;
    struct ext_info rarexts[3];
    struct archparams *ap;

    rarexts[0].from = ".rar",  rarexts[0].to = NULL;
    rarexts[1].from = ".sfx",  rarexts[1].to = NULL;
    rarexts[2].from = NULL;

    res = av_archive_init("urar", rarexts, AV_VER, module, &avfs);
    if(res < 0)
        return res;
    
    ap = (struct archparams *) avfs->data;
    ap->parse = parse_rarfile;
    ap->open = rar_open;
    ap->close = rar_close;
    ap->read = rar_read;

    initCRC();

    av_add_avfs(avfs);

    return 0;
}

Here is the call graph for this function:

static void conv_tolower ( char *  s) [static]

Definition at line 245 of file urar.c.

{
    for(; *s; s++) *s = tolower((int) *s);
}

Here is the caller graph for this function:

static int crc_additional_header ( vfile *  vf,
struct rar_entinfo ei,
int  bytes_crcd,
avuint crc 
) [static]

Definition at line 357 of file urar.c.

{
    /* In the header there are some optional entries (e.g. salt, exttime; see arcread.ccp::ReadHeader
     * from unrar package). We need to use these bytes for the CRC.
     * Currently this optional stuff is not supported and I don't want to
     * add additional code to handle these information so I just read the
     * remaining bytes up to bh_headsize
     *
     * TODO: The salt is needed for crypted files which are not supported right now
     *       so this is not a problem.
     *       But perhaps it is a good idea to support the additional time information.
     */
    int res, tlen = bytes_crcd;
    avbyte *tempbuf;
    
    tlen = bh_headsize(ei->bh) - 2 - tlen;
    
    if(tlen > 0) {
        tempbuf = av_malloc(tlen);
       res = av_read_all(vf, (char*)tempbuf, tlen);
       if(res < 0) {
           av_free(tempbuf);
           return res;
       }
       *crc = CRC_string(*crc, tempbuf, tlen);
       av_free(tempbuf);
    } else if(tlen < 0) {
        return -EIO;
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avuint CRC_byte ( avuint  crc,
avbyte  byte 
) [static]

Definition at line 143 of file urar.c.

{
    return CRC_table[(avbyte)crc ^ byte] ^ (crc >> 8);
}

Here is the caller graph for this function:

static avuint CRC_string ( avuint  crc,
avbyte buf,
long  size 
) [static]

Definition at line 148 of file urar.c.

{
    long i;

    for (i = 0; i < size; i++)
        crc = CRC_byte(crc, buf[i]);
    return crc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_unrar ( ventry *  ve,
struct archfile fil 
) [static]

Definition at line 579 of file urar.c.

{
    int res;
    struct rarfile *rfil;
    char *tmpfile;
    int fd;

    res = av_get_tmpfile(&tmpfile);
    if(res < 0)
        return res;

    fd = open(tmpfile, O_RDWR | O_CREAT | O_TRUNC, 0644);
    if(fd == -1) {
        res = -errno; 
        av_log(AVLOG_ERROR, "RAR: Could not open %s: %s", tmpfile,
               strerror(errno));
        av_del_tmpfile(tmpfile);
        return res;
    }

    res = get_rar_file(ve, fil, fd);
    if(res < 0) {
        close(fd);
        av_del_tmpfile(tmpfile);
        return res;
    }

    AV_NEW(rfil);
    rfil->tmpfile = tmpfile;
    rfil->fd = fd;

    fil->data = rfil;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avmode_t dos2unix_attr ( avuint  da,
avmode_t  archmode 
) [static]

Definition at line 273 of file urar.c.

{
    avmode_t mode = (archmode & 0666);
    if (da & 0x01) mode = mode & ~0222;
    if (da & 0x10) mode = mode | ((mode & 0444) >> 2) | AV_IFDIR;
    else mode |= AV_IFREG;

    return mode;
}

Here is the caller graph for this function:

static void dos2unix_path ( char *  path) [static]

Definition at line 251 of file urar.c.

{
    char *pos = path;

    while((pos = strchr(pos, DOS_DIR_SEP_CHAR)) != NULL)
        *pos = '/';
}

Here is the caller graph for this function:

static avtime_t dos2unix_time ( avuint  dt) [static]

Definition at line 259 of file urar.c.

{
    struct avtm ut;

    ut.sec = dos_ftsec(dt);
    ut.min = dos_ftmin(dt);
    ut.hour = dos_fthour(dt);
    ut.day = dos_ftday(dt);
    ut.mon = dos_ftmonth(dt);
    ut.year = dos_ftyear(dt);

    return av_mktime(&ut);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fill_rarentry ( struct archive arch,
struct entry ent,
struct rar_entinfo ei 
) [static]

Definition at line 300 of file urar.c.

{
    struct rarnode *info;
    struct archnode *nod;
    int isdir = AV_ISDIR(rar_get_mode(ei, 0));

    nod = av_arch_new_node(arch, ent, isdir);

    nod->st.mode = rar_get_mode(ei, nod->st.mode);
    nod->st.mtime.sec = dos2unix_time(fh_time(ei->fh));
    nod->st.mtime.nsec = 0;
    nod->st.atime = nod->st.mtime;
    nod->st.ctime = nod->st.mtime;
    nod->st.size = fh_origsize(ei->fh);
    nod->st.blocks = AV_BLOCKS(nod->st.size);
    nod->st.blksize = 4096;

    nod->offset = ei->datastart;
    if(fh_method(ei->fh) == M_STORE)
        nod->realsize = fh_origsize(ei->fh);
    else
        nod->realsize = 0;

    nod->linkname = av_strdup(ei->linkname);

    AV_NEW_OBJ(info, rarnode_delete);
    nod->data = info;

    info->flags = bh_flags(ei->bh);
    info->hostos = fh_hostos(ei->fh);
    info->packer_version = fh_version(ei->fh);
    info->method = fh_method(ei->fh);
    info->path = av_strdup(ei->name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_rar_file ( ventry *  ve,
struct archfile fil,
int  fd 
) [static]

Definition at line 511 of file urar.c.

{
    int res;
    struct rarnode *info = (struct rarnode *) fil->nod->data;
    struct realfile *rf;
    const char *prog[7];
    struct proginfo pri;
    static int rar_available = 1;

    res = av_get_realfile(ve->mnt->base, &rf);
    if(res < 0)
        return res;

    /* prepare arguments */
    prog[0] = "rar";
    prog[1] = "p";
    prog[2] = "-c-";
    prog[3] = "-ierr";
    prog[4] = rf->name;
    prog[5] = info->path;
    prog[6] = NULL;
 
    if(rar_available) {
        av_init_proginfo(&pri);
        pri.prog = prog;
        pri.ifd = open("/dev/null", O_RDONLY);
        pri.ofd = fd;
        pri.efd = pri.ifd;
        
        res = av_start_prog(&pri);
        close(pri.ifd);
        
        if(res == 0)
            res = av_wait_prog(&pri, 0, 0);
    } else {
        /* force unrar execution */
        res = -EIO;
    }
    
    if(res == -EIO)
    {
        /* rar failed or unavailable, try unrar */
        rar_available = 0;
        
        prog[0] = "unrar";
        av_init_proginfo(&pri);
        pri.prog = prog;
        pri.ifd = open("/dev/null", O_RDONLY);
        pri.ofd = fd;
        pri.efd = pri.ifd;
        
        res = av_start_prog(&pri);
        close(pri.ifd);
        
        if(res == 0)
            res = av_wait_prog(&pri, 0, 0);

        if(res == -EIO) {
            /* unrar failed too so reset rar_available */
            rar_available = 1;
        }
    }

    av_unref_obj(rf);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void initCRC ( void  ) [static]

Definition at line 130 of file urar.c.

{
    int i, j;
    avuint c;
  
    for (i = 0; i < CRC_TABLESIZE; i++)
    {
        for (c = i, j = 0; j < 8; j++)
            c = (c & 1) ? (c >> 1) ^ CRC_INIT : (c >> 1);
        CRC_table[i] = c;
    }
}

Here is the caller graph for this function:

static void insert_rarentry ( struct archive arch,
struct rar_entinfo ei 
) [static]

Definition at line 336 of file urar.c.

{
    struct entry *ent;
    int entflags = 0;
    char *path = ei->name;

    dos2unix_path(path);

    if(fh_hostos(ei->fh) == OS_MSDOS) {
        conv_tolower(path);
        entflags |= NSF_NOCASE;
    }

    ent = av_arch_create(arch, path, entflags);
    if(ent == NULL)
        return;

    fill_rarentry(arch, ent, ei);
    av_unref_obj(ent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_rarfile ( void *  data,
ventry *  ve,
struct archive arch 
) [static]

Definition at line 492 of file urar.c.

{
    int res;
    vfile *vf;

    res = av_open(ve->mnt->base, AVO_RDONLY, 0, &vf);
    if(res < 0)
        return res;

    res = read_rarfile(vf, arch);

    av_close(vf);
    
    return res;  
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rar_close ( struct archfile fil) [static]

Definition at line 636 of file urar.c.

{
    struct rarfile *rfil = (struct rarfile *) fil->data;

    if(rfil != NULL) {
        close(rfil->fd);
        av_del_tmpfile(rfil->tmpfile);
        av_free(rfil);
    }
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avmode_t rar_get_mode ( struct rar_entinfo ei,
avmode_t  origmode 
) [static]

Definition at line 288 of file urar.c.

{
    if (bh_flags(ei->bh) & FF_WITH_PASSWORD)
        return AV_IFREG; /* FIXME */
    else {
        if (fh_hostos(ei->fh) == OS_UNIX)
            return fh_attr(ei->fh);
        else 
            return dos2unix_attr(fh_attr(ei->fh), origmode);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rar_open ( ventry *  ve,
struct archfile fil 
) [static]

Definition at line 616 of file urar.c.

{
    struct rarnode *info = (struct rarnode *) fil->nod->data;

    if(info == NULL) {
        /* access to base rar directory */
        return -EISDIR;
    }
    
    if(info->flags & FF_WITH_PASSWORD) {
        av_log(AVLOG_WARNING, "URAR: File password protected, sorry...");
        return -EACCES;
    }

    if(info->method != M_STORE)
        return do_unrar(ve, fil);
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static avssize_t rar_read ( vfile *  vf,
char *  buf,
avsize_t  nbyte 
) [static]

Definition at line 649 of file urar.c.

{
    avssize_t res;
    struct archfile *fil = arch_vfile_file(vf);
    struct rarfile *rfil = (struct rarfile *) fil->data;

    if(rfil == NULL)
        return av_arch_read(vf, buf, nbyte);

    if(lseek(rfil->fd, vf->ptr, SEEK_SET) == -1)
        return -errno;

    res = read(rfil->fd, buf, nbyte);
    if(res == -1)
        return -errno;

    vf->ptr += res;

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rarnode_delete ( struct rarnode info) [static]

Definition at line 283 of file urar.c.

{
    av_free(info->path);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_archive_header ( vfile *  vf) [static]

Definition at line 210 of file urar.c.

{
    int res;
    block_header main_head;
    avuint crc;
    avbyte tmpbuf[6];
    int headlen;

    headlen = read_block_header(vf, main_head, 1);
    if(headlen < 0)
        return headlen;

    if (bh_type(main_head) != B_MAIN) {
        av_log(AVLOG_ERROR, "URAR: Bad archive header");
        return -EIO;
    }

    crc = CRC_string(CRC_START, main_head + 2, headlen - 2);

    /* Read reserved bytes. */
    res = av_read_all(vf, (char*)tmpbuf, 6);
    if(res < 0)
        return res;
    crc = CRC_string(crc, tmpbuf, 6);

    if ((avushort)~crc != bh_CRC(main_head)) {
        av_log(AVLOG_ERROR, "URAR: Bad archive header CRC");
        return -EIO;
    }

    av_lseek(vf, bh_size(main_head) - headlen - 6, AVSEEK_CUR);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_block_header ( vfile *  vf,
block_header  bh,
int  all 
) [static]

Definition at line 157 of file urar.c.

{
    int res;
    int size = SHORT_HEAD_SIZE;
    int i;

    for(i = SHORT_HEAD_SIZE; i < LONG_HEAD_SIZE; i++) bh[i] = 0;

    if(all)
        res = av_read_all(vf, (char*)bh, SHORT_HEAD_SIZE);
    else
        res = av_read(vf, (char*)bh, SHORT_HEAD_SIZE);
    if(res < 0)
        return res;
    if(res < SHORT_HEAD_SIZE)
        return 0;

    if ((bh_flags(bh) & FB_WITH_BODY) != 0) {
        res = av_read_all(vf, (char*) ( bh+SHORT_HEAD_SIZE ), 4);
        if(res < 0)
            return res;

        size += 4;
    }

    return size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_marker_block ( vfile *  vf) [static]

Definition at line 185 of file urar.c.

{
    int res;
    avbyte buf[MARKER_HEAD_SIZE], *pos = buf;
    int readsize = MARKER_HEAD_SIZE;

    /* An SFX module starts with the extraction header. Skip that part by
       searching for the marker head. */
    while(1) {
        res = av_read_all(vf, (char*)( buf + MARKER_HEAD_SIZE - readsize ), readsize);
        if(res < 0)
            return res;

        if (memcmp(buf, good_marker_head, MARKER_HEAD_SIZE) == 0) return 0;

        pos = memchr(buf + 1, good_marker_head[0], MARKER_HEAD_SIZE-1);
        if (pos == NULL) readsize = MARKER_HEAD_SIZE;
        else {
            readsize = pos - buf;
            memmove(buf, pos, MARKER_HEAD_SIZE - readsize);
        }
    }
    return 0; /* Just to avoid warnings. Never reaches this line. */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_rarentry ( vfile *  vf,
struct rar_entinfo ei 
) [static]

Definition at line 389 of file urar.c.

{
    int res;
    block_header ch;
    avuint crc;

    if (bh_size(ei->bh) < LONG_HEAD_SIZE + FILE_HEAD_SIZE) {
        av_log(AVLOG_ERROR, "URAR: bad header");
        return -EIO;
    }
            
    res = av_read_all(vf, (char*)( ei->fh ), FILE_HEAD_SIZE);
    if(res < 0)
        return res;

    ei->name = av_malloc(fh_namelen(ei->fh)+1);
    res = av_read_all(vf, ei->name, fh_namelen(ei->fh));
    if(res < 0)
        return res;
    ei->name[fh_namelen(ei->fh)] = '\0';
    
    crc = CRC_string(CRC_START, ei->bh + 2, LONG_HEAD_SIZE - 2);
    crc = CRC_string(crc, ei->fh, FILE_HEAD_SIZE);
    crc = CRC_string(crc, (avbyte*)( ei->name ), fh_namelen(ei->fh));

    if(crc_additional_header(vf, ei,
                          LONG_HEAD_SIZE - 2 + FILE_HEAD_SIZE + fh_namelen(ei->fh),
                          &crc) != 0) {
        av_log(AVLOG_ERROR, "URAR: bad header");
        return -EIO;
    }
    
    if ((avushort)~crc != bh_CRC(ei->bh)) {
        av_log(AVLOG_ERROR, "URAR: bad CRC");
        return -EIO;
    }
    
    if ((bh_flags(ei->bh) & FF_WITH_COMMENT) != 0) {
        res = read_block_header(vf, ch, 1);
        if(res < 0)
            return res;

        av_lseek(vf, bh_size(ch) - res, AVSEEK_CUR);
    }
    
    if(fh_hostos(ei->fh) == OS_UNIX && AV_ISLNK(fh_attr(ei->fh))) {
        ei->linkname = av_malloc(fh_origsize(ei->fh) + 1);
        res = av_read_all(vf, ei->linkname, fh_origsize(ei->fh));
        if(res < 0)
            return res;

        ei->linkname[fh_origsize(ei->fh)] = '\0';
    }
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_rarfile ( vfile *  vf,
struct archive arch 
) [static]

Definition at line 446 of file urar.c.

{
    avoff_t headstart;
    int res;

    res = read_marker_block(vf);
    if(res < 0)
        return res;

    res = read_archive_header(vf);
    if(res < 0)
        return res;

    headstart = vf->ptr;
    while(1) {
        struct rar_entinfo ei;
    
        res = read_block_header(vf, ei.bh, 0);
        if(res < 0)
            return res;
        if(res == 0)
            break;

        if (bh_type(ei.bh) == B_FILE) {
            ei.name = NULL;
            ei.linkname = NULL;

            res = read_rarentry(vf, &ei);
            if(res < 0) {
                av_free(ei.name);
                av_free(ei.linkname);
                return res;
            }
            ei.datastart = vf->ptr;

            insert_rarentry(arch, &ei);
            av_free(ei.name);
            av_free(ei.linkname);
        }
        av_lseek(vf, headstart + bh_size(ei.bh), AVSEEK_SET);
        headstart = vf->ptr;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 107 of file urar.c.

Initial value:
 
{ 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }

Definition at line 23 of file urar.c.