00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
00088
00089
00090
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
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
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
00123 xml->s = (char*)pkg_malloc( xml->len+1 );
00124 if (!xml->s) {
00125 LM_ERR("no more free pkg memory\n");
00126 goto error;
00127 }
00128
00129
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
00161
00162
00163
00164 void write_to_file( char *file, str *txt, int n )
00165 {
00166 int fd;
00167
00168
00169 fd = open( file, O_WRONLY|O_CREAT|O_TRUNC, 0600 );
00170 if (fd==-1) {
00171 LM_ERR("cannot open response file "
00172 "<%s>: %s\n", file, strerror(errno));
00173 return;
00174 }
00175
00176
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
00190 close( fd );
00191 return;
00192 }
00193
00194
00195
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
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
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
00247
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
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
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
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
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
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
00325 if(!(cmd->kids && cmd->kids->next== NULL))
00326 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00327
00328
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
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
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 }