コード例 #1
0
ファイル: vmnetfillcl.cpp プロジェクト: HieuLsw/iphonefrotz
/*
 *   Open a network file 
 */
CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc,
                             int mode, os_filetype_t typ,
                             const char *mime_type)
{
    vm_val_t filespec;
    
    /* check for a TadsObject implementing getFilename */
    if (G_predef->filespec_getFilename != VM_INVALID_PROP
        && vm_val_cast_ok(CVmObjTads, val))
    {
        /* call getFilename - the return value is the file spec */
        G_interpreter->get_prop(
            vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc);

        /* the result is the real file spec */
        filespec = *G_interpreter->get_r0();
    }
    else
    {
        /* it's not a TadsObject, so it must directly have the file name */
        filespec = *val;
    }

    /* check the file spec argument type */
    CVmNetFile *nf = 0;
    CVmObjTemporaryFile *tmp = 0;
    CVmObjFileName *ofn = 0;
    if ((tmp = vm_val_cast(CVmObjTemporaryFile, &filespec)) != 0)
    {
        /* if the temporary file object is invalid, it's an error */
        if (tmp->get_fname() == 0)
            err_throw(VMERR_CREATE_FILE);

        /* create the local file descriptor for the temp file path */
        nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ);

        /* mark it as a temp file */
        nf->is_temp = TRUE;
    }
    else if (filespec.is_numeric(vmg0_)
             || ((ofn = vm_val_cast(CVmObjFileName, &filespec)) != 0
                 && ofn->is_special_file()))
    {
        /* 
         *   It's a special file ID, either as an integer or as a FileName
         *   wrapping a special file int.  Get the value. 
         */
        int32_t sfid = (ofn != 0 ? ofn->get_sfid()
                                 : filespec.num_to_int(vmg0_));

        /* resolve the file system path for the given special file ID */
        char fname[OSFNMAX] = { '\0' };
        if (!CVmObjFile::sfid_to_path(vmg_ fname, sizeof(fname), sfid))
            err_throw(VMERR_BAD_VAL_BIF);

        /* create the special file descriptor */
        nf = open(vmg_ fname, sfid, mode, typ, mime_type);
    }
    else
    {
        /* anything else has to be a string */
        char fname[OSFNMAX];
        CVmBif::get_fname_val(vmg_ fname, sizeof(fname), &filespec);

        /* 
         *   if it's a local file, and it has a relative path, explicitly
         *   apply the image file path as the default working directory 
         */
        if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_))
        {
            /* build the full, absolute name based on the file base path */
            char fnabs[OSFNMAX];
            os_build_full_path(fnabs, sizeof(fnabs), G_file_path, fname);

            /* replace the relative path with the new absolute path */
            lib_strcpy(fname, sizeof(fname), fnabs);
        }

        /* create the regular network file descriptor */
        nf = open(vmg_ fname, 0, mode, typ, mime_type);
    }

    /* if they gave us an object as our file spec, remember it */
    if (nf != 0 && val->typ == VM_OBJ)
        nf->filespec = val->val.obj;

    /* return the network file descriptor */
    return nf;
}
コード例 #2
0
ファイル: vmnetfillcl.cpp プロジェクト: tags07/gpm-maze
/*
 *   Open a network file 
 */
CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc,
                             int mode, os_filetype_t typ,
                             const char *mime_type)
{
    vm_val_t filespec;
    
    /* check for a TadsObject implementing getFilename */
    if (G_predef->filespec_getFilename != VM_INVALID_PROP
        && val->typ == VM_OBJ
        && CVmObjTads::is_tadsobj_obj(vmg_ val->val.obj))
    {
        /* call getFilename - the return value is the file spec */
        G_interpreter->get_prop(
            vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc);

        /* the result is the real file spec */
        filespec = *G_interpreter->get_r0();
    }
    else
    {
        /* it's not a TadsObject, so it must directly have the file name */
        filespec = *val;
    }

    /* check the argument type */
    CVmNetFile *nf = 0;
    if (filespec.typ == VM_OBJ
        && CVmObjTemporaryFile::is_tmpfil_obj(vmg_ filespec.val.obj))
    {
        /* temporary file object - get the object, properly cast */
        CVmObjTemporaryFile *tmp = (CVmObjTemporaryFile *)vm_objp(
            vmg_ filespec.val.obj);

        /* if the temporary file object is invalid, it's an error */
        if (tmp->get_fname() == 0)
            err_throw(VMERR_CREATE_FILE);

        /* create the local file descriptor for the temp file path */
        nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ);

        /* mark it as a temp file */
        nf->is_temp = TRUE;
    }
    else
    {
        /* anything else has to be a string */
        char fname[OSFNMAX];
        CVmBif::get_str_val_fname(vmg_ fname, sizeof(fname),
                                  CVmBif::get_str_val(vmg_ &filespec));

        /* 
         *   if it's a local file, and it has a relative path, explicitly
         *   apply the image file path as the default working directory 
         */
        if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_))
        {
            /* build the full, absolute name based on the image file path */
            char fname_abs[OSFNMAX];
            os_build_full_path(fname_abs, sizeof(fname_abs),
                               G_image_loader->get_path(), fname);

            /* replace the relative path with the new absolute path */
            lib_strcpy(fname, sizeof(fname), fname_abs);
        }

        /* create the regular network file descriptor */
        nf = open(vmg_ fname, 0, mode, typ, mime_type);
    }

    /* if they gave us an object as our file spec, remember it */
    if (nf != 0 && val->typ == VM_OBJ)
        nf->filespec = val->val.obj;

    /* return the network file descriptor */
    return nf;
}
コード例 #3
0
ファイル: osdosnui.c プロジェクト: cspiegel/garglk
/*
 *   Is the given file in the given directory?  
 */
int os_is_file_in_dir(const char *filename, const char *path,
                      int allow_subdirs, int match_self)
{
    char filename_buf[OSFNMAX], path_buf[OSFNMAX];
    size_t flen, plen;
    int endsep = FALSE;

    /* absolute-ize the filename, if necessary */
    if (!os_is_file_absolute(filename))
    {
        os_get_abs_filename(filename_buf, sizeof(filename_buf), filename);
        filename = filename_buf;
    }

    /* absolute-ize the path, if necessary */
    if (!os_is_file_absolute(path))
    {
        os_get_abs_filename(path_buf, sizeof(path_buf), path);
        path = path_buf;
    }

    /* 
     *   canonicalize the paths, to remove .. and . elements - this will make
     *   it possible to directly compare the path strings 
     */
    safe_strcpy(filename_buf, sizeof(filename_buf), filename);
    canonicalize_path(filename_buf);
    filename = filename_buf;

    safe_strcpy(path_buf, sizeof(path_buf), path);
    canonicalize_path(path_buf);
    path = path_buf;

    /* get the length of the filename and the length of the path */
    flen = strlen(filename);
    plen = strlen(path);

    /* 
     *   If the path ends in a separator character, ignore that.  Exception:
     *   if the path is a root path, leave the separator intact. 
     */
    if (plen > 0 && (path[plen-1] == '\\' || path[plen-1] == '/')
        && !is_root_path(path))
        --plen;

    /* if the path still ends in a path separator, so note */
    endsep = (plen > 0 && (path[plen-1] == '\\' || path[plen-1] == '/'));

    /* 
     *   if the names match, return true if and only if the caller wants
     *   us to match the directory to itself
     */
    if (flen == plen && memicmp(filename, path, flen) == 0)
        return match_self;

    /* 
     *   Check that the filename has 'path' as its path prefix.  First, check
     *   that the leading substring of the filename matches 'path', ignoring
     *   case.  Note that we need the filename to be at least two characters
     *   longer than the path: it must have a path separator after the path
     *   name, and at least one character for a filename past that.
     *   Exception: if the path already ends in a path separator, we don't
     *   need to add another one, so the filename just needs to be one
     *   character longer.
     */
    if (flen < plen + (endsep ? 1 : 2) || !patheq(filename, path, plen))
        return FALSE;

    /* 
     *   Okay, 'path' is the leading substring of 'filename'; next make sure
     *   that this prefix actually ends at a path separator character in the
     *   filename.  (This is necessary so that we don't confuse "c:\a\b.txt"
     *   as matching "c:\abc\d.txt" - if we only matched the "c:\a" prefix,
     *   we'd miss the fact that the file is actually in directory "c:\abc",
     *   not "c:\a".)  If the path itself ends in a path separator, we've
     *   made this check already simply by the substring match.
     */
    if (!endsep && (filename[plen] != '\\' && filename[plen] != '/'))
        return FALSE;

    /*
     *   We're good on the path prefix - we definitely have a file that's
     *   within the 'path' directory or one of its subdirectories.  If we're
     *   allowed to match on subdirectories, we already have our answer
     *   (true).  If we're not allowed to match subdirectories, we still have
     *   one more check, which is that the rest of the filename is free of
     *   path separator charactres.  If it is, we have a file that's directly
     *   in the 'path' directory; otherwise it's in a subdirectory of 'path'
     *   and thus isn't a match.  
     */
    if (allow_subdirs)
    {
        /* 
         *   filename is in the 'path' directory or one of its
         *   subdirectories, and we're allowed to match on subdirectories, so
         *   we have a match 
         */
        return TRUE;
    }
    else
    {
        const char *p;

        /* 
         *   We're not allowed to match subdirectories, so scan the rest of
         *   the filename for path separators.  If we find any, the file is
         *   in a subdirectory of 'path' rather than directly in 'path'
         *   itself, so it's not a match.  If we don't find any separators,
         *   we have a file directly in 'path', so it's a match. 
         */
        for (p = filename + plen + (endsep ? 1 : 0) ;
             *p != '\0' && *p != '/' && *p != '\\' ; ++p) ;

        /* 
         *   if we reached the end of the string without finding a path
         *   separator character, it's a match 
         */
        return (*p == '\0');
    }
}