diff options
Diffstat (limited to 'connect.c')
-rw-r--r-- | connect.c | 45 |
1 files changed, 36 insertions, 9 deletions
@@ -115,12 +115,7 @@ struct ref **get_remote_heads(int in, struct ref **list, return list; } -int server_supports(const char *feature) -{ - return !!parse_feature_request(server_capabilities, feature); -} - -const char *parse_feature_request(const char *feature_list, const char *feature) +const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp) { int len; @@ -132,14 +127,46 @@ const char *parse_feature_request(const char *feature_list, const char *feature) const char *found = strstr(feature_list, feature); if (!found) return NULL; - if ((feature_list == found || isspace(found[-1])) && - (!found[len] || isspace(found[len]) || found[len] == '=')) - return found; + if (feature_list == found || isspace(found[-1])) { + const char *value = found + len; + /* feature with no value (e.g., "thin-pack") */ + if (!*value || isspace(*value)) { + if (lenp) + *lenp = 0; + return value; + } + /* feature with a value (e.g., "agent=git/1.2.3") */ + else if (*value == '=') { + value++; + if (lenp) + *lenp = strcspn(value, " \t\n"); + return value; + } + /* + * otherwise we matched a substring of another feature; + * keep looking + */ + } feature_list = found + 1; } return NULL; } +int parse_feature_request(const char *feature_list, const char *feature) +{ + return !!parse_feature_value(feature_list, feature, NULL); +} + +const char *server_feature_value(const char *feature, int *len) +{ + return parse_feature_value(server_capabilities, feature, len); +} + +int server_supports(const char *feature) +{ + return !!server_feature_value(feature, NULL); +} + enum protocol { PROTO_LOCAL = 1, PROTO_SSH, |