-rw-r--r-- | cgit.c | 2 | ||||
-rw-r--r-- | cgit.h | 4 | ||||
-rw-r--r-- | ui-commit.c | 9 | ||||
-rw-r--r-- | ui-snapshot.c | 77 |
4 files changed, 55 insertions, 37 deletions
@@ -23,97 +23,97 @@ static int cgit_prepare_cache(struct cacheitem *item) item->name = xstrdup(fmt("%s/index.html", cgit_cache_root)); item->ttl = cgit_cache_root_ttl; return 1; } if (!cgit_cmd) { item->name = xstrdup(fmt("%s/%s/index.%s.html", cgit_cache_root, cache_safe_filename(cgit_repo->url), cache_safe_filename(cgit_querystring))); item->ttl = cgit_cache_repo_ttl; } else { item->name = xstrdup(fmt("%s/%s/%s/%s.html", cgit_cache_root, cache_safe_filename(cgit_repo->url), cgit_query_page, cache_safe_filename(cgit_querystring))); if (cgit_query_has_symref) item->ttl = cgit_cache_dynamic_ttl; else if (cgit_query_has_sha1) item->ttl = cgit_cache_static_ttl; else item->ttl = cgit_cache_repo_ttl; } return 1; } static void cgit_print_repo_page(struct cacheitem *item) { char *title; int show_search; if (!cgit_query_head) cgit_query_head = cgit_repo->defbranch; if (chdir(cgit_repo->path)) { title = fmt("%s - %s", cgit_root_title, "Bad request"); cgit_print_docstart(title, item); cgit_print_pageheader(title, 0); cgit_print_error(fmt("Unable to scan repository: %s", strerror(errno))); cgit_print_docend(); return; } title = fmt("%s - %s", cgit_repo->name, cgit_repo->desc); show_search = 0; setenv("GIT_DIR", cgit_repo->path, 1); if ((cgit_cmd == CMD_SNAPSHOT) && cgit_repo->snapshots) { - cgit_print_snapshot(item, cgit_query_sha1, "zip", + cgit_print_snapshot(item, cgit_query_sha1, cgit_repo->url, cgit_query_name); return; } if (cgit_cmd == CMD_BLOB) { cgit_print_blob(item, cgit_query_sha1, cgit_query_path); return; } show_search = (cgit_cmd == CMD_LOG); cgit_print_docstart(title, item); if (!cgit_cmd) { cgit_print_pageheader("summary", show_search); cgit_print_summary(); cgit_print_docend(); return; } cgit_print_pageheader(cgit_query_page, show_search); switch(cgit_cmd) { case CMD_LOG: cgit_print_log(cgit_query_sha1, cgit_query_ofs, cgit_max_commit_count, cgit_query_search, cgit_query_path, 1); break; case CMD_TREE: cgit_print_tree(cgit_query_sha1, cgit_query_path); break; case CMD_COMMIT: cgit_print_commit(cgit_query_sha1); break; case CMD_DIFF: cgit_print_diff(cgit_query_sha1, cgit_query_sha2); break; default: cgit_print_error("Invalid request"); } cgit_print_docend(); } static void cgit_fill_cache(struct cacheitem *item, int use_cache) { static char buf[PATH_MAX]; int stdout2; getcwd(buf, sizeof(buf)); item->st.st_mtime = time(NULL); @@ -185,52 +185,52 @@ extern void html_link_open(char *url, char *title, char *class); extern void html_link_close(void); extern void html_filemode(unsigned short mode); extern int html_include(const char *filename); extern int cgit_read_config(const char *filename, configfn fn); extern int cgit_parse_query(char *txt, configfn fn); extern struct commitinfo *cgit_parse_commit(struct commit *commit); extern struct taginfo *cgit_parse_tag(struct tag *tag); extern void cgit_parse_url(const char *url); extern char *cache_safe_filename(const char *unsafe); extern int cache_lock(struct cacheitem *item); extern int cache_unlock(struct cacheitem *item); extern int cache_cancel_lock(struct cacheitem *item); extern int cache_exist(struct cacheitem *item); extern int cache_expired(struct cacheitem *item); extern char *cgit_repourl(const char *reponame); extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); extern void cgit_tree_link(char *name, char *title, char *class, char *head, char *rev, char *path); extern void cgit_log_link(char *name, char *title, char *class, char *head, char *rev, char *path, int ofs); extern void cgit_commit_link(char *name, char *title, char *class, char *head, char *rev); extern void cgit_diff_link(char *name, char *title, char *class, char *head, char *new_rev, char *old_rev, char *path); extern void cgit_print_error(char *msg); extern void cgit_print_date(time_t secs, char *format); extern void cgit_print_age(time_t t, time_t max_relative, char *format); extern void cgit_print_docstart(char *title, struct cacheitem *item); extern void cgit_print_docend(); extern void cgit_print_pageheader(char *title, int show_search); extern void cgit_print_snapshot_start(const char *mimetype, const char *filename, struct cacheitem *item); extern void cgit_print_repolist(struct cacheitem *item); extern void cgit_print_summary(); extern void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *path, int pager); extern void cgit_print_blob(struct cacheitem *item, const char *hex, char *path); extern void cgit_print_tree(const char *rev, char *path); extern void cgit_print_commit(char *hex); extern void cgit_print_diff(const char *new_hex, const char *old_hex); extern void cgit_print_snapshot(struct cacheitem *item, const char *hex, - const char *format, const char *prefix, - const char *filename); + const char *prefix, const char *filename); +extern void cgit_print_snapshot_links(const char *repo, const char *hex); #endif /* CGIT_H */ diff --git a/ui-commit.c b/ui-commit.c index 2679b59..bf5e6dc 100644 --- a/ui-commit.c +++ b/ui-commit.c @@ -94,135 +94,132 @@ void print_fileinfo(struct fileinfo *info) html("</tr></table></td></tr>\n"); } void cgit_count_diff_lines(char *line, int len) { if (line && (len > 0)) { if (line[0] == '+') lines_added++; else if (line[0] == '-') lines_removed++; } } void inspect_filepair(struct diff_filepair *pair) { files++; lines_added = 0; lines_removed = 0; cgit_diff_files(pair->one->sha1, pair->two->sha1, cgit_count_diff_lines); if (files >= slots) { if (slots == 0) slots = 4; else slots = slots * 2; items = xrealloc(items, slots * sizeof(struct fileinfo)); } items[files-1].status = pair->status; hashcpy(items[files-1].old_sha1, pair->one->sha1); hashcpy(items[files-1].new_sha1, pair->two->sha1); items[files-1].old_mode = pair->one->mode; items[files-1].new_mode = pair->two->mode; items[files-1].old_path = xstrdup(pair->one->path); items[files-1].new_path = xstrdup(pair->two->path); items[files-1].added = lines_added; items[files-1].removed = lines_removed; if (lines_added + lines_removed > max_changes) max_changes = lines_added + lines_removed; total_adds += lines_added; total_rems += lines_removed; } void cgit_print_commit(char *hex) { struct commit *commit, *parent; struct commitinfo *info; struct commit_list *p; unsigned char sha1[20]; - char *filename; char *tmp; int i; if (!hex) hex = cgit_query_head; curr_rev = hex; if (get_sha1(hex, sha1)) { cgit_print_error(fmt("Bad object id: %s", hex)); return; } commit = lookup_commit_reference(sha1); if (!commit) { cgit_print_error(fmt("Bad commit reference: %s", hex)); return; } info = cgit_parse_commit(commit); html("<table class='commit-info'>\n"); html("<tr><th>author</th><td>"); html_txt(info->author); html(" "); html_txt(info->author_email); html("</td><td class='right'>"); cgit_print_date(info->author_date, FMT_LONGDATE); html("</td></tr>\n"); html("<tr><th>committer</th><td>"); html_txt(info->committer); html(" "); html_txt(info->committer_email); html("</td><td class='right'>"); cgit_print_date(info->committer_date, FMT_LONGDATE); html("</td></tr>\n"); html("<tr><th>tree</th><td colspan='2' class='sha1'>"); tmp = xstrdup(hex); cgit_tree_link(sha1_to_hex(commit->tree->object.sha1), NULL, NULL, cgit_query_head, tmp, NULL); html("</td></tr>\n"); for (p = commit->parents; p ; p = p->next) { parent = lookup_commit_reference(p->item->object.sha1); if (!parent) { html("<tr><td colspan='3'>"); cgit_print_error("Error reading parent commit"); html("</td></tr>"); continue; } html("<tr><th>parent</th>" "<td colspan='2' class='sha1'>"); cgit_commit_link(sha1_to_hex(p->item->object.sha1), NULL, NULL, cgit_query_head, sha1_to_hex(p->item->object.sha1)); html(" ("); cgit_diff_link("diff", NULL, NULL, cgit_query_head, hex, sha1_to_hex(p->item->object.sha1), NULL); html(")</td></tr>"); } if (cgit_repo->snapshots) { - htmlf("<tr><th>download</th><td colspan='2' class='sha1'><a href='"); - filename = fmt("%s-%s.zip", cgit_query_repo, hex); - html_attr(cgit_pageurl(cgit_query_repo, "snapshot", - fmt("id=%s&name=%s", hex, filename))); - htmlf("'>%s</a></td></tr>", filename); + html("<tr><th>download</th><td colspan='2' class='sha1'>"); + cgit_print_snapshot_links(cgit_query_repo,hex); + html("</td></tr>"); } html("</table>\n"); html("<div class='commit-subject'>"); html_txt(info->subject); html("</div>"); html("<div class='commit-msg'>"); html_txt(info->msg); html("</div>"); if (!(commit->parents && commit->parents->next && commit->parents->next->next)) { html("<div class='diffstat-header'>Diffstat</div>"); html("<table class='diffstat'>"); max_changes = 0; cgit_diff_commit(commit, inspect_filepair); for(i = 0; i<files; i++) print_fileinfo(&items[i]); html("</table>"); html("<div class='diffstat-summary'>"); htmlf("%d files changed, %d insertions, %d deletions (", files, total_adds, total_rems); cgit_diff_link("show diff", NULL, NULL, cgit_query_head, hex, NULL, NULL); html(")</div>"); } cgit_free_commitinfo(info); } diff --git a/ui-snapshot.c b/ui-snapshot.c index 2257d6b..eb5f1cd 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -1,47 +1,68 @@ /* ui-snapshot.c: generate snapshot of a commit * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" -static void cgit_print_zip(struct cacheitem *item, const char *hex, - const char *prefix, const char *filename) +static const struct snapshot_archive_t { + const char *suffix; + const char *mimetype; + write_archive_fn_t write_func; +} snapshot_archives[] = { + { ".zip", "application/x-zip", write_zip_archive }, + { ".tar.gz", "application/x-gzip", write_tar_archive } +}; + +void cgit_print_snapshot(struct cacheitem *item, const char *hex, + const char *prefix, const char *filename) { - struct archiver_args args; - struct commit *commit; - unsigned char sha1[20]; + int fnl = strlen(filename); + int f; + for(f=0;f<(sizeof(snapshot_archives)/sizeof(*snapshot_archives));++f) { + const struct snapshot_archive_t* sat = &snapshot_archives[f]; + int sl = strlen(sat->suffix); + if(fnl<sl || strcmp(&filename[fnl-sl],sat->suffix)) + continue; - if (get_sha1(hex, sha1)) { - cgit_print_error(fmt("Bad object id: %s", hex)); - return; - } - commit = lookup_commit_reference(sha1); + struct archiver_args args; + struct commit *commit; + unsigned char sha1[20]; + + if(get_sha1(hex, sha1)) { + cgit_print_error(fmt("Bad object id: %s", hex)); + return; + } + commit = lookup_commit_reference(sha1); + + if(!commit) { + cgit_print_error(fmt("Not a commit reference: %s", hex)); + return;; + } - if (!commit) { - cgit_print_error(fmt("Not a commit reference: %s", hex)); + memset(&args,0,sizeof(args)); + args.base = fmt("%s/", prefix); + args.tree = commit->tree; + + cgit_print_snapshot_start(sat->mimetype, filename, item); + (*sat->write_func)(&args); return; } - - memset(&args, 0, sizeof(args)); - args.base = fmt("%s/", prefix); - args.tree = commit->tree; - - cgit_print_snapshot_start("application/x-zip", filename, item); - write_zip_archive(&args); + cgit_print_error(fmt("Unsupported snapshot format: %s", filename)); } - -void cgit_print_snapshot(struct cacheitem *item, const char *hex, - const char *format, const char *prefix, - const char *filename) +void cgit_print_snapshot_links(const char *repo,const char *hex) { - if (!strcmp(format, "zip")) - cgit_print_zip(item, hex, prefix, filename); - else - cgit_print_error(fmt("Unsupported snapshot format: %s", - format)); + char *filename; + int f; + for(f=0;f<(sizeof(snapshot_archives)/sizeof(*snapshot_archives));++f) { + const struct snapshot_archive_t* sat = &snapshot_archives[f]; + filename = fmt("%s-%s%s",repo,hex,sat->suffix); + htmlf("<a href='%s'>%s</a><br/>", + cgit_pageurl(repo,"snapshot", + fmt("id=%s&name=%s",hex,filename)), filename); + } } |