s3: smbd: Change canonicalize_ea_name() to take a const smb_filename * parameter...
[sfrench/samba-autobuild/.git] / source3 / smbd / dmapi.c
index 0fa3a16760d304e0b382280dab62c2bc0c1f4bf1..7e8244551a85dab4b548f2db805b0fe4304d412d 100644 (file)
@@ -6,7 +6,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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 to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_DMAPI
 
-#if defined(HAVE_LIBDM)
-#if (defined(HAVE_XFS_DMAPI_H) || defined(HAVE_SYS_DMI_H))
-#define USE_DMAPI 1
-#endif
-#endif
-
 #ifndef USE_DMAPI
 
-int dmapi_init_session(void) { return -1; }
-uint32 dmapi_file_flags(const char * const path) { return 0; }
-BOOL dmapi_have_session(void) { return False; }
+uint32_t dmapi_file_flags(const char * const path) { return 0; }
+bool dmapi_have_session(void) { return False; }
+const void * dmapi_get_current_session(void) { return NULL; }
 
 #else /* USE_DMAPI */
 
 #ifdef HAVE_XFS_DMAPI_H
 #include <xfs/dmapi.h>
-#endif
-
-#ifdef HAVE_SYS_DMI_H
+#elif defined(HAVE_SYS_DMI_H)
 #include <sys/dmi.h>
+#elif defined(HAVE_SYS_JFSDMAPI_H)
+#include <sys/jfsdmapi.h>
+#elif defined(HAVE_SYS_DMAPI_H)
+#include <sys/dmapi.h>
+#elif defined(HAVE_DMAPI_H)
+#include <dmapi.h>
 #endif
 
 #define DMAPI_SESSION_NAME "samba"
 #define DMAPI_TRACE 10
 
-static dm_sessid_t dmapi_session = DM_NO_SESSION;
-
-/* Initialise the DMAPI interface. Make sure that we only end up initialising
- * once per process to avoid resource leaks across different DMAPI
- * implementations.
- */
-static int init_dmapi_service(void)
-{
-       static pid_t lastpid;
-
-       pid_t mypid;
-
-       mypid = sys_getpid();
-       if (mypid != lastpid) {
-               char *version;
-
-               lastpid = mypid;
-               if (dm_init_service(&version) < 0) {
-                       return -1;
-               }
-
-               DEBUG(0, ("Initializing DMAPI: %s\n", version));
-       }
-
-       return 0;
-}
+struct smbd_dmapi_context {
+       dm_sessid_t session;
+       unsigned session_num;
+};
 
-BOOL dmapi_have_session(void)
-{
-       return dmapi_session != DM_NO_SESSION;
-}
-
-static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
-{
-       dm_sessid_t *nsessions;
-
-       nsessions = TALLOC_REALLOC_ARRAY(NULL, sessions, dm_sessid_t, count);
-       if (nsessions == NULL) {
-               TALLOC_FREE(sessions);
-               return NULL;
-       }
-
-       return nsessions;
-}
-
-/* Initialise DMAPI session. The session is persistant kernel state, so it
- * might already exist, in which case we merely want to reconnect to it. This
- * function should be called as root.
- */
-int dmapi_init_session(void)
+/* 
+   Initialise DMAPI session. The session is persistant kernel state, 
+   so it might already exist, in which case we merely want to 
+   reconnect to it. This function should be called as root.
+*/
+static int dmapi_init_session(struct smbd_dmapi_context *ctx)
 {
        char    buf[DM_SESSION_INFO_LEN];
        size_t  buflen;
-
-       uint        nsessions = 10;
+       uint        nsessions = 5;
        dm_sessid_t *sessions = NULL;
+       char    *version;
+       char    *session_name;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
 
        int i, err;
 
-       /* If we aren't root, something in the following will fail due to lack
-        * of privileges. Aborting seems a little extreme.
-        */
-       SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
+       if (ctx->session_num == 0) {
+               session_name = talloc_strdup(tmp_ctx, DMAPI_SESSION_NAME);
+       } else {
+               session_name = talloc_asprintf(tmp_ctx, "%s%u", DMAPI_SESSION_NAME,
+                                              ctx->session_num);
+       }
 
-       dmapi_session = DM_NO_SESSION;
-       if (init_dmapi_service() < 0) {
+       if (session_name == NULL) {
+               DEBUG(0,("Out of memory in dmapi_init_session\n"));
+               talloc_free(tmp_ctx);
                return -1;
        }
 
-retry:
-
-       if ((sessions = realloc_session_list(sessions, nsessions)) == NULL) {
+       if (dm_init_service(&version) < 0) {
+               DEBUG(0, ("dm_init_service failed - disabling DMAPI\n"));
+               talloc_free(tmp_ctx);
                return -1;
        }
 
-       err = dm_getall_sessions(nsessions, sessions, &nsessions);
-       if (err < 0) {
-               if (errno == E2BIG) {
-                       nsessions *= 2;
-                       goto retry;
+       ZERO_STRUCT(buf);
+
+       /* Fetch kernel DMAPI sessions until we get any of them */
+       do {
+               dm_sessid_t *new_sessions;
+               nsessions *= 2;
+               new_sessions = talloc_realloc(tmp_ctx, sessions, 
+                                                   dm_sessid_t, nsessions);
+               if (new_sessions == NULL) {
+                       talloc_free(tmp_ctx);
+                       return -1;
                }
 
+               sessions = new_sessions;
+               err = dm_getall_sessions(nsessions, sessions, &nsessions);
+       } while (err == -1 && errno == E2BIG);
+
+       if (err == -1) {
                DEBUGADD(DMAPI_TRACE,
                        ("failed to retrieve DMAPI sessions: %s\n",
                        strerror(errno)));
-               TALLOC_FREE(sessions);
+               talloc_free(tmp_ctx);
                return -1;
        }
 
+       /* Look through existing kernel DMAPI sessions to find out ours */
        for (i = 0; i < nsessions; ++i) {
                err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
                buf[sizeof(buf) - 1] = '\0';
-               if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
-                       dmapi_session = sessions[i];
+               if (err == 0 && strcmp(session_name, buf) == 0) {
+                       ctx->session = sessions[i];
                        DEBUGADD(DMAPI_TRACE,
                                ("attached to existing DMAPI session "
                                 "named '%s'\n", buf));
@@ -150,108 +128,177 @@ retry:
                }
        }
 
-       TALLOC_FREE(sessions);
-
        /* No session already defined. */
-       if (dmapi_session == DM_NO_SESSION) {
-               err = dm_create_session(DM_NO_SESSION, DMAPI_SESSION_NAME,
-                                       &dmapi_session);
+       if (ctx->session == DM_NO_SESSION) {
+               err = dm_create_session(DM_NO_SESSION, 
+                                       session_name,
+                                       &ctx->session);
                if (err < 0) {
                        DEBUGADD(DMAPI_TRACE,
                                ("failed to create new DMAPI session: %s\n",
                                strerror(errno)));
-                       dmapi_session = DM_NO_SESSION;
+                       ctx->session = DM_NO_SESSION;
+                       talloc_free(tmp_ctx);
                        return -1;
                }
 
-               DEBUGADD(DMAPI_TRACE,
-                       ("created new DMAPI session named '%s'\n",
-                       DMAPI_SESSION_NAME));
+               DEBUG(0, ("created new DMAPI session named '%s' for %s\n",
+                         session_name, version));
+       }
+
+       if (ctx->session != DM_NO_SESSION) {
+               set_effective_capability(DMAPI_ACCESS_CAPABILITY);
        }
 
-       /* Note that we never end the DMAPI session. This enables child
-        * processes to continue to use the session after we exit. It also lets
-        * you run a second Samba server on different ports without any
-        * conflict.
+       /* 
+          Note that we never end the DMAPI session. It gets re-used if possiblie. 
+          DMAPI session is a kernel resource that is usually lives until server reboot
+          and doesn't get destroed when an application finishes.
+
+          However, we free list of references to DMAPI sessions we've got from the kernel
+          as it is not needed anymore once we have found (or created) our session.
         */
 
+       talloc_free(tmp_ctx);
        return 0;
 }
 
-/* Reattach to an existing dmapi session. Called from service processes that
- * might not be running as root.
- */
-static int reattach_dmapi_session(void)
+/*
+  Return a pointer to our DMAPI session, if available.
+  This assumes that you have called dmapi_have_session() first.
+*/
+const void *dmapi_get_current_session(void)
 {
-       char    buf[DM_SESSION_INFO_LEN];
-       size_t  buflen;
+       if (!dmapi_ctx) {
+               return NULL;
+       }
 
-       if (dmapi_session != DM_NO_SESSION ) {
-               become_root();
+       if (dmapi_ctx->session == DM_NO_SESSION) {
+               return NULL;
+       }
 
-               /* NOTE: On Linux, this call opens /dev/dmapi, costing us a
-                * file descriptor. Ideally, we would close this when we fork.
-                */
-               if (init_dmapi_service() < 0) {
-                       dmapi_session = DM_NO_SESSION;
-                       unbecome_root();
-                       return -1;
-               }
+       return (void *)&dmapi_ctx->session;
+}
+       
+/*
+  dmapi_have_session() must be the first DMAPI call you make in Samba. It will
+  initialize DMAPI, if available, and tell you if you can get a DMAPI session.
+  This should be called in the client-specific child process.
+*/
 
-               if (dm_query_session(dmapi_session, sizeof(buf),
-                           buf, &buflen) < 0) {
-                       /* Session is stale. Disable DMAPI. */
-                       dmapi_session = DM_NO_SESSION;
-                       unbecome_root();
-                       return -1;
+bool dmapi_have_session(void)
+{
+       if (!dmapi_ctx) {
+               dmapi_ctx = talloc(NULL, struct smbd_dmapi_context);
+               if (!dmapi_ctx) {
+                       exit_server("unable to allocate smbd_dmapi_context");
                }
+               dmapi_ctx->session = DM_NO_SESSION;
+               dmapi_ctx->session_num = 0;
 
-               set_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
-               DEBUG(DMAPI_TRACE, ("reattached DMAPI session\n"));
+               become_root();
+               dmapi_init_session(dmapi_ctx);
                unbecome_root();
+
        }
 
-       return 0;
+       return dmapi_ctx->session != DM_NO_SESSION;
+}
+
+/*
+  only call this when you get back an EINVAL error indicating that the
+  session you are using is invalid. This destroys the existing session
+  and creates a new one.
+ */
+bool dmapi_new_session(void)
+{
+       if (dmapi_have_session()) {
+               /* try to destroy the old one - this may not succeed */
+               dm_destroy_session(dmapi_ctx->session);
+       }
+       dmapi_ctx->session = DM_NO_SESSION;
+       become_root();
+       dmapi_ctx->session_num++;
+       dmapi_init_session(dmapi_ctx);
+       unbecome_root();
+       return dmapi_ctx->session != DM_NO_SESSION;
 }
 
-uint32 dmapi_file_flags(const char * const path)
+/* 
+    only call this when exiting from master smbd process. DMAPI sessions
+    are long-lived kernel resources we ought to share across smbd processes.
+    However, we must free them when all smbd processes are finished to
+    allow other subsystems clean up properly. Not freeing DMAPI session
+    blocks certain HSM implementations from proper shutdown.
+*/
+bool dmapi_destroy_session(void)
 {
-       static int attached = 0;
+       if (!dmapi_ctx) {
+               return true;
+       }
+       if (dmapi_ctx->session != DM_NO_SESSION) {
+               become_root();
+               if (0 == dm_destroy_session(dmapi_ctx->session)) {
+                       dmapi_ctx->session_num--;
+                       dmapi_ctx->session = DM_NO_SESSION;
+               } else {
+                       DEBUG(0,("Couldn't destroy DMAPI session: %s\n",
+                                strerror(errno)));
+               }
+               unbecome_root();
+       }
+       return dmapi_ctx->session == DM_NO_SESSION;
+}
+
 
+/* 
+   This is default implementation of dmapi_file_flags() that is 
+   called from VFS is_offline() call to know whether file is offline.
+   For GPFS-specific version see modules/vfs_tsmsm.c. It might be
+   that approach on quering existence of a specific attribute that
+   is used in vfs_tsmsm.c will work with other DMAPI-based HSM 
+   implementations as well.
+*/
+uint32_t dmapi_file_flags(const char * const path)
+{
        int             err;
        dm_eventset_t   events = {0};
        uint            nevents;
 
-       void    *dm_handle;
-       size_t  dm_handle_len;
+       dm_sessid_t     dmapi_session;
+       dm_sessid_t     *dmapi_session_ptr;
+       const void      *_dmapi_session_ptr;
+       void            *dm_handle = NULL;
+       size_t          dm_handle_len = 0;
 
-       uint32  flags = 0;
+       uint32_t        flags = 0;
 
-       /* If a DMAPI session has been initialised, then we need to make sure
-        * we are attached to it and have the correct privileges. This is
-        * necessary to be able to do DMAPI operations across a fork(2). If
-        * it fails, there is no liklihood of that failure being transient.
-        *
-        * Note that this use of the static attached flag relies on the fact
-        * that dmapi_file_flags() is never called prior to forking the
-        * per-client server process.
-        */
-       if (dmapi_have_session() && !attached) {
-               attached++;
-               if (reattach_dmapi_session() < 0) {
-                       return 0;
-               }
+       _dmapi_session_ptr = dmapi_get_current_session();
+       if (_dmapi_session_ptr == NULL) {
+               return 0;
        }
 
-       err = dm_path_to_handle(CONST_DISCARD(char *, path),
+       dmapi_session_ptr = discard_const_p(dm_sessid_t, _dmapi_session_ptr);
+       dmapi_session = *dmapi_session_ptr;
+       if (dmapi_session == DM_NO_SESSION) {
+               return 0;
+       }
+
+       /* AIX has DMAPI but no POSIX capablities support. In this case,
+        * we need to be root to do DMAPI manipulations.
+        */
+#ifndef HAVE_POSIX_CAPABILITIES
+       become_root();
+#endif
+
+       err = dm_path_to_handle(discard_const_p(char, path),
                &dm_handle, &dm_handle_len);
        if (err < 0) {
                DEBUG(DMAPI_TRACE, ("dm_path_to_handle(%s): %s\n",
                            path, strerror(errno)));
 
                if (errno != EPERM) {
-                       return 0;
+                       goto done;
                }
 
                /* Linux capabilities are broken in that changing our
@@ -263,13 +310,13 @@ uint32 dmapi_file_flags(const char * const path)
 
                set_effective_capability(DMAPI_ACCESS_CAPABILITY);
 
-               err = dm_path_to_handle(CONST_DISCARD(char *, path),
+               err = dm_path_to_handle(discard_const_p(char, path),
                        &dm_handle, &dm_handle_len);
                if (err < 0) {
                        DEBUG(DMAPI_TRACE,
                            ("retrying dm_path_to_handle(%s): %s\n",
                            path, strerror(errno)));
-                       return 0;
+                       goto done;
                }
        }
 
@@ -279,15 +326,14 @@ uint32 dmapi_file_flags(const char * const path)
                DEBUG(DMAPI_TRACE, ("dm_get_eventlist(%s): %s\n",
                            path, strerror(errno)));
                dm_handle_free(dm_handle, dm_handle_len);
-               return 0;
+               goto done;
        }
 
        /* We figure that the only reason a DMAPI application would be
         * interested in trapping read events is that part of the file is
         * offline.
         */
-       DEBUG(DMAPI_TRACE, ("DMAPI event list for %s is %#llx\n",
-                   path, events));
+       DEBUG(DMAPI_TRACE, ("DMAPI event list for %s\n", path));
        if (DMEV_ISSET(DM_EVENT_READ, events)) {
                flags = FILE_ATTRIBUTE_OFFLINE;
        }
@@ -298,279 +344,14 @@ uint32 dmapi_file_flags(const char * const path)
                DEBUG(DMAPI_TRACE, ("%s is OFFLINE\n", path));
        }
 
-       return flags;
-}
-
-#endif /* USE_DMAPI */
-/* 
-   Unix SMB/CIFS implementation.
-   DMAPI Support routines
-
-   Copyright (C) Silicon Graphics, Inc.        2006. All rights reserved.
-       James Peach <jpeach@sgi.com>
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  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 to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
+done:
 
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_DMAPI
-
-#if defined(HAVE_LIBDM)
-#if (defined(HAVE_XFS_DMAPI_H) || defined(HAVE_SYS_DMI_H))
-#define USE_DMAPI 1
-#endif
+#ifndef HAVE_POSIX_CAPABILITIES
+       unbecome_root();
 #endif
 
-#ifndef USE_DMAPI
-
-int dmapi_init_session(void) { return -1; }
-uint32 dmapi_file_flags(const char * const path) { return 0; }
-BOOL dmapi_have_session(void) { return False; }
-
-#else /* USE_DMAPI */
-
-#ifdef HAVE_XFS_DMAPI_H
-#include <xfs/dmapi.h>
-#endif
-
-#ifdef HAVE_SYS_DMI_H
-#include <sys/dmi.h>
-#endif
-
-#define DMAPI_SESSION_NAME "samba"
-#define DMAPI_TRACE 10
-
-static dm_sessid_t dmapi_session = DM_NO_SESSION;
-
-/* Initialise the DMAPI interface. Make sure that we only end up initialising
- * once per process to avoid resource leaks across different DMAPI
- * implementations.
- */
-static int init_dmapi_service(void)
-{
-       static pid_t lastpid;
-
-       pid_t mypid;
-
-       mypid = sys_getpid();
-       if (mypid != lastpid) {
-               char *version;
-
-               lastpid = mypid;
-               if (dm_init_service(&version) < 0) {
-                       return -1;
-               }
-
-               DEBUG(0, ("Initializing DMAPI: %s\n", version));
-       }
-
-       return 0;
-}
-
-BOOL dmapi_have_session(void)
-{
-       return dmapi_session != DM_NO_SESSION;
-}
-
-static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
-{
-       dm_sessid_t *nsessions;
-
-       nsessions = TALLOC_REALLOC_ARRAY(NULL, sessions, dm_sessid_t, count);
-       if (nsessions == NULL) {
-               TALLOC_FREE(sessions);
-               return NULL;
-       }
-
-       return nsessions;
-}
-
-/* Initialise DMAPI session. The session is persistant kernel state, so it
- * might already exist, in which case we merely want to reconnect to it. This
- * function should be called as root.
- */
-int dmapi_init_session(void)
-{
-       char    buf[DM_SESSION_INFO_LEN];
-       size_t  buflen;
-
-       uint        nsessions = 10;
-       dm_sessid_t *sessions = NULL;
-
-       int i, err;
-
-       /* If we aren't root, something in the following will fail due to lack
-        * of privileges. Aborting seems a little extreme.
-        */
-       SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
-
-       dmapi_session = DM_NO_SESSION;
-       if (init_dmapi_service() < 0) {
-               return -1;
-       }
-
-retry:
-
-       if ((sessions = realloc_session_list(sessions, nsessions)) == NULL) {
-               return -1;
-       }
-
-       err = dm_getall_sessions(nsessions, sessions, &nsessions);
-       if (err < 0) {
-               if (errno == E2BIG) {
-                       nsessions *= 2;
-                       goto retry;
-               }
-
-               DEBUGADD(DMAPI_TRACE,
-                       ("failed to retrieve DMAPI sessions: %s\n",
-                       strerror(errno)));
-               TALLOC_FREE(sessions);
-               return -1;
-       }
-
-       for (i = 0; i < nsessions; ++i) {
-               err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
-               buf[sizeof(buf) - 1] = '\0';
-               if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
-                       dmapi_session = sessions[i];
-                       DEBUGADD(DMAPI_TRACE,
-                               ("attached to existing DMAPI session "
-                                "named '%s'\n", buf));
-                       break;
-               }
-       }
-
-       TALLOC_FREE(sessions);
-
-       /* No session already defined. */
-       if (dmapi_session == DM_NO_SESSION) {
-               err = dm_create_session(DM_NO_SESSION, DMAPI_SESSION_NAME,
-                                       &dmapi_session);
-               if (err < 0) {
-                       DEBUGADD(DMAPI_TRACE,
-                               ("failed to create new DMAPI session: %s\n",
-                               strerror(errno)));
-                       return -1;
-               }
-
-               DEBUGADD(DMAPI_TRACE,
-                       ("created new DMAPI session named '%s'\n",
-                       DMAPI_SESSION_NAME));
-       }
-
-       /* Note that we never end the DMAPI session. This enables child
-        * processes to continue to use the session after we exit. It also lets
-        * you run a second Samba server on different ports without any
-        * conflict.
-        */
-
-       return 0;
-}
-
-/* Reattach to an existing dmapi session. Called from service processes that
- * might not be running as root.
- */
-static int reattach_dmapi_session(void)
-{
-       char    buf[DM_SESSION_INFO_LEN];
-       size_t  buflen;
-
-       if (dmapi_session != DM_NO_SESSION ) {
-               become_root();
-
-               /* NOTE: On Linux, this call opens /dev/dmapi, costing us a
-                * file descriptor. Ideally, we would close this when we fork.
-                */
-               if (init_dmapi_service() < 0) {
-                       dmapi_session = DM_NO_SESSION;
-                       unbecome_root();
-                       return -1;
-               }
-
-               if (dm_query_session(dmapi_session, sizeof(buf),
-                           buf, &buflen) < 0) {
-                       /* Session is stale. Disable DMAPI. */
-                       dmapi_session = DM_NO_SESSION;
-                       unbecome_root();
-                       return -1;
-               }
-
-               set_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
-               DEBUG(DMAPI_TRACE, ("reattached DMAPI session\n"));
-               unbecome_root();
-               return 0;
-       }
-
-       return 0;
-}
-
-uint32 dmapi_file_flags(const char * const path)
-{
-       int             err;
-       dm_eventset_t   events = {0};
-       uint            nevents;
-
-       void    *dm_handle;
-       size_t  dm_handle_len;
-
-       uint32  flags = 0;
-
-       if (dmapi_have_session()) {
-               if (reattach_dmapi_session() < 0) {
-                       return 0;
-               }
-       }
-
-       err = dm_path_to_handle(CONST_DISCARD(char *, path),
-               &dm_handle, &dm_handle_len);
-       if (err < 0) {
-               DEBUG(DMAPI_TRACE, ("dm_path_to_handle(%s): %s\n",
-                           path, strerror(errno)));
-               return 0;
-       }
-
-       err = dm_get_eventlist(dmapi_session, dm_handle, dm_handle_len,
-               DM_NO_TOKEN, DM_EVENT_MAX, &events, &nevents);
-       if (err < 0) {
-               DEBUG(DMAPI_TRACE, ("dm_get_eventlist: %s\n",
-                           strerror(errno)));
-               dm_handle_free(dm_handle, dm_handle_len);
-               return 0;
-       }
-
-       /* We figure that the only reason a DMAPI application would be
-        * interested in trapping read events is that part of the file is
-        * offline.
-        */
-       DEBUG(DMAPI_TRACE, ("DMAPI event list for %s is %#llx\n",
-                   path, events));
-       if (DMEV_ISSET(DM_EVENT_READ, events)) {
-               flags = FILE_ATTRIBUTE_OFFLINE;
-       }
-
-       dm_handle_free(dm_handle, dm_handle_len);
-
-       if (flags & FILE_ATTRIBUTE_OFFLINE) {
-               DEBUG(DMAPI_TRACE, ("%s is OFFLINE\n", path));
-       }
-
        return flags;
 }
 
+
 #endif /* USE_DMAPI */