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); }
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); } }
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; }
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); }
/*********************************************************************************************************************************** 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 {
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); }