📄 view.c
字号:
void encode_string(unsigned char *name, unsigned char **data, int *len){ for (; *name; name++) { if (*name == ' ') add_chr_to_str(data, len, '+'); else if (safe_char(*name)) add_chr_to_str(data, len, *name); else { unsigned char n[4]; sprintf(n, "%%%02X", *name); add_to_str(data, len, n); } }}void encode_controls(struct list_head *l, unsigned char **data, int *len, int cp_from, int cp_to){ struct submitted_value *sv; int lst = 0; char *p2; struct conv_table *convert_table = get_translation_table(cp_from, cp_to); *len = 0; *data = init_str(); foreach(sv, *l) { unsigned char *p = sv->value; struct document_options o; memset(&o, 0, sizeof o); o.plain = 1; d_opt = &o; /*if (sv->type == FC_TEXTAREA) p = encode_textarea(sv->value);*/ if (lst) add_to_str(data, len, "&"); else lst = 1; encode_string(sv->name, data, len); add_to_str(data, len, "="); if (sv->type == FC_TEXT || sv->type == FC_PASSWORD || sv->type == FC_TEXTAREA) p2 = convert_string(convert_table, p, strlen(p)); else p2 = stracpy(p); encode_string(p2, data, len); mem_free(p2); /*if (sv->type == FC_TEXTAREA) mem_free(p);*/ }}#define BL 56#define BL1 27void encode_multipart(struct session *ses, struct list_head *l, unsigned char **data, int *len, unsigned char *bound, int cp_from, int cp_to){ int *bound_ptrs = DUMMY; int nbound_ptrs = 0; unsigned char *m1, *m2; struct submitted_value *sv; int i, j; int flg = 0; char *p; struct conv_table *convert_table = get_translation_table(cp_from, cp_to); memset(bound, 'x', BL); *len = 0; *data = init_str(); foreach(sv, *l) { unsigned char *ct; bnd: add_to_str(data, len, "--"); if (!(nbound_ptrs & (ALLOC_GR-1))) { if ((unsigned)nbound_ptrs > MAXINT / sizeof(int) - ALLOC_GR) overalloc(); bound_ptrs = mem_realloc(bound_ptrs, (nbound_ptrs + ALLOC_GR) * sizeof(int)); } bound_ptrs[nbound_ptrs++] = *len; add_bytes_to_str(data, len, bound, BL); if (flg) break; add_to_str(data, len, "\r\nContent-Disposition: form-data; name=\""); add_to_str(data, len, sv->name); add_to_str(data, len, "\""); if (sv->type == FC_FILE) { add_to_str(data, len, "; filename=\""); add_to_str(data, len, strip_file_name(sv->value)); /* It sends bad data if the file name contains ", but Netscape does the same */ add_to_str(data, len, "\""); if (*sv->value) if ((ct = get_content_type(NULL, sv->value))) { add_to_str(data, len, "\r\nContent-Type: "); add_to_str(data, len, ct); if (strlen(ct) >= 4 && !casecmp(ct, "text", 4)) { add_to_str(data, len, "; charset="); add_to_str(data, len, get_cp_mime_name(ses->term->spec->charset)); } mem_free(ct); } } add_to_str(data, len, "\r\n\r\n"); if (sv->type != FC_FILE) { struct document_options o; o.plain = 1; d_opt = &o; if (sv->type == FC_TEXT || sv->type == FC_PASSWORD || sv->type == FC_TEXTAREA) p = convert_string(convert_table, sv->value, strlen(sv->value)); else p = stracpy(sv->value); add_to_str(data, len, p); mem_free(p); } else { int fh, rd;#define F_BUFLEN 1024 unsigned char buffer[F_BUFLEN]; /*if (!check_file_name(sv->value)) { err = "File access forbidden"; goto error; }*/ if (*sv->value) { if (anonymous) { errno = EPERM; goto error; } if ((fh = open(sv->value, O_RDONLY)) == -1) goto error; set_bin(fh); do { if ((rd = read(fh, buffer, F_BUFLEN)) == -1) { close(fh); goto error; } if (rd) add_bytes_to_str(data, len, buffer, rd); } while (rd); close(fh); } } add_to_str(data, len, "\r\n"); } if (!flg) { flg = 1; goto bnd; } add_to_str(data, len, "--\r\n"); memset(bound, '-', BL1); memset(bound + BL1, '0', BL - BL1); again: for (i = 0; i <= *len - BL; i++) { for (j = 0; j < BL; j++) if ((*data)[i + j] != bound[j]) goto nb; for (j = BL - 1; j >= 0; j--) if (bound[j] < '0') bound[j] = '0' - 1; if (bound[j]++ >= '9') bound[j] = '0'; else goto again; internal("Counld not assing boundary"); nb:; } for (i = 0; i < nbound_ptrs; i++) memcpy(*data + bound_ptrs[i], bound, BL); mem_free(bound_ptrs); return; error: mem_free(bound_ptrs); mem_free(*data); *data = NULL; m1 = stracpy(sv->value); m2 = stracpy(strerror(errno)); msg_box(ses->term, getml(m1, m2, NULL), TEXT(T_ERROR_WHILE_POSTING_FORM), AL_CENTER | AL_EXTD_TEXT, TEXT(T_COULD_NOT_GET_FILE), " ", m1, ": ", m2, NULL, ses, 1, TEXT(T_CANCEL), NULL, B_ENTER | B_ESC);}void reset_form(struct f_data_c *f, int form_num){ struct form_control *form; foreach(form, f->f_data->forms) if (form->form_num == form_num) { struct form_state *fs; if ((fs = find_form_state(f, form))) init_ctrl(form, fs); }} unsigned char *get_form_url(struct session *ses, struct f_data_c *f, struct form_control *form){ struct list_head submit; unsigned char *data; unsigned char bound[BL]; int len; unsigned char *go = NULL; int cp_from, cp_to; if (!form) return NULL; if (form->type == FC_RESET) { reset_form(f, form->form_num); return NULL; } if (!form->action) return NULL; get_succesful_controls(f, form, &submit); cp_from = ses->term->spec->charset; cp_to = f->f_data->cp; if (form->method == FM_GET || form->method == FM_POST) encode_controls(&submit, &data, &len, cp_from, cp_to); else encode_multipart(ses, &submit, &data, &len, bound, cp_from, cp_to); if (!data) goto ff; if (form->method == FM_GET) { unsigned char *pos; if (strlen(form->action) + 2 + len < (unsigned)len) overalloc(); go = mem_alloc(strlen(form->action) + 1 + len + 1); strcpy(go, form->action); if ((pos = strchr(go, '#'))) { unsigned char *poss = pos; pos = stracpy(pos); *poss = 0; } if (strchr(go, '?')) strcat(go, "&"); else strcat(go, "?"); strcat(go, data); if (pos) strcat(go, pos), mem_free(pos); } else { int l = 0; int i; go = init_str(); add_to_str(&go, &l, form->action); add_chr_to_str(&go, &l, POST_CHAR); if (form->method == FM_POST) add_to_str(&go, &l, "application/x-www-form-urlencoded\n"); else { add_to_str(&go, &l, "multipart/form-data; boundary="); add_bytes_to_str(&go, &l, bound, BL); add_to_str(&go, &l, "\n"); } for (i = 0; i < len; i++) { unsigned char p[3]; sprintf(p, "%02x", (int)data[i]); add_to_str(&go, &l, p); } } mem_free(data); ff: free_succesful_controls(&submit); return go;}unsigned char *get_link_url(struct session *ses, struct f_data_c *f, struct link *l){ if (l->type == L_LINK) { if (!l->where) return stracpy(l->where_img); return stracpy(l->where); } if (l->type != L_BUTTON && l->type != L_FIELD) return NULL; return get_form_url(ses, f, l->form);}void set_frame(struct session *ses, struct f_data_c *f, int a){ if (f == ses->screen) return; goto_url(ses, f->vs->url);}int enter(struct session *ses, struct f_data_c *f, int a){ struct link *link; unsigned char *u; if (f->vs->current_link == -1) return 1; link = &f->f_data->links[f->vs->current_link]; if (link->type == L_LINK || link->type == L_BUTTON) { submit: if ((u = get_link_url(ses, f, link))) { if (strlen(u) >= 4 && !casecmp(u, "MAP@", 4)) goto_imgmap(ses, u + 4, stracpy(u + 4), stracpy(link->target)); else goto_url_f(ses, u, link->target); mem_free(u); return 2; } } else if (link->type == L_FIELD || link->type == L_AREA) { if (!has_form_submit(f->f_data, link->form)) goto submit; down(ses, f, 0); } else if (link->type == L_CHECKBOX) { struct form_state *fs = find_form_state(f, link->form); if (link->form->ro) return 1; if (link->form->type == FC_CHECKBOX) fs->state = !fs->state; else { struct form_control *fc; foreach(fc, f->f_data->forms) if (fc->form_num == link->form->form_num && fc->type == FC_RADIO && !xstrcmp(fc->name, link->form->name)) { struct form_state *ffs = find_form_state(f, fc); if (ffs) ffs->state = 0; } fs = find_form_state(f, link->form); fs->state = 1; } } else if (link->type == L_SELECT) { if (link->form->ro) return 1; f->f_data->refcount++; add_empty_window(ses->term, (void (*)(void *))decrement_fc_refcount, f->f_data); do_select_submenu(ses->term, link->form->menu, ses); } else internal("bad link type %d", link->type); return 1;}void toggle(struct session *ses, struct f_data_c *f, int a){ if (!f || !f->vs) return; f->vs->plain = !f->vs->plain; html_interpret(ses); draw_formatted(ses);}void back(struct session *ses, struct f_data_c *f, int a){ go_back(ses);}void selected_item(struct terminal *term, void *pitem, struct session *ses){ int item = (int)pitem; struct f_data_c *f = current_frame(ses); struct link *l; struct form_state *fs; if (!f) return; if (f->vs->current_link == -1) return; l = &f->f_data->links[f->vs->current_link]; if (l->type != L_SELECT) return; if ((fs = find_form_state(f, l->form))) { struct form_control *form= l->form; if (item >= 0 && item < form->nvalues) { fs->state = item; if (fs->value) mem_free(fs->value); fs->value = stracpy(form->values[item]); } fixup_select_state(form, fs); } draw_doc(ses->term, f, 1); print_screen_status(ses); redraw_from_window(ses->win); /*if (!has_form_submit(f->f_data, l->form)) { goto_form(ses, f, l->form, l->target); }*/}int get_current_state(struct session *ses){ struct f_data_c *f = current_frame(ses); struct link *l; struct form_state *fs; if (!f) return -1; if (f->vs->current_link == -1) return -1; l = &f->f_data->links[f->vs->current_link]; if (l->type != L_SELECT) return -1; if ((fs = find_form_state(f, l->form))) return fs->state; return -1;}int textarea_adjust_viewport(struct f_data_c *fd, struct link *l){ struct form_control *fc = l->form; struct view_state *vs = fd->vs; int r = 0; if (l->pos[0].x + fc->cols > fd->xw + vs->view_posx) vs->view_posx = l->pos[0].x + fc->cols - fd->xw, r = 1; if (l->pos[0].x < vs->view_posx) vs->view_posx = l->pos[0].x, r = 1; if (l->pos[0].y + fc->rows > fd->yw + vs->view_pos) vs->view_pos = l->pos[0].y + fc->rows - fd->yw, r = 1; if (l->pos[0].y < vs->view_pos) vs->view_pos = l->pos[0].y, r = 1; vs->orig_view_pos = vs->view_pos; vs->orig_view_posx = vs->view_posx; return r;}int field_op(struct session *ses, struct f_data_c *f, struct link *l, struct event *ev, int rep){ struct form_control *form = l->form; struct form_state *fs; int x = 1; if (!form) { internal("link has no form control"); return 0; } if (l->form->ro == 2) return 0; if (!(fs = find_form_state(f, form))) return 0; if (!fs->value) return 0; if (ev->ev == EV_KBD) { switch (kbd_action(KM_EDIT, ev)) { case ACT_LEFT: fs->state = fs->state ? fs->state - 1 : 0; break; case ACT_RIGHT: fs->state = (size_t)fs->state < strlen(fs->value) ? fs->state + 1 : (int)strlen(fs->value); break; case ACT_HOME: if (form->type == FC_TEXTAREA) { struct line_info *ln; if ((ln = format_text(fs->value, form->cols, form->wrap))) { int y; for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) { fs->state = ln[y].st - fs->value; goto x; } fs->state = 0; x: mem_free(ln); } } else fs->state = 0; break; case ACT_UP: if (form->type == FC_TEXTAREA) { struct line_info *ln; if ((ln = format_text(fs->value, form->cols, form->wrap))) { int y; rep1: for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) { if (!y) { mem_free(ln); goto b; } fs->state -= ln[y].st - ln[y-1].st; if (fs->value + fs->state > ln[y-1].en) fs->state = ln[y-1].en - fs->value; goto xx; } mem_free(ln); goto b; xx: if (rep) goto rep1; mem_free(ln); } } else x = 0; break; case ACT_DOWN: if (form->type == FC_TEXTAREA) { struct line_info *ln; if ((ln = format_text(fs->value, form->cols, form->wrap))) { int y; rep2: for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) { if (!ln[y+1].st) { mem_free(ln); goto b; } fs->state += ln[y+1].st - ln[y].st; if (fs->value + fs->state > ln[y+1].en) fs->state = ln[y+1].en - fs->value; goto yy; } mem_free(ln); goto b; yy: if (rep) goto rep2; mem_free(ln); } } else x = 0; break; case ACT_END: if (form->type == FC_TEXTAREA) { struct line_info *ln; if ((ln = format_text(fs->value, form->cols, form->wrap))) { int y; for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) { fs->state = ln[y].en - fs->value; if (fs->state && (size_t)fs->state < strlen(fs->value) && ln[y+1].st == ln[y].en) fs->state--; goto yyyy; } fs->state = strlen(fs->value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -