--- /usr/ports/net/gitup/work/gitup-0.93/gitup.c 2021-05-09 07:57:39.000000000 +0300
+++ gitup.c 2021-05-10 19:12:50.942962000 +0300
@@ -70,7 +70,8 @@
char *ref_delta_hash;
uint32_t pack_offset;
char *buffer;
- uint32_t buffer_size;
+ uint32_t buffer_size,file_offset;
+ char can_free;
};
struct file_node {
@@ -119,6 +120,7 @@
int verbosity;
uint8_t display_depth;
char *updating;
+ int back_store;
} connector;
static void append(char **, unsigned int *, const char *, size_t);
@@ -165,7 +167,32 @@
static void unpack_objects(connector *);
static uint32_t unpack_variable_length_integer(char *, uint32_t *);
static void usage(const char *);
+static void load_buffer(connector *,struct object_node *);
+static void release_buffer(struct object_node *);
+static void release_buffer(struct object_node *obj)
+{
+if(!obj->can_free) {
+ // dont release non file backed objects
+ free(obj->buffer);
+ obj->buffer = NULL;
+ }
+}
+
+static void load_buffer(connector * connection,struct object_node *obj)
+{
+ int rd;
+ if(!obj->buffer) {
+ obj->buffer = malloc(obj->buffer_size);
+ if(!obj->buffer)
+ err(EXIT_FAILURE, "load_buffer: malloc");
+ lseek(connection->back_store,obj->file_offset,SEEK_SET);
+ rd = read(connection->back_store,obj->buffer,obj->buffer_size);
+ if(rd != (int)obj->buffer_size) {
+ err(EXIT_FAILURE, "load_buffer: read %d %d",rd,obj->buffer_size);
+ }
+ }
+ }
/*
* node_compare
*
@@ -1734,7 +1761,6 @@
char *hash = NULL;
hash = calculate_object_hash(buffer, buffer_size, type);
-
/* Check to make sure the object doesn't already exist. */
find.hash = hash;
@@ -1762,6 +1788,8 @@
object->ref_delta_hash = (ref_delta_hash ? legible_hash(ref_delta_hash) : NULL);
object->buffer = buffer;
object->buffer_size = buffer_size;
+ object->can_free = 1;
+ object->file_offset = -1;
if (connection->verbosity > 1)
fprintf(stdout,
@@ -1798,9 +1826,20 @@
uint32_t file_size = 0, file_bits = 0, pack_offset = 0;
uint32_t lookup_offset = 0, position = 4;
unsigned char zlib_out[16384];
+ int nobj_old,tot_len = 0;
+ char remote_files_tmp[BUFFER_UNIT_SMALL];
/* Check the pack version number. */
+ snprintf(remote_files_tmp, BUFFER_UNIT_SMALL,
+ "%s.tmp",
+ connection->remote_files);
+ connection->back_store = open(remote_files_tmp, O_WRONLY | O_CREAT | O_TRUNC);
+ if (connection->back_store == -1)
+ err(EXIT_FAILURE,
+ "save_tmp: write file failure %s",
+ remote_files_tmp);
+
version = (unsigned char)connection->response[position + 3];
position += 4;
@@ -1904,6 +1943,8 @@
inflateEnd(&stream);
position += stream.total_in;
+ write(connection->back_store,buffer,buffer_size);
+ nobj_old = connection->objects;
store_object(connection,
object_type,
@@ -1912,9 +1953,23 @@
pack_offset,
index_delta,
ref_delta_hash);
-
+ if(nobj_old != connection->objects) {
+ connection->object[nobj_old]->buffer = NULL;
+ connection->object[nobj_old]->can_free = 0;
+ connection->object[nobj_old]->file_offset = tot_len;
+ }
+ tot_len += buffer_size;
+ free(buffer);
free(ref_delta_hash);
}
+ close(connection->back_store);
+ connection->back_store = open(remote_files_tmp, O_RDONLY);
+ if (connection->back_store == -1)
+ err(EXIT_FAILURE,
+ "open tmp ro: failure %s",
+ remote_files_tmp);
+
+ unlink(remote_files_tmp); /* unlink now / dealocate when exit */
}
@@ -2029,7 +2084,7 @@
if ((merge_buffer = (char *)malloc(base->buffer_size)) == NULL)
err(EXIT_FAILURE,
"apply_deltas: malloc");
-
+ load_buffer(connection,base);
memcpy(merge_buffer, base->buffer, base->buffer_size);
merge_buffer_size = base->buffer_size;
@@ -2037,6 +2092,7 @@
for (x = delta_count - 1; x >= 0; x--) {
delta = connection->object[deltas[x]];
+ load_buffer(connection,delta);
position = 0;
new_position = 0;
old_file_size = unpack_variable_length_integer(delta->buffer, &position);
@@ -2101,10 +2157,11 @@
*/
memcpy(merge_buffer, layer_buffer, new_file_size);
+ release_buffer(delta);
}
/* Store the completed object. */
-
+ release_buffer(base);
store_object(connection,
base->type,
merge_buffer,
@@ -2175,7 +2232,7 @@
object.hash);
/* Remove the base path from the list of upcoming deletions. */
-
+ load_buffer(connection,tree);
file.path = base_path;
found_file = RB_FIND(Tree_Local_Path, &Local_Path, &file);
@@ -2291,7 +2348,7 @@
}
/* Add the tree data to the remote files list. */
-
+ release_buffer(tree);
write(remote_descriptor, buffer, buffer_size);
write(remote_descriptor, "\n", 1);
@@ -2346,6 +2403,7 @@
*/
if (missing == false) {
+ load_buffer(connection,found_object);
check_hash = calculate_file_hash(
found_file->path,
found_file->mode);
@@ -2354,19 +2412,20 @@
found_object->buffer,
found_object->buffer_size,
3);
-
+ release_buffer(found_object);
if (strncmp(check_hash, buffer_hash, 40) == 0)
update = false;
}
if (update == true) {
+ load_buffer(connection,found_object);
save_file(found_file->path,
found_file->mode,
found_object->buffer,
found_object->buffer_size,
connection->verbosity,
connection->display_depth);
-
+ release_buffer(found_object);
if (strstr(found_file->path, "UPDATING"))
extend_updating_list(connection,
found_file->path);
@@ -2409,13 +2468,14 @@
"save_objects: cannot find %s",
connection->want);
+ load_buffer(connection,found_object);
if (memcmp(found_object->buffer, "tree ", 5) != 0)
errc(EXIT_FAILURE, EINVAL,
"save_objects: first object is not a commit");
memcpy(tree, found_object->buffer + 5, 40);
tree[40] = '\0';
-
+ release_buffer(found_object);
/* Recursively start processing the tree. */
snprintf(remote_files_new, BUFFER_UNIT_SMALL,
@@ -2460,14 +2520,14 @@
errc(EXIT_FAILURE, EINVAL,
"save_objects: cannot find %s",
found_file->hash);
-
+ load_buffer(connection,found_object);
save_file(found_file->path,
found_file->mode,
found_object->buffer,
found_object->buffer_size,
connection->verbosity,
connection->display_depth);
-
+ release_buffer(found_object);
if (strstr(found_file->path, "UPDATING"))
extend_updating_list(connection, found_file->path);
}