Back to index

avfs  1.0.1
Classes | Functions | Variables
parse.c File Reference
#include "internal.h"
#include "version.h"
#include "local.h"
#include "mod_static.h"
#include "operutil.h"
#include "oper.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

Go to the source code of this file.

Classes

struct  avfs_list
struct  parse_state

Functions

static AV_LOCK_DECL (initlock)
static AV_LOCK_DECL (avfs_lock)
static int copyrightstat_get (struct entry *ent, const char *param, char **retp)
static int modstat_get (struct entry *ent, const char *param, char **retp)
static int versionstat_get (struct entry *ent, const char *param, char **retp)
static int symlinkrewrite_get (struct entry *ent, const char *param, char **retp)
static int symlinkrewrite_set (struct entry *ent, const char *param, const char *val)
static void init_stats ()
static void destroy ()
static int init ()
void av_add_avfs (struct avfs *newavfs)
static int av_copy_parsestate (struct parse_state *ps, struct parse_state *destps)
static void set_prevseg (struct parse_state *ps, const char *name)
static int lookup_virtual (struct parse_state *ps, const char *name)
static struct avmountnew_mount (ventry *base, struct avfs *avfs, const char *opts)
static int is_root (ventry *ve)
static int enter_mount (struct parse_state *ps, struct avfs *avfs, const char *opts, const char *param)
static struct ext_infofind_ext (struct ext_info *exts, const char *prevseg)
static struct avfsfind_auto_avfs (const char *prevseg, struct ext_info **extp)
static void get_new_name (struct parse_state *ps, struct ext_info *ext)
static int lookup_auto_avfs (struct parse_state *ps, const char *opts, const char *param)
static int is_handler_char (int ch)
static struct avfsfind_avfs_name (char *name)
static int is_special (const char *name)
static int lookup_avfs (struct parse_state *ps, char *name)
static int lookup_segment (struct parse_state *ps, int noavfs)
static int segment_islocal (struct parse_state *ps, unsigned int seglen)
static unsigned int segment_len (struct parse_state *ps, int ignoreMagic)
static int is_last (struct parse_state *ps, unsigned int seglen)
static struct avfsget_local_avfs ()
static int parse_path (struct parse_state *ps, int force_localfile)
static int follow_link (struct parse_state *ps)
int av_get_ventry (const char *path, int resolvelast, ventry **resp)
int av_copy_vmount (struct avmount *mnt, struct avmount **resp)
int av_copy_ventry (ventry *ve, ventry **resp)
void av_free_vmount (struct avmount *mnt)
void av_free_ventry (ventry *ve)
static int ipath_len (const char *s)
static void ipath_copy (char *dst, const char *src)
static char * expand_segment (char *segment)
static int add_segment (ventry *ve, char **pathp)
int av_generate_path (ventry *ve, char **pathp)
int av_get_symlink_rewrite ()

Variables

static int inited
static struct avfs_list
static int symlink_rewrite = 0

Class Documentation

struct avfs_list

Definition at line 28 of file parse.c.

Collaboration diagram for avfs_list:
Class Members
struct avfs * avfs
struct avfs_list * next
struct avfs_list * prev
struct parse_state

Definition at line 38 of file parse.c.

Class Members
int first_seg
int islink
int linkctr
int nextseg
char * path
char * prevseg
int resolvelast
ventry * ve

Function Documentation

static int add_segment ( ventry *  ve,
char **  pathp 
) [static]

Definition at line 940 of file parse.c.

{
    int res;
    char *segment;
    struct avfs *avfs = ve->mnt->avfs;

    if(ve->data != NULL) {
        AVFS_LOCK(avfs);
        res = avfs->getpath(ve, &segment);
        AVFS_UNLOCK(avfs);
        if(res < 0)
            return res;
    }
    else 
        segment = av_strdup("");

    if(ve->mnt->base == NULL)
       *pathp = av_stradd(*pathp, segment, NULL);
    else {
       char *avfsname = avfs->name;
       char *opts = ve->mnt->opts;
       char avfssep[] = { AVFS_SEP_CHAR, '\0' };
        const char *paramsep;
        
        if(segment[0] && segment[0] != AV_DIR_SEP_CHAR)
            paramsep = ":";
        else
            paramsep = "";
       
        segment = expand_segment(segment);
       
       *pathp = av_stradd(*pathp, avfssep, avfsname, opts, paramsep,
                             segment, NULL);
    }
    av_free(segment);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_add_avfs ( struct avfs newavfs)

Definition at line 247 of file parse.c.

{
    struct avfs_list *li;

    AV_NEW(li);
    AV_LOCK(avfs_lock);
    li->avfs = newavfs;
    li->next = &avfs_list;
    li->prev = avfs_list.prev;
    avfs_list.prev = li;
    li->prev->next = li;
    AV_UNLOCK(avfs_lock);
}

Here is the caller graph for this function:

static int av_copy_parsestate ( struct parse_state ps,
struct parse_state destps 
) [static]

Definition at line 261 of file parse.c.

{
    destps->linkctr = ps->linkctr;
    destps->nextseg = ps->nextseg;
    destps->resolvelast = ps->resolvelast;
    destps->islink = ps->islink;

    if(ps->path)
      destps->path = av_strdup(ps->path);
    else
      destps->path = NULL;

    destps->first_seg = ps->first_seg;

    if(ps->prevseg)
      destps->prevseg = av_strdup(ps->prevseg);
    else
      destps->prevseg = NULL;

    av_copy_ventry(ps->ve, &(destps->ve));
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int av_copy_ventry ( ventry *  ve,
ventry **  resp 
)

Definition at line 854 of file parse.c.

{
    int res;
    ventry *newve;
    struct avmount *newmnt;
    void *newdata;
    struct avfs *avfs = ve->mnt->avfs;

    res = av_copy_vmount(ve->mnt, &newmnt);
    if(res < 0)
       return res;

    if(ve->data != NULL) {
        AVFS_LOCK(avfs);
        res = avfs->copyent(ve, &newdata);
        AVFS_UNLOCK(avfs);
        if(res < 0)
            return res;
    }
    else
       newdata = NULL;
    
    AV_NEW(newve);
    
    newve->data = newdata;
    newve->mnt = newmnt;

    *resp = newve;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int av_copy_vmount ( struct avmount mnt,
struct avmount **  resp 
)

Definition at line 834 of file parse.c.

{
    int res;
    ventry *newbase;
    
    if(mnt->base != NULL) {
        res = av_copy_ventry(mnt->base, &newbase);
        if(res < 0)
            return res;
    }
    else
        newbase = NULL;

    av_ref_obj(mnt->avfs);

    *resp = new_mount(newbase, mnt->avfs, mnt->opts);
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_free_ventry ( ventry *  ve)

Definition at line 895 of file parse.c.

{
    if(ve != NULL) {
       struct avfs *avfs = ve->mnt->avfs;

        if(ve->data != NULL) {
            AVFS_LOCK(avfs);
            avfs->putent(ve);
            AVFS_UNLOCK(avfs);
        }

        av_free_vmount(ve->mnt);
        av_free(ve);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void av_free_vmount ( struct avmount mnt)

Definition at line 886 of file parse.c.

{
    av_unref_obj(mnt->avfs);

    av_free(mnt->opts);
    av_free_ventry(mnt->base);
    av_free(mnt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int av_generate_path ( ventry *  ve,
char **  pathp 
)

Definition at line 979 of file parse.c.

{
    int res;

    if(ve == NULL) 
        *pathp = NULL;
    else {
        res = av_generate_path(ve->mnt->base, pathp);
        if(res < 0)
            return res;

        res = add_segment(ve, pathp);
        if(res < 0) {
            av_free(*pathp);
            return res;
        }
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1000 of file parse.c.

{
    return symlink_rewrite;
}

Here is the caller graph for this function:

int av_get_ventry ( const char *  path,
int  resolvelast,
ventry **  resp 
)

Definition at line 783 of file parse.c.

{
    int res;
    struct parse_state ps;
    char *copypath;

    res = init();
    if(res < 0)
        return res;

    if(path == NULL)
        return -ENOENT;

    copypath = av_strdup(path);
    ps.path = copypath;
    ps.resolvelast = resolvelast;
    ps.linkctr = 10;

    AV_NEW(ps.ve);
    ps.ve->mnt = new_mount(NULL, get_local_avfs(), NULL);
    ps.ve->data = av_strdup("");

    res = parse_path(&ps, 0);

    /* no ventry so force localfile to be able to create files with
       the magic character inside filename */
    if(res < 0) {
        av_free(copypath);
        copypath = av_strdup(path);
        av_free_ventry(ps.ve);
        ps.path = copypath;
        ps.resolvelast = resolvelast;
        ps.linkctr = 10;
        AV_NEW(ps.ve);
        ps.ve->mnt = new_mount(NULL, get_local_avfs(), NULL);
        ps.ve->data = av_strdup("");
        res = parse_path(&ps, 1);
    }

    if(res < 0) {
        av_free_ventry(ps.ve);
        *resp = NULL;
    }
    else
        *resp = ps.ve;

    av_free(copypath);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static AV_LOCK_DECL ( initlock  ) [static]
static AV_LOCK_DECL ( avfs_lock  ) [static]
static int copyrightstat_get ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 49 of file parse.c.

{
    char buf[256];

    sprintf(buf, 
            "AVFS Virtual File System (C) Miklos Szeredi 1998-2001, Version %i.%i.%i,\n"
            "AVFS comes with ABSOLUTELY NO WARRANTY.\n", 
            AV_VER / 100,
            (AV_VER / 10) % 10,
            AV_VER % 10);
    
    *retp = av_strdup(buf);
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void destroy ( ) [static]

Definition at line 185 of file parse.c.

{
    av_log(AVLOG_DEBUG, "DESTROY");

    AV_LOCK(initlock);
    if(inited) {
        av_close_all_files();

        AV_LOCK(avfs_lock);
        while(avfs_list.next != &avfs_list) {
            struct avfs_list *li = avfs_list.next;

            li->next->prev = li->prev;
            li->prev->next = li->next;
            av_unref_obj(li->avfs);
            av_free(li);
        }
        AV_UNLOCK(avfs_lock);

        av_do_exit();
       av_delete_tmpdir();

        inited = 0;
    }
    AV_UNLOCK(initlock);

    av_check_malloc();
    av_log(AVLOG_DEBUG, "DESTROY successful");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int enter_mount ( struct parse_state ps,
struct avfs avfs,
const char *  opts,
const char *  param 
) [static]

Definition at line 365 of file parse.c.

{
    int res;
    ventry *newve;
    
    AV_NEW(newve);

    newve->mnt = new_mount(ps->ve, avfs, opts);
    newve->data = NULL;

    ps->ve = newve;

    if((avfs->flags & AVF_ONLYROOT) != 0 && !is_root(ps->ve->mnt->base))
        return -ENOENT;

    res = lookup_virtual(ps, param);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* expand_segment ( char *  segment) [static]

Definition at line 929 of file parse.c.

{
    char *tmp;

    tmp = (char *) av_malloc(ipath_len(segment) + 1);
    ipath_copy(tmp, segment);
    av_free(segment);

    return tmp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct avfs* find_auto_avfs ( const char *  prevseg,
struct ext_info **  extp 
) [static, read]

Definition at line 402 of file parse.c.

{
    struct ext_info *exts;
    struct avfs_list *li;

    for(li = avfs_list.next; li != &avfs_list; li = li->next) {
        exts = li->avfs->exts;
        if(exts != NULL) {
            struct ext_info *e;
            e = find_ext(exts, prevseg);
            if(e != NULL) {
                *extp = e;
                return li->avfs;
            }
        }
    }

    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct avfs* find_avfs_name ( char *  name) [static, read]

Definition at line 472 of file parse.c.

{
    struct avfs_list *li;

    if(!*name)
       return NULL;

    AV_LOCK(avfs_lock);
    for(li = avfs_list.next; li != &avfs_list; li = li->next)
       if(li->avfs->name != NULL && 
          strcmp(li->avfs->name, name) == 0) {
            av_ref_obj(li->avfs);
            break;
        }
    AV_UNLOCK(avfs_lock);
    
    return li->avfs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct ext_info* find_ext ( struct ext_info exts,
const char *  prevseg 
) [static, read]

Definition at line 386 of file parse.c.

{
    int ei;
    unsigned int prevseglen = strlen(prevseg);

    for(ei = 0; exts[ei].from != NULL; ei++) {
        unsigned int extlen = strlen(exts[ei].from);
        if(prevseglen >= extlen) {
            const char *prevsegext = prevseg + prevseglen - extlen;
            if(strncasecmp(prevsegext, exts[ei].from, extlen) == 0)
                return &exts[ei];
        }
    }
    return NULL;
}

Here is the caller graph for this function:

static int follow_link ( struct parse_state ps) [static]

Definition at line 697 of file parse.c.

{
    int res;
    struct parse_state linkps;
    char *buf;

    if(!ps->linkctr)
        return -ELOOP;

    res = av_readlink(ps->ve, &buf);
    if(res < 0)
        return res;

    linkps.path = buf;
    linkps.resolvelast = 1;
    linkps.linkctr = ps->linkctr - 1;

    if(buf[0] != AV_DIR_SEP_CHAR) {
        linkps.ve = ps->ve;
        
        res = lookup_virtual(&linkps, NULL);
        if(res == 0)
            res = parse_path(&linkps, 0);
    }
    else {
        av_free_ventry(ps->ve);

        AV_NEW(linkps.ve);
        linkps.ve->mnt = new_mount(NULL, get_local_avfs(), NULL);
        linkps.ve->data = av_strdup("");

        res = parse_path(&linkps, 0);
    }

    
    av_free(buf);
    ps->ve = linkps.ve;
    
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct avfs* get_local_avfs ( ) [static, read]

Definition at line 683 of file parse.c.

{
    struct avfs *localavfs;

    AV_LOCK(avfs_lock);
    localavfs = avfs_list.next->avfs;
    av_ref_obj(localavfs);
    AV_UNLOCK(avfs_lock);

    return localavfs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_new_name ( struct parse_state ps,
struct ext_info ext 
) [static]

Definition at line 422 of file parse.c.

{
    unsigned int extlen = strlen(ext->from);
    unsigned int prevseglen = strlen(ps->prevseg);
        
    ps->prevseg[prevseglen - extlen] = '\0';
    if(ext->to != NULL) 
        ps->prevseg = av_stradd(ps->prevseg, ext->to, NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int init ( ) [static]

Definition at line 215 of file parse.c.

{
    int res = 0;

    AV_LOCK(initlock);    
    if(!inited) {
        av_log(AVLOG_DEBUG, "INIT");

        avfs_list.next = &avfs_list;
        avfs_list.prev = &avfs_list;

        res = av_init_module_local();
        if(res == 0) {
            av_init_avfsstat();
            av_init_static_modules();
            av_init_dynamic_modules();
            av_init_logstat();
            init_stats();
            av_init_cache();
            av_init_filecache();
            atexit(destroy);
            inited = 1;
            av_log(AVLOG_DEBUG, "INIT successful");
        }
        else
            av_log(AVLOG_DEBUG, "INIT failed");
    }
    AV_UNLOCK(initlock);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_stats ( ) [static]

Definition at line 164 of file parse.c.

{
    struct statefile statf;
    
    statf.data = NULL;
    statf.set = NULL;

    statf.get = copyrightstat_get;
    av_avfsstat_register("copyright", &statf);
    
    statf.get = modstat_get;
    av_avfsstat_register("modules", &statf);

    statf.get = versionstat_get;
    av_avfsstat_register("version", &statf);

    statf.get = symlinkrewrite_get;
    statf.set = symlinkrewrite_set;
    av_avfsstat_register("symlink_rewrite", &statf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ipath_copy ( char *  dst,
const char *  src 
) [static]

Definition at line 921 of file parse.c.

{
    for(; *src; dst++, src++) {
        *dst = *src;
    }
    *dst = '\0';
}

Here is the caller graph for this function:

static int ipath_len ( const char *  s) [static]

Definition at line 912 of file parse.c.

{
    int cnt;

    for(cnt = 0; *s; s++, cnt++);

    return cnt;
}

Here is the caller graph for this function:

static int is_handler_char ( int  ch) [static]

Definition at line 467 of file parse.c.

{
    return isalpha(ch) || isdigit(ch) || ch == '_';
}

Here is the caller graph for this function:

static int is_last ( struct parse_state ps,
unsigned int  seglen 
) [static]

Definition at line 672 of file parse.c.

{
    const char *s;

    for(s = ps->path + seglen; *s && *s == AV_DIR_SEP_CHAR; s++);
    if(!*s)
        return 1;
    else
        return 0;
}

Here is the caller graph for this function:

static int is_root ( ventry *  ve) [static]

Definition at line 336 of file parse.c.

{
    char *path;
    struct stat pathstat;
    struct stat rootstat;
    int res;

    if(ve->mnt->base != NULL)
       return 0;

    for(path = (char *) ve->data; *path == AV_DIR_SEP_CHAR; path++);
    if(!*path)
       return 1;

    res = stat((char *) ve->data, &pathstat);
    if(res == -1)
       return 0;

    res = stat("/", &rootstat);
    if(res == -1)
       return 0;
    
    if(rootstat.st_dev == pathstat.st_dev &&
       rootstat.st_ino == pathstat.st_ino)
       return 1;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_special ( const char *  name) [static]

Definition at line 491 of file parse.c.

{
    if(name[0] == '.' &&
       (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
       return 1;

    return 0;
}

Here is the caller graph for this function:

static int lookup_auto_avfs ( struct parse_state ps,
const char *  opts,
const char *  param 
) [static]

Definition at line 433 of file parse.c.

{
    int res;
    struct avfs *avfs;
    struct ext_info *ext = NULL;

    AV_LOCK(avfs_lock);
    avfs = find_auto_avfs(ps->prevseg, &ext);
    if(avfs == NULL)
        res = -ENOENT;
    else {
        av_ref_obj(avfs);

        get_new_name(ps, ext);
        if(find_auto_avfs(ps->prevseg, &ext) == NULL)
            set_prevseg(ps, "");
        else {
            param = "";
            ps->nextseg = 0;
        }
        res = 0;
    }
    AV_UNLOCK(avfs_lock);

    if(res == 0) {
        res = enter_mount(ps, avfs, opts, param);
        if(res == 0)
            ps->ve->mnt->flags = 1;
    }

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int lookup_avfs ( struct parse_state ps,
char *  name 
) [static]

Definition at line 500 of file parse.c.

{
    int res;
    char c;
    char *s;
    char *opts;
    const char *param;
    struct avfs *avfs;

    if(is_special(ps->prevseg))
        return -ENOENT;

    for(s = name; *s && is_handler_char(*s); s++);
    opts = s;
    for(; *s && *s != ':'; s++);
    c = *s;
    if(*s == ':') {
        *s = '\0';
        param = s + 1;
        if(*param == '\0' || *param == AV_DIR_SEP_CHAR)
            return -ENOENT;
    }
    else
        param = "";

    if(name == opts) {
        res = lookup_auto_avfs(ps, opts, param);
        *s = c;
        return res;
    }

    c = *opts;
    *s = '\0';
    avfs = find_avfs_name(name);
    *opts = c;

    if(avfs == NULL)
        return -ENOENT;
    
    res = enter_mount(ps, avfs, opts, param);
    set_prevseg(ps, "");

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int lookup_segment ( struct parse_state ps,
int  noavfs 
) [static]

Definition at line 545 of file parse.c.

{
    int res;
    char *name = ps->path;
    ventry *ve = ps->ve;

    /* only enter next avfs hierarchie if the magic char is not the
       very first char (first_seg) and we really want this action
       (noavfs needed by segment_islocal() test */

    if((name[0] == AVFS_SEP_CHAR) && (noavfs == 0) && (ps->first_seg == 0))
      res = lookup_avfs(ps, name+1);
    else {
        /* reset first_seg as we now process a path segment and from now on 
          the next magic char is always the magic char and not from a local
          filename */
        ps->first_seg = 0;

        for(;*name && *name == AV_DIR_SEP_CHAR; name++);
        set_prevseg(ps, name);

       if((ve->mnt->avfs->flags & AVF_NEEDSLASH) != 0)
          name = ps->path;
        
        if(name[0] != '\0')
            res = lookup_virtual(ps, name);
        else
            res = 0;
    }
        
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int lookup_virtual ( struct parse_state ps,
const char *  name 
) [static]

Definition at line 290 of file parse.c.

{
    int res;
    ventry *ve = ps->ve;
    struct avfs *avfs = ve->mnt->avfs;
    void *newdata;

    AVFS_LOCK(avfs);
    res = avfs->lookup(ve, name, &newdata);
    AVFS_UNLOCK(avfs);
    if(res < 0)
        return res;
    
    ve->data = newdata;
    if(ve->data != NULL) {
        if(res == (AV_IFLNK >> 12))
            ps->islink = 1;

        res = 0;
    }
    else {
        ps->ve = ve->mnt->base;
        ve->mnt->base = NULL;
        av_free_ventry(ve);

        res = lookup_virtual(ps, NULL);
    }

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int modstat_get ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 65 of file parse.c.

{
    char *ret = av_strdup("");
    char buf[128];

    struct avfs_list *li;

    AV_LOCK(avfs_lock);
    for(li = avfs_list.next; li != &avfs_list; li = li->next) {
        struct avfs *avfs = li->avfs;
        struct ext_info *exts;
        int ei;
        int ver = avfs->version;

       sprintf(buf, "%2d.%d.%d\t", (ver / 100) % 100, (ver / 10) % 10,
                ver % 10);

        ret = av_stradd(ret, buf, avfs->name, ":\t", NULL);

       exts = avfs->exts;
       if(exts != NULL) 
           for(ei = 0; exts[ei].from != NULL; ei++) {
                ret = av_stradd(ret, exts[ei].from, NULL);
              if(exts[ei].to != NULL)
                    ret = av_stradd(ret, "(", exts[ei].to, ")", NULL);
                
                ret = av_stradd(ret, " ", NULL);
           }

        ret = av_stradd(ret, "\n", NULL);
    }
    AV_UNLOCK(avfs_lock);

    *retp = ret;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct avmount* new_mount ( ventry *  base,
struct avfs avfs,
const char *  opts 
) [static, read]

Definition at line 321 of file parse.c.

{
    struct avmount *mnt;

    AV_NEW(mnt);

    mnt->base = base;
    mnt->avfs = avfs;
    mnt->opts = av_strdup(opts);
    mnt->flags = 0;

    return mnt;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_path ( struct parse_state ps,
int  force_localfile 
) [static]

Definition at line 738 of file parse.c.

{
    int res = 0;
    int numseg = 0;

    ps->prevseg = av_strdup("");
    ps->first_seg = 1;
    while(ps->path[0]) {
        unsigned int seglen;
        int lastseg;
        char c;

       seglen = segment_len(ps, force_localfile);
       
        lastseg = is_last(ps, seglen);
        ps->nextseg = seglen;
        c = ps->path[seglen];
        ps->path[seglen] = '\0';
        ps->islink = 0;
        
        res = lookup_segment(ps,0);
        if(res < 0)
            break;
        
        if(ps->islink && (ps->resolvelast || !lastseg)) {
            res = follow_link(ps);
            if(res < 0) 
                break;
        }
        ps->path[seglen] = c;
        ps->path += ps->nextseg;
        numseg ++;
        
        if(numseg > 1000) {
            av_log(AVLOG_ERROR, "Infinate loop in parse_path");
            res = -EFAULT;
            break;
        }
    }

    av_free(ps->prevseg);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int segment_islocal ( struct parse_state ps,
unsigned int  seglen 
) [static]

Definition at line 578 of file parse.c.

{
    int islocal = 0;
    char c;
    struct parse_state tempps;
    int f;

    /* we will copy the whole parse_state and try to find a local entry
       if open succeed there is a local file and we can return true */

    av_copy_parsestate( ps, &tempps );
    
    tempps.nextseg = seglen;
    c = tempps.path[seglen];
    tempps.path[seglen] = '\0';
    
    /* we force lookup_segment() to not enter any avfs hierarchie */
    lookup_segment(&tempps, 1);
    f = av_fd_open_entry(tempps.ve, AVO_RDONLY, 0);
    av_free_ventry(tempps.ve);
    av_free(tempps.path);
    av_free(tempps.prevseg);
    if ( f >= 0 ) {
      islocal = 1;
      av_fd_close(f);
    }
    return islocal;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned int segment_len ( struct parse_state ps,
int  ignoreMagic 
) [static]

Definition at line 607 of file parse.c.

{
    const char *s = ps->path,
               *first_s = ps->path;
    unsigned int seglen, orig_seglen;
    int found_magic = 0, search_avfs_key = 0;

    /* this function will find the next segment len by also checking for local files
       with magic chars inside the filename
       two cases:
       1.magic at the beginning:
         in this case we are searching for an avfs key (#utar, #ugz...)
        so we will stop at the next magic char or dir separator
        except when this magic char is the very first character
        where it makes no sense to accept this as an avfs key
        (imagine open("#utar"))
        For this case there is a new flag first_seg which takes
        care of this
       2.Otherwise we are searching for the longest path segment
         starting at the next dir separator skipping any magic char
        we stop after first local hit
        If no local file was found we return whole segment len to be able
        to open new files with magic chars
       If no magic char was found or we are forced to ignore it
       we immediately return the whole path segment without any checking
    */

    if(s[0] == AVFS_SEP_CHAR) {
        s++;
       if(ps->first_seg == 0)
            search_avfs_key = 1;
    } else while(*s == AV_DIR_SEP_CHAR)
        s++;
    
    while(*s && *s != AV_DIR_SEP_CHAR) {
        if(*s == AVFS_SEP_CHAR) {
            if(found_magic == 0) {
               first_s = s;
           }
           found_magic++;
        }
        s++;
    }
    seglen = s - ps->path;

    if((ignoreMagic == 1) || (found_magic == 0)) return seglen;

    /* a magic char was already found so first_s is correct */
    if(search_avfs_key == 1)
        return (first_s - ps->path);

    orig_seglen = seglen;
    /* found magic char so check for existing local file */
    while(seglen > 0) {
        if(segment_islocal(ps, seglen) == 1)
           break;
        for(seglen = seglen - 1;
            (seglen > 0) && ( ps->path[seglen] != AVFS_SEP_CHAR );
            seglen--);
    }

    if(seglen > 0) return seglen;
    else return orig_seglen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void set_prevseg ( struct parse_state ps,
const char *  name 
) [static]

Definition at line 284 of file parse.c.

{
    av_free(ps->prevseg);
    ps->prevseg = av_strdup(name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symlinkrewrite_get ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 128 of file parse.c.

{
    char buf[32];
    
    AV_LOCK(avfs_lock);
    sprintf(buf, "%d\n", symlink_rewrite);
    AV_UNLOCK(avfs_lock);

    *retp = av_strdup(buf);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int symlinkrewrite_set ( struct entry ent,
const char *  param,
const char *  val 
) [static]

Definition at line 140 of file parse.c.

{
    int mode;

    if(strlen(val) < 2)
        return -EINVAL;

    if(val[1] != '\n' && val[1] != ' ') 
        return -EINVAL;

    if(val[0] == '0')
        mode = 0;
    else if(val[0] == '1')
        mode = 1;
    else
        return -EINVAL;
    
    AV_LOCK(avfs_lock);
    symlink_rewrite = mode;
    AV_UNLOCK(avfs_lock);

    return 0;
}

Here is the caller graph for this function:

static int versionstat_get ( struct entry ent,
const char *  param,
char **  retp 
) [static]

Definition at line 103 of file parse.c.

{
    char buf[128];
    char *compiledate;
    char *compilesys;
    char *moduledir;

    sprintf(buf, "%i.%i.%i", AV_VER / 100, (AV_VER / 10) % 10, AV_VER % 10);

    compiledate = av_get_config("compiledate");
    compilesys = av_get_config("compilesystem");
    moduledir = av_get_config("moduledir");

    *retp = av_stradd(NULL, "Interface version: ", buf, 
                        "\nCompile date: ", compiledate,
                        "\nCompile system: ", compilesys,
                        "\nModule directory: ", moduledir, "\n", NULL);

    av_free(compiledate);
    av_free(compilesys);
    av_free(moduledir);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct avfs_list [static]

Definition at line 35 of file parse.c.

int inited [static]

Definition at line 26 of file parse.c.

int symlink_rewrite = 0 [static]

Definition at line 36 of file parse.c.