Устранение некоторых ошибок локализации в пакете samba-2.2.2

Я живу в большом микрорайоне Москвы, где имеется районная локальная сеть. Число компьютеров в ней уже перевалило за 500. Конечно, в сети преобладает Microsoft. В "часы пик" в Microsoft network работает до 150 компьютеров.

Основное время я работаю под Solaris 8 x86. Это операционная система типа UNIX.

Для того, чтобы иметь возможность, как самому экспортировать ресурсы, так и иметь доступ к ресурсам других я установил пакет samba-2.2.2, взятый с http://www.sunfreeware.com.

При работе с пакетом возникли замечания, связанные с локализацией.

1) Некоторые компьютеры в нашей сети используют netbios имена компьютеров и доменов написанные по-русски, с использованием пробелов.

Программа nmblookup выдаёт русские имена точками, программа smbclient не соединяется с такими компьютерами.

Имена директорий, записанные русскими буквами в кодировке UNICODE, программой smbclient показываются неправильно. Войти в эти директории невозможно. Имена файлов, записанные русскими буквами в кодировке UNICODE, также показываются неправильно. К таким файлам доступ из UNIX отсутствует.

Текстовые строки с комментариями в конфигурационном файле нужно вводить в кодировке DOS и сообщения, посылаемые через WinPopUp (по команде smbclient -M), кодируются в DOS, но не в UNIX. Это неудобно.

Для исправления внесите следующие изменения:

a) В программу samba-2.2.2/source/libsmb/nmblib.c, функцию debug_nmb_res_rec()

$ diff nmblib.c nmblib.c.orig
83,89c83,85
< 	  uchar x[2];
< 	  x[0] = res->rdata[i+j];
< 	  x[1] = '\0';
< 
< 	  if (x[0] < 32 || !is_indos_printable(x[0])) x[0] = '.';
< 	  dos_to_unix(x, True);
<  
---
> 	  uchar x = res->rdata[i+j];
> 	  if (x < 32 || x > 127) x = '.';
> 	  
91c87
< 	  DEBUGADD(4, ("%c", x[0]));
---
> 	  DEBUGADD(4, ("%c", x));
$ 

b) В программу samba-2.2.2/source/utils/nmblookup.c, функцию do_node_status()

$ diff nmblookup.c nmblookup.c.orig
120d119
< 			dos_to_unix(cleanname, True);
122c121
< 				if ((uchar)cleanname[j] < 32) cleanname[j] = '.';
---
> 				if (!isprint((int)cleanname[j])) cleanname[j] = '.';
$ 

с) В программу samba-2.2.2/source/lib/charcnv.c, необходимо добавить функцию is_indos_printable()

$ diff charcnv.c charcnv.c.orig
371,378d370
< 
< int is_indos_printable(char c)
< {
<     if (dos2unix[(unsigned char) c] != CTRLZ)
< 	return 1;
<     else
< 	return 0;
< }
$ 

d) В программу samba-2.2.2/source/client/client.c, функцию do_connect()

$ diff client.c client.c.orig
2013c2013
< 			 dos_to_unix(called.name, False), cli_errstr(c)));
---
> 			 called.name, cli_errstr(c)));
$ 

e) В программу samba-2.2.2/source/libsmb/cliconnect.c, функцию cli_send_tconX()

$ diff cliconnect.c cliconnect.c.orig
279c279
< 	p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE);
---
> 	p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE);
$ 

f) В программу samba-2.2.2/source/libsmb/clistr.c, функции clistr_push() и clistr_pull()

$ diff clistr.c clistr.c.orig
72c72
< 		dos_PutUniCode(dest, unix_to_dos(src,False), dest_len, flags & STR_TERMINATE);
---
> 		dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
129,131c129
< 		int i;
< 		uint16 c;
< 		char *d = dest;
---
> 		int i, c;
135c133
< 			unicode_to_dos_char(d++, c);
---
> 			*dest++ = c;
137c135
< 		*d = 0;
---
> 		*dest++ = 0;

g) В программу samba-2.2.2/source/libsmb/clilist.c, функцию interpret_long_filename()

$ diff clilist.c clilist.c.orig
139,140c139
< /* FIX p[1] < 32. I test it only for Russian locale. */
< 					if (p[1] < 32 && namelen > 1) flags |= STR_UNICODE;
---
> 					if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
$ 

Это исправление не позволяет использовать все номера таблиц UNICODE, покрываются только основные локализации, в том числе и русская. Как исправить более корректно - не знаю.

Здесь находятся все вышеупомянутые файлы в скорректированном виде. Вы можете использовать их для справки.

Затем Вы должны оттранслировать samba, и переписать новые версии ВСЕХ программ из директории samba-2.2.2/source/bin в директорию /usr/local/samba/bin.

Для экономии дисковой памяти сделайте strip.

$ strip *

В Makefile это не предусмотрено.

Все файлы в директории /usr/local/samba/bin должны принадлежать bin:bin

# cd /usr/local/samba/bin; chmod bin:bin *

2) Имеется полезный скрипт findsmb, написанный на Perl. В binary пакете SMCsamba для Solaris он почему-то отсутствует, но Вы можете найти его, например, в каталоге samba-2.2.2/packaging/RedHat/findsmb пакета с исходным текстом.

Скрипт позволяет вывести информацию о сетевом окружении и экспортируемых ресурсах компьютеров Вашей локальной сети.

Однако и здесь имеется ошибка. В netbios-именах допустимы пробелы, а скрипт этого не учитывает.

Поправить можно так:

$ diff findsmb findsmb.orig
18c18
< $SAMBABIN = "/usr/local/samba/bin";
---
> $SAMBABIN = "/usr/bin";
76c76
< 	/\s*([^<]*[^< ])\s* 	/(\S+)/;
106c106
< 	/\s*([^<]*[^< ])\s*         /(\S+)/;
$ 

Возможно имеются ещё ошибки.

Заметил, что логфайлы log.<имя_машины> получают названия в кодировке DOS, если имя машины задано русскими буквами.

Исправлю, если руки дойдут...


This page last updated on Jan 20, 2003. Copyright © 2002-2003, Vitaly Filatov, Moscow, Russia
Webmaster