2 * Copyright (C) 2016 J. Ali Harlow <ali@juiblex.co.uk>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "plover/plover.h"
27 #include "uri-handler.h"
28 #include "ascii-ctype.h"
30 static gboolean has_valid_scheme(const char *uri)
33 * RFC 3986 defines valid schemes as:
34 * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
37 if (!ascii_isalpha(*uri))
42 else if (!ascii_isalnum(*s) && *s!='+' && *s!='-' && *s!='.')
46 static GFile *file_for_uri(const char *uri)
49 if (!has_valid_scheme(uri))
51 g_warning("%s: Not a valid URI",uri);
52 file=g_file_new_for_path(uri);
56 if (strstr(uri+1,"file:/"))
57 g_warning("%s: Implausible URI",uri);
58 file=g_file_new_for_uri(uri);
63 int uri_mkdir(const char *uri,mode_t mode,struct razor_error **error)
69 file=file_for_uri(uri);
70 retval=!g_file_make_directory(file,NULL,&err);
73 if (g_error_matches(err,G_IO_ERROR,G_IO_ERROR_EXISTS))
75 info=g_file_query_info(file,G_FILE_ATTRIBUTE_STANDARD_TYPE,
76 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,NULL);
80 if (g_file_info_get_file_type(info)==G_FILE_TYPE_DIRECTORY)
83 razor_set_error(error,RAZOR_POSIX_ERROR,EEXIST,uri,
89 plover_propagate_g_error(error,err);
95 int uri_unlink(const char *uri,struct razor_error **error)
100 file=file_for_uri(uri);
101 retval=!g_file_delete(file,NULL,&err);
103 plover_propagate_g_error(error,err);
104 g_object_unref(file);
108 int uri_move(const char *src_uri,const char *dst_uri,
109 struct razor_error **error)
114 src=file_for_uri(src_uri);
115 dst=file_for_uri(dst_uri);
116 retval=!g_file_move(src,dst,G_FILE_COPY_OVERWRITE,NULL,NULL,NULL,&err);
118 plover_propagate_g_error(error,err);
124 static void *uri_get_contents(const char *uri,size_t *length,int private,
125 struct razor_error **error)
132 file=file_for_uri(uri);
133 if (!g_file_load_contents(file,NULL,&contents,&len,NULL,&err))
135 plover_propagate_g_error(error,err);
144 g_object_unref(file);
148 static int uri_free_contents(void *addr,size_t length)
154 int uri_is_directory(const char *uri,struct razor_error **error)
160 file=file_for_uri(uri);
161 info=g_file_query_info(file,G_FILE_ATTRIBUTE_STANDARD_TYPE,
162 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,&err);
165 if (g_file_info_get_file_type(info)==G_FILE_TYPE_DIRECTORY)
169 g_object_unref(info);
174 plover_propagate_g_error(error,err);
176 g_object_unref(file);
180 void *uri_opendir(const char *uri,struct razor_error **error)
183 GFileEnumerator *dir;
185 file=file_for_uri(uri);
186 dir=g_file_enumerate_children(file,G_FILE_ATTRIBUTE_STANDARD_NAME,
187 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,&err);
189 plover_propagate_g_error(error,err);
190 g_object_unref(file);
194 char *uri_readdir(void *dp,struct razor_error **error)
196 GFileEnumerator *dir=dp;
200 info=g_file_enumerator_next_file(dir,NULL,&err);
204 plover_propagate_g_error(error,err);
208 name=strdup(g_file_info_get_name(info));
209 g_object_unref(info);
214 int uri_closedir(void *dp,struct razor_error **error)
216 GFileEnumerator *dir=dp;
219 retval=!g_file_enumerator_close(dir,NULL,&err);
221 plover_propagate_g_error(error,err);
226 void plover__uri_handler_init(void)
229 struct razor_uri_vtable uri_vtable={0,};
230 if (g_once_init_enter(&init))
232 uri_vtable.structure_size=sizeof(uri_vtable);
233 uri_vtable.mkdir=uri_mkdir;
234 uri_vtable.unlink=uri_unlink;
235 uri_vtable.move=uri_move;
236 uri_vtable.get_contents=uri_get_contents;
237 uri_vtable.free_contents=uri_free_contents;
238 uri_vtable.is_directory=uri_is_directory;
239 uri_vtable.opendir=uri_opendir;
240 uri_vtable.readdir=uri_readdir;
241 uri_vtable.closedir=uri_closedir;
242 razor_uri_set_vtable(NULL,&uri_vtable,NULL);
243 g_once_init_leave(&init,1);