#include "cache.h"
#include "pkt-line.h"
#include "exec_cmd.h"
#include "run-command.h"
#include "strbuf.h"
#include <syslog.h>
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
#ifndef NI_MAXSERV
#define NI_MAXSERV 32
#endif
static int log_syslog;
static int verbose;
static int reuseaddr;
static const char daemon_usage[] =
"git daemon [--verbose] [--syslog] [--export-all]\n"
" [--timeout=n] [--init-timeout=n] [--max-connections=n]\n"
" [--strict-paths] [--base-path=path] [--base-path-relaxed]\n"
" [--user-path | --user-path=path]\n"
" [--interpolated-path=path]\n"
" [--reuseaddr] [--detach] [--pid-file=file]\n"
" [--[enable|disable|allow-override|forbid-override]=service]\n"
" [--inetd | [--listen=host_or_ipaddr] [--port=n]\n"
" [--user=user [--group=group]]\n"
" [directory...]";
/* List of acceptable pathname prefixes */
static char **ok_paths;
static int strict_paths;
/* If this is set, git-daemon-export-ok is not required */
static int export_all_trees;
/* Take all paths relative to this one if non-NULL */
static char *base_path;
static char *interpolated_path;
static int base_path_relaxed;
/* Flag indicating client sent extra args. */
static int saw_extended_args;
/* 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;
/* Timeout, and initial timeout */
static unsigned int timeout;
static unsigned int init_timeout;
static char *hostname;
static char *canon_hostname;
static char *ip_address;
static char *tcp_port;
static void logreport(int priority, const char *err, va_list params)
{
if (log_syslog) {
char buf[1024];
vsnprintf(buf, sizeof(buf), err, params);
syslog(priority, "%s", buf);
} else {
/*
* Since stderr is set to linebuffered mode, the
* logging of different processes will not overlap
*/
fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid());
vfprintf(stderr, err, params);
fputc('\n', stderr);
}
}
static void logerror(const char *err, ...)
{
va_list params;
va_start(params, err);
logreport(LOG_ERR, err, params);
va_end(params);
}
static void loginfo(const char *err, ...)
{
va_list params;
if (!verbose)
return;
va_start(params, err);
logreport(LOG_INFO, err, params);
va_end(params);
}
static void NORETURN daemon_die(const char *err, va_list params)
{
logreport(LOG_ERR, err, params);
exit(1);
}
static int avoid_alias(char *p)
{
int sl, ndot;
/*
* This resurrects the belts and suspenders paranoia check by HPA
* done in <435560F7.4080006@zytor.com> thread, now enter_repo()
* does not do getcwd() based path canonicalizations.
*
* sl becomes true immediately after seeing '/' and continues to
* be true as long as dots continue after that without intervening
* non-dot character.
*/
if (!p || (*p != '/' && *p != '~'))
return -1;
sl = 1; ndot = 0;
p++;
while (1) {
char ch = *p++;
if (sl) {
if (ch == '.')
ndot++;
else if (ch == '/') {
if (ndot < 3)
/* reject //, /./ and /../ */
return -1;
ndot = 0;
}
else if (ch == 0) {
if (0 < ndot && ndot < 3)
/* reject /.$ and /..$ */
return -1;
return 0;
}
else
sl = ndot = 0;
}
else if (ch == 0)
return 0;
else if (ch == '/') {
sl = 1;
ndot = 0;
}
}
}
static char *path_ok(char *directory)
{
static char rpath[PATH_MAX];
static char interp_path[PATH_MAX];
char *path;
char *dir;
dir = directory;
|