Exemplo n.º 1
0
void OpConvertFileFormats::Do(OpDescriptor*)
{
	ERROR3 ("Please read the following comments BEFORE using this op!");	// comment this out to use the op

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// set up the search path, file util allows us just to pass the path/*.xar
	String_256 SearchPath = TEXT ("d:\\clipart\\xara\\");		// YOU MUST CHANGE THIS PATH
	
	String_256 FileSpecifier = SearchPath;						// YOU MUST CHANGE THIS EXTENSION
				FileSpecifier += TEXT("*.art");
	String_256 FileSpecifier2 = TEXT("xar");					// YOU MUST CHANGE THIS EXTENSION

////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

	BOOL ok = FileUtil::StartFindingFiles(&FileSpecifier);
	active = TRUE;
	String_256 Filename;
	while (ok)
	{
		// fileutil will give us the next filename
		ok = FileUtil::FindNextFile(&Filename);
		String_256 FilePath = SearchPath;
		FilePath += Filename;
		PathName Path (FilePath);

		if (ok)
		{
			CDocument* pDoc = theApp.OpenDocumentFile((TCHAR*)FilePath);
			if (pDoc!=NULL)
			{
				// Make sure that the files name is sensible
				theApp.MakeDocumentNative(pDoc, &Path);
				
				Path.SetType (FileSpecifier2);
				String_256 newPath = Path.GetPath ();
				pDoc->DoSave ((TCHAR*) newPath, TRUE);

				FileCloseAction ();
			}
		}
	}
	active = FALSE;
	FileUtil::StopFindingFiles ();
}
Exemplo n.º 2
0
bool PackageManagerImpl::TryVerifyInstalledPackage(const string& packageId)
{
  PackageInfo packageInfo = GetPackageInfo(packageId);

  PathName prefix;

  if (!session->IsAdminMode() && IsValidTimeT(packageInfo.timeInstalledByUser))
  {
    prefix = session->GetSpecialPath(SpecialPath::UserInstallRoot);
  }

  if (prefix.Empty())
  {
    prefix = session->GetSpecialPath(SpecialPath::CommonInstallRoot);
  }

  FileDigestTable fileDigests;

  if (!TryCollectFileDigests(prefix, packageInfo.runFiles, fileDigests)
    || !TryCollectFileDigests(prefix, packageInfo.docFiles, fileDigests)
    || !TryCollectFileDigests(prefix, packageInfo.sourceFiles, fileDigests))
  {
    return false;
  }

  MD5Builder md5Builder;

  for (const pair<string, MD5> p : fileDigests)
  {
    PathName path(p.first);
    // we must dosify the path name for backward compatibility
    path.ConvertToDos();
    md5Builder.Update(path.GetData(), path.GetLength());
    md5Builder.Update(p.second.data(), p.second.size());
  }

  bool ok = md5Builder.Final() == packageInfo.digest;

  if (!ok)
  {
    trace_mpm->WriteLine(TRACE_FACILITY, fmt::format(T_("package {0} verification failed: some files have been modified"), Q_(packageId)));
    trace_mpm->WriteLine(TRACE_FACILITY, fmt::format(T_("expected digest: {0}"), packageInfo.digest));
    trace_mpm->WriteLine(TRACE_FACILITY, fmt::format(T_("computed digest: {0}"), md5Builder.GetMD5()));
  }

  return ok;
}
Exemplo n.º 3
0
miktex_find_miktex_executable (/*[in]*/ const char *	lpszExeName,
			       /*[out]*/ char *		lpszExePath)
{
  C_FUNC_BEGIN ();
  MIKTEX_ASSERT_STRING (lpszExeName);
  MIKTEX_ASSERT_PATH_BUFFER (lpszExePath);
  PathName temp;
  if (! SessionImpl::GetSession()->FindFile(lpszExeName,
					    FileType::EXE,
					    temp))
    {
      return (0);
    }
  Utils::CopyString (lpszExePath, BufferSizes::MaxPath, temp.Get());
  return (1);
  C_FUNC_END ();
}
Exemplo n.º 4
0
void ParsedPath::parse(const PathName& path)
{
	clear();

	if (path.length() == 1) {
		add(path);
		return;
	}

	PathName oldpath = path;
	do {
		PathName newpath, elem;
		PathUtils::splitLastComponent(newpath, elem, oldpath);
		oldpath = newpath;
		insert(0, elem);
	} while (oldpath.length() > 0);
}
Exemplo n.º 5
0
// Checks that argument doesn't contain colon or directory separator
static inline bool hasSeparator(const PathName& name)
{
	for (const char* p = name.c_str(); *p; p++)
	{
		if (*p == ':' || *p == '/' || *p == '\\')
			return true;
	}
	return false;
}
Exemplo n.º 6
0
bool Utils::SupportsHardLinks(const PathName& path)
{
  DWORD fileSystemFlags;
  wchar_t fileSystemName[_MAX_PATH];
  PathName root = path.GetMountPoint();
  if (GetVolumeInformationW(root.ToWideCharString().c_str(), nullptr, 0, nullptr, nullptr, &fileSystemFlags, fileSystemName, _MAX_PATH) == 0)
  {
    MIKTEX_FATAL_WINDOWS_ERROR_2("GetVolumeInformationW", "root", root.ToString());
  }
  if (WindowsVersion::IsWindows7OrGreater())
  {
    return (fileSystemFlags & FILE_SUPPORTS_HARD_LINKS) != 0;
  }
  else
  {
    return _wcsicmp(fileSystemName, L"NTFS") == 0;
  }
}
Exemplo n.º 7
0
void WebAppInputLine::SetAuxDirectory(const PathName& path)
{
  if (pimpl->auxDirectory == path)
  {
    return;
  }
  LogInfo("setting aux directory: " + path.ToString());
  pimpl->auxDirectory = path;
}
Exemplo n.º 8
0
bool PathName::makeRelativeTo(const PathName& root)
{
  mDebugAssert(root.getPath() != NULL);
  mDebugAssert(mRelativePath != NULL);

  if (!isChildOf(root))
  {
    return false;
  }
  
  mRelativePath = mRelativePath + root.getPathLength();
  if (*mRelativePath != '\0')
  {
    // Move beyond path separator
    mRelativePath++;
  }

  return true;
}
bool
MakeNTEmacsClientCommandLine (/*[out]*/ string &	program,
			      /*[out]*/ string &	arguments)
{
  PathName pathEmacs;
  if (! LocateNTEmacs(pathEmacs, "gnuclientw.exe"))
  {
    wchar_t szEmacs[_MAX_PATH];
    wchar_t * lpszFileName;
    if (! SearchPathW(0, L"gnuclientw.exe", 0, _MAX_PATH, szEmacs, &lpszFileName))
    {
      return (false);
    }
    pathEmacs = szEmacs;
  }
  program = pathEmacs.Get();
  arguments = "-F +%l \"%f\"";
  return (true);
}
Exemplo n.º 10
0
void
CommandLineBuilder::AppendStdinRedirection (/*[in]*/ const char * lpszPath)
{
  pData->str += '<';
#if defined(MIKTEX_WINDOWS)
  PathName dosish (lpszPath);
  lpszPath = dosish.ToDos().Get();
#endif
  bool needsQuoting = (StrChr(lpszPath, ' ') != 0);
  if (needsQuoting)
    {
      pData->str += '"';
    }
  pData->str += lpszPath;
  if (needsQuoting)
    {
      pData->str += '"';
    }
}
Exemplo n.º 11
0
bool
LocateNTEmacs (/*[out]*/ PathName &	ntEmacs,
	       /*[in]*/ const char *	lpszName)
{
  PathName path;
  if (! ReadPath(HKEY_LOCAL_MACHINE, L"SOFTWARE\\GNU\\Emacs", L"emacs_dir", path))
  {
    return (false);
  }
  path += "bin";
  path += lpszName;
  path.SetExtension (".exe");
  if (! File::Exists(path))
  {
    return (false);
  }
  ntEmacs = path;
  return (true);
}
Exemplo n.º 12
0
static int raw_devices_unlink_database(const PathName& file_name)
{
	char header[MIN_PAGE_SIZE];
	int desc = -1;

	for (int i = 0; i < IO_RETRY; i++)
	{
		if ((desc = open (file_name.c_str(), O_RDWR | O_BINARY)) != -1)
			break;

		if (!SYSCALL_INTERRUPTED(errno))
		{
			ERR_post(Arg::Gds(isc_io_error) << Arg::Str("open") << Arg::Str(file_name) <<
					 Arg::Gds(isc_io_open_err) << Arg::Unix(errno));
		}
	}

	memset(header, 0xa5, sizeof(header));

	int i;

	for (i = 0; i < IO_RETRY; i++)
	{
		const ssize_t bytes = write (desc, header, sizeof(header));
		if (bytes == sizeof(header))
			break;
		if (bytes == -1 && SYSCALL_INTERRUPTED(errno))
			continue;
		ERR_post(Arg::Gds(isc_io_error) << Arg::Str("write") << Arg::Str(file_name) <<
				 Arg::Gds(isc_io_write_err) << Arg::Unix(errno));
	}

	//if (desc != -1) perhaps it's better to check this???
		close(desc);

#ifdef DEV_BUILD
	gds__log ("raw_devices_unlink_database: %s -> %s\n",
				file_name.c_str(), i < IO_RETRY ? "true" : "false");
#endif

	return 0;
}
Exemplo n.º 13
0
void OpGenericDownload::OnDownloadSuccess()
{
	// get a pointer to the OpParam so that I can retrieve some useful information
	GenericDownloadParam* pGenericParam = (GenericDownloadParam*) pParam;

	String_256 GenericFile = (pGenericParam->file).GetFileName();
	if (IsUserName("Olivier"))
		TRACE1("OpGenericDownload::OnDownloadSuccess(), file = %s\n", (TCHAR*)GenericFile);

	Filter* pFilter = pGenericParam->m_pFilter;
	PathName Path = pGenericParam->file;
	String_256 URL = pGenericParam->strURL;
	SelOperation* Op = pGenericParam->m_Op;

	// call the DoImport function from OpMenuImport class
	((OpMenuImport*)Op)->DoImport(Path, pFilter, &URL);

	// remove the temporary file
	remove((TCHAR*) (String_256) Path.GetPath());
}
Exemplo n.º 14
0
BOOL OpMenuSave::Save ( Filter *pFilter, CCLexFile *pFile )
{
	// Check that the extension is ok according to this filter
	// But only if the operation requires it
	if (FixFileType())
	{
		PathName pth = pFile->GetPathName();
		if (pth.IsValid()) EnsureFileTypeCorrectId(pFilter, pth);
	}

	// open the file and export into it
	if (!SaveSpecificFile(pFilter, pFile))
	{
		FailAndExecute();
		return FALSE;
	}

	// Success.
	return TRUE;
}
Exemplo n.º 15
0
bool PackageManagerImpl::ReadDirectory(const PathName& path, vector<string>& subDirNames, vector<string>& fileNames, vector<string>& fileNameInfos)
{
  const DirectoryInfo& directoryInfo = directoryInfoTable[path.ToString()];
  for (const string& name : directoryInfo.subDirectoryNames)
  {
    subDirNames.push_back(name);
  }
  fileNames = directoryInfo.fileNames;
  fileNameInfos = directoryInfo.packageNames;
  return true;
}
Exemplo n.º 16
0
void
TpmParser::GetFiles (/*[in]*/ const XML_Char *		lpszFiles,
		     /*[out]*/ vector<string> &		files)
{
  MIKTEX_ASSERT (Utils::IsAscii(lpszFiles));
  for (Tokenizer tok (lpszFiles, X_(";\n\r \t"));
       tok.GetCurrent() != 0;
       ++ tok)
    {
      PathName path (tok.GetCurrent());
#if defined(MIKTEX_UNIX)
      path.ToUnix ();
#endif
      if (texMFPrefix.length() == 0
	  || (PathName::Compare(texMFPrefix, path, texMFPrefix.length()) == 0))
	{
	  files.push_back (path.ToString());
	}
    }
}
Exemplo n.º 17
0
void
SiteWizLocal::initializePage ()
{
  try
    {
      PathName path;
      if (pManager->TryGetLocalPackageRepository(path))
	{
	  leDirectory->setText (QString::fromLocal8Bit(path.Get()));
	}
    }
  catch (const MiKTeXException & e)
    {
      ErrorDialog::DoModal (this, e);
    }
  catch (const exception & e)
    {
      ErrorDialog::DoModal (this, e);
    }
}
Exemplo n.º 18
0
void
Process::Run (/*[in]*/ const PathName &		fileName,
	      /*[in]*/ const char *		lpszArguments,
	      /*[int]*/ IRunProcessCallback *	pCallback)
{
  if (! Run(fileName, lpszArguments, pCallback, 0, 0))
    {
      FATAL_MIKTEX_ERROR ("Process::Run",
			  T_("The operation failed for some reason."),
			  fileName.Get());
    }
}
Exemplo n.º 19
0
static int raw_devices_unlink_database(const PathName& file_name)
{
	UCHAR header_buffer[RAW_HEADER_SIZE + PAGE_ALIGNMENT];
	UCHAR* const header = FB_ALIGN(header_buffer, PAGE_ALIGNMENT);

	int desc = os_utils::open(file_name.c_str(), O_RDWR | O_BINARY);
	if (desc < 0)
	{
		ERR_post(Arg::Gds(isc_io_error) << Arg::Str("open") << Arg::Str(file_name) <<
				 Arg::Gds(isc_io_open_err) << Arg::Unix(errno));
	}

	memset(header, 0xa5, RAW_HEADER_SIZE);

	int i;

	for (i = 0; i < IO_RETRY; i++)
	{
		const ssize_t bytes = write(desc, header, RAW_HEADER_SIZE);

		if (bytes == RAW_HEADER_SIZE)
			break;

		if (bytes == -1 && SYSCALL_INTERRUPTED(errno))
			continue;

		ERR_post(Arg::Gds(isc_io_error) << Arg::Str("write") << Arg::Str(file_name) <<
				 Arg::Gds(isc_io_write_err) << Arg::Unix(errno));
	}

	//if (desc != -1) perhaps it's better to check this???
		close(desc);

#ifdef DEV_BUILD
	gds__log ("raw_devices_unlink_database: %s -> %s\n",
				file_name.c_str(), i < IO_RETRY ? "true" : "false");
#endif

	return 0;
}
Exemplo n.º 20
0
void PipeStream::Open(const PathName& fileName, const vector<string>& arguments)
{
  childStartInfo.FileName = fileName.ToString();
  childStartInfo.Arguments = arguments;
  childStartInfo.RedirectStandardInput = true;
  childStartInfo.RedirectStandardError = true;
  childStartInfo.RedirectStandardOutput = true;
  childProcess = Process::Start(childStartInfo);
  Application::GetApplication()->LogInfo("started PipeStream child process " + std::to_string(childProcess->GetSystemId()) + ": " + StringUtil::Flatten(arguments, ' '));
  childStdinFile = childProcess->get_StandardInput();
  setvbuf(childStdinFile, nullptr, _IONBF, 0);
  StartThreads();
}
Exemplo n.º 21
0
bool
Directory::Exists (/*[in]*/ const PathName & path)
{
  struct stat statbuf;
  if (stat(path.Get(), &statbuf) == 0)
    {
      if (S_ISDIR(statbuf.st_mode) == 0)
	{
	  SessionImpl::theSession->trace_access->WriteFormattedLine
	    ("core",
	     T_("%s is not a directory"),
	     Q_(path));
	  return (false);
	}
      return (true);
    }
  int error = errno;
  if (error != ENOENT)
    {
      FATAL_CRT_ERROR ("stat", path.Get());
    }
  return (false);
}
Exemplo n.º 22
0
// if pathNameTo is provided, lookup file before that
SysStatus
FileSystemK42RamFS::lookup(PathName *pathName, uval pathLen,
			   PathName *pathNameTo, FileToken *retToken)
{
    PathName *currentName = pathName;
    PathName *endName;
    char buf[PATH_MAX+1];
    FileToken rtoken, entryToken;

    if (pathNameTo) {
	endName = pathNameTo;
    } else {
	endName = (PathName*)(uval(pathName) + pathLen);
    }
    tassertMsg((currentName <= endName), "currentName > endName");

    SysStatus rc;

    rtoken = root;

    uval currentNameLen = pathLen;
    while (currentName < endName) {
	currentNameLen = currentName->getCompLen(currentNameLen);
	memcpy(buf, currentName->getCompName(currentNameLen), currentNameLen);
	buf[currentNameLen] = 0;

	rc = lookup(rtoken, buf, currentNameLen, &entryToken);
	_IF_FAILURE_RET(rc);

	rtoken = entryToken;
	currentName = currentName->getNext(currentNameLen);
    }

    *retToken = rtoken;

    return 0;
}
Exemplo n.º 23
0
// Set a prefix to a filename based on the ISC_PATH user variable.
// Returns true if database name is expanded using ISC_PATH.
static bool setPath(const PathName& filename, PathName& expandedName)
{
	// Look for the environment variables to tack onto the beginning of the database path.
	PathName pathname;
	if (!fb_utils::readenv("ISC_PATH", pathname))
		return false;

	// If the file already contains a remote node or any path at all forget it.
	if (hasSeparator(filename))
		return false;

	// concatenate the strings

	expandedName = pathname;

	// CVC: Make the concatenation work if no slash is present.
	char lastChar = expandedName[expandedName.length() - 1];
	if (lastChar != ':' && lastChar != '/' && lastChar != '\\')
		expandedName.append(1, PathUtils::dir_sep);

	expandedName.append(filename);

	return true;
}
Exemplo n.º 24
0
bool ConfigFile::wildCards(const char* currentFileName, const PathName& pathPrefix, FilesArray& components)
{
	// Any change in directory can cause config change
	PathName prefix(pathPrefix);
	if(!pathPrefix.hasData())
		prefix = ".";

	bool found = false;
	PathName next(components.pop());

#ifdef DEBUG_INCLUDES
	fprintf(stderr, "wildCards: prefix=%s next=%s left=%d\n",
		prefix.c_str(), next.c_str(), components.getCount());
#endif

	ScanDir list(prefix.c_str(), next.c_str());
	while (list.next())
	{
		PathName name;
		const PathName fileName = list.getFileName();
		if (fileName == ".")
			continue;
		if (fileName[0] == '.' && next[0] != '.')
			continue;
		PathUtils::concatPath(name, pathPrefix, fileName);

#ifdef DEBUG_INCLUDES
		fprintf(stderr, "in Scan: name=%s pathPrefix=%s list.fileName=%s\n",
			name.c_str(), pathPrefix.c_str(), fileName.c_str());
#endif

		if (filesCache)
			filesCache->addFile(name);

		if (components.hasData())	// should be directory
		{
			found = found || wildCards(currentFileName, name, components);
		}
		else
		{
			MainStream include(name.c_str(), false);
			if (include.active())
			{
				found = true;
				parse(&include);
			}
		}
	}

	return found;
}
Exemplo n.º 25
0
void
File::SetTimes (/*[in]*/ const PathName &	path,
		/*[in]*/ time_t			creationTime,
		/*[in]*/ time_t			lastAccessTime,
		/*[in]*/ time_t			lastWriteTime)
{
  UNUSED_ALWAYS (creationTime);
  utimbuf times;
  time_t now = time(0);
  if (lastAccessTime == static_cast<time_t>(-1))
    {
      lastAccessTime = now;
    }
  if (lastWriteTime == static_cast<time_t>(-1))
    {
      lastWriteTime = now;
    }
  times.actime = lastAccessTime;
  times.modtime = lastWriteTime;
  if (utime(path.Get(), &times) != 0)
    {
      FATAL_CRT_ERROR ("utimes", path.Get());
    }
}
Exemplo n.º 26
0
BOOL PlugInPathList::DeletePathName( const PathName& OldPath )
{
	String_256 OldPathStr = OldPath.GetPath();
	PlugInPath* pPath = (PlugInPath *)GetHead();
	while (pPath)
	{
		PathName Path = pPath->GetPathName();
		if (Path.GetPath() == OldPathStr)
		{
			RemoveItem(pPath);
			// remove item returns NULL if problem
			if (pPath == NULL)
				return FALSE;
			delete pPath;
			return TRUE;
		}

		// Try the next pathname in the list
		pPath = (PlugInPath *)GetNext(pPath);
	}

	// Failed to find the path in the list
	return FALSE;
}
Exemplo n.º 27
0
void
Process::Run (/*[in]*/ const PathName &	fileName,
	      /*[in]*/ const char *	lpszArguments)
{
  if (! Process::Run (fileName,
		      lpszArguments,
		      reinterpret_cast<IRunProcessCallback*>(0),
		      0,
		      0))
    {
      FATAL_MIKTEX_ERROR ("Process::Run",
			  T_("The operation failed for some reason."),
			  fileName.Get());
    }
}
Exemplo n.º 28
0
bool PIO_on_raw_device(const PathName& file_name)
{
/**************************************
 *
 *	P I O _ o n _ r a w _ d e v i c e
 *
 **************************************
 *
 * Functional description
 *	Checks if the supplied file name is a special file
 *
 **************************************/
	struct stat s;

	return (stat(file_name.c_str(), &s) == 0 && (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)));
}
Exemplo n.º 29
0
INT32 PluginOILFilter::HowCompatible(PathName& FileName)
{
	INT32 HowCompatible = 0;

	// Here we need to run the plugin synchronously with the following options
	// -c -f <filename>

	// Check stderr for errors
	// Get HowCompatible from stdout
	if (!m_CanImport.IsEmpty())
	{
		wxString sCommand(m_CanImport);
		sCommand.Replace(_T("%IN%"), (LPCTSTR)FileName.GetPath());

		TRACEUSER("Gerry", _T("Running '%s'"), sCommand.c_str());

		wxArrayString saOutput;
		wxArrayString saErrors;
		INT32 code = wxExecute(sCommand, saOutput, saErrors, wxEXEC_NODISABLE);
		TRACEUSER("Gerry", _T("wxExecute returned %d"), code);
		if (code == 0)
		{
			// Extract the value from saOutput
			if (saOutput.Count() > 0)
			{
				INT32 Val = wxAtoi(saOutput[0]);
				TRACEUSER("Gerry", _T("Command '%s' returned string '%s'"), sCommand.c_str(), saOutput[0].c_str());
				TRACEUSER("Gerry", _T("Value = %d"), Val);
				if (Val >= 0 && Val <= 10)
				{
					HowCompatible = Val;
				}
			}
			else
			{
				TRACEUSER("Gerry", _T("Command '%s' returned no output value"), sCommand.c_str());
			}
		}
		else
		{
			TRACEUSER("Gerry", _T("Command '%s' exited with code %d"), sCommand.c_str(), code);
		}
	}

	return(HowCompatible);
}
Exemplo n.º 30
0
void InternalConnection::attach(thread_db* tdbb, const PathName& dbName,
		const MetaName& user, const string& pwd,
		const MetaName& role)
{
	fb_assert(!m_attachment);
	Database* dbb = tdbb->getDatabase();
	fb_assert(dbName.isEmpty() || dbName == dbb->dbb_database_name.c_str());

	// Don't wrap raised errors. This is needed for backward compatibility.
	setWrapErrors(false);

	Jrd::Attachment* attachment = tdbb->getAttachment();
	if ((user.isEmpty() || user == attachment->att_user->getUserName()) &&
		pwd.isEmpty() &&
		(role.isEmpty() || role == attachment->att_user->getSqlRole()))
	{
		m_isCurrent = true;
		m_attachment = attachment->getInterface();
	}
	else
	{
		m_isCurrent = false;
		m_dbName = dbb->dbb_database_name.c_str();
		generateDPB(tdbb, m_dpb, user, pwd, role);

		// Avoid change of m_dpb by validatePassword() below
		ClumpletWriter newDpb(m_dpb);
		validatePassword(tdbb, m_dbName, newDpb);

		FbLocalStatus status;
		{
			EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
			RefPtr<JProvider> jInstance(JProvider::getInstance());
			jInstance->setDbCryptCallback(&status, tdbb->getAttachment()->att_crypt_callback);
			m_attachment.assignRefNoIncr(jInstance->attachDatabase(&status, m_dbName.c_str(),
				newDpb.getBufferLength(), newDpb.getBuffer()));
		}

		if (status->getState() & IStatus::STATE_ERRORS)
			raise(&status, tdbb, "JProvider::attach");
	}

	m_sqlDialect = (m_attachment->getHandle()->att_database->dbb_flags & DBB_DB_SQL_dialect_3) ?
					SQL_DIALECT_V6 : SQL_DIALECT_V5;
}