Example #1
0
void Zshow_config(void)
{
	int i;
	char line[STRMAX * 2];
	zbuff_t *tbuff = cmakebuff(CONFBUFF, NULL);
	if (!tbuff)
		return;

	bempty(Bbuff);
	for (i = 0; i < NUMVARS; ++i) {
		if (Vars[i].vtype == V_STRING) {
			if (VARSTR(i))
				strfmt(line, sizeof(line), "%-15s %s\n",
					 Vars[i].vname, VARSTR(i));
			else
				strfmt(line, sizeof(line), "#%-15s\n",
					 Vars[i].vname);
		} else if (Vars[i].vtype == V_DECIMAL)
			strfmt(line, sizeof(line), "%-15s %d\n",
				 Vars[i].vname, VAR(i));
		else if (Vars[i].vtype == V_FLAG)
			strfmt(line, sizeof(line), "%-15s %s\n",
				 Vars[i].vname,
				 VAR(i) ? "true" : "false");

		binstr(Bbuff, line);
	}

	tbuff->buff->bmodf = false;
	btostart(Bbuff);
	cswitchto(tbuff);
}
Example #2
0
static void setit(int i, const char *ptr)
{
	switch (Vars[i].vtype) {
	case V_STRING:
		if (strcmp(VARSTR(i), ptr))
			VARSTR(i) = strdup(ptr);
		break;
	case V_FLAG:
		if (strncasecmp(ptr, "true", 4) == 0)
			VAR(i) = 1;
		else if (strncasecmp(ptr, "false", 5) == 0)
			VAR(i) = 0;
		else
			VAR(i) = strtol(ptr, NULL, 0);
		break;
	case V_DECIMAL:
		VAR(i) = strtol(ptr, NULL, 0);
	}
}
Example #3
0
static void setavar(const char *vin, bool display)
{
	char msg[STRMAX + 1];
	int i = 0;

	strlcpy(msg, vin, sizeof(msg));
	strtok(msg, " \t");

	for (i = 0; i < NUMVARS; ++i)
		if (strcasecmp(msg, Vars[i].vname) == 0) {
			do_var_match(i, vin);
			if (display) {
				if (i == VTABS || i == VCTABS || i == VSHTABS) {
					settabsize(Curbuff->bmode);
					redisplay();
				}
				if (Vars[i].vtype == V_STRING) {
					if (VARSTR(i))
						putpaw("%s = %s",
							   Vars[i].vname,
							   VARSTR(i));
					else
						putpaw("%s = NONE",
							   Vars[i].vname);
				} else
					putpaw("%s = %d",
						Vars[i].vname, VAR(i));
				if (i == VCOMMENTS)
					redisplay();
			}
			break;
		}
	if (i == NUMVARS) {
		if (display)
			putpaw("Variable '%s' Not Found", vin);
	}
	Arg = 0;
}
Example #4
0
void Zset_variable(void)
{
	char pstr[STRMAX], arg[STRMAX];
	int rc = getplete("Variable: ", NULL, (char **)Vars,
			  sizeof(struct avar), NUMVARS);
	if (rc == -1)
		return;

	if (!Argp || Vars[rc].vtype == V_STRING) {
		strconcat(pstr, sizeof(pstr), Vars[rc].vname, ": ", NULL);
		if (Vars[rc].vtype == V_STRING)
			if (VARSTR(rc))
				strlcpy(arg, VARSTR(rc), sizeof(arg));
			else
				*arg = '\0';
		else
			strfmt(arg, sizeof(arg), "%d", VAR(rc));
		if (getarg(pstr, arg, STRMAX))
			return;
		strconcat(pstr, sizeof(pstr), Vars[rc].vname, " ", arg, NULL);
		setavar(pstr, true);
	} else
		setavar(Vars[rc].vname, true);
}
Example #5
0
/***********************************************************************************************************************************
Get an archive file from the repository (WAL segment, history file, etc.)
***********************************************************************************************************************************/
int
cmdArchiveGet(void)
{
    FUNCTION_LOG_VOID(logLevelDebug);

    // Set the result assuming the archive file will not be found
    int result = 1;

    MEM_CONTEXT_TEMP_BEGIN()
    {
        // Check the parameters
        const StringList *commandParam = cfgCommandParam();

        if (strLstSize(commandParam) != 2)
        {
            if (strLstSize(commandParam) == 0)
                THROW(ParamRequiredError, "WAL segment to get required");

            if (strLstSize(commandParam) == 1)
                THROW(ParamRequiredError, "path to copy WAL segment required");

            THROW(ParamInvalidError, "extra parameters found");
        }

        // Get the segment name
        String *walSegment = strBase(strLstGet(commandParam, 0));

        // Destination is wherever we were told to move the WAL segment
        const String *walDestination =
            walPath(strLstGet(commandParam, 1), cfgOptionStr(cfgOptPgPath), STR(cfgCommandName(cfgCommand())));

        // Async get can only be performed on WAL segments, history or other files must use synchronous mode
        if (cfgOptionBool(cfgOptArchiveAsync) && walIsSegment(walSegment))
        {
            bool found = false;                                         // Has the WAL segment been found yet?
            bool queueFull = false;                                     // Is the queue half or more full?
            bool forked = false;                                        // Has the async process been forked yet?
            bool confessOnError = false;                                // Should we confess errors?

            // Loop and wait for the WAL segment to be pushed
            Wait *wait = waitNew((TimeMSec)(cfgOptionDbl(cfgOptArchiveTimeout) * MSEC_PER_SEC));

            do
            {
                // Check for errors or missing files.  For archive-get ok indicates that the process succeeded but there is no WAL
                // file to download.
                if (archiveAsyncStatus(archiveModeGet, walSegment, confessOnError))
                {
                    storageRemoveP(
                        storageSpoolWrite(),
                        strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s" STATUS_EXT_OK, strPtr(walSegment)), .errorOnMissing = true);
                    break;
                }

                // Check if the WAL segment is already in the queue
                found = storageExistsNP(storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment)));

                // If found then move the WAL segment to the destination directory
                if (found)
                {
                    // Source is the WAL segment in the spool queue
                    StorageFileRead *source = storageNewReadNP(
                        storageSpool(), strNewFmt(STORAGE_SPOOL_ARCHIVE_IN "/%s", strPtr(walSegment)));

                    // A move will be attempted but if the spool queue and the WAL path are on different file systems then a copy
                    // will be performed instead.
                    //
                    // It looks scary that we are disabling syncs and atomicity (in case we need to copy intead of move) but this
                    // is safe because if the system crashes Postgres will not try to reuse a restored WAL segment but will instead
                    // request it again using the restore_command. In the case of a move this hardly matters since path syncs are
                    // cheap but if a copy is required we could save a lot of writes.
                    StorageFileWrite *destination = storageNewWriteP(
                        storageLocalWrite(), walDestination, .noCreatePath = true, .noSyncFile = true, .noSyncPath = true,
                        .noAtomic = true);

                    // Move (or copy if required) the file
                    storageMoveNP(storageSpoolWrite(), source, destination);

                    // Return success
                    result = 0;

                    // Get a list of WAL segments left in the queue
                    StringList *queue = storageListP(
                        storageSpool(), STORAGE_SPOOL_ARCHIVE_IN_STR, .expression = WAL_SEGMENT_REGEXP_STR);

                    if (strLstSize(queue) > 0)
                    {
                        // Get size of the WAL segment
                        uint64_t walSegmentSize = storageInfoNP(storageLocal(), walDestination).size;

                        // Use WAL segment size to estimate queue size and determine if the async process should be launched
                        queueFull = strLstSize(queue) * walSegmentSize > cfgOptionUInt64(cfgOptArchiveGetQueueMax) / 2;
                    }
                }

                // If the WAL segment has not already been found then start the async process to get it.  There's no point in
                // forking the async process off more than once so track that as well.  Use an archive lock to prevent forking if
                // the async process was launched by another process.
                if (!forked && (!found || !queueFull)  &&
                    lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, false))
                {
                    // Get control info
                    PgControl pgControl = pgControlFromFile(cfgOptionStr(cfgOptPgPath));

                    // Create the queue
                    storagePathCreateNP(storageSpoolWrite(), STORAGE_SPOOL_ARCHIVE_IN_STR);

                    // The async process should not output on the console at all
                    KeyValue *optionReplace = kvNew();

                    kvPut(optionReplace, VARSTR(CFGOPT_LOG_LEVEL_CONSOLE_STR), VARSTRDEF("off"));
                    kvPut(optionReplace, VARSTR(CFGOPT_LOG_LEVEL_STDERR_STR), VARSTRDEF("off"));

                    // Generate command options
                    StringList *commandExec = cfgExecParam(cfgCmdArchiveGetAsync, optionReplace);
                    strLstInsert(commandExec, 0, cfgExe());

                    // Clean the current queue using the list of WAL that we ideally want in the queue.  queueNeed()
                    // will return the list of WAL needed to fill the queue and this will be passed to the async process.
                    const StringList *queue = queueNeed(
                        walSegment, found, cfgOptionUInt64(cfgOptArchiveGetQueueMax), pgControl.walSegmentSize,
                        pgControl.version);

                    for (unsigned int queueIdx = 0; queueIdx < strLstSize(queue); queueIdx++)
                        strLstAdd(commandExec, strLstGet(queue, queueIdx));

                    // Release the lock so the child process can acquire it
                    lockRelease(true);

                    // Fork off the async process
                    if (forkSafe() == 0)
                    {
                        // Disable logging and close log file
                        logClose();

                        // Detach from parent process
                        forkDetach();

                        // Execute the binary.  This statement will not return if it is successful.
                        THROW_ON_SYS_ERROR(
                            execvp(strPtr(cfgExe()), (char ** const)strLstPtr(commandExec)) == -1,
                            ExecuteError, "unable to execute '" CFGCMD_ARCHIVE_GET_ASYNC "'");
                    }

                    // Mark the async process as forked so it doesn't get forked again.  A single run of the async process should be
                    // enough to do the job, running it again won't help anything.
                    forked = true;
                }

                // Exit loop if WAL was found
                if (found)
                    break;

                // Now that the async process has been launched, confess any errors that are found
                confessOnError = true;
            }
            while (waitMore(wait));
        }
        // Else perform synchronous get
        else
        {
Example #6
0
void TDataManager::KHRParse(AnsiString fileName)
{
// создаёт новую структуру КХР, разбирает все данные из xml-файла и заполняет
	// вызывает функцию контроллера AddKHR(TKHR *khr)
	// контроллер добавляет КХР в вектор элементов
	TKHR *khr = new TKHR;

	//---------------------------
	// открытие xml-файла
	string temp =  fileName.c_str();
	khr->path = temp;
	formMain->xmlReader->LoadFromFile(UnicodeString(fileName.c_str()));
	// parse xml
	try
	{
		_di_IXMLNode Root = formMain->xmlReader->DocumentElement;
		khr->szNumber 		= VARSTR(Root->Attributes["number"]);
		khr->szTitle  		= VARSTR(Root->Attributes["name"]);
		khr->dtStartDate	= StrToDate(VARSTR(Root->Attributes["begin"]));
		khr->szOrder 		= VARSTR(Root->Attributes["orderNum"]);
		khr->szFileName 	= VARSTR(Root->Attributes["file"]);
		//-----------------------------------------------------------------------------------------
		// разбираем вложенные теги КХР
		for (int i=0; i < Root->ChildNodes->Count; i++)
		{
			// работы
			if (Root->ChildNodes->Nodes[i]->NodeName == "work")
			{
				TWork *work = new TWork;
				_di_IXMLNode oneWork = Root->ChildNodes->Nodes[i];
				work->ulWorkNum = int(oneWork->Attributes["number"]);
				work->bPayment 	= StrToBool(VARSTR(oneWork->Attributes["type"]));
				work->szTitle 	= VARSTR(oneWork->Attributes["name"]);
				work->dtStart 	= StrToDate(VARSTR(oneWork->Attributes["begin"]));
				work->dtEnd 	= StrToDate(VARSTR(oneWork->Attributes["end"]));
				work->dtMoveTo 	= StrToDate(VARSTR(oneWork->Attributes["move"]));
				work->ulLength 	= int(oneWork->Attributes["length"]);
				work->havePayment 	= StrToBool(VARSTR(oneWork->Attributes["pay"]));
				work->haveStage 	= StrToBool(VARSTR(oneWork->Attributes["stage"]));
				work->eWorkState    = int(oneWork->Attributes["state"]);
				work->center.x 		= float(oneWork->Attributes["x"]);
				work->center.y		= float(oneWork->Attributes["y"]);
				// вспомогательные переменные
				int iCmdCounter = 0; // счетчик команд работы

				// вложенные теги работы
				for (int j=0; j < oneWork->ChildNodes->Count; j++)
				{
					// точки связи к доплате
					if (oneWork->ChildNodes->Nodes[j]->NodeName == "paypoint")
					{
						_di_IXMLNode point = oneWork->ChildNodes->Nodes[j];
						T2d dot;
						dot.x = float(point->Attributes["x"]);
						dot.y = float(point->Attributes["y"]);
						work->connectPayment.push_back(dot);
					}
					// исполнители
					else if (oneWork->ChildNodes->Nodes[j]->NodeName == "executor")
					{
						TWorkVolume *vol = new TWorkVolume;
						_di_IXMLNode oneEx = oneWork->ChildNodes->Nodes[j];
						vol->ulExecutor = int(oneEx->Attributes["number"]);

						for (int k=0; k < oneEx->ChildNodes->Count; k++)
						{
							if (oneEx->ChildNodes->Nodes[k]->NodeName == "quartvol")
							{
								_di_IXMLNode oneVol = oneEx->ChildNodes->Nodes[k];
								vol->ulVolume[k] = int(oneVol->Attributes["volume"]);
							}
						}
						work->WorkVolume.push_back(vol);
					}
					// зависимости
					else if (oneWork->ChildNodes->Nodes[j]->NodeName == "dependence")
					{

						TDependance *dep 	= new TDependance;
						_di_IXMLNode oneDep = oneWork->ChildNodes->Nodes[j];
						dep->bNeedToStart 	= StrToBool(VARSTR(oneDep->Attributes["need"]));
						dep->ulWork			= int(oneDep->Attributes["work"]);
						work->WorkDep.push_back(dep);
					}
					// команды
					else if (oneWork->ChildNodes->Nodes[j]->NodeName == "command")
					{
						_di_IXMLNode oneCmd = oneWork->ChildNodes->Nodes[j];
						work->eCommand[iCmdCounter++] = int(oneCmd->Attributes["code"]);
					}
				}

				khr->Works.push_back(work);
			}
			// доплаты
			else if (Root->ChildNodes->Nodes[i]->NodeName == "payment")
			{
				TWork *work = new TWork;
				_di_IXMLNode oneWork = Root->ChildNodes->Nodes[i];
				work->ulWorkNum = int(oneWork->Attributes["number"]);
				work->bPayment 	= StrToBool(VARSTR(oneWork->Attributes["type"]));
				work->szTitle 	= VARSTR(oneWork->Attributes["name"]);
				work->dtStart 	= StrToDate(VARSTR(oneWork->Attributes["begin"]));
				work->dtEnd 	= StrToDate(VARSTR(oneWork->Attributes["end"]));
				work->dtMoveTo 	= StrToDate(VARSTR(oneWork->Attributes["move"]));
				work->ulLength 	= int(oneWork->Attributes["length"]);
				work->eWorkState    = int(oneWork->Attributes["state"]);
				work->center.x 		= float(oneWork->Attributes["x"]);
				work->center.y		= float(oneWork->Attributes["y"]);
				// вспомогательные переменные
				int iCmdCounter = 0; // счетчик команд работы

				// вложенные теги доплаты
				for (int j=0; j < oneWork->ChildNodes->Count; j++)
				{
					// исполнители
					if (oneWork->ChildNodes->Nodes[j]->NodeName == "executor")
					{
						TWorkVolume *vol = new TWorkVolume;
						_di_IXMLNode oneEx = oneWork->ChildNodes->Nodes[j];
						vol->ulExecutor = int(oneEx->Attributes["number"]);

						for (int k=0; k < oneEx->ChildNodes->Count; k++)
						{
							if (oneEx->ChildNodes->Nodes[k]->NodeName == "quartvol")
							{
								_di_IXMLNode oneVol = oneEx->ChildNodes->Nodes[k];
								vol->ulVolume[k] = int(oneVol->Attributes["volume"]);
							}
						}
						work->WorkVolume.push_back(vol);
					}
					// зависимости
					else if (oneWork->ChildNodes->Nodes[j]->NodeName == "dependence")
					{

						TDependance *dep 	= new TDependance;
						_di_IXMLNode oneDep = oneWork->ChildNodes->Nodes[j];
						dep->bNeedToStart 	= StrToBool(VARSTR(oneDep->Attributes["need"]));
						dep->ulWork			= int(oneDep->Attributes["work"]);
						work->WorkDep.push_back(dep);
					}
					// команды
					else if (oneWork->ChildNodes->Nodes[j]->NodeName == "command")
					{
						_di_IXMLNode oneCmd = oneWork->ChildNodes->Nodes[j];
						work->eCommand[iCmdCounter++] = int(oneCmd->Attributes["code"]);
					}
				}

				khr->Payments.push_back(work);
			}
			// ссылки
			else if (Root->ChildNodes->Nodes[i]->NodeName == "link")
			{
				TLink *link = new TLink;
				_di_IXMLNode oneLink = Root->ChildNodes->Nodes[i];

				link->ulWorkNum = int(oneLink->Attributes["number"]);
				link->slText->Text 	= VARSTR(oneLink->Attributes["text"]);
				link->dtDate 	= StrToDate(VARSTR(oneLink->Attributes["date"]));
				link->szNumber  = VARSTR(oneLink->Attributes["khrnum"]);
				link->center.x 	= float(oneLink->Attributes["x"]);
				link->center.y 	= float(oneLink->Attributes["y"]);

				// вложенные теги ссылки
				for (int j=0; j < oneLink->ChildNodes->Count; j++)
				{
					// зависимости
					if (oneLink->ChildNodes->Nodes[j]->NodeName == "linkdependence")
					{
						TDependance *dep 	= new TDependance;
						_di_IXMLNode oneDep = oneLink->ChildNodes->Nodes[j];
						dep->bNeedToStart 	= StrToBool(VARSTR(oneDep->Attributes["need"]));
						dep->ulWork			= int(oneDep->Attributes["num"]);
						link->WorkDep.push_back(dep);
					}
				}

				khr->Links.push_back(link);
			}
			// вехи
			else if (Root->ChildNodes->Nodes[i]->NodeName == "stage")
			{
				TStage *nstage = new TStage;
				_di_IXMLNode oneStage = Root->ChildNodes->Nodes[i];
				nstage->ulStageNum = int(oneStage->Attributes["number"]);
				nstage->center.x  =  float(oneStage->Attributes["x"]);
				nstage->center.y  =  float(oneStage->Attributes["y"]);

				// вложенные теги вехи
				for(int j=0; j<oneStage->ChildNodes->Count; j++)
				{
					// точки связи
					if (oneStage->ChildNodes->Nodes[j]->NodeName == "point")
					{
						T2d point;
						_di_IXMLNode onePoint = oneStage->ChildNodes->Nodes[j];
						point.x = float(onePoint->Attributes["x"]);
						point.y = float(onePoint->Attributes["y"]);
						nstage->connect.push_back(point);
					}
				}

				khr->Stages.push_back(nstage);
			}
			// стрелки
			else if (Root->ChildNodes->Nodes[i]->NodeName == "connect")
			{
				TConnection *connect = new TConnection;
				_di_IXMLNode oneLine = Root->ChildNodes->Nodes[i];
				connect->begin = int(oneLine->Attributes["begin"]);
				connect->end = int(oneLine->Attributes["end"]);
				connect->needStart = StrToBool(VARSTR(oneLine->Attributes["need"]));

				// вложенные теги стрелки
				for(int j=0; j<oneLine->ChildNodes->Count; j++)
				{
					T2d point;
					_di_IXMLNode onePoint = oneLine->ChildNodes->Nodes[j];
					point.x = float(onePoint->Attributes["x"]);
					point.y = float(onePoint->Attributes["y"]);
					connect->connect.push_back(point);
				}

				khr->Connects.push_back(connect);
			}
			// исполнители КХР
			else if (Root->ChildNodes->Nodes[i]->NodeName == "executor")
			{
				TExecutor *exec 		= new TExecutor;
				_di_IXMLNode oneExec 	= Root->ChildNodes->Nodes[i];
				exec->id 				= int(oneExec->Attributes["id"]);
				exec->szName			= VARSTR(oneExec->Attributes["name"]);
				khr->Executors.push_back(exec);
			}
			// подписи исполнителей
			else if (Root->ChildNodes->Nodes[i]->NodeName == "signature")
			{
				TSignature *sig 	= new TSignature;
				_di_IXMLNode oneSig = Root->ChildNodes->Nodes[i];
				sig->szChair 		= VARSTR(oneSig->Attributes["chair"]);
				sig->szName  		= VARSTR(oneSig->Attributes["name"]);
				khr->Signatures.push_back(sig);
			}

			khr->selected = true;
		}
	}
	catch(EConvertError* e)
	{
		ShowMessage("Ошибка загрузки файла КХР: "+ e->ToString());
	}
	//---------------------------
	control->addKHR(khr);
}