示例#1
0
文件: app.c 项目: dabear/Rocrail
static int _Main( iOApp inst, int argc, char** argv ) {
  iOAppData data = Data(inst);
  iOTrace trc = NULL;
  Boolean cd = False;

  /* check commandline arguments */
  iOCmdLn     arg     = CmdLnOp.inst( argc, (const char**)argv );
  tracelevel  debug   = CmdLnOp.hasKey( arg, wCmdline.debug  ) ? TRCLEVEL_DEBUG:0;
  tracelevel  dump    = CmdLnOp.hasKey( arg, wCmdline.byte   ) ? TRCLEVEL_BYTE:0;
  tracelevel  parse   = CmdLnOp.hasKey( arg, wCmdline.parse  ) ? TRCLEVEL_PARSE:0;
  tracelevel  monitor = CmdLnOp.hasKey( arg, wCmdline.monitor) ? TRCLEVEL_MONITOR:0;
  tracelevel  info    = CmdLnOp.hasKey( arg, wCmdline.info   ) ? TRCLEVEL_INFO:0;
  tracelevel  http    = CmdLnOp.hasKey( arg, wCmdline.http   ) ? TRCLEVEL_USER2:0;

  const char* wd      = CmdLnOp.getStr( arg, wCmdline.workdir );
  const char* tf      = CmdLnOp.getStr( arg, wCmdline.trcfile );
  const char* pf      = CmdLnOp.getStr( arg, wCmdline.planfile );
  const char* lf      = CmdLnOp.getStr( arg, wCmdline.locofile );
  const char* port    = CmdLnOp.getStr( arg, wCmdline.port );
  const char* nf      = CmdLnOp.getStr( arg, wCmdline.inifile );

  Boolean initfield   = CmdLnOp.hasKey( arg, wCmdline.initfield );
  Boolean      help   = CmdLnOp.hasKey( arg, wCmdline.help ) | CmdLnOp.hasKey( arg, "-?" );
  Boolean     nocom   = CmdLnOp.hasKey( arg, wCmdline.nocom );
  Boolean   console   = CmdLnOp.hasKey( arg, wCmdline.console );
  Boolean       doc   = CmdLnOp.hasKey( arg, wCmdline.doc );
  Boolean   version   = CmdLnOp.hasKey( arg, wCmdline.version );
  Boolean   service   = CmdLnOp.hasKey( arg, wCmdline.service );
  Boolean       lcd   = CmdLnOp.hasKey( arg, wCmdline.lcd );
  Boolean nodevcheck  = CmdLnOp.hasKey( arg, wCmdline.nodevcheck );


  Boolean automode    = CmdLnOp.hasKey( arg, wCmdline.automode );
  Boolean resume      = CmdLnOp.hasKey( arg, wCmdline.resume );
  data->run           = CmdLnOp.hasKey( arg, wCmdline.run );
  data->stress        = CmdLnOp.hasKey( arg, wCmdline.stress );
  data->createmodplan = CmdLnOp.hasKey( arg, wCmdline.modplan );
  data->szLibPath     = CmdLnOp.getStr( arg, wCmdline.libpath );
  data->szImgPath     = CmdLnOp.getStr( arg, wCmdline.imgpath );

  /* change the programs working directory */
  if( wd != NULL ) {
    cd = FileOp.cd( wd );
  }

  trc = TraceOp.inst( debug | dump | monitor | parse | info | http | TRCLEVEL_WARNING | TRCLEVEL_CALC | TRCLEVEL_STATUS, tf, True );
  TraceOp.setAppID( trc, "r" );

  if( wd != NULL ) {
    char* pwd = FileOp.pwd();
    TraceOp.trc( name, cd?TRCLEVEL_CALC:TRCLEVEL_EXCEPTION, __LINE__, 9999, "workdir [%s] pwd [%s]", wd, pwd );
    StrOp.free(pwd);
    if( !cd ) {
      cd = FileOp.cd( wd );
      if( !cd )
        TraceOp.terrno( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, errno, "Error changing workdir" );
    }
  }


  data->consoleMode = console;

  if( service ) {
    /* block reading console */
    console = False;
    nocom   = False;
  }
  else {
    if( help ) {
      data->revno = __logo();
      __help();
      return 0;
    }
    else if( doc ) {
      /* Write the embeded documentation into local HTML files: */
      extern const char rocrail_doc[]; /* xspooler.ini doc */

      char* fname = StrOp.fmt( "%s.html", wGlobal.productname );
      iOFile f = FileOp.inst( fname, OPEN_WRITE );
      __logo();
      if( f != NULL ) {
        Boolean ok = FileOp.write( f, rocrail_doc, StrOp.len( rocrail_doc ) );
        FileOp.base.del( f );
        TraceOp.println( "%s %s", fname, ok?"successfully written.":"not written."  );
      }
      StrOp.free( fname );
      return 0;
    }
    else if( version ) {
      __logo();
      return 0;
    }
  }


  /* Read the Inifile: */
  {
    char* iniXml = NULL;
    iODoc iniDoc = NULL;
    Boolean newIni = False;
    data->szIniFile = nf?nf:wRocRail.getfile(NULL);
    iniXml = __readIniFile(data->szIniFile);
    if( iniXml == NULL ) {
      iniXml = StrOp.fmt( "<%s/>", wRocRail.name());
      newIni = True;
      TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "empty ini file! [%s]", data->szIniFile );
    }

    /* Parse the Inifile: */
    iniDoc = DocOp.parse( iniXml );
    if( iniDoc != NULL ) {
      data->ini = DocOp.getRootNode( iniDoc );
      if( newIni ) {
        /* activate use block side routes for new work spaces */
        iONode ctrl = NodeOp.inst( wCtrl.name(), data->ini, ELEMENT_NODE );
        NodeOp.addChild( data->ini, ctrl );
      }
    }
    else {
      TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "Invalid ini file! [%s]", nf?nf:wRocRail.getfile(NULL) );
      return -1;
    }
  }

  if( nodevcheck ) {
    wRocRail.setnodevcheck(data->ini, nodevcheck );
  }

  if( FileOp.exist(wRocRail.getkeypath(data->ini)) ) {
    iOFile f = FileOp.inst( wRocRail.getkeypath(data->ini), OPEN_READONLY );
    char* buffer = (char*)allocMem( FileOp.size( f ) +1 );
    FileOp.read( f, buffer, FileOp.size( f ) );
    FileOp.base.del( f );
    iOStrTok tok = StrTokOp.inst( buffer, ';' );
    if( StrTokOp.hasMoreTokens(tok))
      data->doneml = StrOp.dup(StrTokOp.nextToken(tok) );
    if( StrTokOp.hasMoreTokens(tok))
      data->donkey = StrOp.dup(StrTokOp.nextToken(tok) );
    StrTokOp.base.del( tok );
    freeMem(buffer);
  }
  if( data->donkey == NULL || StrOp.len(data->donkey) == 0 ) {
    data->donkey = wRocRail.getdonkey( data->ini );
    data->donkey = wRocRail.getdoneml( data->ini );
  }

  if( wRocRail.isrunasroot( data->ini ) ) {
      TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "Try to run rocrail as root..." );
      if( !SystemOp.setAdmin() ) {
         TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "Only user 'root' can start rocrail! Abort!" );
         return -1;
      }
  }

  if( data->szLibPath == NULL ) {
    data->szLibPath = wRocRail.getlibpath( data->ini );
  }

  if( info != TRCLEVEL_INFO ){ /* Check info tracelevel. */
    int         level = TraceOp.getLevel( trc );
    Boolean infoParam = wTrace.isinfo( wRocRail.gettrace( data->ini ) );
    Boolean   infoCmd = (info & TRCLEVEL_INFO) ? True:False;
    if( infoCmd != infoParam ) {
      level &= 0xfffff ^ TRCLEVEL_INFO;
      level |= infoParam ? TRCLEVEL_INFO:0;
      TraceOp.setLevel( trc, level );
    }
  }

  /* Tracefile and listener */
  if( wRocRail.gettrace( data->ini ) == NULL ) {
    iONode trace = NodeOp.inst( wTrace.name(), data->ini, ELEMENT_NODE );
    NodeOp.addChild( data->ini, trace );
  }

  if( wTrace.isdebug( wRocRail.gettrace( data->ini ) ) || debug )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_DEBUG );
  if( wTrace.isautomatic( wRocRail.gettrace( data->ini ) ) )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_USER1 );
  if( wTrace.ismonitor( wRocRail.gettrace( data->ini ) ) || monitor )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_MONITOR );
  if( wTrace.isbyte( wRocRail.gettrace( data->ini ) ) || dump )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_BYTE );
  if( wTrace.isparse( wRocRail.gettrace( data->ini ) ) || parse )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_PARSE );
  if( wTrace.iscalc( wRocRail.gettrace( data->ini ) ) )
    TraceOp.setLevel( trc, TraceOp.getLevel( trc ) | TRCLEVEL_CALC );


  /* Tracefile and listener */
  {
    iONode tini = wRocRail.gettrace( data->ini );
    char*    tracefilename = NULL;
    const char*   protpath = wTrace.getprotpath( tini );
    Boolean        unique  = wTrace.isunique( tini );
    const char*        tf2 = wTrace.getrfile( tini );
    int               size = wTrace.getsize( tini );
    int                 nr = wTrace.getnr( tini );
    Boolean  exceptionfile = wTrace.isexceptionfile( tini );
    const char*     invoke = wTrace.getinvoke( tini );
    Boolean    invokeasync = wTrace.isinvokeasync( tini );
    int           dumpsize = wTrace.getdumpsize( tini );

    TraceOp.setFileSize( trc, size );
    TraceOp.setNrFiles( trc, nr );
    TraceOp.setExceptionFile( trc, exceptionfile );
    TraceOp.setInvoke( trc, invoke, invokeasync );
    TraceOp.setDumpsize( trc, dumpsize );

    if( tf == NULL )
      tf = tf2;
    else {
      char* p = FileOp.getPath( tf );
      TraceOp.trc( name, TRCLEVEL_DEBUG, __LINE__, 9999, "ProtPath set to [%s]. (tf=\"%s\")", p, tf );
      wTrace.setprotpath( tini, p );
      StrOp.free( p );
      protpath = wTrace.getprotpath( tini );
      wTrace.setrfile( tini, FileOp.ripPath( tf ) );
    }

    /* Check protpath. */
    if( protpath != NULL ) {
      if( !FileOp.access( protpath ) ) {
        if( FileOp.mkdir( protpath ) )
          TraceOp.trc( name, TRCLEVEL_DEBUG, __LINE__, 9999, "ProtPath [%s] created.", protpath );
        else {
          TraceOp.trc( name, TRCLEVEL_WARNING, __LINE__, 1002,
              "Protocol path [%s] invalid.(Using current folder.", protpath );
          protpath = NULL;
        }
      }
      else
        TraceOp.trc( name, TRCLEVEL_DEBUG, __LINE__, 9999, "ProtPath [%s] OK.", protpath );
    }

    if( protpath != NULL && !FileOp.isAbsolute( tf ) ) {
      char* stamp = StrOp.createStamp();

      if( !FileOp.isAbsolute( protpath ) ) {
        char* wd = FileOp.pwd();
        tracefilename = StrOp.fmt( "%s%c%s%c%s%s",
                                   wd,
                                   SystemOp.getFileSeparator(),
                                   protpath,
                                   SystemOp.getFileSeparator(),
                                   tf,
                                   unique ? stamp:"" );
        StrOp.free( wd );
      }
      else {
        tracefilename = StrOp.fmt( "%s%c%s%s",
                                   protpath,
                                   SystemOp.getFileSeparator(),
                                   tf,
                                   unique ? stamp:"" );
      }

      StrOp.free( stamp );
    }
    else {
      char* stamp = StrOp.createStamp();
      tracefilename = StrOp.fmt( "%s%s", tf, unique ? stamp:"" );
      StrOp.free( stamp );
    }

    TraceOp.setFilename( trc, tracefilename );
    TraceOp.setExceptionListener( trc, __exception, False, wTrace.islisten2all(tini) );

    StrOp.free( tracefilename );
  }



  /* Logo. */
  data->revno = __logo();
  TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "dpIID = [%s]", wRocRail.getdpiid(data->ini) );
  TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "ptIID = [%s]", wRocRail.getptiid(data->ini) );
  TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "svIID = [%s]", wRocRail.getsviid(data->ini) );
  TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "lcIID = [%s]", wRocRail.getlciid(data->ini) );

  /* planDoc */
  pf = pf?pf:wRocRail.getplanfile(data->ini);
  lf = lf?lf:wRocRail.getlocs(data->ini);
  data->model = ModelOp.inst( pf, lf );
  if( !ModelOp.init( data->model ) ) {
    TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "unable to create model: EXIT" );
    return 0;
  }

  MemOp.setDebug( False );


  /* Control */
  data->control = ControlOp.inst( nocom );

  /* Weather */
  data->weather = WeatherOp.inst(ModelOp.getWeather(data->model, wRocRail.getweatherid(data->ini)));

  /* Client connection */
  {
    iONode tcp = wRocRail.gettcp(data->ini);
    int iPort = 0;
    if( tcp == NULL ) {
      tcp = NodeOp.inst( wTcp.name(), data->ini, ELEMENT_NODE );
      NodeOp.addChild( data->ini, tcp );
    }

    iPort = port?atoi(port):wTcp.getport(tcp);
    data->clntCon = ClntConOp.inst( tcp, iPort, ControlOp.getCallback( data->control), (obj)data->control );
  }

  /* Client connection */
  {
    iONode srcpini = wRocRail.getsrcpcon(data->ini);
    if( srcpini != NULL && wSrcpCon.getport(srcpini) > 0 && wSrcpCon.isactive(srcpini) ) {
      data->srcpCon = SrcpConOp.inst( srcpini, ControlOp.getCallback( data->control), (obj)data->control );
    }
  }

  /* Http (Optional)*/
  {
    iONode http = wRocRail.gethttp( data->ini );
    if( http != NULL ) {
      iONode tcp  = wRocRail.gettcp(data->ini);
      const char* controlcode = NULL;
      const char* slavecode   = NULL;
      if( tcp != NULL ) {
        controlcode = wTcp.getcontrolcode(tcp);
        slavecode   = wTcp.getslavecode(tcp);
      }
      data->http = HttpOp.inst( http, ControlOp.getCallback( data->control), (obj)data->control, wRocRail.getimgpath(data->ini), controlcode, slavecode );
    }
  }

  /* Snmp (Optional)*/
  {
    iONode snmp = wRocRail.getSnmpService( data->ini );
    if( snmp != NULL && wSnmpService.isactive(snmp) )
      data->snmp = SNMPOp.inst( snmp );
  }


  if( wRocRail.ispoweronatinit(data->ini) ) {
    AppOp.go();
  }

  ModelOp.initField( data->model, initfield );

  /* update the feedback arrays */
  ModelOp.updateFB( data->model );

  /* run every thing at startup */
  if( automode ) {
    iONode cmd = NULL;
    clntcon_callback pfun = ControlOp.getCallback(data->control);

    /* power on */
    AppOp.go();

    /* auto mode on */
    cmd = NodeOp.inst( wAutoCmd.name(), NULL, ELEMENT_NODE );
    wAutoCmd.setcmd( cmd, wAutoCmd.on );
    pfun( (obj)AppOp.getControl(), cmd );

    /* start all */
    if(data->run || resume) {
      cmd = NodeOp.inst( wAutoCmd.name(), NULL, ELEMENT_NODE );
      wAutoCmd.setcmd( cmd, resume? wAutoCmd.resume:wAutoCmd.start );
      pfun( (obj)AppOp.getControl(), cmd );
    }
  }

  /* Memory watcher */
  while( !bShutdown ) {
    static int cnt1 = 0;
    int cnt2 = MemOp.getAllocCount();
    if( cnt2 > cnt1 ) {
      TraceOp.trc( name, TRCLEVEL_BYTE, __LINE__, 9999, "memory allocations old=%u new=%u", cnt1, cnt2 );
      if(wTrace.ismeminfo( wRocRail.gettrace( data->ini ) ))
        rocsStatistics( True );
    }
    cnt1 = cnt2;
    ThreadOp.sleep( 1000 );

    /* Check for command. */
    if( data->consoleMode )
      __checkConsole( data );
  };

  return 0;
}
/* --------- */
int
__parseCommandLine(Luna *self, int argCount, char *argList[])
{
	int  ndx         = 0;
	char *cmdLineArg = 0;
	char hostName[256];
	char *separator, *destination;

	if (!self) { return 0; }

	/* help */
	if (argCount < 2) {
		__help(argList[0]);
		return 0;
	}
	if (!strncmp(argList[1], "-h", 2) || !strncmp(argList[1], "--help", 6)) {
		__help(argList[0]); return 0; }

	/* set destination */
	if (!strncmp(argList[1], "-", 1)) {
		printf("Missing destination host.\n%s\n", LUNA_HAIKU_6); return 0; }

	if ((separator = strchr(argList[1], '@')) != NULL) {
		destination = separator + 1;

		ndx = (strlen(argList[1]) - strlen(destination)) - 1; // ndx == length
		if ((self->_user = malloc(ndx + 1)) == NULL) { return 0; }
		strncpy(self->_user, argList[1], ndx);
		self->_user[ndx + 1] = '\0';
	} else {
		destination = argList[1];
	}
	self->_destination = Luna_resolve(destination);
	if (!self->_destination) {
		printf("Unable to set destination host.\n%s\n", LUNA_HAIKU_5); return 0; }

	/* set options */
	for (ndx = 2; ndx < argCount; ++ndx) {
		cmdLineArg = argList[ndx];
		
		if (strncmp(argList[ndx], "-", 1)) { continue; }
		
		/* set source ip address */
		CASE("-s", "--source")
			CHECKARG
			self->_source = Luna_resolve(argList[++ndx]);
			if (!self->_source) {
				printf("Unable to set source host.\n%s\n", LUNA_HAIKU_5); return 0; }
		ESAC
		
		/* set device */
		CASE("-d", "--device")
			CHECKARG
			self->_device = argList[++ndx];
		ESAC
		
		/* set fork mode */
		CASE("-f", "--fork")
			self->_fork = 1;
		ESAC
		
		/* set datagram size */
		CASE("-g", "--datagram-size")
			CHECKARG
			self->_datagramSize = atoi(argList[++ndx]);

		ESAC
		
		/* set max time lapse */
		CASE("-l", "--max-time-lapse")
			CHECKARG
			self->_maxTimeLapse = atoi(argList[++ndx]);
		ESAC
		
		/* set verbosity */
		CASE("-v", "--verbose")
			self->_verbose = 1;
		ESAC

		/* help */
		CASE("-h", "--help")
			__help(argList[0]);
			return 0;
		ESAC

		printf("\nUnrecognizeable argument: %s\n%s\n", argList[ndx], LUNA_HAIKU_6);
		return 0;
	}

	/* set default values */
	if (!self->_source) {
		gethostname(hostName, 256);
		self->_source = Luna_resolve(hostName);
		if (!self->_source) {
			printf("Unable to determine source host; please manually specify the source with '-s'.\n%s\n", 
				LUNA_HAIKU_2); 
			return 0; 
		}
	}

	if (!self->_device) {
		self->_device = pcap_lookupdev((char *)NULL);
		if (!self->_device) {
			self->_device = DEFAULT_DEVICE;
		}
	}
	return 1;
}