]> arthur.barton.de Git - netatalk.git/commitdiff
Merge remote-tracking branch 'origin/develop' into spotlight
authorRalph Boehme <sloowfranklin@gmail.com>
Tue, 8 Jan 2013 09:54:11 +0000 (10:54 +0100)
committerRalph Boehme <sloowfranklin@gmail.com>
Tue, 8 Jan 2013 09:54:11 +0000 (10:54 +0100)
Conflicts:
etc/netatalk/netatalk.c

12 files changed:
1  2 
bin/ad/ad_cp.c
bin/ad/ad_mv.c
configure.ac
etc/afpd/afp_dsi.c
etc/afpd/file.c
etc/afpd/main.c
etc/netatalk/netatalk.c
etc/uams/uams_dhx2_pam.c
include/atalk/util.h
libatalk/unicode/util_unistr.c
libatalk/util/netatalk_conf.c
macros/netatalk.m4

diff --combined bin/ad/ad_cp.c
index 61b94b5e0f275d849211b076b85a9c5fb95cbfe0,239936dc06940cb788a62fd198e60f6c0051878b..5cefe9648a30484cb007d99fd834eabd8bacd4bc
@@@ -95,36 -95,14 +95,14 @@@ static volatile sig_atomic_t alarmed
  static int badcp, rval;
  static int ftw_options = FTW_MOUNT | FTW_PHYS | FTW_ACTIONRETVAL;
  
- static char           *netatalk_dirs[] = {
-     ".AppleDouble",
-     ".AppleDB",
-     ".AppleDesktop",
-     NULL
- };
  /* Forward declarations */
  static int copy(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf);
  static int ftw_copy_file(const struct FTW *, const char *, const struct stat *, int);
  static int ftw_copy_link(const struct FTW *, const char *, const struct stat *, int);
  static int setfile(const struct stat *, int);
- static int preserve_dir_acls(const struct stat *, char *, char *);
// static int preserve_dir_acls(const struct stat *, char *, char *);
  static int preserve_fd_acls(int, int);
  
- /*
-   Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
-   Returns pointer to name or NULL.
- */
- static const char *check_netatalk_dirs(const char *name)
- {
-     int c;
-     for (c=0; netatalk_dirs[c]; c++) {
-         if ((strcmp(name, netatalk_dirs[c])) == 0)
-             return netatalk_dirs[c];
-     }
-     return NULL;
- }
  static void upfunc(void)
  {
      did = pdid;
@@@ -531,7 -509,7 +509,7 @@@ static int copy(const char *path
  
              /* Get CNID of Parent and add new childir to CNID database */
              ppdid = pdid;
 -            if ((did = cnid_for_path(&dvolume, to.p_path, &pdid)) == CNID_INVALID) {
 +            if ((did = cnid_for_path(dvolume.vol->v_cdb, dvolume.vol->v_path, to.p_path, &pdid)) == CNID_INVALID) {
                  SLOG("Error resolving CNID for %s", to.p_path);
                  badcp = rval = 1;
                  return -1;
              /* Get CNID of Parent and add new childir to CNID database */
              pdid = did;
              cnid_t cnid;
 -            if ((cnid = cnid_for_path(&dvolume, to.p_path, &did)) == CNID_INVALID) {
 +            if ((cnid = cnid_for_path(dvolume.vol->v_cdb, dvolume.vol->v_path, to.p_path, &did)) == CNID_INVALID) {
                  SLOG("Error resolving CNID for %s", to.p_path);
                  badcp = rval = 1;
                  return -1;
@@@ -953,9 -931,9 +931,9 @@@ static int preserve_fd_acls(int source_
      return (0);
  }
  
+ #if 0
  static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest_dir)
  {
- #if 0
      acl_t (*aclgetf)(const char *, acl_type_t);
      int (*aclsetf)(const char *, acl_type_t, acl_t);
      struct acl *aclp;
          return (1);
      }
      acl_free(acl);
- #endif
      return (0);
  }
+ #endif
diff --combined bin/ad/ad_mv.c
index e48cae99976614237413bc5cf3208ad3ee9e5db0,72698f73e9ad363e2ee5495d0596c77d19144fc2..3fdf1ea97ed052418913759c26b19168ad899be2
@@@ -50,31 -50,9 +50,9 @@@ static int fflg, iflg, nflg, vflg
  static afpvol_t svolume, dvolume;
  static cnid_t did, pdid;
  static volatile sig_atomic_t alarmed;
- static char           *netatalk_dirs[] = {
-     ".AppleDouble",
-     ".AppleDB",
-     ".AppleDesktop",
-     NULL
- };
  
  static int copy(const char *, const char *);
  static int do_move(const char *, const char *);
- static void preserve_fd_acls(int source_fd, int dest_fd, const char *source_path,
-                              const char *dest_path);
- /*
-   Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop"
-   Returns pointer to name or NULL.
- */
- static const char *check_netatalk_dirs(const char *name)
- {
-     int c;
-     for (c=0; netatalk_dirs[c]; c++) {
-         if ((strcmp(name, netatalk_dirs[c])) == 0)
-             return netatalk_dirs[c];
-     }
-     return NULL;
- }
  
  /*
    SIGNAL handling:
@@@ -242,7 -220,6 +220,6 @@@ int ad_mv(int argc, char *argv[], AFPOb
          }
      }
  
- exit:
      closevol(&dvolume);
      return rval;
  }
@@@ -301,7 -278,7 +278,7 @@@ static int do_move(const char *from, co
      
      cnid_t cnid = 0;
      if (!mustcopy) {
 -        if ((cnid = cnid_for_path(&svolume, from, &did)) == CNID_INVALID) {
 +        if ((cnid = cnid_for_path(svolume.vol->v_cdb, svolume.vol->v_path, from, &did)) == CNID_INVALID) {
              SLOG("Couldn't resolve CNID for %s", from);
              return -1;
          }
@@@ -465,12 -442,3 +442,3 @@@ static int copy(const char *from, cons
      }
      return 0;
  }
- static void
- preserve_fd_acls(int source_fd,
-                  int dest_fd,
-                  const char *source_path,
-                  const char *dest_path)
- {
-     ;
- }
diff --combined configure.ac
index 5c4a92c29d9294c313528fee7a98b93f2f1a0054,bfb578cae8108a7aa947a18cd395f2efad5384e1..b148e9d02dab58991f7ddee6e4c8aa7f7a56d525
@@@ -25,8 -25,6 +25,8 @@@ AC_PROG_P
  AM_PROG_CC_C_O
  AC_C_BIGENDIAN
  AC_C_INLINE
 +AC_PROG_LEX
 +AC_PROG_YACC
  
  dnl Check if we can use attribute unused (gcc only) from ethereal
  AC_MSG_CHECKING(to see if we can add '__attribute__((unused))' to CFLAGS)
@@@ -76,7 -74,7 +76,7 @@@ AC_CHECK_MEMBERS(struct tm.tm_gmtoff,,
  
  dnl these tests have been comfirmed to be needed in 2011
  AC_CHECK_FUNCS(backtrace_symbols dirfd getusershell pread pwrite pselect)
- AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen)
+ AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen mempcpy)
  AC_CHECK_FUNCS(mmap utime getpagesize) dnl needed by tbd
  
  dnl search for necessary libraries
@@@ -182,9 -180,6 +182,9 @@@ AC_NETATALK_SENDFIL
  dnl Check whether bundled libevent shall not be used
  AC_NETATALK_LIBEVENT
  
 +dnl Check for Tracker
 +AC_NETATALK_SPOTLIGHT
 +
  dnl FHS stuff has to be done last because it overrides other defaults
  AC_NETATALK_FHS
  
@@@ -260,7 -255,6 +260,7 @@@ AC_OUTPUT([Makefil
        libatalk/compat/Makefile
        libatalk/dsi/Makefile
        libatalk/iniparser/Makefile
 +      libatalk/talloc/Makefile
        libatalk/tdb/Makefile
        libatalk/unicode/Makefile
        libatalk/unicode/charsets/Makefile
diff --combined etc/afpd/afp_dsi.c
index be0b4b72c703d95be1b7e37ccf8ed11c94272b2b,8e1f90d290a08809451c121fc8cc206bfe0dcf8f..c59c6106fbf20ed968a46fee1abbce2b77cc9f17
@@@ -44,7 -44,6 +44,7 @@@
  #include "auth.h"
  #include "fork.h"
  #include "dircache.h"
 +#include "spotlight.h"
  
  #ifndef SOL_TCP
  #define SOL_TCP IPPROTO_TCP
@@@ -144,8 -143,6 +144,6 @@@ static void afp_dsi_die(int sig
  /* SIGQUIT handler */
  static void ipc_reconnect_handler(int sig _U_)
  {
-     DSI *dsi = (DSI *)AFPobj->dsi;
      if (reconnect_ipc(AFPobj) != 0) {
          LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect");
          afp_dsi_close(AFPobj);
@@@ -493,10 -490,6 +491,10 @@@ void afp_over_dsi(AFPObj *obj
      int flag = 1;
      setsockopt(dsi->socket, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
  
 +    /* Initialize Spotlight */
 +    if (obj->options.flags & OPTION_SPOTLIGHT)
 +        sl_mod_load(_PATH_AFPDUAMPATH "mod_spotlight.so");
 +
      /* get stuck here until the end */
      while (1) {
          if (sigsetjmp(recon_jmp, 1) != 0)
                      LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
  
                      err = (*afp_switch[function])(obj,
-                                                   dsi->commands, dsi->cmdlen,
+                                                   (char *)dsi->commands, dsi->cmdlen,
                                                    (char *)&dsi->data, &dsi->datalen);
  
                      LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
                  LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
  
                  err = (*afp_switch[function])(obj,
-                                               dsi->commands, dsi->cmdlen,
+                                               (char *)dsi->commands, dsi->cmdlen,
                                                (char *)&dsi->data, &dsi->datalen);
  
                  LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
diff --combined etc/afpd/file.c
index 0ff57995f96b861a2f19dc71239b08b696efd49d,f62e05eeb7f52bd6cc5b10e787559aedf8e152e1..265d6356c248be73bdff5a8261fae67d5fe84b6a
@@@ -34,7 -34,6 +34,7 @@@
  #include "file.h"
  #include "filedir.h"
  #include "unix.h"
 +#include "spotlight.h"
  
  /* the format for the finderinfo fields (from IM: Toolbox Essentials):
   * field         bytes        subfield    bytes
@@@ -101,7 -100,7 +101,7 @@@ void *get_finderinfo(const struct vol *
          }
      }
  
-     if (islink){
+     if (islink && !vol_syml_opt(vol)) {
          uint16_t linkflag;
          memcpy(&linkflag, (char *)data + FINDERINFO_FRFLAGOFF, 2);
          linkflag |= htons(FINDERINFO_ISALIAS);
@@@ -605,7 -604,7 +605,7 @@@ int getfilparams(const AFPObj *obj, str
      struct adouble    ad, *adp;
      int                 opened = 0;
      int rc;    
-     int flags;
+     int flags; /* uninitialized ok */
  
      LOG(log_debug, logtype_afpd, "getfilparams(\"%s\")", path->u_name);
  
          }
      }
      rc = getmetadata(obj, vol, bitmap, path, dir, buf, buflen, adp);
-     ad_close(adp, ADFLAGS_HF | flags);
+     if (opened)
+         ad_close(adp, ADFLAGS_HF | flags);
  
      return( rc );
  }
@@@ -686,7 -687,7 +688,7 @@@ int afp_createfile(AFPObj *obj, char *i
      ad_init(&ad, vol);
      
      /* if upath is deleted we already in trouble anyway */
-     if ((of = of_findname(s_path))) {
+     if ((of = of_findname(vol, s_path))) {
          if (creatf)
              return AFPERR_BUSY;
          else
@@@ -749,10 -750,9 +751,9 @@@ createfile_iderr
      ad_flush(&ad);
      ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF );
      fce_register(FCE_FILE_CREATE, fullpathname(upath), NULL, fce_file);
 +    sl_index_file(path);
  
- createfile_done:
      curdir->d_offcnt++;
 -
      setvoltime(obj, vol );
  
      return (retvalue);
@@@ -840,6 -840,9 +841,9 @@@ int setfilparams(const AFPObj *obj, str
      uint32_t           cdate,bdate;
      u_char              finder_buf[32];
      int symlinked = S_ISLNK(path->st.st_mode);
+     int fp;
+     ssize_t len;
+     char symbuf[MAXPATHLEN+1];
  
  #ifdef DEBUG
      LOG(log_debug9, logtype_afpd, "begin setfilparams:");
              break;
          case FILPBIT_FINFO :
              change_mdate = 1;
-             memcpy(finder_buf, buf, 32 );
-             if (memcmp(buf, "slnkrhap", 8) == 0 && !S_ISLNK(path->st.st_mode)) {
-                 int fp;
-                 ssize_t len;
-                 int erc=1;
-                 char buf[PATH_MAX+1];
-                 if ((fp = open(path->u_name, O_RDONLY)) >= 0) {
-                     if ((len = read(fp, buf, PATH_MAX+1))) {
-                         if (unlink(path->u_name) == 0) {
-                             buf[len] = 0;
-                             erc = symlink(buf, path->u_name);
-                             if (!erc)
-                                 of_stat(path);
-                         }
-                     }
-                     close(fp);
+             if (memcmp(buf,"slnkrhap",8) == 0
+                 && !(S_ISLNK(path->st.st_mode))
+                 && !(vol->v_flags & AFPVOL_FOLLOWSYM)) {
+                 /* request to turn this into a symlink */
+                 if ((fp = open(path->u_name, O_RDONLY)) == -1) {
+                     err = AFPERR_MISC;
+                     goto setfilparam_done;
+                 }
+                 len = read(fp, symbuf, MAXPATHLEN);
+                 close(fp);
+                 if (!(len > 0)) {
+                     err = AFPERR_MISC;
+                     goto setfilparam_done;
+                 }
+                 if (unlink(path->u_name) != 0) {
+                     err = AFPERR_MISC;
+                     goto setfilparam_done;
                  }
-                 if (erc != 0) {
-                     err=AFPERR_BITMAP;
+                 symbuf[len] = 0;
+                 if (symlink(symbuf, path->u_name) != 0) {
+                     err = AFPERR_MISC;
                      goto setfilparam_done;
                  }
+                 of_stat(vol, path);
                  symlinked = 1;
              }
+             memcpy(finder_buf, buf, 32 );
              buf += 32;
              break;
          case FILPBIT_UNIXPR :
@@@ -1696,7 -1703,7 +1704,7 @@@ static int reenumerate_loop(struct dire
      cnid_t        did  = param->did;
      cnid_t      aint;
      
-     if ( lstat(de->d_name, &path.st) < 0 )
+     if (ostat(de->d_name, &path.st, vol_syml_opt(vol)) < 0)
          return 0;
      
      /* update or add to cnid */
@@@ -1721,7 -1728,7 +1729,7 @@@ reenumerate_id(struct vol *vol, char *n
      }
      
      /* FIXME use of_statdir ? */
-     if (lstat(name, &st)) {
+     if (ostat(name, &st, vol_syml_opt(vol))) {
        return -1;
      }
  
@@@ -1800,7 -1807,7 +1808,7 @@@ retry
  
      memset(&path, 0, sizeof(path));
      path.u_name = upath;
-     if ( of_stat(&path) < 0 ) {
+     if (of_stat(vol, &path) < 0 ) {
  #ifdef ESTALE
          /* with nfs and our working directory is deleted */
        if (errno == ESTALE) {
@@@ -1895,7 -1902,7 +1903,7 @@@ int afp_deleteid(AFPObj *obj _U_, char 
      }
  
      err = AFP_OK;
-     if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) {
+     if ((movecwd(vol, dir) < 0) || (ostat(upath, &st, vol_syml_opt(vol)) < 0)) {
          switch (errno) {
          case EACCES:
          case EPERM:
@@@ -1958,7 -1965,7 +1966,7 @@@ static struct adouble *find_adouble(con
          return NULL;
      }
      
-     if ((*of = of_findname(path))) {
+     if ((*of = of_findname(vol, path))) {
          /* reuse struct adouble so it won't break locks */
          adp = (*of)->of_ad;
      }
@@@ -2103,11 -2110,13 +2111,13 @@@ int afp_exchangefiles(AFPObj *obj, cha
       * NOTE: the temp file will be in the dest file's directory. it
       * will also be inaccessible from AFP. */
      memcpy(temp, APPLETEMP, sizeof(APPLETEMP));
-     if (!mktemp(temp)) {
+     int fd;
+     if ((fd = mkstemp(temp)) == -1) {
          err = AFPERR_MISC;
          goto err_exchangefile;
      }
-     
+     close(fd);
      if (crossdev) {
          /* FIXME we need to close fork for copy, both s_of and d_of are null */
         ad_close(adsp, ADFLAGS_HF);
      if (did)
          cnid_delete(vol->v_cdb, did);
  
-     if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || 
+     if ((did && ( (crossdev && ostat(upath, &srcst, vol_syml_opt(vol)) < 0) || 
                  cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0))
         ||
-        (sid && ( (crossdev && lstat(p, &destst) < 0) ||
+         (sid && ( (crossdev && ostat(p, &destst, vol_syml_opt(vol)) < 0) ||
                  cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0))
      ) {
          switch (errno) {
diff --combined etc/afpd/main.c
index 411b1a7d772e7ee0ac10595d54a75caaa01d8ef9,0e0a858e84ce51b9b6bad2ee2f4118e10e837232..28b74e478c2c45d73079b489b005b90536b0bcb8
@@@ -38,7 -38,6 +38,7 @@@
  #include "fork.h"
  #include "uam_auth.h"
  #include "afp_zeroconf.h"
 +#include "spotlight.h"
  
  #define AFP_LISTENERS 32
  #define FDSET_SAFETY  5
@@@ -211,8 -210,6 +211,6 @@@ static int setlimits(void
  
  int main(int ac, char **av)
  {
-     fd_set              rfds;
-     void                *ipc;
      struct sigaction  sv;
      sigset_t            sigs;
      int                 ret;
  
      /* Initialize */
      cnid_init();
 -    
 +
      /* watch atp, dsi sockets and ipc parent/child file descriptor. */
  
      if (obj.options.flags & OPTION_KEEPSESSIONS) {
                  switch (polldata[i].fdtype) {
  
                  case LISTEN_FD:
-                     if (child = dsi_start(&obj, (DSI *)polldata[i].data, server_children)) {
+                     if ((child = dsi_start(&obj, (DSI *)polldata[i].data, server_children))) {
                          /* Add IPC fd to select fd set */
                          fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY,
                                       &fdset,
diff --combined etc/netatalk/netatalk.c
index e2235a85ba649a5449ac9b648b0a94dfdf7c35b9,9ac72c5ad5d4cc8ebc5530f3f090d1305fd24c11..03bab4909628f75a6ee2f87a0080d2e60f30072f
@@@ -1,8 -1,16 +1,16 @@@
- /*
-  * Copyright (c) 1990,1993 Regents of The University of Michigan.
-  * All Rights Reserved.  See COPYRIGHT.
-  */
+ /* 
+    Copyright (c) 2012 Frank Lahm <franklahm@gmail.com>
+    
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+  
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ */
  #ifdef HAVE_CONFIG_H
  #include "config.h"
  #endif /* HAVE_CONFIG_H */
@@@ -32,8 -40,6 +40,8 @@@
  #include <atalk/errchk.h>
  #include <atalk/globals.h>
  #include <atalk/netatalk_conf.h>
 +#include <atalk/bstrlib.h>
 +#include <atalk/bstradd.h>
  
  #include <event2/event.h>
  
@@@ -46,50 -52,11 +54,49 @@@ static void kill_childs(int sig, ...)
  
  /* static variables */
  static AFPObj obj;
- static sig_atomic_t got_chldsig;
 -static pid_t afpd_pid = -1,  cnid_metad_pid = -1;
 -static uint afpd_restarts, cnid_metad_restarts;
 +static pid_t afpd_pid = -1,  cnid_metad_pid = -1, dbus_pid = -1;
 +static uint afpd_restarts, cnid_metad_restarts, dbus_restarts;
  static struct event_base *base;
  struct event *sigterm_ev, *sigquit_ev, *sigchld_ev, *timer_ev;
  static int in_shutdown;
 +static const char *dbus_path;
 +
 +/******************************************************************
 + * Misc stuff
 + ******************************************************************/
 +
 +/* Set Tracker Miners to index all our volumes */
 +static int set_sl_volumes(void)
 +{
 +    EC_INIT;
 +    const struct vol *volumes, *vol;
 +    struct bstrList *vollist = bstrListCreate();
 +    bstring sep = bfromcstr(", ");
 +    bstring volnamelist = NULL, cmd = NULL;
 +
 +    EC_NULL_LOG( volumes = getvolumes() );
 +
 +    for (vol = volumes; vol; vol = vol->v_next) {
 +        bstring volnamequot = bformat("'%s'", vol->v_path);
 +        bstrListPush(vollist, volnamequot);
 +    }
 +
 +    volnamelist = bjoin(vollist, sep);
 +    cmd = bformat("gsettings set org.freedesktop.Tracker.Miner.Files index-recursive-directories \"[%s]\"", bdata(volnamelist));
 +    LOG(log_debug, logtype_sl, "set_sl_volumes: %s", bdata(cmd));
 +    system(bdata(cmd));
 +
 +EC_CLEANUP:
 +    if (cmd)
 +        bdestroy(cmd);
 +    if (sep)
 +        bdestroy(sep);
 +    if (vollist)
 +        bstrListDestroy(vollist);
 +    if (volnamelist)
 +        bdestroy(volnamelist);
 +    EC_EXIT;
 +}
  
  /******************************************************************
   * libevent helper functions
@@@ -146,16 -113,14 +153,16 @@@ static void sigterm_cb(evutil_socket_t 
      event_del(sigquit_ev);
      event_del(timer_ev);
  
 -    kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, NULL);
 +    system("tracker-control -t");
 +    kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, &dbus_pid, NULL);
  }
  
  /* SIGQUIT callback */
  static void sigquit_cb(evutil_socket_t fd, short what, void *arg)
  {
      LOG(log_note, logtype_afpd, "Exiting on SIGQUIT");
 -    kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL);
 +    system("tracker-control -t");
 +    kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, &dbus_pid, NULL);
  }
  
  /* SIGQUIT callback */
@@@ -168,41 -133,39 +175,39 @@@ static void sighup_cb(evutil_socket_t f
  /* SIGCHLD callback */
  static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
  {
-     int status, i;
+     int status;
      pid_t pid;
  
 -    LOG(log_debug, logtype_afpd, "Got SIGCHLD event");
 -  
      while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
          if (WIFEXITED(status)) {
              if (WEXITSTATUS(status))
 -                LOG(log_info, logtype_afpd, "child[%d]: exited %d", pid, WEXITSTATUS(status));
 +                LOG(log_info, logtype_default, "child[%d]: exited %d", pid, WEXITSTATUS(status));
              else
 -                LOG(log_info, logtype_afpd, "child[%d]: done", pid);
 +                LOG(log_info, logtype_default, "child[%d]: done", pid);
          } else {
              if (WIFSIGNALED(status))
 -                LOG(log_info, logtype_afpd, "child[%d]: killed by signal %d", pid, WTERMSIG(status));
 +                LOG(log_info, logtype_default, "child[%d]: killed by signal %d", pid, WTERMSIG(status));
              else
 -                LOG(log_info, logtype_afpd, "child[%d]: died", pid);
 +                LOG(log_info, logtype_default, "child[%d]: died", pid);
          }
  
          if (pid == afpd_pid)
              afpd_pid = -1;
          else if (pid == cnid_metad_pid)
              cnid_metad_pid = -1;
 +        else if (pid == dbus_pid)
 +            dbus_pid = -1;
          else
              LOG(log_error, logtype_afpd, "Bad pid: %d", pid);
      }
  
 -    if (in_shutdown && afpd_pid == -1 && cnid_metad_pid == -1)
 +    if (in_shutdown && afpd_pid == -1 && cnid_metad_pid == -1 && dbus_pid == -1)
          event_base_loopbreak(base);
  }
  
  /* timer callback */
  static void timer_cb(evutil_socket_t fd, short what, void *arg)
  {
-     static int i = 0;
      if (in_shutdown)
          return;
  
          afpd_restarts++;
          LOG(log_note, logtype_afpd, "Restarting 'afpd' (restarts: %u)", afpd_restarts);
          if ((afpd_pid = run_process(_PATH_AFPD, "-d", "-F", obj.options.configfile, NULL)) == -1) {
 -            LOG(log_error, logtype_afpd, "Error starting 'afpd'");
 +            LOG(log_error, logtype_default, "Error starting 'afpd'");
          }
      }
  
          cnid_metad_restarts++;
          LOG(log_note, logtype_afpd, "Restarting 'cnid_metad' (restarts: %u)", cnid_metad_restarts);
          if ((cnid_metad_pid = run_process(_PATH_CNID_METAD, "-d", "-F", obj.options.configfile, NULL)) == -1) {
 -            LOG(log_error, logtype_afpd, "Error starting 'cnid_metad'");
 +            LOG(log_error, logtype_default, "Error starting 'cnid_metad'");
 +        }
 +    }
 +
 +    if (dbus_pid == -1) {
 +        dbus_restarts++;
 +        LOG(log_note, logtype_afpd, "Restarting 'dbus' (restarts: %u)", dbus_restarts);
 +        if ((dbus_pid = run_process(dbus_path, "--config-file=" _PATH_CONFDIR "dbus.session.conf", NULL)) == -1) {
 +            LOG(log_error, logtype_default, "Error starting '%s'", dbus_path);
          }
      }
  }
@@@ -294,7 -249,6 +299,6 @@@ static void usage(void
  
  int main(int argc, char **argv)
  {
-     const char *configfile = NULL;
      int c, ret, debug = 0;
      sigset_t blocksigs;
      struct timeval tv;
      if (afp_config_parse(&obj, "netatalk") != 0)
          netatalk_exit(EXITERR_CONF);
  
 +    load_volumes(&obj);
 +
      event_set_log_callback(libevent_logmsg_cb);
      event_set_fatal_callback(netatalk_exit);
  
      sigdelset(&blocksigs, SIGHUP);
      sigprocmask(SIG_SETMASK, &blocksigs, NULL);
  
 +    dbus_path = iniparser_getstring(obj.iniconfig, INISEC_GLOBAL, "dbus daemon path", "/bin/dbus-daemon");
 +    LOG(log_debug, logtype_default, "DBUS: '%s'", dbus_path);
 +    if ((dbus_pid = run_process(dbus_path, "--config-file=" _PATH_CONFDIR "dbus-session.conf", NULL)) == -1) {
 +        LOG(log_error, logtype_default, "Error starting '%s'", dbus_path);
 +        netatalk_exit(EXITERR_CONF);
 +    }
 +
 +    /* Allow dbus some time to start up */
 +    sleep(1);
 +
 +    setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/spotlight.ipc", 1);
 +    set_sl_volumes();
 +    system(TRACKER_PREFIX "/bin/tracker-control -s");
 +
      /* run the event loop */
      ret = event_base_dispatch(base);
  
 -    if (afpd_pid != -1 || cnid_metad_pid != -1) {
 +    if (afpd_pid != -1 || cnid_metad_pid != -1 || dbus_pid != -1) {
          if (afpd_pid != -1)
              LOG(log_error, logtype_afpd, "AFP service did not shutdown, killing it");
          if (cnid_metad_pid != -1)
              LOG(log_error, logtype_afpd, "CNID database service did not shutdown, killing it");
 -        kill_childs(SIGKILL, &afpd_pid, &cnid_metad_pid, NULL);
 +        if (dbus_pid != -1)
 +            LOG(log_error, logtype_afpd, "DBUS session daemon still running, killing it");
 +        kill_childs(SIGKILL, &afpd_pid, &cnid_metad_pid, &dbus_pid, NULL);
      }
  
      LOG(log_note, logtype_afpd, "Netatalk AFP server exiting");
diff --combined etc/uams/uams_dhx2_pam.c
index 9c6bd29d267ccd34f8e80e7438ec9a6d38efd640,76e9143f6a97bd20e6cab84f8027cff6e44a64ce..5229d372433603b810ece221f427e92ed71079ee
@@@ -136,7 -136,11 +136,11 @@@ error
   * echo off means password.
   */
  static int PAM_conv (int num_msg,
+ #ifdef LINUX
                       const struct pam_message **msg,
+ #else
+                      struct pam_message **msg,
+ #endif
                       struct pam_response **resp,
                       void *appdata_ptr _U_) {
      int count = 0;
@@@ -948,6 -952,7 +952,6 @@@ static void uam_cleanup(void
      gcry_mpi_release(g);
  }
  
 -
  UAM_MODULE_EXPORT struct uam_export uams_dhx2 = {
      UAM_MODULE_SERVER,
      UAM_MODULE_VERSION,
diff --combined include/atalk/util.h
index ef6420bd9cf09587d2da41b61c0bb355b9557472,08c373948a3f7a9a7e77e53fcf26fe0d1d4d1f47..a7db8999fa10203b91b0c10c261fd162da3d39fc
  #include <sys/socket.h>
  #include <unistd.h>
  #include <poll.h>
+ #include <sys/stat.h>
  
  #include <atalk/unicode.h>
  #include <atalk/bstrlib.h>
 +#include <atalk/cnid.h>
  
  /* exit error codes */
  #define EXITERR_CLNT 1  /* client related error */
@@@ -179,7 -179,6 +180,6 @@@ extern int recv_fd(int fd, int nonblock
  extern const char *getcwdpath(void);
  extern const char *fullpathname(const char *);
  extern char *stripped_slashes_basename(char *p);
- extern int lchdir(const char *dir);
  extern void randombytes(void *buf, int n);
  extern int daemonize(int nochdir, int noclose);
  extern int run_cmd(const char *cmd, char **cmd_argv);
@@@ -187,12 -186,17 +187,18 @@@ extern char *realpath_safe(const char *
  extern const char *basename_safe(const char *path);
  extern char *strtok_quote (char *s, const char *delim);
  
+ extern int ochdir(const char *dir, int options);
+ extern int ostat(const char *path, struct stat *buf, int options);
+ extern int ostatat(int dirfd, const char *path, struct stat *st, int options);
+ extern int ochown(const char *path, uid_t owner, gid_t group, int options);
+ extern int ochmod(char *path, mode_t mode, const struct stat *st, int options);
  /******************************************************************
   * cnid.c
   *****************************************************************/
  
  extern bstring rel_path_in_vol(const char *path, const char *volpath);
 +extern cnid_t cnid_for_path(struct _cnid_db *cdb, const char *volpath, const char *path, cnid_t *did);
  
  /******************************************************************
   * cnid.c
index c163d6f6e3f6366d75d7503ba64787dd3356e255,0eba9a3c25faaa4ce255db5fdff95aaeaf1e315c..5108a4c8e86f0ef8d73d97f7300f025eeae84b92
@@@ -22,9 -22,8 +22,9 @@@
  #include <arpa/inet.h>
  
  #include <atalk/unicode.h>
 +#include <atalk/byteorder.h>
 +
  #include "precompose.h"
 -#include "byteorder.h"
  
  /*******************************************************************
   Convert a string to lower case.
@@@ -292,12 -291,12 +292,12 @@@ int strcasecmp_w(const ucs2_t *a, cons
  
        while (*a && *b) {
                if ((0xD800 <= *a) && (*a < 0xDC00)) {
-                       if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret;
+                       if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret;
                        a++;
                        b++;
                        if (!(*a && *b)) return (tolower_w(*a) - tolower_w(*b)); /* avoid buffer over run */
                } else {
-                       if (ret = tolower_w(*a) - tolower_w(*b)) return ret;
+                       if ((ret = tolower_w(*a) - tolower_w(*b))) return ret;
                }
                a++;
                b++;
@@@ -318,13 -317,13 +318,13 @@@ int strncasecmp_w(const ucs2_t *a, cons
  
        while ((n < len) && *a && *b) {
                if ((0xD800 <= *a) && (*a < 0xDC00)) {
-                       if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret;
+                       if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret;
                        a++;
                        b++;
                        n++;
                        if (!((n < len) && *a && *b)) return (tolower_w(*a) - tolower_w(*b));
                } else {
-                       if (ret = tolower_w(*a) - tolower_w(*b)) return ret;
+                       if ((ret = tolower_w(*a) - tolower_w(*b))) return ret;
                }
                a++;
                b++;
@@@ -608,7 -607,7 +608,7 @@@ size_t precompose_w (ucs2_t *name, size
                                base_sp = ((uint32_t)base << 16) | (uint32_t)comb;
                                do {
                                        comb_sp = ((uint32_t)in[1] << 16) | (uint32_t)in[2];
-                                       if (result_sp = do_precomposition_sp(base_sp, comb_sp)) {
+                                       if ((result_sp = do_precomposition_sp(base_sp, comb_sp))) {
                                                base_sp = result_sp;
                                                i += 4;
                                                in +=2;
                }
  
                /* Binary Search for BMP */
-               else if (result = do_precomposition(base, comb)) {
+               else if ((result = do_precomposition(base, comb))) {
                        base = result;
                }
                
index 739a6ab939a35f99d7112242249356f17e59ca7a,46d6f76684eb260b6c9c54fd45c49591adc10859..47baf384feb98b7dfa9d3e8eaa0f9a3c63f67378
@@@ -51,6 -51,7 +51,7 @@@
  #include <atalk/uuid.h>
  #include <atalk/netatalk_conf.h>
  #include <atalk/bstrlib.h>
+ #include <atalk/bstradd.h>
  
  #define VOLPASSLEN  8
  #ifndef UUID_PRINTABLE_STRING_LENGTH
@@@ -513,13 -514,11 +514,11 @@@ static int hostaccessvol(const AFPObj *
   */
  static const char *getoption(const dictionary *conf, const char *vol, const char *opt, const char *defsec, const char *defval)
  {
-     EC_INIT;
      const char *result;
  
      if ((!(result = iniparser_getstring(conf, vol, opt, NULL))) && (defsec != NULL))
          result = iniparser_getstring(conf, defsec, opt, NULL);
      
- EC_CLEANUP:
      if (result == NULL)
          result = defval;
      return result;
   */
  static int getoption_bool(const dictionary *conf, const char *vol, const char *opt, const char *defsec, int defval)
  {
-     EC_INIT;
      int result;
  
      if (((result = iniparser_getboolean(conf, vol, opt, -1)) == -1) && (defsec != NULL))
          result = iniparser_getboolean(conf, defsec, opt, -1);
      
- EC_CLEANUP:
      if (result == -1)
          result = defval;
      return result;
@@@ -639,14 -636,14 +636,14 @@@ static struct vol *creatvol(AFPObj *obj
      volume->v_vfs_ea = AFPVOL_EA_AUTO;
      volume->v_umask = obj->options.umask;
  
-     if (val = getoption(obj->iniconfig, section, "password", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "password", preset, NULL)))
          EC_NULL( volume->v_password = strdup(val) );
  
-     if (val = getoption(obj->iniconfig, section, "veto files", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "veto files", preset, NULL)))
          EC_NULL( volume->v_veto = strdup(val) );
  
      /* vol charset is in [G] and [V] */
-     if (val = getoption(obj->iniconfig, section, "vol charset", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "vol charset", preset, NULL))) {
          if (strcasecmp(val, "UTF-8") == 0) {
              val = strdup("UTF8");
          }
          EC_NULL( volume->v_volcodepage = strdup(obj->options.volcodepage) );
  
      /* mac charset is in [G] and [V] */
-     if (val = getoption(obj->iniconfig, section, "mac charset", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "mac charset", preset, NULL))) {
          if (strncasecmp(val, "MAC", 3) != 0) {
              LOG(log_warning, logtype_afpd, "Is '%s' really mac charset? ", val);
          }
          if(tmpname[i] == '/') tmpname[i] = ':';
  
      bstring dbpath;
-     EC_NULL_LOG( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
-     EC_NULL_LOG( dbpath = bformat("%s/%s/", val, tmpname) );
-     EC_NULL_LOG( volume->v_dbpath = strdup(bdata(dbpath)) );
+     EC_NULL( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") );
+     EC_NULL( dbpath = bformat("%s/%s/", val, tmpname) );
+     EC_NULL( volume->v_dbpath = strdup(cfrombstr(dbpath)) );
      bdestroy(dbpath);
  
-     if (val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL)))
          EC_NULL( volume->v_cnidscheme = strdup(val) );
      else
          volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME);
  
-     if (val = getoption(obj->iniconfig, section, "umask", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "umask", preset, NULL)))
          volume->v_umask = (int)strtol(val, NULL, 8);
  
-     if (val = getoption(obj->iniconfig, section, "directory perm", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "directory perm", preset, NULL)))
          volume->v_dperm = (int)strtol(val, NULL, 8);
  
-     if (val = getoption(obj->iniconfig, section, "file perm", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "file perm", preset, NULL)))
          volume->v_fperm = (int)strtol(val, NULL, 8);
  
-     if (val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL)))
          volume->v_limitsize = (uint32_t)strtoul(val, NULL, 10);
  
-     if (val = getoption(obj->iniconfig, section, "preexec", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "preexec", preset, NULL)))
          EC_NULL( volume->v_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
  
-     if (val = getoption(obj->iniconfig, section, "postexec", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "postexec", preset, NULL)))
          EC_NULL( volume->v_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
  
-     if (val = getoption(obj->iniconfig, section, "root preexec", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "root preexec", preset, NULL)))
          EC_NULL( volume->v_root_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
  
-     if (val = getoption(obj->iniconfig, section, "root postexec", preset, NULL))
+     if ((val = getoption(obj->iniconfig, section, "root postexec", preset, NULL)))
          EC_NULL( volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) );
  
-     if (val = getoption(obj->iniconfig, section, "appledouble", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "appledouble", preset, NULL))) {
          if (strcmp(val, "v2") == 0)
              volume->v_adouble = AD_VERSION2;
          else if (strcmp(val, "ea") == 0)
          volume->v_adouble = AD_VERSION;
      }
  
-     if (val = getoption(obj->iniconfig, section, "cnid server", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "cnid server", preset, NULL))) {
          EC_NULL( p = strdup(val) );
          volume->v_cnidserver = p;
-         if (q = strrchr(val, ':')) {
+         if ((q = strrchr(val, ':'))) {
              *q++ = 0;
              volume->v_cnidport = strdup(q);
          } else {
          volume->v_cnidport = strdup(obj->options.Cnid_port);
      }
  
-     if (val = getoption(obj->iniconfig, section, "ea", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "ea", preset, NULL))) {
          if (strcasecmp(val, "ad") == 0)
              volume->v_vfs_ea = AFPVOL_EA_AD;
          else if (strcasecmp(val, "sys") == 0)
              volume->v_vfs_ea = AFPVOL_EA_NONE;
      }
  
-     if (val = getoption(obj->iniconfig, section, "casefold", preset, NULL)) {
+     if ((val = getoption(obj->iniconfig, section, "casefold", preset, NULL))) {
          if (strcasecmp(val, "tolower") == 0)
              volume->v_casefold = AFPVOL_UMLOWER;
          else if (strcasecmp(val, "toupper") == 0)
  #endif
      if (!getoption_bool(obj->iniconfig, section, "convert appledouble", preset, 1))
          volume->v_flags |= AFPVOL_NOV2TOEACONV;
+     if (getoption_bool(obj->iniconfig, section, "follow symlinks", preset, 0))
+         volume->v_flags |= AFPVOL_FOLLOWSYM;
  
      if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0))
          volume->v_preexec_close = 1;
          volume->v_ad_options |= ADVOL_UNIXPRIV;
      if ((volume->v_flags & AFPVOL_INV_DOTS))
          volume->v_ad_options |= ADVOL_INVDOTS;
+     if ((volume->v_flags & AFPVOL_FOLLOWSYM))
+         volume->v_ad_options |= ADVOL_FOLLO_SYML;
  
      /* Mac to Unix conversion flags*/
      if ((volume->v_flags & AFPVOL_EILSEQ))
      initvol_vfs(volume);
  
      /* get/store uuid from file in afpd master*/
 -    if (!(pwd) && (volume->v_flags & AFPVOL_TM)) {
 -        char *uuid = get_vol_uuid(obj, volume->v_localname);
 -        if (!uuid) {
 -            LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID",
 -                volume->v_localname);
 -        } else {
 -            volume->v_uuid = uuid;
 -            LOG(log_debug, logtype_afpd, "Volume '%s': UUID '%s'",
 -                volume->v_localname, volume->v_uuid);
 -        }
 +    become_root();
 +    char *uuid = get_vol_uuid(obj, volume->v_localname);
 +    unbecome_root();
 +    if (!uuid) {
 +        LOG(log_error, logtype_afpd, "Volume '%s': couldn't get UUID",
 +            volume->v_localname);
 +    } else {
 +        volume->v_uuid = uuid;
 +        LOG(log_debug, logtype_afpd, "Volume '%s': UUID '%s'",
 +            volume->v_localname, volume->v_uuid);
      }
  
      /* no errors shall happen beyond this point because the cleanup would mess the volume chain up */
@@@ -977,9 -978,7 +978,7 @@@ static int readvolfile(AFPObj *obj, con
      char        volname[AFPVOL_U8MNAMELEN + 1];
      char        path[MAXPATHLEN + 1], tmp[MAXPATHLEN + 1];
      const char  *preset, *default_preset, *p, *basedir;
-     char        *q, *u;
      int         i;
-     struct passwd   *pw;
      regmatch_t match[1];
  
      LOG(log_debug, logtype_afpd, "readvolfile: BEGIN");
                  continue;
              }
  
-             if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) {
+             if ((p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) {
                  strlcat(tmp, "/", MAXPATHLEN);
                  strlcat(tmp, p, MAXPATHLEN);
              }
          free(realvolpath);
      }
  
- EC_CLEANUP:
// EC_CLEANUP:
      EC_EXIT;
  }
  
@@@ -1534,7 -1533,7 +1533,7 @@@ struct vol *getvolbypath(AFPObj *obj, c
          p++;
      EC_NULL_LOG( user = strdup(p) );
  
-     if (prw = strchr(user, '/'))
+     if ((prw = strchr(user, '/')))
          *prw++ = 0;
      if (prw != 0)
          subpath = prw;
      strlcat(tmpbuf, "/", MAXPATHLEN);
  
      /* (6) */
-     if (subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) {
+     if ((subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) {
          /*
          if (!subpath || strncmp(subpathconfig, subpath, strlen(subpathconfig)) != 0) {
              EC_FAIL;
@@@ -1611,8 -1610,8 +1610,8 @@@ int afp_config_parse(AFPObj *AFPObj, ch
      EC_INIT;
      dictionary *config;
      struct afp_options *options = &AFPObj->options;
-     int i, c;
-     const char *p, *tmp;
+     int c;
+     const char *p;
      char *q, *r;
      char val[MAXVAL];
  
          options->flags |= OPTION_SHARE_RESERV;
      if (iniparser_getboolean(config, INISEC_GLOBAL, "afp read locks", 0))
          options->flags |= OPTION_AFP_READ_LOCK;
 +    if (iniparser_getboolean(config, INISEC_GLOBAL, "spotlight", 0))
 +        options->flags |= OPTION_SPOTLIGHT;
      if (!iniparser_getboolean(config, INISEC_GLOBAL, "save password", 1))
          options->passwdbits |= PASSWD_NOSAVE;
      if (iniparser_getboolean(config, INISEC_GLOBAL, "set password", 0))
diff --combined macros/netatalk.m4
index 024a0971ca1e3ad1c2b05ddc19aece8065dff0d6,d7a8c8b67b4de5e35610cbfc65d07b156c9fca52..22ca226a7c1dc27f2c795d55a08ab173cfe98a3b
@@@ -13,49 -13,6 +13,49 @@@ AC_DEFUN([AC_DEVELOPER], 
      AM_CONDITIONAL(DEVELOPER, test x"$enable_dev" = x"yes")
  ])
  
 +dnl Tracker, for Spotlight
 +AC_DEFUN([AC_NETATALK_SPOTLIGHT], [
 +    ac_cv_tracker_pkg_default=tracker-sparql-0.12
 +    AC_ARG_WITH([tracker-pkg-config],
 +      [AS_HELP_STRING([--with-tracker-pkg-config],[name of the Tracker SPARQL pkg in pkg-config])],
 +      [ac_cv_tracker_pkg=$withval],
 +      [ac_cv_tracker_pkg=$ac_cv_tracker_pkg_default])
 +
 +    AC_MSG_NOTICE([searching for $ac_cv_tracker_pkg])
 +
 +    PKG_CHECK_MODULES([TRACKER], [$ac_cv_tracker_pkg >= 0.12], [ac_cv_have_tracker=yes], [ac_cv_have_tracker=no])
 +
 +    if test x"$ac_cv_have_tracker" = x"no" ; then
 +        if test x"$need_tracker" = x"yes" ; then
 +            AC_MSG_ERROR([$ac_cv_tracker_pkg not found])
 +        fi
 +    else
 +        AC_DEFINE(HAVE_TRACKER, 1, [Define if Tracker library is available])
 +        ac_cv_tracker_prefix=`pkg-config --variable=prefix $ac_cv_tracker_pkg`
 +        AC_DEFINE_UNQUOTED(TRACKER_PREFIX, ["$ac_cv_tracker_prefix"], [Path to Tracker])
 +      fi
 +
 +    AC_SUBST(TRACKER_CFLAGS)
 +    AC_SUBST(TRACKER_LIBS)
 +    AM_CONDITIONAL(HAVE_TRACKER, [test x"$ac_cv_have_tracker" = x"yes"])
 +
 +    ac_cv_tracker_miner_pkg_default=tracker-miner-0.12
 +    AC_ARG_WITH([tracker-miner-pkg-config],
 +      [AS_HELP_STRING([--with-tracker-miner-pkg-config],[name of the Tracker miner pkg in pkg-config])],
 +      [ac_cv_tracker_miner_pkg=$withval],
 +      [ac_cv_tracker_miner_pkg=$ac_cv_tracker_miner_pkg_default])
 +
 +    AC_MSG_NOTICE([searching for $ac_cv_tracker_miner_pkg])
 +
 +    PKG_CHECK_MODULES([TRACKER_MINER], [$ac_cv_tracker_miner_pkg >= 0.12], [ac_cv_have_tracker_miner=yes], [ac_cv_have_tracker_miner=no])
 +
 +    if test x"$ac_cv_have_tracker_miner" = x"yes" ; then
 +        AC_DEFINE(HAVE_TRACKER_MINER, 1, [Define if Tracker miner library is available])
 +        AC_SUBST(TRACKER_MINER_CFLAGS)
 +        AC_SUBST(TRACKER_MINER_LIBS)
 +      fi
 +])
 +
  dnl Whether to disable bundled libevent
  AC_DEFUN([AC_NETATALK_LIBEVENT], [
      AC_MSG_CHECKING([whether to use bundled libevent])
@@@ -402,7 -359,7 +402,7 @@@ f
  dnl ----- Linux specific -----
  if test x"$this_os" = "xlinux"; then 
        AC_MSG_RESULT([ * Linux specific configuration])
-       
+     AC_DEFINE(LINUX, 1, [OS is Linux])        
        dnl ----- check if we need the quotactl wrapper
      AC_CHECK_HEADERS(linux/dqblk_xfs.h,,
                [AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h)