From bee597cb7fa40bd24ed8da8f3c581215ad38e15a Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Sun, 27 Aug 2006 13:19:45 +0200 Subject: [PATCH 1/9] git-cherry: remove unused variable Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- git-cherry.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/git-cherry.sh b/git-cherry.sh index f0e8831fa4..8832573fee 100755 --- a/git-cherry.sh +++ b/git-cherry.sh @@ -51,9 +51,6 @@ patch=$tmp-patch mkdir $patch trap "rm -rf $tmp-*" 0 1 2 3 15 -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" - for c in $inup do git-diff-tree -p $c From 2e6183840e5c8f1a478975346549be7440405175 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Sun, 27 Aug 2006 13:19:58 +0200 Subject: [PATCH 2/9] git-reset: remove unused variable Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- git-reset.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/git-reset.sh b/git-reset.sh index 36fc8ce25b..3133b5bd25 100755 --- a/git-reset.sh +++ b/git-reset.sh @@ -3,9 +3,6 @@ USAGE='[--mixed | --soft | --hard] []' . git-sh-setup -tmp=${GIT_DIR}/reset.$$ -trap 'rm -f $tmp-*' 0 1 2 3 15 - update= reset_type=--mixed case "$1" in From c470701a98700533024b1864b789d4fc17e5e823 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Mon, 28 Aug 2006 01:55:46 +0200 Subject: [PATCH 3/9] Use fstat instead of fseek Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- dir.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dir.c b/dir.c index d53d48f70c..5a40d8ff8c 100644 --- a/dir.c +++ b/dir.c @@ -112,17 +112,15 @@ static int add_excludes_from_file_1(const char *fname, int baselen, struct exclude_list *which) { + struct stat st; int fd, i; long size; char *buf, *entry; fd = open(fname, O_RDONLY); - if (fd < 0) + if (fd < 0 || fstat(fd, &st) < 0) goto err; - size = lseek(fd, 0, SEEK_END); - if (size < 0) - goto err; - lseek(fd, 0, SEEK_SET); + size = st.st_size; if (size == 0) { close(fd); return 0; From b3c952f8386cebe12fc95227866683bb1cec99a9 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Mon, 28 Aug 2006 02:26:07 +0200 Subject: [PATCH 4/9] Use xcalloc instead of calloc Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- object-refs.c | 2 +- object.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/object-refs.c b/object-refs.c index b1b8065851..b0034e4b21 100644 --- a/object-refs.c +++ b/object-refs.c @@ -30,7 +30,7 @@ static void grow_refs_hash(void) int new_hash_size = (refs_hash_size + 1000) * 3 / 2; struct object_refs **new_hash; - new_hash = calloc(new_hash_size, sizeof(struct object_refs *)); + new_hash = xcalloc(new_hash_size, sizeof(struct object_refs *)); for (i = 0; i < refs_hash_size; i++) { struct object_refs *ref = refs_hash[i]; if (!ref) diff --git a/object.c b/object.c index 60bf16b902..92813001e2 100644 --- a/object.c +++ b/object.c @@ -73,7 +73,7 @@ static void grow_object_hash(void) int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size; struct object **new_hash; - new_hash = calloc(new_hash_size, sizeof(struct object *)); + new_hash = xcalloc(new_hash_size, sizeof(struct object *)); for (i = 0; i < obj_hash_size; i++) { struct object *obj = obj_hash[i]; if (!obj) From 4cac42b1324951579036a9d3ac403f5c2c3eeed8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 27 Aug 2006 21:19:39 -0700 Subject: [PATCH 5/9] free(NULL) is perfectly valid. Jonas noticed some places say "if (X) free(X)" which is totally unnecessary. Signed-off-by: Junio C Hamano --- builtin-apply.c | 6 ++---- builtin-fmt-merge-msg.c | 3 +-- builtin-repo-config.c | 6 ++---- builtin-rev-list.c | 6 ++---- config.c | 6 ++---- fetch.c | 3 +-- http-fetch.c | 13 ++++--------- http-push.c | 13 ++++--------- path-list.c | 3 +-- refs.c | 6 ++---- 10 files changed, 21 insertions(+), 44 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index b47ccacc2e..1a1deaf78c 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1131,8 +1131,7 @@ static struct fragment *parse_binary_hunk(char **buf_p, return frag; corrupt: - if (data) - free(data); + free(data); *status_p = -1; error("corrupt binary patch at line %d: %.*s", linenr-1, llen-1, buffer); @@ -1329,8 +1328,7 @@ static void show_stats(struct patch *patch) printf(" %s%-*s |%5d %.*s%.*s\n", prefix, len, name, patch->lines_added + patch->lines_deleted, add, pluses, del, minuses); - if (qname) - free(qname); + free(qname); } static int read_old_data(struct stat *st, const char *path, void *buf, unsigned long size) diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index a5ed8dbbac..76d22b47ba 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -55,8 +55,7 @@ static void free_list(struct list *list) for (i = 0; i < list->nr; i++) { free(list->list[i]); - if (list->payload[i]) - free(list->payload[i]); + free(list->payload[i]); } free(list->list); free(list->payload); diff --git a/builtin-repo-config.c b/builtin-repo-config.c index c416480208..6560cf1c2d 100644 --- a/builtin-repo-config.c +++ b/builtin-repo-config.c @@ -122,10 +122,8 @@ static int get_value(const char* key_, const char* regex_) ret = (seen == 1) ? 0 : 1; free_strings: - if (repo_config) - free(repo_config); - if (global) - free(global); + free(repo_config); + free(global); return ret; } diff --git a/builtin-rev-list.c b/builtin-rev-list.c index bc48a3e230..7f3e1fcfb3 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -93,10 +93,8 @@ static void show_commit(struct commit *commit) free_commit_list(commit->parents); commit->parents = NULL; } - if (commit->buffer) { - free(commit->buffer); - commit->buffer = NULL; - } + free(commit->buffer); + commit->buffer = NULL; } static void process_blob(struct blob *blob, diff --git a/config.c b/config.c index 82b3562454..d9f2b787b9 100644 --- a/config.c +++ b/config.c @@ -361,8 +361,7 @@ int git_config(config_fn_t fn) } ret += git_config_from_file(fn, filename); - if (repo_config) - free(repo_config); + free(repo_config); return ret; } @@ -734,8 +733,7 @@ int git_config_set_multivar(const char* key, const char* value, out_free: if (0 <= fd) close(fd); - if (config_filename) - free(config_filename); + free(config_filename); if (lock_file) { unlink(lock_file); free(lock_file); diff --git a/fetch.c b/fetch.c index ef60b045ea..7d3812c406 100644 --- a/fetch.c +++ b/fetch.c @@ -302,8 +302,7 @@ int pull(int targets, char **target, const char **write_ref, if (ret) goto unlock_and_fail; } - if (msg) - free(msg); + free(msg); return 0; diff --git a/http-fetch.c b/http-fetch.c index 7619b338fe..6806f3678c 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -696,10 +696,8 @@ xml_start_tag(void *userData, const char *name, const char **atts) strcat(ctx->name, "."); strcat(ctx->name, c); - if (ctx->cdata) { - free(ctx->cdata); - ctx->cdata = NULL; - } + free(ctx->cdata); + ctx->cdata = NULL; ctx->userFunc(ctx, 0); } @@ -726,8 +724,7 @@ static void xml_cdata(void *userData, const XML_Char *s, int len) { struct xml_ctx *ctx = (struct xml_ctx *)userData; - if (ctx->cdata) - free(ctx->cdata); + free(ctx->cdata); ctx->cdata = xmalloc(len + 1); strlcpy(ctx->cdata, s, len + 1); } @@ -765,9 +762,7 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed) ls->dentry_flags |= IS_DIR; } } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) { - if (ls->dentry_name) { - free(ls->dentry_name); - } + free(ls->dentry_name); ls->dentry_name = NULL; ls->dentry_flags = 0; } diff --git a/http-push.c b/http-push.c index 04cb238e96..7814666d8d 100644 --- a/http-push.c +++ b/http-push.c @@ -1238,10 +1238,8 @@ xml_start_tag(void *userData, const char *name, const char **atts) strcat(ctx->name, "."); strcat(ctx->name, c); - if (ctx->cdata) { - free(ctx->cdata); - ctx->cdata = NULL; - } + free(ctx->cdata); + ctx->cdata = NULL; ctx->userFunc(ctx, 0); } @@ -1268,8 +1266,7 @@ static void xml_cdata(void *userData, const XML_Char *s, int len) { struct xml_ctx *ctx = (struct xml_ctx *)userData; - if (ctx->cdata) - free(ctx->cdata); + free(ctx->cdata); ctx->cdata = xmalloc(len + 1); strlcpy(ctx->cdata, s, len + 1); } @@ -1518,9 +1515,7 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed) ls->dentry_flags |= IS_DIR; } } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) { - if (ls->dentry_name) { - free(ls->dentry_name); - } + free(ls->dentry_name); ls->dentry_name = NULL; ls->dentry_flags = 0; } diff --git a/path-list.c b/path-list.c index f15a10de37..b1ee72d1dc 100644 --- a/path-list.c +++ b/path-list.c @@ -85,8 +85,7 @@ void path_list_clear(struct path_list *list, int free_items) for (i = 0; i < list->nr; i++) { if (list->strdup_paths) free(list->items[i].path); - if (list->items[i].util) - free(list->items[i].util); + free(list->items[i].util); } free(list->items); } diff --git a/refs.c b/refs.c index e70ef0ae0f..aab14fc107 100644 --- a/refs.c +++ b/refs.c @@ -348,10 +348,8 @@ void unlock_ref(struct ref_lock *lock) if (lock->lk) rollback_lock_file(lock->lk); } - if (lock->ref_file) - free(lock->ref_file); - if (lock->log_file) - free(lock->log_file); + free(lock->ref_file); + free(lock->log_file); free(lock); } From 370e0966ef4abff81f08c9ea5c7d167eb0b0d354 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Sun, 27 Aug 2006 13:19:49 +0200 Subject: [PATCH 6/9] Add git-zip-tree to .gitignore Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3da0e5e809..78cb671539 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,7 @@ git-verify-pack git-verify-tag git-whatchanged git-write-tree +git-zip-tree git-core-*/?* gitweb/gitweb.cgi test-date From d819e4e682d68ca41378e4352b9e2bba084971dc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 20 Aug 2006 19:03:13 -0700 Subject: [PATCH 7/9] daemon: prepare for multiple services. This adds an infrastructure to selectively enable and disable more than one services in git-daemon. Currently upload-pack service, which serves the git-fetch-pack and git-peek-remote clients, is the only service that is defined. Signed-off-by: Junio C Hamano --- daemon.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 9 deletions(-) diff --git a/daemon.c b/daemon.c index 66ec830b7c..e430cfbc8d 100644 --- a/daemon.c +++ b/daemon.c @@ -232,13 +232,42 @@ static char *path_ok(char *dir) return NULL; /* Fallthrough. Deny by default */ } -static int upload(char *dir) -{ - /* Timeout as string */ - char timeout_buf[64]; - const char *path; +typedef int (*daemon_service_fn)(void); +struct daemon_service { + const char *name; + const char *config_name; + daemon_service_fn fn; + int enabled; + int overridable; +}; - loginfo("Request for '%s'", dir); +static struct daemon_service *service_looking_at; +static int service_enabled; + +static int git_daemon_config(const char *var, const char *value) +{ + if (!strncmp(var, "daemon.", 7) && + !strcmp(var + 7, service_looking_at->config_name)) { + service_enabled = git_config_bool(var, value); + return 0; + } + + /* we are not interested in parsing any other configuration here */ + return 0; +} + +static int run_service(char *dir, struct daemon_service *service) +{ + const char *path; + int enabled = service->enabled; + + loginfo("Request %s for '%s'", service->name, dir); + + if (!enabled && !service->overridable) { + logerror("'%s': service not enabled.", service->name); + errno = EACCES; + return -1; + } if (!(path = path_ok(dir))) return -1; @@ -260,12 +289,34 @@ static int upload(char *dir) return -1; } + if (service->overridable) { + service_looking_at = service; + service_enabled = -1; + git_config(git_daemon_config); + if (0 <= service_enabled) + enabled = service_enabled; + } + if (!enabled) { + logerror("'%s': service not enabled for '%s'", + service->name, path); + errno = EACCES; + return -1; + } + /* * We'll ignore SIGTERM from now on, we have a * good client. */ signal(SIGTERM, SIG_IGN); + return service->fn(); +} + +static int upload_pack(void) +{ + /* Timeout as string */ + char timeout_buf[64]; + snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout); /* git-upload-pack only ever reads stuff, so this is safe */ @@ -273,10 +324,36 @@ static int upload(char *dir) return -1; } +static struct daemon_service daemon_service[] = { + { "upload-pack", "uploadpack", upload_pack, 1, 1 }, +}; + +static void enable_service(const char *name, int ena) { + int i; + for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + if (!strcmp(daemon_service[i].name, name)) { + daemon_service[i].enabled = ena; + return; + } + } + die("No such service %s", name); +} + +static void make_service_overridable(const char *name, int ena) { + int i; + for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + if (!strcmp(daemon_service[i].name, name)) { + daemon_service[i].overridable = ena; + return; + } + } + die("No such service %s", name); +} + static int execute(struct sockaddr *addr) { static char line[1000]; - int pktlen, len; + int pktlen, len, i; if (addr) { char addrbuf[256] = ""; @@ -313,8 +390,14 @@ static int execute(struct sockaddr *addr) if (len && line[len-1] == '\n') line[--len] = 0; - if (!strncmp("git-upload-pack ", line, 16)) - return upload(line+16); + for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + struct daemon_service *s = &(daemon_service[i]); + int namelen = strlen(s->name); + if (!strncmp("git-", line, 4) && + !strncmp(s->name, line + 4, namelen) && + line[namelen + 4] == ' ') + return run_service(line + namelen + 5, s); + } logerror("Protocol error: '%s'", line); return -1; @@ -805,6 +888,22 @@ int main(int argc, char **argv) group_name = arg + 8; continue; } + if (!strncmp(arg, "--enable=", 9)) { + enable_service(arg + 9, 1); + continue; + } + if (!strncmp(arg, "--disable=", 10)) { + enable_service(arg + 10, 0); + continue; + } + if (!strncmp(arg, "--enable-override=", 18)) { + make_service_overridable(arg + 18, 1); + continue; + } + if (!strncmp(arg, "--disable-override=", 19)) { + make_service_overridable(arg + 19, 0); + continue; + } if (!strcmp(arg, "--")) { ok_paths = &argv[i+1]; break; From 74c0cc21a57a15bbce46ee02bc882064ee9bcf6b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 20 Aug 2006 19:03:50 -0700 Subject: [PATCH 8/9] daemon: add upload-tar service. This allows clients to ask for tarballs with: git tar-tree --remote=git://server/repo refname By default, the upload-tar service is not enabled. To enable it server-wide, the server can be started with: git-daemon --enable=upload-tar This service is by default overridable per repostiory, so alternatively, a repository can define "daemon.uploadtar = true" to enable it. Signed-off-by: Junio C Hamano --- daemon.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/daemon.c b/daemon.c index e430cfbc8d..a4a08f39d5 100644 --- a/daemon.c +++ b/daemon.c @@ -324,8 +324,15 @@ static int upload_pack(void) return -1; } +static int upload_tar(void) +{ + execl_git_cmd("upload-tar", ".", NULL); + return -1; +} + static struct daemon_service daemon_service[] = { { "upload-pack", "uploadpack", upload_pack, 1, 1 }, + { "upload-tar", "uploadtar", upload_tar, 0, 1 }, }; static void enable_service(const char *name, int ena) { @@ -896,12 +903,12 @@ int main(int argc, char **argv) enable_service(arg + 10, 0); continue; } - if (!strncmp(arg, "--enable-override=", 18)) { - make_service_overridable(arg + 18, 1); + if (!strncmp(arg, "--allow-override=", 17)) { + make_service_overridable(arg + 17, 1); continue; } - if (!strncmp(arg, "--disable-override=", 19)) { - make_service_overridable(arg + 19, 0); + if (!strncmp(arg, "--forbid-override=", 18)) { + make_service_overridable(arg + 18, 0); continue; } if (!strcmp(arg, "--")) { From 355f541249633487aa2685e7e7e29963f596b308 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 20 Aug 2006 19:32:43 -0700 Subject: [PATCH 9/9] multi-service daemon: documentation Signed-off-by: Junio C Hamano --- Documentation/git-daemon.txt | 47 ++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index 17619a3f57..35c3c4b619 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -11,17 +11,16 @@ SYNOPSIS 'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all] [--timeout=n] [--init-timeout=n] [--strict-paths] [--base-path=path] [--user-path | --user-path=path] - [--reuseaddr] [--detach] [--pid-file=file] - [--user=user [--group=group]] [directory...] + [--enable=service] [--disable=service] + [--allow-override=service] [--forbid-override=service] + [--reuseaddr] [--detach] [--pid-file=file] + [--user=user [--group=group]] [directory...] DESCRIPTION ----------- A really simple TCP git daemon that normally listens on port "DEFAULT_GIT_PORT" -aka 9418. It waits for a connection, and will just execute "git-upload-pack" -when it gets one. - -It's careful in that there's a magic request-line that gives the command and -what directory to upload, and it verifies that the directory is OK. +aka 9418. It waits for a connection asking for a service, and will serve +that service if it is enabled. It verifies that the directory has the magic file "git-daemon-export-ok", and it will refuse to export any git directory that hasn't explicitly been marked @@ -29,7 +28,12 @@ for export this way (unless the '--export-all' parameter is specified). If you pass some directory paths as 'git-daemon' arguments, you can further restrict the offers to a whitelist comprising of those. -This is ideally suited for read-only updates, i.e., pulling from git repositories. +By default, only `upload-pack` service is enabled, which serves +`git-fetch-pack` and `git-peek-remote` clients that are invoked +from `git-fetch`, `git-ls-remote`, and `git-clone`. + +This is ideally suited for read-only updates, i.e., pulling from +git repositories. OPTIONS ------- @@ -105,11 +109,38 @@ Giving these options is an error when used with `--inetd`; use the facility of inet daemon to achieve the same before spawning `git-daemon` if needed. +--enable-service, --disable-service:: + Enable/disable the service site-wide per default. Note + that a service disabled site-wide can still be enabled + per repository if it is marked overridable and the + repository enables the service with an configuration + item. + +--allow-override, --forbid-override:: + Allow/forbid overriding the site-wide default with per + repository configuration. By default, all the services + are overridable. + :: A directory to add to the whitelist of allowed directories. Unless --strict-paths is specified this will also include subdirectories of each named directory. +SERVICES +-------- + +upload-pack:: + This serves `git-fetch-pack` and `git-peek-remote` + clients. It is enabled by default, but a repository can + disable it by setting `daemon.uploadpack` configuration + item to `false`. + +upload-tar:: + This serves `git-tar-tree --remote=repository` client. + It is not enabled by default, but a repository can + enable it by setting `daemon.uploadtar` configuration + item to `true`. + Author ------ Written by Linus Torvalds , YOSHIFUJI Hideaki