cpl_loader.c

Go to the documentation of this file.
00001 /*
00002  * $Id: cpl_loader.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  * Copyright (C) 2006 Voice-Sistem SRL
00006  *
00007  * This file is part of Kamailio, a free SIP server.
00008  *
00009  * Kamailio is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * Kamailio is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  *
00024  * History:
00025  * -------
00026  * 2003-08-21: cpl_remove() added (bogdan)
00027  * 2003-06-24: file created (bogdan)
00028  */
00029 
00030 
00031 #include <stdio.h>
00032 #include <sys/types.h>
00033 #include <sys/uio.h>
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036 #include <sys/stat.h>
00037 #include <fcntl.h>
00038 #include <sys/uio.h>
00039 #include <errno.h>
00040 #include <string.h>
00041 #include <ctype.h>
00042 #include "../../str.h"
00043 #include "../../dprint.h"
00044 #include "../../mem/mem.h"
00045 #include "../../mem/shm_mem.h"
00046 #include "../../parser/parse_uri.h"
00047 #include "../../mi/mi.h"
00048 #include "cpl_db.h"
00049 #include "cpl_env.h"
00050 #include "cpl_parser.h"
00051 #include "cpl_loader.h"
00052 
00053 
00054 extern db_con_t* db_hdl;
00055 
00056 #if 0
00057 /* debug function -> write into a file the content of a str struct. */
00058 int write_to_file(char *filename, str *buf)
00059 {
00060    int fd;
00061    int ret;
00062 
00063    fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644);
00064    if (!fd) {
00065       LM_ERR("cannot open file : %s\n",
00066          strerror(errno));
00067       goto error;
00068    }
00069 
00070    while ( (ret=write( fd, buf->s, buf->len))!=buf->len) {
00071       if ((ret==-1 && errno!=EINTR)|| ret!=-1) {
00072          LM_ERR("cannot write to file:"
00073             "%s write_ret=%d\n",strerror(errno), ret );
00074          goto error;
00075       }
00076    }
00077    close(fd);
00078 
00079    return 0;
00080 error:
00081    return -1;
00082 }
00083 #endif
00084 
00085 
00086 
00087 /* Loads a file into a buffer; first the file length will be determined for
00088  * allocated an exact buffer len for storing the file content into.
00089  * Returns:  1 - success
00090  *          -1 - error
00091  */
00092 int load_file( char *filename, str *xml)
00093 {
00094    int n;
00095    int offset;
00096    int fd;
00097 
00098    xml->s = 0;
00099    xml->len = 0;
00100 
00101    /* open the file for reading */
00102    fd = open(filename,O_RDONLY);
00103    if (fd==-1) {
00104       LM_ERR("cannot open file for reading:"
00105          " %s\n",strerror(errno));
00106       goto error;
00107    }
00108 
00109    /* get the file length */
00110    if ( (xml->len=lseek(fd,0,SEEK_END))==-1) {
00111       LM_ERR("cannot get file length (lseek):"
00112          " %s\n", strerror(errno));
00113       goto error;
00114    }
00115    LM_DBG("file size = %d\n",xml->len);
00116    if ( lseek(fd,0,SEEK_SET)==-1 ) {
00117       LM_ERR("cannot go to beginning (lseek):"
00118          " %s\n",strerror(errno));
00119       goto error;
00120    }
00121 
00122    /* get some memory */
00123    xml->s = (char*)pkg_malloc( xml->len+1/*null terminated*/ );
00124    if (!xml->s) {
00125       LM_ERR("no more free pkg memory\n");
00126       goto error;
00127    }
00128 
00129    /*start reading */
00130    offset = 0;
00131    while ( offset<xml->len ) {
00132       n=read( fd, xml->s+offset, xml->len-offset);
00133       if (n==-1) {
00134          if (errno!=EINTR) {
00135             LM_ERR("read failed:"
00136                " %s\n", strerror(errno));
00137             goto error;
00138          }
00139       } else {
00140          if (n==0) break;
00141          offset += n;
00142       }
00143    }
00144    if (xml->len!=offset) {
00145       LM_ERR("couldn't read all file!\n");
00146       goto error;
00147    }
00148    xml->s[xml->len] = 0;
00149 
00150    close(fd);
00151    return 1;
00152 error:
00153    if (fd!=-1) close(fd);
00154    if (xml->s) pkg_free( xml->s);
00155    return -1;
00156 }
00157 
00158 
00159 
00160 /* Writes an array of texts into the given response file.
00161  * Accepts also empty texts, case in which it will be created an empty
00162  * response file.
00163  */
00164 void write_to_file( char *file, str *txt, int n )
00165 {
00166    int fd;
00167 
00168    /* open file for write */
00169    fd = open( file, O_WRONLY|O_CREAT|O_TRUNC/*|O_NOFOLLOW*/, 0600 );
00170    if (fd==-1) {
00171       LM_ERR("cannot open response file "
00172          "<%s>: %s\n", file, strerror(errno));
00173       return;
00174    }
00175 
00176    /* write the txt, if any */
00177    if (n>0) {
00178 again:
00179       if ( writev( fd, (struct iovec*)txt, n)==-1) {
00180          if (errno==EINTR) {
00181             goto again;
00182          } else {
00183             LM_ERR("write_logs_to_file: writev failed: "
00184                "%s\n", strerror(errno) );
00185          }
00186       }
00187    }
00188 
00189    /* close the file*/
00190    close( fd );
00191    return;
00192 }
00193 
00194 
00195 /**************************** MI ****************************/
00196 #define FILE_LOAD_ERR_S   "Cannot read CPL file"
00197 #define FILE_LOAD_ERR_LEN (sizeof(FILE_LOAD_ERR_S)-1)
00198 #define DB_SAVE_ERR_S     "Cannot save CPL to database"
00199 #define DB_SAVE_ERR_LEN   (sizeof(DB_SAVE_ERR_S)-1)
00200 #define CPLFILE_ERR_S     "Bad CPL file"
00201 #define CPLFILE_ERR_LEN   (sizeof(CPLFILE_ERR_S)-1)
00202 #define USRHOST_ERR_S     "Bad user@host"
00203 #define USRHOST_ERR_LEN   (sizeof(USRHOST_ERR_S)-1)
00204 #define DB_RMV_ERR_S      "Database remove failed"
00205 #define DB_RMV_ERR_LEN    (sizeof(DB_RMV_ERR_S)-1)
00206 #define DB_GET_ERR_S      "Database query failed"
00207 #define DB_GET_ERR_LEN    (sizeof(DB_GET_ERR_S)-1)
00208 
00209 struct mi_root* mi_cpl_load(struct mi_root *cmd_tree, void *param)
00210 {
00211    struct mi_root *rpl_tree;
00212    struct mi_node *cmd;
00213    struct sip_uri uri;
00214    str xml = {0,0};
00215    str bin = {0,0};
00216    str enc_log = {0,0};
00217    str val;
00218    char *file;
00219 
00220    LM_DBG("\"LOAD_CPL\" MI command received!\n");
00221    cmd = &cmd_tree->node;
00222 
00223    /* check user+host */
00224    if((cmd->kids==NULL) ||(cmd->kids->next==NULL) || (cmd->kids->next->next))
00225       return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00226 
00227    val = cmd->kids->value;
00228    if (parse_uri( val.s, val.len, &uri)!=0){
00229       LM_ERR("invalid sip URI [%.*s]\n",
00230          val.len, val.s);
00231       return init_mi_tree( 400, USRHOST_ERR_S, USRHOST_ERR_LEN );
00232    }
00233    LM_DBG("user@host=%.*s@%.*s\n",
00234       uri.user.len,uri.user.s,uri.host.len,uri.host.s);
00235 
00236    /* second argument is the cpl file */
00237    val = cmd->kids->next->value;
00238    file = pkg_malloc(val.len+1);
00239    if (file==NULL) {
00240       LM_ERR("no more pkg mem\n");
00241       return 0;
00242    }
00243    memcpy( file, val.s, val.len);
00244    file[val.len]= '\0';
00245 
00246    /* load the xml file - this function will allocated a buff for the loading
00247     * the cpl file and attach it to xml.s -> don't forget to free it! */
00248    if (load_file( file, &xml)!=1) {
00249       pkg_free(file);
00250       return init_mi_tree( 500, FILE_LOAD_ERR_S, FILE_LOAD_ERR_LEN );
00251    }
00252    LM_DBG("cpl file=%s loaded\n",file);
00253    pkg_free(file);
00254 
00255    /* get the binary coding for the XML file */
00256    if (encodeCPL( &xml, &bin, &enc_log)!=1) {
00257       rpl_tree = init_mi_tree( 500, CPLFILE_ERR_S, CPLFILE_ERR_LEN );
00258       goto error;
00259    }
00260 
00261    /* write both the XML and binary formats into database */
00262    if (write_to_db( &uri.user,cpl_env.use_domain?&uri.host:0, &xml, &bin)!=1){
00263       rpl_tree = init_mi_tree( 500, DB_SAVE_ERR_S, DB_SAVE_ERR_LEN );
00264       goto error;
00265    }
00266 
00267    /* everything was OK */
00268    rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00269 
00270 error:
00271    if (rpl_tree && enc_log.len)
00272       add_mi_node_child(&rpl_tree->node,MI_DUP_VALUE,"Log",3,enc_log.s,enc_log.len);
00273    if (enc_log.s)
00274       pkg_free ( enc_log.s );
00275    if (xml.s)
00276       pkg_free ( xml.s );
00277    return rpl_tree;
00278 }
00279 
00280 
00281 
00282 struct mi_root * mi_cpl_remove(struct mi_root *cmd_tree, void *param)
00283 {
00284    struct mi_node *cmd;
00285    struct sip_uri uri;
00286    str user;
00287 
00288    LM_DBG("\"REMOVE_CPL\" MI command received!\n");
00289    cmd = &cmd_tree->node;
00290 
00291    /* check if there is only one parameter*/
00292    if(!(cmd->kids && cmd->kids->next== NULL))
00293       return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00294 
00295    user = cmd->kids->value;
00296 
00297    /* check user+host */
00298    if (parse_uri( user.s, user.len, &uri)!=0){
00299       LM_ERR("invalid SIP uri [%.*s]\n",
00300          user.len,user.s);
00301       return init_mi_tree( 400, USRHOST_ERR_S, USRHOST_ERR_LEN );
00302    }
00303    LM_DBG("user@host=%.*s@%.*s\n",
00304       uri.user.len,uri.user.s,uri.host.len,uri.host.s);
00305 
00306    if (rmv_from_db( &uri.user, cpl_env.use_domain?&uri.host:0)!=1)
00307       return init_mi_tree( 500, DB_RMV_ERR_S, DB_RMV_ERR_LEN );
00308 
00309    return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00310 }
00311 
00312 
00313 
00314 struct mi_root * mi_cpl_get(struct mi_root *cmd_tree, void *param)
00315 {
00316    struct mi_node *cmd;
00317    struct sip_uri uri;
00318    struct mi_root* rpl_tree;
00319    str script = {0,0};
00320    str user;
00321 
00322    cmd = &cmd_tree->node;
00323 
00324    /* check if there is only one parameter*/
00325    if(!(cmd->kids && cmd->kids->next== NULL))
00326       return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00327 
00328    /* check user+host */
00329    user = cmd->kids->value;
00330    if (parse_uri( user.s, user.len, &uri)!=0) {
00331       LM_ERR("invalid user@host [%.*s]\n",
00332          user.len,user.s);
00333       return init_mi_tree( 400, USRHOST_ERR_S, USRHOST_ERR_LEN );
00334    }
00335    LM_DBG("user@host=%.*s@%.*s\n",
00336       uri.user.len,uri.user.s,uri.host.len,uri.host.s);
00337 
00338    /* get the script for this user */
00339    str query_str = str_init("cpl_xml");
00340    if (get_user_script( &uri.user, cpl_env.use_domain?&uri.host:0,
00341    &script, &query_str)==-1)
00342       return init_mi_tree( 500, DB_GET_ERR_S, DB_GET_ERR_LEN );
00343 
00344    /* write the response into response file - even if script is null */
00345    rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00346    if (rpl_tree!=NULL)
00347       add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE, 0, 0,
00348          script.s, script.len);
00349 
00350    if (script.s)
00351       shm_free( script.s );
00352 
00353    return rpl_tree;
00354 }

Generated on Mon May 21 18:00:25 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6