X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=stagit-index.c;h=2b243ec15660ba042313d4317b2d33810f9300a3;hb=dd32948ba00cb30c852de72260255a5ebb24ccff;hp=44b603cddf72d8aae6e843a66406b37ca0a64590;hpb=f631d4ce702893c2207b1a12f2c048829c5f5ac7;p=stagit.git diff --git a/stagit-index.c b/stagit-index.c index 44b603c..2b243ec 100644 --- a/stagit-index.c +++ b/stagit-index.c @@ -1,38 +1,31 @@ -#include - #include -#include -#include -#include #include #include #include #include +#include #include #include -#include "compat.h" -#include "config.h" - static git_repository *repo; static const char *relpath = ""; -static const char *repodir; static char description[255] = "Repositories"; -static char name[255]; +static char *name = ""; static char owner[255]; -FILE * -efopen(const char *name, const char *flags) +void +joinpath(char *buf, size_t bufsiz, const char *path, const char *path2) { - FILE *fp; - - if (!(fp = fopen(name, flags))) - err(1, "fopen"); + int r; - return fp; + r = snprintf(buf, bufsiz, "%s%s%s", + path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); + if (r < 0 || (size_t)r >= bufsiz) + errx(1, "path truncated: '%s%s%s'", + path, path[0] && path[strlen(path) - 1] != '/' ? "/" : "", path2); } /* Escape characters below as HTML 2.0 / XML 1.0. */ @@ -45,7 +38,7 @@ xmlencode(FILE *fp, const char *s, size_t len) switch(*s) { case '<': fputs("<", fp); break; case '>': fputs(">", fp); break; - case '\'': fputs("'", fp); break; + case '\'': fputs("'" , fp); break; case '&': fputs("&", fp); break; case '"': fputs(""", fp); break; default: fputc(*s, fp); @@ -53,87 +46,60 @@ xmlencode(FILE *fp, const char *s, size_t len) } } -/* Some implementations of basename(3) return a pointer to a static - * internal buffer (OpenBSD). Others modify the contents of `path` (POSIX). - * This is a wrapper function that is compatible with both versions. - * The program will error out if basename(3) failed, this can only happen - * with the OpenBSD version. */ -char * -xbasename(const char *path) -{ - char *p, *b; - - if (!(p = strdup(path))) - err(1, "strdup"); - if (!(b = basename(p))) - err(1, "basename"); - if (!(b = strdup(b))) - err(1, "strdup"); - free(p); - - return b; -} - void -printtimeformat(FILE *fp, const git_time *intime, const char *fmt) +printtimeshort(FILE *fp, const git_time *intime) { struct tm *intm; time_t t; char out[32]; - t = (time_t) intime->time + (intime->offset * 60); - intm = gmtime(&t); - strftime(out, sizeof(out), fmt, intm); + t = (time_t)intime->time; + if (!(intm = gmtime(&t))) + return; + strftime(out, sizeof(out), "%Y-%m-%d %H:%M", intm); fputs(out, fp); } void -printtimeshort(FILE *fp, const git_time *intime) -{ - printtimeformat(fp, intime, "%Y-%m-%d %H:%M"); -} - -int writeheader(FILE *fp) { - fputs("" - "\n\n" + fputs("\n" + "\n\n" "\n" - "\n", fp); + "<title>", fp); xmlencode(fp, description, strlen(description)); fprintf(fp, "\n\n", relpath); fprintf(fp, "\n", relpath); fputs("\n\n", fp); fprintf(fp, "\n\n" - "\n
\"\"

%s

%s
\n", - relpath, name, description); - fputs("
\n
\n" - "\n" - "" - "\n", fp); - - return 0; + "\n
NameDescriptionOwnerLast commit
", relpath); + xmlencode(fp, description, strlen(description)); + fputs("
\n" + "
\n
\n
\n" + "\n" + "" + "" + "\n", fp); } -int +void writefooter(FILE *fp) { - return !fputs("
NameDescriptionOwnerLast commit
\n", fp); + fputs("\n\n
\n\n\n", fp); } int writelog(FILE *fp) { - char *stripped_name, *p; git_commit *commit = NULL; const git_signature *author; git_revwalk *w = NULL; git_oid id; + char *stripped_name = NULL, *p; int ret = 0; git_revwalk_new(&w, repo); git_revwalk_push_head(w); - git_revwalk_sorting(w, GIT_SORT_TIME); git_revwalk_simplify_first_parent(w); if (git_revwalk_next(&id, w) || @@ -144,17 +110,17 @@ writelog(FILE *fp) author = git_commit_author(commit); - fputs("", fp); - /* strip .git suffix */ if (!(stripped_name = strdup(name))) err(1, "strdup"); if ((p = strrchr(stripped_name, '.'))) - *p = '\0'; - xmlencode(fp, stripped_name, strlen(stripped_name)); + if (!strcmp(p, ".git")) + *p = '\0'; + fputs("", fp); + xmlencode(fp, stripped_name, strlen(stripped_name)); fputs("", fp); xmlencode(fp, description, strlen(description)); fputs("", fp); @@ -167,6 +133,7 @@ writelog(FILE *fp) git_commit_free(commit); err: git_revwalk_free(w); + free(stripped_name); return ret; } @@ -174,44 +141,54 @@ err: int main(int argc, char *argv[]) { - const git_error *e = NULL; FILE *fp; - char path[PATH_MAX], *p; + char path[PATH_MAX], repodirabs[PATH_MAX + 1]; + const char *repodir; int i, ret = 0; if (argc < 2) { fprintf(stderr, "%s [repodir...]\n", argv[0]); return 1; } + git_libgit2_init(); +#ifdef __OpenBSD__ + for (i = 1; i < argc; i++) + if (unveil(argv[i], "r") == -1) + err(1, "unveil: %s", argv[i]); + + if (pledge("stdio rpath", NULL) == -1) + err(1, "pledge"); +#endif + writeheader(stdout); for (i = 1; i < argc; i++) { repodir = argv[i]; + if (!realpath(repodir, repodirabs)) + err(1, "realpath"); if (git_repository_open_ext(&repo, repodir, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL)) { - e = giterr_last(); - fprintf(stderr, "%s: %s\n", argv[0], e->message); + fprintf(stderr, "%s: cannot open repository\n", argv[0]); ret = 1; continue; } /* use directory name as name */ - p = xbasename(repodir); - snprintf(name, sizeof(name), "%s", p); - free(p); + if ((name = strrchr(repodirabs, '/'))) + name++; + else + name = ""; /* read description or .git/description */ - description[0] = '\0'; - snprintf(path, sizeof(path), "%s%s%s", - repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "description"); + joinpath(path, sizeof(path), repodir, "description"); if (!(fp = fopen(path, "r"))) { - snprintf(path, sizeof(path), "%s%s%s", - repodir, repodir[strlen(repodir)] == '/' ? "" : "/", ".git/description"); + joinpath(path, sizeof(path), repodir, ".git/description"); fp = fopen(path, "r"); } + description[0] = '\0'; if (fp) { if (!fgets(description, sizeof(description), fp)) description[0] = '\0'; @@ -219,14 +196,12 @@ main(int argc, char *argv[]) } /* read owner or .git/owner */ - owner[0] = '\0'; - snprintf(path, sizeof(path), "%s%s%s", - repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "owner"); + joinpath(path, sizeof(path), repodir, "owner"); if (!(fp = fopen(path, "r"))) { - snprintf(path, sizeof(path), "%s%s%s", - repodir, repodir[strlen(repodir)] == '/' ? "" : "/", ".git/owner"); + joinpath(path, sizeof(path), repodir, ".git/owner"); fp = fopen(path, "r"); } + owner[0] = '\0'; if (fp) { if (!fgets(owner, sizeof(owner), fp)) owner[0] = '\0';