⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpcclient.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
字号:
/* Copyright (C) 2003 MySQL AB   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <ndb_global.h>#include <NdbOut.hpp>#include <NdbTCP.h>#include "CpcClient.hpp"#define CPC_CMD(name, value, desc) \ { (name), \   0, \   ParserRow_t::Cmd, \   ParserRow_t::String, \   ParserRow_t::Optional, \   ParserRow_t::IgnoreMinMax, \   0, 0, \   0, \   (desc), \   (value) }#define CPC_ARG(name, type, opt, desc) \ { (name), \   0, \   ParserRow_t::Arg, \   ParserRow_t::type, \   ParserRow_t::opt, \   ParserRow_t::IgnoreMinMax, \   0, 0, \   0, \  (desc), 0 }#define CPC_END() \ { 0, \   0, \   ParserRow_t::Arg, \   ParserRow_t::Int, \   ParserRow_t::Optional, \   ParserRow_t::IgnoreMinMax, \   0, 0, \   0, \   0, 0 }#ifdef DEBUG_PRINT_PROPERTIES static void printprop(const Properties &p) {  Properties::Iterator iter(&p);  const char *name;  while((name = iter.next()) != NULL) {    PropertiesType t;    Uint32 val_i;    BaseString val_s;    p.getTypeOf(name, &t);    switch(t) {    case PropertiesType_Uint32:      p.get(name, &val_i);      ndbout << name << " (Uint32): " << val_i << endl;      break;    case PropertiesType_char:      p.get(name, val_s);      ndbout << name << " (string): " << val_s << endl;      break;    default:      ndbout << "Unknown type " << t << endl;      break;    }  }}#endifvoidSimpleCpcClient::cmd_stop(char *arg) {  Properties p;  Vector<Process> proc_list;  list_processes(proc_list, p);  bool stopped = false;  for(size_t i = 0; i < proc_list.size(); i++) {    if(strcmp(proc_list[i].m_name.c_str(), arg) == 0) {      stopped = true;      Properties reply;      stop_process(proc_list[i].m_id, reply);      Uint32 status;      reply.get("status", &status);      if(status != 0) {	BaseString msg;	reply.get("errormessage", msg);	ndbout << "Stop failed: " << msg << endl;      }    }  }    if(!stopped)    ndbout << "No such process" << endl;}intSimpleCpcClient::stop_process(Uint32 id, Properties& reply){  const ParserRow_t stop_reply[] = {    CPC_CMD("stop process", NULL, ""),    CPC_ARG("status", Int, Mandatory, ""),    CPC_ARG("id", Int, Optional, ""),    CPC_ARG("errormessage", String, Optional, ""),        CPC_END()  };  Properties args;  args.put("id", id);    const Properties* ret = cpc_call("stop process", args, stop_reply);  if(ret == 0){    reply.put("status", (Uint32)0);    reply.put("errormessage", "unknown error");    return -1;  }  Uint32 status = 0;  ret->get("status", &status);  reply.put("status", status);  if(status != 0) {    BaseString msg;    ret->get("errormessage", msg);    reply.put("errormessage", msg.c_str());  }  return status;}voidSimpleCpcClient::cmd_start(char *arg) {  Properties p;  Vector<Process> proc_list;  list_processes(proc_list, p);  bool startped = false;  for(size_t i = 0; i < proc_list.size(); i++) {    if(strcmp(proc_list[i].m_name.c_str(), arg) == 0) {      startped = true;      Properties reply;      start_process(proc_list[i].m_id, reply);      Uint32 status;      reply.get("status", &status);      if(status != 0) {	BaseString msg;	reply.get("errormessage", msg);	ndbout << "Start failed: " << msg << endl;      }    }  }    if(!startped)    ndbout << "No such process" << endl;}intSimpleCpcClient::start_process(Uint32 id, Properties& reply){  const ParserRow_t start_reply[] = {    CPC_CMD("start process", NULL, ""),    CPC_ARG("status", Int, Mandatory, ""),    CPC_ARG("id", Int, Optional, ""),    CPC_ARG("errormessage", String, Optional, ""),        CPC_END()  };  Properties args;  args.put("id", id);    const Properties* ret = cpc_call("start process", args, start_reply);  if(ret == 0){    reply.put("status", (Uint32)0);    reply.put("errormessage", "unknown error");    return -1;  }  Uint32 status = 0;  ret->get("status", &status);  reply.put("status", status);  if(status != 0) {    BaseString msg;    ret->get("errormessage", msg);    reply.put("errormessage", msg.c_str());  }  return status;}intSimpleCpcClient::undefine_process(Uint32 id, Properties& reply){  const ParserRow_t stop_reply[] = {    CPC_CMD("undefine process", NULL, ""),    CPC_ARG("status", Int, Mandatory, ""),    CPC_ARG("id", Int, Optional, ""),    CPC_ARG("errormessage", String, Optional, ""),        CPC_END()  };  Properties args;  args.put("id", id);    const Properties* ret = cpc_call("undefine process", args, stop_reply);  if(ret == 0){    reply.put("status", (Uint32)0);    reply.put("errormessage", "unknown error");    return -1;  }  Uint32 status = 0;  ret->get("status", &status);  reply.put("status", status);  if(status != 0) {    BaseString msg;    ret->get("errormessage", msg);    reply.put("errormessage", msg.c_str());  }  return status;}static voidprintproc(SimpleCpcClient::Process & p) {  ndbout.println("Name:                %s", p.m_name.c_str());  ndbout.println("Id:                  %d", p.m_id);  ndbout.println("Type:                %s", p.m_type.c_str());  ndbout.println("Group:               %s", p.m_group.c_str());  ndbout.println("Program path:        %s", p.m_path.c_str());  ndbout.println("Arguments:           %s", p.m_args.c_str());  ndbout.println("Environment:         %s", p.m_env.c_str());  ndbout.println("Working directory:   %s", p.m_cwd.c_str());  ndbout.println("Owner:               %s", p.m_owner.c_str());  ndbout.println("Runas:               %s", p.m_runas.c_str());  ndbout.println("Ulimit:              %s", p.m_ulimit.c_str());  ndbout.println("");}voidSimpleCpcClient::cmd_list(char *arg) {  Properties p;  Vector<Process> proc_list;  list_processes(proc_list, p);  for(size_t i = 0; i < proc_list.size(); i++) {    printproc(proc_list[i]);  }}static intconvert(const Properties & src, SimpleCpcClient::Process & dst){  bool b = true;  b &= src.get("id", (Uint32*)&dst.m_id);  b &= src.get("name",   dst.m_name);  b &= src.get("type",   dst.m_type);  b &= src.get("status", dst.m_status);  b &= src.get("owner",  dst.m_owner);  b &= src.get("group",  dst.m_group);  b &= src.get("path",   dst.m_path);  b &= src.get("args",   dst.m_args);  b &= src.get("env",    dst.m_env);  b &= src.get("cwd",    dst.m_cwd);  b &= src.get("runas",  dst.m_runas);  b &= src.get("stdin",  dst.m_stdin);  b &= src.get("stdout", dst.m_stdout);  b &= src.get("stderr", dst.m_stderr);  b &= src.get("ulimit", dst.m_ulimit);  b &= src.get("shutdown", dst.m_shutdown_options);  return b;}static intconvert(const SimpleCpcClient::Process & src, Properties & dst ){  bool b = true;  //b &= dst.put("id",     (Uint32)src.m_id);  b &= dst.put("name",   src.m_name.c_str());  b &= dst.put("type",   src.m_type.c_str());  //b &= dst.put("status", src.m_status.c_str());  b &= dst.put("owner",  src.m_owner.c_str());  b &= dst.put("group",  src.m_group.c_str());  b &= dst.put("path",   src.m_path.c_str());  b &= dst.put("args",   src.m_args.c_str());  b &= dst.put("env",    src.m_env.c_str());  b &= dst.put("cwd",    src.m_cwd.c_str());  b &= dst.put("runas",  src.m_runas.c_str());  b &= dst.put("stdin",  src.m_stdin.c_str());  b &= dst.put("stdout", src.m_stdout.c_str());  b &= dst.put("stderr", src.m_stderr.c_str());  b &= dst.put("ulimit", src.m_ulimit.c_str());  b &= dst.put("shutdown", src.m_shutdown_options.c_str());    return b;}intSimpleCpcClient::define_process(Process & p, Properties& reply){  const ParserRow_t define_reply[] = {    CPC_CMD("define process", NULL, ""),    CPC_ARG("status", Int, Mandatory, ""),    CPC_ARG("id", Int, Optional, ""),    CPC_ARG("errormessage", String, Optional, ""),        CPC_END()  };  Properties args;  convert(p, args);  const Properties* ret = cpc_call("define process", args, define_reply);  if(ret == 0){    reply.put("status", (Uint32)0);    reply.put("errormessage", "unknown error");    return -1;  }  Uint32 status = 0;  ret->get("status", &status);  reply.put("status", status);  if(status != 0) {    BaseString msg;    ret->get("errormessage", msg);    reply.put("errormessage", msg.c_str());  }  Uint32 id;  if(!ret->get("id", &id)){    return -1;  }  p.m_id = id;    return status;}intSimpleCpcClient::list_processes(Vector<Process> &procs, Properties& reply) {  int start, end, entry;   const ParserRow_t list_reply[] = {    CPC_CMD("start processes", &start, ""),    CPC_CMD("end processes", &end, ""),    CPC_CMD("process", &entry, ""),    CPC_ARG("id",    Int,    Mandatory, "Id of process."),    CPC_ARG("name",  String, Mandatory, "Name of process"),    CPC_ARG("group", String, Mandatory, "Group of process"),    CPC_ARG("env",   String, Mandatory, "Environment variables for process"),    CPC_ARG("path",  String, Mandatory, "Path to binary"),    CPC_ARG("args",  String, Mandatory, "Arguments to process"),    CPC_ARG("type",  String, Mandatory, "Type of process"),    CPC_ARG("cwd",   String, Mandatory, "Working directory of process"),    CPC_ARG("owner", String, Mandatory, "Owner of process"),    CPC_ARG("status",String, Mandatory, "Status of process"),    CPC_ARG("runas", String, Mandatory, "Run as user"),    CPC_ARG("stdin", String, Mandatory, "Redirect stdin"),    CPC_ARG("stdout",String, Mandatory, "Redirect stdout"),    CPC_ARG("stderr",String, Mandatory, "Redirect stderr"),    CPC_ARG("ulimit",String, Mandatory, "ulimit"),        CPC_ARG("shutdown",String, Mandatory, "shutdown"),            CPC_END()  };  reply.clear();  const Properties args;  cpc_send("list processes", args);  bool done = false;  while(!done) {    const Properties *proc;    void *p;    cpc_recv(list_reply, &proc, &p);    if(p == &start)    {      /* do nothing */    }    else if(p == &end)    {      done = true;    }    else if(p == &entry)    {      if(proc != NULL){	Process p;	convert(* proc, p);	procs.push_back(p);      }    }    else    {      ndbout_c("internal error: %d", __LINE__);      return -1;    }  }  return 0;}voidSimpleCpcClient::cmd_help(char *arg) {  ndbout    << "HELP				Print help text" << endl    << "LIST				List processes" << endl    << "START				Start process" << endl    << "STOP				Stop process" << endl;}SimpleCpcClient::SimpleCpcClient(const char *_host, int _port) {  host = strdup(_host);  port = _port;  cpc_sock = -1;  cpc_in = NULL;  cpc_out = NULL;}SimpleCpcClient::~SimpleCpcClient() {  if(host != NULL) {    free(host);    host = NULL;  }  port = 0;  if(cpc_sock == -1) {    close(cpc_sock);    cpc_sock = -1;  }  if(cpc_in != NULL)    delete cpc_in;  if(cpc_out != NULL)    delete cpc_out;}intSimpleCpcClient::connect() {  struct sockaddr_in sa;  struct hostent *hp;  /* Create socket */  cpc_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  if(cpc_sock < 0)    return -1;  /* Connect socket */  sa.sin_family = AF_INET;  hp = gethostbyname(host);  if(hp == NULL) {    errno = ENOENT;    return -1;  }  memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);  sa.sin_port = htons(port);  if (::connect(cpc_sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)    return -1;  cpc_in = new SocketInputStream(cpc_sock, 60000);  cpc_out = new SocketOutputStream(cpc_sock);    return 0;}intSimpleCpcClient::cpc_send(const char *cmd,			  const Properties &args) {    cpc_out->println(cmd);  Properties::Iterator iter(&args);  const char *name;  while((name = iter.next()) != NULL) {    PropertiesType t;    Uint32 val_i;    BaseString val_s;    args.getTypeOf(name, &t);    switch(t) {    case PropertiesType_Uint32:      args.get(name, &val_i);      cpc_out->println("%s: %d", name, val_i);      break;    case PropertiesType_char:      args.get(name, val_s);      cpc_out->println("%s: %s", name, val_s.c_str());      break;    default:      /* Silently ignore */      break;    }  }  cpc_out->println("");  return 0;}/** * Receive a response from the CPCD. The argument reply will point * to a Properties object describing the reply. Note that the caller * is responsible for deleting the Properties object returned. */SimpleCpcClient::Parser_t::ParserStatusSimpleCpcClient::cpc_recv(const ParserRow_t *syntax,			  const Properties **reply,			  void **user_value) {  Parser_t::Context ctx;  ParserDummy session(cpc_sock);  Parser_t parser(syntax, *cpc_in, true, true, true);  *reply = parser.parse(ctx, session);  if(user_value != NULL)    *user_value = ctx.m_currentCmd->user_value;  return ctx.m_status;}const Properties *SimpleCpcClient::cpc_call(const char *cmd,			  const Properties &args,			  const ParserRow_t *reply_syntax) {  cpc_send(cmd, args);#if 0  Parser_t::Context ctx;  ParserDummy session(cpc_sock);  Parser_t parser(reply_syntax, *cpc_in, true, true, true);  const Properties *ret = parser.parse(ctx, session);  return ret;#endif  const Properties *ret;  cpc_recv(reply_syntax, &ret);  return ret;}SimpleCpcClient::ParserDummy::ParserDummy(NDB_SOCKET_TYPE sock)  : SocketServer::Session(sock) {} template class Vector<SimpleCpcClient::Process>; template class Vector<ParserRow<SimpleCpcClient::ParserDummy> const*>;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -