Esempio n. 1
0
static int ssl_set_private_paths(void)
{
	unsigned char *path, *c;
	int r;
#ifdef OPENVMS
	path = stracpy(g_argv[0]);
#else
	path = stracpy(path_to_exe);
#endif
	for (c = path + strlen(cast_const_char path); c > path; c--) {
		if (dir_sep(c[-1])
#ifdef OPENVMS
		    || c[-1] == ']' || c[-1] == ':'
#endif
		    )
			break;
	}
	c[0] = 0;
	add_to_strn(&path, cast_uchar stringify(LINKS_CRT_FILE));
	r = SSL_CTX_load_verify_locations(context, cast_const_char path, NULL);
	mem_free(path);
	if (r != 1)
		return -1;
	return 0;
}
Esempio n. 2
0
static int search_list_and_wildcards(const_char_ptr const *list, int len, unsigned char *name)
{
	unsigned char *dot, *x;
	int sl;

	if (search_list(list, len, name)) return 1;

	x = stracpy(cast_uchar "*.");
	add_to_strn(&x, name);
	sl = search_list(list, len, x);
	mem_free(x);
	if (sl) return 1;

	dot = cast_uchar strchr(cast_const_char name, '.');
	if (!dot) return 0;
	x = stracpy(cast_uchar "*");
	add_to_strn(&x, dot);
	sl = search_list(list, len, x);
	mem_free(x);
	return sl;
}
Esempio n. 3
0
static struct connection_state
init_nntp_header(struct connection *conn, struct read_buffer *rb)
{
	struct nntp_connection_info *nntp = conn->info;

	if (!conn->cached) {
		conn->cached = get_cache_entry(conn->uri);
		if (!conn->cached) return connection_state(S_OUT_OF_MEM);

	} else if (conn->cached->head || conn->cached->content_type) {
		/* If the head is set wipe out the content to be sure */
		delete_entry_content(conn->cached);
		mem_free_set(&conn->cached->head, NULL);
	}

	/* XXX: Override any Content-Type line in the header */
	mem_free_set(&conn->cached->content_type, stracpy("text/html"));
	if (!conn->cached->content_type)
		return connection_state(S_OUT_OF_MEM);

	switch (nntp->target) {
	case NNTP_TARGET_ARTICLE_NUMBER:
	case NNTP_TARGET_MESSAGE_ID:
	case NNTP_TARGET_GROUP_MESSAGE_ID:
	{
		unsigned char *end;

		end = get_nntp_message_header_end(rb->data, rb->length);
		if (!end) {
			/* Redo the whole cache entry thing next time */
			return connection_state(S_TRANS);
		}

		/* FIXME: Add the NNTP response code line */
		conn->cached->head = stracpy("FIXME NNTP response code\r\n");
		if (!conn->cached->head) return connection_state(S_OUT_OF_MEM);

		add_to_strn(&conn->cached->head, rb->data);

		/* ... and remove it */
		conn->received += end - rb->data;
		kill_buffer_data(rb, end - rb->data);
		break;
	}
	case NNTP_TARGET_ARTICLE_RANGE:
	case NNTP_TARGET_GROUP:
	case NNTP_TARGET_GROUPS:
	case NNTP_TARGET_QUIT:
		break;
	}

	return connection_state(S_OK);
}
Esempio n. 4
0
static int get_address(void)
{
	struct sockaddr_un *su;
	unsigned char *path;
	if (!links_home) return -1;
	path = stracpy(links_home);
	su = mem_alloc(sizeof(struct sockaddr_un) + strlen(path) + 1);
	s_unix_acc = mem_alloc(sizeof(struct sockaddr_un) + strlen(path) + 1);
	memset(su, 0, sizeof(struct sockaddr_un) + strlen(path) + 1);
	su->sun_family = AF_UNIX;
	add_to_strn(&path, LINKS_SOCK_NAME);
	strcpy(su->sun_path, path);
	mem_free(path);
	s_unix = (struct sockaddr *)su;
	s_unix_l = (char *)&su->sun_path - (char *)su + strlen(su->sun_path) + 1;
	return PF_UNIX;
}
Esempio n. 5
0
/* sezere 1 cookie z retezce str, na zacatku nesmi byt zadne whitechars
 * na konci muze byt strednik nebo 0
 * cookie musi byt ve tvaru nazev=hodnota, kolem rovnase nesmi byt zadne mezery
 * (respektive mezery se budou pocitat do nazvu a do hodnoty)
 */
int set_cookie(struct terminal *term, unsigned char *url, unsigned char *str)
{
	int noval = 0;
	struct cookie *cookie;
	struct c_server *cs;
	unsigned char *p, *q, *s, *server, *date;
	d_opt = &dd_opt;
    int accept_cookies = dds.allow_cookies;
	if (accept_cookies == ACCEPT_NONE) {
		return 0;
	}
	for (p = str; *p != ';' && *p; p++) { /*if (WHITECHAR(*p)) return 0;*/ }
	for (q = str; *q != '='; q++) if (!*q || q >= p) {
		noval = 1;
		break;
	}
	if (str == q || q + 1 == p) return 0;
	cookie = mem_alloc(sizeof(struct cookie));
	server = get_host_name(url);
	cookie->name = memacpy(str, q - str);
	cookie->value = !noval ? memacpy(q + 1, p - q - 1) : NULL;
	cookie->server = stracpy(server);
	date = parse_header_param(str, cast_uchar "expires", 0);
	if (date) {
		cookie->expires = parse_http_date(date);
		/* kdo tohle napsal a proc ?? */
		/*if (! cookie->expires) cookie->expires++;*/ /* no harm and we can use zero then */
		mem_free(date);
	} else
		cookie->expires = 0;
	if (!(cookie->path = parse_header_param(str, cast_uchar "path", 0))) {
		/*unsigned char *w;*/
		cookie->path = stracpy(cast_uchar "/");
		/*
		add_to_strn(&cookie->path, document);
		for (w = cookie->path; *w; w++) if (end_of_dir(cookie->path, *w)) {
			*w = 0;
			break;
		}
		for (w = cookie->path + strlen(cast_const_char cookie->path) - 1; w >= cookie->path; w--)
			if (*w == '/') {
				w[1] = 0;
				break;
			}
		*/
	} else {
		if (cookie->path[0] != '/') {
			add_to_strn(&cookie->path, cast_uchar "x");
			memmove(cookie->path + 1, cookie->path, strlen(cast_const_char cookie->path) - 1);
			cookie->path[0] = '/';
		}
	}
	if (!(cookie->domain = parse_header_param(str, cast_uchar "domain", 0))) cookie->domain = stracpy(server);
	if (cookie->domain[0] == '.') memmove(cookie->domain, cookie->domain + 1, strlen(cast_const_char cookie->domain));
	if ((s = parse_header_param(str, cast_uchar "secure", 0))) {
		cookie->secure = 1;
		mem_free(s);
	} else cookie->secure = 0;
	if (check_domain_security(server, cookie->domain)) {
		mem_free(cookie->domain);
		cookie->domain = stracpy(server);
	}
	foreach (cs, c_servers) if (!strcasecmp(cast_const_char cs->server, cast_const_char server)) {
		if (cs->accpt) goto ok;
		else {
			free_cookie(cookie);
			mem_free(cookie);
			mem_free(server);
			return 0;
		}
	}
	if (accept_cookies != ACCEPT_ALL) {
		free_cookie(cookie);
		mem_free(cookie);
		mem_free(server);
		return 1;
	}
	ok:
	accept_cookie(cookie);
	mem_free(server);
	return 0;
}
Esempio n. 6
0
File: main.c Progetto: ebichu/dd-wrt
void end_dump(struct status *stat, void *p)
{
	struct cache_entry *ce = stat->ce;
	int oh = get_output_handle();
	if (oh == -1) return;
	if (ce && ce->redirect && dump_red_count++ < MAX_REDIRECTS) {
		unsigned char *u, *p;
		if (stat->state >= 0) change_connection(stat, NULL, PRI_CANCEL);
		u = join_urls(ce->url, ce->redirect);
		if (!http_bugs.bug_302_redirect) if (!ce->redirect_get && (p = strchr(ce->url, POST_CHAR))) add_to_strn(&u, p);
		load_url(u, stat, PRI_MAIN, 0);
		mem_free(u);
		return;
	}
	if (stat->state >= 0 && stat->state < S_TRANS) return;
	if (stat->state >= S_TRANS && dmp != D_SOURCE) return;
	if (dmp == D_SOURCE) {
		if (ce) {
			struct fragment *frag;
			nextfrag:
			foreach(frag, ce->frag) if (frag->offset <= dump_pos && frag->offset + frag->length > dump_pos) {
				int l = frag->length - (dump_pos - frag->offset);
				int w = hard_write(oh, frag->data + dump_pos - frag->offset, l);
				if (w != l) {
					detach_connection(stat, dump_pos);
					if (w < 0) fprintf(stderr, "Error writing to stdout: %s.\n", strerror(errno));
					else fprintf(stderr, "Can't write to stdout.\n");
					retval = RET_ERROR;
					goto terminate;
				}
				dump_pos += w;
				detach_connection(stat, dump_pos);
				goto nextfrag;
			}
		}
		if (stat->state >= 0) return;
	} else if (ce) {
Esempio n. 7
0
File: file.c Progetto: Gingar/port
void file_func(struct connection *c)
{
	struct cache_entry *e;
	unsigned char *file, *name, *head;
	int fl;
	DIR *d;
	int h, r;
	struct stat stt;
	if (anonymous && !anonymousGinga) {
		setcstate(c, S_BAD_URL);
		abort_connection(c);
		return;
	}
	if (!(name = get_filename(c->url))) {
		setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
	}
	
	if (anonymousGinga && !allowedPath(name)){
		setcstate(c, S_BAD_URL);
		abort_connection(c);
		return;
	}

	if (stat(name, &stt)) {
		mem_free(name);
		setcstate(c, -errno); abort_connection(c); return;
	}
	if (!S_ISDIR(stt.st_mode) && !S_ISREG(stt.st_mode)) {
		mem_free(name);
		setcstate(c, S_FILE_TYPE); abort_connection(c); return;
	}
	if ((h = open(name, O_RDONLY | O_NOCTTY)) == -1) {
		int er = errno;
		if ((d = opendir(name))) goto dir;
		mem_free(name);
		setcstate(c, -er); abort_connection(c); return;
	}
	set_bin(h);
	if (S_ISDIR(stt.st_mode)) {
		struct dirs *dir;
		int dirl;
		int i;
		struct dirent *de;
		d = opendir(name);
		close(h);
		if (!d) {
			mem_free(name);
			setcstate(c, -errno); abort_connection(c); return;
		}
		dir:
		dir = DUMMY, dirl = 0;
		if (name[0] && !dir_sep(name[strlen(name) - 1])) {
			if (get_cache_entry(c->url, &e)) {
				mem_free(name);
				closedir(d);
				setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
			}
			c->cache = e;
			if (e->redirect) mem_free(e->redirect);
			e->redirect = stracpy(c->url);
			e->redirect_get = 1;
			add_to_strn(&e->redirect, "/");
			mem_free(name);
			closedir(d);
			goto end;
		}
		last_uid = -1;
		last_gid = -1;
		file = init_str();
		fl = 0;
		add_to_str(&file, &fl, "<html><head><title>");
		add_conv_str(&file, &fl, name, strlen(name), -1);
		add_to_str(&file, &fl, "</title></head><body><h2>Directory ");
		add_conv_str(&file, &fl, name, strlen(name), -1);
		add_to_str(&file, &fl, "</h2><pre>");
		while ((de = readdir(d))) {
			struct stat stt, *stp;
			unsigned char **p;
			int l;
			unsigned char *n;
			if (!strcmp(de->d_name, ".")) continue;
			if ((unsigned)dirl > MAXINT / sizeof(struct dirs) - 1) overalloc();
			dir = mem_realloc(dir, (dirl + 1) * sizeof(struct dirs));
			dir[dirl].f = stracpy(de->d_name);
			*(p = &dir[dirl++].s) = init_str();
			l = 0;
			n = stracpy(name);
			add_to_strn(&n, de->d_name);
#ifdef FS_UNIX_SOFTLINKS
			if (lstat(n, &stt))
#else
			if (stat(n, &stt))
#endif
			     stp = NULL;
			else stp = &stt;
			mem_free(n);
			stat_mode(p, &l, stp);
			stat_links(p, &l, stp);
			stat_user(p, &l, stp, 0);
			stat_user(p, &l, stp, 1);
			stat_size(p, &l, stp);
			stat_date(p, &l, stp);
		}
		closedir(d);
		if (dirl) qsort(dir, dirl, sizeof(struct dirs), (int(*)(const void *, const void *))comp_de);
		for (i = 0; i < dirl; i++) {
			unsigned char *lnk = NULL;
#ifdef FS_UNIX_SOFTLINKS
			if (dir[i].s[0] == 'l') {
				unsigned char *buf = NULL;
				int size = 0;
				int r;
				unsigned char *n = stracpy(name);
				add_to_strn(&n, dir[i].f);
				do {
					if (buf) mem_free(buf);
					size += ALLOC_GR;
					if ((unsigned)size > MAXINT) overalloc();
					buf = mem_alloc(size);
					r = readlink(n, buf, size);
				} while (r == size);
				if (r == -1) goto yyy;
				buf[r] = 0;
				lnk = buf;
				goto xxx;
				yyy:
				mem_free(buf);
				xxx:
				mem_free(n);
			}
#endif
			/*add_to_str(&file, &fl, "   ");*/
			add_to_str(&file, &fl, dir[i].s);
			add_to_str(&file, &fl, "<a href=\"");
			add_conv_str(&file, &fl, dir[i].f, strlen(dir[i].f), 1);
			if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "/");
			else if (lnk) {
				struct stat st;
				unsigned char *n = stracpy(name);
				add_to_strn(&n, dir[i].f);
				if (!stat(n, &st)) if (S_ISDIR(st.st_mode)) add_to_str(&file, &fl, "/");
				mem_free(n);
			}
			add_to_str(&file, &fl, "\">");
			/*if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "<font color=\"yellow\">");*/
			add_conv_str(&file, &fl, dir[i].f, strlen(dir[i].f), 0);
			/*if (dir[i].s[0] == 'd') add_to_str(&file, &fl, "</font>");*/
			add_to_str(&file, &fl, "</a>");
			if (lnk) {
				add_to_str(&file, &fl, " -> ");
				add_to_str(&file, &fl, lnk);
				mem_free(lnk);
			}
			add_to_str(&file, &fl, "\n");
		}
		mem_free(name);
		for (i = 0; i < dirl; i++) mem_free(dir[i].s), mem_free(dir[i].f);
		mem_free(dir);
		add_to_str(&file, &fl, "</pre></body></html>\n");
		head = stracpy("\r\nContent-Type: text/html\r\n");
	} else {
		mem_free(name);
		/* + !stt.st_size is there because of bug in Linux. Read returns
		   -EACCES when reading 0 bytes to invalid address */
		if (stt.st_size > MAXINT) {
			close(h);
			setcstate(c, S_LARGE_FILE); abort_connection(c);
			return;
		}
		file = mem_alloc(stt.st_size + !stt.st_size);
		if ((r = read(h, file, stt.st_size)) != stt.st_size) {
			mem_free(file); close(h);
			setcstate(c, r == -1 ? -errno : S_FILE_ERROR);
			abort_connection(c); return;
		}
		close(h);
		fl = stt.st_size;
		head = stracpy("");
	}
	if (get_cache_entry(c->url, &e)) {
		mem_free(file);
		setcstate(c, S_OUT_OF_MEM); abort_connection(c); return;
	}
	if (e->head) mem_free(e->head);
	e->head = head;
	c->cache = e;
	add_fragment(e, 0, file, fl);
	truncate_entry(e, fl, 1);
	mem_free(file);
	end:
	c->cache->incomplete = 0;
	setcstate(c, S_OK);
	abort_connection(c);
}
Esempio n. 8
0
unsigned char *translate_url(unsigned char *url, unsigned char *cwd)
{
	unsigned char *ch;
	unsigned char *nu, *da;
	unsigned char *prefix;
	int sl;
	while (*url == ' ') url++;
	if (*url && url[strlen(cast_const_char url) - 1] == ' ') {
		nu = stracpy(url);
		while (*nu && nu[strlen(cast_const_char nu) - 1] == ' ') nu[strlen(cast_const_char nu) - 1] = 0;
		ch = translate_url(nu, cwd);
		mem_free(nu);
		return ch;
	}
	if (!casecmp(cast_uchar "proxy://", url, 8)) return NULL;
	if (!parse_url(url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &da, NULL, NULL)) {
		nu = stracpy(url);
		goto return_nu;
	}
	if (strchr(cast_const_char url, POST_CHAR)) return NULL;
	if (strstr(cast_const_char url, "://")) {
		nu = stracpy(url);
		extend_str(&nu, 1);
		ch = cast_uchar strrchr(cast_const_char nu, '#');
		if (!ch || strchr(cast_const_char ch, '/')) ch = nu + strlen(cast_const_char nu);
		memmove(ch + 1, ch, strlen(cast_const_char ch) + 1);
		*ch = '/';
		if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
		mem_free(nu);
	}
	prefix = cast_uchar "file://";
	if (url[0] == '[' && strchr(cast_const_char url, ']')) {
		ch = url;
		goto http;
	}
	ch = url + strcspn(cast_const_char url, ".:/@");
	sl = 0;
#ifdef SPAD
	if (strchr(cast_const_char url, ':') && _is_local(cast_const_char url)) goto set_prefix;
#endif
	if (*ch != ':' || *(url + strcspn(cast_const_char url, "/@")) == '@') {
		if (*url != '.' && *ch == '.') {
			unsigned char *e, *f, *g;
			int tl;
			for (e = ch + 1; *(f = e + strcspn(cast_const_char e, ".:/")) == '.'; e = f + 1)
				;
			g = memacpy(e, f - e);
			tl = is_tld(g);
			mem_free(g);
			if (tl)
				http: prefix = cast_uchar "http://", sl = 1;
		}
		if (*ch == '@' || *ch == ':' || !cmpbeg(url, cast_uchar "ftp.")) prefix = cast_uchar "ftp://", sl = 1;
		goto set_prefix;
		set_prefix:
		nu = stracpy(prefix);
		add_to_strn(&nu, url);
		if (sl && !strchr(cast_const_char url, '/')) add_to_strn(&nu, cast_uchar "/");
		if (parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
			mem_free(nu);
			return NULL;
		}
		goto return_nu;
	}
#ifdef DOS_FS
	if (ch == url + 1) goto set_prefix;
#endif
	if (!(nu = memacpy(url, ch - url + 1))) return NULL;
	add_to_strn(&nu, cast_uchar "//");
	add_to_strn(&nu, ch + 1);
	if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
	add_to_strn(&nu, cast_uchar "/");
	if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
	mem_free(nu);
	return NULL;

	return_nu:
	insert_wd(&nu, cwd);
	extend_str(&nu, 1);
	translate_directories(nu);
	nu = translate_hashbang(nu);
	return nu;
}
Esempio n. 9
0
/*
 * U funkce join_urls musi byt prvni url absolutni (takove, co projde funkci
 * parse_url bez chyby --- pokud neni absolutni, tak to spatne na internal) a
 * druhe url je relativni cesta vuci nemu nebo taky absolutni url. Pokud je
 * druhe url absolutni, vrati se to; pokud je relativni, tak se spoji prvni a
 * druhe url.
 */
unsigned char *join_urls(unsigned char *base, unsigned char *rel)
{
	unsigned char *p, *n, *pp, *ch;
	int l;
	int lo = !casecmp(base, cast_uchar "file://", 7);
	int data = !casecmp(base, cast_uchar "data:", 5);
	if (rel[0] == '#' || !rel[0]) {
		n = stracpy(base);
		for (p = n; *p && *p != POST_CHAR && *p != '#'; p++)
			;
		*p = 0;
		add_to_strn(&n, rel);
		goto return_n;
	}
	if (rel[0] == '?' || rel[0] == '&') {
		unsigned char rj[3];
		unsigned char *d = get_url_data(base);
		if (!d) goto bad_base;
		rj[0] = rel[0];
		rj[1] = POST_CHAR;
		rj[2] = 0;
		d += strcspn(cast_const_char d, cast_const_char rj);
		n = memacpy(base, d - base);
		add_to_strn(&n, rel);
		goto return_n;
	}
	if (rel[0] == '/' && rel[1] == '/' && !data) {
		unsigned char *s;
		if (!(s = cast_uchar strstr(cast_const_char base, "//"))) {
			if (!(s = cast_uchar strchr(cast_const_char base, ':'))) {
				bad_base:
				internal("bad base url: %s", base);
				return NULL;
			}
			s++;
		}
		n = memacpy(base, s - base);
		add_to_strn(&n, rel);
		if (!parse_url(n, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_n;
		add_to_strn(&n, cast_uchar "/");
		if (!parse_url(n, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_n;
		mem_free(n);
	}
	if (!casecmp(cast_uchar "proxy://", rel, 8)) goto prx;
	if (!parse_url(rel, &l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
		n = stracpy(rel);
		goto return_n;
	}
	n = stracpy(rel);
	while (n[0] && n[strlen(cast_const_char n) - 1] <= ' ') n[strlen(cast_const_char n) - 1] = 0;
	extend_str(&n, 1);
	ch = cast_uchar strrchr(cast_const_char n, '#');
	if (!ch || strchr(cast_const_char ch, '/')) ch = n + strlen(cast_const_char n);
	memmove(ch + 1, ch, strlen(cast_const_char ch) + 1);
	*ch = '/';
	if (!parse_url(n, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_n;
	mem_free(n);
	prx:
	if (parse_url(base, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &p, NULL, NULL) || !p) {
		goto bad_base;
	}
	if (!dsep(*p)) p--;
	if (!data) {
		if (end_of_dir(base, rel[0])) for (; *p; p++) {
			if (end_of_dir(base, *p)) break;
		} else if (!dsep(rel[0])) for (pp = p; *pp; pp++) {
			if (end_of_dir(base, *pp)) break;
			if (dsep(*pp)) p = pp + 1;
		}
	}
	n = memacpy(base, p - base);
	add_to_strn(&n, rel);
	goto return_n;

	return_n:
	extend_str(&n, 1);
	translate_directories(n);
	return n;
}
Esempio n. 10
0
File: url.c Progetto: engine12/links
unsigned char *translate_url(unsigned char *url, unsigned char *cwd)
{
	unsigned char *ch;
	unsigned char *nu, *da;
	unsigned char *prefix;
	int sl;
	while (*url == ' ') url++;
	if (*url && url[strlen(cast_const_char url) - 1] == ' ') {
		nu = stracpy(url);
		while (*nu && nu[strlen(cast_const_char nu) - 1] == ' ') nu[strlen(cast_const_char nu) - 1] = 0;
		ch = translate_url(nu, cwd);
		mem_free(nu);
		return ch;
	}
	if (!casecmp(cast_uchar "proxy://", url, 8)) return NULL;
	if (!parse_url(url, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &da, NULL, NULL)) {
		nu = stracpy(url);
		goto return_nu;
	}
	if (strchr(cast_const_char url, POST_CHAR)) return NULL;
	if (strstr(cast_const_char url, "://")) {
		nu = stracpy(url);
		extend_str(&nu, 1);
		ch = cast_uchar strrchr(cast_const_char nu, '#');
		if (!ch || strchr(cast_const_char ch, '/')) ch = nu + strlen(cast_const_char nu);
		memmove(ch + 1, ch, strlen(cast_const_char ch) + 1);
		*ch = '/';
		if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
		mem_free(nu);
	}
	prefix = cast_uchar "file://";
	if (url[0] == '[' && strchr(cast_const_char url, ']')) {
		ch = url;
		goto http;
	}
	ch = url + strcspn(cast_const_char url, ".:/@");
	sl = 0;
#ifdef SPAD
	if (strchr(cast_const_char url, ':') && _is_local(cast_const_char url)) goto set_prefix;
#endif
	if (*ch != ':' || *(url + strcspn(cast_const_char url, "/@")) == '@') {
		if (*url != '.' && *ch == '.') {
			unsigned char *f, *e;
			int i;
			for (e = ch + 1; *(f = e + strcspn(cast_const_char e, ".:/")) == '.'; e = f + 1)
				;
			for (i = 0; i < f - e; i++) if (e[i] < '0' || e[i] > '9') goto noip;
			goto http;
			noip:
			if (f - e == 2 && casecmp(e, cast_uchar "gz", 2)) {
				http:
				prefix = cast_uchar "http://", sl = 1;
			} else {
				char *tld[] = {
					"com",
					"edu",
					"net",
					"org",
					"gov",
					"mil",
					"int",
					"arpa",
					"aero",
					"biz",
					"coop",
					"info",
					"museum",
					"name",
					"pro",
					"cat",
					"jobs",
					"mobi",
					"travel",
					"tel",
					"onion",
					"exit",
					NULL };
				for (i = 0; tld[i]; i++) if ((size_t)(f - e) == strlen(cast_const_char tld[i]) && !casecmp(cast_uchar tld[i], e, f - e)) goto http;
			}
		}
		if (*ch == '@' || *ch == ':' || !cmpbeg(url, cast_uchar "ftp.")) prefix = cast_uchar "ftp://", sl = 1;
		goto set_prefix;
		set_prefix:
		nu = stracpy(prefix);
		add_to_strn(&nu, url);
		if (sl && !strchr(cast_const_char url, '/')) add_to_strn(&nu, cast_uchar "/");
		if (parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
			mem_free(nu);
			return NULL;
		}
		goto return_nu;
	}
#ifdef DOS_FS
	if (ch == url + 1) goto set_prefix;
#endif
	if (!(nu = memacpy(url, ch - url + 1))) return NULL;
	add_to_strn(&nu, cast_uchar "//");
	add_to_strn(&nu, ch + 1);
	if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
	add_to_strn(&nu, cast_uchar "/");
	if (!parse_url(nu, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto return_nu;
	mem_free(nu);
	return NULL;

	return_nu:
	insert_wd(&nu, cwd);
	extend_str(&nu, 1);
	translate_directories(nu);
	nu = translate_hashbang(nu);
	return nu;
}
Esempio n. 11
0
void http_got_header(struct connection *c, struct read_buffer *rb)
{
    int cf;
    int state = c->state != S_PROC ? S_GETH : S_PROC;
    unsigned char *head;
    unsigned char *cookie, *ch;
    int a, h, version;
    unsigned char *d;
    struct cache_entry *e;
    struct http_connection_info *info;
    unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
    set_timeout(c);
    info = c->info;
    if (rb->close == 2) {
        unsigned char *h;
        if (!c->tries && (h = get_host_name(host))) {
            if (info->bl_flags & BL_NO_CHARSET) {
                del_blacklist_entry(h, BL_NO_CHARSET);
            } else {
                add_blacklist_entry(h, BL_NO_CHARSET);
                c->tries = -1;
            }
            mem_free(h);
        }
        setcstate(c, S_CANT_READ);
        retry_connection(c);
        return;
    }
    rb->close = 0;
again:
    if ((a = get_header(rb)) == -1) {
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (!a) {
        read_from_socket(c, c->sock1, rb, http_got_header);
        setcstate(c, state);
        return;
    }
    if (a != -2) {
        head = mem_alloc(a + 1);
        memcpy(head, rb->data, a);
        head[a] = 0;
        kill_buffer_data(rb, a);
    } else {
        head = stracpy("HTTP/0.9 200 OK\r\nContent-Type: text/html\r\n\r\n");
    }
    if (get_http_code(head, &h, &version) || h == 101) {
        mem_free(head);
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (check_http_server_bugs(host, c->info, head) && is_connection_restartable(c)) {
        mem_free(head);
        setcstate(c, S_RESTART);
        retry_connection(c);
        return;
    }
    ch = head;
    while ((cookie = parse_http_header(ch, "Set-Cookie", &ch))) {
        unsigned char *host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
        set_cookie(NULL, host, cookie);
        mem_free(cookie);
    }
    if (h == 100) {
        mem_free(head);
        state = S_PROC;
        goto again;
    }
    if (h < 200) {
        mem_free(head);
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if (h == 204) {
        mem_free(head);
        setcstate(c, S_HTTP_204);
        http_end_request(c, 0);
        return;
    }
    if (h == 304) {
        mem_free(head);
        setcstate(c, S_OK);
        http_end_request(c, 1);
        return;
    }
    if ((h == 500 || h == 502 || h == 503 || h == 504) && http_bugs.retry_internal_errors && is_connection_restartable(c)) {
        /* !!! FIXME: wait some time ... */
        mem_free(head);
        setcstate(c, S_RESTART);
        retry_connection(c);
        return;
    }
    if (!c->cache && get_cache_entry(c->url, &c->cache)) {
        mem_free(head);
        setcstate(c, S_OUT_OF_MEM);
        abort_connection(c);
        return;
    }
    e = c->cache;
    e->http_code = h;
    if (e->head) mem_free(e->head);
    e->head = head;
    if ((d = parse_http_header(head, "Expires", NULL))) {
        time_t t = parse_http_date(d);
        if (t && e->expire_time != 1) e->expire_time = t;
        mem_free(d);
    }
    if ((d = parse_http_header(head, "Pragma", NULL))) {
        if (!casecmp(d, "no-cache", 8)) e->expire_time = 1;
        mem_free(d);
    }
    if ((d = parse_http_header(head, "Cache-Control", NULL))) {
        char *f = d;
        while (1) {
            while (*f && (*f == ' ' || *f == ',')) f++;
            if (!*f) break;
            if (!casecmp(f, "no-cache", 8) || !casecmp(f, "must-revalidate", 15)) {
                e->expire_time = 1;
            }
            if (!casecmp(f, "max-age=", 8)) {
                if (e->expire_time != 1) e->expire_time = time(NULL) + atoi(f + 8);
            }
            while (*f && *f != ',') f++;
        }
        mem_free(d);
    }
#ifdef HAVE_SSL
    if (c->ssl) {
        int l = 0;
        if (e->ssl_info) mem_free(e->ssl_info);
        e->ssl_info = init_str();
        add_num_to_str(&e->ssl_info, &l, SSL_get_cipher_bits(c->ssl, NULL));
        add_to_str(&e->ssl_info, &l, "-bit ");
        add_to_str(&e->ssl_info, &l, SSL_get_cipher_version(c->ssl));
        add_to_str(&e->ssl_info, &l, " ");
        add_to_str(&e->ssl_info, &l, (unsigned  char *)SSL_get_cipher_name(c->ssl));
    }
#endif
    if (e->redirect) mem_free(e->redirect), e->redirect = NULL;
    if (h == 301 || h == 302 || h == 303 || h == 307) {
        if ((h == 302 || h == 307) && !e->expire_time) e->expire_time = 1;
        if ((d = parse_http_header(e->head, "Location", NULL))) {
            unsigned char *user, *ins;
            unsigned char *newuser, *newpassword;
            if (!parse_url(d, NULL, &user, NULL, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && !user && ins && (newuser = get_user_name(host))) {
                if (*newuser) {
                    int ins_off = ins - d;
                    newpassword = get_pass(host);
                    if (!newpassword) newpassword = stracpy("");
                    add_to_strn(&newuser, ":");
                    add_to_strn(&newuser, newpassword);
                    add_to_strn(&newuser, "@");
                    extend_str(&d, strlen(newuser));
                    ins = d + ins_off;
                    memmove(ins + strlen(newuser), ins, strlen(ins) + 1);
                    memcpy(ins, newuser, strlen(newuser));
                    mem_free(newpassword);
                }
                mem_free(newuser);
            }
            if (e->redirect) mem_free(e->redirect);
            e->redirect = d;
            e->redirect_get = h == 303;
        }
    }
    if (!e->expire_time && strchr(c->url, POST_CHAR)) e->expire_time = 1;
    info->close = 0;
    info->length = -1;
    info->version = version;
    if ((d = parse_http_header(e->head, "Connection", NULL)) || (d = parse_http_header(e->head, "Proxy-Connection", NULL))) {
        if (!strcasecmp(d, "close")) info->close = 1;
        mem_free(d);
    } else if (version < 11) info->close = 1;
    cf = c->from;
    c->from = 0;
    if ((d = parse_http_header(e->head, "Content-Range", NULL))) {
        if (strlen(d) > 6) {
            d[5] = 0;
            if (!(strcasecmp(d, "bytes")) && d[6] >= '0' && d[6] <= '9') {
#if defined(HAVE_STRTOLL)
                long long f = strtoll(d + 6, NULL, 10);
#elif defined(HAVE_STRTOQ)
                longlong f = strtoq(d + 6, NULL, 10);
#else
                long f = strtol(d + 6, NULL, 10);
                if (f == MAXLONG) f = -1;
#endif
                if (f >= 0 && (off_t)f >= 0 && (off_t)f == f) c->from = f;
            }
        }
        mem_free(d);
    }
    if (cf && !c->from && !c->unrestartable) c->unrestartable = 1;
    if (c->from > cf || c->from < 0) {
        setcstate(c, S_HTTP_ERROR);
        abort_connection(c);
        return;
    }
    if ((d = parse_http_header(e->head, "Content-Length", NULL))) {
        unsigned char *ep;
#if defined(HAVE_STRTOLL)
        long long l = strtoll(d, (char **)(void *)&ep, 10);
#elif defined(HAVE_STRTOQ)
        longlong l = strtoq(d, (char **)(void *)&ep, 10);
#else
        long l = strtol(d, (char **)(void *)&ep, 10);
        if (l == MAXLONG) l = -1;
#endif
        if (!*ep && l >= 0 && (off_t)l >= 0 && (off_t)l == l) {
            if (!info->close || version >= 11) info->length = l;
            if (c->from + l >= 0) c->est_length = c->from + l;
        }
        mem_free(d);
    }
    if ((d = parse_http_header(e->head, "Accept-Ranges", NULL))) {
        if (!strcasecmp(d, "none") && !c->unrestartable) c->unrestartable = 1;
        mem_free(d);
    } else {
        if (!c->unrestartable && !c->from) c->unrestartable = 1;
    }
    if (info->bl_flags & BL_NO_RANGE && !c->unrestartable) c->unrestartable = 1;
    if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) {
        if (!strcasecmp(d, "chunked")) {
            info->length = -2;
            info->chunk_remaining = -1;
        }
        mem_free(d);
    }
    if (!info->close && info->length == -1) info->close = 1;
    if ((d = parse_http_header(e->head, "Last-Modified", NULL))) {
        if (e->last_modified && strcasecmp(e->last_modified, d)) {
            delete_entry_content(e);
            if (c->from) {
                c->from = 0;
                mem_free(d);
                setcstate(c, S_MODIFIED);
                retry_connection(c);
                return;
            }
        }
        if (!e->last_modified) e->last_modified = d;
        else mem_free(d);
    }
    if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL)))
        e->last_modified = d;
    if (info->length == -1 || (version < 11 && info->close)) rb->close = 1;
    read_http_data(c, rb);
}
static unsigned char *
directfb_fb_init_driver (unsigned char *param, unsigned char *display)
{
  DFBDisplayLayerConfig  config;
  DFBResult              ret;
  unsigned char          *error;
  unsigned char          *result;

  DirectFBInit (&g_argc, (char ***)(void *)&g_argv);
  if ((ret = DirectFBCreate (&dfb)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret;
    }

  if ((ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_dfb;
  }

  if ((ret = layer->GetConfiguration (layer, &config)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_layer;
  }

  pixelformat = config.pixelformat;

  directfb_driver.depth = (((DFB_BYTES_PER_PIXEL (pixelformat) & 0x7)) |
                           ((DFB_COLOR_BITS_PER_PIXEL  (pixelformat) & 0x1F) << 3));

  if (directfb_driver.depth == 4)
	directfb_driver.depth = 196;

  /* endian test */
  if (htons (0x1234) == 0x1234) {
     if ((directfb_driver.depth & 0x7) == 2)
	directfb_driver.depth |= 0x100;
     if ((directfb_driver.depth & 0x7) == 4)
	directfb_driver.depth |= 0x200;
  }

  if (!get_color_fn(directfb_driver.depth)) {
	error = cast_uchar "Unsupported color depth";
	goto ret_layer;
  }

  directfb_driver.x = config.width;
  directfb_driver.y = config.height;

  memset (directfb_hash_table, 0, sizeof (directfb_hash_table));

  if ((ret = dfb->CreateEventBuffer (dfb, &events)) != DFB_OK) {
      error = (unsigned char *)DirectFBErrorString(ret);
      goto ret_layer;
  }

  event_timer = install_timer (20, directfb_check_events, events);

  if (dfb->CreateSurface (dfb, directfb_get_arrow_desc(), &arrow) != DFB_OK)
    arrow = NULL;

  return NULL;

ret_layer:
  layer->Release(layer);
ret_dfb:
  dfb->Release(dfb);
ret:
  result = init_str();
  add_to_strn(&result, error);
  add_to_strn(&result, cast_uchar "\n");
  return result;
}