282
return NULL; /* Fallthrough. Deny by default */
283
}
284
285
-typedef int (*daemon_service_fn)(void);
285
+typedef int (*daemon_service_fn)(const struct argv_array *env);
286
struct daemon_service {
287
const char *name;
288
const char *config_name;
363
}
364
365
static int run_service(const char *dir, struct daemon_service *service,
366
- struct hostinfo *hi)
366
+ struct hostinfo *hi, const struct argv_array *env)
367
{
368
const char *path;
369
int enabled = service->enabled;
422
*/
423
signal(SIGTERM, SIG_IGN);
424
425
- return service->fn();
425
+ return service->fn(env);
426
}
427
428
static void copy_to_log(int fd)
462
return finish_command(cld);
463
}
464
465
-static int upload_pack(void)
465
+static int upload_pack(const struct argv_array *env)
466
{
467
struct child_process cld = CHILD_PROCESS_INIT;
468
argv_array_pushl(&cld.args, "upload-pack", "--strict", NULL);
469
argv_array_pushf(&cld.args, "--timeout=%u", timeout);
470
+
471
+ argv_array_pushv(&cld.env_array, env->argv);
472
+
473
return run_service_command(&cld);
474
}
475
473
-static int upload_archive(void)
476
+static int upload_archive(const struct argv_array *env)
477
{
478
struct child_process cld = CHILD_PROCESS_INIT;
479
argv_array_push(&cld.args, "upload-archive");
480
+
481
+ argv_array_pushv(&cld.env_array, env->argv);
482
+
483
return run_service_command(&cld);
484
}
485
480
-static int receive_pack(void)
486
+static int receive_pack(const struct argv_array *env)
487
{
488
struct child_process cld = CHILD_PROCESS_INIT;
489
argv_array_push(&cld.args, "receive-pack");
490
+
491
+ argv_array_pushv(&cld.env_array, env->argv);
492
+
493
return run_service_command(&cld);
494
}
495
582
583
/*
584
* Read the host as supplied by the client connection.
585
+ *
586
+ * Returns a pointer to the character after the NUL byte terminating the host
587
+ * arguemnt, or 'extra_args' if there is no host arguemnt.
588
*/
577
-static void parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
589
+static char *parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
590
{
591
char *val;
592
int vallen;
614
if (extra_args < end && *extra_args)
615
die("Invalid request");
616
}
617
+
618
+ return extra_args;
619
+}
620
+
621
+static void parse_extra_args(struct hostinfo *hi, struct argv_array *env,
622
+ char *extra_args, int buflen)
623
+{
624
+ const char *end = extra_args + buflen;
625
+ struct strbuf git_protocol = STRBUF_INIT;
626
+
627
+ /* First look for the host argument */
628
+ extra_args = parse_host_arg(hi, extra_args, buflen);
629
+
630
+ /* Look for additional arguments places after a second NUL byte */
631
+ for (; extra_args < end; extra_args += strlen(extra_args) + 1) {
632
+ const char *arg = extra_args;
633
+
634
+ /*
635
+ * Parse the extra arguments, adding most to 'git_protocol'
636
+ * which will be used to set the 'GIT_PROTOCOL' envvar in the
637
+ * service that will be run.
638
+ *
639
+ * If there ends up being a particular arg in the future that
640
+ * git-daemon needs to parse specificly (like the 'host' arg)
641
+ * then it can be parsed here and not added to 'git_protocol'.
642
+ */
643
+ if (*arg) {
644
+ if (git_protocol.len > 0)
645
+ strbuf_addch(&git_protocol, ':');
646
+ strbuf_addstr(&git_protocol, arg);
647
+ }
648
+ }
649
+
650
+ if (git_protocol.len > 0)
651
+ argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s",
652
+ git_protocol.buf);
653
+ strbuf_release(&git_protocol);
654
}
655
656
/*
744
int pktlen, len, i;
745
char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
746
struct hostinfo hi;
747
+ struct argv_array env = ARGV_ARRAY_INIT;
748
749
hostinfo_init(&hi);
750
766
pktlen--;
767
}
768
769
+ /* parse additional args hidden behind a NUL byte */
770
if (len != pktlen)
720
- parse_host_arg(&hi, line + len + 1, pktlen - len - 1);
771
+ parse_extra_args(&hi, &env, line + len + 1, pktlen - len - 1);
772
773
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
774
struct daemon_service *s = &(daemon_service[i]);
781
* Note: The directory here is probably context sensitive,
782
* and might depend on the actual service being performed.
783
*/
733
- int rc = run_service(arg, s, &hi);
784
+ int rc = run_service(arg, s, &hi, &env);
785
hostinfo_clear(&hi);
786
+ argv_array_clear(&env);
787
return rc;
788
}
789
}
790
791
hostinfo_clear(&hi);
792
+ argv_array_clear(&env);
793
logerror("Protocol error: '%s'", line);
794
return -1;
795
}