Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / storage / size.c
index 594c624..73e6102 100644 (file)
 
 #include "captive/storage.h"   /* self */
 #include "../client/giochannel-blind.h"        /* for captive_giochannel_blind_get_size() */
+#include "../client/giochannel-subrange.h"     /* for captive_giochannel_subrange_get_size() */
 #include "../sandbox/client-CaptiveIOChannel.h"        /* for captive_io_channel_get_size() */
 #include <glib/gmessages.h>
 #include <glib/gtypes.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
-#include <linux/types.h>       /* for __u64 for u64 for BLKGETSIZE64 */
-#define u64 __u64
-#include <linux/fs.h>  /* for BLKGETSIZE64 */
+/* Do not: #include <linux/fs.h>       * for 'BLKGETSIZE64' *
+ * as including any Linux kernel include files is too much incompatible.
+ */
+#include <sys/mount.h> /* for 'BLKGETSIZE' */
+#include "iounixchannel.h"
 
 
-static guint64 size_blind(GIOChannel *iochannel)
+static guint64 size_subrange(GIOChannel *iochannel)
 {
 guint64 r;
 
        g_return_val_if_fail(iochannel!=NULL,0);
 
-       if (!captive_giochannel_blind_get_size(iochannel,&r))
+       if (!captive_giochannel_subrange_get_size(iochannel,&r))
                return 0;
 
        return r;
 }
 
 
-static guint64 size_sandbox(GIOChannel *iochannel)
+static guint64 size_blind(GIOChannel *iochannel)
 {
 guint64 r;
 
        g_return_val_if_fail(iochannel!=NULL,0);
 
-       if (!captive_io_channel_get_size(iochannel,&r))
+       if (!captive_giochannel_blind_get_size(iochannel,&r))
                return 0;
 
        return r;
 }
 
 
-static GIOChannel *iochannel_null;
-
-static int iounixchannel_get_fd(GIOChannel *iochannel)
+static guint64 size_sandbox(GIOChannel *iochannel)
 {
-int r;
-
-       g_return_val_if_fail(iochannel!=NULL,-1);
-
-       if (!iochannel_null) {
-int fd;
-
-               fd=open("/dev/null",O_RDONLY);
-               g_return_val_if_fail(fd!=-1,-1);
-               iochannel_null=g_io_channel_unix_new(fd);
-               g_return_val_if_fail(iochannel_null!=NULL,-1);
-               }
+guint64 r;
 
-       if (iochannel->funcs!=iochannel_null->funcs) {
-               /* Not a UNIX file descriptor */
-               return -1;
-               }
+       g_return_val_if_fail(iochannel!=NULL,0);
 
-       /* It is forbidden to callg_io_channel_unix_get_fd()
-        * if you are not sure it is a 'GIOUnixChannel'.
-        */
-       r=g_io_channel_unix_get_fd(iochannel);
-       g_return_val_if_fail(r!=-1,-1);
+       if (!captive_io_channel_get_size(iochannel,&r))
+               return 0;
 
        return r;
 }
 
 
-static guint64 size_ioctl(GIOChannel *iochannel)
+guint64 captive_giochannel_size_ioctl(GIOChannel *iochannel)
 {
-int fd,err;
+int fd;
 guint64 r;
+long r_long;
 
        g_return_val_if_fail(iochannel!=NULL,0);
 
-       if (-1==(fd=iounixchannel_get_fd(iochannel)))
+       if (-1==(fd=captive_iounixchannel_get_fd(iochannel)))
                return 0;
 
-       if ((err=ioctl(fd,BLKGETSIZE64,&r)))
+#ifdef BLKGETSIZE64
+       if (!ioctl(fd,BLKGETSIZE64,&r))
+               return r;
+#endif
+       if (ioctl(fd,BLKGETSIZE,&r_long))
+               return 0;
+       if (r_long<0)
                return 0;
+       r=((guint64)512)*r_long;
 
        return r;
 }
@@ -116,11 +108,11 @@ off_t offset_orig,offset;
 
        /* We may need '_FILE_OFFSET_BITS=64'.
         * Setting '__USE_FILE_OFFSET64' did not help.
-        * Done by 'AC_SYS_LARGEFILE' of configure.in.
+        * Done by 'AC_SYS_LARGEFILE' of configure.ac.
         */
        g_return_val_if_fail(sizeof(offset)==sizeof(guint64),0);
 
-       if (-1==(fd=iounixchannel_get_fd(iochannel)))
+       if (-1==(fd=captive_iounixchannel_get_fd(iochannel)))
                return 0;
 
        if (-1==(offset_orig=lseek(fd,0,SEEK_CUR)))
@@ -208,11 +200,13 @@ guint64 captive_giochannel_size(GIOChannel *iochannel)
 {
 guint64 r;
 
+       if ((r=size_subrange(iochannel)))
+               return r;
        if ((r=size_blind(iochannel)))
                return r;
        if ((r=size_sandbox(iochannel)))
                return r;
-       if ((r=size_ioctl(iochannel)))
+       if ((r=captive_giochannel_size_ioctl(iochannel)))
                return r;
        if ((r=size_seek(iochannel)))
                return r;