| 3857 g_free(cmd); |
3857 g_free(cmd); |
| 3858 if (params) |
3858 if (params) |
| 3859 g_hash_table_destroy(params); |
3859 g_hash_table_destroy(params); |
| 3860 } |
3860 } |
| 3861 |
3861 |
| 3862 /* |
|
| 3863 * TODO: Should probably add a "gboolean *ret_ishttps" parameter that |
|
| 3864 * is set to TRUE if this URL is https, otherwise it is set to |
|
| 3865 * FALSE. But that change will break the API. |
|
| 3866 * |
|
| 3867 * This is important for Yahoo! web messenger login. They now |
|
| 3868 * force https login, and if you access the web messenger login |
|
| 3869 * page via http then it redirects you to the https version, but |
|
| 3870 * purple_util_fetch_url() ignores the "https" and attempts to |
|
| 3871 * fetch the URL via http again, which gets redirected again. |
|
| 3872 */ |
|
| 3873 gboolean |
3862 gboolean |
| 3874 purple_url_parse(const char *url, char **ret_host, int *ret_port, |
3863 purple_url_parse(const char *url, char **ret_proto, char **ret_host, |
| 3875 char **ret_path, char **ret_user, char **ret_passwd) |
3864 int *ret_port, char **ret_path, char **ret_user, char **ret_passwd) |
| 3876 { |
3865 { |
| 3877 gboolean is_https = FALSE; |
3866 gboolean is_https = FALSE; |
| 3878 const char * scan_info; |
3867 const char * scan_info; |
| 3879 char port_str[6]; |
3868 char port_str[6]; |
| 3880 int f; |
3869 int f; |
| 3881 const char *at, *slash; |
3870 const char *at, *slash, *colon; |
| 3882 const char *turl; |
3871 char proto[256], host[256], path[256], user[256], passwd[256]; |
| 3883 char host[256], path[256], user[256], passwd[256]; |
|
| 3884 int port = 0; |
3872 int port = 0; |
| 3885 /* hyphen at end includes it in control set */ |
3873 /* hyphen at end includes it in control set */ |
| 3886 |
3874 |
| |
3875 #define PROTO_CTRL "A-Za-z" |
| 3887 #define ADDR_CTRL "A-Za-z0-9.-" |
3876 #define ADDR_CTRL "A-Za-z0-9.-" |
| 3888 #define PORT_CTRL "0-9" |
3877 #define PORT_CTRL "0-9" |
| 3889 #define PAGE_CTRL "A-Za-z0-9.,~_/:*!@&%%?=+^-" |
3878 #define PAGE_CTRL "A-Za-z0-9.,~_/:*!@&%%?=+^-" |
| 3890 #define USER_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-" |
3879 #define USER_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-" |
| 3891 #define PASSWD_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-" |
3880 #define PASSWD_CTRL "A-Za-z0-9.,~_/*!&%%?=+^-" |
| 3892 |
3881 |
| 3893 g_return_val_if_fail(url != NULL, FALSE); |
3882 g_return_val_if_fail(url != NULL, FALSE); |
| 3894 |
3883 g_return_val_if_fail(strlen(url) >= 256, FALSE); |
| 3895 if ((turl = purple_strcasestr(url, "http://")) != NULL) |
3884 |
| 3896 { |
3885 colon = strchr(url, ':'); |
| 3897 turl += 7; |
3886 if (colon) { |
| 3898 url = turl; |
3887 scan_info = "%255[" PROTO_CTRL "]:"; |
| 3899 } |
3888 f = sscanf(url, scan_info, proto); |
| 3900 else if ((turl = purple_strcasestr(url, "https://")) != NULL) |
3889 |
| 3901 { |
3890 if (f == 1) { |
| 3902 is_https = TRUE; |
3891 url = colon + 1; |
| 3903 turl += 8; |
3892 if (url[0] == '/') url++; |
| 3904 url = turl; |
3893 if (url[0] == '/') url++; |
| 3905 } |
3894 } else |
| |
3895 proto[0] = '\0'; |
| |
3896 } |
| |
3897 |
| |
3898 is_https = (g_ascii_strcasecmp(proto, "https") == 0); |
| 3906 |
3899 |
| 3907 /* parse out authentication information if supplied */ |
3900 /* parse out authentication information if supplied */ |
| 3908 /* Only care about @ char BEFORE the first / */ |
3901 /* Only care about @ char BEFORE the first / */ |
| 3909 at = strchr(url, '@'); |
3902 at = strchr(url, '@'); |
| 3910 slash = strchr(url, '/'); |
3903 slash = strchr(url, '/'); |
| 3948 if (f <= 1) |
3941 if (f <= 1) |
| 3949 *path = '\0'; |
3942 *path = '\0'; |
| 3950 |
3943 |
| 3951 sscanf(port_str, "%d", &port); |
3944 sscanf(port_str, "%d", &port); |
| 3952 |
3945 |
| |
3946 if (ret_proto != NULL) *ret_proto = g_strdup(proto); |
| 3953 if (ret_host != NULL) *ret_host = g_strdup(host); |
3947 if (ret_host != NULL) *ret_host = g_strdup(host); |
| 3954 if (ret_port != NULL) *ret_port = port; |
3948 if (ret_port != NULL) *ret_port = port; |
| 3955 if (ret_path != NULL) *ret_path = g_strdup(path); |
3949 if (ret_path != NULL) *ret_path = g_strdup(path); |
| 3956 if (ret_user != NULL) *ret_user = g_strdup(user); |
3950 if (ret_user != NULL) *ret_user = g_strdup(user); |
| 3957 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd); |
3951 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd); |