Intial commit
[profile/ivi/w3m.git] / w3mbookmark.c
1 /* $Id: w3mbookmark.c,v 1.12 2007/05/31 01:19:50 inu Exp $ */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "config.h"
5 #include "Str.h"
6 #include "indep.h"
7 #include "textlist.h"
8 #include "parsetag.h"
9
10 #if LANG == JA
11 /* FIXME: gettextize here */
12 #define BKMARK_TITLE "¥Ö¥Ã¥¯¥Þ¡¼¥¯¤ÎÅÐÏ¿"
13 #define BKMARK_ADD "ÅÐÏ¿"
14 #define DEFAULT_SECTION "̤ʬÎà"
15 #else
16 #define BKMARK_TITLE "Register to my bookmark"
17 #define BKMARK_ADD "ADD"
18 #define DEFAULT_SECTION "Miscellaneous"
19 #endif
20
21 static char *bkmark_src1 =
22     "<html>\n\
23 <head>\n\
24 <title>" BKMARK_TITLE "</title>\n\
25 </head>\n\
26 <body>\n\
27 <h1>" BKMARK_TITLE "</h1>\n\
28 <form method=post action=\"file:///$LIB/" W3MBOOKMARK_CMDNAME "\">\n\
29 <input type=hidden name=mode value=register>\n\
30 <input type=hidden name=bmark value=\"%s\">\n\
31 <input type=hidden name=cookie value=\"%s\">\n\
32 <table cellpadding=0>\n";
33
34 static char *bkmark_src2 =
35     "<tr><td>New&nbsp;Section:<td><input type=text name=newsection size=60>\n\
36 <tr><td>URL:<td><input type=text name=url value=\"%s\" size=60>\n\
37 <tr><td>Title:<td><input type=text name=title value=\"%s\" size=60>\n\
38 <tr><td><input type=submit value=\"" BKMARK_ADD "\">\n\
39 </table>\n\
40 </form>\n\
41 </body>\n\
42 </html>\n";
43
44 #undef FALSE
45 #define FALSE 0
46 #undef TRUE
47 #define TRUE 1
48
49 static char end_section[] =
50     "<!--End of section (do not delete this comment)-->\n";
51
52 static char *Local_cookie = NULL;
53
54 void
55 print_bookmark_panel(char *bmark, char *url, char *title, char *charset)
56 {
57     Str tmp, tmp2;
58     FILE *f;
59     char *p;
60
61     if (charset == NULL) {
62         printf("Content-Type: text/html\n\n");
63     }
64     else {
65         printf("Content-Type: text/html; charset=%s\n\n", charset);
66     }
67     printf(bkmark_src1, html_quote(bmark), html_quote(Local_cookie));
68     if ((f = fopen(bmark, "r")) != NULL) {
69         printf("<tr><td>Section:<td><select name=\"section\">\n");
70         while (tmp = Strfgets(f), tmp->length > 0) {
71             Strremovefirstspaces(tmp);
72             if (Strncasecmp_charp(tmp, "<h2>", 4) == 0) {
73                 p = tmp->ptr + 4;
74                 tmp2 = Strnew();
75                 while (*p && *p != '<')
76                     Strcat_char(tmp2, *p++);
77                 printf("<option value=\"%s\">%s\n", tmp2->ptr,
78                        tmp2->ptr);
79             }
80         }
81         printf("</select>\n");
82     }
83     printf(bkmark_src2, html_quote(url), html_quote(title));
84 }
85
86 /* create new bookmark */
87 static int
88 create_new_bookmark(char *bmark, char *section, char *title, char *url,
89                     char *mode)
90 {
91     FILE *f;
92     f = fopen(bmark, mode);
93     if (f == NULL) {
94         printf("\nCan't open bookmark %s\n", bmark);
95         return FALSE;
96     }
97     else {
98         fprintf(f, "<html><head><title>Bookmarks</title></head>\n");
99         fprintf(f, "<body>\n<h1>Bookmarks</h1>\n");
100         fprintf(f, "<h2>%s</h2>\n<ul>\n", section);
101         fprintf(f, "<li><a href=\"%s\">%s</a>\n", url, title);
102         fprintf(f, end_section);
103         fprintf(f, "</ul>\n</body>\n</html>\n");
104         fclose(f);
105     }
106     return TRUE;
107 }
108
109 int
110 insert_bookmark(char *bmark, struct parsed_tagarg *data)
111 {
112     char *url, *title, *section;
113     FILE *f;
114     TextList *tl = newTextList();
115     int section_found = 0;
116     int bmark_added = 0;
117     Str tmp, section_tmp;
118
119     url = tag_get_value(data, "url");
120     title = tag_get_value(data, "title");
121     section = tag_get_value(data, "newsection");
122     if (section == NULL || *section == '\0')
123         section = tag_get_value(data, "section");
124     if (section == NULL || *section == '\0')
125         section = DEFAULT_SECTION;
126
127     if (url == NULL || *url == '\0' || title == NULL || *title == '\0') {
128         /* Bookmark not added */
129         return FALSE;
130     }
131     url = html_quote(url);
132     title = html_quote(title);
133     section = html_quote(section);
134
135     f = fopen(bmark, "r");
136     if (f == NULL)
137         return create_new_bookmark(bmark, section, title, url, "w");
138
139     section_tmp = Sprintf("<h2>%s</h2>\n", section);
140     for (;;) {
141         tmp = Strfgets(f);
142         if (tmp->length == 0)
143             break;
144         if (Strcasecmp(tmp, section_tmp) == 0)
145             section_found = 1;
146         if (section_found && !bmark_added) {
147             Strremovefirstspaces(tmp);
148             if (Strcmp_charp(tmp, end_section) == 0) {
149                 pushText(tl,
150                          Sprintf("<li><a href=\"%s\">%s</a>\n", url,
151                                  title)->ptr);
152                 bmark_added = 1;
153             }
154         }
155         if (!bmark_added && Strcasecmp_charp(tmp, "</body>\n") == 0) {
156             pushText(tl, Sprintf("<h2>%s</h2>\n<ul>\n", section)->ptr);
157             pushText(tl,
158                      Sprintf("<li><a href=\"%s\">%s</a>\n", url, title)->ptr);
159             pushText(tl, end_section);
160             pushText(tl, "</ul>\n");
161             bmark_added = 1;
162         }
163         pushText(tl, tmp->ptr);
164     }
165     fclose(f);
166     if (!bmark_added) {
167         /* Bookmark not added; perhaps the bookmark file is ill-formed */
168         /* In this case, a new bookmark is appeneded after the bookmark file */
169         return create_new_bookmark(bmark, section, title, url, "a");
170     }
171     f = fopen(bmark, "w");
172     while (tl->nitem) {
173         fputs(popText(tl), f);
174     }
175     fclose(f);
176     return TRUE;
177 }
178
179 int
180 main(int argc, char *argv[], char **envp)
181 {
182     extern char *getenv();
183     char *p;
184     int length;
185     Str qs = NULL;
186     struct parsed_tagarg *cgiarg;
187     char *mode;
188     char *bmark;
189     char *url;
190     char *title;
191     char *charset;
192     char *sent_cookie;
193
194     GC_INIT();
195     p = getenv("REQUEST_METHOD");
196     if (p == NULL || strcasecmp(p, "post"))
197         goto request_err;
198     p = getenv("CONTENT_LENGTH");
199     if (p == NULL || (length = atoi(p)) <= 0)
200         goto request_err;
201
202     qs = Strfgets(stdin);
203     Strchop(qs);
204     if (qs->length != length)
205         goto request_err;
206     cgiarg = cgistr2tagarg(qs->ptr);
207
208     p = getenv("LOCAL_COOKIE_FILE");
209     if (p) {
210         FILE *f = fopen(p, "r");
211         if (f) {
212             Local_cookie = Strfgets(f)->ptr;
213             fclose(f);
214         }
215     }
216     sent_cookie = tag_get_value(cgiarg, "cookie");
217     if (sent_cookie == NULL || Local_cookie == NULL ||
218         strcmp(sent_cookie, Local_cookie) != 0) {
219         /* local cookie doesn't match: It may be an illegal invocation */
220         printf("Content-Type: text/plain\n\n");
221         printf("Local cookie doesn't match: It may be an illegal invocation\n");
222         exit(1);
223     }
224
225     mode = tag_get_value(cgiarg, "mode");
226     bmark = expandPath(tag_get_value(cgiarg, "bmark"));
227     url = tag_get_value(cgiarg, "url");
228     title = tag_get_value(cgiarg, "title");
229     charset = tag_get_value(cgiarg, "charset");
230     if (bmark == NULL || url == NULL)
231         goto request_err;
232     if (mode && !strcmp(mode, "panel")) {
233         if (title == NULL)
234             title = "";
235         print_bookmark_panel(bmark, url, title, charset);
236     }
237     else if (mode && !strcmp(mode, "register")) {
238         printf("Content-Type: text/plain\n");
239         if (insert_bookmark(bmark, cgiarg)) {
240             printf("w3m-control: BACK\n");
241             printf("w3m-control: BACK\n");
242         }
243         printf("\n");
244     }
245     return 0;
246
247   request_err:
248     printf("Content-Type: text/plain\n\n");
249     printf("Incomplete Request: %s\n", qs ? qs->ptr : "(null)");
250     exit(1);
251 }