Самое важное - не молчать. Спросите в конференции ports@openbsd.org, не ведется ли работа над этим портом. Напишите о создании порта автору программы, сообщите о проблемах, которые вам удалось найти. Если сведения о лицензии некорректны, сообщите ему об этом. Если для того, чтобы собрать порт, вам пришлось пройти огонь, воду и медные трубы, расскажите автору программы, что в ней нужно исправить. И, наконец, если автор программы пишет только под Linux и не думает, что пользователи других систем заслуживают внимания, постарайтесь переубедить его.
Прежде всего прочитайте информацию на этой странице. После этого обратитесь к смежным документам, в особенности к списку требований к портированным приложениям.
Наконец, проведите как можно более тщательное тестирование порта!
После этого порт можно отсылать. Запакуйте директорию, в которой хранятся файлы порта, tar-ом и gzip-ом. Выложите архив на FTP или веб-сервере и пошлите ссылку на него в конференцию ports@openbsd.org. Вы можете также послать в конференцию сам файл в кодировке MIME, если вам так удобнее.
/usr/local/etc/rc.d./usr/local часто экспортируется по NFS и используется
несколькими машинами. По этой причине конфигурационные файлы для каждой
отдельной машины хранятся не в /usr/local, а в
/etc. Еще одним правилом OpenBSD является то, что файлы в
/etc никогда не обновляются автоматически. Если для порта
требуется выполнение каких-либо действий при загрузке системы, то вместо
автоматической правки файлов в /etc, администратору должны
быть предоставлены сведения о том, что необходимо сделать.
-lcrypt.libc.
/usr/ports/infrastructure/db/user.list.
$OpenBSD$.
Если программа портируется с другой системы, оставьте в Makefile
тэг этой системы. Однако тэг $Id$ для FreeBSD
должен быть заменен на $FreeBSD$.
strcat/strcpy/strcmp/sprintf.
sprintf должен быть заменён на snprintf.
/tmp
символическими ссылками на более важные системные файлы, например,
/etc/master.passwd.
fopen и freopen создают новый файл
или открывают существующий файл для записи. Злоумышленник может создать
символическую ссылку /tmp/addrpool_dump на файл
/etc/master.passwd. Как только ссылка будет открыта, файл
паролей будет поврежден. Даже если перед открытием вы вызовете функцию
unlink, этим вы просто ограничите вероятность атаки.
Вместо fopen и freopen рекомендуется
использовать open с O_CREAT|O_EXCL и
fdopen.
mktemp. Если линковщик bsd выдает предупреждения по поводу ее
использования, внесите необходимые поправки в исходный код.
Это не просто s/mktemp/mkstemp/g.mktemp(3) за более
подробной информацией. Правильное использование mkstemp
можно увидеть в исходном коде ed и mail.
Редким случаем правильного использования mktemp
является порт rsync.
startx. Поскольку это была setuid-программа, то ее можно
было запускать с любым файлом в роли скрипта. Если файл не был скриптом,
выдавалось сообщение о синтаксической ошибке в выводилась первая
строка этого файла без проверки прав доступа. Это позволяло, например,
получить первую строку из файла паролей, который обычно начинается с
записи root. Не следует также открывать файл, а затем смотреть с
помощью fstat, возможно ли открытие (злоумышленник может
воспользоваться этим, чтобы получить доступ к /dev/rst0 и перемотать
ленту). Вместо этого, открывайте файл с заведомо правильными uid, gid
и списком групп.
popen и system. Вместо них
используйте fork, pipe и execve.
/dev/fd/0.
inetd и просто
добавить необходимые записи в inetd.conf. Для написания
таких сервисов, необходимы специальные знания, а без них лучше и не
пытаться писать setuid-программы.
PATH (не используйте system с неопределенным
именем, избегайте использования execvp), а также более
тонких вещей вроде локали, часового пояса, настроек терминала и так
далее. Помните о том, что даже если вы приняли все меры предосторожности,
программы которые вы вызываете - нет. Никогда не
используйте system в привилегированных программах.
Полностью создавайте строку исполнения программы, переменные окружения
и только тогда вызывайте execve. Прочитайте страницу
руководства perlsec, в котором хорошо освещен данный вопрос.
__OpenBSD__ или вообще
откажитесь от нее. Использование конструкции вроде
#if defined(__NetBSD__) || defined(__FreeBSD__)
редко уместно. Мы не советуем вам просто добавлять к этому списку
__OpenBSD__. Вместо этого выясните, использование какой
функциональности за этим стоит. Помощь в этом вам могут оказать страницы
руководства, из которых можно узнать, когда та или иная функциональность
была впервые введена в BSD. Обычно правильное решение - это сравнение
переменной BSD с номерами релизов. За дополнительной
информацией обратитесь к NetBSD package guide.
BSD. Вместо этого подключите
sys/param.h. Это определит параметр BSD и
присвоит ему верное значение. Фрагмент правильного кода:
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
tcgetattr, чем
определять выполняется ли программа под BSD 4.3 или SystemVR4. Тесты
такого рода лишь вносят путаницу. Проведите тестирование под одной
конкретной системой, установите значение HAVE_TCGETATTR,
после чего переходите к другой системе. Бывает, что портирующий программу
человек, чтобы сэкономить время, добавляет набор определений
-DHAVE_XXX в Makefile. Или пишет конфигурационный скрипт,
который проверяет наличие какой-либо функции и автоматически ее добавляет.
Отрицательный пример - исходный код порта nethack 3.2.2, в котором очень
много зависимостей от типа ОС. Большинство из них неактуальны: более
удобно использовать POSIX функции, чем старые несовместимые функции BSD
и SystemV. Тем более, что поддержка традиционных bsd функций сейчас
осуществляется только через библиотеки совместимости.
#define POSIX_C_SOURCE для
всего проекта, а не там где вы этого захотите.
unistd.h, fcntl.h или termios.h.
Об их местоположении написано на соответствующей странице руководства.
Для включения нужного файла вам может понадобиться набор из макросов
HAVE_XXX. Даже если файл будет включен дважды, ничего
страшного не произойдет.unsigned long вместо size_t). К тому же,
некоторые компиляторы, как gcc в OpenBSD, могут работать эффективнее
с часто используемыми функциями, как strlen, если подключен
правильный файл заголовка.
/* prototype part */
#ifdef USE_OWN_GCVT
char *foo_gcvt(double number, size_t ndigit, char *buf);
#else
/* include correct file */
#include <stdlib.h>
/* use system function */
#define foo_gcvt gcvt
#endif
/* definition part */
#ifdef USE_OWN_GCVT
char *foo_gcvt(double number, size_t ndigit, char *buf)
{
/* proper definition */
}
/* typical use */
s = foo_gcvt(n, 15, b);
${NO_SHARED_LIBS} (но будьте
внимательны, она может быть определена только после включения
bsd.port.mk). Если ваш порт использует GNU configure,
добавьте строку
CONFIGURE_ARGS += ${CONFIGURE_SHARED} в Makefile.
bsd.port.mk, поскольку предполагается, что пользователи
должны обновлять все дерево портов, в том числе и bsd.port.mk.
NEED_VERSION более не используется.
curses.h/libcurses/libtermlib относятся к
``new curses''. Замените ncurses.h на curses.h.
Чтобы использовать ``old (BSD) curses'', определите
_USE_OLD_CURSES_ перед включением файла curses.h
(обычно в Makefile) и делайте линковку с параметром -locurses.
sgtty
на новую tcgetattr семейства POSIX. Не рекомендуется
использовать старую организацию в новых версиях программ. В некоторых
случаях tcgetattr может определяться как синоним к
sgtty, но в OpenBSD это может рассматриваться лишь в
качестве временной меры. Отрицательным примером в данном случае может
служить исходный код xterm. Правильно представьте функциональность
системы: вам необходим тип данных, который запоминает состояние
термианала (возможно typedef), необходима функция которая извлечет
текущее состояние и функция которая установит новое состояние терминала.
Функции, которые изменяют состояние более сложны, поскольку они различны
в разных системах. Помните, что вам необходимо обработать случаи,
при которых программа не соединена с терминалом; не забывайте и о
сигналах, причем не только о сигнале завершения, но и о сигнале
перевода процесса в фоновый режим (SIGTSTP). Программа
должна возвращать терминал в нормальное состояние. Протестируйте свою
программу под старой оболочкой, например sh, которая не возвращает
терминал в исходное состояние.
TERMCAP для корректной работы.
sigaction за дополнительной
информацией.