コード例 #1
0
static const char *unpack(void)
{
	struct pack_header hdr;
	const char *hdr_err;
	char hdr_arg[38];

	hdr_err = parse_pack_header(&hdr);
	if (hdr_err)
		return hdr_err;
	snprintf(hdr_arg, sizeof(hdr_arg),
			"--pack_header=%"PRIu32",%"PRIu32,
			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));

	if (ntohl(hdr.hdr_entries) < unpack_limit) {
		int code, i = 0;
		const char *unpacker[4];
		unpacker[i++] = "unpack-objects";
		if (receive_fsck_objects)
			unpacker[i++] = "--strict";
		unpacker[i++] = hdr_arg;
		unpacker[i++] = NULL;
		code = run_command_v_opt(unpacker, RUN_GIT_CMD);
		switch (code) {
		case 0:
			return NULL;
		case -ERR_RUN_COMMAND_FORK:
			return "unpack fork failed";
		case -ERR_RUN_COMMAND_EXEC:
			return "unpack execute failed";
		case -ERR_RUN_COMMAND_WAITPID:
			return "waitpid failed";
		case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
			return "waitpid is confused";
		case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
			return "unpacker died of signal";
		case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
			return "unpacker died strangely";
		default:
			return "unpacker exited with error code";
		}
	} else {
		const char *keeper[7];
		int s, status, i = 0;
		char keep_arg[256];
		struct child_process ip;

		s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
			strcpy(keep_arg + s, "localhost");

		keeper[i++] = "index-pack";
		keeper[i++] = "--stdin";
		if (receive_fsck_objects)
			keeper[i++] = "--strict";
		keeper[i++] = "--fix-thin";
		keeper[i++] = hdr_arg;
		keeper[i++] = keep_arg;
		keeper[i++] = NULL;
		memset(&ip, 0, sizeof(ip));
		ip.argv = keeper;
		ip.out = -1;
		ip.git_cmd = 1;
		if (start_command(&ip))
			return "index-pack fork failed";
		pack_lockfile = index_pack_lockfile(ip.out);
		close(ip.out);
		status = finish_command(&ip);
		if (!status) {
			reprepare_packed_git();
			return NULL;
		}
		return "index-pack abnormal exit";
	}
}
コード例 #2
0
ファイル: ps.c プロジェクト: seanvk/MiniVideo
/*!
 * \brief Parse a mp4 file.
 * \param *video A pointer to a VideoFile_t structure.
 * \return retcode 1 if succeed, 0 otherwise.
 *
 * This parser is based on the 'ISO/IEC 13818-1' international standard, part 1:
 * 'Transmission multiplexing and synchronization'.
 */
int ps_fileParse(VideoFile_t *video)
{
    TRACE_INFO(MPS, BLD_GREEN "ps_fileParse()\n" CLR_RESET);
    int retcode = SUCCESS;
    int sid = 0;

    // Init bitstream to parse container infos
    Bitstream_t *bitstr = init_bitstream(video, NULL);

    if (bitstr != NULL)
    {
        // Init bitstream_map to store container infos
        retcode = init_bitstream_map(&video->tracks_audio[0], 999999);
        retcode = init_bitstream_map(&video->tracks_video[0], 999999);

        if (retcode == SUCCESS)
        {
            video->tracks_audio[0]->stream_type = stream_AUDIO;
            video->tracks_audio[0]->stream_level = stream_level_PES;
            video->tracks_audio[0]->stream_codec = CODEC_MPEG_L3;
            video->tracks_audio[0]->sample_alignment = false;

            video->tracks_video[0]->stream_type = stream_VIDEO;
            video->tracks_video[0]->stream_level = stream_level_PES;
            video->tracks_video[0]->stream_codec = CODEC_MPEG12;
            video->tracks_video[0]->sample_alignment = false;

            // Read bitstream
            while (retcode == SUCCESS &&
                   (bitstream_get_absolute_byte_offset(bitstr) + 4) < video->file_size &&
                   next_bits(bitstr, 32) != PES_PROGRAM_END)
            {
                PackHeader_t pack_header;
                SystemHeader_t system_header;

                if (read_bits(bitstr, 32) == PES_PACK_HEADER)
                {
                    // Parse pack & system header
                    retcode = parse_pack_header(bitstr, &pack_header, &system_header);

                    // Then loop on PES
                    while (retcode == SUCCESS &&
                           (bitstream_get_absolute_byte_offset(bitstr) + 4) < video->file_size &&
                           next_bits(bitstr, 32) != PES_PACK_HEADER &&
                           next_bits(bitstr, 32) != PES_PROGRAM_END)
                    {
                        // Init
                        PesPacket_t pes_packet;
                        ProgramStreamMap_t pes_streammap;
                        ProgramStreamDirectory_t pes_streamdirectory;

                        // Parse start code
                        pes_packet.packet_start_offset = bitstream_get_absolute_byte_offset(bitstr);
                        pes_packet.packet_start_code   = read_bits(bitstr, 24);
                        pes_packet.stream_id           = (uint8_t)read_bits(bitstr, 8);

                        if (pes_packet.packet_start_code == PES_PACKETSTARTCODE)
                        {
                            switch (pes_packet.stream_id)
                            {
                            case SID_PROGRAM_STREAM_MAP:
                                retcode = parse_program_stream_map(bitstr, &pes_streammap);
                                break;
                            case SID_PROGRAM_STREAM_DIRECTORY:
                                retcode = parse_program_stream_directory(bitstr, &pes_streamdirectory);
                                break;
                            case SID_PADDING:
                                retcode = parse_pes_padding(bitstr, &pes_packet);
                                break;
                            case SID_PRIVATE_STREAM_1:
                                TRACE_2(MPS, BLD_GREEN "Private Stream 1 PES" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            case SID_PRIVATE_STREAM_2:
                                TRACE_2(MPS, BLD_GREEN "Private Stream 2 PES" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            case SID_VIDEO:
                                TRACE_INFO(MPS, BLD_GREEN "parse_pes_video()" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = parse_pes(bitstr, &pes_packet);
                                //print_pes(&pes_packet);

                                // Set sample into the bitstream_map
                                video->tracks_video[0]->sample_count++;
                                sid = video->tracks_video[0]->sample_count;
                                if (sid < 999999)
                                {
                                    video->tracks_video[0]->sample_type[sid] = sample_VIDEO;
                                    video->tracks_video[0]->sample_size[sid] = pes_packet.PES_packet_length + 6;
                                    video->tracks_video[0]->sample_offset[sid] = pes_packet.packet_start_offset;
                                    video->tracks_video[0]->sample_pts[sid] = pes_packet.PTS;
                                    video->tracks_video[0]->sample_dts[sid] = pes_packet.DTS;
                                }
                                break;
                            case SID_AUDIO:
                                TRACE_INFO(MPS, BLD_GREEN "parse_pes_audio()" CLR_RESET " @ %i\n", pes_packet.packet_start_offset);
                                retcode = parse_pes(bitstr, &pes_packet);
                                //print_pes(&pes_packet);

                                // Set sample into the bitstream_map
                                video->tracks_audio[0]->sample_count++;
                                sid = video->tracks_audio[0]->sample_count;
                                if (sid < 999999)
                                {
                                    video->tracks_audio[0]->sample_type[sid] = sample_AUDIO;
                                    video->tracks_audio[0]->sample_size[sid] = pes_packet.PES_packet_length + 6;
                                    video->tracks_audio[0]->sample_offset[sid] = pes_packet.packet_start_offset;
                                    video->tracks_audio[0]->sample_pts[sid] = pes_packet.PTS;
                                    video->tracks_audio[0]->sample_dts[sid] = pes_packet.DTS;
                                }
                                break;
                            default:
                                TRACE_WARNING(MPS, "Unknown PES type (0x%06X%02X) @ %i\n", pes_packet.packet_start_code, pes_packet.stream_id, pes_packet.packet_start_offset);
                                retcode = skip_pes(bitstr, &pes_packet);
                                break;
                            }
                        }
                        else
                        {
                            TRACE_ERROR(MPS, "No valid packet_start_code at %i\n", pes_packet.packet_start_offset);
                            retcode = FAILURE;
                        }
                    }
                }
                else
                {
                    TRACE_ERROR(MPS, "No pack header\n");
                    retcode = FAILURE;
                }
            }
        }

        // Free bitstream
        free_bitstream(&bitstr);
    }

    return retcode;
}
コード例 #3
0
ファイル: receive-pack.c プロジェクト: FerretH5N1/git-po
static const char *unpack(void)
{
	struct pack_header hdr;
	const char *hdr_err;
	char hdr_arg[38];
	int fsck_objects = (receive_fsck_objects >= 0
			    ? receive_fsck_objects
			    : transfer_fsck_objects >= 0
			    ? transfer_fsck_objects
			    : 0);

	hdr_err = parse_pack_header(&hdr);
	if (hdr_err)
		return hdr_err;
	snprintf(hdr_arg, sizeof(hdr_arg),
			"--pack_header=%"PRIu32",%"PRIu32,
			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));

	if (ntohl(hdr.hdr_entries) < unpack_limit) {
		int code, i = 0;
		const char *unpacker[4];
		unpacker[i++] = "unpack-objects";
		if (fsck_objects)
			unpacker[i++] = "--strict";
		unpacker[i++] = hdr_arg;
		unpacker[i++] = NULL;
		code = run_command_v_opt(unpacker, RUN_GIT_CMD);
		if (!code)
			return NULL;
		return "unpack-objects abnormal exit";
	} else {
		const char *keeper[7];
		int s, status, i = 0;
		char keep_arg[256];
		struct child_process ip;

		s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
			strcpy(keep_arg + s, "localhost");

		keeper[i++] = "index-pack";
		keeper[i++] = "--stdin";
		if (fsck_objects)
			keeper[i++] = "--strict";
		keeper[i++] = "--fix-thin";
		keeper[i++] = hdr_arg;
		keeper[i++] = keep_arg;
		keeper[i++] = NULL;
		memset(&ip, 0, sizeof(ip));
		ip.argv = keeper;
		ip.out = -1;
		ip.git_cmd = 1;
		status = start_command(&ip);
		if (status) {
			return "index-pack fork failed";
		}
		pack_lockfile = index_pack_lockfile(ip.out);
		close(ip.out);
		status = finish_command(&ip);
		if (!status) {
			reprepare_packed_git();
			return NULL;
		}
		return "index-pack abnormal exit";
	}
}
コード例 #4
0
ファイル: receive-pack.c プロジェクト: 1tgr/git
static const char *unpack(int err_fd, struct shallow_info *si)
{
	struct pack_header hdr;
	const char *hdr_err;
	int status;
	char hdr_arg[38];
	struct child_process child = CHILD_PROCESS_INIT;
	int fsck_objects = (receive_fsck_objects >= 0
			    ? receive_fsck_objects
			    : transfer_fsck_objects >= 0
			    ? transfer_fsck_objects
			    : 0);

	hdr_err = parse_pack_header(&hdr);
	if (hdr_err) {
		if (err_fd > 0)
			close(err_fd);
		return hdr_err;
	}
	snprintf(hdr_arg, sizeof(hdr_arg),
			"--pack_header=%"PRIu32",%"PRIu32,
			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));

	if (si->nr_ours || si->nr_theirs) {
		alt_shallow_file = setup_temporary_shallow(si->shallow);
		argv_array_push(&child.args, "--shallow-file");
		argv_array_push(&child.args, alt_shallow_file);
	}

	if (ntohl(hdr.hdr_entries) < unpack_limit) {
		argv_array_pushl(&child.args, "unpack-objects", hdr_arg, NULL);
		if (quiet)
			argv_array_push(&child.args, "-q");
		if (fsck_objects)
			argv_array_pushf(&child.args, "--strict%s",
				fsck_msg_types.buf);
		child.no_stdout = 1;
		child.err = err_fd;
		child.git_cmd = 1;
		status = run_command(&child);
		if (status)
			return "unpack-objects abnormal exit";
	} else {
		char hostname[256];

		argv_array_pushl(&child.args, "index-pack",
				 "--stdin", hdr_arg, NULL);

		if (gethostname(hostname, sizeof(hostname)))
			xsnprintf(hostname, sizeof(hostname), "localhost");
		argv_array_pushf(&child.args,
				 "--keep=receive-pack %"PRIuMAX" on %s",
				 (uintmax_t)getpid(),
				 hostname);

		if (!quiet && err_fd)
			argv_array_push(&child.args, "--show-resolving-progress");
		if (use_sideband)
			argv_array_push(&child.args, "--report-end-of-input");
		if (fsck_objects)
			argv_array_pushf(&child.args, "--strict%s",
				fsck_msg_types.buf);
		if (!reject_thin)
			argv_array_push(&child.args, "--fix-thin");
		child.out = -1;
		child.err = err_fd;
		child.git_cmd = 1;
		status = start_command(&child);
		if (status)
			return "index-pack fork failed";
		pack_lockfile = index_pack_lockfile(child.out);
		close(child.out);
		status = finish_command(&child);
		if (status)
			return "index-pack abnormal exit";
		reprepare_packed_git();
	}
	return NULL;
}
コード例 #5
0
ファイル: ps.cpp プロジェクト: emericg/MiniVideo
int ps_fileParse(MediaFile_t *media)
{
    int retcode = SUCCESS;

    TRACE_INFO(MPS, BLD_GREEN "ps_fileParse()" CLR_RESET);

    // Init bitstream to parse container infos
    Bitstream_t *bitstr = init_bitstream(media, NULL);

    if (bitstr != NULL)
    {
        // Init an MpegPs structure
        MpegPs_t mpg;
        memset(&mpg, 0, sizeof(MpegPs_t));

        // A convenient way to stop the parser
        mpg.run = true;

        // stuff
        const int64_t min_packet_size = 4;

        // Loop on PES packets
        while (mpg.run == true &&
               retcode == SUCCESS &&
               bitstream_get_absolute_byte_offset(bitstr) < (media->file_size - min_packet_size))
        {
            // Init
            PackHeader_t pack_header;
            memset(&pack_header, 0, sizeof(PackHeader_t));
            SystemHeader_t system_header;
            memset(&system_header, 0, sizeof(SystemHeader_t));

            PesHeader_t pes_header;
            memset(&pes_header, 0, sizeof(PesHeader_t));
            PesPacket_t pes_packet;
            memset(&pes_packet, 0, sizeof(PesPacket_t));
            ProgramStreamMap_t pes_streammap;
            memset(&pes_streammap, 0, sizeof(ProgramStreamMap_t));
            ProgramStreamDirectory_t pes_streamdirectory;
            memset(&pes_streamdirectory, 0, sizeof(ProgramStreamDirectory_t));

            // Parse packet header
            parse_pes_header(bitstr, &pes_header);

            switch (pes_header.stream_id)
            {
            case SID_PACK_HEADER:
                retcode = parse_pack_header(bitstr, &pes_header, &pack_header);
                mpg.stat_packheader++;
                break;
            case SID_SYSTEM_HEADER:
                retcode = parse_system_header(bitstr, &pes_header, &system_header);
                mpg.stat_systemheader++;
                break;

            case SID_PROGRAM_STREAM_MAP:
                retcode = parse_program_stream_map(bitstr, &pes_header, &pes_streammap);
                mpg.stat_packet_psm++;
                break;
            case SID_PROGRAM_STREAM_DIRECTORY:
                retcode = parse_program_stream_directory(bitstr, &pes_header, &pes_streamdirectory);
                mpg.stat_packet_psd++;
                break;
            case SID_PRIVATE_STREAM_2:
                TRACE_2(MPS, BLD_GREEN "Private Stream 2 PES" CLR_RESET " @ %lli", pes_header.offset_start);
                mpg.stat_packet_private++;
                break;
            case SID_PADDING:
                retcode = parse_pes_padding(bitstr, &pes_header, &pes_packet);
                mpg.stat_packet_other++;
                break;

            case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6:
            case 0xC7: case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC:
            case 0xCD: case 0xCE: case 0xCF: case 0xD0: case 0xD1: case 0xD2:
            case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7: case 0xD8:
            case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE:
            case 0xDF: case SID_PRIVATE_STREAM_1: case SID_AUDIO:
            {
                TRACE_INFO(MPS, BLD_GREEN "parse_pes_audio()" CLR_RESET " @ %lli", pes_header.offset_start);

                // Find a trackid
                unsigned track_id = pes_header.stream_id - 0xC0;
                if (pes_header.stream_id == SID_PRIVATE_STREAM_1)
                    track_id = 0;

                // If a private stream is in the stream, the 'regular' trackid order is shifted
                //while (media->tracks_audio[track_id] == NULL)
                //    track_id--;

                // Init bitstream_map (as needed) to store samples
                if (media->tracks_audio[track_id] == NULL)
                {
                    retcode = init_bitstream_map(&media->tracks_audio[track_id], 0, 999999);
                    media->tracks_audio_count++;
                    media->tracks_audio[track_id]->stream_type = stream_AUDIO;
                }

                retcode = parse_pes(bitstr, &pes_header, &pes_packet);
                parse_pes_a(bitstr, &pes_header, &pes_packet, media->tracks_audio[track_id]);
                mpg.stat_packet_audio++;

                // Set sample into the bitstream_map
                unsigned sample_id = media->tracks_audio[track_id]->sample_count++;
                if (sample_id < 999999)
                {
                    media->tracks_audio[track_id]->sample_type[sample_id] = sample_AUDIO;
                    media->tracks_audio[track_id]->sample_size[sample_id] = pes_header.payload_length - pes_packet.PES_header_data_length;
                    media->tracks_audio[track_id]->sample_offset[sample_id] = pes_header.offset_start + 6 + pes_packet.PES_header_data_length;
                    media->tracks_audio[track_id]->sample_pts[sample_id] = pes_packet.PTS;
                    media->tracks_audio[track_id]->sample_dts[sample_id] = pes_packet.DTS;
                }
            }
            break;

            case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5:
            case 0xE6: case 0xE7: case 0xE8: case 0xE9: case 0xEA:
            case 0xEB: case 0xEC: case 0xED: case 0xEE: case 0xEF:
            case SID_VIDEO:
            {
                TRACE_INFO(MPS, BLD_GREEN "parse_pes_video()" CLR_RESET " @ %lli", pes_header.offset_start + 6);

                // Init bitstream_map (as needed) to store samples
                unsigned track_id = pes_header.stream_id - 0xE0;
                if (media->tracks_video[track_id] == NULL)
                {
                    retcode = init_bitstream_map(&media->tracks_video[track_id], 0, 999999);
                    media->tracks_video_count++;
                    media->tracks_video[track_id]->stream_type = stream_VIDEO;
                }

                retcode = parse_pes(bitstr, &pes_header, &pes_packet);
                parse_pes_v(bitstr, &pes_header, &pes_packet, media->tracks_video[track_id]);
                mpg.stat_packet_video++;

                // Set sample into the bitstream_map
                unsigned sample_id = media->tracks_video[track_id]->sample_count++;
                if (sample_id < 999999)
                {
                    media->tracks_video[track_id]->sample_type[sample_id] = sample_VIDEO;
                    media->tracks_video[track_id]->sample_size[sample_id] = pes_header.payload_length - pes_packet.PES_header_data_length;
                    media->tracks_video[track_id]->sample_offset[sample_id] = pes_header.offset_start + 6 + pes_packet.PES_header_data_length;
                    media->tracks_video[track_id]->sample_pts[sample_id] = pes_packet.PTS;
                    media->tracks_video[track_id]->sample_dts[sample_id] = pes_packet.DTS;
                }
            }
            break;

            case SID_PROGRAM_END:
                mpg.stat_packet_other++;
                mpg.run = false;
                break;

            default:
                TRACE_WARNING(MPS, "Unknown PES packet type (0x%02X) @ %lli",
                              pes_header.stream_id, pes_header.offset_start);
                mpg.stat_packet_other++;
                break;
            }

            retcode = jumpy_pes(bitstr, &pes_header);
        }

        // Free bitstream
        free_bitstream(&bitstr);

        // Recap
        TRACE_INFO(MPS, "MPEG PS (version %u) stats", mpg.mpeg_version);
        TRACE_INFO(MPS, "- Pack Headers:    %u", mpg.stat_packheader);
        TRACE_INFO(MPS, "- System Headers:  %u", mpg.stat_systemheader);
        TRACE_INFO(MPS, "- PSM packets:     %u", mpg.stat_packet_psm);
        TRACE_INFO(MPS, "- PSD packets:     %u", mpg.stat_packet_psd);
        TRACE_INFO(MPS, "- Private packets: %u", mpg.stat_packet_private);
        TRACE_INFO(MPS, "- Audio packets:   %u", mpg.stat_packet_audio);
        TRACE_INFO(MPS, "- Video packets:   %u", mpg.stat_packet_video);
        TRACE_INFO(MPS, "- Unknown packets: %u", mpg.stat_packet_other);
    }
    else
    {
        retcode = FAILURE;
    }

    return retcode;
}
コード例 #6
0
ファイル: receive-pack.c プロジェクト: 1974kpkpkp/git
static const char *unpack(int err_fd, struct shallow_info *si)
{
	struct pack_header hdr;
	struct argv_array av = ARGV_ARRAY_INIT;
	const char *hdr_err;
	int status;
	char hdr_arg[38];
	struct child_process child;
	int fsck_objects = (receive_fsck_objects >= 0
			    ? receive_fsck_objects
			    : transfer_fsck_objects >= 0
			    ? transfer_fsck_objects
			    : 0);

	hdr_err = parse_pack_header(&hdr);
	if (hdr_err) {
		if (err_fd > 0)
			close(err_fd);
		return hdr_err;
	}
	snprintf(hdr_arg, sizeof(hdr_arg),
			"--pack_header=%"PRIu32",%"PRIu32,
			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));

	if (si->nr_ours || si->nr_theirs) {
		alt_shallow_file = setup_temporary_shallow(si->shallow);
		argv_array_pushl(&av, "--shallow-file", alt_shallow_file, NULL);
	}

	memset(&child, 0, sizeof(child));
	if (ntohl(hdr.hdr_entries) < unpack_limit) {
		argv_array_pushl(&av, "unpack-objects", hdr_arg, NULL);
		if (quiet)
			argv_array_push(&av, "-q");
		if (fsck_objects)
			argv_array_push(&av, "--strict");
		child.argv = av.argv;
		child.no_stdout = 1;
		child.err = err_fd;
		child.git_cmd = 1;
		status = run_command(&child);
		if (status)
			return "unpack-objects abnormal exit";
	} else {
		int s;
		char keep_arg[256];

		s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
			strcpy(keep_arg + s, "localhost");

		argv_array_pushl(&av, "index-pack",
				 "--stdin", hdr_arg, keep_arg, NULL);
		if (fsck_objects)
			argv_array_push(&av, "--strict");
		if (fix_thin)
			argv_array_push(&av, "--fix-thin");
		child.argv = av.argv;
		child.out = -1;
		child.err = err_fd;
		child.git_cmd = 1;
		status = start_command(&child);
		if (status)
			return "index-pack fork failed";
		pack_lockfile = index_pack_lockfile(child.out);
		close(child.out);
		status = finish_command(&child);
		if (status)
			return "index-pack abnormal exit";
		reprepare_packed_git();
	}
	return NULL;
}