diff options
Diffstat (limited to 'source/cmd.c')
| -rw-r--r-- | source/cmd.c | 162 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 85 insertions, 77 deletions
diff --git a/source/cmd.c b/source/cmd.c index c17d8d9..456a937 100644 --- a/source/cmd.c +++ b/source/cmd.c @@ -1,15 +1,14 @@ -/* cmd.c: the cgit command dispatcher - * - * Copyright (C) 2006-2017 cgit Development Team <cgit@lists.zx2c4.com> - * - * Licensed under GNU General Public License v2 - * (see LICENSE.txt for full license text) +/* + * One thunk per page, each pulling the parts of the request its renderer + * needs out of the global ctx, plus the table that maps a page name onto its + * thunk. Keeping the thunks here lets every renderer take ordinary arguments + * instead of reaching into the request state itself. */ +#include "cache.h" #include "cgit.h" #include "cmd.h" -#include "cache.h" -#include "ui-shared.h" +#include "html.h" #include "ui-atom.h" #include "ui-blame.h" #include "ui-blob.h" @@ -21,50 +20,56 @@ #include "ui-plain.h" #include "ui-refs.h" #include "ui-repolist.h" +#include "ui-shared.h" #include "ui-snapshot.h" #include "ui-stats.h" #include "ui-summary.h" #include "ui-tag.h" #include "ui-tree.h" -#define def_cmd(name, want_repo, want_vpath, is_clone) \ - {#name, name##_fn, want_repo, want_vpath, is_clone} -static void HEAD_fn(void) +static void head_fn(void) { cgit_clone_head(); } -static void atom_fn(void) +static void about_fn(void) { - cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items); + char *currenturl, *redirect; + size_t path_info_len; + + if (!ctx.repo) { + cgit_print_site_readme(); + return; + } + + // The about page resolves relative links against its own URL, so it + // only works with a trailing slash. + path_info_len = ctx.env.path_info ? strlen(ctx.env.path_info) : 0; + if (!ctx.qry.path && + (!ctx.qry.url || !*ctx.qry.url || + ctx.qry.url[strlen(ctx.qry.url) - 1] != '/') && + (!path_info_len || ctx.env.path_info[path_info_len - 1] != '/')) { + currenturl = cgit_currenturl(); + redirect = cgit_fmtalloc("%s/", currenturl); + cgit_redirect(redirect, true); + free(currenturl); + free(redirect); + } else if (ctx.repo->readme.nr) { + cgit_print_repo_readme(ctx.qry.path); + } else if (ctx.repo->homepage) { + cgit_redirect(ctx.repo->homepage, false); + } else { + currenturl = cgit_currenturl(); + redirect = cgit_fmtalloc("%s../", currenturl); + cgit_redirect(redirect, false); + free(currenturl); + free(redirect); + } } -static void about_fn(void) +static void atom_fn(void) { - if (ctx.repo) { - size_t path_info_len = ctx.env.path_info ? strlen(ctx.env.path_info) : 0; - if (!ctx.qry.path && - (!ctx.qry.url || !*ctx.qry.url || - ctx.qry.url[strlen(ctx.qry.url) - 1] != '/') && - (!path_info_len || ctx.env.path_info[path_info_len - 1] != '/')) { - char *currenturl = cgit_currenturl(); - char *redirect = cgit_fmtalloc("%s/", currenturl); - cgit_redirect(redirect, true); - free(currenturl); - free(redirect); - } else if (ctx.repo->readme.nr) - cgit_print_repo_readme(ctx.qry.path); - else if (ctx.repo->homepage) - cgit_redirect(ctx.repo->homepage, false); - else { - char *currenturl = cgit_currenturl(); - char *redirect = cgit_fmtalloc("%s../", currenturl); - cgit_redirect(redirect, false); - free(currenturl); - free(redirect); - } - } else - cgit_print_site_readme(); + cgit_print_atom(ctx.qry.head, ctx.qry.path, ctx.cfg.max_atom_items); } static void blame_fn(void) @@ -90,11 +95,6 @@ static void diff_fn(void) cgit_print_diff(ctx.qry.oid, ctx.qry.oid2, ctx.qry.path, 1, 0); } -static void rawdiff_fn(void) -{ - cgit_print_diff(ctx.qry.oid, ctx.qry.oid2, ctx.qry.path, 1, 1); -} - static void info_fn(void) { cgit_clone_info(); @@ -110,8 +110,8 @@ static void log_fn(void) static void ls_cache_fn(void) { - /* The listing exposes the cache path and the URLs other visitors - * requested, so it stays off unless an admin opts in. */ + // The listing names the cache path and the URLs other visitors asked + // for, so it stays off until an administrator opts in. if (!ctx.cfg.enable_cache_list) { cgit_print_error_page(404, "Not found", "Not found"); return; @@ -127,11 +127,6 @@ static void objects_fn(void) cgit_clone_objects(); } -static void repolist_fn(void) -{ - cgit_print_repolist(); -} - static void patch_fn(void) { cgit_print_patch(ctx.qry.oid, ctx.qry.oid2, ctx.qry.path); @@ -142,11 +137,21 @@ static void plain_fn(void) cgit_print_plain(); } +static void rawdiff_fn(void) +{ + cgit_print_diff(ctx.qry.oid, ctx.qry.oid2, ctx.qry.path, 1, 1); +} + static void refs_fn(void) { cgit_print_refs(); } +static void repolist_fn(void) +{ + cgit_print_repolist(); +} + static void snapshot_fn(void) { cgit_print_snapshot(ctx.qry.head, ctx.qry.oid, ctx.qry.path, @@ -176,31 +181,34 @@ static void tree_fn(void) cgit_print_tree(ctx.qry.oid, ctx.qry.path); } -struct cgit_cmd *cgit_get_cmd(void) +// The name is what a request spells as p=, so these strings are part of the +// URL space and cannot be renamed. +static const struct cgit_cmd commands[] = { + { .name = "HEAD", .fn = head_fn, .want_repo = 1, .is_clone = 1 }, + { .name = "about", .fn = about_fn }, + { .name = "atom", .fn = atom_fn, .want_repo = 1 }, + { .name = "blame", .fn = blame_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "blob", .fn = blob_fn, .want_repo = 1 }, + { .name = "commit", .fn = commit_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "diff", .fn = diff_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "info", .fn = info_fn, .want_repo = 1, .is_clone = 1 }, + { .name = "log", .fn = log_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "ls_cache", .fn = ls_cache_fn }, + { .name = "objects", .fn = objects_fn, .want_repo = 1, .is_clone = 1 }, + { .name = "patch", .fn = patch_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "plain", .fn = plain_fn, .want_repo = 1 }, + { .name = "rawdiff", .fn = rawdiff_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "refs", .fn = refs_fn, .want_repo = 1 }, + { .name = "repolist", .fn = repolist_fn }, + { .name = "snapshot", .fn = snapshot_fn, .want_repo = 1 }, + { .name = "stats", .fn = stats_fn, .want_repo = 1, .want_vpath = 1 }, + { .name = "summary", .fn = summary_fn, .want_repo = 1 }, + { .name = "tag", .fn = tag_fn, .want_repo = 1 }, + { .name = "tree", .fn = tree_fn, .want_repo = 1, .want_vpath = 1 }, +}; + +const struct cgit_cmd *cgit_get_cmd(void) { - static struct cgit_cmd cmds[] = { - def_cmd(HEAD, 1, 0, 1), - def_cmd(atom, 1, 0, 0), - def_cmd(about, 0, 0, 0), - def_cmd(blame, 1, 1, 0), - def_cmd(blob, 1, 0, 0), - def_cmd(commit, 1, 1, 0), - def_cmd(diff, 1, 1, 0), - def_cmd(info, 1, 0, 1), - def_cmd(log, 1, 1, 0), - def_cmd(ls_cache, 0, 0, 0), - def_cmd(objects, 1, 0, 1), - def_cmd(patch, 1, 1, 0), - def_cmd(plain, 1, 0, 0), - def_cmd(rawdiff, 1, 1, 0), - def_cmd(refs, 1, 0, 0), - def_cmd(repolist, 0, 0, 0), - def_cmd(snapshot, 1, 0, 0), - def_cmd(stats, 1, 1, 0), - def_cmd(summary, 1, 0, 0), - def_cmd(tag, 1, 0, 0), - def_cmd(tree, 1, 1, 0), - }; size_t i; if (ctx.qry.page == NULL) { @@ -210,8 +218,8 @@ struct cgit_cmd *cgit_get_cmd(void) ctx.qry.page = "repolist"; } - for (i = 0; i < ARRAY_SIZE(cmds); i++) - if (!strcmp(ctx.qry.page, cmds[i].name)) - return &cmds[i]; + for (i = 0; i < ARRAY_SIZE(commands); i++) + if (!strcmp(ctx.qry.page, commands[i].name)) + return &commands[i]; return NULL; } |
