session.c

来自「this is the file used to browse web」· C语言 代码 · 共 1,618 行 · 第 1/4 页

C
1,618
字号
	if (w < 1) w = 1;	y = 0;	dlg_format_text(NULL, term, u, 0, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);	y++;	if (t && stat->prg->size >= 0) y += 2;	dlg_format_text(NULL, term, m, 0, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);	y++;	dlg_format_buttons(NULL, term, dlg->items, dlg->n, 0, &y, w, NULL, AL_CENTER);	dlg->xw = w + 2 * DIALOG_LB;	dlg->yw = y + 2 * DIALOG_TB;	center_dlg(dlg);	draw_dlg(dlg);	y = dlg->y + DIALOG_TB + 1;	x = dlg->x + DIALOG_LB;	dlg_format_text(term, term, u, x, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);	if (t && stat->prg->size >= 0) {		unsigned char q[64];		int p = w - 6;		y++;		set_only_char(term, x, y, '[');		set_only_char(term, x + w - 5, y, ']');		fill_area(term, x + 1, y, (int)((longlong)p * (longlong)stat->prg->pos / (longlong)stat->prg->size), 1, COLOR_DIALOG_METER);		sprintf(q, "%3d%%", (int)((longlong)100 * (longlong)stat->prg->pos / (longlong)stat->prg->size));		print_text(term, x + w - 4, y, strlen(q), q, COLOR_DIALOG_TEXT);		y++;	}	y++;	dlg_format_text(term, term, m, x, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);	y++;	dlg_format_buttons(term, term, dlg->items, dlg->n, x, &y, w, NULL, AL_CENTER);	mem_free(u);	mem_free(m);}void display_download(struct terminal *term, struct download *down, struct session *ses){	struct dialog *dlg;	struct download *dd;	foreach(dd, downloads) if (dd == down) goto found;	return;	found:	dlg = mem_alloc(sizeof(struct dialog) + 3 * sizeof(struct dialog_item));	memset(dlg, 0, sizeof(struct dialog) + 3 * sizeof(struct dialog_item));	undisplay_download(down);	down->ses = ses;	dlg->title = TEXT(T_DOWNLOAD);	dlg->fn = download_window_function;	dlg->abort = download_abort_function;	dlg->udata = down;	dlg->align = AL_CENTER;	dlg->items[0].type = D_BUTTON;	dlg->items[0].gid = B_ENTER | B_ESC;	dlg->items[0].fn = dlg_undisplay_download;	dlg->items[0].text = TEXT(T_BACKGROUND);	dlg->items[1].type = D_BUTTON;	dlg->items[1].gid = 0;	dlg->items[1].fn = dlg_abort_download;	dlg->items[1].text = TEXT(T_ABORT);	dlg->items[2].type = D_END;	do_dialog(term, dlg, getml(dlg, NULL));}time_t parse_http_date(const char *date)	/* this functions is bad !!! */{	const char *months[12] =		{"Jan", "Feb", "Mar", "Apr", "May", "Jun",		 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};	time_t t = 0;	/* Mon, 03 Jan 2000 21:29:33 GMT */	struct tm tm;	if (!date || strlen(date) < 28) return 0;	date += 5;	tm.tm_mday = (date[0] - '0') * 10 + date[1] - '0';	date += 3;	for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++)		if (!strncmp(date, months[tm.tm_mon], 3)) break;	date += 4;	tm.tm_year = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0' - 1900;	date += 5;	tm.tm_hour = (date[0] - '0') * 10 + date[1] - '0';	date += 3;	tm.tm_min = (date[0] - '0') * 10 + date[1] - '0';	date += 3;	tm.tm_sec = (date[0] - '0') * 10 + date[1] - '0';	t = mktime(&tm);	if (t == (time_t) - 1) return 0;	else return t;}void download_data(struct status *stat, struct download *down){	struct cache_entry *ce;	struct fragment *frag;	if (stat->state >= S_WAIT && stat->state < S_TRANS) goto end_store;	if (!(ce = stat->ce)) goto end_store;	if (ce->last_modified)	down->remotetime = parse_http_date(ce->last_modified);/*	  fprintf(stderr,"\nFEFE date %s\n",ce->last_modified); */	if (ce->redirect && down->redirect_cnt++ < MAX_REDIRECTS) {		unsigned char *u, *p, *pos;		if (stat->state >= 0) change_connection(&down->stat, NULL, PRI_CANCEL);		u = join_urls(down->url, ce->redirect);		if (!u) goto x;		if ((pos = extract_position(u))) mem_free(pos);		if (!http_bugs.bug_302_redirect) if (!ce->redirect_get && (p = strchr(down->url, POST_CHAR))) add_to_strn(&u, p);		mem_free(down->url);		down->url = u;		down->stat.state = S_WAIT_REDIR;		if (down->win) {			struct event ev = { EV_REDRAW, 0, 0, 0 };			ev.x = down->win->term->x;			ev.y = down->win->term->y;			down->win->handler(down->win, &ev, 0);		}		/*if (!strchr(down->url, POST_CHAR)) {*/			load_url(down->url, &down->stat, PRI_DOWNLOAD, down->redirect_cnt < MAX_CACHED_REDIRECTS ? NC_CACHE : NC_RELOAD);			return;		/*} else {			unsigned char *msg = init_str();			int l = 0;			add_bytes_to_str(&msg, &l, down->url, (unsigned char *)strchr(down->url, POST_CHAR) - down->url);			msg_box(get_download_ses(down)->term, getml(msg, NULL), TEXT(T_WARNING), AL_CENTER | AL_EXTD_TEXT, TEXT(T_DO_YOU_WANT_TO_FOLLOW_REDIRECT_AND_POST_FORM_DATA_TO_URL), "", msg, "?", NULL, down, 3, TEXT(T_YES), down_post_yes, B_ENTER, TEXT(T_NO), down_post_no, 0, TEXT(T_CANCEL), down_post_cancel, B_ESC);		}*/	}	x:	foreach(frag, ce->frag) while (frag->offset <= down->last_pos && frag->offset + frag->length > down->last_pos) {		int w;#ifdef HAVE_OPEN_PREALLOC		if (!down->last_pos && (!down->stat.prg || down->stat.prg->size > 0) && can_prealloc(down->file)) {			struct stat st;			if (fstat(down->handle, &st) || !S_ISREG(st.st_mode)) goto skip_prealloc;			close(down->handle);			down->handle = open_prealloc(down->file, O_CREAT|O_WRONLY|O_TRUNC, 0666, down->stat.prg ? down->stat.prg->size : ce->length);			if (down->handle == -1) goto error;			set_bin(down->handle);			skip_prealloc:;		}#endif		w = write(down->handle, frag->data + (down->last_pos - frag->offset), frag->length - (down->last_pos - frag->offset));		if (w == -1) {#ifdef HAVE_OPEN_PREALLOC			error:#endif			if (!list_empty(sessions)) {				unsigned char *emsg = stracpy(strerror(errno));				unsigned char *msg = stracpy(down->file);				msg_box(get_download_ses(down)->term, getml(msg, emsg, NULL), TEXT(T_DOWNLOAD_ERROR), AL_CENTER | AL_EXTD_TEXT, TEXT(T_COULD_NOT_WRITE_TO_FILE), " ", msg, ": ", emsg, NULL, NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);			}			detach_connection(stat, down->last_pos);			abort_download(down);			return;		}		down->last_pos += w;	}	detach_connection(stat, down->last_pos);	end_store:;	if (stat->state < 0) {		if (stat->state != S_OK) {			unsigned char *t = get_err_msg(stat->state);			if (t) {				unsigned char *tt = stracpy(down->url);				if (strchr(tt, POST_CHAR)) *strchr(tt, POST_CHAR) = 0;				msg_box(get_download_ses(down)->term, getml(tt, NULL), TEXT(T_DOWNLOAD_ERROR), AL_CENTER | AL_EXTD_TEXT, TEXT(T_ERROR_DOWNLOADING), " ", tt, ":\n\n", t, NULL, get_download_ses(down), 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC/*, TEXT(T_RETRY), NULL, 0 !!! FIXME: retry */);			}		} else {			if (down->prog) {				prealloc_truncate(down->handle, down->last_pos);				close(down->handle), down->handle = -1;				exec_on_terminal(get_download_ses(down)->term, down->prog, down->file, !!down->prog_flags);				mem_free(down->prog), down->prog = NULL;			} else if (down->remotetime && download_utime) {				struct utimbuf foo;				foo.actime = foo.modtime = down->remotetime;				utime(down->file, &foo);			}		}		abort_download(down);		return;	}	if (down->win) {		struct event ev = { EV_REDRAW, 0, 0, 0 };		ev.x = down->win->term->x;		ev.y = down->win->term->y;		down->win->handler(down->win, &ev, 0);	}}int create_download_file(struct terminal *term, unsigned char *fi, int safe){	unsigned char *file = fi;	unsigned char *wd = NULL;	int h;	int i;#ifdef NO_FILE_SECURITY	int sf = 0;#else	int sf = safe;#endif	if (!safe) {		wd = get_cwd();		set_cwd(term->cwd);		if (file[0] == '~' && dir_sep(file[1])) {			unsigned char *h = getenv("HOME");			if (h) {				int fl = 0;				file = init_str();				add_to_str(&file, &fl, h);				add_to_str(&file, &fl, fi + 1);			}		}	}	h = open(file, O_CREAT|O_WRONLY|O_TRUNC|(safe?O_EXCL:0), sf ? 0600 : 0666);	if (h == -1) {		unsigned char *msg, *msge;		if (errno == EEXIST && safe) {			h = -2;			goto x;		}		msg = stracpy(file);		msge = stracpy(strerror(errno));		msg_box(term, getml(msg, msge, NULL), TEXT(T_DOWNLOAD_ERROR), AL_CENTER | AL_EXTD_TEXT, TEXT(T_COULD_NOT_CREATE_FILE), " ", msg, ": ", msge, NULL, NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);		goto x;	}	set_bin(h);	if (safe) goto x;	if (strlen(file) >= MAX_STR_LEN) memcpy(download_dir, file, MAX_STR_LEN - 1), download_dir[MAX_STR_LEN - 1] = 0;	else strcpy(download_dir, file);	for (i = strlen(download_dir) - 1; i >= 0; i--) if (dir_sep(download_dir[i])) {		download_dir[i + 1] = 0;		goto x;	}	download_dir[0] = 0;	x:	if (file != fi) mem_free(file);	if (wd) set_cwd(wd), mem_free(wd);	return h;}unsigned char *get_temp_name(unsigned char *url){	int l, nl;	unsigned char *name, *fn, *fnn, *fnnn, *s;	unsigned char *nm;	unsigned char *directory = NULL;#ifdef WIN32	directory = getenv("TMP");	if (!directory) directory = getenv("TEMP");#endif	nm = tempnam(directory, "links");	if (!nm) return NULL;#ifdef OS2	if (strlen(nm) > 4 && !strcasecmp(nm + strlen(nm) - 4, ".tmp")) nm[strlen(nm) - 4] = 0;#endif	name = init_str();	nl = 0;	add_to_str(&name, &nl, nm);	free(nm);	get_filename_from_url(url, &fn, &l);	fnnn = NULL;	for (fnn = fn; fnn < fn + l; fnn++) if (*fnn == '.') fnnn = fnn;	if (fnnn) {		s = memacpy(fnnn, l - (fnnn - fn));		check_shell_security(&s);		add_to_str(&name, &nl, s);		mem_free(s);	}	return name;}unsigned char *subst_file(unsigned char *prog, unsigned char *file){	unsigned char *n = init_str();	int l = 0;	while (*prog) {		int p;		for (p = 0; prog[p] && prog[p] != '%'; p++) ;		add_bytes_to_str(&n, &l, prog, p);		prog += p;		if (*prog == '%') {#if defined(HAVE_CYGWIN_CONV_TO_FULL_WIN32_PATH)#ifdef MAX_PATH			unsigned char new_path[MAX_PATH];#else			unsigned char new_path[1024];#endif			cygwin_conv_to_full_win32_path(file, new_path);			add_to_str(&n, &l, new_path);#else			add_to_str(&n, &l, file);#endif			prog++;		}	}	return n;}void start_download(struct session *ses, unsigned char *file){	struct download *down;	int h;	unsigned char *url = ses->dn_url;	if (!url) return;	kill_downloads_to_file(file);	if ((h = create_download_file(ses->term, file, 0)) < 0) return;	down = mem_alloc(sizeof(struct download));	memset(down, 0, sizeof(struct download));	down->url = stracpy(url);	down->stat.end = (void (*)(struct status *, void *))download_data;	down->stat.data = down;	down->last_pos = 0;	down->file = stracpy(file);	down->handle = h;	down->ses = ses;	down->remotetime = 0;	add_to_list(downloads, down);	load_url(url, &down->stat, PRI_DOWNLOAD, NC_CACHE);	display_download(ses->term, down, ses);}void tp_cancel(struct session *);void tp_free(struct session *);void continue_download(struct session *ses, unsigned char *file){	struct download *down;	int h;	int namecount = 0;	unsigned char *url = ses->tq_url;	if (!url) return;	if (ses->tq_prog) {		new_name:		if (!(file = get_temp_name(url))) {			tp_cancel(ses);			return;		}	}	kill_downloads_to_file(file);	if (!ses->tq_prog) kill_downloads_to_file(file);	if ((h = create_download_file(ses->term, file, !!ses->tq_prog)) < 0) {		if (h == -2 && ses->tq_prog) {			if (++namecount < DOWNLOAD_NAME_TRIES) {				mem_free(file);				goto new_name;			}			msg_box(ses->term, NULL, TEXT(T_DOWNLOAD_ERROR), AL_CENTER | AL_EXTD_TEXT, TEXT(T_COULD_NOT_CREATE_TEMPORARY_FILE), NULL, NULL, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);		}		if (ses->tq_prog) mem_free(file);		tp_cancel(ses);		return;	}	down = mem_alloc(sizeof(struct download));	memset(down, 0, sizeof(struct download));	down->url = stracpy(url);	down->stat.end = (void (*)(struct status *, void *))download_data;	down->stat.data = down;	down->last_pos = 0;	down->file = stracpy(file);	down->handle = h;	down->ses = ses;	if (ses->tq_prog) {		down->prog = subst_file(ses->tq_prog, file);		mem_free(file);		mem_free(ses->tq_prog);		ses->tq_prog = NULL;	}	down->prog_flags = ses->tq_prog_flags;	add_to_list(downloads, down);	change_connection(&ses->tq, &down->stat, PRI_DOWNLOAD);	tp_free(ses);	display_download(ses->term, down, ses);}void tp_free(struct session *ses){	ses->tq_ce->refcount--;	mem_free(ses->tq_url);	ses->tq_url = NULL;	if (ses->tq_goto_position) mem_free(ses->tq_goto_position), ses->tq_goto_position = NULL;	ses->tq_ce = NULL;}void tp_cancel(struct session *ses){	change_connection(&ses->tq, NULL, PRI_CANCEL);	tp_free(ses);}void tp_save(struct session *ses){	if (ses->tq_prog) mem_free(ses->tq_prog), ses->tq_prog = NULL;	query_file(ses, ses->tq_url, continue_download, tp_cancel);}void tp_open(struct session *ses){	continue_download(ses, "");}void display_timer(struct session *);void tp_display(struct session *ses)	/* !!! FIXME: frames */{	struct location *l;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?