- Modules can properly register processes in SER process table
[sip-router] / core_cmd.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2005 iptelorg GmbH
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #include <time.h>
29 #include <sys/types.h>
30 #include <signal.h>
31 #include "mem/mem.h"
32 #include "sr_module.h"
33 #include "dprint.h"
34 #include "core_cmd.h"
35 #include "globals.h"
36 #include "pt.h"
37 #include "ut.h"
38 #include "core_cmd.h"
39
40
41 #define MAX_CTIME_LEN 128
42
43 /* up time */
44 static time_t up_since;
45 static char up_since_ctime[MAX_CTIME_LEN];
46
47
48 static const char* system_listMethods_doc[] = {
49         "Lists all RPC methods supported by the server.",  /* Documentation string */
50         0                                                  /* Method signature(s) */
51 };
52
53 static void system_listMethods(rpc_t* rpc, void* c)
54 {
55         struct sr_module* t;
56         rpc_export_t* ptr;
57         
58         for(ptr = core_rpc_methods; ptr && ptr->name; ptr++) {
59                 if (rpc->add(c, "s", ptr->name) < 0) return;
60         }
61
62         for(t = modules; t; t = t->next) {
63                 for(ptr = t->exports->rpc_methods; ptr && ptr->name; ptr++) {
64                         if (rpc->add(c, "s", ptr->name) < 0) return;
65                 }
66         }
67 }
68
69 static const char* system_methodSignature_doc[] = {
70         "Returns signature of given method.",  /* Documentation string */
71         0                                      /* Method signature(s) */
72 };
73
74 static void system_methodSignature(rpc_t* rpc, void* c)
75 {
76         rpc->fault(c, 500, "Not Implemented Yet");
77 }
78
79
80 static const char* system_methodHelp_doc[] = {
81         "Print the help string for given method.",  /* Documentation string */
82         0                                           /* Method signature(s) */
83 };
84
85 static void system_methodHelp(rpc_t* rpc, void* c)
86 {       
87         struct sr_module* t;
88         rpc_export_t* ptr;
89         char* name;
90
91         if (rpc->scan(c, "s", &name) < 0) return;
92
93         for(t = modules; t; t = t->next) {
94                 for(ptr = t->exports->rpc_methods; ptr && ptr->name; ptr++) {
95                         if (strcmp(name, ptr->name) == 0) {
96                                 if (ptr->doc_str && ptr->doc_str[0]) {
97                                         rpc->add(c, "s", ptr->doc_str[0]);
98                                 } else {
99                                         rpc->add(c, "s", "");
100                                 }
101                                 return;
102                         }
103                 }
104         }
105         rpc->fault(c, 500, "Method Not Implemented");
106 }
107
108
109 static const char* core_prints_doc[] = {
110         "Returns the string given as parameter.",   /* Documentation string */
111         0                                           /* Method signature(s) */
112 };
113
114 static void core_prints(rpc_t* rpc, void* c)
115 {
116         char* string;
117
118         if (rpc->scan(c, "s", &string) < 0) return;
119         rpc->add(c, "s", string);
120 }
121
122
123 static const char* core_version_doc[] = {
124         "Returns the version string of the server.", /* Documentation string */
125         0                                           /* Method signature(s) */
126 };
127
128 static void core_version(rpc_t* rpc, void* c)
129 {
130         rpc->add(c, "s", SERVER_HDR);
131 }
132
133
134
135 static const char* core_uptime_doc[] = {
136         "Returns uptime of SER server.",  /* Documentation string */
137         0                                 /* Method signature(s) */
138 };
139
140
141 static void core_uptime(rpc_t* rpc, void* c)
142 {
143         time_t now;
144
145         time(&now);
146         rpc->printf(c, "now: %s", ctime(&now));
147         rpc->printf(c, "up_since: %s", up_since_ctime);
148         rpc->printf(c, "uptime: %f", difftime(now, up_since));
149 }
150
151
152 static const char* core_ps_doc[] = {
153         "Returns the description of running SER processes.",  /* Documentation string */
154         0                                                     /* Method signature(s) */
155 };
156
157
158 static void core_ps(rpc_t* rpc, void* c)
159 {
160         int p;
161
162         for (p=0; p<process_count;p++) {
163                 rpc->printf(c, "pid: %d", pt[p].pid);
164                 rpc->printf(c, "desc: %s", pt[p].desc);
165         }
166 }
167
168
169 static const char* core_pwd_doc[] = {
170         "Returns the working directory of SER server.",    /* Documentation string */
171         0                                                  /* Method signature(s) */
172 };
173
174
175 static void core_pwd(rpc_t* rpc, void* c)
176 {
177         char *cwd_buf;
178         int max_len;
179
180         max_len = pathmax();
181         cwd_buf = pkg_malloc(max_len);
182         if (!cwd_buf) {
183                 ERR("core_pwd: No memory left\n");
184                 rpc->fault(c, 500, "Server Ran Out of Memory");
185                 return;
186         }
187
188         if (getcwd(cwd_buf, max_len)) {
189                 rpc->add(c, "s", cwd_buf);
190         } else {
191                 rpc->fault(c, 500, "getcwd Failed");
192         }
193         pkg_free(cwd_buf);
194 }
195
196
197 static const char* core_arg_doc[] = {
198         "Returns the list of command line arguments used on SER startup.",  /* Documentation string */
199         0                                                                   /* Method signature(s) */
200 };
201
202
203 static void core_arg(rpc_t* rpc, void* c)
204 {
205         int p;
206
207         for (p = 0; p < my_argc; p++) {
208                 if (rpc->add(c, "s", my_argv[p]) < 0) return;
209         }
210 }
211
212
213 static const char* core_kill_doc[] = {
214         "Sends the given signal to SER.",  /* Documentation string */
215         0                                  /* Method signature(s) */
216 };
217
218
219 static void core_kill(rpc_t* rpc, void* c)
220 {
221         int sig_no;
222         if (rpc->scan(c, "d", &sig_no) < 0) return;
223         rpc->send(c);
224         kill(0, sig_no);
225 }
226
227
228 /* 
229  * RPC Methods exported by this module 
230  */
231 rpc_export_t core_rpc_methods[] = {
232         {"system.listMethods",     system_listMethods,     system_listMethods_doc,     RET_ARRAY},
233         {"system.methodSignature", system_methodSignature, system_methodSignature_doc, RET_VALUE},
234         {"system.methodHelp",      system_methodHelp,      system_methodHelp_doc,      RET_VALUE},
235         {"core.prints",            core_prints,            core_prints_doc,            RET_VALUE},
236         {"core.version",           core_version,           core_version_doc,           RET_VALUE},
237         {"core.uptime",            core_uptime,            core_uptime_doc,            RET_ARRAY},
238         {"core.ps",                core_ps,                core_ps_doc,                RET_ARRAY},
239         {"core.pwd",               core_pwd,               core_pwd_doc,               RET_VALUE},
240         {"core.arg",               core_arg,               core_arg_doc,               RET_ARRAY},
241         {"core.kill",              core_kill,              core_kill_doc,              RET_VALUE},
242         {0, 0, 0, 0}
243 };
244
245 int rpc_init_time(void)
246 {
247         char *t;
248         time(&up_since);
249         t=ctime(&up_since);
250         if (strlen(t)+1>=MAX_CTIME_LEN) {
251                 ERR("Too long data %d\n", (int)strlen(t));
252                 return -1;
253         }
254         memcpy(up_since_ctime,t,strlen(t)+1);
255         return 0;
256 }