+static int recv_file(int fd, const char *fname, unsigned int addr,
+ unsigned int size)
+{
+ int retval = -1;
+ char *buf = NULL;
+ FILE *f = NULL;
+ struct {
+ unsigned int addr;
+ unsigned int size;
+ } addr_size;
+ int ret;
+
+ f = fopen(fname, "wb");
+ if (f == NULL) {
+ fprintf(stderr, "fopen %s: ", fname);
+ perror("");
+ return -1;
+ }
+
+ buf = malloc(size);
+ if (buf == NULL) {
+ fprintf(stderr, "OOM?\n");
+ goto out;
+ }
+
+ send_cmd(fd, "*xd");
+
+ addr_size.addr = htonl(addr);
+ addr_size.size = htonl(size);
+ ret = write_with_check(fd, &addr_size, sizeof(addr_size), 'k');
+ if (ret)
+ return ret;
+
+ ret = read_from_cart(fd, buf, size);
+ if (ret)
+ goto out;
+
+ ret = fwrite(buf, 1, size, f);
+ if (ret != size) {
+ fprintf(stderr, "fwrite %d/%d: ", ret, size);
+ perror("");
+ goto out;
+ }
+
+ retval = 0;
+out:
+ if (f != NULL)
+ fclose(f);
+ free(buf);
+
+ return retval;
+}
+