summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gsiorom.c')
-rw-r--r--base/gsiorom.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/base/gsiorom.c b/base/gsiorom.c
index 6516568a..767a35cf 100644
--- a/base/gsiorom.c
+++ b/base/gsiorom.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -412,3 +412,40 @@ romfs_enumerate_next(gs_memory_t * mem, file_enum *pfen, char *ptr, uint maxlen)
romfs_enumerate_close(mem, pfen);
return ~(uint)0;
}
+
+int
+romfs_file_len(gs_memory_t * mem, const char *fname)
+{
+ extern const uint32_t *gs_romfs[];
+ extern const time_t gs_romfs_buildtime;
+ const uint32_t *node_scan = gs_romfs[0], *node = NULL;
+ uint32_t filelen, blocks;
+ int i;
+ char *filename;
+ uint namelen = strlen(fname);
+
+ /* a build time of zero indicates we have the "dummy" romfs
+ * used when COMPILE_INITS==0 - returning a specific error here
+ * gives us a quick way to check for that.
+ */
+ if (gs_romfs_buildtime == (time_t)0) {
+ return_error(gs_error_unregistered);
+ }
+
+ /* scan the inodes to find the requested file */
+ for (i=0; node_scan != 0; i++, node_scan = gs_romfs[i]) {
+ filelen = get_u32_big_endian(node_scan) & 0x7fffffff; /* ignore compression bit */
+ blocks = (filelen+ROMFS_BLOCKSIZE-1)/ ROMFS_BLOCKSIZE;
+ filename = (char *)(&(node_scan[1+(2*blocks)]));
+ if ((namelen == strlen(filename)) &&
+ (strncmp(filename, fname, namelen) == 0)) {
+ node = node_scan;
+ break;
+ }
+ }
+ /* inode points to the file (or NULL if not found */
+ if (node == NULL)
+ return_error(gs_error_undefinedfilename);
+
+ return (int)filelen;
+}