Author: ranger
Date: Tue Jan  2 20:42:38 2007
New Revision: 551

URL: 
<http://svn.finkproject.org/websvn/listing.php?sc=1&rev=551&repname=user%3a+ranger>
Log:
libfam builds, time to test it

Added:
    trunk/experimental/common/main/finkinfo/libs/fam.info
    trunk/experimental/common/main/finkinfo/libs/fam.patch

Added: trunk/experimental/common/main/finkinfo/libs/fam.info
URL: 
<http://svn.finkproject.org/websvn/filedetails.php?path=/trunk/experimental/common/main/finkinfo/libs/fam.info&rev=551&repname=user%3a+ranger>
==============================================================================
--- trunk/experimental/common/main/finkinfo/libs/fam.info (added)
+++ trunk/experimental/common/main/finkinfo/libs/fam.info Tue Jan  2 20:42:38 
2007
@@ -1,0 +1,55 @@
+Package: fam
+Version: 2.7.0
+Revision: 1
+Depends: %N-shlibs (>= %v-%r)
+BuildDepends: libtool14, autoconf (>= 2.60-1), automake1.9
+
+Source: ftp://oss.sgi.com/projects/%n/download/stable/%n-%v.tar.gz
+Source-MD5: 1bf3ae6c0c58d3201afc97c6a4834e39
+Patch: %n.patch
+
+SetCPPFLAGS: -DHAVE_KQUEUE=1 -DNDEBUG
+SetCFLAGS: -Os
+CompileScript: <<
+#!/bin/sh -ev
+
+       autoreconf -f -v -i
+       ./configure --prefix=%p/lib/%N --mandir=%p/share/man 
--sysconfdir=%p/etc --bindir=%p/bin --sbindir=%p/sbin --libexecdir=%p/sbin
+       make
+<<
+
+InstallScript: <<
+       make -j1 install DESTDIR=%d
+       perl -pi -e 's,local_only = false,local_only = true,' %i/etc/fam.conf
+<<
+SplitOff: <<
+  Package: %N-shlibs
+  Description: Shared libraries for FAM
+  Files: lib/%N/lib/libfam.*.dylib
+  Shlibs: %p/lib/%N/lib/libfam.0.dylib 1.0.0 libfam-shlibs (>= 2.7.0-1)
+<<
+SplitOff2: <<
+  Package: %N-dev
+  Depends: %N-shlibs (= %v-%r)
+  Replaces: %N
+  Description: Development headers and libraries for FAM
+  Files: lib share/man/man3
+<<
+
+ConfFiles: %p/etc/fam.conf
+DocFiles: AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
+Description: File Alteration Monitor
+Maintainer: Benjamin Reed <[EMAIL PROTECTED]>
+Homepage: http://oss.sgi.com/projects/fam/
+License: GPL
+DescPackaging: <<
+Includes patches from NetBSD pkgsrc to use the BSD kqueue APIs instead
+of the (linux- and SGI-only) imon support.
+<<
+DescDetail: <<
+GUI tools should not mislead the user; they should display the current
+state of the system, even when changes to the system originate from
+outside of the tools themselves.  FAM helps make GUI tools more usable
+by notifying them when the files they're interested in are created,
+modified, executed, and removed.
+<<

Added: trunk/experimental/common/main/finkinfo/libs/fam.patch
URL: 
<http://svn.finkproject.org/websvn/filedetails.php?path=/trunk/experimental/common/main/finkinfo/libs/fam.patch&rev=551&repname=user%3a+ranger>
==============================================================================
--- trunk/experimental/common/main/finkinfo/libs/fam.patch (added)
+++ trunk/experimental/common/main/finkinfo/libs/fam.patch Tue Jan  2 20:42:38 
2007
@@ -1,0 +1,1482 @@
+diff -uNr fam-2.7.0/configure.ac fam-2.7.0-patched/configure.ac
+--- fam-2.7.0/configure.ac     2003-11-26 14:47:59.000000000 -0500
++++ fam-2.7.0-patched/configure.ac     2007-01-02 13:22:13.000000000 -0500
+@@ -31,7 +31,7 @@
+ # Checks for header files.
+ AC_HEADER_STDC
+ AC_HEADER_DIRENT
+-AC_CHECK_HEADERS([fcntl.h limits.h linux/imon.h netinet/in.h rpc/rpc.h 
rpcsvc/mount.h stddef.h stdlib.h string.h syslog.h sys/imon.h sys/param.h 
sys/select.h sys/statvfs.h sys/syssgi.h sys/time.h sys/types.h sys/un.h 
unistd.h])
++AC_CHECK_HEADERS([fcntl.h limits.h linux/imon.h netinet/in.h rpc/rpc.h 
rpc/rpcent.h rpcsvc/mount.h stddef.h stdlib.h string.h syslog.h sys/filio.h 
sys/imon.h sys/param.h sys/select.h sys/statvfs.h sys/syssgi.h sys/time.h 
sys/types.h sys/un.h unistd.h mntent.h sys/mnttab.h sys/sysmacros.h])
+ 
+ if test "$have_sys_imon_h"; then
+       MONITOR_FUNCS=IMonIRIX
+@@ -51,12 +51,14 @@
+ AC_TYPE_PID_T
+ AC_TYPE_SIZE_T
+ AC_HEADER_TIME
+-AC_CHECK_MEMBERS(struct sockaddr.sa_len, struct sockaddr_un.sun_len)
++AC_CHECK_MEMBERS(struct sockaddr.sa_len,,,[#include <sys/socket.h>])
++AC_CHECK_MEMBERS(struct sockaddr_un.sun_len,,,[#include <sys/types.h>
++#include <sys/un.h>])
+ 
+ # Checks for library functions.
+ AC_FUNC_ERROR_AT_LINE
+ AC_FUNC_SELECT_ARGTYPES
+-AC_CHECK_FUNCS([bindresvport _daemonize daemon getgrmember select])
++AC_CHECK_FUNCS([bindresvport _daemonize daemon getgrmember select unsetenv])
+ 
+ AC_CONFIG_FILES([Makefile
+                  src/Makefile
+diff -uNr fam-2.7.0/include/BTree.h fam-2.7.0-patched/include/BTree.h
+--- fam-2.7.0/include/BTree.h  2003-01-19 23:22:30.000000000 -0500
++++ fam-2.7.0-patched/include/BTree.h  2007-01-02 13:22:14.000000000 -0500
+@@ -76,8 +76,6 @@
+ 
+     static unsigned sizeofnode()      { return sizeof (Node); }
+ 
+-private:
+-
+     enum { fanout = 32 };
+     enum Status { OK, NO, OVER, UNDER };
+ 
+diff -uNr fam-2.7.0/lib/Client.c++ fam-2.7.0-patched/lib/Client.c++
+--- fam-2.7.0/lib/Client.c++   2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/lib/Client.c++   2007-01-02 13:22:14.000000000 -0500
+@@ -24,6 +24,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <netinet/in.h>
++#include <arpa/inet.h>
+ #include <sys/un.h>
+ #include <sys/socket.h>
+ #include <rpc/rpc.h>
+diff -uNr fam-2.7.0/lib/fam.c++ fam-2.7.0-patched/lib/fam.c++
+--- fam-2.7.0/lib/fam.c++      2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/lib/fam.c++      2007-01-02 13:22:14.000000000 -0500
+@@ -20,8 +20,12 @@
+ //  with this program; if not, write the Free Software Foundation, Inc., 59
+ //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ 
++#include "config.h"
+ #include <sys/types.h>
+ #include <rpc/rpc.h>
++#ifdef HAVE_RPC_RPCENT_H
++#include <rpc/rpcent.h>
++#endif
+ #include <sys/time.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+diff -uNr fam-2.7.0/src/Client.h fam-2.7.0-patched/src/Client.h
+--- fam-2.7.0/src/Client.h     2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/Client.h     2007-01-02 13:22:14.000000000 -0500
+@@ -25,6 +25,7 @@
+ 
+ #include <sys/types.h>
+ #include <netinet/in.h>  // for in_addr
++#include <arpa/inet.h>
+ 
+ #include "Activity.h"
+ #include "Boolean.h"
+diff -uNr fam-2.7.0/src/FileSystem.c++ fam-2.7.0-patched/src/FileSystem.c++
+--- fam-2.7.0/src/FileSystem.c++       2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/FileSystem.c++       2007-01-02 13:22:13.000000000 
-0500
+@@ -22,14 +22,20 @@
+ 
+ #include "FileSystem.h"
+ 
+-#include <mntent.h>
++#include "fam-mntent.h"
+ #include <string.h>
+ 
+ #include "Event.h"
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++FileSystem::FileSystem(const mnttab& mnt)
++    : mydir   (strcpy(new char[strlen(mnt.mnt_mountp) + 1], mnt.mnt_mountp)),
++      myfsname(strcpy(new char[strlen(mnt.mnt_special) + 1], mnt.mnt_special))
++#else
+ FileSystem::FileSystem(const mntent& mnt)
+     : mydir   (strcpy(new char[strlen(mnt.mnt_dir   ) + 1], mnt.mnt_dir   )),
+       myfsname(strcpy(new char[strlen(mnt.mnt_fsname) + 1], mnt.mnt_fsname))
++#endif
+ { }
+ 
+ FileSystem::~FileSystem()
+@@ -40,9 +46,15 @@
+ }
+ 
+ bool
++#if defined(HAVE_SYS_MNTTAB_H)
++FileSystem::matches(const mnttab& mnt) const
++{
++    return !strcmp(mydir, mnt.mnt_mountp) && !strcmp(myfsname, 
mnt.mnt_special);
++#else
+ FileSystem::matches(const mntent& mnt) const
+ {
+     return !strcmp(mydir, mnt.mnt_dir) && !strcmp(myfsname, mnt.mnt_fsname);
++#endif
+ }
+ 
+ void
+diff -uNr fam-2.7.0/src/FileSystem.h fam-2.7.0-patched/src/FileSystem.h
+--- fam-2.7.0/src/FileSystem.h 2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/FileSystem.h 2007-01-02 13:22:14.000000000 -0500
+@@ -27,7 +27,13 @@
+ #include "Request.h"
+ #include "Set.h"
+ 
++#include "fam-mntent.h"
++
++#if defined(HAVE_SYS_MNTTAB_H)
++struct mnttab;
++#else
+ struct mntent;
++#endif
+ struct stat;
+ 
+ //  FileSystem is the abstract base class for a per-filesystem object.
+@@ -91,12 +97,20 @@
+ 
+     typedef Set<ClientInterest *> Interests;
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    FileSystem(const mnttab&);
++#else
+     FileSystem(const mntent&);
++#endif
+     virtual ~FileSystem();
+ 
+     //  Miscellaneous routines
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    bool matches(const mnttab& m) const;
++#else
+     bool matches(const mntent& m) const;
++#endif
+     const char *dir() const           { return mydir; }
+     const char *fsname() const                { return myfsname; }
+     const Interests& interests()      { return myinterests; }
+diff -uNr fam-2.7.0/src/FileSystemTable.c++ 
fam-2.7.0-patched/src/FileSystemTable.c++
+--- fam-2.7.0/src/FileSystemTable.c++  2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/FileSystemTable.c++  2007-01-02 13:22:13.000000000 
-0500
+@@ -21,11 +21,13 @@
+ //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ 
+ #include <stddef.h>
++#include <stdio.h>
+ #include "FileSystemTable.h"
+ 
+-#include <mntent.h>
++#include "fam-mntent.h"
+ #include <stdlib.h>
+ #include <string.h>
++#include <sys/param.h>
+ 
+ #if HAVE_STATVFS
+ #include <sys/statvfs.h>
+@@ -106,7 +108,11 @@
+ 
+     //  Read /etc/mtab.
+     Cred::SuperUser.become_user();
++#if defined(HAVE_SYS_MNTTAB_H)
++    FILE *mtab = fopen(mtab_name, "r");
++#else
+     FILE *mtab = setmntent(mtab_name, "r");
++#endif
+     if(mtab == NULL)
+     {
+         Log::error("couldn't open %s for reading", mtab_name);
+@@ -114,40 +120,86 @@
+         return;
+     }
+     root = NULL;
++#if defined(HAVE_SYS_MNTTAB_H)
++    resetmnttab(mtab);
++    int ret = 0;
++    do
++#else
+     for (mntent *mp; ((mp = getmntent(mtab)) != NULL); )
++#endif
+     {
++#if defined(HAVE_SYS_MNTTAB_H)
++      struct mnttab ment, *mp;
++      mp = &ment;
++      ret = getmntent(mtab, mp);
++      FileSystem *fs = fs_by_name ? fs_by_name->find(mp->mnt_mountp) : NULL;
++#else
+       FileSystem *fs = fs_by_name ? fs_by_name->find(mp->mnt_dir) : NULL;
++#endif
+       if (fs && fs->matches(*mp))
+       {
+           Log::debug("mtab: MATCH     \"%s\" on \"%s\" using type <%s>",
++#if defined(HAVE_SYS_MNTTAB_H)
++                     mp->mnt_special, mp->mnt_mountp, mp->mnt_fstype);
++
++          new_fs_by_name->insert(mp->mnt_mountp, fs);
++          if (dismounted_fses.find(mp->mnt_mountp))
++              dismounted_fses.remove(mp->mnt_mountp);
++#else
+                      mp->mnt_fsname, mp->mnt_dir, mp->mnt_type);
+ 
+           new_fs_by_name->insert(mp->mnt_dir, fs);
+           if (dismounted_fses.find(mp->mnt_dir))
+               dismounted_fses.remove(mp->mnt_dir);
++#endif
+       }
+       else
+       {
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++            if ((!strcmp(mp->mnt_fstype, MNTTYPE_NFS)
++#else
+             if ((!strcmp(mp->mnt_type, MNTTYPE_NFS)
++#endif
+ #if HAVE_MNTTYPE_NFS2
++#if defined(HAVE_SYS_MNTTAB_H)
++                || !strcmp(mp->mnt_fstype, MNTTYPE_NFS2)
++#else
+                 || !strcmp(mp->mnt_type, MNTTYPE_NFS2)
+ #endif
++#endif
+ #if HAVE_MNTTYPE_NFS3
++#if defined(HAVE_SYS_MNTTAB_H)
++                || !strcmp(mp->mnt_fstype, MNTTYPE_NFS3)
++#else
+                 || !strcmp(mp->mnt_type, MNTTYPE_NFS3)
+ #endif
++#endif
+ #if HAVE_MNTTYPE_CACHEFS
++#if defined(HAVE_SYS_MNTTAB_H)
++                || !strcmp(mp->mnt_fstype, MNTTYPE_CACHEFS)
++#else
+                 || !strcmp(mp->mnt_type, MNTTYPE_CACHEFS)
+ #endif
++#endif
++#if defined(HAVE_SYS_MNTTAB_H)
++                ) && strchr(mp->mnt_special, ':'))
++#else
+                 ) && strchr(mp->mnt_fsname, ':'))
++#endif
+             {
+                 if(Log::get_level() == Log::DEBUG)
+                 {
+                     const char *mntopt = hasmntopt(mp, "dev");
+                     if(mntopt == NULL) mntopt = "";
+                   Log::debug("mtab: new NFS   \"%s\" on \"%s\" %s using <%s>",
++#if defined(HAVE_SYS_MNTTAB_H)
++                             mp->mnt_special, mp->mnt_mountp, mntopt,
++                               mp->mnt_fstype);
++#else
+                              mp->mnt_fsname, mp->mnt_dir, mntopt,
+                                mp->mnt_type);
++#endif
+                 }
+ 
+               fs = new NFSFileSystem(*mp);
+@@ -155,24 +207,45 @@
+           else
+           {
+               Log::debug("mtab: new local \"%s\" on \"%s\"",
++#if defined(HAVE_SYS_MNTTAB_H)
++                         mp->mnt_special, mp->mnt_mountp);
++#else
+                          mp->mnt_fsname, mp->mnt_dir);
++#endif
+ 
+               fs = new LocalFileSystem(*mp);
+           }
++#if defined(HAVE_SYS_MNTTAB_H)
++          new_fs_by_name->insert(mp->mnt_mountp, fs);
++#else
+           new_fs_by_name->insert(mp->mnt_dir, fs);
++#endif
+           if (fs_by_name)
+           {
+               // Find parent filesystem.
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++              FileSystem *parent = longest_prefix(mp->mnt_mountp);
++#else
+               FileSystem *parent = longest_prefix(mp->mnt_dir);
++#endif
+               assert(parent);
+               mount_parents.insert(parent->dir(), parent);
+           }
+       }
++#if defined(HAVE_SYS_MNTTAB_H)
++      if (!strcmp(mp->mnt_mountp, "/"))
++#else
+       if (!strcmp(mp->mnt_dir, "/"))
++#endif
+           root = fs;
+     }
++#if defined(HAVE_SYS_MNTTAB_H)
++    while (ret != -1);
++    fclose(mtab);
++#else
+     endmntent(mtab);
++#endif
+ 
+     if(root == NULL)
+     {
+@@ -255,7 +328,10 @@
+     //  create_fs_by_name initializes our "root" member variable.
+     if (!fs_by_name)
+     {   create_fs_by_name();
++#if !defined(BSD)
++        /* there is no mtab "file" in BSD */
+       mtab_watcher = new InternalClient(mtab_name, mtab_event_handler, NULL);
++#endif
+     }
+ 
+     cr.become_user();
+diff -uNr fam-2.7.0/src/IMon.c++ fam-2.7.0-patched/src/IMon.c++
+--- fam-2.7.0/src/IMon.c++     2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/IMon.c++     2007-01-02 13:22:13.000000000 -0500
+@@ -25,6 +25,7 @@
+ #include <assert.h>
+ #include <errno.h>
+ #include <fcntl.h>
++#include <sys/param.h>
+ 
+ #if HAVE_IMON
+ #ifdef __sgi
+@@ -32,15 +33,18 @@
+ #else
+ #include <linux/imon.h>
+ #endif
++#else // HAVE_IMON
++#include "imon-compat.h"
+ #endif
+ 
++#if HAVE_SYS_SYSMACROS_H
+ #include <sys/sysmacros.h>
++#endif
+ #include <unistd.h>
+ 
+ #include "Interest.h"
+ #include "Log.h"
+ #include "Scheduler.h"
+-#include "alloc.h"
+ 
+ int              IMon::imonfd = -2;
+ IMon::EventHandler IMon::ehandler = NULL;
+diff -uNr fam-2.7.0/src/IMonKQueue.c++ fam-2.7.0-patched/src/IMonKQueue.c++
+--- fam-2.7.0/src/IMonKQueue.c++       1969-12-31 19:00:00.000000000 -0500
++++ fam-2.7.0-patched/src/IMonKQueue.c++       2007-01-02 13:23:06.000000000 
-0500
+@@ -0,0 +1,453 @@
++//  $NetBSD: IMonKQueue.c++,v 1.3 2005/01/05 16:21:06 jmmv Exp $
++//
++//  Copyright (c) 2004, 2005 Julio M. Merino Vidal.
++//  
++//  This program is free software; you can redistribute it and/or modify it
++//  under the terms of version 2 of the GNU General Public License as
++//  published by the Free Software Foundation.
++//
++//  This program is distributed in the hope that it would be useful, but
++//  WITHOUT ANY WARRANTY; without even the implied warranty of
++//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any
++//  license provided herein, whether implied or otherwise, is limited to
++//  this program in accordance with the express provisions of the GNU
++//  General Public License.  Patent licenses, if any, provided herein do not
++//  apply to combinations of this program with other product or programs, or
++//  any other product whatsoever.  This program is distributed without any
++//  warranty that the program is delivered free of the rightful claim of any
++//  third person by way of infringement or the like.  See the GNU General
++//  Public License for more details.
++//
++//  You should have received a copy of the GNU General Public License along
++//  with this program; if not, write the Free Software Foundation, Inc., 59
++//  Temple Place - Suite 330, Boston MA 02111-1307, USA.
++
++// ------------------------------------------------------------------------
++
++//  imon emulation through kqueue
++//  -----------------------------
++//
++//  The code in this file provides an imon-like interface to FAM using kqueue,
++//  the kernel event notification mechanism found in FreeBSD, NetBSD and
++//  OpenBSD.
++//
++//  The idea is the following: a thread, kqueue_monitor, simulates the kernel
++//  part of imon.  This thread can receive commands (ioctl(2)s) and produces
++//  notifications when there is something to notify.  The thread is constantly
++//  running in the background, calling kevent(2) to see if there are new
++//  events in the monitored files since the last call.
++//
++//  Communication with kqueue_monitor is accomplished by using two pipes.
++//  pipe_out is used by the monitor to provide notifications; i.e., it is the
++//  same as the read end of the regular /dev/imon device, and produces
++//  compatible messages.  On the other hand we have pipe_in, which is used
++//  to give commands to the monitor (express and revoke); we can't emulate
++//  ioctl(2)s from user space, so we have to go this route.
++//
++//  Why we use pipe_in to provide commands to the thread, instead of some
++//  mutexes?  If we used mutexes, we'd have to give kevent(2) a timeout, to
++//  let it "reload" the list of changes to be monitored in case it was
++//  externally modified.  By using a pipe, we can tell kqueue(2) to monitor
++//  it for us, and let kevent(2) immediately return when there is a command
++//  to process.
++//
++//  However, there is a little problem when using kqueue instead of imon or
++//  polling.  kqueue(2) works by monitoring open file descriptors, instead
++//  of inodes on the disk.  Therefore we must keep all files being monitored
++//  open, and the number of open files can quickly raise in some environments.
++//  This is why the code unlimits the number of open files in imon_open and
++//  sets a reasonable maximum based on kern.maxfiles (to avoid overflowing
++//  it quickly).  If we overflow this limit, the poller will enter the game
++//  (because we will return an error).
++//
++//  Known problem: if we receive *lots* of events quickly, famd may end up
++//  locked.  To reproduce, run the test program provided by fam against a
++//  local directory, say /tmp/foo, and do the following:
++//     cd /tmp/foo; for f in $(jot 1000); do touch $(jot 100); rm *; done
++//  You should receive some messages like:
++//     famd[21058]: kqueue can't revoke "75", dev = 0, ino = 1113421
++//  while the test is running (not a lot), and it will eventually lock up.
++//
++//  Having said all this, let's go to the code...
++
++// ------------------------------------------------------------------------
++
++#include "IMon.h"
++#include "Log.h"
++
++#include "config.h"
++#include "imon-compat.h"
++
++#include <sys/event.h>
++#include <sys/param.h>
++#include <sys/resource.h>
++#include <sys/sysctl.h>
++#include <sys/time.h>
++
++#include <assert.h>
++#include <fcntl.h>
++#include <pthread.h>
++#include <string.h>
++#include <unistd.h>
++
++#include <map>
++
++// ------------------------------------------------------------------------
++
++// devino is a structure that holds a device/inode pair.  It is used as an
++// indentifier of files managed by imon.
++struct devino {
++    dev_t di_dev;
++    ino_t di_ino;
++
++    bool operator<(const struct devino& di) const
++        { return (di_dev < di.di_dev) or
++                 (di_dev == di.di_dev and di_ino < di.di_ino); }
++};
++
++// imon_cmd simulates commands thrown to imon as ioctl(2)s (but remember
++// we use a pipe).
++struct imon_cmd {
++#define IMON_CMD_EXPRESS 0
++#define IMON_CMD_REVOKE 1
++    int ic_type;
++
++    // imon identifies files through a device/inode pair.
++    struct devino ic_di;
++
++    // A pipe that will be used to receive the result of the command
++    // (asynchronously).
++    int ic_stat[2];
++
++    // If this is an 'express' command, we need the descriptor to monitor.
++    int ic_fd;
++};
++
++// ------------------------------------------------------------------------
++
++static int max_changes;
++static int last_change;
++static int kqueue_fd;
++static int pipe_in[2], pipe_out[2];
++static pthread_t kevent_thread;
++static struct kevent *changes;
++
++typedef std::map<struct devino, int> DEVINOFD_MAP;
++static DEVINOFD_MAP devino_to_fd;
++typedef std::map<int, struct devino> FDDEVINO_MAP;
++static FDDEVINO_MAP fd_to_devino;
++
++// ------------------------------------------------------------------------
++
++static void *kqueue_monitor(void *data);
++static void process_command(void);
++
++// ------------------------------------------------------------------------
++
++int
++IMon::imon_open(void)
++{
++    // Get the kernel event queue.  We only need one during all the life
++    // of famd.
++    kqueue_fd = kqueue();
++    if (kqueue_fd == -1)
++        return -1;
++
++    // Create "emulation" pipes.
++    if (pipe(pipe_in) == -1) {
++        close(kqueue_fd);
++        return -1;
++    }
++    if (pipe(pipe_out) == -1) {
++        close(kqueue_fd);
++        close(pipe_in[0]); close(pipe_in[1]);
++        return -1;
++    }
++
++    // Get the maximum number of files we can open and use it to set a
++    // limit of the files we can monitor.
++    size_t len = sizeof(max_changes);
++    if (sysctlbyname("kern.maxfiles", &max_changes, &len, NULL, 0) == -1)
++        max_changes = 128;
++    else
++        max_changes /= 2;
++
++    // Unlimit maximum number of open files.  We don't go to RLIM_INFINITY
++    // to avoid possible open descriptor leaks produce a system DoS.  75%
++    // of the system limit seems a good number (we request more than the
++    // number calculated previously to leave room for temporary pipes).
++    // We need to be root to do this.
++    uid_t olduid = geteuid();
++    seteuid(0);
++    struct rlimit rlp;
++    rlp.rlim_cur = rlp.rlim_max = max_changes * 3 / 2;
++    if (setrlimit(RLIMIT_NOFILE, &rlp) == -1)
++        Log::error("can't unlimit number of open files");
++    seteuid(olduid);
++
++    changes = new struct kevent[max_changes];
++
++    // We must monitor pipe_in for any commands that may alter the actual
++    // set of files being monitored.
++    EV_SET(&changes[0], pipe_in[0], EVFILT_READ,
++           EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
++    last_change = 1;
++
++    // Create a thread that will run the kevent(2) function continuously.
++    if (pthread_create(&kevent_thread, NULL, kqueue_monitor, NULL) != 0) {
++        close(kqueue_fd);
++        close(pipe_in[0]); close(pipe_in[1]);
++        close(pipe_out[0]); close(pipe_out[1]);
++        return -1;
++    }
++
++    return pipe_out[0];
++}
++
++// ------------------------------------------------------------------------
++
++IMon::Status
++IMon::imon_express(const char *name, struct stat *status)
++{
++    // Get file information.
++    struct stat sb;
++    if (status == NULL)
++        status = &sb;
++    if (lstat(name, status) == -1)
++        return BAD;
++
++    // Open the file to be monitored; kqueue only works with open descriptors
++    // so we have to keep this descriptor during the life of this 'interest'.
++    int fd = open(name, O_RDONLY);
++    if (fd == -1)
++        return BAD;
++
++    // Construct a command to 'express' interest in a file.  This will be
++    // handled by the kqueue_monitor thread as soon as possible.
++    struct imon_cmd cmd;
++    cmd.ic_type = IMON_CMD_EXPRESS;
++    cmd.ic_di.di_dev = status->st_dev;
++    cmd.ic_di.di_ino = status->st_ino;
++    cmd.ic_fd = fd;
++    if (pipe(cmd.ic_stat) == -1) {
++        close(fd);
++        return BAD;
++    }
++    write(pipe_in[1], &cmd, sizeof(struct imon_cmd));
++
++    // Wait for a result form the previous operation.
++    bool result;
++    read(cmd.ic_stat[0], &result, sizeof(bool));
++    close(cmd.ic_stat[0]); close(cmd.ic_stat[1]);
++    if (!result) {
++        close(fd);
++        Log::error("kqueue can't monitor more than %d files", max_changes);
++        return BAD;
++    }
++
++    Log::debug("told kqueue to monitor \"%s\", descriptor = %d, dev = %d, "
++               "ino = %d", name, cmd.ic_fd, cmd.ic_di.di_dev,
++               cmd.ic_di.di_ino);
++
++    return OK;
++}
++
++// ------------------------------------------------------------------------
++
++IMon::Status
++IMon::imon_revoke(const char *name, dev_t dev, ino_t ino)
++{
++    // Construct a command to 'revoke' interest from a file.  This will be
++    // handled by the kqueue_monitor thread as soon as possible.
++    struct imon_cmd cmd;
++    cmd.ic_type = IMON_CMD_REVOKE;
++    cmd.ic_di.di_dev = dev;
++    cmd.ic_di.di_ino = ino;
++    if (pipe(cmd.ic_stat) == -1)
++        return BAD;
++    write(pipe_in[1], &cmd, sizeof(struct imon_cmd));
++
++    // Wait for a result form the previous operation.
++    bool result;
++    read(cmd.ic_stat[0], &result, sizeof(bool));
++    close(cmd.ic_stat[0]); close(cmd.ic_stat[1]);
++    if (!result) {
++        Log::error("kqueue can't revoke \"%s\", dev = %d, ino = %d", name,
++                   cmd.ic_di.di_dev, cmd.ic_di.di_ino);
++        return BAD;
++    }
++
++    Log::debug("told kqueue to forget \"%s\", dev = %d, ino = %d", name,
++               cmd.ic_di.di_dev, cmd.ic_di.di_ino);
++
++    return OK;
++}
++
++// ------------------------------------------------------------------------
++
++static void *
++kqueue_monitor(void *data)
++{
++    struct kevent event;
++
++    for (;;) {
++        int nev = kevent(kqueue_fd, changes, last_change, &event, 1, NULL);
++        if (nev == -1)
++            Log::perror("kevent");
++        else if (nev > 0) {
++            assert(nev == 1);
++
++            if (event.flags & EV_ERROR) {
++                int fd = event.ident;
++
++                FDDEVINO_MAP::const_iterator iter = fd_to_devino.find(fd);
++                assert(iter != fd_to_devino.end());
++                struct devino di = iter->second;
++
++                Log::error("kqueue returned error for fd = %d, dev = %d, "
++                           "ino = %d", fd, di.di_dev, di.di_ino);
++
++                // Remove offending entry from the mappings.
++                assert(devino_to_fd.find(di) != devino_to_fd.end());
++                devino_to_fd.erase(di);
++                assert(devino_to_fd.find(di) == devino_to_fd.end());
++                assert(fd_to_devino.find(fd) != fd_to_devino.end());
++                fd_to_devino.erase(fd);
++                assert(fd_to_devino.find(fd) == fd_to_devino.end());
++
++                // Remove the entry associated to the descriptor from the list
++                // of changes monitored by kqueue.
++                int i;
++                for (i = 1; i < last_change; i++)
++                    if (changes[i].ident == fd)
++                        break;
++                for (int j = i; j < last_change - 1; j++)
++                    changes[j] = changes[j + 1];
++                last_change--;
++
++                close(fd);
++
++                continue;
++            }
++
++            if (event.ident == pipe_in[0]) {
++                // We have got a control command, so process it.
++                process_command();
++            } else {
++                // One of the descriptors we are monitoring has got activity.
++                FDDEVINO_MAP::const_iterator iter =
++                    fd_to_devino.find(event.ident);
++                if (iter != fd_to_devino.end()) {
++                    qelem_t elem;
++
++                    // Set device/inode identifier on imon element.
++                    const struct devino &di = (*iter).second;
++                    elem.qe_dev = di.di_dev;
++                    elem.qe_inode = di.di_ino;
++
++                    // Convert the modification flags reported by kqueue to
++                    // flags understood by imon.
++                    elem.qe_what = 0;
++                    if (event.fflags & NOTE_DELETE)
++                        elem.qe_what |= IMON_DELETE;
++                    if (event.fflags & NOTE_RENAME)
++                        elem.qe_what |= IMON_RENAME;
++                    if (event.fflags & NOTE_ATTRIB or event.fflags & 
NOTE_LINK)
++                        elem.qe_what |= IMON_ATTRIBUTE;
++                    if (event.fflags & NOTE_WRITE or event.fflags & 
NOTE_EXTEND)
++                        elem.qe_what |= IMON_CONTENT;
++
++                    // Deliver the element.
++                    write(pipe_out[1], &elem, sizeof(qelem_t));
++                } else
++                    Log::error("got an event from an unhandled device/inode "
++                               "pair");
++            }
++        }
++    }
++}
++
++// ------------------------------------------------------------------------
++
++static void
++process_command(void)
++{
++    bool result = false;
++    struct imon_cmd cmd;
++
++    // Read the command from the control pipe.
++    read(pipe_in[0], &cmd, sizeof(struct imon_cmd));
++    if (cmd.ic_type == IMON_CMD_EXPRESS) {
++        Log::debug("process_command: express, dev = %d, ino = %d",
++                   cmd.ic_di.di_dev, cmd.ic_di.di_ino);
++        if (devino_to_fd.find(cmd.ic_di) != devino_to_fd.end()) {
++            // The file is already being monitored.
++            close(cmd.ic_fd);
++            result = true;
++        } else if (fd_to_devino.find(cmd.ic_fd) != fd_to_devino.end()) {
++            // We can't receive a new interest of a descriptor that is
++            // already being monitored.  If this happens, there is an
++            // inconsistency in the data somewhere.
++            assert(false);
++        } else if (last_change < max_changes) {
++            // Add the new descriptor to the list of changes to monitor.
++            // We watch for any change that happens on it.
++            EV_SET(&changes[last_change], cmd.ic_fd, EVFILT_VNODE,
++                   EV_ADD | EV_ENABLE | EV_ONESHOT,
++                   NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB |
++                   NOTE_LINK | NOTE_RENAME | NOTE_REVOKE,
++                   0, 0);
++            last_change++;
++
++            // Map the device/inode pair to the file descriptor associated
++            // to it and viceversa.  We will need this information during
++            // 'revoke' and when we receive events.  We use two different
++            // maps to speed up searches in both directions later.
++            assert(devino_to_fd.find(cmd.ic_di) == devino_to_fd.end());
++            devino_to_fd.insert
++                (DEVINOFD_MAP::value_type(cmd.ic_di, cmd.ic_fd));
++            assert(devino_to_fd.find(cmd.ic_di) != devino_to_fd.end());
++            assert(fd_to_devino.find(cmd.ic_fd) == fd_to_devino.end());
++            fd_to_devino.insert
++                (FDDEVINO_MAP::value_type(cmd.ic_fd, cmd.ic_di));
++            assert(fd_to_devino.find(cmd.ic_fd) != fd_to_devino.end());
++
++            result = true;
++        }
++    } else if (cmd.ic_type == IMON_CMD_REVOKE) {
++        Log::debug("process_command: revoke, dev = %d, ino = %d",
++                   cmd.ic_di.di_dev, cmd.ic_di.di_ino);
++        DEVINOFD_MAP::const_iterator iter = devino_to_fd.find(cmd.ic_di);
++        if (iter != devino_to_fd.end()) {
++            // Get the descriptor associated to the given device/inode pair
++            // and remove the mapping from the required structure.
++            int fd = (*iter).second;
++            assert(devino_to_fd.find(cmd.ic_di) != devino_to_fd.end());
++            devino_to_fd.erase(cmd.ic_di);
++            assert(devino_to_fd.find(cmd.ic_di) == devino_to_fd.end());
++            assert(fd_to_devino.find(fd) != fd_to_devino.end());
++            fd_to_devino.erase(fd);
++            assert(fd_to_devino.find(fd) == fd_to_devino.end());
++
++            // Remove the entry associated to the descriptor from the list
++            // of changes monitored by kqueue.
++            int i;
++            for (i = 1; i < last_change; i++)
++                if (changes[i].ident == fd)
++                    break;
++            for (int j = i; j < last_change - 1; j++)
++                changes[j] = changes[j + 1];
++            last_change--;
++
++            close(fd);
++
++            result = true;
++        }
++    } else {
++        // Huh?  Unknown command received.
++        assert(false);
++    }
++
++    // Deliver the result of the operation.
++    write(cmd.ic_stat[1], &result, sizeof(bool));
++}
+diff -uNr fam-2.7.0/src/Interest.c++ fam-2.7.0-patched/src/Interest.c++
+--- fam-2.7.0/src/Interest.c++ 2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/Interest.c++ 2007-01-02 13:22:13.000000000 -0500
+@@ -23,7 +23,9 @@
+ #include "Interest.h"
+ 
+ #include <sys/param.h>
++#if HAVE_SYS_SYSMACROS_H
+ #include <sys/sysmacros.h>
++#endif
+ 
+ #include <errno.h>
+ #include <string.h>
+@@ -46,7 +48,7 @@
+ #include "Pollster.h"
+ #include "timeval.h"
+ 
+-Interest *Interest::hashtable[];
++Interest *Interest::hashtable[HASHSIZE];
+ IMon      Interest::imon(imon_handler);
+ bool      Interest::xtab_verification = true;
+ 
+diff -uNr fam-2.7.0/src/InternalClient.c++ 
fam-2.7.0-patched/src/InternalClient.c++
+--- fam-2.7.0/src/InternalClient.c++   2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/InternalClient.c++   2007-01-02 13:22:13.000000000 
-0500
+@@ -35,8 +35,8 @@
+ {
+     assert(filename);
+     assert(h);
+-    assert(filename[0] == '/');
+     Log::debug("%s watching %s", name(), filename);
++    assert(filename[0] == '/');
+     interest = new File(filename, this, Request(0), Cred::SuperUser);
+ }
+ 
+diff -uNr fam-2.7.0/src/Listener.c++ fam-2.7.0-patched/src/Listener.c++
+--- fam-2.7.0/src/Listener.c++ 2003-01-19 19:37:29.000000000 -0500
++++ fam-2.7.0-patched/src/Listener.c++ 2007-01-02 13:22:13.000000000 -0500
+@@ -22,6 +22,8 @@
+ 
+ #include "Listener.h"
+ 
++#include <stdio.h>
++#include <stdlib.h>
+ #include <assert.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+@@ -32,6 +34,7 @@
+ #include <rpc/clnt.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
++#include <sys/param.h>
+ #include <sys/stat.h>
+ #include <sys/un.h>
+ #include <unistd.h>
+@@ -205,11 +208,11 @@
+ #ifdef HAVE_UNSETENV
+     unsetenv("TMPDIR");
+ #else
+-    putenv("TMPDIR=");
++    putenv("TMPDIR=/tmp");
+ #endif
+ 
+     char *tmpfile = tempnam("/tmp", ".fam");
+-#ifdef HAVE_SOCKADDR_SUN_LEN
++#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
+     sockaddr_un sun = { sizeof(sockaddr_un), AF_UNIX, "" };
+ #else
+     sockaddr_un sun = { AF_UNIX, "" };
+@@ -283,7 +286,7 @@
+ 
+     // Get the new socket.
+ 
+-#ifdef HAVE_SOCKADDR_SUN_LEN
++#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
+     struct sockaddr_un sun = { sizeof(sockaddr_un), AF_UNIX, "" };
+ #else
+     struct sockaddr_un sun = { AF_UNIX, "" };
+@@ -349,7 +352,7 @@
+ void
+ Listener::dirty_ugly_hack()
+ {
+-#ifdef HAVE_SOCKADDR_SUN_LEN
++#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
+     static sockaddr_un sun = { sizeof (sockaddr_un), AF_UNIX, 
"/tmp/.fam_socket" };
+ #else
+     static sockaddr_un sun = { AF_UNIX, "/tmp/.fam_socket" };
+diff -uNr fam-2.7.0/src/LocalFileSystem.c++ 
fam-2.7.0-patched/src/LocalFileSystem.c++
+--- fam-2.7.0/src/LocalFileSystem.c++  2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/LocalFileSystem.c++  2007-01-02 13:22:14.000000000 
-0500
+@@ -27,7 +27,11 @@
+ #include "Log.h"
+ #include "Pollster.h"
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++LocalFileSystem::LocalFileSystem(const mnttab& mnt)
++#else
+ LocalFileSystem::LocalFileSystem(const mntent& mnt)
++#endif
+     : FileSystem(mnt)
+ { }
+ 
+diff -uNr fam-2.7.0/src/LocalFileSystem.h 
fam-2.7.0-patched/src/LocalFileSystem.h
+--- fam-2.7.0/src/LocalFileSystem.h    2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/LocalFileSystem.h    2007-01-02 13:22:14.000000000 
-0500
+@@ -38,7 +38,11 @@
+ 
+ public:
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    LocalFileSystem(const mnttab&);
++#else
+     LocalFileSystem(const mntent&);
++#endif
+ 
+     virtual bool dir_entries_scanned() const;
+     virtual int get_attr_cache_timeout() const;
+diff -uNr fam-2.7.0/src/Log.c++ fam-2.7.0-patched/src/Log.c++
+--- fam-2.7.0/src/Log.c++      2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/Log.c++      2007-01-02 13:22:14.000000000 -0500
+@@ -28,9 +28,9 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <syslog.h>
++#include <sys/time.h>
+ #include <sys/resource.h>
+ #include <sys/stat.h>
+-#include <sys/time.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #ifdef HAVE_AUDIT
+diff -uNr fam-2.7.0/src/NFSFileSystem.c++ 
fam-2.7.0-patched/src/NFSFileSystem.c++
+--- fam-2.7.0/src/NFSFileSystem.c++    2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/NFSFileSystem.c++    2007-01-02 13:22:13.000000000 
-0500
+@@ -24,7 +24,7 @@
+ #include "NFSFileSystem.h"
+ 
+ #include <assert.h>
+-#include <mntent.h>
++#include "fam-mntent.h"
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -41,12 +41,20 @@
+ #define ACREGMIN 3
+ #endif
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++NFSFileSystem::NFSFileSystem(const mnttab& mnt)
++#else
+ NFSFileSystem::NFSFileSystem(const mntent& mnt)
++#endif
+     : FileSystem(mnt)
+ {
+     //  Extract the host name from the fs name.
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    const char *fsname = mnt.mnt_special;
++#else
+     const char *fsname = mnt.mnt_fsname;
++#endif
+     const char *colon = strchr(fsname, ':');
+     if(colon == NULL)
+     {
+@@ -55,12 +63,12 @@
+         assert(colon);
+         colon = fsname;
+     }
+-    char hostname[NAME_MAX + 1];
++    char hostname[MAXPATHLEN + 1];
+     int hostnamelen = colon - fsname;
+-    if(hostnamelen > NAME_MAX)
++    if(hostnamelen > MAXPATHLEN)
+     {
+-        assert(hostnamelen <= NAME_MAX);
+-        hostnamelen = NAME_MAX;
++        assert(hostnamelen <= MAXPATHLEN);
++        hostnamelen = MAXPATHLEN;
+     }
+     strncpy(hostname, fsname, hostnamelen);
+     hostname[hostnamelen] = '\0';
+@@ -84,7 +92,11 @@
+     // acregmin, acregmax, actimeo, and noac options in the mount
+     // options.  Otherwise, use defaults.
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    const char * opt = mnt.mnt_mntopts;
++#else
+     const char * opt = mnt.mnt_opts;
++#endif
+ 
+     bool f_noac = false;
+     bool f_actimeo = false;
+@@ -102,20 +114,20 @@
+     if (strstr(opt, "noac")) {
+         f_noac = true;
+     }
+-    if ((p = strstr(opt, "actimeo"))) 
++    if ((p = strstr((char *)opt, "actimeo"))) 
+     {
+         if (sscanf(p, "actimeo=%i", &actimeo) == 1) {
+             f_actimeo = true;
+         }
+     }
+     
+-    if ((p = strstr(opt, "acregmin"))) {
++    if ((p = strstr((char *)opt, "acregmin"))) {
+         if (sscanf(p, "acregmin=%i", &acregmin) == 1) {
+             f_acregmin = true;
+         }
+     }
+     
+-    if ((p = strstr(opt, "acregmax"))) {
++    if ((p = strstr((char *)opt, "acregmax"))) {
+         if (sscanf(p, "acregmax=%i", &acregmax) == 1) {
+             f_acregmax = true;
+         }
+diff -uNr fam-2.7.0/src/NFSFileSystem.h fam-2.7.0-patched/src/NFSFileSystem.h
+--- fam-2.7.0/src/NFSFileSystem.h      2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/NFSFileSystem.h      2007-01-02 13:22:14.000000000 
-0500
+@@ -39,7 +39,11 @@
+ 
+ public:
+ 
++#if defined(HAVE_SYS_MNTTAB_H)
++    NFSFileSystem(const mnttab&);
++#else
+     NFSFileSystem(const mntent&);
++#endif
+     ~NFSFileSystem();
+ 
+     virtual bool dir_entries_scanned() const;
+diff -uNr fam-2.7.0/src/NetConnection.c++ 
fam-2.7.0-patched/src/NetConnection.c++
+--- fam-2.7.0/src/NetConnection.c++    2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/NetConnection.c++    2007-01-02 13:22:14.000000000 
-0500
+@@ -21,6 +21,7 @@
+ //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ 
+ #include "NetConnection.h"
++#include "config.h"
+ 
+ #include <assert.h>
+ #include <errno.h>
+@@ -29,6 +30,9 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <sys/ioctl.h>
++#ifdef HAVE_SYS_FILIO_H
++#include <sys/filio.h>
++#endif
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <netinet/in.h>
+diff -uNr fam-2.7.0/src/NetConnection.h fam-2.7.0-patched/src/NetConnection.h
+--- fam-2.7.0/src/NetConnection.h      2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/NetConnection.h      2007-01-02 13:22:14.000000000 
-0500
+@@ -68,6 +68,8 @@
+     void ready_for_input(bool);
+     int get_fd() const { return fd; }
+ 
++    enum { MAXMSGSIZE = PATH_MAX + 40 };
++
+ protected:
+ 
+     virtual bool input_msg(const char *data, unsigned nbytes) = 0;
+@@ -75,7 +77,6 @@
+ 
+ private:
+ 
+-    enum { MAXMSGSIZE = PATH_MAX + 40 };
+     typedef u_int32_t Length;
+     typedef struct msgList_s {
+         char msg[MAXMSGSIZE+5];  //  + 4 for 32-bit length, + 1 for overflow
+diff -uNr fam-2.7.0/src/RPC_TCP_Connector.c++ 
fam-2.7.0-patched/src/RPC_TCP_Connector.c++
+--- fam-2.7.0/src/RPC_TCP_Connector.c++        2003-01-18 09:18:12.000000000 
-0500
++++ fam-2.7.0-patched/src/RPC_TCP_Connector.c++        2007-01-02 
13:22:14.000000000 -0500
+@@ -21,11 +21,23 @@
+ //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ 
+ #include "RPC_TCP_Connector.h"
++#include "config.h"
++
++#define PORTMAP
+ 
+ #include <errno.h>
++#ifdef __SUNPRO_CC
++extern "C" {
++#endif
+ #include <rpc/rpc.h>
+ #include <rpc/pmap_prot.h>
++#ifdef __SUNPRO_CC
++}
++#endif
+ #include <sys/ioctl.h>
++#ifdef HAVE_SYS_FILIO_H
++#include <sys/filio.h>
++#endif
+ #include <sys/socket.h>
+ #include <unistd.h>
+ #include <string.h>
+diff -uNr fam-2.7.0/src/Scheduler.h fam-2.7.0-patched/src/Scheduler.h
+--- fam-2.7.0/src/Scheduler.h  2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/Scheduler.h  2007-01-02 13:22:14.000000000 -0500
+@@ -88,8 +88,6 @@
+     static void loop()                        { running = true;
+                                         while (running) select(); }
+ 
+-private:
+-
+     //  Per-filedescriptor info is the set of three handlers and their
+     //  closures.
+ 
+diff -uNr fam-2.7.0/src/ServerHost.h fam-2.7.0-patched/src/ServerHost.h
+--- fam-2.7.0/src/ServerHost.h 2003-01-18 09:18:12.000000000 -0500
++++ fam-2.7.0-patched/src/ServerHost.h 2007-01-02 13:22:14.000000000 -0500
+@@ -24,6 +24,7 @@
+ #define ServerHost_included
+ 
+ #include <limits.h>
++#include <stdio.h>
+ #include "Boolean.h"
+ #include "ClientInterest.h"
+ #include "RequestMap.h"
+@@ -101,7 +102,7 @@
+     private:
+ 
+       Request myrequest;
+-      char mypath[NAME_MAX];
++      char mypath[MAXPATHLEN];
+ 
+     };
+ 
+diff -uNr fam-2.7.0/src/fam-mntent.h fam-2.7.0-patched/src/fam-mntent.h
+--- fam-2.7.0/src/fam-mntent.h 1969-12-31 19:00:00.000000000 -0500
++++ fam-2.7.0-patched/src/fam-mntent.h 2007-01-02 13:22:14.000000000 -0500
+@@ -0,0 +1,62 @@
++/*
++ *  mntent
++ *  fam-mntent.h - compatability header for BSD
++ *
++ *  Copyright (c) 2001 David Rufino <[EMAIL PROTECTED]>
++ *  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#if defined(HAVE_MNTENT_H)
++#include <mntent.h>
++#elif defined(HAVE_SYS_MNTTAB_H)
++#include <stdio.h>
++#include <unistd.h>
++#include <sys/mntent.h>
++#include <sys/mnttab.h>
++#define MOUNTED MNTTAB
++#else
++#ifndef _MNTENT_H
++#define _MNTENT_H
++#include <stdio.h>
++
++#define MOUNTED "dummy"
++
++#define MNTTYPE_NFS "nfs"
++
++struct mntent {
++      char *mnt_fsname;
++      char *mnt_dir;
++      char *mnt_type;
++      char *mnt_opts;
++      int mnt_freq;
++      int mnt_passno;
++};
++
++#define setmntent(x,y) ((FILE *)0x1)
++struct mntent *getmntent __P ((FILE *fp));
++char *hasmntopt __P ((const struct mntent *mnt, const char *option));
++#define endmntent(x) ((int)1)
++
++#endif /* _MNTENT_H */
++#endif /* HAVE_MNTENT_H */
+diff -uNr fam-2.7.0/src/imon-compat.h fam-2.7.0-patched/src/imon-compat.h
+--- fam-2.7.0/src/imon-compat.h        1969-12-31 19:00:00.000000000 -0500
++++ fam-2.7.0-patched/src/imon-compat.h        2007-01-02 13:23:12.000000000 
-0500
+@@ -0,0 +1,53 @@
++//  $NetBSD: imon-compat.h,v 1.1 2004/10/17 19:20:53 jmmv Exp $
++//
++//  Copyright (c) 2004 Julio M. Merino Vidal.
++//  
++//  This program is free software; you can redistribute it and/or modify it
++//  under the terms of version 2 of the GNU General Public License as
++//  published by the Free Software Foundation.
++//
++//  This program is distributed in the hope that it would be useful, but
++//  WITHOUT ANY WARRANTY; without even the implied warranty of
++//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any
++//  license provided herein, whether implied or otherwise, is limited to
++//  this program in accordance with the express provisions of the GNU
++//  General Public License.  Patent licenses, if any, provided herein do not
++//  apply to combinations of this program with other product or programs, or
++//  any other product whatsoever.  This program is distributed without any
++//  warranty that the program is delivered free of the rightful claim of any
++//  third person by way of infringement or the like.  See the GNU General
++//  Public License for more details.
++//
++//  You should have received a copy of the GNU General Public License along
++//  with this program; if not, write the Free Software Foundation, Inc., 59
++//  Temple Place - Suite 330, Boston MA 02111-1307, USA.
++
++#if !defined(IMON_COMPAT_H)
++#define IMON_COMPAT_H
++
++#if defined(HAVE_IMON)
++#  error "cannot include imon-compat.h if imon is really present"
++#endif
++
++#if defined(HAVE_KQUEUE)
++#define HAVE_IMON 1
++
++typedef int intmask_t;
++
++typedef struct {
++    dev_t qe_dev;
++    ino_t qe_inode;
++    intmask_t qe_what;
++} qelem_t;
++
++#define IMON_CONTENT    (1 << 0)
++#define IMON_ATTRIBUTE  (1 << 1)
++#define IMON_DELETE     (1 << 2)
++#define IMON_EXEC       (1 << 3)
++#define IMON_EXIT       (1 << 4)
++#define IMON_RENAME     (1 << 5)
++#define IMON_OVER       0xff
++
++#endif // defined(HAVE_KQUEUE)
++
++#endif // !defined(IMON_COMPAT_H)
+diff -uNr fam-2.7.0/src/mntent_compat.c++ 
fam-2.7.0-patched/src/mntent_compat.c++
+--- fam-2.7.0/src/mntent_compat.c++    1969-12-31 19:00:00.000000000 -0500
++++ fam-2.7.0-patched/src/mntent_compat.c++    2007-01-02 13:22:14.000000000 
-0500
+@@ -0,0 +1,191 @@
++/*
++ * Copyright (c) 1980, 1989, 1993, 1994
++ *      The Regents of the University of California.  All rights reserved.
++ * Copyright (c) 2001
++ *      David Rufino <[EMAIL PROTECTED]>
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ *    must display the following acknowledgement:
++ *      This product includes software developed by the University of
++ *      California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++/* most of this was ripped from the mount(3) source */
++
++#include "config.h"
++#include "fam-mntent.h"
++#if !defined(HAVE_MNTENT_H) && !defined(HAVE_SYS_MNTTAB_H)
++#include <stdlib.h>
++#include <string.h>
++#include <sys/param.h>
++#include <sys/ucred.h>
++#include <sys/mount.h>
++#if defined(HAVE_SYS_STATVFS_H) && !defined(__APPLE__) && 
!defined(__DragonFly__) && !defined(__FreeBSD__)
++# include <sys/statvfs.h>
++#endif
++
++static int pos = -1;
++static int mntsize = -1;
++static struct mntent _mntent;
++
++char *
++hasmntopt (const struct mntent *mnt, const char *option)
++{
++        int found;
++        char *opt, *optbuf;
++
++        optbuf = strdup(mnt->mnt_opts);
++        found = 0;
++        for (opt = optbuf; (opt = strtok(opt, " ")) != NULL; opt = NULL) {
++                if (!strcasecmp(opt, option)) {
++                      opt = opt - optbuf + mnt->mnt_opts;
++                      free (optbuf);
++                      return (opt);
++              }
++        }
++      free (optbuf);
++        return (NULL);
++}
++
++static char *
++catopt (char *s0, const char *s1)
++{
++        size_t i;
++        char *cp;
++
++        if (s1 == NULL || *s1 == '\0')
++                return s0;
++        if (s0 && *s0) {
++                i = strlen(s0) + strlen(s1) + 1 + 1;
++                if ((cp = (char *)malloc(i)) == NULL)
++                      return (NULL);
++                (void)snprintf(cp, i, "%s %s", s0, s1);
++        } else
++                cp = strdup(s1);
++
++        if (s0)
++                free(s0);
++        return (cp);
++}
++
++
++static char *
++flags2opts (int flags)
++{
++        char *res;
++        res = NULL;
++        res = catopt(res, (flags & MNT_RDONLY) ? "ro" : "rw");
++        if (flags & MNT_SYNCHRONOUS)    res = catopt(res, "sync");
++        if (flags & MNT_NOEXEC)         res = catopt(res, "noexec");
++        if (flags & MNT_NOSUID)         res = catopt(res, "nosuid");
++        if (flags & MNT_NODEV)          res = catopt(res, "nodev");
++        if (flags & MNT_UNION)          res = catopt(res, "union");
++        if (flags & MNT_ASYNC)          res = catopt(res, "async");
++#ifdef MNT_NOATIME
++        if (flags & MNT_NOATIME)        res = catopt(res, "noatime");
++#endif
++#ifdef MNT_NOCLUSTERR
++        if (flags & MNT_NOCLUSTERR)     res = catopt(res, "noclusterr");
++#endif
++#ifdef MNT_NOCLUSTERW
++        if (flags & MNT_NOCLUSTERW)     res = catopt(res, "noclusterw");
++#endif
++#ifdef MNT_NOSYMFOLLOW
++        if (flags & MNT_NOSYMFOLLOW)    res = catopt(res, "nosymfollow");
++#endif
++#ifdef MNT_SUIDDIR
++        if (flags & MNT_SUIDDIR)        res = catopt(res, "suiddir");
++#endif
++#ifdef MNT_NOCOREDUMP
++        if (flags & MNT_NOCOREDUMP)   res = catopt(res, "nocoredump");
++#endif
++#ifdef MNT_IGNORE
++        if (flags & MNT_IGNORE)               res = catopt(res, "hidden");
++#endif
++#ifdef MNT_SYMPERM
++        if (flags & MNT_SYMPERM)      res = catopt(res, "symperm");
++#endif
++#ifdef MNT_NODEVMTIME
++        if (flags & MNT_NODEVMTIME)   res = catopt(res, "nodevmtime");
++#endif
++#ifdef MNT_SOFTDEP
++        if (flags & MNT_SOFTDEP)      res = catopt(res, "softdep");
++#endif
++
++        return res;
++}
++
++static struct mntent *
++#if defined(HAVE_SYS_STATVFS_H) && !defined(__APPLE__) && 
!defined(__DragonFly__) && !defined(__FreeBSD__)
++statfs_to_mntent (struct statvfs *mntbuf)
++#else
++statfs_to_mntent (struct statfs *mntbuf)
++#endif
++{
++      static char opts_buf[40], *tmp;
++      
++      _mntent.mnt_fsname = mntbuf->f_mntfromname;
++      _mntent.mnt_dir = mntbuf->f_mntonname;
++      _mntent.mnt_type = mntbuf->f_fstypename;
++#if defined(HAVE_SYS_STATVFS_H) && !defined(__APPLE__) && 
!defined(__DragonFly__) && !defined(__FreeBSD__)
++      tmp = flags2opts (mntbuf->f_flag);
++#else
++      tmp = flags2opts (mntbuf->f_flags);
++#endif
++      if (tmp) {
++              opts_buf[sizeof(opts_buf)-1] = '\0';
++              strncpy (opts_buf, tmp, sizeof(opts_buf)-1);
++              free (tmp);
++      } else {
++              *opts_buf = '\0';
++      }
++      _mntent.mnt_opts = opts_buf;    
++      _mntent.mnt_freq = _mntent.mnt_passno = 0;
++      return (&_mntent);
++}
++
++struct mntent *
++getmntent (FILE *fp)
++{
++#if defined(HAVE_SYS_STATVFS_H) && !defined(__APPLE__) && 
!defined(__DragonFly__) && !defined(__FreeBSD__)
++      static struct statvfs *mntbuf;
++#else
++      static struct statfs *mntbuf;
++#endif
++
++      if (pos == -1 || mntsize == -1)
++              mntsize = getmntinfo (&mntbuf, MNT_NOWAIT);
++
++      ++pos;
++      if (pos == mntsize) {
++              pos = mntsize = -1;
++              return (NULL);
++      }
++
++      return (statfs_to_mntent (&mntbuf[pos]));
++}
++
++#endif /* HAVE_MNTENT_H */
+--- fam-2.7.0/src/Makefile.am  2003-01-19 07:00:17.000000000 -0500
++++ fam-2.7.0-patched/src/Makefile.am  2007-01-02 14:19:24.000000000 -0500
+@@ -71,7 +71,8 @@
+   main.c++ \
+   timeval.c++ \
+   timeval.h \
+-  @[EMAIL PROTECTED]
++  IMonKQueue.c++ \
++  mntent_compat.c++
+ 
+ EXTRA_famd_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++
+ 


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Fink-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fink-commits

Reply via email to