+Changes in 3.1.3
+================
+* UPD: Spotlight: more SPARQL query optimisations
+* UPD: Spotlight: new options "sparql results limit", "spotlight
+ attributes" and "spotlight expr"
+* FIX: afpd: Unarchiving certain ZIP archives fails, bug #569
+* UPD: Update Unicode support to version 7.0.0
+* FIX: Memory overflow caused by 'basedir regex', bug #567
+* NEW: afpd: delete empty resource forks, from FR #92
+* FIX: afpd: fix a crash when accessing ._ AppleDouble files created
+ by OS X via SMB, bug #564
+* FIX: afpd and dbd: Converting from AppleDouble v2 to ea may corrupt
+ the resource fork. In some circumstances an offset calculation
+ is wrong resulting in corrupt resource forks after the
+ conversion. Bug #568.
+* FIX: ad: fix for bug #563 broke ad file utilities, bug #570.
+* NEW: afpd: new advanced option controlling permissions and ACLs,
+ from FR #93
+
+Changes in 3.1.2
+================
+* FIX: Option "vol dbpath" was broken in 3.1.1
+* FIX: Spotlight: file modification date, bug #545
+* FIX: Improve reliability of afpd child handler
+* FIX: debian initscript: add 0 and 6 to Default-Stop. debian-bug#745520
+* FIX: put the Solaris share reservation after our locking stuff, bug #560.
+* UPD: Improve Linux quota behaviour
+* FIX: xattrs on *BSD, bug #562
+* NEW: afpd: support for using $u username variable in AFP volume
+ definitions. FR#90.
+* FIX: getvolbypath returns incorrect volume, bug #563
+* FIX: fd leak when using appledouble = v2, bug #554
+* UPD: New options that control whether dbus and Tracker are started:
+ 'start dbus' and 'start tracker', both default to yes, FR#91
+* UPD: Spotlight: SPARQL query optimisations
+
+Changes in 3.1.1
+================
+* FIX: Add asprint() compatibility function for systems lacking it
+* FIX: Fix ressource fork name conversion. Bug #534.
+* FIX: Fix a bug where only the first configured UAM was loaded.
+ Bug #537.
+* UPD: Add support for AFP 3.4. From FR #85.
+* FIX: Registering with mDNS crashed. Bug #540
+* FIX: Saving from applications like Photoshop may fail, because
+ removing the ressource fork AppleDouble file failed. Bug #542.
+* FIX: dbd: remove orphaned ._ AppleDouble files. Bug #549.
+* NEW: afpd: Automatic conversion of ._ AppleDouble files
+ created by OS X. Bug #550.
+* FIX: afpd: Fix a crash in of_closefork(). Bug #551.
+* FIX: dbd: Don't print message "Ignoring ._file" for every ._ file.
+ Bug #552.
+* FIX: afpd: Don't flood log with failed sys_set_ea() messages.
+
+Changes in 3.1.0
+================
+* NEW: AFP Spotlight support with Gnome Tracker
+* NEW: New option "spotlight" (G/V)
+* NEW: Configure option --with-tracker-pkgconfig-version
+* NEW: Configure option --with-tracker-prefix
+* NEW: If Spotlight is enabled, launch our own dbus instance
+* NEW: New option "dbus daemon" (G)
+* UPD: Add configure option --with-afpstats for overriding the
+ result of autodetecting dbus-glib presence
+* NEW: Add recvfile support with splice() on Linux. New global options
+ "recvfile" (default: no) and "splice size" (default 64k).
+* NEW: CNID backend "mysql" for use with a MySQL server
+
+Changes in 3.0.7
+================
+* FIX: Build fixes for the Kerberos UAM
+* UPD: Use dedicated exit code for AFP connections that were dropped
+ by the client right after the TCP handshake
+* FIX: Workaround for a problem which cannot be advertized by Avahi. Bug #541.
+* FIX: Registering with mDNS crashed. Bug #540
+* FIX: Saving from applications like Photoshop may fail, because
+ removing the ressource fork AppleDouble file failed. Bug #542.
+* FIX: macusers showed root user. Bug #495.
+* UPD: Add file pathname to logmessage parse_entries: bogus eid. FR#87.
+
+Changes in 3.0.6
+================
+* FIX: charset conversion failed when copying from Mac OS 9. Bug #523.
+* UPD: Don't force S_ISGID for directories on FreeBSD. Bug #525.
+* NEW: Add support for ZFS ACLs on FreeBSD with libsunacl. From FR#83.
+* FIX: Active Directory LDAP queries for ACL support with new options
+ "ldap user filter" and "ldap group filter". Bug #526.
+* NEW: Option "vol dbnest", when set to true, the CNID database for
+ a volume is stored in the volume root of a share in a directory
+ .AppleDB like in Netatalk 2. Defaults to false. From FR#84.
+* FIX: Small fix in the DSI tickle handling. Bug #528.
+* UPD: Enhance handling of connection attempts when hitting the
+ connection limit. Bug #529.
+* FIX: Saving from Word to a folder that is a symlink to a folder on
+ another filesystem results in a crash of the afpd process and
+ the save to fail. This happens only if the option
+ "follow symlinks" is enabled. Bug #532.
+* FIX: Disable Kerberos UAM if AFP service principal name can't be
+ evaluated. Fixes bug #531.
+* FIX: Fix handling of large number of volumes. Bug #527.
+* NEW: Configure option --with-tbd which can be used to disable the
+ use of the bundled tdb and use a system installed version.
+
+Changes in 3.0.5
+================
+* FIX: Fix a crash when using pam_winbind. Fixes bug #516.
+* NEW: New global/volume option "ignored attributes"
+* FIX: "afp listen" option failed to take IPv6 addresses. Bug #515.
+* FIX: Fix a possible crash in set_groups. Bug #518.
+* NEW: Send optional AFP messages for vetoed files, new option
+ "veto message" can be used to enable sending messages.
+ Then whenever a client tries to access any file or directory
+ with a vetoed name, it will be sent an AFP message indicating
+ the name and the directory. From FR #81.
+* NEW: New boolean volume option "delete veto files". If this option is
+ set to yes, then Netatalk will attempt to recursively delete any
+ vetoed files and directories. FR #82.
+* UPD: systemd unit dir is /usr/lib/systemd/system .
+* FIX: Saving files from application like MS Word may result in the file
+ loosing metadata like the Finder label. Bug #521.
+
+Changes in 3.0.4
+================
+* FIX: Opening files without metadata EA may result in an invalid
+ metadata EA. Check for malformed metadata EAs and delete them.
+ Fixes bug #510.
+* FIX: Fix an issue with filenames containing non-ASCII characters that
+ lead to a failure setting the size of a files ressource fork.
+ This affected application like Adobe Photoshop where saving
+ files may fail. Fixes bug #511.
+* UPD: Enhance ACL mapping, change global ACL option 'map acls' to take
+ the following options: "none", "rights" (default), "mode".
+ none = no mapping, this resembles the previous false/no setting
+ rights = map ACLs to Finder UARights, this resembles the previous
+ true/yes setting. This is the default.
+ mode = map ACLs to Finder UARights and UNIX mode
+ From FR #73.
+* FIX: Fix a possible crash in cname() where cname_mtouname calls
+ dirlookup() where the curdir is freed because the dircache
+ detected a dev/inode cache difference and evicted the object
+ from the cache. Fixes bug #498.
+* FIX: Add missing include, fixes bug #512.
+* FIX: Change default FinderInfo for directories to be all 0, fixes
+ bug 514.
+* NEW: New option "afp interfaces" which allows specifying where
+ Netatalk listens for AFP connections by interface names.
+ From FR #79.
+
+Changes in 3.0.3
+================
+* UPD: afpd: Increase default DSI server quantum to 1 MB
+* UPD: bundled libevent2 is now static
+* NEW: --with-lockfile=PATH configure option for specifying an
+ alternative path for the netatalk lockfile.
+* UPD: systemd service file use PIDFile and ExecReload.
+ From FR #70.
+* UPD: RedHat sysvinit: rm graceful, reimplement reload, add condrestart
+* FIX: Couldn't create folders on FreeBSD 9.1 ZFS fileystems.
+ Fixed bug #491.
+* FIX: Fix an issue with user homes when user home directory has not the
+ same name as the username.
+ Fixes bug #497.
+* UPD: Fix PAM config install, new default installation dir is
+ $sysconfdir/pam.d/. Add configure option --with-pam-confdir
+ to specify alternative path.
+* NEW: AFP stats about active session via dbus IPC. Client side python
+ program `afpstats`. Requires dbus, dbus-glib any python-dbus.
+ configure option --dbus-sysconf-dir for specifying dbus
+ system security configuration files.
+ New option 'afpstats' (default: no) which determines whether
+ to enable the feature or not.
+* NEW: configure option --with-init-dir
+* NEW: dtrace probes, cf include/atalk/afp_dtrace.d for available
+ probes.
+* UPD: Reload groups when reloading volumes. FR #71.
+* FIX: Attempt to read read-only ._ rfork results in disconnect.
+ Fixes bug #502.
+* FIX: File's ressource fork can't be read if metadata EA is missing.
+ Fixes bug #501.
+* FIX: Conversion from adouble v2 to ea for directories.
+ Fixes bug #500.
+* FIX: Error messages when mounting read-only filesystems.
+ Fixes bug #504.
+* FIX: Permissions of ._ AppleDouble ressource fork after conversion
+ from v2 to ea.
+ Fixes bug #505.
+* UPD: Use FreeBSD sendfile() capability to send protocol header.
+ From FR #75.
+* UPD: Increase IO size when sendfile() is not used.
+ From FR #76.
+* FIX: Can't set Finder label on symlinked folder with "follow symlinks = yes".
+ Fixes bug #508.
+* FIX: Setting POSIX ACLs on Linux
+ Fixes bug #506.
+* FIX: "ad ls" segfault if requested object is not in an AFP volume.
+ Fixes bug #496.
+
+Changes in 3.0.2
+================
+* NEW: afpd: Put file extension type/creator mapping back in which had
+ been removed in 3.0.
+* NEW: afpd: new option 'ad domain'. From FR #66.
+* FIX: volumes and home share with symlinks in the path
+* FIX: Copying packages to a Netatalk share could fail, bug #469
+* FIX: Reloading volumes from config file was broken. Fixes bug #474.
+* FIX: Fix _device-info service type registered with dns-sd API
+* FIX: Fix pathname bug for FCE modified event.
+* FIX: Remove length limitation of options like "valid users".
+ Fixes bug #473.
+* FIX: Dont copy our metadata EA in copyfile(). Fixes bug #452.
+* FIX: Fix an error where catalog search gave incomplete results.
+ Fixes bug #479.
+* REM: Remove TimeMachine volume used size FCE event.
+* UPD: Add quoting support to '[in]valid users' option. Fixes bug #472.
+* FIX: Install working PAM config on Solaris 11. Fixes bug #481.
+* FIX: Fix a race condition between dbd and the cnid_dbd daemon
+ which could result in users being disconnected from volumes
+ when dbd was scanning their volumes. Fixes bug #477.
+* FIX: Netatalk didn't start when the last line of the config file
+ afp.conf wasn't terminated by a newline. Fixes bug #476.
+* NEW: Add a new volumes option 'follow symlinks'. The default setting is
+ false, symlinks are not followed on the server. This is the same
+ behaviour as OS X's AFP server.
+ Setting the option to true causes afpd to follow symlinks on the
+ server. symlinks may point outside of the AFP volume, currently
+ afpd doesn't do any checks for "wide symlinks".
+* FIX: Automatic AppleDouble conversion to EAs failing for directories.
+ Fixes bug #486.
+* FIX: dbd failed to convert appledouble files of symlinks.
+ Fixes bug #490.
+
Changes in 3.0.1
================
* NEW: afpd: Optional "ldap uuid encoding = string | ms-guid" parameter to
Changes in 2.2.1
================
- * NEW: afpd: disable continous service feature by default, new option
+ * NEW: afpd: disable continuous service feature by default, new option
-keepsessions to enable it
* NEW: configure option "--enable-redhat-systemd" for Fedora15 and later.
"--enable-redhat" is renamed "--enable-redhat-sysv".
- 3.1.3
-3.0.1
++3.1.3-ab
outlen = convert_charset(ch_to, ch_to, ch_mac, (char *)p, strlen((char *)p), (char *)q, sizeof(buffer) -2, &flags);
if ((size_t)-1 == outlen) {
/* it's not UTF8... */
- fprintf(stderr, "ERROR: conversion from '%s' to '%s' for '%s' in DID %u failed!!!\n",
- from_charset, to_charset, name, ntohl(cur_did));
+ fprintf(stderr, "ERROR: conversion from '%s' to '%s' for '%s' in DID %u failed!\n",
+ from_charset, to_charset, name, ntohl(cur_did));
return name;
}
{
DIR* startdir;
- if (NULL == (cdb = cnid_open (path, 0, cnid_type, 0, "localhost", "4700")) ) {
+ if (NULL == (cdb = cnid_open (path, 0, cnid_type, 0, "localhost", "4700", NULL, NULL)) ) {
fprintf (stderr, "ERROR: cannot open CNID database in '%s'\n", path);
fprintf (stderr, "ERROR: check the logs for reasons, aborting\n");
return -1;
fprintf (stdout, "\t-V\tPrint version and exit\n");
fprintf (stdout, "\t-h\tThis help screen\n\n");
fprintf (stdout, "WARNING:\n");
- fprintf (stdout, " Setting the wrong options might render your data unusable!!!\n");
+ fprintf (stdout, " Setting the wrong options might render your data unusable!\n");
fprintf (stdout, " Make sure you know what you are doing. Always backup your data first.\n\n");
fprintf (stdout, " It is *strongly* recommended to do a `dry run' first and to check the\n");
fprintf (stdout, " output for conversion errors.\n");
- fprintf (stdout, " USE AT YOUR OWN RISK!!!\n\n");
+ fprintf (stdout, " USE AT YOUR OWN RISK!\n\n");
}
#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"
afp_switch = postauth_switch;
switch (obj->afp_version) {
+ case 34:
case 33:
case 32:
#ifdef HAVE_ACLS
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
return AFPERR_NOTAUTH;
}
- 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 */
-
+ if (obj->cnx_cnt > obj->cnx_max) {
+ LOG(log_error, logtype_dsi, "login: too many connections, limit: %d", obj->cnx_max);
+ return AFPERR_MAXSESS;
}
- /* Basically if the user is in the admin group, we stay root */
+ LOG(log_note, logtype_afpd, "Login by %s (%s)",
+ pwd->pw_name, afp_versions[afp_version_index].av_name);
- if ((obj->ngroups = getgroups( 0, NULL )) < 0 ) {
- LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
+ if (set_groups(obj, pwd) != 0)
return AFPERR_BADUAM;
- }
-
- if ( NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
- LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
- 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);
}
}
if ( ibuf[0] != '\0' || ibuf[1] != '\0')
return AFPERR_PARAM;
ibuf += 2;
- len = MIN(sizeof(username), strlen(obj->username));
+ len = MIN(sizeof(username) - 1, strlen(obj->username));
memcpy(username, obj->username, len);
username[ len ] = '\0';
}
atalk_uuid_t uuid;
ret = getuuidfromname( obj->username, UUID_USER, uuid);
if (ret != 0) {
- LOG(log_info, logtype_afpd, "afp_getuserinfo: error getting UUID !");
+ LOG(log_info, logtype_afpd, "afp_getuserinfo: error getting UUID!");
return AFPERR_NOITEM;
}
LOG(log_debug, logtype_afpd, "afp_getuserinfo: got UUID: %s", uuid_bin2string(uuid));
}
/* load all of the modules */
-int auth_load(const char *path, const char *list)
+int auth_load(AFPObj *obj, const char *path, const char *list)
{
- char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p;
+ char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p, *last;
struct uam_mod *mod;
struct stat st;
size_t len;
if (!path || !*path || !list || (len = strlen(path)) > sizeof(name) - 2)
return -1;
+ LOG(log_debug, logtype_afpd, "auth_load: %s, %s", path, list);
+
strlcpy(buf, list, sizeof(buf));
- if ((p = strtok(buf, ", ")) == NULL)
+ if ((p = strtok_r(buf, ", ", &last)) == NULL)
return -1;
strcpy(name, path);
if ((stat(name, &st) == 0) && (mod = uam_load(name, p))) {
*/
if (stat(name, &st) == 0) {
- if ((mod = uam_load(name, p))) {
+ if ((mod = uam_load(obj, name, p))) {
uam_attach(&uam_modules, mod);
LOG(log_debug, logtype_afpd, "uam: %s loaded", p);
} else {
} else {
LOG(log_info, logtype_afpd, "uam: uam not found (status=%d)", stat(name, &st));
}
- p = strtok(NULL, ", ");
+ p = strtok_r(NULL, ", ", &last);
}
return 0;
static int status_server(char *data, const char *server, const struct afp_options *options)
{
char *start = data;
- char *Obj, *Type, *Zone;
+ char *Obj;
char buf[32];
uint16_t status;
size_t len;
return (data - begin);
}
-static bool append_directoryname(char **pdata,
- size_t offset,
- size_t *size,
- char* DirectoryNamesCount,
- size_t len,
- char *principal)
-{
- if (sizeof(uint8_t) + len > maxstatuslen - offset - *size) {
- LOG(log_error, logtype_afpd,
- "status:DirectoryNames: out of space for principal '%s' (len=%d)",
- principal, len);
- return false;
- } else if (len > 255) {
- LOG(log_error, logtype_afpd,
- "status:DirectoryNames: principal '%s' (len=%d) too long (max=255)",
- principal, len);
- return false;
- }
-
- LOG(log_info, logtype_afpd,
- "DirectoryNames[%d]=%s",
- *DirectoryNamesCount, principal);
-
- *DirectoryNamesCount += 1;
- char *data = *pdata;
- *data++ = len;
- strncpy(data, principal, len);
-
- *pdata += len + 1;
- *size += sizeof(uint8_t) + len;
-
- return true;
-}
/**
* DirectoryNamesCount offset: uint16_t
static size_t status_directorynames(char *data,
int *diroffset,
const DSI *dsi _U_,
- const struct afp_options *options _U_)
+ const struct afp_options *options)
{
char *begin = data;
uint16_t offset;
offset = ntohs(offset);
data += offset;
- char *DirectoryNamesCount = data++;
- char *DirectoryNames = data;
- size_t size = sizeof(uint8_t);
- *DirectoryNamesCount = 0;
-
- if (!uam_gss_enabled())
- goto offset_calc;
-
-#ifdef HAVE_KERBEROS
- krb5_context context;
- krb5_error_code ret;
- const char *error_msg;
-
- if (krb5_init_context(&context)) {
- LOG(log_error, logtype_afpd,
- "status:DirectoryNames failed to intialize a krb5_context");
- goto offset_calc;
- }
-
- krb5_keytab keytab;
- if ((ret = krb5_kt_default(context, &keytab)))
- goto krb5_error;
-
- // figure out which service principal to use
- krb5_keytab_entry entry;
- char *principal;
- if (options->k5service && options->fqdn && options->k5realm) {
- LOG(log_debug, logtype_afpd,
- "status:DirectoryNames: using service principal specified in options");
-
- krb5_principal service_principal;
- if ((ret = krb5_build_principal(context,
- &service_principal,
- strlen(options->k5realm),
- options->k5realm,
- options->k5service,
- options->fqdn,
- NULL)))
- goto krb5_error;
-
- // try to get the given service principal from keytab
- ret = krb5_kt_get_entry(context,
- keytab,
- service_principal,
- 0, // kvno - wildcard
- 0, // enctype - wildcard
- &entry);
- if (ret == KRB5_KT_NOTFOUND) {
- krb5_unparse_name(context, service_principal, &principal);
- LOG(log_error, logtype_afpd,
- "status:DirectoryNames: specified service principal '%s' not found in keytab",
- principal);
- // XXX: should this be krb5_xfree?
-#ifdef HAVE_KRB5_FREE_UNPARSED_NAME
- krb5_free_unparsed_name(context, principal);
-#else
- krb5_xfree(principal);
-#endif
- goto krb5_cleanup;
- }
- krb5_free_principal(context, service_principal);
- if (ret)
- goto krb5_error;
+ if (!uam_gss_enabled() || !options->k5principal) {
+ *data = 0;
+ data++;
} else {
- LOG(log_debug, logtype_afpd,
- "status:DirectoryNames: using first entry from keytab as service principal");
-
- krb5_kt_cursor cursor;
- if ((ret = krb5_kt_start_seq_get(context, keytab, &cursor)))
- goto krb5_error;
-
- ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
- krb5_kt_end_seq_get(context, keytab, &cursor);
- if (ret)
- goto krb5_error;
+ memcpy(data, options->k5principal, options->k5principal_buflen);
+ data += options->k5principal_buflen;
}
- krb5_unparse_name(context, entry.principal, &principal);
- krb5_kt_free_entry(context, &entry);
-
- append_directoryname(&data,
- offset,
- &size,
- DirectoryNamesCount,
- strlen(principal),
- principal);
-
- free(principal);
- goto krb5_cleanup;
-
-krb5_error:
- if (ret) {
- error_msg = krb5_get_error_message(context, ret);
- LOG(log_note, logtype_afpd, "Can't get principal from default keytab: %s",
- (char *)error_msg);
-#ifdef HAVE_KRB5_FREE_ERROR_MESSAGE
- krb5_free_error_message(context, error_msg);
-#else
- krb5_xfree(error_msg);
-#endif
- }
-
-krb5_cleanup:
- krb5_kt_close(context, keytab);
- krb5_free_context(context);
-#else
- if (!options->k5service || !options->fqdn || !options->k5realm)
- goto offset_calc;
-
- char principal[255];
- size_t len = snprintf(principal, sizeof(principal), "%s/%s@%s",
- options->k5service, options->fqdn, options->k5realm);
-
- append_directoryname(&data,
- offset,
- &size,
- DirectoryNamesCount,
- strlen(principal),
- principal);
-#endif // HAVE_KERBEROS
-
-offset_calc:
/* Calculate and store offset for UTF8ServerName */
*diroffset += sizeof(uint16_t);
offset = htons(data - begin);
uint16_t namelen;
size_t len;
char *begin = data;
- uint16_t offset, status;
+ uint16_t offset;
memcpy(&offset, data + *nameoffset, sizeof(offset));
offset = ntohs(offset);
char *servername_conf;
int header = 0;
char buf[1024], *p;
- FILE *fp = NULL, *randomp;
+ FILE *fp = NULL;
size_t len;
char *server_tmp;
if (len == 0) {
goto server_signature_auto; /* default */
} else if (len < 3) {
- LOG(log_warning, logtype_afpd, "WARNING: signature string %s is very short !", options->signatureopt);
+ LOG(log_warning, logtype_afpd, "WARNING: signature string %s is very short!", options->signatureopt);
goto server_signature_user;
} else if (len > 16) {
- LOG(log_warning, logtype_afpd, "WARNING: signature string %s is very long !", options->signatureopt);
+ LOG(log_warning, logtype_afpd, "WARNING: signature string %s is very long!", options->signatureopt);
len = 16;
goto server_signature_user;
} else {
#include <atalk/iniparser.h>
#include <atalk/unix.h>
#include <atalk/netatalk_conf.h>
+#include <atalk/server_ipc.h>
#ifdef CNID_DB
#include <atalk/cnid.h>
DIR *dir = NULL;
const struct dirent *entry;
const char *p;
- struct stat st;
long int links;
time_t now = time(NULL);
EC_NULL_LOG( infoplist = bformat("%s/%s/%s", vol->v_path, entry->d_name, "Info.plist") );
- if ((bandsize = get_tm_bandsize(cfrombstr(infoplist))) == -1)
+ if ((bandsize = get_tm_bandsize(cfrombstr(infoplist))) == -1) {
+ bdestroy(infoplist);
continue;
+ }
EC_NULL_LOG( bandsdir = bformat("%s/%s/%s/", vol->v_path, entry->d_name, "bands") );
- if ((links = get_tm_bands(cfrombstr(bandsdir))) == -1)
+ if ((links = get_tm_bands(cfrombstr(bandsdir))) == -1) {
+ bdestroy(infoplist);
+ bdestroy(bandsdir);
continue;
+ }
used += (links - 1) * bandsize;
LOG(log_debug, logtype_afpd, "getused(\"%s\"): bands: %" PRIu64 " bytes",
{
int spaceflag, rc;
uint32_t maxsize;
- VolSpace used;
#ifndef NO_QUOTA_SUPPORT
VolSpace qfree, qtotal;
#endif
return( AFP_OK );
}
-#define FCE_TM_DELTA 10 /* send notification every 10 seconds */
-void vol_fce_tm_event(void)
-{
- static time_t last;
- time_t now = time(NULL);
- struct vol *vol = getvolumes();
-
- if ((last + FCE_TM_DELTA) < now) {
- last = now;
- for ( ; vol; vol = vol->v_next ) {
- if (vol->v_flags & AFPVOL_TM)
- (void)fce_register_tm_size(vol->v_path, vol->v_tm_used + vol->v_appended);
- }
- }
-}
-
/* -----------------------
* set volume creation date
* avoid duplicate, well at least it tries
}
/* prior 2.1 only VOLPBIT_ATTR_RO is defined */
if (obj->afp_version > 20) {
- if (vol->v_cdb != NULL && (vol->v_cdb->flags & CNID_FLAG_PERSISTENT))
+ if (vol->v_cdb != NULL && (vol->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT))
ashort |= VOLPBIT_ATTR_FILEID;
ashort |= VOLPBIT_ATTR_CATSEARCH;
char *namebuf;
int vcnt;
size_t len;
+ uint32_t aint;
- load_volumes(obj, closevol);
+ load_volumes(obj, lv_none);
data = rbuf + 5;
- for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
+ for ( vcnt = 0, volume = getvolumes(); volume && vcnt < 255; volume = volume->v_next ) {
if (!(volume->v_flags & AFPVOL_NOSTAT)) {
struct maccess ma;
if (len == (size_t)-1)
continue;
+ /*
+ * There seems to be an undocumented limit on how big our reply can get
+ * before the client chokes and closes the connection.
+ * Testing with 10.8.4 found the limit at ~4600 bytes. Go figure.
+ */
+ if (((data + len + 3) - rbuf) > 4600)
+ break;
+
/* set password bit if there's a volume password */
*data = (volume->v_password) ? AFPSRVR_PASSWD : 0;
*rbuflen = data - rbuf;
data = rbuf;
if ( gettimeofday( &tv, NULL ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_getsrvrparms(%s): gettimeofday: %s", volume->v_path, strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_getsrvrparms: gettimeofday: %s", strerror(errno) );
*rbuflen = 0;
return AFPERR_PARAM;
}
- tv.tv_sec = AD_DATE_FROM_UNIX(tv.tv_sec);
- memcpy(data, &tv.tv_sec, sizeof( uint32_t));
+
+ aint = AD_DATE_FROM_UNIX(tv.tv_sec);
+ memcpy(data, &aint, sizeof( uint32_t));
data += sizeof( uint32_t);
*data = vcnt;
return( AFP_OK );
}
if ( NULL == (charset = find_charset_functions(volume->v_volcodepage)) || charset->flags & CHARSET_ICONV ) {
- LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems !!!!", volume->v_volcodepage);
+ LOG (log_warning, logtype_afpd, "WARNING: volume encoding %s is *not* supported by netatalk, expect problems!", volume->v_volcodepage);
}
if (!volume->v_maccodepage)
flags |= CNID_FLAG_NODEV;
}
- LOG(log_debug, logtype_afpd, "CNID server: %s:%s", volume->v_cnidserver, volume->v_cnidport);
-
- volume->v_cdb = cnid_open(volume->v_path,
- volume->v_umask,
- volume->v_cnidscheme,
- flags,
- volume->v_cnidserver,
- volume->v_cnidport);
+ volume->v_cdb = cnid_open(volume, volume->v_cnidscheme, flags);
if ( ! volume->v_cdb && ! (flags & CNID_FLAG_MEMORY)) {
/* The first attempt failed and it wasn't yet an attempt to open in-memory */
LOG(log_error, logtype_afpd, "Reopen volume %s using in memory temporary CNID DB.",
volume->v_path);
flags |= CNID_FLAG_MEMORY;
- volume->v_cdb = cnid_open (volume->v_path, volume->v_umask, "tdb", flags, NULL, NULL);
+ volume->v_cdb = cnid_open(volume, "tdb", flags);
#ifdef SERVERTEXT
/* kill ourself with SIGUSR2 aka msg pending */
if (volume->v_cdb) {
return (!volume->v_cdb)?-1:0;
}
+/*
+ * Send list of open volumes to afpd master via IPC
+ */
+static void server_ipc_volumes(AFPObj *obj)
+{
+ struct vol *volume, *vols;
+ volume = vols = getvolumes();
+ bstring openvolnames = bfromcstr("");
+ bool firstvol = true;
+
+ while (volume) {
+ if (volume->v_flags & AFPVOL_OPEN) {
+ if (!firstvol)
+ bcatcstr(openvolnames, ", ");
+ else
+ firstvol = false;
+ bcatcstr(openvolnames, volume->v_localname);
+ }
+ volume = volume->v_next;
+ }
+
+ ipc_child_write(obj->ipc_fd, IPC_VOLUMES, blength(openvolnames), bdata(openvolnames));
+ bdestroy(openvolnames);
+}
+
/* -------------------------
* we are the user here
*/
{
struct stat st;
char *volname;
- char *p;
struct vol *volume;
struct dir *dir;
int len, ret;
size_t namelen;
uint16_t bitmap;
- char path[ MAXPATHLEN + 1];
char *vol_uname;
- char *vol_mname;
+ char *vol_mname = NULL;
char *volname_tmp;
ibuf += 2;
if ((len + 1) & 1) /* pad to an even boundary */
ibuf++;
- load_volumes(obj, closevol);
+ load_volumes(obj, lv_none);
for ( volume = getvolumes(); volume; volume = volume->v_next ) {
if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) {
return AFPERR_PARAM;
}
- if ( NULL == getcwd(path, MAXPATHLEN)) {
- /* shouldn't be fatal but it will fail later */
- LOG(log_error, logtype_afpd, "afp_openvol(%s): volume pathlen too long", volume->v_path);
- return AFPERR_MISC;
- }
-
- /* Normalize volume path */
-#ifdef REALPATH_TAKES_NULL
- if ((volume->v_path = realpath(path, NULL)) == NULL)
- return AFPERR_MISC;
-#else
- if ((volume->v_path = malloc(MAXPATHLEN+1)) == NULL)
- return AFPERR_MISC;
- if (realpath(path, volume->v_path) == NULL) {
- free(volume->v_path);
- return AFPERR_MISC;
- }
- /* Safe some memory */
- char *tmp;
- if ((tmp = strdup(volume->v_path)) == NULL) {
- free(volume->v_path);
- return AFPERR_MISC;
- }
- free(volume->v_path);
- volume->v_path = tmp;
-#endif
-
if (volume_codepage(obj, volume) < 0) {
ret = AFPERR_MISC;
goto openvol_err;
goto openvol_err;
}
- if ((vol_uname = strrchr(path, '/')) == NULL)
- vol_uname = path;
- else if (*(vol_uname + 1) != '\0')
+ if ((vol_uname = strrchr(volume->v_path, '/')) == NULL)
+ vol_uname = volume->v_path;
+ else if (vol_uname[1] != '\0')
vol_uname++;
if ((dir = dir_new(vol_mname,
ret = AFPERR_MISC;
goto openvol_err;
}
- free(vol_mname);
volume->v_root = dir;
curdir = dir;
* fixing the trash at DID 17.
* FIXME (RL): should it be done inside a CNID backend ? (always returning Trash DID when asked) ?
*/
- if ((volume->v_cdb->flags & CNID_FLAG_PERSISTENT)) {
+ if ((volume->v_cdb->cnid_db_flags & CNID_FLAG_PERSISTENT)) {
/* FIXME find db time stamp */
if (cnid_getstamp(volume->v_cdb, volume->v_stamp, sizeof(volume->v_stamp)) < 0) {
}
const char *msg;
- if ((msg = iniparser_getstring(obj->iniconfig, volume->v_configname, "login message", NULL)) != NULL)
+ if ((msg = atalk_iniparser_getstring(obj->iniconfig, volume->v_configname, "login message", NULL)) != NULL)
setmessage(msg);
+ free(vol_mname);
+ server_ipc_volumes(obj);
return( AFP_OK );
}
cnid_close(volume->v_cdb);
volume->v_cdb = NULL;
}
+ free(vol_mname);
*rbuflen = 0;
return ret;
}
(void)chdir("/");
curdir = NULL;
closevol(obj, vol);
+ server_ipc_volumes(obj);
return( AFP_OK );
}
/*
- * $Id: cnid_cdb_close.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
*/
#ifdef HAVE_CONFIG_H
CNID_private *db;
if (!cdb) {
- LOG(log_error, logtype_afpd, "cnid_close called with NULL argument !");
+ LOG(log_error, logtype_afpd, "cnid_close called with NULL argument!");
return;
}
- if (!(db = cdb->_private)) {
+ if (!(db = cdb->cnid_db_private)) {
return;
}
db->db_didname->sync(db->db_didname, 0);
db->dbenv->close(db->dbenv, 0);
free(db);
- free(cdb->volpath);
free(cdb);
}
#include <atalk/logger.h>
#include <atalk/util.h>
#include <atalk/compat.h>
+#include <atalk/volume.h>
/* List of all registered modules. */
static struct list_head modules = ATALK_LIST_HEAD_INIT(modules);
/* Check if our module is already registered. */
list_for_each(ptr, &modules)
if (0 == strcmp(list_entry(ptr, cnid_module, db_list)->name, module->name)) {
- LOG(log_error, logtype_afpd, "Module with name [%s] is already registered !", module->name);
+ LOG(log_error, logtype_afpd, "Module with name [%s] is already registered!", module->name);
return;
}
}
/* Opens CNID database using particular back-end */
-struct _cnid_db *cnid_open(const char *volpath, mode_t mask, char *type, int flags,
- const char *cnidsrv, const char *cnidport)
+struct _cnid_db *cnid_open(struct vol *vol, char *type, int flags)
{
struct _cnid_db *db;
cnid_module *mod = NULL;
LOG(log_error, logtype_afpd, "seteuid failed %s", strerror(errno));
return NULL;
}
- if (cnid_dir(volpath, mask) < 0) {
+ if (cnid_dir(vol->v_path, vol->v_umask) < 0) {
if ( setegid(gid) < 0 || seteuid(uid) < 0) {
LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno));
exit(EXITERR_SYS);
}
}
- struct cnid_open_args args = {volpath, mask, flags, cnidsrv, cnidport};
+ struct cnid_open_args args = {
+ .cnid_args_flags = flags,
+ .cnid_args_vol = vol
+ };
+
db = mod->cnid_open(&args);
if ((mod->flags & CNID_FLAG_SETUID) && !(flags & CNID_FLAG_MEMORY)) {
}
if (NULL == db) {
- LOG(log_error, logtype_afpd, "Cannot open CNID db at [%s].", volpath);
+ LOG(log_error, logtype_afpd, "Cannot open CNID db at [%s].", vol->v_path);
return NULL;
}
- /* FIXME should module know about it ? */
- if ((flags & CNID_FLAG_NODEV)) {
- db->flags |= CNID_FLAG_NODEV;
- }
- db->flags |= mod->flags;
- if ((db->flags & CNID_FLAG_BLOCK)) {
+ db->cnid_db_flags |= mod->flags;
+ if (flags & CNID_FLAG_NODEV)
+ db->cnid_db_flags |= CNID_FLAG_NODEV;
+
+ if (db->cnid_db_flags & CNID_FLAG_BLOCK) {
sigemptyset(&sigblockset);
sigaddset(&sigblockset, SIGTERM);
sigaddset(&sigblockset, SIGHUP);
uint32_t flags;
if (NULL == db) {
- LOG(log_error, logtype_afpd, "Error: cnid_close called with NULL argument !");
+ LOG(log_error, logtype_afpd, "Error: cnid_close called with NULL argument!");
return;
}
/* cnid_close free db */
- flags = db->flags;
+ flags = db->cnid_db_flags;
block_signal(flags);
db->cnid_close(db);
unblock_signal(flags);
if (len == 0)
return CNID_INVALID;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = valide(cdb->cnid_add(cdb, st, did, name, len, hint));
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
{
int ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_delete(cdb, id);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
{
cnid_t ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = valide(cdb->cnid_get(cdb, did, name, len));
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
memcpy(buffer, &t, sizeof(time_t));
return 0;
}
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_getstamp(cdb, buffer, len);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
{
cnid_t ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = valide(cdb->cnid_lookup(cdb, st, did, name, len));
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
return -1;
}
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_find(cdb, name, namelen, buffer, buflen);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
{
char *ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_resolve(cdb, id, buffer, len);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
if (ret && !strcmp(ret, "..")) {
LOG(log_error, logtype_afpd, "cnid_resolve: name is '..', corrupted db? ");
ret = NULL;
{
int ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_update(cdb, id, st, did, name, len);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
{
cnid_t ret;
- block_signal(cdb->flags);
+ block_signal(cdb->cnid_db_flags);
ret = cdb->cnid_rebuild_add(cdb, st, did, name, len, hint);
- unblock_signal(cdb->flags);
+ unblock_signal(cdb->cnid_db_flags);
+ return ret;
+}
+
+/* --------------- */
+int cnid_wipe(struct _cnid_db *cdb)
+{
+ int ret = 0;
+
+ block_signal(cdb->cnid_db_flags);
+ if (cdb->cnid_wipe)
+ ret = cdb->cnid_wipe(cdb);
+ unblock_signal(cdb->cnid_db_flags);
return ret;
}
#include <atalk/logger.h>
#include <atalk/adouble.h>
#include <atalk/cnid.h>
-#include <atalk/cnid_dbd_private.h>
+#include <atalk/cnid_bdb_private.h>
#include <atalk/util.h>
+#include <atalk/volume.h>
#include "cnid_dbd.h"
}
/* --------------------- */
-static int init_tsock(CNID_private *db)
+static int init_tsock(CNID_bdb_private *db)
{
int fd;
- int len;
- struct iovec iov[2];
+ int len[DBD_NUM_OPEN_ARGS];
+ int iovecs;
+ struct iovec iov[DBD_NUM_OPEN_ARGS + 1] = {{0}};
+ struct vol *vol = db->vol;
+ ssize_t iovlen;
- LOG(log_debug, logtype_cnid, "init_tsock: BEGIN. Opening volume '%s', CNID Server: %s/%s",
- db->db_dir, db->cnidserver, db->cnidport);
+ LOG(log_debug, logtype_cnid, "connecting to CNID server: %s:%s",
+ vol->v_cnidserver, vol->v_cnidport);
- if ((fd = tsock_getfd(db->cnidserver, db->cnidport)) < 0)
+ if ((fd = tsock_getfd(vol->v_cnidserver, vol->v_cnidport)) < 0)
return -1;
- len = strlen(db->db_dir);
+ LOG(log_debug, logtype_cnid, "connecting volume '%s', path: %s, user: %s",
+ vol->v_configname, vol->v_path, vol->v_obj->username[0] ? vol->v_obj->username : "-");
+
+ iovecs = 1 + DBD_NUM_OPEN_ARGS - 1;
+
+ len[0] = strlen(vol->v_configname) + 1;
+ len[1] = strlen(vol->v_path) + 1;
+ len[2] = strlen(vol->v_obj->username);
+
+ iov[0].iov_base = &len[0];
+ iov[0].iov_len = DBD_NUM_OPEN_ARGS * sizeof(int);
- iov[0].iov_base = &len;
- iov[0].iov_len = sizeof(int);
+ iov[1].iov_base = vol->v_configname;
+ iov[1].iov_len = len[0];
- iov[1].iov_base = db->db_dir;
- iov[1].iov_len = len;
+ iov[2].iov_base = vol->v_path;
+ iov[2].iov_len = len[1];
- if (write_vec(fd, iov, len + sizeof(int), 2) != len + sizeof(int)) {
+ if (len[2] > 0) {
+ len[2] += 1;
+ iovecs++;
+ iov[3].iov_base = vol->v_obj->username;
+ iov[3].iov_len = len[2];
+ }
+
+ iovlen = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len + iov[3].iov_len;
+
+ if (write_vec(fd, iov, iovlen, iovecs) != iovlen) {
LOG(log_error, logtype_cnid, "init_tsock: Error/short write: %s", strerror(errno));
close(fd);
return -1;
}
/* --------------------- */
-static int send_packet(CNID_private *db, struct cnid_dbd_rqst *rqst)
+static int send_packet(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst)
{
struct iovec iov[2];
size_t towrite;
}
if (write_vec(db->fd, iov, towrite, vecs) != towrite) {
- LOG(log_warning, logtype_cnid, "send_packet: Error writev rqst (db_dir %s): %s",
- db->db_dir, strerror(errno));
+ LOG(log_warning, logtype_cnid, "send_packet: Error writev rqst (volume %s): %s",
+ db->vol->v_localname, strerror(errno));
return -1;
}
* assume send is non blocking
* if no answer after sometime (at least MAX_DELAY secondes) return an error
*/
-static int dbd_rpc(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
+static int dbd_rpc(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
{
ssize_t ret;
char *nametmp;
ret = readt(db->fd, rply, sizeof(struct cnid_dbd_rply), 0, ONE_DELAY);
if (ret != sizeof(struct cnid_dbd_rply)) {
- LOG(log_debug, logtype_cnid, "dbd_rpc: Error reading header from fd (db_dir %s): %s",
- db->db_dir, ret == -1 ? strerror(errno) : "closed");
+ LOG(log_debug, logtype_cnid, "dbd_rpc: Error reading header from fd (volume %s): %s",
+ db->vol->v_localname, ret == -1 ? strerror(errno) : "closed");
rply->name = nametmp;
return -1;
}
rply->name = nametmp;
if (rply->namelen && rply->namelen > len) {
LOG(log_error, logtype_cnid,
- "dbd_rpc: Error reading name (db_dir %s): %s name too long: %d. only wanted %d, garbage?",
- db->db_dir, rply->name, rply->namelen, len);
+ "dbd_rpc: Error reading name (volume %s): %s name too long: %d. only wanted %d, garbage?",
+ db->vol->v_localname, rply->name, rply->namelen, len);
return -1;
}
if (rply->namelen && (ret = readt(db->fd, rply->name, rply->namelen, 0, ONE_DELAY)) != (ssize_t)rply->namelen) {
- LOG(log_error, logtype_cnid, "dbd_rpc: Error reading name from fd (db_dir %s): %s",
- db->db_dir, ret == -1?strerror(errno):"closed");
+ LOG(log_error, logtype_cnid, "dbd_rpc: Error reading name from fd (volume %s): %s",
+ db->vol->v_localname, ret == -1?strerror(errno):"closed");
return -1;
}
}
/* -------------------- */
-static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
+static int transmit(CNID_bdb_private *db, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
{
time_t orig, t;
int clean = 1; /* no errors so far - to prevent sleep on first try */
- if (db->changed) {
- /* volume and db don't have the same timestamp
- */
- return -1;
- }
while (1) {
if (db->fd == -1) {
- struct cnid_dbd_rqst rqst_stamp;
- struct cnid_dbd_rply rply_stamp;
- char stamp[ADEDLEN_PRIVSYN];
-
LOG(log_maxdebug, logtype_cnid, "transmit: connecting to cnid_dbd ...");
if ((db->fd = init_tsock(db)) < 0) {
goto transmit_fail;
}
- dbd_initstamp(&rqst_stamp);
- memset(stamp, 0, ADEDLEN_PRIVSYN);
- rply_stamp.name = stamp;
- rply_stamp.namelen = ADEDLEN_PRIVSYN;
-
- if (dbd_rpc(db, &rqst_stamp, &rply_stamp) < 0)
- goto transmit_fail;
- if (dbd_reply_stamp(&rply_stamp ) < 0)
- goto transmit_fail;
-
if (db->notfirst) {
- LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd, comparing database stamps...");
- if (memcmp(stamp, db->stamp, ADEDLEN_PRIVSYN)) {
- LOG(log_error, logtype_cnid, "transmit: ... not the same db!");
- db->changed = 1;
- return -1;
- }
- LOG(log_debug7, logtype_cnid, "transmit: ... OK.");
+ LOG(log_debug7, logtype_cnid, "transmit: reconnected to cnid_dbd");
} else { /* db->notfirst == 0 */
db->notfirst = 1;
- if (db->client_stamp)
- memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
- memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
}
- LOG(log_debug, logtype_cnid, "transmit: attached to '%s', stamp: '%08lx'.",
- db->db_dir, *(uint64_t *)stamp);
+ LOG(log_debug, logtype_cnid, "transmit: attached to '%s'", db->vol->v_localname);
}
if (!dbd_rpc(db, rqst, rply)) {
LOG(log_maxdebug, logtype_cnid, "transmit: {done}");
if (errno == ECONNREFUSED) { /* errno carefully injected in tsock_getfd */
/* give up */
- LOG(log_error, logtype_cnid, "transmit: connection refused (db_dir %s)", db->db_dir);
+ LOG(log_error, logtype_cnid, "transmit: connection refused (volume %s)", db->vol->v_localname);
return -1;
}
if (!clean) { /* don't sleep if just got disconnected by cnid server */
time(&t);
if (t - orig > MAX_DELAY) {
- LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (db_dir %s) timed out.", db->db_dir);
+ LOG(log_error, logtype_cnid, "transmit: Request to dbd daemon (volume %s) timed out.", db->vol->v_localname);
return -1;
}
/* sleep a little before retry */
}
/* ---------------------- */
-static struct _cnid_db *cnid_dbd_new(const char *volpath)
+static struct _cnid_db *cnid_dbd_new(struct vol *vol)
{
struct _cnid_db *cdb;
if ((cdb = (struct _cnid_db *)calloc(1, sizeof(struct _cnid_db))) == NULL)
return NULL;
- if ((cdb->volpath = strdup(volpath)) == NULL) {
- free(cdb);
- return NULL;
- }
-
- cdb->flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
-
+ cdb->cnid_db_vol = vol;
+ cdb->cnid_db_flags = CNID_FLAG_PERSISTENT | CNID_FLAG_LAZY_INIT;
cdb->cnid_add = cnid_dbd_add;
cdb->cnid_delete = cnid_dbd_delete;
cdb->cnid_get = cnid_dbd_get;
cdb->cnid_update = cnid_dbd_update;
cdb->cnid_rebuild_add = cnid_dbd_rebuild_add;
cdb->cnid_close = cnid_dbd_close;
-
+ cdb->cnid_wipe = cnid_dbd_wipe;
return cdb;
}
/* ---------------------- */
struct _cnid_db *cnid_dbd_open(struct cnid_open_args *args)
{
- CNID_private *db = NULL;
+ CNID_bdb_private *db = NULL;
struct _cnid_db *cdb = NULL;
- if (!args->dir) {
- return NULL;
- }
-
- if ((cdb = cnid_dbd_new(args->dir)) == NULL) {
+ if ((cdb = cnid_dbd_new(args->cnid_args_vol)) == NULL) {
LOG(log_error, logtype_cnid, "cnid_open: Unable to allocate memory for database");
return NULL;
}
- if ((db = (CNID_private *)calloc(1, sizeof(CNID_private))) == NULL) {
+ if ((db = (CNID_bdb_private *)calloc(1, sizeof(CNID_bdb_private))) == NULL) {
LOG(log_error, logtype_cnid, "cnid_open: Unable to allocate memory for database");
goto cnid_dbd_open_fail;
}
- cdb->_private = db;
+ cdb->cnid_db_private = db;
- /* We keep a copy of the directory in the db structure so that we can
- transparently reconnect later. */
- strcpy(db->db_dir, args->dir);
- db->magic = CNID_DB_MAGIC;
db->fd = -1;
- db->cnidserver = strdup(args->cnidserver);
- db->cnidport = strdup(args->cnidport);
+ db->vol = args->cnid_args_vol;
- LOG(log_debug, logtype_cnid, "cnid_dbd_open: Finished initializing cnid dbd module for volume '%s'", db->db_dir);
+ LOG(log_debug, logtype_cnid, "Finished initializing CNID dbd module for volume '%s'",
+ args->cnid_args_vol->v_localname);
return cdb;
cnid_dbd_open_fail:
- if (cdb != NULL) {
- if (cdb->volpath != NULL) {
- free(cdb->volpath);
- }
+ if (cdb != NULL)
free(cdb);
- }
if (db != NULL)
free(db);
/* ---------------------- */
void cnid_dbd_close(struct _cnid_db *cdb)
{
- CNID_private *db;
+ CNID_bdb_private *db;
if (!cdb) {
- LOG(log_error, logtype_cnid, "cnid_close called with NULL argument !");
+ LOG(log_error, logtype_cnid, "cnid_close called with NULL argument!");
return;
}
- if ((db = cdb->_private) != NULL) {
- LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'", db->db_dir);
+ if ((db = cdb->cnid_db_private) != NULL) {
+ LOG(log_debug, logtype_cnid, "closing database connection for volume '%s'", db->vol->v_localname);
if (db->fd >= 0)
close(db->fd);
free(db);
}
- free(cdb->volpath);
free(cdb);
return;
}
+/**
+ * Get the db stamp
+ **/
+static int cnid_dbd_stamp(CNID_bdb_private *db)
+{
+ struct cnid_dbd_rqst rqst_stamp;
+ struct cnid_dbd_rply rply_stamp;
+ char stamp[ADEDLEN_PRIVSYN];
+
+ dbd_initstamp(&rqst_stamp);
+ memset(stamp, 0, ADEDLEN_PRIVSYN);
+ rply_stamp.name = stamp;
+ rply_stamp.namelen = ADEDLEN_PRIVSYN;
+
+ if (transmit(db, &rqst_stamp, &rply_stamp) < 0)
+ return -1;
+ if (dbd_reply_stamp(&rply_stamp ) < 0)
+ return -1;
+
+ if (db->client_stamp)
+ memcpy(db->client_stamp, stamp, ADEDLEN_PRIVSYN);
+ memcpy(db->stamp, stamp, ADEDLEN_PRIVSYN);
+
+ return 0;
+}
+
/* ---------------------- */
cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st,
cnid_t did, const char *name, size_t len, cnid_t hint)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
cnid_t id;
- if (!cdb || !(db = cdb->_private) || !st || !name) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
LOG(log_error, logtype_cnid, "cnid_add: Parameter error");
errno = CNID_ERR_PARAM;
return CNID_INVALID;
RQST_RESET(&rqst);
rqst.op = CNID_DBD_OP_ADD;
- if (!(cdb->flags & CNID_FLAG_NODEV)) {
+ if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
rqst.dev = st->st_dev;
}
rqst.name = name;
rqst.namelen = len;
- LOG(log_debug, logtype_cnid, "cnid_dbd_add: CNID: %u, name: '%s', inode: 0x%llx, type: %d (0=file, 1=dir)",
- ntohl(did), name, (long long)st->st_ino, rqst.type);
+ LOG(log_debug, logtype_cnid, "cnid_dbd_add: CNID: %u, name: '%s', dev: 0x%llx, inode: 0x%llx, type: %s",
+ ntohl(did), name, (long long)rqst.dev, (long long)st->st_ino, rqst.type ? "dir" : "file");
rply.namelen = 0;
if (transmit(db, &rqst, &rply) < 0) {
/* ---------------------- */
cnid_t cnid_dbd_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t len)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
cnid_t id;
- if (!cdb || !(db = cdb->_private) || !name) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !name) {
LOG(log_error, logtype_cnid, "cnid_dbd_get: Parameter error");
errno = CNID_ERR_PARAM;
return CNID_INVALID;
/* ---------------------- */
char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
char *name;
- if (!cdb || !(db = cdb->_private) || !id || !(*id)) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !id || !(*id)) {
LOG(log_error, logtype_cnid, "cnid_resolve: Parameter error");
errno = CNID_ERR_PARAM;
return NULL;
return name;
}
-/* ---------------------- */
+/**
+ * Caller passes buffer where we will store the db stamp
+ **/
int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len)
{
- CNID_private *db;
+ CNID_bdb_private *db;
- if (!cdb || !(db = cdb->_private) || len != ADEDLEN_PRIVSYN) {
+ if (!cdb || !(db = cdb->cnid_db_private) || len != ADEDLEN_PRIVSYN) {
LOG(log_error, logtype_cnid, "cnid_getstamp: Parameter error");
errno = CNID_ERR_PARAM;
return -1;
}
db->client_stamp = buffer;
db->stamp_size = len;
- memset(buffer,0, len);
- return 0;
+
+ return cnid_dbd_stamp(db);
}
/* ---------------------- */
cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did,
const char *name, size_t len)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
cnid_t id;
- if (!cdb || !(db = cdb->_private) || !st || !name) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !st || !name) {
LOG(log_error, logtype_cnid, "cnid_lookup: Parameter error");
errno = CNID_ERR_PARAM;
return CNID_INVALID;
RQST_RESET(&rqst);
rqst.op = CNID_DBD_OP_LOOKUP;
- if (!(cdb->flags & CNID_FLAG_NODEV)) {
+ if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
rqst.dev = st->st_dev;
}
/* ---------------------- */
int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
int count;
- if (!cdb || !(db = cdb->_private) || !name) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !name) {
LOG(log_error, logtype_cnid, "cnid_find: Parameter error");
errno = CNID_ERR_PARAM;
return CNID_INVALID;
int cnid_dbd_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st,
cnid_t did, const char *name, size_t len)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
- if (!cdb || !(db = cdb->_private) || !id || !st || !name) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name) {
LOG(log_error, logtype_cnid, "cnid_update: Parameter error");
errno = CNID_ERR_PARAM;
return -1;
RQST_RESET(&rqst);
rqst.op = CNID_DBD_OP_UPDATE;
rqst.cnid = id;
- if (!(cdb->flags & CNID_FLAG_NODEV)) {
+ if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
rqst.dev = st->st_dev;
}
rqst.ino = st->st_ino;
cnid_t cnid_dbd_rebuild_add(struct _cnid_db *cdb, const struct stat *st,
cnid_t did, const char *name, size_t len, cnid_t hint)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
cnid_t id;
- if (!cdb || !(db = cdb->_private) || !st || !name || hint == CNID_INVALID) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !st || !name || hint == CNID_INVALID) {
LOG(log_error, logtype_cnid, "cnid_rebuild_add: Parameter error");
errno = CNID_ERR_PARAM;
return CNID_INVALID;
RQST_RESET(&rqst);
rqst.op = CNID_DBD_OP_REBUILD_ADD;
- if (!(cdb->flags & CNID_FLAG_NODEV)) {
+ if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) {
rqst.dev = st->st_dev;
}
/* ---------------------- */
int cnid_dbd_delete(struct _cnid_db *cdb, const cnid_t id)
{
- CNID_private *db;
+ CNID_bdb_private *db;
struct cnid_dbd_rqst rqst;
struct cnid_dbd_rply rply;
- if (!cdb || !(db = cdb->_private) || !id) {
+ if (!cdb || !(db = cdb->cnid_db_private) || !id) {
LOG(log_error, logtype_cnid, "cnid_delete: Parameter error");
errno = CNID_ERR_PARAM;
return -1;
}
}
+int cnid_dbd_wipe(struct _cnid_db *cdb)
+{
+ CNID_bdb_private *db;
+ struct cnid_dbd_rqst rqst;
+ struct cnid_dbd_rply rply;
+
+ if (!cdb || !(db = cdb->cnid_db_private)) {
+ LOG(log_error, logtype_cnid, "cnid_wipe: Parameter error");
+ errno = CNID_ERR_PARAM;
+ return -1;
+ }
+
+ LOG(log_debug, logtype_cnid, "cnid_dbd_wipe");
+
+ RQST_RESET(&rqst);
+ rqst.op = CNID_DBD_OP_WIPE;
+ rqst.cnid = 0;
+
+ rply.namelen = 0;
+ if (transmit(db, &rqst, &rply) < 0) {
+ errno = CNID_ERR_DB;
+ return -1;
+ }
+
+ if (rply.result != CNID_DBD_RES_OK) {
+ errno = CNID_ERR_DB;
+ return -1;
+ }
+ LOG(log_debug, logtype_cnid, "cnid_dbd_wipe: ok");
+
+ return cnid_dbd_stamp(db);
+}
+
struct _cnid_module cnid_dbd_module = {
"dbd",
dnl Kitchen sink for configuration macros
+dnl Check for docbook
+AC_DEFUN(AX_CHECK_DOCBOOK, [
+ # It's just rude to go over the net to build
+ XSLTPROC_FLAGS=--nonet
+ DOCBOOK_ROOT=
+ XSLTPROC_WORKS=no
+
+ AC_ARG_WITH(docbook,
+ AS_HELP_STRING(
+ [--with-docbook],
+ [Path to Docbook XSL directory]
+ ),
+ [DOCBOOK_ROOT=$withval]
+ )
+
+ if test -n "$DOCBOOK_ROOT" ; then
+ AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,)
+ if test -n "$XSLTPROC"; then
+ AC_MSG_CHECKING([whether xsltproc works])
+ DB_FILE="$DOCBOOK_ROOT/html/docbook.xsl"
+ $XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<book id="test">
+</book>
+END
+ if test "$?" = 0; then
+ XSLTPROC_WORKS=yes
+ fi
+ AC_MSG_RESULT($XSLTPROC_WORKS)
+ fi
+ fi
+
+ AC_MSG_CHECKING([whether to build Docbook documentation])
+ AC_MSG_RESULT($XSLTPROC_WORKS)
+
+ AM_CONDITIONAL(HAVE_XSLTPROC, test x"$XSLTPROC_WORKS" = x"yes")
+ AC_SUBST(XSLTPROC_FLAGS)
+ AC_SUBST(DOCBOOK_ROOT)
+ AC_SUBST(XSLTPROC)
+])
+
+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], [
+ atalk_cv_with_dbus=no
+
+ AC_ARG_WITH(afpstats,
+ AS_HELP_STRING(
+ [--with-afpstats],
+ [Enable AFP statistics via dbus (default: enabled if dbus found)]
+ ),,[withval=auto]
+ )
+
+ if test x"$withval" != x"no" ; then
+ PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1, have_dbus=yes, have_dbus=no)
+ PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1, have_dbus_glib=yes, have_dbus_glib=no)
+ PKG_CHECK_MODULES(DBUS_GTHREAD, gthread-2.0, have_dbus_gthread=yes, have_dbus_gthread=no)
+ if test x$have_dbus_glib = xyes -a x$have_dbus = xyes -a x$have_dbus_gthread = xyes ; then
+ saved_CFLAGS=$CFLAGS
+ saved_LIBS=$LIBS
+ CFLAGS="$CFLAGS $DBUS_GLIB_CFLAGS"
+ LIBS="$LIBS $DBUS_GLIB_LIBS"
+ AC_CHECK_FUNC([dbus_g_bus_get_private], [atalk_cv_with_dbus=yes], [atalk_cv_with_dbus=no])
+ CFLAGS="$saved_CFLAGS"
+ LIBS="$saved_LIBS"
+ fi
+ fi
+
+ if test x"$withval" = x"yes" -a x"$atalk_cv_with_dbus" = x"no"; then
+ AC_MSG_ERROR([afpstats requested but dbus-glib not found])
+ fi
+
+ AC_ARG_WITH(
+ dbus-sysconf-dir,
+ [AS_HELP_STRING([--with-dbus-sysconf-dir=PATH],[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'
+ )
+ DBUS_SYS_DIR=""
+ if test x$atalk_cv_with_dbus = xyes ; then
+ AC_DEFINE(HAVE_DBUS_GLIB, 1, [Define if support for dbus-glib was found])
+ DBUS_SYS_DIR="$ac_cv_dbus_sysdir"
+ fi
+
+ AC_SUBST(DBUS_SYS_DIR)
+ 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$atalk_cv_with_dbus = xyes)
+])
+
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
+ ac_cv_tracker_pkg_version_default=0.12
+ ac_cv_tracker_pkg_version_min=0.12
+
+ dnl Tracker SPARQL
+ AC_ARG_WITH([tracker-pkgconfig-version],
+ [AS_HELP_STRING([--with-tracker-pkgconfig-version=VERSION],[Version suffix of the Tracker SPARQL and tracker-miner pkg in pkg-config (default: 0.12)])],
+ [ac_cv_tracker_pkg_version=$withval],
+ [ac_cv_tracker_pkg_version=$ac_cv_tracker_pkg_version_default]
+ )
+
+ AC_ARG_WITH([tracker-prefix],
+ [AS_HELP_STRING([--with-tracker-prefix=PATH],[Prefix of Tracker installation (default: none)])],
+ [ac_cv_tracker_prefix=$withval],
+ [ac_cv_tracker_prefix="`pkg-config --variable=prefix tracker-sparql-$ac_cv_tracker_pkg_version`"]
+ )
+
+ AC_ARG_VAR([PKG_CONFIG_PATH], [Path to additional pkg-config packages])
+ PKG_CHECK_MODULES([TRACKER], [tracker-sparql-$ac_cv_tracker_pkg_version >= $ac_cv_tracker_pkg_version_min], [ac_cv_have_tracker_sparql=yes], [ac_cv_have_tracker_sparql=no])
+ PKG_CHECK_MODULES([TRACKER_MINER], [tracker-miner-$ac_cv_tracker_pkg_version >= $ac_cv_tracker_pkg_version_min], [ac_cv_have_tracker_miner=yes], [ac_cv_have_tracker_miner=no])
+
+ if test x"$ac_cv_have_tracker_sparql" = x"no" -o x"$ac_cv_have_tracker_miner" = x"no" ; then
+ if test x"$need_tracker_sparql" = 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_DEFINE(HAVE_TRACKER_MINER, 1, [Define if Tracker miner library is available])
+ AC_DEFINE_UNQUOTED(TRACKER_PREFIX, ["$ac_cv_tracker_prefix"], [Path to Tracker])
+ AC_DEFINE([DBUS_DAEMON_PATH], ["/bin/dbus-daemon"], [Path to dbus-daemon])
+ fi
+
+ if test x"$ac_cv_have_tracker_sparql" = x"yes" ; then
+ ac_cv_have_tracker=yes
+ fi
+
+ AC_SUBST(TRACKER_CFLAGS)
+ AC_SUBST(TRACKER_LIBS)
+ AC_SUBST(TRACKER_MINER_CFLAGS)
+ AC_SUBST(TRACKER_MINER_LIBS)
+ AM_CONDITIONAL(HAVE_TRACKER_SPARQL, [test x"$ac_cv_have_tracker_sparql" = x"yes"])
+])
+
dnl Whether to disable bundled libevent
AC_DEFUN([AC_NETATALK_LIBEVENT], [
- use_bundled_libevent=no
- AC_MSG_CHECKING([whether to use bundled or installed libevent])
+ AC_MSG_CHECKING([whether to use bundled libevent])
+ AC_ARG_WITH(
+ libevent,
+ [AS_HELP_STRING([--with-libevent],[whether to use the bundled libevent (default: yes)])],
+ use_bundled_libevent=$withval,
+ use_bundled_libevent=yes
+ )
AC_ARG_WITH(
libevent-header,
[AS_HELP_STRING([--with-libevent-header],[path to libevent header files])],
- LIBEVENT_CFLAGS=-I$withval,
- use_bundled_libevent=yes
+ [use_bundled_libevent=no; LIBEVENT_CFLAGS=-I$withval]
)
AC_ARG_WITH(
libevent-lib,
- [AS_HELP_STRING([--with-libevent-lib],[path to libevent header library])],
- LIBEVENT_LDFLAGS=-L$withval,
- use_bundled_libevent=yes
+ [AS_HELP_STRING([--with-libevent-lib],[path to libevent library])],
+ [use_bundled_libevent=no; LIBEVENT_LDFLAGS=-L$withval]
)
+ if test x"$LIBEVENT_CFLAGS" = x"-Iyes" -o x"$LIBEVENT_LDFLAGS" = x"-Lyes" ; then
+ AC_MSG_ERROR([--with-libevent requires a path])
+ fi
AC_MSG_RESULT([$use_bundled_libevent])
if test x"$use_bundled_libevent" = x"yes" ; then
AC_CONFIG_SUBDIRS([libevent])
AM_CONDITIONAL(USE_BUILTIN_LIBEVENT, test x"$use_bundled_libevent" = x"yes")
])
+dnl Whether to disable bundled tdb
+AC_DEFUN([AC_NETATALK_TDB], [
+ AC_ARG_WITH(
+ tdb,
+ [AS_HELP_STRING([--with-tdb],[whether to use the bundled tdb (default: yes)])],
+ use_bundled_tdb=$withval,
+ use_bundled_tdb=yes
+ )
+ AC_MSG_CHECKING([whether to use bundled tdb])
+ AC_MSG_RESULT([$use_bundled_tdb])
+
+ if test x"$use_bundled_tdb" = x"yes" ; then
+ AC_DEFINE(USE_BUILTIN_TDB, 1, [Use internal tbd])
+ else
+ if test -z "$TDB_LIBS" ; then
+ PKG_CHECK_MODULES(TDB, tdb, , [AC_MSG_ERROR([couldn't find tdb with pkg-config])])
+ fi
+ use_bundled_tdb=no
+ fi
+
+ AC_SUBST(TDB_CFLAGS)
+ AC_SUBST(TDB_LIBS)
+ AM_CONDITIONAL(USE_BUILTIN_TDB, test x"$use_bundled_tdb" = x"yes")
+])
+
dnl Filesystem Hierarchy Standard (FHS) compatibility
AC_DEFUN([AC_NETATALK_FHS], [
AC_MSG_CHECKING([whether to use Filesystem Hierarchy Standard (FHS) compatibility])
use_pam_so=yes
AC_DEFINE(FHS_COMPATIBILITY, 1, [Define if you want compatibily with the FHS])
AC_MSG_RESULT([yes])
+ atalk_cv_fhs_compat=yes
else
AC_MSG_RESULT([no])
+ atalk_cv_fhs_compat=no
fi
],[
AC_MSG_RESULT([no])
- ]
-)])
+ atalk_cv_fhs_compat=no
+])])
+
+dnl netatalk lockfile path
+AC_DEFUN([AC_NETATALK_LOCKFILE], [
+ AC_MSG_CHECKING([netatalk lockfile path])
+ AC_ARG_WITH(
+ lockfile,
+ [AS_HELP_STRING([--with-lockfile=PATH],[Path of netatalk lockfile])],
+ ac_cv_netatalk_lock=$withval,
+ ac_cv_netatalk_lock=""
+ )
+ if test -z "$ac_cv_netatalk_lock" ; then
+ ac_cv_netatalk_lock=/var/spool/locks/netatalk
+ if test x"$atalk_cv_fhs_compat" = x"yes" ; then
+ ac_cv_netatalk_lock=/var/run/netatalk.pid
+ else
+ case "$host_os" in
+ *freebsd*)
+ ac_cv_netatalk_lock=/var/spool/lock/netatalk
+ ;;
+ *netbsd*|*openbsd*)
+ ac_cv_netatalk_lock=/var/run/netatalk.pid
+ ;;
+ *linux*)
+ ac_cv_netatalk_lock=/var/lock/netatalk
+ ;;
+ esac
+ fi
+ fi
+ AC_DEFINE_UNQUOTED(PATH_NETATALK_LOCK, ["$ac_cv_netatalk_lock"], [netatalk lockfile path])
+ AC_SUBST(PATH_NETATALK_LOCK, ["$ac_cv_netatalk_lock"])
+ AC_MSG_RESULT([$ac_cv_netatalk_lock])
+])
dnl 64bit platform check
AC_DEFUN([AC_NETATALK_64BIT_LIBS], [
)
])
-dnl Check for optional sysv initscript install
+dnl Check for optional initscript install
AC_DEFUN([AC_NETATALK_INIT_STYLE], [
AC_ARG_WITH(init-style,
[ --with-init-style use OS specific init config [[redhat-sysv|redhat-systemd|suse-sysv|suse-systemd|gentoo|netbsd|debian|solaris|systemd]]],
;;
"redhat-sysv")
AC_MSG_RESULT([enabling redhat-style sysv initscript support])
+ ac_cv_init_dir="/etc/rc.d/init.d"
;;
"redhat-systemd")
AC_MSG_RESULT([enabling redhat-style systemd support])
+ ac_cv_init_dir="/usr/lib/systemd/system"
;;
"suse")
AC_MSG_ERROR([--with-init-style=suse is obsoleted. Use suse-sysv or suse-systemd.])
;;
"suse-sysv")
AC_MSG_RESULT([enabling suse-style sysv initscript support])
+ ac_cv_init_dir="/etc/init.d"
;;
"suse-systemd")
AC_MSG_RESULT([enabling suse-style systemd support (>=openSUSE12.1)])
+ ac_cv_init_dir="/usr/lib/systemd/system"
;;
"gentoo")
AC_MSG_RESULT([enabling gentoo-style initscript support])
+ ac_cv_init_dir="/etc/init.d"
;;
"netbsd")
AC_MSG_RESULT([enabling netbsd-style initscript support])
+ ac_cv_init_dir="/etc/rc.d"
;;
"debian")
AC_MSG_RESULT([enabling debian-style initscript support])
+ ac_cv_init_dir="/etc/init.d"
;;
"solaris")
AC_MSG_RESULT([enabling solaris-style SMF support])
+ ac_cv_init_dir="/lib/svc/manifest/network/"
;;
"systemd")
AC_MSG_RESULT([enabling general systemd support])
+ ac_cv_init_dir="/usr/lib/systemd/system"
;;
"none")
AC_MSG_RESULT([disabling init-style support])
+ ac_cv_init_dir="none"
;;
*)
AC_MSG_ERROR([illegal init-style])
AM_CONDITIONAL(USE_SYSTEMD, test x$init_style = xsystemd || test x$init_style = xredhat-systemd || test x$init_style = xsuse-systemd)
AM_CONDITIONAL(USE_UNDEF, test x$init_style = xnone)
+ AC_ARG_WITH(init-dir,
+ [ --with-init-dir=PATH path to OS specific init directory],
+ ac_cv_init_dir="$withval", ac_cv_init_dir="$ac_cv_init_dir"
+ )
+ INIT_DIR="$ac_cv_init_dir"
+ AC_SUBST(INIT_DIR, ["$ac_cv_init_dir"])
])
dnl OS specific configuration
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)
AC_DEFINE(SOLARIS, 1, [Solaris compatibility macro])
AC_DEFINE(_XOPEN_SOURCE, 600, [Solaris compilation environment])
AC_DEFINE(__EXTENSIONS__, 1, [Solaris compilation environment])
- CFLAGS="-I\$(top_srcdir)/sys/generic $CFLAGS"
need_dash_r=yes
init_style=solaris
-
- solaris_module=no
- AC_MSG_CHECKING([if we can build Solaris kernel module])
- if test -x /usr/ccs/bin/ld && test x"$netatalk_cv_ddp_enabled" = x"yes" ; then
- solaris_module=yes
- fi
- AC_MSG_RESULT([$solaris_module])
-
- COMPILE_64BIT_KMODULE=no
- KCFLAGS=""
- KLDFLAGS=""
- COMPILE_KERNEL_GCC=no
-
- if test "$solaris_module" = "yes"; then
- dnl Solaris kernel module stuff
- AC_MSG_CHECKING([if we have to build a 64bit kernel module])
-
- # check for isainfo, if not found it has to be a 32 bit kernel (<=2.6)
- if test -x /usr/bin/isainfo; then
- # check for 64 bit platform
- if isainfo -kv | grep '^64-bit'; then
- COMPILE_64BIT_KMODULE=yes
- fi
- fi
-
- AC_MSG_RESULT([$COMPILE_64BIT_KMODULE])
-
- if test "${GCC}" = yes; then
- COMPILE_KERNEL_GCC=yes
- if test "$COMPILE_64BIT_KMODULE" = yes; then
-
- AC_MSG_CHECKING([if we can build a 64bit kernel module])
-
- case `$CC --version 2>/dev/null` in
- [[12]].* | 3.0.*)
- COMPILE_64BIT_KMODULE=no
- COMPILE_KERNEL_GCC=no
- solaris_module=no;;
- *)
- # use for 64 bit
- KCFLAGS="-m64"
- #KLDFLAGS="-melf64_sparc"
- KLDFLAGS="-64";;
- esac
-
- AC_MSG_RESULT([$COMPILE_64BIT_KMODULE])
-
- else
- KCFLAGS=""
- KLDFLAGS=""
- fi
- KCFLAGS="$KCFLAGS -D_KERNEL -Wall -Wstrict-prototypes"
- else
- if test "$COMPILE_64BIT_KMODULE" = yes; then
- # use Sun CC (for a 64-bit kernel, uncomment " -xarch=v9 -xregs=no%appl ")
- KCFLAGS="-xarch=v9 -xregs=no%appl"
- KLDFLAGS="-64"
- else
- KCFLAGS=""
- KLDFLAGS=""
- fi
- KCFLAGS="-D_KERNEL $KCFLAGS -mno-app-regs -munaligned-doubles -fpcc-struct-return"
- fi
-
- AC_CACHE_CHECK([for timeout_id_t],netatalk_cv_HAVE_TIMEOUT_ID_T,[
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[\
-#include <sys/stream.h>
-#include <sys/ddi.h>]], [[\
-timeout_id_t dummy;
-]])],[netatalk_cv_HAVE_TIMEOUT_ID_T=yes],[netatalk_cv_HAVE_TIMEOUT_ID_T=no])])
-
- AC_DEFINE(HAVE_TIMEOUT_ID_T, test x"$netatalk_cv_HAVE_TIMEOUT_ID" = x"yes", [define for timeout_id_t])
- fi
-
- AC_SUBST(COMPILE_KERNEL_GCC)
- AC_SUBST(COMPILE_64BIT_KMODULE)
- AC_SUBST(KCFLAGS)
- AC_SUBST(KLDFLAGS)
fi
dnl Whether to run ldconfig after installing libraries
save_LIBS="$LIBS"
CFLAGS="$KRB5_CFLAGS"
LIBS="$KRB5_LIBS"
-AC_CHECK_FUNCS([krb5_free_unparsed_name krb5_free_error_message])
+AC_CHECK_FUNCS([krb5_free_unparsed_name krb5_free_error_message krb5_free_keytab_entry_contents krb5_kt_free_entry])
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
])
AC_DEFUN([AC_NETATALK_LDAP], [
AC_MSG_CHECKING(for LDAP (necessary for client-side ACL visibility))
AC_ARG_WITH(ldap,
- [AS_HELP_STRING([--with-ldap],
+ [AS_HELP_STRING([--with-ldap[[=PATH]]],
[LDAP support (default=auto)])],
netatalk_cv_ldap=$withval,
netatalk_cv_ldap=auto
AC_SUBST(LDAP_LDFLAGS)
AC_SUBST(LDAP_LIBS)
CFLAGS="$save_CFLAGS"
-LDLFLAGS="$save_LDLFLAGS"
+LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
])
dnl Check for ACL support
AC_DEFUN([AC_NETATALK_ACL], [
+ac_cv_have_acls=no
AC_MSG_CHECKING(whether to support ACLs)
AC_ARG_WITH(acls,
[AS_HELP_STRING([--with-acls],
if test x"$with_acl_support" = x"no"; then
AC_MSG_RESULT(Disabling ACL support)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support should be built in])
-else
- with_acl_support=yes
fi
-if test x"$with_acl_support" = x"yes" ; then
- AC_MSG_NOTICE(checking whether ACL support is available:)
+# Platform specific checks
+if test x"$with_acl_support" != x"no" ; then
case "$host_os" in
- *sysv5*)
- AC_MSG_NOTICE(Using UnixWare ACLs)
- AC_DEFINE(HAVE_UNIXWARE_ACLS,1,[Whether UnixWare ACLs are available])
- ;;
*solaris*)
AC_MSG_NOTICE(Using solaris ACLs)
- AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether solaris ACLs are available])
+ AC_DEFINE(HAVE_SOLARIS_ACLS,1,[Whether Solaris ACLs are available])
+ AC_DEFINE(HAVE_NFSV4_ACLS,1,[Whether NFSv4 ACLs are available])
ACL_LIBS="$ACL_LIBS -lsec"
+ ac_cv_have_acls=yes
;;
- *hpux*)
- AC_MSG_NOTICE(Using HPUX ACLs)
- AC_DEFINE(HAVE_HPUX_ACLS,1,[Whether HPUX ACLs are available])
- ;;
- *irix*)
- AC_MSG_NOTICE(Using IRIX ACLs)
- AC_DEFINE(HAVE_IRIX_ACLS,1,[Whether IRIX ACLs are available])
- ;;
- *aix*)
- AC_MSG_NOTICE(Using AIX ACLs)
- AC_DEFINE(HAVE_AIX_ACLS,1,[Whether AIX ACLs are available])
- ;;
- *osf*)
- AC_MSG_NOTICE(Using Tru64 ACLs)
- AC_DEFINE(HAVE_TRU64_ACLS,1,[Whether Tru64 ACLs are available])
- ACL_LIBS="$ACL_LIBS -lpacl"
+ *freebsd*)
+ AC_MSG_NOTICE(checking whether libsunacl is available)
+ sunacl_include_path="/usr/local/include"
+ sunacl_lib_path="/usr/local/lib"
+
+ save_CPPFLAGS=$CPPFLAGS
+ save_LDFLAGS=$LDFLAGS
+ save_LIBS=$LIBS
+
+ CPPFLAGS="-I$sunacl_include_path $CPPFLAGS"
+ AC_CHECK_HEADER([sunacl.h])
+
+ LDFLAGS="-L$sunacl_lib_path $LDFLAGS"
+ AC_CHECK_LIB([sunacl], [acl])
+
+ if test x"$ac_cv_header_sunacl_h" = x"yes" -a x"$ac_cv_lib_sunacl_acl" = x"yes" ; then
+ AC_MSG_NOTICE([Enabling support for ZFS ACLs using libsunacl])
+ ac_cv_have_acls=yes
+ CFLAGS="-I$sunacl_include_path $CFLAGS"
+ ACL_LIBS="$ACL_LIBS -L$sunacl_lib_path -lsunacl"
+ AC_DEFINE(HAVE_FREEBSD_SUNACL, 1, [Whether FreeBSD ZFS ACLs with libsunacl are available])
+ AC_DEFINE(HAVE_NFSV4_ACLS,1,[Whether NFSv4 ACLs are available])
+ else
+ AC_MSG_NOTICE([libsunacl not found, disabling ZFS ACL support])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
;;
- *darwin*)
- AC_MSG_NOTICE(ACLs on Darwin currently not supported)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
+ esac
+fi
+
+if test x"$with_acl_support" != x"no" -a x"$ac_cv_have_acls" != x"yes" ; then
+ # Runtime checks for POSIX ACLs
+ AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
+ case "$host_os" in
+ *linux*)
+ AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
;;
- *)
- AC_CHECK_LIB(acl,acl_get_file,[ACL_LIBS="$ACL_LIBS -lacl"])
- case "$host_os" in
- *linux*)
- AC_CHECK_LIB(attr,getxattr,[ACL_LIBS="$ACL_LIBS -lattr"])
- ;;
- esac
- AC_CACHE_CHECK([for POSIX ACL support],netatalk_cv_HAVE_POSIX_ACLS,[
+ esac
+
+ AC_CACHE_CHECK([for POSIX ACL support],netatalk_cv_HAVE_POSIX_ACLS,[
+ acl_LIBS=$LIBS
+ LIBS="$LIBS $ACL_LIBS"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <sys/types.h>
+ #include <sys/acl.h>
+ ]], [[
+ acl_t acl;
+ int entry_id;
+ acl_entry_t *entry_p;
+ return acl_get_entry(acl, entry_id, entry_p);
+ ]])],
+ [netatalk_cv_HAVE_POSIX_ACLS=yes; ac_cv_have_acls=yes],
+ [netatalk_cv_HAVE_POSIX_ACLS=no; ac_cv_have_acls=no]
+ )
+ LIBS=$acl_LIBS
+ ])
+
+ if test x"$netatalk_cv_HAVE_POSIX_ACLS" = x"yes"; then
+ AC_MSG_NOTICE(Using POSIX ACLs)
+ AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
+
+ AC_CACHE_CHECK([for acl_get_perm_np],netatalk_cv_HAVE_ACL_GET_PERM_NP,[
acl_LIBS=$LIBS
LIBS="$LIBS $ACL_LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/acl.h>
]], [[
- acl_t acl;
- int entry_id;
- acl_entry_t *entry_p;
- return acl_get_entry(acl, entry_id, entry_p);
- ]])],[netatalk_cv_HAVE_POSIX_ACLS=yes],[netatalk_cv_HAVE_POSIX_ACLS=no
- with_acl_support=no])
+ acl_permset_t permset_d;
+ acl_perm_t perm;
+ return acl_get_perm_np(permset_d, perm);
+ ]])],[netatalk_cv_HAVE_ACL_GET_PERM_NP=yes],[netatalk_cv_HAVE_ACL_GET_PERM_NP=no])
LIBS=$acl_LIBS
])
- if test x"$netatalk_cv_HAVE_POSIX_ACLS" = x"yes"; then
- AC_MSG_NOTICE(Using POSIX ACLs)
- AC_DEFINE(HAVE_POSIX_ACLS,1,[Whether POSIX ACLs are available])
- AC_CACHE_CHECK([for acl_get_perm_np],netatalk_cv_HAVE_ACL_GET_PERM_NP,[
- acl_LIBS=$LIBS
- LIBS="$LIBS $ACL_LIBS"
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #include <sys/types.h>
- #include <sys/acl.h>
- ]], [[
- acl_permset_t permset_d;
- acl_perm_t perm;
- return acl_get_perm_np(permset_d, perm);
- ]])],[netatalk_cv_HAVE_ACL_GET_PERM_NP=yes],[netatalk_cv_HAVE_ACL_GET_PERM_NP=no])
- LIBS=$acl_LIBS
- ])
- if test x"$netatalk_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
- AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
- fi
-
-
- AC_CACHE_CHECK([for acl_from_mode], netatalk_cv_HAVE_ACL_FROM_MODE,[
- acl_LIBS=$LIBS
- LIBS="$LIBS $ACL_LIBS"
- AC_CHECK_FUNCS(acl_from_mode,
- [netatalk_cv_HAVE_ACL_FROM_MODE=yes],
- [netatalk_cv_HAVE_ACL_FROM_MODE=no])
- LIBS=$acl_LIBS
- ])
- if test x"netatalk_cv_HAVE_ACL_FROM_MODE" = x"yes"; then
- AC_DEFINE(HAVE_ACL_FROM_MODE,1,[Whether acl_from_mode() is available])
- fi
+ if test x"$netatalk_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
+ AC_DEFINE(HAVE_ACL_GET_PERM_NP,1,[Whether acl_get_perm_np() is available])
+ fi
- else
- AC_MSG_NOTICE(ACL support is not avaliable)
- AC_DEFINE(HAVE_NO_ACLS,1,[Whether no ACLs support is available])
+ AC_CACHE_CHECK([for acl_from_mode], netatalk_cv_HAVE_ACL_FROM_MODE,[
+ acl_LIBS=$LIBS
+ LIBS="$LIBS $ACL_LIBS"
+ AC_CHECK_FUNCS(acl_from_mode,
+ [netatalk_cv_HAVE_ACL_FROM_MODE=yes],
+ [netatalk_cv_HAVE_ACL_FROM_MODE=no]
+ )
+ LIBS=$acl_LIBS
+ ])
+ if test x"netatalk_cv_HAVE_ACL_FROM_MODE" = x"yes"; then
+ AC_DEFINE(HAVE_ACL_FROM_MODE,1,[Whether acl_from_mode() is available])
fi
- ;;
- esac
+ fi
fi
-if test x"$with_acl_support" = x"yes" ; then
- AC_CHECK_HEADERS([acl/libacl.h])
- AC_DEFINE(HAVE_ACLS,1,[Whether ACLs support is available])
- AC_SUBST(ACL_LIBS)
+if test x"$ac_cv_have_acls" = x"no" ; then
+ if test x"$with_acl_support" = x"yes" ; then
+ AC_MSG_ERROR(ACL support requested but not found)
+ else
+ AC_MSG_NOTICE(ACL support is not avaliable)
+ fi
+else
+ AC_CHECK_HEADERS([acl/libacl.h])
+ AC_DEFINE(HAVE_ACLS,1,[Whether ACLs support is available])
fi
+AC_SUBST(ACL_LIBS)
])
dnl Check for Extended Attributes support
AC_DEFUN([AC_NETATALK_SENDFILE], [
netatalk_cv_search_sendfile=yes
AC_ARG_ENABLE(sendfile,
- [ --disable-sendfile disable sendfile syscall],
+ [ --disable-sendfile disable sendfile syscall],
[if test x"$enableval" = x"no"; then
netatalk_cv_search_sendfile=no
fi]
fi
])
+dnl ------ Check for recvfile() --------
+AC_DEFUN([AC_NETATALK_RECVFILE], [
+case "$host_os" in
+*linux*)
+ AC_CHECK_FUNCS([splice], [atalk_cv_use_recvfile=yes])
+ ;;
+
+*)
+ ;;
+
+esac
+
+if test x"$atalk_cv_use_recvfile" = x"yes"; then
+ AC_DEFINE(WITH_RECVFILE, 1, [Whether recvfile should be used])
+fi
+])
+
dnl --------------------- Check if realpath() takes NULL
AC_DEFUN([AC_NETATALK_REALPATH], [
AC_CACHE_CHECK([if the realpath function allows a NULL argument],
-dnl $Id: quota-check.m4,v 1.6 2005-07-20 23:58:21 didg Exp $
dnl Autoconf macro to check for quota support
dnl FIXME: This is in now way complete.
AC_DEFUN([AC_NETATALK_CHECK_QUOTA], [
AC_ARG_ENABLE(quota,
- [ --enable-quota Turn on quota support (default=auto)])
+ [ --enable-quota Turn on quota support (default=auto)])
if test x$enable_quota != xno; then
QUOTA_LIBS=""