w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

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 }