Ejemplo n.º 1
0
/* Lazily create backing packfile for the state */
static void prepare_to_stream(struct bulk_checkin_state *state,
			      unsigned flags)
{
	if (!(flags & HASH_WRITE_OBJECT) || state->f)
		return;

	state->f = create_tmp_packfile(&state->pack_tmp_name);
	reset_pack_idx_option(&state->pack_idx_opts);

	/* Pretend we are going to write only one object */
	state->offset = write_pack_header(state->f, 1);
	if (!state->offset)
		die_errno("unable to write pack header");
}
Ejemplo n.º 2
0
/*
 * Extract data and output it as PS
 *
 * Returns 0 if all went well, 1 if something went wrong.
 */
static int extract_data(int      input,
                        FILE    *output,
                        uint16_t program_number,
                        int      max,
                        int      verbose,
                        int      quiet)
{
  int           err;
  PES_reader_p  reader;

  err = build_PES_reader(input,TRUE,!quiet,!quiet,program_number,&reader);
  if (err)
  {
    print_err("### Error building PES reader over input file\n");
    return 1;
  }

  // Temporarily, just writes out PES packets, not a PS stream...
  for (;;)
  {
    size_t count;
    err = read_next_PES_packet(reader);
    if (err == EOF)
      break;
    else if (err)
    {
      print_err("### Error reading next PES packet\n");
      (void) free_PES_reader(&reader);
      return 1;
    }
    err = write_pack_header(output);
    if (err)
    {
      print_err("### Error writing PS pack header\n");
      (void) free_PES_reader(&reader);
      return 1;
    }
    // It is possible that the TS data for video might have specified a zero
    // length in the PES. Our TS reader will have read all of the packet for
    // us, but will not have "adjusted" said length at the start of the packet.
    // It is thus up to us to catch this case and amend it before we output
    // the data...
    if (reader->packet->data[4] == 0 &&
        reader->packet->data[5] == 0)
    {
      int32_t PES_packet_length = reader->packet->data_len - 6;
      byte   *start  = reader->packet->data;
      // Our maximum length is determined by the maximum length we can
      // indicate in the two bytes of the PES_packet_length. When we're
      // *writing* data, we also have to allow for writing the two flag
      // bytes and PES_header_data_length that come thereafter. 
#define MAX_LENGTH 0xFFFF
      if (PES_packet_length > MAX_LENGTH)
      {
        fprint_err("PES packet of 'zero' length is really %6d - too long for one packet\n",
                   PES_packet_length);
        // Output what we can of the original packet
        reader->packet->data[4] = (MAX_LENGTH & 0xFF00) >> 8;
        reader->packet->data[5] = (MAX_LENGTH & 0x00FF);
        // Remember that we also write out the 6 bytes preceding those
        // MAX_LENGTH bytes...
        fprint_err(".. writing out %5d (%5d total)\n",MAX_LENGTH,MAX_LENGTH+6);
        count = fwrite(reader->packet->data,MAX_LENGTH+6,1,output);
        if (count != 1)
        {
          print_err("### Error writing (start of) PES packet out to file\n");
          (void) free_PES_reader(&reader);
          return 1;
        }
        PES_packet_length -= MAX_LENGTH;
        start             += MAX_LENGTH+6;
        while (PES_packet_length > 0)
        {
          // Now, when writing out chunks of data as PES packets,
          // we have 6 bytes of header (00 00 01 stream_id length/length)
          // followed by two bytes of flags (81 00) and a zero
          // PES_header_data_length (00). Those last three bytes have
          // to be included in the PES_packet_length of the PES packet
          // we write out, which means that the longest "chunk" of data
          // we can write is three less than the (otherwise) maximum.
          int this_length = min(MAX_LENGTH-3,PES_packet_length);
          int err;
          fprint_err(".. writing out %5d\n",this_length);
          err = write_PES_packet(output,start,this_length,
                                 reader->packet->data[3]);
          if (err)
          {
            print_err("### Error writing (part of) PES packet out to file\n");
            (void) free_PES_reader(&reader);
            return 1;
          }
          PES_packet_length -= this_length;
          start             += this_length;
        }
      }
      else
      {
Ejemplo n.º 3
0
int transport_update_ref_remote(struct transport* transport,
				struct ref *remote_refs) {
	// On this command, we need to reproduce small parts of other commands,
	// but because we want to avoid the assumption that we are running from
	// a local git repository, we'll not re-use that code.
	struct git_transport_data *data = transport->data;
	int ret = 0;
	if (!data->got_remote_heads) {
		struct ref *tmp_refs;
		connect_setup(transport, 1, 0);
		get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL,
				 NULL, &data->shallow);
		data->got_remote_heads = 1;
	}
	

	// Now we skip into the functionality from send_pack, where
	// we send the new refs to the server. Since this is a lower-level
	// command, we do not do all the checks from
	// set_ref_status_for_push. We also do support all the options
	// that send_pack does
	//
	// TODO: support omitting the old value for existing refs
	struct strbuf req_buf = STRBUF_INIT;
	struct ref *ref;
	int out = data->fd[1];
	for (ref = remote_refs; ref; ref = ref->next) {
	  char *old_hex = sha1_to_hex(ref->old_sha1);
	  char *new_hex = sha1_to_hex(ref->new_sha1);
	  packet_buf_write(&req_buf, "%s %s %s",
			     old_hex, new_hex, ref->name);
	}
	write_or_die(out, req_buf.buf, req_buf.len);
	packet_flush(out);
	strbuf_release(&req_buf);

	// And finally, we skip all the way to write_pack_file
	// This is actually the part that would absolutely depend on
	// having a local git repository.
	//
	// The basic assumption here is that you can only use this
	// command for objects that are already in the remote,
	// otherwise this would be a regular push.
	//
	// The end result is that the pack we need to send is always
	// empty.
	struct sha1file *f;
	unsigned char sha1[20];
	f = sha1fd_throughput(out, "<stdout>", NULL);
	write_pack_header(f, 0);
	sha1close(f, sha1, CSUM_CLOSE);

	// We now finish the connection on the same fashion that
	// git_transport_push does
	close(data->fd[1]);
	close(data->fd[0]);
	ret |= finish_connect(data->conn);
	data->conn = NULL;
	data->got_remote_heads = 0;

	return ret;
}