Patch for freeipmi-0.1.3 to run on FreeBSD

Requirements:

  1. FreeBSD (tested on FreeBSD 5.3-BETA7).
     You will need "options SYSVSEM" in your kernel config
     or sysvsem.ko module loaded. On FreeBSD > 5.2.1 You will
     also need "device io" in kernel or loaded as module unless
     You specify USE_IOPERM compilation option (see note
     on i386_set_ioperm below).
  2. guile library (ports/lang/guile, tested with guile-1.6.4_6)
  3. argp library (ports/devel/argp-standalone, argp-standalone-1.3 tested)
  4. gmake

Installation:

  tar xzvf freeipmi-0.1.3.tar.gz
  cd freeipmi-0.1.3
  patch -p0 < /path/to/this/patch
  env CFLAGS="-I/usr/local/include" \
    LDFLAGS="-L/usr/local/lib -largp" \
    ./configure
  gmake all
  # su to root
  gmake install
  mkdir -p /var/lib/freeipmi
  chmod 0700 /var/lib/freeipmi
  touch /var/lib/freeipmi/ipckey

Using i386_set_ioperm(2) instead of io(4):

  i386_set_ioperm has known issues on FreeBSD 5.x (bus errors
  on io port access), so this patch uses io(4) to access io ports by default.
  To enable using i386_set_ioperm instead of io(4) specify USE_IOPERM
  copmilation option at configure time:

    env CFLAGS="-DUSE_IOPERM -I/usr/local/include" \
      LDFLAGS="-L/usr/local/lib -largp" \
      ./configure

Dmitry Frolov <frol(at)nov.net>

=============================================================================

--- ../freeipmi-0.1.3/bmc-watchdog/src/bmc-watchdog.c	Mon Oct 11 23:45:23 2004
+++ ./bmc-watchdog/src/bmc-watchdog.c	Mon Oct 25 20:39:43 2004
@@ -33,7 +33,9 @@
 #if STDC_HEADERS
 #include <string.h>
 #endif
+#ifndef __FreeBSD__
 #include <sys/io.h>
+#endif
 #include <syslog.h>
 #include <assert.h>
 #include <stdarg.h>
@@ -1805,9 +1807,22 @@
 int 
 main(int argc, char **argv)
 {
+#if	defined(__FreeBSD__) && !defined(USE_IOPERM)
+  int dev_io_fd;
+#endif
+
   _err_init(argv[0]);
 
+#ifdef __FreeBSD__
+#ifdef USE_IOPERM
+  if (i386_set_ioperm(0, 0x10000, 1) == -1)
+#else
+  dev_io_fd = open("/dev/io", O_RDONLY);
+  if (dev_io_fd == -1)
+#endif /* !USE_IOPERM */
+#else
   if(iopl(3) != 0)
+#endif /* !__FreeBSD__ */
     {
       /* glibc bug on older ia64 systems returns EACCES instead of EPERM */  
       if (errno == EPERM || errno == EACCES)
@@ -1842,6 +1857,10 @@
     _daemon_cmd();
   else
     _err_exit("internal error, command not set");
+
+#if defined(__FreeBSD__) && !defined(USE_IOPERM)
+  close(dev_io_fd);
+#endif
             
   close(logfile_fd);
   closelog();
--- ../freeipmi-0.1.3/fish/src/fi-commands.c	Fri May  7 05:26:27 2004
+++ ./fish/src/fi-commands.c	Mon Oct 25 20:39:43 2004
@@ -42,7 +42,9 @@
 #endif
 
 #include "freeipmi.h"
+#ifndef __FreeBSD__
 #include <error.h>
+#endif
 
 #include "fish.h"
 #include "fi-utils.h"
--- ../freeipmi-0.1.3/fish/src/fi-utils.c	Thu May  6 04:00:19 2004
+++ ./fish/src/fi-utils.c	Mon Oct 25 20:39:43 2004
@@ -80,7 +80,11 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#ifdef __FreeBSD__
+#include "freeipmi.h"
+#else
 #include <error.h>
+#endif
 
 #include <sys/socket.h>
 #include <netinet/in.h>
--- ../freeipmi-0.1.3/fish/src/fi-utils.h	Thu May  6 04:00:19 2004
+++ ./fish/src/fi-utils.h	Mon Oct 25 20:39:43 2004
@@ -72,9 +72,11 @@
   bell (); \
 }
 
+#ifndef __FreeBSD__
 /* defining strcasestr function temporarily */
 extern char *strcasestr (__const char *__haystack, __const char *__needle)
      __THROW __attribute_pure__;
+#endif
 
 void get_terminal_attributes (void);
 void set_terminal_attributes (void);
--- ../freeipmi-0.1.3/fish/src/fish.c	Fri Oct 22 07:17:08 2004
+++ ./fish/src/fish.c	Mon Oct 25 20:39:43 2004
@@ -36,7 +36,9 @@
 #include <sys/stat.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
+#ifndef __FreeBSD__
 #include <error.h>
+#endif
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
--- ../freeipmi-0.1.3/fish/src/ipmi-wrapper-sensor.c	Sat Oct  9 06:16:44 2004
+++ ./fish/src/ipmi-wrapper-sensor.c	Mon Oct 25 20:39:43 2004
@@ -6,7 +6,11 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef __FreeBSD__
+#include <stdlib.h>
+#else
 #include <alloca.h>
+#endif
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
--- ../freeipmi-0.1.3/fish/src/ipmi-wrapper.c	Thu Jun 24 00:14:31 2004
+++ ./fish/src/ipmi-wrapper.c	Mon Oct 25 20:39:43 2004
@@ -35,6 +35,9 @@
 #endif
 
 #include <stdio.h>
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -44,7 +47,11 @@
 #include <string.h>
 #endif
 
+#ifdef __FreeBSD__
+#include <stdlib.h>
+#else
 #include <alloca.h>
+#endif
 #include <netdb.h>
 
 #include "fish.h"
--- ../freeipmi-0.1.3/fish/src/scm-procedures.c	Fri Sep 10 07:09:17 2004
+++ ./fish/src/scm-procedures.c	Mon Oct 25 20:39:43 2004
@@ -54,6 +54,10 @@
 # endif
 #endif
 
+#if defined(__FreeBSD__) && !defined(EBADMSG)
+#define EBADMSG		ENOMSG
+#endif
+
 #include "fish.h"
 #include "extension.h"
 #include "fi-utils.h"
--- ../freeipmi-0.1.3/fish/src/xmalloc.h	Thu May  6 04:00:19 2004
+++ ./fish/src/xmalloc.h	Mon Oct 25 20:39:43 2004
@@ -56,7 +56,11 @@
 # define _(Text) Text
 #endif
 
+#ifdef __FreeBSD__
+#include "freeipmi.h"
+#else
 #include "error.h"
+#endif
 
 #ifndef EXIT_FAILURE
 # define EXIT_FAILURE 1
@@ -71,10 +75,12 @@
 void xfree (__VOID *p);
 #endif
 
+#ifndef __FreeBSD__
 #if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
 void error (int, int, const char *, ...);
 #else
 void error ();
+#endif
 #endif
 
 #ifdef __cplusplus
--- ../freeipmi-0.1.3/ipmipower/src/ipmipower_output.c	Tue Oct  5 08:09:55 2004
+++ ./ipmipower/src/ipmipower_output.c	Mon Oct 25 20:39:43 2004
@@ -123,7 +123,7 @@
   return;
 }
 
-auth_type_t 
+output_type_t 
 ipmipower_output_index(char *str) 
 {
   assert(str != NULL);
--- ../freeipmi-0.1.3/ipmipower/src/wrappers.c	Sat Oct  9 06:16:44 2004
+++ ./ipmipower/src/wrappers.c	Mon Oct 25 20:39:43 2004
@@ -50,6 +50,18 @@
 #endif
 #include <sys/poll.h>
 
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#if __FreeBSD_version >= 502010
+#include <sys/limits.h>
+#else
+#include <machine/limits.h>
+#endif
+#ifndef REG_NOERROR
+#define REG_NOERROR 0
+#endif
+#endif /* __FreeBSD__ */
+
 #include "wrappers.h"
 #include "cbuf.h"
 #include "error.h"
@@ -362,7 +374,10 @@
          */
         if (!((errno == EWOULDBLOCK) ||
               (errno == ECONNABORTED) ||
-              (errno == EPROTO) || (errno == EINTR)))
+#ifndef __FreeBSD__
+              (errno == EPROTO) ||
+#endif
+              (errno == EINTR)))
             lsd_fatal_error(__FILE__, __LINE__, "accept");
     }
     return new;
@@ -509,8 +524,10 @@
     int n;
     char buf[MAX_REG_BUF];
 
+#ifndef __FreeBSD__
     /* Review: undocumented, is it needed? */
     re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
+#endif
     Strncpy(buf, string, MAX_REG_BUF);
     n = regexec(preg, buf, nmatch, pmatch, eflags);
     return n;
--- ../freeipmi-0.1.3/ipmipower/src/wrappers.h	Wed May 12 00:05:25 2004
+++ ./ipmipower/src/wrappers.h	Mon Oct 25 20:39:43 2004
@@ -27,6 +27,9 @@
 #ifndef WRAPPERS_H
 #define WRAPPERS_H
 
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
 #include <regex.h>
 #include <netdb.h>
 #include <sys/types.h>
--- ../freeipmi-0.1.3/libfreeipmi/src/freeipmi.h	Fri May 14 00:32:57 2004
+++ ./libfreeipmi/src/freeipmi.h	Tue Oct 26 00:24:56 2004
@@ -88,6 +88,65 @@
 #include "ipmi-watchdog.h"
 #include "ipmi-msg-interface-desc.h"
 #include "ipmi-ping.h"
+
+#ifdef __FreeBSD__
+
+extern void freeipmi_error(int __status, int __errnum,
+	const char *__format, ...)
+		__attribute__ ((__format__ (__printf__, 3, 4)));
+char *freeipmi_strndup(const char *, size_t);
+ssize_t freeipmi_getline(char **buf, size_t *bufsize, FILE *fp);
+
+#define error	freeipmi_error
+#define strndup	freeipmi_strndup
+#define getline	freeipmi_getline
+
+#if __GNUC__
+#define _program_name   __progname
+#define program_invocation_short_name	__progname
+extern char *__progname;
+#else
+#define _program_name   (NULL)
+#define	program_invocation_short_name	(NULL)
+#endif /* !__GNUC__ */
+
+/* Replacements for glibc-isms */
+
+#ifdef __GNUC__
+/* Duplicate S, returning an identical alloca'd string.  */
+#define strdupa(s)									\
+	(__extension__									\
+		({											\
+			__const char *__old = (s);				\
+			size_t __len = strlen (__old) + 1;		\
+			char *__new = (char *) alloca (__len);	\
+			(char *) memcpy (__new, __old, __len);	\
+		}))
+
+/* Return an alloca'd copy of at most N bytes of string.  */
+#define strndupa(s, n)								\
+	(__extension__									\
+		({											\
+			__const char *__old = (s);				\
+			size_t __len = strlen (__old);			\
+			char *__new = (char *) alloca (__len + 1);	\
+			__new[__len] = '\0';					\
+			(char *) memcpy (__new, __old, __len);	\
+		}))
+
+/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
+ *    set to EINTR.  */
+
+#define TEMP_FAILURE_RETRY(expression)				\
+	(__extension__									\
+		({ long int __result;						\
+			do __result = (long int) (expression);	\
+			while (__result == -1L && errno == EINTR);	\
+		__result; }))
+#endif /* __GNUC__ */
+
+#endif /* __FreeBSD__ */
+
 #else
 #include <freeipmi/bit-ops.h>
 #include <freeipmi/fiid.h>
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-kcs-interface.c	Fri May 14 01:24:22 2004
+++ ./libfreeipmi/src/ipmi-kcs-interface.c	Mon Oct 25 20:39:43 2004
@@ -62,6 +62,10 @@
 # endif
 #endif
 
+#if defined(__FreeBSD__) && !defined(USE_IOPERM)
+#include <fcntl.h>
+#endif
+
 #include <errno.h>
 #include "freeipmi.h"
 
@@ -77,6 +81,10 @@
 static unsigned long kcs_sleep_usecs = IPMI_KCS_SLEEP_USECS;
 static int kcs_mutex_semid;
 
+#if defined(__FreeBSD__) && !defined(USE_IOPERM)
+static int ipmi_ksc_dev_io_fd = -1;
+#endif
+
 fiid_template_t tmpl_hdr_kcs =
   {
     {2, "lun"},
@@ -104,8 +112,17 @@
   kcs_mutex_semid = ipmi_mutex_init (IPMI_KCS_IPCKEY ());
   ERR (kcs_mutex_semid != -1);
 
-#if defined(__FreeBSD__)
-  return (ioperm (sms_io_base, 0x02, 0x01));
+#ifdef __FreeBSD__
+#ifdef USE_IOPERM
+  /* i386_set_ioperm has known problems on FBSD 5.x (bus errors). */
+  return (i386_set_ioperm(sms_io_base, 0x02, 0x01));
+#else
+  /* Opening /dev/io raises IOPL bits for current process. */
+  /* XXX This fd will remain open until exit as there is no
+   * uninitialization routine. */
+  ipmi_ksc_dev_io_fd = open("/dev/io", O_RDONLY);
+  return (ipmi_ksc_dev_io_fd == -1 ? -1 : 0);
+#endif
 #else
   return (iopl (3));
 #endif
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-lan-interface.c	Sat Jul 10 07:16:06 2004
+++ ./libfreeipmi/src/ipmi-lan-interface.c	Mon Oct 25 20:39:43 2004
@@ -62,6 +62,10 @@
 # endif
 #endif
 
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
+
 #include <sys/socket.h>
 #include <netdb.h>
 #include <netinet/in.h>
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-msg-support-cmds.c	Fri May 14 01:24:22 2004
+++ ./libfreeipmi/src/ipmi-msg-support-cmds.c	Mon Oct 25 20:39:43 2004
@@ -62,6 +62,9 @@
 #endif
 
 #include <errno.h>
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
 #include <netinet/in.h>
 
 #include "freeipmi.h"
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-sdr-repo-cache.c	Fri May 14 01:24:22 2004
+++ ./libfreeipmi/src/ipmi-sdr-repo-cache.c	Mon Oct 25 20:39:43 2004
@@ -38,8 +38,8 @@
 #endif
 
 #include <stdio.h>
-#include <sys/mman.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 
 #ifdef HAVE_FCNTL_H
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-semaphores.h	Fri Oct 15 04:08:13 2004
+++ ./libfreeipmi/src/ipmi-semaphores.h	Mon Oct 25 20:47:41 2004
@@ -79,7 +79,7 @@
 
 #define IPMI_MUTEX_UP(semid)                 IPMI_MUTEX_UNLOCK (semid)
 
-#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+#if defined(__FreeBSD__)
   /* union semun is defined by including <sys/sem.h> */
 #else
   /* according to X/OPEN we have to define it ourselves */
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-smic-interface.c	Thu May  6 04:00:19 2004
+++ ./libfreeipmi/src/ipmi-smic-interface.c	Mon Oct 25 20:39:43 2004
@@ -29,6 +29,10 @@
 #include <string.h>
 #endif
 
+#if defined(__FreeBSD__) && !defined(USE_IOPERM)
+#include <fcntl.h>
+#endif
+
 #include <errno.h>
 #include "freeipmi.h"
 
@@ -40,6 +44,9 @@
 #define _OUTB(data, port)  outb (data, port)
 #endif
 
+#if defined(__FreeBSD__) && !defined(USE_IOPERM)
+static int ipmi_smic_dev_io_fd = -1;
+#endif
 
 static u_int64_t smic_poll_count;
 static unsigned long smic_sleep_usecs = IPMI_SMIC_SLEEP_USECS;
@@ -62,8 +69,17 @@
 {
   smic_sleep_usecs = sleep_usecs;
 
-#if defined(__FreeBSD__)
-  return (ioperm (sms_io_base, 0x02, 0x01));
+#ifdef __FreeBSD__
+#ifdef USE_IOPERM
+  /* i386_set_ioperm has known problems on FBSD 5.x (bus errors). */
+  return (i386_set_ioperm(sms_io_base, 0x02, 0x01));
+#else
+  /* Opening /dev/io raises IOPL bits for that process. */
+  /* XXX This fd will remain open until exit as there is no
+   * uninitialization routine. */
+  ipmi_smic_dev_io_fd = open("/dev/io", O_RDONLY);
+  return (ipmi_smic_dev_io_fd == -1 ? -1 : 0);
+#endif
 #else
   return (iopl (3));
 #endif
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-utils.c	Thu May  6 04:00:19 2004
+++ ./libfreeipmi/src/ipmi-utils.c	Mon Oct 25 20:39:43 2004
@@ -33,6 +33,9 @@
 #endif
 
 #include <errno.h>
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
 
 #include "freeipmi.h"
 
--- ../freeipmi-0.1.3/libfreeipmi/src/ipmi-watchdog.c	Sat Jun 26 07:42:30 2004
+++ ./libfreeipmi/src/ipmi-watchdog.c	Mon Oct 25 20:39:43 2004
@@ -29,6 +29,9 @@
 #endif
 
 #include <errno.h>
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
 #include <netinet/in.h>
 
 #include "freeipmi.h"
--- ../freeipmi-0.1.3/libfreeipmi/src/libfreeipmi.c	Thu May  6 04:00:19 2004
+++ ./libfreeipmi/src/libfreeipmi.c	Tue Oct 26 00:24:13 2004
@@ -29,4 +29,97 @@
 #include "freeipmi.h"
 
 
+#ifdef __FreeBSD__
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <readline/readline.h>
+
+/* Replacement for glibc error() */
+void
+freeipmi_error(int status, int errnum, const char *message, ...)
+{
+	va_list args;
+
+	fflush(stdout);
+	if (_program_name)
+		fprintf(stderr, "%s: ", _program_name);
+
+	va_start(args, message);
+	vfprintf(stderr, message, args);
+	va_end(args);
+
+	if (errnum)
+		/* XXX strerror is not not thread safe */
+		fprintf(stderr, ": %s", strerror(errnum));
+	putc('\n', stderr);
+	fflush (stderr);
+	if (status)
+		exit(status);
+}
+
+/* Replacement for glibc strndup() */
+char *
+freeipmi_strndup(const char *s, size_t n)
+{
+	/* XXX strlen -> strnlen */
+	size_t len = strlen(s);
+	char *new = (char *)malloc(len + 1);
+
+	if (new == NULL)
+		return NULL;
+
+	new[len] = '\0';
+	return (char *)memcpy(new, s, len);
+}
+
+/* Replacement for glibc getline */
+ssize_t
+freeipmi_getline(char **buf, size_t *size, FILE *fp)
+{
+	ssize_t n = 0;
+
+	if (buf == NULL || size == NULL) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (*buf == NULL || *size == 0) {
+		*size = 120;
+		*buf = (char *)malloc(*size);
+		if (*buf == NULL)
+			return -1;
+	}
+
+	for (;;) {
+		int ch;
+
+		if (n + 2 > *size) {
+			size_t newsize = *size * 2;
+			char *newbuf = (char *)realloc(*buf, newsize);
+
+			if (newbuf == NULL)
+				return -1;
+			*buf = newbuf;
+			*size = newsize;
+		}
+
+		ch = fgetc(fp);
+
+		if (ch == -1) {
+			(*buf)[n++] = '\0';
+			return -1;
+		}
+
+		(*buf)[n++] = ch;
+
+		if (ch == '\n') {
+			(*buf)[n++] = '\0';
+			return n;
+		}
+	}
+}
+
+#endif /* __FreeBSD__ */
--- ../freeipmi-0.1.3/libfreeipmi/src/rmcp.c	Wed Oct 20 05:07:43 2004
+++ ./libfreeipmi/src/rmcp.c	Mon Oct 25 20:39:43 2004
@@ -62,8 +62,16 @@
 # endif
 #endif
 
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
+
 #include <errno.h>
 #include <netinet/in.h>
+
+#if defined(__FreeBSD__) && !defined(EBADMSG)
+#define EBADMSG		ENOMSG
+#endif
 
 #include "freeipmi.h"
 
