plover/fileio.c
changeset 44 43ffed8669ce
parent 43 6b3034a884dc
child 45 a166277bc796
     1.1 --- a/plover/fileio.c	Thu Jun 16 18:00:21 2016 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,417 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (C) 2016  J. Ali Harlow <ali@juiblex.co.uk>
     1.6 - *
     1.7 - * This program is free software; you can redistribute it and/or modify
     1.8 - * it under the terms of the GNU General Public License as published by
     1.9 - * the Free Software Foundation; either version 2 of the License, or
    1.10 - * (at your option) any later version.
    1.11 - *
    1.12 - * This program is distributed in the hope that it will be useful,
    1.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.15 - * GNU General Public License for more details.
    1.16 - *
    1.17 - * You should have received a copy of the GNU General Public License along
    1.18 - * with this program; if not, write to the Free Software Foundation, Inc.,
    1.19 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    1.20 - */
    1.21 -
    1.22 -#include <stdlib.h>
    1.23 -#include <string.h>
    1.24 -#include <errno.h>
    1.25 -#include <razor.h>
    1.26 -#include <glib.h>
    1.27 -#include <gio/gio.h>
    1.28 -#include "config.h"
    1.29 -#include "plover/plover.h"
    1.30 -
    1.31 -static GList *open_razor_files;
    1.32 -
    1.33 -static gboolean has_valid_scheme(const char *uri)
    1.34 -{
    1.35 -    /*
    1.36 -     * RFC 2396 defines valid schemes as:
    1.37 -     * scheme = alpha *( alpha | digit | "+" | "-" | "." )
    1.38 -     */
    1.39 -    const char *s;
    1.40 -    if (!g_ascii_isalpha(*uri))
    1.41 -	return FALSE;
    1.42 -    for(s=uri+1;;s++)
    1.43 -	if (*s==':')
    1.44 -	    return TRUE;
    1.45 -	else if (!g_ascii_isalnum(*s) && *s!='+' && *s!='-' && *s!='.')
    1.46 -	    return FALSE;
    1.47 -}
    1.48 -
    1.49 -static GFile *file_for_uri(const char *uri)
    1.50 -{
    1.51 -    GFile *file;
    1.52 -    if (!has_valid_scheme(uri))
    1.53 -    {
    1.54 -	g_warning("%s: Not a valid URI",uri);
    1.55 -	file=g_file_new_for_path(uri);
    1.56 -    }
    1.57 -    else
    1.58 -    {
    1.59 -	if (strstr(uri+1,"file:/"))
    1.60 -	    g_warning("%s: Implausible URI",uri);
    1.61 -	file=g_file_new_for_uri(uri);
    1.62 -    }
    1.63 -    return file;
    1.64 -}
    1.65 -
    1.66 -int file_mkdir(const char *uri,mode_t mode,struct razor_error **error)
    1.67 -{
    1.68 -    GFile *file;
    1.69 -    GFileInfo *info;
    1.70 -    gchar *path;
    1.71 -    int retval;
    1.72 -    GError *err=NULL;
    1.73 -    g_message("file_mkdir(%s)",uri);
    1.74 -    file=file_for_uri(uri);
    1.75 -    path=g_file_get_path(file);
    1.76 -    if (path)
    1.77 -    {
    1.78 -	retval=razor_file_default_mkdir(path,mode,error);
    1.79 -	g_free(path);
    1.80 -    }
    1.81 -    else if (!g_file_make_directory(file,NULL,&err))
    1.82 -    {
    1.83 -	retval=-1;
    1.84 -	if (g_error_matches(err,G_IO_ERROR,G_IO_ERROR_EXISTS))
    1.85 -	{
    1.86 -	    info=g_file_query_info(file,G_FILE_ATTRIBUTE_STANDARD_TYPE,
    1.87 -	      G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,NULL);
    1.88 -	    if (info)
    1.89 -	    {
    1.90 -		g_clear_error(&err);
    1.91 -		if (g_file_info_get_file_type(info)==G_FILE_TYPE_DIRECTORY)
    1.92 -		    retval=0;
    1.93 -		else
    1.94 -		    razor_set_error(error,RAZOR_POSIX_ERROR,EEXIST,uri,
    1.95 -		      "Not a directory");
    1.96 -		g_object_unref(info);
    1.97 -	    }
    1.98 -	}
    1.99 -	if (err)
   1.100 -	    plover_propagate_g_error(error,err);
   1.101 -    }
   1.102 -    else
   1.103 -	retval=0;
   1.104 -    g_object_unref(file);
   1.105 -    return retval;
   1.106 -}
   1.107 -
   1.108 -int file_unlink(const char *uri,struct razor_error **error)
   1.109 -{
   1.110 -    GFile *file;
   1.111 -    gchar *path;
   1.112 -    int retval;
   1.113 -    GError *err=NULL;
   1.114 -    g_message("file_unlink(%s)",uri);
   1.115 -    file=file_for_uri(uri);
   1.116 -    path=g_file_get_path(file);
   1.117 -    if (path)
   1.118 -    {
   1.119 -	retval=razor_file_default_unlink(path,error);
   1.120 -	g_free(path);
   1.121 -    }
   1.122 -    else if (!g_file_delete(file,NULL,&err))
   1.123 -    {
   1.124 -	plover_propagate_g_error(error,err);
   1.125 -	retval=-1;
   1.126 -    }
   1.127 -    else
   1.128 -	retval=0;
   1.129 -    g_object_unref(file);
   1.130 -    return retval;
   1.131 -}
   1.132 -
   1.133 -int file_open(const char *uri,int flags,mode_t mode,struct razor_error **error)
   1.134 -{
   1.135 -    GFile *file;
   1.136 -    gchar *path;
   1.137 -    int retval;
   1.138 -    GError *err=NULL;
   1.139 -    g_message("file_open(%s)",uri);
   1.140 -    file=file_for_uri(uri);
   1.141 -    path=g_file_get_path(file);
   1.142 -    if (path)
   1.143 -    {
   1.144 -	retval=razor_file_default_open(path,flags,mode,error);
   1.145 -	g_free(path);
   1.146 -    }
   1.147 -    else
   1.148 -    {
   1.149 -	razor_set_error(error,RAZOR_GENERAL_ERROR,RAZOR_GENERAL_ERROR_FAILED,
   1.150 -	  uri,"File is not local");
   1.151 -	retval=-1;
   1.152 -    }
   1.153 -    g_object_unref(file);
   1.154 -    return retval;
   1.155 -}
   1.156 -
   1.157 -int file_move(const char *src_uri,const char *dst_uri,
   1.158 -  struct razor_error **error)
   1.159 -{
   1.160 -    GFile *src,*dst;
   1.161 -    gchar *src_path,*dst_path;
   1.162 -    int retval;
   1.163 -    GError *err=NULL;
   1.164 -    g_message("file_move(%s,%s)",src_uri,dst_uri);
   1.165 -    src=file_for_uri(src_uri);
   1.166 -    dst=file_for_uri(dst_uri);
   1.167 -    src_path=g_file_get_path(src);
   1.168 -    dst_path=g_file_get_path(dst);
   1.169 -    if (src_path && dst_path)
   1.170 -	retval=razor_file_default_move(src_path,dst_path,error);
   1.171 -    else if (!g_file_move(src,dst,G_FILE_COPY_OVERWRITE,NULL,NULL,NULL,&err))
   1.172 -    {
   1.173 -	plover_propagate_g_error(error,err);
   1.174 -	retval=-1;
   1.175 -    }
   1.176 -    else
   1.177 -	retval=0;
   1.178 -    g_free(src_path);
   1.179 -    g_free(dst_path);
   1.180 -    g_object_unref(src);
   1.181 -    g_object_unref(dst);
   1.182 -    return retval;
   1.183 -}
   1.184 -
   1.185 -static void *file_get_contents(const char *uri,size_t *length,int private,
   1.186 -  struct razor_error **error)
   1.187 -{
   1.188 -    GFile *file;
   1.189 -    gchar *path;
   1.190 -    void *addr;
   1.191 -    char *contents;
   1.192 -    gsize len;
   1.193 -    GError *err=NULL;
   1.194 -    g_message("file_get_contents(%s)",uri);
   1.195 -    file=file_for_uri(uri);
   1.196 -    path=g_file_get_path(file);
   1.197 -    if (path)
   1.198 -    {
   1.199 -	g_object_unref(file);
   1.200 -	addr=razor_file_default_get_contents(path,length,private,error);
   1.201 -	if (addr)
   1.202 -	    open_razor_files=g_list_prepend(open_razor_files,addr);
   1.203 -	g_free(path);
   1.204 -    }
   1.205 -    else if (!g_file_load_contents(file,NULL,&contents,&len,NULL,&err))
   1.206 -    {
   1.207 -	plover_propagate_g_error(error,err);
   1.208 -	g_object_unref(file);
   1.209 -	addr=NULL;
   1.210 -    }
   1.211 -    else
   1.212 -    {
   1.213 -	g_object_unref(file);
   1.214 -	addr=contents;
   1.215 -	if (length)
   1.216 -	    *length=len;
   1.217 -    }
   1.218 -    return addr;
   1.219 -}
   1.220 -
   1.221 -static int file_free_contents(void *addr,size_t length)
   1.222 -{
   1.223 -    int retval;
   1.224 -    GList *lnk;
   1.225 -    g_message("file_free_contents(%p)",addr);
   1.226 -    lnk=g_list_find(open_razor_files,addr);
   1.227 -    if (lnk)
   1.228 -    {
   1.229 -	open_razor_files=g_list_delete_link(open_razor_files,lnk);
   1.230 -	retval=razor_file_default_free_contents(addr,length);
   1.231 -    }
   1.232 -    else
   1.233 -    {
   1.234 -	g_free(addr);
   1.235 -	retval=0;
   1.236 -    }
   1.237 -    return retval;
   1.238 -}
   1.239 -
   1.240 -int file_is_directory(const char *uri,struct razor_error **error)
   1.241 -{
   1.242 -    GFile *file;
   1.243 -    GFileInfo *info;
   1.244 -    gchar *path;
   1.245 -    int retval;
   1.246 -    GError *err=NULL;
   1.247 -    g_message("file_is_directory(%s)",uri);
   1.248 -    file=file_for_uri(uri);
   1.249 -    path=g_file_get_path(file);
   1.250 -    if (path)
   1.251 -    {
   1.252 -	retval=razor_file_default_is_directory(path,error);
   1.253 -	g_free(path);
   1.254 -    }
   1.255 -    else
   1.256 -    {
   1.257 -	info=g_file_query_info(file,G_FILE_ATTRIBUTE_STANDARD_TYPE,
   1.258 -	  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,&err);
   1.259 -	if (info)
   1.260 -	{
   1.261 -	    if (g_file_info_get_file_type(info)==G_FILE_TYPE_DIRECTORY)
   1.262 -		retval=1;
   1.263 -	    else
   1.264 -		retval=0;
   1.265 -	    g_object_unref(info);
   1.266 -	}
   1.267 -	else
   1.268 -	{
   1.269 -	    retval=-1;
   1.270 -	    plover_propagate_g_error(error,err);
   1.271 -	}
   1.272 -    }
   1.273 -    g_object_unref(file);
   1.274 -    return retval;
   1.275 -}
   1.276 -
   1.277 -char *file_mkdtemp_near(const char *uri,const char *template,
   1.278 -  struct razor_error **error)
   1.279 -{
   1.280 -    GFile *file;
   1.281 -    gchar *path,*tmpuri;
   1.282 -    char *tmppath,*retval;
   1.283 -    GError *err=NULL;
   1.284 -    g_message("file_mkdtemp_near(%s)",uri);
   1.285 -    file=file_for_uri(uri);
   1.286 -    path=g_file_get_path(file);
   1.287 -    g_object_unref(file);
   1.288 -    if (path)
   1.289 -    {
   1.290 -	tmppath=razor_file_default_mkdtemp_near(path,template,error);
   1.291 -	g_free(path);
   1.292 -	if (tmppath)
   1.293 -	{
   1.294 -	    file=g_file_new_for_path(tmppath);
   1.295 -	    tmpuri=g_file_get_uri(file);
   1.296 -	    g_object_unref(file);
   1.297 -	    retval=strdup(tmpuri);
   1.298 -	    g_free(tmpuri);
   1.299 -	}
   1.300 -	else
   1.301 -	    retval=NULL;
   1.302 -    }
   1.303 -    else
   1.304 -    {
   1.305 -	razor_set_error(error,RAZOR_GENERAL_ERROR,RAZOR_GENERAL_ERROR_FAILED,
   1.306 -	  uri,"File is not local");
   1.307 -	retval=NULL;
   1.308 -    }
   1.309 -    return retval;
   1.310 -}
   1.311 -
   1.312 -struct file_dir {
   1.313 -    void *razor_file_default;
   1.314 -    GFileEnumerator *enumerator;
   1.315 -};
   1.316 -
   1.317 -void *file_opendir(const char *uri,struct razor_error **error)
   1.318 -{
   1.319 -    GFile *file;
   1.320 -    gchar *path;
   1.321 -    struct file_dir *dir;
   1.322 -    GError *err=NULL;
   1.323 -    g_message("file_opendir(%s)",uri);
   1.324 -    dir=g_new0(struct file_dir,1);
   1.325 -    file=file_for_uri(uri);
   1.326 -    path=g_file_get_path(file);
   1.327 -    if (path)
   1.328 -    {
   1.329 -	dir->razor_file_default=razor_file_default_opendir(path,error);
   1.330 -	if (!dir->razor_file_default)
   1.331 -	{
   1.332 -	    g_free(dir);
   1.333 -	    dir=NULL;
   1.334 -	}
   1.335 -	g_free(path);
   1.336 -    }
   1.337 -    else
   1.338 -    {
   1.339 -	dir->enumerator=g_file_enumerate_children(file,
   1.340 -	  G_FILE_ATTRIBUTE_STANDARD_NAME,G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
   1.341 -	  NULL,&err);
   1.342 -	if (!dir->enumerator)
   1.343 -	{
   1.344 -	    g_free(dir);
   1.345 -	    dir=NULL;
   1.346 -	    plover_propagate_g_error(error,err);
   1.347 -	}
   1.348 -    }
   1.349 -    g_object_unref(file);
   1.350 -    return dir;
   1.351 -}
   1.352 -
   1.353 -char *file_readdir(void *dp,struct razor_error **error)
   1.354 -{
   1.355 -    struct file_dir *dir=dp;
   1.356 -    char *name;
   1.357 -    GError *err=NULL;
   1.358 -    GFileInfo *info;
   1.359 -    g_message("file_readdir(%p)",dp);
   1.360 -    if (dir->razor_file_default)
   1.361 -	name=razor_file_default_readdir(dir->razor_file_default,error);
   1.362 -    else
   1.363 -    {
   1.364 -	info=g_file_enumerator_next_file(dir->enumerator,NULL,&err);
   1.365 -	if (!info)
   1.366 -	{
   1.367 -	    name=NULL;
   1.368 -	    plover_propagate_g_error(error,err);
   1.369 -	}
   1.370 -	else
   1.371 -	{
   1.372 -	    name=strdup(g_file_info_get_name(info));
   1.373 -	    g_object_unref(info);
   1.374 -	}
   1.375 -    }
   1.376 -    return name;
   1.377 -}
   1.378 -
   1.379 -int file_closedir(void *dp,struct razor_error **error)
   1.380 -{
   1.381 -    struct file_dir *dir=dp;
   1.382 -    int retval;
   1.383 -    GError *err=NULL;
   1.384 -    g_message("file_closedir(%p)",dp);
   1.385 -    if (dir->razor_file_default)
   1.386 -	retval=razor_file_default_closedir(dir->razor_file_default,error);
   1.387 -    else
   1.388 -    {
   1.389 -	retval=g_file_enumerator_close(dir->enumerator,NULL,&err)?0:-1;
   1.390 -	if (retval)
   1.391 -	    plover_propagate_g_error(error,err);
   1.392 -	g_object_unref(dir->enumerator);
   1.393 -    }
   1.394 -    g_free(dir);
   1.395 -    return retval;
   1.396 -}
   1.397 -
   1.398 -void plover__file_io_init(void)
   1.399 -{
   1.400 -    static gsize init=0;
   1.401 -    struct razor_file_vtable file_vtable={0,};
   1.402 -    g_message("plover__file_io_init()");
   1.403 -    if (g_once_init_enter(&init))
   1.404 -    {
   1.405 -	file_vtable.structure_size=sizeof(file_vtable);
   1.406 -	file_vtable.mkdir=file_mkdir;
   1.407 -	file_vtable.unlink=file_unlink;
   1.408 -	file_vtable.open=file_open;
   1.409 -	file_vtable.move=file_move;
   1.410 -	file_vtable.get_contents=file_get_contents;
   1.411 -	file_vtable.free_contents=file_free_contents;
   1.412 -	file_vtable.is_directory=file_is_directory;
   1.413 -	file_vtable.mkdtemp_near=file_mkdtemp_near;
   1.414 -	file_vtable.opendir=file_opendir;
   1.415 -	file_vtable.readdir=file_readdir;
   1.416 -	file_vtable.closedir=file_closedir;
   1.417 -	razor_file_set_vtable(&file_vtable);
   1.418 -	g_once_init_leave(&init,1);
   1.419 -    }
   1.420 -}