Git fork
at reftables-rust 1536 lines 39 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "config.h" 5#include "environment.h" 6#include "gettext.h" 7#include "hex.h" 8#include "pkt-line.h" 9#include "quote.h" 10#include "refs.h" 11#include "run-command.h" 12#include "remote.h" 13#include "connect.h" 14#include "url.h" 15#include "string-list.h" 16#include "oid-array.h" 17#include "path.h" 18#include "transport.h" 19#include "trace2.h" 20#include "strbuf.h" 21#include "version.h" 22#include "protocol.h" 23#include "alias.h" 24#include "bundle-uri.h" 25#include "promisor-remote.h" 26 27static char *server_capabilities_v1; 28static struct strvec server_capabilities_v2 = STRVEC_INIT; 29static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset); 30 31static int check_ref(const char *name, unsigned int flags) 32{ 33 if (!flags) 34 return 1; 35 36 if (!skip_prefix(name, "refs/", &name)) 37 return 0; 38 39 /* REF_NORMAL means that we don't want the magic fake tag refs */ 40 if ((flags & REF_NORMAL) && check_refname_format(name, 41 REFNAME_ALLOW_ONELEVEL)) 42 return 0; 43 44 /* REF_BRANCHES means that we want regular branch heads */ 45 if ((flags & REF_BRANCHES) && starts_with(name, "heads/")) 46 return 1; 47 48 /* REF_TAGS means that we want tags */ 49 if ((flags & REF_TAGS) && starts_with(name, "tags/")) 50 return 1; 51 52 /* All type bits clear means that we are ok with anything */ 53 return !(flags & ~REF_NORMAL); 54} 55 56int check_ref_type(const struct ref *ref, int flags) 57{ 58 return check_ref(ref->name, flags); 59} 60 61static NORETURN void die_initial_contact(int unexpected) 62{ 63 /* 64 * A hang-up after seeing some response from the other end 65 * means that it is unexpected, as we know the other end is 66 * willing to talk to us. A hang-up before seeing any 67 * response does not necessarily mean an ACL problem, though. 68 */ 69 if (unexpected) 70 die(_("the remote end hung up upon initial contact")); 71 else 72 die(_("Could not read from remote repository.\n\n" 73 "Please make sure you have the correct access rights\n" 74 "and the repository exists.")); 75} 76 77/* Checks if the server supports the capability 'c' */ 78int server_supports_v2(const char *c) 79{ 80 size_t i; 81 82 for (i = 0; i < server_capabilities_v2.nr; i++) { 83 const char *out; 84 if (skip_prefix(server_capabilities_v2.v[i], c, &out) && 85 (!*out || *out == '=')) 86 return 1; 87 } 88 return 0; 89} 90 91void ensure_server_supports_v2(const char *c) 92{ 93 if (!server_supports_v2(c)) 94 die(_("server doesn't support '%s'"), c); 95} 96 97int server_feature_v2(const char *c, const char **v) 98{ 99 size_t i; 100 101 for (i = 0; i < server_capabilities_v2.nr; i++) { 102 const char *out; 103 if (skip_prefix(server_capabilities_v2.v[i], c, &out) && 104 (*out == '=')) { 105 *v = out + 1; 106 return 1; 107 } 108 } 109 return 0; 110} 111 112int server_supports_feature(const char *c, const char *feature, 113 int die_on_error) 114{ 115 size_t i; 116 117 for (i = 0; i < server_capabilities_v2.nr; i++) { 118 const char *out; 119 if (skip_prefix(server_capabilities_v2.v[i], c, &out) && 120 (!*out || *(out++) == '=')) { 121 if (parse_feature_request(out, feature)) 122 return 1; 123 else 124 break; 125 } 126 } 127 128 if (die_on_error) 129 die(_("server doesn't support feature '%s'"), feature); 130 131 return 0; 132} 133 134static void process_capabilities_v2(struct packet_reader *reader) 135{ 136 while (packet_reader_read(reader) == PACKET_READ_NORMAL) 137 strvec_push(&server_capabilities_v2, reader->line); 138 139 if (reader->status != PACKET_READ_FLUSH) 140 die(_("expected flush after capabilities")); 141} 142 143enum protocol_version discover_version(struct packet_reader *reader) 144{ 145 enum protocol_version version = protocol_unknown_version; 146 147 /* 148 * Peek the first line of the server's response to 149 * determine the protocol version the server is speaking. 150 */ 151 switch (packet_reader_peek(reader)) { 152 case PACKET_READ_EOF: 153 die_initial_contact(0); 154 case PACKET_READ_FLUSH: 155 case PACKET_READ_DELIM: 156 case PACKET_READ_RESPONSE_END: 157 version = protocol_v0; 158 break; 159 case PACKET_READ_NORMAL: 160 version = determine_protocol_version_client(reader->line); 161 break; 162 } 163 164 switch (version) { 165 case protocol_v2: 166 process_capabilities_v2(reader); 167 break; 168 case protocol_v1: 169 /* Read the peeked version line */ 170 packet_reader_read(reader); 171 break; 172 case protocol_v0: 173 break; 174 case protocol_unknown_version: 175 BUG("unknown protocol version"); 176 } 177 178 trace2_data_intmax("transfer", NULL, "negotiated-version", version); 179 180 return version; 181} 182 183static void parse_one_symref_info(struct string_list *symref, const char *val, int len) 184{ 185 char *sym, *target; 186 struct string_list_item *item; 187 188 if (!len) 189 return; /* just "symref" */ 190 /* e.g. "symref=HEAD:refs/heads/master" */ 191 sym = xmemdupz(val, len); 192 target = strchr(sym, ':'); 193 if (!target) 194 /* just "symref=something" */ 195 goto reject; 196 *(target++) = '\0'; 197 if (check_refname_format(sym, REFNAME_ALLOW_ONELEVEL) || 198 check_refname_format(target, REFNAME_ALLOW_ONELEVEL)) 199 /* "symref=bogus:pair */ 200 goto reject; 201 item = string_list_append_nodup(symref, sym); 202 item->util = target; 203 return; 204reject: 205 free(sym); 206 return; 207} 208 209static void annotate_refs_with_symref_info(struct ref *ref) 210{ 211 struct string_list symref = STRING_LIST_INIT_DUP; 212 size_t offset = 0; 213 214 while (1) { 215 size_t len; 216 const char *val; 217 218 val = next_server_feature_value("symref", &len, &offset); 219 if (!val) 220 break; 221 parse_one_symref_info(&symref, val, len); 222 } 223 string_list_sort(&symref); 224 225 for (; ref; ref = ref->next) { 226 struct string_list_item *item; 227 item = string_list_lookup(&symref, ref->name); 228 if (!item) 229 continue; 230 ref->symref = xstrdup((char *)item->util); 231 } 232 string_list_clear(&symref, 0); 233} 234 235static void process_capabilities(struct packet_reader *reader, size_t *linelen) 236{ 237 const char *feat_val; 238 size_t feat_len; 239 const char *line = reader->line; 240 size_t nul_location = strlen(line); 241 if (nul_location == *linelen) 242 return; 243 server_capabilities_v1 = xstrdup(line + nul_location + 1); 244 *linelen = nul_location; 245 246 feat_val = server_feature_value("object-format", &feat_len); 247 if (feat_val) { 248 char *hash_name = xstrndup(feat_val, feat_len); 249 int hash_algo = hash_algo_by_name(hash_name); 250 if (hash_algo != GIT_HASH_UNKNOWN) 251 reader->hash_algo = &hash_algos[hash_algo]; 252 free(hash_name); 253 } else { 254 reader->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY]; 255 } 256} 257 258static int process_dummy_ref(const struct packet_reader *reader) 259{ 260 const char *line = reader->line; 261 struct object_id oid; 262 const char *name; 263 264 if (parse_oid_hex_algop(line, &oid, &name, reader->hash_algo)) 265 return 0; 266 if (*name != ' ') 267 return 0; 268 name++; 269 270 return oideq(reader->hash_algo->null_oid, &oid) && 271 !strcmp(name, "capabilities^{}"); 272} 273 274static void check_no_capabilities(const char *line, size_t len) 275{ 276 if (strlen(line) != len) 277 warning(_("ignoring capabilities after first line '%s'"), 278 line + strlen(line)); 279} 280 281static int process_ref(const struct packet_reader *reader, size_t len, 282 struct ref ***list, unsigned int flags, 283 struct oid_array *extra_have) 284{ 285 const char *line = reader->line; 286 struct object_id old_oid; 287 const char *name; 288 289 if (parse_oid_hex_algop(line, &old_oid, &name, reader->hash_algo)) 290 return 0; 291 if (*name != ' ') 292 return 0; 293 name++; 294 295 if (extra_have && !strcmp(name, ".have")) { 296 oid_array_append(extra_have, &old_oid); 297 } else if (!strcmp(name, "capabilities^{}")) { 298 die(_("protocol error: unexpected capabilities^{}")); 299 } else if (check_ref(name, flags)) { 300 struct ref *ref = alloc_ref(name); 301 oidcpy(&ref->old_oid, &old_oid); 302 **list = ref; 303 *list = &ref->next; 304 } 305 check_no_capabilities(line, len); 306 return 1; 307} 308 309static int process_shallow(const struct packet_reader *reader, size_t len, 310 struct oid_array *shallow_points) 311{ 312 const char *line = reader->line; 313 const char *arg; 314 struct object_id old_oid; 315 316 if (!skip_prefix(line, "shallow ", &arg)) 317 return 0; 318 319 if (get_oid_hex_algop(arg, &old_oid, reader->hash_algo)) 320 die(_("protocol error: expected shallow sha-1, got '%s'"), arg); 321 if (!shallow_points) 322 die(_("repository on the other end cannot be shallow")); 323 oid_array_append(shallow_points, &old_oid); 324 check_no_capabilities(line, len); 325 return 1; 326} 327 328enum get_remote_heads_state { 329 EXPECTING_FIRST_REF = 0, 330 EXPECTING_REF, 331 EXPECTING_SHALLOW, 332 EXPECTING_DONE, 333}; 334 335/* 336 * Read all the refs from the other end 337 */ 338struct ref **get_remote_heads(struct packet_reader *reader, 339 struct ref **list, unsigned int flags, 340 struct oid_array *extra_have, 341 struct oid_array *shallow_points) 342{ 343 struct ref **orig_list = list; 344 size_t len = 0; 345 enum get_remote_heads_state state = EXPECTING_FIRST_REF; 346 347 *list = NULL; 348 349 while (state != EXPECTING_DONE) { 350 switch (packet_reader_read(reader)) { 351 case PACKET_READ_EOF: 352 die_initial_contact(1); 353 case PACKET_READ_NORMAL: 354 len = reader->pktlen; 355 break; 356 case PACKET_READ_FLUSH: 357 state = EXPECTING_DONE; 358 break; 359 case PACKET_READ_DELIM: 360 case PACKET_READ_RESPONSE_END: 361 die(_("invalid packet")); 362 } 363 364 switch (state) { 365 case EXPECTING_FIRST_REF: 366 process_capabilities(reader, &len); 367 if (process_dummy_ref(reader)) { 368 state = EXPECTING_SHALLOW; 369 break; 370 } 371 state = EXPECTING_REF; 372 /* fallthrough */ 373 case EXPECTING_REF: 374 if (process_ref(reader, len, &list, flags, extra_have)) 375 break; 376 state = EXPECTING_SHALLOW; 377 /* fallthrough */ 378 case EXPECTING_SHALLOW: 379 if (process_shallow(reader, len, shallow_points)) 380 break; 381 die(_("protocol error: unexpected '%s'"), reader->line); 382 case EXPECTING_DONE: 383 break; 384 } 385 } 386 387 annotate_refs_with_symref_info(*orig_list); 388 389 return list; 390} 391 392/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */ 393static int process_ref_v2(struct packet_reader *reader, struct ref ***list, 394 const char **unborn_head_target) 395{ 396 int ret = 1; 397 size_t i = 0; 398 struct object_id old_oid; 399 struct ref *ref; 400 struct string_list line_sections = STRING_LIST_INIT_DUP; 401 const char *end; 402 const char *line = reader->line; 403 404 /* 405 * Ref lines have a number of fields which are space deliminated. The 406 * first field is the OID of the ref. The second field is the ref 407 * name. Subsequent fields (symref-target and peeled) are optional and 408 * don't have a particular order. 409 */ 410 if (string_list_split(&line_sections, line, " ", -1) < 2) { 411 ret = 0; 412 goto out; 413 } 414 415 if (!strcmp("unborn", line_sections.items[i].string)) { 416 i++; 417 if (unborn_head_target && 418 !strcmp("HEAD", line_sections.items[i++].string)) { 419 /* 420 * Look for the symref target (if any). If found, 421 * return it to the caller. 422 */ 423 for (; i < line_sections.nr; i++) { 424 const char *arg = line_sections.items[i].string; 425 426 if (skip_prefix(arg, "symref-target:", &arg)) { 427 *unborn_head_target = xstrdup(arg); 428 break; 429 } 430 } 431 } 432 goto out; 433 } 434 if (parse_oid_hex_algop(line_sections.items[i++].string, &old_oid, &end, reader->hash_algo) || 435 *end) { 436 ret = 0; 437 goto out; 438 } 439 440 ref = alloc_ref(line_sections.items[i++].string); 441 442 memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz); 443 **list = ref; 444 *list = &ref->next; 445 446 for (; i < line_sections.nr; i++) { 447 const char *arg = line_sections.items[i].string; 448 if (skip_prefix(arg, "symref-target:", &arg)) 449 ref->symref = xstrdup(arg); 450 451 if (skip_prefix(arg, "peeled:", &arg)) { 452 struct object_id peeled_oid; 453 char *peeled_name; 454 struct ref *peeled; 455 if (parse_oid_hex_algop(arg, &peeled_oid, &end, 456 reader->hash_algo) || *end) { 457 ret = 0; 458 goto out; 459 } 460 461 peeled_name = xstrfmt("%s^{}", ref->name); 462 peeled = alloc_ref(peeled_name); 463 464 memcpy(peeled->old_oid.hash, peeled_oid.hash, 465 reader->hash_algo->rawsz); 466 **list = peeled; 467 *list = &peeled->next; 468 469 free(peeled_name); 470 } 471 } 472 473out: 474 string_list_clear(&line_sections, 0); 475 return ret; 476} 477 478void check_stateless_delimiter(int stateless_rpc, 479 struct packet_reader *reader, 480 const char *error) 481{ 482 if (!stateless_rpc) 483 return; /* not in stateless mode, no delimiter expected */ 484 if (packet_reader_read(reader) != PACKET_READ_RESPONSE_END) 485 die("%s", error); 486} 487 488static void send_capabilities(int fd_out, struct packet_reader *reader) 489{ 490 const char *hash_name; 491 const char *promisor_remote_info; 492 493 if (server_supports_v2("agent")) 494 packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); 495 496 if (server_feature_v2("object-format", &hash_name)) { 497 int hash_algo = hash_algo_by_name(hash_name); 498 if (hash_algo == GIT_HASH_UNKNOWN) 499 die(_("unknown object format '%s' specified by server"), hash_name); 500 reader->hash_algo = &hash_algos[hash_algo]; 501 packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name); 502 } else { 503 reader->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY]; 504 } 505 if (server_feature_v2("promisor-remote", &promisor_remote_info)) { 506 char *reply = promisor_remote_reply(promisor_remote_info); 507 if (reply) { 508 packet_write_fmt(fd_out, "promisor-remote=%s", reply); 509 free(reply); 510 } 511 } 512} 513 514int get_remote_bundle_uri(int fd_out, struct packet_reader *reader, 515 struct bundle_list *bundles, int stateless_rpc) 516{ 517 int line_nr = 1; 518 519 /* Assert bundle-uri support */ 520 ensure_server_supports_v2("bundle-uri"); 521 522 /* (Re-)send capabilities */ 523 send_capabilities(fd_out, reader); 524 525 /* Send command */ 526 packet_write_fmt(fd_out, "command=bundle-uri\n"); 527 packet_delim(fd_out); 528 529 packet_flush(fd_out); 530 531 /* Process response from server */ 532 while (packet_reader_read(reader) == PACKET_READ_NORMAL) { 533 const char *line = reader->line; 534 line_nr++; 535 536 if (!bundle_uri_parse_line(bundles, line)) 537 continue; 538 539 return error(_("error on bundle-uri response line %d: %s"), 540 line_nr, line); 541 } 542 543 if (reader->status != PACKET_READ_FLUSH) 544 return error(_("expected flush after bundle-uri listing")); 545 546 /* 547 * Might die(), but obscure enough that that's OK, e.g. in 548 * serve.c we'll call BUG() on its equivalent (the 549 * PACKET_READ_RESPONSE_END check). 550 */ 551 check_stateless_delimiter(stateless_rpc, reader, 552 _("expected response end packet after ref listing")); 553 554 return 0; 555} 556 557struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, 558 struct ref **list, int for_push, 559 struct transport_ls_refs_options *transport_options, 560 const struct string_list *server_options, 561 int stateless_rpc) 562{ 563 size_t i; 564 struct strvec *ref_prefixes = transport_options ? 565 &transport_options->ref_prefixes : NULL; 566 const char **unborn_head_target = transport_options ? 567 &transport_options->unborn_head_target : NULL; 568 *list = NULL; 569 570 ensure_server_supports_v2("ls-refs"); 571 packet_write_fmt(fd_out, "command=ls-refs\n"); 572 573 /* Send capabilities */ 574 send_capabilities(fd_out, reader); 575 576 if (server_options && server_options->nr) { 577 ensure_server_supports_v2("server-option"); 578 for (i = 0; i < server_options->nr; i++) 579 packet_write_fmt(fd_out, "server-option=%s", 580 server_options->items[i].string); 581 } 582 583 packet_delim(fd_out); 584 /* When pushing we don't want to request the peeled tags */ 585 if (!for_push) 586 packet_write_fmt(fd_out, "peel\n"); 587 packet_write_fmt(fd_out, "symrefs\n"); 588 if (server_supports_feature("ls-refs", "unborn", 0)) 589 packet_write_fmt(fd_out, "unborn\n"); 590 for (i = 0; ref_prefixes && i < ref_prefixes->nr; i++) { 591 packet_write_fmt(fd_out, "ref-prefix %s\n", 592 ref_prefixes->v[i]); 593 } 594 packet_flush(fd_out); 595 596 /* Process response from server */ 597 while (packet_reader_read(reader) == PACKET_READ_NORMAL) { 598 if (!process_ref_v2(reader, &list, unborn_head_target)) 599 die(_("invalid ls-refs response: %s"), reader->line); 600 } 601 602 if (reader->status != PACKET_READ_FLUSH) 603 die(_("expected flush after ref listing")); 604 605 check_stateless_delimiter(stateless_rpc, reader, 606 _("expected response end packet after ref listing")); 607 608 return list; 609} 610 611const char *parse_feature_value(const char *feature_list, const char *feature, size_t *lenp, size_t *offset) 612{ 613 const char *orig_start = feature_list; 614 size_t len; 615 616 if (!feature_list) 617 return NULL; 618 619 len = strlen(feature); 620 if (offset) 621 feature_list += *offset; 622 while (*feature_list) { 623 const char *found = strstr(feature_list, feature); 624 if (!found) 625 return NULL; 626 if (feature_list == found || isspace(found[-1])) { 627 const char *value = found + len; 628 /* feature with no value (e.g., "thin-pack") */ 629 if (!*value || isspace(*value)) { 630 if (lenp) 631 *lenp = 0; 632 if (offset) 633 *offset = found + len - orig_start; 634 return value; 635 } 636 /* feature with a value (e.g., "agent=git/1.2.3-Linux") */ 637 else if (*value == '=') { 638 size_t end; 639 640 value++; 641 end = strcspn(value, " \t\n"); 642 if (lenp) 643 *lenp = end; 644 if (offset) 645 *offset = value + end - orig_start; 646 return value; 647 } 648 /* 649 * otherwise we matched a substring of another feature; 650 * keep looking 651 */ 652 } 653 feature_list = found + 1; 654 } 655 return NULL; 656} 657 658int server_supports_hash(const char *desired, int *feature_supported) 659{ 660 size_t offset = 0; 661 size_t len; 662 const char *hash; 663 664 hash = next_server_feature_value("object-format", &len, &offset); 665 if (feature_supported) 666 *feature_supported = !!hash; 667 if (!hash) { 668 hash = hash_algos[GIT_HASH_SHA1_LEGACY].name; 669 len = strlen(hash); 670 } 671 while (hash) { 672 if (!xstrncmpz(desired, hash, len)) 673 return 1; 674 675 hash = next_server_feature_value("object-format", &len, &offset); 676 } 677 return 0; 678} 679 680int parse_feature_request(const char *feature_list, const char *feature) 681{ 682 return !!parse_feature_value(feature_list, feature, NULL, NULL); 683} 684 685static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset) 686{ 687 return parse_feature_value(server_capabilities_v1, feature, len, offset); 688} 689 690const char *server_feature_value(const char *feature, size_t *len) 691{ 692 return parse_feature_value(server_capabilities_v1, feature, len, NULL); 693} 694 695int server_supports(const char *feature) 696{ 697 return !!server_feature_value(feature, NULL); 698} 699 700enum protocol { 701 PROTO_LOCAL = 1, 702 PROTO_FILE, 703 PROTO_SSH, 704 PROTO_GIT 705}; 706 707int url_is_local_not_ssh(const char *url) 708{ 709 const char *colon = strchr(url, ':'); 710 const char *slash = strchr(url, '/'); 711 return !colon || (slash && slash < colon) || 712 (has_dos_drive_prefix(url) && is_valid_path(url)); 713} 714 715static const char *prot_name(enum protocol protocol) 716{ 717 switch (protocol) { 718 case PROTO_LOCAL: 719 case PROTO_FILE: 720 return "file"; 721 case PROTO_SSH: 722 return "ssh"; 723 case PROTO_GIT: 724 return "git"; 725 default: 726 return "unknown protocol"; 727 } 728} 729 730static enum protocol get_protocol(const char *name) 731{ 732 if (!strcmp(name, "ssh")) 733 return PROTO_SSH; 734 if (!strcmp(name, "git")) 735 return PROTO_GIT; 736 if (!strcmp(name, "git+ssh")) /* deprecated - do not use */ 737 return PROTO_SSH; 738 if (!strcmp(name, "ssh+git")) /* deprecated - do not use */ 739 return PROTO_SSH; 740 if (!strcmp(name, "file")) 741 return PROTO_FILE; 742 die(_("protocol '%s' is not supported"), name); 743} 744 745static char *host_end(char **hoststart, int removebrackets) 746{ 747 char *host = *hoststart; 748 char *end; 749 char *start = strstr(host, "@["); 750 if (start) 751 start++; /* Jump over '@' */ 752 else 753 start = host; 754 if (start[0] == '[') { 755 end = strchr(start + 1, ']'); 756 if (end) { 757 if (removebrackets) { 758 *end = 0; 759 memmove(start, start + 1, end - start); 760 end++; 761 } 762 } else 763 end = host; 764 } else 765 end = host; 766 return end; 767} 768 769#define STR_(s) # s 770#define STR(s) STR_(s) 771 772static void get_host_and_port(char **host, const char **port) 773{ 774 char *colon, *end; 775 end = host_end(host, 1); 776 colon = strchr(end, ':'); 777 if (colon) { 778 long portnr = strtol(colon + 1, &end, 10); 779 if (end != colon + 1 && *end == '\0' && 0 <= portnr && portnr < 65536) { 780 *colon = 0; 781 *port = colon + 1; 782 } else if (!colon[1]) { 783 *colon = 0; 784 } 785 } 786} 787 788static void enable_keepalive(int sockfd) 789{ 790 int ka = 1; 791 792 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0) 793 error_errno(_("unable to set SO_KEEPALIVE on socket")); 794} 795 796#ifndef NO_IPV6 797 798static const char *ai_name(const struct addrinfo *ai) 799{ 800 static char addr[NI_MAXHOST]; 801 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, sizeof(addr), NULL, 0, 802 NI_NUMERICHOST) != 0) 803 xsnprintf(addr, sizeof(addr), "(unknown)"); 804 805 return addr; 806} 807 808/* 809 * Returns a connected socket() fd, or else die()s. 810 */ 811static int git_tcp_connect_sock(char *host, int flags) 812{ 813 struct strbuf error_message = STRBUF_INIT; 814 int sockfd = -1; 815 const char *port = STR(DEFAULT_GIT_PORT); 816 struct addrinfo hints, *ai0, *ai; 817 int gai; 818 int cnt = 0; 819 820 get_host_and_port(&host, &port); 821 if (!*port) 822 port = "<none>"; 823 824 memset(&hints, 0, sizeof(hints)); 825 if (flags & CONNECT_IPV4) 826 hints.ai_family = AF_INET; 827 else if (flags & CONNECT_IPV6) 828 hints.ai_family = AF_INET6; 829 hints.ai_socktype = SOCK_STREAM; 830 hints.ai_protocol = IPPROTO_TCP; 831 832 if (flags & CONNECT_VERBOSE) 833 fprintf(stderr, _("Looking up %s ... "), host); 834 835 gai = getaddrinfo(host, port, &hints, &ai); 836 if (gai) 837 die(_("unable to look up %s (port %s) (%s)"), host, port, gai_strerror(gai)); 838 839 if (flags & CONNECT_VERBOSE) 840 /* TRANSLATORS: this is the end of "Looking up %s ... " */ 841 fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port); 842 843 for (ai0 = ai; ai; ai = ai->ai_next, cnt++) { 844 sockfd = socket(ai->ai_family, 845 ai->ai_socktype, ai->ai_protocol); 846 if ((sockfd < 0) || 847 (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) { 848 strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n", 849 host, cnt, ai_name(ai), strerror(errno)); 850 if (0 <= sockfd) 851 close(sockfd); 852 sockfd = -1; 853 continue; 854 } 855 if (flags & CONNECT_VERBOSE) 856 fprintf(stderr, "%s ", ai_name(ai)); 857 break; 858 } 859 860 freeaddrinfo(ai0); 861 862 if (sockfd < 0) 863 die(_("unable to connect to %s:\n%s"), host, error_message.buf); 864 865 enable_keepalive(sockfd); 866 867 if (flags & CONNECT_VERBOSE) 868 /* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */ 869 fprintf_ln(stderr, _("done.")); 870 871 strbuf_release(&error_message); 872 873 return sockfd; 874} 875 876#else /* NO_IPV6 */ 877 878/* 879 * Returns a connected socket() fd, or else die()s. 880 */ 881static int git_tcp_connect_sock(char *host, int flags) 882{ 883 struct strbuf error_message = STRBUF_INIT; 884 int sockfd = -1; 885 const char *port = STR(DEFAULT_GIT_PORT); 886 char *ep; 887 struct hostent *he; 888 struct sockaddr_in sa; 889 char **ap; 890 unsigned int nport; 891 int cnt; 892 893 get_host_and_port(&host, &port); 894 895 if (flags & CONNECT_VERBOSE) 896 fprintf(stderr, _("Looking up %s ... "), host); 897 898 he = gethostbyname(host); 899 if (!he) 900 die(_("unable to look up %s (%s)"), host, hstrerror(h_errno)); 901 nport = strtoul(port, &ep, 10); 902 if ( ep == port || *ep ) { 903 /* Not numeric */ 904 struct servent *se = getservbyname(port,"tcp"); 905 if ( !se ) 906 die(_("unknown port %s"), port); 907 nport = se->s_port; 908 } 909 910 if (flags & CONNECT_VERBOSE) 911 /* TRANSLATORS: this is the end of "Looking up %s ... " */ 912 fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port); 913 914 for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) { 915 memset(&sa, 0, sizeof sa); 916 sa.sin_family = he->h_addrtype; 917 sa.sin_port = htons(nport); 918 memcpy(&sa.sin_addr, *ap, he->h_length); 919 920 sockfd = socket(he->h_addrtype, SOCK_STREAM, 0); 921 if ((sockfd < 0) || 922 connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { 923 strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n", 924 host, 925 cnt, 926 inet_ntoa(*(struct in_addr *)&sa.sin_addr), 927 strerror(errno)); 928 if (0 <= sockfd) 929 close(sockfd); 930 sockfd = -1; 931 continue; 932 } 933 if (flags & CONNECT_VERBOSE) 934 fprintf(stderr, "%s ", 935 inet_ntoa(*(struct in_addr *)&sa.sin_addr)); 936 break; 937 } 938 939 if (sockfd < 0) 940 die(_("unable to connect to %s:\n%s"), host, error_message.buf); 941 942 enable_keepalive(sockfd); 943 944 if (flags & CONNECT_VERBOSE) 945 /* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */ 946 fprintf_ln(stderr, _("done.")); 947 948 return sockfd; 949} 950 951#endif /* NO_IPV6 */ 952 953 954/* 955 * Dummy child_process returned by git_connect() if the transport protocol 956 * does not need fork(2). 957 */ 958static struct child_process no_fork = CHILD_PROCESS_INIT; 959 960int git_connection_is_socket(struct child_process *conn) 961{ 962 return conn == &no_fork; 963} 964 965static struct child_process *git_tcp_connect(int fd[2], char *host, int flags) 966{ 967 int sockfd = git_tcp_connect_sock(host, flags); 968 969 fd[0] = sockfd; 970 fd[1] = dup(sockfd); 971 972 return &no_fork; 973} 974 975 976static char *git_proxy_command; 977 978static int git_proxy_command_options(const char *var, const char *value, 979 const struct config_context *ctx, void *cb) 980{ 981 if (!strcmp(var, "core.gitproxy")) { 982 const char *for_pos; 983 int matchlen = -1; 984 int hostlen; 985 const char *rhost_name = cb; 986 int rhost_len = strlen(rhost_name); 987 988 if (git_proxy_command) 989 return 0; 990 if (!value) 991 return config_error_nonbool(var); 992 /* [core] 993 * ;# matches www.kernel.org as well 994 * gitproxy = netcatter-1 for kernel.org 995 * gitproxy = netcatter-2 for sample.xz 996 * gitproxy = netcatter-default 997 */ 998 for_pos = strstr(value, " for "); 999 if (!for_pos) 1000 /* matches everybody */ 1001 matchlen = strlen(value); 1002 else { 1003 hostlen = strlen(for_pos + 5); 1004 if (rhost_len < hostlen) 1005 matchlen = -1; 1006 else if (!strncmp(for_pos + 5, 1007 rhost_name + rhost_len - hostlen, 1008 hostlen) && 1009 ((rhost_len == hostlen) || 1010 rhost_name[rhost_len - hostlen -1] == '.')) 1011 matchlen = for_pos - value; 1012 else 1013 matchlen = -1; 1014 } 1015 if (0 <= matchlen) { 1016 /* core.gitproxy = none for kernel.org */ 1017 if (matchlen == 4 && 1018 !memcmp(value, "none", 4)) 1019 matchlen = 0; 1020 git_proxy_command = xmemdupz(value, matchlen); 1021 } 1022 return 0; 1023 } 1024 1025 return git_default_config(var, value, ctx, cb); 1026} 1027 1028static int git_use_proxy(const char *host) 1029{ 1030 git_proxy_command = getenv("GIT_PROXY_COMMAND"); 1031 repo_config(the_repository, git_proxy_command_options, (void*)host); 1032 return (git_proxy_command && *git_proxy_command); 1033} 1034 1035static struct child_process *git_proxy_connect(int fd[2], char *host) 1036{ 1037 const char *port = STR(DEFAULT_GIT_PORT); 1038 struct child_process *proxy; 1039 1040 get_host_and_port(&host, &port); 1041 1042 if (looks_like_command_line_option(host)) 1043 die(_("strange hostname '%s' blocked"), host); 1044 if (looks_like_command_line_option(port)) 1045 die(_("strange port '%s' blocked"), port); 1046 1047 proxy = xmalloc(sizeof(*proxy)); 1048 child_process_init(proxy); 1049 strvec_push(&proxy->args, git_proxy_command); 1050 strvec_push(&proxy->args, host); 1051 strvec_push(&proxy->args, port); 1052 proxy->in = -1; 1053 proxy->out = -1; 1054 if (start_command(proxy)) 1055 die(_("cannot start proxy %s"), git_proxy_command); 1056 fd[0] = proxy->out; /* read from proxy stdout */ 1057 fd[1] = proxy->in; /* write to proxy stdin */ 1058 return proxy; 1059} 1060 1061static char *get_port(char *host) 1062{ 1063 char *end; 1064 char *p = strchr(host, ':'); 1065 1066 if (p) { 1067 long port = strtol(p + 1, &end, 10); 1068 if (end != p + 1 && *end == '\0' && 0 <= port && port < 65536) { 1069 *p = '\0'; 1070 return p+1; 1071 } 1072 } 1073 1074 return NULL; 1075} 1076 1077/* 1078 * Extract protocol and relevant parts from the specified connection URL. 1079 * The caller must free() the returned strings. 1080 */ 1081static enum protocol parse_connect_url(const char *url_orig, char **ret_host, 1082 char **ret_path) 1083{ 1084 char *url; 1085 char *host, *path; 1086 char *end; 1087 int separator = '/'; 1088 enum protocol protocol = PROTO_LOCAL; 1089 1090 if (is_url(url_orig)) 1091 url = url_decode(url_orig); 1092 else 1093 url = xstrdup(url_orig); 1094 1095 host = strstr(url, "://"); 1096 if (host) { 1097 *host = '\0'; 1098 protocol = get_protocol(url); 1099 host += 3; 1100 } else { 1101 host = url; 1102 if (!url_is_local_not_ssh(url)) { 1103 protocol = PROTO_SSH; 1104 separator = ':'; 1105 } 1106 } 1107 1108 /* 1109 * Don't do destructive transforms as protocol code does 1110 * '[]' unwrapping in get_host_and_port() 1111 */ 1112 end = host_end(&host, 0); 1113 1114 if (protocol == PROTO_LOCAL) 1115 path = end; 1116 else if (protocol == PROTO_FILE && *host != '/' && 1117 !has_dos_drive_prefix(host) && 1118 offset_1st_component(host - 2) > 1) 1119 path = host - 2; /* include the leading "//" */ 1120 else if (protocol == PROTO_FILE && has_dos_drive_prefix(end)) 1121 path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */ 1122 else 1123 path = strchr(end, separator); 1124 1125 if (!path || !*path) 1126 die(_("no path specified; see 'git help pull' for valid url syntax")); 1127 1128 /* 1129 * null-terminate hostname and point path to ~ for URL's like this: 1130 * ssh://host.xz/~user/repo 1131 */ 1132 1133 end = path; /* Need to \0 terminate host here */ 1134 if (separator == ':') 1135 path++; /* path starts after ':' */ 1136 if (protocol == PROTO_GIT || protocol == PROTO_SSH) { 1137 if (path[1] == '~') 1138 path++; 1139 } 1140 1141 path = xstrdup(path); 1142 *end = '\0'; 1143 1144 *ret_host = xstrdup(host); 1145 *ret_path = path; 1146 free(url); 1147 return protocol; 1148} 1149 1150static const char *get_ssh_command(void) 1151{ 1152 const char *ssh; 1153 1154 if ((ssh = getenv("GIT_SSH_COMMAND"))) 1155 return ssh; 1156 1157 if (!repo_config_get_string_tmp(the_repository, "core.sshcommand", &ssh)) 1158 return ssh; 1159 1160 return NULL; 1161} 1162 1163enum ssh_variant { 1164 VARIANT_AUTO, 1165 VARIANT_SIMPLE, 1166 VARIANT_SSH, 1167 VARIANT_PLINK, 1168 VARIANT_PUTTY, 1169 VARIANT_TORTOISEPLINK, 1170}; 1171 1172static void override_ssh_variant(enum ssh_variant *ssh_variant) 1173{ 1174 const char *variant = getenv("GIT_SSH_VARIANT"); 1175 1176 if (!variant && repo_config_get_string_tmp(the_repository, "ssh.variant", &variant)) 1177 return; 1178 1179 if (!strcmp(variant, "auto")) 1180 *ssh_variant = VARIANT_AUTO; 1181 else if (!strcmp(variant, "plink")) 1182 *ssh_variant = VARIANT_PLINK; 1183 else if (!strcmp(variant, "putty")) 1184 *ssh_variant = VARIANT_PUTTY; 1185 else if (!strcmp(variant, "tortoiseplink")) 1186 *ssh_variant = VARIANT_TORTOISEPLINK; 1187 else if (!strcmp(variant, "simple")) 1188 *ssh_variant = VARIANT_SIMPLE; 1189 else 1190 *ssh_variant = VARIANT_SSH; 1191} 1192 1193static enum ssh_variant determine_ssh_variant(const char *ssh_command, 1194 int is_cmdline) 1195{ 1196 enum ssh_variant ssh_variant = VARIANT_AUTO; 1197 const char *variant; 1198 char *p = NULL; 1199 1200 override_ssh_variant(&ssh_variant); 1201 1202 if (ssh_variant != VARIANT_AUTO) 1203 return ssh_variant; 1204 1205 if (!is_cmdline) { 1206 p = xstrdup(ssh_command); 1207 variant = basename(p); 1208 } else { 1209 const char **ssh_argv; 1210 1211 p = xstrdup(ssh_command); 1212 if (split_cmdline(p, &ssh_argv) > 0) { 1213 variant = basename((char *)ssh_argv[0]); 1214 /* 1215 * At this point, variant points into the buffer 1216 * referenced by p, hence we do not need ssh_argv 1217 * any longer. 1218 */ 1219 free(ssh_argv); 1220 } else { 1221 free(p); 1222 return ssh_variant; 1223 } 1224 } 1225 1226 if (!strcasecmp(variant, "ssh") || 1227 !strcasecmp(variant, "ssh.exe")) 1228 ssh_variant = VARIANT_SSH; 1229 else if (!strcasecmp(variant, "plink") || 1230 !strcasecmp(variant, "plink.exe")) 1231 ssh_variant = VARIANT_PLINK; 1232 else if (!strcasecmp(variant, "tortoiseplink") || 1233 !strcasecmp(variant, "tortoiseplink.exe")) 1234 ssh_variant = VARIANT_TORTOISEPLINK; 1235 1236 free(p); 1237 return ssh_variant; 1238} 1239 1240/* 1241 * Open a connection using Git's native protocol. 1242 * 1243 * The caller is responsible for freeing hostandport, but this function may 1244 * modify it (for example, to truncate it to remove the port part). 1245 */ 1246static struct child_process *git_connect_git(int fd[2], char *hostandport, 1247 const char *path, const char *prog, 1248 enum protocol_version version, 1249 int flags) 1250{ 1251 struct child_process *conn; 1252 struct strbuf request = STRBUF_INIT; 1253 /* 1254 * Set up virtual host information based on where we will 1255 * connect, unless the user has overridden us in 1256 * the environment. 1257 */ 1258 char *target_host = getenv("GIT_OVERRIDE_VIRTUAL_HOST"); 1259 if (target_host) 1260 target_host = xstrdup(target_host); 1261 else 1262 target_host = xstrdup(hostandport); 1263 1264 transport_check_allowed("git"); 1265 if (strchr(target_host, '\n') || strchr(path, '\n')) 1266 die(_("newline is forbidden in git:// hosts and repo paths")); 1267 1268 /* 1269 * These underlying connection commands die() if they 1270 * cannot connect. 1271 */ 1272 if (git_use_proxy(hostandport)) 1273 conn = git_proxy_connect(fd, hostandport); 1274 else 1275 conn = git_tcp_connect(fd, hostandport, flags); 1276 /* 1277 * Separate original protocol components prog and path 1278 * from extended host header with a NUL byte. 1279 * 1280 * Note: Do not add any other headers here! Doing so 1281 * will cause older git-daemon servers to crash. 1282 */ 1283 strbuf_addf(&request, 1284 "%s %s%chost=%s%c", 1285 prog, path, 0, 1286 target_host, 0); 1287 1288 /* If using a new version put that stuff here after a second null byte */ 1289 if (version > 0) { 1290 strbuf_addch(&request, '\0'); 1291 strbuf_addf(&request, "version=%d%c", 1292 version, '\0'); 1293 } 1294 1295 packet_write(fd[1], request.buf, request.len); 1296 1297 free(target_host); 1298 strbuf_release(&request); 1299 return conn; 1300} 1301 1302/* 1303 * Append the appropriate environment variables to `env` and options to 1304 * `args` for running ssh in Git's SSH-tunneled transport. 1305 */ 1306static void push_ssh_options(struct strvec *args, struct strvec *env, 1307 enum ssh_variant variant, const char *port, 1308 enum protocol_version version, int flags) 1309{ 1310 if (variant == VARIANT_SSH && 1311 version > 0) { 1312 strvec_push(args, "-o"); 1313 strvec_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT); 1314 strvec_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d", 1315 version); 1316 } 1317 1318 if (flags & CONNECT_IPV4) { 1319 switch (variant) { 1320 case VARIANT_AUTO: 1321 BUG("VARIANT_AUTO passed to push_ssh_options"); 1322 case VARIANT_SIMPLE: 1323 die(_("ssh variant 'simple' does not support -4")); 1324 case VARIANT_SSH: 1325 case VARIANT_PLINK: 1326 case VARIANT_PUTTY: 1327 case VARIANT_TORTOISEPLINK: 1328 strvec_push(args, "-4"); 1329 } 1330 } else if (flags & CONNECT_IPV6) { 1331 switch (variant) { 1332 case VARIANT_AUTO: 1333 BUG("VARIANT_AUTO passed to push_ssh_options"); 1334 case VARIANT_SIMPLE: 1335 die(_("ssh variant 'simple' does not support -6")); 1336 case VARIANT_SSH: 1337 case VARIANT_PLINK: 1338 case VARIANT_PUTTY: 1339 case VARIANT_TORTOISEPLINK: 1340 strvec_push(args, "-6"); 1341 } 1342 } 1343 1344 if (variant == VARIANT_TORTOISEPLINK) 1345 strvec_push(args, "-batch"); 1346 1347 if (port) { 1348 switch (variant) { 1349 case VARIANT_AUTO: 1350 BUG("VARIANT_AUTO passed to push_ssh_options"); 1351 case VARIANT_SIMPLE: 1352 die(_("ssh variant 'simple' does not support setting port")); 1353 case VARIANT_SSH: 1354 strvec_push(args, "-p"); 1355 break; 1356 case VARIANT_PLINK: 1357 case VARIANT_PUTTY: 1358 case VARIANT_TORTOISEPLINK: 1359 strvec_push(args, "-P"); 1360 } 1361 1362 strvec_push(args, port); 1363 } 1364} 1365 1366/* Prepare a child_process for use by Git's SSH-tunneled transport. */ 1367static void fill_ssh_args(struct child_process *conn, const char *ssh_host, 1368 const char *port, enum protocol_version version, 1369 int flags) 1370{ 1371 const char *ssh; 1372 enum ssh_variant variant; 1373 1374 if (looks_like_command_line_option(ssh_host)) 1375 die(_("strange hostname '%s' blocked"), ssh_host); 1376 1377 ssh = get_ssh_command(); 1378 if (ssh) { 1379 variant = determine_ssh_variant(ssh, 1); 1380 } else { 1381 /* 1382 * GIT_SSH is the no-shell version of 1383 * GIT_SSH_COMMAND (and must remain so for 1384 * historical compatibility). 1385 */ 1386 conn->use_shell = 0; 1387 1388 ssh = getenv("GIT_SSH"); 1389 if (!ssh) 1390 ssh = "ssh"; 1391 variant = determine_ssh_variant(ssh, 0); 1392 } 1393 1394 if (variant == VARIANT_AUTO) { 1395 struct child_process detect = CHILD_PROCESS_INIT; 1396 1397 detect.use_shell = conn->use_shell; 1398 detect.no_stdin = detect.no_stdout = detect.no_stderr = 1; 1399 1400 strvec_push(&detect.args, ssh); 1401 strvec_push(&detect.args, "-G"); 1402 push_ssh_options(&detect.args, &detect.env, 1403 VARIANT_SSH, port, version, flags); 1404 strvec_push(&detect.args, ssh_host); 1405 1406 variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH; 1407 } 1408 1409 strvec_push(&conn->args, ssh); 1410 push_ssh_options(&conn->args, &conn->env, variant, port, version, 1411 flags); 1412 strvec_push(&conn->args, ssh_host); 1413} 1414 1415/* 1416 * This returns the dummy child_process `no_fork` if the transport protocol 1417 * does not need fork(2), or a struct child_process object if it does. Once 1418 * done, finish the connection with finish_connect() with the value returned 1419 * from this function (it is safe to call finish_connect() with NULL to 1420 * support the former case). 1421 * 1422 * If it returns, the connect is successful; it just dies on errors (this 1423 * will hopefully be changed in a libification effort, to return NULL when 1424 * the connection failed). 1425 */ 1426struct child_process *git_connect(int fd[2], const char *url, 1427 const char *name, 1428 const char *prog, int flags) 1429{ 1430 char *hostandport, *path; 1431 struct child_process *conn; 1432 enum protocol protocol; 1433 enum protocol_version version = get_protocol_version_config(); 1434 1435 /* 1436 * NEEDSWORK: If we are trying to use protocol v2 and we are planning 1437 * to perform any operation that doesn't involve upload-pack (i.e., a 1438 * fetch, ls-remote, etc), then fallback to v0 since we don't know how 1439 * to do anything else (like push or remote archive) via v2. 1440 */ 1441 if (version == protocol_v2 && strcmp("git-upload-pack", name)) 1442 version = protocol_v0; 1443 1444 /* Without this we cannot rely on waitpid() to tell 1445 * what happened to our children. 1446 */ 1447 signal(SIGCHLD, SIG_DFL); 1448 1449 protocol = parse_connect_url(url, &hostandport, &path); 1450 if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) { 1451 printf("Diag: url=%s\n", url ? url : "NULL"); 1452 printf("Diag: protocol=%s\n", prot_name(protocol)); 1453 printf("Diag: hostandport=%s\n", hostandport ? hostandport : "NULL"); 1454 printf("Diag: path=%s\n", path ? path : "NULL"); 1455 conn = NULL; 1456 } else if (protocol == PROTO_GIT) { 1457 conn = git_connect_git(fd, hostandport, path, prog, version, flags); 1458 conn->trace2_child_class = "transport/git"; 1459 } else { 1460 struct strbuf cmd = STRBUF_INIT; 1461 const char *const *var; 1462 1463 conn = xmalloc(sizeof(*conn)); 1464 child_process_init(conn); 1465 1466 if (looks_like_command_line_option(path)) 1467 die(_("strange pathname '%s' blocked"), path); 1468 1469 strbuf_addstr(&cmd, prog); 1470 strbuf_addch(&cmd, ' '); 1471 sq_quote_buf(&cmd, path); 1472 1473 /* remove repo-local variables from the environment */ 1474 for (var = local_repo_env; *var; var++) 1475 strvec_push(&conn->env, *var); 1476 1477 conn->use_shell = 1; 1478 conn->in = conn->out = -1; 1479 if (protocol == PROTO_SSH) { 1480 char *ssh_host = hostandport; 1481 const char *port = NULL; 1482 transport_check_allowed("ssh"); 1483 get_host_and_port(&ssh_host, &port); 1484 1485 if (!port) 1486 port = get_port(ssh_host); 1487 1488 if (flags & CONNECT_DIAG_URL) { 1489 printf("Diag: url=%s\n", url ? url : "NULL"); 1490 printf("Diag: protocol=%s\n", prot_name(protocol)); 1491 printf("Diag: userandhost=%s\n", ssh_host ? ssh_host : "NULL"); 1492 printf("Diag: port=%s\n", port ? port : "NONE"); 1493 printf("Diag: path=%s\n", path ? path : "NULL"); 1494 1495 free(hostandport); 1496 free(path); 1497 child_process_clear(conn); 1498 free(conn); 1499 strbuf_release(&cmd); 1500 return NULL; 1501 } 1502 conn->trace2_child_class = "transport/ssh"; 1503 fill_ssh_args(conn, ssh_host, port, version, flags); 1504 } else { 1505 transport_check_allowed("file"); 1506 conn->trace2_child_class = "transport/file"; 1507 if (version > 0) { 1508 strvec_pushf(&conn->env, 1509 GIT_PROTOCOL_ENVIRONMENT "=version=%d", 1510 version); 1511 } 1512 } 1513 strvec_push(&conn->args, cmd.buf); 1514 1515 if (start_command(conn)) 1516 die(_("unable to fork")); 1517 1518 fd[0] = conn->out; /* read from child's stdout */ 1519 fd[1] = conn->in; /* write to child's stdin */ 1520 strbuf_release(&cmd); 1521 } 1522 free(hostandport); 1523 free(path); 1524 return conn; 1525} 1526 1527int finish_connect(struct child_process *conn) 1528{ 1529 int code; 1530 if (!conn || git_connection_is_socket(conn)) 1531 return 0; 1532 1533 code = finish_command(conn); 1534 free(conn); 1535 return code; 1536}