summaryrefslogtreecommitdiffabout
authorNatanael Copa <natanael.copa@gmail.com>2008-11-30 05:49:07 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-11-30 12:39:53 (UTC)
commit314d9ea5a3bc60ec518e314bb0bf8072123dc08f (patch) (unidiff)
treeca65f83e89b301ff6df228785c73c8413a072361
parent7b5cee65fd9cf31e4f19ce4ff613778cb95512a9 (diff)
downloadcgit-314d9ea5a3bc60ec518e314bb0bf8072123dc08f.zip
cgit-314d9ea5a3bc60ec518e314bb0bf8072123dc08f.tar.gz
cgit-314d9ea5a3bc60ec518e314bb0bf8072123dc08f.tar.bz2
Set prefix in snapshots when using dwimmery
This patch sets the directory prefix in archives to be the filename, excluding the suffix (.tar.gz, .tar.bz2 etc). The patch also removes the prefix parameter in cgit_print_snapshot() as the prefix might differ. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--cmd.c3
-rw-r--r--ui-snapshot.c14
-rw-r--r--ui-snapshot.h3
3 files changed, 14 insertions, 6 deletions
diff --git a/cmd.c b/cmd.c
index 5b3c14c..8914fa5 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,165 +1,164 @@
1/* cmd.c: the cgit command dispatcher 1/* cmd.c: the cgit command dispatcher
2 * 2 *
3 * Copyright (C) 2008 Lars Hjemli 3 * Copyright (C) 2008 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "cmd.h" 10#include "cmd.h"
11#include "cache.h" 11#include "cache.h"
12#include "ui-shared.h" 12#include "ui-shared.h"
13#include "ui-atom.h" 13#include "ui-atom.h"
14#include "ui-blob.h" 14#include "ui-blob.h"
15#include "ui-clone.h" 15#include "ui-clone.h"
16#include "ui-commit.h" 16#include "ui-commit.h"
17#include "ui-diff.h" 17#include "ui-diff.h"
18#include "ui-log.h" 18#include "ui-log.h"
19#include "ui-patch.h" 19#include "ui-patch.h"
20#include "ui-plain.h" 20#include "ui-plain.h"
21#include "ui-refs.h" 21#include "ui-refs.h"
22#include "ui-repolist.h" 22#include "ui-repolist.h"
23#include "ui-snapshot.h" 23#include "ui-snapshot.h"
24#include "ui-summary.h" 24#include "ui-summary.h"
25#include "ui-tag.h" 25#include "ui-tag.h"
26#include "ui-tree.h" 26#include "ui-tree.h"
27 27
28static void HEAD_fn(struct cgit_context *ctx) 28static void HEAD_fn(struct cgit_context *ctx)
29{ 29{
30 cgit_clone_head(ctx); 30 cgit_clone_head(ctx);
31} 31}
32 32
33static void atom_fn(struct cgit_context *ctx) 33static void atom_fn(struct cgit_context *ctx)
34{ 34{
35 cgit_print_atom(ctx->qry.head, ctx->qry.path, 10); 35 cgit_print_atom(ctx->qry.head, ctx->qry.path, 10);
36} 36}
37 37
38static void about_fn(struct cgit_context *ctx) 38static void about_fn(struct cgit_context *ctx)
39{ 39{
40 if (ctx->repo) 40 if (ctx->repo)
41 cgit_print_repo_readme(); 41 cgit_print_repo_readme();
42 else 42 else
43 cgit_print_site_readme(); 43 cgit_print_site_readme();
44} 44}
45 45
46static void blob_fn(struct cgit_context *ctx) 46static void blob_fn(struct cgit_context *ctx)
47{ 47{
48 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head); 48 cgit_print_blob(ctx->qry.sha1, ctx->qry.path, ctx->qry.head);
49} 49}
50 50
51static void commit_fn(struct cgit_context *ctx) 51static void commit_fn(struct cgit_context *ctx)
52{ 52{
53 cgit_print_commit(ctx->qry.sha1); 53 cgit_print_commit(ctx->qry.sha1);
54} 54}
55 55
56static void diff_fn(struct cgit_context *ctx) 56static void diff_fn(struct cgit_context *ctx)
57{ 57{
58 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path); 58 cgit_print_diff(ctx->qry.sha1, ctx->qry.sha2, ctx->qry.path);
59} 59}
60 60
61static void info_fn(struct cgit_context *ctx) 61static void info_fn(struct cgit_context *ctx)
62{ 62{
63 cgit_clone_info(ctx); 63 cgit_clone_info(ctx);
64} 64}
65 65
66static void log_fn(struct cgit_context *ctx) 66static void log_fn(struct cgit_context *ctx)
67{ 67{
68 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count, 68 cgit_print_log(ctx->qry.sha1, ctx->qry.ofs, ctx->cfg.max_commit_count,
69 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1); 69 ctx->qry.grep, ctx->qry.search, ctx->qry.path, 1);
70} 70}
71 71
72static void ls_cache_fn(struct cgit_context *ctx) 72static void ls_cache_fn(struct cgit_context *ctx)
73{ 73{
74 ctx->page.mimetype = "text/plain"; 74 ctx->page.mimetype = "text/plain";
75 ctx->page.filename = "ls-cache.txt"; 75 ctx->page.filename = "ls-cache.txt";
76 cgit_print_http_headers(ctx); 76 cgit_print_http_headers(ctx);
77 cache_ls(ctx->cfg.cache_root); 77 cache_ls(ctx->cfg.cache_root);
78} 78}
79 79
80static void objects_fn(struct cgit_context *ctx) 80static void objects_fn(struct cgit_context *ctx)
81{ 81{
82 cgit_clone_objects(ctx); 82 cgit_clone_objects(ctx);
83} 83}
84 84
85static void repolist_fn(struct cgit_context *ctx) 85static void repolist_fn(struct cgit_context *ctx)
86{ 86{
87 cgit_print_repolist(); 87 cgit_print_repolist();
88} 88}
89 89
90static void patch_fn(struct cgit_context *ctx) 90static void patch_fn(struct cgit_context *ctx)
91{ 91{
92 cgit_print_patch(ctx->qry.sha1); 92 cgit_print_patch(ctx->qry.sha1);
93} 93}
94 94
95static void plain_fn(struct cgit_context *ctx) 95static void plain_fn(struct cgit_context *ctx)
96{ 96{
97 cgit_print_plain(ctx); 97 cgit_print_plain(ctx);
98} 98}
99 99
100static void refs_fn(struct cgit_context *ctx) 100static void refs_fn(struct cgit_context *ctx)
101{ 101{
102 cgit_print_refs(); 102 cgit_print_refs();
103} 103}
104 104
105static void snapshot_fn(struct cgit_context *ctx) 105static void snapshot_fn(struct cgit_context *ctx)
106{ 106{
107 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, 107 cgit_print_snapshot(ctx->qry.head, ctx->qry.sha1, ctx->qry.path,
108 cgit_repobasename(ctx->repo->url), ctx->qry.path,
109 ctx->repo->snapshots, ctx->qry.nohead); 108 ctx->repo->snapshots, ctx->qry.nohead);
110} 109}
111 110
112static void summary_fn(struct cgit_context *ctx) 111static void summary_fn(struct cgit_context *ctx)
113{ 112{
114 cgit_print_summary(); 113 cgit_print_summary();
115} 114}
116 115
117static void tag_fn(struct cgit_context *ctx) 116static void tag_fn(struct cgit_context *ctx)
118{ 117{
119 cgit_print_tag(ctx->qry.sha1); 118 cgit_print_tag(ctx->qry.sha1);
120} 119}
121 120
122static void tree_fn(struct cgit_context *ctx) 121static void tree_fn(struct cgit_context *ctx)
123{ 122{
124 cgit_print_tree(ctx->qry.sha1, ctx->qry.path); 123 cgit_print_tree(ctx->qry.sha1, ctx->qry.path);
125} 124}
126 125
127#define def_cmd(name, want_repo, want_layout) \ 126#define def_cmd(name, want_repo, want_layout) \
128 {#name, name##_fn, want_repo, want_layout} 127 {#name, name##_fn, want_repo, want_layout}
129 128
130struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx) 129struct cgit_cmd *cgit_get_cmd(struct cgit_context *ctx)
131{ 130{
132 static struct cgit_cmd cmds[] = { 131 static struct cgit_cmd cmds[] = {
133 def_cmd(HEAD, 1, 0), 132 def_cmd(HEAD, 1, 0),
134 def_cmd(atom, 1, 0), 133 def_cmd(atom, 1, 0),
135 def_cmd(about, 0, 1), 134 def_cmd(about, 0, 1),
136 def_cmd(blob, 1, 0), 135 def_cmd(blob, 1, 0),
137 def_cmd(commit, 1, 1), 136 def_cmd(commit, 1, 1),
138 def_cmd(diff, 1, 1), 137 def_cmd(diff, 1, 1),
139 def_cmd(info, 1, 0), 138 def_cmd(info, 1, 0),
140 def_cmd(log, 1, 1), 139 def_cmd(log, 1, 1),
141 def_cmd(ls_cache, 0, 0), 140 def_cmd(ls_cache, 0, 0),
142 def_cmd(objects, 1, 0), 141 def_cmd(objects, 1, 0),
143 def_cmd(patch, 1, 0), 142 def_cmd(patch, 1, 0),
144 def_cmd(plain, 1, 0), 143 def_cmd(plain, 1, 0),
145 def_cmd(refs, 1, 1), 144 def_cmd(refs, 1, 1),
146 def_cmd(repolist, 0, 0), 145 def_cmd(repolist, 0, 0),
147 def_cmd(snapshot, 1, 0), 146 def_cmd(snapshot, 1, 0),
148 def_cmd(summary, 1, 1), 147 def_cmd(summary, 1, 1),
149 def_cmd(tag, 1, 1), 148 def_cmd(tag, 1, 1),
150 def_cmd(tree, 1, 1), 149 def_cmd(tree, 1, 1),
151 }; 150 };
152 int i; 151 int i;
153 152
154 if (ctx->qry.page == NULL) { 153 if (ctx->qry.page == NULL) {
155 if (ctx->repo) 154 if (ctx->repo)
156 ctx->qry.page = "summary"; 155 ctx->qry.page = "summary";
157 else 156 else
158 ctx->qry.page = "repolist"; 157 ctx->qry.page = "repolist";
159 } 158 }
160 159
161 for(i = 0; i < sizeof(cmds)/sizeof(*cmds); i++) 160 for(i = 0; i < sizeof(cmds)/sizeof(*cmds); i++)
162 if (!strcmp(ctx->qry.page, cmds[i].name)) 161 if (!strcmp(ctx->qry.page, cmds[i].name))
163 return &cmds[i]; 162 return &cmds[i];
164 return NULL; 163 return NULL;
165} 164}
diff --git a/ui-snapshot.c b/ui-snapshot.c
index 9c4d086..76457d6 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -1,188 +1,198 @@
1/* ui-snapshot.c: generate snapshot of a commit 1/* ui-snapshot.c: generate snapshot of a commit
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "html.h" 10#include "html.h"
11#include "ui-shared.h" 11#include "ui-shared.h"
12 12
13static int write_compressed_tar_archive(struct archiver_args *args,const char *filter) 13static int write_compressed_tar_archive(struct archiver_args *args,const char *filter)
14{ 14{
15 int rw[2]; 15 int rw[2];
16 pid_t gzpid; 16 pid_t gzpid;
17 int stdout2; 17 int stdout2;
18 int status; 18 int status;
19 int rv; 19 int rv;
20 20
21 stdout2 = chk_non_negative(dup(STDIN_FILENO), "Preserving STDOUT before compressing"); 21 stdout2 = chk_non_negative(dup(STDIN_FILENO), "Preserving STDOUT before compressing");
22 chk_zero(pipe(rw), "Opening pipe from compressor subprocess"); 22 chk_zero(pipe(rw), "Opening pipe from compressor subprocess");
23 gzpid = chk_non_negative(fork(), "Forking compressor subprocess"); 23 gzpid = chk_non_negative(fork(), "Forking compressor subprocess");
24 if(gzpid==0) { 24 if(gzpid==0) {
25 /* child */ 25 /* child */
26 chk_zero(close(rw[1]), "Closing write end of pipe in child"); 26 chk_zero(close(rw[1]), "Closing write end of pipe in child");
27 chk_zero(close(STDIN_FILENO), "Closing STDIN"); 27 chk_zero(close(STDIN_FILENO), "Closing STDIN");
28 chk_non_negative(dup2(rw[0],STDIN_FILENO), "Redirecting compressor input to stdin"); 28 chk_non_negative(dup2(rw[0],STDIN_FILENO), "Redirecting compressor input to stdin");
29 execlp(filter,filter,NULL); 29 execlp(filter,filter,NULL);
30 _exit(-1); 30 _exit(-1);
31 } 31 }
32 /* parent */ 32 /* parent */
33 chk_zero(close(rw[0]), "Closing read end of pipe"); 33 chk_zero(close(rw[0]), "Closing read end of pipe");
34 chk_non_negative(dup2(rw[1],STDOUT_FILENO), "Redirecting output to compressor"); 34 chk_non_negative(dup2(rw[1],STDOUT_FILENO), "Redirecting output to compressor");
35 35
36 rv = write_tar_archive(args); 36 rv = write_tar_archive(args);
37 37
38 chk_zero(close(STDOUT_FILENO), "Closing STDOUT redirected to compressor"); 38 chk_zero(close(STDOUT_FILENO), "Closing STDOUT redirected to compressor");
39 chk_non_negative(dup2(stdout2,STDOUT_FILENO), "Restoring uncompressed STDOUT"); 39 chk_non_negative(dup2(stdout2,STDOUT_FILENO), "Restoring uncompressed STDOUT");
40 chk_zero(close(stdout2), "Closing uncompressed STDOUT"); 40 chk_zero(close(stdout2), "Closing uncompressed STDOUT");
41 chk_zero(close(rw[1]), "Closing write end of pipe in parent"); 41 chk_zero(close(rw[1]), "Closing write end of pipe in parent");
42 chk_positive(waitpid(gzpid,&status,0), "Waiting on compressor process"); 42 chk_positive(waitpid(gzpid,&status,0), "Waiting on compressor process");
43 if(! ( WIFEXITED(status) && WEXITSTATUS(status)==0 ) ) 43 if(! ( WIFEXITED(status) && WEXITSTATUS(status)==0 ) )
44 cgit_print_error("Failed to compress archive"); 44 cgit_print_error("Failed to compress archive");
45 45
46 return rv; 46 return rv;
47} 47}
48 48
49static int write_tar_gzip_archive(struct archiver_args *args) 49static int write_tar_gzip_archive(struct archiver_args *args)
50{ 50{
51 return write_compressed_tar_archive(args,"gzip"); 51 return write_compressed_tar_archive(args,"gzip");
52} 52}
53 53
54static int write_tar_bzip2_archive(struct archiver_args *args) 54static int write_tar_bzip2_archive(struct archiver_args *args)
55{ 55{
56 return write_compressed_tar_archive(args,"bzip2"); 56 return write_compressed_tar_archive(args,"bzip2");
57} 57}
58 58
59const struct cgit_snapshot_format cgit_snapshot_formats[] = { 59const struct cgit_snapshot_format cgit_snapshot_formats[] = {
60 { ".zip", "application/x-zip", write_zip_archive, 0x1 }, 60 { ".zip", "application/x-zip", write_zip_archive, 0x1 },
61 { ".tar.gz", "application/x-tar", write_tar_gzip_archive, 0x2 }, 61 { ".tar.gz", "application/x-tar", write_tar_gzip_archive, 0x2 },
62 { ".tar.bz2", "application/x-tar", write_tar_bzip2_archive, 0x4 }, 62 { ".tar.bz2", "application/x-tar", write_tar_bzip2_archive, 0x4 },
63 { ".tar", "application/x-tar", write_tar_archive, 0x8 }, 63 { ".tar", "application/x-tar", write_tar_archive, 0x8 },
64 {} 64 {}
65}; 65};
66 66
67static const struct cgit_snapshot_format *get_format(const char *filename) 67static const struct cgit_snapshot_format *get_format(const char *filename)
68{ 68{
69 const struct cgit_snapshot_format *fmt; 69 const struct cgit_snapshot_format *fmt;
70 int fl, sl; 70 int fl, sl;
71 71
72 fl = strlen(filename); 72 fl = strlen(filename);
73 for(fmt = cgit_snapshot_formats; fmt->suffix; fmt++) { 73 for(fmt = cgit_snapshot_formats; fmt->suffix; fmt++) {
74 sl = strlen(fmt->suffix); 74 sl = strlen(fmt->suffix);
75 if (sl >= fl) 75 if (sl >= fl)
76 continue; 76 continue;
77 if (!strcmp(fmt->suffix, filename + fl - sl)) 77 if (!strcmp(fmt->suffix, filename + fl - sl))
78 return fmt; 78 return fmt;
79 } 79 }
80 return NULL; 80 return NULL;
81} 81}
82 82
83static int make_snapshot(const struct cgit_snapshot_format *format, 83static int make_snapshot(const struct cgit_snapshot_format *format,
84 const char *hex, const char *prefix, 84 const char *hex, const char *prefix,
85 const char *filename) 85 const char *filename)
86{ 86{
87 struct archiver_args args; 87 struct archiver_args args;
88 struct commit *commit; 88 struct commit *commit;
89 unsigned char sha1[20]; 89 unsigned char sha1[20];
90 90
91 if(get_sha1(hex, sha1)) { 91 if(get_sha1(hex, sha1)) {
92 cgit_print_error(fmt("Bad object id: %s", hex)); 92 cgit_print_error(fmt("Bad object id: %s", hex));
93 return 1; 93 return 1;
94 } 94 }
95 commit = lookup_commit_reference(sha1); 95 commit = lookup_commit_reference(sha1);
96 if(!commit) { 96 if(!commit) {
97 cgit_print_error(fmt("Not a commit reference: %s", hex)); 97 cgit_print_error(fmt("Not a commit reference: %s", hex));
98 return 1; 98 return 1;
99 } 99 }
100 memset(&args, 0, sizeof(args)); 100 memset(&args, 0, sizeof(args));
101 if (prefix) { 101 if (prefix) {
102 args.base = fmt("%s/", prefix); 102 args.base = fmt("%s/", prefix);
103 args.baselen = strlen(prefix) + 1; 103 args.baselen = strlen(prefix) + 1;
104 } else { 104 } else {
105 args.base = ""; 105 args.base = "";
106 args.baselen = 0; 106 args.baselen = 0;
107 } 107 }
108 args.tree = commit->tree; 108 args.tree = commit->tree;
109 args.time = commit->date; 109 args.time = commit->date;
110 ctx.page.mimetype = xstrdup(format->mimetype); 110 ctx.page.mimetype = xstrdup(format->mimetype);
111 ctx.page.filename = xstrdup(filename); 111 ctx.page.filename = xstrdup(filename);
112 cgit_print_http_headers(&ctx); 112 cgit_print_http_headers(&ctx);
113 format->write_func(&args); 113 format->write_func(&args);
114 return 0; 114 return 0;
115} 115}
116 116
117char *dwim_filename = NULL; 117char *dwim_filename = NULL;
118const char *dwim_refname = NULL; 118const char *dwim_refname = NULL;
119 119
120static int ref_cb(const char *refname, const unsigned char *sha1, int flags, 120static int ref_cb(const char *refname, const unsigned char *sha1, int flags,
121 void *cb_data) 121 void *cb_data)
122{ 122{
123 const char *r = refname; 123 const char *r = refname;
124 while (r && *r) { 124 while (r && *r) {
125 fprintf(stderr, " cmp %s with %s:", dwim_filename, r); 125 fprintf(stderr, " cmp %s with %s:", dwim_filename, r);
126 if (!strcmp(dwim_filename, r)) { 126 if (!strcmp(dwim_filename, r)) {
127 fprintf(stderr, "MATCH!\n"); 127 fprintf(stderr, "MATCH!\n");
128 dwim_refname = refname; 128 dwim_refname = refname;
129 return 1; 129 return 1;
130 } 130 }
131 fprintf(stderr, "no match\n"); 131 fprintf(stderr, "no match\n");
132 if (isdigit(*r)) 132 if (isdigit(*r))
133 break; 133 break;
134 r++; 134 r++;
135 } 135 }
136 return 0; 136 return 0;
137} 137}
138 138
139/* Try to guess the requested revision by combining repo name and tag name 139/* Try to guess the requested revision by combining repo name and tag name
140 * and comparing this to the requested snapshot name. E.g. the requested 140 * and comparing this to the requested snapshot name. E.g. the requested
141 * snapshot is "cgit-0.7.2.tar.gz" while repo name is "cgit" and tag name 141 * snapshot is "cgit-0.7.2.tar.gz" while repo name is "cgit" and tag name
142 * is "v0.7.2". First, the reponame is stripped off, leaving "-0.7.2.tar.gz". 142 * is "v0.7.2". First, the reponame is stripped off, leaving "-0.7.2.tar.gz".
143 * Next, any '-' and '_' characters are stripped, leaving "0.7.2.tar.gz". 143 * Next, any '-' and '_' characters are stripped, leaving "0.7.2.tar.gz".
144 * Finally, the requested format suffix is removed and we end up with "0.7.2". 144 * Finally, the requested format suffix is removed and we end up with "0.7.2".
145 * Then we test each tag against this dwimmed filename, and for each tag 145 * Then we test each tag against this dwimmed filename, and for each tag
146 * we even try to remove any leading characters which are non-digits. I.e. 146 * we even try to remove any leading characters which are non-digits. I.e.
147 * we first compare with "v0.7.2", then with "0.7.2" and we've got a match. 147 * we first compare with "v0.7.2", then with "0.7.2" and we've got a match.
148 */ 148 */
149static const char *get_ref_from_filename(const char *url, const char *filename, 149static const char *get_ref_from_filename(const char *url, const char *filename,
150 const struct cgit_snapshot_format *fmt) 150 const struct cgit_snapshot_format *fmt)
151{ 151{
152 const char *reponame = cgit_repobasename(url); 152 const char *reponame = cgit_repobasename(url);
153 fprintf(stderr, "reponame=%s, filename=%s\n", reponame, filename); 153 fprintf(stderr, "reponame=%s, filename=%s\n", reponame, filename);
154 if (prefixcmp(filename, reponame)) 154 if (prefixcmp(filename, reponame))
155 return NULL; 155 return NULL;
156 filename += strlen(reponame); 156 filename += strlen(reponame);
157 while (filename && (*filename == '-' || *filename == '_')) 157 while (filename && (*filename == '-' || *filename == '_'))
158 filename++; 158 filename++;
159 dwim_filename = xstrdup(filename); 159 dwim_filename = xstrdup(filename);
160 dwim_filename[strlen(filename) - strlen(fmt->suffix)] = '\0'; 160 dwim_filename[strlen(filename) - strlen(fmt->suffix)] = '\0';
161 for_each_tag_ref(ref_cb, NULL); 161 for_each_tag_ref(ref_cb, NULL);
162 return dwim_refname; 162 return dwim_refname;
163} 163}
164 164
165void cgit_print_snapshot(const char *head, const char *hex, const char *prefix, 165void cgit_print_snapshot(const char *head, const char *hex,
166 const char *filename, int snapshots, int dwim) 166 const char *filename, int snapshots, int dwim)
167{ 167{
168 const struct cgit_snapshot_format* f; 168 const struct cgit_snapshot_format* f;
169 char *prefix = NULL;
169 170
170 f = get_format(filename); 171 f = get_format(filename);
171 if (!f) { 172 if (!f) {
172 ctx.page.mimetype = "text/html"; 173 ctx.page.mimetype = "text/html";
173 cgit_print_http_headers(&ctx); 174 cgit_print_http_headers(&ctx);
174 cgit_print_docstart(&ctx); 175 cgit_print_docstart(&ctx);
175 cgit_print_pageheader(&ctx); 176 cgit_print_pageheader(&ctx);
176 cgit_print_error(fmt("Unsupported snapshot format: %s", filename)); 177 cgit_print_error(fmt("Unsupported snapshot format: %s", filename));
177 cgit_print_docend(); 178 cgit_print_docend();
178 return; 179 return;
179 } 180 }
180 181
181 if (!hex && dwim) 182 if (!hex && dwim) {
182 hex = get_ref_from_filename(ctx.repo->url, filename, f); 183 hex = get_ref_from_filename(ctx.repo->url, filename, f);
184 if (hex != NULL) {
185 prefix = xstrdup(filename);
186 prefix[strlen(filename) - strlen(f->suffix)] = '\0';
187 }
188 }
183 189
184 if (!hex) 190 if (!hex)
185 hex = head; 191 hex = head;
186 192
193 if (!prefix)
194 prefix = xstrdup(cgit_repobasename(ctx.repo->url));
195
187 make_snapshot(f, hex, prefix, filename); 196 make_snapshot(f, hex, prefix, filename);
197 free(prefix);
188} 198}
diff --git a/ui-snapshot.h b/ui-snapshot.h
index 3540303..b6ede52 100644
--- a/ui-snapshot.h
+++ b/ui-snapshot.h
@@ -1,8 +1,7 @@
1#ifndef UI_SNAPSHOT_H 1#ifndef UI_SNAPSHOT_H
2#define UI_SNAPSHOT_H 2#define UI_SNAPSHOT_H
3 3
4extern void cgit_print_snapshot(const char *head, const char *hex, 4extern void cgit_print_snapshot(const char *head, const char *hex,
5 const char *prefix, const char *filename, 5 const char *filename, int snapshot, int dwim);
6 int snapshot, int dwim);
7 6
8#endif /* UI_SNAPSHOT_H */ 7#endif /* UI_SNAPSHOT_H */