]> arthur.barton.de Git - netatalk.git/commitdiff
sendfile for LARGE_FILE. use sys_ftruncate in ad_open too, temporary fix with
authordidg <didg>
Fri, 17 Oct 2003 00:01:10 +0000 (00:01 +0000)
committerdidg <didg>
Fri, 17 Oct 2003 00:01:10 +0000 (00:01 +0000)
dbd if socket is closed (sleep a little rather than DoS). use SIG_SETMASK
rather than SIG_UNBLOCK with dsi functions.

18 files changed:
configure.in
etc/afpd/desktop.c
etc/afpd/file.c
etc/afpd/fork.c
etc/afpd/volume.c
include/atalk/adouble.h
include/atalk/dsi.h
include/atalk/util.h
libatalk/adouble/ad_open.c
libatalk/adouble/ad_sendfile.c
libatalk/adouble/ad_write.c
libatalk/cnid/dbd/cnid_dbd.c
libatalk/cnid/dbd/cnid_dbd.h
libatalk/dsi/dsi_attn.c
libatalk/dsi/dsi_read.c
libatalk/dsi/dsi_stream.c
libatalk/dsi/dsi_tickle.c
libatalk/dsi/dsi_write.c

index 52c1165b05d6a12f76baaba57f5376bc6633ae34..dd09973cf2b158b799357f89b580d5e156247cdf 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.179.2.3.2.6 2003-09-26 23:46:21 bfernhomberg Exp $
+dnl $Id: configure.in,v 1.179.2.3.2.7 2003-10-17 00:01:10 didg Exp $
 dnl configure.in for netatalk
 
 AC_INIT(bin/adv1tov2/adv1tov2.c)
@@ -722,20 +722,42 @@ if test x"$this_os" = "xlinux"; then
         )
 
        if test x"$linux_sendfile" = "xyes"; then 
-           dnl --- added by Yoshinobu Ishizaki (2001.03.13) ---
-           dnl ----- check if version is newer than 2.2.x
-           changequote(<<,>>)
-           majorvers="`uname -r | sed 's/\([0-9]\)..*/\1/'`"
-           minorvers="`uname -r | sed 's/[0-9]\.\([0-9]\)\..*/\1/'`"
-           if [ $majorvers -ge 2 ]; then
-               if [ $minorvers -ge 2 ]; then
-                       changequote([,])
-                       AC_MSG_RESULT([ * found Linux 2.2.x or higher])
-                       AC_DEFINE(SENDFILE_FLAVOR_LINUX, 1, [Define if the sendfile() function uses Linux semantics])
-               else
-                       AC_MSG_RESULT([ * found Linux 2.0.x ]) 
-               fi
-            fi
+           AC_CACHE_CHECK([for linux sendfile support],netatalk_cv_HAVE_SENDFILE,[
+           AC_TRY_LINK([#include <sys/sendfile.h>],
+[\
+int tofd, fromfd;
+off_t offset;
+size_t total;
+ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
+],
+netatalk_cv_HAVE_SENDFILE=yes,netatalk_cv_HAVE_SENDFILE=no)])
+
+# Try and cope with broken Linux sendfile....
+           AC_CACHE_CHECK([for broken linux sendfile support],samba_cv_HAVE_BROKEN_LINUX_SENDFILE,[
+           AC_TRY_LINK([\
+#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
+#undef _FILE_OFFSET_BITS
+#endif
+#include <sys/sendfile.h>],
+[\
+int tofd, fromfd;
+off_t offset;
+size_t total;
+ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
+],
+netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=no)])
+
+           if test x"$netatalk_cv_HAVE_SENDFILE" = x"yes"; then
+               AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
+               AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
+               AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
+           elif test x"$netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then
+               AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
+               AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken])
+               AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used])
+           else
+               AC_MSG_RESULT(no);
+           fi
        fi
 
        dnl ----- Linux/alpha specific -----
index a052e965068f8f96ec6863e57fc8b216bebd5a1f..13b99645a8c3b87d4458bc9a9e5ba72a4ba6fd4b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.c,v 1.26.2.4.2.4 2003-09-28 13:58:55 didg Exp $
+ * $Id: desktop.c,v 1.26.2.4.2.5 2003-10-17 00:01:10 didg Exp $
  *
  * See COPYRIGHT.
  *
@@ -528,22 +528,20 @@ int               ibuflen, *rbuflen;
         /* do to the streaming nature, we have to exit if we encounter
          * a problem. much confusion results otherwise. */
         while (*rbuflen > 0) {
-#if defined(SENDFILE_FLAVOR_LINUX) || defined(SENDFILE_FLAVOR_BSD)
+#ifdef WITH_SENDFILE
             if (!obj->options.flags & OPTION_DEBUG) {
-#ifdef SENDFILE_FLAVOR_LINUX
-                if (sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0)
-                    goto geticon_exit;
-#endif /* SENDFILE_FLAVOR_LINUX */
-
-#ifdef SENDFILE_FLAVOR_BSD
-                if (sendfile(si.sdt_fd, dsi->socket, offset, rc, NULL, NULL, 0) < 0)
-                    goto geticon_exit;
-#endif /* SENDFILE_FLAVOR_BSD */
-
+                if (sys_sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0) {
+                    switch (errno) {
+                    case ENOSYS:
+                    case EINVAL:  /* there's no guarantee that all fs support sendfile */
+                        break;
+                    default:
+                        goto geticon_exit;
+                    }
+                }
                 goto geticon_done;
             }
-#endif /* SENDFILE_FLAVOR_LINUX || SENDFILE_FLAVOR_BSD */
-
+#endif
             buflen = read(si.sdt_fd, rbuf, *rbuflen);
             if (buflen < 0)
                 goto geticon_exit;
@@ -577,11 +575,11 @@ geticon_exit:
             return( AFPERR_PARAM );
         }
         *rbuflen = rc;
-        return AFP_OK;
     }
+    return AFP_OK;
 }
 
-
+/* ---------------------- */
 static char            hexdig[] = "0123456789abcdef";
 char *dtfile(const struct vol *vol, u_char creator[], char *ext )
 {
index 833da449de534420b115d8e06935c166da0eaf37..385a6725839cdf51dc032033aa1150695e5ca919 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.92.2.2.2.3 2003-09-28 13:58:57 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.4 2003-10-17 00:01:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -1262,30 +1262,39 @@ static int copy_fd(int dfd, int sfd)
     ssize_t cc;
     int     err = AFP_OK;
     char    filebuf[8192];
-
+    
 #ifdef SENDFILE_FLAVOR_LINUX
+    off_t   offset = 0;
+    size_t  size;
     struct stat         st;
+    #define BUF 128*1024*1024
 
     if (fstat(sfd, &st) == 0) {
-        if ((cc = sendfile(dfd, sfd, NULL, st.st_size)) < 0) {
-            switch (errno) {
-            case EINVAL:  /* there's no guarantee that all fs support sendfile */
-                break;
-            case EDQUOT:
-            case EFBIG:
-            case ENOSPC:
-                return AFPERR_DFULL;
-            case EROFS:
-                return AFPERR_VLOCK;
-            default:
-                return AFPERR_PARAM;
+        
+        while (1) {
+            if ( offset >= st.st_size) {
+               return AFP_OK;
+            }
+            size = (st.st_size -offset > BUF)?BUF:st.st_size -offset;
+            if ((cc = sys_sendfile(dfd, sfd, &offset, size)) < 0) {
+                switch (errno) {
+                case ENOSYS:
+                case EINVAL:  /* there's no guarantee that all fs support sendfile */
+                    goto no_sendfile;
+                case EDQUOT:
+                case EFBIG:
+                case ENOSPC:
+                    return AFPERR_DFULL;
+                case EROFS:
+                    return AFPERR_VLOCK;
+                default:
+                    return AFPERR_PARAM;
+                }
             }
-        }
-        else {
-           return AFP_OK;
         }
     }
-#endif /* SENDFILE_FLAVOR_LINUX */
+    no_sendfile:
+#endif 
 
     while (1) {
         if ((cc = read(sfd, filebuf, sizeof(filebuf))) < 0) {
index 392bf523fdd0999ea6ab0831dde900e86018d351..df06ae9e85427e3f938cf4f8f97f1cfa5eb83120 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.51.2.2.2.3 2003-09-28 13:58:57 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.4 2003-10-17 00:01:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
 #include "desktop.h"
 #include "volume.h"
 
+#ifdef DEBUG1
+#define Debug(a) ((a)->options.flags & OPTION_DEBUG)
+#else
+#define Debug(a) (0)
+#endif
+
 struct ofork           *writtenfork;
 extern int getmetadata(struct vol *vol,
                  u_int16_t bitmap,
@@ -951,8 +957,7 @@ int is64;
 
 #define min(a,b)       ((a)<(b)?(a):(b))
     *rbuflen = min( reqcount, *rbuflen );
-    err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen,
-                    xlate);
+    err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
     if (err < 0)
         goto afp_read_done;
 
@@ -963,8 +968,7 @@ int is64;
 
 #ifdef DEBUG1
         if (obj->options.flags & OPTION_DEBUG) {
-            printf( "(read) reply: %d/%d, %d\n", *rbuflen,
-                    (int) reqcount, dsi->clientID);
+            printf( "(read) reply: %d/%d, %d\n", *rbuflen,(int) reqcount, dsi->clientID);
             bprint(rbuf, *rbuflen);
         }
 #endif        
@@ -985,11 +989,10 @@ int is64;
 
         /* due to the nature of afp packets, we have to exit if we get
            an error. we can't do this with translation on. */
-#ifdef HAVE_SENDFILE_READ
-        if (!(xlate || (obj->options.flags & OPTION_DEBUG))) {
-            if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset,
-                            dsi->datasize) < 0) {
-                if (errno == EINVAL)
+#ifdef WITH_SENDFILE
+        if (!(xlate || Debug(obj) )) {
+            if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
+                if (errno == EINVAL || errno == ENOSYS)
                     goto afp_read_loop;
                 else {
                     LOG(log_error, logtype_afpd, "afp_read: ad_readfile: %s", strerror(errno));
@@ -1002,12 +1005,11 @@ int is64;
         }
 
 afp_read_loop:
-#endif /* HAVE_SENDFILE_READ */
+#endif 
 
         /* fill up our buffer. */
         while (*rbuflen > 0) {
-            cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,
-                           rbuflen, xlate);
+            cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,rbuflen, xlate);
             if (cc < 0)
                 goto afp_read_exit;
 
@@ -1347,8 +1349,7 @@ int                 is64;
 
             /* find out what we have already and write it out. */
             cc = dsi_writeinit(dsi, rbuf, *rbuflen);
-            if (!cc ||
-                    (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
+            if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
                 dsi_writeflush(dsi);
                 *rbuflen = 0;
                 ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
index b1ab92b98847ba5939fd43189f8247f393cd0ece..de0a1892e90ceca60075b05d71d9e25a1c1b0215 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.51.2.7.2.6 2003-09-30 12:24:49 didg Exp $
+ * $Id: volume.c,v 1.51.2.7.2.7 2003-10-17 00:01:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -351,9 +351,9 @@ static void volset(struct vol_option *options, struct vol_option *save,
         volname[vlen] = 0;
         return;
     }
-
+#if 0
     LOG(log_debug, logtype_afpd, "Parsing volset %s", val);
-
+#endif
     if (optionok(tmp, "allow:", val)) {
         setoption(options, save, VOLOPT_ALLOW, val);
 
index 9bf7144b1a6258127a58801571090c310ffd821b..e87e086f42eb47681ac312e2a2b9b9e4b691b0f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: adouble.h,v 1.21.6.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: adouble.h,v 1.21.6.2 2003-10-17 00:01:12 didg Exp $
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
 #include <sys/mman.h>
 #include <netatalk/endian.h>
 
-/* XXX: this is the wrong place to put this. 
- * NOTE: as of 2.2.1, linux can't do a sendfile from a socket. 
- * and it doesn't have 64 bits sendfile
- */
-#ifdef SENDFILE_FLAVOR_LINUX
-
-#if _FILE_OFFSET_BITS == 64 
-
-#undef SENDFILE_FLAVOR_LINUX
-
-#else /* _FILE_OFFSET_BITS != 64 */
-
-#define HAVE_SENDFILE_READ
-#define HAVE_SENDFILE_WRITE
-#include <asm/unistd.h>
-
-#ifdef __NR_sendfile
-#ifdef ATACC
-extern int sendfile __P((int , int , off_t *, size_t ));
-#else /* !ATACC */
-static __inline__ int sendfile(int fdout, int fdin, off_t *off, size_t count)
-{
-  return syscall(__NR_sendfile, fdout, fdin, off, count);
-}
-#endif /* ATACC */
-
-#else /* !__NR_sendfile */
-#include <sys/sendfile.h>
-#endif /* __NR_sendfile */
-#endif /* _FILE_OFFSET_BITS */
-#endif /* SENDFILE_FLAVOR_LINUX */
-
-#ifdef SENDFILE_FLAVOR_BSD
-#define HAVE_SENDFILE_READ
-#endif
-
 /* version info */
 #define AD_VERSION1    0x00010000
 #define AD_VERSION2    0x00020000
@@ -450,7 +414,7 @@ extern int ad_setid __P((struct adouble *, const struct stat *, const u_int32_t,
 #define ad_setid(a, b, c)
 #endif
 
-#ifdef HAVE_SENDFILE_READ
+#ifdef WITH_SENDFILE
 extern ssize_t ad_readfile __P((const struct adouble *, const int, 
                                const int, off_t, const size_t));
 #endif
index 8bb49345ae860859c2b5dc9663e7b995221d64f5..bf08122af9416b30afb5a2dddb6fb7dbd60153ce 100644 (file)
@@ -57,8 +57,11 @@ typedef struct DSI {
   dsi_proto protocol;
   struct dsi_block header;
   struct sockaddr_in server, client;
-  sigset_t sigblockset;
+  
+  sigset_t sigblockset, oldset;
+  int      sigblocked;
   struct itimerval timer, savetimer;
+  
   u_int32_t attn_quantum, datasize, server_quantum;
   u_int16_t serverID, clientID;
   u_int8_t *status, commands[DSI_CMDSIZ], data[DSI_DATASIZ];
@@ -142,7 +145,7 @@ extern void dsi_close __P((DSI *));
 extern void dsi_sleep __P((DSI *, const int ));
 
 /* low-level stream commands -- in dsi_stream.c */
-extern size_t dsi_stream_write __P((DSI *, void *, const size_t));
+extern size_t dsi_stream_write __P((DSI *, void *, const size_t, const int mode));
 extern size_t dsi_stream_read __P((DSI *, void *, const size_t));
 extern int dsi_stream_send __P((DSI *, void *, size_t));
 extern int dsi_stream_receive __P((DSI *, void *, const size_t, size_t *));
index 77f521e45ff33472a8dfb553e80cb6cf37b10a3c..2a8ec22fef1a1062d788cb194d6a47354957b3b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: util.h,v 1.7.10.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: util.h,v 1.7.10.2 2003-10-17 00:01:12 didg Exp $
  */
 
 #ifndef _ATALK_UTIL_H
 #endif /* HAVE_UNISTD_H */
 #include <netatalk/at.h>
 
+extern int     sys_ftruncate __P((int fd, off_t length));
+
+#ifdef WITH_SENDFILE
+extern ssize_t sys_sendfile __P((int __out_fd, int __in_fd, off_t *__offset,size_t __count));
+#endif
+
 extern const int _diacasemap[], _dialowermap[];
 
 extern char **getifacelist(void);
index b66fca0475349c143889a46570cbe2727bb7b9af..5b236551acc24ffc6b5aacb079302c03274772ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_open.c,v 1.30.6.1 2003-09-09 16:42:21 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.2 2003-10-17 00:01:12 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
@@ -49,6 +49,7 @@
 
 #include <netatalk/endian.h>
 #include <atalk/adouble.h>
+#include <atalk/util.h>
 
 #include "ad_private.h"
 
@@ -243,7 +244,7 @@ static int ad_v1tov2(struct adouble *ad, const char *path)
     goto bail_lock;
   
   if (fstat(fd, &st) ||
-      ftruncate(fd, st.st_size + SHIFTDATA) < 0) {
+      sys_ftruncate(fd, st.st_size + SHIFTDATA) < 0) {
     goto bail_open;
   }
   if (st.st_size > 0x7fffffff) {
@@ -324,7 +325,7 @@ static int ad_v1tov2(struct adouble *ad, const char *path)
   return 0;
   
 bail_truncate:
-  ftruncate(fd, st.st_size);
+  sys_ftruncate(fd, st.st_size);
 bail_open:
   close(fd);
 bail_lock:
index 21e4126f86eed247ff96bee45eddf9dfc9ad3d55..562e5a14c92cbdbef7a803bd9a6ccc9ba31ac1e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_sendfile.c,v 1.6 2003-02-17 01:51:07 srittau Exp $
+ * $Id: ad_sendfile.c,v 1.6.6.1 2003-10-17 00:01:13 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -7,13 +7,32 @@
  * NOTE: the following uses the fact that sendfile() only exists on
  * machines with SA_RESTART behaviour. this is all very machine specific. 
  *
- * 
+ * sendfile chainsaw from samba.
+ Unix SMB/Netbios implementation.
+ Version 2.2.x / 3.0.x
+ sendfile implementations.
+ Copyright (C) Jeremy Allison 2002.
+ 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.
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#ifdef WITH_SENDFILE
+
 #include <stdio.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #include <sys/socket.h>
 #include <sys/uio.h>
 
+#include <errno.h>  
 #include <atalk/adouble.h>
 
 #include <atalk/logger.h>
 
 #include "ad_private.h"
 
-#ifdef ATACC
+#if defined(LINUX_BROKEN_SENDFILE_API)
+
+extern int32_t sendfile (int fdout, int fdin, int32_t *offset, u_int32_t count);
 
-#if defined(HAVE_SENDFILE_READ)
-#ifdef __NR_sendfile
-int sendfile(int fdout, int fdin, off_t *off, size_t count)
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
-#if _FILE_OFFSET_BITS == 64 
-#error sendfile
-  return syscall(__NR_sendfile64, fdout, fdin, off, count);
+u_int32_t small_total = 0;
+int32_t small_offset;
+
+    /*
+     * Fix for broken Linux 2.4 systems with no working sendfile64().
+     * If the offset+count > 2 GB then pretend we don't have the
+     * system call sendfile at all. The upper layer catches this
+     * and uses a normal read. JRA.
+     */
+     if ((sizeof(off_t) >= 8) && (*offset + count > (off_t)0x7FFFFFFF)) {
+         errno = ENOSYS;
+         return -1;
+     }
+     small_total = (u_int32_t)count;
+     small_offset = (int32_t)*offset;
+     while (small_total) {
+         int32_t nwritten;
+         do {
+             nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
+         } while (nwritten == -1 && errno == EINTR);
+         if (nwritten == -1)
+             return -1;
+         if (nwritten == 0)
+             return -1; /* I think we're at EOF here... */
+         small_total -= nwritten;
+    }
+    *offset += count;
+    return count;
+}
+
+#elif defined(SENDFILE_FLAVOR_LINUX)
+#include <sys/sendfile.h>
+
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
+{
+size_t total=0;
+
+    total = count;
+    while (total) {
+        ssize_t nwritten;
+        do {
+            nwritten = sendfile(tofd, fromfd, offset, total);
+        } while (nwritten == -1 && errno == EINTR);
+        if (nwritten == -1)
+            return -1;
+        if (nwritten == 0)
+            return -1; /* I think we're at EOF here... */
+        total -= nwritten;
+    }
+    return count;
+}
+
+
+#elif defined(SENDFILE_FLAVOR_BSD )
+/* FIXME untested */
+#include <sys/sendfile.h>
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
+{
+size_t total=0;
+int    ret;
+
+    total = count;
+    while (total) {
+        ssize_t nwritten;
+        do {
+           ret = sendfile(fromfd, tofd, offset, count, NULL, &nwritten, 0);
+        while (ret == -1 && errno == EINTR);
+        if (ret == -1)
+            return -1;
+        total -= nwritten;
+        offset += nwritten;
+    }
+    return count;
+}
+
 #else
-  return syscall(__NR_sendfile, fdout, fdin, off, count);
-#endif
+
+ssize_t sys_sendfile(int out_fd, int in_fd, off_t *_offset, size_t count)
+{
+    /* No sendfile syscall. */
+    errno = ENOSYS;
+    return -1;
 }
 #endif
-#endif
-#endif
 
-#if defined(HAVE_SENDFILE_READ) || defined(HAVE_SENDFILE_WRITE)
+/* ------------------------------- */
 static __inline__ int ad_sendfile_init(const struct adouble *ad, 
                                       const int eid, off_t *off,
                                       const int end)
@@ -65,12 +161,11 @@ static __inline__ int ad_sendfile_init(const struct adouble *ad,
 
   return fd;
 }
-#endif
 
 
-/* read from adouble file and write to socket. sendfile doesn't change
+/* --------------------------------
+ * read from adouble file and write to socket. sendfile doesn't change
  * the file pointer position. */
-#ifdef HAVE_SENDFILE_READ
 ssize_t ad_readfile(const struct adouble *ad, const int eid, 
                    const int sock, off_t off, const size_t len)
 {
@@ -78,19 +173,11 @@ ssize_t ad_readfile(const struct adouble *ad, const int eid,
   int fd;
 
   fd = ad_sendfile_init(ad, eid, &off, 0);
-#ifdef __linux__
-  cc = sendfile(sock, fd, &off, len);
-#endif /* __linux__ */
-
-#ifdef BSD4_4
-  if (sendfile(fd, sock, off, len, NULL, &cc, 0) < 0)
-    return -1;
-#endif /* BSD4_4 */
-
+  cc = sys_sendfile(sock, fd, &off, len);
   return cc;
 }
-#endif /* HAVE_SENDFILE_READ */
 
+/* ------------------------ */
 #if 0
 #ifdef HAVE_SENDFILE_WRITE
 /* read from a socket and write to an adouble file */
@@ -103,7 +190,7 @@ ssize_t ad_writefile(struct adouble *ad, const int eid,
   int fd;
 
   fd = ad_sendfile_init(ad, eid, &off, end);
-  if ((cc = sendfile(fd, sock, &off, len)) < 0)
+  if ((cc = sys_sendfile(fd, sock, &off, len)) < 0)
     return -1;
 
   if ((eid != ADEID_DFORK) && (off > ad_getentrylen(ad, eid))) 
@@ -114,3 +201,4 @@ ssize_t ad_writefile(struct adouble *ad, const int eid,
 }
 #endif /* HAVE_SENDFILE_WRITE */
 #endif /* 0 */
+#endif
index 47347f72ca96e23e5b67b3ae9f1c01641652a720..c061846136980b443072fda664f3b38df199e7f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ad_write.c,v 1.7.6.2 2003-10-13 22:05:17 didg Exp $
+ * $Id: ad_write.c,v 1.7.6.3 2003-10-17 00:01:13 didg Exp $
  *
  * Copyright (c) 1990,1995 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -96,7 +96,7 @@ ssize_t ad_write( ad, eid, off, end, buf, buflen )
  * the caller set the locks
  * ftruncate is undefined when the file length is smaller than 'size'
  */
-static int sys_ftruncate(int fd, off_t length)
+int sys_ftruncate(int fd, off_t length)
 {
 
 #ifndef  HAVE_PWRITE
index 2761d899407112e767a23e1cfbbf8f0d17e6a032..5649db0a981981f9f8f9021697ce916a7908118f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_dbd.c,v 1.1.4.3 2003-09-22 07:21:34 bfernhomberg Exp $
+ * $Id: cnid_dbd.c,v 1.1.4.4 2003-10-17 00:01:13 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYRIGHT.
@@ -203,6 +203,13 @@ static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_db
         return 0;
  
  transmit_fail:
+{
+        struct timeval tv;
+            tv.tv_usec = 0;
+            tv.tv_sec  = 5;
+            select(0, NULL, NULL, NULL, &tv);
+}
+
         if (db->fd != -1) {
             close(db->fd);
         }
@@ -471,7 +478,7 @@ char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, u_int32_t
 }
 
 /* ---------------------- */
-int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, u_int32_t len)
+int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const int len)
 {
     CNID_private *db;
     struct cnid_dbd_rqst rqst;
index 0d10d7bb849e6618b1c00be7700896d28aaf6516..8cd042d0fa2577d816e81cd35bb6dc320533a3cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_dbd.h,v 1.1.4.1 2003-09-09 16:42:21 didg Exp $
+ * $Id: cnid_dbd.h,v 1.1.4.2 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYRIGHT.
@@ -24,7 +24,7 @@ extern cnid_t cnid_dbd_add __P((struct _cnid_db *, const struct stat *, const cn
                            const char *, const int, cnid_t));
 extern cnid_t cnid_dbd_get __P((struct _cnid_db *, const cnid_t, const char *, const int)); 
 extern char *cnid_dbd_resolve __P((struct _cnid_db *, cnid_t *, void *, u_int32_t )); 
-extern int cnid_dbd_getstamp __P((struct _cnid_db *, void *, u_int32_t )); 
+extern int cnid_dbd_getstamp __P((struct _cnid_db *, void *, const int )); 
 extern cnid_t cnid_dbd_lookup __P((struct _cnid_db *, const struct stat *, const cnid_t,
                               const char *, const int));
 extern int cnid_dbd_update __P((struct _cnid_db *, const cnid_t, const struct stat *,
index b22db8d652563b1091337f4522035f347449dfc4..97cbcaea634ca60f289de3b9cb09153f52103703 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_attn.c,v 1.5 2003-03-12 15:07:05 didg Exp $
+ * $Id: dsi_attn.c,v 1.5.6.1 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -54,7 +54,7 @@ int dsi_attention(DSI *dsi, AFPUserBytes flags)
 
   /* send an attention */
   sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
-  len = dsi_stream_write(dsi, block, DSI_BLOCKSIZ + len);
+  len = dsi_stream_write(dsi, block, DSI_BLOCKSIZ + len, 0);
   sigprocmask(SIG_SETMASK, &oldset, NULL);
 
   return len;
index 0f33c174b9f7dacd10cc9b90a00c4ed8ef89d414..d6e3c4297c3f44d5ab3e434ae5aa6cb9680d74db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_read.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: dsi_read.c,v 1.3.14.1 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -40,8 +40,10 @@ ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
   dsi->header.dsi_len = htonl(size);
   dsi->header.dsi_code = htonl(err);
 
-  sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
+  sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
+  dsi->sigblocked = 1;
   setitimer(ITIMER_REAL, &none, &dsi->savetimer);
+  
   if (dsi_stream_send(dsi, buf, buflen)) {
     dsi->datasize = size - buflen;
     return min(dsi->datasize, buflen);
@@ -53,13 +55,17 @@ ssize_t dsi_readinit(DSI *dsi, void *buf, const size_t buflen,
 void dsi_readdone(DSI *dsi)
 {
   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
-  sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+  sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+  dsi->sigblocked = 0;
 }
 
 /* send off the data */
 ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
 {
-  size_t len = dsi_stream_write(dsi, buf, buflen);
+  size_t len;
+  int delay = (dsi->datasize != buflen)?1:0;
+  
+  len  = dsi_stream_write(dsi, buf, buflen, delay);
 
   if (len == buflen) {
     dsi->datasize -= len;
index b177b579dde077b1ea17e87a95236cf049f203d0..d88cf4bed2f31dd16118a8672e3ff2fd5f23039f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_stream.c,v 1.11 2003-03-12 15:07:06 didg Exp $
+ * $Id: dsi_stream.c,v 1.11.6.1 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
 
 #include <stdio.h>
 #include <stdlib.h>
+
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif /* HAVE_UNISTD_H */
+#endif
+
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
+#include <sys/socket.h>
+
 #ifdef USE_WRITEV
 #include <sys/uio.h>
-#endif /* USE_WRITEV */
+#endif
+
 #include <atalk/logger.h>
 
 #include <atalk/dsi.h>
 
 #define min(a,b)  ((a) < (b) ? (a) : (b))
 
+#ifndef MSG_MORE
+#define MSG_MORE 0x8000
+#endif
 
 /* write raw data. return actual bytes read. checks against EINTR
  * aren't necessary if all of the signals have SA_RESTART
  * specified. */
-size_t dsi_stream_write(DSI *dsi, void *data, const size_t length)
+size_t dsi_stream_write(DSI *dsi, void *data, const size_t length, int mode)
 {
   size_t written;
   ssize_t len;
+  unsigned int flags = (mode)?MSG_MORE:0;
 
   written = 0;
   while (written < length) {
-    if ((-1 == (len = write(dsi->socket, (u_int8_t *) data + written,
-                     length - written)) && errno == EINTR) ||
+    if ((-1 == (len = send(dsi->socket, (u_int8_t *) data + written,
+                     length - written, flags)) && errno == EINTR) ||
        !len)
       continue;
 
@@ -63,8 +72,10 @@ size_t dsi_stream_write(DSI *dsi, void *data, const size_t length)
   return written;
 }
 
-/* read raw data. return actual bytes read. this will wait until 
- * it gets length bytes */
+/* ---------------------------------------
+ * read raw data. return actual bytes read. this will wait until 
+ * it gets length bytes 
+ */
 size_t dsi_stream_read(DSI *dsi, void *data, const size_t length)
 {
   size_t stored;
@@ -87,17 +98,34 @@ size_t dsi_stream_read(DSI *dsi, void *data, const size_t length)
   return stored;
 }
 
+/* ---------------------------------------
+*/
 void dsi_sleep(DSI *dsi, const int state)
 {
     dsi->asleep = state;
 }
 
-/* write data. 0 on failure. this assumes that dsi_len will never
- * cause an overflow in the data buffer. */
+/* ---------------------------------------
+*/
+static void block_sig(DSI *dsi)
+{
+  if (!dsi->sigblocked) sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
+}
+
+/* ---------------------------------------
+*/
+static void unblock_sig(DSI *dsi)
+{
+  if (!dsi->sigblocked) sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+}
+
+/* ---------------------------------------
+ * write data. 0 on failure. this assumes that dsi_len will never
+ * cause an overflow in the data buffer. 
+ */
 int dsi_stream_send(DSI *dsi, void *buf, size_t length)
 {
   char block[DSI_BLOCKSIZ];
-  sigset_t oldset;
 #ifdef USE_WRITEV
   struct iovec iov[2];
   size_t towrite;
@@ -114,11 +142,11 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
         sizeof(dsi->header.dsi_reserved));
 
   /* block signals */
-  sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
+  block_sig(dsi);
 
   if (!length) { /* just write the header */
-    length = (dsi_stream_write(dsi, block, sizeof(block)) == sizeof(block));
-    sigprocmask(SIG_SETMASK, &oldset, NULL);
+    length = (dsi_stream_write(dsi, block, sizeof(block), 0) == sizeof(block));
+    unblock_sig(dsi);
     return length; /* really 0 on failure, 1 on success */
   }
   
@@ -139,7 +167,7 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
       break;
     else if (len < 0) { /* error */
       LOG(log_error, logtype_default, "dsi_stream_send: %s", strerror(errno));
-      sigprocmask(SIG_SETMASK, &oldset, NULL);
+      unblock_sig(dsi);
       return 0;
     }
     
@@ -159,19 +187,20 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length)
   
 #else /* USE_WRITEV */
   /* write the header then data */
-  if ((dsi_stream_write(dsi, block, sizeof(block)) != sizeof(block)) ||
-      (dsi_stream_write(dsi, buf, length) != length)) {
-    sigprocmask(SIG_SETMASK, &oldset, NULL);
-    return 0;
+  if ((dsi_stream_write(dsi, block, sizeof(block), 1) != sizeof(block)) ||
+            (dsi_stream_write(dsi, buf, length, 0) != length)) {
+      unblock_sig(dsi);
+      return 0;
   }
 #endif /* USE_WRITEV */
 
-  sigprocmask(SIG_SETMASK, &oldset, NULL);
+  unblock_sig(dsi);
   return 1;
 }
 
 
-/* read data. function on success. 0 on failure. data length gets
+/* ---------------------------------------
+ * read data. function on success. 0 on failure. data length gets
  * stored in length variable. this should really use size_t's, but
  * that would require changes elsewhere. */
 int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
index 6f1e095d533ad1707f083e41e0617f40af08375e..96d4ccbf32464433d9780301b6d79d7ebbe85b5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_tickle.c,v 1.5 2003-03-12 15:07:07 didg Exp $
+ * $Id: dsi_tickle.c,v 1.5.6.1 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -39,7 +39,7 @@ int dsi_tickle(DSI *dsi)
   /* code = len = reserved = 0 */
 
   sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
-  ret = dsi_stream_write(dsi, block, DSI_BLOCKSIZ) == DSI_BLOCKSIZ;
+  ret = dsi_stream_write(dsi, block, DSI_BLOCKSIZ, 0) == DSI_BLOCKSIZ;
   sigprocmask(SIG_SETMASK, &oldset, NULL);
   return ret;
 }
index 8ce85c2ca547f4cff7977681b4e5e6d549f06a96..e4ee24dfd2f398876a8e5450fbc7c0e8096cee1d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: dsi_write.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: dsi_write.c,v 1.3.14.1 2003-10-17 00:01:14 didg Exp $
  *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -57,7 +57,7 @@ size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen)
   /* deal with signals. i'm doing it this way to ensure that we don't
    * get confused if a writeflush on zero remaining data is, for some
    * reason, needed. */
-  sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
+  sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
   setitimer(ITIMER_REAL, &none, &dsi->savetimer);
   return len;
 }
@@ -76,7 +76,7 @@ size_t dsi_write(DSI *dsi, void *buf, const size_t buflen)
   }
 
   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
-  sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+  sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
   return 0;
 }
 
@@ -95,5 +95,5 @@ void dsi_writeflush(DSI *dsi)
   }
 
   setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
-  sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+  sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
 }