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

📄 log.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- Mode: C++; -*-//                          Package   : omniNames// log.cc                   Author    : Tristan Richardson (tjr)////    Copyright (C) 1997-1999 AT&T Laboratories Cambridge////  This file is part of omniNames.////  omniNames 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 <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <time.h>#include <fcntl.h>#if defined(__VMS) && __VMS_VER < 70000000#  include <omniVMS/unlink.hxx>#  include <omniVms/utsname.hxx>#endif#include <NamingContext_i.h>#include <ObjectBinding.h>#include <INSMapper.h>#include <log.h>#ifdef HAVE_STD#  include <iostream>#  include <iomanip>   using namespace std;#else#  include <iostream.h>#  include <iomanip.h>#endif#ifdef __WIN32__#  include <io.h>#  include <winbase.h>#  define stat(x,y) _stat(x,y)#  define unlink(x) _unlink(x)#else#  include <unistd.h>#  include <sys/utsname.h>#endif#if defined(__nextstep__)#  include <libc.h>#  include <sys/param.h>#endif#ifndef O_SYNC#  ifdef  O_FSYNC              // FreeBSD 3.2 does not have O_SYNC???#    define O_SYNC O_FSYNC#  endif#endif#ifdef HAVE_STD#  define USE_STREAM_OPEN#  define OPEN(name,mode,perm) open(name,mode)#elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500#  define USE_STREAM_OPEN#  define OPEN(name,mode,perm) open(name,mode,perm)#elif defined(__DMC__)#  define USE_STREAM_OPEN#  define OPEN(name,mode,perm) open(name,mode,perm)#elif defined(__ICC)#  define USE_STREAM_OPEN#  define OPEN(name,mode,perm) open(name,mode,perm)#endif#ifndef HAVE_STRDUP// we have no strdupstatic char *strdup (char* str){  char *newstr;  newstr = (char *) malloc (strlen (str) + 1);  if (newstr)    strcpy (newstr, str);  return newstr;}#endif  // not HAVE_STRDUPstaticinline void reallyFlush(ofstream& f) {    f.flush();#ifdef needsExplicitFsync    ::fsync(f.rdbuf()->fd());#endif}extern void usage();//// This class can be used to generate timestamps.  The t() method normally// returns a timestamp string, but if the same timestamp (to the nearest// second) would be returned as last time then an empty string is returned// instead.//class timestamp {  char str[29];public:  timestamp(void) {    str[0] = '\n';    str[1] = str[28] = '\0';  }  char* t(void) {    time_t t = time(NULL);    char *p = ctime(&t);    if (strncmp(p, &str[1], 24) == 0) {      return &str[28];    }    strncpy(&str[1], p, 24);    str[25] = ':';    str[26] = '\n';    str[27] = '\n';    return str;  }};timestamp ts;//// Constructor for class omniNameslog.  There will normally be only one// instance of this class.  Unfortunately the initialisation of the class// cannot be completed in the constructor - the rest is done in the init()// member function.  This is because the main program cannot give us// pointers to the ORB and the BOA until it has worked out which port to// listen on, but it normally finds out the port from the log file.  So in// this constructor we initialise as much as we can, find out the port from// the log file if there is one and return.  Then the main program// initialises the ORB and the BOA and calls init().//omniNameslog::omniNameslog(int& p,char* logdir) : port(p){  startingUp = 1;  checkpointNeeded = 1;  line = 1;#ifdef __WIN32__  struct _stat sb;#else  struct stat sb;#endif  if (!logdir && (logdir = getenv(LOGDIR_ENV_VAR)) == NULL)    logdir = strdup(DEFAULT_LOGDIR);#if !defined(__WIN32__) && !defined(__VMS)  if (logdir[0] != '/') {    cerr << ts.t() << "Error: " << LOGDIR_ENV_VAR << " (" << logdir	 << ") is not an absolute path name." << endl;    exit(1);  }  if (logdir[strlen(logdir)-1] == '/') {    logdir[strlen(logdir)-1] = '\0';		// strip trailing '/'  }#ifdef HAVE_UNAME  struct utsname un;  if (uname(&un) < 0) {    cerr << ts.t() << "Error: cannot get the name of this host." << endl;	    exit(1);  }  char* logname = new char[strlen(logdir) + strlen("/omninames-")			   + strlen(un.nodename) + 1];  sprintf(logname, "%s/omninames-%s", logdir, un.nodename);#elif HAVE_GETHOSTNAME  // Apparently on some AIX versions, MAXHOSTNAMELEN is too small (32) to  // reflect the true size a hostname can be. Check and fix the value.#ifndef MAXHOSTNAMELEN#  define MAXHOSTNAMELEN 256#elif   MAXHOSTNAMELEN < 64#  undef  MAXHOSTNAMELEN#  define MAXHOSTNAMELEN 256#endif  char hostname[MAXHOSTNAMELEN+1];  if (gethostname(hostname, MAXHOSTNAMELEN) < 0) {    cerr << ts.t() << "Error: cannot get the name of this host." << endl;	    exit(1);  }  char* logname = new char[strlen(logdir) + strlen("/omninames-")			   + strlen(hostname) + 1];  sprintf(logname, "%s/omninames-%s", logdir, hostname);#endif // HAVE_UNAME#elif defined(__WIN32__)  // Get host name:  DWORD machineName_len = MAX_COMPUTERNAME_LENGTH+1;  char* machineName = new char[machineName_len];  if (!GetComputerName((LPTSTR) machineName, &machineName_len)) {    cerr << ts.t() << "Error: cannot get the name of this host." << endl;	    exit(1);  }  char* logname = new char[strlen(logdir) + strlen("\\omninames-")			   + strlen(machineName) + 1];  sprintf(logname, "%s\\omninames-%s", logdir, machineName);    delete[] machineName;#else // VMS  char last(    logdir[strlen(logdir)-1]  );  if (last != ':' && last != ']') {    cerr << ts.t() << "Error: " << LOGDIR_ENV_VAR << " (" << logdir         << ") is not a directory name." << endl;    exit(1);  }//  if (logdir[strlen(logdir)-1] == '/') {//    logdir[strlen(logdir)-1] = '\0';          // strip trailing '/'//  }  struct utsname un;  if (uname(&un) < 0) {    cerr << ts.t() << "Error: cannot get the name of this host." << endl;            exit(1);  }  char* logname = new char[strlen(logdir) + strlen("/omninames-")                           + strlen(un.nodename) + 1];  sprintf(logname, "%somninames-%s", logdir, un.nodename);#endif#ifndef __VMS  active = new char[strlen(logname)+strlen(".log")+1];  sprintf(active,"%s.log",logname);  backup = new char[strlen(logname)+strlen(".bak")+1];  sprintf(backup,"%s.bak",logname);  checkpt = new char[strlen(logname)+strlen(".ckp")+1];  sprintf(checkpt,"%s.ckp",logname);#else  // specify latest version:  active = new char[strlen(logname)+strlen(".log;")+1];  sprintf(active,"%s.log;",logname);  backup = new char[strlen(logname)+strlen(".bak;")+1];  sprintf(backup,"%s.bak;",logname);  checkpt = new char[strlen(logname)+strlen(".ckp;")+1];  sprintf(checkpt,"%s.ckp;",logname);#endif  delete [] logname;  if (port != 0) {    //    // Starting for the first time - make sure log file doesn't exist, and    // for safety, that there is no backup file either.    //    firstTime = 1;    if (stat(active,&sb) == 0) {      cerr << ts.t() << "Error: log file '" << active	   << "' exists.  Can't use -start option." << endl;      exit(1);    }    if (stat(backup,&sb) == 0) {      cerr << ts.t() << "Error: backup file '" << backup	   << "' exists.  Can't use -start option." << endl;      exit(1);    }  } else {    //    // Restart - get port info from log file.    //    firstTime = 0;#ifdef __WIN32__    ifstream initf(active,ios::in);#else    ifstream initf(active);#endif    if (!initf) {      cerr << ts.t() << "Error: cannot open log file '" << active << "'."	   << endl;      if (stat(backup,&sb) == 0) {	cerr << "Info: backup file '" << backup << "' exists." << endl	     << "This must be removed if you want to use the -start option."	     << endl;      }      usage();    }    try {      getPort(initf);    } catch (IOError&) {      cerr << ts.t() << "Error: reading log file '" << active << "' failed: "	   << flush;      perror("");      initf.close();      exit(1);    } catch (ParseError&) {      cerr << ts.t() << "Error: parse error in log file '" << active	   << "' at line " << line << "." << endl;      initf.close();      exit(1);    }    p = port;    initf.close();  }}voidomniNameslog::init(CORBA::ORB_ptr          the_orb,		   PortableServer::POA_ptr the_poa,		   PortableServer::POA_ptr the_ins_poa){  orb     = the_orb;  poa     = the_poa;  ins_poa = the_ins_poa;  if (firstTime) {    //    // starting for the first time - create an initial log file with the    // port specification and the root context.    //    cerr << ts.t() << "Starting omniNames for the first time." << endl;    try {#ifdef USE_STREAM_OPEN      logf.OPEN(active,ios::out|ios::trunc,0666);      if (!logf)	throw IOError();#else#  ifdef __WIN32__      int fd = _open(active, O_WRONLY | O_CREAT | O_TRUNC, _S_IWRITE);#  else      int fd = open(active, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0666);#  endif      if (fd < 0)	throw IOError();      logf.attach(fd);#endif      putPort(port, logf);      reallyFlush(logf);      {	PortableServer::ObjectId_var refid =	  PortableServer::string_to_ObjectId("NameService");	putCreate(refid, logf);      }      logf.close();      if (!logf)	throw IOError();// a bug in sparcworks C++ means that the fd doesn't get closed.#if defined(__sunos__) && defined(__SUNPRO_CC) && __SUNPRO_CC < 0x500      if (close(fd) < 0)	throw IOError();#endif    } catch (IOError& ex) {      cerr << ts.t() << "Error: cannot create initial log file '" << active	   << "': " << endl;      perror("");      cerr << "\nYou can set the environment variable " << LOGDIR_ENV_VAR	   << " to specify the\ndirectory where the log files are kept.\n"	   << endl;      logf.close();      unlink(active);      exit(1);    }    cerr << ts.t() << "Wrote initial log file." << endl;  }  // claim the global lock as a writer (ie exclusive).  NamingContext_i::lock.writerIn();  ifstream initf(active);  if (!initf) {    cerr << ts.t() << "Error: cannot open log file '" << active << "'."	 << endl;    exit(1);  }  try {    line = 1;    while (initf && (initf.peek() != EOF)) {      char* cmd;      getNonfinalString(cmd, initf);      if (strcmp(cmd, "port") == 0) {	while (initf && (initf.get() != '\n'));	// ignore rest of line	line++;      } else if (strcmp(cmd, "create") == 0) {	getCreate(initf);      } else if (strcmp(cmd, "destroy") == 0) {	getDestroy(initf);      } else if (strcmp(cmd, "bind") == 0) {	getBind(initf);      } else if (strcmp(cmd, "unbind") == 0) {	getUnbind(initf);      } else {	cerr << ts.t() << "Error: unknown command '" << cmd	     << "' in log file '" << active << "'." << endl;	throw ParseError();      }      delete [] cmd;    }    initf.close();  } catch (IOError&) {    cerr << ts.t() << "Error: reading log file '" << active << "' failed: "	 << flush;    perror("");    initf.close();    exit(1);  } catch (ParseError&) {    cerr << ts.t() << "Error: parse error in log file '" << active	 << "' at line " << line << "." << endl;    initf.close();    exit(1);  }  cerr << ts.t() << "Read log file successfully." << endl;  CosNaming::NamingContext_ptr rootContext    = NamingContext_i::headContext->_this();  {    // Check to see if we need an INS forwarding agent    omniIOR_var ior;    ior = rootContext->_getIOR();    IIOP::ProfileBody iiop;    const IOP::TaggedProfileList& profiles = ior->iopProfiles();    for (CORBA::ULong index = 0; index < profiles.length(); index++) {      if (profiles[index].tag == IOP::TAG_INTERNET_IOP) {	IIOP::unmarshalProfile(profiles[index],iiop);	break;      }    }    if (strncmp((const char*)iiop.object_key.get_buffer(),		"NameService", 11)) {      cerr << ts.t() << "(Pre-INS log file)" << endl;      new INSMapper(the_ins_poa, rootContext);    }  }  char* p = orb->object_to_string(rootContext);  cerr << ts.t() << "Root context is " << p << endl;  // Now use the backdoor to tell the bootstrap agent in this  // address space to return this root context in response to  // CORBA::InitialReferences::get("NameService");  _omni_set_NameService(rootContext);  delete p;  CORBA::release(rootContext);	// dispose of the object reference#ifdef USE_STREAM_OPEN  logf.OPEN(active,ios::out|ios::app,0666);  if (!logf) {    cerr << ts.t() << "Error: cannot open log file '" << active	 << "' for writing." << endl;    exit(1);  }#else#  ifdef __WIN32__  int fd = _open(active, O_WRONLY | O_APPEND);#  else  int fd = open(active, O_WRONLY | O_APPEND | O_SYNC);#  endif  if (fd < 0) {    cerr << ts.t() << "Error: cannot open log file '" << active	 << "' for writing." << endl;    exit(1);  }  logf.attach(fd);#endif  startingUp = 0;  NamingContext_i::lock.writerOut();  // remove checkpoint. This will protect us from trouble if the previous  // incarnation crashed during checkpointing and at the  // time when both active and checkpoint are linked to the same file.  unlink(checkpt);}voidomniNameslog::create(const PortableServer::ObjectId& id){  if (!startingUp) {    try {      putCreate(id, logf);      reallyFlush(logf);    } catch (IOError& ex) {      cerr << ts.t() << flush;      perror("I/O error writing log file");      logf.clear();      throw CORBA::PERSIST_STORE();    }    checkpointNeeded = 1;  }}voidomniNameslog::destroy(CosNaming::NamingContext_ptr nc){  if (!startingUp) {    try {      putDestroy(nc, logf);      reallyFlush(logf);    } catch (IOError& ex) {      cerr << ts.t() << flush;      perror("I/O error writing log file");      logf.clear();      throw CORBA::PERSIST_STORE();    }    checkpointNeeded = 1;  }}voidomniNameslog::bind(CosNaming::NamingContext_ptr nc, const CosNaming::Name& n,	  CORBA::Object_ptr obj, CosNaming::BindingType t){  if (!startingUp) {    try {      putBind(nc, n, obj, t, logf);      reallyFlush(logf);    } catch (IOError& ex) {      cerr << ts.t() << flush;      perror("I/O error writing log file");      logf.clear();      throw CORBA::PERSIST_STORE();    }    checkpointNeeded = 1;  }}voidomniNameslog::unbind(CosNaming::NamingContext_ptr nc, const CosNaming::Name& n){  if (!startingUp) {    try {      putUnbind(nc, n, logf);      reallyFlush(logf);    } catch (IOError& ex) {      cerr << ts.t() << flush;      perror("I/O error writing log file");      logf.clear();

⌨️ 快捷键说明

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