20 #include <ndb_global.h>
24 #include "CpcClient.hpp"
26 #define CPC_CMD(name, value, desc) \
30 ParserRow_t::String, \
31 ParserRow_t::Optional, \
32 ParserRow_t::IgnoreMinMax, \
38 #define CPC_ARG(name, type, opt, desc) \
44 ParserRow_t::IgnoreMinMax, \
54 ParserRow_t::Optional, \
55 ParserRow_t::IgnoreMinMax, \
60 #ifdef DEBUG_PRINT_PROPERTIES
64 while((name = iter.next()) != NULL) {
69 p.getTypeOf(name, &t);
71 case PropertiesType_Uint32:
73 ndbout << name <<
" (Uint32): " << val_i << endl;
75 case PropertiesType_char:
77 ndbout << name <<
" (string): " << val_s << endl;
80 ndbout <<
"Unknown type " << t << endl;
90 const ParserRow_t stop_reply[] = {
91 CPC_CMD(
"stop process", NULL,
""),
92 CPC_ARG(
"status", Int, Mandatory,
""),
93 CPC_ARG(
"id", Int, Optional,
""),
94 CPC_ARG(
"errormessage",
String, Optional,
""),
102 const Properties*
ret = cpc_call(
"stop process", args, stop_reply);
104 reply.
put(
"status", (Uint32)0);
105 reply.
put(
"errormessage",
"unknown error");
110 ret->get(
"status", &status);
111 reply.
put(
"status", status);
114 ret->get(
"errormessage", msg);
115 reply.
put(
"errormessage", msg.
c_str());
123 SimpleCpcClient::start_process(Uint32
id,
Properties& reply){
124 const ParserRow_t start_reply[] = {
125 CPC_CMD(
"start process", NULL,
""),
126 CPC_ARG(
"status", Int, Mandatory,
""),
127 CPC_ARG(
"id", Int, Optional,
""),
128 CPC_ARG(
"errormessage",
String, Optional,
""),
136 const Properties* ret = cpc_call(
"start process", args, start_reply);
138 reply.
put(
"status", (Uint32)0);
139 reply.
put(
"errormessage",
"unknown error");
144 ret->get(
"status", &status);
145 reply.
put(
"status", status);
148 ret->get(
"errormessage", msg);
149 reply.
put(
"errormessage", msg.
c_str());
158 SimpleCpcClient::undefine_process(Uint32
id,
Properties& reply){
159 const ParserRow_t stop_reply[] = {
160 CPC_CMD(
"undefine process", NULL,
""),
161 CPC_ARG(
"status", Int, Mandatory,
""),
162 CPC_ARG(
"id", Int, Optional,
""),
163 CPC_ARG(
"errormessage",
String, Optional,
""),
171 const Properties* ret = cpc_call(
"undefine process", args, stop_reply);
173 reply.
put(
"status", (Uint32)0);
174 reply.
put(
"errormessage",
"unknown error");
179 ret->get(
"status", &status);
180 reply.
put(
"status", status);
183 ret->get(
"errormessage", msg);
184 reply.
put(
"errormessage", msg.
c_str());
195 ndbout.println(
"Name: %s", p.m_name.
c_str());
196 ndbout.println(
"Id: %d", p.m_id);
197 ndbout.println(
"Type: %s", p.m_type.
c_str());
198 ndbout.println(
"Group: %s", p.m_group.
c_str());
199 ndbout.println(
"Program path: %s", p.m_path.
c_str());
200 ndbout.println(
"Arguments: %s", p.m_args.
c_str());
201 ndbout.println(
"Environment: %s", p.m_env.
c_str());
202 ndbout.println(
"Working directory: %s", p.m_cwd.
c_str());
203 ndbout.println(
"Owner: %s", p.m_owner.
c_str());
204 ndbout.println(
"Runas: %s", p.m_runas.
c_str());
205 ndbout.println(
"Ulimit: %s", p.m_ulimit.
c_str());
206 ndbout.println(
"%s",
"");
213 b &= src.get(
"id", (Uint32*)&dst.m_id);
214 b &= src.get(
"name", dst.m_name);
215 b &= src.get(
"type", dst.m_type);
216 b &= src.get(
"status", dst.m_status);
217 b &= src.get(
"owner", dst.m_owner);
218 b &= src.get(
"group", dst.m_group);
219 b &= src.get(
"path", dst.m_path);
220 b &= src.get(
"args", dst.m_args);
221 b &= src.get(
"env", dst.m_env);
222 b &= src.get(
"cwd", dst.m_cwd);
223 b &= src.get(
"runas", dst.m_runas);
225 b &= src.get(
"stdin", dst.m_stdin);
226 b &= src.get(
"stdout", dst.m_stdout);
227 b &= src.get(
"stderr", dst.m_stderr);
228 b &= src.get(
"ulimit", dst.m_ulimit);
229 b &= src.get(
"shutdown", dst.m_shutdown_options);
238 b &= dst.
put(
"name", src.m_name.
c_str());
239 b &= dst.
put(
"type", src.m_type.
c_str());
241 b &= dst.
put(
"owner", src.m_owner.
c_str());
242 b &= dst.
put(
"group", src.m_group.
c_str());
243 b &= dst.
put(
"path", src.m_path.
c_str());
244 b &= dst.
put(
"args", src.m_args.
c_str());
245 b &= dst.
put(
"env", src.m_env.
c_str());
246 b &= dst.
put(
"cwd", src.m_cwd.
c_str());
247 b &= dst.
put(
"runas", src.m_runas.
c_str());
249 b &= dst.
put(
"stdin", src.m_stdin.
c_str());
250 b &= dst.
put(
"stdout", src.m_stdout.
c_str());
251 b &= dst.
put(
"stderr", src.m_stderr.
c_str());
252 b &= dst.
put(
"ulimit", src.m_ulimit.
c_str());
253 b &= dst.
put(
"shutdown", src.m_shutdown_options.
c_str());
259 SimpleCpcClient::define_process(Process & p,
Properties& reply){
260 const ParserRow_t define_reply[] = {
261 CPC_CMD(
"define process", NULL,
""),
262 CPC_ARG(
"status", Int, Mandatory,
""),
263 CPC_ARG(
"id", Int, Optional,
""),
264 CPC_ARG(
"errormessage",
String, Optional,
""),
272 const Properties* ret = cpc_call(
"define process", args, define_reply);
274 reply.
put(
"status", (Uint32)0);
275 reply.
put(
"errormessage",
"unknown error");
280 ret->get(
"status", &status);
281 reply.
put(
"status", status);
284 ret->get(
"errormessage", msg);
285 reply.
put(
"errormessage", msg.
c_str());
289 if(!ret->get(
"id", &
id)){
300 int start = 0, end = 0,
entry;
301 const ParserRow_t list_reply[] = {
302 CPC_CMD(
"start processes", &start,
""),
303 CPC_CMD(
"end processes", &end,
""),
305 CPC_CMD(
"process", &
entry,
""),
306 CPC_ARG(
"id", Int, Mandatory,
"Id of process."),
307 CPC_ARG(
"name",
String, Mandatory,
"Name of process"),
308 CPC_ARG(
"group",
String, Mandatory,
"Group of process"),
309 CPC_ARG(
"env",
String, Mandatory,
"Environment variables for process"),
310 CPC_ARG(
"path",
String, Mandatory,
"Path to binary"),
311 CPC_ARG(
"args",
String, Mandatory,
"Arguments to process"),
312 CPC_ARG(
"type",
String, Mandatory,
"Type of process"),
313 CPC_ARG(
"cwd",
String, Mandatory,
"Working directory of process"),
314 CPC_ARG(
"owner",
String, Mandatory,
"Owner of process"),
315 CPC_ARG(
"status",
String, Mandatory,
"Status of process"),
316 CPC_ARG(
"runas",
String, Mandatory,
"Run as user"),
317 CPC_ARG(
"stdin",
String, Mandatory,
"Redirect stdin"),
318 CPC_ARG(
"stdout",
String, Mandatory,
"Redirect stdout"),
319 CPC_ARG(
"stderr",
String, Mandatory,
"Redirect stderr"),
320 CPC_ARG(
"ulimit",
String, Mandatory,
"ulimit"),
321 CPC_ARG(
"shutdown",
String, Mandatory,
"shutdown"),
330 cpc_send(
"list processes", args);
336 cpc_recv(list_reply, &proc, &p);
358 ndbout_c(
"JONAS: start: %d loop: %d cnt: %u got p == &entry with proc == NULL",
359 start, end, procs.size());
364 ndbout_c(
"internal error: %d", __LINE__);
376 SimpleCpcClient::SimpleCpcClient(
const char *_host,
int _port) {
377 host = strdup(_host);
379 my_socket_invalidate(&cpc_sock);
382 SimpleCpcClient::~SimpleCpcClient() {
390 if(my_socket_valid(cpc_sock)) {
391 my_socket_close(cpc_sock);
392 my_socket_invalidate(&cpc_sock);
397 SimpleCpcClient::connect() {
398 struct sockaddr_in sa;
402 cpc_sock = my_socket_create(AF_INET, SOCK_STREAM, IPPROTO_TCP);
403 if(!my_socket_valid(cpc_sock))
407 sa.sin_family = AF_INET;
408 hp = gethostbyname(host);
414 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
415 sa.sin_port = htons(port);
416 if (my_connect_inet(cpc_sock, &sa) < 0)
423 SimpleCpcClient::cpc_send(
const char *cmd,
427 cpc_out.println(cmd);
431 while((name = iter.next()) != NULL) {
436 args.getTypeOf(name, &t);
438 case PropertiesType_Uint32:
439 args.get(name, &val_i);
440 cpc_out.println(
"%s: %d", name, val_i);
442 case PropertiesType_char:
443 args.get(name, val_s);
444 if (strlen(val_s.
c_str()) > Parser_t::Context::MaxParseBytes)
446 ndbout <<
"Argument " << name <<
" at "
447 << strlen(val_s.
c_str())
448 <<
" longer than max of "
449 << Parser_t::Context::MaxParseBytes
453 cpc_out.println(
"%s: %s", name, val_s.
c_str());
460 cpc_out.println(
"%s",
"");
471 SimpleCpcClient::cpc_recv(
const ParserRow_t *syntax,
478 Parser_t parser(syntax, cpc_in,
true,
true,
true);
479 *reply = parser.
parse(ctx, session);
480 if(user_value != NULL)
481 *user_value = ctx.m_currentCmd->user_value;
486 SimpleCpcClient::cpc_call(
const char *cmd,
488 const ParserRow_t *reply_syntax) {
492 cpc_recv(reply_syntax, &ret);
497 SimpleCpcClient::ParserDummy::ParserDummy(NDB_SOCKET_TYPE sock)