+static int read_file(const char *fname, void **buff_out, int *size, int limit)
+{
+ int file_size, ret;
+ void *data;
+ FILE *file;
+
+ file = fopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "can't open file: %s\n", fname);
+ return -1;
+ }
+
+ fseek(file, 0, SEEK_END);
+ file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ if (file_size > limit)
+ fprintf(stderr, "warning: input file \"%s\" too large\n", fname);
+ if (file_size < 0) {
+ fprintf(stderr, "bad/empty file: %s\n", fname);
+ goto fail;
+ }
+
+ data = malloc(file_size);
+ if (data == NULL) {
+ fprintf(stderr, "low memory\n");
+ goto fail;
+ }
+
+ ret = fread(data, 1, file_size, file);
+ if (ret != file_size) {
+ fprintf(stderr, "failed to read file: %s\n", fname);
+ goto fail;
+ }
+
+ *buff_out = data;
+ *size = file_size;
+ fclose(file);
+ return 0;
+
+fail:
+ fclose(file);
+ return -1;
+}
+
+static int write_file(const char *fname, void *buff, int size)
+{
+ FILE *file;
+ int ret;
+
+ file = fopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "can't open for writing: %s\n", fname);
+ return -1;
+ }
+
+ ret = fwrite(fname, 1, size, file);
+ fclose(file);
+ if (ret != size)
+ fprintf(stderr, "write failed to %s\n", fname);
+ else
+ printf("saved to %s.\n", fname);
+
+ return 0;
+}
+