Exemplo n.º 1
0
/* Make a reusable file stream. */
static int
make_rfs(i_ctx_t *i_ctx_p, os_ptr op, stream *fs, long offset, long length)
{
    uint save_space = icurrent_space;
    uint stream_space = imemory_space((const gs_ref_memory_t *)fs->memory);
    gs_const_string fname;
    gs_parsed_file_name_t pname;
    stream *s;
    int code;

    if (sfilename(fs, &fname) < 0)
        return_error(e_ioerror);
    code = gs_parse_file_name(&pname, (const char *)fname.data, fname.size,
                              imemory);
    if (code < 0)
        return code;
    if (pname.len == 0)		/* %stdin% etc. won't have a filename */
        return_error(e_invalidfileaccess); /* can't reopen */
    if (pname.iodev == NULL)
        pname.iodev = iodev_default(imemory);
    /* Open the file again, to be independent of the source. */
    ialloc_set_space(idmemory, stream_space);
    code = zopen_file(i_ctx_p, &pname, "r", &s, imemory);
    ialloc_set_space(idmemory, save_space);
    if (code < 0)
        return code;
    if (sread_subfile(s, offset, length) < 0) {
        sclose(s);
        return_error(e_ioerror);
    }
    s->close_at_eod = false;
    make_stream_file(op, s, "r");
    return 0;
}
Exemplo n.º 2
0
/* return zero for success, -ve for error, +1 for continue */
static int
lib_file_open_search_with_combine(gs_file_path_ptr  lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx_p,
                                  const char *fname, uint flen, char *buffer, int blen, uint *pclen, ref *pfile,
                                  gx_io_device *iodev, bool starting_arg_file, char *fmode)
{
    stream *s;
    const gs_file_path *pfpath = lib_path;
    uint pi;

    for (pi = 0; pi < r_size(&pfpath->list); ++pi) {
        const ref *prdir = pfpath->list.value.refs + pi;
        const char *pstr = (const char *)prdir->value.const_bytes;
        uint plen = r_size(prdir), blen1 = blen;
        gs_parsed_file_name_t pname;
        gp_file_name_combine_result r;

        /* We need to concatenate and parse the file name here
         * if this path has a %device% prefix.              */
        if (pstr[0] == '%') {
            int code;

            /* We concatenate directly since gp_file_name_combine_*
             * rules are not correct for other devices such as %rom% */
            code = gs_parse_file_name(&pname, pstr, plen, mem);
            if (code < 0)
                continue;
            memcpy(buffer, pname.fname, pname.len);
            memcpy(buffer+pname.len, fname, flen);
            code = pname.iodev->procs.open_file(pname.iodev, buffer, pname.len + flen, fmode,
                                          &s, (gs_memory_t *)mem);
            if (code < 0)
                continue;
            make_stream_file(pfile, s, "r");
            /* fill in the buffer with the device concatenated */
            memcpy(buffer, pstr, plen);
            memcpy(buffer+plen, fname, flen);
            *pclen = plen + flen;
            return 0;
        } else {
            r = gp_file_name_combine(pstr, plen,
                    fname, flen, false, buffer, &blen1);
            if (r != gp_combine_success)
                continue;
            if (iodev_os_open_file(iodev, (const char *)buffer, blen1, (const char *)fmode,
                                    &s, (gs_memory_t *)mem) == 0) {
                if (starting_arg_file ||
                    check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) {
                    *pclen = blen1;
                    make_stream_file(pfile, s, "r");
                    return 0;
                }
                sclose(s);
                return_error(e_invalidfileaccess);
            }
        }
    }
    return 1;
}
Exemplo n.º 3
0
/* Parse a real (non-device) file name and convert to a C string. */
int
gs_parse_real_file_name(gs_parsed_file_name_t * pfn, const char *pname,
			uint len, gs_memory_t *mem, client_name_t cname)
{
    int code = gs_parse_file_name(pfn, pname, len);

    if (code < 0)
	return code;
    if (pfn->len == 0)
	return_error(gs_error_invalidfileaccess);	/* device only */
    return gs_terminate_file_name(pfn, mem, cname);
}
Exemplo n.º 4
0
/* Parse a real (non-device) file name and convert to a C string. */
int
gs_parse_real_file_name(gs_parsed_file_name_t * pfn, const char *pname,
                        uint len, gs_memory_t *mem, client_name_t cname)
{
    int code = gs_parse_file_name(pfn, pname, len, mem);

    if (code < 0)
        return code;
    if (pfn->len == 0)  /* device only */
        return_error(gs_error_undefinedfilename); /* for CET 23-23.ps */
    return gs_terminate_file_name(pfn, mem, cname);
}
Exemplo n.º 5
0
/*
 * Open a stream using a filename that can include a PS style IODevice prefix
 * If iodev_default is the '%os' device, then the file will be on the host
 * file system transparently to the caller. The "%os%" prefix can be used
 * to explicilty access the host file system.
 */
stream *
sfopen(const char *path, const char *mode, gs_memory_t *memory)
{
    gs_parsed_file_name_t pfn;
    stream *s;
    iodev_proc_open_file((*open_file));
    gs_memory_t *mem = (memory == NULL) ? gs_lib_ctx_get_non_gc_memory_t() : memory;

    int code = gs_parse_file_name(&pfn, path, strlen(path));
    if (code < 0) {
#	define EMSG	"sfopen: gs_parse_file_name failed.\n"
	errwrite(EMSG, strlen(EMSG));
#	undef EMSG
	return NULL;
    }
    if (pfn.fname == NULL) {	/* just a device */
#	define EMSG	"sfopen: not allowed with %device only.\n"
	errwrite(EMSG, strlen(EMSG));
#	undef EMSG
	return NULL;
    }
    if (pfn.iodev == NULL)
	pfn.iodev = iodev_default;
    open_file = pfn.iodev->procs.open_file;
    if (open_file == 0)
	code = file_open_stream(pfn.fname, pfn.len, mode, 2048, &s,
				pfn.iodev, pfn.iodev->procs.fopen, mem);
    else
	code = open_file(pfn.iodev, pfn.fname, pfn.len, mode, &s, mem);
    if (code < 0)
	return NULL;
    s->position = 0;
    code = ssetfilename(s, (const byte *)path, strlen(path));
    if (code < 0) {
	/* Only error is e_VMerror */
	sclose(s);
	gs_free_object(s->memory, s, "sfopen: allocation error");
#	define EMSG	"sfopen: allocation error setting path name into stream.\n"
	errwrite(EMSG, strlen(EMSG));
#	undef EMSG
	return NULL;
    }
    return s;
}
Exemplo n.º 6
0
/* See gsfname.c for details. */
static int
parse_file_name(const ref * op, gs_parsed_file_name_t * pfn, bool safemode)
{
    int code;

    check_read_type(*op, t_string);
    code = gs_parse_file_name(pfn, (const char *)op->value.const_bytes,
			      r_size(op));
    if (code < 0)
	return code;
    /*
     * Check here for the %pipe device which is illegal when
     * LockFilePermissions is true. In the future we might want to allow
     * the %pipe device to be included on the PermitFile... paths, but
     * for now it is simply disallowed.
     */
    if (pfn->iodev && safemode && strcmp(pfn->iodev->dname, "%pipe%") == 0)
	return e_invalidfileaccess;
    return code;
}
Exemplo n.º 7
0
/* The startup code also calls this to open @-files. */
int
lib_file_open(gs_file_path_ptr  lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx_p,      
		       const char *fname, uint flen, char *buffer, int blen, uint *pclen, ref *pfile)
{   /* i_ctx_p is NULL running arg (@) files. 
     * lib_path and mem are never NULL 
     */
    bool starting_arg_file = (i_ctx_p == NULL) ? true : i_ctx_p->starting_arg_file;
    bool search_with_no_combine = false;
    bool search_with_combine = false;
    char fmode[4] = { 'r', 0, 0, 0 };		/* room for binary suffix */
    stream *s;
    gx_io_device *iodev = iodev_default;

    /* when starting arg files (@ files) iodev_default is not yet set */
    if (iodev == 0)
        iodev = (gx_io_device *)gx_io_device_table[0];
    
    strcat(fmode, gp_fmode_binary_suffix);
    if (gp_file_name_is_absolute(fname, flen)) {
       search_with_no_combine = true;
       search_with_combine = false;
    } else {
       search_with_no_combine = starting_arg_file;
       search_with_combine = true;
    }
    if (search_with_no_combine) {
	uint blen1 = blen;

	if (gp_file_name_reduce(fname, flen, buffer, &blen1) != gp_combine_success)
	    goto skip;
	if (iodev_os_open_file(iodev, (const char *)buffer, blen1,
				(const char *)fmode, &s, (gs_memory_t *)mem) == 0) {
	    if (starting_arg_file ||
			check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) {
		*pclen = blen1;
		make_stream_file(pfile, s, "r");
		return 0;
	    }
	    sclose(s);
	    return_error(e_invalidfileaccess);
	}
	skip:;
    } 
    if (search_with_combine) {
	const gs_file_path *pfpath = lib_path;
	uint pi;

	for (pi = 0; pi < r_size(&pfpath->list); ++pi) {
	    const ref *prdir = pfpath->list.value.refs + pi;
	    const char *pstr = (const char *)prdir->value.const_bytes;
	    uint plen = r_size(prdir), blen1 = blen;
    	    gs_parsed_file_name_t pname;
	    gp_file_name_combine_result r;

	    /* We need to concatenate and parse the file name here
	     * if this path has a %device% prefix.		*/
	    if (pstr[0] == '%') {
		int code;

		/* We concatenate directly since gp_file_name_combine_*
		 * rules are not correct for other devices such as %rom% */
		gs_parse_file_name(&pname, pstr, plen);
		memcpy(buffer, pname.fname, pname.len);
		memcpy(buffer+pname.len, fname, flen);
		code = pname.iodev->procs.open_file(pname.iodev, buffer, pname.len + flen, fmode,
					      &s, (gs_memory_t *)mem);
		if (code < 0)
		    continue;
		make_stream_file(pfile, s, "r");
		/* fill in the buffer with the device concatenated */
		memcpy(buffer, pstr, plen);
		memcpy(buffer+plen, fname, flen);
		*pclen = plen + flen;
		return 0;
	    } else {
		r = gp_file_name_combine(pstr, plen, 
			fname, flen, false, buffer, &blen1);
		if (r != gp_combine_success)
		    continue;
		if (iodev_os_open_file(iodev, (const char *)buffer, blen1, (const char *)fmode,
					&s, (gs_memory_t *)mem) == 0) {
		    if (starting_arg_file ||
			check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) {
			*pclen = blen1;
			make_stream_file(pfile, s, "r");
			return 0;
		    }
		    sclose(s);
		    return_error(e_invalidfileaccess);
		}
	    }
	}
    }
    return_error(e_undefinedfilename);
}