MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
main.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <ndb_global.h>
19 #include <my_sys.h>
20 #include <my_getopt.h>
21 #include <mysql_version.h>
22 #include <ndb_version.h>
23 
24 #include "CPCD.hpp"
25 #include "APIService.hpp"
26 #include <NdbMain.h>
27 #include <NdbSleep.h>
28 #include <portlib/NdbDir.hpp>
29 #include <BaseString.hpp>
30 #include <logger/Logger.hpp>
31 #include <logger/FileLogHandler.hpp>
32 #include <logger/SysLogHandler.hpp>
33 
34 #include "common.hpp"
35 
36 static const char *work_dir = CPCD_DEFAULT_WORK_DIR;
37 static int unsigned port;
38 static int use_syslog;
39 static const char *logfile = NULL;
40 static const char *user = 0;
41 
42 static struct my_option my_long_options[] =
43 {
44  { "work-dir", 'w', "Work directory",
45  (uchar**) &work_dir, (uchar**) &work_dir, 0,
46  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
47  { "port", 'p', "TCP port to listen on",
48  (uchar**) &port, (uchar**) &port, 0,
49  GET_INT, REQUIRED_ARG, CPCD_DEFAULT_TCP_PORT, 0, 0, 0, 0, 0 },
50  { "syslog", 'S', "Log events to syslog",
51  (uchar**) &use_syslog, (uchar**) &use_syslog, 0,
52  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
53  { "logfile", 'L', "File to log events to",
54  (uchar**) &logfile, (uchar**) &logfile, 0,
55  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
56  { "debug", 'D', "Enable debug mode",
57  (uchar**) &debug, (uchar**) &debug, 0,
58  GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
59  { "user", 'u', "Run as user",
60  (uchar**) &user, (uchar**) &user, 0,
61  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
62  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
63 };
64 
65 static my_bool
66 get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
67  char *argument)
68 {
69  return 0;
70 }
71 
72 static CPCD * g_cpcd = 0;
73 
74 
75 int main(int argc, char** argv){
76  const char *load_default_groups[]= { "ndb_cpcd",0 };
77  NDB_INIT(argv[0]);
78 
79  load_defaults("ndb_cpcd",load_default_groups,&argc,&argv);
80  if (handle_options(&argc, &argv, my_long_options, get_one_option)) {
81  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
82  puts("");
83  my_print_help(my_long_options);
84  my_print_variables(my_long_options);
85  exit(1);
86  }
87 
88  logger.setCategory("ndb_cpcd");
89  logger.enable(Logger::LL_ALL);
90 
91  if(debug)
92  logger.createConsoleHandler();
93 
94 #ifndef _WIN32
95  if(user && runas(user) != 0){
96  logger.critical("Unable to change user: %s", user);
97  _exit(1);
98  }
99 #endif
100 
101  if(logfile != NULL){
102  BaseString tmp;
103  if(logfile[0] != '/')
104  tmp.append(work_dir);
105  tmp.append(logfile);
106  logger.addHandler(new FileLogHandler(tmp.c_str()));
107  }
108 
109 #ifndef _WIN32
110  if(use_syslog)
111  logger.addHandler(new SysLogHandler());
112 #endif
113 
114  logger.info("Starting");
115 
116 #if defined SIGPIPE && !defined _WIN32
117  (void)signal(SIGPIPE, SIG_IGN);
118 #endif
119 #ifdef SIGCHLD
120  /* Only "poll" for child to be alive, never use 'wait' */
121  (void)signal(SIGCHLD, SIG_IGN);
122 #endif
123 
124  CPCD cpcd;
125  g_cpcd = &cpcd;
126 
127  /* Create working directory unless it already exists */
128  if (access(work_dir, F_OK))
129  {
130  logger.info("Working directory '%s' does not exist, trying "
131  "to create it", work_dir);
132  if (!NdbDir::create(work_dir,
133  NdbDir::u_rwx() | NdbDir::g_r() | NdbDir::o_r()))
134  {
135  logger.error("Failed to create working directory, terminating!");
136  exit(1);
137  }
138  }
139 
140  if(strlen(work_dir) > 0){
141  logger.debug("Changing dir to '%s'", work_dir);
142  if(NdbDir::chdir(work_dir) != 0){
143  logger.error("Cannot change directory to '%s', error: %d, terminating!",
144  work_dir, errno);
145  exit(1);
146  }
147  }
148 
149  cpcd.loadProcessList();
150 
151  SocketServer * ss = new SocketServer();
152  CPCDAPIService * serv = new CPCDAPIService(cpcd);
153  unsigned short real_port= port; // correct type
154  if(!ss->setup(serv, &real_port)){
155  logger.critical("Cannot setup server: %s", strerror(errno));
156  sleep(1);
157  delete ss;
158  delete serv;
159  return 1;
160  }
161 
162  ss->startServer();
163 
164  logger.debug("Start completed");
165  while(true)
166  NdbSleep_MilliSleep(1000);
167 
168  delete ss;
169  return 0;
170 }