summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.h8
-rw-r--r--shared.c27
-rw-r--r--ui-shared.c17
-rw-r--r--ui-snapshot.c98
4 files changed, 77 insertions, 73 deletions
diff --git a/cgit.h b/cgit.h
index 295441b..e2d5126 100644
--- a/cgit.h
+++ b/cgit.h
@@ -132,100 +132,108 @@ struct cgit_config {
132 char *clone_prefix; 132 char *clone_prefix;
133 char *css; 133 char *css;
134 char *index_header; 134 char *index_header;
135 char *index_info; 135 char *index_info;
136 char *logo; 136 char *logo;
137 char *logo_link; 137 char *logo_link;
138 char *module_link; 138 char *module_link;
139 char *repo_group; 139 char *repo_group;
140 char *robots; 140 char *robots;
141 char *root_title; 141 char *root_title;
142 char *script_name; 142 char *script_name;
143 char *virtual_root; 143 char *virtual_root;
144 int cache_dynamic_ttl; 144 int cache_dynamic_ttl;
145 int cache_max_create_time; 145 int cache_max_create_time;
146 int cache_repo_ttl; 146 int cache_repo_ttl;
147 int cache_root_ttl; 147 int cache_root_ttl;
148 int cache_static_ttl; 148 int cache_static_ttl;
149 int enable_index_links; 149 int enable_index_links;
150 int enable_log_filecount; 150 int enable_log_filecount;
151 int enable_log_linecount; 151 int enable_log_linecount;
152 int max_commit_count; 152 int max_commit_count;
153 int max_lock_attempts; 153 int max_lock_attempts;
154 int max_msg_len; 154 int max_msg_len;
155 int max_repodesc_len; 155 int max_repodesc_len;
156 int nocache; 156 int nocache;
157 int renamelimit; 157 int renamelimit;
158 int snapshots; 158 int snapshots;
159 int summary_branches; 159 int summary_branches;
160 int summary_log; 160 int summary_log;
161 int summary_tags; 161 int summary_tags;
162}; 162};
163 163
164struct cgit_page { 164struct cgit_page {
165 time_t modified; 165 time_t modified;
166 time_t expires; 166 time_t expires;
167 char *mimetype; 167 char *mimetype;
168 char *charset; 168 char *charset;
169 char *filename; 169 char *filename;
170 char *title; 170 char *title;
171}; 171};
172 172
173struct cgit_context { 173struct cgit_context {
174 struct cgit_query qry; 174 struct cgit_query qry;
175 struct cgit_config cfg; 175 struct cgit_config cfg;
176 struct cgit_repo *repo; 176 struct cgit_repo *repo;
177 struct cgit_page page; 177 struct cgit_page page;
178}; 178};
179 179
180struct cgit_snapshot_format {
181 const char *suffix;
182 const char *mimetype;
183 write_archive_fn_t write_func;
184 int bit;
185};
186
180extern const char *cgit_version; 187extern const char *cgit_version;
181 188
182extern struct cgit_repolist cgit_repolist; 189extern struct cgit_repolist cgit_repolist;
183extern struct cgit_context ctx; 190extern struct cgit_context ctx;
191extern const struct cgit_snapshot_format cgit_snapshot_formats[];
184extern int cgit_cmd; 192extern int cgit_cmd;
185 193
186extern void cgit_prepare_context(struct cgit_context *ctx); 194extern void cgit_prepare_context(struct cgit_context *ctx);
187extern struct cgit_repo *cgit_get_repoinfo(const char *url); 195extern struct cgit_repo *cgit_get_repoinfo(const char *url);
188extern void cgit_global_config_cb(const char *name, const char *value); 196extern void cgit_global_config_cb(const char *name, const char *value);
189extern void cgit_repo_config_cb(const char *name, const char *value); 197extern void cgit_repo_config_cb(const char *name, const char *value);
190extern void cgit_querystring_cb(const char *name, const char *value); 198extern void cgit_querystring_cb(const char *name, const char *value);
191 199
192extern int chk_zero(int result, char *msg); 200extern int chk_zero(int result, char *msg);
193extern int chk_positive(int result, char *msg); 201extern int chk_positive(int result, char *msg);
194extern int chk_non_negative(int result, char *msg); 202extern int chk_non_negative(int result, char *msg);
195 203
196extern int hextoint(char c); 204extern int hextoint(char c);
197extern char *trim_end(const char *str, char c); 205extern char *trim_end(const char *str, char c);
198extern char *strlpart(char *txt, int maxlen); 206extern char *strlpart(char *txt, int maxlen);
199extern char *strrpart(char *txt, int maxlen); 207extern char *strrpart(char *txt, int maxlen);
200 208
201extern void cgit_add_ref(struct reflist *list, struct refinfo *ref); 209extern void cgit_add_ref(struct reflist *list, struct refinfo *ref);
202extern int cgit_refs_cb(const char *refname, const unsigned char *sha1, 210extern int cgit_refs_cb(const char *refname, const unsigned char *sha1,
203 int flags, void *cb_data); 211 int flags, void *cb_data);
204 212
205extern void *cgit_free_commitinfo(struct commitinfo *info); 213extern void *cgit_free_commitinfo(struct commitinfo *info);
206 214
207extern int cgit_diff_files(const unsigned char *old_sha1, 215extern int cgit_diff_files(const unsigned char *old_sha1,
208 const unsigned char *new_sha1, 216 const unsigned char *new_sha1,
209 linediff_fn fn); 217 linediff_fn fn);
210 218
211extern void cgit_diff_tree(const unsigned char *old_sha1, 219extern void cgit_diff_tree(const unsigned char *old_sha1,
212 const unsigned char *new_sha1, 220 const unsigned char *new_sha1,
213 filepair_fn fn, const char *prefix); 221 filepair_fn fn, const char *prefix);
214 222
215extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); 223extern void cgit_diff_commit(struct commit *commit, filepair_fn fn);
216 224
217extern char *fmt(const char *format,...); 225extern char *fmt(const char *format,...);
218 226
219extern int cgit_read_config(const char *filename, configfn fn); 227extern int cgit_read_config(const char *filename, configfn fn);
220extern int cgit_parse_query(char *txt, configfn fn); 228extern int cgit_parse_query(char *txt, configfn fn);
221extern struct commitinfo *cgit_parse_commit(struct commit *commit); 229extern struct commitinfo *cgit_parse_commit(struct commit *commit);
222extern struct taginfo *cgit_parse_tag(struct tag *tag); 230extern struct taginfo *cgit_parse_tag(struct tag *tag);
223extern void cgit_parse_url(const char *url); 231extern void cgit_parse_url(const char *url);
224 232
225extern char *cache_safe_filename(const char *unsafe); 233extern char *cache_safe_filename(const char *unsafe);
226extern int cache_lock(struct cacheitem *item); 234extern int cache_lock(struct cacheitem *item);
227extern int cache_unlock(struct cacheitem *item); 235extern int cache_unlock(struct cacheitem *item);
228extern int cache_cancel_lock(struct cacheitem *item); 236extern int cache_cancel_lock(struct cacheitem *item);
229extern int cache_exist(struct cacheitem *item); 237extern int cache_exist(struct cacheitem *item);
230extern int cache_expired(struct cacheitem *item); 238extern int cache_expired(struct cacheitem *item);
231 239
diff --git a/shared.c b/shared.c
index 67eb67b..800c06a 100644
--- a/shared.c
+++ b/shared.c
@@ -434,48 +434,75 @@ int cgit_diff_files(const unsigned char *old_sha1,
434 emit_params.ctxlen = 3; 434 emit_params.ctxlen = 3;
435 emit_params.flags = XDL_EMIT_FUNCNAMES; 435 emit_params.flags = XDL_EMIT_FUNCNAMES;
436 emit_params.find_func = NULL; 436 emit_params.find_func = NULL;
437 emit_cb.outf = filediff_cb; 437 emit_cb.outf = filediff_cb;
438 emit_cb.priv = fn; 438 emit_cb.priv = fn;
439 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb); 439 xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
440 return 0; 440 return 0;
441} 441}
442 442
443void cgit_diff_tree(const unsigned char *old_sha1, 443void cgit_diff_tree(const unsigned char *old_sha1,
444 const unsigned char *new_sha1, 444 const unsigned char *new_sha1,
445 filepair_fn fn, const char *prefix) 445 filepair_fn fn, const char *prefix)
446{ 446{
447 struct diff_options opt; 447 struct diff_options opt;
448 int ret; 448 int ret;
449 int prefixlen; 449 int prefixlen;
450 450
451 diff_setup(&opt); 451 diff_setup(&opt);
452 opt.output_format = DIFF_FORMAT_CALLBACK; 452 opt.output_format = DIFF_FORMAT_CALLBACK;
453 opt.detect_rename = 1; 453 opt.detect_rename = 1;
454 opt.rename_limit = ctx.cfg.renamelimit; 454 opt.rename_limit = ctx.cfg.renamelimit;
455 DIFF_OPT_SET(&opt, RECURSIVE); 455 DIFF_OPT_SET(&opt, RECURSIVE);
456 opt.format_callback = cgit_diff_tree_cb; 456 opt.format_callback = cgit_diff_tree_cb;
457 opt.format_callback_data = fn; 457 opt.format_callback_data = fn;
458 if (prefix) { 458 if (prefix) {
459 opt.nr_paths = 1; 459 opt.nr_paths = 1;
460 opt.paths = &prefix; 460 opt.paths = &prefix;
461 prefixlen = strlen(prefix); 461 prefixlen = strlen(prefix);
462 opt.pathlens = &prefixlen; 462 opt.pathlens = &prefixlen;
463 } 463 }
464 diff_setup_done(&opt); 464 diff_setup_done(&opt);
465 465
466 if (old_sha1 && !is_null_sha1(old_sha1)) 466 if (old_sha1 && !is_null_sha1(old_sha1))
467 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); 467 ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt);
468 else 468 else
469 ret = diff_root_tree_sha1(new_sha1, "", &opt); 469 ret = diff_root_tree_sha1(new_sha1, "", &opt);
470 diffcore_std(&opt); 470 diffcore_std(&opt);
471 diff_flush(&opt); 471 diff_flush(&opt);
472} 472}
473 473
474void cgit_diff_commit(struct commit *commit, filepair_fn fn) 474void cgit_diff_commit(struct commit *commit, filepair_fn fn)
475{ 475{
476 unsigned char *old_sha1 = NULL; 476 unsigned char *old_sha1 = NULL;
477 477
478 if (commit->parents) 478 if (commit->parents)
479 old_sha1 = commit->parents->item->object.sha1; 479 old_sha1 = commit->parents->item->object.sha1;
480 cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL); 480 cgit_diff_tree(old_sha1, commit->object.sha1, fn, NULL);
481} 481}
482
483int cgit_parse_snapshots_mask(const char *str)
484{
485 const struct cgit_snapshot_format *f;
486 static const char *delim = " \t,:/|;";
487 int tl, sl, rv = 0;
488
489 /* favor legacy setting */
490 if(atoi(str))
491 return 1;
492 for(;;) {
493 str += strspn(str,delim);
494 tl = strcspn(str,delim);
495 if (!tl)
496 break;
497 for (f = cgit_snapshot_formats; f->suffix; f++) {
498 sl = strlen(f->suffix);
499 if((tl == sl && !strncmp(f->suffix, str, tl)) ||
500 (tl == sl-1 && !strncmp(f->suffix+1, str, tl-1))) {
501 rv |= f->bit;
502 break;
503 }
504 }
505 str += tl;
506 }
507 return rv;
508}
diff --git a/ui-shared.c b/ui-shared.c
index 2596023..aa65988 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -528,49 +528,64 @@ void cgit_print_pageheader(struct cgit_context *ctx)
528 for_each_branch_ref(print_branch_option, ctx->qry.head); 528 for_each_branch_ref(print_branch_option, ctx->qry.head);
529 html("</select>\n"); 529 html("</select>\n");
530 // html("</td><td>"); 530 // html("</td><td>");
531 html("<noscript><input type='submit' id='switch-btn' value='switch'/></noscript>\n"); 531 html("<noscript><input type='submit' id='switch-btn' value='switch'/></noscript>\n");
532 // html("</td></tr></table>"); 532 // html("</td></tr></table>");
533 html("</form>\n"); 533 html("</form>\n");
534 534
535 html("<h1>search</h1>\n"); 535 html("<h1>search</h1>\n");
536 html("<form method='get' action='"); 536 html("<form method='get' action='");
537 if (ctx->cfg.virtual_root) 537 if (ctx->cfg.virtual_root)
538 html_attr(cgit_fileurl(ctx->qry.repo, "log", 538 html_attr(cgit_fileurl(ctx->qry.repo, "log",
539 ctx->qry.path, NULL)); 539 ctx->qry.path, NULL));
540 html("'>\n"); 540 html("'>\n");
541 add_hidden_formfields(1, 0, "log"); 541 add_hidden_formfields(1, 0, "log");
542 html("<select name='qt'>\n"); 542 html("<select name='qt'>\n");
543 html_option("grep", "log msg", ctx->qry.grep); 543 html_option("grep", "log msg", ctx->qry.grep);
544 html_option("author", "author", ctx->qry.grep); 544 html_option("author", "author", ctx->qry.grep);
545 html_option("committer", "committer", ctx->qry.grep); 545 html_option("committer", "committer", ctx->qry.grep);
546 html("</select>\n"); 546 html("</select>\n");
547 html("<input class='txt' type='text' name='q' value='"); 547 html("<input class='txt' type='text' name='q' value='");
548 html_attr(ctx->qry.search); 548 html_attr(ctx->qry.search);
549 html("'/>\n"); 549 html("'/>\n");
550 html("</form>\n"); 550 html("</form>\n");
551 } else { 551 } else {
552 if (!ctx->cfg.index_info || html_include(ctx->cfg.index_info)) 552 if (!ctx->cfg.index_info || html_include(ctx->cfg.index_info))
553 html(default_info); 553 html(default_info);
554 } 554 }
555 555
556 html("</td></tr></table></td>\n"); 556 html("</td></tr></table></td>\n");
557 557
558 html("<td id='content'>\n"); 558 html("<td id='content'>\n");
559} 559}
560 560
561void cgit_print_filemode(unsigned short mode) 561void cgit_print_filemode(unsigned short mode)
562{ 562{
563 if (S_ISDIR(mode)) 563 if (S_ISDIR(mode))
564 html("d"); 564 html("d");
565 else if (S_ISLNK(mode)) 565 else if (S_ISLNK(mode))
566 html("l"); 566 html("l");
567 else if (S_ISGITLINK(mode)) 567 else if (S_ISGITLINK(mode))
568 html("m"); 568 html("m");
569 else 569 else
570 html("-"); 570 html("-");
571 html_fileperm(mode >> 6); 571 html_fileperm(mode >> 6);
572 html_fileperm(mode >> 3); 572 html_fileperm(mode >> 3);
573 html_fileperm(mode); 573 html_fileperm(mode);
574} 574}
575 575
576/* vim:set sw=8: */ 576void cgit_print_snapshot_links(const char *repo, const char *head,
577 const char *hex, int snapshots)
578{
579 const struct cgit_snapshot_format* f;
580 char *filename;
581
582 for (f = cgit_snapshot_formats; f->suffix; f++) {
583 if (!(snapshots & f->bit))
584 continue;
585 filename = fmt("%s-%s%s", cgit_repobasename(repo), hex,
586 f->suffix);
587 cgit_snapshot_link(filename, NULL, NULL, (char *)head,
588 (char *)hex, filename);
589 html("<br/>");
590 }
591}
diff --git a/ui-snapshot.c b/ui-snapshot.c
index c741469..512fcd2 100644
--- a/ui-snapshot.c
+++ b/ui-snapshot.c
@@ -10,150 +10,104 @@
10#include "html.h" 10#include "html.h"
11 11
12static int write_compressed_tar_archive(struct archiver_args *args,const char *filter) 12static int write_compressed_tar_archive(struct archiver_args *args,const char *filter)
13{ 13{
14 int rw[2]; 14 int rw[2];
15 pid_t gzpid; 15 pid_t gzpid;
16 int stdout2; 16 int stdout2;
17 int status; 17 int status;
18 int rv; 18 int rv;
19 19
20 stdout2 = chk_non_negative(dup(STDIN_FILENO), "Preserving STDOUT before compressing"); 20 stdout2 = chk_non_negative(dup(STDIN_FILENO), "Preserving STDOUT before compressing");
21 chk_zero(pipe(rw), "Opening pipe from compressor subprocess"); 21 chk_zero(pipe(rw), "Opening pipe from compressor subprocess");
22 gzpid = chk_non_negative(fork(), "Forking compressor subprocess"); 22 gzpid = chk_non_negative(fork(), "Forking compressor subprocess");
23 if(gzpid==0) { 23 if(gzpid==0) {
24 /* child */ 24 /* child */
25 chk_zero(close(rw[1]), "Closing write end of pipe in child"); 25 chk_zero(close(rw[1]), "Closing write end of pipe in child");
26 chk_zero(close(STDIN_FILENO), "Closing STDIN"); 26 chk_zero(close(STDIN_FILENO), "Closing STDIN");
27 chk_non_negative(dup2(rw[0],STDIN_FILENO), "Redirecting compressor input to stdin"); 27 chk_non_negative(dup2(rw[0],STDIN_FILENO), "Redirecting compressor input to stdin");
28 execlp(filter,filter,NULL); 28 execlp(filter,filter,NULL);
29 _exit(-1); 29 _exit(-1);
30 } 30 }
31 /* parent */ 31 /* parent */
32 chk_zero(close(rw[0]), "Closing read end of pipe"); 32 chk_zero(close(rw[0]), "Closing read end of pipe");
33 chk_non_negative(dup2(rw[1],STDOUT_FILENO), "Redirecting output to compressor"); 33 chk_non_negative(dup2(rw[1],STDOUT_FILENO), "Redirecting output to compressor");
34 34
35 rv = write_tar_archive(args); 35 rv = write_tar_archive(args);
36 36
37 chk_zero(close(STDOUT_FILENO), "Closing STDOUT redirected to compressor"); 37 chk_zero(close(STDOUT_FILENO), "Closing STDOUT redirected to compressor");
38 chk_non_negative(dup2(stdout2,STDOUT_FILENO), "Restoring uncompressed STDOUT"); 38 chk_non_negative(dup2(stdout2,STDOUT_FILENO), "Restoring uncompressed STDOUT");
39 chk_zero(close(stdout2), "Closing uncompressed STDOUT"); 39 chk_zero(close(stdout2), "Closing uncompressed STDOUT");
40 chk_zero(close(rw[1]), "Closing write end of pipe in parent"); 40 chk_zero(close(rw[1]), "Closing write end of pipe in parent");
41 chk_positive(waitpid(gzpid,&status,0), "Waiting on compressor process"); 41 chk_positive(waitpid(gzpid,&status,0), "Waiting on compressor process");
42 if(! ( WIFEXITED(status) && WEXITSTATUS(status)==0 ) ) 42 if(! ( WIFEXITED(status) && WEXITSTATUS(status)==0 ) )
43 cgit_print_error("Failed to compress archive"); 43 cgit_print_error("Failed to compress archive");
44 44
45 return rv; 45 return rv;
46} 46}
47 47
48static int write_tar_gzip_archive(struct archiver_args *args) 48static int write_tar_gzip_archive(struct archiver_args *args)
49{ 49{
50 return write_compressed_tar_archive(args,"gzip"); 50 return write_compressed_tar_archive(args,"gzip");
51} 51}
52 52
53static int write_tar_bzip2_archive(struct archiver_args *args) 53static int write_tar_bzip2_archive(struct archiver_args *args)
54{ 54{
55 return write_compressed_tar_archive(args,"bzip2"); 55 return write_compressed_tar_archive(args,"bzip2");
56} 56}
57 57
58static const struct snapshot_archive_t { 58const struct cgit_snapshot_format cgit_snapshot_formats[] = {
59 const char *suffix;
60 const char *mimetype;
61 write_archive_fn_t write_func;
62 int bit;
63 }snapshot_archives[] = {
64 { ".zip", "application/x-zip", write_zip_archive, 0x1 }, 59 { ".zip", "application/x-zip", write_zip_archive, 0x1 },
65 { ".tar.gz", "application/x-tar", write_tar_gzip_archive, 0x2 }, 60 { ".tar.gz", "application/x-tar", write_tar_gzip_archive, 0x2 },
66 { ".tar.bz2", "application/x-tar", write_tar_bzip2_archive, 0x4 }, 61 { ".tar.bz2", "application/x-tar", write_tar_bzip2_archive, 0x4 },
67 { ".tar", "application/x-tar", write_tar_archive, 0x8 } 62 { ".tar", "application/x-tar", write_tar_archive, 0x8 },
63 {}
68}; 64};
69 65
70#define snapshot_archives_len (sizeof(snapshot_archives) / sizeof(*snapshot_archives)) 66static int make_snapshot(const struct cgit_snapshot_format *format,
71 67 const char *hex, const char *prefix,
72void cgit_print_snapshot(const char *head, const char *hex, const char *prefix, 68 const char *filename)
73 const char *filename, int snapshots)
74{ 69{
75 const struct snapshot_archive_t* sat;
76 struct archiver_args args; 70 struct archiver_args args;
77 struct commit *commit; 71 struct commit *commit;
78 unsigned char sha1[20]; 72 unsigned char sha1[20];
79 int f, sl, fnl = strlen(filename);
80 73
81 for(f=0; f<snapshot_archives_len; f++) {
82 sat = &snapshot_archives[f];
83 if(!(snapshots & sat->bit))
84 continue;
85 sl = strlen(sat->suffix);
86 if(fnl<sl || strcmp(&filename[fnl-sl],sat->suffix))
87 continue;
88 if (!hex)
89 hex = head;
90 if(get_sha1(hex, sha1)) { 74 if(get_sha1(hex, sha1)) {
91 cgit_print_error(fmt("Bad object id: %s", hex)); 75 cgit_print_error(fmt("Bad object id: %s", hex));
92 return; 76 return 1;
93 } 77 }
94 commit = lookup_commit_reference(sha1); 78 commit = lookup_commit_reference(sha1);
95 if(!commit) { 79 if(!commit) {
96 cgit_print_error(fmt("Not a commit reference: %s", hex)); 80 cgit_print_error(fmt("Not a commit reference: %s", hex));
97 return;; 81 return 1;
98 } 82 }
99 memset(&args,0,sizeof(args)); 83 memset(&args,0,sizeof(args));
100 args.base = fmt("%s/", prefix); 84 args.base = fmt("%s/", prefix);
101 args.tree = commit->tree; 85 args.tree = commit->tree;
102 args.time = commit->date; 86 args.time = commit->date;
103 ctx.page.mimetype = xstrdup(sat->mimetype); 87 ctx.page.mimetype = xstrdup(format->mimetype);
104 ctx.page.filename = xstrdup(filename); 88 ctx.page.filename = xstrdup(filename);
105 cgit_print_http_headers(&ctx); 89 cgit_print_http_headers(&ctx);
106 (*sat->write_func)(&args); 90 format->write_func(&args);
107 return; 91 return 0;
108 }
109 cgit_print_error(fmt("Unsupported snapshot format: %s", filename));
110} 92}
111 93
112void cgit_print_snapshot_links(const char *repo, const char *head, 94void cgit_print_snapshot(const char *head, const char *hex, const char *prefix,
113 const char *hex, int snapshots) 95 const char *filename, int snapshots)
114{ 96{
115 const struct snapshot_archive_t* sat; 97 const struct cgit_snapshot_format* f;
116 char *filename; 98 int sl, fnl;
117 int f;
118 99
119 for(f=0; f<snapshot_archives_len; f++) { 100 fnl = strlen(filename);
120 sat = &snapshot_archives[f]; 101 if (!hex)
121 if(!(snapshots & sat->bit)) 102 hex = head;
103 for (f = cgit_snapshot_formats; f->suffix; f++) {
104 if (!(snapshots & f->bit))
122 continue; 105 continue;
123 filename = fmt("%s-%s%s", cgit_repobasename(repo), hex, 106 sl = strlen(f->suffix);
124 sat->suffix); 107 if(fnl < sl || strcmp(&filename[fnl-sl], f->suffix))
125 cgit_snapshot_link(filename, NULL, NULL, (char *)head, 108 continue;
126 (char *)hex, filename); 109 make_snapshot(f, hex, prefix, filename);
127 html("<br/>"); 110 return;
128 }
129}
130
131int cgit_parse_snapshots_mask(const char *str)
132{
133 const struct snapshot_archive_t* sat;
134 static const char *delim = " \t,:/|;";
135 int f, tl, sl, rv = 0;
136
137 /* favor legacy setting */
138 if(atoi(str))
139 return 1;
140 for(;;) {
141 str += strspn(str,delim);
142 tl = strcspn(str,delim);
143 if(!tl)
144 break;
145 for(f=0; f<snapshot_archives_len; f++) {
146 sat = &snapshot_archives[f];
147 sl = strlen(sat->suffix);
148 if((tl == sl && !strncmp(sat->suffix, str, tl)) ||
149 (tl == sl-1 && !strncmp(sat->suffix+1, str, tl-1))) {
150 rv |= sat->bit;
151 break;
152 }
153 }
154 str += tl;
155 } 111 }
156 return rv; 112 cgit_print_error(fmt("Unsupported snapshot format: %s", filename));
157} 113}
158
159/* vim:set sw=8: */