summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rwxr-xr-xtests/t0107-snapshot.sh5
-rw-r--r--ui-snapshot.c8
2 files changed, 11 insertions, 2 deletions
diff --git a/tests/t0107-snapshot.sh b/tests/t0107-snapshot.sh
index 8e90e10..d97c465 100755
--- a/tests/t0107-snapshot.sh
+++ b/tests/t0107-snapshot.sh
@@ -1,36 +1,39 @@
1#!/bin/sh 1#!/bin/sh
2 2
3. ./setup.sh 3. ./setup.sh
4 4
5prepare_tests "Verify snapshot" 5prepare_tests "Verify snapshot"
6 6
7run_test 'get foo/snapshot/test.tar.gz' ' 7run_test 'get foo/snapshot/test.tar.gz' '
8 cgit_url "foo/snapshot/test.tar.gz" >trash/tmp 8 cgit_url "foo/snapshot/test.tar.gz" >trash/tmp
9' 9'
10 10
11run_test 'check html headers' ' 11run_test 'check html headers' '
12 head -n 1 trash/tmp | 12 head -n 1 trash/tmp |
13 grep -e "Content-Type: application/x-tar" && 13 grep -e "Content-Type: application/x-tar" &&
14 14
15 head -n 2 trash/tmp | 15 head -n 2 trash/tmp |
16 grep -e "Content-Disposition: inline; filename=.test.tar.gz." 16 grep -e "Content-Disposition: inline; filename=.test.tar.gz."
17' 17'
18 18
19run_test 'strip off the header lines' ' 19run_test 'strip off the header lines' '
20 tail -n +6 trash/tmp > trash/test.tar.gz 20 tail -n +6 trash/tmp > trash/test.tar.gz
21' 21'
22 22
23run_test 'verify gzip format' 'gunzip --test trash/test.tar.gz' 23run_test 'verify gzip format' 'gunzip --test trash/test.tar.gz'
24run_test 'untar' 'tar -xf trash/test.tar.gz -C trash' 24run_test 'untar' '
25 rm -rf trash/foo &&
26 tar -xf trash/test.tar.gz -C trash
27'
25 28
26run_test 'count files' ' 29run_test 'count files' '
27 c=$(ls -1 trash/foo/ | wc -l) && 30 c=$(ls -1 trash/foo/ | wc -l) &&
28 test $c = 5 31 test $c = 5
29' 32'
30 33
31run_test 'verify untarred file-5' ' 34run_test 'verify untarred file-5' '
32 grep -e "^5$" trash/foo/file-5 && 35 grep -e "^5$" trash/foo/file-5 &&
33 test $(cat trash/foo/file-5 | wc -l) = 1 36 test $(cat trash/foo/file-5 | wc -l) = 1
34' 37'
35 38
36tests_done 39tests_done
diff --git a/ui-snapshot.c b/ui-snapshot.c
index 966a140..7a597ff 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -37,78 +37,84 @@ static int write_compressed_tar_archive(struct archiver_args *args,const char *f
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 int make_snapshot(const struct cgit_snapshot_format *format, 67static int make_snapshot(const struct cgit_snapshot_format *format,
68 const char *hex, const char *prefix, 68 const char *hex, const char *prefix,
69 const char *filename) 69 const char *filename)
70{ 70{
71 struct archiver_args args; 71 struct archiver_args args;
72 struct commit *commit; 72 struct commit *commit;
73 unsigned char sha1[20]; 73 unsigned char sha1[20];
74 74
75 if(get_sha1(hex, sha1)) { 75 if(get_sha1(hex, sha1)) {
76 cgit_print_error(fmt("Bad object id: %s", hex)); 76 cgit_print_error(fmt("Bad object id: %s", hex));
77 return 1; 77 return 1;
78 } 78 }
79 commit = lookup_commit_reference(sha1); 79 commit = lookup_commit_reference(sha1);
80 if(!commit) { 80 if(!commit) {
81 cgit_print_error(fmt("Not a commit reference: %s", hex)); 81 cgit_print_error(fmt("Not a commit reference: %s", hex));
82 return 1; 82 return 1;
83 } 83 }
84 memset(&args, 0, sizeof(args)); 84 memset(&args, 0, sizeof(args));
85 args.base = fmt("%s/", prefix); 85 if (prefix) {
86 args.base = fmt("%s/", prefix);
87 args.baselen = strlen(prefix) + 1;
88 } else {
89 args.base = "";
90 args.baselen = 0;
91 }
86 args.tree = commit->tree; 92 args.tree = commit->tree;
87 args.time = commit->date; 93 args.time = commit->date;
88 ctx.page.mimetype = xstrdup(format->mimetype); 94 ctx.page.mimetype = xstrdup(format->mimetype);
89 ctx.page.filename = xstrdup(filename); 95 ctx.page.filename = xstrdup(filename);
90 cgit_print_http_headers(&ctx); 96 cgit_print_http_headers(&ctx);
91 format->write_func(&args); 97 format->write_func(&args);
92 return 0; 98 return 0;
93} 99}
94 100
95void cgit_print_snapshot(const char *head, const char *hex, const char *prefix, 101void cgit_print_snapshot(const char *head, const char *hex, const char *prefix,
96 const char *filename, int snapshots) 102 const char *filename, int snapshots)
97{ 103{
98 const struct cgit_snapshot_format* f; 104 const struct cgit_snapshot_format* f;
99 int sl, fnl; 105 int sl, fnl;
100 106
101 fnl = strlen(filename); 107 fnl = strlen(filename);
102 if (!hex) 108 if (!hex)
103 hex = head; 109 hex = head;
104 for (f = cgit_snapshot_formats; f->suffix; f++) { 110 for (f = cgit_snapshot_formats; f->suffix; f++) {
105 if (!(snapshots & f->bit)) 111 if (!(snapshots & f->bit))
106 continue; 112 continue;
107 sl = strlen(f->suffix); 113 sl = strlen(f->suffix);
108 if(fnl < sl || strcmp(&filename[fnl-sl], f->suffix)) 114 if(fnl < sl || strcmp(&filename[fnl-sl], f->suffix))
109 continue; 115 continue;
110 make_snapshot(f, hex, prefix, filename); 116 make_snapshot(f, hex, prefix, filename);
111 return; 117 return;
112 } 118 }
113 cgit_print_error(fmt("Unsupported snapshot format: %s", filename)); 119 cgit_print_error(fmt("Unsupported snapshot format: %s", filename));
114} 120}