Intial commit
[profile/ivi/w3m.git] / w3mhelperpanel.c
1 /* $Id: w3mhelperpanel.c,v 1.14 2007/05/31 01:19:50 inu Exp $ */
2 #include <errno.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "config.h"
7 #include "Str.h"
8 #include "indep.h"
9 #include "textlist.h"
10 #include "parsetag.h"
11 #include "myctype.h"
12
13 #if LANG == JA
14 /* FIXME: gettextize here */
15 #define MSG_TITLE               "³°Éô¥Ó¥å¡¼¥¢¤ÎÊÔ½¸"
16 #define MSG_NEW_ENTRY           "¿·µ¬ÅÐÏ¿"
17 #define MSG_TYPE                "¥Ç¡¼¥¿¥¿¥¤¥×"
18 #define MSG_COMMAND             "³°Éô¥³¥Þ¥ó¥É"
19 #define MSG_REGISTER            "ÅÐÏ¿"
20 #define MSG_DELETE              "ºï½ü"
21 #define MSG_DOIT                "¼Â¹Ô"
22 #else                           /* LANG != JA */
23 #define MSG_TITLE               "External Viewers Setup"
24 #define MSG_NEW_ENTRY           "New Entry"
25 #define MSG_TYPE                "Type"
26 #define MSG_COMMAND             "Command"
27 #define MSG_REGISTER            "Register"
28 #define MSG_DELETE              "Delete"
29 #define MSG_DOIT                "Do it"
30 #endif                          /* LANG != JA */
31
32 char *local_cookie;
33
34 void
35 extractMailcapEntry(char *mcap_entry, char **type, char **cmd)
36 {
37     int j;
38
39     while (*mcap_entry && IS_SPACE(*mcap_entry))
40         mcap_entry++;
41     for (j = 0;
42          mcap_entry[j] && mcap_entry[j] != ';' && !IS_SPACE(mcap_entry[j]);
43          j++) ;
44     *type = allocStr(mcap_entry, j);
45     if (mcap_entry[j] == ';')
46         j++;
47     while (mcap_entry[j] && IS_SPACE(mcap_entry[j]))
48         j++;
49     *cmd = allocStr(&mcap_entry[j], -1);
50 }
51
52 static void
53 bye(const char *action, const char *mailcap)
54 {
55     printf("Content-Type: text/plain\n\n%s %s\n", action, mailcap);
56     exit(1);
57 }
58
59 void
60 printMailcapPanel(char *mailcap)
61 {
62     FILE *f;
63     Str tmp;
64     char *type, *viewer;
65
66     if ((f = fopen(mailcap, "rt")) == NULL) {
67         if (errno != ENOENT)
68             bye("Can't open", mailcap);
69
70         if (!(f = fopen(mailcap, "a+")))        /* if $HOME/.mailcap is not found, make it now! */
71             bye("Can't open", mailcap);
72
73         {
74             char *SysMailcap = getenv("SYS_MAILCAP");
75             FILE *s = fopen(SysMailcap ? SysMailcap : "/etc/mailcap", "r");
76             if (s) {
77                 char buffer[256];
78                 while (fgets(buffer, sizeof buffer, s)) /* Copy system mailcap to */
79                     fputs(buffer, f);   /* users' new one         */
80                 fclose(s);
81                 rewind(f);
82             }
83         }
84     }
85 #if LANG == JA
86     /* FIXME: gettextize here */
87     printf("Content-Type: text/html; charset=EUC-JP\n\n");
88 #else
89     printf("Content-Type: text/html\n\n");
90 #endif
91     printf("<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n<h1>%s</h1>\n",
92            MSG_TITLE, MSG_TITLE);
93     printf("<form method=post action=\"file:///$LIB/" W3MHELPERPANEL_CMDNAME
94            "\">\n");
95     printf("<input type=hidden name=mode value=edit>\n");
96     printf("<input type=hidden name=cookie value=\"%s\">\n",
97            html_quote(local_cookie));
98     printf("<table>\n<tr><td>%s:<td>%s=<input type=text name=newtype size=40>\n\
99 <tr><td><td>%s=<input type=text name=newcmd size=40>\n\
100 <tr><td><input type=submit name=submit value=\"%s\">\n</table>\n",
101            MSG_NEW_ENTRY, MSG_TYPE, MSG_COMMAND, MSG_REGISTER);
102     printf("<p><hr width=50%%><p>\n<table border='0' cellpadding='0'>\n\
103 <tr><th align=left><b>%s</b><th><b>%s</b>\n",
104            MSG_TYPE, MSG_COMMAND);
105     while (tmp = Strfgets(f), tmp->length > 0) {
106         if (tmp->ptr[0] == '#')
107             continue;
108         Strchop(tmp);
109         extractMailcapEntry(tmp->ptr, &type, &viewer);
110         printf("<tr valign=top><td>%s<td>%s<td nowrap>", html_quote(type),
111                html_quote(viewer));
112         printf("<input type=checkbox name=delete value=\"%s\">%s\n",
113                html_quote(type), MSG_DELETE);
114     }
115     printf("</table>\n<input type=submit name=submit value=\"%s\">\n</form>\n\
116 </body>\n</html>\n",
117            MSG_DOIT);
118 }
119
120 void
121 editMailcap(char *mailcap, struct parsed_tagarg *args)
122 {
123     TextList *t = newTextList();
124     TextListItem *ti;
125     FILE *f;
126     Str tmp;
127     char *type, *viewer;
128     struct parsed_tagarg *a;
129     int delete_it;
130
131     if ((f = fopen(mailcap, "rt")) == NULL)
132         bye("Can't open", mailcap);
133
134     while (tmp = Strfgets(f), tmp->length > 0) {
135         if (tmp->ptr[0] == '#')
136             continue;
137         Strchop(tmp);
138         extractMailcapEntry(tmp->ptr, &type, &viewer);
139         delete_it = 0;
140         for (a = args; a != NULL; a = a->next) {
141             if (!strcmp(a->arg, "delete") && !strcmp(a->value, type)) {
142                 delete_it = 1;
143                 break;
144             }
145         }
146         if (!delete_it)
147             pushText(t, Sprintf("%s;\t%s\n", type, viewer)->ptr);
148     }
149     type = tag_get_value(args, "newtype");
150     viewer = tag_get_value(args, "newcmd");
151     if (type != NULL && *type != '\0' && viewer != NULL && *viewer != '\0')
152         pushText(t, Sprintf("%s;\t%s\n", type, viewer)->ptr);
153     fclose(f);
154     if ((f = fopen(mailcap, "w")) == NULL)
155         bye("Can't write to", mailcap);
156
157     for (ti = t->first; ti != NULL; ti = ti->next)
158         fputs(ti->ptr, f);
159     fclose(f);
160     printf("Content-Type: text/plain\n");
161     printf("w3m-control: BACK\nw3m-control: BACK\n");
162     printf("w3m-control: REINIT MAILCAP\n");
163 }
164
165 int
166 main(int argc, char *argv[], char **envp)
167 {
168     Str mailcapfile;
169     extern char *getenv();
170     char *p;
171     int length;
172     Str qs = NULL;
173     struct parsed_tagarg *cgiarg;
174     char *mode;
175     char *sent_cookie;
176
177     GC_INIT();
178     p = getenv("REQUEST_METHOD");
179     if (p == NULL || strcasecmp(p, "post"))
180         goto request_err;
181     p = getenv("CONTENT_LENGTH");
182     if (p == NULL || (length = atoi(p)) <= 0)
183         goto request_err;
184
185     qs = Strfgets(stdin);
186     Strchop(qs);
187     if (qs->length != length)
188         goto request_err;
189     cgiarg = cgistr2tagarg(qs->ptr);
190
191     p = getenv("LOCAL_COOKIE_FILE");
192     if (p) {
193         FILE *f = fopen(p, "r");
194         if (f) {
195             local_cookie = Strfgets(f)->ptr;
196             fclose(f);
197         }
198     }
199     sent_cookie = tag_get_value(cgiarg, "cookie");
200     if (local_cookie == NULL || sent_cookie == NULL ||
201         strcmp(local_cookie, sent_cookie) != 0) {
202         /* Local cookie doesn't match */
203         bye("Local cookie doesn't match: It may be an illegal execution", "");
204     }
205
206     mode = tag_get_value(cgiarg, "mode");
207     mailcapfile = Strnew_charp(expandPath(USER_MAILCAP));
208     if (mode && !strcmp(mode, "edit")) {
209         char *referer;
210         /* check if I can edit my mailcap */
211         if ((referer = getenv("HTTP_REFERER")) != NULL) {
212             if (strncmp(referer, "file://", 7) != 0 &&
213                 strncmp(referer, "exec://", 7) != 0) {
214                 /* referer is not file: nor exec: */
215                 bye("It may be an illegal execution\n referer=", referer);
216             }
217         }
218         /* edit mailcap */
219         editMailcap(mailcapfile->ptr, cgiarg);
220     }
221     else {
222         /* initial panel */
223         printMailcapPanel(mailcapfile->ptr);
224     }
225     return 0;
226
227   request_err:
228     bye("Incomplete Request:", qs ? qs->ptr : "(null)");
229     exit(1);
230 }