]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/mothra/forms.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / mothra / forms.c
index 885de18ac16ebfacc55eb2bba01836e45b631b53..90cfe4683699429d1df4bfdedab1b8b924e67485 100644 (file)
@@ -72,7 +72,7 @@ char *selgen(Panel *, int);
 char *nullgen(Panel *, int);
 Field *newfield(Form *form){
        Field *f;
-       f=emallocz(sizeof(Field), 1);
+       f=emalloc(sizeof(Field));
        if(form->efields==0)
                form->fields=f;
        else
@@ -99,11 +99,11 @@ void rdform(Hglob *g){
                        htmlerror(g->name, g->lineno, "nested forms illegal\n");
                        break;
                }
-               g->form=emallocz(sizeof(Form), 1);
+               g->form=emalloc(sizeof(Form));
                s=pl_getattr(g->attr, "action");
-               g->form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
+               g->form->action=strdup((s && *s) ? s : g->dst->url->fullname);
                s=pl_getattr(g->attr, "method");
-               if(s==0)
+               if(s==0 || *s==0)
                        g->form->method=GET;
                else if(cistrcmp(s, "post")==0)
                        g->form->method=POST;
@@ -120,19 +120,24 @@ void rdform(Hglob *g){
 
                g->form->next = g->dst->form;
                g->dst->form = g->form;
-
                break;
        case Tag_input:
        case Tag_button:
                if(g->form==0){
-               BadTag:
-                       htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n",
-                               tag[g->tag].name);
-                       break;
-               }
-               f=newfield(g->form);
+                       /* no form, assume link button */
+                       form = emalloc(sizeof(Form));   
+                       form->method = 0;
+                       form->fields = 0;
+                       form->efields = 0;
+                       if(g->state->link[0])
+                               form->action = strdup(g->state->link);
+                       form->next = g->dst->form;
+                       g->dst->form = form;
+                       f=newfield(form);
+               } else
+                       f=newfield(g->form);
                s=pl_getattr(g->attr, "name");
-               if(s==0)
+               if(s==0 || *s == 0)
                        f->name=0;
                else
                        f->name=strdup(s);
@@ -143,12 +148,12 @@ void rdform(Hglob *g){
                        f->value=strdup(s);
                f->checked=pl_hasattr(g->attr, "checked");
                s=pl_getattr(g->attr, "size");
-               if(s==0)
+               if(s==0 || *s==0)
                        f->size=20;
                else
                        f->size=atoi(s);
                s=pl_getattr(g->attr, "maxlength");
-               if(s==0)
+               if(s==0 || *s==0)
                        f->maxlength=0x3fffffff;
                else
                        f->maxlength=atoi(s);
@@ -164,10 +169,27 @@ void rdform(Hglob *g){
                        f->type=RADIO;
                else if(cistrcmp(s, "submit")==0)
                        f->type=SUBMIT;
+               else if(cistrcmp(s, "image")==0){
+                       f->type=SUBMIT;
+                       s=pl_getattr(g->attr, "src");
+                       if(s && *s)
+                               nstrcpy(g->state->image, s, sizeof(g->state->image));
+                       s=pl_getattr(g->attr, "width");
+                       if(s && *s)
+                               g->state->width=strtolength(g, HORIZ, s);
+                       s=pl_getattr(g->attr, "height");
+                       if(s && *s)
+                               g->state->height=strtolength(g, VERT, s);
+                       s=pl_getattr(g->attr, "alt");
+                       if(s==0 || *s == 0) s = f->value;
+                       pl_htmloutput(g, g->nsp, s, f);
+                       g->state->image[0] = 0;
+                       g->state->width=0;
+                       g->state->height=0;
+                       break;
+               }
                else if(cistrcmp(s, "button")==0)
                        f->type=BUTTON;
-               else if(cistrcmp(s, "image")==0)
-                       f->type=FILE;
                else if(cistrcmp(s, "file")==0)
                        f->type=FILE;
                else if(cistrcmp(s, "reset")==0)
@@ -178,7 +200,6 @@ void rdform(Hglob *g){
                        f->type=TYPEIN;
                        if(cistrcmp(s, "password")==0)
                                f->type=PASSWD;
-
                        s=f->name;
                        if(s && cistrcmp(s, "isindex")==0)
                                f->type=INDEX;
@@ -203,23 +224,23 @@ void rdform(Hglob *g){
                        pl_htmloutput(g, g->nsp, f->value[0]?f->value:"blank field", f);
                break;
        case Tag_select:
-               if(g->form==0) goto BadTag;
+               if(g->form==0){
+               BadTag:
+                       htmlerror(g->name, g->lineno, "<%s> not in form, ignored\n",
+                               tag[g->tag].name);
+                       break;
+               }
                f=newfield(g->form);
                s=pl_getattr(g->attr, "name");
-               if(s==0){
+               if(s==0 || *s==0){
                        f->name=strdup("select");
                        htmlerror(g->name, g->lineno, "select has no name=\n");
                }
                else
                        f->name=strdup(s);
-               s=pl_getattr(g->attr, "size");
-               if(s==0) f->size=4;
-               else{
-                       f->size=atoi(s);
-                       if(f->size<=0) f->size=1;
-               }
                f->multiple=pl_hasattr(g->attr, "multiple");
                f->type=SELECT;
+               f->size=0;
                f->options=0;
                g->text=g->token;
                g->tp=g->text;
@@ -228,7 +249,9 @@ void rdform(Hglob *g){
        case Tag_option:
                if(g->form==0) goto BadTag;
                if((f=g->form->efields)==0) goto BadTag;
-               o=emallocz(sizeof(Option), 1);
+               if(f->size<8)
+                       f->size++;
+               o=emalloc(sizeof(Option));
                for(op=&f->options;*op;op=&(*op)->next);
                *op=o;
                o->next=0;
@@ -251,16 +274,16 @@ void rdform(Hglob *g){
                if(g->form==0) goto BadTag;
                f=newfield(g->form);
                s=pl_getattr(g->attr, "name");
-               if(s==0){
+               if(s==0 || *s==0){
                        f->name=strdup("enter text");
                        htmlerror(g->name, g->lineno, "select has no name=\n");
                }
                else
                        f->name=strdup(s);
                s=pl_getattr(g->attr, "rows");
-               f->rows=s?atoi(s):8;
+               f->rows=(s && *s)?atoi(s):8;
                s=pl_getattr(g->attr, "cols");
-               f->cols=s?atoi(s):30;
+               f->cols=(s && *s)?atoi(s):30;
                f->type=TEXTWIN;
                /* suck up initial text */
                pl_htmloutput(g, g->nsp, f->name, f);
@@ -275,7 +298,7 @@ void rdform(Hglob *g){
                form->fields=0;
                form->efields=0;
                s=pl_getattr(g->attr, "action");
-               form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
+               form->action=strdup((s && *s) ? s : g->dst->url->fullname);
                form->method=GET;
                form->fields=0;
                f=newfield(form);
@@ -371,6 +394,8 @@ void mkfieldpanel(Rtext *t){
                f->p=plbutton(0, 0, f->value[0]?f->value:"file", h_fileinput);
                break;
        case SELECT:
+               if(f->size <= 0)
+                       f->size=1;
                f->pulldown=plgroup(0,0);
                scrl=plscrollbar(f->pulldown, PACKW|FILLY);
                win=pllist(f->pulldown, PACKN, nullgen, f->size, h_select);
@@ -385,8 +410,7 @@ void mkfieldpanel(Rtext *t){
                f->p=plframe(0,0);
                pllabel(f->p, PACKN|FILLX, f->name);
                scrl=plscrollbar(f->p, PACKW|FILLY);
-               f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height),
-                       0, 0, 0);
+               f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), 0, 0, 0);
                f->textwin->userp=f;
                plscroll(f->textwin, 0, scrl);
                break;
@@ -399,7 +423,7 @@ void mkfieldpanel(Rtext *t){
                free(t->text);
                t->text=0;
                t->p=f->p;
-               t->hot=1;
+               t->flags|=PL_HOT;
        }
 }
 void h_checkinput(Panel *p, int, int v){
@@ -440,6 +464,13 @@ void h_resetinput(Panel *p, int){
        case PASSWD:
                plinitentry(f->p, USERFL, f->size*chrwidth, f->value, 0);
                break;
+       case FILE:
+               free(f->value);
+               f->value=strdup("");
+               if(f->p==nil) break;
+               f->p->state=0;
+               pldraw(f->p, screen);
+               break;
        case CHECK:
        case RADIO:
                f->state=f->checked;
@@ -452,8 +483,15 @@ void h_resetinput(Panel *p, int){
        }
        pldraw(text, screen);
 }
+
 void h_buttoninput(Panel *p, int){
+       Field *f;
+
+       f = p->userp;
+       if(f && f->form && f->form->method != POST && f->form->action)
+               geturl(f->form->action, -1, 0, 0);
 }
+
 void h_fileinput(Panel *p, int){
        char name[NNAME];
        Field *f;
@@ -506,17 +544,17 @@ void mencodeform(Form *form, int fd){
                break;
        case CHECK:
        case RADIO:
+       case SUBMIT:
                if(!f->state) break;
        case HIDDEN:
                if(f->name==0 || f->value==0)
-                       continue;
+                       break;
                fprint(fd, "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s",
                        sep, f->name, f->value);
                sep = "\r\n--" BOUNDARY;
                break;
        case SELECT:
-               if(f->name==0)
-                       continue;
+               if(f->name==0) break;
                for(o=f->options;o;o=o->next)
                        if(o->selected && o->value){
                                fprint(fd, "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s",
@@ -525,13 +563,12 @@ void mencodeform(Form *form, int fd){
                        }
                break;
        case TEXTWIN:
-               if(f->name==0)
-                       continue;
+               if(f->name==0) break;
                n=plelen(f->textwin);
                rp=pleget(f->textwin);
                p=b=malloc(UTFmax*n+1);
                if(b == nil)
-                       continue;
+                       break;
                while(n > 0){
                        p += runetochar(p, rp);
                        rp++;
@@ -545,13 +582,13 @@ void mencodeform(Form *form, int fd){
                break;
        case FILE:
                if(f->name==0 || f->value[0]==0)
-                       continue;
+                       break;
                if(p = strrchr(f->value, '/'))
                        p++;
                if(p == 0 || *p == 0)
                        p = f->value;
                if((b = malloc(nb = 8192)) == nil)
-                       continue;
+                       break;
                if((ifd = open(f->value, OREAD)) >= 0){
                        if(filetype(ifd, b, nb) < 0)
                                strcpy(b, "application/octet-stream");
@@ -589,16 +626,16 @@ void uencodeform(Form *form, int fd){
                break;
        case CHECK:
        case RADIO:
+       case SUBMIT:
                if(!f->state) break;
        case HIDDEN:
                if(f->name==0 || f->value==0)
-                       continue;
+                       break;
                fprint(fd, "%s%U=%U", sep, f->name, f->value);
                sep = "&";
                break;
        case SELECT:
-               if(f->name==0)
-                       continue;
+               if(f->name==0) break;
                for(o=f->options;o;o=o->next)
                        if(o->selected && o->value){
                                fprint(fd, "%s%U=%U", sep, f->name, o->value);
@@ -606,13 +643,12 @@ void uencodeform(Form *form, int fd){
                        }
                break;
        case TEXTWIN:
-               if(f->name==0)
-                       continue;
+               if(f->name==0) break;
                n=plelen(f->textwin);
                rp=pleget(f->textwin);
                p=b=malloc(UTFmax*n+1);
                if(b == nil)
-                       continue;
+                       break;
                while(n > 0){
                        p += runetochar(p, rp);
                        rp++;
@@ -629,14 +665,27 @@ void uencodeform(Form *form, int fd){
 void h_submitinput(Panel *p, int){
        char buf[NNAME];
        Form *form;
+       Field *f;
        int n, fd;
 
-       form=((Field *)p->userp)->form;
-       if(form->method==GET){
+       f = p->userp;
+       form=f->form;
+       for(f=form->fields;f;f=f->next)
+               if(f->type==SUBMIT)
+                       f->state = (f->p == p);
+
+       switch(form->method){
+       case GET:
                strcpy(buf, "/tmp/mfXXXXXXXXXXX");
                fd = create(mktemp(buf), ORDWR|ORCLOSE, 0600);
-       } else
+               break;
+       case POST:
                fd = urlpost(selurl(form->action), form->ctype);
+               break;
+       default:
+               return;
+       }
+
        if(fd < 0){
                message("submit: %r");
                return;
@@ -652,7 +701,6 @@ void h_submitinput(Panel *p, int){
                        return;
                }
                buf[n] = 0;
-               if(debug)fprint(2, "GET %s\n", buf);
                geturl(buf, -1, 0, 0);
        } else {
                /* only set for multipart/form-data */
@@ -660,7 +708,6 @@ void h_submitinput(Panel *p, int){
                        mencodeform(form, fd);
                else
                        uencodeform(form, fd);
-               if(debug)fprint(2, "POST %s\n", form->action);
                geturl(form->action, fd, 0, 0);
        }
 }