OSDN Git Service

replace implementation to using timfparser_t.
[bbk/bchan.git] / src / postres.c
1 /*
2  * postres.c
3  *
4  * Copyright (c) 2009-2010 project bchan
5  *
6  * This software is provided 'as-is', without any express or implied
7  * warranty. In no event will the authors be held liable for any damages
8  * arising from the use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software. If you use this software
16  *    in a product, an acknowledgment in the product documentation would be
17  *    appreciated but is not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  *    misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source
23  *    distribution.
24  *
25  */
26
27 #include        <basic.h>
28 #include        <bstdlib.h>
29 #include        <bstdio.h>
30 #include        <bctype.h>
31 #include        <errcode.h>
32 #include        <tstring.h>
33 #include        <tcode.h>
34 #include        <btron/btron.h>
35 #include        <btron/hmi.h>
36 #include        <btron/tf.h>
37
38 #include    "postres.h"
39 #include    "sjisstring.h"
40 #include    "tadimf.h"
41
42 LOCAL W postresdata_appendstring(TC **dest, W *dest_len, TC *str, W len)
43 {
44         *dest = realloc(*dest, sizeof(TC)*(*dest_len + len + 1));
45         if (*dest == NULL) {
46                 *dest_len = 0;
47                 return -1;
48         }
49         memcpy((*dest)+*dest_len, str, sizeof(TC)*len);
50         *dest_len += len;
51         (*dest)[*dest_len] = TNULL;
52
53         return 0;
54 }
55
56 #define POSTRESDATA_VALID_FROM 1
57 #define POSTRESDATA_VALID_mail 2
58 LOCAL tctokenchecker_valuetuple_t postreadata_nametable[] = {
59   {(TC[]){TK_F, TK_R, TK_O, TK_M, TNULL}, POSTRESDATA_VALID_FROM},
60   {(TC[]){TK_m, TK_a, TK_i, TK_l, TNULL}, POSTRESDATA_VALID_mail},
61 };
62
63 LOCAL W postresdata_readtad(postresdata_t *post, TC *str, W len)
64 {
65         timfparser_t timf;
66         TIMFPARSER_RESULT_T cont;
67         UB *bin;
68         W rcvlen, val, err = 0;
69
70         timfparser_initialize(&timf, postreadata_nametable, 2, str, len);
71
72         for (;;) {
73                 cont = timfparser_next(&timf, &val, &bin, &rcvlen);
74                 if (cont == TIMFPARSER_RESULT_HEADERVALUE) {
75                         if (val == POSTRESDATA_VALID_FROM) {
76                                 err = postresdata_appendstring(&(post->from), &(post->from_len), (TC*)bin, rcvlen/sizeof(TC));
77                                 if (err < 0) {
78                                         break;
79                                 }
80                         } else if (val == POSTRESDATA_VALID_mail) {
81                                 err = postresdata_appendstring(&(post->mail), &(post->mail_len), (TC*)bin, rcvlen/sizeof(TC));
82                                 if (err < 0) {
83                                         break;
84                                 }
85                         }
86                 } else if (cont == TIMFPARSER_RESULT_BODY) {
87                         err = postresdata_appendstring(&(post->message), &(post->message_len), (TC*)bin, rcvlen/sizeof(TC));
88                         if (err < 0) {
89                                 break;
90                         }
91                 } else if (cont == TIMFPARSER_RESULT_END) {
92                         break;
93                 } else {
94                         break;
95                 }
96         }
97
98         timfparser_finalize(&timf);
99
100         return err;
101 }
102
103 EXPORT W postresdata_readfile(postresdata_t *post, VLINK *vlnk)
104 {
105         W fd, err, size;
106         UB *buf;
107
108         fd = opn_fil((LINK*)vlnk, F_READ, NULL);
109         if (fd < 0) {
110                 return fd;
111         }
112         err = fnd_rec(fd, F_TOPEND, RM_TADDATA, 0, NULL);
113         if (err < 0) {
114                 cls_fil(fd);
115                 return err;
116         }
117         err = rea_rec(fd, 0, NULL, 0, &size, NULL);
118         if (err < 0) {
119                 cls_fil(fd);
120                 return err;
121         }
122         buf = malloc(size*sizeof(UB));
123         if (buf == NULL) {
124                 cls_fil(fd);
125                 return -1; /* TODO */
126         }
127         err = rea_rec(fd, 0, buf, size, NULL, NULL);
128         if (err < 0) {
129                 free(buf);
130                 cls_fil(fd);
131                 return err;
132         }
133         cls_fil(fd);
134
135         err =  postresdata_readtad(post, (TC *)buf, size/sizeof(TC));
136
137         free(buf);
138
139         return err;
140 }
141
142 LOCAL W postresdata_appendasciistring(UB **dest, W *dest_len, UB *str, W len)
143 {
144         return sjstring_appendasciistring(dest, dest_len, str, len);
145 }
146
147 LOCAL W postesdata_appendconvertedstring(TF_CTX *ctx, UB **dest, W *dlen, TC *src, W slen)
148 {
149         UB *buf;
150         W buf_len, err;
151
152         if (slen == 0) {
153                 return 0;
154         }
155
156         err = tf_tcstostr(*ctx, src, slen, 0, TF_ATTR_START, NULL, &buf_len);
157         if (err < 0) {
158                 return err;
159         }
160         buf = malloc(buf_len);
161         if (buf == NULL) {
162                 return -1; /* TODO */
163         }
164         err = tf_tcstostr(*ctx, src, slen, 0, TF_ATTR_START, buf, &buf_len);
165         if (err < 0) {
166                 return err;
167         }
168
169         err = sjstring_appendurlencodestring(dest, dlen, buf, buf_len);
170         free(buf);
171
172         return err;
173 }
174
175 LOCAL W postesdata_appendUWstring(UB **dest, W *dlen, UW n)
176 {
177         return sjstring_appendUWstring(dest, dlen, n);
178 }
179
180 EXPORT W postresdata_genrequestbody(postresdata_t *post, UB *board, W board_len, UB *thread, W thread_len, STIME time, UB **body, W *body_len)
181 {
182         TF_CTX ctx;
183         UB *buf_ret = NULL;
184         W err, ctx_id, buf_ret_len = 0;
185         UB name_bbs[] = "bbs=";
186         UB name_key[] = "&key=";
187         UB name_time[] = "&time=";
188         UB name_FROM[] = "&FROM=";
189         UB name_mail[] = "&mail=";
190         UB name_MESSAGE[] = "&MESSAGE=";
191         UB name_submit[] = "&submit=%8F%91%82%AB%8D%9E%82%DE";
192
193         err = tf_open_ctx(&ctx);
194         if (err < 0) {
195                 return err;
196         }
197         ctx_id = tf_to_id(TF_ID_PROFSET_CONVERTTO, "Shift_JIS");
198         if (ctx_id < 0) {
199                 tf_close_ctx(ctx);
200                 return err;
201         }
202         err = tf_set_profile(ctx, ctx_id);
203         if (err < 0) {
204                 tf_close_ctx(ctx);
205                 return err;
206         }
207
208         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_bbs, strlen(name_bbs));
209         if (err < 0) {
210                 free(buf_ret);
211                 return err;
212         }
213         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, board, board_len);
214         if (err < 0) {
215                 free(buf_ret);
216                 return err;
217         }
218         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_key, strlen(name_key));
219         if (err < 0) {
220                 free(buf_ret);
221                 return err;
222         }
223         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, thread, thread_len);
224         if (err < 0) {
225                 free(buf_ret);
226                 return err;
227         }
228         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_time, strlen(name_time));
229         if (err < 0) {
230                 free(buf_ret);
231                 return err;
232         }
233         err = postesdata_appendUWstring(&buf_ret, &buf_ret_len, time + 473385600);
234         if (err < 0) {
235                 free(buf_ret);
236                 return err;
237         }
238         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_FROM, strlen(name_FROM));
239         if (err < 0) {
240                 free(buf_ret);
241                 return err;
242         }
243         err = postesdata_appendconvertedstring(&ctx, &buf_ret, &buf_ret_len, post->from, post->from_len);
244         if (err < 0) {
245                 free(buf_ret);
246                 return err;
247         }
248         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_mail, strlen(name_mail));
249         if (err < 0) {
250                 free(buf_ret);
251                 return err;
252         }
253         err = postesdata_appendconvertedstring(&ctx, &buf_ret, &buf_ret_len, post->mail, post->mail_len);
254         if (err < 0) {
255                 free(buf_ret);
256                 return err;
257         }
258         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_MESSAGE, strlen(name_MESSAGE));
259         if (err < 0) {
260                 free(buf_ret);
261                 return err;
262         }
263         err = postesdata_appendconvertedstring(&ctx, &buf_ret, &buf_ret_len, post->message, post->message_len);
264         if (err < 0) {
265                 free(buf_ret);
266                 return err;
267         }
268         err = postresdata_appendasciistring(&buf_ret, &buf_ret_len, name_submit, strlen(name_submit));
269         if (err < 0) {
270                 free(buf_ret);
271                 return err;
272         }
273
274         tf_close_ctx(ctx);
275
276         *body = buf_ret;
277         *body_len = buf_ret_len;
278
279         return 0;
280 }
281
282 EXPORT postresdata_t* postresdata_new()
283 {
284         postresdata_t *post;
285
286         post = (postresdata_t*)malloc(sizeof(postresdata_t));
287         if (post == NULL) {
288                 return NULL;
289         }
290         post->from = NULL;
291         post->from_len = 0;
292         post->mail = NULL;
293         post->mail_len = 0;
294         post->message = NULL;
295         post->message_len = 0;
296
297         return post;
298 }
299
300 EXPORT VOID postresdata_delete(postresdata_t *post)
301 {
302         if (post->message != NULL) {
303                 free(post->message);
304         }
305         if (post->mail != NULL) {
306                 free(post->mail);
307         }
308         if (post->from != NULL) {
309                 free(post->message);
310         }
311         free(post);
312 }