]> arthur.barton.de Git - netatalk.git/commitdiff
Merge branch-2-1
authorFrank Lahm <franklahm@googlemail.com>
Tue, 16 Nov 2010 10:15:32 +0000 (11:15 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Tue, 16 Nov 2010 10:15:32 +0000 (11:15 +0100)
1  2 
NEWS
etc/afpd/acl_mappings.h
etc/cnid_dbd/cnid_metad.c
etc/cnid_dbd/comm.c
etc/cnid_dbd/usockfd.c
include/atalk/util.h
libatalk/cnid/dbd/cnid_dbd.c
libatalk/util/socket.c

diff --combined NEWS
index 4b2873c504d4aeb1a9636afe69f3f1177f75273d,66a9c397252deb83759654adf16135693ca2f91a..5abf8490efad54b2c1e16fae6073bc41bfda0e08
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,43 -1,14 +1,47 @@@
 +Changes in 2.2alpha3
 +====================
 +
 +* FIX: afpd: various fixes
 +* FIX: Any daemon did not run if atalkd doesn't exist (redhat/debian)
 +
 +Changes in 2.2alpha2
 +====================
 +
 +* FIX: afpd: fix compilation error when ACL support is not available
 +* FIX: Ensure Appletalk manpages and config files are distributed
 +
 +Changes in 2.2alpha1
 +====================
 +
 +* NEW: ad utility: ad cp
 +* NEW: ad utility: ad rm
 +* NEW: ad utility: ad mv
 +* NEW: afpd: dynamic directoy and CNID cache (new config option -dircachesize)
 +* NEW: afpd: POSIX 1e ACL support
 +* NEW: afpd: automagic Zeroconf registration with avahi, registering both
 +       the service _afpovertcp._tcp and TimeMachine volumes with _adisk._tcp.
 +* UPD: afpd: ACLs usable (though not visible on the client side) without common
 +       directory service, by mapping ACLs to UARight
 +* UPD: afpd: performance improvements for ACL access calculations
 +* UPD: AppleTalk is disabled by default at configuration time. If needed
 +       use configure switch --enable-ddp.
 +* FIX: afpd: Solaris 10 compatibilty fix: don't use SO_SNDTIMEO/SO_RCVTIMEO,
 +       use non-blocking IO and select instead.
 +* FIX: cnid_dbd: Solaris 10 compatibilty fix: don't use SO_SNDTIMEO/SO_RCVTIMEO,
 +       use non-blocking IO and select instead.
 +* REM: afile/achfile/apple_cp/apple_mv/apple_rm: use ad
 +
  Changes in 2.1.5
  ================
  
  * UPD: afpd: support newlines in -loginmesg with \n escaping syntax
  * UPD: afpd: support for changed chmod semantics on ZFS with ACLs
         in onnv145+
- * FIX: afpd: fix leaking resource when moving objects on the server
+ * FIX: afpd: fix leaking ressource when moving objects on the server
+ * FIX: afpd: backport Solaris 10 compatibilty fix from 2.2: don't use
+        SO_SNDTIMEO/SO_RCVTIMEO, use non-blocking IO and select instead.
+ * FIX: cnid_dbd: backport Solaris 10 compatibilty fix from 2.2: don't
+        use SO_SNDTIMEO/SO_RCVTIMEO, use non-blocking IO and select instead.
  
  Changes in 2.1.4
  ================
@@@ -47,7 -18,7 +51,7 @@@
  * FIX: afpd: Better handling of symlinks in combination with ACLs and EAs.
         Fixes bug 3074076.
  * FIX: dbd: Adding a file with the CNID from it's adouble file did
 -       not work in case that CNID was alread occupied in the database
 +       not work in case that CNID was already occupied in the database
  * FIX: macusers: add support for Solaris
  * NEW: cnid_metad: use a PID lockfile
  * NEW: afpd: prevent log flooding
@@@ -99,7 -70,6 +103,7 @@@ Changes in 2.1-releas
  
  Changes in 2.1-beta2
  ====================
 +
  * NEW: afpd: static generated AFP signature stored in afp_signature.conf,
         cf man 5 afp_signature.conf
  * NEW: afpd: clustering support: new per volume option "cnidserver".
diff --combined etc/afpd/acl_mappings.h
index 9bab0d76b6cd013ffbabbc4b1be22fa99837f18b,e2d9f3d2d051d3600a8275b05572a4f3c0fc7fe0..b7c4b6d266fdb9863005c61dc889cd66785453e7
@@@ -1,5 -1,4 +1,4 @@@
  /*
-    $Id: acl_mappings.h,v 1.1 2009-02-02 11:55:00 franklahm Exp $
     Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
  
     This program is free software; you can redistribute it and/or modify
  #ifndef ACL_MAPPINGS
  #define ACL_MAPPINGS
  
 +#ifdef HAVE_SOLARIS_ACLS
  #include <sys/acl.h>
 +#endif
 +
  #include "acls.h"
  
  /* 
   * Stuff for mapping between ACL implementations
   */
  
+ /* Solaris 10u8 still hasn't got ACE_INHERITED_ACE */
+ #ifndef ACE_INHERITED_ACE
+ #define ACE_INHERITED_ACE 0x0080
+ #endif
  struct ace_rights_map {
      u_int32_t from;
      u_int32_t to;
  };
  
 +#ifdef HAVE_SOLARIS_ACLS
  struct ace_rights_map nfsv4_to_darwin_rights[] = {
      {ACE_READ_DATA,         DARWIN_ACE_READ_DATA},
      {ACE_WRITE_DATA,        DARWIN_ACE_WRITE_DATA},
@@@ -93,6 -93,5 +97,6 @@@ struct darwin_to_nfsv4_flags_map darwin
      {DARWIN_ACE_FLAGS_INHERITED,         ACE_INHERITED_ACE},
      {0,0}
  };
 +#endif /* HAVE_SOLARIS_ACLS */
  
  #endif        /* ACL_MAPPINGS */
index 66108c013b3532b9b303935feb69f3f9547167a5,3ce9151c9a4f94eff9be641b2fe9264c08fec657..23a6fd0266334e05e9dbb7f9e396890780cade9a
@@@ -1,8 -1,9 +1,8 @@@
  /*
 - * $Id: cnid_metad.c,v 1.22 2009-11-16 02:04:47 didg Exp $
 - *
   * Copyright (C) Joerg Lenneis 2003
 - * All Rights Reserved.  See COPYING.
 + * Copyright (C) Frank Lahm 2009, 2010
   *
 + * All Rights Reserved.  See COPYING.
   */
  
  /* 
@@@ -21,8 -22,6 +21,8 @@@
     Result:
                         via TCP socket
     4.       afpd          ------->         cnid_dbd
 +
 +   cnid_metad and cnid_dbd have been converted to non-blocking IO in 2010.
   */
  
  
  #include <errno.h>
  #include <string.h>
  #include <signal.h>
 -#ifdef HAVE_SYS_TYPES_H
  #include <sys/types.h>
 -#endif
 -#ifdef HAVE_SYS_TIME_H
  #include <sys/time.h>
 -#endif
 -#ifdef HAVE_SYS_WAIT_H
  #include <sys/wait.h>
 -#endif
 -#ifdef HAVE_SYS_UIO_H
  #include <sys/uio.h>
 -#endif
  #include <sys/un.h>
  #define _XPG4_2 1
  #include <sys/socket.h>
@@@ -597,7 -604,9 +597,8 @@@ int main(int argc, char *argv[]
          if (rqstfd <= 0)
              continue;
  
-         ret = readt(rqstfd, &len, sizeof(int), 4);
 -        /* TODO: Check out read errors, broken pipe etc. in libatalk. Is
 -           SIGIPE ignored there? Answer: Ignored for dsi, but not for asp ... */
 -        ret = readt(rqstfd, &len, sizeof(int), 1, 5);
++        ret = readt(rqstfd, &len, sizeof(int), 1, 4);
++
          if (!ret) {
              /* already close */
              goto loop_end;
              goto loop_end;
          }
  
 -        actual_len = read(rqstfd, dbdir, len);
 +        actual_len = readt(rqstfd, dbdir, len, 1);
          if (actual_len < 0) {
              LOG(log_severe, logtype_cnid, "Read(2) error : %s", strerror(errno));
              goto loop_end;
diff --combined etc/cnid_dbd/comm.c
index 8038f2668f7795479e2472919f6673c60f14173e,284ecae4c2fcb7f4f2664253c957de689eca5461..89355d767b8c0072a01d42763a935850b03e5a9c
@@@ -1,7 -1,7 +1,7 @@@
  /*
 - * $Id: comm.c,v 1.6 2009-10-19 08:09:07 didg Exp $
 - *
   * Copyright (C) Joerg Lenneis 2003
 + * Copyright (C) Frank Lahm 2010
 + *
   * All Rights Reserved.  See COPYING.
   */
  
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
 -
 -#ifdef HAVE_UNISTD_H
  #include <unistd.h>
 -#endif
 -
  #include <sys/param.h>
 -#define _XPG4_2 1
 -#include <sys/socket.h>
 -
 -#ifdef HAVE_SYS_TYPES_H
  #include <sys/types.h>
 -#endif
 -
 -#ifdef HAVE_SYS_TIME_H
  #include <sys/time.h>
 -#endif
 -
 -#ifdef HAVE_SYS_UIO_H
  #include <sys/uio.h>
 -#endif
 -
 -#ifdef HAVE_SYS_SOCKET_H
 +#define _XPG4_2 1
  #include <sys/socket.h>
 -#endif
 -
  #include <sys/select.h>
 -
  #include <assert.h>
  #include <time.h>
  
  #include <atalk/logger.h>
 +#include <atalk/util.h>
  #include <atalk/cnid_dbd_private.h>
  
  #include "db_param.h"
@@@ -246,16 -264,8 +246,16 @@@ int comm_rcv(struct cnid_dbd_rqst *rqst
  
      if (!cur_fd)
          return 0;
 +
 +    LOG(log_maxdebug, logtype_cnid, "comm_rcv: got data on fd %u", cur_fd);
 +
 +    if (setnonblock(cur_fd, 1) != 0) {
 +        LOG(log_error, logtype_cnid, "comm_rcv: setnonblock: %s", strerror(errno));
 +        return -1;
 +    }
 +
      nametmp = rqst->name;
-     if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), CNID_DBD_TIMEOUT))
 -    if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, 5))
++    if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, CNID_DBD_TIMEOUT))
          != sizeof(struct cnid_dbd_rqst)) {
          if (b)
              LOG(log_error, logtype_cnid, "error reading message header: %s", strerror(errno));
          return 0;
      }
      rqst->name = nametmp;
-     if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, CNID_DBD_TIMEOUT)
 -    if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, 1, 5) != rqst->namelen) {
++    if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT)
 +        != rqst->namelen) {
          LOG(log_error, logtype_cnid, "error reading message name: %s", strerror(errno));
          invalidate_fd(cur_fd);
          return 0;
         needs zero terminated strings. */
      rqst->name[rqst->namelen] = '\0';
  
 +    LOG(log_maxdebug, logtype_cnid, "comm_rcv: got %u bytes", b + rqst->namelen);
 +
      return 1;
  }
  
diff --combined etc/cnid_dbd/usockfd.c
index d9dadb5b9828a879d447897a4acf8e8e060a177a,1817c0bc0a0756115a171d56af6f7e8941cda771..ceb6ff211ad6628693b18e48bb2c1fbec2925c03
@@@ -1,4 -1,6 +1,4 @@@
  /*
 - * $Id: usockfd.c,v 1.6 2009-11-05 14:38:07 franklahm Exp $
 - *
   * Copyright (C) Joerg Lenneis 2003
   * All Rights Reserved.  See COPYING.
   */
@@@ -155,7 -157,6 +155,6 @@@ int usockfd_check(int sockfd, const sig
      socklen_t size;
      fd_set readfds;
      int ret;
-     struct timeval tv;
       
      FD_ZERO(&readfds);
      FD_SET(sockfd, &readfds);
                  strerror(errno));
              return -1;
          }
-         if (setnonblock(fd, 1) != 0) {
-             LOG(log_error, logtype_cnid, "setnonblock: %s", strerror(errno));
-             return -1;
-         }
          return fd;
      } else
          return 0;
diff --combined include/atalk/util.h
index 790f5941dc0beedead9132f68c8854163538edeb,13929953dd3ba9411cbbd816e37924fc0269a058..d6209ed93c86cf624ba3292c4cd98096cb3b8aab
@@@ -1,3 -1,7 +1,3 @@@
 -/*
 - * $Id: util.h,v 1.21 2010-02-28 22:29:16 didg Exp $
 - */
 -
  /*!
   * @file
   * Netatalk utility functions
  #define EXITERR_CONF 2  /* error in config files/cmd line parameters */
  #define EXITERR_SYS  3  /* local system error */
  
 +/* Print a SBT and exit */
 +#define AFP_PANIC(why) \
 +    do {                                            \
 +        netatalk_panic(why);                        \
 +        abort();                                    \
 +    } while(0);
 +
 +/* LOG assert errors */
 +#ifndef NDEBUG
 +#define AFP_ASSERT(b) \
 +    do {                                                                \
 +        if (!(b)) {                                                     \
 +            AFP_PANIC(#b);                                              \
 +        } \
 +    } while(0);
 +#else
 +#define AFP_ASSERT(b)
 +#endif /* NDEBUG */
 +
 +#define STRCMP(a,b,c) (strcmp(a,c) b 0)
  
  #ifdef WITH_SENDFILE
  extern ssize_t sys_sendfile (int __out_fd, int __in_fd, off_t *__offset,size_t __count);
@@@ -60,9 -44,9 +60,9 @@@ extern int atalk_aton     (char *, stru
  extern void bprint        (char *, int);
  extern int strdiacasecmp  (const char *, const char *);
  extern int strndiacasecmp (const char *, const char *, size_t);
 -extern pid_t server_lock  (char * /*program*/, char * /*file*/, 
 -                             int /*debug*/);
 +extern pid_t server_lock  (char * /*program*/, char * /*file*/, int /*debug*/);
  extern void fault_setup         (void (*fn)(void *));
 +extern void netatalk_panic(const char *why);
  #define server_unlock(x)  (unlink(x))
  
  /* strlcpy and strlcat are used by pam modules */
@@@ -127,7 -111,7 +127,7 @@@ extern int lock_reg(int fd, int cmd, in
   ******************************************************************/
  
  extern int setnonblock(int fd, int cmd);
- extern ssize_t readt(int socket, void *data, const size_t length, int timeout);
+ extern ssize_t readt(int socket, void *data, const size_t length, int setnonblocking, int timeout);
  extern const char *getip_string(const struct sockaddr *sa);
  extern unsigned int getip_port(const struct sockaddr *sa);
  extern void apply_ip_mask(struct sockaddr *ai, int maskbits);
@@@ -138,7 -122,6 +138,7 @@@ extern int compare_ip(const struct sock
   *****************************************************************/
  
  extern const char *getcwdpath(void);
 +extern char *stripped_slashes_basename(char *p);
  extern int lchdir(const char *dir);
  
  #endif  /* _ATALK_UTIL_H */
index 20d3a900881ef0ce9a2ad5a2cd266c6c3b0b4143,a01cfaaf3170c9cc45af82d35a2676d4705a3b79..01c984062543317ea6bfb65f1f3c2206af05fe47
@@@ -89,7 -89,7 +89,7 @@@ static int tsock_getfd(const char *host
          if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
              LOG(log_info, logtype_default, "tsock_getfd: socket CNID server %s:: %s",
                  host, strerror(errno));
-                 continue;
+             continue;
          }
  
          attr = 1;
              sock = -1;
              return -1;
          }
-         
          if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
              if (errno == EINPROGRESS) {
                  struct timeval tv;
                              strerror(errno));
                      }
                      close(sock);
 -                    sock=-1;
 +                    sock = -1;
                      continue;
                  }
              } else {
                  continue;
              }
          }
-         
          /* We've got a socket */
          break;
      }
  static int write_vec(int fd, struct iovec *iov, ssize_t towrite, int vecs)
  {
      ssize_t len;
+     int slept = 0;
+     int sleepsecs;
  
      while (1) {
          if (((len = writev(fd, iov, vecs)) == -1 && errno == EINTR))
              continue;
  
+         if ((! slept) && len == -1 && errno == EAGAIN) {
+             sleepsecs = 5;
+             while ((sleepsecs = sleep(sleepsecs)));
+             slept = 1;
+             continue;
+         }
          if (len == towrite) /* wrote everything out */
              break;
  
@@@ -224,7 -233,7 +233,7 @@@ static int init_tsock(CNID_private *db
      int len;
      struct iovec iov[2];
  
-     LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s", 
+     LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s",
          db->db_dir, db->cnidserver, db->cnidport);
  
      if ((fd = tsock_getfd(db->cnidserver, db->cnidport)) < 0)
@@@ -273,7 -282,7 +282,7 @@@ static int send_packet(CNID_private *db
              db->db_dir, strerror(errno));
          return -1;
      }
-     
      LOG(log_maxdebug, logtype_cnid, "send_packet: {done}");
      return 0;
  }
@@@ -321,7 -330,7 +330,7 @@@ static ssize_t read_packet(int socket, 
      stored = 0;
  
      while (stored < length) {
-         len = read(socket, (u_int8_t *) data + stored, length - stored);
+         len = readt(socket, (u_int8_t *) data + stored, length - stored, 0, 5);
          if (len == -1) {
              switch (errno) {
              case EINTR:
@@@ -443,7 -452,7 +452,7 @@@ static int transmit(CNID_private *db, s
                      memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
                  memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
              }
-             LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.", 
+             LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.",
                  db->db_dir, *(uint64_t *)stamp);
          }
          if (!dbd_rpc(db, rqst, rply)) {
diff --combined libatalk/util/socket.c
index 4f8445929b6f0f3f915633e1bcdb16b7510a3484,543f38036f40d00928ab434e34ab08e08d7b49d2..06ee10e580d909de12a87854e5f0f12dd7a92219
@@@ -1,4 -1,5 +1,4 @@@
  /*
 -   $Id: socket.c,v 1.6 2010-01-05 19:05:52 franklahm Exp $
     Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
  
     This program is free software; you can redistribute it and/or modify
@@@ -30,6 -31,8 +30,8 @@@
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
+ #include <sys/time.h>
+ #include <time.h>
  
  #include <atalk/logger.h>
  
@@@ -67,23 -70,35 +69,35 @@@ int setnonblock(int fd, int cmd
  /*!
   * non-blocking drop-in replacement for read with timeout using select
   *
-  * @param socket   (r)  must be nonblocking !
-  * @param data     (rw) buffer for the read data
-  * @param lenght   (r)  how many bytes to read
-  * @param timeout  (r)  number of seconds to try reading
+  * @param socket          (r)  socket, if in blocking mode, pass "setnonblocking" arg as 1
+  * @param data            (rw) buffer for the read data
+  * @param lenght          (r)  how many bytes to read
+  * @param setnonblocking  (r)  when non-zero this func will enable and disable non blocking
+  *                             io mode for the socket
+  * @param timeout         (r)  number of seconds to try reading
   *
   * @returns number of bytes actually read or -1 on fatal error
   */
- ssize_t readt(int socket, void *data, const size_t length, int timeout)
+ ssize_t readt(int socket, void *data, const size_t length, int setnonblocking, int timeout)
  {
      size_t stored;
      ssize_t len;
-     struct timeval tv;
+     struct timeval now, end, tv;
      fd_set rfds;
      int ret;
  
      stored = 0;
  
+     if (setnonblocking) {
+         if (setnonblock(socket, 1) != 0)
+             return -1;
+     }
+     /* Calculate end time */
+     (void)gettimeofday(&now, NULL);
+     end = now;
+     end.tv_sec += timeout;
      while (stored < length) {
          len = read(socket, (char *) data + stored, length - stored);
          if (len == -1) {
              case EINTR:
                  continue;
              case EAGAIN:
-                 tv.tv_usec = 0;
-                 tv.tv_sec  = timeout;
                  FD_ZERO(&rfds);
                  FD_SET(socket, &rfds);
+                 tv.tv_usec = 0;
+                 tv.tv_sec  = timeout;
+                         
                  while ((ret = select(socket + 1, &rfds, NULL, NULL, &tv)) < 1) {
                      switch (ret) {
                      case 0:
-                         LOG(log_warning, logtype_cnid, "select timeout 1s");
-                         return stored;
+                         LOG(log_warning, logtype_afpd, "select timeout %d s", timeout);
+                         goto exit;
                      default: /* -1 */
-                         LOG(log_error, logtype_cnid, "select: %s", strerror(errno));
-                         return -1;
+                         if (errno == EINTR) {
+                             (void)gettimeofday(&now, NULL);
+                             if (now.tv_sec >= end.tv_sec && now.tv_usec >= end.tv_usec) {
+                                 LOG(log_warning, logtype_afpd, "select timeout %d s", timeout);
+                                 goto exit;
+                             }
+                             if (now.tv_usec > end.tv_usec) {
+                                 tv.tv_usec = 1000000 + end.tv_usec - now.tv_usec;
+                                 tv.tv_sec  = end.tv_sec - now.tv_sec - 1;
+                             } else {
+                                 tv.tv_usec = end.tv_usec - now.tv_usec;
+                                 tv.tv_sec  = end.tv_sec - now.tv_sec;
+                             }
+                             FD_ZERO(&rfds);
+                             FD_SET(socket, &rfds);
+                             continue;
+                         }
+                         LOG(log_error, logtype_afpd, "select: %s", strerror(errno));
+                         stored = -1;
+                         goto exit;
                      }
-                 }
+                 } /* while (select) */
                  continue;
-             }
-             LOG(log_error, logtype_cnid, "read: %s", strerror(errno));
-             return -1;
-         }
+             } /* switch (errno) */
+             LOG(log_error, logtype_afpd, "read: %s", strerror(errno));
+             stored = -1;
+             goto exit;
+         } /* (len == -1) */
          else if (len > 0)
              stored += len;
          else
              break;
+     } /* while (stored < length) */
+ exit:
+     if (setnonblocking) {
+         if (setnonblock(socket, 0) != 0)
+             return -1;
      }
      return stored;
  }