Diff options
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Describe each snapshot format as data in the table
Diffstat (limited to 'source/ui-snapshot.c')
-rw-r--r--source/ui-snapshot.c118
1 file changed, 41 insertions, 77 deletions
diff --git a/source/ui-snapshot.c b/source/ui-snapshot.c
index bd5ebf2..0d8ecdf 100644
--- a/source/ui-snapshot.c
+++ b/source/ui-snapshot.c
@@ -1,13 +1,13 @@
/*
* Serves a commit as a downloadable archive. Writing the archive is git's
- * work, so each format here is a thin wrapper that either calls write_archive
- * directly or pipes its tar output through an external compressor. The table
- * of formats also lives here, and since a repository's snapshots mask is one
- * bit per table position, that order is part of what cgitrc means. When the
- * request carries no revision the file name is worked backwards to find one,
- * so that a link to cgit-1.2.tar.gz can serve the tag it was named after. A
- * name ending in .asc asks for the detached signature kept under refs/notes
- * instead of the archive itself.
+ * work, so each format here is only a row in a table, naming the archive
+ * format git writes and, for a compressed tar, the compressor its output is
+ * piped through. A repository's snapshots mask is one bit per table position,
+ * so that order is part of what cgitrc means. When the request carries no
+ * revision the file name is worked backwards to find one, so that a link to
+ * cgit-1.2.tar.gz can serve the tag it was named after. A name ending in .asc
+ * asks for the detached signature kept under refs/notes instead of the archive
+ * itself.
*/
#define USE_THE_REPOSITORY_VARIABLE
@@ -21,11 +21,10 @@
#define SIG_SUFFIX ".asc"
-static int write_archive_format(const char *format_arg, const char *hex, const char *prefix)
+static void write_archive_format(const char *format_arg, const char *hex, const char *prefix)
{
struct strvec argv = STRVEC_INIT;
const char **args;
- int result;
strvec_push(&argv, "snapshot");
strvec_push(&argv, format_arg);
@@ -48,20 +47,25 @@ static int write_archive_format(const char *format_arg, const char *hex, const c
args = xmalloc(sizeof(char *) * (argv.nr + 1));
memcpy(args, argv.v, sizeof(char *) * (argv.nr + 1));
- result = write_archive(argv.nr, args, NULL, the_repository, NULL, 0);
+ write_archive(argv.nr, args, NULL, the_repository, NULL, 0);
strvec_clear(&argv);
free(args);
- return result;
}
-static int write_tar_archive(const char *hex, const char *prefix)
+static void write_snapshot(const struct cgit_snapshot_format *format,
+ const char *hex, const char *prefix)
{
- return write_archive_format("--format=tar", hex, prefix);
-}
+ struct cgit_exec_filter compressor;
+ struct cgit_filter *filter = NULL;
-static int write_zip_archive(const char *hex, const char *prefix)
-{
- return write_archive_format("--format=zip", hex, prefix);
+ if (format->compressor) {
+ cgit_exec_filter_init(&compressor, format->compressor[0],
+ format->compressor);
+ filter = &compressor.base;
+ }
+ cgit_open_filter(filter);
+ write_archive_format(format->format_arg, hex, prefix);
+ cgit_close_filter(filter);
}
static int program_on_path(const char *program)
@@ -101,66 +105,25 @@ static int program_on_path(const char *program)
return found;
}
-static int write_compressed_tar_archive(const char *hex, const char *prefix, const char *argv[])
-{
- struct cgit_exec_filter filter;
- int result;
-
- cgit_exec_filter_init(&filter, argv[0], argv);
- cgit_open_filter(&filter.base);
- result = write_tar_archive(hex, prefix);
- cgit_close_filter(&filter.base);
- return result;
-}
-
-static int write_tar_gzip_archive(const char *hex, const char *prefix)
-{
- const char *argv[] = { "gzip", "-n", NULL };
-
- return write_compressed_tar_archive(hex, prefix, argv);
-}
-
-static int write_tar_bzip2_archive(const char *hex, const char *prefix)
-{
- const char *argv[] = { "bzip2", NULL };
-
- return write_compressed_tar_archive(hex, prefix, argv);
-}
-
-static int write_tar_lzip_archive(const char *hex, const char *prefix)
-{
- const char *argv[] = { "lzip", NULL };
-
- return write_compressed_tar_archive(hex, prefix, argv);
-}
-
-static int write_tar_xz_archive(const char *hex, const char *prefix)
-{
- // Current xz runs a thread per core unless told otherwise.
- const char *argv[] = { "xz", "-T1", NULL };
-
- return write_compressed_tar_archive(hex, prefix, argv);
-}
-
-static int write_tar_zstd_archive(const char *hex, const char *prefix)
-{
- // Single-threaded like the other compressors, since -T0 would let one
- // request pin every core.
- const char *argv[] = { "zstd", NULL };
-
- return write_compressed_tar_archive(hex, prefix, argv);
-}
+static const char *gzip_argv[] = { "gzip", "-n", NULL };
+static const char *bzip2_argv[] = { "bzip2", NULL };
+static const char *lzip_argv[] = { "lzip", NULL };
+// Current xz runs a thread per core unless told otherwise.
+static const char *xz_argv[] = { "xz", "-T1", NULL };
+// Single-threaded like the other compressors, since -T0 would let one
+// request pin every core.
+static const char *zstd_argv[] = { "zstd", NULL };
// ui-shared.c reads entry zero as the tar whose signature stands in for every
// tar variant, so this order cannot change.
const struct cgit_snapshot_format cgit_snapshot_formats[] = {
- { ".tar", "application/x-tar", write_tar_archive, NULL },
- { ".tar.gz", "application/gzip", write_tar_gzip_archive, "gzip" },
- { ".tar.bz2", "application/x-bzip2", write_tar_bzip2_archive, "bzip2" },
- { ".tar.lz", "application/x-lzip", write_tar_lzip_archive, "lzip" },
- { ".tar.xz", "application/x-xz", write_tar_xz_archive, "xz" },
- { ".tar.zst", "application/zstd", write_tar_zstd_archive, "zstd" },
- { ".zip", "application/zip", write_zip_archive, NULL },
+ { ".tar", "application/x-tar", "--format=tar", NULL },
+ { ".tar.gz", "application/gzip", "--format=tar", gzip_argv },
+ { ".tar.bz2", "application/x-bzip2", "--format=tar", bzip2_argv },
+ { ".tar.lz", "application/x-lzip", "--format=tar", lzip_argv },
+ { ".tar.xz", "application/x-xz", "--format=tar", xz_argv },
+ { ".tar.zst", "application/zstd", "--format=tar", zstd_argv },
+ { ".zip", "application/zip", "--format=zip", NULL },
{ 0 }
};
@@ -277,8 +240,9 @@ static int send_snapshot(const struct cgit_snapshot_format *format, const char *
// A compressor that cannot run only shows up as a broken pipe once
// the tar is under way, so it is looked for while a status can still
// say so.
- if (format->program && !program_on_path(format->program)) {
- cgit_print_error_page(500, "Internal Server Error", "Unable to run %s", format->program);
+ if (format->compressor && !program_on_path(format->compressor[0])) {
+ cgit_print_error_page(500, "Internal Server Error", "Unable to run %s",
+ format->compressor[0]);
return 1;
}
ctx.page.mimetype = xstrdup(format->mimetype);
@@ -287,7 +251,7 @@ static int send_snapshot(const struct cgit_snapshot_format *format, const char *
init_archivers();
// The archiver reads its arguments as a command line, so it gets the
// resolved id and never the name.
- format->write_func(oid_to_hex(&oid), prefix);
+ write_snapshot(format, oid_to_hex(&oid), prefix);
return 0;
}