Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

test_mime.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * test_mime.c: A simple program for testing the mime parser
00059  *
00060  * We add carriage returs to the source, so that output of some editors are 
00061  * acceptable and remove them from component files, in case someone likes to 
00062  * compile them (come on, this is only a test program).
00063  * We panic on errors, so that this function can be used by a shell script
00064  * for testing purposes.
00065  *
00066  * By Aarno Syvänen for Wiral Ltd
00067  */
00068 
00069 #include <stdio.h>
00070 
00071 #include "gwlib/gwlib.h"
00072 #include "gw/wap_push_pap_mime.h"
00073 
00074 static void prepend_crlf(Octstr **os)
00075 {
00076     octstr_insert(*os, octstr_imm("\r\n"), 0);
00077 }
00078 
00079 static void append_crlf(Octstr *os)
00080 {
00081     octstr_append(os, octstr_imm("\r\n"));
00082 }
00083 
00084 static void add_crs(Octstr *os)
00085 {
00086     long i;
00087     Octstr *nos;
00088 
00089     if (os == NULL)
00090         return;
00091 
00092     nos = octstr_format("%c", '\r');
00093     i = 0;
00094     while (i < octstr_len(os)) {
00095         if (octstr_get_char(os, i) == '\n') {
00096         octstr_insert(os, nos, i);
00097             ++i;
00098         }
00099         ++i;
00100     }
00101 
00102     octstr_destroy(nos);
00103 }
00104 
00105 static void remove_crs(Octstr *os)
00106 {
00107     long i;
00108 
00109     if (os == NULL)
00110         return;
00111 
00112     i = 0;
00113     while (i < octstr_len(os)) {
00114         if (octstr_get_char(os, i) == '\r') {
00115         octstr_delete(os, i, 1);
00116             --i;
00117         }
00118         ++i;
00119     }
00120 }
00121 
00122 static int skip_tail(Octstr **os, int delimiter)
00123 {
00124     long delimiter_pos;
00125 
00126     if ((delimiter_pos = octstr_search_char(*os, delimiter, 0)) == -1)
00127         return 0;
00128 
00129     octstr_delete(*os, delimiter_pos, octstr_len(*os) - delimiter_pos);
00130 
00131     return 1;
00132 }
00133 
00134 static void help(void)
00135 {
00136     info(0, "Usage: test_mime [options] source_file");
00137     info(0, "Parse source file into component parts.");
00138     info(0, "Source file has the following format:");
00139     info(0, "    boundary=<mime boundary>;");
00140     info(0, "    content=<mime content>;");
00141     info(0, "Content headers are added into the content_file. This file has");
00142     info(0, "following format:");
00143     info(0, "    headers=<content_headers>;");
00144     info(0, "    content=<push-content>;");
00145     info(0, "And options are");
00146     info(0, "    -h");
00147     info(0, "print this info");
00148     info(0, "    -d filename");
00149     info(0, "store push data to file filename. Default test/data.txt");
00150     info(0, "    -c filename");
00151     info(0, "store push control message to file filename. Default");
00152     info(0, " test/pap.txt");
00153     info(0, "    -s");
00154     info(0, "write push control message and push data to standard output");
00155     info(0, "Default write it to the file.");
00156 }
00157 
00158 int main(int argc, char **argv)
00159 {
00160     Octstr *mime_content,
00161            *pap_content,
00162            *push_data,
00163            *rdf_content,
00164            *boundary,
00165            *push_content_file = NULL,
00166            *this_header,
00167            *pap_osname,
00168            *data_osname;
00169     List *content_headers,
00170          *source_parts;
00171     char *pap_content_file,
00172          *push_data_file,
00173          *rdf_content_file;
00174     int ret,
00175         std_out,
00176         opt,
00177         d_file,
00178         c_file;
00179     FILE *fp1,
00180          *fp2,
00181          *fp3;
00182 
00183     gwlib_init();
00184     std_out = 0;
00185     d_file = 0;
00186     c_file = 0;
00187     data_osname = NULL;
00188     pap_osname = NULL;
00189 
00190     while ((opt = getopt(argc, argv, "hd:sc:")) != EOF) {
00191         switch(opt) {
00192             case 'h':
00193                 help();
00194                 exit(1);
00195             break;
00196 
00197             case 'd':
00198             d_file = 1;
00199                 data_osname = octstr_create(optarg);
00200             break;
00201 
00202             case 'c':
00203             c_file = 1;
00204                 pap_osname = octstr_create(optarg);
00205             break;
00206 
00207             case 's':
00208                 std_out = 1;
00209             break;
00210 
00211             case '?':
00212             default:
00213                 error(0, "Invalid option %c", opt);
00214                 help();
00215                 panic(0, "Stopping");
00216             break;
00217         }
00218     }    
00219 
00220     if (optind >= argc) {
00221         help();
00222         panic(0, "missing arguments, stopping");
00223     }
00224 
00225     if (!c_file)
00226         pap_content_file = "test/pap.txt";
00227     else
00228         pap_content_file = octstr_get_cstr(pap_osname);
00229     if (!d_file)
00230         push_data_file = "test/data.txt";
00231     else
00232         push_data_file = octstr_get_cstr(data_osname);
00233     rdf_content_file = "test/rdf.txt";
00234 
00235     mime_content = octstr_read_file(argv[optind]);
00236     if (mime_content == NULL) {
00237         octstr_destroy(mime_content);
00238         error(0, "No MIME source");
00239         panic(0, "Stopping");
00240     }
00241 
00242     source_parts = octstr_split(mime_content, octstr_imm("content="));
00243     if (gwlist_len(source_parts) == 1) {     /* a hack to circumvent a bug */
00244         error(0, "Badly formatted source:");
00245         octstr_destroy(mime_content);
00246         gwlist_destroy(source_parts, octstr_destroy_item);
00247         panic(0, "Stopping");
00248     }
00249 
00250     boundary = gwlist_extract_first(source_parts);
00251     octstr_delete(boundary, 0, octstr_len(octstr_imm("boundary=")));
00252     if (skip_tail(&boundary, ';') == 0) {
00253         error(0, "Cannot determine boundary, no delimiter; possible");
00254         octstr_dump(boundary, 0);
00255         goto no_parse;
00256     }
00257     
00258     octstr_destroy(mime_content);
00259     mime_content = gwlist_extract_first(source_parts);
00260     if (skip_tail(&mime_content, ';') == 0){
00261         error(0, "Cannot determine mime content, no delimiter");
00262         octstr_dump(mime_content, 0);
00263         goto no_parse;
00264     }
00265     prepend_crlf(&mime_content);
00266     add_crs(mime_content);
00267     append_crlf(mime_content);
00268     
00269     ret = mime_parse(boundary, mime_content, &pap_content, &push_data, 
00270                      &content_headers, &rdf_content);
00271     if (ret == 0) {
00272         error(0, "Mime_parse returned 0, cannot continue");
00273         goto error;
00274     }
00275 
00276     remove_crs(pap_content);
00277     if (!std_out) {
00278         fp1 = fopen(pap_content_file, "a");
00279         if (fp1 == NULL) {
00280             error(0, "Cannot open the file for pap control message");
00281             goto error;
00282         }
00283         octstr_print(fp1, pap_content);
00284         debug("test.mime", 0, "pap control message appended to the file");
00285         fclose(fp1);
00286     } else {
00287         debug("test.mime", 0, "pap control message was");
00288         octstr_dump(pap_content, 0);
00289     }
00290 
00291     remove_crs(push_data);
00292     if (!std_out) {
00293         fp2 = fopen(push_data_file, "a");
00294         if (fp2 == NULL) {
00295             error(0, "Cannot open the push data file");
00296             goto error;
00297         }
00298         push_content_file = octstr_create("");
00299         octstr_append(push_content_file, octstr_imm("headers="));
00300         while (gwlist_len(content_headers) > 0) {
00301             octstr_append(push_content_file, 
00302                           this_header = gwlist_extract_first(content_headers));
00303             octstr_format_append(push_content_file, "%c", ' ');
00304             octstr_destroy(this_header);
00305         }
00306         octstr_append(push_content_file, octstr_imm(";\n"));
00307         octstr_append(push_content_file, octstr_imm("content="));
00308         octstr_append(push_content_file, push_data);
00309         octstr_append(push_content_file, octstr_imm(";\n"));
00310         octstr_print(fp2, push_content_file);
00311         debug("test.mime", 0, "push content appended to the file");
00312         fclose(fp2);
00313     } else {
00314         debug("test.mime", 0, "Content headers were");
00315         http_header_dump(content_headers);
00316         debug("test.mime", 0, "And push content itself");
00317         octstr_dump(push_data, 0);
00318     }
00319 
00320     if (rdf_content != NULL)
00321         remove_crs(rdf_content);
00322     if (!std_out && rdf_content != NULL) {
00323         fp3 = NULL;
00324         if (rdf_content != NULL) {
00325             fp3 = fopen(rdf_content_file, "a");
00326             if (fp3 == NULL) {
00327                 error(0, "Cannot open the rdf file");
00328                 goto cerror;
00329              }
00330             octstr_print(fp3, rdf_content);
00331             debug("test.mime", 0, "push caps message appended to the file");
00332             fclose(fp3);
00333         }
00334     } else {
00335         if (rdf_content != NULL) {
00336             debug("test.mime", 0, "push caps message was");
00337             octstr_dump(rdf_content, 0);
00338         }
00339     }
00340     
00341     octstr_destroy(boundary);
00342     octstr_destroy(mime_content);
00343     octstr_destroy(pap_content);
00344     octstr_destroy(push_data);
00345     octstr_destroy(rdf_content);
00346     octstr_destroy(pap_osname);
00347     octstr_destroy(data_osname);
00348     http_destroy_headers(content_headers);
00349     gwlist_destroy(source_parts, octstr_destroy_item);
00350     octstr_destroy(push_content_file);
00351     gwlib_shutdown();
00352 
00353     info(0, "MIME data parsed successfully");
00354     return 0;
00355 
00356 no_parse:
00357     octstr_destroy(mime_content);
00358     octstr_destroy(pap_osname);
00359     octstr_destroy(data_osname);
00360     gwlist_destroy(source_parts, octstr_destroy_item);
00361     octstr_destroy(boundary);
00362     gwlib_shutdown();
00363     panic(0, "Stopping");
00364 
00365 error:
00366     octstr_destroy(mime_content);
00367     gwlist_destroy(source_parts, octstr_destroy_item);
00368     octstr_destroy(boundary);
00369     octstr_destroy(pap_content);
00370     octstr_destroy(push_data);
00371     octstr_destroy(pap_osname);
00372     octstr_destroy(data_osname);
00373     http_destroy_headers(content_headers);
00374     octstr_destroy(rdf_content);
00375     gwlib_shutdown();
00376     panic(0, "Stopping");
00377 
00378 cerror:
00379     octstr_destroy(mime_content);
00380     gwlist_destroy(source_parts, octstr_destroy_item);
00381     octstr_destroy(boundary);
00382     octstr_destroy(pap_content);
00383     octstr_destroy(push_data);
00384     octstr_destroy(push_content_file);
00385     octstr_destroy(pap_osname);
00386     octstr_destroy(data_osname);
00387     http_destroy_headers(content_headers);
00388     octstr_destroy(rdf_content);
00389     gwlib_shutdown();
00390     panic(0, "Stopping");
00391 /* return after panic always required by gcc */
00392     return 1;
00393 }
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.