+static int write_compressed_tar_archive(struct archiver_args *args,const char *filter)
+{
+ int rv;
+ struct cgit_filter f;
+
+ f.cmd = xstrdup(filter);
+ f.argv = malloc(2 * sizeof(char *));
+ f.argv[0] = f.cmd;
+ f.argv[1] = NULL;
+ cgit_open_filter(&f);
+ rv = write_tar_archive(args);
+ cgit_close_filter(&f);
+ return rv;
+}
+
+static int write_tar_gzip_archive(struct archiver_args *args)
+{
+ return write_compressed_tar_archive(args,"gzip");
+}
+
+static int write_tar_bzip2_archive(struct archiver_args *args)
+{
+ return write_compressed_tar_archive(args,"bzip2");
+}
+
+static int write_tar_xz_archive(struct archiver_args *args)
+{
+ return write_compressed_tar_archive(args,"xz");
+}
+
+const struct cgit_snapshot_format cgit_snapshot_formats[] = {
+ { ".zip", "application/x-zip", write_zip_archive, 0x01 },
+ { ".tar.gz", "application/x-gzip", write_tar_gzip_archive, 0x02 },
+ { ".tar.bz2", "application/x-bzip2", write_tar_bzip2_archive, 0x04 },
+ { ".tar", "application/x-tar", write_tar_archive, 0x08 },
+ { ".tar.xz", "application/x-xz", write_tar_xz_archive, 0x10 },
+ {}
+};
+
+static const struct cgit_snapshot_format *get_format(const char *filename)
+{
+ const struct cgit_snapshot_format *fmt;
+ int fl, sl;
+
+ fl = strlen(filename);
+ for(fmt = cgit_snapshot_formats; fmt->suffix; fmt++) {
+ sl = strlen(fmt->suffix);
+ if (sl >= fl)
+ continue;
+ if (!strcmp(fmt->suffix, filename + fl - sl))
+ return fmt;
+ }
+ return NULL;
+}
+
+static int make_snapshot(const struct cgit_snapshot_format *format,
+ const char *hex, const char *prefix,
+ const char *filename)