1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>KLone: entry.c Source File</title>
<link href="kl.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a></div>
<div class="nav">
<a class="el" href="dir_000000.html">src</a> / <a class="el" href="dir_000003.html">kloned</a></div>
<h1>entry.c</h1><a href="entry_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*</span>
00002 <span class="comment"> * Copyright (c) 2005, 2006 by KoanLogic s.r.l. <http://www.koanlogic.com></span>
00003 <span class="comment"> * All rights reserved.</span>
00004 <span class="comment"> *</span>
00005 <span class="comment"> * This file is part of KLone, and as such it is subject to the license stated</span>
00006 <span class="comment"> * in the LICENSE file which you have received as part of this distribution.</span>
00007 <span class="comment"> *</span>
00008 <span class="comment"> * $Id: entry.c,v 1.20 2006/04/06 14:50:03 tat Exp $</span>
00009 <span class="comment"> */</span>
00010
00011 <span class="preprocessor">#include "klone_conf.h"</span>
00012 <span class="preprocessor">#include <stdlib.h></span>
00013 <span class="preprocessor">#include <unistd.h></span>
00014 <span class="preprocessor">#include <stdio.h></span>
00015 <span class="preprocessor">#include <u/libu.h></span>
00016 <span class="preprocessor">#include <<a class="code" href="klone_8h.html">klone/klone.h</a>></span>
00017 <span class="preprocessor">#include <<a class="code" href="server_8h.html">klone/server.h</a>></span>
00018 <span class="preprocessor">#include <<a class="code" href="os_8h.html">klone/os.h</a>></span>
00019 <span class="preprocessor">#include <<a class="code" href="context_8h.html">klone/context.h</a>></span>
00020 <span class="preprocessor">#include <<a class="code" href="utils_8h.html">klone/utils.h</a>></span>
00021 <span class="preprocessor">#include <<a class="code" href="version_8h.html">klone/version.h</a>></span>
00022 <span class="preprocessor">#include "<a class="code" href="main_8h.html">main.h</a>"</span>
00023
<a name="l00024"></a><a class="code" href="entry_8c.html#a1">00024</a> <span class="keywordtype">int</span> <a class="code" href="entry_8c.html#a1">facility</a> = LOG_LOCAL0;
00025
00026 <span class="keyword">static</span> <a class="code" href="context_8h.html#a0">context_t</a> c;
<a name="l00027"></a><a class="code" href="context_8h.html#a1">00027</a> <a class="code" href="context_8h.html#a0">context_t</a> *<a class="code" href="entry_8c.html#a3">ctx</a> = &c; <span class="comment">/* exported */</span>
00028
00029 <span class="preprocessor">#ifdef OS_WIN</span>
00030 <span class="preprocessor"></span> <span class="comment">/* Win32 service name and description */</span>
00031 <span class="keyword">enum</span> { SS_NAME_BUFSZ = 64, SS_DESC_BUFSZ = 256 };
00032 <span class="keyword">static</span> <span class="keywordtype">char</span> ss_name[SS_NAME_BUFSZ] = <span class="stringliteral">"kloned"</span>;
00033 <span class="keyword">static</span> <span class="keywordtype">char</span> ss_desc[SS_DESC_BUFSZ] = <span class="stringliteral">"kloned daemon"</span>;
00034
00035 <span class="keywordtype">int</span> InstallService();
00036 <span class="keywordtype">int</span> RemoveService();
00037 <span class="preprocessor">#endif</span>
00038 <span class="preprocessor"></span>
00039 <span class="keyword">static</span> <span class="keywordtype">void</span> usage()
00040 {
00041 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *us =
00042 <span class="stringliteral">"Usage: kloned OPTIONS ARGUMENTS \n"</span>
00043 <span class="stringliteral">"Version: %s - Copyright (c) 2005, 2006 KoanLogic s.r.l. - All rights reserved. \n"</span>
00044 <span class="stringliteral">"\n"</span>
00045 <span class="stringliteral">" -d turn on debugging \n"</span>
00046 <span class="stringliteral">" -f file load an external config file \n"</span>
00047 <span class="stringliteral">" -F run in foreground \n"</span>
00048 <span class="stringliteral">" -h display this help \n"</span>
00049 <span class="preprocessor">#ifdef OS_WIN</span>
00050 <span class="preprocessor"></span><span class="stringliteral">" -i install KLone Windows service \n"</span>
00051 <span class="stringliteral">" -u remove KLone Windows service \n"</span>
00052 <span class="preprocessor">#endif</span>
00053 <span class="preprocessor"></span><span class="stringliteral">" -V print KLone version and exit \n"</span>
00054 <span class="stringliteral">"\n"</span>;
00055
00056 fprintf(stderr, us, <a class="code" href="group__u__t.html#ga43">klone_version</a>());
00057
00058 exit(1);
00059 }
00060
00061 <span class="keyword">static</span> <span class="keywordtype">int</span> parse_opt(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
00062 {
00063 <span class="keywordtype">int</span> ret;
00064 <span class="preprocessor">#ifdef OS_WIN</span>
00065 <span class="preprocessor"></span><span class="preprocessor"> #define CMDLINE_FORMAT "hVFdiuf:"</span>
00066 <span class="preprocessor"></span><span class="preprocessor">#else</span>
00067 <span class="preprocessor"></span><span class="preprocessor"> #define CMDLINE_FORMAT "hVFdf:"</span>
00068 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
00069 <span class="preprocessor"></span>
00070 <span class="comment">/* set defaults */</span>
00071 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o5">daemon</a>++;
00072
00073 <span class="keywordflow">while</span>((ret = getopt(argc, argv, CMDLINE_FORMAT)) != -1)
00074 {
00075 <span class="keywordflow">switch</span>(ret)
00076 {
00077 <span class="keywordflow">case</span> <span class="charliteral">'f'</span>: <span class="comment">/* source a config file */</span>
00078 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o3">ext_config</a> = u_strdup(optarg);
00079 dbg_err_if(<a class="code" href="entry_8c.html#a3">ctx</a>->ext_config == NULL);
00080 dbg(<span class="stringliteral">"ext config: %s"</span>, <a class="code" href="entry_8c.html#a3">ctx</a>->ext_config);
00081 <span class="keywordflow">break</span>;
00082
00083 <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: <span class="comment">/* turn on debugging */</span>
00084 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o4">debug</a>++;
00085 <span class="keywordflow">break</span>;
00086
00087 <span class="keywordflow">case</span> <span class="charliteral">'F'</span>: <span class="comment">/* run in foreground (not as a daemon/service) */</span>
00088 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o5">daemon</a> = 0;
00089 <span class="keywordflow">break</span>;
00090
00091 <span class="keywordflow">case</span> <span class="charliteral">'V'</span>: <span class="comment">/* print version and exit */</span>
00092 <a class="code" href="group__u__t.html#ga22">u_print_version_and_exit</a>();
00093 <span class="keywordflow">break</span>;
00094
00095 <span class="preprocessor">#ifdef OS_WIN</span>
00096 <span class="preprocessor"></span> <span class="keywordflow">case</span> <span class="charliteral">'i'</span>: <span class="comment">/* install kloned service and exit */</span>
00097 <a class="code" href="entry_8c.html#a3">ctx</a>->serv_op = SERV_INSTALL;
00098 <span class="keywordflow">break</span>;
00099
00100 <span class="keywordflow">case</span> <span class="charliteral">'u'</span>: <span class="comment">/* uninstall kloned service and exit */</span>
00101 <a class="code" href="entry_8c.html#a3">ctx</a>->serv_op = SERV_REMOVE;
00102 <span class="keywordflow">break</span>;
00103
00104 <span class="preprocessor">#endif</span>
00105 <span class="preprocessor"></span>
00106 <span class="keywordflow">default</span>:
00107 <span class="keywordflow">case</span> <span class="charliteral">'h'</span>:
00108 usage();
00109 }
00110 }
00111
00112 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o7">narg</a> = argc - optind;
00113 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o6">arg</a> = argv + optind;
00114
00115 <span class="keywordflow">return</span> 0;
00116 err:
00117 <span class="keywordflow">return</span> ~0;
00118 }
00119
00120 <span class="preprocessor">#if defined(OS_WIN)</span>
00121 <span class="preprocessor"></span>
00122 <span class="comment">/* install the service with the service manager. after successful installation</span>
00123 <span class="comment"> you can run the service from ControlPanel->AdminTools->Services */</span>
00124 <span class="keywordtype">int</span> InstallService(<span class="keywordtype">void</span>)
00125 {
00126 SC_HANDLE hSCM, hService;
00127 <span class="keywordtype">char</span> szModulePathname[_MAX_PATH];
00128 SERVICE_DESCRIPTION sd = { ss_desc };
00129 <span class="keywordtype">int</span> rc;
00130
00131 <span class="comment">// Open the SCM on this machine.</span>
00132 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
00133
00134 dbg_err_if(hSCM == NULL);
00135
00136 dbg_err_if(GetModuleFileName(GetModuleHandle(NULL), szModulePathname,
00137 _MAX_PATH) == 0 );
00138
00139 <span class="comment">/* add this service to the SCM's database */</span>
00140 hService = CreateService(hSCM, ss_name, ss_name,
00141 SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS,
00142 SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE,
00143 szModulePathname, NULL, NULL, NULL, NULL, NULL);
00144
00145 dbg_err_if(hService == NULL);
00146
00147 rc = ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd);
00148
00149 dbg_err_if(rc == 0);
00150
00151 <span class="comment">/* success */</span>
00152 MessageBox(NULL, <span class="stringliteral">"Service installation succeded"</span>, ss_name, MB_OK);
00153
00154 <span class="keywordflow">return</span> 0;
00155 err:
00156 <span class="comment">/* common error handling */</span>
00157 warn_strerror(GetLastError());
00158 MessageBox(NULL, <span class="stringliteral">"Service installation error"</span>, ss_name, MB_OK);
00159 <span class="keywordflow">return</span> ~0;
00160 }
00161
00162 <span class="comment">/* uninstall this service from the system */</span>
00163 <span class="keywordtype">int</span> RemoveService(<span class="keywordtype">void</span>)
00164 {
00165 SC_HANDLE hSCM, hService;
00166 <span class="keywordtype">int</span> rc;
00167
00168 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
00169
00170 dbg_err_if(hSCM == NULL);
00171
00172 <span class="comment">/* Open this service for DELETE access */</span>
00173 hService = OpenService(hSCM, ss_name, DELETE);
00174
00175 dbg_err_if(hService == NULL);
00176
00177 <span class="comment">/* Remove this service from the SCM's database */</span>
00178 rc = DeleteService(hService);
00179
00180 dbg_err_if(rc == 0);
00181
00182 <span class="comment">/* success */</span>
00183 MessageBox(NULL, <span class="stringliteral">"Uninstall secceded"</span>, ss_name, MB_OK);
00184 <span class="keywordflow">return</span> 0;
00185 err:
00186 <span class="comment">/* common error handling */</span>
00187 warn_strerror(GetLastError());
00188 MessageBox(NULL, <span class="stringliteral">"Uninstall failed"</span>, ss_name, MB_OK);
00189 <span class="keywordflow">return</span> ~0;
00190 }
00191
00192 <span class="comment">/* this function will be called by the SCM to request an action */</span>
00193 DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType,
00194 LPVOID lpEventData, LPVOID lpContext)
00195 {
00196 <span class="keyword">enum</span> { DENY_ACTION = 0xff };
00197
00198 <span class="keywordflow">switch</span>(dwControl)
00199 {
00200 <span class="keywordflow">case</span> SERVICE_CONTROL_INTERROGATE:
00201 dbg(<span class="stringliteral">"SERVICE_CONTROL_INTERROGATE"</span> );
00202 SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, &<a class="code" href="entry_8c.html#a3">ctx</a>->status);
00203 <span class="keywordflow">return</span> NO_ERROR;
00204
00205 <span class="keywordflow">case</span> SERVICE_CONTROL_STOP:
00206 dbg(<span class="stringliteral">"SERVICE_CONTROL_STOP"</span>);
00207
00208 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCurrentState == SERVICE_STOPPED)
00209 <span class="keywordflow">return</span> NO_ERROR; <span class="comment">/* service already stopped */</span>
00210
00211 <span class="comment">/* start the stop procedure, move to stop_pending state */</span>
00212 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCheckPoint = 1;
00213 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwWaitHint = 2000;
00214 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCurrentState = SERVICE_STOP_PENDING;
00215 SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, &<a class="code" href="entry_8c.html#a3">ctx</a>->status);
00216
00217 <a class="code" href="server_8h.html#a15">server_stop</a>(<a class="code" href="entry_8c.html#a3">ctx</a>->server);
00218 <span class="keywordflow">return</span> NO_ERROR;
00219
00220 <span class="keywordflow">case</span> SERVICE_CONTROL_PAUSE:
00221 dbg(<span class="stringliteral">"SERVICE_CONTROL_PAUSE"</span>);
00222 <span class="keywordflow">break</span>;
00223
00224 <span class="keywordflow">case</span> SERVICE_CONTROL_CONTINUE:
00225 dbg(<span class="stringliteral">"SERVICE_CONTROL_CONTINUE"</span>);
00226 <span class="keywordflow">break</span>;
00227
00228 <span class="keywordflow">case</span> SERVICE_CONTROL_SHUTDOWN:
00229 dbg(<span class="stringliteral">"SERVICE_CONTROL_SHUTDOWN"</span>);
00230 <span class="keywordflow">break</span>;
00231
00232 <span class="keywordflow">case</span> SERVICE_CONTROL_PARAMCHANGE:
00233 dbg(<span class="stringliteral">"SERVICE_CONTROL_PARAMCHANGE"</span>);
00234 <span class="keywordflow">break</span>;
00235
00236 <span class="keywordflow">default</span>:
00237 dbg(<span class="stringliteral">"SERVICE_CONTROL_UNKNOWN!!!!"</span>);
00238 }
00239 <span class="keywordflow">if</span>(dwControl > 127 && dwControl < 255)
00240 {
00241 <span class="comment">/* user defined control code */</span>
00242 dbg(<span class="stringliteral">"SERVICE_CONTROL_USER_DEFINED"</span>);
00243 }
00244
00245 <span class="keywordflow">return</span> ERROR_CALL_NOT_IMPLEMENTED;
00246 }
00247
00248 <span class="comment">/* this is the main function of the service. when this function returns the</span>
00249 <span class="comment"> * service will be terminated by the SCM */</span>
00250 <span class="keywordtype">void</span> WINAPI ServiceMain(DWORD argc, PTSTR *argv)
00251 {
00252 SERVICE_STATUS *pSt = &<a class="code" href="entry_8c.html#a3">ctx</a>->status;
00253
00254 <span class="comment">/* register the service with the ServiceControlManager */</span>
00255 <a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus = RegisterServiceCtrlHandlerEx(ss_name, HandlerEx, ctx);
00256 dbg_err_if( <a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus == 0 );
00257
00258 <span class="comment">/* init the status struct and update the service status */</span>
00259 ZeroMemory(pSt, <span class="keyword">sizeof</span>(SERVICE_STATUS));
00260 <span class="comment">/* just one service in this exe */</span>
00261 pSt->dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00262 <span class="comment">/* action supported by the service */</span>
00263 pSt->dwControlsAccepted = SERVICE_ACCEPT_STOP;
00264 <span class="comment">/* error returned while starting/stopping */</span>
00265 pSt->dwWin32ExitCode = NO_ERROR;
00266 <span class="comment">/* service specific exit code */</span>
00267 pSt->dwServiceSpecificExitCode = 0;
00268 <span class="comment">/* we're still initializing */</span>
00269 pSt->dwCurrentState = SERVICE_START_PENDING;
00270 <span class="comment">/* for progress operation */</span>
00271 pSt->dwCheckPoint = 1;
00272 <span class="comment">/* wait hint */</span>
00273 pSt->dwWaitHint = 1000;
00274 <span class="comment">/* set status */</span>
00275 dbg_err_if(SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, pSt) == 0);
00276
00277 dbg_err_if(parse_opt(argc, argv));
00278
00279 <span class="comment">/* load config and initialize */</span>
00280 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a4">app_init</a>());
00281
00282 <span class="comment">/* this should happen after initialization but I don't want to</span>
00283 <span class="comment"> mess main.c with win32-only code */</span>
00284
00285 <span class="comment">/* notify the end of initialization */</span>
00286 dbg(<span class="stringliteral">"SERVICE_RUNNING"</span>);
00287 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCurrentState = SERVICE_RUNNING;
00288 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCheckPoint = <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwWaitHint = 0;
00289 dbg_err_if(!SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, &<a class="code" href="entry_8c.html#a3">ctx</a>->status));
00290
00291 <span class="comment">/* run the main loop */</span>
00292 <a class="code" href="kloned_2main_8c.html#a6">app_run</a>();
00293
00294 <span class="comment">/* let the service terminate */</span>
00295 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCurrentState = SERVICE_STOPPED;
00296 dbg_err_if(!SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, &<a class="code" href="entry_8c.html#a3">ctx</a>->status));
00297
00298 <span class="keywordflow">return</span>;
00299
00300 err:
00301 warn_strerror(GetLastError());
00302
00303 <span class="comment">/* let the service terminate */</span>
00304 <a class="code" href="entry_8c.html#a3">ctx</a>->status.dwCurrentState = SERVICE_STOPPED;
00305 dbg_err_if(!SetServiceStatus(<a class="code" href="entry_8c.html#a3">ctx</a>->hServiceStatus, &<a class="code" href="entry_8c.html#a3">ctx</a>->status));
00306 }
00307
00308 <span class="keywordtype">int</span> APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
00309 LPSTR lpCmdLine, <span class="keywordtype">int</span> nCmdShow)
00310 {
00311 SERVICE_TABLE_ENTRY ServiceTable[] =
00312 {
00313 { ss_name, ServiceMain },
00314 { NULL, NULL } <span class="comment">/* end of list */</span>
00315 };
00316 <span class="keywordtype">int</span> rc = 0;
00317 <span class="keyword">const</span> <span class="keywordtype">char</span> *name, *desc;
00318
00319 memset(ctx, 0, <span class="keyword">sizeof</span>(context_t));
00320
00321 <span class="comment">/* parse command line parameters (and set ctx vars). NOTE: this work only </span>
00322 <span class="comment"> if launched by command line, for services see ServiceMain */</span>
00323 dbg_err_if(parse_opt(__argc, __argv));
00324
00325 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->serv_op)
00326 {
00327 <span class="comment">/* load config and initialize */</span>
00328 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a4">app_init</a>());
00329
00330 <span class="comment">/* set up service name and description reading from the config file */</span>
00331 name = u_config_get_subkey_value(<a class="code" href="entry_8c.html#a3">ctx</a>->config, <span class="stringliteral">"daemon.name"</span>);
00332 <span class="keywordflow">if</span>(name)
00333 strncpy(ss_name, name, SS_NAME_BUFSZ);
00334
00335 desc = u_config_get_subkey_value(<a class="code" href="entry_8c.html#a3">ctx</a>->config, <span class="stringliteral">"daemon.description"</span>);
00336 <span class="keywordflow">if</span>(desc)
00337 strncpy(ss_desc, desc, SS_DESC_BUFSZ);
00338
00339 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->serv_op == SERV_INSTALL)
00340 dbg_err_if(InstallService());
00341 <span class="keywordflow">else</span>
00342 dbg_err_if(RemoveService());
00343 } <span class="keywordflow">else</span> <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->daemon) {
00344 dbg(<span class="stringliteral">"Starting in service mode..."</span>);
00345 <span class="comment">/* StartServiceCtrlDispatcher does not return until the service </span>
00346 <span class="comment"> has stopped running... */</span>
00347 <span class="keywordflow">if</span>(!StartServiceCtrlDispatcher(ServiceTable))
00348 warn_strerror(GetLastError());
00349 } <span class="keywordflow">else</span> {
00350 <span class="comment">/* load config and initialize */</span>
00351 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a4">app_init</a>());
00352
00353 rc = <a class="code" href="kloned_2main_8c.html#a6">app_run</a>();
00354 }
00355
00356 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a5">app_term</a>());
00357
00358 <span class="comment">/* if debugging then call exit(3) because it's needed to gprof to dump </span>
00359 <span class="comment"> its stats file (gmon.out) */</span>
00360 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->debug)
00361 <span class="keywordflow">return</span> rc;
00362
00363 <span class="comment">/* don't use return because exit(3) will be called and we don't want</span>
00364 <span class="comment"> FILE* buffers to be automatically flushed (klog_file_t will write same </span>
00365 <span class="comment"> lines more times, once by the parent process and N times by any child</span>
00366 <span class="comment"> created when FILE buffer was not empty) */</span>
00367 _exit(rc);
00368 err:
00369 <a class="code" href="kloned_2main_8c.html#a5">app_term</a>();
00370
00371 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->debug)
00372 <span class="keywordflow">return</span> rc;
00373 _exit(EXIT_FAILURE);
00374 }
00375
00376 <span class="preprocessor">#elif defined(OS_UNIX)</span>
00377 <span class="preprocessor"></span>
00378 <span class="keywordtype">int</span> <a class="code" href="tools_2klone_2main_8c.html#a21">main</a>(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
00379 {
00380 <span class="keywordtype">int</span> rc = 0;
00381
00382 memset(ctx, 0, <span class="keyword">sizeof</span>(context_t));
00383
00384 <span class="comment">/* parse command line parameters (and set ctx vars) */</span>
00385 dbg_err_if(parse_opt(argc, argv));
00386
00387 <span class="keywordflow">if</span>(getenv(<span class="stringliteral">"GATEWAY_INTERFACE"</span>))
00388 <a class="code" href="entry_8c.html#a3">ctx</a>-><a class="code" href="structcontext__s.html#o9">cgi</a> = 1;
00389
00390 <span class="comment">/* load config and initialize */</span>
00391 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a4">app_init</a>());
00392
00393 <span class="comment">/* daemonize if not -F */</span>
00394 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->daemon && !<a class="code" href="entry_8c.html#a3">ctx</a>->cgi)
00395 con_err_ifm(daemon(0, 0), <span class="stringliteral">"daemon error"</span>);
00396
00397 <span class="comment">/* jump to the main loop */</span>
00398 rc = <a class="code" href="kloned_2main_8c.html#a6">app_run</a>();
00399
00400 dbg_err_if(<a class="code" href="kloned_2main_8c.html#a5">app_term</a>());
00401
00402 <span class="comment">/* if debugging then call exit(3) because it's needed to gprof to dump </span>
00403 <span class="comment"> its stats file (gmon.out) */</span>
00404 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->debug)
00405 <span class="keywordflow">return</span> rc;
00406
00407 <span class="comment">/* don't use return because exit(3) will be called and we don't want</span>
00408 <span class="comment"> FILE* buffers to be automatically flushed (klog_file_t will write same </span>
00409 <span class="comment"> lines more times, once by the parent process and N times by any child</span>
00410 <span class="comment"> created when FILE buffer was not empty) */</span>
00411 _exit(rc);
00412 err:
00413 <a class="code" href="kloned_2main_8c.html#a5">app_term</a>();
00414 <span class="keywordflow">if</span>(<a class="code" href="entry_8c.html#a3">ctx</a>->debug)
00415 <span class="keywordflow">return</span> ~0;
00416 _exit(EXIT_FAILURE);
00417 }
00418
00419 <span class="preprocessor">#else</span>
00420 <span class="preprocessor"></span><span class="preprocessor"> #error unsupported platform</span>
00421 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
00422 <span class="preprocessor"></span>
</pre></div><hr>
<div>
<div style="text-align:left">
<a href="http://www.koanlogic.com/kl/cont/gb/html/products.html">←Products</a>
</div>
<div style="text-align:center;">
© 2005-2006 - <a href="http://www.koanlogic.com">KoanLogic S.r.l.</a> - All rights reserved
</div>
</div>
</body>
</html>
|