w3mhelperpanel.c (6245B)
1 /* $Id$ */ 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 }