Re: feature request -- zip archives support

Radomir Dopieralski <[email protected]> Thu, 25 Nov 2004 11:02:26 +0100
Newsgroups gmane.comp.gnome.apps.gqview.user
Message-ID <[email protected]>
Dnia Sun, Nov 21, 2004 at 01:22:26PM +0100, Radomir Dopieralski napisal: 
> I want to try to add such a feature to gqview by myself, but the chances
> of success are rather slim -- I'm no expert programmer, have no knowledge
> of gtk, and I don't know the sources very well -- plus I'm short on time
> to spare for this effort.

Ok, I've hacked on the sources until it worked.
It uses zziplib 0.13.*, and is really ugly.  But it works.
It probably breaks many things, like the utf8 paths, etc. and all the
changes are not behind #ifdef's.
Also, I'm not sure how to add zziplib to the configure script, so I just
edit the resulting Makefile and add -lzzip to the LIBS variable.

I hope that this hack will prove somehow useful. It's for gqview-1.5.4.

I attach the diff of the src subdirectory.


-- 
  Radomir          @**@_  Bee!     Create your own computer role playing
`The Sheep'        ('') 3          game using the great H-World engine!
Dopieralski   .vvVvVVVVVVvVVvv.v.  http://h-world.simugraph.com/
zziplib.diff (text/plain, 8.9 KB)
diff -ur gqview-1.5.4/src/filelist.c gqview/gqview-1.5.4/src/filelist.c
--- gqview-1.5.4/src/filelist.c	2004-09-28 18:16:18.000000000 +0200
+++ gqview/gqview-1.5.4/src/filelist.c	2004-11-22 19:55:23.182668024 +0100
@@ -658,8 +658,8 @@
 
 gint filelist_read(const gchar *path, GList **files, GList **dirs)
 {
-	DIR *dp;
-	struct dirent *dir;
+	ZZIP_DIR *dp;
+	struct zzip_dirent *dir;
 	struct stat ent_sbuf;
 	gchar *pathl;
 	GList *dlist;
@@ -669,7 +669,7 @@
 	flist = NULL;
 
 	pathl = path_from_utf8(path);
-	if (!pathl || (dp = opendir(pathl)) == NULL)
+	if (!pathl || (dp = zzip_opendir(pathl)) == NULL)
 		{
 		g_free(pathl);
 		if (files) *files = NULL;
@@ -684,15 +684,26 @@
 		pathl = g_strdup("");
 		}
 
-	while ((dir = readdir(dp)) != NULL)
+	while ((dir = zzip_readdir(dp)) != NULL)
 		{
 		gchar *name = dir->d_name;
 		if (show_dot_files || !ishidden(name))
 			{
 			gchar *filepath = g_strconcat(pathl, "/", name, NULL);
-			if (stat(filepath, &ent_sbuf) >= 0)
+			if ((stat(filepath, &ent_sbuf) >= 0)||(!zzip_dir_real(dp)))
 				{
-				if (S_ISDIR(ent_sbuf.st_mode))
+                                gint l = strlen(name);
+                                gint iszip = 0;
+                                if ((name[l-1]=='p')&&
+                                        (name[l-2]=='i')&&
+                                        (name[l-3]=='z')&&
+                                        (name[l-4]=='.')) {
+                                    name[l-4] = '\0';
+                                    l=strlen(filepath);
+                                    filepath[l-4] = '\0';
+                                    iszip = 1;
+                                }
+				if ((S_ISDIR(ent_sbuf.st_mode))|| iszip)
 					{
 					/* we ignore the .thumbnails dir for cleanliness */
 					if ((dirs) &&
@@ -715,7 +726,7 @@
 			}
 		}
 
-	closedir(dp);
+	zzip_closedir(dp);
 
 	g_free(pathl);
 
diff -ur gqview-1.5.4/src/gqview.h gqview/gqview-1.5.4/src/gqview.h
--- gqview-1.5.4/src/gqview.h	2004-09-15 00:59:57.000000000 +0200
+++ gqview/gqview-1.5.4/src/gqview.h	2004-11-21 20:52:55.000000000 +0100
@@ -40,6 +40,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <fcntl.h>
+#include <zzip/lib.h>
 
 /*
  *-------------------------------------
diff -ur gqview-1.5.4/src/image-load.c gqview/gqview-1.5.4/src/image-load.c
--- gqview-1.5.4/src/image-load.c	2004-09-28 17:45:39.000000000 +0200
+++ gqview/gqview-1.5.4/src/image-load.c	2004-11-21 21:27:55.000000000 +0100
@@ -16,6 +16,7 @@
 #include "ui_fileops.h"
 
 #include <fcntl.h>
+#include <zzip.h>
 
 
 /* the number of bytes to read per idle call (define x 512 bytes) */
@@ -75,10 +76,10 @@
 		il->loader = NULL;
 		}
 
-	if (il->load_fd != -1)
+	if (il->load_zf != NULL)
 		{
-		close(il->load_fd);
-		il->load_fd = -1;
+		zzip_close(il->load_zf);
+		il->load_zf = NULL;
 		}
 
 	il->done = TRUE;
@@ -128,7 +129,7 @@
 	c = il->buffer_size ? il->buffer_size : 1;
 	while (c > 0)
 		{
-		b = read(il->load_fd, &buf, sizeof(buf));
+		b = zzip_read(il->load_zf, &buf, sizeof(buf));
 
 		if (b == 0)
 			{
@@ -162,7 +163,7 @@
 
 	if (!il->loader || il->pixbuf) return FALSE;
 
-	b = read(il->load_fd, &buf, sizeof(buf));
+	b = zzip_read(il->load_zf, &buf, sizeof(buf));
 
 	if (b < 1)
 		{
@@ -192,7 +193,7 @@
 			/* read until size is known */
 			while(il->loader && !gdk_pixbuf_loader_get_pixbuf(il->loader) && b > 0)
 				{
-				b = read(il->load_fd, &buf, sizeof(buf));
+				b = zzip_read(il->load_zf, &buf, sizeof(buf));
 				if (b < 0 || (b > 0 && !gdk_pixbuf_loader_write(il->loader, buf, b, NULL)))
 					{
 					image_loader_stop(il);
@@ -235,17 +236,18 @@
 
 static gint image_loader_setup(ImageLoader *il)
 {
-	struct stat st;
+	//struct stat st;
+        ZZIP_STAT st;
 	gchar *pathl;
 
 	if (!il) return FALSE;
 
 	pathl = path_from_utf8(il->path);
-	il->load_fd = open(pathl, O_RDONLY | O_NONBLOCK);
+	il->load_zf = zzip_open(pathl, O_RDONLY | O_NONBLOCK);
 	g_free(pathl);
-	if (il->load_fd == -1) return FALSE;
+	if (il->load_zf == NULL) return FALSE;
 
-	if (fstat(il->load_fd, &st) == 0)
+	if (zzip_fstat(il->load_zf, &st) == 0)
 		{
 		il->bytes_total = st.st_size;
 		}
diff -ur gqview-1.5.4/src/typedefs.h gqview/gqview-1.5.4/src/typedefs.h
--- gqview-1.5.4/src/typedefs.h	2004-09-25 19:58:34.000000000 +0200
+++ gqview/gqview-1.5.4/src/typedefs.h	2004-11-21 19:03:05.000000000 +0100
@@ -80,7 +80,8 @@
 	gint idle_priority;
 
 	GdkPixbufLoader *loader;
-	gint load_fd;
+//	gint load_fd;
+        ZZIP_FILE *load_zf;
 
 	void (*func_area_ready)(ImageLoader *, guint x, guint y, guint w, guint h, gpointer);
 	void (*func_error)(ImageLoader *, gpointer);
diff -ur gqview-1.5.4/src/ui_fileops.c gqview/gqview-1.5.4/src/ui_fileops.c
--- gqview-1.5.4/src/ui_fileops.c	2004-11-08 23:32:49.000000000 +0100
+++ gqview/gqview-1.5.4/src/ui_fileops.c	2004-11-22 19:50:17.421150840 +0100
@@ -29,6 +29,8 @@
 
 #include "ui_utildlg.h"	/* for locale warning dialog */
 
+#include <zzip/lib.h>
+
 /*
  *-----------------------------------------------------------------------------
  * generic file information and manipulation routines (public)
@@ -184,7 +186,6 @@
 {
 	gchar *sl;
 	gint ret;
-
 	if (!s) return FALSE;
 	sl = path_from_utf8(s);
 	ret = (stat(sl, st) == 0);
@@ -193,25 +194,69 @@
 	return ret;
 }
 
+
 gint isname(const gchar *s)
 {
 	struct stat st;
 
-	return stat_utf8(s, &st);
+	if (stat_utf8(s, &st)) {
+            return TRUE;
+        } else {
+            ZZIP_FILE *zf;
+            zf = zzip_open(s, O_RDONLY | O_NONBLOCK);
+            if (zf==NULL) {
+                ZZIP_DIR *zd;
+                zd = zzip_opendir(s);
+                if (zd==NULL) {
+                    return FALSE;
+                } else {
+                    zzip_closedir(zd);
+                    return TRUE;
+                }
+            } else {
+                zzip_close(zf);
+                return TRUE;
+            }
+        }
 }
 
 gint isfile(const gchar *s)
 {
 	struct stat st;
 
-	return (stat_utf8(s, &st) && S_ISREG(st.st_mode));
+	if (stat_utf8(s, &st)) {
+            return S_ISREG(st.st_mode);
+        } else {
+            ZZIP_FILE *zf;
+            zf = zzip_open(s, O_RDONLY | O_NONBLOCK);
+            if (zf==NULL) {
+                return FALSE;
+            } else {
+                zzip_close(zf);
+                return TRUE;
+            }
+        }
 }
 
 gint isdir(const gchar *s)
 {
 	struct stat st;
+        gint l;
    
-	return (stat_utf8(s ,&st) && S_ISDIR(st.st_mode));
+        if (stat_utf8(s ,&st)) {
+                if (S_ISDIR(st.st_mode)) {
+                    return TRUE;
+                }
+        } else {
+                ZZIP_DIR *zd;
+                zd = zzip_opendir(s);
+                if (zd==NULL) {
+                    return FALSE;
+                } else {
+                    zzip_closedir(zd);
+                    return TRUE;
+                }
+        }
 }
 
 gint64 filesize(const gchar *s)
@@ -482,8 +527,8 @@
 
 gint path_list(const gchar *path, GList **files, GList **dirs)
 {
-	DIR *dp;
-	struct dirent *dir;
+	ZZIP_DIR *dp;
+	struct zzip_dirent *dir;
 	struct stat ent_sbuf;
 	GList *f_list = NULL;
 	GList *d_list = NULL;
@@ -492,7 +537,7 @@
 	if (!path) return FALSE;
 
 	pathl = path_from_utf8(path);
-	dp = opendir(pathl);
+	dp = zzip_opendir(pathl);
 	if (!dp)
 		{
 		/* dir not found */
@@ -507,23 +552,40 @@
 		pathl = g_strdup("");
 		}
 
-	while ((dir = readdir(dp)) != NULL)
+	while ((dir = zzip_readdir(dp)) != NULL)
 		{
 		/* skip removed files */
-		if (dir->d_ino > 0)
-			{
+//		if (dir->d_ino > 0)
+//			{
 			gchar *name = dir->d_name;
 			gchar *filepath = g_strconcat(pathl, "/", name, NULL);
-			if (stat(filepath, &ent_sbuf) >= 0)
+			if ((stat(filepath, &ent_sbuf) >= 0)||(!zzip_dir_real(dp)))
 				{
+                                gint isdir = 0;
 				gchar *path8;
 				gchar *name8;
 
+
+                                if ((zzip_dir_real(dp))) {
+                                    gint l;
+
+                                    l = strlen(name);
+                                    if (S_ISDIR(ent_sbuf.st_mode)) {
+                                            isdir==1;
+                                    } else if ((name[l-1]=='p')&&
+                                            (name[l-2]=='i')&&
+                                            (name[l-3]=='z')&&
+                                            (name[l-4]=='.')) {
+                                        name[l-4]='\0';
+                                        isdir==1;
+                                    } 
+                                }
+
 				name8 = path_to_utf8(name);
 				path8 = g_strconcat(path, "/", name8, NULL);
 				g_free(name8);
 
-				if (dirs && S_ISDIR(ent_sbuf.st_mode) &&
+				if ((dirs && isdir) && 
 				    !(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) )
 					{
 					d_list = g_list_prepend(d_list, path8);
@@ -537,9 +599,9 @@
 				g_free(path8);
 				}
 			g_free(filepath);
-			}
+//			}
 		}
-	closedir(dp);
+	zzip_closedir(dp);
 
 	g_free(pathl);