Coverage Report

Created: 2024-09-16 06:10

/src/git/transport-helper.c
Line
Count
Source (jump to first uncovered line)
1
#define USE_THE_REPOSITORY_VARIABLE
2
3
#include "git-compat-util.h"
4
#include "transport.h"
5
#include "quote.h"
6
#include "run-command.h"
7
#include "commit.h"
8
#include "environment.h"
9
#include "gettext.h"
10
#include "hex.h"
11
#include "object-name.h"
12
#include "repository.h"
13
#include "remote.h"
14
#include "string-list.h"
15
#include "thread-utils.h"
16
#include "sigchain.h"
17
#include "strvec.h"
18
#include "refs.h"
19
#include "refspec.h"
20
#include "transport-internal.h"
21
#include "protocol.h"
22
#include "packfile.h"
23
24
static int debug;
25
26
struct helper_data {
27
  char *name;
28
  struct child_process *helper;
29
  FILE *out;
30
  unsigned fetch : 1,
31
    import : 1,
32
    bidi_import : 1,
33
    export : 1,
34
    option : 1,
35
    push : 1,
36
    connect : 1,
37
    stateless_connect : 1,
38
    signed_tags : 1,
39
    check_connectivity : 1,
40
    no_disconnect_req : 1,
41
    no_private_update : 1,
42
    object_format : 1;
43
44
  /*
45
   * As an optimization, the transport code may invoke fetch before
46
   * get_refs_list. If this happens, and if the transport helper doesn't
47
   * support connect or stateless_connect, we need to invoke
48
   * get_refs_list ourselves if we haven't already done so. Keep track of
49
   * whether we have invoked get_refs_list.
50
   */
51
  unsigned get_refs_list_called : 1;
52
53
  char *export_marks;
54
  char *import_marks;
55
  /* These go from remote name (as in "list") to private name */
56
  struct refspec rs;
57
  /* Transport options for fetch-pack/send-pack (should one of
58
   * those be invoked).
59
   */
60
  struct git_transport_options transport_options;
61
};
62
63
static void sendline(struct helper_data *helper, struct strbuf *buffer)
64
0
{
65
0
  if (debug)
66
0
    fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf);
67
0
  if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0)
68
0
    die_errno(_("full write to remote helper failed"));
69
0
}
70
71
static int recvline_fh(FILE *helper, struct strbuf *buffer)
72
0
{
73
0
  strbuf_reset(buffer);
74
0
  if (debug)
75
0
    fprintf(stderr, "Debug: Remote helper: Waiting...\n");
76
0
  if (strbuf_getline(buffer, helper) == EOF) {
77
0
    if (debug)
78
0
      fprintf(stderr, "Debug: Remote helper quit.\n");
79
0
    return 1;
80
0
  }
81
82
0
  if (debug)
83
0
    fprintf(stderr, "Debug: Remote helper: <- %s\n", buffer->buf);
84
0
  return 0;
85
0
}
86
87
static int recvline(struct helper_data *helper, struct strbuf *buffer)
88
0
{
89
0
  return recvline_fh(helper->out, buffer);
90
0
}
91
92
static void write_constant(int fd, const char *str)
93
0
{
94
0
  if (debug)
95
0
    fprintf(stderr, "Debug: Remote helper: -> %s", str);
96
0
  if (write_in_full(fd, str, strlen(str)) < 0)
97
0
    die_errno(_("full write to remote helper failed"));
98
0
}
99
100
static const char *remove_ext_force(const char *url)
101
0
{
102
0
  if (url) {
103
0
    const char *colon = strchr(url, ':');
104
0
    if (colon && colon[1] == ':')
105
0
      return colon + 2;
106
0
  }
107
0
  return url;
108
0
}
109
110
static void do_take_over(struct transport *transport)
111
0
{
112
0
  struct helper_data *data;
113
0
  data = (struct helper_data *)transport->data;
114
0
  transport_take_over(transport, data->helper);
115
0
  fclose(data->out);
116
0
  free(data->name);
117
0
  free(data);
118
0
}
119
120
static void standard_options(struct transport *t);
121
122
static struct child_process *get_helper(struct transport *transport)
123
0
{
124
0
  struct helper_data *data = transport->data;
125
0
  struct strbuf buf = STRBUF_INIT;
126
0
  struct child_process *helper;
127
0
  int duped;
128
0
  int code;
129
130
0
  if (data->helper)
131
0
    return data->helper;
132
133
0
  helper = xmalloc(sizeof(*helper));
134
0
  child_process_init(helper);
135
0
  helper->in = -1;
136
0
  helper->out = -1;
137
0
  helper->err = 0;
138
0
  strvec_pushf(&helper->args, "remote-%s", data->name);
139
0
  strvec_push(&helper->args, transport->remote->name);
140
0
  strvec_push(&helper->args, remove_ext_force(transport->url));
141
0
  helper->git_cmd = 1;
142
0
  helper->silent_exec_failure = 1;
143
144
0
  if (have_git_dir())
145
0
    strvec_pushf(&helper->env, "%s=%s",
146
0
           GIT_DIR_ENVIRONMENT, get_git_dir());
147
148
0
  helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */
149
150
0
  code = start_command(helper);
151
0
  if (code < 0 && errno == ENOENT)
152
0
    die(_("unable to find remote helper for '%s'"), data->name);
153
0
  else if (code != 0)
154
0
    exit(code);
155
156
0
  data->helper = helper;
157
0
  data->no_disconnect_req = 0;
158
0
  refspec_init(&data->rs, REFSPEC_FETCH);
159
160
  /*
161
   * Open the output as FILE* so strbuf_getline_*() family of
162
   * functions can be used.
163
   * Do this with duped fd because fclose() will close the fd,
164
   * and stuff like taking over will require the fd to remain.
165
   */
166
0
  duped = dup(helper->out);
167
0
  if (duped < 0)
168
0
    die_errno(_("can't dup helper output fd"));
169
0
  data->out = xfdopen(duped, "r");
170
171
0
  write_constant(helper->in, "capabilities\n");
172
173
0
  while (1) {
174
0
    const char *capname, *arg;
175
0
    int mandatory = 0;
176
0
    if (recvline(data, &buf))
177
0
      exit(128);
178
179
0
    if (!*buf.buf)
180
0
      break;
181
182
0
    if (*buf.buf == '*') {
183
0
      capname = buf.buf + 1;
184
0
      mandatory = 1;
185
0
    } else
186
0
      capname = buf.buf;
187
188
0
    if (debug)
189
0
      fprintf(stderr, "Debug: Got cap %s\n", capname);
190
0
    if (!strcmp(capname, "fetch"))
191
0
      data->fetch = 1;
192
0
    else if (!strcmp(capname, "option"))
193
0
      data->option = 1;
194
0
    else if (!strcmp(capname, "push"))
195
0
      data->push = 1;
196
0
    else if (!strcmp(capname, "import"))
197
0
      data->import = 1;
198
0
    else if (!strcmp(capname, "bidi-import"))
199
0
      data->bidi_import = 1;
200
0
    else if (!strcmp(capname, "export"))
201
0
      data->export = 1;
202
0
    else if (!strcmp(capname, "check-connectivity"))
203
0
      data->check_connectivity = 1;
204
0
    else if (skip_prefix(capname, "refspec ", &arg)) {
205
0
      refspec_append(&data->rs, arg);
206
0
    } else if (!strcmp(capname, "connect")) {
207
0
      data->connect = 1;
208
0
    } else if (!strcmp(capname, "stateless-connect")) {
209
0
      data->stateless_connect = 1;
210
0
    } else if (!strcmp(capname, "signed-tags")) {
211
0
      data->signed_tags = 1;
212
0
    } else if (skip_prefix(capname, "export-marks ", &arg)) {
213
0
      data->export_marks = xstrdup(arg);
214
0
    } else if (skip_prefix(capname, "import-marks ", &arg)) {
215
0
      data->import_marks = xstrdup(arg);
216
0
    } else if (starts_with(capname, "no-private-update")) {
217
0
      data->no_private_update = 1;
218
0
    } else if (starts_with(capname, "object-format")) {
219
0
      data->object_format = 1;
220
0
    } else if (mandatory) {
221
0
      die(_("unknown mandatory capability %s; this remote "
222
0
            "helper probably needs newer version of Git"),
223
0
          capname);
224
0
    }
225
0
  }
226
0
  if (!data->rs.nr && (data->import || data->bidi_import || data->export)) {
227
0
    warning(_("this remote helper should implement refspec capability"));
228
0
  }
229
0
  strbuf_release(&buf);
230
0
  if (debug)
231
0
    fprintf(stderr, "Debug: Capabilities complete.\n");
232
0
  standard_options(transport);
233
0
  return data->helper;
234
0
}
235
236
static int disconnect_helper(struct transport *transport)
237
0
{
238
0
  struct helper_data *data = transport->data;
239
0
  int res = 0;
240
241
0
  if (data->helper) {
242
0
    if (debug)
243
0
      fprintf(stderr, "Debug: Disconnecting.\n");
244
0
    if (!data->no_disconnect_req) {
245
      /*
246
       * Ignore write errors; there's nothing we can do,
247
       * since we're about to close the pipe anyway. And the
248
       * most likely error is EPIPE due to the helper dying
249
       * to report an error itself.
250
       */
251
0
      sigchain_push(SIGPIPE, SIG_IGN);
252
0
      xwrite(data->helper->in, "\n", 1);
253
0
      sigchain_pop(SIGPIPE);
254
0
    }
255
0
    close(data->helper->in);
256
0
    close(data->helper->out);
257
0
    fclose(data->out);
258
0
    res = finish_command(data->helper);
259
0
    FREE_AND_NULL(data->name);
260
0
    FREE_AND_NULL(data->helper);
261
0
  }
262
0
  return res;
263
0
}
264
265
static const char *unsupported_options[] = {
266
  TRANS_OPT_UPLOADPACK,
267
  TRANS_OPT_RECEIVEPACK,
268
  TRANS_OPT_THIN,
269
  TRANS_OPT_KEEP
270
  };
271
272
static const char *boolean_options[] = {
273
  TRANS_OPT_THIN,
274
  TRANS_OPT_KEEP,
275
  TRANS_OPT_FOLLOWTAGS,
276
  TRANS_OPT_DEEPEN_RELATIVE
277
  };
278
279
static int strbuf_set_helper_option(struct helper_data *data,
280
            struct strbuf *buf)
281
0
{
282
0
  int ret;
283
284
0
  sendline(data, buf);
285
0
  if (recvline(data, buf))
286
0
    exit(128);
287
288
0
  if (!strcmp(buf->buf, "ok"))
289
0
    ret = 0;
290
0
  else if (starts_with(buf->buf, "error"))
291
0
    ret = -1;
292
0
  else if (!strcmp(buf->buf, "unsupported"))
293
0
    ret = 1;
294
0
  else {
295
0
    warning(_("%s unexpectedly said: '%s'"), data->name, buf->buf);
296
0
    ret = 1;
297
0
  }
298
0
  return ret;
299
0
}
300
301
static int string_list_set_helper_option(struct helper_data *data,
302
           const char *name,
303
           struct string_list *list)
304
0
{
305
0
  struct strbuf buf = STRBUF_INIT;
306
0
  int i, ret = 0;
307
308
0
  for (i = 0; i < list->nr; i++) {
309
0
    strbuf_addf(&buf, "option %s ", name);
310
0
    quote_c_style(list->items[i].string, &buf, NULL, 0);
311
0
    strbuf_addch(&buf, '\n');
312
313
0
    if ((ret = strbuf_set_helper_option(data, &buf)))
314
0
      break;
315
0
    strbuf_reset(&buf);
316
0
  }
317
0
  strbuf_release(&buf);
318
0
  return ret;
319
0
}
320
321
static int set_helper_option(struct transport *transport,
322
        const char *name, const char *value)
323
0
{
324
0
  struct helper_data *data = transport->data;
325
0
  struct strbuf buf = STRBUF_INIT;
326
0
  int i, ret, is_bool = 0;
327
328
0
  get_helper(transport);
329
330
0
  if (!data->option)
331
0
    return 1;
332
333
0
  if (!strcmp(name, "deepen-not"))
334
0
    return string_list_set_helper_option(data, name,
335
0
                 (struct string_list *)value);
336
337
0
  for (i = 0; i < ARRAY_SIZE(unsupported_options); i++) {
338
0
    if (!strcmp(name, unsupported_options[i]))
339
0
      return 1;
340
0
  }
341
342
0
  for (i = 0; i < ARRAY_SIZE(boolean_options); i++) {
343
0
    if (!strcmp(name, boolean_options[i])) {
344
0
      is_bool = 1;
345
0
      break;
346
0
    }
347
0
  }
348
349
0
  strbuf_addf(&buf, "option %s ", name);
350
0
  if (is_bool)
351
0
    strbuf_addstr(&buf, value ? "true" : "false");
352
0
  else
353
0
    quote_c_style(value, &buf, NULL, 0);
354
0
  strbuf_addch(&buf, '\n');
355
356
0
  ret = strbuf_set_helper_option(data, &buf);
357
0
  strbuf_release(&buf);
358
0
  return ret;
359
0
}
360
361
static void standard_options(struct transport *t)
362
0
{
363
0
  char buf[16];
364
0
  int v = t->verbose;
365
366
0
  set_helper_option(t, "progress", t->progress ? "true" : "false");
367
368
0
  xsnprintf(buf, sizeof(buf), "%d", v + 1);
369
0
  set_helper_option(t, "verbosity", buf);
370
371
0
  switch (t->family) {
372
0
  case TRANSPORT_FAMILY_ALL:
373
    /*
374
     * this is already the default,
375
     * do not break old remote helpers by setting "all" here
376
     */
377
0
    break;
378
0
  case TRANSPORT_FAMILY_IPV4:
379
0
    set_helper_option(t, "family", "ipv4");
380
0
    break;
381
0
  case TRANSPORT_FAMILY_IPV6:
382
0
    set_helper_option(t, "family", "ipv6");
383
0
    break;
384
0
  }
385
0
}
386
387
static int release_helper(struct transport *transport)
388
0
{
389
0
  int res = 0;
390
0
  struct helper_data *data = transport->data;
391
0
  refspec_clear(&data->rs);
392
0
  res = disconnect_helper(transport);
393
0
  free(transport->data);
394
0
  return res;
395
0
}
396
397
static int fetch_with_fetch(struct transport *transport,
398
          int nr_heads, struct ref **to_fetch)
399
0
{
400
0
  struct helper_data *data = transport->data;
401
0
  int i;
402
0
  struct strbuf buf = STRBUF_INIT;
403
404
0
  for (i = 0; i < nr_heads; i++) {
405
0
    const struct ref *posn = to_fetch[i];
406
0
    if (posn->status & REF_STATUS_UPTODATE)
407
0
      continue;
408
409
0
    strbuf_addf(&buf, "fetch %s %s\n",
410
0
          oid_to_hex(&posn->old_oid),
411
0
          posn->symref ? posn->symref : posn->name);
412
0
  }
413
414
0
  strbuf_addch(&buf, '\n');
415
0
  sendline(data, &buf);
416
417
0
  while (1) {
418
0
    const char *name;
419
420
0
    if (recvline(data, &buf))
421
0
      exit(128);
422
423
0
    if (skip_prefix(buf.buf, "lock ", &name)) {
424
0
      if (transport->pack_lockfiles.nr)
425
0
        warning(_("%s also locked %s"), data->name, name);
426
0
      else
427
0
        string_list_append(&transport->pack_lockfiles,
428
0
               name);
429
0
    }
430
0
    else if (data->check_connectivity &&
431
0
       data->transport_options.check_self_contained_and_connected &&
432
0
       !strcmp(buf.buf, "connectivity-ok"))
433
0
      data->transport_options.self_contained_and_connected = 1;
434
0
    else if (!buf.len)
435
0
      break;
436
0
    else
437
0
      warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf);
438
0
  }
439
0
  strbuf_release(&buf);
440
441
0
  reprepare_packed_git(the_repository);
442
0
  return 0;
443
0
}
444
445
static int get_importer(struct transport *transport, struct child_process *fastimport)
446
0
{
447
0
  struct child_process *helper = get_helper(transport);
448
0
  struct helper_data *data = transport->data;
449
0
  int cat_blob_fd, code;
450
0
  child_process_init(fastimport);
451
0
  fastimport->in = xdup(helper->out);
452
0
  strvec_push(&fastimport->args, "fast-import");
453
0
  strvec_push(&fastimport->args, "--allow-unsafe-features");
454
0
  strvec_push(&fastimport->args, debug ? "--stats" : "--quiet");
455
456
0
  if (data->bidi_import) {
457
0
    cat_blob_fd = xdup(helper->in);
458
0
    strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd);
459
0
  }
460
0
  fastimport->git_cmd = 1;
461
462
0
  code = start_command(fastimport);
463
0
  return code;
464
0
}
465
466
static int get_exporter(struct transport *transport,
467
      struct child_process *fastexport,
468
      struct string_list *revlist_args)
469
0
{
470
0
  struct helper_data *data = transport->data;
471
0
  struct child_process *helper = get_helper(transport);
472
0
  int i;
473
474
0
  child_process_init(fastexport);
475
476
  /* we need to duplicate helper->in because we want to use it after
477
   * fastexport is done with it. */
478
0
  fastexport->out = dup(helper->in);
479
0
  strvec_push(&fastexport->args, "fast-export");
480
0
  strvec_push(&fastexport->args, "--use-done-feature");
481
0
  strvec_push(&fastexport->args, data->signed_tags ?
482
0
    "--signed-tags=verbatim" : "--signed-tags=warn-strip");
483
0
  if (data->export_marks)
484
0
    strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks);
485
0
  if (data->import_marks)
486
0
    strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks);
487
488
0
  for (i = 0; i < revlist_args->nr; i++)
489
0
    strvec_push(&fastexport->args, revlist_args->items[i].string);
490
491
0
  fastexport->git_cmd = 1;
492
0
  return start_command(fastexport);
493
0
}
494
495
static int fetch_with_import(struct transport *transport,
496
           int nr_heads, struct ref **to_fetch)
497
0
{
498
0
  struct child_process fastimport;
499
0
  struct helper_data *data = transport->data;
500
0
  int i;
501
0
  struct ref *posn;
502
0
  struct strbuf buf = STRBUF_INIT;
503
504
0
  get_helper(transport);
505
506
0
  if (get_importer(transport, &fastimport))
507
0
    die(_("couldn't run fast-import"));
508
509
0
  for (i = 0; i < nr_heads; i++) {
510
0
    posn = to_fetch[i];
511
0
    if (posn->status & REF_STATUS_UPTODATE)
512
0
      continue;
513
514
0
    strbuf_addf(&buf, "import %s\n",
515
0
          posn->symref ? posn->symref : posn->name);
516
0
    sendline(data, &buf);
517
0
    strbuf_reset(&buf);
518
0
  }
519
520
0
  write_constant(data->helper->in, "\n");
521
  /*
522
   * remote-helpers that advertise the bidi-import capability are required to
523
   * buffer the complete batch of import commands until this newline before
524
   * sending data to fast-import.
525
   * These helpers read back data from fast-import on their stdin, which could
526
   * be mixed with import commands, otherwise.
527
   */
528
529
0
  if (finish_command(&fastimport))
530
0
    die(_("error while running fast-import"));
531
532
  /*
533
   * The fast-import stream of a remote helper that advertises
534
   * the "refspec" capability writes to the refs named after the
535
   * right hand side of the first refspec matching each ref we
536
   * were fetching.
537
   *
538
   * (If no "refspec" capability was specified, for historical
539
   * reasons we default to the equivalent of *:*.)
540
   *
541
   * Store the result in to_fetch[i].old_sha1.  Callers such
542
   * as "git fetch" can use the value to write feedback to the
543
   * terminal, populate FETCH_HEAD, and determine what new value
544
   * should be written to peer_ref if the update is a
545
   * fast-forward or this is a forced update.
546
   */
547
0
  for (i = 0; i < nr_heads; i++) {
548
0
    char *private, *name;
549
0
    posn = to_fetch[i];
550
0
    if (posn->status & REF_STATUS_UPTODATE)
551
0
      continue;
552
0
    name = posn->symref ? posn->symref : posn->name;
553
0
    if (data->rs.nr)
554
0
      private = apply_refspecs(&data->rs, name);
555
0
    else
556
0
      private = xstrdup(name);
557
0
    if (private) {
558
0
      if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0)
559
0
        die(_("could not read ref %s"), private);
560
0
      free(private);
561
0
    }
562
0
  }
563
0
  strbuf_release(&buf);
564
0
  return 0;
565
0
}
566
567
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
568
0
{
569
0
  struct helper_data *data = transport->data;
570
0
  int ret = 0;
571
0
  int duped;
572
0
  FILE *input;
573
0
  struct child_process *helper;
574
575
0
  helper = get_helper(transport);
576
577
  /*
578
   * Yes, dup the pipe another time, as we need unbuffered version
579
   * of input pipe as FILE*. fclose() closes the underlying fd and
580
   * stream buffering only can be changed before first I/O operation
581
   * on it.
582
   */
583
0
  duped = dup(helper->out);
584
0
  if (duped < 0)
585
0
    die_errno(_("can't dup helper output fd"));
586
0
  input = xfdopen(duped, "r");
587
0
  setvbuf(input, NULL, _IONBF, 0);
588
589
0
  sendline(data, cmdbuf);
590
0
  if (recvline_fh(input, cmdbuf))
591
0
    exit(128);
592
593
0
  if (!strcmp(cmdbuf->buf, "")) {
594
0
    data->no_disconnect_req = 1;
595
0
    if (debug)
596
0
      fprintf(stderr, "Debug: Smart transport connection "
597
0
        "ready.\n");
598
0
    ret = 1;
599
0
  } else if (!strcmp(cmdbuf->buf, "fallback")) {
600
0
    if (debug)
601
0
      fprintf(stderr, "Debug: Falling back to dumb "
602
0
        "transport.\n");
603
0
  } else {
604
0
    die(_("unknown response to connect: %s"),
605
0
        cmdbuf->buf);
606
0
  }
607
608
0
  fclose(input);
609
0
  return ret;
610
0
}
611
612
static int process_connect_service(struct transport *transport,
613
           const char *name, const char *exec)
614
0
{
615
0
  struct helper_data *data = transport->data;
616
0
  struct strbuf cmdbuf = STRBUF_INIT;
617
0
  int ret = 0;
618
619
  /*
620
   * Handle --upload-pack and friends. This is fire and forget...
621
   * just warn if it fails.
622
   */
623
0
  if (strcmp(name, exec)) {
624
0
    int r = set_helper_option(transport, "servpath", exec);
625
0
    if (r > 0)
626
0
      warning(_("setting remote service path not supported by protocol"));
627
0
    else if (r < 0)
628
0
      warning(_("invalid remote service path"));
629
0
  }
630
631
0
  if (data->connect) {
632
0
    strbuf_addf(&cmdbuf, "connect %s\n", name);
633
0
    ret = run_connect(transport, &cmdbuf);
634
0
  } else if (data->stateless_connect &&
635
0
       (get_protocol_version_config() == protocol_v2) &&
636
0
       (!strcmp("git-upload-pack", name) ||
637
0
        !strcmp("git-upload-archive", name))) {
638
0
    strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
639
0
    ret = run_connect(transport, &cmdbuf);
640
0
    if (ret)
641
0
      transport->stateless_rpc = 1;
642
0
  }
643
644
0
  strbuf_release(&cmdbuf);
645
0
  return ret;
646
0
}
647
648
static int process_connect(struct transport *transport,
649
             int for_push)
650
0
{
651
0
  struct helper_data *data = transport->data;
652
0
  const char *name;
653
0
  const char *exec;
654
0
  int ret;
655
656
0
  name = for_push ? "git-receive-pack" : "git-upload-pack";
657
0
  if (for_push)
658
0
    exec = data->transport_options.receivepack;
659
0
  else
660
0
    exec = data->transport_options.uploadpack;
661
662
0
  ret = process_connect_service(transport, name, exec);
663
0
  if (ret)
664
0
    do_take_over(transport);
665
0
  return ret;
666
0
}
667
668
static int connect_helper(struct transport *transport, const char *name,
669
       const char *exec, int fd[2])
670
0
{
671
0
  struct helper_data *data = transport->data;
672
673
  /* Get_helper so connect is inited. */
674
0
  get_helper(transport);
675
676
0
  if (!process_connect_service(transport, name, exec))
677
0
    die(_("can't connect to subservice %s"), name);
678
679
0
  fd[0] = data->helper->out;
680
0
  fd[1] = data->helper->in;
681
682
0
  do_take_over(transport);
683
0
  return 0;
684
0
}
685
686
static struct ref *get_refs_list_using_list(struct transport *transport,
687
              int for_push);
688
689
static int fetch_refs(struct transport *transport,
690
          int nr_heads, struct ref **to_fetch)
691
0
{
692
0
  struct helper_data *data = transport->data;
693
0
  int i, count;
694
695
0
  get_helper(transport);
696
697
0
  if (process_connect(transport, 0))
698
0
    return transport->vtable->fetch_refs(transport, nr_heads, to_fetch);
699
700
  /*
701
   * If we reach here, then the server, the client, and/or the transport
702
   * helper does not support protocol v2. --negotiate-only requires
703
   * protocol v2.
704
   */
705
0
  if (data->transport_options.acked_commits) {
706
0
    warning(_("--negotiate-only requires protocol v2"));
707
0
    return -1;
708
0
  }
709
710
0
  if (!data->get_refs_list_called)
711
0
    get_refs_list_using_list(transport, 0);
712
713
0
  count = 0;
714
0
  for (i = 0; i < nr_heads; i++)
715
0
    if (!(to_fetch[i]->status & REF_STATUS_UPTODATE))
716
0
      count++;
717
718
0
  if (!count)
719
0
    return 0;
720
721
0
  if (data->check_connectivity &&
722
0
      data->transport_options.check_self_contained_and_connected)
723
0
    set_helper_option(transport, "check-connectivity", "true");
724
725
0
  if (transport->cloning)
726
0
    set_helper_option(transport, "cloning", "true");
727
728
0
  if (data->transport_options.update_shallow)
729
0
    set_helper_option(transport, "update-shallow", "true");
730
731
0
  if (data->transport_options.refetch)
732
0
    set_helper_option(transport, "refetch", "true");
733
734
0
  if (data->transport_options.filter_options.choice) {
735
0
    const char *spec = expand_list_objects_filter_spec(
736
0
      &data->transport_options.filter_options);
737
0
    set_helper_option(transport, "filter", spec);
738
0
  }
739
740
0
  if (data->transport_options.negotiation_tips)
741
0
    warning("Ignoring --negotiation-tip because the protocol does not support it.");
742
743
0
  if (data->fetch)
744
0
    return fetch_with_fetch(transport, nr_heads, to_fetch);
745
746
0
  if (data->import)
747
0
    return fetch_with_import(transport, nr_heads, to_fetch);
748
749
0
  return -1;
750
0
}
751
752
struct push_update_ref_state {
753
  struct ref *hint;
754
  struct ref_push_report *report;
755
  int new_report;
756
};
757
758
static int push_update_ref_status(struct strbuf *buf,
759
           struct push_update_ref_state *state,
760
           struct ref *remote_refs)
761
0
{
762
0
  char *refname, *msg;
763
0
  int status, forced = 0;
764
765
0
  if (starts_with(buf->buf, "option ")) {
766
0
    struct object_id old_oid, new_oid;
767
0
    const char *key, *val;
768
0
    char *p;
769
770
0
    if (!state->hint || !(state->report || state->new_report))
771
0
      die(_("'option' without a matching 'ok/error' directive"));
772
0
    if (state->new_report) {
773
0
      if (!state->hint->report) {
774
0
        CALLOC_ARRAY(state->hint->report, 1);
775
0
        state->report = state->hint->report;
776
0
      } else {
777
0
        state->report = state->hint->report;
778
0
        while (state->report->next)
779
0
          state->report = state->report->next;
780
0
        CALLOC_ARRAY(state->report->next, 1);
781
0
        state->report = state->report->next;
782
0
      }
783
0
      state->new_report = 0;
784
0
    }
785
0
    key = buf->buf + 7;
786
0
    p = strchr(key, ' ');
787
0
    if (p)
788
0
      *p++ = '\0';
789
0
    val = p;
790
0
    if (!strcmp(key, "refname"))
791
0
      state->report->ref_name = xstrdup_or_null(val);
792
0
    else if (!strcmp(key, "old-oid") && val &&
793
0
       !parse_oid_hex(val, &old_oid, &val))
794
0
      state->report->old_oid = oiddup(&old_oid);
795
0
    else if (!strcmp(key, "new-oid") && val &&
796
0
       !parse_oid_hex(val, &new_oid, &val))
797
0
      state->report->new_oid = oiddup(&new_oid);
798
0
    else if (!strcmp(key, "forced-update"))
799
0
      state->report->forced_update = 1;
800
    /* Not update remote namespace again. */
801
0
    return 1;
802
0
  }
803
804
0
  state->report = NULL;
805
0
  state->new_report = 0;
806
807
0
  if (starts_with(buf->buf, "ok ")) {
808
0
    status = REF_STATUS_OK;
809
0
    refname = buf->buf + 3;
810
0
  } else if (starts_with(buf->buf, "error ")) {
811
0
    status = REF_STATUS_REMOTE_REJECT;
812
0
    refname = buf->buf + 6;
813
0
  } else
814
0
    die(_("expected ok/error, helper said '%s'"), buf->buf);
815
816
0
  msg = strchr(refname, ' ');
817
0
  if (msg) {
818
0
    struct strbuf msg_buf = STRBUF_INIT;
819
0
    const char *end;
820
821
0
    *msg++ = '\0';
822
0
    if (!unquote_c_style(&msg_buf, msg, &end))
823
0
      msg = strbuf_detach(&msg_buf, NULL);
824
0
    else
825
0
      msg = xstrdup(msg);
826
0
    strbuf_release(&msg_buf);
827
828
0
    if (!strcmp(msg, "no match")) {
829
0
      status = REF_STATUS_NONE;
830
0
      FREE_AND_NULL(msg);
831
0
    }
832
0
    else if (!strcmp(msg, "up to date")) {
833
0
      status = REF_STATUS_UPTODATE;
834
0
      FREE_AND_NULL(msg);
835
0
    }
836
0
    else if (!strcmp(msg, "non-fast forward")) {
837
0
      status = REF_STATUS_REJECT_NONFASTFORWARD;
838
0
      FREE_AND_NULL(msg);
839
0
    }
840
0
    else if (!strcmp(msg, "already exists")) {
841
0
      status = REF_STATUS_REJECT_ALREADY_EXISTS;
842
0
      FREE_AND_NULL(msg);
843
0
    }
844
0
    else if (!strcmp(msg, "fetch first")) {
845
0
      status = REF_STATUS_REJECT_FETCH_FIRST;
846
0
      FREE_AND_NULL(msg);
847
0
    }
848
0
    else if (!strcmp(msg, "needs force")) {
849
0
      status = REF_STATUS_REJECT_NEEDS_FORCE;
850
0
      FREE_AND_NULL(msg);
851
0
    }
852
0
    else if (!strcmp(msg, "stale info")) {
853
0
      status = REF_STATUS_REJECT_STALE;
854
0
      FREE_AND_NULL(msg);
855
0
    }
856
0
    else if (!strcmp(msg, "remote ref updated since checkout")) {
857
0
      status = REF_STATUS_REJECT_REMOTE_UPDATED;
858
0
      FREE_AND_NULL(msg);
859
0
    }
860
0
    else if (!strcmp(msg, "forced update")) {
861
0
      forced = 1;
862
0
      FREE_AND_NULL(msg);
863
0
    }
864
0
    else if (!strcmp(msg, "expecting report")) {
865
0
      status = REF_STATUS_EXPECTING_REPORT;
866
0
      FREE_AND_NULL(msg);
867
0
    }
868
0
  }
869
870
0
  if (state->hint)
871
0
    state->hint = find_ref_by_name(state->hint, refname);
872
0
  if (!state->hint)
873
0
    state->hint = find_ref_by_name(remote_refs, refname);
874
0
  if (!state->hint) {
875
0
    warning(_("helper reported unexpected status of %s"), refname);
876
0
    return 1;
877
0
  }
878
879
0
  if (state->hint->status != REF_STATUS_NONE) {
880
    /*
881
     * Earlier, the ref was marked not to be pushed, so ignore the ref
882
     * status reported by the remote helper if the latter is 'no match'.
883
     */
884
0
    if (status == REF_STATUS_NONE)
885
0
      return 1;
886
0
  }
887
888
0
  if (status == REF_STATUS_OK)
889
0
    state->new_report = 1;
890
0
  state->hint->status = status;
891
0
  state->hint->forced_update |= forced;
892
0
  state->hint->remote_status = msg;
893
0
  return !(status == REF_STATUS_OK);
894
0
}
895
896
static int push_update_refs_status(struct helper_data *data,
897
            struct ref *remote_refs,
898
            int flags)
899
0
{
900
0
  struct ref *ref;
901
0
  struct ref_push_report *report;
902
0
  struct strbuf buf = STRBUF_INIT;
903
0
  struct push_update_ref_state state = { remote_refs, NULL, 0 };
904
905
0
  for (;;) {
906
0
    if (recvline(data, &buf)) {
907
0
      strbuf_release(&buf);
908
0
      return 1;
909
0
    }
910
0
    if (!buf.len)
911
0
      break;
912
0
    push_update_ref_status(&buf, &state, remote_refs);
913
0
  }
914
0
  strbuf_release(&buf);
915
916
0
  if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
917
0
    return 0;
918
919
  /* propagate back the update to the remote namespace */
920
0
  for (ref = remote_refs; ref; ref = ref->next) {
921
0
    char *private;
922
923
0
    if (ref->status != REF_STATUS_OK)
924
0
      continue;
925
926
0
    if (!ref->report) {
927
0
      private = apply_refspecs(&data->rs, ref->name);
928
0
      if (!private)
929
0
        continue;
930
0
      refs_update_ref(get_main_ref_store(the_repository),
931
0
          "update by helper", private,
932
0
          &(ref->new_oid),
933
0
          NULL, 0, 0);
934
0
      free(private);
935
0
    } else {
936
0
      for (report = ref->report; report; report = report->next) {
937
0
        private = apply_refspecs(&data->rs,
938
0
               report->ref_name
939
0
               ? report->ref_name
940
0
               : ref->name);
941
0
        if (!private)
942
0
          continue;
943
0
        refs_update_ref(get_main_ref_store(the_repository),
944
0
            "update by helper", private,
945
0
            report->new_oid
946
0
            ? report->new_oid
947
0
            : &(ref->new_oid),
948
0
            NULL, 0, 0);
949
0
        free(private);
950
0
      }
951
0
    }
952
0
  }
953
0
  return 0;
954
0
}
955
956
static void set_common_push_options(struct transport *transport,
957
           const char *name, int flags)
958
0
{
959
0
  if (flags & TRANSPORT_PUSH_DRY_RUN) {
960
0
    if (set_helper_option(transport, "dry-run", "true") != 0)
961
0
      die(_("helper %s does not support dry-run"), name);
962
0
  } else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) {
963
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0)
964
0
      die(_("helper %s does not support --signed"), name);
965
0
  } else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) {
966
0
    if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0)
967
0
      die(_("helper %s does not support --signed=if-asked"), name);
968
0
  }
969
970
0
  if (flags & TRANSPORT_PUSH_ATOMIC)
971
0
    if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0)
972
0
      die(_("helper %s does not support --atomic"), name);
973
974
0
  if (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES)
975
0
    if (set_helper_option(transport, TRANS_OPT_FORCE_IF_INCLUDES, "true") != 0)
976
0
      die(_("helper %s does not support --%s"),
977
0
          name, TRANS_OPT_FORCE_IF_INCLUDES);
978
979
0
  if (flags & TRANSPORT_PUSH_OPTIONS) {
980
0
    struct string_list_item *item;
981
0
    for_each_string_list_item(item, transport->push_options)
982
0
      if (set_helper_option(transport, "push-option", item->string) != 0)
983
0
        die(_("helper %s does not support 'push-option'"), name);
984
0
  }
985
0
}
986
987
static int push_refs_with_push(struct transport *transport,
988
             struct ref *remote_refs, int flags)
989
0
{
990
0
  int force_all = flags & TRANSPORT_PUSH_FORCE;
991
0
  int mirror = flags & TRANSPORT_PUSH_MIRROR;
992
0
  int atomic = flags & TRANSPORT_PUSH_ATOMIC;
993
0
  struct helper_data *data = transport->data;
994
0
  struct strbuf buf = STRBUF_INIT;
995
0
  struct ref *ref;
996
0
  struct string_list cas_options = STRING_LIST_INIT_DUP;
997
0
  struct string_list_item *cas_option;
998
999
0
  get_helper(transport);
1000
0
  if (!data->push)
1001
0
    return 1;
1002
1003
0
  for (ref = remote_refs; ref; ref = ref->next) {
1004
0
    if (!ref->peer_ref && !mirror)
1005
0
      continue;
1006
1007
    /* Check for statuses set by set_ref_status_for_push() */
1008
0
    switch (ref->status) {
1009
0
    case REF_STATUS_REJECT_NONFASTFORWARD:
1010
0
    case REF_STATUS_REJECT_STALE:
1011
0
    case REF_STATUS_REJECT_ALREADY_EXISTS:
1012
0
    case REF_STATUS_REJECT_REMOTE_UPDATED:
1013
0
      if (atomic) {
1014
0
        reject_atomic_push(remote_refs, mirror);
1015
0
        string_list_clear(&cas_options, 0);
1016
0
        return 0;
1017
0
      } else
1018
0
        continue;
1019
0
    case REF_STATUS_UPTODATE:
1020
0
      continue;
1021
0
    default:
1022
0
      ; /* do nothing */
1023
0
    }
1024
1025
0
    if (force_all)
1026
0
      ref->force = 1;
1027
1028
0
    strbuf_addstr(&buf, "push ");
1029
0
    if (!ref->deletion) {
1030
0
      if (ref->force)
1031
0
        strbuf_addch(&buf, '+');
1032
0
      if (ref->peer_ref)
1033
0
        strbuf_addstr(&buf, ref->peer_ref->name);
1034
0
      else
1035
0
        strbuf_addstr(&buf, oid_to_hex(&ref->new_oid));
1036
0
    }
1037
0
    strbuf_addch(&buf, ':');
1038
0
    strbuf_addstr(&buf, ref->name);
1039
0
    strbuf_addch(&buf, '\n');
1040
1041
    /*
1042
     * The "--force-with-lease" options without explicit
1043
     * values to expect have already been expanded into
1044
     * the ref->old_oid_expect[] field; we can ignore
1045
     * transport->smart_options->cas altogether and instead
1046
     * can enumerate them from the refs.
1047
     */
1048
0
    if (ref->expect_old_sha1) {
1049
0
      struct strbuf cas = STRBUF_INIT;
1050
0
      strbuf_addf(&cas, "%s:%s",
1051
0
            ref->name, oid_to_hex(&ref->old_oid_expect));
1052
0
      string_list_append_nodup(&cas_options,
1053
0
             strbuf_detach(&cas, NULL));
1054
0
    }
1055
0
  }
1056
0
  if (buf.len == 0) {
1057
0
    string_list_clear(&cas_options, 0);
1058
0
    return 0;
1059
0
  }
1060
1061
0
  for_each_string_list_item(cas_option, &cas_options)
1062
0
    set_helper_option(transport, "cas", cas_option->string);
1063
0
  set_common_push_options(transport, data->name, flags);
1064
1065
0
  strbuf_addch(&buf, '\n');
1066
0
  sendline(data, &buf);
1067
0
  strbuf_release(&buf);
1068
0
  string_list_clear(&cas_options, 0);
1069
1070
0
  return push_update_refs_status(data, remote_refs, flags);
1071
0
}
1072
1073
static int push_refs_with_export(struct transport *transport,
1074
    struct ref *remote_refs, int flags)
1075
0
{
1076
0
  struct ref *ref;
1077
0
  struct child_process *helper, exporter;
1078
0
  struct helper_data *data = transport->data;
1079
0
  struct string_list revlist_args = STRING_LIST_INIT_DUP;
1080
0
  struct strbuf buf = STRBUF_INIT;
1081
1082
0
  if (!data->rs.nr)
1083
0
    die(_("remote-helper doesn't support push; refspec needed"));
1084
1085
0
  set_common_push_options(transport, data->name, flags);
1086
0
  if (flags & TRANSPORT_PUSH_FORCE) {
1087
0
    if (set_helper_option(transport, "force", "true") != 0)
1088
0
      warning(_("helper %s does not support '--force'"), data->name);
1089
0
  }
1090
1091
0
  helper = get_helper(transport);
1092
1093
0
  write_constant(helper->in, "export\n");
1094
1095
0
  for (ref = remote_refs; ref; ref = ref->next) {
1096
0
    char *private;
1097
0
    struct object_id oid;
1098
1099
0
    private = apply_refspecs(&data->rs, ref->name);
1100
0
    if (private && !repo_get_oid(the_repository, private, &oid)) {
1101
0
      strbuf_addf(&buf, "^%s", private);
1102
0
      string_list_append_nodup(&revlist_args,
1103
0
             strbuf_detach(&buf, NULL));
1104
0
      oidcpy(&ref->old_oid, &oid);
1105
0
    }
1106
0
    free(private);
1107
1108
0
    if (ref->peer_ref) {
1109
0
      if (strcmp(ref->name, ref->peer_ref->name)) {
1110
0
        if (!ref->deletion) {
1111
0
          const char *name;
1112
0
          int flag;
1113
1114
          /* Follow symbolic refs (mainly for HEAD). */
1115
0
          name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
1116
0
                       ref->peer_ref->name,
1117
0
                       RESOLVE_REF_READING,
1118
0
                       &oid,
1119
0
                       &flag);
1120
0
          if (!name || !(flag & REF_ISSYMREF))
1121
0
            name = ref->peer_ref->name;
1122
1123
0
          strbuf_addf(&buf, "%s:%s", name, ref->name);
1124
0
        } else
1125
0
          strbuf_addf(&buf, ":%s", ref->name);
1126
1127
0
        string_list_append(&revlist_args, "--refspec");
1128
0
        string_list_append(&revlist_args, buf.buf);
1129
0
        strbuf_release(&buf);
1130
0
      }
1131
0
      if (!ref->deletion)
1132
0
        string_list_append(&revlist_args, ref->peer_ref->name);
1133
0
    }
1134
0
  }
1135
1136
0
  if (get_exporter(transport, &exporter, &revlist_args))
1137
0
    die(_("couldn't run fast-export"));
1138
1139
0
  string_list_clear(&revlist_args, 1);
1140
1141
0
  if (finish_command(&exporter))
1142
0
    die(_("error while running fast-export"));
1143
0
  if (push_update_refs_status(data, remote_refs, flags))
1144
0
    return 1;
1145
1146
0
  if (data->export_marks) {
1147
0
    strbuf_addf(&buf, "%s.tmp", data->export_marks);
1148
0
    rename(buf.buf, data->export_marks);
1149
0
    strbuf_release(&buf);
1150
0
  }
1151
1152
0
  return 0;
1153
0
}
1154
1155
static int push_refs(struct transport *transport,
1156
    struct ref *remote_refs, int flags)
1157
0
{
1158
0
  struct helper_data *data = transport->data;
1159
1160
0
  if (process_connect(transport, 1))
1161
0
    return transport->vtable->push_refs(transport, remote_refs, flags);
1162
1163
0
  if (!remote_refs) {
1164
0
    fprintf(stderr,
1165
0
      _("No refs in common and none specified; doing nothing.\n"
1166
0
        "Perhaps you should specify a branch.\n"));
1167
0
    return 0;
1168
0
  }
1169
1170
0
  if (data->push)
1171
0
    return push_refs_with_push(transport, remote_refs, flags);
1172
1173
0
  if (data->export)
1174
0
    return push_refs_with_export(transport, remote_refs, flags);
1175
1176
0
  return -1;
1177
0
}
1178
1179
1180
static int has_attribute(const char *attrs, const char *attr)
1181
0
{
1182
0
  int len;
1183
0
  if (!attrs)
1184
0
    return 0;
1185
1186
0
  len = strlen(attr);
1187
0
  for (;;) {
1188
0
    const char *space = strchrnul(attrs, ' ');
1189
0
    if (len == space - attrs && !strncmp(attrs, attr, len))
1190
0
      return 1;
1191
0
    if (!*space)
1192
0
      return 0;
1193
0
    attrs = space + 1;
1194
0
  }
1195
0
}
1196
1197
static struct ref *get_refs_list(struct transport *transport, int for_push,
1198
         struct transport_ls_refs_options *transport_options)
1199
0
{
1200
0
  get_helper(transport);
1201
1202
0
  if (process_connect(transport, for_push))
1203
0
    return transport->vtable->get_refs_list(transport, for_push,
1204
0
              transport_options);
1205
1206
0
  return get_refs_list_using_list(transport, for_push);
1207
0
}
1208
1209
static struct ref *get_refs_list_using_list(struct transport *transport,
1210
              int for_push)
1211
0
{
1212
0
  struct helper_data *data = transport->data;
1213
0
  struct child_process *helper;
1214
0
  struct ref *ret = NULL;
1215
0
  struct ref **tail = &ret;
1216
0
  struct ref *posn;
1217
0
  struct strbuf buf = STRBUF_INIT;
1218
1219
0
  data->get_refs_list_called = 1;
1220
0
  helper = get_helper(transport);
1221
1222
0
  if (data->object_format)
1223
0
    set_helper_option(transport, "object-format", "true");
1224
1225
0
  if (data->push && for_push)
1226
0
    write_constant(helper->in, "list for-push\n");
1227
0
  else
1228
0
    write_constant(helper->in, "list\n");
1229
1230
0
  while (1) {
1231
0
    char *eov, *eon;
1232
0
    if (recvline(data, &buf))
1233
0
      exit(128);
1234
1235
0
    if (!*buf.buf)
1236
0
      break;
1237
0
    else if (buf.buf[0] == ':') {
1238
0
      const char *value;
1239
0
      if (skip_prefix(buf.buf, ":object-format ", &value)) {
1240
0
        int algo = hash_algo_by_name(value);
1241
0
        if (algo == GIT_HASH_UNKNOWN)
1242
0
          die(_("unsupported object format '%s'"),
1243
0
              value);
1244
0
        transport->hash_algo = &hash_algos[algo];
1245
0
      }
1246
0
      continue;
1247
0
    }
1248
1249
0
    eov = strchr(buf.buf, ' ');
1250
0
    if (!eov)
1251
0
      die(_("malformed response in ref list: %s"), buf.buf);
1252
0
    eon = strchr(eov + 1, ' ');
1253
0
    *eov = '\0';
1254
0
    if (eon)
1255
0
      *eon = '\0';
1256
0
    *tail = alloc_ref(eov + 1);
1257
0
    if (buf.buf[0] == '@')
1258
0
      (*tail)->symref = xstrdup(buf.buf + 1);
1259
0
    else if (buf.buf[0] != '?')
1260
0
      get_oid_hex_algop(buf.buf, &(*tail)->old_oid, transport->hash_algo);
1261
0
    if (eon) {
1262
0
      if (has_attribute(eon + 1, "unchanged")) {
1263
0
        (*tail)->status |= REF_STATUS_UPTODATE;
1264
0
        if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0)
1265
0
          die(_("could not read ref %s"),
1266
0
              (*tail)->name);
1267
0
      }
1268
0
    }
1269
0
    tail = &((*tail)->next);
1270
0
  }
1271
0
  if (debug)
1272
0
    fprintf(stderr, "Debug: Read ref listing.\n");
1273
0
  strbuf_release(&buf);
1274
1275
0
  for (posn = ret; posn; posn = posn->next)
1276
0
    resolve_remote_symref(posn, ret);
1277
1278
0
  return ret;
1279
0
}
1280
1281
static int get_bundle_uri(struct transport *transport)
1282
0
{
1283
0
  get_helper(transport);
1284
1285
0
  if (process_connect(transport, 0))
1286
0
    return transport->vtable->get_bundle_uri(transport);
1287
1288
0
  return -1;
1289
0
}
1290
1291
static struct transport_vtable vtable = {
1292
  .set_option = set_helper_option,
1293
  .get_refs_list  = get_refs_list,
1294
  .get_bundle_uri = get_bundle_uri,
1295
  .fetch_refs = fetch_refs,
1296
  .push_refs  = push_refs,
1297
  .connect  = connect_helper,
1298
  .disconnect = release_helper
1299
};
1300
1301
int transport_helper_init(struct transport *transport, const char *name)
1302
0
{
1303
0
  struct helper_data *data = xcalloc(1, sizeof(*data));
1304
0
  data->name = xstrdup(name);
1305
1306
0
  transport_check_allowed(name);
1307
1308
0
  if (getenv("GIT_TRANSPORT_HELPER_DEBUG"))
1309
0
    debug = 1;
1310
1311
0
  list_objects_filter_init(&data->transport_options.filter_options);
1312
1313
0
  transport->data = data;
1314
0
  transport->vtable = &vtable;
1315
0
  transport->smart_options = &(data->transport_options);
1316
0
  return 0;
1317
0
}
1318
1319
/*
1320
 * Linux pipes can buffer 65536 bytes at once (and most platforms can
1321
 * buffer less), so attempt reads and writes with up to that size.
1322
 */
1323
0
#define BUFFERSIZE 65536
1324
/* This should be enough to hold debugging message. */
1325
0
#define PBUFFERSIZE 8192
1326
1327
/* Print bidirectional transfer loop debug message. */
1328
__attribute__((format (printf, 1, 2)))
1329
static void transfer_debug(const char *fmt, ...)
1330
0
{
1331
  /*
1332
   * NEEDSWORK: This function is sometimes used from multiple threads, and
1333
   * we end up using debug_enabled racily. That "should not matter" since
1334
   * we always write the same value, but it's still wrong. This function
1335
   * is listed in .tsan-suppressions for the time being.
1336
   */
1337
1338
0
  va_list args;
1339
0
  char msgbuf[PBUFFERSIZE];
1340
0
  static int debug_enabled = -1;
1341
1342
0
  if (debug_enabled < 0)
1343
0
    debug_enabled = getenv("GIT_TRANSLOOP_DEBUG") ? 1 : 0;
1344
0
  if (!debug_enabled)
1345
0
    return;
1346
1347
0
  va_start(args, fmt);
1348
0
  vsnprintf(msgbuf, PBUFFERSIZE, fmt, args);
1349
0
  va_end(args);
1350
0
  fprintf(stderr, "Transfer loop debugging: %s\n", msgbuf);
1351
0
}
1352
1353
/* Stream state: More data may be coming in this direction. */
1354
0
#define SSTATE_TRANSFERRING 0
1355
/*
1356
 * Stream state: No more data coming in this direction, flushing rest of
1357
 * data.
1358
 */
1359
0
#define SSTATE_FLUSHING 1
1360
/* Stream state: Transfer in this direction finished. */
1361
0
#define SSTATE_FINISHED 2
1362
1363
0
#define STATE_NEEDS_READING(state) ((state) <= SSTATE_TRANSFERRING)
1364
0
#define STATE_NEEDS_WRITING(state) ((state) <= SSTATE_FLUSHING)
1365
0
#define STATE_NEEDS_CLOSING(state) ((state) == SSTATE_FLUSHING)
1366
1367
/* Unidirectional transfer. */
1368
struct unidirectional_transfer {
1369
  /* Source */
1370
  int src;
1371
  /* Destination */
1372
  int dest;
1373
  /* Is source socket? */
1374
  int src_is_sock;
1375
  /* Is destination socket? */
1376
  int dest_is_sock;
1377
  /* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */
1378
  int state;
1379
  /* Buffer. */
1380
  char buf[BUFFERSIZE];
1381
  /* Buffer used. */
1382
  size_t bufuse;
1383
  /* Name of source. */
1384
  const char *src_name;
1385
  /* Name of destination. */
1386
  const char *dest_name;
1387
};
1388
1389
/* Closes the target (for writing) if transfer has finished. */
1390
static void udt_close_if_finished(struct unidirectional_transfer *t)
1391
0
{
1392
0
  if (STATE_NEEDS_CLOSING(t->state) && !t->bufuse) {
1393
0
    t->state = SSTATE_FINISHED;
1394
0
    if (t->dest_is_sock)
1395
0
      shutdown(t->dest, SHUT_WR);
1396
0
    else
1397
0
      close(t->dest);
1398
0
    transfer_debug("Closed %s.", t->dest_name);
1399
0
  }
1400
0
}
1401
1402
/*
1403
 * Tries to read data from source into buffer. If buffer is full,
1404
 * no data is read. Returns 0 on success, -1 on error.
1405
 */
1406
static int udt_do_read(struct unidirectional_transfer *t)
1407
0
{
1408
0
  ssize_t bytes;
1409
1410
0
  if (t->bufuse == BUFFERSIZE)
1411
0
    return 0; /* No space for more. */
1412
1413
0
  transfer_debug("%s is readable", t->src_name);
1414
0
  bytes = xread(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse);
1415
0
  if (bytes < 0) {
1416
0
    error_errno(_("read(%s) failed"), t->src_name);
1417
0
    return -1;
1418
0
  } else if (bytes == 0) {
1419
0
    transfer_debug("%s EOF (with %i bytes in buffer)",
1420
0
      t->src_name, (int)t->bufuse);
1421
0
    t->state = SSTATE_FLUSHING;
1422
0
  } else if (bytes > 0) {
1423
0
    t->bufuse += bytes;
1424
0
    transfer_debug("Read %i bytes from %s (buffer now at %i)",
1425
0
      (int)bytes, t->src_name, (int)t->bufuse);
1426
0
  }
1427
0
  return 0;
1428
0
}
1429
1430
/* Tries to write data from buffer into destination. If buffer is empty,
1431
 * no data is written. Returns 0 on success, -1 on error.
1432
 */
1433
static int udt_do_write(struct unidirectional_transfer *t)
1434
0
{
1435
0
  ssize_t bytes;
1436
1437
0
  if (t->bufuse == 0)
1438
0
    return 0; /* Nothing to write. */
1439
1440
0
  transfer_debug("%s is writable", t->dest_name);
1441
0
  bytes = xwrite(t->dest, t->buf, t->bufuse);
1442
0
  if (bytes < 0) {
1443
0
    error_errno(_("write(%s) failed"), t->dest_name);
1444
0
    return -1;
1445
0
  } else if (bytes > 0) {
1446
0
    t->bufuse -= bytes;
1447
0
    if (t->bufuse)
1448
0
      memmove(t->buf, t->buf + bytes, t->bufuse);
1449
0
    transfer_debug("Wrote %i bytes to %s (buffer now at %i)",
1450
0
      (int)bytes, t->dest_name, (int)t->bufuse);
1451
0
  }
1452
0
  return 0;
1453
0
}
1454
1455
1456
/* State of bidirectional transfer loop. */
1457
struct bidirectional_transfer_state {
1458
  /* Direction from program to git. */
1459
  struct unidirectional_transfer ptg;
1460
  /* Direction from git to program. */
1461
  struct unidirectional_transfer gtp;
1462
};
1463
1464
static void *udt_copy_task_routine(void *udt)
1465
0
{
1466
0
  struct unidirectional_transfer *t = (struct unidirectional_transfer *)udt;
1467
0
  while (t->state != SSTATE_FINISHED) {
1468
0
    if (STATE_NEEDS_READING(t->state))
1469
0
      if (udt_do_read(t))
1470
0
        return NULL;
1471
0
    if (STATE_NEEDS_WRITING(t->state))
1472
0
      if (udt_do_write(t))
1473
0
        return NULL;
1474
0
    if (STATE_NEEDS_CLOSING(t->state))
1475
0
      udt_close_if_finished(t);
1476
0
  }
1477
0
  return udt; /* Just some non-NULL value. */
1478
0
}
1479
1480
#ifndef NO_PTHREADS
1481
1482
/*
1483
 * Join thread, with appropriate errors on failure. Name is name for the
1484
 * thread (for error messages). Returns 0 on success, 1 on failure.
1485
 */
1486
static int tloop_join(pthread_t thread, const char *name)
1487
0
{
1488
0
  int err;
1489
0
  void *tret;
1490
0
  err = pthread_join(thread, &tret);
1491
0
  if (!tret) {
1492
0
    error(_("%s thread failed"), name);
1493
0
    return 1;
1494
0
  }
1495
0
  if (err) {
1496
0
    error(_("%s thread failed to join: %s"), name, strerror(err));
1497
0
    return 1;
1498
0
  }
1499
0
  return 0;
1500
0
}
1501
1502
/*
1503
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1504
 * -1 on failure.
1505
 */
1506
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1507
0
{
1508
0
  pthread_t gtp_thread;
1509
0
  pthread_t ptg_thread;
1510
0
  int err;
1511
0
  int ret = 0;
1512
0
  err = pthread_create(&gtp_thread, NULL, udt_copy_task_routine,
1513
0
    &s->gtp);
1514
0
  if (err)
1515
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1516
0
  err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine,
1517
0
    &s->ptg);
1518
0
  if (err)
1519
0
    die(_("can't start thread for copying data: %s"), strerror(err));
1520
1521
0
  ret |= tloop_join(gtp_thread, "Git to program copy");
1522
0
  ret |= tloop_join(ptg_thread, "Program to git copy");
1523
0
  return ret;
1524
0
}
1525
#else
1526
1527
/* Close the source and target (for writing) for transfer. */
1528
static void udt_kill_transfer(struct unidirectional_transfer *t)
1529
{
1530
  t->state = SSTATE_FINISHED;
1531
  /*
1532
   * Socket read end left open isn't a disaster if nobody
1533
   * attempts to read from it (mingw compat headers do not
1534
   * have SHUT_RD)...
1535
   *
1536
   * We can't fully close the socket since otherwise gtp
1537
   * task would first close the socket it sends data to
1538
   * while closing the ptg file descriptors.
1539
   */
1540
  if (!t->src_is_sock)
1541
    close(t->src);
1542
  if (t->dest_is_sock)
1543
    shutdown(t->dest, SHUT_WR);
1544
  else
1545
    close(t->dest);
1546
}
1547
1548
/*
1549
 * Join process, with appropriate errors on failure. Name is name for the
1550
 * process (for error messages). Returns 0 on success, 1 on failure.
1551
 */
1552
static int tloop_join(pid_t pid, const char *name)
1553
{
1554
  int tret;
1555
  if (waitpid(pid, &tret, 0) < 0) {
1556
    error_errno(_("%s process failed to wait"), name);
1557
    return 1;
1558
  }
1559
  if (!WIFEXITED(tret) || WEXITSTATUS(tret)) {
1560
    error(_("%s process failed"), name);
1561
    return 1;
1562
  }
1563
  return 0;
1564
}
1565
1566
/*
1567
 * Spawn the transfer tasks and then wait for them. Returns 0 on success,
1568
 * -1 on failure.
1569
 */
1570
static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s)
1571
{
1572
  pid_t pid1, pid2;
1573
  int ret = 0;
1574
1575
  /* Fork thread #1: git to program. */
1576
  pid1 = fork();
1577
  if (pid1 < 0)
1578
    die_errno(_("can't start thread for copying data"));
1579
  else if (pid1 == 0) {
1580
    udt_kill_transfer(&s->ptg);
1581
    exit(udt_copy_task_routine(&s->gtp) ? 0 : 1);
1582
  }
1583
1584
  /* Fork thread #2: program to git. */
1585
  pid2 = fork();
1586
  if (pid2 < 0)
1587
    die_errno(_("can't start thread for copying data"));
1588
  else if (pid2 == 0) {
1589
    udt_kill_transfer(&s->gtp);
1590
    exit(udt_copy_task_routine(&s->ptg) ? 0 : 1);
1591
  }
1592
1593
  /*
1594
   * Close both streams in parent as to not interfere with
1595
   * end of file detection and wait for both tasks to finish.
1596
   */
1597
  udt_kill_transfer(&s->gtp);
1598
  udt_kill_transfer(&s->ptg);
1599
  ret |= tloop_join(pid1, "Git to program copy");
1600
  ret |= tloop_join(pid2, "Program to git copy");
1601
  return ret;
1602
}
1603
#endif
1604
1605
/*
1606
 * Copies data from stdin to output and from input to stdout simultaneously.
1607
 * Additionally filtering through given filter. If filter is NULL, uses
1608
 * identity filter.
1609
 */
1610
int bidirectional_transfer_loop(int input, int output)
1611
0
{
1612
0
  struct bidirectional_transfer_state state;
1613
1614
  /* Fill the state fields. */
1615
0
  state.ptg.src = input;
1616
0
  state.ptg.dest = 1;
1617
0
  state.ptg.src_is_sock = (input == output);
1618
0
  state.ptg.dest_is_sock = 0;
1619
0
  state.ptg.state = SSTATE_TRANSFERRING;
1620
0
  state.ptg.bufuse = 0;
1621
0
  state.ptg.src_name = "remote input";
1622
0
  state.ptg.dest_name = "stdout";
1623
1624
0
  state.gtp.src = 0;
1625
0
  state.gtp.dest = output;
1626
0
  state.gtp.src_is_sock = 0;
1627
0
  state.gtp.dest_is_sock = (input == output);
1628
0
  state.gtp.state = SSTATE_TRANSFERRING;
1629
0
  state.gtp.bufuse = 0;
1630
0
  state.gtp.src_name = "stdin";
1631
0
  state.gtp.dest_name = "remote output";
1632
1633
0
  return tloop_spawnwait_tasks(&state);
1634
0
}
1635
1636
void reject_atomic_push(struct ref *remote_refs, int mirror_mode)
1637
0
{
1638
0
  struct ref *ref;
1639
1640
  /* Mark other refs as failed */
1641
0
  for (ref = remote_refs; ref; ref = ref->next) {
1642
0
    if (!ref->peer_ref && !mirror_mode)
1643
0
      continue;
1644
1645
0
    switch (ref->status) {
1646
0
    case REF_STATUS_NONE:
1647
0
    case REF_STATUS_OK:
1648
0
    case REF_STATUS_EXPECTING_REPORT:
1649
0
      ref->status = REF_STATUS_ATOMIC_PUSH_FAILED;
1650
0
      continue;
1651
0
    default:
1652
0
      break; /* do nothing */
1653
0
    }
1654
0
  }
1655
0
  return;
1656
0
}