11#include "cache.h"
22#include "pkt-line.h"
33#include "exec_cmd.h"
4- #include "interpolate.h"
54
65#include <syslog.h>
76
@@ -54,26 +53,11 @@ static const char *user_path;
5453static unsigned int timeout ;
5554static unsigned int init_timeout ;
5655
57- /*
58- * Static table for now. Ugh.
59- * Feel free to make dynamic as needed.
60- */
61- #define INTERP_SLOT_HOST (0)
62- #define INTERP_SLOT_CANON_HOST (1)
63- #define INTERP_SLOT_IP (2)
64- #define INTERP_SLOT_PORT (3)
65- #define INTERP_SLOT_DIR (4)
66- #define INTERP_SLOT_PERCENT (5)
67-
68- static struct interp interp_table [] = {
69- { "%H" , 0 },
70- { "%CH" , 0 },
71- { "%IP" , 0 },
72- { "%P" , 0 },
73- { "%D" , 0 },
74- { "%%" , 0 },
75- };
76-
56+ static char * hostname ;
57+ static char * canon_hostname ;
58+ static char * ip_address ;
59+ static char * tcp_port ;
60+ static char * directory ;
7761
7862static void logreport (int priority , const char * err , va_list params )
7963{
@@ -163,15 +147,15 @@ static int avoid_alias(char *p)
163147 }
164148}
165149
166- static char * path_ok (struct interp * itable )
150+ static char * path_ok (void )
167151{
168152 static char rpath [PATH_MAX ];
169153 static char interp_path [PATH_MAX ];
170154 int retried_path = 0 ;
171155 char * path ;
172156 char * dir ;
173157
174- dir = itable [ INTERP_SLOT_DIR ]. value ;
158+ dir = directory ;
175159
176160 if (avoid_alias (dir )) {
177161 logerror ("'%s': aliased" , dir );
@@ -201,14 +185,27 @@ static char *path_ok(struct interp *itable)
201185 }
202186 }
203187 else if (interpolated_path && saw_extended_args ) {
188+ struct strbuf expanded_path = STRBUF_INIT ;
189+ struct strbuf_expand_dict_entry dict [] = {
190+ { "H" , hostname },
191+ { "CH" , canon_hostname },
192+ { "IP" , ip_address },
193+ { "P" , tcp_port },
194+ { "D" , directory },
195+ { "%" , "%" },
196+ { NULL }
197+ };
198+
204199 if (* dir != '/' ) {
205200 /* Allow only absolute */
206201 logerror ("'%s': Non-absolute path denied (interpolated-path active)" , dir );
207202 return NULL ;
208203 }
209204
210- interpolate (interp_path , PATH_MAX , interpolated_path ,
211- interp_table , ARRAY_SIZE (interp_table ));
205+ strbuf_expand (& expanded_path , interpolated_path ,
206+ strbuf_expand_dict_cb , & dict );
207+ strlcpy (interp_path , expanded_path .buf , PATH_MAX );
208+ strbuf_release (& expanded_path );
212209 loginfo ("Interpolated dir '%s'" , interp_path );
213210
214211 dir = interp_path ;
@@ -233,7 +230,7 @@ static char *path_ok(struct interp *itable)
233230 * prefixing the base path
234231 */
235232 if (base_path && base_path_relaxed && !retried_path ) {
236- dir = itable [ INTERP_SLOT_DIR ]. value ;
233+ dir = directory ;
237234 retried_path = 1 ;
238235 continue ;
239236 }
@@ -299,22 +296,20 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
299296 return 0 ;
300297}
301298
302- static int run_service (struct interp * itable , struct daemon_service * service )
299+ static int run_service (struct daemon_service * service )
303300{
304301 const char * path ;
305302 int enabled = service -> enabled ;
306303
307- loginfo ("Request %s for '%s'" ,
308- service -> name ,
309- itable [INTERP_SLOT_DIR ].value );
304+ loginfo ("Request %s for '%s'" , service -> name , directory );
310305
311306 if (!enabled && !service -> overridable ) {
312307 logerror ("'%s': service not enabled." , service -> name );
313308 errno = EACCES ;
314309 return -1 ;
315310 }
316311
317- if (!(path = path_ok (itable )))
312+ if (!(path = path_ok ()))
318313 return -1 ;
319314
320315 /*
@@ -413,9 +408,8 @@ static void make_service_overridable(const char *name, int ena)
413408
414409/*
415410 * Separate the "extra args" information as supplied by the client connection.
416- * Any resulting data is squirreled away in the given interpolation table.
417411 */
418- static void parse_extra_args (struct interp * table , char * extra_args , int buflen )
412+ static void parse_extra_args (char * extra_args , int buflen )
419413{
420414 char * val ;
421415 int vallen ;
@@ -433,9 +427,11 @@ static void parse_extra_args(struct interp *table, char *extra_args, int buflen)
433427 if (port ) {
434428 * port = 0 ;
435429 port ++ ;
436- interp_set_entry (table , INTERP_SLOT_PORT , port );
430+ free (tcp_port );
431+ tcp_port = xstrdup (port );
437432 }
438- interp_set_entry (table , INTERP_SLOT_HOST , host );
433+ free (hostname );
434+ hostname = xstrdup (host );
439435 }
440436
441437 /* On to the next one */
@@ -444,14 +440,14 @@ static void parse_extra_args(struct interp *table, char *extra_args, int buflen)
444440 }
445441}
446442
447- static void fill_in_extra_table_entries (struct interp * itable )
443+ static void fill_in_extra_table_entries (void )
448444{
449445 char * hp ;
450446
451447 /*
452448 * Replace literal host with lowercase-ized hostname.
453449 */
454- hp = interp_table [ INTERP_SLOT_HOST ]. value ;
450+ hp = hostname ;
455451 if (!hp )
456452 return ;
457453 for ( ; * hp ; hp ++ )
@@ -470,17 +466,17 @@ static void fill_in_extra_table_entries(struct interp *itable)
470466 memset (& hints , 0 , sizeof (hints ));
471467 hints .ai_flags = AI_CANONNAME ;
472468
473- gai = getaddrinfo (interp_table [ INTERP_SLOT_HOST ]. value , 0 , & hints , & ai0 );
469+ gai = getaddrinfo (hostname , 0 , & hints , & ai0 );
474470 if (!gai ) {
475471 for (ai = ai0 ; ai ; ai = ai -> ai_next ) {
476472 struct sockaddr_in * sin_addr = (void * )ai -> ai_addr ;
477473
478474 inet_ntop (AF_INET , & sin_addr -> sin_addr ,
479475 addrbuf , sizeof (addrbuf ));
480- interp_set_entry ( interp_table ,
481- INTERP_SLOT_CANON_HOST , ai -> ai_canonname );
482- interp_set_entry ( interp_table ,
483- INTERP_SLOT_IP , addrbuf );
476+ free ( canon_hostname );
477+ canon_hostname = xstrdup ( ai -> ai_canonname );
478+ free ( ip_address );
479+ ip_address = xstrdup ( addrbuf );
484480 break ;
485481 }
486482 freeaddrinfo (ai0 );
@@ -493,7 +489,7 @@ static void fill_in_extra_table_entries(struct interp *itable)
493489 char * * ap ;
494490 static char addrbuf [HOST_NAME_MAX + 1 ];
495491
496- hent = gethostbyname (interp_table [ INTERP_SLOT_HOST ]. value );
492+ hent = gethostbyname (hostname );
497493
498494 ap = hent -> h_addr_list ;
499495 memset (& sa , 0 , sizeof sa );
@@ -504,8 +500,10 @@ static void fill_in_extra_table_entries(struct interp *itable)
504500 inet_ntop (hent -> h_addrtype , & sa .sin_addr ,
505501 addrbuf , sizeof (addrbuf ));
506502
507- interp_set_entry (interp_table , INTERP_SLOT_CANON_HOST , hent -> h_name );
508- interp_set_entry (interp_table , INTERP_SLOT_IP , addrbuf );
503+ free (canon_hostname );
504+ canon_hostname = xstrdup (hent -> h_name );
505+ free (ip_address );
506+ ip_address = xstrdup (addrbuf );
509507 }
510508#endif
511509}
@@ -557,15 +555,16 @@ static int execute(struct sockaddr *addr)
557555 pktlen -- ;
558556 }
559557
560- /*
561- * Initialize the path interpolation table for this connection.
562- */
563- interp_clear_table (interp_table , ARRAY_SIZE (interp_table ));
564- interp_set_entry (interp_table , INTERP_SLOT_PERCENT , "%" );
558+ free (hostname );
559+ free (canon_hostname );
560+ free (ip_address );
561+ free (tcp_port );
562+ free (directory );
563+ hostname = canon_hostname = ip_address = tcp_port = directory = NULL ;
565564
566565 if (len != pktlen ) {
567- parse_extra_args (interp_table , line + len + 1 , pktlen - len - 1 );
568- fill_in_extra_table_entries (interp_table );
566+ parse_extra_args (line + len + 1 , pktlen - len - 1 );
567+ fill_in_extra_table_entries ();
569568 }
570569
571570 for (i = 0 ; i < ARRAY_SIZE (daemon_service ); i ++ ) {
@@ -578,9 +577,9 @@ static int execute(struct sockaddr *addr)
578577 * Note: The directory here is probably context sensitive,
579578 * and might depend on the actual service being performed.
580579 */
581- interp_set_entry ( interp_table ,
582- INTERP_SLOT_DIR , line + namelen + 5 );
583- return run_service (interp_table , s );
580+ free ( directory );
581+ directory = xstrdup ( line + namelen + 5 );
582+ return run_service (s );
584583 }
585584 }
586585
0 commit comments