📄 view.c
字号:
} if (!q) internal("form is not on list"); return 0;}struct submitted_value { struct submitted_value *next; struct submitted_value *prev; int type; unsigned char *name; unsigned char *value; void *file_content; int fc_len; int position;};void free_succesful_controls(struct list_head *submit){ struct submitted_value *v; foreach(v, *submit) { if (v->name) mem_free(v->name); if (v->value) mem_free(v->value); if (v->file_content) mem_free(v->file_content); } free_list(*submit);}unsigned char *encode_textarea(unsigned char *t){ int len = 0; unsigned char *o = init_str(); for (; *t; t++) { if (*t != '\n') add_chr_to_str(&o, &len, *t); else add_to_str(&o, &len, "\r\n"); } return o;}int compare_submitted(struct submitted_value *sub1, struct submitted_value *sub2);int compare_submitted(struct submitted_value *sub1, struct submitted_value *sub2){ /*int c = (sub1->type == FC_IMAGE) - (sub2->type == FC_IMAGE); if (c) return c;*/ return sub1->position - sub2->position;}void get_succesful_controls(struct f_data_c *f, struct form_control *fc, struct list_head *subm){ int ch; struct form_control *form; init_list(*subm); foreach(form, f->f_data->forms) { if (form->form_num == fc->form_num && ((form->type != FC_SUBMIT && form->type != FC_IMAGE && form->type != FC_RESET && form->type != FC_BUTTON) || form == fc) && form->name && form->name[0]) { struct submitted_value *sub; struct form_state *fs; int fi = form->type == FC_IMAGE && form->default_value && *form->default_value ? -1 : 0; int svl; if (!(fs = find_form_state(f, form))) continue; if ((form->type == FC_CHECKBOX || form->type == FC_RADIO) && !fs->state) continue; if (form->type == FC_BUTTON) continue; if (form->type == FC_SELECT && !form->nvalues) continue; fi_rep: sub = mem_calloc(sizeof(struct submitted_value)); sub->type = form->type; sub->name = stracpy(form->name); switch (form->type) { case FC_TEXT: case FC_PASSWORD: case FC_FILE: sub->value = stracpy(fs->value); break; case FC_TEXTAREA: sub->value = encode_textarea(fs->value); break; case FC_CHECKBOX: case FC_RADIO: case FC_SUBMIT: case FC_HIDDEN: sub->value = encode_textarea(form->default_value); break; case FC_SELECT: fixup_select_state(form, fs); sub->value = encode_textarea(fs->value); break; case FC_IMAGE: if (fi == -1) { sub->value = encode_textarea(form->default_value); break; } add_to_strn(&sub->name, fi ? ".x" : ".y"); /*sub->value = stracpy("0");*/ sub->value = init_str(); svl = 0; add_num_to_str(&sub->value, &svl, fi ? ismap_x : ismap_y); break; default: internal("bad form control type"); mem_free(sub); continue; } sub->position = form->form_num + form->ctrl_num; add_to_list(*subm, sub); if (form->type == FC_IMAGE && fi < 1) { fi++; goto fi_rep; } } } do { struct submitted_value *sub, *nx; ch = 0; foreach(sub, *subm) if (sub->next != (void *)subm) if (compare_submitted(sub->next, sub) < 0) { nx = sub->next; del_from_list(sub); add_at_pos(nx, sub); sub = nx; ch = 1; } foreachback(sub, *subm) if (sub->next != (void *)subm) if (compare_submitted(sub->next, sub) < 0) { nx = sub->next; del_from_list(sub); add_at_pos(nx, sub); sub = nx; ch = 1; } } while (ch); }unsigned char *strip_file_name(unsigned char *f){ unsigned char *n; unsigned char *l = f - 1; for (n = f; *n; n++) if (dir_sep(*n)) l = n; return l + 1;}static inline int safe_char(unsigned char c){ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c== '.' || c == '-' || 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; 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), NULL); else p2 = stracpy(p); encode_string(p2, data, len); mem_free(p2); }}#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="); if (!F) add_to_str(data, len, get_cp_mime_name(ses->term->spec->charset));#ifdef G else add_to_str(data, len, get_cp_mime_name(ses->ds.assume_cp));#endif } mem_free(ct); } } add_to_str(data, len, "\r\n\r\n"); if (sv->type != FC_FILE) { if (sv->type == FC_TEXT || sv->type == FC_PASSWORD || sv->type == FC_TEXTAREA) p = convert_string(convert_table, sv->value, strlen(sv->value), NULL); 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, int *onsubmit){ 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); if (F) draw_fd(f); return NULL; } if (onsubmit)*onsubmit=0;#ifdef JS if (form->onsubmit) { jsint_execute_code(f,form->onsubmit,strlen(form->onsubmit),-1,form->form_num,form->form_num, NULL); if (onsubmit)*onsubmit=1; }#endif 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 (!strncasecmp(form->action,"javascript:",11)) { go=stracpy(form->action); goto x; } if (form->method == FM_GET) { unsigned char *pos, *da; if (strlen(form->action) + 2 + len < (unsigned)len) overalloc(); go = mem_alloc(strlen(form->action) + 1 + len + 1); strcpy(go, form->action); pos = extract_position(go); if (!(da = get_url_data(go))) da = go; if (strchr(da, '?')) 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); } } x: mem_free(data); ff: free_succesful_controls(&submit); return go;}int ismap_link = 0, ismap_x = 1, ismap_y = 1;/* if onsubmit is not NULL it will contain 1 if link is submit and the form has an onsubmit handler */unsigned char *get_link_url(struct session *ses, struct f_data_c *f, struct link *l, int *onsubmit){ if (l->type == L_LINK) { if (!l->where) { if (l->where_img && (!F || (!f->f_data->opt.display_images && f->f_data->opt.plain != 2))) return stracpy(l->where_img); return NULL; } if (ismap_link && strlen(l->where) >= 4 && !strcmp(l->where + strlen(l->where) - 4, "?0,0")) { unsigned char *nu = init_str(); int ll = 0; add_bytes_to_str(&nu, &ll, l->where, strlen(l->where) - 3); add_num_to_str(&nu, &ll, ismap_x); add_chr_to_str(&nu, &ll, ','); add_num_to_str(&nu, &ll, ismap_y); return nu; } return stracpy(l->where); } if (l->type != L_BUTTON && l->type != L_FIELD) return NULL; return get_form_url(ses, f, l->form, onsubmit);}struct menu_item *clone_select_menu(struct menu_item *m){ struct menu_item *n = DUMMY; int i = 0; do { if ((unsigned)i > MAXINT / sizeof(struct menu_item) - 1) overalloc(); n = mem_realloc(n, (i + 1) * sizeof(struct menu_item)); n[i].text = stracpy(m->text); n[i].rtext = stracpy(m->rtext); n[i].hotkey = stracpy(m->hotkey); n[i].in_m = m->in_m; n[i].free_i = 0; if ((n[i].func = m->func) != MENU_FUNC do_select_submenu) { n[i].data = m->data; } else n[i].data = clone_select_menu(m->data); i++; } while (m++->text); return n;}void free_select_menu(struct menu_item *m){ struct menu_item *om = m; do { if (m->text) mem_free(m->text); if (m->rtext) mem_free(m->rtext); if (m->hotkey) mem_free(m->hotkey); if (m->func == MENU_FUNC do_select_submenu) free_select_menu(m->data); } while (m++->text); mem_free(om);}void set_frame(struct session *ses, struct f_data_c *f, int a){ if (f =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -