/* <string1> <string2> renamefile - */ static int zrenamefile(i_ctx_t *i_ctx_p) { int code; os_ptr op = osp; gs_parsed_file_name_t pname1, pname2; code = parse_real_file_name(op, &pname2, imemory, "renamefile(to)"); if (code < 0) return code; pname1.fname = 0; code = parse_real_file_name(op - 1, &pname1, imemory, "renamefile(from)"); if (code >= 0) { gx_io_device *iodev_dflt = iodev_default(imemory); if (pname1.iodev != pname2.iodev ) { if (pname1.iodev == iodev_dflt) pname1.iodev = pname2.iodev; if (pname2.iodev == iodev_dflt) pname2.iodev = pname1.iodev; } if (pname1.iodev != pname2.iodev || (pname1.iodev == iodev_dflt && /* * We require FileControl permissions on the source path * unless it is a temporary file. Also, we require FileControl * and FileWriting permissions to the destination file/path. */ ((check_file_permissions(i_ctx_p, pname1.fname, pname1.len, "PermitFileControl") < 0 && !file_is_tempfile(i_ctx_p, op[-1].value.bytes, r_size(op - 1))) || (check_file_permissions(i_ctx_p, pname2.fname, pname2.len, "PermitFileControl") < 0 || check_file_permissions(i_ctx_p, pname2.fname, pname2.len, "PermitFileWriting") < 0 )))) { code = gs_note_error(e_invalidfileaccess); } else { code = (*pname1.iodev->procs.rename_file)(pname1.iodev, pname1.fname, pname2.fname); } } gs_free_file_name(&pname2, "renamefile(to)"); gs_free_file_name(&pname1, "renamefile(from)"); if (code < 0) return code; pop(2); return 0; }
/* <string> deletefile - */ static int zdeletefile(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_parsed_file_name_t pname; int code = parse_real_file_name(op, &pname, imemory, "deletefile"); if (code < 0) return code; if (pname.iodev == iodev_default) { if ((code = check_file_permissions(i_ctx_p, pname.fname, pname.len, "PermitFileControl")) < 0 && !file_is_tempfile(i_ctx_p, op->value.bytes, r_size(op))) { return code; } } code = (*pname.iodev->procs.delete_file)(pname.iodev, pname.fname); gs_free_file_name(&pname, "deletefile"); if (code < 0) return code; pop(1); return 0; }
/* <string> status false */ static int zstatus(i_ctx_t *i_ctx_p) { os_ptr op = osp; switch (r_type(op)) { case t_file: { stream *s; make_bool(op, (file_is_valid(s, op) ? 1 : 0)); } return 0; case t_string: { gs_parsed_file_name_t pname; struct stat fstat; int code = parse_file_name(op, &pname, i_ctx_p->LockFilePermissions); if (code < 0) return code; code = gs_terminate_file_name(&pname, imemory, "status"); if (code < 0) return code; code = (*pname.iodev->procs.file_status)(pname.iodev, pname.fname, &fstat); switch (code) { case 0: check_ostack(4); /* * Check to make sure that the file size fits into * a PostScript integer. (On some systems, long is * 32 bits, but file sizes are 64 bits.) */ push(4); make_int(op - 4, stat_blocks(&fstat)); make_int(op - 3, fstat.st_size); /* * We can't check the value simply by using ==, * because signed/unsigned == does the wrong thing. * Instead, since integer assignment only keeps the * bottom bits, we convert the values to double * and then test for equality. This handles all * cases of signed/unsigned or width mismatch. */ if ((double)op[-4].value.intval != (double)stat_blocks(&fstat) || (double)op[-3].value.intval != (double)fstat.st_size ) return_error(e_limitcheck); make_int(op - 2, fstat.st_mtime); make_int(op - 1, fstat.st_ctime); make_bool(op, 1); break; case e_undefinedfilename: make_bool(op, 0); code = 0; } gs_free_file_name(&pname, "status"); return code; } default: return_op_typecheck(op); } }