NetSurf
file.c
Go to the documentation of this file.
1/*
2 * Copyright 2014 Ole Loots <ole@monochrom.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20#include <stdarg.h>
21#include <string.h>
22#include <stdio.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <unistd.h>
26
27#include "utils/utils.h"
28#include "utils/corestrings.h"
29#include "utils/url.h"
30#include "utils/nsurl.h"
31#include "utils/file.h"
32#include "utils/string.h"
33
34/**
35 * \file
36 * Atari file handling callbacks.
37 *
38 * Most of this code was taken from windows/gui.c
39 */
40
41/**
42 * Generate a GEMDOS path from one or more component elemnts.
43 *
44 * If a string is allocated it must be freed by the caller.
45 *
46 * @param[in,out] str pointer to string pointer if this is NULL enough
47 * storage will be allocated for the complete path.
48 * @param[in,out] size The size of the space available if \a str not
49 * NULL on input and if not NULL set to the total
50 * output length on output.
51 * @param[in] nelm The number of elements.
52 * @param[in] ap The elements of the path as string pointers.
53 * @return NSERROR_OK and the complete path is written to str
54 * or error code on faliure.
55 */
56static nserror atari_mkpath(char **str, size_t *size, size_t nelm, va_list ap)
57{
58 return vsnstrjoin(str, size, '\\', nelm, ap);
59}
60
61/**
62 * Get the basename of a file using GEMDOS path handling.
63 *
64 * This gets the last element of a path and returns it.
65 *
66 * @param[in] path The path to extract the name from.
67 * @param[in,out] str Pointer to string pointer if this is NULL enough
68 * storage will be allocated for the path element.
69 * @param[in,out] size The size of the space available if \a
70 * str not NULL on input and set to the total
71 * output length on output.
72 * @return NSERROR_OK and the complete path is written to str
73 * or error code on faliure.
74 */
75static nserror atari_basename(const char *path, char **str, size_t *size)
76{
77 const char *leafname;
78 char *fname;
79
80 if (path == NULL) {
82 }
83
84 leafname = strrchr(path, '\\');
85 if (!leafname) {
86 leafname = path;
87 } else {
88 leafname += 1;
89 }
90
91 fname = strdup(leafname);
92 if (fname == NULL) {
93 return NSERROR_NOMEM;
94 }
95
96 *str = fname;
97 if (size != NULL) {
98 *size = strlen(fname);
99 }
100 return NSERROR_OK;
101}
102
103/**
104 * Create a path from a nsurl using GEMDOS file handling.
105 *
106 * @param[in] url The url to encode.
107 * @param[out] path_out A string containing the result path which should
108 * be freed by the caller.
109 * @return NSERROR_OK and the path is written to \a path or error code
110 * on faliure.
111 */
112static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
113{
114 lwc_string *urlpath;
115 size_t path_len;
116 char *path;
117 bool match;
118 lwc_string *scheme;
119 nserror res;
120
121 if ((url == NULL) || (path_out == NULL)) {
123 }
124
125 scheme = nsurl_get_component(url, NSURL_SCHEME);
126
127 if (lwc_string_caseless_isequal(scheme, corestring_lwc_file,
128 &match) != lwc_error_ok)
129 {
131 }
132 lwc_string_unref(scheme);
133 if (match == false) {
135 }
136
137 urlpath = nsurl_get_component(url, NSURL_PATH);
138 if (urlpath == NULL) {
140 }
141
142 res = url_unescape(lwc_string_data(urlpath),
143 lwc_string_length(urlpath),
144 &path_len,
145 &path);
146 lwc_string_unref(urlpath);
147 if (res != NSERROR_OK) {
148 return res;
149 }
150
151 /* if there is a drive: prefix treat path as DOS filename */
152 if ((path[2] == ':') || (path[2] == '|')) {
153
154 /* move the string down to remove leading / note the
155 * strlen is *not* copying too much data as we are
156 * moving the null too!
157 */
158 memmove(path, path + 1, path_len);
159 }
160 /* if the path does not have a drive letter we return the
161 * complete path.
162 */
163 /** @todo Need to check returning the unaltered path in this
164 * case is correct
165 */
166
167 *path_out = path;
168
169 return NSERROR_OK;
170}
171
172/**
173 * Create a nsurl from a path using GEMDOS file handling.
174 *
175 * Perform the necessary operations on a path to generate a nsurl.
176 *
177 * @param[in] path The path to convert.
178 * @param[out] url_out pointer to recive the nsurl, The returned url
179 * should be unreferenced by the caller.
180 * @return NSERROR_OK and the url is placed in \a url or error code on
181 * faliure.
182 */
183static nserror atari_path_to_nsurl(const char *path, struct nsurl **url_out)
184{
185 nserror ret;
186 int urllen;
187 char *urlstr;
188 char *escpath; /* escaped version of the path */
189 char *escpaths;
190
191 if ((path == NULL) || (url_out == NULL) || (*path == 0)) {
193 }
194
195 /* escape the path so it can be placed in a url */
196 ret = url_escape(path, false, "/", &escpath);
197 if (ret != NSERROR_OK) {
198 return ret;
199 }
200 /* remove unecessary / as file: paths are already absolute */
201 escpaths = escpath;
202 while (*escpaths == '/') {
203 escpaths++;
204 }
205
206 /* build url as a string for nsurl constructor */
207 urllen = strlen(escpaths) + FILE_SCHEME_PREFIX_LEN + 1;
208 urlstr = malloc(urllen);
209 if (urlstr == NULL) {
210 free(escpath);
211 return NSERROR_NOMEM;
212 }
213
214 snprintf(urlstr, urllen, "%s%s", FILE_SCHEME_PREFIX, escpaths);
215 free(escpath);
216
217 ret = nsurl_create(urlstr, url_out);
218 free(urlstr);
219
220 return ret;
221}
222
223/**
224 * Ensure that all directory elements needed to store a filename exist.
225 *
226 * @param fname The filename to ensure the path to exists.
227 * @return NSERROR_OK on success or error code on failure.
228 */
229static nserror atari_mkdir_all(const char *fname)
230{
231 char *dname;
232 char *sep;
233 struct stat sb;
234
235 dname = strdup(fname);
236
237 sep = strrchr(dname, '\\');
238 if (sep == NULL) {
239 /* no directory separator path is just filename so its ok */
240 free(dname);
241 return NSERROR_OK;
242 }
243
244 *sep = 0; /* null terminate directory path */
245
246 if (stat(dname, &sb) == 0) {
247 free(dname);
248 if (S_ISDIR(sb.st_mode)) {
249 /* path to file exists and is a directory */
250 return NSERROR_OK;
251 }
253 }
254 *sep = '\\'; /* restore separator */
255
256 sep = dname;
257 while (*sep == '\\') {
258 sep++;
259 }
260 while ((sep = strchr(sep, '\\')) != NULL) {
261 *sep = 0;
262 if (stat(dname, &sb) != 0) {
263 if (nsmkdir(dname, S_IRWXU) != 0) {
264 /* could not create path element */
265 free(dname);
266 return NSERROR_NOT_FOUND;
267 }
268 } else {
269 if (! S_ISDIR(sb.st_mode)) {
270 /* path element not a directory */
271 free(dname);
273 }
274 }
275 *sep = '\\'; /* restore separator */
276 /* skip directory separators */
277 while (*sep == '\\') {
278 sep++;
279 }
280 }
281
282 free(dname);
283 return NSERROR_OK;
284}
285
286
287/* atari file handling table */
288static struct gui_file_table file_table = {
290 .basename = atari_basename,
291 .nsurl_to_path = atari_nsurl_to_path,
292 .path_to_nsurl = atari_path_to_nsurl,
293 .mkdir_all = atari_mkdir_all,
294};
295
297
298
Useful interned string pointers (interface).
#define FILE_SCHEME_PREFIX_LEN
File url prefix length.
Definition: corestrings.h:33
#define FILE_SCHEME_PREFIX
File url prefix.
Definition: corestrings.h:30
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOT_FOUND
Requested item not found.
Definition: errors.h:34
@ NSERROR_BAD_PARAMETER
Bad Parameter.
Definition: errors.h:48
@ NSERROR_NOT_DIRECTORY
Missing directory.
Definition: errors.h:35
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
static nserror atari_path_to_nsurl(const char *path, struct nsurl **url_out)
Create a nsurl from a path using GEMDOS file handling.
Definition: file.c:183
static nserror atari_mkdir_all(const char *fname)
Ensure that all directory elements needed to store a filename exist.
Definition: file.c:229
static nserror atari_mkpath(char **str, size_t *size, size_t nelm, va_list ap)
Generate a GEMDOS path from one or more component elemnts.
Definition: file.c:56
static struct gui_file_table file_table
Definition: file.c:288
static nserror atari_basename(const char *path, char **str, size_t *size)
Get the basename of a file using GEMDOS path handling.
Definition: file.c:75
struct gui_file_table * atari_file_table
Definition: file.c:296
static nserror atari_nsurl_to_path(struct nsurl *url, char **path_out)
Create a path from a nsurl using GEMDOS file handling.
Definition: file.c:112
NetSurf URL handling (interface).
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
lwc_string * nsurl_get_component(const nsurl *url, nsurl_component part)
Get part of a URL as a lwc_string, from a NetSurf URL object.
@ NSURL_SCHEME
Definition: nsurl.h:45
@ NSURL_PATH
Definition: nsurl.h:52
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Interface to utility string handling.
nserror vsnstrjoin(char **str, size_t *size, char sep, size_t nelm, va_list ap)
Generate a string from one or more component elements separated with a single value.
Definition: utils.c:107
/brief function table for file and filename operations.
Definition: file.h:50
nserror(* mkpath)(char **str, size_t *size, size_t nemb, va_list ap)
Generate a path from one or more component elemnts.
Definition: file.h:68
nserror url_escape(const char *unescaped, bool sptoplus, const char *escexceptions, char **result)
Escape a string suitable for inclusion in an URL.
Definition: url.c:131
nserror url_unescape(const char *str, size_t length, size_t *length_out, char **result_out)
Convert an escaped string to plain.
Definition: url.c:67
Interface to URL parsing and joining operations.
Default operations table for files.
Interface to a number of general purpose functionality.
#define nsmkdir(dir, mode)
POSIX mkdir function.
Definition: utils.h:64
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plot.c:821