LINUX.ORG.RU

Может кто поможет, ну не пойму в чём затык...


0

0

Пытаюсь кое-что исправить в vsftpd.

в файле sysutil.c

Добавляю в конец функцию:

char * utfTOwin(const char *buf)
{
  iconv_t ic;
  ic = iconv_open("UTF8", "CP1251");
  if (ic == (icon_t)(-1)) return NULL;
/* Дальше код не привожу, так как до него дело не доходит
}

Всё прекрасно собирается.

Не понимаю, почему никогда не инициализируется ic, то есть из этой
функции выход всегда NULL. Может кто промоделировать может. Грешу на 
патч openwall, но думаю врядли, всё же работает, а тут не хочет :-(
anonymous

Как смоделировать, ну например в функцию:
const char* vsf_sysutil_ulong_to_str(unsigned long the_ulong)

вставить в начале вот такие строки:

  iconv_t ic;

  ic = iconv_open("UTF8", "CP1251");
  if (ic == (iconv_t)(-1)) die("Don't work.");
  else die("It's OK.");

И попробуйте подключиться. Посмотрите, с какой надписью разорвался коннект.

Заметил такую особенность в функция которые возвращают тип int, всё
в порядке, iconv_open выполняется нормально, а вот в функциях которые
возвращают char* не инициализируется, почему такое может быть?

anonymous
()
Ответ на: комментарий от Die-Hard

Есть такие charset-ы, повторю если примерчик выше разместить в функции которая возвращает int, всё в порядке, которая возвращают char* - не в порядке. Почему?

anonymous
()
Ответ на: комментарий от nobody

Хе, сам vsftpd конечно не в chroot, но пользователи chroot-ятся.

anonymous
()
Ответ на: комментарий от nobody

>А vsftpd у тебя случайно не в chroot работает?

Вот что значит опыт программирования! Это именно из-за этого, то есть из-за того что пользователи chroot-ятся. Спасибо, а то я уже более 12 часов бьюсь с этой бедой. Логичный вопрос, как эту проблему решить?

anonymous
()
Ответ на: комментарий от anonymous

> Логичный вопрос, как эту проблему решить?

Сначала причина проблемы: после chroot нет каталога /usr/lib/gconv (или как он называется в твоей libc). В нем лежит инфа по перекодированию для iconv. Ее, соответственно, тоже нет.

А отсюда и варианты решения:
1) Открыть все необходимые файлы заранее, до chroot. А файлов там ну очень много.
2) Если нужен только русский, вставить в vsftpd свой перекодировщик. Примитивный код + куча таблиц, которые можно выдрать из libc.
3) Вкомпилить iconv со всеми таблицами в vsftpd статически. Гемор страшенный.
4) Не юзать chroot. Может быть небезопасно, если юзера левые. Т.е. не из твоей фирмы, и стало быть, наказать их в случае чего административными способами не получится.
5) Каждому юзеру создать ${HOME}/usr/libc/gconv со всеми файлами. Кривизна жуткая.
6) Заюзать pure-ftpd без chroot. Код у него чистый. Можно спать спокойно. Ну... почти спокойно. Но, с другой стороны, где гарантии, что ядерный chroot не дыряв?
7) Написать свой ftp сервер.

Это так, навскидку. Если подумать денек-другой, можно еще с полсотни вариантов придумать, более или менее кривых.

nobody ★★
()
Ответ на: комментарий от nobody

Делаем вывод:
1. Если много языков, то подходит либо 1) либо 3). Не знаю что проще.

Мне нужен только русский, но...
если с cp1251 <-> koi8-r всё просто, то как сделать utf-8 <-> cp1251 и utf-8 <-> koi8-r я не пойму, так просто не получается, может где глянуть можно?

anonymous
()
Ответ на: комментарий от anonymous

> как сделать utf-8 <-> cp1251 и utf-8 <-> koi8-r я не пойму

Если кодировок несколько, то лучше для каждой хранить только таблицу UCS<->codepage и гонять codepage1->codepage2 == codepage1->UCS->codepage2. Перевод UCS<->UTF-8 тривиален (на unicode.org где-то был).

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от watashiwa_daredeska

В общем если перед тем как на пользователя будет сделан chroot, открыть iconv, то в chroot у пользователя всё работает.

Вот только не знаю где этот дискриптор хранить, чтоб в конце сессии его нормально закрыть, а по возможности вообще его и использовать во время работы? Кто-нить ковырялся в исходниках vsftpd, где там можно хранить дискриптор открытой iconv?

anonymous
()
Ответ на: комментарий от anonymous

> Вот только не знаю где этот дискриптор хранить, чтоб в конце сессии его нормально закрыть

А на кой тебе его закрывать? Сначала делается fork, затем в контексте потомка -- chroot. Между fork и chroot открываешь файлы. По окончании сессии потомок умирает. Все открытые им файлы закрывает ядро.

> а по возможности вообще его и использовать во время работы

Дык, и используй, в чем проблема-то?

nobody ★★
()
Ответ на: комментарий от nobody

Честно признаюсь, я не профессиональный программист, программированием увлекался в универе помаленьку да и больше под Win32.

Значит сделал я между fork и chroot:

ic = iconv_open(from_char, to_char);

Воппрос, в каком месте обьявить переменную:

iconv_t ic

Чтобы она была отовсюду видна, чтобы мне не проходилось каждый раз когда нужно перекодировать делать icone_open; iconv_close. То есть вот перед chroot открыл, получил дескриптор ic, и чтоб этот дискриптор в любой функции юзать, его надо где то глобально обьявить, а вот где?

anonymous
()
Ответ на: комментарий от anonymous

Вот правила (объедини их по И):

1) Переменная должна быть объявлена перед ее использованием.
2) Переменная, которая должна быть видна везде, должна быть объявлена вне функции.
3) Переменная типа iconv_t должна быть объявлена после #include <iconv.h>.

Если переменная объявлена в одном файле .c, а используется в другом файле .с, то в другом файле перед типом переменной должно стоять слово extern.

nobody ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.