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,10 @@ 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 ;
7760
7861static void logreport (int priority , const char * err , va_list params )
7962{
@@ -163,15 +146,15 @@ static int avoid_alias(char *p)
163146 }
164147}
165148
166- static char * path_ok (struct interp * itable )
149+ static char * path_ok (char * directory )
167150{
168151 static char rpath [PATH_MAX ];
169152 static char interp_path [PATH_MAX ];
170153 int retried_path = 0 ;
171154 char * path ;
172155 char * dir ;
173156
174- dir = itable [ INTERP_SLOT_DIR ]. value ;
157+ dir = directory ;
175158
176159 if (avoid_alias (dir )) {
177160 logerror ("'%s': aliased" , dir );
@@ -201,14 +184,27 @@ static char *path_ok(struct interp *itable)
201184 }
202185 }
203186 else if (interpolated_path && saw_extended_args ) {
187+ struct strbuf expanded_path = STRBUF_INIT ;
188+ struct strbuf_expand_dict_entry dict [] = {
189+ { "H" , hostname },
190+ { "CH" , canon_hostname },
191+ { "IP" , ip_address },
192+ { "P" , tcp_port },
193+ { "D" , directory },
194+ { "%" , "%" },
195+ { NULL }
196+ };
197+
204198 if (* dir != '/' ) {
205199 /* Allow only absolute */
206200 logerror ("'%s': Non-absolute path denied (interpolated-path active)" , dir );
207201 return NULL ;
208202 }
209203
210- interpolate (interp_path , PATH_MAX , interpolated_path ,
211- interp_table , ARRAY_SIZE (interp_table ));
204+ strbuf_expand (& expanded_path , interpolated_path ,
205+ strbuf_expand_dict_cb , & dict );
206+ strlcpy (interp_path , expanded_path .buf , PATH_MAX );
207+ strbuf_release (& expanded_path );
212208 loginfo ("Interpolated dir '%s'" , interp_path );
213209
214210 dir = interp_path ;
@@ -233,7 +229,7 @@ static char *path_ok(struct interp *itable)
233229 * prefixing the base path
234230 */
235231 if (base_path && base_path_relaxed && !retried_path ) {
236- dir = itable [ INTERP_SLOT_DIR ]. value ;
232+ dir = directory ;
237233 retried_path = 1 ;
238234 continue ;
239235 }
@@ -299,22 +295,20 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
299295 return 0 ;
300296}
301297
302- static int run_service (struct interp * itable , struct daemon_service * service )
298+ static int run_service (char * dir , struct daemon_service * service )
303299{
304300 const char * path ;
305301 int enabled = service -> enabled ;
306302
307- loginfo ("Request %s for '%s'" ,
308- service -> name ,
309- itable [INTERP_SLOT_DIR ].value );
303+ loginfo ("Request %s for '%s'" , service -> name , dir );
310304
311305 if (!enabled && !service -> overridable ) {
312306 logerror ("'%s': service not enabled." , service -> name );
313307 errno = EACCES ;
314308 return -1 ;
315309 }
316310
317- if (!(path = path_ok (itable )))
311+ if (!(path = path_ok (dir )))
318312 return -1 ;
319313
320314 /*
@@ -413,13 +407,13 @@ static void make_service_overridable(const char *name, int ena)
413407
414408/*
415409 * Separate the "extra args" information as supplied by the client connection.
416- * Any resulting data is squirreled away in the given interpolation table.
417410 */
418- static void parse_extra_args (struct interp * table , char * extra_args , int buflen )
411+ static void parse_extra_args (char * extra_args , int buflen )
419412{
420413 char * val ;
421414 int vallen ;
422415 char * end = extra_args + buflen ;
416+ char * hp ;
423417
424418 while (extra_args < end && * extra_args ) {
425419 saw_extended_args = 1 ;
@@ -433,25 +427,22 @@ 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 */
442438 extra_args = val + vallen ;
443439 }
444440 }
445- }
446-
447- static void fill_in_extra_table_entries (struct interp * itable )
448- {
449- char * hp ;
450441
451442 /*
452443 * Replace literal host with lowercase-ized hostname.
453444 */
454- hp = interp_table [ INTERP_SLOT_HOST ]. value ;
445+ hp = hostname ;
455446 if (!hp )
456447 return ;
457448 for ( ; * hp ; hp ++ )
@@ -470,17 +461,17 @@ static void fill_in_extra_table_entries(struct interp *itable)
470461 memset (& hints , 0 , sizeof (hints ));
471462 hints .ai_flags = AI_CANONNAME ;
472463
473- gai = getaddrinfo (interp_table [ INTERP_SLOT_HOST ]. value , 0 , & hints , & ai0 );
464+ gai = getaddrinfo (hostname , 0 , & hints , & ai0 );
474465 if (!gai ) {
475466 for (ai = ai0 ; ai ; ai = ai -> ai_next ) {
476467 struct sockaddr_in * sin_addr = (void * )ai -> ai_addr ;
477468
478469 inet_ntop (AF_INET , & sin_addr -> sin_addr ,
479470 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 );
471+ free ( canon_hostname );
472+ canon_hostname = xstrdup ( ai -> ai_canonname );
473+ free ( ip_address );
474+ ip_address = xstrdup ( addrbuf );
484475 break ;
485476 }
486477 freeaddrinfo (ai0 );
@@ -493,7 +484,7 @@ static void fill_in_extra_table_entries(struct interp *itable)
493484 char * * ap ;
494485 static char addrbuf [HOST_NAME_MAX + 1 ];
495486
496- hent = gethostbyname (interp_table [ INTERP_SLOT_HOST ]. value );
487+ hent = gethostbyname (hostname );
497488
498489 ap = hent -> h_addr_list ;
499490 memset (& sa , 0 , sizeof sa );
@@ -504,8 +495,10 @@ static void fill_in_extra_table_entries(struct interp *itable)
504495 inet_ntop (hent -> h_addrtype , & sa .sin_addr ,
505496 addrbuf , sizeof (addrbuf ));
506497
507- interp_set_entry (interp_table , INTERP_SLOT_CANON_HOST , hent -> h_name );
508- interp_set_entry (interp_table , INTERP_SLOT_IP , addrbuf );
498+ free (canon_hostname );
499+ canon_hostname = xstrdup (hent -> h_name );
500+ free (ip_address );
501+ ip_address = xstrdup (addrbuf );
509502 }
510503#endif
511504}
@@ -557,16 +550,14 @@ static int execute(struct sockaddr *addr)
557550 pktlen -- ;
558551 }
559552
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 , "%" ) ;
553+ free ( hostname );
554+ free ( canon_hostname );
555+ free ( ip_address );
556+ free ( tcp_port );
557+ hostname = canon_hostname = ip_address = tcp_port = NULL ;
565558
566- if (len != pktlen ) {
567- parse_extra_args (interp_table , line + len + 1 , pktlen - len - 1 );
568- fill_in_extra_table_entries (interp_table );
569- }
559+ if (len != pktlen )
560+ parse_extra_args (line + len + 1 , pktlen - len - 1 );
570561
571562 for (i = 0 ; i < ARRAY_SIZE (daemon_service ); i ++ ) {
572563 struct daemon_service * s = & (daemon_service [i ]);
@@ -578,9 +569,7 @@ static int execute(struct sockaddr *addr)
578569 * Note: The directory here is probably context sensitive,
579570 * and might depend on the actual service being performed.
580571 */
581- interp_set_entry (interp_table ,
582- INTERP_SLOT_DIR , line + namelen + 5 );
583- return run_service (interp_table , s );
572+ return run_service (line + namelen + 5 , s );
584573 }
585574 }
586575
0 commit comments