/ src / emc / task / emcsvr.cc
emcsvr.cc
  1  /********************************************************************
  2  * Description: emcsvr.cc
  3  *   Network server for EMC NML
  4  *
  5  *   Derived from a work by Fred Proctor & Will Shackleford
  6  *
  7  * Author:
  8  * License: GPL Version 2
  9  * System: Linux
 10  *    
 11  * Copyright (c) 2004 All rights reserved.
 12  *
 13  * Last change:
 14  ********************************************************************/
 15  
 16  #include <stdio.h>		// sscanf()
 17  #include <math.h>		// fabs()
 18  #include <stdlib.h>		// exit()
 19  #include <string.h>		// strncpy()
 20  #include <unistd.h>             // _exit()
 21  #include <signal.h>
 22  
 23  #include "rcs.hh"		// EMC NML
 24  #include "emc.hh"		// EMC NML
 25  #include "emc_nml.hh"		// EMC NML
 26  #include "emcglb.h"		// emcGetArgs(), EMC_NMLFILE
 27  #include "inifile.hh"
 28  #include "rcs_print.hh"
 29  #include "nml_oi.hh"
 30  #include "timer.hh"
 31  #include "nml_srv.hh"           // run_nml_servers()
 32  
 33  static int tool_channels = 1;
 34  
 35  static int iniLoad(const char *filename)
 36  {
 37      IniFile inifile;
 38      const char *inistring;
 39  
 40      // open it
 41      if (inifile.Open(filename) == false) {
 42  	return -1;
 43      }
 44  
 45      if (NULL != (inistring = inifile.Find("DEBUG", "EMC"))) {
 46  	// copy to global
 47  	if (1 != sscanf(inistring, "%x", &emc_debug)) {
 48  	    emc_debug = 0;
 49  	}
 50      } else {
 51  	// not found, use default
 52  	emc_debug = 0;
 53      }
 54      if (emc_debug & EMC_DEBUG_RCS) {
 55  	set_rcs_print_flag(PRINT_EVERYTHING);
 56  	max_rcs_errors_to_print = -1;
 57      }
 58  
 59      if (NULL != (inistring = inifile.Find("NML_FILE", "EMC"))) {
 60  	// copy to global
 61  	strcpy(emc_nmlfile, inistring);
 62      } else {
 63  	// not found, use default
 64      }
 65      inifile.Find(&tool_channels,"TOOL_CHANNELS","EMC");
 66      // close it
 67      inifile.Close();
 68  
 69      return 0;
 70  }
 71  
 72  // based on code from
 73  // http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html
 74  static void daemonize()
 75  {
 76      pid_t pid = fork();
 77      if (pid < 0) {
 78          perror("daemonize: fork()");
 79      } else if (pid) {
 80          _exit(0);
 81      }
 82  
 83      if(setsid() < 0)
 84          perror("daemonize: setsid()");
 85  
 86      // otherwise the parent may deliver a SIGHUP to this process when it
 87      // terminates
 88      signal(SIGHUP,SIG_IGN);
 89  
 90      pid=fork();
 91      if (pid < 0) {
 92          perror("daemonize: fork() 2");
 93      } else if (pid) {
 94          _exit(0);
 95      }
 96  }
 97  
 98  static RCS_CMD_CHANNEL *emcCommandChannel = NULL;
 99  static RCS_STAT_CHANNEL *emcStatusChannel = NULL;
100  static NML *emcErrorChannel = NULL;
101  static RCS_CMD_CHANNEL *toolCommandChannel = NULL;
102  static RCS_STAT_CHANNEL *toolStatusChannel = NULL;
103  
104  int main(int argc, char *argv[])
105  {
106      double start_time;
107  
108      // process command line args
109      if (0 != emcGetArgs(argc, argv)) {
110  	rcs_print_error("Error in argument list\n");
111  	exit(1);
112      }
113      // get configuration information
114      iniLoad(emc_inifile);
115  
116      set_rcs_print_destination(RCS_PRINT_TO_NULL);
117  
118      rcs_print("after iniLoad()\n");
119  
120  
121      start_time = etime();
122  
123      while (fabs(etime() - start_time) < 10.0 &&
124  	   (emcCommandChannel == NULL || emcStatusChannel == NULL
125  	    || (tool_channels && (toolCommandChannel == NULL || toolStatusChannel == NULL))
126  	    || emcErrorChannel == NULL)
127  	) {
128  	if (NULL == emcCommandChannel) {
129  	    rcs_print("emcCommandChannel==NULL, attempt to create\n");
130  	    emcCommandChannel =
131  		new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "emcsvr",
132  				    emc_nmlfile);
133  	}
134  	if (NULL == emcStatusChannel) {
135  	    rcs_print("emcStatusChannel==NULL, attempt to create\n");
136  	    emcStatusChannel =
137  		new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "emcsvr",
138  				     emc_nmlfile);
139  	}
140  	if (NULL == emcErrorChannel) {
141  	    emcErrorChannel =
142  		new NML(nmlErrorFormat, "emcError", "emcsvr", emc_nmlfile);
143  	}
144  	if (tool_channels) {
145  	    if (NULL == toolCommandChannel) {
146  		toolCommandChannel =
147  		    new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emcsvr",
148  					emc_nmlfile);
149  	    }
150  	    if (NULL == toolStatusChannel) {
151  		toolStatusChannel =
152  		    new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emcsvr",
153  					 emc_nmlfile);
154  	    }
155  	}
156  
157  	if (!emcCommandChannel->valid()) {
158  	    delete emcCommandChannel;
159  	    emcCommandChannel = NULL;
160  	}
161  	if (!emcStatusChannel->valid()) {
162  	    delete emcStatusChannel;
163  	    emcStatusChannel = NULL;
164  	}
165  	if (!emcErrorChannel->valid()) {
166  	    delete emcErrorChannel;
167  	    emcErrorChannel = NULL;
168  	}
169  	if (tool_channels) {
170  	    if (!toolCommandChannel->valid()) {
171  		delete toolCommandChannel;
172  		toolCommandChannel = NULL;
173  	    }
174  	    if (!toolStatusChannel->valid()) {
175  		delete toolStatusChannel;
176  		toolStatusChannel = NULL;
177  	    }
178  	}
179  	esleep(0.200);
180      }
181  
182      set_rcs_print_destination(RCS_PRINT_TO_STDERR);
183  
184      if (NULL == emcCommandChannel) {
185  	emcCommandChannel =
186  	    new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "emcsvr",
187  				emc_nmlfile);
188      }
189      if (NULL == emcStatusChannel) {
190  	emcStatusChannel =
191  	    new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "emcsvr",
192  				 emc_nmlfile);
193      }
194      if (NULL == emcErrorChannel) {
195  	emcErrorChannel =
196  	    new NML(nmlErrorFormat, "emcError", "emcsvr", emc_nmlfile);
197      }
198      if (tool_channels) {
199  	if (NULL == toolCommandChannel) {
200  	    toolCommandChannel =
201  		new RCS_CMD_CHANNEL(emcFormat, "toolCmd", "emcsvr",
202  				    emc_nmlfile);
203  	}
204  	if (NULL == toolStatusChannel) {
205  	    toolStatusChannel =
206  		new RCS_STAT_CHANNEL(emcFormat, "toolSts", "emcsvr",
207  				     emc_nmlfile);
208  	}
209      }
210      daemonize();
211      run_nml_servers();
212  
213      return 0;
214  }
215  
216  // vim:sw=4:sts=4:et