Ejemplo n.º 1
0
static int fetch(struct walker *walker, unsigned char *sha1)
{
	struct object *obj = lookup_object(sha1);
	if (obj && obj->type == OBJ_BLOB) {

		int skip_object = walker->sparse_checkout_list_count > 0 ? 1 : 0;
		for (int i = 0; i < walker->sparse_checkout_list_count; i++) {
			if (memcmp(walker->sparse_checkout_list + sizeof(unsigned char[20]) * i, sha1, sizeof(unsigned char[20])) == 0) {
				skip_object = 0;
				break;
			}
		}

		if (skip_object) {
			/* xxd -i .git/objects/6c/a8147f8b21da66ea9e90c1e88d70f1e8aa5f9d which represents: 'This is a dummy file' */
			static unsigned char git_dummy_file[] = {
			  0x78, 0x01, 0x4b, 0xca, 0xc9, 0x4f, 0x52, 0x30, 0x32, 0x64, 0x08, 0xc9,
			  0xc8, 0x2c, 0x56, 0x00, 0xa2, 0x44, 0x85, 0x94, 0xd2, 0xdc, 0xdc, 0x4a,
			  0x85, 0xb4, 0xcc, 0x9c, 0x54, 0x2e, 0x00, 0x89, 0x4a, 0x09, 0x4e
			};
			static unsigned int git_dummy_file_len = 35;

			safe_create_leading_directories_const(sha1_file_name(sha1));
			FILE *f = fopen(sha1_file_name(sha1), "wb");
			if (f == NULL) {
				fprintf(stderr, _("Unable to create file for intercepting"));
				exit(-1);
			}
			else if (f != NULL) {
				fwrite(git_dummy_file, git_dummy_file_len, 1, f);
				fclose(f);
			}

			return 0;
		}
	}

	struct walker_data *data = walker->data;
	struct alt_base *altbase = data->alt;

	if (!fetch_object(walker, altbase, sha1))
		return 0;
	while (altbase) {
		if (!http_fetch_pack(walker, altbase, sha1))
			return 0;
		fetch_alternates(walker, data->alt->base);
		altbase = altbase->next;
	}
	return error("Unable to find %s under %s", sha1_to_hex(sha1),
		     data->alt->base);
}
Ejemplo n.º 2
0
static void prefetch(struct walker *walker, unsigned char *sha1)
{
	struct object_request *newreq;
	struct object_request *tail;
	struct walker_data *data = walker->data;
	char *filename = sha1_file_name(sha1);

	newreq = xmalloc(sizeof(*newreq));
	newreq->walker = walker;
	hashcpy(newreq->sha1, sha1);
	newreq->repo = data->alt;
	newreq->url = NULL;
	newreq->local = -1;
	newreq->state = WAITING;
	snprintf(newreq->filename, sizeof(newreq->filename), "%s", filename);
	snprintf(newreq->tmpfile, sizeof(newreq->tmpfile),
		 "%s.temp", filename);
	newreq->slot = NULL;
	newreq->next = NULL;

	if (object_queue_head == NULL) {
		object_queue_head = newreq;
	} else {
		tail = object_queue_head;
		while (tail->next != NULL) {
			tail = tail->next;
		}
		tail->next = newreq;
	}

#ifdef USE_CURL_MULTI
	fill_active_slots();
	step_active_slots();
#endif
}
Ejemplo n.º 3
0
static int check_valid_sha1(unsigned char *sha1)
{
	char *filename = sha1_file_name(sha1);
	int ret;

	/* If we were anal, we'd check that the sha1 of the contents actually matches */
	ret = access(filename, R_OK);
	if (ret)
		perror(filename);
	return ret;
}
Ejemplo n.º 4
0
static int fetch_file(const unsigned char *sha1)
{
	static int object_name_start = -1;
	static char filename[PATH_MAX];
	char *hex = sha1_to_hex(sha1);
	char *dest_filename = sha1_file_name(sha1);

 	if (object_name_start < 0) {
		strcpy(filename, path); /* e.g. git.git */
		strcat(filename, "/objects/");
		object_name_start = strlen(filename);
	}
	filename[object_name_start+0] = hex[0];
	filename[object_name_start+1] = hex[1];
	filename[object_name_start+2] = '/';
	strcpy(filename + object_name_start + 3, hex + 2);
	return copy_file(filename, dest_filename, hex, 0);
}
Ejemplo n.º 5
0
static int fetch_object(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
{
	char *hex = sha1_to_hex(sha1);
	int ret = 0;
	struct object_request *obj_req = object_queue_head;
	struct http_object_request *req;

	while (obj_req != NULL && hashcmp(obj_req->sha1, sha1))
		obj_req = obj_req->next;
	if (obj_req == NULL)
		return error("Couldn't find request for %s in the queue", hex);

	if (has_sha1_file(obj_req->sha1)) {
		if (obj_req->req != NULL)
			abort_http_object_request(obj_req->req);
		abort_object_request(obj_req);
		return 0;
	}

#ifdef USE_CURL_MULTI
	while (obj_req->state == WAITING)
		step_active_slots();
#else
	start_object_request(walker, obj_req);
#endif

	/*
	 * obj_req->req might change when fetching alternates in the callback
	 * process_object_response; therefore, the "shortcut" variable, req,
	 * is used only after we're done with slots.
	 */
	while (obj_req->state == ACTIVE)
		run_active_slot(obj_req->req->slot);

	req = obj_req->req;

	if (req->localfile != -1) {
		close(req->localfile);
		req->localfile = -1;
	}

	if (obj_req->state == ABORTED) {
		ret = error("Request for %s aborted", hex);
	} else if (req->curl_result != CURLE_OK &&
		   req->http_code != 416) {
		if (missing_target(req))
			ret = -1; /* Be silent, it is probably in a pack. */
		else
			ret = error("%s (curl_result = %d, http_code = %ld, sha1 = %s)",
				    req->errorstr, req->curl_result,
				    req->http_code, hex);
	} else if (req->zret != Z_STREAM_END) {
		walker->corrupt_object_found++;
		ret = error("File %s (%s) corrupt", hex, req->url);
	} else if (hashcmp(obj_req->sha1, req->real_sha1)) {
		ret = error("File %s has bad hash", hex);
	} else if (req->rename < 0) {
		ret = error("unable to write sha1 filename %s",
			    sha1_file_name(req->sha1));
	}

	release_http_object_request(req);
	release_object_request(obj_req);
	return ret;
}