Forwarding this to this list, since hurdextras-hackers seems a bit deserted.


-------- Original Message --------
Subject: [httpfs][PATCH] Fix compilation and bugs.
Date: Sat, 14 Jul 2012 03:41:35 +0200
From: Cyril Roelandt <tipec...@gmail.com>
To: hurdextras-hack...@nongnu.org

Hi !

I wanted to try httpfs, but the code from the CVS repository failed to
compile on my Debian GNU/Hurd box. So, here are a few patches.

- The first patch fixes the compilation of httpfs. This is a mix of an
old patch
(https://savannah.nongnu.org/patch/?func=detailitem&item_id=4839) and of
some really simple fixes.

- The second patch adds -lpthread to the linker options. Basically,
there is a bug that prevents libpthread from being dlopened properly,
and the standard workaround is to link the application itself with
libpthread.

- The third patch just reindents http.c :)

- The fourth patch fixes a bug that caused some calls to free() in
fill_dirnode() to fail. It is caused by an error in the sizes passed to
malloc(). I'm really not sure of what I did for the code located in the
"if (go->f_type == HTTP_URL)" statement (the original code looked a bit
obfuscated to me) but I'm pretty sure I'm doing the right thing in the
rest of the patch. Anyway, this made httpfs work for me.


I hope it helps.

Cyril.



diff --git a/Makefile.am b/Makefile.am
index 7eb6622..fdd269f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,7 @@
 
 bin_PROGRAMS=httpfs
 
-httpfs_LDADD=-lhurdbugaddr -lnetfs -lfshelp -lthreads -lports -liohelp -lxml2 -lshouldbeinlibc
+httpfs_LDADD=$(LIBS) -lhurdbugaddr -lnetfs -lfshelp -lthreads -lports -liohelp -lshouldbeinlibc
 httpfs_SOURCES=httpfs.c \
 	netfs.c \
 	args.c \
diff --git a/configure.in b/configure.in
index a53d11c..8de56fb 100644
--- a/configure.in
+++ b/configure.in
@@ -1,10 +1,16 @@
+AC_INIT(httpfs, 0.1)
+AC_CONFIG_SRCDIR(Makefile.am)
+AM_INIT_AUTOMAKE
 
+AC_PROG_CC
 
-AC_INIT(Makefile.am)
+PKG_CHECK_MODULES(HTTPFS, libxml-2.0)
 
-AM_INIT_AUTOMAKE(httpfs, 0.1, no-define)
+CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 $HTTPFS_CFLAGS"
+LIBS="$LIBS $HTTPFS_LIBS"
 
-AC_PROG_CC
+AC_SUBST(LIBS)
+AM_CONFIG_HEADER(config.h)
 
 AC_OUTPUT(
 	Makefile
diff --git a/httpfs.c b/httpfs.c
index ca92d41..a3c1b0d 100644
--- a/httpfs.c
+++ b/httpfs.c
@@ -42,6 +42,9 @@ struct files *list_of_entries = NULL, *this_entry;
 struct httpfs *httpfs;		/* filesystem global pointer */
 volatile struct mapped_time_value *httpfs_maptime;
 
+char *netfs_server_name    = HTTPFS_SERVER_NAME;
+char *netfs_server_version = HTTPFS_SERVER_VERSION;
+
 int
 main (int argc, char **argv)
 {
diff --git a/httpfs.h b/httpfs.h
index cdf825f..e3c7a25 100644
--- a/httpfs.h
+++ b/httpfs.h
@@ -23,6 +23,11 @@
 
 #include <hurd/hurd_types.h>
 
+#include "config.h"
+
+#define HTTPFS_SERVER_NAME    PACKAGE
+#define HTTPFS_SERVER_VERSION VERSION
+
 /* declaration of global configuration parameters */
 extern int debug_flag;
 extern volatile struct mapped_time_value *httpfs_maptime;
diff --git a/netfs.c b/netfs.c
index 720f8c0..4fe8085 100644
--- a/netfs.c
+++ b/netfs.c
@@ -77,16 +77,14 @@ netfs_attempt_utimes (struct iouser *cred, struct node *node,
 		err = fshelp_isowner (&node->nn_stat, cred);
 
 	if (!err) {
-		if (atime) {
-			node->nn_stat.st_atime = atime->tv_sec;
-			node->nn_stat.st_atime_usec = atime->tv_nsec / 1000;
-		} else
+		if (atime)
+			node->nn_stat.st_atim = *atime;
+		else
 			flags |= TOUCH_ATIME;
 
-		if (mtime) {
-			node->nn_stat.st_mtime = mtime->tv_sec;
-			node->nn_stat.st_mtime_usec = mtime->tv_nsec / 1000;
-		} else
+		if (mtime)
+			node->nn_stat.st_mtim = *mtime;
+		else
 			flags |= TOUCH_MTIME;
 
 		fshelp_touch (&node->nn_stat, flags, httpfs_maptime);
@@ -412,7 +410,7 @@ error_t netfs_attempt_chflags (struct iouser *cred, struct node *node,
 /* This should attempt to set the size of the file NODE (for user CRED) to
    SIZE bytes long. */
 error_t netfs_attempt_set_size (struct iouser *cred, struct node *node,
-				off_t size)
+				loff_t size)
 {
 	return EROFS;
 }
@@ -420,7 +418,7 @@ error_t netfs_attempt_set_size (struct iouser *cred, struct node *node,
 /* This should attempt to fetch filesystem status information for the remote
    filesystem, for the user CRED. */
 error_t netfs_attempt_statfs (struct iouser *cred, struct node *node,
-			struct statfs *st)
+			fsys_statfsbuf_t *st)
 {
 	return EOPNOTSUPP;
 }
@@ -464,7 +462,7 @@ error_t netfs_attempt_readlink (struct iouser *user, struct node *node,
    up to *LEN bytes.  Put the data at DATA.  Set *LEN to the amount
    successfully read upon return.  */
 error_t netfs_attempt_read (struct iouser *cred, struct node *node,
-          		off_t offset, size_t *len, void *data)
+          		loff_t offset, size_t *len, void *data)
 {
 	error_t err;
 	static int remote_fd;
@@ -504,7 +502,7 @@ error_t netfs_attempt_read (struct iouser *cred, struct node *node,
    to *LEN bytes from DATA.  Set *LEN to the amount seccessfully written upon
    return. */
 error_t netfs_attempt_write (struct iouser *cred, struct node *node,
-			 off_t offset, size_t *len, void *data)
+			 loff_t offset, size_t *len, void *data)
 {
 	return EROFS;
 }

diff --git a/Makefile.am b/Makefile.am
index fdd269f..9bd334d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,10 @@
 
 bin_PROGRAMS=httpfs
 
-httpfs_LDADD=$(LIBS) -lhurdbugaddr -lnetfs -lfshelp -lthreads -lports -liohelp -lshouldbeinlibc
+# XXX At some point, we are using libpthread, and this causes httpfs to crash:
+# httpfs: ./pthread/../sysdeps/generic/pt-mutex-timedlock.c:68: __pthread_mutex_timedlock_internal: Assertion `__pthread_threads' failed.
+# Linking httpfs with libpthread is a workaround.
+httpfs_LDADD= -lpthread $(LIBS) -lhurdbugaddr -lnetfs -lfshelp -lthreads -lports -liohelp -lshouldbeinlibc
 httpfs_SOURCES=httpfs.c \
 	netfs.c \
 	args.c \

diff --git a/http.c b/http.c
index 005631e..4be45d4 100644
--- a/http.c
+++ b/http.c
@@ -247,52 +247,52 @@ error_t fill_dirnode (struct netnode *dir)
 				if ( go != list_of_entries )
 				{
 					conn_req=(char *)malloc((strlen(dir->conn_req)+strlen(go->f_name)+1)*sizeof(char));
-				sprintf(conn_req,"%s%s",dir->conn_req,go->f_name);
-				}
-				else
-				{
-				if ( dir_tok[no_of_slashes] == NULL ) 
-				{
-					/* the file corresponding to base url
-					 * user has given a file explicitly in
-					 * the url */
-					conn_req=(char *)malloc((strlen(dir->conn_req)+strlen(go->f_name)+1)*sizeof(char));
 					sprintf(conn_req,"%s%s",dir->conn_req,go->f_name);
 				}
-				else 
+				else
 				{
-					/* the file corresponding to base url
-					 * user has not given a file explicitly 
-					 * the url so its the index.html */
-					
-					conn_req=(char *)malloc((strlen(dir->conn_req)+1)*sizeof(char));
-					sprintf(conn_req,"%s",dir->conn_req);
+					if ( dir_tok[no_of_slashes] == NULL ) 
+					{
+						/* the file corresponding to base url
+						 * user has given a file explicitly in
+						 * the url */
+						conn_req=(char *)malloc((strlen(dir->conn_req)+strlen(go->f_name)+1)*sizeof(char));
+						sprintf(conn_req,"%s%s",dir->conn_req,go->f_name);
+					}
+					else 
+					{
+						/* the file corresponding to base url
+						 * user has not given a file explicitly 
+						 * the url so its the index.html */
+						
+						conn_req=(char *)malloc((strlen(dir->conn_req)+1)*sizeof(char));
+						sprintf(conn_req,"%s",dir->conn_req);
+					}
 				}
+				if( go->f_type==HTTP_DIR || go->f_type==HTTP_DIR_NOT_FILLED ) 
+					/* the filled file is directory so it has to end
+					 * with a / */
+					strcat(conn_req,"/");
 			}
-			if( go->f_type==HTTP_DIR || go->f_type==HTTP_DIR_NOT_FILLED ) 
-				/* the filled file is directory so it has to end
-				 * with a / */
-				strcat(conn_req,"/");
-		}
-		comm_buf=(char *)malloc((strlen(conn_req)+20)*sizeof(char));
-		sprintf(comm_buf,"GET %s HTTP/1.0",conn_req);
+			comm_buf=(char *)malloc((strlen(conn_req)+20)*sizeof(char));
+			sprintf(comm_buf,"GET %s HTTP/1.0",conn_req);
 
-		nd = httpfs_make_node (go->f_type,url,conn_req,comm_buf,f_name);
-	  	if (!nd)
-		{
-			err = ENOMEM;
-			return err;
-	 	}
-		free(comm_buf);
-		free(conn_req);
-		free(f_name);
-		*prevp = nd;
-		nd->prevp = prevp;
-		prevp = &nd->next;
-		dir->num_ents++;
-		if (dir->noents)
-			dir->noents = FALSE;
-	}
+			nd = httpfs_make_node (go->f_type,url,conn_req,comm_buf,f_name);
+			if (!nd)
+			{
+				err = ENOMEM;
+				return err;
+			}
+			free(comm_buf);
+			free(conn_req);
+			free(f_name);
+			*prevp = nd;
+			nd->prevp = prevp;
+			prevp = &nd->next;
+			dir->num_ents++;
+			if (dir->noents)
+				dir->noents = FALSE;
+		}
 	}
 	return err;
 }

diff --git a/http.c b/http.c
index 4be45d4..caacfbe 100644
--- a/http.c
+++ b/http.c
@@ -220,23 +220,13 @@ error_t fill_dirnode (struct netnode *dir)
 				 * www.gnu.org/gpl.html will be changed to
 				 * www.gnu.org.gpl.html */
 				conn_req=(char *)malloc((strlen(go->f_name)+8)*sizeof(char));
-				url  = strdup(go->f_name);
-				strcpy(url,strtok(url,"/"));
-				temp = strdup(go->f_name);
-				f_name = (char *) malloc(strlen(go->f_name)*sizeof(char));
-				bzero(f_name,sizeof(f_name));
-				while ( temp!=NULL && strchr(temp,'/') != NULL )
-				{
-					/* find / replace it with . */
-					temp1 = strdup(temp);
-					strcat(f_name,strtok(temp1,"/"));
-					strcpy(temp,strchr(temp,'/'));
-					temp++;  
-					if ( strchr(temp,'/') != NULL )
-						strcat(f_name,".");
-				}
-				if ( strlen(temp) > 0 )
-					strcat(f_name,temp);
+				url = strndup(go->f_name, strchr(go->f_name, '/') - go->f_name);
+				f_name = strdup(go->f_name);
+				int i;
+				for (i = 0; f_name[i] != '\0'; i++)
+					if (f_name[i] == '/')
+						f_name[i] = '.';
+				
 				sprintf(conn_req,"%s%s","http://",go->f_name);
 			}
 			else 
@@ -246,7 +236,10 @@ error_t fill_dirnode (struct netnode *dir)
 				url=strdup(dir->url);
 				if ( go != list_of_entries )
 				{
-					conn_req=(char *)malloc((strlen(dir->conn_req)+strlen(go->f_name)+1)*sizeof(char));
+					size_t conn_req_size = strlen(dir->conn_req) + strlen(go->f_name) + 1;
+					if( go->f_type==HTTP_DIR || go->f_type==HTTP_DIR_NOT_FILLED )
+						conn_req_size++; /* We'll need to add a trailing slash later. */
+					conn_req=(char *)malloc(conn_req_size*sizeof(char));
 					sprintf(conn_req,"%s%s",dir->conn_req,go->f_name);
 				}
 				else
@@ -256,7 +249,10 @@ error_t fill_dirnode (struct netnode *dir)
 						/* the file corresponding to base url
 						 * user has given a file explicitly in
 						 * the url */
-						conn_req=(char *)malloc((strlen(dir->conn_req)+strlen(go->f_name)+1)*sizeof(char));
+						size_t conn_req_size = strlen(dir->conn_req) + strlen(go->f_name) + 1;
+						if( go->f_type==HTTP_DIR || go->f_type==HTTP_DIR_NOT_FILLED )
+							conn_req_size++; /* We'll need to add a trailing slash later. */
+						conn_req=(char *)malloc(conn_req_size*sizeof(char));
 						sprintf(conn_req,"%s%s",dir->conn_req,go->f_name);
 					}
 					else 
@@ -264,8 +260,10 @@ error_t fill_dirnode (struct netnode *dir)
 						/* the file corresponding to base url
 						 * user has not given a file explicitly 
 						 * the url so its the index.html */
-						
-						conn_req=(char *)malloc((strlen(dir->conn_req)+1)*sizeof(char));
+						size_t conn_req_size = strlen(dir->conn_req) + 1;
+						if( go->f_type==HTTP_DIR || go->f_type==HTTP_DIR_NOT_FILLED )
+							conn_req_size++; /* We'll need to add a trailing slash later. */
+						conn_req=(char *)malloc(conn_req_size*sizeof(char));
 						sprintf(conn_req,"%s",dir->conn_req);
 					}
 				}

Reply via email to