diff --git a/amiga/file.c b/amiga/file.c index acc1166e5..24c1fd902 100644 --- a/amiga/file.c +++ b/amiga/file.c @@ -76,7 +76,7 @@ static const ULONG ami_file_asl_mime_hook(struct Hook *mh, void ami_file_open(struct gui_window_2 *gwin) { - char *temp, *temp2; + char *temp; nsurl *url; if(AslRequestTags(filereq, @@ -93,9 +93,8 @@ void ami_file_open(struct gui_window_2 *gwin) { strlcpy(temp, filereq->fr_Drawer, 1024); AddPart(temp, filereq->fr_File, 1024); - temp2 = path_to_url(temp); - if (nsurl_create(temp2, &url) != NSERROR_OK) { + if (netsurf_path_to_nsurl(temp, &url) != NSERROR_OK) { warn_user("NoMemory", 0); } else { browser_window_navigate(gwin->bw, @@ -108,7 +107,6 @@ void ami_file_open(struct gui_window_2 *gwin) nsurl_unref(url); } - free(temp2); FreeVec(temp); } } diff --git a/amiga/gui.c b/amiga/gui.c index 2c6104444..2592352b7 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -222,127 +222,6 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh nsoptions_default[NSOPTION_##OPTION].value.i = VALUE -/** - * Generate a posix path from one or more component elemnts. - * - * If a string is allocated it must be freed by the caller. - * - * @param[in,out] str pointer to string pointer if this is NULL enough - * storage will be allocated for the complete path. - * @param[in,out] size The size of the space available if \a str not - * NULL on input and if not NULL set to the total - * output length on output. - * @param[in] nemb The number of elements. - * @param[in] ... The elements of the path as string pointers. - * @return NSERROR_OK and the complete path is written to str - * or error code on faliure. - */ -static nserror amiga_vmkpath(char **str, size_t *size, size_t nelm, va_list ap) -{ - const char *elm[16]; - size_t elm_len[16]; - size_t elm_idx; - char *fname; - size_t fname_len = 0; - - /* check the parameters are all sensible */ - if ((nelm == 0) || (nelm > 16)) { - return NSERROR_BAD_PARAMETER; - } - if ((*str != NULL) && (size == NULL)) { - /* if the caller is providing the buffer they must say - * how much space is available. - */ - return NSERROR_BAD_PARAMETER; - } - - /* calculate how much storage we need for the complete path - * with all the elements. - */ - for (elm_idx = 0; elm_idx < nelm; elm_idx++) { - elm[elm_idx] = va_arg(ap, const char *); - /* check the argument is not NULL */ - if (elm[elm_idx] == NULL) { - return NSERROR_BAD_PARAMETER; - } - elm_len[elm_idx] = strlen(elm[elm_idx]); - fname_len += elm_len[elm_idx]; - } - fname_len += nelm; /* allow for separators and terminator */ - - /* ensure there is enough space */ - fname = *str; - if (fname != NULL) { - if (fname_len > *size) { - return NSERROR_NOSPACE; - } - } else { - fname = malloc(fname_len); - if (fname == NULL) { - return NSERROR_NOMEM; - } - } - - /* copy the first element complete */ - memmove(fname, elm[0], elm_len[0]); - fname[elm_len[0]] = 0; - - /* add the remaining elements */ - for (elm_idx = 1; elm_idx < nelm; elm_idx++) { - if (!AddPart(fname, elm[elm_idx], fname_len)) { - break; - } - } - - *str = fname; - if (size != NULL) { - *size = fname_len; - } - - return NSERROR_OK; -} - -/** - * Get the basename of a file using posix path handling. - * - * This gets the last element of a path and returns it. - * - * @param[in] path The path to extract the name from. - * @param[in,out] str Pointer to string pointer if this is NULL enough - * storage will be allocated for the path element. - * @param[in,out] size The size of the space available if \a - * str not NULL on input and set to the total - * output length on output. - * @return NSERROR_OK and the complete path is written to str - * or error code on faliure. - */ -static nserror amiga_basename(const char *path, char **str, size_t *size) -{ - const char *leafname; - char *fname; - - if (path == NULL) { - return NSERROR_BAD_PARAMETER; - } - - leafname = FilePart(path); - if (leafname == NULL) { - return NSERROR_BAD_PARAMETER; - } - - fname = strdup(leafname); - if (fname == NULL) { - return NSERROR_NOMEM; - } - - *str = fname; - if (size != NULL) { - *size = strlen(fname); - } - return NSERROR_OK; -} - - STRPTR ami_locale_langs(void) { @@ -778,11 +657,7 @@ static nsurl *gui_get_resource_url(const char *path) else return NULL; } - raw = path_to_url(buf); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + netsurf_path_to_nsurl(buf, &url); return url; } @@ -1036,7 +911,13 @@ static void gui_init2(int argc, char** argv) DevNameFromLock(wbarg->wa_Lock,fullpath,1024,DN_FULLPATH); AddPart(fullpath,wbarg->wa_Name,1024); - if(!temp_homepage_url) temp_homepage_url = path_to_url(fullpath); + if(!temp_homepage_url) { + nsurl temp_url; + if (netsurf_path_to_nsurl(fullpath, &temp_url) == NSERROR_OK) { + temp_homepage_url = strcpy(nsurl_data(temp_url)); + nsurl_unref(temp_url); + } + } if(notalreadyrunning) { @@ -2378,7 +2259,6 @@ void ami_handle_appmsg(void) int x, y; struct WBArg *appwinargs; STRPTR filename; - char *urlfilename; int i = 0; while(appmsg=(struct AppMessage *)GetMsg(appport)) @@ -2410,9 +2290,8 @@ void ami_handle_appmsg(void) appmsg->am_MouseX, appmsg->am_MouseY) == false) { nsurl *url; - urlfilename = path_to_url(filename); - if (nsurl_create(urlfilename, &url) != NSERROR_OK) { + if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) { warn_user("NoMemory", 0); } else @@ -2440,17 +2319,14 @@ void ami_handle_appmsg(void) } nsurl_unref(url); } - - free(urlfilename); } else { if(browser_window_drop_file_at_point(gwin->bw, x, y, filename) == false) { nsurl *url; - urlfilename = path_to_url(filename); - if (nsurl_create(urlfilename, &url) != NSERROR_OK) { + if (netsurf_path_to_nsurl(filename, &url) != NSERROR_OK) { warn_user("NoMemory", 0); } else @@ -2480,7 +2356,6 @@ void ami_handle_appmsg(void) } nsurl_unref(url); } - free(urlfilename); } } FreeVec(filename); @@ -2527,11 +2402,8 @@ void ami_handle_applib(void) { struct ApplicationOpenPrintDocMsg *applibopdmsg = (struct ApplicationOpenPrintDocMsg *)applibmsg; - char *tempurl; - tempurl = path_to_url(applibopdmsg->fileName); - - error = nsurl_create(tempurl, &url); + error = netsurf_path_to_nsurl(applibopdmsg->fileName, &url); if (error == NSERROR_OK) { error = browser_window_create(BW_CREATE_HISTORY, url, @@ -2543,7 +2415,6 @@ void ami_handle_applib(void) if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } - free(tempurl); } break; @@ -5206,16 +5077,9 @@ static struct gui_window_table amiga_window_table = { .save_link = gui_window_save_link, }; -/* amiga file handling operations */ -static struct gui_file_table amiga_file_table = { - .mkpath = amiga_vmkpath, - .basename = amiga_basename, -}; static struct gui_fetch_table amiga_fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, }; @@ -5253,7 +5117,7 @@ int main(int argc, char** argv) .clipboard = amiga_clipboard_table, .download = amiga_download_table, .fetch = &amiga_fetch_table, - .file = &amiga_file_table, + .file = amiga_file_table, .utf8 = amiga_utf8_table, .search = amiga_search_table, .search_web = &amiga_search_web_table, diff --git a/amiga/icon.c b/amiga/icon.c index 66a008faf..95fd685cd 100644 --- a/amiga/icon.c +++ b/amiga/icon.c @@ -144,14 +144,12 @@ bool amiga_icon_convert(struct content *c) uint8 r, g, b, a; ULONG offset; const char *url; - char *filename; + char *filename = NULL; char *p; ULONG trans, pals1; struct ColorRegister *pal1; - url = nsurl_access(content_get_url(c)); - filename = url_to_path(url); - + netsurf_nsurl_to_path(content_get_url(c), &filename); /* This loader will only work on local files, so fail if not a local path */ if(filename == NULL) { diff --git a/amiga/misc.c b/amiga/misc.c index 3b4363ff5..d2b243a24 100755 --- a/amiga/misc.c +++ b/amiga/misc.c @@ -36,6 +36,7 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/url.h" +#include "utils/file.h" #include "utils/utils.h" void warn_user(const char *warning, const char *detail) @@ -105,54 +106,91 @@ void die(const char *error) exit(1); } -char *url_to_path(const char *url) +/** + * Create a path from a nsurl using amiga file handling. + * + * @parm[in] url The url to encode. + * @param[out] path_out A string containing the result path which should + * be freed by the caller. + * @return NSERROR_OK and the path is written to \a path or error code + * on faliure. + */ +static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out) { - char *unesc, *slash, *colon, *url2; + lwc_string *urlpath; + char *path; + bool match; + lwc_string *scheme; + nserror res; + char *colon; + char *slash; - if (strncmp(url, "file://", SLEN("file://")) != 0) - return NULL; + if ((url == NULL) || (path_out == NULL)) { + return NSERROR_BAD_PARAMETER; + } - url += SLEN("file://"); + scheme = nsurl_get_component(url, NSURL_SCHEME); - if (strncmp(url, "localhost", SLEN("localhost")) == 0) - url += SLEN("localhost"); + if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) != lwc_error_ok) + { + return NSERROR_BAD_PARAMETER; + } + lwc_string_unref(scheme); + if (match == false) { + return NSERROR_BAD_PARAMETER; + } - if (strncmp(url, "/", SLEN("/")) == 0) - url += SLEN("/"); + urlpath = nsurl_get_component(url, NSURL_PATH); + if (urlpath == NULL) { + return NSERROR_BAD_PARAMETER; + } - if(*url == '\0') - return NULL; /* file:/// is not a valid path */ + res = url_unescape(lwc_string_data(urlpath) + 1, &path); + lwc_string_unref(urlpath); + if (res != NSERROR_OK) { + return res; + } - url2 = malloc(strlen(url) + 2); - strcpy(url2, url); - - colon = strchr(url2, ':'); + colon = strchr(path, ':'); if(colon == NULL) { - if(slash = strchr(url2, '/')) + slash = strchr(path, '/'); + if(slash) { *slash = ':'; } else { - int len = strlen(url2); - url2[len] = ':'; - url2[len + 1] = '\0'; + int len = strlen(path); + path[len] = ':'; + path[len + 1] = '\0'; } } - if(url_unescape(url2,&unesc) == NSERROR_OK) - return unesc; + *path_out = path; - return (char *)url2; + return NSERROR_OK; } -char *path_to_url(const char *path) +/** + * Create a nsurl from a path using amiga file handling. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The path to convert. + * @param[out] url_out pointer to recive the nsurl, The returned url + * must be unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error code on + * faliure. + */ +static nserror amiga_path_to_nsurl(const char *path, struct nsurl **url_out) { char *colon = NULL; char *r = NULL; char newpath[1024 + strlen(path)]; BPTR lock = 0; + nserror ret; if(lock = Lock(path, MODE_OLDFILE)) { @@ -162,13 +200,19 @@ char *path_to_url(const char *path) else strlcpy(newpath, path, sizeof newpath); r = malloc(strlen(newpath) + SLEN("file:///") + 1); + if (r == NULL) { + return NSERROR_NOMEM; + } if(colon = strchr(newpath, ':')) *colon = '/'; strcpy(r, "file:///"); strcat(r, newpath); - return r; + ret = nsurl_create(r, url_out); + free(r); + + return ret; } /** @@ -196,3 +240,133 @@ char *translate_escape_chars(const char *s) ret[ii] = '\0'; return ret; } + +/** + * Generate a posix path from one or more component elemnts. + * + * If a string is allocated it must be freed by the caller. + * + * @param[in,out] str pointer to string pointer if this is NULL enough + * storage will be allocated for the complete path. + * @param[in,out] size The size of the space available if \a str not + * NULL on input and if not NULL set to the total + * output length on output. + * @param[in] nemb The number of elements. + * @param[in] ... The elements of the path as string pointers. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. + */ +static nserror amiga_vmkpath(char **str, size_t *size, size_t nelm, va_list ap) +{ + const char *elm[16]; + size_t elm_len[16]; + size_t elm_idx; + char *fname; + size_t fname_len = 0; + + /* check the parameters are all sensible */ + if ((nelm == 0) || (nelm > 16)) { + return NSERROR_BAD_PARAMETER; + } + if ((*str != NULL) && (size == NULL)) { + /* if the caller is providing the buffer they must say + * how much space is available. + */ + return NSERROR_BAD_PARAMETER; + } + + /* calculate how much storage we need for the complete path + * with all the elements. + */ + for (elm_idx = 0; elm_idx < nelm; elm_idx++) { + elm[elm_idx] = va_arg(ap, const char *); + /* check the argument is not NULL */ + if (elm[elm_idx] == NULL) { + return NSERROR_BAD_PARAMETER; + } + elm_len[elm_idx] = strlen(elm[elm_idx]); + fname_len += elm_len[elm_idx]; + } + fname_len += nelm; /* allow for separators and terminator */ + + /* ensure there is enough space */ + fname = *str; + if (fname != NULL) { + if (fname_len > *size) { + return NSERROR_NOSPACE; + } + } else { + fname = malloc(fname_len); + if (fname == NULL) { + return NSERROR_NOMEM; + } + } + + /* copy the first element complete */ + memmove(fname, elm[0], elm_len[0]); + fname[elm_len[0]] = 0; + + /* add the remaining elements */ + for (elm_idx = 1; elm_idx < nelm; elm_idx++) { + if (!AddPart(fname, elm[elm_idx], fname_len)) { + break; + } + } + + *str = fname; + if (size != NULL) { + *size = fname_len; + } + + return NSERROR_OK; +} + +/** + * Get the basename of a file using posix path handling. + * + * This gets the last element of a path and returns it. + * + * @param[in] path The path to extract the name from. + * @param[in,out] str Pointer to string pointer if this is NULL enough + * storage will be allocated for the path element. + * @param[in,out] size The size of the space available if \a + * str not NULL on input and set to the total + * output length on output. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. + */ +static nserror amiga_basename(const char *path, char **str, size_t *size) +{ + const char *leafname; + char *fname; + + if (path == NULL) { + return NSERROR_BAD_PARAMETER; + } + + leafname = FilePart(path); + if (leafname == NULL) { + return NSERROR_BAD_PARAMETER; + } + + fname = strdup(leafname); + if (fname == NULL) { + return NSERROR_NOMEM; + } + + *str = fname; + if (size != NULL) { + *size = strlen(fname); + } + return NSERROR_OK; +} + +/* amiga file handling operations */ +static struct gui_file_table file_table = { + .mkpath = amiga_vmkpath, + .basename = amiga_basename, + .nsurl_to_path = amiga_nsurl_to_path, + .path_to_nsurl = amiga_path_to_nsurl, +}; + +struct gui_file_table *amiga_file_table = &file_table; diff --git a/amiga/misc.h b/amiga/misc.h index 60f249c2c..db559f78a 100644 --- a/amiga/misc.h +++ b/amiga/misc.h @@ -19,9 +19,10 @@ #ifndef AMIGA_MISC_H #define AMIGA_MISC_H +extern struct gui_file_table *amiga_file_table; + char *translate_escape_chars(const char *s); int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2, struct Window *win); -char *url_to_path(const char *url); -char *path_to_url(const char *path); + #endif diff --git a/atari/findfile.c b/atari/findfile.c index 7badc7149..356a9333f 100755 --- a/atari/findfile.c +++ b/atari/findfile.c @@ -68,59 +68,6 @@ char * local_file_to_url( const char * filename ) #undef BACKSLASH } -/* convert an local path to an URL, memory for URL is allocated. */ -char *path_to_url(const char *path_in) -{ - #define BACKSLASH 0x5C - char * path; - - LOG(("path2url in: %s\n", path_in)); - - path = (char*)path_in; - - int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - char *url = malloc(urllen); - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - int i=0; - while( url[i] != 0 ){ - if( url[i] == BACKSLASH ){ - url[i] = '/'; - } - i++; - } - - LOG(("path2url out: %s\n", url)); - return url; - #undef BACKSLASH -} - - -char *url_to_path(const char *url) -{ - char *url_path = curl_unescape(url, 0); - char *path; - char abspath[PATH_MAX+1]; - - LOG(( "url2path in: %s (%s)\n", url, url_path )); - - // is the URL relative? - if (url_path[7] == '.') { - // yes, make it absolute... - gemdos_realpath(url_path + (FILE_SCHEME_PREFIX_LEN-1), abspath); - path = strdup(abspath); - } else { - path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN)); - } - - curl_free(url_path); - - LOG(( "url2path out: %s\n", path )); - - return path; -} - /** * Locate a shared resource file by searching known places in order. diff --git a/atari/findfile.h b/atari/findfile.h index cced0092c..9a6f7848a 100755 --- a/atari/findfile.h +++ b/atari/findfile.h @@ -23,7 +23,5 @@ extern char *atari_find_resource(char *buf, const char *filename, const char *def); char *local_file_to_url(const char *filename); -char *path_to_url(const char *path_in); -char *url_to_path(const char *url); #endif /* NETSURF_ATARI_FINDFILE_H */ diff --git a/atari/gui.c b/atari/gui.c index 317f68013..7cac90c3b 100644 --- a/atari/gui.c +++ b/atari/gui.c @@ -890,15 +890,11 @@ static inline void create_cursor(int flags, short mode, void * form, static nsurl *gui_get_resource_url(const char *path) { char buf[PATH_MAX]; - char *raw; nsurl *url = NULL; atari_find_resource((char*)&buf, path, path); - raw = path_to_url((char*)&buf); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + + netsurf_path_to_nsurl(buf, &url); return url; } @@ -1042,8 +1038,6 @@ static struct gui_clipboard_table atari_clipboard_table = { static struct gui_fetch_table atari_fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, }; diff --git a/atari/misc.c b/atari/misc.c index 35ef18e52..a84ce2bd3 100755 --- a/atari/misc.c +++ b/atari/misc.c @@ -210,7 +210,6 @@ static nserror load_icon_callback(hlcache_handle *handle, hlcache_handle *load_icon(const char *name, hlcache_handle_callback cb, void * pw ) { - char *url = NULL; const char *icon_url = NULL; hlcache_handle *c; nserror err; @@ -220,7 +219,7 @@ hlcache_handle *load_icon(const char *name, hlcache_handle_callback cb, /** @todo something like bitmap_from_disc is needed here */ if (!strncmp(name, "file://", 7)) { - icon_url = name; + err = nsurl_create(name, &icon_nsurl); } else { char *native_path = NULL; @@ -228,22 +227,15 @@ hlcache_handle *load_icon(const char *name, hlcache_handle_callback cb, return NULL; err = netsurf_mkpath(&native_path, NULL, 2, icons_dir, name); - if (err != NSERROR_OK) { - warn_user(messages_get_errorcode(err), 0); - return NULL; + if (err == NSERROR_OK) { + /* Convert native path to URL */ + err = netsurf_path_to_nsurl(native_path, &icon_nsurl); + free(native_path); } - - /* Convert native path to URL */ - url = path_to_url(native_path); - - free(native_path); - icon_url = url; } - err = nsurl_create(icon_url, &icon_nsurl); if (err != NSERROR_OK) { - if (url != NULL) - free(url); + warn_user(messages_get_errorcode(err), 0); return NULL; } diff --git a/beos/gui.cpp b/beos/gui.cpp index 56d5bfe99..d21dbe512 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -964,25 +964,6 @@ static void nsbeos_create_ssl_verify_window(struct browser_window *bw, CALLED(); } -static char *path_to_url(const char *path) -{ - int urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - char *url = (char *)malloc(urllen); - - if (url == NULL) { - return NULL; - } - - if (*path == '/') { - path++; /* file: paths are already absolute */ - } - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - return url; -} - - static void *myrealloc(void *ptr, size_t len, void *pw) { if (len == 0) { @@ -1001,8 +982,6 @@ static struct gui_clipboard_table beos_clipboard_table = { static struct gui_fetch_table beos_fetch_table = { fetch_filetype, - path_to_url, - url_to_path, gui_get_resource_url, NULL //fetch_mimetype }; diff --git a/cocoa/BrowserViewController.m b/cocoa/BrowserViewController.m index b4e436063..f1b25d9d0 100644 --- a/cocoa/BrowserViewController.m +++ b/cocoa/BrowserViewController.m @@ -28,6 +28,7 @@ #import "utils/corestrings.h" #import "utils/filename.h" +#import "utils/file.h" #import "utils/messages.h" #import "utils/url.h" #import "content/hlcache.h" @@ -166,7 +167,7 @@ struct hlcache_handle *content; size_t size; const char *source; - const char *path = NULL; + char *path = NULL; if (browser == NULL) return; @@ -178,14 +179,7 @@ return; /* try to load local files directly. */ - lwc_string *scheme = nsurl_get_component(hlcache_handle_get_url(content), NSURL_SCHEME); - if (scheme == NULL) - return; - - bool match; - if (lwc_string_isequal(scheme, corestring_lwc_file, &match) == lwc_error_ok && match == true) - path = url_to_path(nsurl_access(hlcache_handle_get_url(content))); - lwc_string_unref(scheme); + netsurf_nsurl_to_path(hlcache_handle_get_url(content), &path); if (path == NULL) { /* We cannot release the requested filename until after it diff --git a/cocoa/fetch.h b/cocoa/fetch.h index 5d2e9288d..1b0991ef5 100644 --- a/cocoa/fetch.h +++ b/cocoa/fetch.h @@ -17,5 +17,3 @@ */ extern struct gui_fetch_table *cocoa_fetch_table; - -char *url_to_path(const char *url); diff --git a/cocoa/fetch.m b/cocoa/fetch.m index 8cc2cb966..df424c3e8 100644 --- a/cocoa/fetch.m +++ b/cocoa/fetch.m @@ -95,18 +95,6 @@ static const char *fetch_filetype(const char *unix_path) return cocoafiletype; } -char *url_to_path(const char *url) -{ - NSURL *nsurl = [NSURL URLWithString: [NSString stringWithUTF8String: url]]; - return strdup([[nsurl path] UTF8String]); -} - -static char *path_to_url(const char *path) -{ - return strdup( [[[NSURL fileURLWithPath: [NSString stringWithUTF8String: path]] - absoluteString] UTF8String] ); -} - static nsurl *gui_get_resource_url(const char *path) { nsurl *url = NULL; @@ -118,8 +106,6 @@ static nsurl *gui_get_resource_url(const char *path) static struct gui_fetch_table fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, }; diff --git a/content/dirlist.c b/content/dirlist.c index 0c0e2aee2..1d7a67e1f 100644 --- a/content/dirlist.c +++ b/content/dirlist.c @@ -24,9 +24,12 @@ #include #include #include -#include "content/dirlist.h" + +#include "utils/nsurl.h" #include "utils/messages.h" +#include "content/dirlist.h" + static int dirlist_filesize_calculate(unsigned long *bytesize); static int dirlist_filesize_value(unsigned long bytesize); static char* dirlist_filesize_unit(unsigned long bytesize); @@ -262,7 +265,7 @@ bool dirlist_generate_headings(char *buffer, int buffer_length) * dirlist_generate_bottom() */ -bool dirlist_generate_row(bool even, bool directory, char *url, char *name, +bool dirlist_generate_row(bool even, bool directory, nsurl *url, char *name, const char *mimetype, long long size, char *date, char *time, char *buffer, int buffer_length) { @@ -288,7 +291,7 @@ bool dirlist_generate_row(bool even, bool directory, char *url, char *name, "\t%s\n" "\t%s\n" "\n", - url, even ? "even" : "odd", + nsurl_access(url), even ? "even" : "odd", directory ? "dir" : "file", name, mimetype, size_string, unit, date, time); if (error < 0 || error >= buffer_length) diff --git a/content/dirlist.h b/content/dirlist.h index bf90ec6d4..687f50688 100644 --- a/content/dirlist.h +++ b/content/dirlist.h @@ -39,7 +39,7 @@ bool dirlist_generate_title(const char *title, char *buffer, int buffer_length); bool dirlist_generate_parent_link(const char *parent, char *buffer, int buffer_length); bool dirlist_generate_headings(char *buffer, int buffer_length); -bool dirlist_generate_row(bool even, bool directory, char *url, char *name, +bool dirlist_generate_row(bool even, bool directory, nsurl *url, char *name, const char *mimetype, long long size, char *date, char *time, char *buffer, int buffer_length); bool dirlist_generate_bottom(char *buffer, int buffer_length); diff --git a/content/fetchers/about.c b/content/fetchers/about.c index d6a8c202c..b2aeeb35e 100644 --- a/content/fetchers/about.c +++ b/content/fetchers/about.c @@ -44,7 +44,6 @@ #include "testament.h" #include "utils/config.h" -#include "content/dirlist.h" #include "content/fetch.h" #include "content/fetchers/about.h" #include "content/urldb.h" diff --git a/content/fetchers/file.c b/content/fetchers/file.c index 7e7229649..7834b2702 100644 --- a/content/fetchers/file.c +++ b/content/fetchers/file.c @@ -138,13 +138,14 @@ fetch_file_setup(struct fetch *fetchh, { struct fetch_file_context *ctx; int i; + nserror ret; ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; - ctx->path = guit->fetch->url_to_path(nsurl_access(url)); - if (ctx->path == NULL) { + ret = guit->file->nsurl_to_path(url, &ctx->path); + if (ret != NSERROR_OK) { free(ctx); return NULL; } @@ -503,11 +504,11 @@ process_dir_ent(struct fetch_file_context *ctx, size_t buffer_len) { nserror ret; - char *path; /* url for list entries */ char *urlpath = NULL; /* buffer for leaf entry path */ struct stat ent_stat; /* stat result of leaf entry */ char datebuf[64]; /* buffer for date text */ char timebuf[64]; /* buffer for time text */ + nsurl *url; /* skip hidden files */ if (ent->d_name[0] == '.') { @@ -539,16 +540,17 @@ process_dir_ent(struct fetch_file_context *ctx, } } - if ((path = guit->fetch->path_to_url(urlpath)) == NULL) { + ret = guit->file->path_to_nsurl(urlpath, &url); + if (ret != NSERROR_OK) { free(urlpath); - return NSERROR_NOMEM; + return ret; } if (S_ISREG(ent_stat.st_mode)) { /* regular file */ dirlist_generate_row(even, false, - path, + url, ent->d_name, guit->fetch->filetype(urlpath), ent_stat.st_size, @@ -558,7 +560,7 @@ process_dir_ent(struct fetch_file_context *ctx, /* directory */ dirlist_generate_row(even, true, - path, + url, ent->d_name, messages_get("FileDirectory"), -1, @@ -568,7 +570,7 @@ process_dir_ent(struct fetch_file_context *ctx, /* something else */ dirlist_generate_row(even, false, - path, + url, ent->d_name, "", -1, @@ -576,7 +578,7 @@ process_dir_ent(struct fetch_file_context *ctx, buffer, buffer_len); } - free(path); + nsurl_unref(url); free(urlpath); return NSERROR_OK; diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c index 4ce49a06b..664c45720 100644 --- a/content/fetchers/resource.c +++ b/content/fetchers/resource.c @@ -37,7 +37,6 @@ #include #include "utils/config.h" -#include "content/dirlist.h" #include "content/fetch.h" #include "content/fetchers/resource.h" #include "content/urldb.h" diff --git a/desktop/gui.h b/desktop/gui.h index 5710d5328..bc7553c16 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -331,23 +331,6 @@ struct gui_fetch_table { */ const char *(*filetype)(const char *unix_path); - /** - * Convert a pathname to a file: URL. - * - * \param path pathname - * \return URL, allocated on heap, or NULL on failure - */ - char *(*path_to_url)(const char *path); - - /** - * Convert a file: URL to a pathname. - * - * \param url a file: URL - * \return pathname, allocated on heap, or NULL on failure - */ - char *(*url_to_path)(const char *url); - - /* Optional entries */ /** @@ -379,7 +362,6 @@ struct gui_fetch_table { }; - /** * User interface utf8 characterset conversion routines. */ diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c index 96c28e29d..a60766647 100644 --- a/desktop/gui_factory.c +++ b/desktop/gui_factory.c @@ -479,13 +479,6 @@ static nserror verify_fetch_register(struct gui_fetch_table *gft) if (gft->filetype == NULL) { return NSERROR_BAD_PARAMETER; } - if (gft->path_to_url == NULL) { - return NSERROR_BAD_PARAMETER; - } - if (gft->url_to_path == NULL) { - return NSERROR_BAD_PARAMETER; - } - /* fill in the optional entries with defaults */ if (gft->get_resource_url == NULL) { diff --git a/framebuffer/fetch.c b/framebuffer/fetch.c index 6d97cfda7..b32a95168 100644 --- a/framebuffer/fetch.c +++ b/framebuffer/fetch.c @@ -26,66 +26,15 @@ #include #include "utils/nsurl.h" -#include "utils/url.h" #include "utils/log.h" #include "utils/filepath.h" +#include "utils/file.h" #include "desktop/gui.h" #include "framebuffer/findfile.h" #include "framebuffer/fetch.h" -/** - * Convert a pathname to a file: URL. - * - * \param path pathname - * \return URL, allocated on heap, or NULL on failure - */ -static char *path_to_url(const char *path) -{ - int urllen; - char *url; - - if (path == NULL) - return NULL; - - urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - url = malloc(urllen); - - if (*path == '/') { - path++; /* file: paths are already absolute */ - } - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - return url; -} - -/** - * Convert a file: URL to a pathname. - * - * \param url a file: URL - * \return pathname, allocated on heap, or NULL on failure - */ -static char *url_to_path(const char *url) -{ - char *path; - char *respath; - nserror res; /* result from url routines */ - - res = url_path(url, &path); - if (res != NSERROR_OK) { - return NULL; - } - - res = url_unescape(path, &respath); - free(path); - if (res != NSERROR_OK) { - return NULL; - } - - return respath; -} /** * Translate resource to full url. @@ -101,17 +50,12 @@ static char *url_to_path(const char *url) static nsurl *get_resource_url(const char *path) { char buf[PATH_MAX]; - char *raw; nsurl *url = NULL; if (strcmp(path, "favicon.ico") == 0) path = "favicon.png"; - raw = path_to_url(filepath_sfind(respaths, buf, path)); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url); return url; } @@ -148,8 +92,6 @@ static const char *fetch_filetype(const char *unix_path) /* table for fetch operations */ static struct gui_fetch_table fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = get_resource_url, }; diff --git a/gtk/dialogs/source.c b/gtk/dialogs/source.c index c53c67fe4..67cb061be 100644 --- a/gtk/dialogs/source.c +++ b/gtk/dialogs/source.c @@ -26,6 +26,7 @@ #include "utils/messages.h" #include "utils/url.h" #include "utils/utils.h" +#include "utils/file.h" #include "desktop/netsurf.h" #include "desktop/browser_private.h" #include "render/html.h" @@ -263,7 +264,6 @@ void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw) nserror error; nserror r; gchar *filename; - char *fileurl; gint handle; source_data = content_get_source_data(bw->current_content, @@ -301,29 +301,21 @@ void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw) fprintf(f, "%s", ndata); fclose(f); free(ndata); - fileurl = path_to_url(filename); - g_free(filename); - if (fileurl == NULL) { - warn_user(messages_get("NoMemory"), 0); - return; - } /* Open tab */ - error = nsurl_create(fileurl, &url); - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } else { + error = netsurf_path_to_nsurl(filename, &url); + g_free(filename); + if (error == NSERROR_OK) { error = browser_window_create(BW_CREATE_TAB, url, NULL, bw, NULL); nsurl_unref(url); - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } } - free(fileurl); + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); + } } static void nsgtk_source_file_save(GtkWindow *parent, const char *filename, diff --git a/gtk/fetch.c b/gtk/fetch.c index c1857ab48..42ba89839 100644 --- a/gtk/fetch.c +++ b/gtk/fetch.c @@ -25,9 +25,9 @@ #include #include "utils/hashtable.h" -#include "utils/url.h" #include "utils/log.h" #include "utils/filepath.h" +#include "utils/file.h" #include "desktop/gui.h" #include "gtk/gui.h" @@ -226,56 +226,10 @@ const char *fetch_filetype(const char *unix_path) return type; } -char *path_to_url(const char *path) -{ - int urllen; - char *url; - - if (path == NULL) { - return NULL; - } - - urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - - url = malloc(urllen); - if (url == NULL) { - return NULL; - } - - if (*path == '/') { - path++; /* file: paths are already absolute */ - } - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - return url; -} - - -static char *url_to_path(const char *url) -{ - char *path; - char *respath; - nserror res; /* result from url routines */ - - res = url_path(url, &path); - if (res != NSERROR_OK) { - return NULL; - } - - res = url_unescape(path, &respath); - free(path); - if (res != NSERROR_OK) { - return NULL; - } - - return respath; -} static nsurl *gui_get_resource_url(const char *path) { char buf[PATH_MAX]; - char *raw; nsurl *url = NULL; /* default.css -> gtkdefault.css */ @@ -288,19 +242,13 @@ static nsurl *gui_get_resource_url(const char *path) path = "favicon.png"; } - raw = path_to_url(filepath_sfind(respaths, buf, path)); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url); return url; } static struct gui_fetch_table fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, }; diff --git a/gtk/fetch.h b/gtk/fetch.h index 400a06a35..a095adbf9 100644 --- a/gtk/fetch.h +++ b/gtk/fetch.h @@ -25,6 +25,4 @@ void gtk_fetch_filetype_init(const char *mimefile); void gtk_fetch_filetype_fin(void); const char *fetch_filetype(const char *unix_path); -char *path_to_url(const char *path); - #endif diff --git a/monkey/fetch.c b/monkey/fetch.c index 01258bb06..88cb27dcf 100644 --- a/monkey/fetch.c +++ b/monkey/fetch.c @@ -23,7 +23,7 @@ #include #include "desktop/gui.h" -#include "utils/url.h" +#include "utils/file.h" #include "utils/nsurl.h" #include "utils/filepath.h" @@ -33,70 +33,18 @@ extern char **respaths; -static char *path_to_url(const char *path) -{ - int urllen; - char *url; - - if (path == NULL) { - return NULL; - } - - urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 1; - - url = malloc(urllen); - if (url == NULL) { - return NULL; - } - - if (*path == '/') { - path++; /* file: paths are already absolute */ - } - - snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, path); - - return url; -} - -static char *url_to_path(const char *url) -{ - char *path; - char *respath; - nserror res; /* result from url routines */ - - res = url_path(url, &path); - if (res != NSERROR_OK) { - return NULL; - } - - res = url_unescape(path, &respath); - free(path); - if (res != NSERROR_OK) { - return NULL; - } - - return respath; -} - static nsurl *gui_get_resource_url(const char *path) { char buf[PATH_MAX]; - char *raw; nsurl *url = NULL; - raw = path_to_url(filepath_sfind(respaths, buf, path)); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url); return url; } static struct gui_fetch_table fetch_table = { .filetype = monkey_fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, }; diff --git a/riscos/gui.c b/riscos/gui.c index d9fcdbd02..51472a4bf 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -729,7 +729,17 @@ void ro_gui_check_resolvers(void) * \return URL, allocated on heap, or 0 on failure */ -static char *path_to_url(const char *path) +/** + * Create a nsurl from a RISC OS pathname. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The RISC OS pathname to convert. + * @param[out] url pointer to recive the nsurl, The returned url must be + * unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error code on faliure. + */ +static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out) { int spare; char *canonical_path; /* canonicalised RISC OS path */ @@ -746,15 +756,13 @@ static char *path_to_url(const char *path) LOG(("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess)); warn_user("PathToURL", error->errmess); - return NULL; + return NSERROR_NOT_FOUND; } canonical_path = malloc(1 - spare); if (canonical_path == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); free(canonical_path); - return NULL; + return NSERROR_NOMEM; } error = xosfscontrol_canonicalise_path(path, canonical_path, 0, 0, 1 - spare, 0); @@ -763,7 +771,7 @@ static char *path_to_url(const char *path) error->errnum, error->errmess)); warn_user("PathToURL", error->errmess); free(canonical_path); - return NULL; + return NSERROR_NOT_FOUND; } /* create a unix path from teh cananocal risc os one */ @@ -772,7 +780,7 @@ static char *path_to_url(const char *path) if (unix_path == NULL) { LOG(("__unixify failed: %s", canonical_path)); free(canonical_path); - return NULL; + return NSERROR_BAD_PARAMETER; } free(canonical_path); @@ -782,7 +790,7 @@ static char *path_to_url(const char *path) if (url == NULL) { LOG(("Unable to allocate url")); free(unix_path); - return NULL; + return NSERROR_NOMEM; } if (*unix_path == '/') { @@ -794,72 +802,93 @@ static char *path_to_url(const char *path) /* We don't want '/' to be escaped. */ url_err = url_escape(url, FILE_SCHEME_PREFIX_LEN, false, "/", &escurl); - free(url); url = NULL; + free(url); if (url_err != NSERROR_OK) { - LOG(("url_escape failed: %s", url)); - return NULL; + return url_err; } - return escurl; + ret = nsurl_create(escurl, url_out); + free(escurl); + + return ret; } - /** - * Convert a file: URL to a RISC OS pathname. + * Create a path from a nsurl using posix file handling. * - * \param url a file: URL - * \return RISC OS pathname, allocated on heap, or 0 on failure + * @parm[in] url The url to encode. + * @param[out] path_out A string containing the result path which should + * be freed by the caller. + * @return NSERROR_OK and the path is written to \a path or error code + * on faliure. */ - -char *url_to_path(const char *url) +static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out) { + lwc_string *urlpath; + char *unpath; char *path; - char *filename; - char *respath; - nserror res; /* result from url routines */ + bool match; + lwc_string *scheme; + nserror res; char *r; - res = url_path(url, &path); - if (res != NSERROR_OK) { - warn_user("NoMemory", 0); - return NULL; + if ((url == NULL) || (path_out == NULL)) { + return NSERROR_BAD_PARAMETER; } - res = url_unescape(path, &respath); - free(path); + scheme = nsurl_get_component(url, NSURL_SCHEME); + + if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) != lwc_error_ok) + { + return NSERROR_BAD_PARAMETER; + } + lwc_string_unref(scheme); + if (match == false) { + return NSERROR_BAD_PARAMETER; + } + + urlpath = nsurl_get_component(url, NSURL_PATH); + if (urlpath == NULL) { + return NSERROR_BAD_PARAMETER; + } + + res = url_unescape(lwc_string_data(urlpath), &unpath); + lwc_string_unref(urlpath); if (res != NSERROR_OK) { - return NULL; + return res; } /* RISC OS path should not be more than 100 characters longer */ - filename = malloc(strlen(respath) + 100); - if (!filename) { - free(respath); - warn_user("NoMemory", 0); - return NULL; + path = malloc(strlen(unpath) + 100); + if (path == NULL) { + free(unpath); + return NSERROR_NOMEM; } - r = __riscosify(respath, 0, __RISCOSIFY_NO_SUFFIX, - filename, strlen(respath) + 100, 0); - - free(respath); - if (r == 0) { - free(filename); - LOG(("__riscosify failed")); - return NULL; + r = __riscosify(unpath, 0, __RISCOSIFY_NO_SUFFIX, + path, strlen(unpath) + 100, 0); + free(unpath); + if (r == NULL) { + free(path); + return NSERROR_NOMEM; } - return filename; + *path_out = path; + + return NSERROR_OK; } + /** * Last-minute gui init, after all other modules have initialised. */ static void gui_init2(int argc, char** argv) { - char *url = 0; - bool open_window = nsoption_bool(open_browser_at_startup); + nsurl *url; + nserror ret; + bool open_window; /* Complete initialisation of the treeview modules. */ @@ -875,13 +904,16 @@ static void gui_init2(int argc, char** argv) /* cookies window */ ro_gui_cookies_postinitialise(); + open_window = nsoption_bool(open_browser_at_startup); /* parse command-line arguments */ if (argc == 2) { LOG(("parameters: '%s'", argv[1])); /* this is needed for launching URI files */ - if (strcasecmp(argv[1], "-nowin") == 0) - open_window = false; + if (strcasecmp(argv[1], "-nowin") == 0) { + return; + } + ret = nsurl_create(NETSURF_HOMEPAGE, &url); } else if (argc == 3) { LOG(("parameters: '%s' '%s'", argv[1], argv[2])); @@ -889,27 +921,21 @@ static void gui_init2(int argc, char** argv) /* HTML files */ if (strcasecmp(argv[1], "-html") == 0) { - url = path_to_url(argv[2]); - if (!url) { - LOG(("malloc failed")); - die("Insufficient memory for URL"); - } + ret = netsurf_path_to_nsurl(argv[2], &url); } /* URL files */ else if (strcasecmp(argv[1], "-urlf") == 0) { - url = ro_gui_url_file_parse(argv[2]); + char *urlf = ro_gui_url_file_parse(argv[2]); if (!url) { LOG(("malloc failed")); die("Insufficient memory for URL"); } + ret = nsurl_create(urlf, &url); + free(urlf); } /* ANT URL Load */ else if (strcasecmp(argv[1], "-url") == 0) { - url = strdup(argv[2]); - if (!url) { - LOG(("malloc failed")); - die("Insufficient memory for URL"); - } + ret = nsurl_create(argv[2], &url); } /* Unknown => exit here. */ else { @@ -919,42 +945,32 @@ static void gui_init2(int argc, char** argv) } } /* get user's homepage (if configured) */ - else if (nsoption_charp(homepage_url) && nsoption_charp(homepage_url)[0]) { - url = calloc(strlen(nsoption_charp(homepage_url)) + 5, sizeof(char)); - if (!url) { - LOG(("malloc failed")); - die("Insufficient memory for URL"); - } - sprintf(url, "%s", nsoption_charp(homepage_url)); + else if (nsoption_charp(homepage_url) && + nsoption_charp(homepage_url)[0]) { + ret = nsurl_create(nsoption_charp(homepage_url), &url); } /* default homepage */ else { - url = strdup(NETSURF_HOMEPAGE); - if (!url) { - LOG(("malloc failed")); - die("Insufficient memory for URL"); - } + ret = nsurl_create(NETSURF_HOMEPAGE, &url); + } + + /* check for url creation error */ + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); + return; } if (open_window) { - nsurl *urlns; - nserror errorns; - - errorns = nsurl_create(url, &urlns); - if (errorns == NSERROR_OK) { - errorns = browser_window_create(BW_CREATE_HISTORY, - urlns, - NULL, - NULL, - NULL); - nsurl_unref(urlns); - } - if (errorns != NSERROR_OK) { - warn_user(messages_get_errorcode(errorns), 0); + ret = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + if (ret != NSERROR_OK) { + warn_user(messages_get_errorcode(ret), 0); } } - - free(url); + nsurl_unref(url); } /** @@ -1471,12 +1487,20 @@ void ro_msg_dataload(wimp_message *message) case FILETYPE_ACORN_URI: urltxt = ro_gui_uri_file_parse(message->data.data_xfer.file_name, &title); + error = nsurl_create(urltxt, &url); + free(urltxt); break; + case FILETYPE_ANT_URL: urltxt = ro_gui_url_file_parse(message->data.data_xfer.file_name); + error = nsurl_create(urltxt, &url); + free(urltxt); break; + case FILETYPE_IEURL: urltxt = ro_gui_ieurl_file_parse(message->data.data_xfer.file_name); + error = nsurl_create(urltxt, &url); + free(urltxt); break; case FILETYPE_HTML: @@ -1494,50 +1518,40 @@ void ro_msg_dataload(wimp_message *message) case FILETYPE_ARTWORKS: case FILETYPE_SVG: /* display the actual file */ - urltxt = path_to_url(message->data.data_xfer.file_name); + error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, &url); break; default: return; } - if (!urltxt) - /* error has already been reported by one of the - * functions called above */ + /* report error to user */ + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); return; - - - error = nsurl_create(urltxt, &url); - if (error == NSERROR_OK) { - if (g) { - error = browser_window_navigate(g->bw, - url, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - -#ifdef DROPURLHOTLIST /** @todo This was commented out should it be removed? */ - } else if (ro_gui_hotlist_check_window( - message->data.data_xfer.w)) { - /* Drop URL into hotlist */ - ro_gui_hotlist_url_drop(message, urltxt); -#endif - } else { - error = browser_window_create(BW_CREATE_HISTORY, - url, - NULL, - NULL, - NULL); - } - nsurl_unref(url); } + + + if (g) { + error = browser_window_navigate(g->bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + } else { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + } + nsurl_unref(url); if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } - free(urltxt); /* send DataLoadAck */ message->action = message_DATA_LOAD_ACK; @@ -1859,29 +1873,45 @@ void ro_msg_dataopen(wimp_message *message) os_error *oserror; nsurl *urlns; nserror error; + size_t len; - if (file_type == 0xb28) /* ANT URL file */ + switch (file_type) { + case 0xb28: /* ANT URL file */ url = ro_gui_url_file_parse(message->data.data_xfer.file_name); - else if (file_type == 0xfaf) /* HTML file */ - url = path_to_url(message->data.data_xfer.file_name); - else if (file_type == 0x1ba) /* IEURL file */ + error = nsurl_create(url, &urlns); + free(url); + break; + + case 0xfaf: /* HTML file */ + error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, + &urlns); + break; + + case 0x1ba: /* IEURL file */ url = ro_gui_ieurl_file_parse(message-> data.data_xfer.file_name); - else if (file_type == 0x2000) { /* application */ - size_t len = strlen(message->data.data_xfer.file_name); + error = nsurl_create(url, &urlns); + free(url); + break; + + case 0x2000: /* application */ + len = strlen(message->data.data_xfer.file_name); if (len < 9 || strcmp(".!NetSurf", message->data.data_xfer.file_name + len - 9)) return; + if (nsoption_charp(homepage_url) && - nsoption_charp(homepage_url)[0]) { - url = strdup(nsoption_charp(homepage_url)); + nsoption_charp(homepage_url)[0]) { + error = nsurl_create(nsoption_charp(homepage_url), + &urlns); } else { - url = strdup(NETSURF_HOMEPAGE); + error = nsurl_create(NETSURF_HOMEPAGE, &urlns); } - if (!url) - warn_user("NoMemory", 0); - } else + break; + + default: return; + } /* send DataLoadAck */ message->action = message_DATA_LOAD_ACK; @@ -1894,22 +1924,18 @@ void ro_msg_dataopen(wimp_message *message) return; } - if (!url) - /* error has already been reported by one of the - * functions called above */ + if (error != NSERROR_OK) { + warn_user(messages_get_errorcode(error), 0); return; - - error = nsurl_create(url, &urlns); - free(url); - if (error == NSERROR_OK) { - /* create a new window with the file */ - error = browser_window_create(BW_CREATE_HISTORY, - urlns, - NULL, - NULL, - NULL); - nsurl_unref(urlns); } + + /* create a new window with the file */ + error = browser_window_create(BW_CREATE_HISTORY, + urlns, + NULL, + NULL, + NULL); + nsurl_unref(urlns); if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } @@ -2071,8 +2097,7 @@ void ro_gui_view_source(hlcache_handle *c) } /* try to load local files directly. */ - temp_name = url_to_path(nsurl_access(hlcache_handle_get_url(c))); - if (temp_name) { + if (netsurf_nsurl_to_path(hlcache_handle_get_url(c), &temp_name) == NSERROR_OK) { error = xosfile_read_no_path(temp_name, &objtype, 0, 0, 0, 0); if ((!error) && (objtype == osfile_IS_FILE)) { snprintf(message.file_name, 212, "%s", temp_name); @@ -2450,12 +2475,12 @@ static nserror riscos_basename(const char *path, char **str, size_t *size) static struct gui_file_table riscos_file_table = { .mkpath = riscos_mkpath, .basename = riscos_basename, + .nsurl_to_path = ro_nsurl_to_path, + .path_to_nsurl = ro_path_to_nsurl, }; static struct gui_fetch_table riscos_fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, .get_resource_url = gui_get_resource_url, .mimetype = fetch_mimetype, diff --git a/riscos/gui.h b/riscos/gui.h index 548d030a8..0ee426b4c 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -123,7 +123,6 @@ void ro_gui_dump_browser_window(struct browser_window *bw); void ro_gui_drag_box_start(wimp_pointer *pointer); bool ro_gui_prequit(void); const char *ro_gui_default_language(void); -char *url_to_path(const char *url); /* in download.c */ void ro_gui_download_init(void); diff --git a/riscos/window.c b/riscos/window.c index 771f3f5bb..0c95e5b21 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -46,6 +46,7 @@ #include "utils/log.h" #include "utils/talloc.h" #include "utils/url.h" +#include "utils/file.h" #include "utils/utf8.h" #include "utils/utils.h" #include "utils/messages.h" @@ -1673,7 +1674,7 @@ void ro_gui_window_close(wimp_w w) wimp_pointer pointer; os_error *error; char *temp_name, *r; - char *filename; + char *filename = NULL; hlcache_handle *h = NULL; bool destroy; @@ -1688,10 +1689,12 @@ void ro_gui_window_close(wimp_w w) h = g->bw->current_content; if (pointer.buttons & wimp_CLICK_ADJUST) { destroy = !ro_gui_shift_pressed(); - filename = (h && hlcache_handle_get_url(h)) ? - url_to_path(nsurl_access(hlcache_handle_get_url(h))) : - NULL; - if (filename) { + + if (h && hlcache_handle_get_url(h)) { + netsurf_nsurl_to_path(hlcache_handle_get_url(h), + &filename); + } + if (filename != NULL) { temp_name = malloc(strlen(filename) + 32); if (temp_name) { sprintf(temp_name, "Filer_OpenDir %s", diff --git a/utils/file.c b/utils/file.c index cb85d0e90..a2f1e94d0 100644 --- a/utils/file.c +++ b/utils/file.c @@ -22,10 +22,14 @@ #include #include +#include #include "desktop/gui_factory.h" -#include "utils/utils.h" +#include "utils/utils.h" +#include "utils/corestrings.h" +#include "utils/url.h" +#include "utils/nsurl.h" #include "utils/file.h" /** @@ -90,6 +94,118 @@ static nserror posix_basename(const char *path, char **str, size_t *size) return NSERROR_OK; } +/** + * Create a path from a nsurl using posix file handling. + * + * @parm[in] url The url to encode. + * @param[out] path_out A string containing the result path which should + * be freed by the caller. + * @return NSERROR_OK and the path is written to \a path or error code + * on faliure. + */ +static nserror posix_nsurl_to_path(struct nsurl *url, char **path_out) +{ + lwc_string *urlpath; + char *path; + bool match; + lwc_string *scheme; + nserror res; + + if ((url == NULL) || (path_out == NULL)) { + return NSERROR_BAD_PARAMETER; + } + + scheme = nsurl_get_component(url, NSURL_SCHEME); + + if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) != lwc_error_ok) + { + return NSERROR_BAD_PARAMETER; + } + lwc_string_unref(scheme); + if (match == false) { + return NSERROR_BAD_PARAMETER; + } + + urlpath = nsurl_get_component(url, NSURL_PATH); + if (urlpath == NULL) { + return NSERROR_BAD_PARAMETER; + } + + res = url_unescape(lwc_string_data(urlpath), &path); + lwc_string_unref(urlpath); + if (res != NSERROR_OK) { + return res; + } + + *path_out = path; + + return NSERROR_OK; +} + +/** + * Create a nsurl from a path using posix file handling. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The path to convert. + * @param[out] url_out pointer to recive the nsurl, The returned url + * should be unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error code on + * faliure. + */ +static nserror posix_path_to_nsurl(const char *path, struct nsurl **url_out) +{ + nserror ret; + int urllen; + char *urlstr; + char *escpath; /* escaped version of the path */ + char *escpaths; + + if ((path == NULL) || (url_out == NULL) || (*path == 0)) { + return NSERROR_BAD_PARAMETER; + } + + /* escape the path so it can be placed in a url */ + ret = url_escape(path, 0, false, "/", &escpath); + if (ret != NSERROR_OK) { + return ret; + } + /* remove unecessary / as file: paths are already absolute */ + escpaths = escpath; + while (*escpaths == '/') { + escpaths++; + } + + /* build url as a string for nsurl constructor */ + urllen = strlen(escpaths) + FILE_SCHEME_PREFIX_LEN + 1; + urlstr = malloc(urllen); + if (urlstr == NULL) { + free(escpath); + return NSERROR_NOMEM; + } + + snprintf(urlstr, urllen, "%s%s", FILE_SCHEME_PREFIX, escpaths); + free(escpath); + + ret = nsurl_create(urlstr, url_out); + free(urlstr); + + return ret; +} + +/** + * default to using the posix file handling + */ +static struct gui_file_table file_table = { + .mkpath = posix_vmkpath, + .basename = posix_basename, + .nsurl_to_path = posix_nsurl_to_path, + .path_to_nsurl = posix_path_to_nsurl, +}; + +struct gui_file_table *default_file_table = &file_table; + /* exported interface documented in utils/file.h */ nserror netsurf_mkpath(char **str, size_t *size, size_t nelm, ...) { @@ -103,10 +219,14 @@ nserror netsurf_mkpath(char **str, size_t *size, size_t nelm, ...) return ret; } -/* default to using the posix file handling */ -static struct gui_file_table file_table = { - .mkpath = posix_vmkpath, - .basename = posix_basename, -}; +/* exported interface documented in utils/file.h */ +nserror netsurf_nsurl_to_path(struct nsurl *url, char **path_out) +{ + return guit->file->nsurl_to_path(url, path_out); +} -struct gui_file_table *default_file_table = &file_table; +/* exported interface documented in utils/file.h */ +nserror netsurf_path_to_nsurl(const char *path, struct nsurl **url) +{ + return guit->file->path_to_nsurl(path, url); +} diff --git a/utils/file.h b/utils/file.h index f183337c5..2e47e1fa1 100644 --- a/utils/file.h +++ b/utils/file.h @@ -16,8 +16,20 @@ * along with this program. If not, see . */ -/** \file - * Default operations table for files. +/** + * \file utils/file.h + * \brief Default operations table for files. + * + * These are file operations that depend upon the filesystem the + * browser is operating on. These allow the core browser functionality + * to be filesystem agnostic. + * + * The provided defaults operate on POSIX path names with / as a + * directory separator in a single hieracy from a root directory. + * + * Other path conventions require the default operations to be + * overridden. For example windows frontend runs on a filesystem with + * drive letter and a \\ as a separator. */ #ifndef NETSURF_UTILS_FILE_H @@ -25,11 +37,15 @@ #include +struct nsurl; + /** - * function table for file and filename operations. + * /brief function table for file and filename operations. * - * function table implementing GUI interface to file and filename - * functionality appropriate for the OS. + * function table implementing an interface to file and filename + * functionality appropriate for the OS filesystem. All paths are in + * terms of the OS filesystem convention and must not require additional + * system specific changes. */ struct gui_file_table { /* Mandantory entries */ @@ -45,7 +61,7 @@ struct gui_file_table { * NULL on input and if not NULL set to the total * output length on output. * @param[in] nemb The number of elements. - * @param[in] ... The elements of the path as string pointers. + * @param[in] ap The elements of the path as string pointers. * @return NSERROR_OK and the complete path is written to str * or error code on faliure. */ @@ -62,10 +78,34 @@ struct gui_file_table { * @param[in,out] size The size of the space available if \a * str not NULL on input and set to the total * output length on output. - * @return NSERROR_OK and the complete path is written to str + * @return NSERROR_OK and the complete path is written to \a str * or error code on faliure. */ nserror (*basename)(const char *path, char **str, size_t *size); + + /** + * Create a path from a nsurl. + * + * @parm[in] url The url to encode. + * @param[out] path A string containing the result path which + * must be freed by the caller. + * @return NSERROR_OK and the path is written to \a path + * or error code on faliure. + */ + nserror (*nsurl_to_path)(struct nsurl *url, char **path); + + /** + * Create a nsurl from a path. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The path to convert. + * @param[out] url pointer to recive the nsurl, The returned + * url should be unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error + * code on faliure. + */ + nserror (*path_to_nsurl)(const char *path, struct nsurl **url); }; /** Default (posix) file operation table. */ @@ -92,4 +132,28 @@ struct gui_file_table *default_file_table; */ nserror netsurf_mkpath(char **str, size_t *size, size_t nelm, ...); +/** + * Create a path from a nsurl. + * + * @parm[in] url The url to encode. + * @param[out] path_out A string containing the result path which must be + * freed by the caller. + * @return NSERROR_OK and the path is written to \a path_out or error code on + * faliure. + */ +nserror netsurf_nsurl_to_path(struct nsurl *url, char **path_out); + +/** + * Create a nsurl from a path. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The path to convert. + * @param[out] url pointer to recive the nsurl, The returned + * url should be unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error + * code on faliure. + */ +nserror netsurf_path_to_nsurl(const char *path, struct nsurl **url); + #endif diff --git a/windows/findfile.c b/windows/findfile.c index 4862b4476..51ce74829 100644 --- a/windows/findfile.c +++ b/windows/findfile.c @@ -82,61 +82,6 @@ static char *realpath(const char *path, char *resolved_path) return strncpy(resolved_path, path, PATH_MAX); } -char *path_to_url(const char *path) -{ - char *url; - char *sidx; - - if (path == NULL) - return NULL; - - url = malloc(strlen(path) + FILE_SCHEME_PREFIX_LEN + 3); - - if (url == NULL) - return NULL; - - strcpy(url, FILE_SCHEME_PREFIX); - if (*path == '/') { - /* unix style path start, so try wine Z: */ - strcat(url, "Z:"); - } - strcat(url, path); - - sidx = strrchr(url, '\\'); - while (sidx != NULL) { - *sidx = '/'; - sidx = strrchr(url, '\\'); - } - - return url; -} - - -char *url_to_path(const char *url) -{ - char *url_path = curl_unescape(url, 0); - char *path; - char *sidx; - - if ((url_path[FILE_SCHEME_PREFIX_LEN + 1] == ':') || - (url_path[FILE_SCHEME_PREFIX_LEN + 1] == '|')) { - /* url_path contains a drive: prefix */ - path = strdup(url_path + FILE_SCHEME_PREFIX_LEN); - - /* swap / for \ */ - sidx = strrchr(path, '/'); - while (sidx != NULL) { - *sidx = '\\'; - sidx = strrchr(path, '/'); - } - } else { - /* return the absolute path including leading / */ - path = strdup(url_path + (FILE_SCHEME_PREFIX_LEN - 1)); - } - curl_free(url_path); - - return path; -} /** * Locate a shared resource file by searching known places in order. diff --git a/windows/findfile.h b/windows/findfile.h index 8a3e719ec..808adc8ef 100644 --- a/windows/findfile.h +++ b/windows/findfile.h @@ -23,8 +23,4 @@ extern char *nsws_find_resource(char *buf, const char *filename, const char *def char **nsws_init_resource(const char *resource_path); -char *path_to_url(const char *path); -char *url_to_path(const char *url); - - #endif /* _NETSURF_WINDOWS_FINDFILE_H_ */ diff --git a/windows/gui.c b/windows/gui.c index eddb58ff6..fe0c52249 100644 --- a/windows/gui.c +++ b/windows/gui.c @@ -189,7 +189,7 @@ nsws_window_urlbar_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); if (hFont != NULL) { LOG(("Destroyed font object")); - DeleteObject(hFont); + DeleteObject(hFont); } @@ -549,7 +549,7 @@ get_imagelist(int resid, int bsize, int bcnt) LOG(("resource id %d, bzize %d, bcnt %d",resid, bsize, bcnt)); hImageList = ImageList_Create(bsize, bsize, ILC_COLOR24 | ILC_MASK, 0, bcnt); - if (hImageList == NULL) + if (hImageList == NULL) return NULL; hScrBM = LoadImage(hInstance, MAKEINTRESOURCE(resid), @@ -557,7 +557,7 @@ get_imagelist(int resid, int bsize, int bcnt) if (hScrBM == NULL) { win_perror("LoadImage"); - return NULL; + return NULL; } if (ImageList_AddMasked(hImageList, hScrBM, 0xcccccc) == -1) { @@ -669,17 +669,17 @@ nsws_window_create_toolbar(struct gui_window *gw, HWND hWndParent) /* Create the standard image list and assign to toolbar. */ hImageList = get_imagelist(IDR_TOOLBAR_BITMAP, gw->toolbuttonsize, gw->toolbuttonc); - if (hImageList != NULL) + if (hImageList != NULL) SendMessage(hWndToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList); /* Create the disabled image list and assign to toolbar. */ hImageList = get_imagelist(IDR_TOOLBAR_BITMAP_GREY, gw->toolbuttonsize, gw->toolbuttonc); - if (hImageList != NULL) + if (hImageList != NULL) SendMessage(hWndToolbar, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)hImageList); /* Create the hot image list and assign to toolbar. */ hImageList = get_imagelist(IDR_TOOLBAR_BITMAP_HOT, gw->toolbuttonsize, gw->toolbuttonc); - if (hImageList != NULL) + if (hImageList != NULL) SendMessage(hWndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)hImageList); /* Add buttons. */ @@ -1090,7 +1090,7 @@ nsws_window_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (msg == WM_CREATE) { /* To cause all the component child windows to be * re-sized correctly a WM_SIZE message of the actual - * created size must be sent. + * created size must be sent. * * The message must be posted here because the actual * size values of the component windows are not known @@ -1794,7 +1794,7 @@ static void gui_set_clipboard(const char *buffer, size_t length, /** * Create the main window class. */ -nserror +nserror nsws_create_main_class(HINSTANCE hinstance) { nserror ret = NSERROR_OK; WNDCLASSEX w; @@ -1885,10 +1885,134 @@ static nserror windows_basename(const char *path, char **str, size_t *size) return NSERROR_OK; } -/* default to using the posix file handling */ +/** + * Create a path from a nsurl using windows file handling. + * + * @parm[in] url The url to encode. + * @param[out] path_out A string containing the result path which should + * be freed by the caller. + * @return NSERROR_OK and the path is written to \a path or error code + * on faliure. + */ +static nserror windows_nsurl_to_path(struct nsurl *url, char **path_out) +{ + lwc_string *urlpath; + char *path; + bool match; + lwc_string *scheme; + nserror res; + + if ((url == NULL) || (path_out == NULL)) { + return NSERROR_BAD_PARAMETER; + } + + scheme = nsurl_get_component(url, NSURL_SCHEME); + + if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) != lwc_error_ok) + { + return NSERROR_BAD_PARAMETER; + } + lwc_string_unref(scheme); + if (match == false) { + return NSERROR_BAD_PARAMETER; + } + + urlpath = nsurl_get_component(url, NSURL_PATH); + if (urlpath == NULL) { + return NSERROR_BAD_PARAMETER; + } + + res = url_unescape(lwc_string_data(urlpath), &path); + lwc_string_unref(urlpath); + if (res != NSERROR_OK) { + return res; + } + + /* if there is a drive: prefix treat path as DOS filename */ + if ((path[2] == ':') || (path[2] == '|')) { + char *sidx; /* slash index */ + + /* move the string down to remove leading / note the + * strlen is *not* copying too much data as we are + * moving the null too! + */ + memmove(path, path + 1, strlen(path)); + + /* swap / for \ */ + sidx = strrchr(path, '/'); + while (sidx != NULL) { + *sidx = '\\'; + sidx = strrchr(path, '/'); + } + } + /* if the path does not have a drive letter we return the + * complete path. + */ + /** @todo Need to check returning the unaltered path in this + * case is correct + */ + + *path_out = path; + + return NSERROR_OK; +} + +/** + * Create a nsurl from a path using windows file handling. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The path to convert. + * @param[out] url_out pointer to recive the nsurl, The returned url + * should be unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error code on + * faliure. + */ +static nserror windows_path_to_nsurl(const char *path, struct nsurl **url_out) +{ + nserror ret; + int urllen; + char *urlstr; + char *sidx; /* slash index */ + + if ((path == NULL) || (url_out == NULL) || (*path == 0)) { + return NSERROR_BAD_PARAMETER; + } + + /* build url as a string for nsurl constructor */ + urllen = strlen(path) + FILE_SCHEME_PREFIX_LEN + 5; + urlstr = malloc(urllen); + if (urlstr == NULL) { + return NSERROR_NOMEM; + } + + /** @todo check if this should be url escaping the path. */ + if (*path == '/') { + /* unix style path start, so try wine Z: */ + snprintf(urlstr, urllen, "%sZ%%3A%s", FILE_SCHEME_PREFIX, path); + } else { + snprintf(urlstr, urllen, "%s%s", FILE_SCHEME_PREFIX, path); + } + + sidx = strrchr(urlstr, '\\'); + while (sidx != NULL) { + *sidx = '/'; + sidx = strrchr(urlstr, '\\'); + } + + ret = nsurl_create(urlstr, url_out); + free(urlstr); + + return ret; +} + +/* windows file handling */ static struct gui_file_table file_table = { .mkpath = windows_mkpath, .basename = windows_basename, + .nsurl_to_path = windows_nsurl_to_path, + .path_to_nsurl = windows_path_to_nsurl, }; struct gui_file_table *win32_file_table = &file_table; @@ -1926,8 +2050,6 @@ struct gui_clipboard_table *win32_clipboard_table = &clipboard_table; static struct gui_fetch_table fetch_table = { .filetype = fetch_filetype, - .path_to_url = path_to_url, - .url_to_path = url_to_path, }; struct gui_fetch_table *win32_fetch_table = &fetch_table; diff --git a/windows/main.c b/windows/main.c index 7ad3d8550..637aa217f 100644 --- a/windows/main.c +++ b/windows/main.c @@ -44,14 +44,9 @@ char *options_file_location; static nsurl *gui_get_resource_url(const char *path) { char buf[PATH_MAX]; - char *raw; nsurl *url = NULL; - raw = path_to_url(filepath_sfind(respaths, buf, path)); - if (raw != NULL) { - nsurl_create(raw, &url); - free(raw); - } + netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url); return url; }