X-Git-Url: https://gitweb.ps.run/ps-cgit/blobdiff_plain/a69061fdb7380d73715aeb3a0da6e91a24df90e4..776200b1c10536174f68fc6599fc709ae620db54:/parsing.c diff --git a/parsing.c b/parsing.c index 8aad1dd..5093b8b 100644 --- a/parsing.c +++ b/parsing.c @@ -64,19 +64,23 @@ int read_config_line(FILE *f, char *line, const char **value, int bufsize) int cgit_read_config(const char *filename, configfn fn) { - int ret = 0, len; + static int nesting; + int len; char line[256]; const char *value; - FILE *f = fopen(filename, "r"); + FILE *f; - if (!f) + /* cancel deeply nested include-commands */ + if (nesting > 8) return -1; - + if (!(f = fopen(filename, "r"))) + return -1; + nesting++; while((len = read_config_line(f, line, &value, sizeof(line))) > 0) (*fn)(line, value); - + nesting--; fclose(f); - return ret; + return 0; } char *convert_query_hexchar(char *txt) @@ -106,7 +110,7 @@ int cgit_parse_query(char *txt, configfn fn) return 0; t = txt = xstrdup(txt); - + while((c=*t) != '\0') { if (c=='=') { *t = '\0'; @@ -128,6 +132,50 @@ int cgit_parse_query(char *txt, configfn fn) return 0; } +/* + * url syntax: [repo ['/' cmd [ '/' path]]] + * repo: any valid repo url, may contain '/' + * cmd: log | commit | diff | tree | view | blob | snapshot + * path: any valid path, may contain '/' + * + */ +void cgit_parse_url(const char *url) +{ + char *cmd, *p; + + cgit_repo = NULL; + if (!url || url[0] == '\0') + return; + + cgit_repo = cgit_get_repoinfo(url); + if (cgit_repo) { + cgit_query_repo = cgit_repo->url; + return; + } + + cmd = strchr(url, '/'); + while (!cgit_repo && cmd) { + cmd[0] = '\0'; + cgit_repo = cgit_get_repoinfo(url); + if (cgit_repo == NULL) { + cmd[0] = '/'; + cmd = strchr(cmd + 1, '/'); + continue; + } + + cgit_query_repo = cgit_repo->url; + p = strchr(cmd + 1, '/'); + if (p) { + p[0] = '\0'; + if (p[1]) + cgit_query_path = trim_end(p + 1, '/'); + } + cgit_cmd = cgit_get_cmd_index(cmd + 1); + cgit_query_page = xstrdup(cmd + 1); + return; + } +} + char *substr(const char *head, const char *tail) { char *buf; @@ -151,6 +199,10 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) ret->committer_email = NULL; ret->subject = NULL; ret->msg = NULL; + ret->msg_encoding = NULL; + + if (p == NULL) + return ret; if (strncmp(p, "tree ", 5)) die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); @@ -167,7 +219,7 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) p = t; t = strchr(t, '>') + 1; ret->author_email = substr(p, t); - ret->author_date = atol(++t); + ret->author_date = atol(t+1); p = strchr(t, '\n') + 1; } @@ -178,22 +230,54 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) p = t; t = strchr(t, '>') + 1; ret->committer_email = substr(p, t); - ret->committer_date = atol(++t); + ret->committer_date = atol(t+1); p = strchr(t, '\n') + 1; } + if (!strncmp(p, "encoding ", 9)) { + p += 9; + t = strchr(p, '\n') + 1; + ret->msg_encoding = substr(p, t); + p = t; + } else + ret->msg_encoding = xstrdup(PAGE_ENCODING); + + while (*p && (*p != '\n')) + p = strchr(p, '\n') + 1; // skip unknown header fields + while (*p == '\n') p = strchr(p, '\n') + 1; t = strchr(p, '\n'); - if (t && *t) { - ret->subject = substr(p, t); + if (t) { + if (*t == '\0') + ret->subject = "** empty **"; + else + ret->subject = substr(p, t); p = t + 1; while (*p == '\n') p = strchr(p, '\n') + 1; - ret->msg = p; + ret->msg = xstrdup(p); + } else + ret->subject = substr(p, p+strlen(p)); + + if(strcmp(ret->msg_encoding, PAGE_ENCODING)) { + t = reencode_string(ret->subject, PAGE_ENCODING, + ret->msg_encoding); + if(t) { + free(ret->subject); + ret->subject = t; + } + + t = reencode_string(ret->msg, PAGE_ENCODING, + ret->msg_encoding); + if(t) { + free(ret->msg); + ret->msg = t; + } } + return ret; } @@ -201,17 +285,17 @@ struct commitinfo *cgit_parse_commit(struct commit *commit) struct taginfo *cgit_parse_tag(struct tag *tag) { void *data; - char type[20]; + enum object_type type; unsigned long size; char *p, *t; struct taginfo *ret; - data = read_sha1_file(tag->object.sha1, type, &size); - if (!data || strcmp(type, tag_type)) { + data = read_sha1_file(tag->object.sha1, &type, &size); + if (!data || type != OBJ_TAG) { free(data); return 0; } - + ret = xmalloc(sizeof(*ret)); ret->tagger = NULL; ret->tagger_email = NULL; @@ -220,7 +304,7 @@ struct taginfo *cgit_parse_tag(struct tag *tag) p = data; - while (p) { + while (p && *p) { if (*p == '\n') break; @@ -231,14 +315,17 @@ struct taginfo *cgit_parse_tag(struct tag *tag) p = t; t = strchr(t, '>') + 1; ret->tagger_email = substr(p, t); - ret->tagger_date = atol(++t); + ret->tagger_date = atol(t+1); } p = strchr(p, '\n') + 1; } + while (p && *p && (*p != '\n')) + p = strchr(p, '\n') + 1; // skip unknown tag fields + while (p && (*p == '\n')) p = strchr(p, '\n') + 1; - if (p) + if (p && *p) ret->msg = xstrdup(p); free(data); return ret;