source: trunk/third/gnome-vfs/libgnomevfs/gnome-vfs-utils.c @ 15497

Revision 15497, 18.4 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15496, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* gnome-vfs-utils.c - Private utility functions for the GNOME Virtual
3   File System.
4
5   Copyright (C) 1999 Free Software Foundation
6   Copyright (C) 2000 Eazel, Inc.
7
8   The Gnome Library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Library General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.
12
13   The Gnome Library is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Library General Public License for more details.
17
18   You should have received a copy of the GNU Library General Public
19   License along with the Gnome Library; see the file COPYING.LIB.  If not,
20   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.
22
23   Authors: Ettore Perazzoli <ettore@comm2000.it>
24            John Sullivan <sullivan@eazel.com>
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31#ifdef HAVE_SYS_PARAM_H
32#include <sys/param.h>
33#endif
34
35#include "gnome-vfs.h"
36#include "gnome-vfs-private.h"
37#include "gnome-vfs-private-utils.h"
38
39#include <ctype.h>
40#include <stdlib.h>
41#include <string.h>
42#include <sys/stat.h>
43#include <sys/types.h>
44#if HAVE_SYS_STATVFS_H
45#include <sys/statvfs.h>
46#endif
47#if HAVE_SYS_VFS_H
48#include <sys/vfs.h>
49#elif HAVE_SYS_MOUNT_H
50#include <sys/mount.h>
51#endif
52
53gchar*
54gnome_vfs_format_file_size_for_display (GnomeVFSFileSize bytes)
55{
56        if (bytes < (GnomeVFSFileSize) 1e3) {
57                if (bytes == 1)
58                        return g_strdup (_("1 byte"));
59                else
60                        return g_strdup_printf (_("%u bytes"),
61                                                       (guint) bytes);
62        } else {
63                gdouble displayed_size;
64
65                if (bytes < (GnomeVFSFileSize) 1e6) {
66                        displayed_size = (gdouble) bytes / 1.0e3;
67                        return g_strdup_printf (_("%.1fK"),
68                                                       displayed_size);
69                } else if (bytes < (GnomeVFSFileSize) 1e9) {
70                        displayed_size = (gdouble) bytes / 1.0e6;
71                        return g_strdup_printf (_("%.1fM"),
72                                                       displayed_size);
73                } else {
74                        displayed_size = (gdouble) bytes / 1.0e9;
75                        return g_strdup_printf (_("%.1fG"),
76                                                       displayed_size);
77                }
78        }
79}
80
81typedef enum {
82        UNSAFE_ALL        = 0x1,  /* Escape all unsafe characters   */
83        UNSAFE_ALLOW_PLUS = 0x2,  /* Allows '+'  */
84        UNSAFE_PATH       = 0x4,  /* Allows '/' and '?' and '&' and '='  */
85        UNSAFE_DOS_PATH   = 0x8,  /* Allows '/' and '?' and '&' and '=' and ':' */
86        UNSAFE_HOST       = 0x10, /* Allows '/' and ':' and '@' */
87        UNSAFE_SLASHES    = 0x20  /* Allows all characters except for '/' and '%' */
88} UnsafeCharacterSet;
89
90static const guchar acceptable[96] =
91{ /* X0   X1   X2   X3   X4   X5   X6   X7   X8   X9   XA   XB   XC   XD   XE   XF */
92    0x00,0x3F,0x20,0x20,0x20,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x22,0x20,0x3F,0x3F,0x1C, /* 2X  !"#$%&'()*+,-./   */
93    0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x2C, /* 3X 0123456789:;<=>?   */
94    0x30,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, /* 4X @ABCDEFGHIJKLMNO   */
95    0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, /* 5X PQRSTUVWXYZ[\]^_   */
96    0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, /* 6X `abcdefghijklmno   */
97    0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20  /* 7X pqrstuvwxyz{|}~DEL */
98};
99
100enum {
101        RESERVED = 1,
102        UNRESERVED,
103        DELIMITERS,
104        UNWISE,
105        CONTROL,
106        SPACE   
107};
108
109static const guchar uri_character_kind[128] =
110{
111    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
112    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
113    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
114    CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,CONTROL   ,
115    /* ' '        !          "          #          $          %          &          '      */
116    SPACE     ,UNRESERVED,DELIMITERS,DELIMITERS,RESERVED  ,DELIMITERS,RESERVED  ,UNRESERVED,
117    /*  (         )          *          +          ,          -          .          /      */
118    UNRESERVED,UNRESERVED,UNRESERVED,RESERVED  ,RESERVED  ,UNRESERVED,UNRESERVED,RESERVED  ,
119    /*  0         1          2          3          4          5          6          7      */
120    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
121    /*  8         9          :          ;          <          =          >          ?      */
122    UNRESERVED,UNRESERVED,RESERVED  ,RESERVED  ,DELIMITERS,RESERVED  ,DELIMITERS,RESERVED  ,
123    /*  @         A          B          C          D          E          F          G      */
124    RESERVED  ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
125    /*  H         I          J          K          L          M          N          O      */
126    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
127    /*  P         Q          R          S          T          U          V          W      */
128    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
129    /*  X         Y          Z          [          \          ]          ^          _      */
130    UNRESERVED,UNRESERVED,UNRESERVED,UNWISE    ,UNWISE    ,UNWISE    ,UNWISE    ,UNRESERVED,
131    /*  `         a          b          c          d          e          f          g      */
132    UNWISE    ,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
133    /*  h         i          j          k          l          m          n          o      */
134    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
135    /*  p         q          r          s          t          u          v          w      */
136    UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,UNRESERVED,
137    /*  x         y          z         {           |          }          ~         DEL     */
138    UNRESERVED,UNRESERVED,UNRESERVED,UNWISE    ,UNWISE    ,UNWISE    ,UNRESERVED,CONTROL
139};
140
141
142/*  Below modified from libwww HTEscape.c */
143
144#define HEX_ESCAPE '%'
145
146/*  Escape undesirable characters using %
147 *  -------------------------------------
148 *
149 * This function takes a pointer to a string in which
150 * some characters may be unacceptable unescaped.
151 * It returns a string which has these characters
152 * represented by a '%' character followed by two hex digits.
153 *
154 * This routine returns a g_malloced string.
155 */
156
157static const gchar hex[16] = "0123456789ABCDEF";
158
159static gchar *
160gnome_vfs_escape_string_internal (const gchar *string,
161                                  UnsafeCharacterSet mask)
162{
163#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
164
165        const gchar *p;
166        gchar *q;
167        gchar *result;
168        guchar c;
169        gint unacceptable;
170        UnsafeCharacterSet use_mask;
171
172        g_return_val_if_fail (mask == UNSAFE_ALL
173                              || mask == UNSAFE_ALLOW_PLUS
174                              || mask == UNSAFE_PATH
175                              || mask == UNSAFE_DOS_PATH
176                              || mask == UNSAFE_HOST
177                              || mask == UNSAFE_SLASHES, NULL);
178
179        if (string == NULL) {
180                return NULL;
181        }
182       
183        unacceptable = 0;
184        use_mask = mask;
185        for (p = string; *p != '\0'; p++) {
186                c = *p;
187                if (!ACCEPTABLE (c)) {
188                        unacceptable++;
189                }
190                if ((use_mask == UNSAFE_HOST) &&
191                    (unacceptable || (c == '/'))) {
192                        /* when escaping a host, if we hit something that needs to be escaped, or we finally
193                         * hit a path separator, revert to path mode (the host segment of the url is over).
194                         */
195                        use_mask = UNSAFE_PATH;
196                }
197        }
198       
199        result = g_malloc (p - string + unacceptable * 2 + 1);
200
201        use_mask = mask;
202        for (q = result, p = string; *p != '\0'; p++){
203                c = *p;
204               
205                if (!ACCEPTABLE (c)) {
206                        *q++ = HEX_ESCAPE; /* means hex coming */
207                        *q++ = hex[c >> 4];
208                        *q++ = hex[c & 15];
209                } else {
210                        *q++ = c;
211                }
212                if ((use_mask == UNSAFE_HOST) &&
213                    (!ACCEPTABLE (c) || (c == '/'))) {
214                        use_mask = UNSAFE_PATH;
215                }
216        }
217       
218        *q = '\0';
219       
220        return result;
221}
222
223gchar *
224gnome_vfs_escape_string (const gchar *file_name)
225{
226        return gnome_vfs_escape_string_internal (file_name, UNSAFE_ALL);
227}
228
229gchar *
230gnome_vfs_escape_path_string (const gchar *path)
231{
232        return gnome_vfs_escape_string_internal (path, UNSAFE_PATH);
233}
234
235gchar *
236gnome_vfs_escape_host_and_path_string (const gchar *path)
237{
238        return gnome_vfs_escape_string_internal (path, UNSAFE_HOST);
239}
240
241gchar *
242gnome_vfs_escape_slashes (const gchar *string)
243{
244        return gnome_vfs_escape_string_internal (string, UNSAFE_SLASHES);
245}
246
247char *
248gnome_vfs_escape_set (const char *string,
249                      const char *match_set)
250{
251        char *result;
252        const char *scanner;
253        char *result_scanner;
254        int escape_count;
255
256        escape_count = 0;
257
258        if (string == NULL) {
259                return NULL;
260        }
261
262        if (match_set == NULL) {
263                return g_strdup (string);
264        }
265       
266        for (scanner = string; *scanner != '\0'; scanner++) {
267                if (strchr(match_set, *scanner) != NULL) {
268                        /* this character is in the set of characters
269                         * we want escaped.
270                         */
271                        escape_count++;
272                }
273        }
274       
275        if (escape_count == 0) {
276                return g_strdup (string);
277        }
278
279        /* allocate two extra characters for every character that
280         * needs escaping and space for a trailing zero
281         */
282        result = g_malloc (scanner - string + escape_count * 2 + 1);
283        for (scanner = string, result_scanner = result; *scanner != '\0'; scanner++) {
284                if (strchr(match_set, *scanner) != NULL) {
285                        /* this character is in the set of characters
286                         * we want escaped.
287                         */
288                        *result_scanner++ = HEX_ESCAPE;
289                        *result_scanner++ = hex[*scanner >> 4];
290                        *result_scanner++ = hex[*scanner & 15];
291                       
292                } else {
293                        *result_scanner++ = *scanner;
294                }
295        }
296
297        *result_scanner = '\0';
298
299        return result;
300}
301
302static int
303hex_to_int (gchar c)
304{
305        return  c >= '0' && c <= '9' ? c - '0'
306                : c >= 'A' && c <= 'F' ? c - 'A' + 10
307                : c >= 'a' && c <= 'f' ? c - 'a' + 10
308                : -1;
309}
310
311static int
312unescape_character (const char *scanner)
313{
314        int first_digit;
315        int second_digit;
316
317        first_digit = hex_to_int (*scanner++);
318        if (first_digit < 0) {
319                return -1;
320        }
321
322        second_digit = hex_to_int (*scanner++);
323        if (second_digit < 0) {
324                return -1;
325        }
326
327        return (first_digit << 4) | second_digit;
328}
329
330/*  Decode %xx escaped characters
331**  -----------------------------
332**
333** This function takes a pointer to a string in which some
334** characters may have been encoded in %xy form, where xy is
335** the ASCII hex code for character 16x+y.
336*/
337
338gchar *
339gnome_vfs_unescape_string (const gchar *escaped, const gchar *illegal_characters)
340{
341        const gchar *in;
342        gchar *out, *result;
343        gint character;
344       
345        if (escaped == NULL) {
346                return NULL;
347        }
348
349        result = g_malloc (strlen (escaped) + 1);
350       
351        out = result;
352        for (in = escaped; *in != '\0'; in++) {
353                character = *in;
354                if (*in == HEX_ESCAPE) {
355                        character = unescape_character (in + 1);
356
357                        /* Check for an illegal character. We consider '\0' illegal here. */
358                        if (character <= 0
359                            || (illegal_characters != NULL
360                                && strchr (illegal_characters, (char)character) != NULL)) {
361                                g_free (result);
362                                return NULL;
363                        }
364                        in += 2;
365                }
366                *out++ = (char)character;
367        }
368       
369        *out = '\0';
370        g_assert (out - result <= strlen (escaped));
371        return result;
372       
373}
374
375/**
376 * gnome_vfs_unescape_for_display:
377 * @escaped: The string encoded with escaped sequences
378 *
379 * Similar to gnome_vfs_unescape_string, but it returns something
380 * semi-intelligable to a user even upon receiving traumatic input
381 * such as %00 or URIs in bad form.
382 *
383 * See also: gnome_vfs_unescape_string.
384 *
385 * Return value: A pointer to a g_malloc'd string with all characters
386 *               replacing their escaped hex values
387 **/
388gchar *
389gnome_vfs_unescape_string_for_display (const gchar *escaped)
390{
391        const gchar *in, *start_escape;
392        gchar *out, *result;
393        gint i,j;
394        gchar c;
395        gint invalid_escape;
396
397        if (escaped == NULL) {
398                return NULL;
399        }
400
401        result = g_malloc (strlen (escaped) + 1);
402       
403        out = result;
404        for (in = escaped; *in != '\0'; ) {
405                start_escape = in;
406                c = *in++;
407                invalid_escape = 0;
408               
409                if (c == HEX_ESCAPE) {
410                        /* Get the first hex digit. */
411                        i = hex_to_int (*in++);
412                        if (i < 0) {
413                                invalid_escape = 1;
414                                in--;
415                        }
416                        c = i << 4;
417                       
418                        if (invalid_escape == 0) {
419                                /* Get the second hex digit. */
420                                i = hex_to_int (*in++);
421                                if (i < 0) {
422                                        invalid_escape = 2;
423                                        in--;
424                                }
425                                c |= i;
426                        }
427                        if (invalid_escape == 0) {
428                                /* Check for an illegal character. */
429                                if (c == '\0') {
430                                        invalid_escape = 3;
431                                }
432                        }
433                }
434                if (invalid_escape != 0) {
435                        for (j = 0; j < invalid_escape; j++) {
436                                *out++ = *start_escape++;
437                        }
438                } else {
439                        *out++ = c;
440                }
441        }
442       
443        *out = '\0';
444        g_assert (out - result <= strlen (escaped));
445        return result;
446}
447
448/**
449 * gnome_vfs_remove_optional_escapes:
450 * @uri: an escaped uri
451 *
452 * Scans the uri and converts characters that do not have to be
453 * escaped into an un-escaped form. The characters that get treated this
454 * way are defined as unreserved by the RFC.
455 *
456 * Return value: an error value if the uri is found to be malformed.
457 **/
458GnomeVFSResult
459gnome_vfs_remove_optional_escapes (char *uri)
460{
461        guchar *scanner;
462        int character;
463        int length;
464
465        if (uri == NULL) {
466                return GNOME_VFS_OK;
467        }
468       
469        length = strlen (uri);
470
471        for (scanner = uri; *scanner != '\0'; scanner++, length--) {
472                if (*scanner == HEX_ESCAPE) {
473                        character = unescape_character (scanner + 1);
474                        if (character < 0) {
475                                /* invalid hexadecimal character */
476                                return GNOME_VFS_ERROR_INVALID_URI;
477                        }
478
479                        if (uri_character_kind [character] == UNRESERVED) {
480                                /* This character does not need to be escaped, convert it
481                                 * to a non-escaped form.
482                                 */
483                                *scanner = (guchar)character;
484                                g_assert (length >= 3);
485
486                                /* Shrink the string covering up the two extra digits of the
487                                 * escaped character. Include the trailing '\0' in the copy
488                                 * to keep the string terminated.
489                                 */
490                                memmove (scanner + 1, scanner + 3, length - 2);
491                        } else {
492                                /* This character must stay escaped, skip the entire
493                                 * escaped sequence
494                                 */
495                                scanner += 2;
496                        }
497                        length -= 2;
498
499                } else if (*scanner > 127
500                        || uri_character_kind [*scanner] == DELIMITERS
501                        || uri_character_kind [*scanner] == UNWISE
502                        || uri_character_kind [*scanner] == CONTROL) {
503                        /* It is illegal for this character to be in an un-escaped form
504                         * in the uri.
505                         */
506                        return GNOME_VFS_ERROR_INVALID_URI;
507                }
508        }
509        return GNOME_VFS_OK;
510}
511
512char *
513gnome_vfs_make_uri_canonical (const char *original_uri_text)
514{
515        /* For now use a sub-optimal implementation involving a
516         * conversion to GnomeVFSURI and back.
517         */
518        GnomeVFSURI *uri;
519        char *result;
520
521        uri = gnome_vfs_uri_new_private (original_uri_text, TRUE);
522        if (uri == NULL) {
523                return NULL;;
524        }
525
526        result = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
527        gnome_vfs_uri_unref (uri);
528
529        return result;
530}
531
532
533/**
534 * gnome_vfs_make_canonical_pathname:
535 * @path: a file path, relative or absolute
536 *
537 * Calls gnome_vfs_canonicalize_pathname, allocating storage for the result and
538 * providing for a cleaner memory management.
539 *
540 * Return value: a canonical version of @path
541 **/
542gchar *
543gnome_vfs_make_path_name_canonical (const gchar *path)
544{
545        char *path_clone;
546        char *result;
547
548        path_clone = g_strdup (path);
549        result = gnome_vfs_canonicalize_pathname (path_clone);
550        if (result != path_clone) {
551                g_free (path_clone);
552                return g_strdup (result);
553        }
554
555        return path_clone;
556}
557
558void
559gnome_vfs_list_deep_free (GList *list)
560{
561        GList *p;
562
563        if (list == NULL)
564                return;
565
566        for (p = list; p != NULL; p = p->next) {
567                g_free (p->data);
568        }
569        g_list_free (list);
570}
571
572/* Stolen from Nautilus. This belongs in glib. */
573static gboolean
574istr_has_prefix (const char *haystack, const char *needle)
575{
576        const char *h, *n;
577        char hc, nc;
578
579        /* Eat one character at a time. */
580        h = haystack == NULL ? "" : haystack;
581        n = needle == NULL ? "" : needle;
582        do {
583                if (*n == '\0') {
584                        return TRUE;
585                }
586                if (*h == '\0') {
587                        return FALSE;
588                }
589                hc = *h++;
590                nc = *n++;
591                if (isupper ((guchar)hc)) {
592                        hc = tolower ((guchar)hc);
593                }
594                if (isupper ((guchar)nc)) {
595                        nc = tolower ((guchar)nc);
596                }
597        } while (hc == nc);
598        return FALSE;
599}
600
601/**
602 * gnome_vfs_get_local_path_from_uri:
603 *
604 * Return a local path for a file:// URI.
605 *
606 * Return value: the local path or NULL on error.
607 **/
608char *
609gnome_vfs_get_local_path_from_uri (const char *uri)
610{
611        char *result, *unescaped_uri;
612
613        if (uri == NULL) {
614                return NULL;
615        }
616
617        unescaped_uri = gnome_vfs_unescape_string (uri, "/");
618        if (unescaped_uri == NULL) {
619                return NULL;
620        }
621
622        if (istr_has_prefix (unescaped_uri, "file://")) {
623                result = g_strdup (unescaped_uri + 7);
624        } else if (unescaped_uri[0] == '/') {
625                result = g_strdup (unescaped_uri);
626        } else {
627                result = NULL;
628        }
629
630        g_free (unescaped_uri);
631
632        return result;
633}
634
635/**
636 * gnome_vfs_get_uri_from_local_path:
637 *
638 * Return a file:// URI for a local path.
639 *
640 * Return value: the URI (NULL for some bad errors).
641 **/
642char *
643gnome_vfs_get_uri_from_local_path (const char *local_path)
644{
645        char *escaped_path, *result;
646       
647        if (local_path == NULL) {
648                return NULL;
649        }
650
651        g_return_val_if_fail (local_path[0] == '/', NULL);
652
653        escaped_path = gnome_vfs_escape_path_string (local_path);
654        result = g_strconcat ("file://", escaped_path, NULL);
655        g_free (escaped_path);
656        return result;
657}
658
659static gboolean
660str_has_prefix (const char *haystack, const char *needle)
661{
662        const char *h, *n;
663
664        /* Eat one character at a time. */
665        h = haystack == NULL ? "" : haystack;
666        n = needle == NULL ? "" : needle;
667        do {
668                if (*n == '\0') {
669                        return TRUE;
670                }
671                if (*h == '\0') {
672                        return FALSE;
673                }
674        } while (*h++ == *n++);
675        return FALSE;
676}
677
678/* gnome_vfs_get_volume_free_space
679 *
680 * Return total amount of free space on a volume.
681 * This only works for local file systems with
682 * the file: scheme.
683 */
684GnomeVFSResult
685gnome_vfs_get_volume_free_space (const GnomeVFSURI *vfs_uri, GnomeVFSFileSize *size)
686{       
687        size_t total_blocks, block_size;
688        int statfs_result;
689        const char *path, *scheme;
690#if HAVE_STATVFS
691        struct statvfs statfs_buffer;
692#else
693        struct statfs statfs_buffer;
694#endif
695
696        *size = 0;
697
698        /* We can't check non local systems */
699        if (!gnome_vfs_uri_is_local (vfs_uri)) {
700                return GNOME_VFS_ERROR_NOT_SUPPORTED;
701        }
702
703        path = gnome_vfs_uri_get_path (vfs_uri);
704        scheme = gnome_vfs_uri_get_scheme (vfs_uri);
705       
706        /* We only handle the file: scheme for now */
707        if (!str_has_prefix (scheme, "file") || !str_has_prefix (path, "/")) {
708                return GNOME_VFS_ERROR_NOT_SUPPORTED;
709        }
710
711#if HAVE_STATVFS
712        statfs_result = statvfs ("/", &statfs_buffer);
713#else
714        statfs_result = statfs ("/", &statfs_buffer);   
715#endif 
716
717        g_return_val_if_fail (statfs_result == 0, FALSE);
718        block_size = statfs_buffer.f_bsize;
719        total_blocks = statfs_buffer.f_blocks;
720
721        *size = block_size * total_blocks;
722
723        return GNOME_VFS_OK;
724}
725
726
727
728
Note: See TracBrowser for help on using the repository browser.