]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/desktop.c
Performance tuning: sendfilev, MSG_MORE and do not apply AFP read locks by default
[netatalk.git] / etc / afpd / desktop.c
index adf6bbb3d0023dcefac8634b3da5ddd75db9024e..873cc0b1848b7fb8bad88c8db565e7eff79429f6 100644 (file)
 #include <atalk/util.h>
 #include <atalk/logger.h>
 #include <atalk/globals.h>
+#include <atalk/netatalk_conf.h>
+#include <atalk/unix.h>
+#include <atalk/bstrlib.h>
+
 #include "volume.h"
 #include "directory.h"
 #include "fork.h"
 #include "desktop.h"
 #include "mangle.h"
 
+static void create_appledesktop_folder(const struct vol * vol)
+{
+    bstring olddtpath = NULL, dtpath = NULL;
+    struct stat st;
+    char *cmd_argv[4];
+
+    olddtpath = bfromcstr(vol->v_path);
+    bcatcstr(olddtpath, "/" APPLEDESKTOP);
+
+    dtpath = bfromcstr(vol->v_dbpath);
+    bcatcstr(dtpath, "/" APPLEDESKTOP);
+
+    if (lstat(bdata(dtpath), &st) != 0) {
+
+        become_root();
+
+        if (lstat(bdata(olddtpath), &st) == 0) {
+            cmd_argv[0] = "mv";
+            cmd_argv[1] = bdata(olddtpath);
+            cmd_argv[2] = bdata(dtpath);
+            cmd_argv[3] = NULL;
+            if (run_cmd("mv", cmd_argv) != 0) {
+                LOG(log_error, logtype_afpd, "moving .AppleDesktop from \"%s\" to \"%s\" failed",
+                    bdata(olddtpath), bdata(dtpath));
+                mkdir(bdata(dtpath), 0777);
+            }
+        } else {
+            mkdir(bdata(dtpath), 0777);
+        }
+
+        unbecome_root();
+    }
+
+    bdestroy(dtpath);
+    bdestroy(olddtpath);
+}
 
 int afp_opendt(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
@@ -48,6 +88,8 @@ int afp_opendt(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size
         return( AFPERR_PARAM );
     }
 
+    create_appledesktop_folder(vol);
+
     memcpy( rbuf, &vid, sizeof(vid));
     *rbuflen = sizeof(vid);
     return( AFP_OK );
@@ -204,42 +246,34 @@ int afp_addicon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
      */
 addicon_err:
     if ( cc < 0 ) {
-        if (obj->proto == AFPPROTO_DSI) {
-            dsi_writeinit(obj->handle, rbuf, buflen);
-            dsi_writeflush(obj->handle);
-        }
+        dsi_writeinit(obj->dsi, rbuf, buflen);
+        dsi_writeflush(obj->dsi);
         return cc;
     }
 
-    switch (obj->proto) {
-    case AFPPROTO_DSI:
-        {
-            DSI *dsi = obj->handle;
+    DSI *dsi = obj->dsi;
 
-            iovcnt = dsi_writeinit(dsi, rbuf, buflen);
+    iovcnt = dsi_writeinit(dsi, rbuf, buflen);
 
-            /* add headers at end of file */
-            if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
-                LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
-                dsi_writeflush(dsi);
-                return AFPERR_PARAM;
-            }
+    /* add headers at end of file */
+    if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
+        LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
+        dsi_writeflush(dsi);
+        return AFPERR_PARAM;
+    }
 
-            if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
-                LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
-                dsi_writeflush(dsi);
-                return AFPERR_PARAM;
-            }
+    if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
+        LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
+        dsi_writeflush(dsi);
+        return AFPERR_PARAM;
+    }
 
-            while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
-                if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
-                    LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
-                    dsi_writeflush(dsi);
-                    return AFPERR_PARAM;
-                }
-            }
+    while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
+        if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
+            LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
+            dsi_writeflush(dsi);
+            return AFPERR_PARAM;
         }
-        break;
     }
 
     close( si.sdt_fd );
@@ -441,8 +475,8 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
 #define min(a,b)       ((a)<(b)?(a):(b))
     rc = min( bsize, rsize );
 
-    if ((obj->proto == AFPPROTO_DSI) && (buflen < rc)) {
-        DSI *dsi = obj->handle;
+    if (buflen < rc) {
+        DSI *dsi = obj->dsi;
         struct stat st;
         off_t size;
 
@@ -451,29 +485,29 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
             return AFPERR_PARAM;
         }
 
+#ifndef WITH_SENDFILE
         if ((buflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0)
             goto geticon_exit;
+#endif
 
         *rbuflen = buflen;
         /* do to the streaming nature, we have to exit if we encounter
          * a problem. much confusion results otherwise. */
         while (*rbuflen > 0) {
 #ifdef WITH_SENDFILE
-            if (!obj->options.flags & OPTION_DEBUG) {
-                if (dsi_stream_read_file(dsi, 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;
-                    }
-                }
-                else {
-                    dsi_readdone(dsi);
-                    return AFP_OK;
+            if (dsi_stream_read_file(dsi, si.sdt_fd, offset, dsi->datasize, AFP_OK) < 0) {
+                switch (errno) {
+                case ENOSYS:
+                case EINVAL:  /* there's no guarantee that all fs support sendfile */
+                    break;
+                default:
+                    goto geticon_exit;
                 }
             }
+            else {
+                dsi_readdone(dsi);
+                return AFP_OK;
+            }
 #endif
             buflen = read(si.sdt_fd, rbuf, *rbuflen);
             if (buflen < 0)
@@ -513,8 +547,8 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext )
     char       *p;
     unsigned int i;
 
-    strcpy( path, vol->v_path );
-    strcat( path, "/.AppleDesktop/" );
+    strcpy( path, vol->v_dbpath );
+    strcat( path, "/" APPLEDESKTOP "/" );
     for ( p = path; *p != '\0'; p++ )
         ;
 
@@ -626,7 +660,7 @@ utompath_error:
 }
 
 /* ------------------------- */
-static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
+static int ad_addcomment(const AFPObj *obj, struct vol *vol, struct path *path, char *ibuf)
 {
     struct ofork        *of;
     char                *name, *upath;
@@ -638,7 +672,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
     clen = min( clen, 199 );
 
     upath = path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (check_access(obj, vol, upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
     
@@ -673,7 +707,7 @@ static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
 }
 
 /* ----------------------------- */
-int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
+int afp_addcomment(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
 {
     struct vol         *vol;
     struct dir         *dir;
@@ -704,7 +738,7 @@ int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
         ibuf++;
     }
 
-    return ad_addcomment(vol, path, ibuf);
+    return ad_addcomment(obj, vol, path, ibuf);
 }
 
 /* -------------------- */
@@ -782,7 +816,7 @@ int afp_getcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf,
 }
 
 /* ----------------------- */
-static int ad_rmvcomment(struct vol *vol, struct path *path)
+static int ad_rmvcomment(const AFPObj *obj, struct vol *vol, struct path *path)
 {
     struct adouble     ad, *adp;
     struct ofork        *of;
@@ -790,7 +824,7 @@ static int ad_rmvcomment(struct vol *vol, struct path *path)
     char               *upath;
 
     upath = path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (check_access(obj, vol, upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
@@ -848,5 +882,5 @@ int afp_rmvcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _
        return get_afp_errno(AFPERR_NOOBJ);
     }
     
-    return ad_rmvcomment(vol, s_path);
+    return ad_rmvcomment(obj, vol, s_path);
 }