static int run_access_hook(struct daemon_service *service, const char *dir, const char *path, struct hostinfo *hi) { struct child_process child = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; const char *argv[8]; const char **arg = argv; char *eol; int seen_errors = 0; *arg++ = access_hook; *arg++ = service->name; *arg++ = path; *arg++ = hi->hostname.buf; *arg++ = get_canon_hostname(hi); *arg++ = get_ip_address(hi); *arg++ = hi->tcp_port.buf; *arg = NULL; child.use_shell = 1; child.argv = argv; child.no_stdin = 1; child.no_stderr = 1; child.out = -1; if (start_command(&child)) { logerror("daemon access hook '%s' failed to start", access_hook); goto error_return; } if (strbuf_read(&buf, child.out, 0) < 0) { logerror("failed to read from pipe to daemon access hook '%s'", access_hook); strbuf_reset(&buf); seen_errors = 1; } if (close(child.out) < 0) { logerror("failed to close pipe to daemon access hook '%s'", access_hook); seen_errors = 1; } if (finish_command(&child)) seen_errors = 1; if (!seen_errors) { strbuf_release(&buf); return 0; } error_return: strbuf_ltrim(&buf); if (!buf.len) strbuf_addstr(&buf, "service rejected"); eol = strchr(buf.buf, '\n'); if (eol) *eol = '\0'; errno = EACCES; daemon_error(dir, buf.buf); strbuf_release(&buf); return -1; }
static int handle_commit_msg(struct strbuf *line) { static int still_looking = 1; if (!cmitmsg) return 0; if (still_looking) { strbuf_ltrim(line); if (!line->len) return 0; still_looking = check_header(line, s_hdr_data, 0); if (still_looking) return 0; } /* normalize the log message to UTF-8. */ if (metainfo_charset) convert_to_utf8(line, charset.buf); if (use_scissors && is_scissors_line(line)) { int i; rewind(cmitmsg); ftruncate(fileno(cmitmsg), 0); still_looking = 1; /* * We may have already read "secondary headers"; purge * them to give ourselves a clean restart. */ for (i = 0; header[i]; i++) { if (s_hdr_data[i]) strbuf_release(s_hdr_data[i]); s_hdr_data[i] = NULL; } return 0; } if (patchbreak(line)) { fclose(cmitmsg); cmitmsg = NULL; return 1; } fputs(line->buf, cmitmsg); return 0; }
static void shortlog(const char *name, struct origin_data *origin_data, struct commit *head, struct rev_info *rev, int limit, struct strbuf *out) { int i, count = 0; struct commit *commit; struct object *branch; struct string_list subjects = STRING_LIST_INIT_DUP; struct string_list authors = STRING_LIST_INIT_DUP; struct string_list committers = STRING_LIST_INIT_DUP; int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED; struct strbuf sb = STRBUF_INIT; const unsigned char *sha1 = origin_data->sha1; branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40); if (!branch || branch->type != OBJ_COMMIT) return; setup_revisions(0, NULL, rev, NULL); add_pending_object(rev, branch, name); add_pending_object(rev, &head->object, "^HEAD"); head->object.flags |= UNINTERESTING; if (prepare_revision_walk(rev)) die("revision walk setup failed"); while ((commit = get_revision(rev)) != NULL) { struct pretty_print_context ctx = {0}; if (commit->parents && commit->parents->next) { /* do not list a merge but count committer */ record_person('c', &committers, commit); continue; } if (!count) /* the 'tip' committer */ record_person('c', &committers, commit); record_person('a', &authors, commit); count++; if (subjects.nr > limit) continue; format_commit_message(commit, "%s", &sb, &ctx); strbuf_ltrim(&sb); if (!sb.len) string_list_append(&subjects, sha1_to_hex(commit->object.sha1)); else string_list_append(&subjects, strbuf_detach(&sb, NULL)); } add_people_info(out, &authors, &committers); if (count > limit) strbuf_addf(out, "\n* %s: (%d commits)\n", name, count); else strbuf_addf(out, "\n* %s:\n", name); if (origin_data->is_local_branch && use_branch_desc) add_branch_desc(out, name); for (i = 0; i < subjects.nr; i++) if (i >= limit) strbuf_addf(out, " ...\n"); else strbuf_addf(out, " %s\n", subjects.items[i].string); clear_commit_marks((struct commit *)branch, flags); clear_commit_marks(head, flags); free_commit_list(rev->commits); rev->commits = NULL; rev->pending.nr = 0; string_list_clear(&authors, 0); string_list_clear(&committers, 0); string_list_clear(&subjects, 0); }
void strbuf_trim(struct strbuf *sb) { strbuf_rtrim(sb); strbuf_ltrim(sb); }
static int run_access_hook(struct daemon_service *service, const char *dir, const char *path) { struct child_process child; struct strbuf buf = STRBUF_INIT; const char *argv[8]; const char **arg = argv; char *eol; int seen_errors = 0; #define STRARG(x) ((x) ? (x) : "") *arg++ = access_hook; *arg++ = service->name; *arg++ = path; *arg++ = STRARG(hostname); *arg++ = STRARG(canon_hostname); *arg++ = STRARG(ip_address); *arg++ = STRARG(tcp_port); *arg = NULL; #undef STRARG memset(&child, 0, sizeof(child)); child.use_shell = 1; child.argv = argv; child.no_stdin = 1; child.no_stderr = 1; child.out = -1; if (start_command(&child)) { logerror("daemon access hook '%s' failed to start", access_hook); goto error_return; } if (strbuf_read(&buf, child.out, 0) < 0) { logerror("failed to read from pipe to daemon access hook '%s'", access_hook); strbuf_reset(&buf); seen_errors = 1; } if (close(child.out) < 0) { logerror("failed to close pipe to daemon access hook '%s'", access_hook); seen_errors = 1; } if (finish_command(&child)) seen_errors = 1; if (!seen_errors) { strbuf_release(&buf); return 0; } error_return: strbuf_ltrim(&buf); if (!buf.len) strbuf_addstr(&buf, "service rejected"); eol = strchr(buf.buf, '\n'); if (eol) *eol = '\0'; errno = EACCES; daemon_error(dir, buf.buf); strbuf_release(&buf); return -1; }
void print_commit(struct commit *commit, struct rev_info *revs) { struct commitinfo *info; int cols = revs->graph ? 3 : 2; struct strbuf graphbuf = STRBUF_INIT; struct strbuf msgbuf = STRBUF_INIT; if (ctx.repo->enable_log_filecount) cols++; if (ctx.repo->enable_log_linecount) cols++; if (revs->graph) { /* Advance graph until current commit */ while (!graph_next_line(revs->graph, &graphbuf)) { /* Print graph segment in otherwise empty table row */ html("<tr class='nohover'><td class='commitgraph'>"); html(graphbuf.buf); htmlf("</td><td colspan='%d' /></tr>\n", cols); strbuf_setlen(&graphbuf, 0); } /* Current commit's graph segment is now ready in graphbuf */ } info = cgit_parse_commit(commit); htmlf("<tr%s>", ctx.qry.showmsg ? " class='logheader'" : ""); if (revs->graph) { /* Print graph segment for current commit */ html("<td class='commitgraph'>"); html(graphbuf.buf); html("</td>"); strbuf_setlen(&graphbuf, 0); } else { html("<td>"); cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); html("</td>"); } htmlf("<td%s>", ctx.qry.showmsg ? " class='logsubject'" : ""); if (ctx.qry.showmsg) { /* line-wrap long commit subjects instead of truncating them */ size_t subject_len = strlen(info->subject); if (subject_len > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { /* symbol for signaling line-wrap (in PAGE_ENCODING) */ const char wrap_symbol[] = { ' ', 0xE2, 0x86, 0xB5, 0 }; int i = ctx.cfg.max_msg_len - strlen(wrap_symbol); /* Rewind i to preceding space character */ while (i > 0 && !isspace(info->subject[i])) --i; if (!i) /* Oops, zero spaces. Reset i */ i = ctx.cfg.max_msg_len - strlen(wrap_symbol); /* add remainder starting at i to msgbuf */ strbuf_add(&msgbuf, info->subject + i, subject_len - i); strbuf_trim(&msgbuf); strbuf_add(&msgbuf, "\n\n", 2); /* Place wrap_symbol at position i in info->subject */ strcpy(info->subject + i, wrap_symbol); } } cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, sha1_to_hex(commit->object.sha1), ctx.qry.vpath, 0); show_commit_decorations(commit); html("</td><td>"); html_txt(info->author); if (revs->graph) { html("</td><td>"); cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); } if (ctx.repo->enable_log_filecount || ctx.repo->enable_log_linecount) { files = 0; add_lines = 0; rem_lines = 0; cgit_diff_commit(commit, inspect_files, ctx.qry.vpath); } if (ctx.repo->enable_log_filecount) htmlf("</td><td>%d", files); if (ctx.repo->enable_log_linecount) htmlf("</td><td>-%d/+%d", rem_lines, add_lines); html("</td></tr>\n"); if (revs->graph || ctx.qry.showmsg) { /* Print a second table row */ html("<tr class='nohover'>"); if (ctx.qry.showmsg) { /* Concatenate commit message + notes in msgbuf */ if (info->msg && *(info->msg)) { strbuf_addstr(&msgbuf, info->msg); strbuf_addch(&msgbuf, '\n'); } format_note(NULL, commit->object.sha1, &msgbuf, PAGE_ENCODING, NOTES_SHOW_HEADER | NOTES_INDENT); strbuf_addch(&msgbuf, '\n'); strbuf_ltrim(&msgbuf); } if (revs->graph) { int lines = 0; /* Calculate graph padding */ if (ctx.qry.showmsg) { /* Count #lines in commit message + notes */ const char *p = msgbuf.buf; lines = 1; while ((p = strchr(p, '\n'))) { p++; lines++; } } /* Print graph padding */ html("<td class='commitgraph'>"); while (lines > 0 || !graph_is_commit_finished(revs->graph)) { if (graphbuf.len) html("\n"); strbuf_setlen(&graphbuf, 0); graph_next_line(revs->graph, &graphbuf); html(graphbuf.buf); lines--; } html("</td>\n"); } else html("<td/>"); /* Empty 'Age' column */ /* Print msgbuf into remainder of table row */ htmlf("<td colspan='%d'%s>\n", cols, ctx.qry.showmsg ? " class='logmsg'" : ""); html_txt(msgbuf.buf); html("</td></tr>\n"); } strbuf_release(&msgbuf); strbuf_release(&graphbuf); cgit_free_commitinfo(info); }