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

shared.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  * shared.c - some utility routines shared by all Kannel boxes
00059  *
00060  * Lars Wirzenius
00061  */
00062 
00063 #include <sys/utsname.h>
00064 #include <libxml/xmlversion.h>
00065 
00066 #include "gwlib/gwlib.h"
00067 #include "shared.h"
00068 
00069 #if defined(HAVE_LIBSSL) || defined(HAVE_WTLS_OPENSSL) 
00070 #include <openssl/opensslv.h>
00071 #endif
00072 #ifdef HAVE_MYSQL 
00073 #include <mysql_version.h>
00074 #include <mysql.h>
00075 #endif
00076 #ifdef HAVE_SQLITE 
00077 #include <sqlite.h>
00078 #endif
00079 #ifdef HAVE_SQLITE3 
00080 #include <sqlite3.h>
00081 #endif
00082 #ifdef HAVE_ORACLE 
00083 #include <oci.h>
00084 #endif
00085 
00086 
00087 volatile enum program_status program_status = starting_up;
00088 
00089 
00090 void report_versions(const char *boxname)
00091 {
00092     Octstr *os;
00093     
00094     os = version_report_string(boxname);
00095     debug("gwlib.gwlib", 0, "%s", octstr_get_cstr(os));
00096     octstr_destroy(os);
00097 }
00098 
00099 
00100 Octstr *version_report_string(const char *boxname)
00101 {
00102     struct utsname u;
00103 
00104     uname(&u);
00105     return octstr_format(GW_NAME " %s version `%s'.\nBuild `%s', compiler `%s'.\n"
00106                          "System %s, release %s, version %s, machine %s.\n"
00107              "Hostname %s, IP %s.\n"
00108              "Libxml version %s.\n"
00109 #ifdef HAVE_LIBSSL
00110              "Using "
00111 #ifdef HAVE_WTLS_OPENSSL
00112              "WTLS library "
00113 #endif
00114              "%s.\n"
00115 #endif
00116 #ifdef HAVE_MYSQL
00117              "Compiled with MySQL %s, using MySQL %s.\n"
00118 #endif
00119 #ifdef HAVE_SDB
00120              "Using LibSDB %s.\n"
00121 #endif
00122 #if defined(HAVE_SQLITE) || defined(HAVE_SQLITE3)
00123              "Using SQLite %s.\n"
00124 #endif
00125 #ifdef HAVE_ORACLE
00126 #if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
00127              "Using Oracle OCI %d.%d.\n"
00128 #else
00129              "Using Oracle OCI.\n"
00130 #endif
00131 #endif
00132              "Using %s malloc.\n",
00133              boxname, GW_VERSION,
00134 #ifdef __GNUC__ 
00135              (__DATE__ " " __TIME__) ,
00136              __VERSION__,
00137 #else 
00138              "unknown" , "unknown",
00139 #endif 
00140              u.sysname, u.release, u.version, u.machine,
00141              octstr_get_cstr(get_official_name()),
00142              octstr_get_cstr(get_official_ip()),
00143              LIBXML_DOTTED_VERSION,
00144 #ifdef HAVE_LIBSSL
00145              OPENSSL_VERSION_TEXT,
00146 #endif
00147 #ifdef HAVE_MYSQL
00148              MYSQL_SERVER_VERSION, mysql_get_client_info(),
00149 #endif
00150 #ifdef HAVE_SDB
00151              LIBSDB_VERSION,
00152 #endif
00153 #if defined(HAVE_SQLITE) || defined(HAVE_SQLITE3)
00154              SQLITE_VERSION,
00155 #endif
00156 #ifdef HAVE_ORACLE
00157 #if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
00158              OCI_MAJOR_VERSION, OCI_MINOR_VERSION,
00159 #endif
00160 #endif
00161              octstr_get_cstr(gwmem_type()));
00162 }
00163 
00164 
00165 /***********************************************************************
00166  * Communication with the bearerbox.
00167  */
00168 
00169 /* this is a static connection if only *one* boxc connection is 
00170  * established from a foobarbox to bearerbox. */
00171 static Connection *bb_conn;
00172 
00173 
00174 Connection *connect_to_bearerbox_real(Octstr *host, int port, int ssl, Octstr *our_host)
00175 {
00176     Connection *conn;
00177 
00178 #ifdef HAVE_LIBSSL
00179     if (ssl) 
00180         conn = conn_open_ssl(host, port, NULL, our_host);
00181         /* XXX add certkeyfile to be given to conn_open_ssl */
00182     else
00183 #endif /* HAVE_LIBSSL */
00184     conn = conn_open_tcp(host, port, our_host);
00185     if (conn == NULL)
00186         return NULL;
00187 
00188     if (ssl)
00189         info(0, "Connected to bearerbox at %s port %d using SSL.",
00190              octstr_get_cstr(host), port);
00191     else
00192         info(0, "Connected to bearerbox at %s port %d.",
00193              octstr_get_cstr(host), port);
00194 
00195     return conn;
00196 }
00197 
00198 
00199 void connect_to_bearerbox(Octstr *host, int port, int ssl, Octstr *our_host)
00200 {
00201     bb_conn = connect_to_bearerbox_real(host, port, ssl, our_host);
00202     if (bb_conn == NULL)
00203         panic(0, "Couldn't connect to the bearerbox.");
00204 }
00205 
00206 
00207 void close_connection_to_bearerbox_real(Connection *conn)
00208 {
00209     conn_destroy(conn);
00210 }
00211 
00212 
00213 void close_connection_to_bearerbox(void)
00214 {
00215     close_connection_to_bearerbox_real(bb_conn);
00216     bb_conn = NULL;
00217 }
00218 
00219 
00220 void write_to_bearerbox_real(Connection *conn, Msg *pmsg)
00221 {
00222     Octstr *pack;
00223 
00224     pack = msg_pack(pmsg);
00225     if (conn_write_withlen(conn, pack) == -1)
00226         error(0, "Couldn't write Msg to bearerbox.");
00227 
00228     msg_destroy(pmsg);
00229     octstr_destroy(pack);
00230 }
00231 
00232 
00233 void write_to_bearerbox(Msg *pmsg)
00234 {
00235     write_to_bearerbox_real(bb_conn, pmsg);
00236 }
00237 
00238 
00239 int deliver_to_bearerbox_real(Connection *conn, Msg *msg) 
00240 {
00241      
00242     Octstr *pack;
00243     
00244     pack = msg_pack(msg);
00245     if (conn_write_withlen(conn, pack) == -1) {
00246         error(0, "Couldn't deliver Msg to bearerbox.");
00247         octstr_destroy(pack);
00248         return -1;
00249     }
00250                                    
00251     octstr_destroy(pack);
00252     msg_destroy(msg);
00253     return 0;
00254 }
00255 
00256 
00257 int deliver_to_bearerbox(Msg *msg)
00258 {
00259     return deliver_to_bearerbox_real(bb_conn, msg);
00260 }
00261                                            
00262 
00263 int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
00264 {
00265     int ret;
00266     Octstr *pack;
00267 
00268     pack = NULL;
00269     *msg = NULL;
00270     while (program_status != shutting_down) {
00271         pack = conn_read_withlen(conn);
00272         gw_claim_area(pack);
00273         if (pack != NULL)
00274             break;
00275 
00276         if (conn_error(conn)) {
00277             error(0, "Error reading from bearerbox, disconnecting.");
00278             return -1;
00279         }
00280         if (conn_eof(conn)) {
00281             error(0, "Connection closed by the bearerbox.");
00282             return -1;
00283         }
00284 
00285         ret = conn_wait(conn, seconds);
00286         if (ret < 0) {
00287             error(0, "Connection to bearerbox broke.");
00288             return -1;
00289         }
00290         else if (ret == 1) {
00291             /* debug("gwlib.gwlib", 0, "Connection to bearerbox timed out after %.2f seconds.", seconds); */
00292             return 1;
00293         }
00294     }
00295 
00296     if (pack == NULL)
00297         return -1;
00298 
00299     *msg = msg_unpack(pack);
00300     octstr_destroy(pack);
00301 
00302     if (*msg == NULL) {
00303         error(0, "Failed to unpack data!");
00304         return -1;
00305     }
00306 
00307     return 0;
00308 }
00309 
00310 
00311 int read_from_bearerbox(Msg **msg, double seconds)
00312 {
00313     return read_from_bearerbox_real(bb_conn, msg, seconds);
00314 }
00315 
00316 
00317 /*****************************************************************************
00318  *
00319  * Function validates an OSI date. Return unmodified octet string date when it
00320  * is valid, NULL otherwise.
00321  */
00322 
00323 Octstr *parse_date(Octstr *date)
00324 {
00325     long date_value;
00326 
00327     if (octstr_get_char(date, 4) != '-')
00328         goto error;
00329     if (octstr_get_char(date, 7) != '-')
00330         goto error;
00331     if (octstr_get_char(date, 10) != 'T')
00332         goto error;
00333     if (octstr_get_char(date, 13) != ':')
00334         goto error;
00335     if (octstr_get_char(date, 16) != ':')
00336         goto error;
00337     if (octstr_get_char(date, 19) != 'Z')
00338         goto error;
00339 
00340     if (octstr_parse_long(&date_value, date, 0, 10) < 0)
00341         goto error;
00342     if (octstr_parse_long(&date_value, date, 5, 10) < 0)
00343         goto error;
00344     if (date_value < 1 || date_value > 12)
00345         goto error;
00346     if (octstr_parse_long(&date_value, date, 8, 10) < 0)
00347         goto error;
00348     if (date_value < 1 || date_value > 31)
00349         goto error;
00350     if (octstr_parse_long(&date_value, date, 11, 10) < 0)
00351         goto error;
00352     if (date_value < 0 || date_value > 23)
00353         goto error;
00354     if (octstr_parse_long(&date_value, date, 14, 10) < 0)
00355         goto error;
00356     if (date_value < 0 || date_value > 59)
00357         goto error;
00358     if (date_value < 0 || date_value > 59)
00359         goto error;
00360     if (octstr_parse_long(&date_value, date, 17, 10) < 0)
00361         goto error;
00362 
00363     return date;
00364 
00365 error:
00366     warning(0, "parse_date: not an ISO date");
00367     return NULL;
00368 }
00369 
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.