Patchwork [04,of,11,c-hglib:level0,V2] hg_open: additional functions (read_hello and read_header)

login
register
mail settings
Submitter Iulian Stana
Date Sept. 13, 2013, 8:31 p.m.
Message ID <07360f1314434cf1f9c5.1379104314@doppler>
Download mbox | patch
Permalink /patch/2434/
State Deferred, archived
Headers show

Comments

Iulian Stana - Sept. 13, 2013, 8:31 p.m.
# HG changeset patch
# User Iulian Stana <julian.stana@gmail.com>
# Date 1379103044 -10800
#      Fri Sep 13 23:10:44 2013 +0300
# Node ID 07360f1314434cf1f9c514ecedbc916ab2958c6d
# Parent  a214d1affc17a4c03257f6f5d9a30dd520453df2
hg_open: additional functions (read_hello and read_header)

read_hello: reading the hello msg from cmd server
read_header: reading the header from cmd server

It's also an inside function that comes with hg_open function.
Users are not allowed to call this function. I think that it's a protection for
them. This function is called from hg_open function, hg_rawread and hg_rawwrite
functions

Patch

diff --git a/client.c b/client.c
--- a/client.c
+++ b/client.c
@@ -13,6 +13,97 @@ 
 
 
 /*
+ * The function will read the header from the command server and will save it to
+ * */
+hg_header *hg_read_header(hg_handle *handle)
+{
+	uint32_t length;
+	char ch_char;
+
+	if(!handle) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if(handle->bytes_on_pipe == 0){
+		if(read(handle->p_read, &ch_char, 1) < 0){
+			return NULL;
+		}
+		if(read(handle->p_read, &length, sizeof(uint32_t)) < 0){
+			return NULL;
+		}
+		handle->header->length = swap_uint32(length);
+		handle->bytes_on_pipe = handle->header->length;
+		switch(ch_char){
+			case 'o':
+				handle->header->channel = o;
+				break;
+			case 'e':
+				handle->header->channel = e;
+				break;
+			case 'r':
+				handle->header->channel = r;
+				break;
+			case 'I':
+				handle->header->channel = I;
+				break;
+			case 'L':
+				handle->header->channel = L;
+				break;
+			default:
+				handle->header->channel = wrong_channel;
+				break;
+		}
+	}
+	return handle->header;
+}
+
+/**
+ * \brief Reading the hello msg from cmd server.
+ *
+ * After the connection, the command server sends a hello message.
+ * The message contains the command server capabilities and the messages
+ * encoding.
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \retval  0 if succesfull 
+ * \retval -1 to indicate an error, with errno set appropriately
+ * 
+ * errno can be:
+ *       - EINVAL  - Invalid argument (handle it's set to a null pointer)
+ *       - read(2) command errors
+ * */
+int read_hello(hg_handle *handle)
+{
+	char *buffer;
+	hg_header *ch;
+	int nc;
+
+	if(!handle) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	ch = hg_read_header(handle);
+
+	if(ch->length == 0){
+		return -1;
+	}
+
+	buffer = malloc(ch->length + 1);
+
+	if(nc = read(handle->p_read, buffer, ch->length), nc < 0){
+		free(buffer);
+		return -1;
+	}
+	buffer[ch->length] = '\0';
+	handle->bytes_on_pipe -= nc;
+
+	free(buffer);
+
+	return 0;
+}
+
+/*
  * Open the connection with the mercurial command server.
  * */
 hg_handle *hg_open(const char *path, char *encoding)
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -89,6 +89,21 @@ 
 } hg_handle;
 
 /**
+ * \brief Reading the header from cmdsrv.
+ *
+ * The function will read the header from the command server and will save it to
+ * the header parameter of the handle structure.
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \retval header if succesfull 
+ * \retval NULL to indicate an error, with errno set appropriately
+ * 
+ * errno can be:
+ *       - EINVAL  - Invalid argument (handle it's set to a null pointer)
+ *       - read(2) command errors
+ * */
+hg_header *hg_read_header(hg_handle *handle);
+
+/**
  * \brief Open the connection with the mercurial command server.
  *
  * The handle structure will be allocated.