📄 session.c
字号:
if (stat->prg->elapsed >= CURRENT_SPD_AFTER * SPD_DISP_TIME) add_to_str(&m, &l, ", "), add_to_str(&m, &l, _(TEXT(T_CURRENT_SPEED), term)), add_to_str(&m, &l, " "), add_xnum_to_str(&m, &l, stat->prg->cur_loaded / (CURRENT_SPD_SEC * SPD_DISP_TIME / 1000)), add_to_str(&m, &l, "/s"); add_to_str(&m, &l, "\n"); add_to_str(&m, &l, _(TEXT(T_ELAPSED_TIME), term)); add_to_str(&m, &l, " "); add_time_to_str(&m, &l, stat->prg->elapsed / 1000); if (stat->prg->size >= 0 && stat->prg->loaded > 0) { add_to_str(&m, &l, ", "); add_to_str(&m, &l, _(TEXT(T_ESTIMATED_TIME), term)); add_to_str(&m, &l, " "); /*add_time_to_str(&m, &l, stat->prg->elapsed / 1000 * stat->prg->size / stat->prg->loaded * 1000 - stat->prg->elapsed);*/ add_time_to_str(&m, &l, (stat->prg->size - stat->prg->pos) / ((longlong)stat->prg->loaded * 10 / (stat->prg->elapsed / 100))); } } else m = stracpy(_(get_err_msg(stat->state), term)); u = stracpy(down->url); if (strchr(u, POST_CHAR)) *strchr(u, POST_CHAR) = 0; max_text_width(term, u, &max, AL_LEFT); min_text_width(term, u, &min, AL_LEFT); max_text_width(term, m, &max, AL_LEFT); min_text_width(term, m, &min, AL_LEFT); max_buttons_width(term, dlg->items, dlg->n, &max); min_buttons_width(term, dlg->items, dlg->n, &min); w = dlg->win->term->x * 9 / 10 - 2 * DIALOG_LB; if (w < min) w = min; if (!dlg->win->term->spec->braille && w > dlg->win->term->x - 2 * DIALOG_LB) w = dlg->win->term->x - 2 * DIALOG_LB; if (t && stat->prg->size >= 0) { if (w < DOWN_DLG_MIN) w = DOWN_DLG_MIN; } else { if (w > max) w = max; } if (w < 1) w = 1; y = 0; dlg_format_text(dlg, NULL, u, 0, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); y += gf_val(1, G_BFU_FONT_SIZE); if (t && stat->prg->size >= 0) y += gf_val(2, 2 * G_BFU_FONT_SIZE); dlg_format_text(dlg, NULL, m, 0, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); y += gf_val(1, G_BFU_FONT_SIZE); dlg_format_buttons(dlg, NULL, 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 + gf_val(1, G_BFU_FONT_SIZE); x = dlg->x + DIALOG_LB; dlg_format_text(dlg, term, u, x, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); if (t && stat->prg->size >= 0) { if (!F) { unsigned char q[64]; int p = w - 6; if (term->spec->braille && p > 39 - 6) p = 39 - 6; y++; set_only_char(term, x, y, '['); set_only_char(term, x + p + 1, 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 + p + 2, y, strlen(q), q, COLOR_DIALOG_TEXT); y++;#ifdef G } else { unsigned char q[64]; int p, s, ss, m; y += G_BFU_FONT_SIZE; sprintf(q, "]%3d%%", (int)((longlong)100 * (longlong)stat->prg->pos / (longlong)stat->prg->size)); s = g_text_width(bfu_style_bw_mono, "["); ss = g_text_width(bfu_style_bw_mono, q); p = w - s - ss; if (p < 0) p = 0; m = (int)((longlong)p * (longlong)stat->prg->pos / (longlong)stat->prg->size); g_print_text(drv, term->dev, x, y, bfu_style_bw_mono, "[", NULL); drv->fill_area(term->dev, x + s, y, x + s + m, y + G_BFU_FONT_SIZE, bfu_fg_color); drv->fill_area(term->dev, x + s + m, y, x + s + p, y + G_BFU_FONT_SIZE, bfu_bg_color); g_print_text(drv, term->dev, x + w - ss, y, bfu_style_bw_mono, q, NULL); if (dlg->s) exclude_from_set(&dlg->s, x, y, x + w, y + G_BFU_FONT_SIZE); y += G_BFU_FONT_SIZE;#endif } } y += gf_val(1, G_BFU_FONT_SIZE); dlg_format_text(dlg, term, m, x, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT); y += gf_val(1, G_BFU_FONT_SIZE); dlg_format_buttons(dlg, 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_calloc(sizeof(struct dialog) + 4 * 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); if (!down->prog) { dlg->items[2].type = D_BUTTON; dlg->items[2].gid = 0; dlg->items[2].fn = dlg_abort_and_delete_download; dlg->items[2].text = TEXT(T_ABORT_AND_DELETE_FILE); dlg->items[3].type = D_END; } else { dlg->items[2].type = D_END; } do_dialog(term, dlg, getml(dlg, NULL));}time_t parse_http_date(char *date) /* this functions is bad !!! */{ static 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 */ int y; struct tm tm; memset(&tm, 0, sizeof(struct tm)); date = strchr(date, ' '); if (!date) return 0; date++; if (*date >= '0' && *date <= '9') { /* Sun, 06 Nov 1994 08:49:37 GMT */ /* Sunday, 06-Nov-94 08:49:37 GMT */ y = 0; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; tm.tm_mday = (date[0] - '0') * 10 + date[1] - '0'; date += 2; if (*date != ' ' && *date != '-') return 0; date += 1; for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++) if (!casecmp(date, months[tm.tm_mon], 3)) goto f1; return 0; f1: date += 3; if (*date == ' ') { /* Sun, 06 Nov 1994 08:49:37 GMT */ date++; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; if (date[2] < '0' || date[2] > '9') return 0; if (date[3] < '0' || date[3] > '9') return 0; tm.tm_year = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0' - 1900; date += 4; } else if (*date == '-') { /* Sunday, 06-Nov-94 08:49:37 GMT */ date++; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; tm.tm_year = (date[0] >= '7' ? 1900 : 2000) + (date[0] - '0') * 10 + date[1] - '0' - 1900; date += 2; } else return 0; if (*date != ' ') return 0; date++; } else { /* Sun Nov 6 08:49:37 1994 */ y = 1; for (tm.tm_mon = 0; tm.tm_mon < 12; tm.tm_mon++) if (!casecmp(date, months[tm.tm_mon], 3)) goto f2; return 0; f2: date += 3; while (*date == ' ') date++; if (date[0] < '0' || date[0] > '9') return 0; tm.tm_mday = date[0] - '0'; date++; if (*date != ' ') { if (date[0] < '0' || date[0] > '9') return 0; tm.tm_mday = tm.tm_mday * 10 + date[0] - '0'; date++; } if (*date != ' ') return 0; date++; } if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; tm.tm_hour = (date[0] - '0') * 10 + date[1] - '0'; date += 2; if (*date != ':') return 0; date++; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; tm.tm_min = (date[0] - '0') * 10 + date[1] - '0'; date += 2; if (*date != ':') return 0; date++; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; tm.tm_sec = (date[0] - '0') * 10 + date[1] - '0'; date += 2; if (y) { if (*date != ' ') return 0; date++; if (date[0] < '0' || date[0] > '9') return 0; if (date[1] < '0' || date[1] > '9') return 0; if (date[2] < '0' || date[2] > '9') return 0; if (date[3] < '0' || date[3] > '9') return 0; tm.tm_year = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0' - 1900; date += 4; } if (*date != ' ' && *date) return 0; t = mktime(&tm); if (t == (time_t) -1) return 0; return t;}static int download_write(struct download *down, void *ptr, off_t to_write){ int w; if (to_write != (int)to_write || (int)to_write < 0) to_write = MAXINT; try_write_again: errno = 0; w = write(down->handle, ptr, to_write); if (w <= -!to_write) {#ifdef EFBIG if (errno == EFBIG && !down->prog) { if (to_write > 1) { to_write >>= 1; goto try_write_again; } if (down->last_pos == down->file_shift) goto no_e2big; close_download_file(down); increase_download_file(&down->file); if ((down->handle = create_download_file(get_download_ses(down), down->cwd, down->file, 0, down->last_pos - down->file_shift)) < 0) return -1; down->file_shift = down->last_pos; goto try_write_again; no_e2big:; }#endif if (get_download_ses(down)) { unsigned char *emsg = stracpy(errno ? strerror(errno) : "Zero returned"); 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); } return -1; } down->last_pos += w; return 0;}void download_data(struct status *stat, struct download *down){ struct cache_entry *ce; struct fragment *frag; if (!(ce = stat->ce)) goto end_store; if (stat->state >= S_WAIT && stat->state < S_TRANS) goto end_store; if (!down->remotetime && ce->last_modified) down->remotetime = parse_http_date(ce->last_modified);/* fprintf(stderr,"\nFEFE date %s\n",ce->last_modified); */ if (!down->last_pos) { unsigned char *enc = get_content_encoding(ce->head, ce->url); if (enc) { if (!encoding_2_extension(enc)) down->decompress = 1; mem_free(enc); } if (ce->redirect) { if (down->redirect_cnt++ < MAX_REDIRECTS) { unsigned char *u, *p, *pos; unsigned char *prev_down_url; int cache; 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); prev_down_url = 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); } cache = NC_CACHE; if (!strcmp(down->url, prev_down_url) || down->redirect_cnt >= MAX_CACHED_REDIRECTS) cache = NC_RELOAD; mem_free(prev_down_url); load_url(down->url, NULL, &down->stat, PRI_DOWNLOAD, cache); return; } else { if (stat->state >= 0) change_connection(&down->stat, NULL, PRI_CANCEL); stat->state = S_CYCLIC_REDIRECT; goto end_store; } } } x: if (!down->decompress) foreach(frag, ce->frag) while (frag->offset <= down->last_pos && frag->offset + frag->length > down->last_pos) {#ifdef HAVE_OPEN_PREALLOC if (!down->last_pos && (!down->stat.prg || down->stat.prg->size > 0)) { struct stat st; if (fstat(down->handle, &st) || !S_ISREG(st.st_mode)) goto skip_prealloc; close_download_file(down); delete_download_file(down); if ((down->handle = create_download_file(get_download_ses(down), down->cwd, down->file, !!down->prog, down->stat.prg ? down->stat.prg->size : ce->length)) < 0) goto det_abt; skip_prealloc:; }#endif if (download_write(down, frag->data + (down->last_pos - frag->offset), frag->length - (down->last_pos - frag->offset))) { det_abt: detach_connection(stat, down->last_pos); abort_download(down); return; } } detach_connection(stat, down->last_pos); end_store:; if (stat->state < 0) { if (down->decompress) { struct session *ses = get_download_ses(down); unsigned char *start, *end; int err; get_file_by_term(ses ? ses->term : NULL, ce, &start, &end, &err); if (err) goto det_abt; while (down->last_pos < end - start) { if (download_write(down, start + down->last_pos, end - start - down->last_pos)) goto det_abt; } } 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) { close_download_file(down); exec_on_terminal(get_download_ses(down)->term, down->prog, down->orig_file, !!down->prog_flag_block); mem_free(down->prog), down->prog = NULL; } else if (down->remotetime && download_utime) { struct utimbuf foo; unsigned char *file = stracpy(down->orig_file); unsigned char *wd = get_cwd(); set_cwd(down->cwd); foo.actime = foo.modtime = down->remotetime; while (1) { unsigned char *f = translate_download_file(file); utime(file, &foo); mem_free(f); if (!strcmp(file, down->file)) break; increase_download_file(&file); } mem_free(file); if (wd) set_cwd(wd), mem_free(wd); } } 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); }}unsigned char *translate_download_file(unsigned char *fi){ unsigned char *file = stracpy(""); unsigned char *h; if (fi[0] == '~' && dir_sep(fi[1]) && (h = getenv("HOME"))) { add_to_strn(&file, h); fi++; } add_to_strn(&file, fi); return file;}int create_download_file(struct session *ses, unsigned char *cwd, unsigned char *fi, int safe, off_t siz){ unsigned char *wd; unsigned char *file; int h;#ifdef NO_FILE_SECURITY int sf = 0;#else int sf = safe;#endif wd = get_cwd(); set_cwd(cwd); file = translate_download_file(fi);#ifdef HAVE_OPEN_PREALLOC if (siz) { h = open_prealloc(file, O_CREAT|O_WRONLY|O_TRUNC|(safe?O_EXCL:0), sf ? 0600 : 0666, siz); } else#endif { 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; } if (!ses) goto x; msg = stracpy(file); msge = stracpy(strerror(errno)); msg_box(ses->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); x: mem_free(file);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -