diff options
author | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-01-14 04:42:01 +0800 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-01-14 04:42:01 +0800 |
commit | af1c2ceaef7d949e36a7680f463c5e25f79c43d6 (patch) | |
tree | 19c94f1df613831ed8ab92b4ac904be0c20c673f /lib/ephy-string.c | |
parent | 12d96e8a6fc9eddaffdbad58754e712af5fc5fef (diff) | |
download | gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.gz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.bz2 gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.lz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.xz gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.tar.zst gsoc2013-epiphany-af1c2ceaef7d949e36a7680f463c5e25f79c43d6.zip |
Drop gnome-vfs dependency. Now Epiphany depends on glib >= 2.15.1.
Also, optional Zeroconf support depends on Avahi >= 0.6.22.
Bug #507152.
svn path=/trunk/; revision=7858
Diffstat (limited to 'lib/ephy-string.c')
-rw-r--r-- | lib/ephy-string.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/lib/ephy-string.c b/lib/ephy-string.c index 391ad9b39..4dc8d8e9a 100644 --- a/lib/ephy-string.c +++ b/lib/ephy-string.c @@ -26,6 +26,8 @@ #include <string.h> #include <stdlib.h> #include <glib.h> +#include <sys/types.h> +#include <pwd.h> #define ELLIPSIS "\xe2\x80\xa6" @@ -286,3 +288,241 @@ ephy_string_enum_to_string (GType type, return retval; } + +/* Following code copied from gnome-vfs-private-utils.c */ + +static int +find_next_slash (const char *path, int current_offset) +{ + const char *match; + + g_assert (current_offset <= strlen (path)); + + match = strchr (path + current_offset, G_DIR_SEPARATOR); + return match == NULL ? -1 : match - path; +} + +static int +find_slash_before_offset (const char *path, int to) +{ + int result; + int next_offset; + + result = -1; + next_offset = 0; + for (;;) { + next_offset = find_next_slash (path, next_offset); + if (next_offset < 0 || next_offset >= to) { + break; + } + result = next_offset; + next_offset++; + } + return result; +} + +static void +collapse_slash_runs (char *path, int from_offset) +{ + int i; + /* Collapse multiple `/'s in a row. */ + for (i = from_offset;; i++) { + if (path[i] != G_DIR_SEPARATOR) { + break; + } + } + + if (from_offset < i) { + memmove (path + from_offset, path + i, strlen (path + i) + 1); + i = from_offset + 1; + } +} + +/* Canonicalize path, and return a new path. Do everything in situ. The new + path differs from path in: + + Multiple `/'s are collapsed to a single `/'. + Leading `./'s and trailing `/.'s are removed. + Non-leading `../'s and trailing `..'s are handled by removing + portions of the path. */ +char * +ephy_string_canonicalize_pathname (const char *cpath) +{ + char *path; + int i, marker; + + path = g_strdup (cpath); + + if (path == NULL || strlen (path) == 0) { + return ""; + } + + /* Walk along path looking for things to compact. */ + for (i = 0, marker = 0;;) { + if (!path[i]) + break; + + /* Check for `../', `./' or trailing `.' by itself. */ + if (path[i] == '.') { + /* Handle trailing `.' by itself. */ + if (path[i + 1] == '\0') { + if (i > 1 && path[i - 1] == G_DIR_SEPARATOR) { + /* strip the trailing /. */ + path[i - 1] = '\0'; + } else { + /* convert path "/." to "/" */ + path[i] = '\0'; + } + break; + } + + /* Handle `./'. */ + if (path[i + 1] == G_DIR_SEPARATOR) { + memmove (path + i, path + i + 2, + strlen (path + i + 2) + 1); + if (i == 0) { + /* don't leave leading '/' for paths that started + * as relative (.//foo) + */ + collapse_slash_runs (path, i); + marker = 0; + } + continue; + } + + /* Handle `../' or trailing `..' by itself. + * Remove the previous xxx/ part + */ + if (path[i + 1] == '.' + && (path[i + 2] == G_DIR_SEPARATOR + || path[i + 2] == '\0')) { + + /* ignore ../ at the beginning of a path */ + if (i != 0) { + marker = find_slash_before_offset (path, i - 1); + + /* Either advance past '/' or point to the first character */ + marker ++; + if (path [i + 2] == '\0' && marker > 1) { + /* If we are looking at a /.. at the end of the uri and we + * need to eat the last '/' too. + */ + marker--; + } + g_assert(marker < i); + + if (path[i + 2] == G_DIR_SEPARATOR) { + /* strip the entire ../ string */ + i++; + } + + memmove (path + marker, path + i + 2, + strlen (path + i + 2) + 1); + i = marker; + } else { + i = 2; + if (path[i] == G_DIR_SEPARATOR) { + i++; + } + } + collapse_slash_runs (path, i); + continue; + } + } + + /* advance to the next '/' */ + i = find_next_slash (path, i); + + /* If we didn't find any slashes, then there is nothing left to do. */ + if (i < 0) { + break; + } + + marker = i++; + collapse_slash_runs (path, i); + } + return path; +} + +/* End of copied code */ + +char * +ephy_string_get_host_name (const char *url) +{ + const char *start; + const char *p; + + if (url == NULL || g_str_has_prefix (url, "file://")) return NULL; + + start = strstr (url, "//"); + if (start == NULL || start == '\0') + { + /* Not an URL */ + return NULL; + } + if (strlen (start) > 2) + { + /* Go past the protocol part */ + start = start + 2; + } + else + { + /* Not an URL again */ + return NULL; + } + p = strchr (start, '@'); + if (p != NULL) + { + /* We have a username:password@hostname scheme, skip it. */ + if (strlen (p) > 1) start = ++p; + } + p = strchr (start, ':'); + if (p != NULL) + { + /* hostname:port, skip port */ + return g_strndup (start, (p - start)); + } + p = strchr (start, '/'); + if (p == NULL) + { + /* No more slashes in the url, we assume it's a host name */ + return g_strdup (start); + } + + return g_strndup (start, (p - start)); +} + +char * +ephy_string_expand_initial_tilde (const char *path) +{ + char *slash_after_user_name, *user_name; + struct passwd *passwd_file_entry; + + g_return_val_if_fail (path != NULL, NULL); + + if (path[0] != '~') { + return g_strdup (path); + } + + if (path[1] == '/' || path[1] == '\0') { + return g_strconcat (g_get_home_dir (), &path[1], NULL); + } + + slash_after_user_name = strchr (&path[1], '/'); + if (slash_after_user_name == NULL) { + user_name = g_strdup (&path[1]); + } else { + user_name = g_strndup (&path[1], + slash_after_user_name - &path[1]); + } + passwd_file_entry = getpwnam (user_name); + g_free (user_name); + + if (passwd_file_entry == NULL || passwd_file_entry->pw_dir == NULL) { + return g_strdup (path); + } + + return g_strconcat (passwd_file_entry->pw_dir, + slash_after_user_name, + NULL); +} |