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 + -
显示快捷键?