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 -}