commit a9e04cb8a70ee802cac6f0e3a2e8a9c2caff2342
parent fb2bcf6c3f275f4584bd7a0e331f69388a1e4e13
Author: ukai <ukai>
Date: Tue, 5 Nov 2002 15:56:11 +0000
[w3m-dev 03373] setting form on loading
* config.h.dist (PRE_FORM_FILE): added
* configure (PRE_FORM_FILE): added
* etc.c (openPasswdFile): define by openSecretFile()
(openSecretFile): renamed, not static
* file.c (loadGeneralFile): preFOrmUpdateBuffer()
* fm.h (Buffer): add submit
(pre_form_file): added
* form.c (struct pre_form_item): added
(struct pre_form): added
(next_token): added
(PreForm): added
(add_pre_form): added
(add_pre_form_item): added
(loadPreForm): added
(preFormUpdateBuffer): added
* frame.c (renderFrame): add preFormUpdateBuffer()
* main.c (MAIN): buf->submit check
* proto.h (preFormUpdateBuffer): added
(openSecretFile): added
(loadPreForm): added
* rc.c (sync_with_option): add loadPreForm()
From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
Diffstat:
11 files changed, 237 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,5 +1,30 @@
2002-11-06 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
+ * [w3m-dev 03373] setting form on loading
+ * config.h.dist (PRE_FORM_FILE): added
+ * configure (PRE_FORM_FILE): added
+ * etc.c (openPasswdFile): define by openSecretFile()
+ (openSecretFile): renamed, not static
+ * file.c (loadGeneralFile): preFOrmUpdateBuffer()
+ * fm.h (Buffer): add submit
+ (pre_form_file): added
+ * form.c (struct pre_form_item): added
+ (struct pre_form): added
+ (next_token): added
+ (PreForm): added
+ (add_pre_form): added
+ (add_pre_form_item): added
+ (loadPreForm): added
+ (preFormUpdateBuffer): added
+ * frame.c (renderFrame): add preFormUpdateBuffer()
+ * main.c (MAIN): buf->submit check
+ * proto.h (preFormUpdateBuffer): added
+ (openSecretFile): added
+ (loadPreForm): added
+ * rc.c (sync_with_option): add loadPreForm()
+
+2002-11-06 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
+
* [w3m-dev 03371] segmentation fault by large complex table.
* table.c (bsearch_2short): indexarry char to short
(bsearch_double): ditto
diff --git a/config.h.dist b/config.h.dist
@@ -167,6 +167,7 @@ MODEL=Linux.i686-monster-ja
#define HISTORY_FILE "history"
#define PASSWD_FILE RC_DIR "/passwd"
+#define PRE_FORM_FILE RC_DIR "/pre_form"
#define USER_MAILCAP RC_DIR "/mailcap"
#define SYS_MAILCAP "/etc/mailcap"
#define USER_MIMETYPES "~/.mime.types"
diff --git a/configure b/configure
@@ -2389,6 +2389,7 @@ $def_use_xface
#define HISTORY_FILE "history"
#define PASSWD_FILE RC_DIR "/passwd"
+#define PRE_FORM_FILE RC_DIR "/pre_form"
#define USER_MAILCAP RC_DIR "/mailcap"
#define SYS_MAILCAP "/etc/mailcap"
#define USER_MIMETYPES "~/.mime.types"
diff --git a/etc.c b/etc.c
@@ -1034,9 +1034,10 @@ parsePasswd(FILE * fp, int netrc)
}
#define PASS_IS_READABLE_MSG "SECURITY NOTE: passwd file must not be accessible by others"
+#define openPasswdFile(fname) openSecretFile(fname, PASS_IS_READABLE_MSG)
-static FILE *
-openPasswdFile(char *fname)
+FILE *
+openSecretFile(char *fname, char *error_msg)
{
struct stat st;
if (fname == NULL)
@@ -1049,11 +1050,11 @@ openPasswdFile(char *fname)
*/
if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
if (fmInitialized) {
- message(PASS_IS_READABLE_MSG, 0, 0);
+ message(error_msg, 0, 0);
refresh();
}
else {
- fputs(PASS_IS_READABLE_MSG, stderr);
+ fputs(error_msg, stderr);
fputc('\n', stderr);
}
sleep(2);
diff --git a/file.c b/file.c
@@ -2022,6 +2022,7 @@ loadGeneralFile(char *path, ParsedURL *volatile current, char *referer,
if (fmInitialized)
term_raw();
signal(SIGINT, prevtrap);
+ preFormUpdateBuffer(b);
return b;
}
diff --git a/fm.h b/fm.h
@@ -438,6 +438,7 @@ typedef struct _Buffer {
#endif
char image_flag;
char need_reshape;
+ Anchor *submit;
} Buffer;
@@ -842,6 +843,7 @@ global char *ExtBrowser2 init(NULL);
global char *ExtBrowser3 init(NULL);
global int BackgroundExtViewer init(TRUE);
global char *passwd_file init(PASSWD_FILE);
+global char *pre_form_file init(PRE_FORM_FILE);
global char *ftppasswd init(NULL);
#ifdef FTPPASS_HOSTNAMEGEN
global int ftppass_hostnamegen init(TRUE);
diff --git a/form.c b/form.c
@@ -655,3 +655,193 @@ form_write_from_file(FILE * f, char *boundary, char *name, char *filename,
write_end:
fprintf(f, "\r\n");
}
+
+struct pre_form_item {
+ int type;
+ char *name;
+ char *value;
+ int checked;
+ struct pre_form_item *next;
+};
+
+struct pre_form {
+ ParsedURL url;
+ char *action;
+ struct pre_form_item *item;
+ struct pre_form *next;
+};
+
+static Str next_token(Str arg);
+static struct pre_form *PreForm = NULL;
+
+static struct pre_form *
+add_pre_form(struct pre_form *prev, char *url, char *action)
+{
+ struct pre_form *new;
+
+ if (prev)
+ new = prev->next = New(struct pre_form);
+ else
+ new = PreForm = New(struct pre_form);
+ parseURL2(url, &new->url, NULL);
+ if (action && *action)
+ new->action = action;
+ else
+ new->action = NULL;
+ new->item = NULL;
+ new->next = NULL;
+ return new;
+}
+
+static struct pre_form_item *
+add_pre_form_item(struct pre_form *pf, struct pre_form_item *prev, int type,
+ char *name, char *value, char *checked)
+{
+ struct pre_form_item *new;
+
+ if (!pf)
+ return NULL;
+ if (prev)
+ new = prev->next = New(struct pre_form_item);
+ else
+ new = pf->item = New(struct pre_form_item);
+ new->type = type;
+ new->name = name;
+ new->value = value;
+ if (checked && *checked && (!strcmp(checked, "0") ||
+ strcasecmp(checked, "off") || !strcasecmp(checked, "no")))
+ new->checked = 0;
+ else
+ new->checked = 1;
+ new->next = NULL;
+ return new;
+}
+
+/*
+url <url> [<action>]
+text <name> <value>
+file <name> <value>
+passwd <name> <value>
+checkbox <name> <value> [<checked>]
+radio <name> <value>
+submit [<name>]
+*/
+
+#define FILE_IS_READABLE_MSG "SECURITY NOTE: file %s must not be accessible by others"
+
+void
+loadPreForm(void)
+{
+ FILE *fp;
+ Str line = NULL;
+ struct pre_form *pf = NULL;
+ struct pre_form_item *pi = NULL;
+
+ fp = openSecretFile(pre_form_file, Sprintf(FILE_IS_READABLE_MSG,
+ pre_form_file)->ptr);
+ if (fp == NULL) {
+ PreForm = NULL;
+ return;
+ }
+ while (1) {
+ int type = 0;
+ char *p, *s, *arg;
+
+ line = Strfgets(fp);
+ if (line->length == 0)
+ break;
+ Strchop(line);
+ Strremovefirstspaces(line);
+ p = line->ptr;
+ if (*p == '#' || *p == '\0')
+ continue; /* comment or empty line */
+ s = getWord(&p);
+ arg = getWord(&p);
+
+ if (!strcmp(s, "url")) {
+ if (!arg || !*arg)
+ continue;
+ p = getQWord(&p);
+ pf = add_pre_form(pf, arg, p);
+ pi = pf->item;
+ continue;
+ }
+ if (!pf)
+ continue;
+ if (!strcmp(s, "text"))
+ type = FORM_INPUT_TEXT;
+ else if (!strcmp(s, "file"))
+ type = FORM_INPUT_FILE;
+ else if (!strcmp(s, "passwd") || !strcmp(s, "password"))
+ type = FORM_INPUT_PASSWORD;
+ else if (!strcmp(s, "checkbox"))
+ type = FORM_INPUT_CHECKBOX;
+ else if (!strcmp(s, "radio"))
+ type = FORM_INPUT_RADIO;
+ else if (!strcmp(s, "submit"))
+ type = FORM_INPUT_SUBMIT;
+ else
+ continue;
+ s = getQWord(&p);
+ pi = add_pre_form_item(pf, pi, type, arg, s, getQWord(&p));
+ }
+ fclose(fp);
+}
+
+void
+preFormUpdateBuffer(Buffer *buf)
+{
+ struct pre_form *pf;
+ struct pre_form_item *pi;
+ int i;
+ Anchor *a;
+ FormList *fl;
+ FormItemList *fi;
+
+ if (!buf || !buf->formitem || !PreForm)
+ return;
+
+ for (pf = PreForm; pf; pf = pf->next) {
+ if (Strcmp(parsedURL2Str(&buf->currentURL), parsedURL2Str(&pf->url)))
+ continue;
+ for (i = 0; i < buf->formitem->nanchor; i++) {
+ a = &buf->formitem->anchors[i];
+ fi = (FormItemList *)a->url;
+ fl = fi->parent;
+ if (pf->action && (!fl->action || Strcmp_charp(fl->action, pf->action)))
+ continue;
+ for (pi = pf->item; pi; pi = pi->next) {
+ if (pi->type != fi->type)
+ continue;
+ if (pi->type == FORM_INPUT_SUBMIT) {
+ if (!pi->name || !*pi->name ||
+ (fi->name && !Strcmp_charp(fi->name, pi->name)))
+ buf->submit = a;
+ continue;
+ }
+ if (!pi->name || !fi->name || Strcmp_charp(fi->name, pi->name))
+ continue;
+ switch (pi->type) {
+ case FORM_INPUT_TEXT:
+ case FORM_INPUT_FILE:
+ case FORM_INPUT_PASSWORD:
+ fi->value = Strnew_charp(pi->value);
+ formUpdateBuffer(a, buf, fi);
+ break;
+ case FORM_INPUT_CHECKBOX:
+ if (pi->value && fi->value &&
+ !Strcmp_charp(fi->value, pi->value)) {
+ fi->checked = pi->checked;
+ formUpdateBuffer(a, buf, fi);
+ }
+ break;
+ case FORM_INPUT_RADIO:
+ if (pi->value && fi->value &&
+ !Strcmp_charp(fi->value, pi->value))
+ formRecheckRadio(a, buf, fi);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/frame.c b/frame.c
@@ -790,6 +790,7 @@ renderFrame(Buffer *Cbuf, int force_reload)
buf->document_code = Cbuf->document_code;
#endif
copyParsedURL(&buf->currentURL, &Cbuf->currentURL);
+ preFormUpdateBuffer(buf);
return buf;
}
diff --git a/main.c b/main.c
@@ -949,6 +949,13 @@ MAIN(int argc, char **argv, char **envp)
}
onA();
for (;;) {
+ if (Currentbuf->submit) {
+ Anchor *a = Currentbuf->submit;
+ Currentbuf->submit = NULL;
+ gotoLine(Currentbuf, a->start.line);
+ Currentbuf->pos = a->start.pos;
+ _followForm(TRUE);
+ }
/* event processing */
if (n_event_queue > 0) {
for (i = 0; i < n_event_queue; i++) {
diff --git a/proto.h b/proto.h
@@ -331,6 +331,7 @@ extern int formtype(char *typestr);
extern void formRecheckRadio(Anchor *a, Buffer *buf, FormItemList *form);
extern void formResetBuffer(Buffer *buf, AnchorList *formitem);
extern void formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form);
+extern void preFormUpdateBuffer(Buffer *buf);
extern Str textfieldrep(Str s, int width);
extern void input_textarea(FormItemList *fi);
extern void do_internal(char *action, char *data);
@@ -520,7 +521,9 @@ extern Buffer *dirBuffer(char *dirname);
extern void set_environ(char *var, char *value);
extern FILE *localcgi_post(char *, char *, FormList *, char *);
extern FILE *localcgi_get(char *, char *, char *);
+extern FILE *openSecretFile(char *fname, char *error_msg);
extern void loadPasswd(void);
+extern void loadPreForm(void);
extern int find_auth_user_passwd(ParsedURL *pu, char *realm,
Str *uname, Str *pwd, int is_proxy);
extern Str find_auth_cookie(char *host, int port, char *file, char *realm);
diff --git a/rc.c b/rc.c
@@ -1240,6 +1240,7 @@ sync_with_option(void)
displayImage = FALSE; /* XXX */
#endif
loadPasswd();
+ loadPreForm();
if (AcceptLang == NULL || *AcceptLang == '\0') {
#if LANG == JA