+ tal_add_destructor(tmpdir, unlink_all);
+ if (tools_verbose)
+ printf("Created temporary directory %s\n", tmpdir);
+ }
+ return tmpdir;
+}
+
+void keep_temp_dir(void)
+{
+ tal_del_destructor(temp_dir(), unlink_all);
+}
+
+char *temp_file(const void *ctx, const char *extension, const char *srcname)
+{
+ char *f, *base, *suffix;
+ struct stat st;
+ unsigned int count = 0;
+
+ base = path_join(ctx, temp_dir(), take(path_basename(ctx, srcname)));
+ /* Trim extension. */
+ base[path_ext_off(base)] = '\0';
+ suffix = tal_strdup(ctx, extension);
+
+ do {
+ f = tal_strcat(ctx, base, suffix);
+ suffix = tal_fmt(base, "-%u%s", ++count, extension);
+ } while (lstat(f, &st) == 0);
+
+ if (tools_verbose)
+ printf("Creating file %s\n", f);
+
+ tal_free(base);
+ return f;
+}
+
+bool move_file(const char *oldname, const char *newname)
+{
+ char *contents;
+ size_t size;
+ int fd;
+ bool ret;
+
+ if (tools_verbose)
+ printf("Moving file %s to %s: ", oldname, newname);
+
+ /* Simple case: rename works. */
+ if (rename(oldname, newname) == 0) {
+ if (tools_verbose)
+ printf("rename worked\n");
+ return true;
+ }
+
+ /* Try copy and delete: not atomic! */
+ contents = tal_grab_file(NULL, oldname, &size);
+ if (!contents) {
+ if (tools_verbose)
+ printf("read failed: %s\n", strerror(errno));
+ return false;
+ }
+
+ fd = open(newname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd < 0) {
+ if (tools_verbose)
+ printf("output open failed: %s\n", strerror(errno));
+ ret = false;
+ goto free;
+ }
+
+ ret = write_all(fd, contents, size);
+ if (close(fd) != 0)
+ ret = false;
+
+ if (ret) {
+ if (tools_verbose)
+ printf("copy worked\n");
+ unlink(oldname);
+ } else {
+ if (tools_verbose)
+ printf("write/close failed\n");
+ unlink(newname);
+ }
+
+free:
+ tal_free(contents);
+ return ret;
+}
+
+void *do_tal_realloc(void *p, size_t size)
+{
+ tal_resize((char **)&p, size);
+ return p;
+}
+
+void *tal_grab_file(const void *ctx, const char *filename, size_t *size)
+{
+ struct rbuf rbuf;
+ char *buf = tal_arr(ctx, char, 0);
+
+ if (!rbuf_open(&rbuf, filename, buf, 0))
+ return tal_free(buf);
+
+ if (!rbuf_fill_all(&rbuf, do_tal_realloc) && errno)
+ rbuf.buf = tal_free(rbuf.buf);
+ else {
+ rbuf.buf[rbuf.len] = '\0';
+ if (size)
+ *size = rbuf.len;