Формат строки подключения к FB через TCP/IP.

Затеял написать парсер строки с расположением базы данных при подключении к серверу через TCP/IP (INET).

Полез в исходники сервера (FB 2.5.x):

bool ISC_analyze_tcp(tstring& file_name, tstring& node_name)
{
/**************************************
 *
 *	I S C _ a n a l y z e _ t c p		( G E N E R I C )
 *
 **************************************
 *
 * Functional description
 *	Analyze a filename for a TCP node name on the front.  If
 *	one is found, extract the node name, compute the residual
 *	file name, and return true.  Otherwise return false.
 *
 **************************************/

	// Avoid trivial case

	if (!file_name.hasData())
		return false;

/* Scan file name looking for separator character */

	node_name.erase();
	const size p = file_name.find(INET_FLAG);
	if (p == npos || p == 0 || p == file_name.length() - 1)
		return false;

	node_name = file_name.substr(0, p);

#ifdef WIN_NT
/* For Windows NT, insure that a single character node name does
   not conflict with an existing drive letter. */

	if (p == 1)
	{
		const ULONG dtype = GetDriveType((node_name + ":\\").c_str());
		// Is it removable, fixed, cdrom or ramdisk?
		if (dtype > DRIVE_NO_ROOT_DIR && (dtype != DRIVE_REMOTE || Config::getRemoteFileOpenAbility()))
		{
			// CVC: If we didn't match, clean our garbage or we produce side effects
			// in the caller.
			node_name.erase();
			return false;
		}
	}
#endif

	file_name.erase(0, p + 1);
	return true;
}

Из штатного алгоритма видим, что (в случае Windows) проблема только с однобуквенным именем хоста — возможен конфликт с именем локального диска. Если честно, мне раньше и в голову не приходила мысль давать компьютеру имя из одной буквы. Наверное, потому что я еще ни разу не писал подобный парсер.

Нашел вот такой документ — «Connection to the sample database». Из которого узнал, что в Linux локальный путь к базе данных может начинаться с символа ‘/’ — «servername:/filesystem-path/database-file». То есть, формально, строка «с:/windows/system32/cmd.exe» может быть интерпретирована как путь к локальному файлу в Windows, так и к сетевому ресурсу на Linux (хост «C», ресурс «/windows/system32/cmd.exe»).

Вот сижу теперь и думаю — наверное не зря все таки придумали всякие префиксы «http://», «ftp://».

Был бы формат «inet://host:local_path», и не было бы никакой неоднозначности.

Уверен, что я не первый кто про это подумал 🙂

6 комментариев

dimitr  on Февраль 13th, 2015

> Был бы формат «inet://host:local_path», и не было бы никакой неоднозначности.

В тройке он есть 🙂 Только вот так: «inet://host[:port]/local_path». Ну и wnet/xnet соответственно.

Dmitry Kovalenko  on Февраль 13th, 2015

Вот ведь…

Действительно есть. Даже в моей прошлогодней (декабрьской) сборке присутствует нечто похожее.

Правда не получилось проверить.

Декабрьская сборка:
При указании «inet://w7_64-sql2012:c:\works\database\ibp_test_fb30_d3.gdb» я получаю ошибку «unavailable database». Без «inet://» коннект проходит без проблем.

Новую сборку создать не удалось (VS2013):
26> Creating library ..\..\..\temp\Win32\Debug\legacy_auth\legacy_auth.lib and object ..\..\..\temp\Win32\Debug\legacy_auth\legacy_auth.exp
26>common.lib(isc_file.obj) : error LNK2019: unresolved external symbol _WNetOpenEnumA@20 referenced in function «void __cdecl ISC_expand_share(class Firebird::StringBase &)» (?ISC_expand_share@@YAXAAV?$StringBase@VPathNameComparator@Firebird@@@Firebird@@@Z)
26>common.lib(isc_file.obj) : error LNK2019: unresolved external symbol _WNetEnumResourceA@16 referenced in function «void __cdecl ISC_expand_share(class Firebird::StringBase
&)» (?ISC_expand_share@@YAXAAV?$StringBase@VPathNameComparator@Firebird@@@Firebird@@@Z)
26>common.lib(isc_file.obj) : error LNK2019: unresolved external symbol _WNetCloseEnum@4 referenced in function «void __cdecl ISC_expand_share(class Firebird::StringBase
&)» (?ISC_expand_share@@YAXAAV?$StringBase@VPathNameComparator@Firebird@@@Firebird@@@Z)
26>common.lib(isc_file.obj) : error LNK2019: unresolved external symbol _WNetGetUniversalNameA@16 referenced in function «void __cdecl ISC_expand_share(class Firebird::StringBase
&)» (?ISC_expand_share@@YAXAAV?$StringBase@VPathNameComparator@Firebird@@@Firebird@@@Z)
26>..\..\..\temp\Win32\Debug\firebird\plugins\legacy_auth.dll : fatal error LNK1120: 4 unresolved externals

Dmitry Kovalenko  on Февраль 13th, 2015

Методом (остервенелого) тыка удалось подключиться с использованием строки «inet://[w7_64-sql2012]/c:\works\database\ibp_test_fb30_d3.gdb».

Dmitry Kovalenko  on Февраль 13th, 2015

Вспомнив анекдот (гуглим — «достать краба»), задействовал отладчик.

Можно еще подключиться с указанием «inet://w7_64-sql2012/c:\works\database\ibp_test_fb30_d3.gdb».

Подключение с указанием порта, похоже, угроблено.

hvlad  on Февраль 13th, 2015

Билд ещё днём исправлен был.
Ну и:
раз)
…\temp\Win32\Release\firebird>firebird.exe -a -m -p 4000

два)
F:\FB2\fb30.clean\temp\Win32\Release\firebird>isql inet://localhost:4000/s:\Temp\A.FDB -user sysdba -pass masterkey
Database: inet://localhost:4000/s:\Temp\A.FDB, User: sysdba
SQL> show version;
ISQL Version: WI-T3.0.0.31624 Firebird 3.0 Beta 2
Server version:
Firebird/Windows/Intel/i386 (access method), version «WI-T3.0.0.31624 Firebird 3.0 Beta 2»
Firebird/Windows/Intel/i386 (remote server), version «WI-T3.0.0.31624 Firebird 3.0 Beta 2/tcp (Win7x64)/P13:C»
Firebird/Windows/Intel/i386 (remote interface), version «WI-T3.0.0.31624 Firebird 3.0 Beta 2/tcp (Win7x64)/P13:C»
on disk structure version 12.0
SQL> exit;

три)
F:\FB2\fb30.clean\temp\Win32\Release\firebird>isql inet://localhost/s:\Temp\A.FDB -user sysdba -pass masterkey
Statement failed, SQLSTATE = 08006
Unable to complete network request to host «localhost».
-Failed to establish a connection.
Use CONNECT or CREATE DATABASE to specify a database
SQL> exit;

Так штааа…

🙂

Dmitry Kovalenko  on Февраль 13th, 2015

На декабрьской сборке у меня такая проблема:

inet://[w7_64-sql2012]:3050/c:\works\database\ibp_test_fb30_d3.gdb

Unable to complete network request to host "[w7_64-sql2012]:3050".
Failed to locate host machine.
The specified name was not found in the hosts file or Domain Name Services.

Может я что-то не догоняю?


Новую сборку пока не делал. Удолбался.

UPD. Пересобрал сервер и клиента. Строка соединения «inet://[w7_64-sql2012]:3050/c:\works\database\ibp_test_fb30_d3.gdb» начала обрабатываться без ошибок.

Оставить комментарий