First look at the porting information on this page. Then check out the referenced documents, especially the OpenBSD porting checklist.
Test, then re-test, and finally test again!
Submit the port. Create a gzipped tarball of the port directory. You can then either place it on a public FTP or HTTP server, sending its address to ports@openbsd.org or send the port mime encoded to the same address. Pick whichever method works best for you.
/usr/share/mk/bsd.port.mk
. This is the
system ports makefile included at the end of each individual
port makefile. Read the comments at the start of the makefile.
They do a good job of describing the available make options.
/usr/local
is often shared between several machines
thanks to NFS. For this reason, configuration files that are specific
to a given machine can't be stored under /usr/local
,
/etc
is the central repository for per machine
configuration files. Moreover, OpenBSD policy is to never update
files under /etc
automatically. Ports that need some
specific boot setup should advise the administrator about what to do
instead of blindly installing files.
-lcrypt
.libc
.
$
OpenBSD$
CVS tag to
the Makefile. If importing a port from another system be sure to
leave their tag in the Makefile, too. However, replace the FreeBSD
$
Id$
tag with the
$
FreeBSD$
tag.
strcat/strcpy/strcmp/sprintf
. In general,
sprintf
should be replaced with snprintf
.
/tmp
with symbolic links to more strategic files, such as
/etc/passwd
. For instance, the bsd linker warns about
mktemp
uses. These must be fixed.
This is not quite as simple as s/mktemp/mkstemp/g
.
startx
problem. As a setuid program,
you could launch startx with any file as a script. If the file was not
a valid shell script, a syntax error message would follow, along with the
first line of the offending file, without any further permission check.
Pretty handy to grab the first line of a shadow passwd file, considering
these often start with root entry. Do not open your file, and then do
an fstat
on the open descriptor to check if you should have
been able to open it (or the attacked will play with /dev/rst0 and rewind
your tape) -- open it with the correct uid/gid/grouplist set.
popen
and system
.
Use fork
, pipe
and execve
instead.
/dev/fd/0
.
inetd
control and just add the relevant entries to inetd.conf
.
You must know the appropriate magic for writing daemons to achieve that.
It could be argued that you have no business writing setuid programs if you don't
know how to do that.
xkobo
port for an instance of such a change.
PATH
(never use system
with an unqualified name), but also more subtle items
such as your locale, timezone, termcap, and so on. Be aware of transitivity: even though you're
taking full precautions, programs you call directly won't necessarily. Never
use system
in privileged programs, build your command line, a controlled environment,
and call execvp
directly. The perlsec
man page is a good tutorial on
such problems.
issetugid
addresses this problem, from the library writer point
of view. Don't try to port libraries unless you understand this issue thoroughly.
__OpenBSD__
should be used sparingly, if at all.
Constructs that look like
#if defined(__NetBSD__) || defined(__FreeBSD__)are often inappropriate. Don't add blindly
__OpenBSD__
to it. Instead, try to figure out what's going on, and what actual
feature is needed. Manual pages are often useful, as they include
historic comments, stating when a particular feature was incorporated
into BSD. Checking the numeric value of BSD
against known
releases is often the right way. See
the NetBSD package guide
for more information.
BSD
is a bad idea. Try to include sys/param.h
.
This not only defines BSD
, it also gives it a proper value.
The right code fragment should look like:
#if (defined(__unix__) || defined(unix)) && !defined(USG) #include <sys/param.h> #endif
tcgetattr
works than whether you're running
under BSD 4.3 or later, or SystemVR4. These kind of tests just confuse the
issue. The way to go about it is, for instance, to test for one particular
system, set up a slew of HAVE_TCGETATTR
defines, then proceed to
the next system. This technique separates features tests from specific OSes.
In a hurry, another porter can just add the whole set of -DHAVE_XXX
defines to the Makefile. One may also write or add to a configure script to check for
that feature and add it automatically. As an example not to follow, check nethack 3.2.2
source: it assumes loads of things based on the system type. Most of these assumptions
are obsolete and no longer reflect reality: POSIX functions are more useful than older
BSD versus SystemV differences, to the point that some traditional bsd functions are
now only supported through compatibility libraries.
#define POSIX_C_SOURCE
throughout the whole project, not when you feel like it.
unistd.h
, fcntl.h
or termios.h
.
The man page frequently states where the prototype lies. You might need
another slew of HAVE_XXX
macros to procure the right file.
Don't worry about including the same file twice, include files have guards
that prevent all kinds of nastiness.unsigned long
instead of size_t
), or get some
const
status wrong. Also, some compilers, such as OpenBSD's own gcc,
are able to do a better job with some very frequent functions such as
strlen
if you include the right header file.
/* 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);
/usr/local/bin
or
/usr/X11R6/bin
is in the installers path. A good
way to verify this is to create and install your port while
running as root
with only /bin
and
/usr/bin
in your path.
${MACHINE_ARCH} ==
alpha
curses.h/libcurses/libtermlib
are the
``new curses''. Change:ncurses.h ==> curses.h
-lncurses ==> -lcurses
_USE_OLD_CURSES_
before including curses.h
(usually in a Makefile) and
linking with -lcurses
.
sgtty
to the newer POSIX tcgetattr
family.
Avoid the older style in new code. Some code may define tcgetattr
to be a synonym for the older sgtty
, but this is at best a stopgap
measure on OpenBSD. The xterm
source code is a very good example of
what not to do.
Try to get your system functionality right: you want a type that remembers
the state of your terminal (possible typedef), you want a function that
extracts the current state, and a function that sets the new state.
Functions that modify this state are more difficult, as they tend to vary
depending upon the system. Also, don't forget that you will have to handle
cases where you are not connected to the terminal, and that you need to
handle signals: not only termination, but also getting put in the background
you should leave your terminal in a sane state. Do your tests under an
older shell, such as sh, which does not reset the terminal in any way at
program's termination.
TERMCAP
variable and get it to work properly.
sigaction
to ensure a specific semantics, along with other system calls referenced in its manpage.