📄 url.c
字号:
/* url.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"struct { unsigned char *prot; int port; void (*func)(struct connection *); void (*nc_func)(struct session *, unsigned char *); int free_syntax; int need_slashes; int need_slash_after_host; int allow_post; int bypasses_socks;} protocols[]= { {"file", 0, file_func, NULL, 1, 1, 0, 0, 1}, {"https", 443, https_func, NULL, 0, 1, 1, 1, 0}, {"http", 80, http_func, NULL, 0, 1, 1, 1, 0}, {"proxy", 3128, proxy_func, NULL, 0, 1, 1, 1, 0}, {"ftp", 21, ftp_func, NULL, 0, 1, 1, 0, 0}, {"finger", 79, finger_func, NULL, 0, 1, 1, 0, 0},#ifndef DISABLE_SMB {"smb", 139, smb_func, NULL, 0, 1, 1, 0, 1},#endif {"mailto", 0, NULL, mailto_func, 0, 0, 0, 0, 0}, {"telnet", 0, NULL, telnet_func, 0, 0, 0, 0, 1}, {"tn3270", 0, NULL, tn3270_func, 0, 0, 0, 0, 1}, {"mms", 0, NULL, mms_func, 1, 0, 1, 0, 1},#ifdef JS {"javascript", 0, NULL, javascript_func,1, 0, 0, 0, 0},#endif {NULL, 0, NULL, NULL, 0, 0, 0, 0, 0}};/* prototypes */int check_protocol(unsigned char *, int);int get_prot_info(unsigned char *, int *, void (**)(struct connection *), void (**)(struct session *ses, unsigned char *), int *, int *);void translate_directories(unsigned char *);void insert_wd(unsigned char **, unsigned char *);int check_protocol(unsigned char *p, int l){ int i; for (i = 0; protocols[i].prot; i++) if (!casecmp(protocols[i].prot, p, l) && strlen(protocols[i].prot) == (size_t)l) { return i; } return -1;}int get_prot_info(unsigned char *prot, int *port, void (**func)(struct connection *), void (**nc_func)(struct session *ses, unsigned char *), int *allow_post, int *bypasses_socks){ int i; for (i = 0; protocols[i].prot; i++) if (!strcasecmp(protocols[i].prot, prot)) { if (port) *port = protocols[i].port; if (func) *func = protocols[i].func; if (nc_func) *nc_func = protocols[i].nc_func; if (allow_post) *allow_post = protocols[i].allow_post; if (bypasses_socks) *bypasses_socks = protocols[i].bypasses_socks; return 0; } return -1;}int parse_url(unsigned char *url, int *prlen, unsigned char **user, int *uslen, unsigned char **pass, int *palen, unsigned char **host, int *holen, unsigned char **port, int *polen, unsigned char **data, int *dalen, unsigned char **post){ unsigned char *p, *q; unsigned char p_c[2]; int a; if (prlen) *prlen = 0; if (user) *user = NULL; if (uslen) *uslen = 0; if (pass) *pass = NULL; if (palen) *palen = 0; if (host) *host = NULL; if (holen) *holen = 0; if (port) *port = NULL; if (polen) *polen = 0; if (data) *data = NULL; if (dalen) *dalen = 0; if (post) *post = NULL; if (!url || !(p = strchr(url, ':'))) return -1; if (prlen) *prlen = p - url; if ((a = check_protocol(url, p - url)) == -1) return -1; if (p[1] != '/' || p[2] != '/') { if (protocols[a].need_slashes) return -1; p -= 2; } if (protocols[a].free_syntax) { if (data) *data = p + 3; if (dalen) *dalen = strlen(p + 3); return 0; } p += 3; q = p + strcspn(p, "@/?"); if (!*q && protocols[a].need_slash_after_host) return -1; if (*q == '@') { unsigned char *pp; while (strcspn(q + 1, "@") < strcspn(q + 1, "/?")) q = q + 1 + strcspn(q + 1, "@"); pp = strchr(p, ':'); if (!pp || pp > q) { if (user) *user = p; if (uslen) *uslen = q - p; } else { if (user) *user = p; if (uslen) *uslen = pp - p; if (pass) *pass = pp + 1; if (palen) *palen = q - pp - 1; } p = q + 1; } q = p + strcspn(p, ":/?"); if (!*q && protocols[a].need_slash_after_host) return -1; if (host) *host = p; if (holen) *holen = q - p; if (*q == ':') { unsigned char *pp = q + strcspn(q, "/"); int cc; if (*pp != '/' && protocols[a].need_slash_after_host) return -1; if (port) *port = q + 1; if (polen) *polen = pp - q - 1; for (cc = 0; cc < pp - q - 1; cc++) if (q[cc+1] < '0' || q[cc+1] > '9') return -1; q = pp; } if (*q && *q != '?') q++; p = q; p_c[0] = POST_CHAR; p_c[1] = 0; q = p + strcspn(p, p_c); if (data) *data = p; if (dalen) *dalen = q - p; if (post) *post = *q ? q + 1 : NULL; return 0;}unsigned char *get_protocol_name(unsigned char *url){ int l; if (parse_url(url, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) return NULL; return memacpy(url, l);}unsigned char *get_host_and_pass(unsigned char *url){ unsigned char *u, *h, *p, *z, *k; int hl, pl; if (parse_url(url, NULL, &u, NULL, NULL, NULL, &h, &hl, &p, &pl, NULL, NULL, NULL)) return NULL; z = u ? u : h; k = p ? p + pl : h + hl; return memacpy(z, k - z);}unsigned char *get_host_name(unsigned char *url){ unsigned char *h; int hl; if (parse_url(url, NULL, NULL, NULL, NULL, NULL, &h, &hl, NULL, NULL, NULL, NULL, NULL)) return stracpy(""); return memacpy(h, hl);}unsigned char *get_user_name(unsigned char *url){ unsigned char *h; int hl; if (parse_url(url, NULL, &h, &hl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) return NULL; return memacpy(h, hl);}unsigned char *get_pass(unsigned char *url){ unsigned char *h; int hl; if (parse_url(url, NULL,NULL, NULL, &h, &hl, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) return NULL; return memacpy(h, hl);}unsigned char *get_port_str(unsigned char *url){ unsigned char *h; int hl; if (parse_url(url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &h, &hl, NULL, NULL, NULL)) return NULL; return hl ? memacpy(h, hl) : NULL;}int get_port(unsigned char *url){ unsigned char *h; int hl; long n = -1; if (parse_url(url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &h, &hl, NULL, NULL, NULL)) return -1; if (h) { n = strtol(h, NULL, 10); if (n && n < MAXINT) return n; } if ((h = get_protocol_name(url))) { int nn; get_prot_info(h, &nn, NULL, NULL, NULL, NULL); mem_free(h); n = nn; } return n;}void (*get_protocol_handle(unsigned char *url))(struct connection *){ unsigned char *p; void (*f)(struct connection *) = NULL; int post = 0; if (!(p = get_protocol_name(url))) return NULL; get_prot_info(p, NULL, &f, NULL, &post, NULL); mem_free(p); if (!post && strchr(url, POST_CHAR)) return NULL; return f;}void (*get_external_protocol_function(unsigned char *url))(struct session *, unsigned char *){ unsigned char *p; void (*f)(struct session *, unsigned char *) = NULL; int post = 0; if (!(p = get_protocol_name(url))) return NULL; get_prot_info(p, NULL, NULL, &f, &post, NULL); mem_free(p); if (!post && strchr(url, POST_CHAR)) return NULL; return f;}int url_bypasses_socks(unsigned char *url){ int ret; unsigned char *p; if (!(p = get_protocol_name(url))) return 1; get_prot_info(p, NULL, NULL, NULL, NULL, &ret); mem_free(p); return ret;}unsigned char *get_url_data(unsigned char *url){ unsigned char *d; if (parse_url(url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &d, NULL, NULL)) return NULL; return d;}#define dsep(x) (lo ? dir_sep(x) : (x) == '/')void translate_directories(unsigned char *url){ unsigned char *dd = get_url_data(url); unsigned char *s, *d; int lo = !casecmp(url, "file://", 7); if (!casecmp(url, "javascript:", 11)) return; if (!dd || dd == url/* || *--dd != '/'*/) return; if (!dsep(*dd)) { dd--; if (!dsep(*dd)) { dd++; memmove(dd + 1, dd, strlen(dd) + 1); *dd = '/'; } } s = dd; d = dd; r: if (end_of_dir(url, s[0])) { memmove(d, s, strlen(s) + 1); return; } if (dsep(s[0]) && s[1] == '.' && dsep(s[2])) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -