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
00032
00033
00034
00035
00036
00037 #include <time.h>
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <errno.h>
00041 #include <sys/types.h>
00042 #include <signal.h>
00043
00044 #include "../dprint.h"
00045 #include "../globals.h"
00046 #include "../ut.h"
00047 #include "../pt.h"
00048 #include "../mem/mem.h"
00049 #include "mi.h"
00050 #include "../version.h"
00051
00052 #define BUILD_STR __FILE__ " compiled on "__TIME__ " " __DATE__ " with " COMPILER "\n"
00053 #define BUILD_STR_LEN (sizeof(BUILD_STR)-1)
00054
00055 #ifndef SVNREVISION
00056 #define SVNREVISION "unknown"
00057 #endif
00058
00059 static time_t up_since;
00060 static str up_since_ctime;
00061
00062 static int init_mi_uptime(void)
00063 {
00064 char *p;
00065
00066 time(&up_since);
00067 p = ctime(&up_since);
00068 up_since_ctime.len = strlen(p)-1;
00069 up_since_ctime.s = (char*)pkg_malloc(up_since_ctime.len);
00070 if (up_since_ctime.s==0) {
00071 LM_ERR("no more pkg mem\n");
00072 return -1;
00073 }
00074 memcpy(up_since_ctime.s, p , up_since_ctime.len);
00075 return 0;
00076 }
00077
00078
00079 static struct mi_root *mi_uptime(struct mi_root *cmd, void *param)
00080 {
00081 struct mi_root *rpl_tree;
00082 struct mi_node *rpl;
00083 struct mi_node *node;
00084 time_t now;
00085 char *p;
00086
00087 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00088 if (rpl_tree==0)
00089 return 0;
00090 rpl = &rpl_tree->node;
00091
00092 time(&now);
00093 p = ctime(&now);
00094 node = add_mi_node_child( rpl, MI_DUP_VALUE, MI_SSTR("Now"),
00095 p, strlen(p)-1);
00096 if (node==0)
00097 goto error;
00098
00099 node = add_mi_node_child( rpl, 0, MI_SSTR("Up since"),
00100 up_since_ctime.s, up_since_ctime.len);
00101 if (node==0)
00102 goto error;
00103
00104 node = addf_mi_node_child( rpl, 0, MI_SSTR("Up time"),
00105 "%lu [sec]", (unsigned long)difftime(now, up_since) );
00106 if (node==0)
00107 goto error;
00108
00109 return rpl_tree;
00110 error:
00111 LM_ERR("failed to add node\n");
00112 free_mi_tree(rpl_tree);
00113 return 0;
00114 }
00115
00116 static struct mi_root *mi_version(struct mi_root *cmd, void *param)
00117 {
00118 struct mi_root *rpl_tree;
00119 struct mi_node *rpl;
00120 struct mi_node *node;
00121
00122 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00123 if (rpl_tree==0)
00124 return 0;
00125 rpl = &rpl_tree->node;
00126
00127 node = add_mi_node_child( rpl, 0, MI_SSTR("Server"), SERVER_HDR+8,
00128 SERVER_HDR_LEN-8);
00129 if (node==0)
00130 goto error;
00131
00132 node = add_mi_node_child( rpl, 0, MI_SSTR("Build"), BUILD_STR,
00133 BUILD_STR_LEN);
00134 if (node==0)
00135 goto error;
00136
00137 node = add_mi_node_child( rpl, 0, MI_SSTR("Flags"), KAMAILIO_COMPILE_FLAGS,
00138 sizeof(KAMAILIO_COMPILE_FLAGS)-1);
00139 if (node==0)
00140 goto error;
00141
00142 node = add_mi_node_child( rpl, 0, MI_SSTR("SVN"), SVNREVISION,
00143 sizeof(SVNREVISION)-1);
00144 if (node==0)
00145 goto error;
00146
00147
00148
00149 return rpl_tree;
00150 error:
00151 LM_ERR("failed to add node\n");
00152 free_mi_tree(rpl_tree);
00153 return 0;
00154
00155 }
00156
00157
00158
00159 static struct mi_root *mi_pwd(struct mi_root *cmd, void *param)
00160 {
00161 static int max_len = 0;
00162 static char *cwd_buf = 0;
00163 struct mi_root *rpl_tree;
00164 struct mi_node *rpl;
00165 struct mi_node *node;
00166
00167 if (cwd_buf==NULL) {
00168 max_len = pathmax();
00169 cwd_buf = pkg_malloc(max_len);
00170 if (cwd_buf==NULL) {
00171 LM_ERR("no more pkg mem\n");
00172 return 0;
00173 }
00174 }
00175
00176 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00177 if (rpl_tree==0)
00178 return 0;
00179 rpl = &rpl_tree->node;
00180
00181 if (getcwd(cwd_buf, max_len)==0) {
00182 LM_ERR("getcwd failed = %s\n",strerror(errno));
00183 goto error;
00184 }
00185
00186 node = add_mi_node_child( rpl, 0, MI_SSTR("WD"), cwd_buf,strlen(cwd_buf));
00187 if (node==0) {
00188 LM_ERR("failed to add node\n");
00189 goto error;
00190 }
00191
00192 return rpl_tree;
00193 error:
00194 free_mi_tree(rpl_tree);
00195 return 0;
00196 }
00197
00198
00199
00200 static struct mi_root *mi_arg(struct mi_root *cmd, void *param)
00201 {
00202 struct mi_root *rpl_tree;
00203 struct mi_node *rpl;
00204 struct mi_node *node;
00205 int n;
00206
00207 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00208 if (rpl_tree==0)
00209 return 0;
00210 rpl = &rpl_tree->node;
00211
00212 for ( n=0; n<my_argc ; n++ ) {
00213 node = add_mi_node_child(rpl, 0, 0, 0, my_argv[n], strlen(my_argv[n]));
00214 if (node==0) {
00215 LM_ERR("failed to add node\n");
00216 free_mi_tree(rpl_tree);
00217 return 0;
00218 }
00219 }
00220
00221 return rpl_tree;
00222 }
00223
00224
00225
00226 static struct mi_root *mi_which(struct mi_root *cmd, void *param)
00227 {
00228 struct mi_root *rpl_tree;
00229 struct mi_cmd *cmds;
00230 struct mi_node *rpl;
00231 struct mi_node *node;
00232 int size;
00233 int i;
00234
00235 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00236 if (rpl_tree==0)
00237 return 0;
00238 rpl = &rpl_tree->node;
00239
00240 get_mi_cmds( &cmds, &size);
00241 for ( i=0 ; i<size ; i++ ) {
00242 node = add_mi_node_child( rpl, 0, 0, 0, cmds[i].name.s,
00243 cmds[i].name.len);
00244 if (node==0) {
00245 LM_ERR("failed to add node\n");
00246 free_mi_tree(rpl_tree);
00247 return 0;
00248 }
00249 }
00250
00251 return rpl_tree;
00252 }
00253
00254
00255
00256 static struct mi_root *mi_ps(struct mi_root *cmd, void *param)
00257 {
00258 struct mi_root *rpl_tree;
00259 struct mi_node *rpl;
00260 struct mi_node *node;
00261 struct mi_attr *attr;
00262 char *p;
00263 int len;
00264 int i;
00265
00266 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00267 if (rpl_tree==0)
00268 return 0;
00269 rpl = &rpl_tree->node;
00270
00271 for ( i=0 ; i<counted_processes ; i++ ) {
00272 node = add_mi_node_child(rpl, 0, MI_SSTR("Process"), 0, 0 );
00273 if (node==0)
00274 goto error;
00275
00276 p = int2str((unsigned long)i, &len);
00277 attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("ID"), p, len);
00278 if (attr==0)
00279 goto error;
00280
00281 p = int2str((unsigned long)pt[i].pid, &len);
00282 attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("PID"), p, len);
00283 if (attr==0)
00284 goto error;
00285
00286 attr = add_mi_attr( node, 0, MI_SSTR("Type"),
00287 pt[i].desc, strlen(pt[i].desc));
00288 if (attr==0)
00289 goto error;
00290 }
00291
00292 return rpl_tree;
00293 error:
00294 LM_ERR("failed to add node\n");
00295 free_mi_tree(rpl_tree);
00296 return 0;
00297 }
00298
00299
00300
00301 static struct mi_root *mi_kill(struct mi_root *cmd, void *param)
00302 {
00303 kill(0, SIGTERM);
00304
00305 return 0;
00306 }
00307
00308
00309
00310 static struct mi_root *mi_debug(struct mi_root *cmd, void *param)
00311 {
00312 struct mi_root *rpl_tree;
00313 struct mi_node *node;
00314 char *p;
00315 int len;
00316 int new_debug;
00317
00318 #ifdef CHANGEABLE_DEBUG_LEVEL
00319 node = cmd->node.kids;
00320 if (node!=NULL) {
00321 if (str2sint( &node->value, &new_debug) < 0)
00322 return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
00323 } else
00324 new_debug = *debug;
00325 #else
00326 new_debug = debug;
00327 #endif
00328
00329 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00330 if (rpl_tree==0)
00331 return 0;
00332
00333 p = sint2str((long)new_debug, &len);
00334 node = add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE,
00335 MI_SSTR("DEBUG"),p, len);
00336 if (node==0) {
00337 free_mi_tree(rpl_tree);
00338 return 0;
00339 }
00340
00341 #ifdef CHANGEABLE_DEBUG_LEVEL
00342 *debug = new_debug;
00343 #endif
00344
00345 return rpl_tree;
00346 }
00347
00348
00349
00350 static mi_export_t mi_core_cmds[] = {
00351 { "uptime", mi_uptime, MI_NO_INPUT_FLAG, 0, init_mi_uptime },
00352 { "version", mi_version, MI_NO_INPUT_FLAG, 0, 0 },
00353 { "pwd", mi_pwd, MI_NO_INPUT_FLAG, 0, 0 },
00354 { "arg", mi_arg, MI_NO_INPUT_FLAG, 0, 0 },
00355 { "which", mi_which, MI_NO_INPUT_FLAG, 0, 0 },
00356 { "ps", mi_ps, MI_NO_INPUT_FLAG, 0, 0 },
00357 { "kill", mi_kill, MI_NO_INPUT_FLAG, 0, 0 },
00358 { "debug", mi_debug, 0, 0, 0 },
00359 { 0, 0, 0, 0, 0}
00360 };
00361
00362
00363
00364 int init_mi_core(void)
00365 {
00366 if (register_mi_mod( "core", mi_core_cmds)<0) {
00367 LM_ERR("unable to register core MI cmds\n");
00368 return -1;
00369 }
00370
00371 return 0;
00372 }