full featured formating function of the --{base,user}_path arguments,
PATCH 1/1 full featured formating function of the --{base,user}_path arguments,
--- Documentation/git-daemon.txt | 54 +++++++++++ daemon.c | 207 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 240 insertions(+), 21 deletions(-)
Documentation/git-daemon.txt +53 -1
@@ -11,6 +11,8 @@ 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] + [--base-path-fmt=pathfmt] [--user-path-fmt=pathfmt] + [--default-hostname=hostname] [--reuseaddr] [--detach] [--pid-file=file] [directory...] DESCRIPTION
@@ -45,6 +47,10 @@ OPTIONS 'git://example.com/hello.git', `git-daemon` will interpret the path as '/srv/git/hello.git'. +--base-path-fmt=pathfmt:: + Works like --base-path, but uses a format instead. See Path + Formats section below. + --export-all:: Allow pulling from all directories that look like GIT repositories (have the 'objects' and 'refs' subdirectories), even if they
@@ -79,9 +85,20 @@ OPTIONS taken as a request to access `path/foo` repository in the home directory of user `alice`. +--user-path-fmt=pathfmt:: + Allow ~user notation to be used in requests. The path used to look + for the git repository is a format string, see Path Formats + section below. + --verbose:: Log details about the incoming connections and requested files. +--default-hostname=hostname:: + Backward compatibility switch: argument is used as a fallback + hostname to use with virtual hosting (to fill the `%h` format in + path formats) when the client is too old to provide the information + in the query (older than 1.4.0 series). + --reuseaddr:: Use SO_REUSEADDR when binding the listening socket. This allows the server to restart without waiting for
@@ -98,10 +115,45 @@ OPTIONS --strict-paths is specified this will also include subdirectories of each named directory. +Path Formats +------------ + +%h:: + requested hostname. That won't work with clients older than 1.4.0 + that do not pass the hostname in their query, and in that case, the + value of --default-hostname (if any) is used. + +%p:: + requested path. + +%P:: + requested path without the first slash when exists (`/`). + +%u:: + requested username (only allowed for --user-path-fmt). + +%%:: + plain `%`. + +Examples +~~~~~~~~ + +* `--base-path-fmt=/srv/git/%P` emulates `--base-path=/srv/git` + +* `--base-path-fmt=/srv/git/%h%p` will look into + `/srv/git/git.example.com/foo` if the request goes to + git://git.example.com/foo + +* `--user-path-fmt=/home/%u/public_git/%P` works mostly like + `--user-path=public_git` (the difference is that it assumes that home + directories live in `/home/username` instead of using the real `username` + home). + Author ------ Written by Linus Torvalds <[email protected]>, YOSHIFUJI Hideaki -<[email protected]> and the git-list <[email protected]> +<[email protected]>, Pierre Habouzit <[email protected]>, +and the git-list <[email protected]> Documentation --------------
daemon.c +187 -20
307 lines not on this page · raw message
Signature · 1 line
1.4.1.1
Quoted 4 lines · Pierre Habouzit
daemon.c +4
-0+static struct { +const char *path; +int use_as_fmt; +} base_path;
daemon.c static int strict_paths; · line 46
Quoted 10 lines
daemon.c +4
-1/* If defined, ~user notation is allowed and the string is inserted * after ~user/. E.g. a request to git://host/~alice/frotz would * go to /home/alice/pub_git/frotz with --user-path=pub_git. */ -static const char *user_path; +static struct { +const char *path; +int use_as_fmt; +} user_path;
Maybe it does not matter much, but I wonder if we want to keep two structs the same type, like:
static struct {
const char *path;
int use_as_fmt;
} base_path, user_path;I also wondered if we can just extend the semantics of base_path and user_path to autodetect the fmt-ness of them, but that means we would break existing setups that uses per-cent in the pathname. Arguably that would not be so common and we may not need to worry about such an installation, though. What do you think?
Quoted 4 lines
daemon.c +0
-0@@ -174,24 +285,45 @@ static char *path_ok(char *dir) slash = dir + restlen; namlen = slash - dir; restlen -= namlen;
daemon.c static char *path_ok(char *dir) · line 297
Quoted 10 lines
daemon.c +10
-0+ +if (user_path.use_as_fmt) { +loginfo ("host <%s>, " +"userpathfmt <%s>, request <%s>, " +"namlen %d, restlen %d, slash <%s>" , + vhost, + user_path.path, dir, + namlen, restlen, slash); + dir =git_path_fmt (rpath, user_path.path, vhost, + slash, dir +1 , namlen -1 );
When vhost is NULL you would feed it to "%s", which I think glibc works around with (null) fine but other C libraries would not like it. git_path_fmt()'s logging does not have this problem, though.
daemon.c static char *path_ok(char *dir) · line 319
Quoted 11 lines
daemon.c +6
-0+else if (base_path.path) {if (*dir !='/' ) {/* Allow only absolute */ logerror ("'%s': Non-absolute path denied (base-path active)" , dir);return NULL ; } + +if (base_path.use_as_fmt) { + dir =git_base_path_fmt (rpath, base_path.path, vhost, dir); + }else { +snprintf (rpath,PATH_MAX ,"%s%s" , base_path.path, dir);
The level of logging in this branch and in user_path.use_as_fmt branch are inconsistent. Maybe the more detailed one above I commented about vhost==NULL case was primarily meant for debugging and you forgot to remove it?
Quoted 14 lines
daemon.c +7
-0@@ -274,6 +406,7 @@ static int execute(struct sockaddr *addr@@ -303,15 +436,30 @@ #endifalarm (0 ); len =strlen (line); + +if (pktlen != len) { +int arg_pos = len +1 ; +loginfo ("Extended attributes (%d bytes) exist <%.*s>" , (int ) pktlen - len, + (int ) pktlen - len, line + arg_pos); + +while (arg_pos < pktlen) {
daemon.c #endif · line 457
Quoted 10 lines
daemon.c +10
-0+int arg_len =strlen (line + arg_pos); + +if (!strncmp ("host=" , line + arg_pos,5 )) { + vhost = line + arg_pos +5 ; + } + + arg_pos += arg_len +1 ; + } + } +
I think it is easier to do:
if (!vhost)
vhost = default_host;and have git_base_path_fmt() barf if the format calls for %h and vhost passed to it is NULL. Lack of "host=" in the request is logged here already.
Quoted 24 lines · Junio C Hamano
Quoted 9 lines · Pierre Habouzit
daemon.c +4
-0+static struct { +const char *path; +int use_as_fmt; +} base_path;/* If defined, ~user notation is allowed and the string is inserted * after ~user/. E.g. a request to
git://host/~alice/frotz
would * go to/home/alice/pub_git/frotzwith --user-path=pub_git. */daemon.c static int strict_paths; · line 46
Quoted 5 lines
daemon.c +4
-1-static const char *user_path; +static struct { +const char *path; +int use_as_fmt; +} user_path;Maybe it does not matter much, but I wonder if we want to keep two structs the same type, like:
static struct { const char *path; int use_as_fmt; } base_path, user_path;
Quoted 6 lines
I also wondered if we can just extend the semantics of
base_pathanduser_pathto autodetect the fmt-ness of them, but that means we would break existing setups that uses per-cent in the pathname. Arguably that would not be so common and we may not need to worry about such an installation, though. What do you think?
I think that merging the structs is indeed good, but that I do not like to break (even non common) setups when avoidable. but well, I've no *very* strong opinion on this, and if the consensus is that extending the argument with a format is good enough, I'll go for it, it would simplify the code a bit, and remove two arguments, both are good.
Quoted 12 lines
Quoted 12 lines
daemon.c +7
-0@@ -174,24 +285,45 @@ static char *path_ok(char *dir) slash = dir + restlen; namlen = slash - dir; restlen -= namlen; + +if (user_path.use_as_fmt) { + loginfo("host <%s>, " + "userpathfmt <%s>, request <%s>, " + "namlen %d, restlen %d, slash <%s>", + vhost, + user_path.path, dir,
Quoted 8 lines
daemon.c static char *path_ok(char *dir) · line 297
Quoted 3 lines
daemon.c +3
-0+ namlen, restlen, slash); + dir =git_path_fmt (rpath, user_path.path, vhost, + slash, dir +1 , namlen -1 );When vhost is NULL you would feed it to "%s", which I think glibc works around with (null) fine but other C libraries would not like it. git_path_fmt()'s logging does not have this problem, though.
uuhhh, I've always thought that passing NULL to a %s format was allowed by the C standard ... I've no copy here but one at work, I will verify it (for my peace of mind) but I agree it's not pretty.
Quoted 8 lines
Quoted 8 lines
daemon.c +3
-0+else if (base_path.path) {if (*dir !='/' ) {/* Allow only absolute */ logerror ("'%s': Non-absolute path denied (base-path active)" , dir);return NULL ; } + +if (base_path.use_as_fmt) {
Quoted 8 lines
daemon.c static char *path_ok(char *dir) · line 319
Quoted 3 lines
daemon.c +3
-0+ dir =git_base_path_fmt (rpath, base_path.path, vhost, dir); + }else { +snprintf (rpath,PATH_MAX ,"%s%s" , base_path.path, dir);The level of logging in this branch and in user_path.use_as_fmt branch are inconsistent. Maybe the more detailed one above I commented about vhost==NULL case was primarily meant for debugging and you forgot to remove it?
well, it was here before, so I left it, but I do not liked it much either, so if it's ok to remove it, I'd be glad to.
Quoted 27 lines
Quoted 14 lines
daemon.c +7
-0@@ -274,6 +406,7 @@ static int execute(struct sockaddr *addr@@ -303,15 +436,30 @@ #endifalarm (0 ); len =strlen (line); + +if (pktlen != len) { +int arg_pos = len +1 ; +loginfo ("Extended attributes (%d bytes) exist <%.*s>" , (int ) pktlen - len, + (int ) pktlen - len, line + arg_pos); + +while (arg_pos < pktlen) {daemon.c #endif · line 457
Quoted 10 lines
daemon.c +10
-0+int arg_len =strlen (line + arg_pos); + +if (!strncmp ("host=" , line + arg_pos,5 )) { + vhost = line + arg_pos +5 ; + } + + arg_pos += arg_len +1 ; + } + } +I think it is easier to do:
Quoted 6 lines
if (!vhost) vhost = default_host;and have
git_base_path_fmt()barf if the format calls for %h and vhost passed to it is NULL. Lack of "host=" in the request is logged here already.
hmmm, lack of host= is only logged in the git_path_fmt function atm. Its presence is logged though. But I could obviously log that it's missing while parsing the extending attributes, and then only need to barf when the %h is actually needed in the format string. That seems indeed easier. Will do.
Signature · 3 lines
·O· Pierre Habouzit ··O [email protected] OOO http://www.madism.org