Hello community,

here is the log from the commit of package snapper for openSUSE:Factory checked 
in at 2013-06-05 13:38:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/snapper (Old)
 and      /work/SRC/openSUSE:Factory/.snapper.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "snapper"

Changes:
--------
--- /work/SRC/openSUSE:Factory/snapper/snapper.changes  2013-05-13 
15:34:02.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.snapper.new/snapper.changes     2013-06-05 
14:24:49.000000000 +0200
@@ -1,0 +2,5 @@
+Fri May 31 17:35:33 CEST 2013 - aschn...@suse.de
+
+- fixed xattrs reading for certain block/character devices
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ snapper-0.1.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/doc/pam_snapper.8 
new/snapper-0.1.4/doc/pam_snapper.8
--- old/snapper-0.1.4/doc/pam_snapper.8 2013-05-03 09:57:13.000000000 +0200
+++ new/snapper-0.1.4/doc/pam_snapper.8 2013-05-31 17:42:14.000000000 +0200
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "PAM_SNAPPER 8"
-.TH PAM_SNAPPER 8 "2013-05-02" "0.1.4" " "
+.TH "PAM_SNAPPER" "8" "2013-05-23" "0.1.4" "Filesystem Snapshot Management"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -133,7 +133,7 @@
 pam_snapper \- PAM module which creates filesystem snapshots via "Snapper"
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
-pam_snapper.so debug [homeprefix=<>] [ignoreservices=<>] [ignoreusers=<>] 
[rootasroot] [ignoreroot] [openonly] [closeonly]
+pam_snapper.so [debug] [homeprefix=<>] [ignoreservices=<>] [ignoreusers=<>] 
[rootasroot] [ignoreroot] [openonly] [closeonly] [cleanup=<>]
 .SH "DESCRIPTION"
 .IX Header "DESCRIPTION"
 Create a snapshot at every login of a User, thus he or she always have a save 
starting point.
@@ -199,7 +199,7 @@
 \&\*(L"session optional pam_snapper.so\*(R"
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
-\&\fIpam.conf\fR\|(5), \fIpam.d\fR\|(5) \fIpam\fR\|(8), 
pam_snapper_homeconvert, pam_snapper_pamconfig, pam_snapper_useradd, 
pam_snapper_userdel
+snapper(8), pam.conf(5), pam(8), pam_snapper_homeconvert, 
pam_snapper_pamconfig, pam_snapper_useradd, pam_snapper_userdel
 .SH "AUTHORS and CONTRIBUTORS"
 .IX Header "AUTHORS and CONTRIBUTORS"
 pam-snapper was written by Matthias G. Eckermann <m...@suse.com>
@@ -227,7 +227,7 @@
 General Public License for more details.
 .PP
 You should have received a copy of the \s-1GNU\s0 General Public License
-along with this program; if not, contact \s-1SUSE\s0
+along with this program; if not, contact \s-1SUSE\s0.
 .PP
 To contact \s-1SUSE\s0 about this file by physical or electronic mail, you
-may find current contact information at www.suse.com
+may find current contact information at www.suse.com.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/doc/pam_snapper.8.in 
new/snapper-0.1.4/doc/pam_snapper.8.in
--- old/snapper-0.1.4/doc/pam_snapper.8.in      2013-05-02 16:46:40.000000000 
+0200
+++ new/snapper-0.1.4/doc/pam_snapper.8.in      2013-05-23 16:51:34.000000000 
+0200
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "PAM_SNAPPER 8"
-.TH PAM_SNAPPER 8 "2013-05-02" "@VERSION@" " "
+.TH "PAM_SNAPPER" "8" "2013-05-23" "@VERSION@" "Filesystem Snapshot Management"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -133,7 +133,7 @@
 pam_snapper \- PAM module which creates filesystem snapshots via "Snapper"
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
-pam_snapper.so debug [homeprefix=<>] [ignoreservices=<>] [ignoreusers=<>] 
[rootasroot] [ignoreroot] [openonly] [closeonly]
+pam_snapper.so [debug] [homeprefix=<>] [ignoreservices=<>] [ignoreusers=<>] 
[rootasroot] [ignoreroot] [openonly] [closeonly] [cleanup=<>]
 .SH "DESCRIPTION"
 .IX Header "DESCRIPTION"
 Create a snapshot at every login of a User, thus he or she always have a save 
starting point.
@@ -199,7 +199,7 @@
 \&\*(L"session optional pam_snapper.so\*(R"
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
-\&\fIpam.conf\fR\|(5), \fIpam.d\fR\|(5) \fIpam\fR\|(8), 
pam_snapper_homeconvert, pam_snapper_pamconfig, pam_snapper_useradd, 
pam_snapper_userdel
+snapper(8), pam.conf(5), pam(8), pam_snapper_homeconvert, 
pam_snapper_pamconfig, pam_snapper_useradd, pam_snapper_userdel
 .SH "AUTHORS and CONTRIBUTORS"
 .IX Header "AUTHORS and CONTRIBUTORS"
 pam-snapper was written by Matthias G. Eckermann <m...@suse.com>
@@ -227,7 +227,7 @@
 General Public License for more details.
 .PP
 You should have received a copy of the \s-1GNU\s0 General Public License
-along with this program; if not, contact \s-1SUSE\s0
+along with this program; if not, contact \s-1SUSE\s0.
 .PP
 To contact \s-1SUSE\s0 about this file by physical or electronic mail, you
-may find current contact information at www.suse.com
+may find current contact information at www.suse.com.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/pam/pam_snapper.c 
new/snapper-0.1.4/pam/pam_snapper.c
--- old/snapper-0.1.4/pam/pam_snapper.c 2013-05-03 09:56:33.000000000 +0200
+++ new/snapper-0.1.4/pam/pam_snapper.c 2013-05-23 11:46:33.000000000 +0200
@@ -1,5 +1,4 @@
 /**
- * @file
  * @author  Matthias G. Eckermann <m...@suse.com>
  *
  * @section License
@@ -25,14 +24,10 @@
  *
  * @section Usage
  *
- * 1. Create a btrfs subvolume for the new user,
- *    and a snapper configuration, e.g. using
- *      "pam_snapper_useradd.sh".
+ * Add the following line to /etc/pam.d/common-session:
+ *      "session optional pam_snapper.so"
  *
- * 2. Add the following line to /etc/pam.d/common-session:
- *      "session optional pam_snapper.so homeprefix=home_"
- *
- * See "man snapper" for more information.
+ * See "man pam_snapper" and "map snapper" for more information.
  *
  * @section Related Projects
  *
@@ -48,12 +43,10 @@
  *
  * @section Coding Style
  *
- * indent -linux -i8 -ts8 -l140 -cbi8 -cli8 -prs -nbap -nbbb -nbad -sob *.c
+ * indent -linux -i8 -ts8 -l100 -cbi8 -cli8 -prs -nbap -nbbb -nbad -sob *.c
  *
 */
 
-/* #define PAM_SNAPPER_DEBUG */
-
 #include "../config.h"
 
 /*
@@ -68,6 +61,7 @@
 #include <errno.h>
 #include <syslog.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <pwd.h>
 
 /*
@@ -147,51 +141,14 @@
  * Functions for DBUS handling
 */
 
-/**
- * init the connection to the DBUS
- *
- * @param pamh the PAM handle
- *
- * @return DBusConnection *
- *
-*/
-static DBusConnection *cdbus_conn( pam_handle_t * pamh )
-{
-       DBusError err;
-       DBusConnection *conn;
-       dbus_error_init( &err );
-       /* bus connection */
-       conn = dbus_bus_get( DBUS_BUS_SYSTEM, &err );
-       if ( dbus_error_is_set( &err ) ) {
-               pam_syslog( pamh, LOG_ERR, "connection error: %s", strerror( 
errno ) );
-               dbus_error_free( &err );
-       }
-       if ( NULL == conn ) {
-               return NULL;
-       }
-       return conn;
-}
-
-/**
- * send a message to the DBUS
- *
- * @param pamh PAM handle
- * @param conn current DBus connection
- * @param msg message to send
- * @param pend_out handle for a reply
- *
- * @return error condition
- *
-*/
-static int cdbus_msg_send( pam_handle_t * pamh, DBusConnection * conn, 
DBusMessage * msg, DBusPendingCall ** pend_out )
+static int cdbus_msg_send( DBusConnection * conn, DBusMessage * msg, 
DBusPendingCall ** pend_out )
 {
        DBusPendingCall *pending;
        /* send message and get a handle for a reply */
-       if ( !dbus_connection_send_with_reply( conn, msg, &pending, -1 ) ) {
+       if ( !dbus_connection_send_with_reply( conn, msg, &pending, 0x7fffffff 
) ) {
                return -ENOMEM;
        }
        if ( NULL == pending ) {
-               pam_syslog( pamh, LOG_ERR, "Pending Call Null" );
                return -EINVAL;
        }
        dbus_connection_flush( conn );
@@ -199,18 +156,8 @@
        return 0;
 }
 
-/**
- * receive a message from the DBUS
- *
- * @param pamh PAM handle
- * @param conn current DBus connection
- * @param pending pointer for the pending call
- * @param msg_out handle for the result data set
- *
- * @return error condition
- *
-*/
-static int cdbus_msg_recv( pam_handle_t * pamh, DBusConnection * conn, 
DBusPendingCall * pending, DBusMessage ** msg_out )
+static int cdbus_msg_recv( DBusConnection * conn, DBusPendingCall * pending,
+                          DBusMessage ** msg_out )
 {
        DBusMessage *msg;
        /* block until we receive a reply */
@@ -218,7 +165,6 @@
        /* get the reply message */
        msg = dbus_pending_call_steal_reply( pending );
        if ( msg == NULL ) {
-               pam_syslog( pamh, LOG_ERR, "Reply Null" );
                return -ENOMEM;
        }
        /* free the pending message handle */
@@ -227,40 +173,19 @@
        return 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- *
- * @return error condition or OK
- *
-*/
-static int cdbus_type_check( pam_handle_t * pamh, DBusMessageIter * iter, int 
expected_type )
+static int cdbus_type_check( DBusMessageIter * iter, int expected_type )
 {
        int type = dbus_message_iter_get_arg_type( iter );
        if ( type != expected_type ) {
-               pam_syslog( pamh, LOG_ERR, "got type %d, expecting %d", type, 
expected_type );
                return -EINVAL;
        }
        return 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- *
- * @return error condition or OK
- *
-*/
-static int cdbus_type_check_get( pam_handle_t * pamh, DBusMessageIter * iter, 
int expected_type, void *val )
+static int cdbus_type_check_get( DBusMessageIter * iter, int expected_type, 
void *val )
 {
        int ret;
-       ret = cdbus_type_check( pamh, iter, expected_type );
+       ret = cdbus_type_check( iter, expected_type );
        if ( ret < 0 ) {
                return ret;
        }
@@ -268,82 +193,68 @@
        return 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- * @param
- * @param
- *
- * @return -ENOMEM or OK
- *
-*/
-static int cdbus_create_snap_pack( pam_handle_t * pamh, const char 
*snapper_conf, createmode_t create_mode, const char *cleanup,
-                                  uint32_t num_user_data, struct dict 
*user_data, DBusMessage ** req_msg_out )
+static int cdbus_create_snap_pack( const char *snapper_conf, createmode_t 
createmode,
+                                  const char *cleanup, uint32_t num_user_data,
+                                  const struct dict *user_data, const uint32_t 
* snapshot_num_in,
+                                  DBusMessage ** req_msg_out )
 {
        DBusMessage *msg;
        DBusMessageIter args;
        DBusMessageIter array_iter;
        DBusMessageIter struct_iter;
-       const char *desc = MODULE_NAME;
-       uint32_t *snap_id = NULL;
-       bool ret;
-       const char *modestrings[3] = { "CreateSingleSnapshot", 
"CreatePreSnapshot", "CreatePostSnapshot" };
+       const char *modestrings[3] =
+           { "CreateSingleSnapshot", "CreatePreSnapshot", "CreatePostSnapshot" 
};
        msg = dbus_message_new_method_call( "org.opensuse.Snapper",     /* 
target for the method call */
                                            "/org/opensuse/Snapper",    /* 
object to call on */
                                            "org.opensuse.Snapper",     /* 
interface to call on */
-                                           modestrings[create_mode] ); /* 
method name */
+                                           modestrings[createmode] );  /* 
method name */
        if ( msg == NULL ) {
-               pam_syslog( pamh, LOG_ERR, "failed to create req msg" );
                return -ENOMEM;
        }
-       /* append arguments */
+
        dbus_message_iter_init_append( msg, &args );
        if ( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, 
&snapper_conf ) ) {
-               pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
                return -ENOMEM;
        }
-       if ( create_mode == createmode_post ) {
-               pam_get_data( pamh, "pam_snapper_snapshot_num", ( const void ** 
)&snap_id );
-               if ( !dbus_message_iter_append_basic( &args, DBUS_TYPE_UINT32, 
snap_id ) ) {
-                       pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
+       if ( createmode == createmode_post ) {
+               if ( !dbus_message_iter_append_basic( &args, DBUS_TYPE_UINT32, 
snapshot_num_in ) ) {
                        return -ENOMEM;
                }
        }
+
+       const char *desc = MODULE_NAME;
        if ( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, &desc ) 
) {
-               pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
                return -ENOMEM;
        }
-       /* cleanup */
+
        if ( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, &cleanup 
) ) {
-               pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
                return -ENOMEM;
        }
-       ret = dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, 
CDBUS_SIG_STRING_DICT, &array_iter );
+
+       dbus_bool_t ret =
+           dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, 
CDBUS_SIG_STRING_DICT,
+                                             &array_iter );
        if ( !ret ) {
-               pam_syslog( pamh, LOG_ERR, "failed to open array container" );
                return -ENOMEM;
        }
+
        for ( uint32_t i = 0; i < num_user_data; ++i ) {
-               ret = dbus_message_iter_open_container( &array_iter, 
DBUS_TYPE_DICT_ENTRY, NULL, &struct_iter );
+               ret =
+                   dbus_message_iter_open_container( &array_iter, 
DBUS_TYPE_DICT_ENTRY, NULL,
+                                                     &struct_iter );
                if ( !ret ) {
-                       pam_syslog( pamh, LOG_ERR, "failed to open struct 
container" );
                        return -ENOMEM;
                }
-               if ( !dbus_message_iter_append_basic( &struct_iter, 
DBUS_TYPE_STRING, &user_data[i].key ) ) {
-                       pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
+               if ( !dbus_message_iter_append_basic
+                    ( &struct_iter, DBUS_TYPE_STRING, &user_data[i].key ) ) {
                        return -ENOMEM;
                }
-               if ( !dbus_message_iter_append_basic( &struct_iter, 
DBUS_TYPE_STRING, &user_data[i].val ) ) {
-                       pam_syslog( pamh, LOG_ERR, "Out Of Memory!" );
+               if ( !dbus_message_iter_append_basic
+                    ( &struct_iter, DBUS_TYPE_STRING, &user_data[i].val ) ) {
                        return -ENOMEM;
                }
                ret = dbus_message_iter_close_container( &array_iter, 
&struct_iter );
                if ( !ret ) {
-                       pam_syslog( pamh, LOG_ERR, "failed to close struct 
container" );
                        return -ENOMEM;
                }
        }
@@ -352,157 +263,263 @@
        return 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- *
- * @return -EINVAL or OK
- *
-*/
-static int cdbus_create_snap_unpack( pam_handle_t * pamh, DBusConnection * 
conn, DBusMessage * rsp_msg, uint32_t * snap_id_out )
+static int cdbus_create_snap_unpack( DBusConnection * conn, DBusMessage * 
rsp_msg,
+                                    uint32_t * snapshot_num )
 {
        DBusMessageIter iter;
        int msg_type;
        const char *sig;
        msg_type = dbus_message_get_type( rsp_msg );
        if ( msg_type == DBUS_MESSAGE_TYPE_ERROR ) {
-               pam_syslog( pamh, LOG_ERR, "create snap error response: %s", 
dbus_message_get_error_name( rsp_msg ) );
                return -EINVAL;
        }
        if ( msg_type != DBUS_MESSAGE_TYPE_METHOD_RETURN ) {
-               pam_syslog( pamh, LOG_ERR, "unexpected create snap ret type: 
%d", msg_type );
                return -EINVAL;
        }
        sig = dbus_message_get_signature( rsp_msg );
-       if ( ( sig == NULL )
-            || ( strcmp( sig, CDBUS_SIG_CREATE_SNAP_RSP ) != 0 ) ) {
-               pam_syslog( pamh, LOG_ERR, "bad create snap response sig: %s, "
-                           "expected: %s", ( sig ? sig : "NULL" ), 
CDBUS_SIG_CREATE_SNAP_RSP );
+       if ( ( sig == NULL ) || ( strcmp( sig, CDBUS_SIG_CREATE_SNAP_RSP ) != 0 
) ) {
                return -EINVAL;
        }
        /* read the parameters */
        if ( !dbus_message_iter_init( rsp_msg, &iter ) ) {
-               pam_syslog( pamh, LOG_ERR, "Message has no arguments!" );
                return -EINVAL;
        }
-       if ( cdbus_type_check_get( pamh, &iter, DBUS_TYPE_UINT32, snap_id_out ) 
) {
+       if ( cdbus_type_check_get( &iter, DBUS_TYPE_UINT32, snapshot_num ) ) {
                return -EINVAL;
        }
        return 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
- * @return -EINVAL or OK
- *
-*/
-static void cdbus_fill_user_data( pam_handle_t * pamh, struct dict ( 
*user_data )[], int *user_data_num, int user_data_max )
+static int cdbus_create_snapshot( const char *snapper_conf, createmode_t 
createmode,
+                                 const char *cleanup, uint32_t num_user_data,
+                                 const struct dict *user_data, const uint32_t 
* snapshot_num_in,
+                                 uint32_t * snapshot_num_out )
 {
-       int fields[4] = { PAM_RUSER, PAM_RHOST, PAM_TTY, PAM_SERVICE };
-       const char *names[4] = { "ruser", "rhost", "tty", "service" };
-       for ( int i = 0; i < 4; ++i ) {
-               const char *readval = NULL;
-               int ret = pam_get_item( pamh, fields[i], ( const void ** 
)&readval );
-               if ( ret == PAM_SUCCESS && readval ) {
-                       ( *user_data )[*user_data_num].key = names[i];
-                       ( *user_data )[*user_data_num].val = readval;
-                       if ( ( *user_data_num ) < user_data_max ) {
-                               ( *user_data_num )++;
-                       }
-               }
-       }
-}
+       DBusError err;
+       dbus_error_init( &err );
 
-static void cleanup_snapshot_num( pam_handle_t * pamh, void *data, int 
error_status )
-{
-       free( data );
-}
+       /* without a private connection setting uid/gui can be in vain, e.g. 
with gdm */
+
+       DBusConnection *conn = dbus_bus_get_private( DBUS_BUS_SYSTEM, &err );
+       if ( dbus_error_is_set( &err ) ) {
+               dbus_error_free( &err );
+       }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
- * @return -EINVAL or OK
- *
-*/
-static int cdbus_create_snap_call( pam_handle_t * pamh, const char 
*snapper_conf, createmode_t create_mode, const char *cleanup,
-                                  DBusConnection * conn )
-{
-       int ret;
        DBusMessage *req_msg;
-       DBusMessage *rsp_msg;
-       DBusPendingCall *pending;
-       uint32_t *snap_id = malloc( sizeof( uint32_t ) );
-#ifdef PAM_SNAPPER_DEBUG
-       uint32_t *snap_id_check = NULL;
-#endif
-       int user_data_num = 0;
-       enum { user_data_max = 6 };
-       struct dict user_data[user_data_max];
-       cdbus_fill_user_data( pamh, &user_data, &user_data_num, user_data_max );
-       ret = cdbus_create_snap_pack( pamh, snapper_conf, create_mode, cleanup, 
user_data_num, user_data, &req_msg );
+       int ret = cdbus_create_snap_pack( snapper_conf, createmode, cleanup, 
num_user_data,
+                                         user_data, snapshot_num_in, &req_msg 
);
        if ( ret < 0 ) {
-               pam_syslog( pamh, LOG_ERR, "failed to pack create snap request" 
);
+               dbus_connection_close( conn );
+               dbus_connection_unref( conn );
                return ret;
        }
-       ret = cdbus_msg_send( pamh, conn, req_msg, &pending );
+
+       DBusPendingCall *pending;
+       ret = cdbus_msg_send( conn, req_msg, &pending );
        if ( ret < 0 ) {
                dbus_message_unref( req_msg );
+               dbus_connection_close( conn );
+               dbus_connection_unref( conn );
                return ret;
        }
-       ret = cdbus_msg_recv( pamh, conn, pending, &rsp_msg );
+
+       DBusMessage *rsp_msg;
+       ret = cdbus_msg_recv( conn, pending, &rsp_msg );
        if ( ret < 0 ) {
                dbus_message_unref( req_msg );
                dbus_pending_call_unref( pending );
+               dbus_connection_close( conn );
+               dbus_connection_unref( conn );
                return ret;
        }
-       ret = cdbus_create_snap_unpack( pamh, conn, rsp_msg, snap_id );
+
+       ret = cdbus_create_snap_unpack( conn, rsp_msg, snapshot_num_out );
        if ( ret < 0 ) {
-               pam_syslog( pamh, LOG_ERR, "failed to unpack create snap 
response: %s", strerror( -ret ) );
                dbus_message_unref( req_msg );
                dbus_message_unref( rsp_msg );
+               dbus_connection_close( conn );
+               dbus_connection_unref( conn );
                return ret;
        }
-       ret = pam_set_data( pamh, "pam_snapper_snapshot_num", snap_id, 
cleanup_snapshot_num );
-       if ( ret != PAM_SUCCESS ) {
-               pam_syslog( pamh, LOG_ERR, "pam_set_data failed." );
-       }
-#ifdef PAM_SNAPPER_DEBUG
-       pam_syslog( pamh, LOG_DEBUG, "created new snapshot %u", *snap_id );
-       pam_get_data( pamh, "pam_snapper_snapshot_num", ( const void ** 
)&snap_id_check );
-       pam_syslog( pamh, LOG_DEBUG, "Check new snapshot: '%u'", *snap_id_check 
);
-#endif
+
        dbus_message_unref( req_msg );
        dbus_message_unref( rsp_msg );
+       dbus_connection_close( conn );
+       dbus_connection_unref( conn );
        return 0;
 }
 
 /**
- * ??
- *
- * @param
- *
- * @return PAM_SUCCESS
- *
-*/
-static void cdbus_pam_options_setdefault( pam_options_t * options )
+ * Special functions for pam_snapper
+ */
+
+static int forker( pam_handle_t * pamh, uid_t uid, gid_t gid, const char 
*snapper_conf,
+                  createmode_t createmode, const char *cleanup, uint32_t 
num_user_data,
+                  const struct dict *user_data, const uint32_t * 
snapshot_num_in,
+                  uint32_t * snapshot_num_out )
+{
+       int fds[2];
+       if ( pipe( fds ) != 0 ) {
+               pam_syslog( pamh, LOG_ERR, "pipe failed" );
+               return -1;
+       }
+
+       int child = fork(  );
+       if ( child == 0 ) {
+
+               /* setting uid/gui affects other threads so it has to be done 
in a separate process */
+
+               if ( setegid( gid ) != 0 || seteuid( uid ) != 0 ) {
+                       exit( EXIT_FAILURE );
+               }
+
+               close( fds[0] );
+
+               if ( cdbus_create_snapshot( snapper_conf, createmode, cleanup, 
num_user_data,
+                                           user_data, snapshot_num_in, 
snapshot_num_out ) != 0 )
+                       exit( EXIT_FAILURE );
+
+               if ( pam_modutil_write
+                    ( fds[1], ( char * )snapshot_num_out,
+                      sizeof( *snapshot_num_out ) ) != sizeof( 
*snapshot_num_out ) )
+                       exit( EXIT_FAILURE );
+
+               close( fds[1] );
+
+               exit( EXIT_SUCCESS );
+
+       } else if ( child > 0 ) {
+
+               close( fds[1] );
+
+               int status;
+               int ret = waitpid( child, &status, 0 );
+
+               if ( ret == -1 ) {
+                       pam_syslog( pamh, LOG_ERR, "waitpid failed" );
+                       close( fds[0] );
+                       return -1;
+               }
+
+               if ( !WIFEXITED( status ) ) {
+                       pam_syslog( pamh, LOG_ERR, "child exited abnormal" );
+                       close( fds[0] );
+                       return -1;
+               }
+
+               if ( WEXITSTATUS( status ) != EXIT_SUCCESS ) {
+                       pam_syslog( pamh, LOG_ERR, "child exited normal but 
with failure" );
+                       close( fds[0] );
+                       return -1;
+               }
+
+               if ( pam_modutil_read
+                    ( fds[0], ( char * )snapshot_num_out,
+                      sizeof( *snapshot_num_out ) ) != sizeof( 
*snapshot_num_out ) ) {
+                       pam_syslog( pamh, LOG_ERR, "reading snapshot_num_out 
failed" );
+                       close( fds[0] );
+                       return -1;
+               }
+
+               close( fds[0] );
+
+               return 0;
+
+       } else {
+
+               pam_syslog( pamh, LOG_ERR, "fork failed" );
+               return -1;
+
+       }
+}
+
+static void fill_user_data( pam_handle_t * pamh, struct dict ( *user_data )[], 
int *num_user_data,
+                           int max_user_data )
+{
+       int fields[4] = { PAM_RUSER, PAM_RHOST, PAM_TTY, PAM_SERVICE };
+       const char *names[4] = { "ruser", "rhost", "tty", "service" };
+       for ( int i = 0; i < 4; ++i ) {
+               const char *readval = NULL;
+               int ret = pam_get_item( pamh, fields[i], ( const void ** 
)&readval );
+               if ( ret == PAM_SUCCESS && readval ) {
+                       ( *user_data )[*num_user_data].key = names[i];
+                       ( *user_data )[*num_user_data].val = readval;
+                       if ( ( *num_user_data ) < max_user_data ) {
+                               ( *num_user_data )++;
+                       }
+               }
+       }
+}
+
+static void cleanup_snapshot_num( pam_handle_t * pamh, void *data, int 
error_status )
+{
+       free( data );
+}
+
+static int get_ugid( pam_handle_t * pamh, const char *pam_user, uid_t * uid, 
gid_t * gid )
+{
+       struct passwd pwd;
+       struct passwd *result;
+
+       long bufsize = sysconf( _SC_GETPW_R_SIZE_MAX );
+       char buf[bufsize];
+
+       if ( getpwnam_r( pam_user, &pwd, buf, bufsize, &result ) != 0 || result 
!= &pwd ) {
+               pam_syslog( pamh, LOG_ERR, "getpwnam failed" );
+               return -1;
+       }
+
+       memset( pwd.pw_passwd, 0, strlen( pwd.pw_passwd ) );
+
+       *uid = pwd.pw_uid;
+       *gid = pwd.pw_gid;
+
+       return 0;
+}
+
+static int worker( pam_handle_t * pamh, const char *pam_user, const char 
*snapper_conf,
+                  createmode_t createmode, const char *cleanup )
+{
+       const int max_user_data = 5;
+       struct dict user_data[max_user_data];
+       int num_user_data = 0;
+       fill_user_data( pamh, &user_data, &num_user_data, max_user_data );
+
+       uid_t uid;
+       gid_t gid;
+       if ( get_ugid( pamh, pam_user, &uid, &gid ) != 0 )
+               return -1;
+
+       uint32_t *snapshot_num_in = NULL;
+       uint32_t *snapshot_num_out = malloc( sizeof( *snapshot_num_out ) );
+
+       if ( createmode == createmode_post ) {
+               if ( pam_get_data
+                    ( pamh, "pam_snapper_snapshot_num",
+                      ( const void ** )&snapshot_num_in ) != PAM_SUCCESS ) {
+                       pam_syslog( pamh, LOG_ERR, "getting previous 
snapshot_num failed" );
+                       return -1;
+               }
+       }
+
+       if ( forker( pamh, uid, gid, snapper_conf, createmode, cleanup, 
num_user_data, user_data,
+                    snapshot_num_in, snapshot_num_out ) != 0 )
+               return -1;
+
+       if ( pam_set_data
+            ( pamh, "pam_snapper_snapshot_num", snapshot_num_out,
+              cleanup_snapshot_num ) != PAM_SUCCESS ) {
+               pam_syslog( pamh, LOG_ERR, "pam_set_data failed" );
+       }
+
+       return 0;
+}
+
+static void set_default_options( pam_options_t * options )
 {
        options->homeprefix = "home_";
        options->ignoreservices = "crond";
-       options->ignoreusers = NULL;
+       options->ignoreusers = "";
        options->rootasroot = false;
        options->ignoreroot = false;
        options->do_open = true;
@@ -511,18 +528,11 @@
        options->debug = false;
 }
 
-/**
- * ??
- *
- * @param
- *
- * @return PAM status
- *
-*/
 static int csv_contains( pam_handle_t * pamh, const char *haystack, const char 
*needle, bool debug )
 {
        if ( debug ) {
-               pam_syslog( pamh, LOG_DEBUG, "csv_contains haystack: '%s' 
needle: '%s'", haystack, needle );
+               pam_syslog( pamh, LOG_DEBUG, "csv_contains haystack: '%s' 
needle: '%s'", haystack,
+                           needle );
        }
 
        const size_t l = strlen( needle );
@@ -540,16 +550,8 @@
        return strcmp( s, needle ) == 0;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
-*/
-static void cdbus_pam_options_parser( pam_handle_t * pamh, pam_options_t * 
options, int argc, const char **argv )
+static void options_parser( pam_handle_t * pamh, pam_options_t * options, int 
argc,
+                           const char **argv )
 {
        for ( ; argc-- > 0; ++argv ) {
                if ( !strncmp( *argv, "homeprefix=", 11 ) ) {
@@ -574,40 +576,33 @@
                        options->do_close = true;
                } else {
                        pam_syslog( pamh, LOG_ERR, "unknown option: %s", *argv 
);
-                       pam_syslog( pamh, LOG_ERR, "valid options: debug 
homeprefix=<> ignoreservices=<> ignoreusers=<> "
-                                   "rootasroot ignoreroot openonly closeonly 
cleanup=" );
+                       pam_syslog( pamh, LOG_ERR, "valid options: debug 
homeprefix=<> "
+                                   "ignoreservices=<> ignoreusers=<> 
rootasroot ignoreroot "
+                                   "openonly closeonly cleanup=<>" );
                }
        }
+
        if ( options->rootasroot && options->ignoreroot ) {
                options->rootasroot = false;
-               pam_syslog( pamh, LOG_WARNING, "'ignoreroot' options shadows 
'rootasroot'. 'rootasroot' will be ignored." );
+               pam_syslog( pamh, LOG_WARNING, "'ignoreroot' options shadows 
'rootasroot'. "
+                           "'rootasroot' will be ignored." );
        }
+
        if ( options->debug ) {
-               pam_syslog( pamh, LOG_ERR,
-                           "current settings: homeprefix=%s ignoreservices=%s 
ignoreusers=%s",
-                           options->homeprefix, options->ignoreservices, 
options->ignoreusers );
+               pam_syslog( pamh, LOG_ERR, "current settings: homeprefix='%s' 
ignoreservices='%s' "
+                           "ignoreusers='%s' cleanup='%s'", 
options->homeprefix,
+                           options->ignoreservices, options->ignoreusers, 
options->cleanup );
        }
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
- * @return PAM_SUCCESS or PAM_IGNORE
- *
-*/
-static int cdbus_pam_check_ignore( pam_handle_t * pamh, const pam_options_t * 
options )
+static int check_ignore( pam_handle_t * pamh, const pam_options_t * options )
 {
        if ( options->ignoreservices ) {
 
                const char *pam_service = NULL;
                int ret = pam_get_item( pamh, PAM_SERVICE, ( const void ** 
)&pam_service );
                if ( ret != PAM_SUCCESS ) {
-                       pam_syslog( pamh, LOG_ERR, "cannot get PAM_SERVICE: 
%s", strerror( -ret ) );
+                       pam_syslog( pamh, LOG_ERR, "cannot get PAM_SERVICE" );
                        return PAM_IGNORE;
                }
                if ( !pam_service ) {
@@ -615,8 +610,13 @@
                        return PAM_IGNORE;
                }
 
+               if ( options->debug ) {
+                       pam_syslog( pamh, LOG_DEBUG, "PAM_SERVICE is '%s'", 
pam_service );
+               }
+
                if ( options->ignoreservices ) {
-                       if ( csv_contains( pamh, options->ignoreservices, 
pam_service, options->debug ) ) {
+                       if ( csv_contains
+                            ( pamh, options->ignoreservices, pam_service, 
options->debug ) ) {
                                return PAM_IGNORE;
                        }
                }
@@ -627,7 +627,7 @@
                const char *pam_user = NULL;
                int ret = pam_get_item( pamh, PAM_USER, ( const void ** 
)&pam_user );
                if ( ret != PAM_SUCCESS ) {
-                       pam_syslog( pamh, LOG_ERR, "cannot get PAM_USER: %s", 
strerror( -ret ) );
+                       pam_syslog( pamh, LOG_ERR, "cannot get PAM_USER" );
                        return PAM_IGNORE;
                }
                if ( !pam_user ) {
@@ -635,6 +635,10 @@
                        return PAM_IGNORE;
                }
 
+               if ( options->debug ) {
+                       pam_syslog( pamh, LOG_DEBUG, "PAM_USER is '%s'", 
pam_user );
+               }
+
                if ( options->ignoreusers ) {
                        if ( csv_contains( pamh, options->ignoreusers, 
pam_user, options->debug ) ) {
                                return PAM_IGNORE;
@@ -650,217 +654,77 @@
        return PAM_SUCCESS;
 }
 
-/**
- *
- *
- *
-*/
-static int cdbus_pam_switch_to_user( pam_handle_t * pamh, struct passwd 
**user_entry, const char *real_user )
+static char *get_snapper_conf( const char *pam_user, const pam_options_t * 
options )
 {
-       /* save current user */
-       if ( ( ( *user_entry ) = getpwnam( real_user ) ) == NULL ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "getpwnam( %s ) failed: %s", 
real_user, strerror( ret ) );
-               return PAM_IGNORE;
-       }
-       memset( ( *user_entry )->pw_passwd, 0, strlen( ( *user_entry 
)->pw_passwd ) );
-
-       if ( setegid( ( *user_entry )->pw_gid ) == -1 ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "setgid(%lu) failed: %s", ( unsigned 
long )( *user_entry )->pw_gid, strerror( ret ) );
-               return PAM_IGNORE;
-       }
-       if ( seteuid( ( *user_entry )->pw_uid ) == -1 ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "setuid(%lu) failed: %s", ( unsigned 
long )( *user_entry )->pw_uid, strerror( ret ) );
-               return PAM_IGNORE;
+       char *snapper_conf = NULL;
+       if ( options->rootasroot && strcmp( pam_user, "root" ) == 0 ) {
+               snapper_conf = strdup( "root" );
+       } else {
+               snapper_conf = malloc( strlen( options->homeprefix ) + strlen( 
pam_user ) + 1 );
+               strcpy( snapper_conf, options->homeprefix );
+               strcat( snapper_conf, pam_user );
        }
-       return PAM_SUCCESS;
+       return snapper_conf;
 }
 
-/**
- *
- *
- *
-*/
-static int cdbus_pam_drop_privileges( pam_handle_t * pamh, struct passwd 
**user_entry )
+static void pam_session( pam_handle_t * pamh, openclose_t openclose, int argc, 
const char **argv )
 {
-       PAM_MODUTIL_DEF_PRIVS( privs );
-       if ( pam_modutil_drop_priv( pamh, &privs, ( *user_entry ) ) ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "pam_modutil_drop_priv (%lu) failed: 
%s", ( unsigned long )( *user_entry )->pw_uid,
-                           strerror( ret ) );
-               return PAM_IGNORE;
-       }
-       return PAM_SUCCESS;
-}
+       pam_options_t options;
+       set_default_options( &options );
+       options_parser( pamh, &options, argc, argv );
 
-/**
- *
- *
- *
-*/
-static int cdbus_pam_switch_from_user( pam_handle_t * pamh )
-{
-       uid_t ruid, euid, suid;
-       gid_t rgid, egid, sgid;
-       getresuid( &ruid, &euid, &suid );
-       getresgid( &rgid, &egid, &sgid );
-       if ( setegid( sgid ) == -1 ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "setgid(%lu) failed: %s", ( unsigned 
long )sgid, strerror( ret ) );
-       }
-       if ( seteuid( suid ) == -1 ) {
-               int ret = errno;
-               pam_syslog( pamh, LOG_ERR, "setuid(%lu) failed: %s", ( unsigned 
long )suid, strerror( ret ) );
+       if ( check_ignore( pamh, &options ) == PAM_IGNORE ) {
+               return;
        }
-       return PAM_SUCCESS;
-}
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- * @param
- *
- * @return -EINVAL or OK
- *
-*/
-static int cdbus_pam_session( pam_handle_t * pamh, openclose_t openclose, 
const char *real_user, int argc, const char **argv )
-{
-       DBusConnection *conn;
-       int ret = -EINVAL;
-       char *real_user_config = NULL;
-       pam_options_t options;
-       cdbus_pam_options_setdefault( &options );
-       cdbus_pam_options_parser( pamh, &options, argc, argv );
-       ret = cdbus_pam_check_ignore( pamh, &options );
-       if ( ret == PAM_IGNORE ) {
-               goto pam_snapper_ignore;
-       }
-       /* open the connection to the D-Bus */
-       conn = cdbus_conn( pamh );
-       if ( conn == NULL ) {
-               pam_syslog( pamh, LOG_ERR, "connect to D-Bus failed" );
-               goto pam_snapper_ignore;
+       const char *pam_user = NULL;
+       int ret = pam_get_item( pamh, PAM_USER, ( const void ** )&pam_user );
+       if ( ret != PAM_SUCCESS ) {
+               pam_syslog( pamh, LOG_ERR, "cannot get PAM_USER" );
+               return;
        }
-       if ( !strcmp( real_user, "root" ) && options.rootasroot ) {
-               real_user_config = strdup( "root" );
-       } else {
-               real_user_config = malloc( strlen( options.homeprefix ) + 
strlen( real_user ) + 1 );
-               if ( !real_user_config ) {
-                       goto pam_sm_open_session_err;
-               }
-               strcpy( real_user_config, options.homeprefix );
-               strcat( real_user_config, real_user );
+       if ( !pam_user ) {
+               pam_syslog( pamh, LOG_ERR, "PAM_USER is null" );
+               return;
+       }
+
+       char *snapper_conf = get_snapper_conf( pam_user, &options );
+       if ( !snapper_conf ) {
+               return;
        }
+
        if ( options.debug ) {
                pam_syslog( pamh, LOG_DEBUG, MODULE_NAME " version " VERSION );
-               pam_syslog( pamh, LOG_DEBUG, "real_user_config='%s'", 
real_user_config );
+               pam_syslog( pamh, LOG_DEBUG, "pam_user='%s', 
snapper_conf='%s'", pam_user,
+                           snapper_conf );
        }
+
        if ( ( openclose == open_session ) && options.do_open ) {
-               ret =
-                   cdbus_create_snap_call( pamh, real_user_config, 
options.do_close ? createmode_pre : createmode_single, options.cleanup,
-                                           conn );
+               ret = worker( pamh, pam_user, snapper_conf, options.do_close ? 
createmode_pre :
+                             createmode_single, options.cleanup );
        } else if ( ( openclose == close_session ) && options.do_close ) {
-               ret =
-                   cdbus_create_snap_call( pamh, real_user_config, 
options.do_open ? createmode_post : createmode_single, options.cleanup,
-                                           conn );
-       }
-       if ( ret < 0 ) {
-               pam_syslog( pamh, LOG_ERR, "snapshot create call failed: %s", 
strerror( -ret ) );
-       }
- pam_sm_open_session_err:
-       if ( real_user_config ) {
-               free( real_user_config );
+               ret = worker( pamh, pam_user, snapper_conf, options.do_open ? 
createmode_post :
+                             createmode_single, options.cleanup );
        }
-       dbus_connection_unref( conn );
- pam_snapper_ignore:
-       return PAM_SUCCESS;
+
+       free( snapper_conf );
 }
 
 /*
- * HERE the PAM stuff starts
+ * PAM stuff starts here
 */
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
- * @return PAM_SUCCESS (always)
- *
-*/
 PAM_EXTERN int pam_sm_open_session( pam_handle_t * pamh, int flags, int argc, 
const char **argv )
 {
-       int ret = -EINVAL;
-       const char *real_user = NULL;
-       struct passwd *user_entry;
-       ret = pam_get_item( pamh, PAM_USER, ( const void ** )&real_user );
-       if ( ret != PAM_SUCCESS ) {
-               pam_syslog( pamh, LOG_ERR, "cannot get PAM_USER: %s", strerror( 
-ret ) );
-               goto pam_snapper_skip;
-       }
-       if ( !real_user ) {
-               goto pam_snapper_skip;
-       }
-       /* no need to proceed as root */
-       if ( cdbus_pam_switch_to_user( pamh, &user_entry, real_user ) == 
PAM_IGNORE ) {
-               goto pam_snapper_skip;
-       }
-       if ( cdbus_pam_drop_privileges( pamh, &user_entry ) == PAM_IGNORE ) {
-               goto pam_snapper_skip;
-       }
-       /* do the real stuff */
-       cdbus_pam_session( pamh, open_session, real_user, argc, argv );
-       /* go back to original user */
-       cdbus_pam_switch_from_user( pamh );
- pam_snapper_skip:
+       pam_session( pamh, open_session, argc, argv );
+
        return PAM_SUCCESS;
 }
 
-/**
- * ??
- *
- * @param pamh PAM handle
- * @param
- * @param
- * @param
- *
- * @return PAM_SUCCESS (always)
- *
-*/
 PAM_EXTERN int pam_sm_close_session( pam_handle_t * pamh, int flags, int argc, 
const char **argv )
 {
-       int ret = -EINVAL;
-       const char *real_user = NULL;
-       struct passwd *user_entry;
-       ret = pam_get_item( pamh, PAM_USER, ( const void ** )&real_user );
-       if ( ret != PAM_SUCCESS ) {
-               pam_syslog( pamh, LOG_ERR, "cannot get PAM_USER: %s", strerror( 
-ret ) );
-               goto pam_snapper_skip;
-       }
-       if ( !real_user ) {
-               goto pam_snapper_skip;
-       }
-       /* no need to proceed as root */
-       if ( cdbus_pam_switch_to_user( pamh, &user_entry, real_user ) == 
PAM_IGNORE ) {
-               goto pam_snapper_skip;
-       }
-       if ( cdbus_pam_drop_privileges( pamh, &user_entry ) == PAM_IGNORE ) {
-               goto pam_snapper_skip;
-       }
-       /* do the real stuff */
-       cdbus_pam_session( pamh, close_session, real_user, argc, argv );
-       /* go back to original user */
-       cdbus_pam_switch_from_user( pamh );
- pam_snapper_skip:
+       pam_session( pamh, close_session, argc, argv );
+
        return PAM_SUCCESS;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/snapper/FileUtils.cc 
new/snapper-0.1.4/snapper/FileUtils.cc
--- old/snapper-0.1.4/snapper/FileUtils.cc      2013-04-22 16:26:33.000000000 
+0200
+++ new/snapper-0.1.4/snapper/FileUtils.cc      2013-05-31 17:41:33.000000000 
+0200
@@ -68,6 +68,7 @@
            y2err("not a directory path:" << base_path);
            throw IOErrorException();
        }
+
 #ifdef ENABLE_XATTRS
        setXaStatus();
 #endif
@@ -95,6 +96,7 @@
            close(dirfd);
            throw IOErrorException();
        }
+
 #ifdef ENABLE_XATTRS
        xastatus = dir.xastatus;
 #endif
@@ -104,12 +106,13 @@
     SDir::SDir(const SDir& dir)
        : base_path(dir.base_path), path(dir.path)
     {
-       dirfd = dup(dir.dirfd);
+       dirfd = fcntl(dir.dirfd, F_DUPFD_CLOEXEC, 0);
        if (dirfd == -1)
        {
-           y2err("dup failed" << " error:" << stringerror(errno));
+           y2err("fcntl(F_DUPFD_CLOEXEC) failed error:" << stringerror(errno));
            throw IOErrorException();
        }
+
 #ifdef ENABLE_XATTRS
        xastatus = dir.xastatus;
 #endif
@@ -121,16 +124,17 @@
     {
        if (this != &dir)
        {
-#ifdef ENABLE_XATTRS
-           xastatus = dir.xastatus;
-#endif
            ::close(dirfd);
-           dirfd = dup(dir.dirfd);
+           dirfd = fcntl(dir.dirfd, F_DUPFD_CLOEXEC, 0);
            if (dirfd == -1)
            {
-               y2err("dup failed" << " error:" << stringerror(errno));
+               y2err("fcntl(F_DUPFD_CLOEXEC) failed error:" << 
stringerror(errno));
                throw IOErrorException();
            }
+
+#ifdef ENABLE_XATTRS
+           xastatus = dir.xastatus;
+#endif
        }
 
        return *this;
@@ -146,11 +150,11 @@
     SDir
     SDir::deepopen(const SDir& dir, const string& name)
     {
-       string::size_type pos = name.find('/');
-       if (pos == string::npos)
-          return SDir(dir, name);
+       string::size_type pos = name.find('/');
+       if (pos == string::npos)
+           return SDir(dir, name);
 
-       return deepopen(SDir(dir, string(name, 0, pos)), string(name, pos + 1));
+       return deepopen(SDir(dir, string(name, 0, pos)), string(name, pos + 1));
     }
 
 
@@ -185,10 +189,10 @@
     vector<string>
     SDir::entries(entries_pred_t pred) const
     {
-       int fd = dup(dirfd);
+       int fd = fcntl(dirfd, F_DUPFD_CLOEXEC, 0);
        if (fd == -1)
        {
-           y2err("dup failed" << " error:" << stringerror(errno));
+           y2err("fcntl(F_DUPFD_CLOEXEC) failed error:" << stringerror(errno));
            throw IOErrorException();
        }
 
@@ -410,18 +414,15 @@
        assert(path.find('/') == string::npos);
        assert(path != "..");
 
-       int fd = ::openat(dirfd, path.c_str(), O_RDONLY | O_NOFOLLOW | 
O_NOATIME | O_CLOEXEC);
+       int fd = ::openat(dirfd, path.c_str(), O_RDONLY | O_NOFOLLOW | 
O_NONBLOCK | O_NOATIME |
+                         O_CLOEXEC);
        if (fd >= 0)
        {
            ssize_t r1 = ::flistxattr(fd, list, size);
-           close(fd);
+           ::close(fd);
            return r1;
        }
-       else if (errno != ELOOP)
-       {
-           return -1;
-       }
-       else
+       else if (errno == ELOOP || errno == ENXIO || errno == EWOULDBLOCK)
        {
            boost::lock_guard<boost::mutex> lock(cwd_mutex);
 
@@ -436,6 +437,10 @@
            chdir("/");
            return r2;
        }
+       else
+       {
+           return -1;
+       }
     }
 
 
@@ -445,18 +450,15 @@
        assert(path.find('/') == string::npos);
        assert(path != "..");
 
-       int fd = ::openat(dirfd, path.c_str(), O_RDONLY | O_NOFOLLOW | 
O_NOATIME | O_CLOEXEC);
+       int fd = ::openat(dirfd, path.c_str(), O_RDONLY | O_NOFOLLOW | 
O_NONBLOCK | O_NOATIME |
+                         O_CLOEXEC);
        if (fd >= 0)
        {
            ssize_t r1 = ::fgetxattr(fd, name, value, size);
-           close(fd);
+           ::close(fd);
            return r1;
        }
-       else if (errno != ELOOP)
-       {
-           return -1;
-       }
-       else
+       else if (errno == ELOOP || errno == ENXIO || errno == EWOULDBLOCK)
        {
            boost::lock_guard<boost::mutex> lock(cwd_mutex);
 
@@ -471,6 +473,10 @@
            chdir("/");
            return r2;
        }
+       else
+       {
+           return -1;
+       }
     }
 
 
@@ -488,7 +494,8 @@
            }
            else
            {
-                y2err("Couldn't get extended attributes status for " << 
base_path << "/" << path << stringerror(errno));
+                y2err("Couldn't get extended attributes status for " << 
base_path << "/" <<
+                     path << stringerror(errno));
                 throw IOErrorException();
            }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/snapper/Makefile.am 
new/snapper-0.1.4/snapper/Makefile.am
--- old/snapper-0.1.4/snapper/Makefile.am       2013-05-03 09:56:33.000000000 
+0200
+++ new/snapper-0.1.4/snapper/Makefile.am       2013-05-29 14:31:34.000000000 
+0200
@@ -53,7 +53,7 @@
 
 
 libsnapper_la_LDFLAGS = -version-info @LIBVERSION_INFO@
-libsnapper_la_LIBADD = -lboost_thread-mt -lxml2 -lz -lm
+libsnapper_la_LIBADD = -lboost_thread-mt -lboost_system-mt -lxml2 -lz -lm
 
 pkgincludedir = $(includedir)/snapper
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/snapper-0.1.4/snapper/Makefile.in 
new/snapper-0.1.4/snapper/Makefile.in
--- old/snapper-0.1.4/snapper/Makefile.in       2013-05-03 09:56:56.000000000 
+0200
+++ new/snapper-0.1.4/snapper/Makefile.in       2013-05-31 17:41:56.000000000 
+0200
@@ -334,7 +334,7 @@
        SnapperDefines.h $(TMP_XA) $(am__append_1) $(am__append_2) \
        $(am__append_3)
 libsnapper_la_LDFLAGS = -version-info @LIBVERSION_INFO@
-libsnapper_la_LIBADD = -lboost_thread-mt -lxml2 -lz -lm
+libsnapper_la_LIBADD = -lboost_thread-mt -lboost_system-mt -lxml2 -lz -lm
 pkginclude_HEADERS = \
        Factory.h                                       \
        Snapper.h                                       \

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to