Exemple #1
0
void stat_user(unsigned char **p, int *l, struct stat *stp, int g)
{
#ifdef FS_UNIX_USERS
	struct passwd *pwd;
	struct group *grp;
	int id;
	unsigned char *pp;
	int i;
	if (!stp) {
		add_to_str(p, l, "         ");
		return;
	}
	id = !g ? stp->st_uid : stp->st_gid;
	pp = !g ? last_user : last_group;
	if (!g && id == last_uid && last_uid != -1) goto a;
	if (g && id == last_gid && last_gid != -1) goto a;
	if (!g) {
		if (!(pwd = getpwuid(id)) || !pwd->pw_name) sprintf(pp, "%d", id);
		else sprintf(pp, "%.8s", pwd->pw_name);
		last_uid = id;
	} else {
		if (!(grp = getgrgid(id)) || !grp->gr_name) sprintf(pp, "%d", id);
		else sprintf(pp, "%.8s", grp->gr_name);
		last_gid = id;
	}
	a:
	add_to_str(p, l, pp);
	for (i = strlen(pp); i < 8; i++) add_chr_to_str(p, l, ' ');
	add_chr_to_str(p, l, ' ');
#endif
}
Exemple #2
0
void add_conv_str(unsigned char **s, int *l, unsigned char *b, int ll, int encode_special)
{
	for (; ll > 0; ll--, b++) {
		if ((unsigned char)*b < ' ') continue;
		if (special_char(*b) && encode_special == 1) {
			unsigned char h[4];
			sprintf(cast_char h, "%%%02X", (unsigned)*b & 0xff);
			add_to_str(s, l, h);
		} else if (*b == '%' && encode_special <= -1 && ll > 2 && ((b[1] >= '0' && b[1] <= '9') || (b[1] >= 'A' && b[1] <= 'F') || (b[1] >= 'a' && b[1] <= 'f'))) {
			unsigned char h = 0;
			int i;
			for (i = 1; i < 3; i++) {
				if (b[i] >= '0' && b[i] <= '9') h = h * 16 + b[i] - '0';
				if (b[i] >= 'A' && b[i] <= 'F') h = h * 16 + b[i] - 'A' + 10;
				if (b[i] >= 'a' && b[i] <= 'f') h = h * 16 + b[i] - 'a' + 10;
			}
			if (h >= ' ') add_chr_to_str(s, l, h);
			ll -= 2;
			b += 2;
		} else if (*b == ' ' && (!encode_special || encode_special == -1)) {
			add_to_str(s, l, cast_uchar "&nbsp;");
		} else if (accept_char(*b) || encode_special == -2) {
			add_chr_to_str(s, l, *b);
		} else {
			add_to_str(s, l, cast_uchar "&#");
			add_num_to_str(s, l, (int)*b);
			add_chr_to_str(s, l, ';');
		}
	}
}
Exemple #3
0
char *tempnam(const char *dir, const char *pfx)
{
	static int counter = 0;
	unsigned char *d, *s, *a;
	int l;
	if (!(d = cast_uchar getenv("TMPDIR"))) {
		if (dir) d = cast_uchar dir;
		else if (!(d = cast_uchar getenv("TMP")) && !(d = cast_uchar getenv("TEMP"))) {
#ifdef P_tmpdir
			d = cast_uchar(P_tmpdir);
#else
			d = cast_uchar "/tmp";
#endif
		}
	}
	l = 0;
	s = init_str();
	add_to_str(&s, &l, d);
	if (s[0] && s[strlen(cast_const_char s) - 1] != '/') add_chr_to_str(&s, &l, '/');
	add_to_str(&s, &l, cast_uchar pfx);
	add_num_to_str(&s, &l, counter++);
	a = cast_uchar strdup(cast_const_char s);
	mem_free(s);
	return cast_char a;
}
Exemple #4
0
void stat_date(unsigned char **p, int *l, struct stat *stp)
{
	time_t current_time = time(NULL);
	time_t when;
	struct tm *when_local;
	unsigned char *fmt;
	unsigned char str[13];
	int wr;
	if (!stp) {
		add_to_str(p, l, "             ");
		return;
	}
	when = stp->st_mtime;
	when_local = localtime(&when);
	if (current_time > when + 6L * 30L * 24L * 60L * 60L || 
	    current_time < when - 60L * 60L) fmt = "%b %e  %Y";
	else fmt = "%b %e %H:%M";
#ifdef HAVE_STRFTIME
	wr = strftime(str, 13, fmt, when_local);
#else
	wr = 0;
#endif
	while (wr < 12) str[wr++] = ' ';
	str[12] = 0;
	add_to_str(p, l, str);
	add_chr_to_str(p, l, ' ');
}
Exemple #5
0
void ftp_got_user_info(struct connection *c, struct read_buffer *rb)
{
	int g = get_ftp_response(c, rb, 0);
	if (g == -1) { setcstate(c, S_FTP_ERROR); abort_connection(c); return; }
	if (!g) { read_from_socket(c, c->sock1, rb, ftp_got_user_info); return; }
	if (g >= 530 && g < 540) { setcstate(c, S_FTP_LOGIN); retry_connection(c); return; }
	if (g >= 400) { setcstate(c, S_FTP_UNAVAIL); retry_connection(c); return; }
	if (g >= 200 && g < 300) {
		if (ftp_options.fast_ftp) ftp_dummy_info(c, rb);
		else ftp_send_retr_req(c, S_GETH);
	} else {
		if (ftp_options.fast_ftp) ftp_pass_info(c, rb);
		else {
			unsigned char *login;
			unsigned char *u;
			int logl = 0;
			login = init_str();
			add_to_str(&login, &logl, "PASS ");
			if ((u = get_pass(c->url)) && *u) add_to_str(&login, &logl, u);
			else add_to_str(&login, &logl, ftp_options.anon_pass);
			if (u) mem_free(u);
			add_to_str(&login, &logl, "\r\n");
			write_to_socket(c, c->sock1, login, strlen(login), ftp_sent_passwd);
			mem_free(login);
			setcstate(c, S_LOGIN);
		}
	}
}
Exemple #6
0
void add_graphics_drivers(unsigned char **s, int *l)
{
	struct graphics_driver **gd;
	for (gd = graphics_drivers; *gd; gd++) {
		if (gd != graphics_drivers) add_to_str(s, l, cast_uchar ", ");
		add_to_str(s, l, (*gd)->name);
	}
}
Exemple #7
0
void redraw_screen(struct terminal *term)
{
    int x, y, p = 0;
    int cx = term->lcx, cy = term->lcy;
    unsigned char *a;
    int attrib = -1;
    int mode = -1;
    int l = 0;
    struct term_spec *s;
    if (!term->dirty || (term->master && is_blocked())) return;
    a = init_str();
    s = term->spec;
    for (y = 0; y < term->y; y++)
        for (x = 0; x < term->x; x++, p++) {
            if (y == term->y - 1 && x == term->x - 1) break;
            if (term->screen[p] == term->last_screen[p]) continue;
            if ((term->screen[p] & 0x3800) == (term->last_screen[p] & 0x3800) && ((term->screen[p] & 0xff) == 0 || (term->screen[p] & 0xff) == 1 || (term->screen[p] & 0xff) == ' ') && ((term->last_screen[p] & 0xff) == 0 || (term->last_screen[p] & 0xff) == 1 || (term->last_screen[p] & 0xff) == ' ') && (x != term->cx || y != term->cy)) continue;
            term->last_screen[p] = term->screen[p];
            if (cx == x && cy == y) goto pc;/*PRINT_CHAR(p)*/
            else if (cy == y && x - cx < 10 && x - cx > 0) {
                int i;
                for (i = x - cx; i >= 0; i--) PRINT_CHAR(p - i);
            } else {
                add_to_str(&a, &l, "\033[");
                add_num_to_str(&a, &l, y + 1);
                add_to_str(&a, &l, ";");
                add_num_to_str(&a, &l, x + 1);
                add_to_str(&a, &l, "H");
                cx = x;
                cy = y;
pc:
                PRINT_CHAR(p);
            }
        }
    if (l) {
        if (s->col) add_to_str(&a, &l, "\033[37;40m");
        add_to_str(&a, &l, "\033[0m");
        if (s->mode == TERM_LINUX && s->m11_hack) add_to_str(&a, &l, "\033[10m");
        if (s->mode == TERM_VT100) add_to_str(&a, &l, "\x0f");
    }
    term->lcx = cx;
    term->lcy = cy;
    if (term->cx != term->lcx || term->cy != term->lcy) {
        term->lcx = term->cx;
        term->lcy = term->cy;
        add_to_str(&a, &l, "\033[");
        add_num_to_str(&a, &l, term->cy + 1);
        add_to_str(&a, &l, ";");
        add_num_to_str(&a, &l, term->cx + 1);
        add_to_str(&a, &l, "H");
    }
    if (l && term->master) want_draw();
    hard_write(term->fdout, a, l);
    if (l && term->master) done_draw();
    mem_free(a);
    term->dirty = 0;
}
Exemple #8
0
void add_png_version(unsigned char **s, int *l)
{
	add_to_str(s, l, cast_uchar "PNG (");
#ifdef HAVE_PNG_GET_LIBPNG_VER
	add_to_str(s, l, cast_uchar png_get_libpng_ver(NULL));
#else
	add_to_str(s, l, cast_uchar PNG_LIBPNG_VER_STRING);
#endif
	add_to_str(s, l, cast_uchar ")");
}
static void ftp_login(struct connection *c)
{
    unsigned char *login;
    unsigned char *u;
    int logl = 0;
    set_timeout(c);
    login = init_str();
    add_to_str(&login, &logl, cast_uchar "USER ");
    if ((u = get_user_name(c->url)) && *u) add_to_str(&login, &logl, u);
    else add_to_str(&login, &logl, cast_uchar "anonymous");
    if (u) mem_free(u);
    if (ftp_options.fast_ftp) {
        struct ftp_connection_info *fi;
        add_to_str(&login, &logl, cast_uchar "\r\nPASS ");
        if ((u = get_pass(c->url)) && *u) add_to_str(&login, &logl, u);
        else add_to_str(&login, &logl, ftp_options.anon_pass);
        if (u) mem_free(u);
        add_to_str(&login, &logl, cast_uchar "\r\n");
        if (!(fi = add_file_cmd_to_str(c))) {
            mem_free(login);
            return;
        }
        add_to_str(&login, &logl, fi->cmdbuf);
    } else add_to_str(&login, &logl, cast_uchar "\r\n");
    write_to_socket(c, c->sock1, login, strlen(cast_const_char login), ftp_logged);
    mem_free(login);
    setcstate(c, S_SENT);
}
Exemple #10
0
unsigned char *list_graphics_drivers(void)
{ 
	unsigned char *d = init_str();
	int l = 0;
	struct graphics_driver **gd;
	for (gd = graphics_drivers; *gd; gd++) {
		if (l) add_to_str(&d, &l, " ");
		add_to_str(&d, &l, (*gd)->name);
	}
	return d;
}
Exemple #11
0
void stat_links(unsigned char **p, int *l, struct stat *stp)
{
#ifdef FS_UNIX_HARDLINKS
	unsigned char lnk[64];
	if (!stp) add_to_str(p, l, "    ");
	else {
		sprintf(lnk, "%3d ", (int)stp->st_nlink);
		add_to_str(p, l, lnk);
	}
#endif
}
Exemple #12
0
void stat_size(unsigned char **p, int *l, struct stat *stp)
{
	unsigned char size[64];
	if (!stp) z: add_to_str(p, l, "         ");
	else {
		if ((long)(unsigned long)stp->st_size == stp->st_size) {
			sprintf(size, "%8lu ", (unsigned long)stp->st_size);
			add_to_str(p, l, size);
		} else goto z;
	}
}
Exemple #13
0
unsigned char *make_html_font_name(int attr)
{
	unsigned char *str;
	int len;
	
	str=init_str();len=0;
	add_to_str(&str, &len, G_HTML_DEFAULT_FAMILY);
	add_to_str(&str, &len, attr & AT_BOLD ? "-bold" : "-medium");
	add_to_str(&str, &len, attr & AT_ITALIC ? "-italic-serif" :
			"-roman-serif");
	add_to_str(&str, &len, attr & AT_FIXED ? "-mono" : "-vari");
	return str;
}
Exemple #14
0
unsigned char *translate_hashbang(unsigned char *up)
{
	unsigned char *u, *p, *dp, *data, *post_seq;
	int q;
	unsigned char *r;
	int rl;
	if (!strstr(cast_const_char up, "#!") && !strstr(cast_const_char up, "#%21")) return up;
	u = stracpy(up);
	p = extract_position(u);
	if (!p) {
		free_u_ret_up:
		mem_free(u);
		return up;
	}
	if (p[0] == '!') dp = p + 1;
	else if (!casecmp(p, cast_uchar "%21", 3)) dp = p + 3;
	else {
		mem_free(p);
		goto free_u_ret_up;
	}
	if (!(post_seq = cast_uchar strchr(cast_const_char u, POST_CHAR))) post_seq = cast_uchar strchr(cast_const_char u, 0);
	data = get_url_data(u);
	if (!data) data = u;
	r = init_str();
	rl = 0;
	add_bytes_to_str(&r, &rl, u, post_seq - u);
	q = (int)strlen(cast_const_char data);
	if (q && (data[q - 1] == '&' || data[q - 1] == '?'))
		;
	else if (strchr(cast_const_char data, '?')) add_chr_to_str(&r, &rl, '&');
	else add_chr_to_str(&r, &rl, '?');
	add_to_str(&r, &rl, cast_uchar "_escaped_fragment_=");
	for (; *dp; dp++) {
		unsigned char c = *dp;
		if (c <= 0x20 || c == 0x23 || c == 0x25 || c == 0x26 || c == 0x2b || c >= 0x7f) {
			unsigned char h[4];
			sprintf(cast_char h, "%%%02X", c);
			add_to_str(&r, &rl, h);
		} else {
			add_chr_to_str(&r, &rl, c);
		}
	}
	add_to_str(&r, &rl, post_seq);
	mem_free(u);
	mem_free(p);
	mem_free(up);
	return r;
}
Exemple #15
0
void finger_send_request(struct connection *c)
{
	unsigned char *req = init_str();
	int rl = 0;
	unsigned char *user;
	add_to_str(&req, &rl, "/W");
	if ((user = get_user_name(c->url))) {
		add_to_str(&req, &rl, " ");
		add_to_str(&req, &rl, user);
		mem_free(user);
	}
	add_to_str(&req, &rl, "\r\n");
	write_to_socket(c, c->sock1, req, rl, finger_sent_request);
	mem_free(req);
	setcstate(c, S_SENT);
}
Exemple #16
0
void add_cookies(unsigned char **s, int *l, unsigned char *url)
{
	int nc = 0;
	struct c_domain *cd;
	struct cookie *c, *d;
	unsigned char *server = get_host_name(url);
	unsigned char *data = get_url_data(url);
	if (data > url) data--;
	foreach (cd, c_domains) if (is_in_domain(cd->domain, server)) goto ok;
	mem_free(server);
	return;
	ok:
	foreachback (c, all_cookies) if (is_in_domain(c->domain, server)) if (is_path_prefix(c->path, data)) {
		if (cookie_expired(c)) {
			d = c;
			c = c->prev;
			del_from_list(d);
			free_cookie(d);
			mem_free(d);
			continue;
		}
		if (c->secure && casecmp(url, cast_uchar "https://", 8)) continue;
		if (!nc) add_to_str(s, l, cast_uchar "Cookie: "), nc = 1;
		else add_to_str(s, l, cast_uchar "; ");
		add_to_str(s, l, c->name);
		if (c->value) {
			add_to_str(s, l, cast_uchar "=");
			add_to_str(s, l, c->value);
		}
	}
	if (nc) add_to_str(s, l, cast_uchar "\r\n");
	mem_free(server);
}
Exemple #17
0
unsigned char *init_graphics(unsigned char *driver, unsigned char *param, unsigned char *display)
{
	unsigned char *s = init_str();
	int l = 0;
	struct graphics_driver **gd;
#if defined(GRDRV_PMSHELL) && defined(GRDRV_X)
	if (is_xterm()) {
		static unsigned char swapped = 0;
		if (!swapped) {
			for (gd = graphics_drivers; *gd; gd++) {
				if (*gd == &pmshell_driver) *gd = &x_driver;
				else if (*gd == &x_driver) *gd = &pmshell_driver;
			}
			swapped = 1;
		}
	}
#endif
	for (gd = graphics_drivers; *gd; gd++) {
		if (!driver || !*driver || !strcasecmp(cast_const_char (*gd)->name, cast_const_char driver)) {
			unsigned char *r;
			if ((!driver || !*driver) && (*gd)->flags & GD_NOAUTO) continue;
			if (!(r = init_graphics_driver(*gd, param, display))) {
				mem_free(s);
				return NULL;
			}
			if (!l) {
				if (!driver || !*driver) add_to_str(&s, &l, cast_uchar "Could not initialize any graphics driver. Tried the following drivers:\n");
				else add_to_str(&s, &l, cast_uchar "Could not initialize graphics driver ");
			}
			add_to_str(&s, &l, (*gd)->name);
			add_to_str(&s, &l, cast_uchar ":\n");
			add_to_str(&s, &l, r);
			mem_free(r);
		}
	}
	if (!l) {
		add_to_str(&s, &l, cast_uchar "Unknown graphics driver ");
		if (driver) add_to_str(&s, &l, driver);
		add_to_str(&s, &l, cast_uchar ".\nThe following graphics drivers are supported:\n");
		add_graphics_drivers(&s, &l);
		add_to_str(&s, &l, cast_uchar "\n");
	}
	return s;
}
Exemple #18
0
void add_url_to_str(unsigned char **str, int *l, unsigned char *url)
{
    unsigned char *sp;
    for (sp = url; *sp && *sp != POST_CHAR; sp++) {
        if (*sp <= ' ') {
            char esc[4];
            sprintf(esc, "%%%02X", (int)*sp);
            add_to_str(str, l, esc);
        } else if (*sp == '\\') {
            add_chr_to_str(str, l, '/');
        } else {
            add_chr_to_str(str, l, *sp);
        }
    }
}
Exemple #19
0
static void x_update_driver_param(int w, int h)
{
	int l=0;

	if (n_wins!=1)return;
	
	x_default_window_width=w;
	x_default_window_height=h;
	
	if (x_driver_param)mem_free(x_driver_param);
	x_driver_param=init_str();
	add_num_to_str(&x_driver_param,&l,x_default_window_width);
	add_to_str(&x_driver_param,&l,"x");
	add_num_to_str(&x_driver_param,&l,x_default_window_height);
}
Exemple #20
0
void stat_mode(unsigned char **p, int *l, struct stat *stp)
{
	unsigned char c = '?';
	if (stp) {
		if (0) ;
#ifdef S_ISBLK
		else if (S_ISBLK(stp->st_mode)) c = 'b';
#endif
#ifdef S_ISCHR
		else if (S_ISCHR(stp->st_mode)) c = 'c';
#endif
		else if (S_ISDIR(stp->st_mode)) c = 'd';
		else if (S_ISREG(stp->st_mode)) c = '-';
#ifdef S_ISFIFO
		else if (S_ISFIFO(stp->st_mode)) c = 'p';
#endif
#ifdef S_ISLNK
		else if (S_ISLNK(stp->st_mode)) c = 'l';
#endif
#ifdef S_ISSOCK
		else if (S_ISSOCK(stp->st_mode)) c = 's';
#endif
#ifdef S_ISNWK
		else if (S_ISNWK(stp->st_mode)) c = 'n';
#endif
	}
	add_chr_to_str(p, l, c);
#ifdef FS_UNIX_RIGHTS
	{
		unsigned char rwx[10] = "---------";
		if (stp) {
			int mode = stp->st_mode;
			setrwx(mode << 0, &rwx[0]);
			setrwx(mode << 3, &rwx[3]);
			setrwx(mode << 6, &rwx[6]);
			setst(mode, rwx);
		}
		add_to_str(p, l, rwx);
	}
#endif
	add_chr_to_str(p, l, ' ');
}
static void add_port_pasv(unsigned char **s, int *l, struct ftp_connection_info *inf, unsigned char *port_string)
{
    if (!inf->pasv) {
        if (inf->eprt_epsv) {
            add_to_str(s, l, cast_uchar "EPRT ");
            add_to_str(s, l, port_string);
        } else {
            add_to_str(s, l, cast_uchar "PORT ");
            add_to_str(s, l, port_string);
        }
    } else {
        if (inf->eprt_epsv) {
            add_to_str(s, l, cast_uchar "EPSV");
        } else {
            add_to_str(s, l, cast_uchar "PASV");
        }
    }
    add_to_str(s, l, cast_uchar "\r\n");
}
Exemple #22
0
void ftp_send_retr_req(struct connection *c, int state)
{
	struct ftp_connection_info *fi;
	unsigned char *login;
	int logl = 0;
	set_timeout(c);
	login = init_str();
	if (!c->info && !(fi = add_file_cmd_to_str(c))) {
		mem_free(login);
		return;
	} else fi = c->info;
	if (ftp_options.fast_ftp) a:add_to_str(&login, &logl, fi->cmdbuf);
	else {
		unsigned char *nl = strchr(fi->cmdbuf, '\n');
		if (!nl) goto a;
		nl++;
		add_bytes_to_str(&login, &logl, fi->cmdbuf, nl - fi->cmdbuf);
		memmove(fi->cmdbuf, nl, strlen(nl) + 1);
	}
	write_to_socket(c, c->sock1, login, strlen(login), ftp_retr_1);
	mem_free(login);
	setcstate(c, state);
}
Exemple #23
0
/* initiate connection with X server */
static unsigned char * x_init_driver(unsigned char *param, unsigned char *display)
{
	XGCValues gcv;
	XSetWindowAttributes win_attr;
	XVisualInfo vinfo;
	int misordered=-1;

	n_wins=0;

#if defined(HAVE_SETLOCALE) && defined(LC_ALL)
	setlocale(LC_ALL,"");
#endif
#ifdef X_DEBUG
	{
		unsigned char txt[256];
		sprintf(txt,"x_init_driver(%s, %s)\n",param, display);
		MESSAGE(txt);
	}
#endif
	x_input_encoding=-1;
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_LANGINFO_H) && defined(CODESET)
	{
		unsigned char *cp;
		cp=nl_langinfo(CODESET);
		x_input_encoding=get_cp_index(cp);
	}
#endif
	if (x_input_encoding<0)x_driver.flags|=GD_NEED_CODEPAGE;

	if (!display||!(*display))display=0;

/*
	X documentation says on XOpenDisplay(display_name) :

	display_name
		Specifies the hardware display name, which determines the dis-
		play and communications domain to be used.  On a POSIX-confor-
		mant system, if the display_name is NULL, it defaults to the
		value of the DISPLAY environment variable.

	But OS/2 has problems when display_name is NULL ...

*/
	if (!display)display=getenv("DISPLAY");
#ifndef __linux__
	/* on Linux, do not assume XWINDOW present if $DISPLAY is not set
	   --- rather open links on svgalib or framebuffer console */
	if (!display)display=":0.0";	/* needed for MacOS X */
#endif

	x_display=XOpenDisplay(display);
	if (!x_display)
	{
		unsigned char *err=init_str();
		int l=0;

		add_to_str(&err,&l,"Can't open display \"");
		add_to_str(&err,&l,display?display:(unsigned char *)"(null)");
		add_to_str(&err,&l,"\"\n");
		return err;
	}

	x_hash_table_init();

	x_bitmap_bit_order=BitmapBitOrder(x_display);
	x_fd=XConnectionNumber(x_display);
	x_screen=DefaultScreen(x_display);
	x_display_height=DisplayHeight(x_display,x_screen);
	x_display_width=DisplayWidth(x_display,x_screen);
	x_root_window=RootWindow(x_display,x_screen);

	x_default_window_width=x_display_width-50;
	x_default_window_height=x_display_height-50;

	x_driver_param=NULL;

	if (param)
	{
		char *p, *e, *f;
		int w,h;
		
		x_driver_param=stracpy(param);
		
		for (p=x_driver_param;(*p)&&(*p)!='x'&&(*p)!='X';p++);
		if (!(*p))goto done;
		*p=0;
		w=strtoul(x_driver_param,&e,10);
		h=strtoul(p+1,&f,10);
		if (!(*e)&&!(*f)&&w&&h){x_default_window_width=w;x_default_window_height=h;}
		*p='x';
		done:;
	}

	/* find best visual */
	{
#define DEPTHS 5
#define CLASSES 2
		int depths[DEPTHS]={24, 16, 15, 8, 4};
		int classes[CLASSES]={TrueColor, PseudoColor}; /* FIXME: dodelat DirectColor */
		int a,b;
		
		for (a=0;a<DEPTHS;a++)
			for (b=0;b<CLASSES;b++)
			{
				if (XMatchVisualInfo(x_display, x_screen,depths[a],classes[b], &vinfo))
				{
					x_default_visual=vinfo.visual;
					x_depth=vinfo.depth;

					/* determine bytes per pixel */
					{
						XPixmapFormatValues *pfm;
						int n,i;
						
						pfm=XListPixmapFormats(x_display,&n);
						for (i=0;i<n;i++)
							if (pfm[i].depth==x_depth)
							{
								x_bitmap_bpp=pfm[i].bits_per_pixel<8?1:((pfm[i].bits_per_pixel)>>3);
								x_bitmap_scanline_pad=(pfm[i].scanline_pad)>>3;
								XFree(pfm);
								goto bytes_per_pixel_found;
							}
						if(n) XFree(pfm);
						continue;
					}
bytes_per_pixel_found:

					/* test misordered flag */
					switch(x_depth)
					{
						case 4:
						case 8:
						if (x_bitmap_bpp!=1)break;
						if (vinfo.red_mask>=vinfo.green_mask&&vinfo.green_mask>=vinfo.blue_mask)
						{
							misordered=0;
							goto visual_found;
						}
						break;

						case 15:
						case 16:
						if (x_bitmap_bpp!=2)break;
						if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask)
						{
							misordered=256;
							goto visual_found;
						}
						if (x_bitmap_bit_order==MSBFirst)break;
						if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask)
						{
							misordered=0;
							goto visual_found;
						}
						break;

						case 24:
						if (x_bitmap_bpp!=3&&x_bitmap_bpp!=4) break;
						if (vinfo.red_mask<vinfo.green_mask&&vinfo.green_mask<vinfo.blue_mask)
						{
							misordered=256;
							goto visual_found;
						}
						if (x_bitmap_bit_order==MSBFirst&&vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask)
						{
							misordered=512;
							goto visual_found;
						}
						if (vinfo.red_mask>vinfo.green_mask&&vinfo.green_mask>vinfo.blue_mask)
						{
							misordered=0;
							goto visual_found;
						}
						break;
					}
				}
			}
Exemple #24
0
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);
}
static struct ftp_connection_info *add_file_cmd_to_str(struct connection *c)
{
    unsigned char *d = get_url_data(c->url);
    unsigned char *de;
    int del;
    unsigned char port_string[50];
    struct ftp_connection_info *inf, *inf2;
    unsigned char *s;
    int l;
    if (!d) {
        internal("get_url_data failed");
        setcstate(c, S_INTERNAL);
        abort_connection(c);
        return NULL;
    }

    de = init_str(), del = 0;
    add_conv_str(&de, &del, d, strlen(cast_const_char d), -2);
    d = de;
    inf = mem_alloc(sizeof(struct ftp_connection_info));
    memset(inf, 0, sizeof(struct ftp_connection_info));
    l = 0;
    s = init_str();
    inf->pasv = ftp_options.passive_ftp;
#ifdef LINKS_2
    if (*c->socks_proxy) inf->pasv = 1;
    if (ftp_options.eprt_epsv || is_ipv6(c->sock1)) inf->eprt_epsv = 1;
#endif
    c->info = inf;

    if (!inf->pasv) {
        int ps;
#ifdef SUPPORT_IPV6
        if (is_ipv6(c->sock1)) {
            ps = get_pasv_socket_ipv6(c, c->sock1, &c->sock2, port_string);
            if (ps) {
                mem_free(d);
                mem_free(s);
                return NULL;
            }
        } else
#endif
        {
            unsigned char pc[6];
            ps = get_pasv_socket(c, c->sock1, &c->sock2, pc);
            if (ps) {
                mem_free(d);
                mem_free(s);
                return NULL;
            }
            if (inf->eprt_epsv)
                sprintf(cast_char port_string, "|1|%d.%d.%d.%d|%d|", pc[0], pc[1], pc[2], pc[3], (pc[4] << 8) | pc[5]);
            else
                sprintf(cast_char port_string, "%d,%d,%d,%d,%d,%d", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5]);
        }
        if (strlen(cast_const_char port_string) >= sizeof(port_string))
            internal("buffer overflow in get_pasv_socket_ipv6: %d > %d", (int)strlen(cast_const_char port_string), (int)sizeof(port_string));
    }
#ifdef HAVE_IPTOS
    if (ftp_options.set_tos) {
        int rx;
        int on = IPTOS_THROUGHPUT;
        EINTRLOOP(rx, setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)));
    }
#endif
    if (!(de = cast_uchar strchr(cast_const_char d, POST_CHAR))) de = d + strlen(cast_const_char d);
    if (d == de || de[-1] == '/') {
        inf->dir = 1;
        inf->pending_commands = 4;
        add_to_str(&s, &l, cast_uchar "TYPE A\r\n");
        add_port_pasv(&s, &l, inf, port_string);
        add_to_str(&s, &l, cast_uchar "CWD /");
        add_bytes_to_str(&s, &l, d, de - d);
        add_to_str(&s, &l, cast_uchar "\r\nLIST\r\n");
        c->from = 0;
    } else {
        inf->dir = 0;
        inf->pending_commands = 3;
        add_to_str(&s, &l, cast_uchar "TYPE I\r\n");
        add_port_pasv(&s, &l, inf, port_string);
        if (c->from && c->no_cache < NC_IF_MOD) {
            add_to_str(&s, &l, cast_uchar "REST ");
            add_num_to_str(&s, &l, c->from);
            add_to_str(&s, &l, cast_uchar "\r\n");
            inf->rest_sent = 1;
            inf->pending_commands++;
        } else c->from = 0;
        add_to_str(&s, &l, cast_uchar "RETR /");
        add_bytes_to_str(&s, &l, d, de - d);
        add_to_str(&s, &l, cast_uchar "\r\n");
    }
    inf->opc = inf->pending_commands;
    if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc();
    inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1);
    strcpy(cast_char (inf = inf2)->cmdbuf, cast_const_char s);
    mem_free(s);
    c->info = inf;
    mem_free(d);
    return inf;
}
Exemple #26
0
unsigned char *init_graphics(unsigned char *driver, unsigned char *param, unsigned char *display)
{
	unsigned char *s = init_str();
	int l = 0;
	struct graphics_driver **gd;
	for (gd = graphics_drivers; *gd; gd++) {
		if (!driver || !*driver || !strcasecmp((*gd)->name, driver)) {
			unsigned char *r;
			if ((!driver || !*driver) && (*gd)->flags & GD_NOAUTO) continue;
			if (!(r = init_graphics_driver(*gd, param, display))) {
				mem_free(s);
				drv = *gd;
				F = 1;
				return NULL;
			}
			if (!l) {
				if (!driver || !*driver) add_to_str(&s, &l, "Could not initialize any graphics driver. Tried the following drivers:\n");
				else add_to_str(&s, &l, "Could not initialize graphics driver ");
			}
			add_to_str(&s, &l, (*gd)->name);
			add_to_str(&s, &l, ":\n");
			add_to_str(&s, &l, r);
			mem_free(r);
		}
	}
	if (!l) {
		add_to_str(&s, &l, "Unknown graphics driver ");
		if (driver) add_to_str(&s, &l, driver);
		add_to_str(&s, &l, ".\nThe following graphics drivers are supported:\n");
		for (gd = graphics_drivers; *gd; gd++) {
			if (gd != graphics_drivers) add_to_str(&s, &l, ", ");
			add_to_str(&s, &l, (*gd)->name);
		}
		add_to_str(&s, &l, "\n");
	}
	return s;
}
Exemple #27
0
struct ftp_connection_info *add_file_cmd_to_str(struct connection *c)
{
	unsigned char *d = get_url_data(c->url);
	unsigned char *de;
	int del;
	unsigned char pc[6];
	int ps;
	struct ftp_connection_info *inf, *inf2;
	unsigned char *s;
	int l;
	if (!d) {
		internal("get_url_data failed");
		setcstate(c, S_INTERNAL);
		abort_connection(c);
		return NULL;
	}
	de = init_str(), del = 0;
	add_conv_str(&de, &del, d, strlen(d), -2);
	d = de;
	inf = mem_alloc(sizeof(struct ftp_connection_info));
	memset(inf, 0, sizeof(struct ftp_connection_info));
	l = 0;
	s = init_str();
	inf->pasv = ftp_options.passive_ftp;
	if (*c->socks_proxy) inf->pasv = 1;
	c->info = inf;
	if (!inf->pasv) if ((ps = get_pasv_socket(c, c->sock1, &c->sock2, pc))) {
		mem_free(d);
		return NULL;
	}
#ifdef HAVE_IPTOS
	if (ftp_options.set_tos) {
		int on = IPTOS_THROUGHPUT;
		setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int));
	}
#endif
	if (!(de = strchr(d, POST_CHAR))) de = d + strlen(d);
	if (d == de || de[-1] == '/') {
		inf->dir = 1;
		inf->pending_commands = 4;
		add_to_str(&s, &l, "TYPE A\r\n");
		if (!inf->pasv) {
			add_to_str(&s, &l, "PORT ");
			add_num_to_str(&s, &l, pc[0]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[1]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[2]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[3]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[4]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[5]);
			add_to_str(&s, &l, "\r\n");
		} else {
			add_to_str(&s, &l, "PASV\r\n");
		}
		add_to_str(&s, &l, "CWD /");
		add_bytes_to_str(&s, &l, d, de - d);
		add_to_str(&s, &l, "\r\nLIST\r\n");
		c->from = 0;
	} else {
		inf->dir = 0;
		inf->pending_commands = 3;
		add_to_str(&s, &l, "TYPE I\r\n");
		if (!inf->pasv) {
			add_to_str(&s, &l, "PORT ");
			add_num_to_str(&s, &l, pc[0]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[1]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[2]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[3]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[4]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[5]);
			add_to_str(&s, &l, "\r\n");
		} else {
			add_to_str(&s, &l, "PASV\r\n");
		}
		if (c->from && c->no_cache < NC_IF_MOD) {
			add_to_str(&s, &l, "REST ");
			add_num_to_str(&s, &l, c->from);
			add_to_str(&s, &l, "\r\n");
			inf->rest_sent = 1;
			inf->pending_commands++;
		} else c->from = 0;
		add_to_str(&s, &l, "RETR /");
		add_bytes_to_str(&s, &l, d, de - d);
		add_to_str(&s, &l, "\r\n");
	}
	inf->opc = inf->pending_commands;
	if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc();
	inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1);
	strcpy((inf = inf2)->cmdbuf, s);
	mem_free(s);
	c->info = inf;
	mem_free(d);
	return inf;
}
Exemple #28
0
void http_send_header(struct connection *c)
{
    static unsigned char *accept_charset = NULL;
    struct http_connection_info *info;
    int http10 = http_bugs.http10;
    struct cache_entry *e = NULL;
    unsigned char *hdr;
    unsigned char *h, *u;
    int l = 0;
    int la;
    unsigned char *post;
    unsigned char *host;

    find_in_cache(c->url, &c->cache);

    host = upcase(c->url[0]) != 'P' ? c->url : get_url_data(c->url);
    set_timeout(c);
    info = mem_calloc(sizeof(struct http_connection_info));
    c->info = info;
    if ((h = get_host_name(host))) {
        info->bl_flags = get_blacklist_flags(h);
        mem_free(h);
    }
    if (info->bl_flags & BL_HTTP10) http10 = 1;
    info->http10 = http10;
    post = strchr(host, POST_CHAR);
    if (post) post++;
    hdr = init_str();
    if (!post) add_to_str(&hdr, &l, "GET ");
    else {
        add_to_str(&hdr, &l, "POST ");
        c->unrestartable = 2;
    }
    if (upcase(c->url[0]) != 'P') add_to_str(&hdr, &l, "/");
    if (!(u = get_url_data(c->url))) {
        mem_free(hdr);
        setcstate(c, S_BAD_URL);
        http_end_request(c, 0);
        return;
    }
    if (post && post < u) {
        mem_free(hdr);
        setcstate(c, S_BAD_URL);
        http_end_request(c, 0);
        return;
    }
    add_url_to_str(&hdr, &l, u);
    if (!http10) add_to_str(&hdr, &l, " HTTP/1.1\r\n");
    else add_to_str(&hdr, &l, " HTTP/1.0\r\n");
    if ((h = get_host_name(host))) {
        add_to_str(&hdr, &l, "Host: ");
        add_to_str(&hdr, &l, h);
        mem_free(h);
        if ((h = get_port_str(host))) {
            add_to_str(&hdr, &l, ":");
            add_to_str(&hdr, &l, h);
            mem_free(h);
        }
        add_to_str(&hdr, &l, "\r\n");
    }
    add_to_str(&hdr, &l, "User-Agent: ");
    if (!(*http_bugs.fake_useragent)) {
        add_to_str(&hdr, &l, "Links (" VERSION_STRING "; ");
        add_to_str(&hdr, &l, system_name);
        if (!F && !list_empty(terminals)) {
            struct terminal *t = terminals.prev;
            if (!t->spec->braille) {
                add_to_str(&hdr, &l, "; ");
                add_num_to_str(&hdr, &l, t->x);
                add_to_str(&hdr, &l, "x");
                add_num_to_str(&hdr, &l, t->y);
            } else {
                add_to_str(&hdr, &l, "; braille");
            }
        }
#ifdef G
        if (F && drv) {
            add_to_str(&hdr, &l, "; ");
            add_to_str(&hdr, &l, drv->name);
        }
#endif
        add_to_str(&hdr, &l, ")\r\n");
    }
    else {
        add_to_str(&hdr, &l, http_bugs.fake_useragent);
        add_to_str(&hdr, &l, "\r\n");
    }
    switch (http_bugs.referer)
    {
    case REFERER_FAKE:
        add_to_str(&hdr, &l, "Referer: ");
        add_to_str(&hdr, &l, http_bugs.fake_referer);
        add_to_str(&hdr, &l, "\r\n");
        break;

    case REFERER_SAME_URL:
        add_to_str(&hdr, &l, "Referer: ");
        add_url_to_str(&hdr, &l, host);
        add_to_str(&hdr, &l, "\r\n");
        break;

    case REFERER_REAL_SAME_SERVER:
    {
        unsigned char *h, *j;
        int brk = 1;
        if ((h = get_host_name(host))) {
            if ((j = get_host_name(c->prev_url))) {
                if (!strcasecmp(h, j)) brk = 0;
                mem_free(j);
            }
            mem_free(h);
        }
        if (brk) break;
        /* fall through */
    }
    case REFERER_REAL:
    {
        unsigned char *ref;
        unsigned char *user, *ins;
        int ulen;
        if (!(c->prev_url)) break;   /* no referrer */

        ref = stracpy(c->prev_url);
        if (!parse_url(ref, NULL, &user, &ulen, NULL, NULL, &ins, NULL, NULL, NULL, NULL, NULL, NULL) && ulen && ins) {
            memmove(user, ins, strlen(ins) + 1);
        }
        add_to_str(&hdr, &l, "Referer: ");
        add_url_to_str(&hdr, &l, ref);
        add_to_str(&hdr, &l, "\r\n");
        mem_free(ref);
    }
    break;
    }

    add_to_str(&hdr, &l, "Accept: */*\r\n");
#if defined(HAVE_ZLIB) || defined(HAVE_BZIP2)
    if (!http_bugs.no_compression && !(info->bl_flags & BL_NO_COMPRESSION)) {
        int q = strlen(c->url);
        if (q >= 2 && !strcasecmp(c->url + q - 2, ".Z")) goto skip_compress;
        if (q >= 3 && !strcasecmp(c->url + q - 3, ".gz")) goto skip_compress;
        if (q >= 4 && !strcasecmp(c->url + q - 4, ".bz2")) goto skip_compress;
        add_to_str(&hdr, &l, "Accept-Encoding: ");
#if defined(HAVE_ZLIB)
        add_to_str(&hdr, &l, "gzip, deflate, ");
#endif
#if defined(HAVE_BZIP2)
        add_to_str(&hdr, &l, "bzip2, ");
#endif
        hdr[l-2] = '\r';
        hdr[l-1] = '\n';
skip_compress:
        ;
    }
#endif
    if (!(accept_charset)) {
        int i;
        unsigned char *cs, *ac;
        int aclen = 0;
        ac = init_str();
        for (i = 0; (cs = get_cp_mime_name(i)); i++) {
            if (aclen) add_to_str(&ac, &aclen, ", ");
            else add_to_str(&ac, &aclen, "Accept-Charset: ");
            add_to_str(&ac, &aclen, cs);
        }
        if (aclen) add_to_str(&ac, &aclen, "\r\n");
        if ((accept_charset = malloc(strlen(ac) + 1))) strcpy(accept_charset, ac);
        else accept_charset = "";
        mem_free(ac);
    }
    if (!(info->bl_flags & BL_NO_CHARSET) && !http_bugs.no_accept_charset) add_to_str(&hdr, &l, accept_charset);
    if (!(info->bl_flags & BL_NO_ACCEPT_LANGUAGE)) {
        add_to_str(&hdr, &l, "Accept-Language: ");
        la = l;
        add_to_str(&hdr, &l, _(TEXT(T__ACCEPT_LANGUAGE), NULL));
        add_to_str(&hdr, &l, ", ");
        if (!strstr(hdr + la, "en,") && !strstr(hdr + la, "en;")) add_to_str(&hdr, &l, "en;q=0.2, ");
        add_to_str(&hdr, &l, "*;q=0.1\r\n");
    }
    if (!http10) {
        if (upcase(c->url[0]) != 'P') add_to_str(&hdr, &l, "Connection: ");
        else add_to_str(&hdr, &l, "Proxy-Connection: ");
        if (!post || !http_bugs.bug_post_no_keepalive) add_to_str(&hdr, &l, "Keep-Alive\r\n");
        else add_to_str(&hdr, &l, "close\r\n");
    }
    if ((e = c->cache)) {
        int code, vers;
        if (get_http_code(e->head, &code, &vers) || code >= 400) goto skip_ifmod_and_range;
        if (!e->incomplete && e->head && c->no_cache <= NC_IF_MOD) {
            unsigned char *m;
            if (e->last_modified) m = stracpy(e->last_modified);
            else if ((m = parse_http_header(e->head, "Date", NULL))) ;
            else if ((m = parse_http_header(e->head, "Expires", NULL))) ;
            else goto skip_ifmod;
            add_to_str(&hdr, &l, "If-Modified-Since: ");
            add_to_str(&hdr, &l, m);
            add_to_str(&hdr, &l, "\r\n");
            mem_free(m);
        }
skip_ifmod:
        ;
    }
    if (c->from && (c->est_length == -1 || c->from < c->est_length) && c->no_cache < NC_IF_MOD && !(info->bl_flags & BL_NO_RANGE)) {
        /* If the cached entity is compressed and we turned off compression,
           request the whole file */
        if ((info->bl_flags & BL_NO_COMPRESSION || http_bugs.no_compression) && e) {
            unsigned char *d;
            if ((d = parse_http_header(e->head, "Transfer-Encoding", NULL))) {
                mem_free(d);
                goto skip_range;
            }
        }
        add_to_str(&hdr, &l, "Range: bytes=");
        add_num_to_str(&hdr, &l, c->from);
        add_to_str(&hdr, &l, "-\r\n");
skip_range:
        ;
    }
skip_ifmod_and_range:
    if (c->no_cache >= NC_PR_NO_CACHE) add_to_str(&hdr, &l, "Pragma: no-cache\r\nCache-Control: no-cache\r\n");
    if ((h = get_auth_string(c->url))) {
        add_to_str(&hdr, &l, h);
        mem_free(h);
    }
    if (post) {
        unsigned char *pd = strchr(post, '\n');
        if (pd) {
            add_to_str(&hdr, &l, "Content-Type: ");
            add_bytes_to_str(&hdr, &l, post, pd - post);
            add_to_str(&hdr, &l, "\r\n");
            post = pd + 1;
        }
        add_to_str(&hdr, &l, "Content-Length: ");
        add_num_to_str(&hdr, &l, strlen(post) / 2);
        add_to_str(&hdr, &l, "\r\n");
    }
    send_cookies(&hdr, &l, host);
    add_to_str(&hdr, &l, "\r\n");
    if (post) {
        while (post[0] && post[1]) {
            int h1, h2;
            h1 = post[0] <= '9' ? (unsigned)post[0] - '0' : post[0] >= 'A' ? upcase(post[0]) - 'A' + 10 : 0;
            if (h1 < 0 || h1 >= 16) h1 = 0;
            h2 = post[1] <= '9' ? (unsigned)post[1] - '0' : post[1] >= 'A' ? upcase(post[1]) - 'A' + 10 : 0;
            if (h2 < 0 || h2 >= 16) h2 = 0;
            add_chr_to_str(&hdr, &l, h1 * 16 + h2);
            post += 2;
        }
    }
    write_to_socket(c, c->sock1, hdr, l, http_get_header);
    mem_free(hdr);
    setcstate(c, S_SENT);
}
Exemple #29
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);
}