+/**
+ * Get a list of paths where we look for resource (e.g. firmware) files.
+ *
+ * @param res_type The type of resource to get the search paths for.
+ *
+ * @return List of strings that must be freed after use, including the strings.
+ *
+ * @since 0.6.0
+ */
+SR_API GSList *sr_resourcepaths_get(int res_type)
+{
+ const char *subdir = NULL;
+ GSList *l = NULL;
+ const char *env;
+ const char *const *datadirs;
+
+ if (res_type == SR_RESOURCE_FIRMWARE) {
+ subdir = "sigrok-firmware";
+
+ env = g_getenv("SIGROK_FIRMWARE_DIR");
+ if (env)
+ l = g_slist_append(l, g_strdup(env));
+ }
+
+ l = g_slist_append(l, g_build_filename(g_get_user_data_dir(), subdir, NULL));
+
+#ifdef FIRMWARE_DIR
+ if (res_type == SR_RESOURCE_FIRMWARE) {
+ /*
+ * Scan the hard-coded directory before the system directories to
+ * avoid picking up possibly outdated files from a system install.
+ */
+ l = g_slist_append(l, g_strdup(FIRMWARE_DIR));
+ }
+#endif
+
+ datadirs = g_get_system_data_dirs();
+ while (*datadirs)
+ l = g_slist_append(l, g_build_filename(*datadirs++, subdir, NULL));
+
+ return l;
+}
+
+/**
+ * Retrieve the size of the open stream @a file.
+ *
+ * This function only works on seekable streams. However, the set of seekable
+ * streams is generally congruent with the set of streams that have a size.
+ * Code that needs to work with any type of stream (including pipes) should
+ * require neither seekability nor advance knowledge of the size.
+ * On failure, the return value is negative and errno is set.
+ *
+ * @param file An I/O stream opened in binary mode.
+ * @return The size of @a file in bytes, or a negative value on failure.
+ *
+ * @private
+ */
+SR_PRIV int64_t sr_file_get_size(FILE *file)
+{
+ off_t filepos, filesize;
+
+ /* ftello() and fseeko() are not standard C, but part of POSIX.1-2001.
+ * Thus, if these functions are available at all, they can reasonably
+ * be expected to also conform to POSIX semantics. In particular, this
+ * means that ftello() after fseeko(..., SEEK_END) has a defined result
+ * and can be used to get the size of a seekable stream.
+ * On Windows, the result is fully defined only for binary streams.
+ */
+ filepos = ftello(file);
+ if (filepos < 0)
+ return -1;
+
+ if (fseeko(file, 0, SEEK_END) < 0)
+ return -1;
+
+ filesize = ftello(file);
+ if (filesize < 0)
+ return -1;
+
+ if (fseeko(file, filepos, SEEK_SET) < 0)
+ return -1;
+
+ return filesize;
+}
+