示例#1
0
/******************************************************************************
* 函数名称	:  TMdbDAOLoad()
* 函数描述	:  获取Oracle链接项
* 输入		:  pConfig,配置参数
* 输出		:  无
* 返回值	:  无
* 作者		:  li.shugang
*******************************************************************************/
TMdbDAOLoad::TMdbDAOLoad(TMdbConfig *pConfig)
{
    TADD_FUNC("Start.");
    if(NULL == pConfig)
    {
        TADD_ERROR(ERR_APP_INVALID_PARAM,"pConfig is null");
    }
    memset(m_sSQL, 0, sizeof(m_sSQL));
    memset(m_sCkFieldSQL, 0, sizeof(m_sCkFieldSQL));
    memset(m_sDSN, 0, sizeof(m_sDSN));
    memset(m_sUID, 0, sizeof(m_sUID));
    memset(m_sPWD, 0, sizeof(m_sPWD));
    memset(m_sMSQL, 0, sizeof(m_sMSQL));
    memset(m_sQMSQL,0,sizeof(m_sQMSQL));
    memset(m_sUpdateSQL,0,sizeof(m_sUpdateSQL));
    m_pDBLink = NULL;   //链接
    m_pOraQuery  = NULL;   //动作
    m_pInsertQuery = NULL;
    m_pCheckQuery = NULL;
    m_pUpdateQuery = NULL;
    m_pTable = NULL;
    m_pShmDSN = NULL;
    m_iSeqCacheSize = pConfig->GetDSN()->m_iSeqCacheSize;
    SAFESTRCPY(m_sDSN,sizeof(m_sDSN),pConfig->GetDSN()->sOracleID);
    SAFESTRCPY(m_sUID,sizeof(m_sUID),pConfig->GetDSN()->sOracleUID);
    SAFESTRCPY(m_sPWD,sizeof(m_sPWD),pConfig->GetDSN()->sOraclePWD);
    //--HH--m_cType = pConfig->GetDSN()->cType;
    
    TADD_FUNC("Finish.");
}
示例#2
0
	/******************************************************************************
	* 函数名称	:  GetFreePage
	* 函数描述	: 获取自由页
	* 输入		:  
	* 输出		:  
	* 返回值	:  0 - 成功!0 -失败
	* 作者		:  jin.shaohua
	*******************************************************************************/
	int TMdbTableCtrl::GetFreePage(TMdbPage * & pFreePage)
	{
		TADD_FUNC("Start,");
		int iRet = 0;
		CHECK_OBJ(m_pTable);
		pFreePage = NULL;
		//TODO:加锁
		int iFreePageID = m_pTable->m_iFreePageID;
		TADD_DETAIL("iFreePageID=[%d]",iFreePageID);
		do{
			if(iFreePageID > 0)
			{//有自由页
				if((pFreePage = m_tTSCtrl.GetPage(iFreePageID)) == NULL)
				{
					CHECK_RET_BREAK(ERR_OS_NO_MEMROY,"GetPage[%d] failed",iFreePageID);
				}
			}
			else
			{//没有自由页了
				TADD_DETAIL("no free pages");
				CHECK_RET_BREAK(m_tTSCtrl.GetEmptyPage(pFreePage),"GetEmptyPage failed");
				if(NULL != pFreePage)
				{
					CHECK_RET_BREAK(AddPageToTop(pFreePage,m_pTable->m_iFreePageID),"AddPageToTop failed.");
					SAFESTRCPY(pFreePage->m_sState,sizeof(pFreePage->m_sState),"free");//修改状态

					pFreePage->m_iRecordSize = 0;//TODO:从表空间获取页的时候才确定这个页中记录大小
					m_pTable->m_iFreePages ++;
					pFreePage->m_iNextPageID = m_pTable->m_iTablePageID;
					m_pTable->m_iTablePageID = pFreePage->m_iPageID;
				}
			}
		}while(0);
		return iRet;
	}
/*
** Returns 1 or 0 depending on whether or not the host described by #host# can
** be verified to be name server within #timeOut# seconds.
*/
static int
IsANameServer(const struct host_desc *host,
              double timeOut) {

  struct host_cookie hostCookie;
  HostInfo hostInfo;
  char hostName[127 + 1];

  SAFESTRCPY(hostName, HostDImage(host));
  MakeHostCookie(host->host_name, host->port, &hostCookie);

  if(!ConnectToHost(&hostCookie, &hostCookie.sd)) {
    FAIL1("IsANameServer: unable to contact %s\n", hostName);
  }

  if(DoTestHost(hostCookie.sd, &hostInfo, timeOut) != HEALTHY) {
    DisconnectHost(&hostCookie);
    FAIL1("IsANameServer: unable to verify that %s is a name server\n",
          hostName);
  }

  DisconnectHost(&hostCookie);

  if(strcmp(hostName, hostInfo.nameServer) != 0) {
    FAIL1("IsANameServer: %s is not a name server\n", hostName);
  }

  return(1);

}
示例#4
0
//解析命令行参数
int ParseParam(int argc, char* argv[],char *pDSN,const int iDsnLen)
{
    //定义参数格式和选项
    CommandLineParser clp(argc, argv);
    clp.set_check_condition("-H", 0);
    clp.set_check_condition("-h", 0);
    clp.set_check_condition("-c", 1);
    clp.check();

    const vector<CommandLineParser::OptArgsPair>& pairs = clp.opt_args_pairs();
    vector<CommandLineParser::OptArgsPair>::const_iterator it;
    for (it = pairs.begin(); it != pairs.end(); ++it)
    {
        const string& opt = (*it)._first;
        const vector<string>& args = (*it)._second;
        if(opt == "-h" || opt == "-H")
        {
            Help(argc,argv);
            return -1;
        }
        if(opt == "-c")
        {
            SAFESTRCPY(pDSN,iDsnLen,args[0].c_str());
            pDSN[strlen(pDSN)] = '\0';
            continue;
        }
    }
    if(strlen(pDSN) == 0)
    {
        Help(argc,argv);
        return -1;
    }
    return 0;
}
/*
** A "local" function of ProcessRequest().  Implements the MEMORY_CLEAN service
** by deleting all files in the memory directory that have not been accessed
** within the past #idle# seconds.  Returns 1 if successful, else 0.
*/
static int
DoClean(unsigned long idle) {

  struct dirent *entry;
  DIR *directory;
  time_t expiration;
  char filePath[255 + 1];
  struct stat fileStat;
  char *namePlace;

  directory = opendir(memoryDir);
  if(directory == NULL) {
    FAIL1("DoClean: unable to open directory %s\n", memoryDir);
  }

  expiration = (time_t)CurrentTime() - (time_t)idle;
  SAFESTRCPY(filePath, memoryDir);
  namePlace = filePath + strlen(filePath);

  while((entry = readdir(directory)) != NULL) {
    strcpy(namePlace, entry->d_name);
    if(stat(filePath, &fileStat) != 0) {
      WARN1("DoClean: unable to state file %s\n", filePath);
    }
    else if(fileStat.st_mtime < expiration) {
      LOG2("DoClean: deleting %s, last modified %d\n",
           filePath, fileStat.st_mtime);
      (void)unlink(filePath);
    }
  }

  (void)closedir(directory);
  return(1);

}
示例#6
0
//解析连接字符串,分出dsn,uid,pwd
int ParseQmdbOper(const char * sOperStr,char* dsn, char* uid, char* pwd, int iSize)
{
    int iRet = 0;
    TMdbNtcSplit tSplit;
    tSplit.SplitString(sOperStr,';');
    int i = 0;
    const char * sPrefix[] = {"dsn=","uid=","pwd="};
    int iCount = 3;
    char * sContextAddr[] = {dsn,uid,pwd};
    for(i = 0;i < tSplit.GetFieldCount() ;++i)
    {
        int j = 0;
        for(j = 0 ;j < iCount;++j)
        {
            if(TMdbNtcStrFunc::StrNoCaseCmp(tSplit[i],sPrefix[j],strlen(sPrefix[j])) == 0)
            {//前缀相同
                SAFESTRCPY(sContextAddr[j],iSize,tSplit[i]+strlen(sPrefix[j]));
                break;
            }
        }
        if(j == iCount)
        {
            printf("[%s] is error\n",tSplit[i]);
            return ERR_APP_INVALID_PARAM;
        }
    }
    
    return iRet;
}
示例#7
0
int main(int argc, char* argv[])
{   
    int iRet = 0;
    if(argc < 3 || strcmp(argv[1],"-h")==0||strcmp(argv[1],"-H")==0)
    {    
        printf("-------\n"
                " Usage:\n"
                "   %s <DsnName> <Filename>\n"
                "   %s [ -H | -h ] \n"
                " Example:\n" 
                "   %s R12 /ztesoft/data/mdbr12/Insert_Ora.201201011212\n"              
                " Note:\n"
                "     <DsnName>: dsn name.\n"
                "     <Filename>: filename with full path to parse.\n"
                "     -H|-h Print Help.\n"
                "-------\n",argv[0],argv[0],argv[0]);
        return 0;
    }
    
    

    //设置程序名
    char sProcName[1024];
    memset(sProcName, 0, sizeof(sProcName));
    SAFESTRCPY(sProcName,sizeof(sProcName),argv[0]);
   
    TADD_START(argv[1],  sProcName, 0, false, false);  
    try
    {
        mdbReadOraLog oraLog;
        iRet = oraLog.Init(argv[1]); 
        if(iRet < 0)
        {
            TADD_ERROR(ERROR_UNKNOWN,"oraLog.Init(%s) error!\n", argv[1]);  
            return -1;  
        }
        
        oraLog.ParseLogFile(argv[2]);
    }
    catch(TMdbException& e)
    {
        TADD_ERROR(ERROR_UNKNOWN,"ERROR_SQL=%s.\nERROR_MSG=%s\n.",  e.GetErrSql(), e.GetErrMsg());
    }
    catch(TMDBDBExcpInterface &e)
    {
        TADD_ERROR(ERROR_UNKNOWN,"ERROR_SQL=%s.\nERROR_MSG=%s\n.", e.GetErrSql(), e.GetErrMsg());
    }
    catch(...)
    {
        TADD_ERROR(ERROR_UNKNOWN,"Unknown error!\n");       
    }
    //TADD_END();
    return 0;   
}
示例#8
0
main(int argc, char **argv)
{
  size_t size = strlen(argv[3]);
  char *buffer = (char *)malloc(1024);

#ifdef PARANOID
  SAFESTRCPY(buffer, argv[3], size+sizeof(char));
#else
  FASTSTRCPY(buffer, argv[3], size+sizeof(char));
#endif  
}
示例#9
0
	/******************************************************************************
	* 函数名称	:  TablePageFullToFree
	* 函数描述	:  页从满链到自由链
	* 输入		:  
	* 输出		:  
	* 返回值	:  0 - 成功!0 -失败
	* 作者		:  jin.shaohua
	*******************************************************************************/
	int TMdbTableCtrl::TablePageFullToFree(TMdbPage* pCurPage)
	{
		TADD_FUNC("Start.");
		int iRet = 0;
		//从full链上移除
		CHECK_RET(RemovePage(pCurPage,m_pTable->m_iFullPageID),"RemovePage failed.");
		//添加到free链上
		CHECK_RET(AddPageToTop(pCurPage,m_pTable->m_iFreePageID),"AddPageToTop failed.");
		//把状态设置为free
		SAFESTRCPY(pCurPage->m_sState, sizeof(pCurPage->m_sState),"free");
		--m_pTable->m_iFullPages;
		++m_pTable->m_iFreePages;
		TADD_FUNC("Finish.");
		return iRet;
	}
示例#10
0
	/******************************************************************************
	* 函数名称	:  TablePageFreeToFull
	* 函数描述	: 页从自由链到满链
	* 输入		:  
	* 输出		:  
	* 返回值	:  0 - 成功!0 -失败
	* 作者		:  jin.shaohua
	*******************************************************************************/
	int TMdbTableCtrl::TablePageFreeToFull(TMdbPage* pCurPage)
	{
		int iRet = 0;
		TADD_FUNC("Start.");
		//从free链上移除
		CHECK_RET(RemovePage(pCurPage,m_pTable->m_iFreePageID),"RemovePage failed.");
		//添加到full链上
		CHECK_RET(AddPageToTop(pCurPage,m_pTable->m_iFullPageID),"AddPageToTop failed.");
		TADD_DETAIL("Cur-Page-ID=%d, NextPageID=%d, PrePageID=%d.", pCurPage->m_iPageID, pCurPage->m_iPrePageID, pCurPage->m_iNextPageID);
		//把状态设置为full
		SAFESTRCPY(pCurPage->m_sState,sizeof(pCurPage->m_sState), "full");
		++m_pTable->m_iFullPages;
		--m_pTable->m_iFreePages;
		TADD_FUNC("Finish.");
		return iRet;
	}
int DoLogNetLogger(Socket sd, const char* phost, double timeOut)
{ 
  size_t ignored;
  struct loglocation nsMemLog;
  nsMemLog.loc_type = MEMORY_LOG_NETLOGGER;
  SAFESTRCPY(nsMemLog.path,phost);
  return(SendMessageAndData(sd,
                            MEMORY_LOGDEST,
                            &nsMemLog,
                            loglocationDescriptor,
                            loglocationDescriptorLength,
                            timeOut) &&
         RecvMessage(sd, MEMORY_LOGDEST_ACK, &ignored, timeOut));

  
}
示例#12
0
int TMdbOnlineRepQueue::Init(TMdbOnlineRepMemQueue * pOnlineRepMemQueue,TMdbDSN * pDsn, const bool bWriteErrorData)
{
    int iRet = 0;
    if(m_pszRecord == NULL)
    {
        m_pszRecord = new char[MAX_VALUE_LEN];
        CHECK_OBJ(m_pszRecord);
        memset(m_pszRecord,0,MAX_VALUE_LEN);
    }
    if(m_pszErrorRecord == NULL)
    {
        m_pszErrorRecord = new char[MAX_VALUE_LEN];
        CHECK_OBJ(m_pszErrorRecord);
        memset(m_pszErrorRecord,0,MAX_VALUE_LEN);
    }
	m_bWriteErrorData = bWriteErrorData;
    m_pOnlineRepQueueShm = pOnlineRepMemQueue;
    m_pDsn = pDsn;
    CHECK_OBJ(m_pOnlineRepQueueShm);
    CHECK_OBJ(m_pDsn);
    //对于REP和ORACLE同步区需要记录异常文件
    char sErrorLogPath[MAX_PATH_NAME_LEN] = {0};
    memset(sErrorLogPath, 0, sizeof(sErrorLogPath));
    char sDsnName[MAX_NAME_LEN] = {0};
    SAFESTRCPY(sDsnName, sizeof(sDsnName), m_pDsn->sName);
    TMdbNtcStrFunc::ToLower(sDsnName);
#ifdef WIN32
    snprintf(sErrorLogPath, sizeof(sErrorLogPath), "%s\\log\\%s\\", getenv("QuickMDB_HOME"), sDsnName);
#else
    snprintf(sErrorLogPath, sizeof(sErrorLogPath), "%s/log/%s/", getenv("QuickMDB_HOME"), sDsnName);
#endif
    if(!TMdbNtcDirOper::IsExist(sErrorLogPath))
    {
        TMdbNtcDirOper::MakeFullDir(sErrorLogPath);
    }
    snprintf(m_sFileName,sizeof(m_sFileName),"%sRep_Error_Info_%d.log",\
        sErrorLogPath,TMdbOS::GetPID());
    TADD_DETAIL("ERROR_LOG=[%s].",m_sFileName);
    return iRet;
}
示例#13
0
 //设置观测点
 int SetObservePoint(char* argv[])
 {
     int iRet = 0;
     char * sDsn = argv[1];
     TMdbShmDSN * pShmDsn = TMdbShmMgr::GetShmDSN(sDsn);
     CHECK_OBJ(pShmDsn);
     TObservePoint * pObPoint = pShmDsn->GetObPiontByName(argv[2]);
     CHECK_OBJ(pObPoint);
     TObserveMgr  tObMgr;
     TObserveBase * pBase = tObMgr.GetObserveInst(pObPoint->m_iType);
     CHECK_OBJ(pBase);
     CHECK_RET(pBase->Init(sDsn,pObPoint->m_iType),"int[%s,%d] error.",sDsn,pObPoint->m_iType);
     TADD_NORMAL("Parse param[%s]",argv[4]);
     //先检测参数
     CHECK_RET(pBase->ParseParam(argv[4]),"parse Param[%s] error.",argv[4]);
     SAFESTRCPY(pObPoint->m_sParam,sizeof(pObPoint->m_sParam),argv[4]);
     //检测结束时间
     if(TMdbNtcStrFunc::IsDigital(argv[3]))
     {
         long long  llObSec = TMdbNtcStrFunc::StrToInt(argv[3]);
         if(llObSec <= 0)
         {//停止观测
             pBase->StopObServe();
         }
         else
         {//设置观测时间
             gettimeofday(&(pObPoint->m_tTerminal), NULL);
             pObPoint->m_tTerminal.tv_sec += llObSec;
         }
     }
     else
     {
         CHECK_RET(ERR_APP_INVALID_PARAM,"End-time[%s] is error.",argv[3]);
     }
     ShowObservePoint(argv);
     return iRet;
 }
示例#14
0
int main(int argc, char* argv[])
{
    int iRet = 0;
    if(argc < 2 || strcmp(argv[1],"-h")==0||strcmp(argv[1],"-H")==0)
    {
        Help();
        return iRet;
    }
	bool bShowObject = false;
	bool bIncSystable = false;
	char sTypeName[128] = {0};
	char sConStr[256] = {0};
	
    char sDsn[32] = {0};
	char sUid[32] = {0};
	char sPwd[32] = {0};
	
    //定义参数格式和选项
    CommandLineParser clp(argc, argv);
    //clp.set_check_condition("", 7);					// 指定程序的参数个数
    // 指定选项的参数个数,下同
	clp.set_check_condition("-l", 0);

	clp.set_check_condition("-h", 0);
	
	clp.set_check_condition("-n", 1);
	clp.set_check_condition("-s", 0);
	clp.set_check_condition("-c", 1);

	
	
    if(clp.check() == false)
	{
    	Help();
        return 0;
	}
	
	
    const std::vector<CommandLineParser::OptArgsPair>& pairs = clp.opt_args_pairs();
	std::vector<CommandLineParser::OptArgsPair>::const_iterator it;

	
	for (it = pairs.begin(); it != pairs.end(); ++it)
	{
		const string& opt = (*it)._first;
		const std::vector<string>& args = (*it)._second;
		
		if(opt == "-l")
		{
			
           bShowObject = true;
			continue;
		}
		if(opt == "-h" || opt == "-H")
		{
        	Help();
        	return 0;
		}
		if(opt == "-c")
		{
            SAFESTRCPY(sConStr,sizeof(sConStr),args[0].c_str());
			sConStr[strlen(sConStr)] = '\0';
			continue;
		}
        if(opt == "-n")
		{
            SAFESTRCPY(sTypeName,sizeof(sTypeName),args[0].c_str());
			sTypeName[strlen(sTypeName)]='\0';
            continue;
		}
        if(opt == "-s")
		{
           bIncSystable =true;
            continue;
		}
		
       
    
        
    }

	//if(bShowObject && sTypeName[0] != 0)
	//{
	//	TADD_ERROR(ERR_APP_INVALID_PARAM,"can't show object names and export ddl at the same time,the cmd option is invalid");
	//	return 0;

	//}

	CHECK_RET(ParseQmdbOper(sConStr,sDsn,sUid,sPwd,32),"the connection str is invalid");
	CHECK_RET(CheckConStrValid(sDsn,sUid,sPwd),"the user is invaid for this dsn");
	
	

    TADD_START(sDsn,"mdbSchema",0,false,false);
    TADD_NORMAL("[BEGIN]");
    
    CHECK_RET(ExptDDL(sDsn,bShowObject,bIncSystable,sTypeName),"ExptDDL failed");
    TADD_NORMAL("[END]");
    return 0;
}
示例#15
0
int main(int argc, char* argv[])
{
    //Process::SetProcessSignal();
    int iRet = 0;
    char sDsn[16];
    memset(sDsn,0,sizeof(sDsn));
    if(argc == 1)
    {
        Help(argc,argv);
        return iRet;
    }
    CHECK_RET(ParseParam(argc,argv,sDsn,sizeof(sDsn)),"Analytical parameter error.");
    //----------------------------------------------------------
    
#ifndef WIN32
    TADD_START(sDsn,"mdbStartCheck", 0,true,false);
#endif

    TMdbConfig *pConfig = TMdbConfigMgr::GetMdbConfig(sDsn);
    CHECK_OBJ(pConfig);
    
    //获取路径信息
    char sLogPath[MAX_PATH_NAME_LEN];
    memset(sLogPath, 0, sizeof(sLogPath));
    SAFESTRCPY(sLogPath,sizeof(sLogPath),pConfig->GetDSN()->sLogDir);
    if(sLogPath[strlen(sLogPath)-1] != '/')
    {
        sLogPath[strlen(sLogPath)] = '/';
    }
    sLogPath[strlen(sLogPath)] = '\0';

     //检查文件Insert_Ora和Ora0、Ora1 ...,size为0则删除,否则重命名为.OK文件 
    char sFileOra[MAX_PATH_NAME_LEN];
    char sFileOraNew[MAX_PATH_NAME_LEN];
    char sTime[MAX_TIME_LEN];
    memset(sTime,0,MAX_TIME_LEN);
    MDB_UINT64 iFileSize = 0;
    int iOraRepCount = pConfig->GetDSN()->iOraRepCounts;
    for (int i = -1; i<iOraRepCount; i++)
    {
        if (-1 == i)
        {
            snprintf(sFileOra, MAX_PATH_NAME_LEN, "%s%s",sLogPath,"Insert_Ora");
        }
        else
        {
            snprintf(sFileOra, MAX_PATH_NAME_LEN, "%s%s%d", sLogPath, "Ora", i);
        }

        TADD_DETAIL("File name = %s", sFileOra);
        if(TMdbNtcFileOper::IsExist(sFileOra))
        {
            TMdbNtcFileOper::GetFileSize(sFileOra,iFileSize);
            TADD_DETAIL("Oracle rep file=[%s], file size=[%lld].", sFileOra, iFileSize);
            if (iFileSize>0)
            {
                memset(sFileOraNew,0,MAX_PATH_NAME_LEN);
                memset(sTime,0,MAX_TIME_LEN);
                TMdbDateTime::GetCurrentTimeStr(sTime);
                sprintf(sFileOraNew,"%s.%s",sFileOra,sTime);

                TMdbNtcFileOper::Rename(sFileOra, sFileOraNew);//重命名为.OK文件
            }
            else//空文件,删除
            {
                TADD_DETAIL("Delete file = [%s], size = [0].", sFileOra);
                TMdbNtcFileOper::Remove(sFileOra);
            }
        }
    }
    

    int *ipid = new(std::nothrow) int[pConfig->GetDSN()->iOraRepCounts + 1];
	CHECK_OBJ(ipid);
	
	for (int i = 0; i < pConfig->GetDSN()->iOraRepCounts + 1; i++)
	{
		ipid[i] = 0;
	}
    if(pConfig->GetDSN()->bIsOraRep == true 
        && pConfig->GetIsStartOracleRep() == true)
    {
        //启动把日志刷新到Oracle的进程
        int i=-1;
        char sNameTemp[MAX_NAME_LEN];
        for(i=-1; i<pConfig->GetDSN()->iOraRepCounts; ++i)
        {
            memset(sNameTemp, 0, sizeof(sNameTemp));
            sprintf(sNameTemp, "mdbDbRep %s %d %d", sDsn, pConfig->GetDSN()->iOraRepCounts, i);
            TADD_NORMAL("Start process [%s]", sNameTemp);
            system(sNameTemp);
        }

        //查找Insert_Ora Ora        
        TADD_DETAIL("StartCheck : LocalPath=[%s].",sLogPath);
        TMdbFileList tFileList;
        tFileList.Init(sLogPath);
        while(1)
        {
            tFileList.GetFileList(1, 0, "Insert_Ora","");
            int iInsertCount = tFileList.GetFileCounts();
            tFileList.GetFileList(1, 0, "Ora",".OK");
            int iUpdateCount =  tFileList.GetFileCounts();
            if(iInsertCount == 0 && iUpdateCount == 0)
            {
                //kill进程后退出
                char sProcessName[MAX_NAME_LEN];
                memset(sProcessName,0,MAX_NAME_LEN);
                sprintf(sProcessName,"%s %s","mdbDbRep",sDsn);
                TMdbOS::GetPidByName(sProcessName,ipid);
                for(int j=0; j<pConfig->GetDSN()->iOraRepCounts + 1; j++ )
                {
                    if(0 != ipid[j])
                    {
                        TMdbOS::KillProc(ipid[j]);
                    }
                }
                break;
            }
            TMdbDateTime::Sleep(1);//避免陷入死循环
        }
        TADD_NORMAL("StartCheck .");
    }
    SAFE_DELETE_ARRAY(ipid);
    return iRet;
}
int
main(int argc,
     char *argv[]) {

  char address[MAX_MACHINE_NAME + 1];
  IPAddress addresses[MAX_ADDRESSES];
  unsigned int addressesCount;
  char addressList[255 + 1];
  const char *c;
  char errorFile[127 + 1];
  char logFile[127 + 1];
  struct host_desc memoryDesc;
  double nextBeatTime;
  struct host_desc nsDesc;
  double now;
  int opt;
  extern char *optarg;
  char password[127 + 1];
  const char *USAGE =
    "nws_memory [-D] [-a name] [-d dir] [-el file] [-N host] [-p port] [-s size]";

  /* Set up default values that will be overwritten by command line args. */
  addressList[0] = '\0';
  errorFile[0] = '\0';
  fileSize = atoi(GetEnvironmentValue("MEMORY_SIZE",
                                      "~", ".nwsrc", DEFAULT_MEMORY_SIZE));
  journalFileSize = atoi(GetEnvironmentValue("JOURNAL_SIZE",
                                      "~", ".nwsrc", DEFAULT_JOURNAL_SIZE));
  logFile[0] = '\0';
  HostDValue(MyMachineName(), DefaultHostPort(MEMORY_HOST), &memoryDesc);
  SAFESTRCPY(memoryDir,
             GetEnvironmentValue("MEMORY_DIR", "~", ".nwsrc",
                                 DEFAULT_MEMORY_DIR));;
  SAFESTRCPY(nsDesc.host_name,
             GetEnvironmentValue("NAME_SERVER", "~", ".nwsrc", "noname"));
  HostDValue(nsDesc.host_name, DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
  password[0] = '\0';
  memLogLocation.loc_type = MEMORY_LOG_LOCAL;
  debug = 0;

  while((int)(opt = getopt(argc, argv, SWITCHES)) != EOF) {

    switch(opt) {

    case 'a':
      SAFESTRCPY(addressList, optarg);
      break;

    case 'D':
      debug = 1;
      break;

    case 'd':
      SAFESTRCPY(memoryDir, optarg);
      break;

    case 'e':
      SAFESTRCPY(errorFile, optarg);
      break;

    case 'l':
      SAFESTRCPY(logFile, optarg);
      break;

    case 'N':
      HostDValue(optarg, DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
      break;

    case 'p':
      memoryDesc.port = atoi(optarg);
      break;

    case 'P':
      fprintf(stdout, "Password? ");
      fscanf(stdin, "%s", password);
      break;

    case 's':
      fileSize = atoi(optarg);
      break;

    case 'j':
      journalFileSize = atoi(optarg);
      break;
#if defined(ENABLE_CACHE)
    case 'C':
      RC_entries = atoi(optarg);
      break;
#endif
    default:
      fprintf(stderr, "nws_memory: unrecognized switch\n%s\n", USAGE);
      exit(1);
      break;

    }

  }
#if defined(ENABLE_CACHE)
  /*
   * WARNING: these two had better be the same or the cache and backing
   * store could be inconsistent
   */
  RCMemorySize = fileSize;
  /*
   * make sure entries value is sane
   */
  if(RC_entries <= 0)
	  RC_entries = 0;
#endif

  if (debug) {
    DirectDiagnostics(DIAGINFO, stdout);
    DirectDiagnostics(DIAGLOG, stdout);
    DirectDiagnostics(DIAGWARN, stderr);
    DirectDiagnostics(DIAGERROR, stderr);
    DirectDiagnostics(DIAGFATAL, stderr);
  }

  for(addressesCount = 0, c = addressList;
      GETTOK(address, c, ",", &c);
      addressesCount++) {
    if(!IPAddressValue(address, &addresses[addressesCount])) {
      ABORT1("Unable to convert '%s' into an IP address\n", address);
    }
  }
  addressesCount += IPAddressValues(memoryDesc.host_name,
                                    &addresses[addressesCount],
                                    MAX_ADDRESSES - addressesCount);

  if(memoryDir[strlen(memoryDir) - 1] != '/') {
    strcat(memoryDir, "/");
  }
  if(!MakeDirectory(memoryDir, 0775, 1)) {
    ABORT1("Unable to establish %s as state directory\n", memoryDir);
  }
  SAFESTRCPY(memLogLocation.path,memoryDir);

  if(!EstablishHost(NameOfHost(&memoryDesc),
                    MEMORY_HOST,
                    addresses,
                    addressesCount,
                    memoryDesc.port,
                    errorFile,
                    logFile,
                    password,
                    &nsDesc,
                    NULL)) {
    exit(1);
  }

  vstrncpy(journalPath, sizeof(journalPath), 4,
           memoryDir, EstablishedRegistration(), ".", JOURNAL);

  fclose(stdin);
  signal(SIGPIPE, SocketFailure);
  RegisterListener(STORE_STATE, "STORE_STATE", &ProcessRequest);
  RegisterListener(FETCH_STATE, "FETCH_STATE", &ProcessRequest);
  RegisterListener(AUTOFETCH_BEGIN, "AUTOFETCH_BEGIN", &ProcessRequest);
  RegisterListener(MEMORY_CLEAN, "MEMORY_CLEAN", &ProcessRequest);
#ifdef WITH_NETLOGGER
  RegisterListener(MEMORY_LOGDEST, "MEMORY_LOGDEST", &ProcessRequest);
#endif
  NotifyOnDisconnection(&EndAutoFetch);
  nextBeatTime = CurrentTime();

  /* main service loop */
  while(1) {
    now = CurrentTime();
    if(now >= nextBeatTime) {
      RegisterHost(DEFAULT_HOST_BEAT * 2);
      nextBeatTime =
        now + (HostHealthy() ? DEFAULT_HOST_BEAT : SHORT_HOST_BEAT);
    }
    ListenForMessages(nextBeatTime - now);
  }

  /* return(0); Never reached */

}
int
main(int argc,
     char *argv[]) {

  char address[MAX_MACHINE_NAME + 1];
  IPAddress addresses[MAX_ADDRESSES];
  unsigned int addressesCount;
  char addressList[255 + 1];
  const char *c;
  unsigned long compressionFreq;
  char errorFile[127 + 1];
  char logFile[127 + 1];
  unsigned long nextCompression;
  struct host_desc nsDesc;
  char password[127 + 1];
  int opt;
  extern char *optarg;
  char registrationFileName[255 + 1];
  const char *USAGE =
    "nws_nameserver [-D] [-a name] [-c seconds] [-efl file] [-p port]";

  /* Set up default values that will be overwritten by command line args. */
  addressList[0] = '\0';
  compressionFreq = DEFAULT_COMPRESSION_FREQUENCY;
  errorFile[0] = '\0';
  logFile[0] = '\0';
  HostDValue(MyMachineName(), DefaultHostPort(NAME_SERVER_HOST), &nsDesc);
  SAFESTRCPY(registrationFileName, DEFAULT_FILE);
  password[0] = '\0';
  debug = 0;

  while((int)(opt = getopt(argc, argv, SWITCHES)) != EOF) {

    switch(opt) {

    case 'a':
      SAFESTRCPY(addressList, optarg);
      break;

    case 'c':
      compressionFreq = atol(optarg);
      break;

    case 'D':
      debug = 1;
      break;

    case 'e':
      SAFESTRCPY(errorFile, optarg);
      break;

    case 'f':
      SAFESTRCPY(registrationFileName, optarg);
      break;

    case 'l':
      SAFESTRCPY(logFile, optarg);
      break;

    case 'p':
      nsDesc.port = atoi(optarg);
      break;

    case 'P':
      fprintf(stdout, "Password? ");
      fscanf(stdin, "%s", password);
      break;

    default:
      fprintf(stderr, "nws_nameserver: unrecognized switch\n%s\n", USAGE);
      exit(1);
      break;

    }

  }

  if (debug) {
    DirectDiagnostics(DIAGINFO, stdout);
    DirectDiagnostics(DIAGLOG, stdout);
    DirectDiagnostics(DIAGWARN, stderr);
    DirectDiagnostics(DIAGERROR, stderr);
    DirectDiagnostics(DIAGFATAL, stderr);
  }

  addressesCount = IPAddressValues(nsDesc.host_name, addresses, MAX_ADDRESSES);
  for(c = addressList; GETTOK(address, c, ",", &c); ) {
    if(!IPAddressValue(address, &addresses[addressesCount++])) {
      ABORT1("Unable to convert '%s' into an IP address\n", address);
    }
  }

  registrationFile = fopen(registrationFileName, "r+");
  if(registrationFile == NULL) {
    registrationFile = fopen(registrationFileName, "w+");
  }
  
  if(registrationFile == NULL) {
    ABORT1("Unable to open %s for storing registrations\n",
           registrationFileName);
  }

  if(!EstablishHost(NameOfHost(&nsDesc),
                    NAME_SERVER_HOST,
                    addresses,
                    addressesCount,
                    nsDesc.port,
                    errorFile,
                    logFile,
                    password,
                    &nsDesc,
                    &NSExit)) {
    exit(1);
  }

  fclose(stdin);
  signal(SIGPIPE, SocketFailure);
  RegisterListener(NS_REGISTER, "NS_REGISTER", &ProcessRequest);
  RegisterListener(NS_SEARCH, "NS_SEARCH", &ProcessRequest);
  RegisterListener(NS_UNREGISTER, "NS_UNREGISTER", &ProcessRequest);
  nextCompression = CurrentTime() + compressionFreq;

  /* main service loop */
  while(1) {
    ListenForMessages(nextCompression - CurrentTime());
    if(CurrentTime() > nextCompression) {
      CompressRegistrations();
      nextCompression = CurrentTime() + compressionFreq;
    }
  }

  /* return 0; Never reached */

}