SUBDIRS = pam
SUFFIXES = .tmpl .
-TMPLFILES = afp.conf.tmpl
-GENFILES = afp.conf
+TMPLFILES = afp.conf.tmpl dbus-session.conf.tmpl
+GENFILES = afp.conf dbus-session.conf
CLEANFILES = $(GENFILES)
- EXTRA_DIST = afp.conf.tmpl extmap.conf dbus-session.conf.tmpl
-EXTRA_DIST = afp.conf.tmpl extmap.conf netatalk-dbus.conf
++EXTRA_DIST = afp.conf.tmpl extmap.conf dbus-session.conf.tmpl netatalk-dbus.conf
OVERWRITE_CONFIG = @OVERWRITE_CONFIG@
CONFFILES = extmap.conf
pkgconfdir = @PKGCONFDIR@
+
+ if HAVE_DBUS_GLIB
+ dbusservicedir = $(DBUS_SYS_DIR)
+ dbusservice_DATA = netatalk-dbus.conf
+ endif
+
#
# rule to parse template files
#
done
rm -f $(DESTDIR)$(localstatedir)/netatalk/README
rm -f $(DESTDIR)$(localstatedir)/netatalk/CNID/README
+if HAVE_TRACKER_RDF
+ rm -f $(DESTDIR)$(pkgconfdir)/tracker/tracker.cfg
+endif
if USE_DEBIAN
rm -f $(DESTDIR)/etc/default/netatalk
endif
echo "not overwriting $$f"; \
fi; \
done
+if HAVE_TRACKER_RDF
+ if test "x$(OVERWRITE_CONFIG)" = "xyes" -o ! -f $(DESTDIR)$(pkgconfdir)/tracker/tracker.cfg ; then \
+ if test ! -d $(DESTDIR)$(pkgconfdir)/tracker ; then \
+ mkdir $(DESTDIR)$(pkgconfdir)/tracker ; \
+ fi ; \
+ $(INSTALL_DATA) tracker.cfg $(DESTDIR)$(pkgconfdir)/tracker/ ; \
+ fi
+endif
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)
dnl Check whether bundled libevent shall not be used
AC_NETATALK_LIBEVENT
+dnl Check for Tracker
+AC_NETATALK_SPOTLIGHT
+
dnl libatalk API checks
AC_DEVELOPER
+ dnl Check for dtrace
+ AC_NETATALK_DTRACE
+
+ dnl Check for dbus-glib, for AFP stats on dbus
+ AC_NETATALK_DBUS_GLIB
+
dnl FHS stuff has to be done last because it overrides other defaults
AC_NETATALK_FHS
dnl netatalk lockfile path, must come after AC_NETATALK_FHS
AC_NETATALK_LOCKFILE
- CFLAGS="-I\$(top_srcdir)/include -I\$(top_srcdir)/sys $CFLAGS"
+ CFLAGS="-I\$(top_srcdir)/include -I\$(top_builddir)/include $CFLAGS"
UAMS_PATH="${uams_path}"
AC_SUBST(LIBS)
etc/afpd/Makefile
etc/cnid_dbd/Makefile
etc/netatalk/Makefile
+ etc/spotlight/Makefile
etc/uams/Makefile
include/Makefile
include/atalk/Makefile
libatalk/compat/Makefile
libatalk/dsi/Makefile
libatalk/iniparser/Makefile
+ libatalk/talloc/Makefile
libatalk/tdb/Makefile
libatalk/unicode/Makefile
libatalk/unicode/charsets/Makefile
# Makefile.am for etc/afpd/
pkgconfdir = @PKGCONFDIR@
+ BUILT_SOURCES =
+ EXTRA_DIST =
+ CLEANFILES =
+ DISTCLEANFILES =
sbin_PROGRAMS = afpd
-noinst_PROGRAMS = hash fce
+noinst_PROGRAMS = hash fce spot
afpd_SOURCES = \
afp_avahi.c \
nfsquota.c \
ofork.c \
quota.c \
+ spotlight.c \
+ spotlight_marshalling.c \
status.c \
switch.c \
uam.c \
unix.c \
volume.c
+
afpd_LDADD = \
$(top_builddir)/libatalk/libatalk.la \
@LIBGCRYPT_LIBS@ @QUOTA_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ @GSSAPI_LIBS@ @KRB5_LIBS@
afpd_SOURCES += acls.c
endif
+ if HAVE_DBUS_GLIB
+ BUILT_SOURCES += afpstats_service_glue.h
+ EXTRA_DIST += afpstats-service.xml
+ DISTCLEANFILES += afpstats_service_glue.h
+
+ afpstats_service_glue.h: afpstats-service.xml
+ $(LIBTOOL) --mode=execute \
+ dbus-binding-tool \
+ --prefix=afpstats_obj \
+ --mode=glib-server \
+ --output=afpstats_service_glue.h \
+ $(top_srcdir)/etc/afpd/afpstats-service.xml
+
+ afpd_SOURCES += afpstats.c afpstats_obj.c
+ afpd_CFLAGS += $(DBUS_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_GTHREAD_CFLAGS) -DDBUS_COMPILATION
+ afpd_LDFLAGS += $(DBUS_LIBS) $(DBUS_GLIB_LIBS) $(DBUS_GTHREAD_LIBS) -ldbus-glib-1
+ endif
+
+ if WITH_DTRACE
+ DTRACE_OBJ = afpd-afp_dsi.o afpd-fork.o afpd-appl.o afpd-catsearch.o afpd-directory.o afpd-enumerate.o afpd-file.o afpd-filedir.o
+ afp_dtrace.o: $(top_srcdir)/include/atalk/afp_dtrace.d $(DTRACE_OBJ)
+ if test -f afp_dtrace.o ; then rm -f afp_dtrace.o ; fi
+ $(LIBTOOL) --mode=execute dtrace -G -s $(top_srcdir)/include/atalk/afp_dtrace.d -o afp_dtrace.o $(DTRACE_OBJ)
+ afpd_LDADD += afp_dtrace.o @DTRACE_LIBS@
+ CLEANFILES += afp_dtrace.o
+ endif
noinst_HEADERS = auth.h afp_config.h desktop.h directory.h fce_api_internal.h file.h \
filedir.h fork.h icon.h mangle.h misc.h status.h switch.h \
uam_auth.h uid.h unix.h volume.h hash.h acls.h acl_mappings.h extattrs.h \
- dircache.h afp_zeroconf.h afp_avahi.h afp_mdns.h
+ dircache.h afp_zeroconf.h afp_avahi.h afp_mdns.h afpstats.h afpstats_obj.h
hash_SOURCES = hash.c
hash_CFLAGS = -DKAZLIB_TEST_MAIN -I$(top_srcdir)/include
fce_SOURCES = fce_api.c fce_util.c
fce_CFLAGS = -DFCE_TEST_MAIN -I$(top_srcdir)/include
fce_LDADD = $(top_builddir)/libatalk/libatalk.la
+
+spot_SOURCES = spotlight.c spotlight_marshalling.c
+spot_CFLAGS = -DSPOT_TEST_MAIN
+spot_LDADD = $(top_builddir)/libatalk/libatalk.la
#include <atalk/fce_api.h>
#include <atalk/globals.h>
#include <atalk/netatalk_conf.h>
+#include <atalk/spotlight.h>
#include "switch.h"
#include "auth.h"
int flag = 1;
setsockopt(dsi->socket, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
+ /* Initialize Spotlight */
+ if ((obj->options.flags & OPTION_SPOTLIGHT) && (obj->options.slmod_path))
+ sl_mod_load(obj->options.slmod_path);
+
+ ipc_child_state(obj, DSI_RUNNING);
+
/* get stuck here until the end */
while (1) {
if (sigsetjmp(recon_jmp, 1) != 0)
exit(0);
}
- #if 0
- /* got ECONNRESET in read from client => exit*/
- if (dsi->flags & DSI_GOT_ECONNRESET) {
- LOG(log_note, logtype_afpd, "afp_over_dsi: client connection reset");
- afp_dsi_close(obj);
- exit(0);
- }
- #endif
-
if (dsi->flags & DSI_RECONINPROG) {
LOG(log_note, logtype_afpd, "afp_over_dsi: failed reconnect");
afp_dsi_close(obj);
if (dsi_disconnect(dsi) != 0)
afp_dsi_die(EXITERR_CLNT);
+ ipc_child_state(obj, DSI_DISCONNECTED);
+
while (dsi->flags & DSI_DISCONNECTED)
pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
+ ipc_child_state(obj, DSI_RUNNING);
continue; /* continue receiving until disconnect timer expires
* or a primary reconnect succeeds */
}
LOG(log_debug, logtype_afpd, "afp_over_dsi: got data, ending normal sleep");
dsi->flags &= ~DSI_SLEEPING;
dsi->tickle = 0;
+ ipc_child_state(obj, DSI_RUNNING);
}
if (reload_request) {
LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
+ AFP_AFPFUNC_START(function, (char *)AfpNum2name(function));
err = (*afp_switch[function])(obj,
(char *)dsi->commands, dsi->cmdlen,
(char *)&dsi->data, &dsi->datalen);
+ AFP_AFPFUNC_DONE(function, (char *)AfpNum2name(function));
LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
AfpNum2name(function), AfpErr2name(err));
LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));
+ AFP_AFPFUNC_START(function, (char *)AfpNum2name(function));
+
err = (*afp_switch[function])(obj,
(char *)dsi->commands, dsi->cmdlen,
(char *)&dsi->data, &dsi->datalen);
+ AFP_AFPFUNC_DONE(function, (char *)AfpNum2name(function));
+
LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
AfpNum2name(function), AfpErr2name(err));
#include <atalk/server_ipc.h>
#include <atalk/uuid.h>
#include <atalk/globals.h>
+#include <atalk/spotlight.h>
+ #include <atalk/unix.h>
#include "auth.h"
#include "uam_auth.h"
case 31:
uam_afpserver_action(AFP_SYNCDIR, UAM_AFPSERVER_POSTAUTH, afp_syncdir, NULL);
uam_afpserver_action(AFP_SYNCFORK, UAM_AFPSERVER_POSTAUTH, afp_syncfork, NULL);
- uam_afpserver_action(AFP_SPOTLIGHT_PRIVATE, UAM_AFPSERVER_POSTAUTH, afp_null_nolog, NULL);
+ uam_afpserver_action(AFP_SPOTLIGHT_PRIVATE, UAM_AFPSERVER_POSTAUTH, afp_spotlight_rpc, NULL);
uam_afpserver_action(AFP_ENUMERATE_EXT2, UAM_AFPSERVER_POSTAUTH, afp_enumerate_ext2, NULL);
case 30:
return AFP_OK;
}
- #define GROUPSTR_BUFSIZE 1024
- static const char *print_groups(int ngroups, gid_t *groups)
- {
- static char groupsstr[GROUPSTR_BUFSIZE];
- int i;
- char *s = groupsstr;
-
- if (ngroups == 0)
- return "-";
-
- for (i = 0; (i < ngroups) && (s < &groupsstr[GROUPSTR_BUFSIZE]); i++) {
- s += snprintf(s, &groupsstr[GROUPSTR_BUFSIZE] - s, " %u", groups[i]);
- }
-
- return groupsstr;
- }
-
static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expired)
{
#ifdef ADMIN_GRP
LOG(log_note, logtype_afpd, "%s Login by %s",
afp_versions[afp_version_index].av_name, pwd->pw_name);
- if (initgroups( pwd->pw_name, pwd->pw_gid ) < 0) {
- #ifdef RUN_AS_USER
- LOG(log_info, logtype_afpd, "running with uid %d", geteuid());
- #else /* RUN_AS_USER */
- LOG(log_error, logtype_afpd, "login: %s", strerror(errno));
- return AFPERR_BADUAM;
- #endif /* RUN_AS_USER */
-
- }
-
- /* Basically if the user is in the admin group, we stay root */
-
- if ((obj->ngroups = getgroups( 0, NULL )) < 0 ) {
- LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
- return AFPERR_BADUAM;
- }
-
- if ( NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
- LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
+ if (set_groups(obj, pwd) != 0)
return AFPERR_BADUAM;
- }
-
- if (( obj->ngroups = getgroups(obj->ngroups, obj->groups )) < 0 ) {
- LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
- return AFPERR_BADUAM;
- }
#ifdef ADMIN_GRP
LOG(log_debug, logtype_afpd, "obj->options.admingid == %d", obj->options.admingid);
if (dsi->flags & DSI_EXTSLEEP) {
LOG(log_note, logtype_afpd, "afp_zzz: waking up from extended sleep");
dsi->flags &= ~(DSI_SLEEPING | DSI_EXTSLEEP);
+ ipc_child_state(obj, DSI_RUNNING);
}
} else {
/* sleep request */
if (data & AFPZZZ_EXT_SLEEP) {
LOG(log_note, logtype_afpd, "afp_zzz: entering extended sleep");
dsi->flags |= DSI_EXTSLEEP;
+ ipc_child_state(obj, DSI_EXTSLEEP);
} else {
LOG(log_note, logtype_afpd, "afp_zzz: entering normal sleep");
+ ipc_child_state(obj, DSI_SLEEPING);
}
}
#include <atalk/globals.h>
#include <atalk/fce_api.h>
#include <atalk/netatalk_conf.h>
+#include <atalk/spotlight.h>
#include "directory.h"
#include "dircache.h"
catching moved files */
adcnid = ad_getid(adp, st->st_dev, st->st_ino, 0, vol->v_stamp); /* (1) */
+ AFP_CNID_START("cnid_add");
dbcnid = cnid_add(vol->v_cdb, st, did, upath, len, adcnid); /* (2) */
+ AFP_CNID_DONE();
+
/* Throw errors if cnid_add fails. */
if (dbcnid == CNID_INVALID) {
switch (errno) {
ad_flush(&ad);
ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF );
fce_register(FCE_FILE_CREATE, fullpathname(upath), NULL, fce_file);
+ sl_index_file(path);
curdir->d_offcnt++;
-
setvoltime(obj, vol );
return (retvalue);
err = AFPERR_BUSY;
} else if (!(err = vol->vfs->vfs_deletefile(vol, dirfd, file)) && !(err = netatalk_unlinkat(dirfd, file )) ) {
cnid_t id;
- if (checkAttrib && (id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file)))) {
- cnid_delete(vol->v_cdb, id);
+ if (checkAttrib) {
+ AFP_CNID_START("cnid_get");
+ id = cnid_get(vol->v_cdb, curdir->d_did, file, strlen(file));
+ AFP_CNID_DONE();
+ if (id) {
+ AFP_CNID_START("cnid_delete");
+ cnid_delete(vol->v_cdb, id);
+ AFP_CNID_DONE();
+ }
}
}
return AFPERR_PARAM;
}
st = &s_path->st;
- if ((id = cnid_lookup(vol->v_cdb, st, did, upath, len = strlen(upath)))) {
+ AFP_CNID_START("cnid_lookup");
+ id = cnid_lookup(vol->v_cdb, st, did, upath, len = strlen(upath));
+ AFP_CNID_DONE();
+ if (id) {
memcpy(rbuf, &id, sizeof(id));
*rbuflen = sizeof(id);
return AFPERR_EXISTID;
return 0;
/* update or add to cnid */
+ AFP_CNID_START("cnid_add");
aint = cnid_add(vol->v_cdb, &path.st, did, de->d_name, strlen(de->d_name), 0); /* ignore errors */
+ AFP_CNID_DONE();
return 0;
}
return AFPERR_NOID;
}
retry:
- if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
+ AFP_CNID_START("cnid_resolve");
+ upath = cnid_resolve(vol->v_cdb, &id, buffer, len);
+ AFP_CNID_DONE();
+ if (upath == NULL) {
return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */
}
ibuf += sizeof(id);
fileid = id;
- if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
+ AFP_CNID_START("cnid_resolve");
+ upath = cnid_resolve(vol->v_cdb, &id, buffer, len);
+ AFP_CNID_DONE();
+ if (upath == NULL) {
return AFPERR_NOID;
}
return AFPERR_BADTYPE;
delete:
+ AFP_CNID_START("cnid_delete");
if (cnid_delete(vol->v_cdb, fileid)) {
+ AFP_CNID_DONE();
switch (errno) {
case EROFS:
return AFPERR_VLOCK;
return AFPERR_PARAM;
}
}
-
+ AFP_CNID_DONE();
return err;
}
/* look for the source cnid. if it doesn't exist, don't worry about
* it. */
+ AFP_CNID_START("cnid_lookup");
sid = cnid_lookup(vol->v_cdb, &srcst, sdir->d_did, supath,slen = strlen(supath));
+ AFP_CNID_DONE();
if (NULL == ( dir = dirlookup( vol, did )) ) {
err = afp_errno; /* was AFPERR_PARAM */
/* look for destination id. */
upath = path->u_name;
+ AFP_CNID_START("cnid_lookup");
did = cnid_lookup(vol->v_cdb, &destst, curdir->d_did, upath, dlen = strlen(upath));
+ AFP_CNID_DONE();
/* construct a temp name.
* NOTE: the temp file will be in the dest file's directory. it
goto err_dest_to_src;
of_rename(vol, s_of, curdir, temp, curdir, path->m_name);
- /* id's need switching. src -> dest and dest -> src.
+ /*
+ * id's need switching. src -> dest and dest -> src.
* we need to re-stat() if it was a cross device copy.
- */
- if (sid)
+ */
+ if (sid) {
+ AFP_CNID_START("cnid_delete");
cnid_delete(vol->v_cdb, sid);
- if (did)
+ AFP_CNID_DONE();
+ }
+ if (did) {
+ AFP_CNID_START("cnid_delete");
cnid_delete(vol->v_cdb, did);
+ AFP_CNID_DONE();
+ }
if ((did && ( (crossdev && ostat(upath, &srcst, vol_syml_opt(vol)) < 0) ||
cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0))
#include "fork.h"
#include "uam_auth.h"
#include "afp_zeroconf.h"
+ #include "afpstats.h"
#define AFP_LISTENERS 32
#define FDSET_SAFETY 5
/* Initialize */
cnid_init();
-
+
/* watch atp, dsi sockets and ipc parent/child file descriptor. */
fd_set_listening_sockets(&obj);
/* set limits */
(void)setlimits();
+ #ifdef HAVE_DBUS_GLIB
+ /* Run dbus AFP statics thread */
+ (void)afpstats_init(server_children);
+ #endif
+
afp_child_t *child;
int recon_ipc_fd;
pid_t pid;
#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>
/* static variables */
static AFPObj obj;
-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, trackerd_pid = -1;
+static uint afpd_restarts, cnid_metad_restarts, dbus_restarts, trackerd_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;
+static char *trackerd_loglev;
+
+/******************************************************************
+ * 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
event_del(sigquit_ev);
event_del(timer_ev);
- kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, NULL);
+#ifdef HAVE_TRACKER_SPARQL
+ system("tracker-control -t");
+#endif
+ kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, &dbus_pid, &trackerd_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);
+#ifdef HAVE_TRACKER_SPARQL
+ system("tracker-control -t");
+#endif
+ kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, &dbus_pid, &trackerd_pid, NULL);
}
-/* SIGQUIT callback */
+/* SIGHUP callback */
static void sighup_cb(evutil_socket_t fd, short what, void *arg)
{
LOG(log_note, logtype_afpd, "Received SIGHUP, sending all processes signal to reload config");
- kill_childs(SIGHUP, &afpd_pid, &cnid_metad_pid, NULL);
+ kill_childs(SIGHUP, &afpd_pid, &cnid_metad_pid, &trackerd_pid, NULL);
}
/* SIGCHLD callback */
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 if (pid == trackerd_pid)
+ trackerd_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 && trackerd_pid == -1)
event_base_loopbreak(base);
}
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);
}
}
+
+#ifdef HAVE_TRACKER_RDF
+ if (trackerd_pid == -1) {
+ trackerd_restarts++;
+ LOG(log_note, logtype_afpd, "Restarting 'trackerd' (restarts: %u)", trackerd_restarts);
+ if ((trackerd_pid = run_process(TRACKER_RDF_PREFIX "/bin/trackerd", trackerd_loglev, NULL)) == -1) {
+ LOG(log_error, logtype_default, "Error starting '%s'", "/usr/bin/trackerd");
+ }
+ }
+#endif
}
/******************************************************************
static pid_t run_process(const char *path, ...)
{
int ret, i = 0;
- char *myargv[10];
+#define MYARVSIZE 64
+ char *myargv[MYARVSIZE];
va_list args;
pid_t pid;
if (pid == 0) {
myargv[i++] = (char *)path;
va_start(args, path);
- while ((myargv[i++] = va_arg(args, char *)) != NULL)
- ;
+ while (i < MYARVSIZE) {
+ if ((myargv[i++] = va_arg(args, char *)) == NULL)
+ break;
+ }
va_end(args);
ret = execv(path, myargv);
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);
LOG(log_note, logtype_default, "Netatalk AFP server starting");
if ((afpd_pid = run_process(_PATH_AFPD, "-d", "-F", obj.options.configfile, NULL)) == -1) {
- LOG(log_error, logtype_afpd, "Error starting 'cnid_metad'");
+ LOG(log_error, logtype_afpd, "Error starting 'afpd'");
netatalk_exit(EXITERR_CONF);
}
sigdelset(&blocksigs, SIGHUP);
sigprocmask(SIG_SETMASK, &blocksigs, NULL);
+#ifdef HAVE_TRACKER
+ setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/tmp/spotlight.ipc", 1);
+ setenv("XDG_DATA_HOME", _PATH_STATEDIR, 0);
+ setenv("XDG_CACHE_HOME", _PATH_STATEDIR, 0);
+ setenv("XDG_CONFIG_HOME", _PATH_CONFDIR, 0);
+#endif
+
+#ifdef HAVE_TRACKER_RDF
+ /* This assumes Tracker 0.6 with RDF is only used on Solaris and derived platforms */
+ dbus_path = iniparser_getstring(obj.iniconfig, INISEC_GLOBAL, "dbus daemon path", "/usr/lib/dbus-daemon");
+#else
+ dbus_path = iniparser_getstring(obj.iniconfig, INISEC_GLOBAL, "dbus daemon path", "/bin/dbus-daemon");
+#endif
+ 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);
+
+#ifdef HAVE_TRACKER_SPARQL
+ set_sl_volumes();
+ system(TRACKER_PREFIX "/bin/tracker-control -s");
+#endif
+#ifdef HAVE_TRACKER_RDF
+ if (asprintf(&trackerd_loglev, "--verbosity=%d", obj.options.tracker_loglevel) == -1)
+ netatalk_exit(EXITERR_CONF);
+ if ((trackerd_pid = run_process(TRACKER_RDF_PREFIX "/bin/trackerd", trackerd_loglev, NULL)) == -1) {
+ LOG(log_error, logtype_default, "Error starting '%s'", TRACKER_RDF_PREFIX "/bin/trackerd");
+ netatalk_exit(EXITERR_CONF);
+ }
+#endif
+
/* 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 || trackerd_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");
+ if (trackerd_pid != -1)
+ LOG(log_error, logtype_afpd, "trackerd still running, killing it");
+ kill_childs(SIGKILL, &afpd_pid, &cnid_metad_pid, &dbus_pid, &trackerd_pid, NULL);
}
LOG(log_note, logtype_afpd, "Netatalk AFP server exiting");
# Makefile.am for include/atalk/
atalkincludedir = $(includedir)/atalk
+ BUILT_SOURCES =
+ CLEANFILES =
atalkinclude_HEADERS = \
adouble.h \
ftw.h \
dsi.h \
ldapconfig.h \
- fce_api.h
+ talloc.h \
+ dalloc.h \
+ byteorder.h \
+ fce_api.h \
+ spotlight.h
+
+ EXTRA_DIST = afp_dtrace.d
+
+ if WITH_DTRACE
+ BUILT_SOURCES += afp_dtrace.h
+ CLEANFILES += afp_dtrace.h
+ afp_dtrace.h: $(top_srcdir)/include/atalk/afp_dtrace.d
+ $(LIBTOOL) --mode=execute dtrace -o afp_dtrace.h -h -s $(top_srcdir)/include/atalk/afp_dtrace.d
+ endif
uint32_t dsi_reserved; /* reserved field */
};
-#define DSI_DATASIZ 8192
+#define DSI_DATASIZ 65536
/* child and parent processes might interpret a couple of these
* differently. */
#define DSI_RECONSOCKET (1 << 7) /* we have a new socket from primary reconnect */
#define DSI_RECONINPROG (1 << 8) /* used in the new session in reconnect */
#define DSI_AFP_LOGGED_OUT (1 << 9) /* client called afp_logout, quit on next EOF from socket */
- #if 0
- #define DSI_GOT_ECONNRESET (1 << 10) /* got ECONNRESET from client => exit */
- #endif
/* basic initialization: dsi_init.c */
extern DSI *dsi_init(AFPObj *obj, const char *hostname, const char *address, const char *port);
#include <atalk/unicode.h>
#include <atalk/uam.h>
#include <atalk/iniparser.h>
+ #ifdef WITH_DTRACE
+ #include <atalk/afp_dtrace.h>
+ #else
+ /* List of empty dtrace macros */
+ #define AFP_AFPFUNC_START(a,b)
+ #define AFP_AFPFUNC_DONE(a, b)
+ #define AFP_CNID_START(a)
+ #define AFP_CNID_DONE()
+ #define AFP_READ_START(a)
+ #define AFP_READ_DONE()
+ #define AFP_WRITE_START(a)
+ #define AFP_WRITE_DONE()
+ #endif
/* #define DOSFILELEN 12 */ /* Type1, DOS-compat*/
#define MACFILELEN 31 /* Type2, HFS-compat */
#define OPTION_ACL2MACCESS (1 << 8)
#define OPTION_NOZEROCONF (1 << 9)
#define OPTION_SHARE_RESERV (1 << 11) /* whether to use Solaris fcntl F_SHARE locks */
-
+#define OPTION_SPOTLIGHT (1 << 12) /* whether to enable Spotlight support */
#define PASSWD_NONE 0
#define PASSWD_SET (1 << 0)
#define PASSWD_NOSAVE (1 << 1)
char *logfile;
char *mimicmodel;
char *adminauthuser;
+ char *slmod_path;
+ int tracker_loglevel;
struct afp_volume_name volfile;
};
"UAMS", \
"FCE", \
"ad", \
+ "Spotlight", \
"end_of_list_marker"}
/* =========================================================================
DEFAULT_LOG_CONFIG, /* logtype_afpd */
DEFAULT_LOG_CONFIG, /* logtype_dsi */
DEFAULT_LOG_CONFIG, /* logtype_uams */
- DEFAULT_LOG_CONFIG, /* logtype_fce */
- DEFAULT_LOG_CONFIG /* logtype_ad */
+ DEFAULT_LOG_CONFIG, /* logtype_fce */
+ DEFAULT_LOG_CONFIG, /* logtype_ad */
+ DEFAULT_LOG_CONFIG /* logtype_sl */
};
static void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility);
loglevel, logtype);
/* If default wasnt setup its fd is -1 */
- iov[0].iov_base = log_details_buffer;
- iov[0].iov_len = strlen(log_details_buffer);
- iov[1].iov_base = temp_buffer;
- iov[1].iov_len = strlen(temp_buffer);
- writev( fd, iov, 2);
+ write(fd, log_details_buffer, strlen(log_details_buffer));
+ write(fd, temp_buffer, strlen(temp_buffer));
} else {
write(fd, temp_buffer, strlen(temp_buffer));
}
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 */
LOG(log_debug, logtype_afpd, "load_volumes: BEGIN");
+ if (obj->uid)
+ pwent = getpwuid(obj->uid);
+
if (Volumes) {
if (!volfile_changed(&obj->options))
goto EC_CLEANUP;
for (vol = Volumes; vol; vol = vol->v_next) {
vol->v_deleted = 1;
}
+ if (obj->uid) {
+ become_root();
+ ret = set_groups(obj, pwent);
+ unbecome_root();
+ if (ret != 0) {
+ LOG(log_error, logtype_afpd, "load_volumes: set_groups: %s", strerror(errno));
+ EC_FAIL;
+ }
+ }
} else {
LOG(log_debug, logtype_afpd, "load_volumes: no volumes yet");
EC_ZERO_LOG( lstat(obj->options.configfile, &st) );
break;
}
- if (obj->uid)
- pwent = getpwuid(obj->uid);
-
if (obj->iniconfig)
iniparser_freedict(obj->iniconfig);
LOG(log_debug, logtype_afpd, "load_volumes: loading: %s", obj->options.configfile);
return( vol );
}
+ /*
+ * get username by path
+ *
+ * getvolbypath() assumes that the user home directory has the same name as the username.
+ * If that is not true, getuserbypath() is called and tries to retrieve the username
+ * from the directory owner, checking its validity.
+ *
+ * @param path (r) absolute volume path
+ * @returns NULL if no match is found, pointer to username if successfull
+ *
+ */
+ static char *getuserbypath(const char *path)
+ {
+ EC_INIT;
+ struct stat sbuf;
+ struct passwd *pwd;
+ char *hdir = NULL;
+
+ LOG(log_debug, logtype_afpd, "getuserbypath(\"%s\")", path);
+
+ /* does folder exists? */
+ if (stat(path, &sbuf) != 0)
+ EC_FAIL;
+
+ /* get uid of dir owner */
+ if ((pwd = getpwuid(sbuf.st_uid)) == NULL)
+ EC_FAIL;
+
+ /* does user home directory exists? */
+ if (stat(pwd->pw_dir, &sbuf) != 0)
+ EC_FAIL;
+
+ /* resolve and remove symlinks */
+ if ((hdir = realpath_safe(pwd->pw_dir)) == NULL)
+ EC_FAIL;
+
+ /* handle subdirectories, path = */
+ if (strncmp(path, hdir, strlen(hdir)) != 0)
+ EC_FAIL;
+
+ LOG(log_debug, logtype_afpd, "getuserbypath: match user: %s, home: %s, realhome: %s",
+ pwd->pw_name, pwd->pw_dir, hdir);
+
+ EC_CLEANUP:
+ if (hdir)
+ free(hdir);
+ if (ret != 0)
+ return NULL;
+ return pwd->pw_name;
+ }
/*!
* Search volume by path, creating user home vols as necessary
*
* (3) If there is, match "path" with "basedir regex" to get the user home parent dir
* (4) Built user home path by appending the basedir matched in (3) and appending the username
* (5) The next path element then is the username
+ * (5b) getvolbypath() assumes that the user home directory has the same name as the username.
+ * If that is not true, getuserbypath() is called and tries to retrieve the username
+ * from the directory owner, checking its validity
* (6) Append [Homes]->path subdirectory if defined
* (7) Create volume
*
subpath = prw;
strlcat(tmpbuf, user, MAXPATHLEN);
+ if (getpwnam(user) == NULL) {
+ /* (5b) */
+ char *tuser;
+ if ((tuser = getuserbypath(tmpbuf)) != NULL) {
+ free(user);
+ user = strdup(tuser);
+ }
+ }
strlcpy(obj->username, user, MAXUSERLEN);
strlcat(tmpbuf, "/", MAXPATHLEN);
options->configfile = AFPObj->cmdlineconfigfile ? strdup(AFPObj->cmdlineconfigfile) : strdup(_PATH_CONFDIR "afp.conf");
options->sigconffile = strdup(_PATH_STATEDIR "afp_signature.conf");
options->uuidconf = strdup(_PATH_STATEDIR "afp_voluuid.conf");
+#ifdef HAVE_TRACKER_SPARQL
+ options->slmod_path = strdup(_PATH_AFPDUAMPATH "slmod_sparql.so");
+#endif
+#ifdef HAVE_TRACKER_RDF
+ options->slmod_path = strdup(_PATH_AFPDUAMPATH "slmod_rdf.so");
+#endif
options->flags = OPTION_UUID | AFPObj->cmdlineflags;
if ((config = iniparser_load(AFPObj->options.configfile)) == NULL)
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))
options->fce_fmodwait = iniparser_getint (config, INISEC_GLOBAL, "fce holdfmod", 60);
options->sleep = iniparser_getint (config, INISEC_GLOBAL, "sleep time", 10);
options->disconnected = iniparser_getint (config, INISEC_GLOBAL, "disconnect time",24);
+ options->tracker_loglevel = iniparser_getint (config, INISEC_GLOBAL, "tracker loglevel", 1);
if ((p = iniparser_getstring(config, INISEC_GLOBAL, "hostname", NULL))) {
EC_NULL_LOG( options->hostname = strdup(p) );
CONFIG_ARG_FREE(obj->options.Cnid_port);
if (obj->options.fqdn)
CONFIG_ARG_FREE(obj->options.fqdn);
+ if (obj->options.slmod_path)
+ CONFIG_ARG_FREE(obj->options.slmod_path);
if (obj->options.unixcodepage)
CONFIG_ARG_FREE(obj->options.unixcodepage);
dnl Kitchen sink for configuration macros
+ dnl Check for dtrace
+ AC_DEFUN([AC_NETATALK_DTRACE], [
+ AC_ARG_WITH(dtrace,
+ AS_HELP_STRING(
+ [--with-dtrace],
+ [Enable dtrace probes (default: enabled if dtrace found)]
+ ),
+ [WDTRACE=$withval],
+ [WDTRACE=auto]
+ )
+ if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then
+ AC_CHECK_PROG([atalk_cv_have_dtrace], [dtrace], [yes], [no])
+ if test "x$atalk_cv_have_dtrace" = "xno" ; then
+ if test "x$WDTRACE" = "xyes" ; then
+ AC_MSG_FAILURE([dtrace requested but not found])
+ fi
+ WDTRACE="no"
+ else
+ WDTRACE="yes"
+ fi
+ fi
+
+ if test x"$WDTRACE" = x"yes" ; then
+ AC_DEFINE([WITH_DTRACE], [1], [dtrace probes])
+ DTRACE_LIBS=""
+ if test x"$this_os" = x"freebsd" ; then
+ DTRACE_LIBS="-lelf"
+ fi
+ AC_SUBST(DTRACE_LIBS)
+ fi
+ AM_CONDITIONAL(WITH_DTRACE, test "x$WDTRACE" = "xyes")
+ ])
+
+ dnl Check for dbus-glib, for AFP stats
+ AC_DEFUN([AC_NETATALK_DBUS_GLIB], [
+ PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1, have_dbus=yes, have_dbus=no)
+ PKG_CHECK_MODULES(DBUS_GLIB, gobject-2.0 >= 2.6, have_dbus_glib=yes, have_dbus_glib=no)
+ PKG_CHECK_MODULES(DBUS_GTHREAD, gthread-2.0, have_dbus_gthread=yes, have_dbus_gthread=no)
+ AC_SUBST(DBUS_CFLAGS)
+ AC_SUBST(DBUS_LIBS)
+ AC_SUBST(DBUS_GLIB_CFLAGS)
+ AC_SUBST(DBUS_GLIB_LIBS)
+ AC_SUBST(DBUS_GTHREAD_CFLAGS)
+ AC_SUBST(DBUS_GTHREAD_LIBS)
+ AM_CONDITIONAL(HAVE_DBUS_GLIB, test x$have_dbus_glib = xyes -a x$have_dbus = xyes)
+
+ AC_ARG_WITH(
+ dbus-sysconf-dir,
+ [AS_HELP_STRING([--with-dbus-sysconf-dir],[Path to dbus system bus security configuration directory (default: ${sysconfdir}/dbus-1/system.d/)])],
+ ac_cv_dbus_sysdir=$withval,
+ ac_cv_dbus_sysdir='${sysconfdir}/dbus-1/system.d'
+ )
+
+ if test x$have_dbus_glib = xyes -a x$have_dbus = xyes ; then
+ AC_DEFINE(HAVE_DBUS_GLIB, 1, [Define if support for dbus-glib was found])
+ DBUS_SYS_DIR="$ac_cv_dbus_sysdir"
+ AC_SUBST(DBUS_SYS_DIR)
+ fi
+ ])
+
dnl Whether to enable developer build
AC_DEFUN([AC_DEVELOPER], [
AC_MSG_CHECKING([whether to enable developer build])
AM_CONDITIONAL(DEVELOPER, test x"$enable_dev" = x"yes")
])
+dnl Tracker, for Spotlight
+AC_DEFUN([AC_NETATALK_SPOTLIGHT], [
+ ac_cv_have_tracker=no
+ dnl Tracker SPARQL
+ 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])
+
+ PKG_CHECK_MODULES([TRACKER], [$ac_cv_tracker_pkg >= 0.12], [ac_cv_have_tracker_sparql=yes], [ac_cv_have_tracker_sparql=no])
+
+ if test x"$ac_cv_have_tracker_sparql" = 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 is available])
+ AC_DEFINE(HAVE_TRACKER_SPARQL, 1, [Define if Tracker SPARQL 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_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])
+
+ 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 Test for Tracker 0.6 on Solaris and derived platforms
+ if test x"$this_os" = x"solaris" ; then
+ PKG_CHECK_MODULES([TRACKER], [tracker >= 0.6], [ac_cv_have_tracker_rdf=yes], [ac_cv_have_tracker_rdf=no])
+ if test x"$ac_cv_have_tracker_rdf" = x"yes" ; then
+ AC_DEFINE(HAVE_TRACKER, 1, [Define if Tracker is available])
+ AC_DEFINE(HAVE_TRACKER_RDF, 1, [Define if Tracker 0.6 with support for RDF queries is available])
+ ac_cv_tracker_prefix=`pkg-config --variable=prefix tracker`
+ AC_DEFINE_UNQUOTED(TRACKER_RDF_PREFIX, ["$ac_cv_tracker_prefix"], [Path to Tracker])
+ fi
+ fi
+
+ if test x"$ac_cv_have_tracker_sparql" = x"yes" -o x"$ac_cv_have_tracker_rdf" = x"yes" ; then
+ ac_cv_have_tracker=yes
+ fi
+ AC_SUBST(TRACKER_CFLAGS)
+ AC_SUBST(TRACKER_LIBS)
+ AM_CONDITIONAL(HAVE_TRACKER_SPARQL, [test x"$ac_cv_have_tracker_sparql" = x"yes"])
+ AM_CONDITIONAL(HAVE_TRACKER_RDF, [test x"$ac_cv_have_tracker_rdf" = x"yes"])
+])
+
dnl Whether to disable bundled libevent
AC_DEFUN([AC_NETATALK_LIBEVENT], [
AC_MSG_CHECKING([whether to use bundled libevent])
AC_MSG_RESULT([ AFP:])
AC_MSG_RESULT([ Extended Attributes: $neta_cv_eas])
AC_MSG_RESULT([ ACL support: $with_acl_support])
+ AC_MSG_RESULT([ Spotlight: $ac_cv_have_tracker])
AC_MSG_RESULT([ CNID:])
AC_MSG_RESULT([ backends: $compiled_backends])
AC_MSG_RESULT([ UAMS:])
AC_MSG_RESULT([ ACL support: $with_acl_support])
AC_MSG_RESULT([ Kerberos support: $with_kerberos])
AC_MSG_RESULT([ LDAP support: $netatalk_cv_ldap])
+ AC_MSG_RESULT([ dbus support: $have_dbus_glib])
+ AC_MSG_RESULT([ dbus system directory: $ac_cv_dbus_sysdir])
+ AC_MSG_RESULT([ dtrace probes: $WDTRACE])
if test x"$use_pam_so" = x"yes" -a x"$netatalk_cv_install_pam" = x"no"; then
AC_MSG_RESULT([])
AC_MSG_WARN([ PAM support was configured for your system, but the netatalk PAM configuration file])
$(top_srcdir)/etc/afpd/ofork.c \
$(top_srcdir)/etc/afpd/quota.c \
$(top_srcdir)/etc/afpd/status.c \
+ $(top_srcdir)/etc/afpd/spotlight.c \
+ $(top_srcdir)/etc/afpd/spotlight_marshalling.c \
$(top_srcdir)/etc/afpd/switch.c \
$(top_srcdir)/etc/afpd/uam.c \
$(top_srcdir)/etc/afpd/unix.c \
@LIBGCRYPT_LIBS@ @QUOTA_LIBS@ @WRAP_LIBS@ @LIBADD_DL@ @ACL_LIBS@ @ZEROCONF_LIBS@ @PTHREAD_LIBS@ @GSSAPI_LIBS@ @KRB5_LIBS@
test_LDFLAGS = -export-dynamic
+
+ if WITH_DTRACE
+ DTRACE_OBJ = test-afp_dsi.o test-fork.o test-appl.o test-catsearch.o test-directory.o test-enumerate.o test-file.o test-filedir.o
+ afp_dtrace.o: $(top_srcdir)/include/atalk/afp_dtrace.d $(DTRACE_OBJ)
+ if test -f afp_dtrace.o ; then rm -f afp_dtrace.o ; fi
+ $(LIBTOOL) --mode=execute dtrace -G -s $(top_srcdir)/include/atalk/afp_dtrace.d -o afp_dtrace.o $(DTRACE_OBJ)
+ test_LDADD += afp_dtrace.o @DTRACE_LIBS@
+ CLEANFILES += afp_dtrace.o
+ endif