Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$

vfs.c

Go to the documentation of this file.
00001 /*  Audacious
00002  *  Copyright (c) 2006-2007 William Pitcock
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; under version 3 of the License.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program.  If not, see <http://www.gnu.org/licenses>.
00015  *
00016  *  The Audacious team does not consider modular code linking to
00017  *  Audacious or using our public API to be a derived work.
00018  */
00019 
00020 #include "vfs.h"
00021 #include "audstrings.h"
00022 #include <stdio.h>
00023 #include <unistd.h>
00024 #include <sys/stat.h>
00025 #include <sys/types.h>
00026 #include <string.h>
00027 
00028 
00033 GList *vfs_transports = NULL; /* temporary. -nenolod */
00034 
00035 
00041 void vfs_register_transport (VFSConstructor * vtable)
00042 {
00043     vfs_transports = g_list_append (vfs_transports, vtable);
00044 }
00045 
00046 static VFSConstructor *
00047 vfs_get_constructor(const gchar *path)
00048 {
00049     VFSConstructor *vtable = NULL;
00050     GList *node;
00051 
00052     if (path == NULL)
00053         return NULL;
00054 
00055     for (node = vfs_transports; node != NULL; node = g_list_next(node))
00056     {
00057         VFSConstructor *vtptr = (VFSConstructor *) node->data;
00058 
00059         if (!strncasecmp(path, vtptr->uri_id, strlen(vtptr->uri_id)))
00060         {
00061             vtable = vtptr;
00062             break;
00063         }
00064     }
00065 
00066     /* No transport vtable has been registered, bail. */
00067     if (vtable == NULL)
00068         g_warning("Could not open '%s', no transport plugin available.", path);
00069 
00070     return vtable;
00071 }
00072 
00081 VFSFile *
00082 vfs_fopen(const gchar * path,
00083           const gchar * mode)
00084 {
00085     VFSFile *file;
00086     VFSConstructor *vtable = NULL;
00087 
00088     if (path == NULL || mode == NULL || (vtable = vfs_get_constructor(path)) == NULL)
00089         return NULL;
00090 
00091     file = vtable->vfs_fopen_impl(path, mode);
00092 
00093     if (file == NULL)
00094         return NULL;
00095 
00096     file->uri = g_strdup(path);
00097     file->base = vtable;
00098     file->ref = 1;
00099 
00100     return file;
00101 }
00102 
00109 gint
00110 vfs_fclose(VFSFile * file)
00111 {
00112     gint ret = 0;
00113 
00114     if (file == NULL)
00115         return -1;
00116 
00117     if (--file->ref > 0)
00118         return -1;
00119 
00120     if (file->base->vfs_fclose_impl(file) != 0)
00121         ret = -1;
00122 
00123     g_free(file->uri);
00124     g_free(file);
00125 
00126     return ret;
00127 }
00128 
00138 gint64 vfs_fread (void * ptr, gint64 size, gint64 nmemb, VFSFile * file)
00139 {
00140     if (file == NULL)
00141         return 0;
00142 
00143     return file->base->vfs_fread_impl(ptr, size, nmemb, file);
00144 }
00145 
00155 gint64 vfs_fwrite (const void * ptr, gint64 size, gint64 nmemb, VFSFile * file)
00156 {
00157     if (file == NULL)
00158         return 0;
00159 
00160     return file->base->vfs_fwrite_impl(ptr, size, nmemb, file);
00161 }
00162 
00169 gint
00170 vfs_getc(VFSFile *file)
00171 {
00172     if (file == NULL)
00173         return -1;
00174 
00175     return file->base->vfs_getc_impl(file);
00176 }
00177 
00185 gint
00186 vfs_ungetc(gint c, VFSFile *file)
00187 {
00188     if (file == NULL)
00189         return -1;
00190 
00191     return file->base->vfs_ungetc_impl(c, file);
00192 }
00193 
00207 gint
00208 vfs_fseek(VFSFile * file,
00209           gint64 offset,
00210           gint whence)
00211 {
00212     if (file == NULL)
00213         return 0;
00214 
00215     return file->base->vfs_fseek_impl(file, offset, whence);
00216 }
00217 
00223 void
00224 vfs_rewind(VFSFile * file)
00225 {
00226     if (file == NULL)
00227         return;
00228 
00229     file->base->vfs_rewind_impl(file);
00230 }
00231 
00238 glong
00239 vfs_ftell(VFSFile * file)
00240 {
00241     if (file == NULL)
00242         return -1;
00243 
00244     return file->base->vfs_ftell_impl(file);
00245 }
00246 
00253 gboolean
00254 vfs_feof(VFSFile * file)
00255 {
00256     if (file == NULL)
00257         return FALSE;
00258 
00259     return (gboolean) file->base->vfs_feof_impl(file);
00260 }
00261 
00269 gint vfs_ftruncate (VFSFile * file, gint64 length)
00270 {
00271     if (file == NULL)
00272         return -1;
00273 
00274     return file->base->vfs_ftruncate_impl(file, length);
00275 }
00276 
00283 gint64
00284 vfs_fsize(VFSFile * file)
00285 {
00286     if (file == NULL)
00287         return -1;
00288 
00289     return file->base->vfs_fsize_impl(file);
00290 }
00291 
00299 gchar *
00300 vfs_get_metadata(VFSFile * file, const gchar * field)
00301 {
00302     if (file == NULL)
00303         return NULL;
00304 
00305     if (file->base->vfs_get_metadata_impl)
00306         return file->base->vfs_get_metadata_impl(file, field);
00307     return NULL;
00308 }
00309 
00317 gboolean
00318 vfs_file_test(const gchar * path, GFileTest test)
00319 {
00320     if (strncmp (path, "file://", 7))
00321         return FALSE; /* only local files are handled */
00322 
00323     gchar * path2 = uri_to_filename (path);
00324 
00325     if (path2 == NULL)
00326         path2 = g_strdup(path);
00327 
00328     gboolean ret = g_file_test (path2, test);
00329 
00330     g_free(path2);
00331 
00332     return ret;
00333 }
00334 
00341 gboolean
00342 vfs_is_writeable(const gchar * path)
00343 {
00344     struct stat info;
00345     gchar * realfn = uri_to_filename (path);
00346 
00347     if (stat(realfn, &info) == -1)
00348         return FALSE;
00349 
00350     g_free(realfn);
00351 
00352     return (info.st_mode & S_IWUSR);
00353 }
00354 
00364 VFSFile *
00365 vfs_dup(VFSFile *in)
00366 {
00367     g_return_val_if_fail(in != NULL, NULL);
00368 
00369     in->ref++;
00370 
00371     return in;
00372 }
00373 
00380 gboolean
00381 vfs_is_remote(const gchar * path)
00382 {
00383     VFSConstructor *vtable = NULL;
00384 
00385     if (path == NULL || (vtable = vfs_get_constructor(path)) == NULL)
00386         return FALSE;
00387 
00388     /* check if vtable->uri_id is file:// or not, for now. */
00389     if (!strncasecmp("file://", vtable->uri_id, strlen(vtable->uri_id)))
00390         return FALSE;
00391     else
00392         return TRUE;
00393 }
00394 
00401 gboolean
00402 vfs_is_streaming(VFSFile *file)
00403 {
00404     off_t size = 0;
00405 
00406     if (file == NULL)
00407         return FALSE;
00408 
00409     size = file->base->vfs_fsize_impl(file);
00410 
00411     if (size == -1)
00412         return TRUE;
00413     else
00414         return FALSE;
00415 }