From 8162db07e8c4e7ac6044932d754f9eda0096ee09 Mon Sep 17 00:00:00 2001 From: HAT Date: Wed, 3 Oct 2012 02:05:54 +0900 Subject: [PATCH 001/117] do realpath() immediately after parsing "path" parameter in order to cope with symlink --- NEWS | 4 +++ libatalk/util/netatalk_conf.c | 68 ++++++++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 0c2f5580..81863591 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Changes in 3.0.2 +================ +* FIX: "path" parameter value may contain symlink. + Changes in 3.0.1 ================ * NEW: afpd: Optional "ldap uuid encoding = string | ms-guid" parameter to diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 0c0a9416..fe166dd2 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -953,9 +953,9 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) EC_INIT; static int regexerr = -1; static regex_t reg; - char path[MAXPATHLEN + 1]; + char *path; char volname[AFPVOL_U8MNAMELEN + 1]; - char tmp[MAXPATHLEN + 1]; + char tmp[MAXPATHLEN + 1], tmp2[MAXPATHLEN + 1]; const char *preset, *default_preset, *p, *basedir; char *q, *u; int i; @@ -1017,7 +1017,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) strlcpy(tmp, p, MAXPATHLEN); } - if (volxlate(obj, path, sizeof(path) - 1, tmp, pwent, NULL, NULL) == NULL) + if (volxlate(obj, tmp2, sizeof(tmp2) - 1, tmp, pwent, NULL, NULL) == NULL) continue; /* do variable substitution for volume name */ @@ -1035,11 +1035,35 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) } else { strlcpy(tmp, secname, AFPVOL_U8MNAMELEN); } - if (volxlate(obj, volname, sizeof(volname) - 1, tmp, pwent, path, NULL) == NULL) + if (volxlate(obj, volname, sizeof(volname) - 1, tmp, pwent, tmp2, NULL) == NULL) continue; preset = iniparser_getstring(obj->iniconfig, secname, "vol preset", NULL); + /* Normalize volume path */ +#ifdef REALPATH_TAKES_NULL + if ((path = realpath(tmp2, NULL)) == NULL) { + LOG(log_error, logtype_afpd, "readvolfile() cannot resolve path \"%s\"", tmp2); + continue; + } +#else + if ((path = malloc(MAXPATHLEN+1)) == NULL) + continue; + if (realpath(tmp2, path) == NULL) { + free(path); + LOG(log_error, logtype_afpd, "readvolfile() cannot resolve path \"%s\"", tmp2); + continue; + } + /* Safe some memory */ + char *tmp3; + if ((tmp3 = strdup(path)) == NULL) { + free(path); + continue; + } + free(path); + path = tmp3; +#endif + creatvol(obj, pwent, secname, volname, path, preset ? preset : default_preset ? default_preset : NULL); } @@ -1263,7 +1287,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) const struct passwd *pw; char volname[AFPVOL_U8MNAMELEN + 1]; char abspath[MAXPATHLEN + 1]; - char volpath[MAXPATHLEN + 1]; + char volpath[MAXPATHLEN + 1], *realvolpath; char tmpbuf[MAXPATHLEN + 1]; const char *secname, *basedir, *p = NULL, *subpath = NULL, *subpathconfig; char *user = NULL, *prw; @@ -1344,9 +1368,11 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) /* (6) */ if (subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) { + /* if (!subpath || strncmp(subpathconfig, subpath, strlen(subpathconfig)) != 0) { EC_FAIL; } + */ strlcat(tmpbuf, subpathconfig, MAXPATHLEN); strlcat(tmpbuf, "/", MAXPATHLEN); } @@ -1356,23 +1382,47 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) if (volxlate(obj, volpath, sizeof(volpath) - 1, tmpbuf, pw, NULL, NULL) == NULL) return NULL; + /* Normalize volume path */ +#ifdef REALPATH_TAKES_NULL + if ((realvolpath = realpath(volpath, NULL)) == NULL) { + LOG(log_error, logtype_afpd, "getvolbypath() cannot resolve path \"%s\"", volpath); + return NULL; + } +#else + if ((realvolpath = malloc(MAXPATHLEN+1)) == NULL) + return NULL; + if (realpath(volpath, realvolpath) == NULL) { + free(realvolpath); + LOG(log_error, logtype_afpd, "getvolbypath() cannot resolve path \"%s\"", volpath); + return NULL; + } + /* Safe some memory */ + char *tmpbuf2; + if ((tmpbuf2 = strdup(realvolpath)) == NULL) { + free(realvolpath); + return NULL; + } + free(realvolpath); + realvolpath = tmpbuf2; +#endif + EC_NULL( pw = getpwnam(user) ); - LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\"): user: %s, homedir: %s => volpath: \"%s\"", - path, user, pw->pw_dir, volpath); + LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\"): user: %s, homedir: %s => realvolpath: \"%s\"", + path, user, pw->pw_dir, realvolpath); /* do variable substitution for volume name */ p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "home name", "$u's home"); if (strstr(p, "$u") == NULL) p = "$u's home"; strlcpy(tmpbuf, p, AFPVOL_U8MNAMELEN); - EC_NULL_LOG( volxlate(obj, volname, sizeof(volname) - 1, tmpbuf, pw, volpath, NULL) ); + EC_NULL_LOG( volxlate(obj, volname, sizeof(volname) - 1, tmpbuf, pw, realvolpath, NULL) ); const char *preset, *default_preset; default_preset = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol preset", NULL); preset = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "vol preset", NULL); - vol = creatvol(obj, pw, INISEC_HOMES, volname, volpath, preset ? preset : default_preset ? default_preset : NULL); + vol = creatvol(obj, pw, INISEC_HOMES, volname, realvolpath, preset ? preset : default_preset ? default_preset : NULL); EC_CLEANUP: if (user) From b45fbee17198dc7cfe4a95f8f8ee94b11c345a37 Mon Sep 17 00:00:00 2001 From: HAT Date: Wed, 3 Oct 2012 20:08:45 +0900 Subject: [PATCH 002/117] new function realpath_safe() --- libatalk/util/netatalk_conf.c | 86 ++++++++++++++++------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index fe166dd2..cd550be0 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -67,6 +67,42 @@ static int have_uservol = 0; /* whether there's generic user home share in confi static struct vol *Volumes = NULL; static uint16_t lastvid = 0; + +/* + * Normalize volume path + */ +static char *realpath_safe(const char *path) +{ + char *resolved_path; + +#ifdef REALPATH_TAKES_NULL + if ((resolved_path = realpath(path, NULL)) == NULL) { + LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); + return NULL; + } + return resolved_path; + +#else +if ((resolved_path = malloc(MAXPATHLEN+1)) == NULL) + return NULL; + if (realpath(path, resolved_path) == NULL) { + free(resolved_path); + LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); + return NULL; + } + /* Safe some memory */ + char *tmp; + if ((tmp = strdup(resolved_path)) == NULL) { + free(resolved_path); + return NULL; + } + free(resolved_path); + resolved_path = tmp; + return resolved_path; +#endif +} + + /* * Get a volumes UUID from the config file. * If there is none, it is generated and stored there. @@ -953,7 +989,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) EC_INIT; static int regexerr = -1; static regex_t reg; - char *path; + char *realvolpath; char volname[AFPVOL_U8MNAMELEN + 1]; char tmp[MAXPATHLEN + 1], tmp2[MAXPATHLEN + 1]; const char *preset, *default_preset, *p, *basedir; @@ -1040,31 +1076,10 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) preset = iniparser_getstring(obj->iniconfig, secname, "vol preset", NULL); - /* Normalize volume path */ -#ifdef REALPATH_TAKES_NULL - if ((path = realpath(tmp2, NULL)) == NULL) { - LOG(log_error, logtype_afpd, "readvolfile() cannot resolve path \"%s\"", tmp2); - continue; - } -#else - if ((path = malloc(MAXPATHLEN+1)) == NULL) - continue; - if (realpath(tmp2, path) == NULL) { - free(path); - LOG(log_error, logtype_afpd, "readvolfile() cannot resolve path \"%s\"", tmp2); + if ((realvolpath = realpath_safe(tmp2)) == NULL) continue; - } - /* Safe some memory */ - char *tmp3; - if ((tmp3 = strdup(path)) == NULL) { - free(path); - continue; - } - free(path); - path = tmp3; -#endif - creatvol(obj, pwent, secname, volname, path, preset ? preset : default_preset ? default_preset : NULL); + creatvol(obj, pwent, secname, volname, realvolpath, preset ? preset : default_preset ? default_preset : NULL); } EC_CLEANUP: @@ -1382,29 +1397,8 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) if (volxlate(obj, volpath, sizeof(volpath) - 1, tmpbuf, pw, NULL, NULL) == NULL) return NULL; - /* Normalize volume path */ -#ifdef REALPATH_TAKES_NULL - if ((realvolpath = realpath(volpath, NULL)) == NULL) { - LOG(log_error, logtype_afpd, "getvolbypath() cannot resolve path \"%s\"", volpath); + if ((realvolpath = realpath_safe(volpath)) == NULL) return NULL; - } -#else - if ((realvolpath = malloc(MAXPATHLEN+1)) == NULL) - return NULL; - if (realpath(volpath, realvolpath) == NULL) { - free(realvolpath); - LOG(log_error, logtype_afpd, "getvolbypath() cannot resolve path \"%s\"", volpath); - return NULL; - } - /* Safe some memory */ - char *tmpbuf2; - if ((tmpbuf2 = strdup(realvolpath)) == NULL) { - free(realvolpath); - return NULL; - } - free(realvolpath); - realvolpath = tmpbuf2; -#endif EC_NULL( pw = getpwnam(user) ); From 94afc9de97f2118bd28f6971bdec009e4e380b7a Mon Sep 17 00:00:00 2001 From: HAT Date: Wed, 3 Oct 2012 23:23:55 +0900 Subject: [PATCH 003/117] fix: basedir regex symlink problem --- NEWS | 2 ++ libatalk/util/netatalk_conf.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 81863591..e203bd41 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Changes in 3.0.2 ================ * FIX: "path" parameter value may contain symlink. +* FIX: "basedir regex" was never able to treat symlink. + If /home -> /usr/home, set "basedir regex = /usr/home". Changes in 3.0.1 ================ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index cd550be0..6d252e83 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -989,6 +989,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) EC_INIT; static int regexerr = -1; static regex_t reg; + char *realpw_dir; char *realvolpath; char volname[AFPVOL_U8MNAMELEN + 1]; char tmp[MAXPATHLEN + 1], tmp2[MAXPATHLEN + 1]; @@ -1022,6 +1023,8 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) if (pwent->pw_dir == NULL || STRCMP("", ==, pwent->pw_dir)) /* no user home */ continue; + if ((realpw_dir = realpath_safe(pwent->pw_dir)) == NULL) + continue; /* check if user home matches our "basedir regex" */ if ((basedir = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "basedir regex", NULL)) == NULL) { @@ -1036,13 +1039,13 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) LOG(log_debug, logtype_default, "readvolfile: bad basedir regex: %s", errbuf); } - if (regexec(®, pwent->pw_dir, 1, match, 0) == REG_NOMATCH) { + if (regexec(®, realpw_dir, 1, match, 0) == REG_NOMATCH) { LOG(log_debug, logtype_default, "readvolfile: user home \"%s\" doesn't match basedir regex \"%s\"", - pwent->pw_dir, basedir); + realpw_dir, basedir); continue; } - strlcpy(tmp, pwent->pw_dir, MAXPATHLEN); + strlcpy(tmp, realpw_dir, MAXPATHLEN); strlcat(tmp, "/", MAXPATHLEN); if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) strlcat(tmp, p, MAXPATHLEN); From 0b7c10583488e175c58829759029dad65dc0ebc7 Mon Sep 17 00:00:00 2001 From: HAT Date: Thu, 4 Oct 2012 22:30:33 +0900 Subject: [PATCH 004/117] remove realpath() in afp_openvol() because it has already been done, when parsing afp.conf --- etc/afpd/volume.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 3b02b239..ecc9bf13 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -771,26 +771,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t 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 + strlcpy(volume->v_path, path, MAXPATHLEN); if (volume_codepage(obj, volume) < 0) { ret = AFPERR_MISC; From f4436fa67103541b7ea5aee14bfe748ae19f6caa Mon Sep 17 00:00:00 2001 From: HAT Date: Thu, 4 Oct 2012 22:32:13 +0900 Subject: [PATCH 005/117] ignore duplicated or nested volume path --- NEWS | 1 + libatalk/util/netatalk_conf.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index e203bd41..2b943b34 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ Changes in 3.0.2 ================ +* UPD: ignore duplicated or nested volume path. * FIX: "path" parameter value may contain symlink. * FIX: "basedir regex" was never able to treat symlink. If /home -> /usr/home, set "basedir regex = /usr/home". diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 6d252e83..e577ac56 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -598,6 +598,8 @@ static struct vol *creatvol(AFPObj *obj, { EC_INIT; struct vol *volume = NULL; + char current_path[MAXPATHLEN+1], another_path[MAXPATHLEN+1]; + size_t current_pathlen, another_pathlen; int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; char *tmpname; ucs2_t u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2]; @@ -620,9 +622,22 @@ static struct vol *creatvol(AFPObj *obj, } /* Once volumes are loaded, we never change options again, we just delete em when they're removed from afp.conf */ + /* Duplicated or nested volume is ignored */ + strlcpy(current_path, path, MAXPATHLEN); + current_pathlen = strlcat(current_path, "/", MAXPATHLEN); for (struct vol *vol = Volumes; vol; vol = vol->v_next) { - if (STRCMP(path, ==, vol->v_path)) { - LOG(log_debug, logtype_afpd, "createvol('%s'): already loaded", name); + strlcpy(another_path, vol->v_path, MAXPATHLEN); + another_pathlen = strlcat(another_path, "/", MAXPATHLEN); + if ( 0 == strncmp(current_path, another_path, MIN(current_pathlen, another_pathlen))) { + if (current_pathlen == another_pathlen) { + if ( 0 == strcmp(name ,vol->v_localname)) { + LOG(log_debug, logtype_afpd, "createvol('%s'): already loaded", name); + } else { + LOG(log_error, logtype_afpd, "paths are duplicated - \"%s\"", path); + } + } else { + LOG(log_error, logtype_afpd, "paths are nested - \"%s\" and \"%s\"", path, vol->v_path); + } vol->v_deleted = 0; volume = vol; goto EC_CLEANUP; From 816eb343ee3cbab7a3db76ceec16df5957cf9376 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 13:51:34 +0200 Subject: [PATCH 006/117] Remove unneccessary call to getcwd() getcwd() was called after a chdir(vol->v_path) in order to copy the path to vol->v_path. But as v_path is now already set in netatalk_conf.c when parsing the volumes config, this is not neccessary anymore. --- etc/afpd/volume.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index ecc9bf13..7e70c65d 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -686,7 +686,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t int len, ret; size_t namelen; uint16_t bitmap; - char path[ MAXPATHLEN + 1]; char *vol_uname; char *vol_mname; char *volname_tmp; @@ -765,14 +764,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t 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; - } - - strlcpy(volume->v_path, path, MAXPATHLEN); - if (volume_codepage(obj, volume) < 0) { ret = AFPERR_MISC; goto openvol_err; @@ -801,9 +792,9 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t 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, From 0b526b9add47c62c94e4be7f82ab125a5588ebb1 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 14:13:31 +0200 Subject: [PATCH 007/117] Move realpath_safe() to libatalk/util/unix.c and make it a global function --- include/atalk/util.h | 1 + libatalk/util/netatalk_conf.c | 36 ----------------------------------- libatalk/util/unix.c | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/include/atalk/util.h b/include/atalk/util.h index c5b23ee6..9ff6813f 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -182,6 +182,7 @@ extern int lchdir(const char *dir); extern void randombytes(void *buf, int n); extern int daemonize(int nochdir, int noclose); extern int run_cmd(const char *cmd, char **cmd_argv); +extern char *realpath_safe(const char *path); /****************************************************************** * cnid.c diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index e577ac56..48f60783 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -67,42 +67,6 @@ static int have_uservol = 0; /* whether there's generic user home share in confi static struct vol *Volumes = NULL; static uint16_t lastvid = 0; - -/* - * Normalize volume path - */ -static char *realpath_safe(const char *path) -{ - char *resolved_path; - -#ifdef REALPATH_TAKES_NULL - if ((resolved_path = realpath(path, NULL)) == NULL) { - LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); - return NULL; - } - return resolved_path; - -#else -if ((resolved_path = malloc(MAXPATHLEN+1)) == NULL) - return NULL; - if (realpath(path, resolved_path) == NULL) { - free(resolved_path); - LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); - return NULL; - } - /* Safe some memory */ - char *tmp; - if ((tmp = strdup(resolved_path)) == NULL) { - free(resolved_path); - return NULL; - } - free(resolved_path); - resolved_path = tmp; - return resolved_path; -#endif -} - - /* * Get a volumes UUID from the config file. * If there is none, it is generated and stored there. diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 56c3e168..0e8fcab6 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -342,3 +342,36 @@ int gmem(gid_t gid, int ngroups, gid_t *groups) } return( 0 ); } + +/* + * realpath() replacement that always allocates storage for returned path + */ +char *realpath_safe(const char *path) +{ + char *resolved_path; + +#ifdef REALPATH_TAKES_NULL + if ((resolved_path = realpath(path, NULL)) == NULL) { + LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); + return NULL; + } + return resolved_path; +#else + if ((resolved_path = malloc(MAXPATHLEN+1)) == NULL) + return NULL; + if (realpath(path, resolved_path) == NULL) { + free(resolved_path); + LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path); + return NULL; + } + /* Safe some memory */ + char *tmp; + if ((tmp = strdup(resolved_path)) == NULL) { + free(resolved_path); + return NULL; + } + free(resolved_path); + resolved_path = tmp; + return resolved_path; +#endif +} From 1f9ecb322ea2fc83c231102f5d4885277ee71650 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 14:42:38 +0200 Subject: [PATCH 008/117] Avoid excessive path copying when checking for duplicate or nested paths --- libatalk/util/netatalk_conf.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 48f60783..4a309485 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -562,7 +562,6 @@ static struct vol *creatvol(AFPObj *obj, { EC_INIT; struct vol *volume = NULL; - char current_path[MAXPATHLEN+1], another_path[MAXPATHLEN+1]; size_t current_pathlen, another_pathlen; int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; char *tmpname; @@ -586,15 +585,14 @@ static struct vol *creatvol(AFPObj *obj, } /* Once volumes are loaded, we never change options again, we just delete em when they're removed from afp.conf */ - /* Duplicated or nested volume is ignored */ - strlcpy(current_path, path, MAXPATHLEN); - current_pathlen = strlcat(current_path, "/", MAXPATHLEN); + + /* Check for duplicated or nested volumes */ + current_pathlen = strlen(path); for (struct vol *vol = Volumes; vol; vol = vol->v_next) { - strlcpy(another_path, vol->v_path, MAXPATHLEN); - another_pathlen = strlcat(another_path, "/", MAXPATHLEN); - if ( 0 == strncmp(current_path, another_path, MIN(current_pathlen, another_pathlen))) { + another_pathlen = strlen(vol->v_path); + if (strncmp(path, vol->v_path, MIN(current_pathlen, another_pathlen)) == 0) { if (current_pathlen == another_pathlen) { - if ( 0 == strcmp(name ,vol->v_localname)) { + if ( 0 == strcmp(name, vol->v_localname)) { LOG(log_debug, logtype_afpd, "createvol('%s'): already loaded", name); } else { LOG(log_error, logtype_afpd, "paths are duplicated - \"%s\"", path); From 380c7b3065531b134159eb305f0b3c3dbe2d62f0 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 14:52:25 +0200 Subject: [PATCH 009/117] Add ABI file --- libatalk/libatalk-3.0.1dev.abi | 550 +++++++++++++++++++++++++++++++++ 1 file changed, 550 insertions(+) create mode 100644 libatalk/libatalk-3.0.1dev.abi diff --git a/libatalk/libatalk-3.0.1dev.abi b/libatalk/libatalk-3.0.1dev.abi new file mode 100644 index 00000000..645af2b1 --- /dev/null +++ b/libatalk/libatalk-3.0.1dev.abi @@ -0,0 +1,550 @@ +acl_ldap_readconfig: int (dictionary *) +ad_close: int (struct adouble *, int) +ad_convert: int (const char *, const struct stat *, const struct vol *, const char **) +ad_copy_header: int (struct adouble *, struct adouble *) +add_cachebyname: int (const char *, const uuidp_t, const uuidtype_t, const long unsigned int) +add_cachebyuuid: int (uuidp_t, const char *, uuidtype_t, const long unsigned int) +add_charset: charset_t (const char *) +ad_dir: char *(const char *) +ad_dtruncate: int (struct adouble *, const off_t) +adflags2logstr: const char *(int) +ad_flush: int (struct adouble *) +ad_forcegetid: uint32_t (struct adouble *) +adf_pread: ssize_t (struct ad_fd *, void *, size_t, off_t) +adf_pwrite: ssize_t (struct ad_fd *, const void *, size_t, off_t) +ad_getattr: int (const struct adouble *, uint16_t *) +ad_getdate: int (const struct adouble *, unsigned int, uint32_t *) +ad_getentryoff: off_t (const struct adouble *, int) +ad_getfuid: uid_t (void) +ad_getid: uint32_t (struct adouble *, const dev_t, const ino_t, const cnid_t, const void *) +ad_hf_mode: mode_t (mode_t) +ad_init: void (struct adouble *, const struct vol *) +ad_init_old: void (struct adouble *, int, int) +ad_lock: int (struct adouble *, uint32_t, int, off_t, off_t, int) +ad_metadata: int (const char *, int, struct adouble *) +ad_metadataat: int (int, const char *, int, struct adouble *) +ad_mkdir: int (const char *, mode_t) +ad_mode: int (const char *, mode_t) +ad_open: int (struct adouble *, const char *, int, ...) +ad_openat: int (struct adouble *, int, const char *, int, ...) +ad_openforks: uint16_t (struct adouble *, uint16_t) +ad_path: const char *(const char *, int) +ad_path_ea: const char *(const char *, int) +ad_path_osx: const char *(const char *, int) +ad_read: ssize_t (struct adouble *, const uint32_t, off_t, char *, const size_t) +ad_readfile_init: int (const struct adouble *, const int, off_t *, const int) +ad_rebuild_adouble_header_ea: int (struct adouble *) +ad_rebuild_adouble_header_v2: int (struct adouble *) +ad_refresh: int (const char *, struct adouble *) +ad_rtruncate: int (struct adouble *, const off_t) +ad_setattr: int (const struct adouble *, const uint16_t) +ad_setdate: int (struct adouble *, unsigned int, uint32_t) +ad_setfuid: int (const uid_t) +ad_setid: int (struct adouble *, const dev_t, const ino_t, const uint32_t, const cnid_t, const void *) +ad_setname: int (struct adouble *, const char *) +ad_size: off_t (const struct adouble *, const uint32_t) +ad_stat: int (const char *, struct stat *) +ad_testlock: int (struct adouble *, int, const off_t) +ad_tmplock: int (struct adouble *, uint32_t, int, off_t, off_t, int) +ad_unlock: void (struct adouble *, const int, int) +ad_valid_header_osx: int (const char *) +ad_write: ssize_t (struct adouble *, uint32_t, off_t, int, const char *, size_t) +afp_config_parse: int (AFPObj *, char *) +allow_severity: 5 +apply_ip_mask: void (struct sockaddr *, int) +atalk_iconv: size_t (atalk_iconv_t, const char **, size_t *, char **, size_t *) +atalk_iconv_close: int (atalk_iconv_t) +atalk_iconv_open: atalk_iconv_t (const char *, const char *) +atalk_register_charset: int (struct charset_functions *) +balloc: int (bstring, int) +ballocmin: int (bstring, int) +bassign: int (bstring, const_bstring) +bassignblk: int (bstring, const void *, int) +bassigncstr: int (bstring, const char *) +bassignformat: int (bstring, const char *, ...) +bassigngets: int (bstring, bNgetc, void *, char) +bassignmidstr: int (bstring, const_bstring, int, int) +bcatblk: int (bstring, const void *, int) +bcatcstr: int (bstring, const char *) +bconcat: int (bstring, const_bstring) +bconchar: int (bstring, char) +bcstrfree: int (char *) +bdelete: int (bstring, int, int) +bdestroy: int (bstring) +become_root: void (void) +bfindreplace: int (bstring, const_bstring, const_bstring, int) +bfindreplacecaseless: int (bstring, const_bstring, const_bstring, int) +bformat: bstring (const char *, ...) +bformata: int (bstring, const char *, ...) +bfromcstr: bstring (const char *) +bfromcstralloc: bstring (int, const char *) +bgetsa: int (bstring, bNgetc, void *, char) +bgetstream: bstring (bNgetc, void *, char) +binchr: int (const_bstring, int, const_bstring) +binchrr: int (const_bstring, int, const_bstring) +binsert: int (bstring, int, const_bstring, unsigned char) +binsertch: int (bstring, int, int, unsigned char) +binstr: int (const_bstring, int, const_bstring) +binstrcaseless: int (const_bstring, int, const_bstring) +binstrr: int (const_bstring, int, const_bstring) +binstrrcaseless: int (const_bstring, int, const_bstring) +biseq: int (const_bstring, const_bstring) +biseqcaseless: int (const_bstring, const_bstring) +biseqcstr: int (const_bstring, const char *) +biseqcstrcaseless: int (const_bstring, const char *) +bisstemeqblk: int (const_bstring, const void *, int) +bisstemeqcaselessblk: int (const_bstring, const void *, int) +bjoin: bstring (const struct bstrList *, const_bstring) +bjoinInv: bstring (const struct bstrList *, const_bstring) +blk2bstr: bstring (const void *, int) +bltrimws: int (bstring) +bmidstr: bstring (const_bstring, int, int) +bninchr: int (const_bstring, int, const_bstring) +bninchrr: int (const_bstring, int, const_bstring) +bpattern: int (bstring, int) +bread: bstring (bNread, void *) +breada: int (bstring, bNread, void *) +brefcstr: bstring (char *) +breplace: int (bstring, int, int, const_bstring, unsigned char) +brtrimws: int (bstring) +bsbufflength: int (struct bStream *, int) +bsclose: void *(struct bStream *) +bseof: int (const struct bStream *) +bsetstr: int (bstring, int, const_bstring, unsigned char) +bsopen: struct bStream *(bNread, void *) +bspeek: int (bstring, const struct bStream *) +bsplit: struct bstrList *(const_bstring, unsigned char) +bsplitcb: int (const_bstring, unsigned char, int, int (*)(void *, int, int), void *) +bsplits: struct bstrList *(const_bstring, const_bstring) +bsplitscb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *) +bsplitstr: struct bstrList *(const_bstring, const_bstring) +bsplitstrcb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *) +bsread: int (bstring, struct bStream *, int) +bsreada: int (bstring, struct bStream *, int) +bsreadln: int (bstring, struct bStream *, char) +bsreadlna: int (bstring, struct bStream *, char) +bsreadlns: int (bstring, struct bStream *, const_bstring) +bsreadlnsa: int (bstring, struct bStream *, const_bstring) +bssplitscb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *) +bssplitstrcb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *) +bstr2cstr: char *(const_bstring, char) +bstrchrp: int (const_bstring, int, int) +bstrcmp: int (const_bstring, const_bstring) +bstrcpy: bstring (const_bstring) +bstricmp: int (const_bstring, const_bstring) +bstrListAlloc: int (struct bstrList *, int) +bstrListAllocMin: int (struct bstrList *, int) +bstrListCreate: struct bstrList *(void) +bstrListCreateMin: struct bstrList *(int) +bstrListDestroy: int (struct bstrList *) +bstrListPop: bstring (struct bstrList *) +bstrListPush: int (struct bstrList *, bstring) +bstrncmp: int (const_bstring, const_bstring, int) +bstrnicmp: int (const_bstring, const_bstring, int) +bstrrchrp: int (const_bstring, int, int) +bsunread: int (struct bStream *, const_bstring) +btolower: int (bstring) +btoupper: int (bstring) +btrimws: int (bstring) +btrunc: int (bstring, int) +bunrefcstr: int (bstring) +bvcformata: int (bstring, int, const char *, struct __va_list_tag *) +charset_decompose: size_t (charset_t, char *, size_t, char *, size_t) +charset_mac_centraleurope: {name = "MAC_CENTRALEUROPE", kTextEncoding = 29, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_chinese_simp: {name = "MAC_CHINESE_SIMP", kTextEncoding = 25, pull = , push = , flags = 85, iname = "EUC-CN", prev = 0x0, next = 0x0} +charset_mac_chinese_trad: {name = "MAC_CHINESE_TRAD", kTextEncoding = 2, pull = , push = , flags = 85, iname = "BIG-5", prev = 0x0, next = 0x0} +charset_mac_cyrillic: {name = "MAC_CYRILLIC", kTextEncoding = 7, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_greek: {name = "MAC_GREEK", kTextEncoding = 6, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_hebrew: {name = "MAC_HEBREW", kTextEncoding = 5, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_japanese: {name = "MAC_JAPANESE", kTextEncoding = 1, pull = , push = , flags = 85, iname = "SHIFT_JIS", prev = 0x0, next = 0x0} +charset_mac_korean: {name = "MAC_KOREAN", kTextEncoding = 3, pull = , push = , flags = 85, iname = "EUC-KR", prev = 0x0, next = 0x0} +charset_mac_roman: {name = "MAC_ROMAN", kTextEncoding = 0, pull = , push = , flags = 21, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_turkish: {name = "MAC_TURKISH", kTextEncoding = 35, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_precompose: size_t (charset_t, char *, size_t, char *, size_t) +charset_strlower: size_t (charset_t, const char *, size_t, char *, size_t) +charset_strupper: size_t (charset_t, const char *, size_t, char *, size_t) +charset_to_ucs2_allocate: size_t (charset_t, uint16_t **, const char *) +charset_to_utf8_allocate: size_t (charset_t, char **, const char *) +charset_utf8: {name = "UTF8", kTextEncoding = 134217987, pull = , push = , flags = 22, iname = 0x0, prev = 0x0, next = 0x0} +charset_utf8_mac: {name = "UTF8-MAC", kTextEncoding = 134217987, pull = , push = , flags = 27, iname = 0x0, prev = 0x0, next = 0x0} +check_lockfile: int (const char *, const char *) +cjk_char_pull: size_t (uint16_t, uint16_t *, const uint32_t *) +cjk_char_push: size_t (uint16_t, uint8_t *) +cjk_compose: uint16_t (uint16_t, uint16_t, const uint32_t *, size_t) +cjk_compose_seq: uint16_t (const uint16_t *, size_t *, const uint32_t *, size_t) +cjk_generic_pull: size_t (size_t (*)(uint16_t *, const uint8_t *, size_t *), void *, char **, size_t *, char **, size_t *) +cjk_generic_push: size_t (size_t (*)(uint8_t *, const uint16_t *, size_t *), void *, char **, size_t *, char **, size_t *) +cjk_lookup: uint16_t (uint16_t, const cjk_index_t *, const uint16_t *) +cnid_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, const char *, const size_t, cnid_t) +cnid_close: void (struct _cnid_db *) +cnid_dbd_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_dbd_close: void (struct _cnid_db *) +cnid_dbd_delete: int (struct _cnid_db *, const cnid_t) +cnid_dbd_find: int (struct _cnid_db *, const char *, size_t, void *, size_t) +cnid_dbd_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_dbd_getstamp: int (struct _cnid_db *, void *, const size_t) +cnid_dbd_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_dbd_module: {name = "dbd", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0} +cnid_dbd_open: struct _cnid_db *(struct cnid_open_args *) +cnid_dbd_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_dbd_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_dbd_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_delete: int (struct _cnid_db *, cnid_t) +cnid_find: int (struct _cnid_db *, const char *, size_t, void *, size_t) +cnid_get: cnid_t (struct _cnid_db *, const cnid_t, char *, const size_t) +cnid_getstamp: int (struct _cnid_db *, void *, const size_t) +cnid_init: void (void) +cnid_last_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_last_close: void (struct _cnid_db *) +cnid_last_delete: int (struct _cnid_db *, const cnid_t) +cnid_last_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_last_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_last_module: {name = "last", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0} +cnid_last_open: struct _cnid_db *(struct cnid_open_args *) +cnid_last_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_last_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_lookup: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t) +cnid_open: struct _cnid_db *(const char *, mode_t, char *, int, const char *, const char *) +cnid_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t) +cnid_register: void (struct _cnid_module *) +cnid_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_tdb_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_tdb_close: void (struct _cnid_db *) +cnid_tdb_delete: int (struct _cnid_db *, const cnid_t) +cnid_tdb_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_tdb_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_tdb_module: {name = "tdb", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 12} +cnid_tdb_open: struct _cnid_db *(struct cnid_open_args *) +cnid_tdb_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_tdb_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_update: int (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, const size_t) +compare_ip: int (const struct sockaddr *, const struct sockaddr *) +convert_charset: size_t (charset_t, charset_t, charset_t, const char *, size_t, char *, size_t, uint16_t *) +convert_string: size_t (charset_t, charset_t, const void *, size_t, void *, size_t) +convert_string_allocate: size_t (charset_t, charset_t, const void *, size_t, char **) +copy_ea: int (const char *, int, const char *, const char *, mode_t) +copy_file: int (int, const char *, const char *, mode_t) +copy_file_fd: int (int, int) +copy_fork: int (int, struct adouble *, struct adouble *) +create_lockfile: int (const char *, const char *) +daemonize: int (int, int) +decompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *) +deny_severity: 3 +dequeue: void *(q_t *) +_diacasemap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 233, 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 198, 183, 184, 184, 186, 187, 188, 189, 174, 175, 192, 193, 194, 195, 196, 197, 198, 199...} +_dialowermap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 132, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, 176, 177, 178, 179, 180, 181, 198, 183, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199...} +dictionary_del: void (dictionary *) +dictionary_dump: void (dictionary *, FILE *) +dictionary_get: const char *(const dictionary *, const char *, const char *, const char *) +dictionary_hash: unsigned int (char *) +dictionary_new: dictionary *(int) +dictionary_set: int (dictionary *, char *, char *, char *) +dictionary_unset: void (dictionary *, char *, char *) +dir_rx_set: int (mode_t) +dsi_attention: int (DSI *, AFPUserBytes) +dsi_close: void (DSI *) +dsi_cmdreply: int (DSI *, const int) +dsi_disconnect: int (DSI *) +dsi_getsession: int (DSI *, server_child *, int, afp_child_t **) +dsi_getstatus: void (DSI *) +dsi_init: DSI *(AFPObj *, const char *, const char *, const char *) +dsi_opensession: void (DSI *) +dsi_read: ssize_t (DSI *, void *, const size_t) +dsi_readdone: void (DSI *) +dsi_readinit: ssize_t (DSI *, void *, const size_t, const size_t, const int) +dsi_stream_read: size_t (DSI *, void *, const size_t) +dsi_stream_read_file: ssize_t (DSI *, const int, off_t, const size_t, const int) +dsi_stream_receive: int (DSI *) +dsi_stream_send: int (DSI *, void *, size_t) +dsi_stream_write: ssize_t (DSI *, void *, const size_t, int) +dsi_tcp_init: int (DSI *, const char *, const char *, const char *) +dsi_tickle: int (DSI *) +dsi_write: size_t (DSI *, void *, const size_t) +dsi_writeflush: void (DSI *) +dsi_writeinit: size_t (DSI *, void *, const size_t) +ea_chmod_dir: int (const struct vol *, const char *, mode_t, struct stat *) +ea_chmod_file: int (const struct vol *, const char *, mode_t, struct stat *) +ea_chown: int (const struct vol *, const char *, uid_t, gid_t) +ea_close: int (struct ea *) +ea_copyfile: int (const struct vol *, int, const char *, const char *) +ea_deletefile: int (const struct vol *, int, const char *) +ea_open: int (const struct vol *, const char *, eaflags_t, struct ea *) +ea_openat: int (const struct vol *, int, const char *, eaflags_t, struct ea *) +ea_path: char *(const struct ea *, const char *, int) +ea_renamefile: int (const struct vol *, int, const char *, const char *) +enqueue: qnode_t *(q_t *, void *) +fault_setup: void (void (*)(void *)) +fdset_add_fd: void (int, struct pollfd **, struct polldata **, int *, int *, int, enum fdtype, void *) +fdset_del_fd: void (struct pollfd **, struct polldata **, int *, int *, int) +find_charset_functions: struct charset_functions *(const char *) +_fini: +freeifacelist: void (char **) +fullpathname: const char *(const char *) +getcwdpath: const char *(void) +get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int) +get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *) +getifacelist: char **(void) +getip_port: unsigned int (const struct sockaddr *) +getip_string: const char *(const struct sockaddr *) +getnamefromuuid: int (const uuidp_t, char **, uuidtype_t *) +getuuidfromname: int (const char *, uuidtype_t, unsigned char *) +getvolbyname: struct vol *(const char *) +getvolbypath: struct vol *(AFPObj *, const char *) +getvolbyvid: struct vol *(const uint16_t) +getvolumes: struct vol *(void) +gmem: int (gid_t, int, gid_t *) +iniparser_dump: void (const dictionary *, FILE *) +iniparser_dump_ini: void (const dictionary *, FILE *) +iniparser_find_entry: int (const dictionary *, const char *) +iniparser_freedict: void (dictionary *) +iniparser_getboolean: int (const dictionary *, const char *, const char *, int) +iniparser_getdouble: double (const dictionary *, const char *, const char *, double) +iniparser_getint: int (const dictionary *, const char *, const char *, int) +iniparser_getnsec: int (const dictionary *) +iniparser_getsecname: const char *(const dictionary *, int) +iniparser_getstrdup: char *(const dictionary *, const char *, const char *, const char *) +iniparser_getstring: const char *(const dictionary *, const char *, const char *, const char *) +iniparser_load: dictionary *(const char *) +iniparser_set: int (dictionary *, char *, char *, char *) +iniparser_unset: void (dictionary *, char *, char *) +_init: +init_iconv: void (void) +initvol_vfs: void (struct vol *) +ipc_child_write: int (int, uint16_t, int, void *) +ipc_client_uds: int (const char *) +ipc_server_read: int (server_child *, int) +ipc_server_uds: int (const char *) +islower_sp: int (uint32_t) +islower_w: int (uint16_t) +isupper_sp: int (uint32_t) +isupper_w: int (uint16_t) +lchdir: int (const char *) +ldap_auth_dn: 0x0 +ldap_auth_method: 0 +ldap_auth_pw: 0x0 +ldap_config_valid: 0 +ldap_getnamefromuuid: int (const char *, char **, uuidtype_t *) +ldap_getuuidfromname: int (const char *, uuidtype_t, char **) +ldap_group_attr: 0x0 +ldap_groupbase: 0x0 +ldap_groupscope: 0 +ldap_name_attr: 0x0 +ldap_prefs: {{pref = 0x0, name = "ldap server", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap auth method", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap auth dn", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap userbase", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap userscope", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap groupbase", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap groupscope", strorint = 1, intfromarray = 1, valid = -1}, {pref = 0x0, name = "ldap uuid attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap uuid string", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap name attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap group attr", strorint = 0, intfromarray = 0, valid = -1}, {pref = 0x0, name = "ldap uid attr", strorint = 0, intfromarray = 0, valid = 0}, {pref = 0x0, name = "ldap uuid encoding", strorint = 1, intfromarray = 1, valid = 0}, {pref = 0x0, name = 0x0, strorint = 0, intfromarray = 0, valid = -1}} +ldap_server: 0x0 +ldap_uid_attr: 0x0 +ldap_userbase: 0x0 +ldap_userscope: 0 +ldap_uuid_attr: 0x0 +ldap_uuid_encoding: 0 +ldap_uuid_string: 0x0 +list_eas: int (const struct vol *, char *, size_t *, const char *, int) +load_charset: int (struct vol *) +load_volumes: int (AFPObj *, void (*)(const AFPObj *, struct vol *)) +localuuid_from_id: void (unsigned char *, uuidtype_t, unsigned int) +lock_reg: int (int, int, int, off_t, int, off_t) +log_config: {inited = false, syslog_opened = false, console = false, processname = '\0' , syslog_facility = 0, syslog_display_options = 0} +lstatat: int (int, const char *, struct stat *) +make_log_entry: void (enum loglevels, enum logtypes, const char *, int, char *, ...) +make_tdb_data: unsigned char *(uint32_t, const struct stat *, const cnid_t, const char *, const size_t) +mb_generic_pull: size_t (int (*)(uint16_t *, const unsigned char *), void *, char **, size_t *, char **, size_t *) +mb_generic_push: size_t (int (*)(unsigned char *, uint16_t), void *, char **, size_t *, char **, size_t *) +netatalk_panic: void (const char *) +netatalk_rmdir: int (int, const char *) +netatalk_rmdir_all_errors: int (int, const char *) +netatalk_unlink: int (const char *) +netatalk_unlinkat: int (int, const char *) +nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int) +opendirat: DIR *(int, const char *) +openflags2logstr: const char *(int) +posix_chmod: int (const char *, mode_t) +posix_fchmod: int (int, mode_t) +precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *) +prefs_array: {{pref = "ldap auth method", valuestring = "none", value = 0}, {pref = "ldap auth method", valuestring = "simple", value = 128}, {pref = "ldap auth method", valuestring = "sasl", value = 163}, {pref = "ldap userscope", valuestring = "base", value = 0}, {pref = "ldap userscope", valuestring = "one", value = 1}, {pref = "ldap userscope", valuestring = "sub", value = 2}, {pref = "ldap groupscope", valuestring = "base", value = 0}, {pref = "ldap groupscope", valuestring = "one", value = 1}, {pref = "ldap groupscope", valuestring = "sub", value = 2}, {pref = "ldap uuid encoding", valuestring = "ms-guid", value = 1}, {pref = "ldap uuid encoding", valuestring = "string", value = 0}, {pref = 0x0, valuestring = 0x0, value = 0}} +prequeue: qnode_t *(q_t *, void *) +queue_destroy: void (q_t *, void (*)(void *)) +queue_init: q_t *(void) +randombytes: void (void *, int) +readt: ssize_t (int, void *, const size_t, int, int) +realpath_safe: char *(const char *) +reconnect_ipc: int (AFPObj *) +recv_fd: int (int, int) +rel_path_in_vol: bstring (const char *, const char *) +remove_acl_vfs: int (const char *) +remove_ea: int (const struct vol *, const char *, const char *, int) +run_cmd: int (const char *, char **) +search_cachebyname: int (const char *, uuidtype_t *, unsigned char *) +search_cachebyuuid: int (uuidp_t, char **, uuidtype_t *) +send_fd: int (int, int) +server_child_add: afp_child_t *(server_child *, int, pid_t, int) +server_child_alloc: server_child *(const int, const int) +server_child_free: void (server_child *) +server_child_kill: void (server_child *, int, int) +server_child_kill_one_by_id: void (server_child *, int, pid_t, uid_t, uint32_t, char *, uint32_t) +server_child_remove: int (server_child *, const int, pid_t) +server_child_setup: void (server_child *, const int, void (*)(const pid_t)) +server_child_transfer_session: int (server_child *, int, pid_t, uid_t, int, uint16_t) +server_lock: pid_t (char *, char *, int) +server_reset_signal: void (void) +set_charset_name: int (charset_t, const char *) +set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int) +setfilmode: int (const char *, mode_t, struct stat *, mode_t) +setnonblock: int (int, int) +set_processname: void (const char *) +setuplog: void (const char *, const char *) +statat: int (int, const char *, struct stat *) +strcasechr_sp: uint16_t *(const uint16_t *, uint32_t) +strcasechr_w: uint16_t *(const uint16_t *, uint16_t) +strcasecmp_w: int (const uint16_t *, const uint16_t *) +strcasestr_w: uint16_t *(const uint16_t *, const uint16_t *) +strcat_w: uint16_t *(uint16_t *, const uint16_t *) +strchr_w: uint16_t *(const uint16_t *, uint16_t) +strcmp_w: int (const uint16_t *, const uint16_t *) +strdiacasecmp: int (const char *, const char *) +strdup_w: uint16_t *(const uint16_t *) +stripped_slashes_basename: char *(char *) +strlcat: size_t (char *, const char *, size_t) +strlcpy: size_t (char *, const char *, size_t) +strlen_w: size_t (const uint16_t *) +strlower_w: int (uint16_t *) +strncasecmp_w: int (const uint16_t *, const uint16_t *, size_t) +strncat_w: uint16_t *(uint16_t *, const uint16_t *, const size_t) +strncmp_w: int (const uint16_t *, const uint16_t *, size_t) +strncpy_w: uint16_t *(uint16_t *, const uint16_t *, const size_t) +strndiacasecmp: int (const char *, const char *, size_t) +strndup_w: uint16_t *(const uint16_t *, size_t) +strnlen_w: size_t (const uint16_t *, size_t) +strstr_w: uint16_t *(const uint16_t *, const uint16_t *) +strupper_w: int (uint16_t *) +sys_ea_copyfile: int (const struct vol *, int, const char *, const char *) +sys_fgetxattr: ssize_t (int, const char *, void *, size_t) +sys_fsetxattr: int (int, const char *, const void *, size_t, int) +sys_ftruncate: int (int, off_t) +sys_get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int) +sys_get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *) +sys_getxattr: ssize_t (const char *, const char *, void *, size_t) +sys_getxattrfd: int (int, const char *, int, ...) +sys_lgetxattr: ssize_t (const char *, const char *, void *, size_t) +sys_list_eas: int (const struct vol *, char *, size_t *, const char *, int) +sys_listxattr: ssize_t (const char *, char *, size_t) +sys_llistxattr: ssize_t (const char *, char *, size_t) +sys_lremovexattr: int (const char *, const char *) +sys_lsetxattr: int (const char *, const char *, const void *, size_t, int) +sys_remove_ea: int (const struct vol *, const char *, const char *, int) +sys_removexattr: int (const char *, const char *) +sys_sendfile: ssize_t (int, int, off_t *, size_t) +sys_set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int) +sys_setxattr: int (const char *, const char *, const void *, size_t, int) +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) +tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_brlock: int (struct tdb_context *, tdb_off_t, int, int, int, size_t) +tdb_brlock_upgrade: int (struct tdb_context *, tdb_off_t, size_t) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_convert: void *(void *, uint32_t) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_expand: int (struct tdb_context *, tdb_off_t) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_io_init: void (struct tdb_context *) +tdb_lock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_mmap: void (struct tdb_context *) +tdb_munmap: int (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: {dptr = 0x0, dsize = 0} +tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +_tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_lock: int (struct tdb_context *, int) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_recover: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_unlock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_unlock_record: int (struct tdb_context *, tdb_off_t) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) +tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) +tolower_sp: uint32_t (uint32_t) +tolower_w: uint16_t (uint16_t) +toupper_sp: uint32_t (uint32_t) +toupper_w: uint16_t (uint16_t) +type_configs: {{set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}} +ucs2_to_charset: size_t (charset_t, const uint16_t *, char *, size_t) +ucs2_to_charset_allocate: size_t (charset_t, char **, const uint16_t *) +unbecome_root: void (void) +unix_rename: int (int, const char *, int, const char *) +unix_strlower: size_t (const char *, size_t, char *, size_t) +unix_strupper: size_t (const char *, size_t, char *, size_t) +unload_volumes: void (AFPObj *) +utf8_charlen: size_t (char *) +utf8_decompose: size_t (char *, size_t, char *, size_t) +utf8_precompose: size_t (char *, size_t, char *, size_t) +utf8_strlen_validate: size_t (char *) +utf8_strlower: size_t (const char *, size_t, char *, size_t) +utf8_strupper: size_t (const char *, size_t, char *, size_t) +utf8_to_charset_allocate: size_t (charset_t, char **, const char *) +uuid_bin2string: const char *(const unsigned char *) +uuidcache_dump: void (void) +uuid_string2bin: void (const char *, unsigned char *) +uuidtype: {"", "USER", "GROUP", "LOCAL"} +volume_free: void (struct vol *) +volume_unlink: void (struct vol *) +writet: ssize_t (int, void *, const size_t, int, int) From 925815a573293e6a4fc70230cee782338668cf72 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 14:54:16 +0200 Subject: [PATCH 010/117] Bump ABI --- libatalk/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libatalk/Makefile.am b/libatalk/Makefile.am index ed597dcb..e69cdffb 100644 --- a/libatalk/Makefile.am +++ b/libatalk/Makefile.am @@ -29,6 +29,7 @@ VERSION_INFO = 2:0:0 # 3.0.0-beta2 1:0:0 # 3.0 1:0:0 # 3.0.1 2:0:0 +# 3.0.2 3:0:1 SUBDIRS = acl adouble bstring compat cnid dsi iniparser tdb util unicode vfs From db568ec6e05d9b7a5274b7d9a2338eaa146eb867 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 15:34:34 +0200 Subject: [PATCH 011/117] Ensure the volume path is '/' terminated and allow nested volumes The previos change to the way checking for duplicate and nested paths only works if the path is terminated with a '/'. Allow nested volumes. This was working in 2.2 and can be used eg for sharing a ZFS snapshot directory of a volume. Afaict it only works with sane AFP semantics by adding 'cnid sheme = tdb' to the nested volume which also makes it read-only and by adding the name of the nested directory to the veto name list. --- libatalk/util/netatalk_conf.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 4a309485..67979236 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -549,7 +549,7 @@ static int getoption_bool(const dictionary *conf, const char *vol, const char *o * @param pwd (r) struct passwd of logged in user, may be NULL in master afpd * @param section (r) volume name wo variables expanded (exactly as in iniconfig) * @param name (r) volume name - * @param path (r) volume path + * @param path_in (r) volume path * @param preset (r) default preset, may be NULL * @returns vol on success, NULL on error */ @@ -557,7 +557,7 @@ static struct vol *creatvol(AFPObj *obj, const struct passwd *pwd, const char *section, const char *name, - const char *path, + const char *path_in, const char *preset) { EC_INIT; @@ -565,20 +565,24 @@ static struct vol *creatvol(AFPObj *obj, size_t current_pathlen, another_pathlen; int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; char *tmpname; + char path[MAXPATHLEN + 1]; ucs2_t u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2]; char suffix[6]; /* max is #FFFF */ uint16_t flags; const char *val; char *p, *q; + /* Ensure the path is '/' terminated */ + strlcpy(path, path_in, MAXPATHLEN); + if (path[strlen(path) - 1] != '/') + strlcat(path, "/", MAXPATHLEN); + LOG(log_debug, logtype_afpd, "createvol(volume: '%s', path: \"%s\", preset: '%s'): BEGIN", name, path, preset ? preset : "-"); if ( name == NULL || *name == '\0' ) { - if ((name = strrchr( path, '/' )) == NULL) { + if ((name = strrchr( path, '/' )) == NULL) EC_FAIL; - } - /* if you wish to share /, you need to specify a name. */ if (*++name == '\0') EC_FAIL; @@ -592,17 +596,13 @@ static struct vol *creatvol(AFPObj *obj, another_pathlen = strlen(vol->v_path); if (strncmp(path, vol->v_path, MIN(current_pathlen, another_pathlen)) == 0) { if (current_pathlen == another_pathlen) { - if ( 0 == strcmp(name, vol->v_localname)) { - LOG(log_debug, logtype_afpd, "createvol('%s'): already loaded", name); - } else { - LOG(log_error, logtype_afpd, "paths are duplicated - \"%s\"", path); - } + LOG(log_error, logtype_afpd, "volume \"%s\" paths is duplicated: \"%s\"", name, path); + vol->v_deleted = 0; + volume = vol; + goto EC_CLEANUP; } else { - LOG(log_error, logtype_afpd, "paths are nested - \"%s\" and \"%s\"", path, vol->v_path); + LOG(log_note, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); } - vol->v_deleted = 0; - volume = vol; - goto EC_CLEANUP; } } @@ -880,10 +880,9 @@ static struct vol *creatvol(AFPObj *obj, EC_NULL( volume->v_localname = strdup(name) ); EC_NULL( volume->v_u8mname = strdup_w(u8mtmpname) ); EC_NULL( volume->v_macname = strdup_w(mactmpname) ); - EC_NULL( volume->v_path = malloc(strlen(path) + 1) ); - + EC_NULL( volume->v_path = strdup(path) ); + volume->v_name = utf8_encoding(obj) ? volume->v_u8mname : volume->v_macname; - strcpy(volume->v_path, path); #ifdef __svr4__ volume->v_qfd = -1; From bcded883fc430aad1a4634c980895270e4d158f3 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 16:30:06 +0200 Subject: [PATCH 012/117] Fix memory leak and use descriptive variable names --- libatalk/util/netatalk_conf.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 67979236..a1bd40cb 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -965,10 +965,9 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) EC_INIT; static int regexerr = -1; static regex_t reg; - char *realpw_dir; char *realvolpath; char volname[AFPVOL_U8MNAMELEN + 1]; - char tmp[MAXPATHLEN + 1], tmp2[MAXPATHLEN + 1]; + char path[MAXPATHLEN + 1], tmp[MAXPATHLEN + 1]; const char *preset, *default_preset, *p, *basedir; char *q, *u; int i; @@ -999,7 +998,8 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) if (pwent->pw_dir == NULL || STRCMP("", ==, pwent->pw_dir)) /* no user home */ continue; - if ((realpw_dir = realpath_safe(pwent->pw_dir)) == NULL) + + if ((realpath(pwent->pw_dir, tmp)) == NULL) continue; /* check if user home matches our "basedir regex" */ @@ -1013,16 +1013,15 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) char errbuf[1024]; regerror(regexerr, ®, errbuf, sizeof(errbuf)); LOG(log_debug, logtype_default, "readvolfile: bad basedir regex: %s", errbuf); + continue; } - if (regexec(®, realpw_dir, 1, match, 0) == REG_NOMATCH) { - LOG(log_debug, logtype_default, "readvolfile: user home \"%s\" doesn't match basedir regex \"%s\"", - realpw_dir, basedir); + if (regexec(®, tmp, 1, match, 0) == REG_NOMATCH) { + LOG(log_error, logtype_default, "readvolfile: user home \"%s\" doesn't match basedir regex \"%s\"", + tmp, basedir); continue; } - strlcpy(tmp, realpw_dir, MAXPATHLEN); - strlcat(tmp, "/", MAXPATHLEN); if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) strlcat(tmp, p, MAXPATHLEN); } else { @@ -1032,7 +1031,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) strlcpy(tmp, p, MAXPATHLEN); } - if (volxlate(obj, tmp2, sizeof(tmp2) - 1, tmp, pwent, NULL, NULL) == NULL) + if (volxlate(obj, path, sizeof(path) - 1, tmp, pwent, NULL, NULL) == NULL) continue; /* do variable substitution for volume name */ @@ -1050,15 +1049,16 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) } else { strlcpy(tmp, secname, AFPVOL_U8MNAMELEN); } - if (volxlate(obj, volname, sizeof(volname) - 1, tmp, pwent, tmp2, NULL) == NULL) + if (volxlate(obj, volname, sizeof(volname) - 1, tmp, pwent, path, NULL) == NULL) continue; preset = iniparser_getstring(obj->iniconfig, secname, "vol preset", NULL); - if ((realvolpath = realpath_safe(tmp2)) == NULL) + if ((realvolpath = realpath_safe(path)) == NULL) continue; creatvol(obj, pwent, secname, volname, realvolpath, preset ? preset : default_preset ? default_preset : NULL); + free(realvolpath); } EC_CLEANUP: From c0b84c4784727f5313c5849bd518b76bcffaa773 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 10 Oct 2012 16:40:30 +0200 Subject: [PATCH 013/117] Fix memory leak and use EC_FAIL instead of returning directly --- libatalk/util/netatalk_conf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index a1bd40cb..9871663f 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1281,7 +1281,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) const struct passwd *pw; char volname[AFPVOL_U8MNAMELEN + 1]; char abspath[MAXPATHLEN + 1]; - char volpath[MAXPATHLEN + 1], *realvolpath; + char volpath[MAXPATHLEN + 1], *realvolpath = NULL; char tmpbuf[MAXPATHLEN + 1]; const char *secname, *basedir, *p = NULL, *subpath = NULL, *subpathconfig; char *user = NULL, *prw; @@ -1374,11 +1374,9 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) /* (7) */ if (volxlate(obj, volpath, sizeof(volpath) - 1, tmpbuf, pw, NULL, NULL) == NULL) - return NULL; - - if ((realvolpath = realpath_safe(volpath)) == NULL) - return NULL; + EC_FAIL; + EC_NULL( realvolpath = realpath_safe(volpath) ); EC_NULL( pw = getpwnam(user) ); LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\"): user: %s, homedir: %s => realvolpath: \"%s\"", @@ -1400,6 +1398,8 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) EC_CLEANUP: if (user) free(user); + if (realvolpath) + free(realvolpath); if (ret != 0) vol = NULL; return vol; From 2eedbc8172785b9cc29af552ed1ca8627309f963 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 11 Oct 2012 13:02:55 +0200 Subject: [PATCH 014/117] Fix check for nested and duplicated volume paths The previous modification was based on ensuring the volume paths are '/' terminated. That allowed for a simple and quick implementation of the neccessary tests. Unfortunately that completely broke the whole directory machinery and cache. This patch reverts the previous change and tries another simple implementation that avoid copying the paths. --- libatalk/util/netatalk_conf.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 9871663f..01e78292 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -572,10 +572,7 @@ static struct vol *creatvol(AFPObj *obj, const char *val; char *p, *q; - /* Ensure the path is '/' terminated */ strlcpy(path, path_in, MAXPATHLEN); - if (path[strlen(path) - 1] != '/') - strlcat(path, "/", MAXPATHLEN); LOG(log_debug, logtype_afpd, "createvol(volume: '%s', path: \"%s\", preset: '%s'): BEGIN", name, path, preset ? preset : "-"); @@ -590,7 +587,12 @@ static struct vol *creatvol(AFPObj *obj, /* Once volumes are loaded, we never change options again, we just delete em when they're removed from afp.conf */ - /* Check for duplicated or nested volumes */ + /* + * Check for duplicated or nested volumes, eg: + * /Volumes/name /Volumes/name [duplicate], and + * /Volumes/name /Volumes/name/dir [nested], but beware of simple strncmp test: + * /Volumes/name /Volumes/name1 [strncmp match if n=strlen("Volumes/name") -> false positive] + */ current_pathlen = strlen(path); for (struct vol *vol = Volumes; vol; vol = vol->v_next) { another_pathlen = strlen(vol->v_path); @@ -601,7 +603,19 @@ static struct vol *creatvol(AFPObj *obj, volume = vol; goto EC_CLEANUP; } else { - LOG(log_note, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); + const char *shorter_path, *longer_path; + int shorter_len; + if (another_pathlen > current_pathlen) { + shorter_len = current_pathlen; + shorter_path = path; + longer_path = vol->v_path; + } else { + shorter_len = another_pathlen; + shorter_path = vol->v_path; + longer_path = path; + } + if (longer_path[shorter_len] == '/') + LOG(log_info, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); } } } From 23e45f681099477f57a58740016ed666e8c4d284 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 9 Oct 2012 18:23:57 +0200 Subject: [PATCH 015/117] Fix a bug where Mac OS X ZIP archives can't be extracted on Netatalk shares Mac OS X ZIP archives may contain split AppleDouble forks named "._XXX". The client needs to be able to fully access these files but we currently prevent access to any valid AppleDouble file whose name starts with "._". In order to distinguish our own ._ files from the one created by OS X, we look at the filler bytes: luckily OS X stores a string "Mac OS X" there which can be used to detect them. --- libatalk/adouble/ad_flush.c | 2 +- libatalk/adouble/ad_open.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index a637b27f..91f8058b 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -167,7 +167,7 @@ static int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf) memcpy(buf, &temp, sizeof( temp )); buf += sizeof( temp ); - memset(buf, 0, sizeof(ad->ad_filler)); + memcpy(buf, "Netatalk ", 16); buf += sizeof( ad->ad_filler ); nent = htons(ADEID_NUM_OSX); diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index 3e06e93f..045c33c3 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -521,10 +521,18 @@ int ad_valid_header_osx(const char *path) adosx.ad_version = ntohl(adosx.ad_version); if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) { - LOG(log_error, logtype_afpd, "ad_valid_header_osx: not an adouble:ox file"); + LOG(log_warning, logtype_afpd, "ad_valid_header_osx: not an adouble:osx file"); EC_FAIL; } + if (strncmp(buf + ADEDOFF_FILLER, "Mac OS X", strlen("Mac OS X")) == 0) + /* + * It's a split fork created by OS X, it's not our "own" ._ file + * and thus not a valid header in this context. + * We allow enumeration and access. + */ + EC_FAIL; + EC_CLEANUP: LOG(log_debug, logtype_afpd, "ad_valid_header_osx(\"%s\"): END: %d", fullpathname(path), ret); if (fd != -1) From 92b5f92b745c74f9020f35ba27ff479894d60ebe Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 11 Oct 2012 16:42:03 +0200 Subject: [PATCH 016/117] Fix: add a '/' between basedir and subdir in the path for home volumes --- libatalk/util/netatalk_conf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 01e78292..b1d054c8 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1036,8 +1036,10 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) continue; } - if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) + if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) { + strlcat(tmp, "/", MAXPATHLEN); strlcat(tmp, p, MAXPATHLEN); + } } else { /* Get path */ if ((p = iniparser_getstring(obj->iniconfig, secname, "path", NULL)) == NULL) From 4fef95e29456f8eda492fe684a92fbd11176e066 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sun, 14 Oct 2012 12:05:12 +0200 Subject: [PATCH 017/117] Move (unused) file gettok.c to libatalk --- etc/afpd/Makefile.am | 1 - include/atalk/globals.h | 4 ---- include/atalk/util.h | 7 +++++++ libatalk/libatalk-3.0.1dev.abi | 2 ++ libatalk/util/Makefile.am | 1 + {etc/afpd => libatalk/util}/gettok.c | 0 6 files changed, 10 insertions(+), 5 deletions(-) rename {etc/afpd => libatalk/util}/gettok.c (100%) diff --git a/etc/afpd/Makefile.am b/etc/afpd/Makefile.am index 85b51dc8..1cb8913a 100644 --- a/etc/afpd/Makefile.am +++ b/etc/afpd/Makefile.am @@ -28,7 +28,6 @@ afpd_SOURCES = \ file.c \ filedir.c \ fork.c \ - gettok.c \ hash.c \ main.c \ mangle.c \ diff --git a/include/atalk/globals.h b/include/atalk/globals.h index b8412d15..36508e17 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -151,10 +151,6 @@ extern void afp_options_free(struct afp_options *); extern void setmessage (const char *); extern void readmessage (AFPObj *); -/* gettok.c */ -extern void initline (int, char *); -extern int parseline (int, char *); - /* afp_util.c */ extern const char *AfpNum2name (int ); extern const char *AfpErr2name(int err); diff --git a/include/atalk/util.h b/include/atalk/util.h index 9ff6813f..39237e7c 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -190,4 +190,11 @@ extern char *realpath_safe(const char *path); extern bstring rel_path_in_vol(const char *path, const char *volpath); +/****************************************************************** + * cnid.c + *****************************************************************/ + +extern void initline (int, char *); +extern int parseline (int, char *); + #endif /* _ATALK_UTIL_H */ diff --git a/libatalk/libatalk-3.0.1dev.abi b/libatalk/libatalk-3.0.1dev.abi index 645af2b1..fd06b366 100644 --- a/libatalk/libatalk-3.0.1dev.abi +++ b/libatalk/libatalk-3.0.1dev.abi @@ -309,6 +309,7 @@ iniparser_set: int (dictionary *, char *, char *, char *) iniparser_unset: void (dictionary *, char *, char *) _init: init_iconv: void (void) +initline: void (int, char *) initvol_vfs: void (struct vol *) ipc_child_write: int (int, uint16_t, int, void *) ipc_client_uds: int (const char *) @@ -356,6 +357,7 @@ netatalk_unlinkat: int (int, const char *) nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int) opendirat: DIR *(int, const char *) openflags2logstr: const char *(int) +parseline: int (int, char *) posix_chmod: int (const char *, mode_t) posix_fchmod: int (int, mode_t) precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *) diff --git a/libatalk/util/Makefile.am b/libatalk/util/Makefile.am index 65ad1d6c..20195166 100644 --- a/libatalk/util/Makefile.am +++ b/libatalk/util/Makefile.am @@ -9,6 +9,7 @@ libutil_la_SOURCES = \ cnid.c \ fault.c \ getiface.c \ + gettok.c \ locking.c \ logger.c \ module.c \ diff --git a/etc/afpd/gettok.c b/libatalk/util/gettok.c similarity index 100% rename from etc/afpd/gettok.c rename to libatalk/util/gettok.c From a7f754026326a7a5187a969f1de9ce615b49fec1 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sun, 14 Oct 2012 14:53:51 +0200 Subject: [PATCH 018/117] Reintroduce file extension type/creator mapping --- NEWS | 2 + config/Makefile.am | 2 +- config/extmap.conf | 308 +++++++++++++++++++++++++++++++++ etc/afpd/file.c | 21 +++ etc/afpd/file.h | 6 - include/atalk/globals.h | 2 +- include/atalk/netatalk_conf.h | 5 + include/atalk/volume.h | 7 + libatalk/libatalk-3.0.1dev.abi | 2 + libatalk/util/netatalk_conf.c | 158 ++++++++++++++++- man/man5/afp.conf.5.tmpl | 5 + 11 files changed, 509 insertions(+), 9 deletions(-) create mode 100644 config/extmap.conf diff --git a/NEWS b/NEWS index 2b943b34..e1a68c43 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ Changes in 3.0.2 ================ +* NEW: afpd: Put file extension type/creator mapping back in which had + been removed in 3.0. * UPD: ignore duplicated or nested volume path. * FIX: "path" parameter value may contain symlink. * FIX: "basedir regex" was never able to treat symlink. diff --git a/config/Makefile.am b/config/Makefile.am index 47630460..db57476d 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -10,7 +10,7 @@ EXTRA_DIST = afp.conf.tmpl OVERWRITE_CONFIG = @OVERWRITE_CONFIG@ -CONFFILES = +CONFFILES = extmap.conf pkgconfdir = @PKGCONFDIR@ # diff --git a/config/extmap.conf b/config/extmap.conf new file mode 100644 index 00000000..44ccec5b --- /dev/null +++ b/config/extmap.conf @@ -0,0 +1,308 @@ +# Netatalk file extension -> OS X type/creator mapping configuration file +# +# Delete a '#' character at the head of line to uncomment and enable a mapping +# +### Default translation: +#. "????" "????" Unix Binary Unix application/octet-stream +#. "BINA" "UNIX" Unix Binary Unix application/octet-stream +#. "TEXT" "ttxt" ASCII Text SimpleText text/plain + +#.1st "TEXT" "ttxt" Text Readme SimpleText application/text +#.669 "6669" "SNPL" 669 MOD Music PlayerPro +#.8med "STrk" "SCPL" Amiga OctaMed music SoundApp +#.8svx "8SVX" "SCPL" Amiga 8-bit sound SoundApp +#.a "TEXT" "ttxt" Assembly Source SimpleText +#.aif "AIFF" "SCPL" AIFF Sound SoundApp audio/x-aiff +#.aifc "AIFC" "SCPL" AIFF Sound Compressed SoundApp audio/x-aiff +#.aiff "AIFF" "SCPL" AIFF Sound SoundApp audio/x-aiff +#.al "ALAW" "SCPL" ALAW Sound SoundApp +#.ani "ANIi" "GKON" Animated NeoChrome GraphicConverter +#.apd "TEXT" "ALD3" Aldus Printer Description Aldus PageMaker +#.arc "mArc" "SITx" PC ARChive StuffIt Expander +#.arj "BINA" "DArj" ARJ Archive DeArj +#.arr "ARR " "GKON" Amber ARR image GraphicConverter +#.art "ART " "GKON" First Publisher GraphicConverter +#.asc "TEXT" "ttxt" ASCII Text SimpleText text/plain +#.ascii "TEXT" "ttxt" ASCII Text SimpleText text/plain +#.asf "ASF_" "Ms01" Netshow Player Netshow Server video/x-ms-asf +#.asm "TEXT" "ttxt" Assembly Source SimpleText +#.asx "ASX_" "Ms01" Netshow Player Netshow Server video/x-ms-asf +#.au "ULAW" "TVOD" Sun Sound QuickTime Player audio/basic +#.avi "VfW " "TVOD" AVI Movie QuickTime Player video/avi +#.bar "BARF" "S691" Unix BAR Archive SunTar +#.bas "TEXT" "ttxt" BASIC Source SimpleText +#.bat "TEXT" "ttxt" MS-DOS Batch File SimpleText +#.bga "BMPp" "ogle" OS/2 Bitmap PictureViewer +#.bib "TEXT" "ttxt" BibTex Bibliography SimpleText +#.bin "SIT!" "SITx" MacBinary StuffIt Expander application/macbinary +#.binary "BINA" "hDmp" Untyped Binary Data HexEdit application/octet-stream +#.bmp "BMPp" "ogle" Windows Bitmap PictureViewer +#.boo "TEXT" "ttxt" BOO encoded SimpleText +#.bst "TEXT" "ttxt" BibTex Style SimpleText +#.bw "SGI " "GKON" SGI Image GraphicConverter +#.c "TEXT" "CWIE" C Source CodeWarrior +#.cgm "CGMm" "GKON" Computer Graphics Meta GraphicConverter +#.class "Clss" "CWIE" Java Class File CodeWarrior +#.clp "CLPp" "GKON" Windows Clipboard GraphicConverter +#.cmd "TEXT" "ttxt" OS/2 Batch File SimpleText +#.com "PCFA" "SWIN" MS-DOS Executable SoftWindows +#.cp "TEXT" "CWIE" C++ Source CodeWarrior +#.cpp "TEXT" "CWIE" C++ Source CodeWarrior +#.cpt "PACT" "SITx" Compact Pro Archive StuffIt Expander +#.csv "TEXT" "XCEL" Comma Separated Vars Excel +#.ct "..CT" "GKON" Scitex-CT GraphicConverter +#.cut "Halo" "GKON" Dr Halo Image GraphicConverter +#.cvs "drw2" "DAD2" Canvas Drawing Canvas +#.dbf "COMP" "FOX+" DBase Document FoxBase+ +#.dcx "DCXx" "GKON" Some PCX Images GraphicConverter +#.dif "TEXT" "XCEL" Data Interchange Format Excel +#.diz "TEXT" "R*Ch" BBS Descriptive Text BBEdit +#.dl "DL " "AnVw" DL Animation MacAnim Viewer +#.dll "PCFL" "SWIN" Windows DLL SoftWindows +#.doc "WDBN" "MSWD" Word Document Microsoft Word application/msword +#.dot "sDBN" "MSWD" Word for Windows Template Microsoft Word +#.dvi "ODVI" "xdvi" TeX DVI Document xdvi application/x-dvi +#.dwt "TEXT" "DmWr" Dreamweaver Template Dreamweaver +#.dxf "TEXT" "SWVL" AutoCAD 3D Data Swivel Pro +#.eps "EPSF" "vgrd" Postscript LaserWriter 8 application/postscript +#.epsf "EPSF" "vgrd" Postscript LaserWriter 8 application/postscript +#.etx "TEXT" "ezVu" SEText Easy View text/x-setext +#.evy "EVYD" "ENVY" Envoy Document Envoy +#.exe "PCFA" "SWIN" MS-DOS Executable SoftWindows +#.faq "TEXT" "ttxt" ASCII Text SimpleText text/x-usenet-faq +#.fit "FITS" "GKON" Flexible Image Transport GraphicConverter image/x-fits +#.fla "SPA " "MFL2" Flash source Macromedia Flash +#.flc "FLI " "TVOD" FLIC Animation QuickTime Player +#.fli "FLI " "TVOD" FLI Animation QuickTime Player +#.fm "FMPR" "FMPR" FileMaker Pro Database FileMaker Pro +#.for "TEXT" "MPS " Fortran Source MPW Shell +#.fts "FITS" "GKON" Flexible Image Transport GraphicConverter +#.gem "GEM-" "GKON" GEM Metafile GraphicConverter +#.gif "GIFf" "ogle" GIF Picture PictureViewer image/gif +#.gl "GL " "AnVw" GL Animation MacAnim Viewer +#.grp "GRPp" "GKON" GRP Image GraphicConverter +#.gz "SIT!" "SITx" Gnu ZIP Archive StuffIt Expander application/x-gzip +#.h "TEXT" "CWIE" C Include File CodeWarrior +#.hcom "FSSD" "SCPL" SoundEdit Sound ex SOX SoundApp +#.hp "TEXT" "CWIE" C Include File CodeWarrior +#.hpgl "HPGL" "GKON" HP GL/2 GraphicConverter +#.hpp "TEXT" "CWIE" C Include File CodeWarrior +#.hqx "TEXT" "SITx" BinHex StuffIt Expander application/mac-binhex40 +#.htm "TEXT" "MOSS" HyperText Netscape Communicator text/html +#.html "TEXT" "MOSS" HyperText Netscape Communicator text/html +#.i3 "TEXT" "R*ch" Modula 3 Interface BBEdit +#.ic1 "IMAG" "GKON" Atari Image GraphicConverter +#.ic2 "IMAG" "GKON" Atari Image GraphicConverter +#.ic3 "IMAG" "GKON" Atari Image GraphicConverter +#.icn "ICO " "GKON" Windows Icon GraphicConverter +#.ico "ICO " "GKON" Windows Icon GraphicConverter +#.ief "IEF " "GKON" IEF image GraphicConverter image/ief +#.iff "ILBM" "GKON" Amiga IFF Image GraphicConverter +#.ilbm "ILBM" "GKON" Amiga ILBM Image GraphicConverter +#.image "dImg" "ddsk" Apple DiskCopy Image Disk Copy +#.img "IMGg" "GKON" GEM bit image/XIMG GraphicConverter +#.ini "TEXT" "ttxt" Windows INI File SimpleText +#.java "TEXT" "CWIE" Java Source File CodeWarrior +#.jfif "JPEG" "ogle" JFIF Image PictureViewer +#.jpe "JPEG" "ogle" JPEG Picture PictureViewer image/jpeg +#.jpeg "JPEG" "ogle" JPEG Picture PictureViewer image/jpeg +#.jpg "JPEG" "ogle" JPEG Picture PictureViewer image/jpeg +#.latex "TEXT" "OTEX" Latex OzTex application/x-latex +#.lbm "ILBM" "GKON" Amiga IFF Image GraphicConverter +#.lha "LHA " "SITx" LHArc Archive StuffIt Expander +#.lzh "LHA " "SITx" LHArc Archive StuffIt Expander +#.m1a "MPEG" "TVOD" MPEG-1 audiostream MoviePlayer audio/x-mpeg +#.m1s "MPEG" "TVOD" MPEG-1 systemstream MoviePlayer +#.m1v "M1V " "TVOD" MPEG-1 IPB videostream MoviePlayer video/mpeg +#.m2 "TEXT" "R*ch" Modula 2 Source BBEdit +#.m2v "MPG2" "MPG2" MPEG-2 IPB videostream MPEG2decoder +#.m3 "TEXT" "R*ch" Modula 3 Source BBEdit +#.mac "PICT" "ogle" PICT Picture PictureViewer image/x-pict +#.mak "TEXT" "R*ch" Makefile BBEdit +#.mcw "WDBN" "MSWD" Mac Word Document Microsoft Word +#.me "TEXT" "ttxt" Text Readme SimpleText +#.med "STrk" "SCPL" Amiga MED Sound SoundApp +#.mf "TEXT" "*MF*" Metafont Metafont +#.mid "Midi" "TVOD" MIDI Music MoviePlayer +#.midi "Midi" "TVOD" MIDI Music MoviePlayer +#.mif "TEXT" "Fram" FrameMaker MIF FrameMaker application/x-framemaker +#.mime "TEXT" "SITx" MIME Message StuffIt Expander message/rfc822 +#.ml "TEXT" "R*ch" ML Source BBEdit +#.mod "STrk" "SCPL" MOD Music SoundApp +#.mol "TEXT" "RSML" MDL Molfile RasMac +#.moov "MooV" "TVOD" QuickTime Movie MoviePlayer video/quicktime +#.mov "MooV" "TVOD" QuickTime Movie MoviePlayer video/quicktime +#.mp2 "MPEG" "TVOD" MPEG-1 audiostream MoviePlayer audio/x-mpeg +#.mp3 "MPG3" "TVOD" MPEG-3 audiostream MoviePlayer audio/x-mpeg +#.mpa "MPEG" "TVOD" MPEG-1 audiostream MoviePlayer audio/x-mpeg +#.mpe "MPEG" "TVOD" MPEG Movie of some sort MoviePlayer video/mpeg +#.mpeg "MPEG" "TVOD" MPEG Movie of some sort MoviePlayer video/mpeg +#.mpg "MPEG" "TVOD" MPEG Movie of some sort MoviePlayer video/mpeg +#.msp "MSPp" "GKON" Microsoft Paint GraphicConverter +#.mtm "MTM " "SNPL" MultiMOD Music PlayerPro +#.mw "MW2D" "MWII" MacWrite Document MacWrite II application/macwriteii +#.mwii "MW2D" "MWII" MacWrite Document MacWrite II application/macwriteii +#.neo "NeoC" "GKON" Atari NeoChrome GraphicConverter +#.nfo "TEXT" "ttxt" Info Text SimpleText application/text +#.nst "STrk" "SCPL" MOD Music SoundApp +#.obj "PCFL" "SWIN" Object (DOS/Windows) SoftWindows +#.oda "ODIF" "ODA " ODA Document MacODA XTND Translator application/oda +#.okt "OKTA" "SCPL" Oktalyser MOD Music SoundApp +#.out "BINA" "hDmp" Output File HexEdit +#.ovl "PCFL" "SWIN" Overlay (DOS/Windows) SoftWindows +#.p "TEXT" "CWIE" Pascal Source CodeWarrior +#.pac "STAD" "GKON" Atari STAD Image GraphicConverter +#.pas "TEXT" "CWIE" Pascal Source CodeWarrior +#.pbm "PPGM" "GKON" Portable Bitmap GraphicConverter image/x-portable-bitmap +#.pc1 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pc2 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pc3 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pcs "PICS" "GKON" Animated PICTs GraphicConverter +#.pct "PICT" "ogle" PICT Picture PictureViewer image/x-pict +#.pcx "PCXx" "GKON" PC PaintBrush GraphicConverter +#.pdb "TEXT" "RSML" Brookhaven PDB file RasMac +#.pdf "PDF " "CARO" Portable Document Format Acrobat Reader application/pdf +#.pdx "TEXT" "ALD5" Printer Description PageMaker +#.pf "CSIT" "SITx" Private File StuffIt Expander +#.pgm "PPGM" "GKON" Portable Graymap GraphicConverter image/x-portable-graymap +#.pi1 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pi2 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pi3 "Dega" "GKON" Atari Degas Image GraphicConverter +#.pic "PICT" "ogle" PICT Picture PictureViewer image/x-pict +#.pict "PICT" "ogle" PICT Picture PictureViewer image/x-macpict +#.pit "PIT " "SITx" PackIt Archive StuffIt Expander +#.pkg "HBSF" "SITx" AppleLink Package StuffIt Expander +#.pl "TEXT" "McPL" Perl Source MacPerl +#.plt "HPGL" "GKON" HP GL/2 GraphicConverter +#.pm "PMpm" "GKON" Bitmap from xv GraphicConverter +#.pm3 "ALB3" "ALD3" PageMaker 3 Document PageMaker +#.pm4 "ALB4" "ALD4" PageMaker 4 Document PageMaker +#.pm5 "ALB5" "ALD5" PageMaker 5 Document PageMaker +#.png "PNG " "ogle" Portable Network Graphic PictureViewer +#.pntg "PNTG" "ogle" Macintosh Painting PictureViewer +#.ppd "TEXT" "ALD5" Printer Description PageMaker +#.ppm "PPGM" "GKON" Portable Pixmap GraphicConverter image/x-portable-pixmap +#.prn "TEXT" "R*ch" Printer Output File BBEdit +#.ps "TEXT" "vgrd" PostScript LaserWriter 8 application/postscript +#.psd "8BPS" "8BIM" PhotoShop Document Photoshop +#.pt4 "ALT4" "ALD4" PageMaker 4 Template PageMaker +#.pt5 "ALT5" "ALD5" PageMaker 5 Template PageMaker +#.pxr "PXR " "8BIM" Pixar Image Photoshop +#.qdv "QDVf" "GKON" QDV image GraphicConverter +#.qt "MooV" "TVOD" QuickTime Movie MoviePlayer video/quicktime +#.qxd "XDOC" "XPR3" QuarkXpress Document QuarkXpress +#.qxt "XTMP" "XPR3" QuarkXpress Template QuarkXpress +#.raw "BINA" "GKON" Raw Image GraphicConverter +#.readme "TEXT" "ttxt" Text Readme SimpleText application/text +#.rgb "SGI " "GKON" SGI Image GraphicConverter image/x-rgb +#.rgba "SGI " "GKON" SGI Image GraphicConverter image/x-rgb +#.rib "TEXT" "RINI" Renderman 3D Data Renderman +#.rif "RIFF" "GKON" RIFF Graphic GraphicConverter +#.rle "RLE " "GKON" RLE image GraphicConverter +#.rme "TEXT" "ttxt" Text Readme SimpleText +#.rpl "FRL!" "REP!" Replica Document Replica +#.rsc "rsrc" "RSED" Resource File ResEdit +#.rsrc "rsrc" "RSED" Resource File ResEdit +#.rtf "TEXT" "MSWD" Rich Text Format Microsoft Word application/rtf +#.rtx "TEXT" "R*ch" Rich Text BBEdit text/richtext +#.s3m "S3M " "SNPL" ScreamTracker 3 MOD PlayerPro +#.scc "MSX " "GKON" MSX pitcure GraphicConverter +#.scg "RIX3" "GKON" ColoRIX GraphicConverter +#.sci "RIX3" "GKON" ColoRIX GraphicConverter +#.scp "RIX3" "GKON" ColoRIX GraphicConverter +#.scr "RIX3" "GKON" ColoRIX GraphicConverter +#.scu "RIX3" "GKON" ColoRIX GraphicConverter +#.sea "APPL" "????" Self-Extracting Archive Self Extracting Archive +#.sf "IRCM" "SDHK" IRCAM Sound SoundHack +#.sgi ".SGI" "ogle" SGI Image PictureViewer +#.sha "TEXT" "UnSh" Unix Shell Archive UnShar application/x-shar +#.shar "TEXT" "UnSh" Unix Shell Archive UnShar application/x-shar +#.shp "SHPp" "GKON" Printmaster Icon Library GraphicConverter +#.sit "SIT!" "SITx" StuffIt 1.5.1 Archive StuffIt Expander application/x-stuffit +#.sithqx "TEXT" "SITx" BinHexed StuffIt Archive StuffIt Expander application/mac-binhex40 +#.six "SIXE" "GKON" SIXEL image GraphicConverter +#.slk "TEXT" "XCEL" SYLK Spreadsheet Excel +#.snd "BINA" "SCPL" Sound of various types SoundApp +#.spc "Spec" "GKON" Atari Spectrum 512 GraphicConverter +#.sr "SUNn" "GKON" Sun Raster Image GraphicConverter +#.sty "TEXT" "*TEX" TeX Style Textures +#.sun "SUNn" "GKON" Sun Raster Image GraphicConverter +#.sup "SCRN" "GKON" StartupScreen GraphicConverter +#.svx "8SVX" "SCPL" Amiga IFF Sound SoundApp +#.syk "TEXT" "XCEL" SYLK Spreadsheet Excel +#.sylk "TEXT" "XCEL" SYLK Spreadsheet Excel +#.tar "TARF" "SITx" Unix Tape ARchive StuffIt Expander application/x-tar +#.targa "TPIC" "GKON" Truevision Image GraphicConverter +#.taz "ZIVU" "SITx" Compressed Tape ARchive StuffIt Expander application/x-compress +#.tex "TEXT" "OTEX" TeX Document OzTeX application/x-tex +#.texi "TEXT" "OTEX" TeX Document OzTeX +#.texinfo "TEXT" "OTEX" TeX Document OzTeX application/x-texinfo +#.text "TEXT" "ttxt" ASCII Text SimpleText text/plain +#.tga "TPIC" "GKON" Truevision Image GraphicConverter +#.tgz "Gzip" "SITx" Gnu ZIPed Tape ARchive StuffIt Expander application/x-gzip +#.tif "TIFF" "ogle" TIFF Picture PictureViewer image/tiff +#.tiff "TIFF" "ogle" TIFF Picture PictureViewer image/tiff +#.tny "TINY" "GKON" Atari TINY Bitmap GraphicConverter +#.tsv "TEXT" "XCEL" Tab Separated Values Excel text/tab-separated-values +#.tx8 "TEXT" "ttxt" 8-bit ASCII Text SimpleText +#.txt "TEXT" "ttxt" ASCII Text SimpleText text/plain +#.ul "ULAW" "TVOD" Mu-Law Sound MoviePlayer audio/basic +#.url "AURL" "Arch" URL Bookmark Anarchie message/external-body +#.uu "TEXT" "SITx" UUEncode StuffIt Expander +#.uue "TEXT" "SITx" UUEncode StuffIt Expander +#.vff "VFFf" "GKON" DESR VFF Greyscale Image GraphicConverter +#.vga "BMPp" "ogle" OS/2 Bitmap PictureViewer +#.voc "VOC " "SCPL" VOC Sound SoundApp +#.w51 ".WP5" "WPC2" WordPerfect PC 5.1 Doc WordPerfect application/wordperfect5.1 +#.wav "WAVE" "TVOD" Windows WAV Sound MoviePlayer audio/x-wav +#.wk1 "XLBN" "XCEL" Lotus Spreadsheet r2.1 Excel +#.wks "XLBN" "XCEL" Lotus Spreadsheet r1.x Excel +#.wmf "WMF " "GKON" Windows Metafile GraphicConverter +#.wp ".WP5" "WPC2" WordPerfect PC 5.1 Doc WordPerfect application/wordperfect5.1 +#.wp4 ".WP4" "WPC2" WordPerfect PC 4.2 Doc WordPerfect +#.wp5 ".WP5" "WPC2" WordPerfect PC 5.x Doc WordPerfect application/wordperfect5.1 +#.wp6 ".WP6" "WPC2" WordPerfect PC 6.x Doc WordPerfect +#.wpg "WPGf" "GKON" WordPerfect Graphic GraphicConverter +#.wpm "WPD1" "WPC2" WordPerfect Mac WordPerfect +#.wri "WDBN" "MSWD" MS Write/Windows Microsoft Word +#.wve "BINA" "SCPL" PSION sound SoundApp +#.x10 "XWDd" "GKON" X-Windows Dump GraphicConverter image/x-xwd +#.x11 "XWDd" "GKON" X-Windows Dump GraphicConverter image/x-xwd +#.xbm "XBM " "GKON" X-Windows Bitmap GraphicConverter image/x-xbm +#.xl "XLS " "XCEL" Excel Spreadsheet Excel +#.xlc "XLC " "XCEL" Excel Chart Excel +#.xlm "XLM " "XCEL" Excel Macro Excel +#.xls "XLS " "XCEL" Excel Spreadsheet Excel +#.xlw "XLW " "XCEL" Excel Workspace Excel +#.xm "XM " "SNPL" FastTracker MOD Music PlayerPro +#.xpm "XPM " "GKON" X-Windows Pixmap GraphicConverter image/x-xpm +#.xwd "XWDd" "GKON" X-Windows Dump GraphicConverter image/x-xwd +#.Z "ZIVU" "SITx" Unix Compress Archive StuffIt Expander application/x-compress +#.zip "ZIP " "SITx" PC ZIP Archive StuffIt Expander application/zip +#.zoo "Zoo " "Booz" Zoo Archive MacBooz + +# I'd like to dedicate this as follows code to Miss.Tamaki Imazu +# +# Kazuhiko Okudaira the Nursery Teacher +# kokudaira@hotmail.com + +#.bld "BLD " "GKON" BLD GraphicConverter +#.bum ".bMp" "GKON" QuickTime Importer(QuickDraw) GraphicConverter +#.cel "CEL " "GKON" KISS CEL GraphicConverter +#.cur "CUR " "GKON" Windows Cursor GraphicConverter +#.cwj "CWSS" "cwkj" ClarisWorks Document ClarisWorks 4.0 +#.dat "TCLl" "GKON" TCL image GraphicConverter +#.hr "TR80" "GKON" TSR-80 HR GraphicConverter +#.iss "ISS " "GKON" ISS GraphicConverter +#.jif "JIFf" "GKON" JIF99a GraphicConverter +#.lwf "lwfF" "GKON" LuraWave(LWF) GraphicConverter +#.mbm "MBM " "GKON" PSION 5(MBM) GraphicConverter +#.ngg "NGGC" "GKON" Mobile Phone(Nokia)Format GraphicConverter +#.nol "NOL " "GKON" Mobile Phone(Nokia)Format GraphicConverter +#.pal "8BCT" "8BIM" Color Table GraphicConverter +#.pgc "PGCF" "GKON" PGC/PGF Atari Portfolio PCG GraphicConverter +#.pics "PICS" "GKON" PICS-PICT Sequence GraphicConverter +#.swf "SWFL" "SWF2" Flash Macromedia Flash +#.vpb "VPB " "GKON" VPB QUANTEL GraphicConverter +#.wbmp "WBMP" "GKON" WBMP GraphicConverter +#.x-face "TEXT" "GKON" X-Face GraphicConverter diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 8cd5f456..8d5d0ad0 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -77,6 +77,7 @@ static int default_type(void *finder) /* FIXME path : unix or mac name ? (for now it's unix name ) */ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink) { + struct extmap *em; void *ad_finder = NULL; int chk_ext = 0; @@ -85,6 +86,9 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a if (ad_finder) { memcpy(data, ad_finder, ADEDLEN_FINDERI); + /* default type ? */ + if (default_type(ad_finder)) + chk_ext = 1; } else { memcpy(data, ufinderi, ADEDLEN_FINDERI); @@ -105,6 +109,12 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4); } + /** Only enter if no appledouble information and no finder information found. */ + if (chk_ext && (em = getextmap( upath ))) { + memcpy(data, em->em_type, sizeof( em->em_type )); + memcpy((char *)data + 4, em->em_creator, sizeof(em->em_creator)); + } + return data; } @@ -1002,6 +1012,17 @@ int setfilparams(const AFPObj *obj, struct vol *vol, ad_setdate(adp, AD_DATE_BACKUP, bdate); break; case FILPBIT_FINFO : + if (default_type( ad_entry( adp, ADEID_FINDERI )) + && ( + ((em = getextmap( path->m_name )) && + !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) && + !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator))) + || ((em = getdefextmap()) && + !memcmp(finder_buf, em->em_type, sizeof( em->em_type )) && + !memcmp(finder_buf + 4, em->em_creator,sizeof( em->em_creator))) + )) { + memcpy(finder_buf, ufinderi, 8 ); + } memcpy(ad_entry( adp, ADEID_FINDERI ), finder_buf, 32 ); break; case FILPBIT_UNIXPR : diff --git a/etc/afpd/file.h b/etc/afpd/file.h index aa9f3b44..ec811596 100644 --- a/etc/afpd/file.h +++ b/etc/afpd/file.h @@ -51,12 +51,6 @@ extern const u_char ufinderi[]; #define FILPBIT_EXTRFLEN 14 #define FILPBIT_UNIXPR 15 -struct extmap { - char *em_ext; - char em_creator[ 4 ]; - char em_type[ 4 ]; -}; - #define kTextEncodingUTF8 0x08000103 typedef enum { diff --git a/include/atalk/globals.h b/include/atalk/globals.h index 36508e17..a8313a36 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -86,7 +86,7 @@ struct afp_options { char *uampath, *fqdn; char *sigconffile; char *uuidconf; - char *guest, *loginmesg, *keyfile, *passwdfile; + char *guest, *loginmesg, *keyfile, *passwdfile, *extmapfile; char *uamlist; char *signatureopt; unsigned char signature[16]; diff --git a/include/atalk/netatalk_conf.h b/include/atalk/netatalk_conf.h index 33459b31..cadb0aa3 100644 --- a/include/atalk/netatalk_conf.h +++ b/include/atalk/netatalk_conf.h @@ -31,4 +31,9 @@ extern struct vol *getvolbypath(AFPObj *obj, const char *path); extern struct vol *getvolbyname(const char *name); extern void volume_free(struct vol *vol); extern void volume_unlink(struct vol *volume); + +/* Extension type/creator mapping */ +struct extmap *getdefextmap(void); +struct extmap *getextmap(const char *path); + #endif diff --git a/include/atalk/volume.h b/include/atalk/volume.h index 116a4cec..e7f87724 100644 --- a/include/atalk/volume.h +++ b/include/atalk/volume.h @@ -20,6 +20,13 @@ typedef uint64_t VolSpace; +/* This should belong in a file.h */ +struct extmap { + char *em_ext; + char em_creator[4]; + char em_type[4]; +}; + struct vol { struct vol *v_next; AFPObj *v_obj; diff --git a/libatalk/libatalk-3.0.1dev.abi b/libatalk/libatalk-3.0.1dev.abi index fd06b366..f671fcab 100644 --- a/libatalk/libatalk-3.0.1dev.abi +++ b/libatalk/libatalk-3.0.1dev.abi @@ -281,8 +281,10 @@ _fini: freeifacelist: void (char **) fullpathname: const char *(const char *) getcwdpath: const char *(void) +getdefextmap: struct extmap *(void) get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int) get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *) +getextmap: struct extmap *(const char *) getifacelist: char **(void) getip_port: unsigned int (const struct sockaddr *) getip_string: const char *(const struct sockaddr *) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index b1d054c8..2e861a06 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1081,6 +1081,159 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) EC_EXIT; } +static struct extmap *Extmap = NULL, *Defextmap = NULL; +static int Extmap_cnt; + +static int setextmap(char *ext, char *type, char *creator) +{ + EC_INIT; + struct extmap *em; + int cnt; + + if (Extmap == NULL) { + EC_NULL_LOG( Extmap = calloc(1, sizeof( struct extmap )) ); + } + + ext++; + + for (em = Extmap, cnt = 0; em->em_ext; em++, cnt++) + if ((strdiacasecmp(em->em_ext, ext)) == 0) + goto EC_CLEANUP; + + EC_NULL_LOG( Extmap = realloc(Extmap, sizeof(struct extmap) * (cnt + 2)) ); + (Extmap + cnt + 1)->em_ext = NULL; + em = Extmap + cnt; + + EC_NULL( em->em_ext = strdup(ext) ); + + if ( *type == '\0' ) { + memcpy(em->em_type, "\0\0\0\0", sizeof( em->em_type )); + } else { + memcpy(em->em_type, type, sizeof( em->em_type )); + } + if ( *creator == '\0' ) { + memcpy(em->em_creator, "\0\0\0\0", sizeof( em->em_creator )); + } else { + memcpy(em->em_creator, creator, sizeof( em->em_creator )); + } + +EC_CLEANUP: + EC_EXIT; +} + +/* -------------------------- */ +static int extmap_cmp(const void *map1, const void *map2) +{ + const struct extmap *em1 = map1; + const struct extmap *em2 = map2; + return strdiacasecmp(em1->em_ext, em2->em_ext); +} + +static void sortextmap( void) +{ + struct extmap *em; + + Extmap_cnt = 0; + if ((em = Extmap) == NULL) { + return; + } + while (em->em_ext) { + em++; + Extmap_cnt++; + } + if (Extmap_cnt) { + qsort(Extmap, Extmap_cnt, sizeof(struct extmap), extmap_cmp); + if (*Extmap->em_ext == 0) { + /* the first line is really "." the default entry, + * we remove the leading '.' in setextmap + */ + Defextmap = Extmap; + } + } +} + +static void free_extmap( void) +{ + struct extmap *em; + + if (Extmap) { + for ( em = Extmap; em->em_ext; em++) { + free (em->em_ext); + } + free(Extmap); + Extmap = NULL; + Defextmap = Extmap; + Extmap_cnt = 0; + } +} + +static int ext_cmp_key(const void *key, const void *obj) +{ + const char *p = key; + const struct extmap *em = obj; + return strdiacasecmp(p, em->em_ext); +} + +struct extmap *getextmap(const char *path) +{ + char *p; + struct extmap *em; + + if (!Extmap_cnt || NULL == ( p = strrchr( path, '.' )) ) { + return( Defextmap ); + } + p++; + if (!*p) { + return( Defextmap ); + } + em = bsearch(p, Extmap, Extmap_cnt, sizeof(struct extmap), ext_cmp_key); + if (em) { + return( em ); + } else { + return( Defextmap ); + } +} + +struct extmap *getdefextmap(void) +{ + return( Defextmap ); +} + +static int readextmap(const char *file) +{ + EC_INIT; + FILE *fp; + char ext[256]; + char buf[256]; + char type[5], creator[5]; + + LOG(log_debug, logtype_afpd, "readextmap: loading \"%s\"", file); + + EC_NULL_LOGSTR( fp = fopen(file, "r"), "Couldn't open extension maping file %s", file); + + while (fgets(buf, sizeof(buf), fp) != NULL) { + initline(strlen(buf), buf); + parseline(sizeof(ext) - 1, ext); + + switch (ext[0]) { + case '.' : + parseline(sizeof(type) - 1, type); + parseline(sizeof(creator) - 1, creator); + setextmap(ext, type, creator); + LOG(log_debug, logtype_afpd, "readextmap: mapping: '%s' -> %s/%s", ext, type, creator); + break; + } + } + + sortextmap(); + EC_ZERO( fclose(fp) ); + + LOG(log_debug, logtype_afpd, "readextmap: done", file); + +EC_CLEANUP: + EC_EXIT; +} + /************************************************************** * API functions **************************************************************/ @@ -1495,7 +1648,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) /* figure out options w values */ options->loginmesg = iniparser_getstrdup(config, INISEC_GLOBAL, "login message", NULL); options->guest = iniparser_getstrdup(config, INISEC_GLOBAL, "guest account", "nobody"); - options->passwdfile = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file",_PATH_AFPDPWFILE); + options->extmapfile = iniparser_getstrdup(config, INISEC_GLOBAL, "extmap file", _PATH_CONFDIR "afp_extmap.conf"); + options->passwdfile = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file", _PATH_AFPDPWFILE); options->uampath = iniparser_getstrdup(config, INISEC_GLOBAL, "uam path", _PATH_AFPDUAMPATH); options->uamlist = iniparser_getstrdup(config, INISEC_GLOBAL, "uam list", "uams_dhx.so uams_dhx2.so"); options->port = iniparser_getstrdup(config, INISEC_GLOBAL, "afp port", "548"); @@ -1626,6 +1780,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->maccharset = CH_MAC; LOG(log_debug, logtype_afpd, "Global mac charset is %s", options->maccodepage); + EC_ZERO_LOG( readextmap(options->extmapfile) ); + /* Check for sane values */ if (options->tickleval <= 0) options->tickleval = 30; diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index 50e6f81e..b915b779 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -611,6 +611,11 @@ Maximum possible entries in the directory cache\&. The cache stores directories Default size is 8192, maximum size is 131072\&. Given value is rounded up to nearest power of 2\&. Each entry takes about 100 bytes, which is not much, but remember that every afpd child process for every connected user has its cache\&. .RE .PP +extmap file = \fIpath\fR \fB(G)\fR +.RS 4 +Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/extmap\&.conf)\&. +.RE +.PP fce listener = \fIhost[:port]\fR \fB(G)\fR .RS 4 Enables sending FCE events to the specified From 262b35dbdf3edf28451e24a68009b623bad69b46 Mon Sep 17 00:00:00 2001 From: HAT Date: Tue, 16 Oct 2012 22:55:39 +0900 Subject: [PATCH 019/117] apple_dump: use open2(), from Oichinokata --- contrib/shell_utils/apple_dump.in | 48 ++++++++++++++----------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/contrib/shell_utils/apple_dump.in b/contrib/shell_utils/apple_dump.in index 6054e0f8..30dbb425 100755 --- a/contrib/shell_utils/apple_dump.in +++ b/contrib/shell_utils/apple_dump.in @@ -50,6 +50,7 @@ use File::Basename; use File::Spec; use File::Temp qw /tempfile/; use bigint; # require perl >= 5.8 +use IPC::Open2 qw /open2/; # check command for extended attributes ----------------------------------- @@ -841,50 +842,46 @@ sub hexdump { sub checkea { my ($file) = @_; - $file =~ s/\\/\\\\/g; - $file =~ s/\"/\\\"/g; - $file =~ s/\$/\\\$/g; - $file =~ s/\`/\\\`/g; if ( $eacommand == 1 ) { - open(EALIST, "getfattr \"$file\" |"); + open2(\*EALIST, \*EAIN, 'getfattr', $file) or die $@; while() { if ( $_ eq "user.org.netatalk.Metadata\n" ) { - close (EALIST); + close (EALIST, EAIN); return 1; } } - close (EALIST); + close (EALIST, EAIN); return 0; } elsif ( $eacommand == 2 ) { - open(EALIST, "attr -q -l \"$file\" |"); + open2(\*EALIST, \*EAIN, 'attr', '-q', '-l', $file) or die $@; while() { if ( $_ eq "org.netatalk.Metadata\n" ) { - close (EALIST); + close (EALIST, EAIN); return 1; } } - close (EALIST); + close (EALIST, EAIN); return 0; } elsif ( $eacommand == 3 ) { - open(EALIST, "runat \"$file\" ls -1 |"); + open2(\*EALIST, \*EAIN, 'runat', $file, 'ls', '-1') or die $@; while() { if ( $_ eq "org.netatalk.Metadata\n" ) { - close (EALIST); + close (EALIST, EAIN); return 1; } } - close (EALIST); + close (EALIST, EAIN); return 0; } elsif ( $eacommand == 4 ) { - open(EALIST, "lsextattr -q user \"$file\" |"); + open2(\*EALIST, \*EAIN, 'lsextattr', '-q', 'user', $file) or die $@; while() { $_ = "\t".$_; if ( $_ =~ /\torg\.netatalk\.Metadata[\n\t]/ ) { - close (EALIST); + close (EALIST, EAIN); return 1; } } - close (EALIST); + close (EALIST, EAIN); return 0; } else { return 0; @@ -893,25 +890,24 @@ sub checkea { sub eaopenfile { my ($file) = @_; - - $file =~ s/\\/\\\\/g; - $file =~ s/\"/\\\"/g; - $file =~ s/\$/\\\$/g; - $file =~ s/\`/\\\`/g; - ($eatempfh, $eatempfile) = tempfile(UNLINK => 1); + my @eacommands = (); if ( $eacommand == 1 ) { - system("getfattr --only-values -n user.org.netatalk.Metadata \"$file\" > $eatempfile"); + @eacommands = ('getfattr', '--only-values', '-n', 'user.org.netatalk.Metadata', $file); } elsif ( $eacommand == 2 ) { - system("attr -q -g org.netatalk.Metadata \"$file\" > $eatempfile"); + @eacommands = ('attr', '-q', '-g', 'org.netatalk.Metadata', $file); } elsif ( $eacommand == 3 ) { - system("runat \"$file\" cat org.netatalk.Metadata > $eatempfile"); + @eacommands = ('runat', $file, 'cat', 'org.netatalk.Metadata',); } elsif ( $eacommand == 4 ) { - system("getextattr -q user org.netatalk.Metadata \"$file\" > $eatempfile"); + @eacommands = ('getextattr', '-q', 'user', 'org.netatalk.Metadata', $file); } else { return ""; } + my ($eatempfh, $eatempfile) = tempfile(UNLINK => 1); + open2(my $ealist, my $eain, @eacommands) or die $@; + print $eatempfh $_ while(<$ealist>); + close($ealist, $eain); close($eatempfh); return $eatempfile; } From 2bb6d9d9e88d6f1a9c6ed1f06500f1bc5b1e0cc3 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 17 Oct 2012 10:15:28 +0200 Subject: [PATCH 020/117] Default extension mapping filename ought to be extmap.conf Also changed: an error reading the extension mappings shouldn't be treates as a fatal error. --- libatalk/util/netatalk_conf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 2e861a06..dee04aa7 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1648,7 +1648,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) /* figure out options w values */ options->loginmesg = iniparser_getstrdup(config, INISEC_GLOBAL, "login message", NULL); options->guest = iniparser_getstrdup(config, INISEC_GLOBAL, "guest account", "nobody"); - options->extmapfile = iniparser_getstrdup(config, INISEC_GLOBAL, "extmap file", _PATH_CONFDIR "afp_extmap.conf"); + options->extmapfile = iniparser_getstrdup(config, INISEC_GLOBAL, "extmap file", _PATH_CONFDIR "extmap.conf"); options->passwdfile = iniparser_getstrdup(config, INISEC_GLOBAL, "passwd file", _PATH_AFPDPWFILE); options->uampath = iniparser_getstrdup(config, INISEC_GLOBAL, "uam path", _PATH_AFPDUAMPATH); options->uamlist = iniparser_getstrdup(config, INISEC_GLOBAL, "uam list", "uams_dhx.so uams_dhx2.so"); @@ -1780,7 +1780,10 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->maccharset = CH_MAC; LOG(log_debug, logtype_afpd, "Global mac charset is %s", options->maccodepage); - EC_ZERO_LOG( readextmap(options->extmapfile) ); + if (readextmap(options->extmapfile) != 0) { + LOG(log_error, logtype_afpd, "Couldn't load extension -> type/creator mappings file \"%s\"", + options->extmapfile); + } /* Check for sane values */ if (options->tickleval <= 0) From f18d47cfc7fd10a81394aec42ba3e65f4d567614 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 18 Oct 2012 12:38:25 +0200 Subject: [PATCH 021/117] Remove gettok.c from test afpd --- test/afpd/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/test/afpd/Makefile.am b/test/afpd/Makefile.am index 033c9e1d..01278ecd 100644 --- a/test/afpd/Makefile.am +++ b/test/afpd/Makefile.am @@ -31,7 +31,6 @@ test_SOURCES = test.c subtests.c afpfunc_helpers.c \ $(top_srcdir)/etc/afpd/file.c \ $(top_srcdir)/etc/afpd/filedir.c \ $(top_srcdir)/etc/afpd/fork.c \ - $(top_srcdir)/etc/afpd/gettok.c \ $(top_srcdir)/etc/afpd/hash.c \ $(top_srcdir)/etc/afpd/mangle.c \ $(top_srcdir)/etc/afpd/messages.c \ From ac09acab79ba74faa7b792930688d04ea217c4bf Mon Sep 17 00:00:00 2001 From: HAT Date: Fri, 19 Oct 2012 00:24:26 +0900 Subject: [PATCH 022/117] afpd -v: show path of extmap.conf --- etc/afpd/afp_options.c | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/afpd/afp_options.c b/etc/afpd/afp_options.c index 223f1178..6361d18f 100644 --- a/etc/afpd/afp_options.c +++ b/etc/afpd/afp_options.c @@ -222,6 +222,7 @@ static void show_version_extended(void ) static void show_paths( void ) { printf( " afp.conf:\t%s\n", _PATH_CONFDIR "afp.conf"); + printf( " extmap.conf:\t%s\n", _PATH_CONFDIR "extmap.conf"); printf( " state directory:\t%s\n", _PATH_STATEDIR); printf( " afp_signature.conf:\t%s\n", _PATH_STATEDIR "afp_signature.conf"); printf( " afp_voluuid.conf:\t%s\n", _PATH_STATEDIR "afp_voluuid.conf"); From ca9b23503ce9b7940aef2102bf8cb25bece4ab45 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 18 Oct 2012 20:00:27 +0200 Subject: [PATCH 023/117] Add extmap.conf to EXTRA_DIST so that it gets picked up by make dist --- config/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/Makefile.am b/config/Makefile.am index db57476d..57c85ff3 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -6,7 +6,7 @@ SUFFIXES = .tmpl . TMPLFILES = afp.conf.tmpl GENFILES = afp.conf CLEANFILES = $(GENFILES) -EXTRA_DIST = afp.conf.tmpl +EXTRA_DIST = afp.conf.tmpl extmap.conf OVERWRITE_CONFIG = @OVERWRITE_CONFIG@ From d4fdc0119a3fd21571e27aad6c3e6ff5c56ac880 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 24 Oct 2012 12:18:43 +0200 Subject: [PATCH 024/117] --with-libevent-header|lib requires a path Throw an error if any either configure option is passed without a path. Add libevent to library configure summary. --- macros/netatalk.m4 | 24 ++++++++++++++---------- macros/summary.m4 | 7 +++++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/macros/netatalk.m4 b/macros/netatalk.m4 index 7040eb04..51dbdcab 100644 --- a/macros/netatalk.m4 +++ b/macros/netatalk.m4 @@ -15,24 +15,28 @@ AC_DEFUN([AC_DEVELOPER], [ 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] ) - AC_MSG_RESULT([$use_bundled_libevent]) - if test x"$use_bundled_libevent" = x"yes" ; then - AC_CONFIG_SUBDIRS([libevent]) + 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]) + AC_CONFIG_SUBDIRS([libevent]) AC_SUBST(LIBEVENT_CFLAGS) AC_SUBST(LIBEVENT_LDFLAGS) AM_CONDITIONAL(USE_BUILTIN_LIBEVENT, test x"$use_bundled_libevent" = x"yes") diff --git a/macros/summary.m4 b/macros/summary.m4 index 94e84ac9..8d9abc50 100644 --- a/macros/summary.m4 +++ b/macros/summary.m4 @@ -116,4 +116,11 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [ AC_MSG_RESULT([ LIBS = $LDAP_LDLFLAGS $LDAP_LIBS]) AC_MSG_RESULT([ CFLAGS = $LDAP_CFLAGS]) fi + AC_MSG_RESULT([ LIBEVENT:]) + if test x"$use_bundled_libevent" = x"yes"; then + AC_MSG_RESULT([ bundled]) + else + AC_MSG_RESULT([ LIBS = $LIBEVENT_CFLAGS]) + AC_MSG_RESULT([ CFLAGS = $LIBEVENT_LDFLAGS]) + fi ]) From d202fc4ee109f920ec222cb8fd723f48f3803754 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 30 Oct 2012 11:49:40 +0100 Subject: [PATCH 025/117] Fix _device-info service type registered with dns-sd API --- etc/afpd/afp_mdns.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/etc/afpd/afp_mdns.c b/etc/afpd/afp_mdns.c index e14791fe..1dc6cbbb 100644 --- a/etc/afpd/afp_mdns.c +++ b/etc/afpd/afp_mdns.c @@ -232,7 +232,7 @@ static void register_stuff(const AFPObj *obj) { LOG(log_info, logtype_afpd, "Registering server '%s' with model '%s'", dsi->bonjourname, obj->options.mimicmodel); TXTRecordCreate(&txt_devinfo, 0, NULL); - TXTRecordPrintf(&txt_devinfo, "model=%s", obj->options.mimicmodel); + TXTRecordPrintf(&txt_devinfo, "model", obj->options.mimicmodel); error = DNSServiceRegister(&svc_refs[svc_ref_count++], 0, // no flags 0, // all network interfaces @@ -240,7 +240,14 @@ static void register_stuff(const AFPObj *obj) { DEV_INFO_SERVICE_TYPE, "", // default domains NULL, // default host name - 0, + /* + * We would probably use port 0 zero, but we can't, from man DNSServiceRegister: + * "A value of 0 for a port is passed to register placeholder services. + * Place holder services are not found when browsing, but other + * clients cannot register with the same name as the placeholder service." + * We therefor use port 9 which is used by the adisk service type. + */ + htons(9), TXTRecordGetLength(&txt_devinfo), TXTRecordGetBytesPtr(&txt_devinfo), RegisterReply, // callback From 1fa0166843eac60947d08f92c90a686fc8bcbff5 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 7 Nov 2012 12:59:55 +0100 Subject: [PATCH 026/117] Fix memory leak introduce in 18918d1 --- NEWS | 1 + libatalk/util/netatalk_conf.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index e1a68c43..8e192ea0 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Changes in 3.0.2 * FIX: "path" parameter value may contain symlink. * FIX: "basedir regex" was never able to treat symlink. If /home -> /usr/home, set "basedir regex = /usr/home". +* FIX: Memory leak Changes in 3.0.1 ================ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index dee04aa7..fd7ebfd1 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -564,7 +564,7 @@ static struct vol *creatvol(AFPObj *obj, struct vol *volume = NULL; size_t current_pathlen, another_pathlen; int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; - char *tmpname; + char tmpname[AFPVOL_U8MNAMELEN+1]; char path[MAXPATHLEN + 1]; ucs2_t u8mtmpname[(AFPVOL_U8MNAMELEN+1)*2], mactmpname[(AFPVOL_MACNAMELEN+1)*2]; char suffix[6]; /* max is #FFFF */ @@ -670,7 +670,7 @@ static struct vol *creatvol(AFPObj *obj, EC_NULL( volume->v_maccodepage = strdup(obj->options.maccodepage) ); vlen = strlen(name); - tmpname = strdup(name); + strlcpy(tmpname, name, sizeof(tmpname)); for(i = 0; i < vlen; i++) if(tmpname[i] == '/') tmpname[i] = ':'; From 557cee5838047f065091db1ec84f98468540c42c Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 8 Nov 2012 10:41:33 +0100 Subject: [PATCH 027/117] Remove AppleTalk logger types and add FCE type --- include/atalk/logger.h | 3 +-- libatalk/util/logger.c | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/include/atalk/logger.h b/include/atalk/logger.h index cf67bcad..330eb7b6 100644 --- a/include/atalk/logger.h +++ b/include/atalk/logger.h @@ -90,9 +90,8 @@ enum logtypes { logtype_cnid, logtype_afpd, logtype_dsi, - logtype_atalkd, - logtype_papd, logtype_uams, + logtype_fce, logtype_end_of_list_marker /* don't put any logtypes after this */ }; diff --git a/libatalk/util/logger.c b/libatalk/util/logger.c index c8a2a0a8..7bec1b8b 100644 --- a/libatalk/util/logger.c +++ b/libatalk/util/logger.c @@ -59,10 +59,9 @@ Netatalk 2001 (c) "CNID", \ "AFPDaemon", \ "DSI", \ - "ATalkDaemon", \ - "PAPDaemon", \ "UAMS", \ - "end_of_list_marker"} \ + "FCE", \ + "end_of_list_marker"} /* ========================================================================= Config @@ -85,9 +84,8 @@ UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_end_of_list_marker] = { DEFAULT_LOG_CONFIG, /* logtype_cnid */ DEFAULT_LOG_CONFIG, /* logtype_afpd */ DEFAULT_LOG_CONFIG, /* logtype_dsi */ - DEFAULT_LOG_CONFIG, /* logtype_atalkd */ - DEFAULT_LOG_CONFIG, /* logtype_papd */ - DEFAULT_LOG_CONFIG /* logtype_uams */ + DEFAULT_LOG_CONFIG, /* logtype_uams */ + DEFAULT_LOG_CONFIG /* logtype_fce */ }; static void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility); From 302d231a56fd1732a002275951c0ee30b7b3c256 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 8 Nov 2012 10:42:16 +0100 Subject: [PATCH 028/117] Add FCE type names and adjust logtypes to new fce facility --- etc/afpd/fce_api.c | 41 ++++++++++++++++++++++++++++------------- include/atalk/fce_api.h | 2 ++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/etc/afpd/fce_api.c b/etc/afpd/fce_api.c index b40eafb9..bb42bb1e 100644 --- a/etc/afpd/fce_api.c +++ b/etc/afpd/fce_api.c @@ -80,6 +80,16 @@ static const char *skip_files[] = }; static struct fce_close_event last_close_event; +static char *fce_event_names[] = { + "", + "FCE_FILE_MODIFY", + "FCE_FILE_DELETE", + "FCE_DIR_DELETE", + "FCE_FILE_CREATE", + "FCE_DIR_CREATE", + "FCE_TM_SIZE", +}; + /* * * Initialize network structs for any listeners @@ -106,7 +116,7 @@ void fce_init_udp() close(udp_entry->sock); if ((rv = getaddrinfo(udp_entry->addr, udp_entry->port, &hints, &servinfo)) != 0) { - LOG(log_error, logtype_afpd, "fce_init_udp: getaddrinfo(%s:%s): %s", + LOG(log_error, logtype_fce, "fce_init_udp: getaddrinfo(%s:%s): %s", udp_entry->addr, udp_entry->port, gai_strerror(rv)); continue; } @@ -114,7 +124,7 @@ void fce_init_udp() /* loop through all the results and make a socket */ for (p = servinfo; p != NULL; p = p->ai_next) { if ((udp_entry->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { - LOG(log_error, logtype_afpd, "fce_init_udp: socket(%s:%s): %s", + LOG(log_error, logtype_fce, "fce_init_udp: socket(%s:%s): %s", udp_entry->addr, udp_entry->port, strerror(errno)); continue; } @@ -122,7 +132,7 @@ void fce_init_udp() } if (p == NULL) { - LOG(log_error, logtype_afpd, "fce_init_udp: no socket for %s:%s", + LOG(log_error, logtype_fce, "fce_init_udp: no socket for %s:%s", udp_entry->addr, udp_entry->port); } udp_entry->addrinfo = *p; @@ -240,7 +250,7 @@ static void send_fce_event( char *path, int mode ) static uint32_t event_id = 0; /* the unique packet couter to detect packet/data loss. Going from 0xFFFFFFFF to 0x0 is a valid increment */ time_t now = time(NULL); - LOG(log_debug, logtype_afpd, "send_fce_event: start"); + LOG(log_debug, logtype_fce, "send_fce_event: start"); /* initialized ? */ if (first_event == FCE_TRUE) { @@ -273,7 +283,7 @@ static void send_fce_event( char *path, int mode ) if (udp_entry->sock == -1) { /* failed again, so go to rest again */ - LOG(log_error, logtype_afpd, "Cannot recreate socket for fce UDP connection: errno %d", errno ); + LOG(log_error, logtype_fce, "Cannot recreate socket for fce UDP connection: errno %d", errno ); udp_entry->next_try_on_error = now + FCE_SOCKET_RETRY_DELAY_S; continue; @@ -307,7 +317,7 @@ static void send_fce_event( char *path, int mode ) /* Problems ? */ if (sent_data != data_len) { /* Argh, socket broke, we close and retry later */ - LOG(log_error, logtype_afpd, "send_fce_event: error sending packet to %s:%s, transfered %d of %d: %s", + LOG(log_error, logtype_fce, "send_fce_event: error sending packet to %s:%s, transfered %d of %d: %s", udp_entry->addr, udp_entry->port, sent_data, data_len, strerror(errno)); close( udp_entry->sock ); @@ -323,7 +333,7 @@ static int add_udp_socket(const char *target_ip, const char *target_port ) target_port = FCE_DEFAULT_PORT_STRING; if (udp_sockets >= FCE_MAX_UDP_SOCKS) { - LOG(log_error, logtype_afpd, "Too many file change api UDP connections (max %d allowed)", FCE_MAX_UDP_SOCKS ); + LOG(log_error, logtype_fce, "Too many file change api UDP connections (max %d allowed)", FCE_MAX_UDP_SOCKS ); return AFPERR_PARAM; } @@ -350,7 +360,7 @@ static void save_close_event(const char *path) send_fce_event(last_close_event.path, FCE_FILE_MODIFY); } - LOG(log_debug, logtype_afpd, "save_close_event: %s", path); + LOG(log_debug, logtype_fce, "save_close_event: %s", path); last_close_event.time = now; strncpy(last_close_event.path, path, MAXPATHLEN); @@ -365,6 +375,11 @@ static int register_fce(const char *u_name, int is_dir, int mode) { static int first_event = FCE_TRUE; + AFP_ASSERT(mode >= FCE_FIRST_EVENT && mode <= FCE_LAST_EVENT); + + LOG(log_debug, logtype_fce, "register_fce(path: %s, type: %s, event: %s", + fullpathname(u_name), is_dir ? "dir" : "file", fce_event_names[mode]); + if (udp_sockets == 0) /* No listeners configured */ return AFP_OK; @@ -393,13 +408,13 @@ static int register_fce(const char *u_name, int is_dir, int mode) strlcpy(full_path_buffer, u_name, MAXPATHLEN); } else if (!is_dir || mode == FCE_DIR_DELETE) { if (strlen( cwd ) + strlen( u_name) + 1 >= MAXPATHLEN) { - LOG(log_error, logtype_afpd, "FCE file name too long: %s/%s", cwd, u_name ); + LOG(log_error, logtype_fce, "FCE file name too long: %s/%s", cwd, u_name ); return AFPERR_PARAM; } sprintf( full_path_buffer, "%s/%s", cwd, u_name ); } else { if (strlen( cwd ) >= MAXPATHLEN) { - LOG(log_error, logtype_afpd, "FCE directory name too long: %s", cwd); + LOG(log_error, logtype_fce, "FCE directory name too long: %s", cwd); return AFPERR_PARAM; } strcpy( full_path_buffer, cwd); @@ -408,11 +423,11 @@ static int register_fce(const char *u_name, int is_dir, int mode) /* Can we ignore this event based on type or history? */ if (!(mode & FCE_TM_SIZE) && fce_handle_coalescation( full_path_buffer, is_dir, mode )) { - LOG(log_debug9, logtype_afpd, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer ); + LOG(log_debug9, logtype_fce, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer ); return AFP_OK; } - LOG(log_debug9, logtype_afpd, "Detected fc event <%d> for <%s>", mode, full_path_buffer ); + LOG(log_debug9, logtype_fce, "Detected fc event <%d> for <%s>", mode, full_path_buffer ); if (mode & FCE_FILE_MODIFY) { save_close_event(full_path_buffer); @@ -430,7 +445,7 @@ static void check_saved_close_events(int fmodwait) /* check if configured holdclose time has passed */ if (last_close_event.time && ((last_close_event.time + fmodwait) < now)) { - LOG(log_debug, logtype_afpd, "check_saved_close_events: sending event: %s", last_close_event.path); + LOG(log_debug, logtype_fce, "check_saved_close_events: sending event: %s", last_close_event.path); /* yes, send event */ send_fce_event(&last_close_event.path[0], FCE_FILE_MODIFY); last_close_event.path[0] = 0; diff --git a/include/atalk/fce_api.h b/include/atalk/fce_api.h index aebb56ad..b76c06cb 100755 --- a/include/atalk/fce_api.h +++ b/include/atalk/fce_api.h @@ -22,6 +22,8 @@ #define FCE_CONN_START 42 #define FCE_CONN_BROKEN 99 +#define FCE_FIRST_EVENT FCE_FILE_MODIFY /* keep in sync with last file event above */ +#define FCE_LAST_EVENT FCE_TM_SIZE /* keep in sync with last file event above */ /* fce_packet.fce_magic */ #define FCE_PACKET_MAGIC "at_fcapi" From b3b8626162037ab99e9d3919ee663079549716e8 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 8 Nov 2012 11:39:13 +0100 Subject: [PATCH 029/117] Remove TimeMachine volume used size FCE event --- bin/misc/fce.c | 10 +-------- etc/afpd/fce_api.c | 47 +++++----------------------------------- etc/afpd/volume.c | 16 -------------- etc/afpd/volume.h | 1 - include/atalk/fce_api.h | 6 ++--- man/man5/afp.conf.5.tmpl | 2 +- 6 files changed, 9 insertions(+), 73 deletions(-) diff --git a/bin/misc/fce.c b/bin/misc/fce.c index d6969907..dc58602e 100644 --- a/bin/misc/fce.c +++ b/bin/misc/fce.c @@ -27,8 +27,7 @@ static char *fce_ev_names[] = { "FCE_FILE_DELETE", "FCE_DIR_DELETE", "FCE_FILE_CREATE", - "FCE_DIR_CREATE", - "FCE_TM_SIZE" + "FCE_DIR_CREATE" }; // get sockaddr, IPv4 or IPv6: @@ -134,13 +133,6 @@ int main(void) if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) { switch (packet.mode) { - case FCE_TM_SIZE: - memcpy(&tmsize, packet.data, sizeof(uint64_t)); - tmsize = ntoh64(tmsize); - printf("ID: %" PRIu32 ", Event: %s, Volume: %s, TM used size: %" PRIu64 " \n", - packet.event_id, fce_ev_names[packet.mode], packet.data + sizeof(uint64_t), tmsize); - break; - case FCE_CONN_START: printf("FCE Start\n"); break; diff --git a/etc/afpd/fce_api.c b/etc/afpd/fce_api.c index bb42bb1e..7be4336a 100644 --- a/etc/afpd/fce_api.c +++ b/etc/afpd/fce_api.c @@ -70,7 +70,6 @@ static unsigned long fce_ev_enabled = (1 << FCE_FILE_CREATE) | (1 << FCE_DIR_CREATE); -static uint64_t tm_used; /* used for passing to event handler */ #define MAXIOBUF 1024 static char iobuf[MAXIOBUF]; static const char *skip_files[] = @@ -86,8 +85,7 @@ static char *fce_event_names[] = { "FCE_FILE_DELETE", "FCE_DIR_DELETE", "FCE_FILE_CREATE", - "FCE_DIR_CREATE", - "FCE_TM_SIZE", + "FCE_DIR_CREATE" }; /* @@ -190,19 +188,7 @@ static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode /* This is the payload len. Means: the packet has len bytes more until packet is finished */ data_len = FCE_PACKET_HEADER_SIZE + pathlen; - switch (mode) { - case FCE_TM_SIZE: - t = (uint64_t *)packet->data; - *t = hton64(tm_used); - memcpy(packet->data + sizeof(tm_used), path, pathlen); - - packet->datalen = pathlen + sizeof(tm_used); - data_len += sizeof(tm_used); - break; - default: - memcpy(packet->data, path, pathlen); - break; - } + memcpy(packet->data, path, pathlen); /* return the packet len */ return data_len; @@ -401,12 +387,11 @@ static int register_fce(const char *u_name, int is_dir, int mode) } + /* FIXME: use fullpathname() for path? */ char full_path_buffer[MAXPATHLEN + 1] = {""}; const char *cwd = getcwdpath(); - if (mode == FCE_TM_SIZE) { - strlcpy(full_path_buffer, u_name, MAXPATHLEN); - } else if (!is_dir || mode == FCE_DIR_DELETE) { + if (!is_dir || mode == FCE_DIR_DELETE) { if (strlen( cwd ) + strlen( u_name) + 1 >= MAXPATHLEN) { LOG(log_error, logtype_fce, "FCE file name too long: %s/%s", cwd, u_name ); return AFPERR_PARAM; @@ -421,14 +406,11 @@ static int register_fce(const char *u_name, int is_dir, int mode) } /* Can we ignore this event based on type or history? */ - if (!(mode & FCE_TM_SIZE) && fce_handle_coalescation( full_path_buffer, is_dir, mode )) - { + if (fce_handle_coalescation(full_path_buffer, is_dir, mode)) { LOG(log_debug9, logtype_fce, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer ); return AFP_OK; } - LOG(log_debug9, logtype_fce, "Detected fc event <%d> for <%s>", mode, full_path_buffer ); - if (mode & FCE_FILE_MODIFY) { save_close_event(full_path_buffer); return AFP_OK; @@ -462,7 +444,6 @@ static void check_saved_close_events(int fmodwait) void fce_pending_events(AFPObj *obj) { - vol_fce_tm_event(); check_saved_close_events(obj->options.fce_fmodwait); } @@ -540,22 +521,6 @@ int fce_register_file_modification( struct ofork *ofork ) return ret; } - -int fce_register_tm_size(const char *vol, size_t used) -{ - int ret = AFP_OK; - - if (vol == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_TM_SIZE))) - return ret; - - tm_used = used; /* oh what a hack */ - ret = register_fce(vol, false, FCE_TM_SIZE); - - return ret; -} #endif /* @@ -601,8 +566,6 @@ int fce_set_events(const char *events) fce_ev_enabled |= (1 << FCE_FILE_CREATE); } else if (strcmp(p, "dcre") == 0) { fce_ev_enabled |= (1 << FCE_DIR_CREATE); - } else if (strcmp(p, "tmsz") == 0) { - fce_ev_enabled |= (1 << FCE_TM_SIZE); } } diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 7e70c65d..61d8b408 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -264,22 +264,6 @@ static int getvolspace(const AFPObj *obj, struct vol *vol, 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 diff --git a/etc/afpd/volume.h b/etc/afpd/volume.h index 3bca8821..a8bd2b8b 100644 --- a/etc/afpd/volume.h +++ b/etc/afpd/volume.h @@ -19,7 +19,6 @@ extern int ustatfs_getvolspace (const struct vol *, uint32_t *); extern void setvoltime (AFPObj *, struct vol *); extern int pollvoltime (AFPObj *); -extern void vol_fce_tm_event(void); /* FP functions */ int afp_openvol (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen); diff --git a/include/atalk/fce_api.h b/include/atalk/fce_api.h index b76c06cb..211921b7 100755 --- a/include/atalk/fce_api.h +++ b/include/atalk/fce_api.h @@ -18,12 +18,11 @@ #define FCE_DIR_DELETE 3 #define FCE_FILE_CREATE 4 #define FCE_DIR_CREATE 5 -#define FCE_TM_SIZE 6 #define FCE_CONN_START 42 #define FCE_CONN_BROKEN 99 #define FCE_FIRST_EVENT FCE_FILE_MODIFY /* keep in sync with last file event above */ -#define FCE_LAST_EVENT FCE_TM_SIZE /* keep in sync with last file event above */ +#define FCE_LAST_EVENT FCE_DIR_CREATE /* keep in sync with last file event above */ /* fce_packet.fce_magic */ #define FCE_PACKET_MAGIC "at_fcapi" @@ -53,11 +52,10 @@ int fce_register_delete_dir( char *name ); int fce_register_new_dir( struct path *path ); int fce_register_new_file( struct path *path ); int fce_register_file_modification( struct ofork *ofork ); -int fce_register_tm_size(const char *vol, size_t used); int fce_add_udp_socket(const char *target ); // IP or IP:Port int fce_set_coalesce(const char *coalesce_opt ); // all|delete|create -int fce_set_events(const char *events); /* fmod,fdel,ddel,fcre,dcre,tmsz (default is all except tmsz) */ +int fce_set_events(const char *events); /* fmod,fdel,ddel,fcre,dcre */ #define FCE_DEFAULT_PORT 12250 #define FCE_DEFAULT_PORT_STRING "12250" diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index b915b779..0e0bc653 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -624,7 +624,7 @@ Enables sending FCE events to the specified is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&. .RE .PP -fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR +fce events = \fIfmod,fdel,ddel,fcre,dcre\fR \fB(G)\fR .RS 4 Speficies which FCE events are active, default is \fIfmod,fdel,ddel,fcre,dcre\fR\&. From b1ed4851a0e9873f23e585dbdc50f701b8cae3aa Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 8 Nov 2012 12:19:04 +0100 Subject: [PATCH 030/117] 0 terminate packet data --- bin/misc/fce.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/misc/fce.c b/bin/misc/fce.c index dc58602e..b80f6a14 100644 --- a/bin/misc/fce.c +++ b/bin/misc/fce.c @@ -62,6 +62,7 @@ static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet) packet->datalen = ntohs(packet->datalen); memcpy(&packet->data[0], p, packet->datalen); + packet->data[packet->datalen] = 0; /* 0 terminate strings */ p += packet->datalen; return 0; From a4d1520370c375503295705f60d9fa0b6b1083f3 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 9 Nov 2012 11:42:30 +0100 Subject: [PATCH 031/117] Add function basename_safe --- include/atalk/util.h | 1 + libatalk/util/unix.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/atalk/util.h b/include/atalk/util.h index 39237e7c..ad2709a4 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -183,6 +183,7 @@ extern void randombytes(void *buf, int n); extern int daemonize(int nochdir, int noclose); extern int run_cmd(const char *cmd, char **cmd_argv); extern char *realpath_safe(const char *path); +extern const char *basename_safe(const char *path); /****************************************************************** * cnid.c diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 0e8fcab6..6dce0857 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -375,3 +376,13 @@ char *realpath_safe(const char *path) return resolved_path; #endif } + +/** + * Returns pointer to static buffer with basename of path + **/ +const char *basename_safe(const char *path) +{ + static char buf[MAXPATHLEN+1]; + strlcpy(buf, path, MAXPATHLEN); + return basename(buf); +} From d29ded52bda8d46bf341b8a91bac85b195e02dc4 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 9 Nov 2012 11:53:24 +0100 Subject: [PATCH 032/117] FCE API change and cleanup Change the FCE API by using a single function (fce_register()) as a single point for callers to register events. Remove all individual event functions. Add types for events and file/directoy flag. Use standard bool type instead of special defines FCE_TRUE/FALSE. --- etc/afpd/directory.c | 2 +- etc/afpd/fce_api.c | 171 ++++++++---------------------------- etc/afpd/fce_api_internal.h | 18 ++-- etc/afpd/fce_util.c | 35 ++++---- etc/afpd/file.c | 2 +- etc/afpd/filedir.c | 6 +- etc/afpd/ofork.c | 2 +- include/atalk/fce_api.h | 12 ++- 8 files changed, 75 insertions(+), 173 deletions(-) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index ed40a26a..8b36c99b 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -2195,7 +2195,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ ad_setname(&ad, s_path->m_name); ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp); - fce_register_new_dir(s_path); + fce_register(FCE_DIR_CREATE, bdata(curdir->d_fullpath), NULL, fce_dir); ad_flush(&ad); ad_close(&ad, ADFLAGS_HF); diff --git a/etc/afpd/fce_api.c b/etc/afpd/fce_api.c index 7be4336a..5f6b70ba 100644 --- a/etc/afpd/fce_api.c +++ b/etc/afpd/fce_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010 Mark Williams + * Copyright (c) 2012 Frank Lahm * * File change event API for netatalk * @@ -29,13 +30,12 @@ #include #include #include - - #include #include #include #include #include +#include #include #include @@ -56,13 +56,10 @@ // ONLY USED IN THIS FILE #include "fce_api_internal.h" -#define FCE_TRUE 1 -#define FCE_FALSE 0 - /* We store our connection data here */ static struct udp_entry udp_socket_list[FCE_MAX_UDP_SOCKS]; static int udp_sockets = 0; -static int udp_initialized = FCE_FALSE; +static bool udp_initialized = false; static unsigned long fce_ev_enabled = (1 << FCE_FILE_MODIFY) | (1 << FCE_FILE_DELETE) | @@ -99,7 +96,7 @@ void fce_init_udp() int rv; struct addrinfo hints, *servinfo, *p; - if (udp_initialized == FCE_TRUE) + if (udp_initialized == true) return; memset(&hints, 0, sizeof hints); @@ -139,12 +136,12 @@ void fce_init_udp() freeaddrinfo(servinfo); } - udp_initialized = FCE_TRUE; + udp_initialized = true; } void fce_cleanup() { - if (udp_initialized == FCE_FALSE ) + if (udp_initialized == false ) return; for (int i = 0; i < udp_sockets; i++) @@ -158,13 +155,13 @@ void fce_cleanup() udp_entry->sock = -1; } } - udp_initialized = FCE_FALSE; + udp_initialized = false; } /* * Construct a UDP packet for our listeners and return packet size * */ -static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode, uint32_t event_id ) +static ssize_t build_fce_packet( struct fce_packet *packet, const char *path, int event, uint32_t event_id ) { size_t pathlen = 0; ssize_t data_len = 0; @@ -173,7 +170,7 @@ static ssize_t build_fce_packet( struct fce_packet *packet, char *path, int mode /* Set content of packet */ memcpy(packet->magic, FCE_PACKET_MAGIC, sizeof(packet->magic) ); packet->version = FCE_PACKET_VERSION; - packet->mode = mode; + packet->mode = event; packet->event_id = event_id; @@ -227,9 +224,9 @@ static void pack_fce_packet(struct fce_packet *packet, unsigned char *buf, int m * Send the fce information to all (connected) listeners * We dont give return code because all errors are handled internally (I hope..) * */ -static void send_fce_event( char *path, int mode ) +static void send_fce_event(const char *path, int event) { - static int first_event = FCE_TRUE; + static bool first_event = true; struct fce_packet packet; void *data = &packet; @@ -239,15 +236,15 @@ static void send_fce_event( char *path, int mode ) LOG(log_debug, logtype_fce, "send_fce_event: start"); /* initialized ? */ - if (first_event == FCE_TRUE) { - first_event = FCE_FALSE; + if (first_event == true) { + first_event = false; fce_init_udp(); /* Notify listeners the we start from the beginning */ send_fce_event( "", FCE_CONN_START ); } /* build our data packet */ - ssize_t data_len = build_fce_packet( &packet, path, mode, ++event_id ); + ssize_t data_len = build_fce_packet( &packet, path, event, ++event_id ); pack_fce_packet(&packet, iobuf, MAXIOBUF); for (int i = 0; i < udp_sockets; i++) @@ -289,7 +286,7 @@ static void send_fce_event( char *path, int mode ) udp_entry->addrinfo.ai_addrlen); /* Rebuild our original data packet */ - data_len = build_fce_packet( &packet, path, mode, event_id ); + data_len = build_fce_packet(&packet, path, event, event_id); pack_fce_packet(&packet, iobuf, MAXIOBUF); } @@ -357,67 +354,55 @@ static void save_close_event(const char *path) * Dispatcher for all incoming file change events * * */ -static int register_fce(const char *u_name, int is_dir, int mode) +int fce_register(fce_ev_t event, const char *path, const char *oldpath, fce_obj_t type) { - static int first_event = FCE_TRUE; + static bool first_event = true; + const char *bname; - AFP_ASSERT(mode >= FCE_FIRST_EVENT && mode <= FCE_LAST_EVENT); + if (!(fce_ev_enabled & (1 << event))) + return AFP_OK; + + AFP_ASSERT(event >= FCE_FIRST_EVENT && event <= FCE_LAST_EVENT); LOG(log_debug, logtype_fce, "register_fce(path: %s, type: %s, event: %s", - fullpathname(u_name), is_dir ? "dir" : "file", fce_event_names[mode]); + path , type == fce_dir ? "dir" : "file", fce_event_names[event]); + + bname = basename_safe(path); if (udp_sockets == 0) /* No listeners configured */ return AFP_OK; - if (u_name == NULL) + if (path == NULL) return AFPERR_PARAM; /* do some initialization on the fly the first time */ if (first_event) { fce_initialize_history(); - first_event = FCE_FALSE; + first_event = false; } /* handle files which should not cause events (.DS_Store atc. ) */ - for (int i = 0; skip_files[i] != NULL; i++) - { - if (!strcmp( u_name, skip_files[i])) + for (int i = 0; skip_files[i] != NULL; i++) { + if (strcmp(bname, skip_files[i]) == 0) return AFP_OK; } - - /* FIXME: use fullpathname() for path? */ - char full_path_buffer[MAXPATHLEN + 1] = {""}; - const char *cwd = getcwdpath(); - - if (!is_dir || mode == FCE_DIR_DELETE) { - if (strlen( cwd ) + strlen( u_name) + 1 >= MAXPATHLEN) { - LOG(log_error, logtype_fce, "FCE file name too long: %s/%s", cwd, u_name ); - return AFPERR_PARAM; - } - sprintf( full_path_buffer, "%s/%s", cwd, u_name ); - } else { - if (strlen( cwd ) >= MAXPATHLEN) { - LOG(log_error, logtype_fce, "FCE directory name too long: %s", cwd); - return AFPERR_PARAM; - } - strcpy( full_path_buffer, cwd); - } - /* Can we ignore this event based on type or history? */ - if (fce_handle_coalescation(full_path_buffer, is_dir, mode)) { - LOG(log_debug9, logtype_fce, "Coalesced fc event <%d> for <%s>", mode, full_path_buffer ); + if (fce_handle_coalescation(event, path, type)) { + LOG(log_debug9, logtype_fce, "Coalesced fc event <%d> for <%s>", event, path); return AFP_OK; } - if (mode & FCE_FILE_MODIFY) { - save_close_event(full_path_buffer); - return AFP_OK; + switch (event) { + case FCE_FILE_MODIFY: + save_close_event(path); + break; + default: + send_fce_event(path, event); + break; } - send_fce_event( full_path_buffer, mode ); - return AFP_OK; } @@ -440,89 +425,11 @@ static void check_saved_close_events(int fmodwait) /* * API-Calls for file change api, called form outside (file.c directory.c ofork.c filedir.c) * */ -#ifndef FCE_TEST_MAIN - void fce_pending_events(AFPObj *obj) { check_saved_close_events(obj->options.fce_fmodwait); } -int fce_register_delete_file( struct path *path ) -{ - int ret = AFP_OK; - - if (path == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_FILE_DELETE))) - return ret; - - ret = register_fce( path->u_name, false, FCE_FILE_DELETE ); - - return ret; -} -int fce_register_delete_dir( char *name ) -{ - int ret = AFP_OK; - - if (name == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_DIR_DELETE))) - return ret; - - ret = register_fce( name, true, FCE_DIR_DELETE); - - return ret; -} - -int fce_register_new_dir( struct path *path ) -{ - int ret = AFP_OK; - - if (path == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_DIR_CREATE))) - return ret; - - ret = register_fce( path->u_name, true, FCE_DIR_CREATE ); - - return ret; -} - - -int fce_register_new_file( struct path *path ) -{ - int ret = AFP_OK; - - if (path == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_FILE_CREATE))) - return ret; - - ret = register_fce( path->u_name, false, FCE_FILE_CREATE ); - - return ret; -} - -int fce_register_file_modification( struct ofork *ofork ) -{ - int ret = AFP_OK; - - if (ofork == NULL) - return AFPERR_PARAM; - - if (!(fce_ev_enabled & (1 << FCE_FILE_MODIFY))) - return ret; - - ret = register_fce(of_name(ofork), false, FCE_FILE_MODIFY ); - - return ret; -} -#endif - /* * * Extern connect to afpd parameter, can be called multiple times for multiple listeners (up to MAX_UDP_SOCKS times) @@ -646,7 +553,7 @@ int main( int argc, char*argv[] ) if (end_time && now >= end_time) break; - register_fce( path, 0, event_code ); + fce_register(event_code, path, NULL, 0); ev_cnt++; diff --git a/etc/afpd/fce_api_internal.h b/etc/afpd/fce_api_internal.h index 9ed185e5..fb5e58e3 100644 --- a/etc/afpd/fce_api_internal.h +++ b/etc/afpd/fce_api_internal.h @@ -10,6 +10,8 @@ #include +#include + #define FCE_MAX_UDP_SOCKS 5 /* Allow a maximum of udp listeners for file change events */ #define FCE_SOCKET_RETRY_DELAY_S 600 /* Pause this time in s after socket was broken */ #define FCE_PACKET_VERSION 1 @@ -20,8 +22,7 @@ #define FCE_COALESCE_DELETE (1 << 1) #define FCE_COALESCE_ALL (FCE_COALESCE_CREATE | FCE_COALESCE_DELETE) -struct udp_entry -{ +struct udp_entry { int sock; char *addr; char *port; @@ -30,12 +31,11 @@ struct udp_entry time_t next_try_on_error; /* In case of error set next timestamp to retry */ }; -struct fce_history -{ - unsigned char mode; - int is_dir; - char path[MAXPATHLEN + 1]; - struct timeval tv; +struct fce_history { + fce_ev_t fce_h_event; + fce_obj_t fce_h_type; + char fce_h_path[MAXPATHLEN + 1]; + struct timeval fce_h_tv; }; struct fce_close_event { @@ -45,7 +45,7 @@ struct fce_close_event { #define PACKET_HDR_LEN (sizeof(struct fce_packet) - FCE_MAX_PATH_LEN) -bool fce_handle_coalescation( char *path, int is_dir, int mode ); +bool fce_handle_coalescation(int event, const char *path, fce_obj_t type); void fce_initialize_history(); diff --git a/etc/afpd/fce_util.c b/etc/afpd/fce_util.c index 07b59d73..69f6ea0d 100644 --- a/etc/afpd/fce_util.c +++ b/etc/afpd/fce_util.c @@ -54,9 +54,6 @@ // ONLY USED IN THIS FILE #include "fce_api_internal.h" -#define FCE_TRUE 1 -#define FCE_FALSE 0 - /* We store our connection data here */ static uint32_t coalesce = 0; static struct fce_history fce_history_list[FCE_HISTORY_LEN]; @@ -92,7 +89,7 @@ void fce_initialize_history() } } -bool fce_handle_coalescation( char *path, int is_dir, int mode ) +bool fce_handle_coalescation(int event, const char *path, fce_obj_t type) { /* These two are used to eval our next index in history */ /* the history is unsorted, speed should not be a problem, length is 10 */ @@ -104,7 +101,7 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode ) return false; /* After a file creation *ALWAYS* a file modification is produced */ - if ((mode == FCE_FILE_CREATE) && (coalesce & FCE_COALESCE_CREATE)) + if ((event == FCE_FILE_CREATE) && (coalesce & FCE_COALESCE_CREATE)) return true; /* get timestamp */ @@ -115,7 +112,7 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode ) struct fce_history *fh = &fce_history_list[i]; /* Not inited ? */ - if (fh->tv.tv_sec == 0) { + if (fh->fce_h_tv.tv_sec == 0) { /* we can use it for new elements */ oldest_entry = 0; oldest_entry_idx = i; @@ -123,9 +120,9 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode ) } /* Too old ? */ - if (get_ms_difftime( &fh->tv, &tv ) > MAX_COALESCE_TIME_MS) { + if (get_ms_difftime(&fh->fce_h_tv, &tv ) > MAX_COALESCE_TIME_MS) { /* Invalidate entry */ - fh->tv.tv_sec = 0; + fh->fce_h_tv.tv_sec = 0; oldest_entry = 0; oldest_entry_idx = i; continue; @@ -133,33 +130,33 @@ bool fce_handle_coalescation( char *path, int is_dir, int mode ) /* If we find a parent dir wich was created we are done */ - if ((coalesce & FCE_COALESCE_CREATE) && (fh->mode == FCE_DIR_CREATE)) { + if ((coalesce & FCE_COALESCE_CREATE) && (fh->fce_h_event == FCE_DIR_CREATE)) { /* Parent dir ? */ - if (!strncmp(fh->path, path, strlen(fh->path))) + if (!strncmp(fh->fce_h_path, path, strlen(fh->fce_h_path))) return true; } /* If we find a parent dir we should be DELETED we are done */ if ((coalesce & FCE_COALESCE_DELETE) - && fh->is_dir - && (mode == FCE_FILE_DELETE || mode == FCE_DIR_DELETE)) { + && fh->fce_h_type + && (event == FCE_FILE_DELETE || event == FCE_DIR_DELETE)) { /* Parent dir ? */ - if (!strncmp(fh->path, path, strlen(fh->path))) + if (!strncmp(fh->fce_h_path, path, strlen(fh->fce_h_path))) return true; } /* Detect oldest entry for next new entry */ - if (oldest_entry_idx == -1 || fh->tv.tv_sec < oldest_entry) { - oldest_entry = fh->tv.tv_sec; + if (oldest_entry_idx == -1 || fh->fce_h_tv.tv_sec < oldest_entry) { + oldest_entry = fh->fce_h_tv.tv_sec; oldest_entry_idx = i; } } /* We have a new entry for the history, register it */ - fce_history_list[oldest_entry_idx].tv = tv; - fce_history_list[oldest_entry_idx].mode = mode; - fce_history_list[oldest_entry_idx].is_dir = is_dir; - strncpy( fce_history_list[oldest_entry_idx].path, path, MAXPATHLEN); + fce_history_list[oldest_entry_idx].fce_h_tv = tv; + fce_history_list[oldest_entry_idx].fce_h_event = event; + fce_history_list[oldest_entry_idx].fce_h_type = type; + strncpy(fce_history_list[oldest_entry_idx].fce_h_path, path, MAXPATHLEN); /* we have to handle this event */ return false; diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 8d5d0ad0..94030454 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -747,7 +747,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, createfile_iderr: ad_flush(&ad); ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF ); - fce_register_new_file(s_path); + fce_register(FCE_FILE_CREATE, fullpathname(upath), NULL, fce_file); createfile_done: curdir->d_offcnt++; diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 56cbaccf..83f7f1aa 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -525,7 +525,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size delcnid = cnid_get(vol->v_cdb, curdir->d_did, upath, strlen(upath)); if (delcnid != CNID_INVALID) cnid_delete(vol->v_cdb, delcnid); - fce_register_delete_dir(upath); + fce_register(FCE_DIR_DELETE, fullpathname(upath), NULL, fce_dir); } else { /* we have to cache this, the structs are lost in deletcurdir*/ /* but we need the positive returncode to send our event */ @@ -533,7 +533,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size if ((dname = bstrcpy(curdir->d_u_name)) == NULL) return AFPERR_MISC; if ((rc = deletecurdir(vol)) == AFP_OK) - fce_register_delete_dir(cfrombstr(dname)); + fce_register(FCE_DIR_DELETE, fullpathname(cfrombstr(dname)), NULL, fce_dir); bdestroy(dname); } } else if (of_findname(s_path)) { @@ -547,7 +547,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size rc = AFPERR_NOOBJ; } else { if ((rc = deletefile(vol, -1, upath, 1)) == AFP_OK) { - fce_register_delete_file( s_path ); + fce_register(FCE_FILE_DELETE, fullpathname(upath), NULL, fce_file); if (vol->v_tm_used < s_path->st.st_size) vol->v_tm_used = 0; else diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 3d690079..66228b63 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -407,7 +407,7 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork) /* Somone has used write_fork, we assume file was changed, register it to file change event api */ if (ofork->of_flags & AFPFORK_MODIFIED) { - fce_register_file_modification(ofork); + fce_register(FCE_FILE_MODIFY, fullpathname(ofork->of_ad->ad_name), NULL, fce_file); } ad_unlock(ofork->of_ad, ofork->of_refnum, ofork->of_flags & AFPFORK_ERROR ? 0 : 1); diff --git a/include/atalk/fce_api.h b/include/atalk/fce_api.h index 211921b7..d11a2d49 100755 --- a/include/atalk/fce_api.h +++ b/include/atalk/fce_api.h @@ -32,6 +32,7 @@ * Format is network byte order. */ #define FCE_PACKET_HEADER_SIZE 8+1+1+4+2 + struct fce_packet { char magic[8]; @@ -42,17 +43,14 @@ struct fce_packet char data[MAXPATHLEN]; }; +typedef uint32_t fce_ev_t; +typedef enum { fce_file, fce_dir } fce_obj_t; + struct path; struct ofork; void fce_pending_events(AFPObj *obj); - -int fce_register_delete_file( struct path *path ); -int fce_register_delete_dir( char *name ); -int fce_register_new_dir( struct path *path ); -int fce_register_new_file( struct path *path ); -int fce_register_file_modification( struct ofork *ofork ); - +int fce_register(fce_ev_t event, const char *path, const char *oldpath, fce_obj_t type); int fce_add_udp_socket(const char *target ); // IP or IP:Port int fce_set_coalesce(const char *coalesce_opt ); // all|delete|create int fce_set_events(const char *events); /* fmod,fdel,ddel,fcre,dcre */ From 949ba93384843d13099dd467aefc61e3b7185997 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 13 Nov 2012 10:17:36 +0100 Subject: [PATCH 033/117] Enhance handling of nested volume paths Force cnidscheme "last" and read-only behaviour for volumes whos volume path is a subdirectory (nested) of another volume. In case cnid scheme is not last, a message is logged with a logvel of log_note. --- libatalk/util/netatalk_conf.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index fd7ebfd1..8b060e5f 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -571,6 +571,9 @@ static struct vol *creatvol(AFPObj *obj, uint16_t flags; const char *val; char *p, *q; + bool new_vol_nested = false; /* flag whether the new volume path is a subdirectory + * of an existing directory in which case we force + * "last" cnidsheme and read only behaviour */ strlcpy(path, path_in, MAXPATHLEN); @@ -610,12 +613,21 @@ static struct vol *creatvol(AFPObj *obj, shorter_path = path; longer_path = vol->v_path; } else { + new_vol_nested = true; shorter_len = another_pathlen; shorter_path = vol->v_path; longer_path = path; } - if (longer_path[shorter_len] == '/') - LOG(log_info, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); + if (longer_path[shorter_len] == '/') { + if (!new_vol_nested && STRCMP(vol->v_cnidscheme, !=, "last")) { + /* the volume "vol" is nested, we must force cnidscheme "last" and read-only */ + LOG(log_warning, logtype_afpd, "volume \"%s\" path \"%s\" is nested, set to read-only", + vol->v_configname, vol->v_path); + vol->v_flags = AFPVOL_RO; + free(vol->v_cnidscheme); + vol->v_cnidscheme = strdup("last"); + } + } } } } @@ -783,6 +795,14 @@ static struct vol *creatvol(AFPObj *obj, if (getoption_bool(obj->iniconfig, section, "root preexec close", preset, 0)) volume->v_root_preexec_close = 1; + /* Fixup for nested volume */ + if (new_vol_nested && strcmp(volume->v_cnidscheme, "last")) { + LOG(log_note, logtype_afpd, "volume \"%s\" is changed into cnid last and read only. path is nested: \"%s\"", + name, path); + free(volume->v_cnidscheme); + volume->v_cnidscheme = strdup("last"); + } + /* * Handle read-only behaviour. semantics: * 1) neither the rolist nor the rwlist exist -> rw From 107515dc545426fd81fee053243e02113f28cb8c Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 15 Nov 2012 17:53:31 +0100 Subject: [PATCH 034/117] Revert "Enhance handling of nested volume paths" This reverts commit 949ba93384843d13099dd467aefc61e3b7185997. --- libatalk/util/netatalk_conf.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 8b060e5f..fd7ebfd1 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -571,9 +571,6 @@ static struct vol *creatvol(AFPObj *obj, uint16_t flags; const char *val; char *p, *q; - bool new_vol_nested = false; /* flag whether the new volume path is a subdirectory - * of an existing directory in which case we force - * "last" cnidsheme and read only behaviour */ strlcpy(path, path_in, MAXPATHLEN); @@ -613,21 +610,12 @@ static struct vol *creatvol(AFPObj *obj, shorter_path = path; longer_path = vol->v_path; } else { - new_vol_nested = true; shorter_len = another_pathlen; shorter_path = vol->v_path; longer_path = path; } - if (longer_path[shorter_len] == '/') { - if (!new_vol_nested && STRCMP(vol->v_cnidscheme, !=, "last")) { - /* the volume "vol" is nested, we must force cnidscheme "last" and read-only */ - LOG(log_warning, logtype_afpd, "volume \"%s\" path \"%s\" is nested, set to read-only", - vol->v_configname, vol->v_path); - vol->v_flags = AFPVOL_RO; - free(vol->v_cnidscheme); - vol->v_cnidscheme = strdup("last"); - } - } + if (longer_path[shorter_len] == '/') + LOG(log_info, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); } } } @@ -795,14 +783,6 @@ static struct vol *creatvol(AFPObj *obj, if (getoption_bool(obj->iniconfig, section, "root preexec close", preset, 0)) volume->v_root_preexec_close = 1; - /* Fixup for nested volume */ - if (new_vol_nested && strcmp(volume->v_cnidscheme, "last")) { - LOG(log_note, logtype_afpd, "volume \"%s\" is changed into cnid last and read only. path is nested: \"%s\"", - name, path); - free(volume->v_cnidscheme); - volume->v_cnidscheme = strdup("last"); - } - /* * Handle read-only behaviour. semantics: * 1) neither the rolist nor the rwlist exist -> rw From 674f0c60f415d3922f796748d3ac8f2e9296bc83 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sat, 17 Nov 2012 14:14:17 +0100 Subject: [PATCH 035/117] Always generate all initscripts initscripts are now all created with variable substitution from the templates, but they're not installed. Installation happens only if the configure arg for the platform is used. This should help packagers picking up an initscript for a package. --- distrib/initscripts/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/distrib/initscripts/Makefile.am b/distrib/initscripts/Makefile.am index 4b88ba9d..5bdf9510 100644 --- a/distrib/initscripts/Makefile.am +++ b/distrib/initscripts/Makefile.am @@ -39,6 +39,7 @@ TEMPLATES = \ CLEANFILES = $(GENERATED_FILES) $(sysv_SCRIPTS) $(service_DATA) afpd cnid_metad EXTRA_DIST = $(TEMPLATES) +noinst_DATA = $(GENERATED_FILES) # overwrite automake uninstall # not beautiful, but this way we can call the OS specific init script From 4e6168e72ebe215e356b46534ee4ce31179d8695 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sat, 17 Nov 2012 12:30:18 +0100 Subject: [PATCH 036/117] Fix a bug where copying packages to a Netatalk share fails The bug was caused by the 10.6 client trying to set the creation date on a symlink in the package. This caused our setmetadata routine to require a valid adouble handle for the symlink which is not possible as symlink may not allow creating an EA, depending on the filesystem. At least ZFS on Solaris doesnt. The fix is to check whether the adouble handle creation failed on a symlink and ignore the error. Fixes bug #469. --- NEWS | 1 + etc/afpd/file.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8e192ea0..b87cf651 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Changes in 3.0.2 * FIX: "basedir regex" was never able to treat symlink. If /home -> /usr/home, set "basedir regex = /usr/home". * FIX: Memory leak +* FIX: Copying packages to a Netatalk share could fail, bug #469 Changes in 3.0.1 ================ diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 94030454..c4c55fb8 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -838,7 +838,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap = f_bitmap; uint32_t cdate,bdate; u_char finder_buf[32]; - int symlinked = 0; + int symlinked = S_ISLNK(path->st.st_mode); #ifdef DEBUG LOG(log_debug9, logtype_afpd, "begin setfilparams:"); From 7c87a58e70aab8eb2789f49eb4cd7c28f7df5bbc Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 22 Nov 2012 09:58:02 +0100 Subject: [PATCH 037/117] Use sigaction() instead of signal() for ignoring SIGPIPE Move the code to ignore SIGPIPE from the DSI sesssion setup stage to the main signal handling code in main() and avoid the use of deprecated signal() function and use sigaction. --- etc/afpd/main.c | 7 +++++++ libatalk/dsi/dsi_getsess.c | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/etc/afpd/main.c b/etc/afpd/main.c index e89d0a2e..afbd90e0 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -253,6 +253,13 @@ int main(int ac, char **av) afp_exit(EXITERR_SYS); } #endif + + sv.sa_handler = SIG_IGN; + sigemptyset( &sv.sa_mask ); + if (sigaction(SIGPIPE, &sv, NULL ) < 0 ) { + LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) ); + afp_exit(EXITERR_SYS); + } sv.sa_handler = afp_goaway; /* handler for all sigs */ diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index 001279cd..d5b855a8 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -121,7 +121,6 @@ int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_chi /* set up the tickle timer */ dsi->timer.it_interval.tv_sec = dsi->timer.it_value.tv_sec = tickleval; dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0; - signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */ dsi_opensession(dsi); *childp = NULL; return 0; From e57b112e3e20af20dea7c621244fc358e4cc1401 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 9 Nov 2012 12:48:53 +0100 Subject: [PATCH 038/117] Fix pathname bug for FCE modified event It's not guaranteed that cwd is the forks parent directory, thus we can't use the fullpathname(forkname) wrapper. Instead we use the DID stored in the ofork structure to dirlookup the directory and use it's fullpath together with the fork's name. --- etc/afpd/fork.c | 1 + etc/afpd/ofork.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 9c3ed7d2..54e1c149 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 66228b63..3f5a42b0 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -407,7 +407,10 @@ int of_closefork(const AFPObj *obj, struct ofork *ofork) /* Somone has used write_fork, we assume file was changed, register it to file change event api */ if (ofork->of_flags & AFPFORK_MODIFIED) { - fce_register(FCE_FILE_MODIFY, fullpathname(ofork->of_ad->ad_name), NULL, fce_file); + struct dir *dir = dirlookup(ofork->of_vol, ofork->of_did); + bstring forkpath = bformat("%s/%s", bdata(dir->d_fullpath), of_name(ofork)); + fce_register(FCE_FILE_MODIFY, bdata(forkpath), NULL, fce_file); + bdestroy(forkpath); } ad_unlock(ofork->of_ad, ofork->of_refnum, ofork->of_flags & AFPFORK_ERROR ? 0 : 1); From c7683d5aae3d154250df531a5d34e4a464b5ced2 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 23 Nov 2012 08:15:51 +0100 Subject: [PATCH 039/117] "valid users" options and friends only use ',' as field delimiter Netatalk 3 uses ',' and ' ' as field delimiter in the "valid users", "invalid users", "rolist" and "rwlist" option for consistency with other options that also allow the use of ' ' as field delimiter. But as user and groupnames may contain spaces, we need to revert to the Netatalk 2 behaviour where only ',' was used as delimiter. Fixes bug #472. --- libatalk/util/netatalk_conf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index fd7ebfd1..067ed454 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -402,7 +402,7 @@ static char *volxlate(const AFPObj *obj, * check access list * * this function wants something of the following form: - * "@group,name,name2,@group2,name3" or "@group name name2 @group2 name3" + * "@group,name,name2,@group2,name3". * A NULL argument allows everybody to have access. * We return three things: * -1: no list @@ -418,7 +418,7 @@ static int accessvol(const AFPObj *obj, const char *args, const char *name) return -1; strlcpy(buf, args, sizeof(buf)); - if ((p = strtok(buf, ", ")) == NULL) /* nothing, return okay */ + if ((p = strtok(buf, ",")) == NULL) /* nothing, return okay */ return -1; while (p) { From a6e137d15156dac69c594de8de940c5b87bbd0ed Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 23 Nov 2012 10:19:13 +0100 Subject: [PATCH 040/117] Add error check macro EC_EXIT_STATUS --- include/atalk/errchk.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/atalk/errchk.h b/include/atalk/errchk.h index 094065b9..ccc66eb6 100644 --- a/include/atalk/errchk.h +++ b/include/atalk/errchk.h @@ -17,6 +17,7 @@ #define EC_INIT int ret = 0 #define EC_STATUS(a) ret = (a) +#define EC_EXIT_STATUS(a) do { ret = (a); goto cleanup; } while (0) #define EC_FAIL do { ret = -1; goto cleanup; } while (0) #define EC_FAIL_LOG(a, ...) \ do { \ From 0fab5d1cb0e4c0f5539bf60072bd120c236a9233 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 23 Nov 2012 10:23:27 +0100 Subject: [PATCH 041/117] Remove lenght limitation of options like "valid users" The options "valid users", "rolist" and others use the function accessvol() for parsing the options string. accessfull uses a static buffer limited to MAXPATHLEN which limits the maximum length of these options. Fix this by using a strdup()ed buffer instead. Fixes bug #473. --- libatalk/util/netatalk_conf.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 067ed454..36fdfbed 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -411,26 +411,31 @@ static char *volxlate(const AFPObj *obj, */ static int accessvol(const AFPObj *obj, const char *args, const char *name) { - char buf[MAXPATHLEN + 1], *p; + EC_INIT; + char *names = NULL, *p; struct group *gr; if (!args) - return -1; + EC_EXIT_STATUS(-1); - strlcpy(buf, args, sizeof(buf)); - if ((p = strtok(buf, ",")) == NULL) /* nothing, return okay */ - return -1; + EC_NULL_LOG( names = strdup(args) ); + + if ((p = strtok(names, ",")) == NULL) /* nothing, return okay */ + EC_EXIT_STATUS(-1); while (p) { if (*p == '@') { /* it's a group */ if ((gr = getgrnam(p + 1)) && gmem(gr->gr_gid, obj->ngroups, obj->groups)) - return 1; + EC_EXIT_STATUS(1); } else if (strcasecmp(p, name) == 0) /* it's a user name */ - return 1; + EC_EXIT_STATUS(1); p = strtok(NULL, ", "); } - return 0; +EC_CLEANUP: + if (names) + free(names); + EC_EXIT; } static int hostaccessvol(const AFPObj *obj, const char *volname, const char *args) From f5bd1a2be184f7c58d6117c5c2738f52c333378e Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 23 Nov 2012 11:33:06 +0100 Subject: [PATCH 042/117] Import manpage from XML --- man/man5/afp.conf.5.tmpl | 228 +++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index 0e0bc653..e12561a2 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -2,12 +2,12 @@ .\" Title: afp.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 25 Jul 2012 +.\" Date: 22 Nov 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "AFP\&.CONF" "5" "25 Jul 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "AFP\&.CONF" "5" "22 Nov 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -244,116 +244,6 @@ k5 keytab = \fIpath\fR \fB(G)\fR, k5 service = \fIservice\fR \fB(G)\fR, k5 realm These are required if the server supports the Kerberos 5 authentication UAM\&. .RE .PP -ldap auth method = \fInone|simple|sasl\fR \fB(G)\fR -.RS 4 -Authentication method: -\fBnone | simple | sasl\fR -.PP -none -.RS 4 -anonymous LDAP bind -.RE -.PP -simple -.RS 4 -simple LDAP bind -.RE -.PP -sasl -.RS 4 -SASL\&. Not yet supported ! -.RE -.RE -.PP -ldap auth dn = \fIdn\fR \fB(G)\fR -.RS 4 -Distinguished Name of the user for simple bind\&. -.sp -.RE -.PP -ldap auth pw = \fIpassword\fR \fB(G)\fR -.RS 4 -Distinguished Name of the user for simple bind\&. -.sp -.RE -.PP -ldap server = \fIhost\fR \fB(G)\fR -.RS 4 -Name or IP address of your LDAP Server\&. This is only needed for explicit ACL support in order to be able to query LDAP for UUIDs\&. -.sp -You can use -\fBafpldaptest\fR(1) -to syntactically check your config\&. -.RE -.PP -ldap userbase = \fIbase dn\fR \fB(G)\fR -.RS 4 -DN of the user container in LDAP\&. -.sp -.RE -.PP -ldap userscope = \fIscope\fR \fB(G)\fR -.RS 4 -Search scope for user search: -\fBbase | one | sub\fR -.sp -.RE -.PP -ldap groupbase = \fIbase dn\fR \fB(G)\fR -.RS 4 -DN of the group container in LDAP\&. -.sp -.RE -.PP -ldap groupscope = \fIscope\fR \fB(G)\fR -.RS 4 -Search scope for user search: -\fBbase | one | sub\fR -.sp -.RE -.PP -ldap uuid attr = \fIdn\fR \fB(G)\fR -.RS 4 -Name of the LDAP attribute with the UUIDs\&. -.sp -Note: this is used both for users and groups\&. -.sp -.RE -.PP -ldap name attr = \fIdn\fR \fB(G)\fR -.RS 4 -Name of the LDAP attribute with the users short name\&. -.sp -.RE -.PP -ldap uuid string = \fISTRING\fR \fB(G)\fR -.RS 4 -Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a seperator\&. -.sp -Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx -.RE -.PP -ldap uuid encoding = \fIstring | ms\-guid (default: string)\fR \fB(G)\fR -.RS 4 -Format of the UUID of the LDAP attribute, allows usage of the binary objectGUID fields from Active Directory\&. If left unspecified, string is the default, which passes through the ASCII UUID returned by most other LDAP stores\&. If set to ms\-guid, the internal UUID representation is converted to and from the binary format used in the objectGUID attribute found on objects in Active Directory when interacting with the server\&. -.PP -string -.RS 4 -UUID is a string, use with eg OpenDirectory\&. -.RE -.PP -ms\-guid -.RS 4 -Binary objectGUID from Active Directory -.RE -.RE -.PP -ldap group attr = \fIdn\fR \fB(G)\fR -.RS 4 -Name of the LDAP attribute with the groups short name\&. -.sp -.RE -.PP nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPERATOR\fR \fB(G)\fR .RS 4 Use for eg\&. winbind authentication, prepends both strings before the username from login and then tries to authenticate with the result through the availabel and active UAM authentication modules\&. @@ -613,7 +503,7 @@ Default size is 8192, maximum size is 131072\&. Given value is rounded up to nea .PP extmap file = \fIpath\fR \fB(G)\fR .RS 4 -Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/extmap\&.conf)\&. +Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/AppleVolumes\&.system)\&. .RE .PP fce listener = \fIhost[:port]\fR \fB(G)\fR @@ -624,7 +514,7 @@ Enables sending FCE events to the specified is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&. .RE .PP -fce events = \fIfmod,fdel,ddel,fcre,dcre\fR \fB(G)\fR +fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR .RS 4 Speficies which FCE events are active, default is \fIfmod,fdel,ddel,fcre,dcre\fR\&. @@ -775,6 +665,116 @@ With this option enabled, afpd won\'t advertise that it is capable of server not .sp Do not use this option any longer as present Netatalk correctly supports server notifications, allowing connected clients to update folder listings in case another client changed the contents\&. .RE +.SS "Options for ACL handling" +.PP +For a basic mode of operation there\'s nothing to configure\&. afpd reads ACLs on the fly, calculating effective permissions and returning the calculated permissions via the so called UARights permission bits\&. On a Mac the Finder uses these bits to adjust permission in Finder windows\&. For example folder whos UNIX mode would only result in in read\-only permissions for a user will not be displayed with a read\-only icon and the user will be able to write to the folder given the folder has an ACL giving the user write access\&. +.PP +However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\'s a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involed as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\'s or gid\'s\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&. +.PP +Netatalk can query a directory server using LDAP queries\&. Either the directory server already provides an UUID attribute for user and groups (Active Directory, Open Directory) or you reuse an unused attribute (or add a new one) to you directory server (eg OpenLDAP)\&. +.PP +The following LDAP options must be configured for Netatalk: +.PP +ldap auth method = \fInone|simple|sasl\fR \fB(G)\fR +.RS 4 +Authentication method: +\fBnone | simple | sasl\fR +.PP +none +.RS 4 +anonymous LDAP bind +.RE +.PP +simple +.RS 4 +simple LDAP bind +.RE +.PP +sasl +.RS 4 +SASL\&. Not yet supported ! +.RE +.RE +.PP +ldap auth dn = \fIdn\fR \fB(G)\fR +.RS 4 +Distinguished Name of the user for simple bind\&. +.RE +.PP +ldap auth pw = \fIpassword\fR \fB(G)\fR +.RS 4 +Distinguished Name of the user for simple bind\&. +.RE +.PP +ldap server = \fIhost\fR \fB(G)\fR +.RS 4 +Name or IP address of your LDAP Server\&. This is only needed for explicit ACL support in order to be able to query LDAP for UUIDs\&. +.sp +You can use +\fBafpldaptest\fR(1) +to syntactically check your config\&. +.RE +.PP +ldap userbase = \fIbase dn\fR \fB(G)\fR +.RS 4 +DN of the user container in LDAP\&. +.RE +.PP +ldap userscope = \fIscope\fR \fB(G)\fR +.RS 4 +Search scope for user search: +\fBbase | one | sub\fR +.RE +.PP +ldap groupbase = \fIbase dn\fR \fB(G)\fR +.RS 4 +DN of the group container in LDAP\&. +.RE +.PP +ldap groupscope = \fIscope\fR \fB(G)\fR +.RS 4 +Search scope for user search: +\fBbase | one | sub\fR +.RE +.PP +ldap uuid attr = \fIdn\fR \fB(G)\fR +.RS 4 +Name of the LDAP attribute with the UUIDs\&. +.sp +Note: this is used both for users and groups\&. +.RE +.PP +ldap name attr = \fIdn\fR \fB(G)\fR +.RS 4 +Name of the LDAP attribute with the users short name\&. +.RE +.PP +ldap uuid string = \fISTRING\fR \fB(G)\fR +.RS 4 +Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a seperator\&. +.sp +Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx +.RE +.PP +ldap uuid encoding = \fIstring | ms\-guid (default: string)\fR \fB(G)\fR +.RS 4 +Format of the UUID of the LDAP attribute, allows usage of the binary objectGUID fields from Active Directory\&. If left unspecified, string is the default, which passes through the ASCII UUID returned by most other LDAP stores\&. If set to ms\-guid, the internal UUID representation is converted to and from the binary format used in the objectGUID attribute found on objects in Active Directory when interacting with the server\&. +.PP +string +.RS 4 +UUID is a string, use with eg OpenDirectory\&. +.RE +.PP +ms\-guid +.RS 4 +Binary objectGUID from Active Directory +.RE +.RE +.PP +ldap group attr = \fIdn\fR \fB(G)\fR +.RS 4 +Name of the LDAP attribute with the groups short name\&. +.RE .SH "EXPLANATION OF VOLUME PARAMETERS" .SS "Parameters" .PP From 9fae7d8e8f0f744b66819b308b0aff0621e5211c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 24 Nov 2012 16:34:14 +0100 Subject: [PATCH 043/117] Add logtype_ad --- include/atalk/logger.h | 1 + libatalk/adouble/ad_conv.c | 20 ++++----- libatalk/adouble/ad_flush.c | 20 ++++----- libatalk/adouble/ad_lock.c | 18 ++++---- libatalk/adouble/ad_open.c | 86 ++++++++++++++++++------------------- libatalk/adouble/ad_write.c | 6 +-- libatalk/util/logger.c | 4 +- man/man5/afp.conf.5.tmpl | 2 +- 8 files changed, 80 insertions(+), 77 deletions(-) diff --git a/include/atalk/logger.h b/include/atalk/logger.h index 330eb7b6..1847c0d5 100644 --- a/include/atalk/logger.h +++ b/include/atalk/logger.h @@ -92,6 +92,7 @@ enum logtypes { logtype_dsi, logtype_uams, logtype_fce, + logtype_ad, logtype_end_of_list_marker /* don't put any logtypes after this */ }; diff --git a/libatalk/adouble/ad_conv.c b/libatalk/adouble/ad_conv.c index eaac8db9..eef80912 100644 --- a/libatalk/adouble/ad_conv.c +++ b/libatalk/adouble/ad_conv.c @@ -62,7 +62,7 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc uint32_t ctime, mtime, afpinfo = 0; char *emptyad; - LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path)); ad_init(&adea, vol); ad_init_old(&adv2, AD_VERSION2, adea.ad_options); @@ -97,12 +97,12 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc goto copy; } - LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret); goto EC_CLEANUP; copy: /* Create a adouble:ea meta EA */ - LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret); EC_ZERO_LOGSTR( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE), "ad_conv_v22ea_hf(\"%s\"): error creating metadata EA: %s", fullpathname(path), strerror(errno)); @@ -112,7 +112,7 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc EC_CLEANUP: EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_SETSHRMD) ); EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_SETSHRMD) ); - LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret); EC_EXIT; } @@ -122,7 +122,7 @@ static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struc struct adouble adv2; struct adouble adea; - LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path)); if (S_ISDIR(sp->st_mode)) return 0; @@ -147,7 +147,7 @@ static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struc EC_CLEANUP: EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_RF) ); EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_RF) ); - LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret); + LOG(log_debug, logtype_ad,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret); EC_EXIT; } @@ -163,7 +163,7 @@ static int ad_conv_v22ea(const char *path, const struct stat *sp, const struct v EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) ); EC_NULL( adpath = ad_path(path, adflags) ); - LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"", + LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"", path, fullpathname(adpath)); unlink(adpath); @@ -188,7 +188,7 @@ static int ad_conv_dehex(const char *path, const struct stat *sp, const struct v int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0; bstring newpath = NULL; - LOG(log_debug, logtype_default,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path)); *newpathp = NULL; @@ -231,7 +231,7 @@ int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, c EC_INIT; const char *p; - LOG(log_debug, logtype_default,"ad_convert(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad,"ad_convert(\"%s\"): BEGIN", fullpathname(path)); if (newpath) *newpath = NULL; @@ -246,7 +246,7 @@ int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, c } EC_CLEANUP: - LOG(log_debug, logtype_default,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret); + LOG(log_debug, logtype_ad,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret); EC_EXIT; } diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index 91f8058b..61b34f50 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -61,7 +61,7 @@ int ad_rebuild_adouble_header_v2(struct adouble *ad) char *buf, *nentp; int len; - LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_v2"); + LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_v2"); buf = ad->ad_data; @@ -107,7 +107,7 @@ int ad_rebuild_adouble_header_ea(struct adouble *ad) char *buf, *nentp; int len; - LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_ea"); + LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_ea"); buf = ad->ad_data; @@ -155,7 +155,7 @@ static int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf) char *buf; int len; - LOG(log_debug, logtype_default, "ad_rebuild_adouble_header_osx"); + LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_osx"); buf = &adbuf[0]; @@ -253,7 +253,7 @@ static int ad_flush_hf(struct adouble *ad) int len; int cwd = -1; - LOG(log_debug, logtype_default, "ad_flush_hf(%s)", adflags2logstr(ad->ad_adflags)); + LOG(log_debug, logtype_ad, "ad_flush_hf(%s)", adflags2logstr(ad->ad_adflags)); struct ad_fd *adf; @@ -265,7 +265,7 @@ static int ad_flush_hf(struct adouble *ad) adf = &ad->ad_data_fork; break; default: - LOG(log_error, logtype_afpd, "ad_flush: unexpected adouble version"); + LOG(log_error, logtype_ad, "ad_flush: unexpected adouble version"); return -1; } @@ -302,7 +302,7 @@ static int ad_flush_hf(struct adouble *ad) } break; default: - LOG(log_error, logtype_afpd, "ad_flush: unexpected adouble version"); + LOG(log_error, logtype_ad, "ad_flush: unexpected adouble version"); return -1; } } @@ -329,7 +329,7 @@ static int ad_flush_rf(struct adouble *ad) if (ad->ad_vers != AD_VERSION_EA) return 0; - LOG(log_debug, logtype_default, "ad_flush_rf(%s)", adflags2logstr(ad->ad_adflags)); + LOG(log_debug, logtype_ad, "ad_flush_rf(%s)", adflags2logstr(ad->ad_adflags)); if ((ad->ad_rfp->adf_flags & O_RDWR)) { if (ad_getentryoff(ad, ADEID_RFORK)) { @@ -353,7 +353,7 @@ int ad_flush(struct adouble *ad) { EC_INIT; - LOG(log_debug, logtype_default, "ad_flush(%s)", adflags2logstr(ad->ad_adflags)); + LOG(log_debug, logtype_ad, "ad_flush(%s)", adflags2logstr(ad->ad_adflags)); if (AD_META_OPEN(ad)) { EC_ZERO( ad_flush_hf(ad) ); @@ -393,7 +393,7 @@ int ad_close(struct adouble *ad, int adflags) return err; - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_close(%s): BEGIN: {d: %d, m: %d, r: %d} " "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", adflags2logstr(adflags), @@ -447,7 +447,7 @@ int ad_close(struct adouble *ad, int adflags) } } - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_close(%s): END: %d {d: %d, m: %d, r: %d} " "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", adflags2logstr(adflags), err, diff --git a/libatalk/adouble/ad_lock.c b/libatalk/adouble/ad_lock.c index 92f0ab89..6e159cdd 100644 --- a/libatalk/adouble/ad_lock.c +++ b/libatalk/adouble/ad_lock.c @@ -64,7 +64,7 @@ static int set_lock(int fd, int cmd, struct flock *lock) { EC_INIT; - LOG(log_debug, logtype_default, "set_lock(fd: %d, %s, %s, off: %jd (%s), len: %jd): BEGIN", + LOG(log_debug, logtype_ad, "set_lock(fd: %d, %s, %s, off: %jd (%s), len: %jd): BEGIN", fd, cmd == F_SETLK ? "F_SETLK" : "F_GETLK", lock->l_type == F_RDLCK ? "F_RDLCK" : lock->l_type == F_WRLCK ? "F_WRLCK" : "F_UNLCK", (intmax_t)lock->l_start, @@ -361,7 +361,7 @@ int ad_lock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len int type; int ret = 0, fcntl_lock_err = 0; - LOG(log_debug, logtype_default, "ad_lock(%s, %s, off: %jd (%s), len: %jd): BEGIN", + LOG(log_debug, logtype_ad, "ad_lock(%s, %s, off: %jd (%s), len: %jd): BEGIN", eid == ADEID_DFORK ? "data" : "reso", locktypetostr(locktype), (intmax_t)off, @@ -496,7 +496,7 @@ int ad_lock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t len set_lock(adf->adf_fd, F_SETLK, &lock); } } - LOG(log_debug, logtype_default, "ad_lock: END: %d", ret); + LOG(log_debug, logtype_ad, "ad_lock: END: %d", ret); return ret; } @@ -507,7 +507,7 @@ int ad_tmplock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t int err; int type; - LOG(log_debug, logtype_default, "ad_tmplock(%s, %s, off: %jd (%s), len: %jd): BEGIN", + LOG(log_debug, logtype_ad, "ad_tmplock(%s, %s, off: %jd (%s), len: %jd): BEGIN", eid == ADEID_DFORK ? "data" : "reso", locktypetostr(locktype), (intmax_t)off, @@ -564,14 +564,14 @@ int ad_tmplock(struct adouble *ad, uint32_t eid, int locktype, off_t off, off_t adf_relockrange(adf, adf->adf_fd, lock.l_start, len); exit: - LOG(log_debug, logtype_default, "ad_tmplock: END: %d", err); + LOG(log_debug, logtype_ad, "ad_tmplock: END: %d", err); return err; } /* --------------------- */ void ad_unlock(struct adouble *ad, const int fork, int unlckbrl) { - LOG(log_debug, logtype_default, "ad_unlock(unlckbrl: %d): BEGIN", unlckbrl); + LOG(log_debug, logtype_ad, "ad_unlock(unlckbrl: %d): BEGIN", unlckbrl); if (ad_data_fileno(ad) != -1) { adf_unlock(ad, &ad->ad_data_fork, fork, unlckbrl); @@ -580,7 +580,7 @@ void ad_unlock(struct adouble *ad, const int fork, int unlckbrl) adf_unlock(ad, &ad->ad_resource_fork, fork, unlckbrl); } - LOG(log_debug, logtype_default, "ad_unlock: END"); + LOG(log_debug, logtype_ad, "ad_unlock: END"); } /*! @@ -598,7 +598,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off) int ret = 0; off_t lock_offset; - LOG(log_debug, logtype_default, "ad_testlock(%s, off: %jd (%s): BEGIN", + LOG(log_debug, logtype_ad, "ad_testlock(%s, off: %jd (%s): BEGIN", eid == ADEID_DFORK ? "data" : "reso", (intmax_t)off, shmdstrfromoff(off)); @@ -611,7 +611,7 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off) ret = testlock(&ad->ad_data_fork, lock_offset, 1); - LOG(log_debug, logtype_default, "ad_testlock: END: %d", ret); + LOG(log_debug, logtype_ad, "ad_testlock: END: %d", ret); return ret; } diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index 045c33c3..bc72ff0b 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -316,10 +316,10 @@ static int new_ad_header(struct adouble *ad, const char *path, struct stat *stp, uint16_t ashort; struct stat st; - LOG(log_debug, logtype_default, "new_ad_header(\"%s\")", path); + LOG(log_debug, logtype_ad, "new_ad_header(\"%s\")", path); if (ad->ad_magic == AD_MAGIC) { - LOG(log_debug, logtype_default, "new_ad_header(\"%s\"): already initialized", path); + LOG(log_debug, logtype_ad, "new_ad_header(\"%s\"): already initialized", path); return 0; } @@ -409,7 +409,7 @@ static void parse_entries(struct adouble *ad, char *buf, uint16_t nentries) ad->ad_eid[ eid ].ade_len = len; } else if (!warning) { warning = 1; - LOG(log_warning, logtype_default, "parse_entries: bogus eid: %d", eid); + LOG(log_warning, logtype_ad, "parse_entries: bogus eid: %d", eid); } } } @@ -444,7 +444,7 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct ad->ad_version = ntohl( ad->ad_version ); if ((ad->ad_magic != AD_MAGIC) || (ad->ad_version != AD_VERSION2)) { - LOG(log_error, logtype_default, "ad_open: can't parse AppleDouble header."); + LOG(log_error, logtype_ad, "ad_open: can't parse AppleDouble header."); errno = EIO; return -1; } @@ -461,7 +461,7 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct buf += AD_HEADER_LEN; if (len > header_len - AD_HEADER_LEN) { - LOG(log_error, logtype_default, "ad_header_read: can't read entry info."); + LOG(log_error, logtype_ad, "ad_header_read: can't read entry info."); errno = EIO; return -1; } @@ -473,13 +473,13 @@ static int ad_header_read(const char *path _U_, struct adouble *ad, const struct if (!ad_getentryoff(ad, ADEID_RFORK) || (ad_getentryoff(ad, ADEID_RFORK) > sizeof(ad->ad_data)) ) { - LOG(log_error, logtype_default, "ad_header_read: problem with rfork entry offset."); + LOG(log_error, logtype_ad, "ad_header_read: problem with rfork entry offset."); errno = EIO; return -1; } if (ad_getentryoff(ad, ADEID_RFORK) > header_len) { - LOG(log_error, logtype_default, "ad_header_read: can't read in entries."); + LOG(log_error, logtype_ad, "ad_header_read: can't read in entries."); errno = EIO; return -1; } @@ -505,7 +505,7 @@ int ad_valid_header_osx(const char *path) char *buf = &adosx.ad_data[0]; ssize_t header_len; - LOG(log_debug, logtype_afpd, "ad_valid_header_osx(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad, "ad_valid_header_osx(\"%s\"): BEGIN", fullpathname(path)); EC_NEG1( fd = open(path, O_RDONLY) ); @@ -521,7 +521,7 @@ int ad_valid_header_osx(const char *path) adosx.ad_version = ntohl(adosx.ad_version); if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) { - LOG(log_warning, logtype_afpd, "ad_valid_header_osx: not an adouble:osx file"); + LOG(log_warning, logtype_ad, "ad_valid_header_osx: not an adouble:osx file"); EC_FAIL; } @@ -534,7 +534,7 @@ int ad_valid_header_osx(const char *path) EC_FAIL; EC_CLEANUP: - LOG(log_debug, logtype_afpd, "ad_valid_header_osx(\"%s\"): END: %d", fullpathname(path), ret); + LOG(log_debug, logtype_ad, "ad_valid_header_osx(\"%s\"): END: %d", fullpathname(path), ret); if (fd != -1) close(fd); if (ret != 0) @@ -569,7 +569,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st adosx.ad_version = ntohl(adosx.ad_version); if ((adosx.ad_magic != AD_MAGIC) || (adosx.ad_version != AD_VERSION2)) { - LOG(log_error, logtype_afpd, "ad_header_read_osx: can't parse AppleDouble header"); + LOG(log_error, logtype_ad, "ad_header_read_osx: can't parse AppleDouble header"); errno = EIO; return -1; } @@ -583,7 +583,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st buf += AD_HEADER_LEN; if (len > header_len - AD_HEADER_LEN) { - LOG(log_error, logtype_afpd, "ad_header_read_osx: can't read entry info."); + LOG(log_error, logtype_ad, "ad_header_read_osx: can't read entry info."); errno = EIO; return -1; } @@ -595,7 +595,7 @@ static int ad_header_read_osx(const char *path _U_, struct adouble *ad, const st || ad_getentryoff(&adosx, ADEID_RFORK) > sizeof(ad->ad_data) || ad_getentryoff(&adosx, ADEID_RFORK) > header_len ) { - LOG(log_error, logtype_afpd, "ad_header_read_osx: problem with rfork entry offset."); + LOG(log_error, logtype_ad, "ad_header_read_osx: problem with rfork entry offset."); errno = EIO; return -1; } @@ -624,12 +624,12 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct else header_len = sys_lgetxattr(path, AD_EA_META, ad->ad_data, AD_DATASZ_EA); if (header_len < 1) { - LOG(log_debug, logtype_default, "ad_header_read_ea: %s", strerror(errno)); + LOG(log_debug, logtype_ad, "ad_header_read_ea: %s", strerror(errno)); return -1; } if (header_len < AD_HEADER_LEN) { - LOG(log_error, logtype_default, "ad_header_read_ea: bogus AppleDouble header."); + LOG(log_error, logtype_ad, "ad_header_read_ea: bogus AppleDouble header."); errno = EIO; return -1; } @@ -641,7 +641,7 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct ad->ad_version = ntohl( ad->ad_version ); if ((ad->ad_magic != AD_MAGIC) || (ad->ad_version != AD_VERSION2)) { - LOG(log_error, logtype_default, "ad_header_read_ea: wrong magic or version"); + LOG(log_error, logtype_ad, "ad_header_read_ea: wrong magic or version"); errno = EIO; return -1; } @@ -654,7 +654,7 @@ static int ad_header_read_ea(const char *path, struct adouble *ad, const struct if (len + AD_HEADER_LEN > sizeof(ad->ad_data)) len = sizeof(ad->ad_data) - AD_HEADER_LEN; if (len > header_len - AD_HEADER_LEN) { - LOG(log_error, logtype_default, "ad_header_read_ea: can't read entry info."); + LOG(log_error, logtype_ad, "ad_header_read_ea: can't read entry info."); errno = EIO; return -1; } @@ -820,7 +820,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble int st_invalid = -1; ssize_t lsz; - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_df(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -886,7 +886,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble ad->ad_data_fork.adf_refcount++; EC_CLEANUP: - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_df(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ret, ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -906,7 +906,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou mode_t admode; int st_invalid = -1; - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_hf_v2(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -930,7 +930,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou ad_p = ad->ad_ops->ad_path(path, adflags); oflags = O_NOFOLLOW | ad2openflags(ad, ADFLAGS_HF, adflags); - LOG(log_debug, logtype_default,"ad_open_hf_v2(\"%s\"): open flags: %s", + LOG(log_debug, logtype_ad,"ad_open_hf_v2(\"%s\"): open flags: %s", fullpathname(path), openflags2logstr(oflags)); nocreatflags = oflags & ~(O_CREAT | O_EXCL); @@ -957,7 +957,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou /* * We're expecting to create a new adouble header file here */ - LOG(log_debug, logtype_default, "ad_open(\"%s\"): creating adouble file", + LOG(log_debug, logtype_ad, "ad_open(\"%s\"): creating adouble file", fullpathname(path)); admode = mode; errno = 0; @@ -1018,7 +1018,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou ad_meta_fileno(ad) = -1; ad->ad_mdp->adf_refcount = 0; } - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_hf_v2(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ret, ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -1034,7 +1034,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble int oflags; int opened = 0; - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\", %s): BEGIN [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -1051,7 +1051,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble if ((oflags & O_RDWR) && /* and it was already denied: */ (ad->ad_mdp->adf_flags & O_RDONLY)) { - LOG(log_error, logtype_default, "ad_open_hf_ea(%s): rw request for ro file: %s", + LOG(log_error, logtype_ad, "ad_open_hf_ea(%s): rw request for ro file: %s", fullpathname(path), strerror(errno)); errno = EACCES; EC_FAIL; @@ -1064,7 +1064,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble if (adflags & ADFLAGS_DIR) /* For directories we open the directory RDONYL so we can later fchdir() */ oflags = (oflags & ~O_RDWR) | O_RDONLY; - LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path); + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): opening base file for meta adouble EA", path); EC_NEG1(ad_meta_fileno(ad) = open(path, oflags)); opened = 1; ad->ad_mdp->adf_flags = oflags; @@ -1074,16 +1074,16 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble /* Read the adouble header in and parse it.*/ if (ad->ad_ops->ad_header_read(path, ad, NULL) != 0) { if (!(adflags & ADFLAGS_CREATE)) { - LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path); + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): can't read metadata EA", path); errno = ENOENT; EC_FAIL; } - LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): creating metadata EA", path); + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): creating metadata EA", path); /* It doesnt exist, EPERM or another error */ if (!(errno == ENOATTR || errno == ENOENT)) { - LOG(log_error, logtype_default, "ad_open_hf_ea: unexpected: %s", strerror(errno)); + LOG(log_error, logtype_ad, "ad_open_hf_ea: unexpected: %s", strerror(errno)); EC_FAIL; } @@ -1091,7 +1091,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble EC_NEG1_LOG(new_ad_header(ad, path, NULL, adflags)); ad->ad_mdp->adf_flags |= O_CREAT; /* mark as just created */ ad_flush(ad); - LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): created metadata EA", path); + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\"): created metadata EA", path); } if (ad_meta_fileno(ad) != -1) @@ -1104,7 +1104,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble ad_meta_fileno(ad) = -1; ad->ad_mdp->adf_refcount = 0; } - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open_hf_ea(\"%s\", %s): END: %d [dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), ret, ad_data_fileno(ad), ad->ad_data_fork.adf_refcount, @@ -1152,7 +1152,7 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad) goto EC_CLEANUP; } - LOG(log_debug, logtype_default, "ad_reso_size(\"%s\"): BEGIN", path); + LOG(log_debug, logtype_ad, "ad_reso_size(\"%s\"): BEGIN", path); #ifdef HAVE_EAFD ssize_t easz; @@ -1176,7 +1176,7 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad) ad->ad_rlen = 0; #endif - LOG(log_debug, logtype_default, "ad_reso_size(\"%s\"): size: %zd", path, ad->ad_rlen); + LOG(log_debug, logtype_ad, "ad_reso_size(\"%s\"): size: %zd", path, ad->ad_rlen); EC_CLEANUP: if (ret != 0) @@ -1207,7 +1207,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble struct stat st; #endif - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): BEGIN", fullpathname(path)); + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): BEGIN", fullpathname(path)); oflags = O_NOFOLLOW | (ad2openflags(ad, ADFLAGS_RF, adflags) & ~O_CREAT); @@ -1243,7 +1243,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble EC_FAIL; oflags |= O_CREAT; EC_NEG1_LOG( ad_reso_fileno(ad) = open(rfpath, oflags, mode) ); - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork: \"%s\"", + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork: \"%s\"", path, rfpath); } #endif @@ -1255,15 +1255,15 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble EC_ZERO_LOG( fstat(ad_reso_fileno(ad), &st) ); if (ad->ad_rfp->adf_flags & O_CREAT) { /* This is a new adouble header file, create it */ - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork, initializing: \"%s\"", + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork, initializing: \"%s\"", path, rfpath); EC_NEG1_LOG( new_ad_header(ad, path, NULL, adflags) ); - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): created adouble rfork, flushing: \"%s\"", + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): created adouble rfork, flushing: \"%s\"", path, rfpath); ad_flush(ad); } else { /* Read the adouble header */ - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): reading adouble rfork: \"%s\"", + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): reading adouble rfork: \"%s\"", path, rfpath); EC_NEG1_LOG( ad_header_read_osx(NULL, ad, &st) ); } @@ -1288,7 +1288,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble ad->ad_rlen = 0; } - LOG(log_debug, logtype_default, "ad_open_rf(\"%s\"): END: %d", fullpathname(path), ret); + LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): END: %d", fullpathname(path), ret); EC_EXIT; } @@ -1508,7 +1508,7 @@ int ad_mkdir( const char *path, mode_t mode) int st_invalid; struct stat stbuf; - LOG(log_debug, logtype_default, "ad_mkdir(\"%s\", %04o) {cwd: \"%s\"}", + LOG(log_debug, logtype_ad, "ad_mkdir(\"%s\", %04o) {cwd: \"%s\"}", path, mode, getcwdpath()); st_invalid = ad_mode_st(path, &mode, &stbuf); @@ -1611,7 +1611,7 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...) va_list args; mode_t mode = 0; - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open(\"%s\", %s): BEGIN {d: %d, m: %d, r: %d}" "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), adflags2logstr(adflags), @@ -1678,7 +1678,7 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...) } EC_CLEANUP: - LOG(log_debug, logtype_default, + LOG(log_debug, logtype_ad, "ad_open(\"%s\"): END: %d {d: %d, m: %d, r: %d}" "[dfd: %d (ref: %d), mfd: %d (ref: %d), rfd: %d (ref: %d)]", fullpathname(path), ret, @@ -1742,7 +1742,7 @@ int ad_metadataat(int dirfd, const char *name, int flags, struct adouble *adp) if (dirfd != -1) { if (fchdir(cwdfd) != 0) { - LOG(log_error, logtype_afpd, "ad_openat: cant chdir back, exiting"); + LOG(log_error, logtype_ad, "ad_openat: cant chdir back, exiting"); exit(EXITERR_SYS); } } diff --git a/libatalk/adouble/ad_write.c b/libatalk/adouble/ad_write.c index bfed9b40..6e8a0190 100644 --- a/libatalk/adouble/ad_write.c +++ b/libatalk/adouble/ad_write.c @@ -60,7 +60,7 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha return -1; } - LOG(log_debug, logtype_default, "ad_write: off: %ju, size: %zu, eabuflen: %zu", + LOG(log_debug, logtype_ad, "ad_write: off: %ju, size: %zu, eabuflen: %zu", (uintmax_t)off, buflen, ad->ad_rlen); if ( eid == ADEID_DFORK ) { @@ -174,7 +174,7 @@ int ad_rtruncate( struct adouble *ad, const off_t size) if (ret == 0) ad->ad_rlen = size; else - LOG(log_error, logtype_default, "ad_rtruncate(\"%s\"): %s", + LOG(log_error, logtype_ad, "ad_rtruncate(\"%s\"): %s", fullpathname(ad->ad_name), strerror(errno)); EC_EXIT; } @@ -182,7 +182,7 @@ int ad_rtruncate( struct adouble *ad, const off_t size) int ad_dtruncate(struct adouble *ad, const off_t size) { if (sys_ftruncate(ad_data_fileno(ad), size) < 0) { - LOG(log_error, logtype_default, "sys_ftruncate(fd: %d): %s", + LOG(log_error, logtype_ad, "sys_ftruncate(fd: %d): %s", ad_data_fileno(ad), strerror(errno)); return -1; } diff --git a/libatalk/util/logger.c b/libatalk/util/logger.c index 7bec1b8b..55630d1b 100644 --- a/libatalk/util/logger.c +++ b/libatalk/util/logger.c @@ -61,6 +61,7 @@ Netatalk 2001 (c) "DSI", \ "UAMS", \ "FCE", \ + "ad", \ "end_of_list_marker"} /* ========================================================================= @@ -85,7 +86,8 @@ UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_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_fce */ + DEFAULT_LOG_CONFIG /* logtype_ad */ }; static void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility); diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index e12561a2..3850cd8c 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -625,7 +625,7 @@ should be logged\&. By default afpd logs to syslog with a default logging setup equivalent to \fBdefault:note\fR .sp -logtypes: default, afpdaemon, logger, uamsdaemon +logtypes: default, afpdaemon, logger, uamsdaemon, dsi, fce, ad .sp loglevels: severe, error, warn, note, info, debug, debug6, debug7, debug8, debug9, maxdebug .if n \{\ From 528159030a49a14bc9963b1b874c29080211c34c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 23 Nov 2012 18:23:24 +0100 Subject: [PATCH 044/117] Reloading volumes from config file was broken load_volumes() is supposed to be a "reenetrant" function called from various places in different programs (afpd, cnid_metad) to reload the config for updating the volume list. Fix the loop freeing volumes that are deleted. Simplify the loop checking for paths and volume names in createvol(). This is also the loop which checks if a volume is already loaded when config has been loaded before. Remove checks for nested paths. Fixes bug #474. --- NEWS | 2 + bin/ad/ad.c | 2 +- etc/afpd/afp_config.c | 2 +- etc/afpd/afp_dsi.c | 2 +- etc/afpd/volume.c | 4 +- etc/cnid_dbd/cmd_dbd.c | 2 +- etc/cnid_dbd/cnid_metad.c | 4 +- etc/cnid_dbd/main.c | 2 +- include/atalk/netatalk_conf.h | 2 +- libatalk/util/netatalk_conf.c | 96 +++++++++++++++++++---------------- 10 files changed, 63 insertions(+), 55 deletions(-) diff --git a/NEWS b/NEWS index b87cf651..6e2a1287 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ Changes in 3.0.2 If /home -> /usr/home, set "basedir regex = /usr/home". * FIX: Memory leak * FIX: Copying packages to a Netatalk share could fail, bug #469 +* FIX: Reloading volumes from config file was broken. + Fixes bug #474. Changes in 3.0.1 ================ diff --git a/bin/ad/ad.c b/bin/ad/ad.c index 7f5b3da6..3de3030b 100644 --- a/bin/ad/ad.c +++ b/bin/ad/ad.c @@ -58,7 +58,7 @@ int main(int argc, char **argv) setuplog("default:note", "/dev/tty"); - if (load_volumes(&obj, NULL) != 0) + if (load_volumes(&obj) != 0) return 1; if (STRCMP(argv[1], ==, "ls")) diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index a61fe102..fa7da0c9 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -122,7 +122,7 @@ int configinit(AFPObj *obj) /* Now register with zeroconf, we also need the volumes for that */ if (! (obj->options.flags & OPTION_NOZEROCONF)) { - load_volumes(obj, NULL); + load_volumes(obj); zeroconf_register(obj); } diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 3e5cd47c..11e54627 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -549,7 +549,7 @@ void afp_over_dsi(AFPObj *obj) if (reload_request) { reload_request = 0; - load_volumes(AFPobj, closevol); + load_volumes(AFPobj); } /* The first SIGINT enables debugging, the next restores the config */ diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 61d8b408..172584d8 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -527,7 +527,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf int vcnt; size_t len; - load_volumes(obj, closevol); + load_volumes(obj); data = rbuf + 5; for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) { @@ -704,7 +704,7 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t if ((len + 1) & 1) /* pad to an even boundary */ ibuf++; - load_volumes(obj, closevol); + load_volumes(obj); for ( volume = getvolumes(); volume; volume = volume->v_next ) { if ( strcasecmp_w( (ucs2_t*) volname, volume->v_name ) == 0 ) { diff --git a/etc/cnid_dbd/cmd_dbd.c b/etc/cnid_dbd/cmd_dbd.c index 8f8b7342..eb53af79 100644 --- a/etc/cnid_dbd/cmd_dbd.c +++ b/etc/cnid_dbd/cmd_dbd.c @@ -263,7 +263,7 @@ int main(int argc, char **argv) else setuplog("default:debug", "/dev/tty"); - if (load_volumes(&obj, NULL) != 0) { + if (load_volumes(&obj) != 0) { dbd_log( LOGSTD, "Couldn't load volumes"); exit(EXIT_FAILURE); } diff --git a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c index dcf7d5fa..2fc1e8de 100644 --- a/etc/cnid_dbd/cnid_metad.c +++ b/etc/cnid_dbd/cnid_metad.c @@ -502,7 +502,7 @@ int main(int argc, char *argv[]) if (afp_config_parse(&obj, "cnid_metad") != 0) daemon_exit(1); - if (load_volumes(&obj, NULL) != 0) + if (load_volumes(&obj) != 0) daemon_exit(1); (void)setlimits(); @@ -604,7 +604,7 @@ int main(int argc, char *argv[]) LOG(log_debug, logtype_cnid, "main: request for volume: %s", volpath); - if (load_volumes(&obj, NULL) != 0) { + if (load_volumes(&obj) != 0) { LOG(log_severe, logtype_cnid, "main: error reloading config"); goto loop_end; } diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index 8ed0e5ff..df29d151 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -314,7 +314,7 @@ int main(int argc, char *argv[]) EC_ZERO( afp_config_parse(&obj, "cnid_dbd") ); - EC_ZERO( load_volumes(&obj, NULL) ); + EC_ZERO( load_volumes(&obj) ); EC_NULL( vol = getvolbypath(&obj, volpath) ); EC_ZERO( load_charset(vol) ); pack_setvol(vol); diff --git a/include/atalk/netatalk_conf.h b/include/atalk/netatalk_conf.h index cadb0aa3..efa4dba4 100644 --- a/include/atalk/netatalk_conf.h +++ b/include/atalk/netatalk_conf.h @@ -23,7 +23,7 @@ extern int afp_config_parse(AFPObj *obj, char *processname); extern int load_charset(struct vol *vol); -extern int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *)); +extern int load_volumes(AFPObj *obj); extern void unload_volumes(AFPObj *obj); extern struct vol *getvolumes(void); extern struct vol *getvolbyvid(const uint16_t); diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 36fdfbed..ff2ccb7a 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -567,7 +567,6 @@ static struct vol *creatvol(AFPObj *obj, { EC_INIT; struct vol *volume = NULL; - size_t current_pathlen, another_pathlen; int i, suffixlen, vlen, tmpvlen, u8mvlen, macvlen; char tmpname[AFPVOL_U8MNAMELEN+1]; char path[MAXPATHLEN + 1]; @@ -592,37 +591,26 @@ static struct vol *creatvol(AFPObj *obj, /* Once volumes are loaded, we never change options again, we just delete em when they're removed from afp.conf */ - /* - * Check for duplicated or nested volumes, eg: - * /Volumes/name /Volumes/name [duplicate], and - * /Volumes/name /Volumes/name/dir [nested], but beware of simple strncmp test: - * /Volumes/name /Volumes/name1 [strncmp match if n=strlen("Volumes/name") -> false positive] - */ - current_pathlen = strlen(path); for (struct vol *vol = Volumes; vol; vol = vol->v_next) { - another_pathlen = strlen(vol->v_path); - if (strncmp(path, vol->v_path, MIN(current_pathlen, another_pathlen)) == 0) { - if (current_pathlen == another_pathlen) { - LOG(log_error, logtype_afpd, "volume \"%s\" paths is duplicated: \"%s\"", name, path); - vol->v_deleted = 0; - volume = vol; - goto EC_CLEANUP; - } else { - const char *shorter_path, *longer_path; - int shorter_len; - if (another_pathlen > current_pathlen) { - shorter_len = current_pathlen; - shorter_path = path; - longer_path = vol->v_path; - } else { - shorter_len = another_pathlen; - shorter_path = vol->v_path; - longer_path = path; - } - if (longer_path[shorter_len] == '/') - LOG(log_info, logtype_afpd, "volume \"%s\" paths are nested: \"%s\" and \"%s\"", name, path, vol->v_path); - } + if (STRCMP(name, ==, vol->v_localname) && vol->v_deleted) { + /* + * reloading config, volume still present, nothing else to do, + * we don't change options for volumes once they're loaded + */ + vol->v_deleted = 0; + EC_EXIT_STATUS(0); } + if (STRCMP(path, ==, vol->v_path)) { + LOG(log_note, logtype_afpd, "volume \"%s\" path \"%s\" is the same as volumes \"%s\" path", + name, path, vol->v_configname); + EC_EXIT_STATUS(0); + + } + /* + * We could check for nested volume paths here, but + * nobody was able to come up with an implementation yet, + * that is simple, fast and correct. + */ } /* @@ -944,10 +932,8 @@ static struct vol *creatvol(AFPObj *obj, EC_CLEANUP: LOG(log_debug, logtype_afpd, "createvol: END: %d", ret); if (ret != 0) { - if (volume) { + if (volume) volume_free(volume); - free(volume); - } return NULL; } return volume; @@ -1268,12 +1254,14 @@ void volume_unlink(struct vol *volume) } /*! - * Free all resources allocated in a struct vol, only struct dir *v_root can't be freed + * Free all resources allocated in a struct vol in load_volumes() + * + * Actually opening a volume (afp_openvol()) will allocate additional + * ressources which are freed in closevol() */ void volume_free(struct vol *vol) { - LOG(log_debug, logtype_afpd, "volume_free('%s'): BEGIN", vol->v_localname); - + free(vol->v_configname); free(vol->v_localname); free(vol->v_u8mname); free(vol->v_macname); @@ -1288,10 +1276,12 @@ void volume_free(struct vol *vol) free(vol->v_uuid); free(vol->v_cnidserver); free(vol->v_cnidport); + free(vol->v_preexec); free(vol->v_root_preexec); free(vol->v_postexec); + free(vol->v_root_postexec); - LOG(log_debug, logtype_afpd, "volume_free: END"); + free(vol); } /*! @@ -1320,7 +1310,7 @@ int load_charset(struct vol *vol) * @param obj (r) handle * @param delvol_fn (r) callback called for deleted volumes */ -int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *)) +int load_volumes(AFPObj *obj) { EC_INIT; int fd = -1; @@ -1372,12 +1362,24 @@ int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *) EC_ZERO_LOG( readvolfile(obj, pwent) ); - for ( vol = Volumes; vol; vol = vol->v_next ) { - if (vol->v_deleted) { + struct vol *p, *prevvol; + + vol = Volumes; + prevvol = NULL; + + while (vol) { + if (vol->v_deleted && !(vol->v_flags & AFPVOL_OPEN)) { LOG(log_debug, logtype_afpd, "load_volumes: deleted: %s", vol->v_localname); - if (delvol_fn) - delvol_fn(obj, vol); - vol = Volumes; + if (prevvol) + prevvol->v_next = vol->v_next; + else + Volumes = NULL; + p = vol->v_next; + volume_free(vol); + vol = p; + } else { + prevvol = vol; + vol = vol->v_next; } } @@ -1391,12 +1393,16 @@ int load_volumes(AFPObj *obj, void (*delvol_fn)(const AFPObj *obj, struct vol *) void unload_volumes(AFPObj *obj) { - struct vol *vol; + struct vol *vol, *p; LOG(log_debug, logtype_afpd, "unload_volumes: BEGIN"); - for (vol = Volumes; vol; vol = vol->v_next) + p = Volumes; + while (p) { + vol = p; + p = vol->v_next; volume_free(vol); + } Volumes = NULL; obj->options.volfile.mtime = 0; From bbe7828e0a582e5685311be278b695bef35d26e6 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 26 Nov 2012 10:59:01 +0100 Subject: [PATCH 045/117] Update NEWS --- NEWS | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 6e2a1287..46f9c791 100644 --- a/NEWS +++ b/NEWS @@ -2,14 +2,18 @@ Changes in 3.0.2 ================ * NEW: afpd: Put file extension type/creator mapping back in which had been removed in 3.0. -* UPD: ignore duplicated or nested volume path. -* FIX: "path" parameter value may contain symlink. -* FIX: "basedir regex" was never able to treat symlink. - If /home -> /usr/home, set "basedir regex = /usr/home". -* FIX: Memory leak +* UPD: ignore volumes with duplicated volumes paths. +* 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: "valid users" options and friends only use ',' as field delimiter. + Fixes bug #472. +* FIX: Remove lenght limitation of options like "valid users". + Fixes bug #473. +* REM: Remove TimeMachine volume used size FCE event. Changes in 3.0.1 ================ From 865a552af24003422ca4a5714b2c078963a958ef Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 26 Nov 2012 17:18:53 +0100 Subject: [PATCH 046/117] Fix type --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 46f9c791..725d1677 100644 --- a/NEWS +++ b/NEWS @@ -11,7 +11,7 @@ Changes in 3.0.2 * FIX: Fix pathname bug for FCE modified event. * FIX: "valid users" options and friends only use ',' as field delimiter. Fixes bug #472. -* FIX: Remove lenght limitation of options like "valid users". +* FIX: Remove length limitation of options like "valid users". Fixes bug #473. * REM: Remove TimeMachine volume used size FCE event. From cf671eb6c9749a558b55155cdd6cbb2a65703d30 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 26 Nov 2012 16:19:02 +0100 Subject: [PATCH 047/117] Fix a ressource leak Due to the ordering and multiplexing of data- and metadata handle closing in ad_close(), a datafork lock handle was not released. Releasing lock handles is now done when the logic fork counter hits zero, not when the underlying filedescriptor referencing handle count reaches zero. --- libatalk/adouble/ad_flush.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index 61b34f50..a18c2c47 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -412,11 +412,11 @@ int ad_close(struct adouble *ad, int adflags) if ((adflags & ADFLAGS_DF) && (ad_data_fileno(ad) >= 0 || ad_data_fileno(ad) == AD_SYMLINK)) { if (ad->ad_data_refcount) - ad->ad_data_refcount--; + if (--ad->ad_data_refcount == 0) + adf_lock_free(&ad->ad_data_fork); if (--ad->ad_data_fork.adf_refcount == 0) { if (ad_data_closefd(ad) < 0) err = -1; - adf_lock_free(&ad->ad_data_fork); } } @@ -427,14 +427,13 @@ int ad_close(struct adouble *ad, int adflags) if (close( ad_meta_fileno(ad)) < 0) err = -1; ad_meta_fileno(ad) = -1; - if (ad->ad_vers == AD_VERSION2) - adf_lock_free(ad->ad_mdp); } } if (adflags & ADFLAGS_RF) { if (ad->ad_reso_refcount) - ad->ad_reso_refcount--; + if (--ad->ad_reso_refcount == 0) + adf_lock_free(ad->ad_rfp); if (ad->ad_vers == AD_VERSION_EA) { if ((ad_reso_fileno(ad) != -1) && !(--ad->ad_rfp->adf_refcount)) { @@ -442,7 +441,6 @@ int ad_close(struct adouble *ad, int adflags) err = -1; ad->ad_rlen = 0; ad_reso_fileno(ad) = -1; - adf_lock_free(ad->ad_rfp); } } } From 15a36f067598fbad66a6d6b6f7909c6b656071c2 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 27 Nov 2012 10:31:51 +0100 Subject: [PATCH 048/117] creatvol() must return a struct vol pointer --- libatalk/util/netatalk_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index ff2ccb7a..3e775e11 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -598,13 +598,13 @@ static struct vol *creatvol(AFPObj *obj, * we don't change options for volumes once they're loaded */ vol->v_deleted = 0; + volume = vol; EC_EXIT_STATUS(0); } if (STRCMP(path, ==, vol->v_path)) { LOG(log_note, logtype_afpd, "volume \"%s\" path \"%s\" is the same as volumes \"%s\" path", name, path, vol->v_configname); EC_EXIT_STATUS(0); - } /* * We could check for nested volume paths here, but From 59ba70c884ca7356e28873fccab7d3611369e6cc Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 22 Nov 2012 11:31:49 +0100 Subject: [PATCH 049/117] Fix SIGHUP config reloading Add SIGHUP handler to master 'netatalk' process and let it distribute the signal to it's childs, eg afpd. Add function afp_config_free() which releases ressources allocated by afp_config_parse(). Additionally fix configinit()/configfree() which deal with ressources only used in the afpd fileserver (eg sockets, zeroconf registration). Fix an error in the mdns unregister code where pthread_kill() was used but that somehow killed the whole process not just the mdns thread. Use pthread_cancel() instead which seems to work. Fix any ressource leak reported by libumem. --- etc/afpd/afp_config.c | 26 +++++++---- etc/afpd/afp_mdns.c | 23 ++++++---- etc/afpd/afp_options.c | 49 --------------------- etc/afpd/main.c | 7 ++- etc/netatalk/netatalk.c | 9 ++++ etc/uams/uams_dhx2_pam.c | 5 +-- include/atalk/dsi.h | 1 + include/atalk/globals.h | 1 - include/atalk/ldapconfig.h | 2 + include/atalk/netatalk_conf.h | 2 +- include/atalk/unicode.h | 1 + libatalk/acl/ldap.c | 32 +++++++------- libatalk/acl/ldap_config.c | 11 +++++ libatalk/dsi/dsi_tcp.c | 18 ++++++++ libatalk/unicode/charcnv.c | 10 +++++ libatalk/util/netatalk_conf.c | 81 +++++++++++++++++++++++++++++++++-- 16 files changed, 188 insertions(+), 90 deletions(-) diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index fa7da0c9..3d9aff81 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -41,31 +41,38 @@ /*! - * Free and cleanup all linked DSI objects from config + * Free and cleanup config and DSI * - * Preserve object pointed to by "dsi". - * "dsi" can be NULL in which case all DSI objects _and_ the options object are freed + * "dsi" can be NULL in which case all DSI objects and the config object is freed, + * otherwise its an afpd session child and only any unneeded DSI objects are freed */ void configfree(AFPObj *obj, DSI *dsi) { DSI *p, *q; - /* the master loaded the volumes for zeroconf, get rid of that */ - unload_volumes(obj); + if (!dsi) { + /* Master afpd reloading config */ + auth_unload(); + if (! (obj->options.flags & OPTION_NOZEROCONF)) { + unload_volumes(obj); + zeroconf_deregister(); + } + } + /* Master and child releasing unneeded DSI handles */ for (p = obj->dsi; p; p = q) { q = p->next; if (p == dsi) continue; - close(p->socket); + dsi_free(p); free(p); } + obj->dsi = NULL; + /* afpd session child passes dsi handle to obj handle */ if (dsi) { dsi->next = NULL; obj->dsi = dsi; - } else { - afp_options_free(&obj->options); } } @@ -81,6 +88,9 @@ int configinit(AFPObj *obj) auth_load(obj->options.uampath, obj->options.uamlist); set_signature(&obj->options); +#ifdef HAVE_LDAP + acl_ldap_freeconfig(); +#endif /* HAVE_LDAP */ LOG(log_debug, logtype_afpd, "DSIConfigInit: hostname: %s, listen: %s, port: %s", obj->options.hostname, diff --git a/etc/afpd/afp_mdns.c b/etc/afpd/afp_mdns.c index 1dc6cbbb..3158ce7b 100644 --- a/etc/afpd/afp_mdns.c +++ b/etc/afpd/afp_mdns.c @@ -50,15 +50,16 @@ static pthread_t poller; free(str); free(key); \ } +static struct pollfd *fds; /* * This is the thread that polls the filehandles */ -void *polling_thread(void *arg) { +static void *polling_thread(void *arg) { // First we loop through getting the filehandles and adding them to our poll, we // need to allocate our pollfd's DNSServiceErrorType error; - struct pollfd *fds = calloc(svc_ref_count, sizeof(struct pollfd)); + fds = calloc(svc_ref_count, sizeof(struct pollfd)); assert(fds); for(int i=0; i < svc_ref_count; i++) { @@ -78,28 +79,32 @@ void *polling_thread(void *arg) { return(NULL); } - /* * This is the callback for the service register function ... actually there isn't a lot * we can do if we get problems, so we don't really need to do anything other than report * the issue. */ -void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, - const char *name, const char *regtype, const char *domain, void *context) { - - if(errorCode != kDNSServiceErr_NoError) { +static void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, + const char *name, const char *regtype, const char *domain, void *context) +{ + if (errorCode != kDNSServiceErr_NoError) { LOG(log_error, logtype_afpd, "Failed to register mDNS service: %s%s%s: code=%d", name, regtype, domain, errorCode); } } - /* * This function unregisters anything we have already * registered and frees associated memory */ static void unregister_stuff() { - pthread_kill(poller, SIGKILL); + pthread_cancel(poller); + + for (int i = 0; i < svc_ref_count; i++) + close(fds[i].fd); + free(fds); + fds = NULL; + if(svc_refs) { for(int i=0; i < svc_ref_count; i++) { DNSServiceRefDeallocate(svc_refs[i]); diff --git a/etc/afpd/afp_options.c b/etc/afpd/afp_options.c index 6361d18f..bac65d59 100644 --- a/etc/afpd/afp_options.c +++ b/etc/afpd/afp_options.c @@ -44,55 +44,6 @@ #define LENGTH 512 -/* get rid of any allocated afp_option buffers. */ -void afp_options_free(struct afp_options *opt) -{ - if (opt->hostname) - free(opt->hostname); - if (opt->adminauthuser) - free(opt->adminauthuser); - if (opt->configfile) - free(opt->configfile); - if (opt->fqdn) - free(opt->fqdn); - if (opt->guest) - free(opt->guest); - if (opt->listen) - free(opt->listen); - if (opt->k5realm) - free(opt->k5realm); - if (opt->k5keytab) - free(opt->k5keytab); - if (opt->k5service) - free(opt->k5service); - if (opt->logconfig) - free(opt->logconfig); - if (opt->logfile) - free(opt->logfile); - if (opt->loginmesg) - free(opt->loginmesg); - if (opt->maccodepage) - free(opt->maccodepage); - if (opt->mimicmodel) - free(opt->mimicmodel); - if (opt->ntdomain) - free(opt->ntdomain); - if (opt->ntseparator) - free(opt->ntseparator); - if (opt->passwdfile) - free(opt->passwdfile); - if (opt->port) - free(opt->port); - if (opt->signatureopt) - free(opt->signatureopt); - if (opt->uamlist) - free(opt->uamlist); - if (opt->uampath) - free(opt->uampath); - if (opt->unixcodepage) - free(opt->unixcodepage); -} - /* * Show version information about afpd. * Used by "afp -v". diff --git a/etc/afpd/main.c b/etc/afpd/main.c index afbd90e0..106f725c 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -389,12 +389,17 @@ int main(int ac, char **av) if (reloadconfig) { nologin++; - auth_unload(); + fd_reset_listening_sockets(&obj); LOG(log_info, logtype_afpd, "re-reading configuration file"); configfree(&obj, NULL); + afp_config_free(&obj); + + if (afp_config_parse(&obj, "afpd") != 0) + afp_exit(EXITERR_CONF); + if (configinit(&obj) != 0) { LOG(log_error, logtype_afpd, "config re-read: no servers configured"); afp_exit(EXITERR_CONF); diff --git a/etc/netatalk/netatalk.c b/etc/netatalk/netatalk.c index b35d264c..bbae394c 100644 --- a/etc/netatalk/netatalk.c +++ b/etc/netatalk/netatalk.c @@ -116,6 +116,13 @@ static void sigquit_cb(evutil_socket_t fd, short what, void *arg) kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL); } +/* SIGQUIT 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); +} + /* SIGCHLD callback */ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) { @@ -296,6 +303,7 @@ int main(int argc, char **argv) sigterm_ev = event_new(base, SIGTERM, EV_SIGNAL, sigterm_cb, NULL); sigquit_ev = event_new(base, SIGQUIT, EV_SIGNAL | EV_PERSIST, sigquit_cb, NULL); + sigquit_ev = event_new(base, SIGHUP, EV_SIGNAL | EV_PERSIST, sighup_cb, NULL); sigchld_ev = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, sigchld_cb, NULL); timer_ev = event_new(base, -1, EV_PERSIST, timer_cb, NULL); @@ -311,6 +319,7 @@ int main(int argc, char **argv) sigdelset(&blocksigs, SIGTERM); sigdelset(&blocksigs, SIGQUIT); sigdelset(&blocksigs, SIGCHLD); + sigdelset(&blocksigs, SIGHUP); sigprocmask(SIG_SETMASK, &blocksigs, NULL); /* run the event loop */ diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index d033d96b..0de4b5ce 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -927,9 +927,6 @@ static int uam_setup(const char *path) if (uam_register(UAM_SERVER_CHANGEPW, path, "DHX2", dhx2_changepw) < 0) return -1; - p = gcry_mpi_new(0); - g = gcry_mpi_new(0); - LOG(log_debug, logtype_uams, "DHX2: generating mersenne primes"); /* Generate p and g for DH */ if (dh_params_generate(PRIMEBITS) != 0) { @@ -945,6 +942,8 @@ static void uam_cleanup(void) uam_unregister(UAM_SERVER_LOGIN, "DHX2"); uam_unregister(UAM_SERVER_CHANGEPW, "DHX2"); + LOG(log_debug, logtype_uams, "DHX2: uam_cleanup"); + gcry_mpi_release(p); gcry_mpi_release(g); } diff --git a/include/atalk/dsi.h b/include/atalk/dsi.h index 0e776c31..00c80d42 100644 --- a/include/atalk/dsi.h +++ b/include/atalk/dsi.h @@ -162,6 +162,7 @@ typedef struct DSI { extern DSI *dsi_init(AFPObj *obj, const char *hostname, const char *address, const char *port); extern void dsi_setstatus (DSI *, char *, const size_t); extern int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address, const char *port); +extern void dsi_free(DSI *dsi); /* in dsi_getsess.c */ extern int dsi_getsession (DSI *, server_child *, const int, afp_child_t **); diff --git a/include/atalk/globals.h b/include/atalk/globals.h index a8313a36..e50b0a7d 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -147,7 +147,6 @@ extern const char *Cnid_port; extern int get_afp_errno (const int param); extern void afp_options_init (struct afp_options *); extern void afp_options_parse_cmdline(AFPObj *obj, int ac, char **av); -extern void afp_options_free(struct afp_options *); extern void setmessage (const char *); extern void readmessage (AFPObj *); diff --git a/include/atalk/ldapconfig.h b/include/atalk/ldapconfig.h index 16e5484f..adc2a99d 100644 --- a/include/atalk/ldapconfig.h +++ b/include/atalk/ldapconfig.h @@ -7,6 +7,7 @@ /* One function does the whole job */ extern int acl_ldap_readconfig(dictionary *iniconfig); +extern void acl_ldap_freeconfig(void); /* These are the prefvalues */ extern char *ldap_server; @@ -33,6 +34,7 @@ struct ldap_pref { int strorint; /* string to just store in char * or convert to int ? */ int intfromarray; /* convert to int, but use string to int mapping array pref_array[] */ int valid; /* -1 = mandatory, 0 = omittable/valid */ + int valid_save; /* copy of 'valid', used when resettting config */ }; struct pref_array { diff --git a/include/atalk/netatalk_conf.h b/include/atalk/netatalk_conf.h index efa4dba4..858b4f1c 100644 --- a/include/atalk/netatalk_conf.h +++ b/include/atalk/netatalk_conf.h @@ -21,7 +21,7 @@ #include extern int afp_config_parse(AFPObj *obj, char *processname); - +extern void afp_config_free(AFPObj *obj); extern int load_charset(struct vol *vol); extern int load_volumes(AFPObj *obj); extern void unload_volumes(AFPObj *obj); diff --git a/include/atalk/unicode.h b/include/atalk/unicode.h index 0bb43b52..f842ce09 100644 --- a/include/atalk/unicode.h +++ b/include/atalk/unicode.h @@ -125,6 +125,7 @@ extern size_t utf8_strlen_validate ( char *); /* from charcnv.c */ extern int set_charset_name(charset_t, const char *); +extern void free_charset_names(void); extern void init_iconv (void); extern size_t convert_string (charset_t, charset_t, void const *, size_t, void *, size_t); extern size_t convert_string_allocate (charset_t, charset_t, void const *, size_t, char **); diff --git a/libatalk/acl/ldap.c b/libatalk/acl/ldap.c index 8743bafe..44caae83 100644 --- a/libatalk/acl/ldap.c +++ b/libatalk/acl/ldap.c @@ -23,6 +23,7 @@ #include #include #include +#include #define LDAP_DEPRECATED 1 #include @@ -56,21 +57,22 @@ char *ldap_uid_attr; int ldap_uuid_encoding; struct ldap_pref ldap_prefs[] = { - {&ldap_server, "ldap server", 0, 0, -1}, - {&ldap_auth_method,"ldap auth method", 1, 1, -1}, - {&ldap_auth_dn, "ldap auth dn", 0, 0, 0}, - {&ldap_auth_pw, "ldap auth pw", 0, 0, 0}, - {&ldap_userbase, "ldap userbase", 0, 0, -1}, - {&ldap_userscope, "ldap userscope", 1 ,1, -1}, - {&ldap_groupbase, "ldap groupbase", 0, 0, -1}, - {&ldap_groupscope, "ldap groupscope", 1 ,1, -1}, - {&ldap_uuid_attr, "ldap uuid attr", 0, 0, -1}, - {&ldap_uuid_string,"ldap uuid string", 0, 0, 0}, - {&ldap_name_attr, "ldap name attr", 0, 0, -1}, - {&ldap_group_attr, "ldap group attr", 0, 0, -1}, - {&ldap_uid_attr, "ldap uid attr", 0, 0, 0}, - {&ldap_uuid_encoding,"ldap uuid encoding", 1, 1, 0}, - {NULL, NULL, 0, 0, -1} + /* pointer to pref, prefname, strorint, intfromarray, valid, valid_save */ + {&ldap_server, "ldap server", 0, 0, -1, -1}, + {&ldap_auth_method, "ldap auth method", 1, 1, -1, -1}, + {&ldap_auth_dn, "ldap auth dn", 0, 0, 0, 0}, + {&ldap_auth_pw, "ldap auth pw", 0, 0, 0, 0}, + {&ldap_userbase, "ldap userbase", 0, 0, -1, -1}, + {&ldap_userscope, "ldap userscope", 1 ,1, -1, -1}, + {&ldap_groupbase, "ldap groupbase", 0, 0, -1, -1}, + {&ldap_groupscope, "ldap groupscope", 1 ,1, -1, -1}, + {&ldap_uuid_attr, "ldap uuid attr", 0, 0, -1, -1}, + {&ldap_uuid_string, "ldap uuid string", 0, 0, 0, 0}, + {&ldap_name_attr, "ldap name attr", 0, 0, -1, -1}, + {&ldap_group_attr, "ldap group attr", 0, 0, -1, -1}, + {&ldap_uid_attr, "ldap uid attr", 0, 0, 0, 0}, + {&ldap_uuid_encoding, "ldap uuid encoding", 1, 1, 0, 0}, + {NULL, NULL, 0, 0, 0, 0} }; struct pref_array prefs_array[] = { diff --git a/libatalk/acl/ldap_config.c b/libatalk/acl/ldap_config.c index bd9d414b..26a63fa9 100644 --- a/libatalk/acl/ldap_config.c +++ b/libatalk/acl/ldap_config.c @@ -30,6 +30,17 @@ #include #include +void acl_ldap_freeconfig(void) +{ + for (int i = 0; ldap_prefs[i].name != NULL; i++) { + if (ldap_prefs[i].intfromarray == 0 && ldap_prefs[i].strorint == 0) { + free(*((char **)(ldap_prefs[i].pref))); + *((char **)(ldap_prefs[i].pref)) = NULL; + } + ldap_prefs[i].valid = ldap_prefs[i].valid_save; + } +} + int acl_ldap_readconfig(dictionary *iniconfig) { int i, j; diff --git a/libatalk/dsi/dsi_tcp.c b/libatalk/dsi/dsi_tcp.c index e06e87d9..2dc5e15d 100644 --- a/libatalk/dsi/dsi_tcp.c +++ b/libatalk/dsi/dsi_tcp.c @@ -103,6 +103,24 @@ static void dsi_init_buffer(DSI *dsi) dsi->end = dsi->buffer + (dsi->dsireadbuf * dsi->server_quantum); } +/*! + * Free any allocated ressources of the master afpd DSI objects and close server socket + */ +void dsi_free(DSI *dsi) +{ + close(dsi->serversock); + dsi->serversock = -1; + + free(dsi->commands); + dsi->commands = NULL; + + free(dsi->buffer); + dsi->buffer = NULL; + + free(dsi->bonjourname); + dsi->bonjourname = NULL; +} + static struct itimerval itimer; /* accept the socket and do a little sanity checking */ static int dsi_tcp_open(DSI *dsi) diff --git a/libatalk/unicode/charcnv.c b/libatalk/unicode/charcnv.c index 785e4772..d72848e9 100644 --- a/libatalk/unicode/charcnv.c +++ b/libatalk/unicode/charcnv.c @@ -95,6 +95,16 @@ int set_charset_name(charset_t ch, const char *name) return 0; } +void free_charset_names(void) +{ + for (int ch = 0; ch < MAX_CHARSETS; ch++) { + if (charset_names[ch]) { + free(charset_names[ch]); + charset_names[ch] = NULL; + } + } +} + static struct charset_functions* get_charset_functions (charset_t ch) { if (charsets[ch] != NULL) diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 3e775e11..664fd3e5 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1754,11 +1754,11 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) LOG(log_debug, logtype_afpd, "Locale charset is '%s'", p); #else /* system doesn't have LOCALE support */ LOG(log_warning, logtype_afpd, "system doesn't have LOCALE support"); - p = strdup("UTF8"); + p = "UTF8"; #endif } if (strcasecmp(p, "UTF-8") == 0) { - p = strdup("UTF8"); + p = "UTF8"; } options->unixcodepage = strdup(p); set_charset_name(CH_UNIX, p); @@ -1771,7 +1771,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->volcodepage = strdup(options->unixcodepage); } else { if (strcasecmp(p, "UTF-8") == 0) { - p = strdup("UTF8"); + p = "UTF8"; } options->volcodepage = strdup(p); } @@ -1815,3 +1815,78 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) EC_CLEANUP: EC_EXIT; } + +#define CONFIG_ARG_FREE(a) do { \ + free(a); \ + a = NULL; \ + } while (0); + +/* get rid of any allocated afp_option buffers. */ +void afp_config_free(AFPObj *obj) +{ + if (obj->options.configfile) + CONFIG_ARG_FREE(obj->options.configfile); + if (obj->options.sigconffile) + CONFIG_ARG_FREE(obj->options.sigconffile); + if (obj->options.uuidconf) + CONFIG_ARG_FREE(obj->options.uuidconf); + if (obj->options.logconfig) + CONFIG_ARG_FREE(obj->options.logconfig); + if (obj->options.logfile) + CONFIG_ARG_FREE(obj->options.logfile); + if (obj->options.loginmesg) + CONFIG_ARG_FREE(obj->options.loginmesg); + if (obj->options.guest) + CONFIG_ARG_FREE(obj->options.guest); + if (obj->options.extmapfile) + CONFIG_ARG_FREE(obj->options.extmapfile); + if (obj->options.passwdfile) + CONFIG_ARG_FREE(obj->options.passwdfile); + if (obj->options.uampath) + CONFIG_ARG_FREE(obj->options.uampath); + if (obj->options.uamlist) + CONFIG_ARG_FREE(obj->options.uamlist); + if (obj->options.port) + CONFIG_ARG_FREE(obj->options.port); + if (obj->options.signatureopt) + CONFIG_ARG_FREE(obj->options.signatureopt); + if (obj->options.k5service) + CONFIG_ARG_FREE(obj->options.k5service); + if (obj->options.k5realm) + CONFIG_ARG_FREE(obj->options.k5realm); + if (obj->options.listen) + CONFIG_ARG_FREE(obj->options.listen); + if (obj->options.ntdomain) + CONFIG_ARG_FREE(obj->options.ntdomain); + if (obj->options.ntseparator) + CONFIG_ARG_FREE(obj->options.ntseparator); + if (obj->options.mimicmodel) + CONFIG_ARG_FREE(obj->options.mimicmodel); + if (obj->options.adminauthuser) + CONFIG_ARG_FREE(obj->options.adminauthuser); + if (obj->options.hostname) + CONFIG_ARG_FREE(obj->options.hostname); + if (obj->options.k5keytab) + CONFIG_ARG_FREE(obj->options.k5keytab); + if (obj->options.Cnid_srv) + CONFIG_ARG_FREE(obj->options.Cnid_srv); + if (obj->options.Cnid_port) + CONFIG_ARG_FREE(obj->options.Cnid_port); + if (obj->options.fqdn) + CONFIG_ARG_FREE(obj->options.fqdn); + + if (obj->options.unixcodepage) + CONFIG_ARG_FREE(obj->options.unixcodepage); + if (obj->options.maccodepage) + CONFIG_ARG_FREE(obj->options.maccodepage); + if (obj->options.volcodepage) + CONFIG_ARG_FREE(obj->options.volcodepage); + + obj->options.flags = 0; + obj->options.passwdbits = 0; + + /* Free everything called from afp_config_parse() */ + free_extmap(); + iniparser_freedict(obj->iniconfig); + free_charset_names(); +} From 820fc9f0b3b1e2a9f055fc572bae60151fa0ecba Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 20 Nov 2012 18:19:33 +0100 Subject: [PATCH 050/117] Ensure pthread support compiler and linker flags are correct On some platforms using AC_SEARCH_LIBS is not sufficient for finding the linker flags for linking with a pthread library. Add macro ax_pthread.m4 from GNU autoconf macro archive and use the macro AX_PTHREAD. Fix compiler and linker flags for afpd and libatalk. Thanks to Jason Teska for pinpointing this. --- configure.ac | 6 +- etc/afpd/Makefile.am | 2 +- libatalk/Makefile.am | 5 +- macros/Makefile.am | 2 +- macros/ax_pthread.m4 | 309 +++++++++++++++++++++++++++++++++++++++++++ macros/summary.m4 | 7 +- 6 files changed, 321 insertions(+), 10 deletions(-) create mode 100644 macros/ax_pthread.m4 diff --git a/configure.ac b/configure.ac index 49f70c60..116c3fa5 100644 --- a/configure.ac +++ b/configure.ac @@ -80,11 +80,7 @@ AC_CHECK_FUNCS(mmap utime getpagesize) dnl needed by tbd dnl search for necessary libraries AC_SEARCH_LIBS(gethostbyname, nsl) AC_SEARCH_LIBS(connect, socket) -AC_SEARCH_LIBS(pthread_sigmask, pthread,,[AC_MSG_ERROR([missing pthread_sigmask])]) -if test x"$ac_cv_search_pthread_sigmask" != x"none required" ; then - PTHREAD_LIBS=$ac_cv_search_pthread_sigmask -fi -AC_SUBST(PTHREAD_LIBS) +AX_PTHREAD(, [AC_MSG_ERROR([missing pthread_sigmask])]) AC_DEFINE(OPEN_NOFOLLOW_ERRNO, ELOOP, errno returned by open with O_NOFOLLOW) diff --git a/etc/afpd/Makefile.am b/etc/afpd/Makefile.am index 1cb8913a..2404ad7d 100644 --- a/etc/afpd/Makefile.am +++ b/etc/afpd/Makefile.am @@ -49,7 +49,7 @@ afpd_LDADD = \ afpd_LDFLAGS = -export-dynamic afpd_CFLAGS = \ - @ZEROCONF_CFLAGS@ @GSSAPI_CFLAGS@ @KRB5_CFLAGS@\ + @ZEROCONF_CFLAGS@ @GSSAPI_CFLAGS@ @KRB5_CFLAGS@ @PTHREAD_CFLAGS@\ -DAPPLCNAME \ -DSERVERTEXT=\"$(SERVERTEXT)/\" \ -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \ diff --git a/libatalk/Makefile.am b/libatalk/Makefile.am index e69cdffb..fb0e7456 100644 --- a/libatalk/Makefile.am +++ b/libatalk/Makefile.am @@ -37,8 +37,11 @@ lib_LTLIBRARIES = libatalk.la libatalk_la_SOURCES = dummy.c +libatalk_la_CFLAGS = \ + @PTHREAD_CFLAGS@ + libatalk_la_LIBADD = \ - @WRAP_LIBS@ @ACL_LIBS@ \ + @WRAP_LIBS@ @ACL_LIBS@ @PTHREAD_LIBS@ \ acl/libacl.la \ adouble/libadouble.la \ bstring/libbstring.la \ diff --git a/macros/Makefile.am b/macros/Makefile.am index 6c541a8f..8e1f9c69 100644 --- a/macros/Makefile.am +++ b/macros/Makefile.am @@ -1,5 +1,6 @@ EXTRA_DIST = \ afs-check.m4 \ + ax_pthread.m4 \ cnid-backend.m4 \ config-checks.m4 \ db3-check.m4 \ @@ -17,4 +18,3 @@ EXTRA_DIST = \ summary.m4 \ tcp-wrappers.m4 \ util.m4 - diff --git a/macros/ax_pthread.m4 b/macros/ax_pthread.m4 new file mode 100644 index 00000000..9ede48e7 --- /dev/null +++ b/macros/ax_pthread.m4 @@ -0,0 +1,309 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 18 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) + AC_MSG_RESULT($ax_pthread_ok) + if test x"$ax_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case ${host_os} in + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ;; + + darwin*) + ax_pthread_flags="-pthread $ax_pthread_flags" + ;; +esac + +if test x"$ax_pthread_ok" = xno; then +for flag in $ax_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) + if test x"$ax_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($ax_pthread_ok) + if test "x$ax_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $attr; return attr /* ; */])], + [attr_name=$attr; break], + []) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case ${host_os} in + aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; + osf* | hpux*) flag="-D_REENTRANT";; + solaris*) + if test "$GCC" = "yes"; then + flag="-D_REENTRANT" + else + flag="-mt -D_REENTRANT" + fi + ;; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + ax_cv_PTHREAD_PRIO_INHERIT, [ + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$ax_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/macros/summary.m4 b/macros/summary.m4 index 8d9abc50..6c696fc2 100644 --- a/macros/summary.m4 +++ b/macros/summary.m4 @@ -69,8 +69,11 @@ AC_DEFUN([AC_NETATALK_LIBS_SUMMARY], [ dnl # Display summary of libraries detected AC_MSG_RESULT([Using libraries:]) - AC_MSG_RESULT([ LIBS = $LIBS]) - AC_MSG_RESULT([ CFLAGS = $CFLAGS]) + AC_MSG_RESULT([ LIBS = $LIBS]) + AC_MSG_RESULT([ CFLAGS = $CFLAGS]) + AC_MSG_RESULT([ PTHREADS:]) + AC_MSG_RESULT([ LIBS = $PTHREAD_LIBS]) + AC_MSG_RESULT([ CFLAGS = $PTHREAD_CFLAGS]) if test x"$neta_cv_have_openssl" = x"yes"; then AC_MSG_RESULT([ SSL:]) AC_MSG_RESULT([ LIBS = $SSL_LIBS]) From 8f60935cc161eb79dec63b5f791e732920ba5696 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 27 Nov 2012 18:04:29 +0100 Subject: [PATCH 051/117] Don't convert AppleDouble v2 file of symlinks, delete it Netatalk 2.x created AppleDouble files for symlinks. Netatalk's 3 autoconversion of AppleDouble files to AppleDouble metadata extended attributes failed to do the conversion in ad_convert() because some filesystem may not support EAs on symlinks. The new behaviour is to ignore symlinks in ad_convert(). Fixes bug #471. --- libatalk/adouble/ad_conv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libatalk/adouble/ad_conv.c b/libatalk/adouble/ad_conv.c index eef80912..329790bb 100644 --- a/libatalk/adouble/ad_conv.c +++ b/libatalk/adouble/ad_conv.c @@ -64,8 +64,16 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path)); + switch (S_IFMT & sp->st_mode) { + case S_IFREG: + break; + default: + return 0; + } + ad_init(&adea, vol); ad_init_old(&adv2, AD_VERSION2, adea.ad_options); + adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0; /* Open and lock adouble:v2 file */ @@ -124,6 +132,13 @@ static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struc LOG(log_debug, logtype_ad,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path)); + switch (S_IFMT & sp->st_mode) { + case S_IFREG: + break; + default: + return 0; + } + if (S_ISDIR(sp->st_mode)) return 0; From 7cba587c60e60e371687ac074ffe9265e5b1ac6d Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 28 Nov 2012 09:25:28 +0100 Subject: [PATCH 052/117] Import manpage from XML --- man/man5/afp.conf.5.tmpl | 53 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index 3850cd8c..f2fd8b47 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -506,30 +506,6 @@ extmap file = \fIpath\fR \fB(G)\fR Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/AppleVolumes\&.system)\&. .RE .PP -fce listener = \fIhost[:port]\fR \fB(G)\fR -.RS 4 -Enables sending FCE events to the specified -\fIhost\fR, default -\fIport\fR -is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&. -.RE -.PP -fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR -.RS 4 -Speficies which FCE events are active, default is -\fIfmod,fdel,ddel,fcre,dcre\fR\&. -.RE -.PP -fce coalesce = \fIall|delete|create\fR \fB(G)\fR -.RS 4 -Coalesce FCE events\&. -.RE -.PP -fce holdfmod = \fIseconds\fR \fB(G)\fR -.RS 4 -This determines the time delay in seconds which is always waited if another file modification for the same file is done by a client before sending an FCE file modification event (fmod)\&. For example saving a file in Photoshop would generate multiple events by itself because the application is opening, modifying and closing a file mutliple times for every "save"\&. Defautl: 60 seconds\&. -.RE -.PP guest account = \fIname\fR \fB(G)\fR .RS 4 Specifies the user that guests should use (default is "nobody")\&. The name should be quoted\&. @@ -625,7 +601,7 @@ should be logged\&. By default afpd logs to syslog with a default logging setup equivalent to \fBdefault:note\fR .sp -logtypes: default, afpdaemon, logger, uamsdaemon, dsi, fce, ad +logtypes: default, afpdaemon, logger, uamsdaemon .sp loglevels: severe, error, warn, note, info, debug, debug6, debug7, debug8, debug9, maxdebug .if n \{\ @@ -644,6 +620,33 @@ Both logtype and loglevels are case insensitive\&. .sp .5v .RE .RE +.SS "Filesystem Change Events (FCE)" +.PP +Netatalk includes a nifty filesystem change event mechanism where afpd processes notfiy interested listeners about certain filesytem event by UDP network datagrams\&. +.PP +fce listener = \fIhost[:port]\fR \fB(G)\fR +.RS 4 +Enables sending FCE events to the specified +\fIhost\fR, default +\fIport\fR +is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&. +.RE +.PP +fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR +.RS 4 +Speficies which FCE events are active, default is +\fIfmod,fdel,ddel,fcre,dcre\fR\&. +.RE +.PP +fce coalesce = \fIall|delete|create\fR \fB(G)\fR +.RS 4 +Coalesce FCE events\&. +.RE +.PP +fce holdfmod = \fIseconds\fR \fB(G)\fR +.RS 4 +This determines the time delay in seconds which is always waited if another file modification for the same file is done by a client before sending an FCE file modification event (fmod)\&. For example saving a file in Photoshop would generate multiple events by itself because the application is opening, modifying and closing a file mutliple times for every "save"\&. Defautl: 60 seconds\&. +.RE .SS "Debug Parameters" .PP These options are useful for debugging only\&. From bbcce1d9b2b5694fc5662d6d8f033dd38c3579f1 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 28 Nov 2012 14:23:33 +0100 Subject: [PATCH 053/117] Add option 'ad domain' Add option 'ad domain' similar to 'nt domain'. Useful when authenticating against Netatalk on Solaris in case the OS is bound to Active Directory. Currently users have to type in their full AD name user@domain. Adding an option 'ad domain' would allows users to login giving just their usernames. Implements FR #66. --- NEWS | 1 + etc/afpd/uam.c | 34 ++++++++++++++++----------------- include/atalk/globals.h | 2 +- libatalk/util/netatalk_conf.c | 3 +++ man/man5/afp.conf.5.tmpl | 36 ++++++++++++++++++++--------------- 5 files changed, 43 insertions(+), 33 deletions(-) diff --git a/NEWS b/NEWS index 725d1677..c9b6a6a6 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ 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. * UPD: ignore volumes with duplicated volumes paths. * FIX: volumes and home share with symlinks in the path * FIX: Copying packages to a Netatalk share could fail, bug #469 diff --git a/etc/afpd/uam.c b/etc/afpd/uam.c index d99d381e..625cf6a5 100644 --- a/etc/afpd/uam.c +++ b/etc/afpd/uam.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "afp_config.h" #include "auth.h" @@ -209,25 +210,24 @@ struct passwd *uam_getname(void *private, char *name, const int len) return pwent; /* if we have a NT domain name try with it */ - if (obj->options.ntdomain && obj->options.ntseparator) { + if (obj->options.addomain || (obj->options.ntdomain && obj->options.ntseparator)) { /* FIXME What about charset ? */ - size_t ulen = strlen(obj->options.ntdomain) + strlen(obj->options.ntseparator) + strlen(name); - if ((p = malloc(ulen +1))) { - strcpy(p, obj->options.ntdomain); - strcat(p, obj->options.ntseparator); - strcat(p, name); - pwent = getpwnam(p); - free(p); - if (pwent) { - int len = strlen(pwent->pw_name); - if (len < MAXUSERLEN) { - strncpy(name,pwent->pw_name, MAXUSERLEN); - }else{ - LOG(log_error, logtype_uams, "MAJOR:The name %s is longer than %d",pwent->pw_name,MAXUSERLEN); - } - - return pwent; + bstring princ; + if (obj->options.addomain) + princ = bformat("%s@%s", name, obj->options.addomain); + else + princ = bformat("%s%s%s", obj->options.ntdomain, obj->options.ntseparator, name); + pwent = getpwnam(bdata(princ)); + bdestroy(princ); + + if (pwent) { + int len = strlen(pwent->pw_name); + if (len < MAXUSERLEN) { + strncpy(name,pwent->pw_name, MAXUSERLEN); + } else { + LOG(log_error, logtype_uams, "The name '%s' is longer than %d", pwent->pw_name, MAXUSERLEN); } + return pwent; } } #ifndef NO_REAL_USER_NAME diff --git a/include/atalk/globals.h b/include/atalk/globals.h index e50b0a7d..75d4041b 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -98,7 +98,7 @@ struct afp_options { gid_t admingid; int volnamelen; /* default value for winbind authentication */ - char *ntdomain, *ntseparator; + char *ntdomain, *ntseparator, *addomain; char *logconfig; char *logfile; char *mimicmodel; diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 664fd3e5..12b76665 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -1669,6 +1669,7 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) options->k5realm = iniparser_getstrdup(config, INISEC_GLOBAL, "k5 realm", NULL); options->listen = iniparser_getstrdup(config, INISEC_GLOBAL, "afp listen", NULL); options->ntdomain = iniparser_getstrdup(config, INISEC_GLOBAL, "nt domain", NULL); + options->addomain = iniparser_getstrdup(config, INISEC_GLOBAL, "ad domain", NULL); options->ntseparator = iniparser_getstrdup(config, INISEC_GLOBAL, "nt separator", NULL); options->mimicmodel = iniparser_getstrdup(config, INISEC_GLOBAL, "mimic model", NULL); options->adminauthuser = iniparser_getstrdup(config, INISEC_GLOBAL, "admin auth user",NULL); @@ -1858,6 +1859,8 @@ void afp_config_free(AFPObj *obj) CONFIG_ARG_FREE(obj->options.listen); if (obj->options.ntdomain) CONFIG_ARG_FREE(obj->options.ntdomain); + if (obj->options.addomain) + CONFIG_ARG_FREE(obj->options.addomain); if (obj->options.ntseparator) CONFIG_ARG_FREE(obj->options.ntseparator); if (obj->options.mimicmodel) diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index f2fd8b47..e0ba2649 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -37,8 +37,8 @@ The file consists of sections and parameters\&. A section begins with the name o .RS 4 .\} .nf -\fIname\fR = \fIvalue \fR - + \fIname\fR = \fIvalue \fR + .fi .if n \{\ .RE @@ -53,7 +53,7 @@ Only the first equals sign in a parameter is significant\&. Whitespace before or Any line beginning with a semicolon (\(lq;\(rq) or a hash (\(lq#\(rq) character is ignored, as are lines containing only whitespace\&. .PP Any line ending in a -\(lq\e\(rq +\(lq \e \(rq is continued on the next line in the customary UNIX fashion\&. .PP The values following the equals sign in parameters are all either a string (no quotes needed) or a boolean, which may be given as yes/no, 1/0 or true/false\&. Case is not significant in boolean values, but is preserved in string values\&. Some items such as create masks are numeric\&. @@ -93,9 +93,8 @@ baz: .RS 4 .\} .nf -[baz] -path = /foo/bar - + [baz] + path = /foo/bar .fi .if n \{\ .RE @@ -124,9 +123,7 @@ The following example illustrates this\&. Given all user home directories are st .RS 4 .\} .nf -[Homes] -path = afp\-data -basedir regex = /home + [Homes] path = afp\-data basedir regex = /home .fi .if n \{\ @@ -232,6 +229,11 @@ prints dollar sign ($) .SH "EXPLANATION OF GLOBAL PARAMETERS" .SS "Authentication Options" .PP +ad domain = \fIDOMAIN\fR \fB(G)\fR +.RS 4 +Append @DOMAIN to username when authenticating\&. Useful in Active Directory environments that otherwise would require the user to enter the full user@domain string\&. +.RE +.PP admin auth user = \fIuser\fR \fB(G)\fR .RS 4 Specifying eg "\fBadmin auth user = root\fR" whenever a normal user login fails, afpd will try to authenticate as the specified @@ -567,9 +569,9 @@ Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especial .RS 4 .\} .nf -73: limit of Mac OS X 10\&.1 -80: limit of Mac OS X 10\&.4/10\&.5 (default) -255: limit of recent Mac OS X + 73: limit of Mac OS X 10\&.1 80: limit of Mac + OS X 10\&.4/10\&.5 (default) 255: limit of recent Mac OS + X .fi .if n \{\ .RE @@ -697,6 +699,7 @@ sasl .RS 4 SASL\&. Not yet supported ! .RE +.sp .RE .PP ldap auth dn = \fIdn\fR \fB(G)\fR @@ -772,6 +775,7 @@ ms\-guid .RS 4 Binary objectGUID from Active Directory .RE +.sp .RE .PP ldap group attr = \fIdn\fR \fB(G)\fR @@ -910,17 +914,19 @@ is for files only, is for directories only\&. Don\'t use with "\fBunix priv = no\fR"\&. .PP \fBExample.\ \&Volume for a collaborative workgroup\fR + .sp .if n \{\ .RS 4 .\} .nf -file perm = 0660 -directory perm = 0770 +file perm = 0660 directory perm = + 0770 .fi .if n \{\ .RE .\} +.sp .RE .PP @@ -1105,7 +1111,7 @@ The option will allow you to select another volume encoding\&. E\&.g\&. for western users another useful setting could be vol charset ISO\-8859\-15\&. \fBafpd\fR will accept any -\fBiconv\fR(1) +\fB iconv \fR(1) provided charset\&. If a character cannot be converted from the \fBmac charset\fR to the selected From 815ef35acb8a352e4572e1d524a9d404d10a3f70 Mon Sep 17 00:00:00 2001 From: HAT Date: Tue, 27 Nov 2012 01:11:33 +0900 Subject: [PATCH 054/117] systemd service: show doc URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ex. netatalk.service - Netatalk AFP fileserver for Macintosh clients Loaded: loaded (/usr/lib/systemd/system/netatalk.service; disabled) Active: active (running) since Tue, 27 Nov 2012 01:03:44 +0900; 41s ago Docs: man:afp.conf(5) man:netatalk(8) man:afpd(8) man:cnid_metad(8) man:cnid_dbd(8) http://netatalk.sourceforge.net/ Process: 30813 ExecStart=/usr/local/sbin/netatalk (code=exited, status=0/SUCCESS) CGroup: name=systemd:/system/netatalk.service ├ 30815 /usr/local/sbin/netatalk ├ 30816 /usr/local/sbin/afpd -d -F /usr/local/etc/afp.conf ├ 30817 /usr/local/sbin/cnid_metad -d -F /usr/local/etc/afp.conf â”” 30823 /usr/local/sbin/cnid_dbd -F /usr/local/etc/afp.conf -p /export/test -t 7 -l 5 --- distrib/initscripts/service.systemd.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/distrib/initscripts/service.systemd.tmpl b/distrib/initscripts/service.systemd.tmpl index 2183f303..d21dde92 100644 --- a/distrib/initscripts/service.systemd.tmpl +++ b/distrib/initscripts/service.systemd.tmpl @@ -2,6 +2,8 @@ [Unit] Description=Netatalk AFP fileserver for Macintosh clients +Documentation=man:afp.conf(5) man:netatalk(8) man:afpd(8) man:cnid_metad(8) man:cnid_dbd(8) +Documentation=http://netatalk.sourceforge.net/ After=syslog.target network.target avahi-daemon.service [Service] From 1a59f639265e6fc11385a40dcef2a70a53b54954 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 4 Dec 2012 15:58:51 +0100 Subject: [PATCH 055/117] Fix adouble refcounting Opening a file that doesn't have metadata with ADFLAGS_HF | AFFLAGS_NOHF resulted in a successfull open (the error from the failed opening of the nonexistent metadata is suppressed by AFFLAGS_NOHF), but then the metadata refcount was increased becasue the error condition was already reset to 0 at the place where we checked it. Fixing this requires pushing the refcount increment deeper down the stack into the individual functions where the error condition is still available. After fixing this, another bug became apparent in the mostyl empty function ad_open_rf_v2(). Also fix an if check where what should be a comparison clobbered a struct field. --- libatalk/adouble/ad_flush.c | 4 ++-- libatalk/adouble/ad_open.c | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index a18c2c47..cb0be93c 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -237,8 +237,8 @@ int ad_copy_header(struct adouble *add, struct adouble *ads) } add->ad_rlen = ads->ad_rlen; - if ((ads->ad_vers == AD_VERSION2) && (add->ad_vers = AD_VERSION_EA) - || (ads->ad_vers == AD_VERSION_EA) && (add->ad_vers = AD_VERSION2)) { + if (((ads->ad_vers == AD_VERSION2) && (add->ad_vers == AD_VERSION_EA)) + || ((ads->ad_vers == AD_VERSION_EA) && (add->ad_vers == AD_VERSION2))) { cnid_t id; memcpy(&id, ad_entry(add, ADEID_PRIVID), sizeof(cnid_t)); id = htonl(id); diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index bc72ff0b..4f3a832c 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -1133,7 +1133,9 @@ static int ad_open_hf(const char *path, int adflags, int mode, struct adouble *a break; } - if (ret != 0) + if (ret == 0) + ad->ad_meta_refcount++; + else ret = ad_error(ad, adflags); return ret; @@ -1186,13 +1188,23 @@ static int ad_reso_size(const char *path, int adflags, struct adouble *ad) static int ad_open_rf_v2(const char *path, int adflags, int mode, struct adouble *ad) { + EC_INIT; + /* * ad_open_hf_v2() does the work, but if it failed and adflags are ADFLAGS_NOHF | ADFLAGS_RF * ad_open_hf_v2() didn't give an error, but we're supposed to return a reso fork fd */ - if (!AD_RSRC_OPEN(ad) && !(adflags & ADFLAGS_NORF)) - return -1; - return 0; + + LOG(log_debug, logtype_ad, "ad_open_rf_v2(\"%s\"): BEGIN", fullpathname(path)); + + if (!AD_META_OPEN(ad) && !(adflags & ADFLAGS_NORF)) + EC_FAIL; + if (AD_META_OPEN(ad)) + ad->ad_reso_refcount++; + +EC_CLEANUP: + LOG(log_debug, logtype_ad, "ad_open_rf_v2(\"%s\"): END: %d", fullpathname(path), ret); + EC_EXIT; } static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble *ad) @@ -1250,6 +1262,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble opened = 1; ad->ad_rfp->adf_refcount = 1; ad->ad_rfp->adf_flags = oflags; + ad->ad_reso_refcount++; #ifndef HAVE_EAFD EC_ZERO_LOG( fstat(ad_reso_fileno(ad), &st) ); @@ -1276,6 +1289,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble if (opened && (ad_reso_fileno(ad) != -1)) { close(ad_reso_fileno(ad)); ad_reso_fileno(ad) = -1; + ad->ad_reso_refcount--; ad->ad_rfp->adf_refcount = 0; } if (adflags & ADFLAGS_NORF) { @@ -1658,17 +1672,13 @@ int ad_open(struct adouble *ad, const char *path, int adflags, ...) } if (adflags & ADFLAGS_HF) { - ad->ad_meta_refcount++; if (ad_open_hf(path, adflags, mode, ad) != 0) { - ad->ad_meta_refcount--; EC_FAIL; } } if (adflags & ADFLAGS_RF) { - ad->ad_reso_refcount++; if (ad_open_rf(path, adflags, mode, ad) != 0) { - ad->ad_reso_refcount--; EC_FAIL; } } From ff117107526219d5ce89d5ff683eddd414e40293 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 4 Dec 2012 16:08:27 +0100 Subject: [PATCH 056/117] Dont copy our metadata EA in copyfile() Apparently Apple is now relying more on the AFP copyfile function for file copies where source and destination are on the same vol. The copying is done by our copyfile() function. It calls into our VFS stack where in the end _all_ extended attributes of the file, including our metadata EA, will be copied from source to dest. This resulted in an incorrect metadata EA on the destination file, eg the CNID was still the one of the source file. Obviously the metadata EA of the destination file must be created such that all relevant fields are properly assigned. Fixes bug #452. --- NEWS | 2 ++ etc/afpd/directory.c | 10 ++++----- etc/afpd/directory.h | 2 +- etc/afpd/enumerate.c | 2 +- etc/afpd/file.c | 52 +++++++++++++++++++++++++++++-------------- etc/afpd/file.h | 4 ++-- etc/afpd/filedir.c | 4 ++-- libatalk/vfs/ea_sys.c | 3 +++ 8 files changed, 51 insertions(+), 28 deletions(-) diff --git a/NEWS b/NEWS index c9b6a6a6..9c5472cc 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ Changes in 3.0.2 Fixes bug #472. * FIX: Remove length limitation of options like "valid users". Fixes bug #473. +* FIX: Dont copy our metadata EA in copyfile(). + Fixes bug #452. * REM: Remove TimeMachine volume used size FCE event. Changes in 3.0.1 diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 8b36c99b..854b6941 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -185,7 +185,7 @@ static int deletedir(int dirfd, char *dir) } /* do a recursive copy. */ -static int copydir(const struct vol *vol, int dirfd, char *src, char *dst) +static int copydir(struct vol *vol, struct dir *ddir, int dirfd, char *src, char *dst) { char spath[MAXPATHLEN + 1], dpath[MAXPATHLEN + 1]; DIR *dp; @@ -239,9 +239,9 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst) strcpy(dpath + dlen, de->d_name); if (S_ISDIR(st.st_mode)) { - if (AFP_OK != (err = copydir(vol, dirfd, spath, dpath))) + if (AFP_OK != (err = copydir(vol, ddir, dirfd, spath, dpath))) goto copydir_done; - } else if (AFP_OK != (err = copyfile(vol, vol, dirfd, spath, dpath, NULL, NULL))) { + } else if (AFP_OK != (err = copyfile(vol, vol, ddir, dirfd, spath, dpath, NULL, NULL))) { goto copydir_done; } else { @@ -2213,7 +2213,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ * newparent curdir * dirfd -1 means ignore dirfd (or use AT_FDCWD), otherwise src is relative to dirfd */ -int renamedir(const struct vol *vol, +int renamedir(struct vol *vol, int dirfd, char *src, char *dst, @@ -2239,7 +2239,7 @@ int renamedir(const struct vol *vol, case EXDEV: /* this needs to copy and delete. bleah. that means we have * to deal with entire directory hierarchies. */ - if ((err = copydir(vol, dirfd, src, dst)) < 0) { + if ((err = copydir(vol, newparent, dirfd, src, dst)) < 0) { deletedir(-1, dst); return err; } diff --git a/etc/afpd/directory.h b/etc/afpd/directory.h index 7f3e8c56..eb89c606 100644 --- a/etc/afpd/directory.h +++ b/etc/afpd/directory.h @@ -115,7 +115,7 @@ extern int getdirparams (const AFPObj *obj, const struct vol *, uint16_t struct dir *, char *, size_t *); extern int setdirparams(struct vol *, struct path *, uint16_t, char *); -extern int renamedir(const struct vol *, int, char *, char *, struct dir *, +extern int renamedir(struct vol *, int, char *, char *, struct dir *, struct dir *, char *); extern int path_error(struct path *, int error); extern void setdiroffcnt(struct dir *dir, struct stat *st, uint32_t count); diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index d469928c..c3b3acb4 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -370,7 +370,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, if (convname) { s_path.id = cnid_lookup(vol->v_cdb, &s_path.st, curdir->d_did, sd.sd_last, strlen(sd.sd_last)); if (s_path.id != CNID_INVALID) { - if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, convname, strlen(convname)) != 0) + if (cnid_update(vol->v_cdb, s_path.id, &s_path.st, curdir->d_did, (char *)convname, strlen(convname)) != 0) LOG(log_error, logtype_afpd, "enumerate: error updating CNID of \"%s\"", fullpathname(convname)); } } diff --git a/etc/afpd/file.c b/etc/afpd/file.c index c4c55fb8..bc336a4e 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1085,7 +1085,7 @@ int setfilparams(const AFPObj *obj, struct vol *vol, * adp adouble struct of src file, if open, or & zeroed one * */ -int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *newname, struct adouble *adp) +int renamefile(struct vol *vol, struct dir *ddir, int sdir_fd, char *src, char *dst, char *newname, struct adouble *adp) { int rc; @@ -1110,7 +1110,7 @@ int renamefile(const struct vol *vol, int sdir_fd, char *src, char *dst, char *n /* FIXME warning in syslog so admin'd know there's a conflict ?*/ return AFPERR_OLOCK; /* little lie */ } - if (AFP_OK != ( rc = copyfile(vol, vol, sdir_fd, src, dst, newname, NULL )) ) { + if (AFP_OK != ( rc = copyfile(vol, vol, ddir, sdir_fd, src, dst, newname, NULL )) ) { /* on error copyfile delete dest */ return( rc ); } @@ -1344,7 +1344,7 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si goto copy_exit; } - if ( (err = copyfile(s_vol, d_vol, -1, p, upath , newname, adp)) < 0 ) { + if ( (err = copyfile(s_vol, d_vol, curdir, -1, p, upath , newname, adp)) < 0 ) { retvalue = err; goto copy_exit; } @@ -1362,8 +1362,9 @@ int afp_copyfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, si * because we are doing it elsewhere. * currently if newname is NULL then adp is NULL. */ -int copyfile(const struct vol *s_vol, - const struct vol *d_vol, +int copyfile(struct vol *s_vol, + struct vol *d_vol, + struct dir *d_dir, int sfd, char *src, char *dst, @@ -1385,13 +1386,17 @@ int copyfile(const struct vol *s_vol, adp = &ads; } - adflags = ADFLAGS_DF | ADFLAGS_RF | ADFLAGS_NORF; + adflags = ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF | ADFLAGS_RF | ADFLAGS_NORF; if (ad_openat(adp, sfd, src, adflags | ADFLAGS_RDONLY) < 0) { ret_err = errno; goto done; } + if (!AD_META_OPEN(adp)) + /* no resource fork, don't create one for dst file */ + adflags &= ~ADFLAGS_HF; + if (!AD_RSRC_OPEN(adp)) /* no resource fork, don't create one for dst file */ adflags &= ~ADFLAGS_RF; @@ -1424,12 +1429,25 @@ int copyfile(const struct vol *s_vol, if (err < 0) ret_err = errno; - if (!ret_err && newname && (adflags & ADFLAGS_HF)) { - /* set the new name in the resource fork */ - ad_copy_header(&add, adp); - ad_setname(&add, newname); - ad_flush( &add ); + if (AD_META_OPEN(&add)) { + if (AD_META_OPEN(adp)) + ad_copy_header(&add, adp); + ad_setname(&add, dst); + cnid_t id; + struct stat stdest; + if (fstat(ad_meta_fileno(&add), &stdest) != 0) { + ret_err = errno; + goto error; + } + if ((id = get_id(d_vol, &add, &stdest, d_dir->d_did, dst, strlen(dst))) == CNID_INVALID) { + ret_err = EINVAL; + goto error; + } + (void)ad_setid(&add, stdest.st_dev, stdest.st_ino, id, d_dir->d_did, d_vol->v_stamp); + ad_flush(&add); } + +error: ad_close( adp, adflags ); if (ad_close( &add, adflags ) <0) { @@ -2090,17 +2108,17 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U } /* now, quickly rename the file. we error if we can't. */ - if ((err = renamefile(vol, -1, p, temp, temp, adsp)) != AFP_OK) + if ((err = renamefile(vol, curdir, -1, p, temp, temp, adsp)) != AFP_OK) goto err_exchangefile; of_rename(vol, s_of, sdir, spath, curdir, temp); /* rename destination to source */ - if ((err = renamefile(vol, -1, upath, p, spath, addp)) != AFP_OK) + if ((err = renamefile(vol, curdir, -1, upath, p, spath, addp)) != AFP_OK) goto err_src_to_tmp; of_rename(vol, d_of, curdir, path->m_name, sdir, spath); /* rename temp to destination */ - if ((err = renamefile(vol, -1, temp, upath, path->m_name, adsp)) != AFP_OK) + if ((err = renamefile(vol, curdir, -1, temp, upath, path->m_name, adsp)) != AFP_OK) goto err_dest_to_src; of_rename(vol, s_of, curdir, temp, curdir, path->m_name); @@ -2175,17 +2193,17 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U * properly. */ err_temp_to_dest: /* rename dest to temp */ - renamefile(vol, -1, upath, temp, temp, adsp); + renamefile(vol, curdir, -1, upath, temp, temp, adsp); of_rename(vol, s_of, curdir, upath, curdir, temp); err_dest_to_src: /* rename source back to dest */ - renamefile(vol, -1, p, upath, path->m_name, addp); + renamefile(vol, curdir, -1, p, upath, path->m_name, addp); of_rename(vol, d_of, sdir, spath, curdir, path->m_name); err_src_to_tmp: /* rename temp back to source */ - renamefile(vol, -1, temp, p, spath, adsp); + renamefile(vol, curdir, -1, temp, p, spath, adsp); of_rename(vol, s_of, curdir, temp, sdir, spath); err_exchangefile: diff --git a/etc/afpd/file.h b/etc/afpd/file.h index ec811596..1d0ff45e 100644 --- a/etc/afpd/file.h +++ b/etc/afpd/file.h @@ -105,8 +105,8 @@ extern struct extmap *getdefextmap (void); extern int getfilparams (const AFPObj *obj, struct vol *, uint16_t, struct path *, struct dir *, char *buf, size_t *, int); extern int setfilparams (const AFPObj *obj, struct vol *, struct path *, uint16_t, char *); -extern int renamefile (const struct vol *, int, char *, char *, char *, struct adouble *); -extern int copyfile (const struct vol *, const struct vol *, int, char *, char *, char *, struct adouble *); +extern int renamefile (struct vol *, struct dir *, int, char *, char *, char *, struct adouble *); +extern int copyfile (struct vol *, struct vol *, struct dir *, int, char *, char *, char *, struct adouble *); extern int deletefile (const struct vol *, int, char *, int); extern int getmetadata (const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct path *path, diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 83f7f1aa..9a897d1b 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -218,7 +218,7 @@ int check_name(const struct vol *vol, char *name) move and rename sdir:oldname to curdir:newname in volume vol special care is needed for lock */ -static int moveandrename(const struct vol *vol, +static int moveandrename(struct vol *vol, struct dir *sdir, int sdir_fd, char *oldname, @@ -349,7 +349,7 @@ static int moveandrename(const struct vol *vol, if (of_findname(&path)) { rc = AFPERR_EXIST; /* was AFPERR_BUSY; */ } else { - rc = renamefile(vol, sdir_fd, oldunixname, upath, newname, adp ); + rc = renamefile(vol, curdir, sdir_fd, oldunixname, upath, newname, adp ); if (rc == AFP_OK) of_rename(vol, opened, sdir, oldname, curdir, newname); } diff --git a/libatalk/vfs/ea_sys.c b/libatalk/vfs/ea_sys.c index a30e6d96..374248bc 100644 --- a/libatalk/vfs/ea_sys.c +++ b/libatalk/vfs/ea_sys.c @@ -439,6 +439,9 @@ int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE) if (!*name) continue; + if (STRCMP(name, ==, AD_EA_META)) + continue; + if (sfd != -1) { if (fchdir(sfd) == -1) { LOG(log_error, logtype_afpd, "sys_ea_copyfile: cant chdir to sfd: %s", From 0eae4501cb1d6c61288d2edb2f5e865edba6b0c1 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 5 Dec 2012 11:26:09 +0100 Subject: [PATCH 057/117] Fix a log messsage --- etc/afpd/directory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 854b6941..46670e96 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -2308,7 +2308,7 @@ int deletecurdir(struct vol *vol) /* bail if it's not a symlink */ if ((lstat(de->d_name, &st) == 0) && !S_ISLNK(st.st_mode)) { LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): not empty", - curdir->d_fullpath); + bdata(curdir->d_fullpath)); closedir(dp); return AFPERR_DIRNEMPT; } From 828e9561dbf7890dd7720667a29436e55262fb74 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 5 Dec 2012 12:38:09 +0100 Subject: [PATCH 058/117] Enhance log message --- libatalk/adouble/ad_flush.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index cb0be93c..d8fbacf6 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -292,7 +292,8 @@ static int ad_flush_hf(struct adouble *ad) if (ad->ad_adflags & ADFLAGS_DIR) { EC_NEG1_LOG( cwd = open(".", O_RDONLY) ); EC_NEG1_LOG( fchdir(ad_data_fileno(ad)) ); - EC_ZERO_LOG( sys_lsetxattr(".", AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0) ); + EC_ZERO_LOGSTR( sys_lsetxattr(".", AD_EA_META, ad->ad_data, AD_DATASZ_EA, 0), + "sys_lsetxattr(\"%s\"): %s", fullpathname(".") ,strerror(errno)); EC_NEG1_LOG( fchdir(cwd) ); EC_NEG1_LOG( close(cwd) ); cwd = -1; From c998e57a52c29a5952385b818c1fcd0e6dd54059 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 5 Dec 2012 13:06:27 +0100 Subject: [PATCH 059/117] Ensure CNID info is set in metadata --- etc/afpd/file.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/afpd/file.c b/etc/afpd/file.c index bc336a4e..8036c300 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -980,6 +980,12 @@ int setfilparams(const AFPObj *obj, struct vol *vol, isad = 0; } else if ((ad_get_MD_flags( adp ) & O_CREAT) ) { ad_setname(adp, path->m_name); + cnid_t id; + if ((id = get_id(vol, adp, &path->st, curdir->d_did, upath, strlen(upath))) == CNID_INVALID) { + LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): CNID error", upath); + return AFPERR_MISC; + } + (void)ad_setid(adp, path->st.st_dev, path->st.st_ino, id, curdir->d_did, vol->v_stamp); } bit = 0; From dbaae078efa0b9c4559fd85bb8b139508751bf15 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 5 Dec 2012 12:39:08 +0100 Subject: [PATCH 060/117] Don't force errno ENOATTR on Solaris --- libatalk/vfs/extattr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libatalk/vfs/extattr.c b/libatalk/vfs/extattr.c index 26da7063..5206aa6d 100644 --- a/libatalk/vfs/extattr.c +++ b/libatalk/vfs/extattr.c @@ -876,7 +876,6 @@ static int solaris_attropen(const char *path, const char *attrpath, int oflag, m EC_FAIL; default: LOG(log_debug, logtype_default, "open(\"%s\"): %s", fullpathname(path), strerror(errno)); - errno = ENOATTR; EC_FAIL; } } @@ -888,7 +887,6 @@ static int solaris_attropen(const char *path, const char *attrpath, int oflag, m EC_FAIL; default: LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno)); - errno = ENOATTR; EC_FAIL; } } From c9d6b8ccabc28a5bb4b0c6daf8cbc140a81407bd Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 09:55:53 +0100 Subject: [PATCH 061/117] Fix an error where catalog search gave incomplete results The bug was immediately solved when chaning the current implementation of using the function dirlookup_bybath() with paths form the dirstack, to dirlook() with dids stored in the dirstack. Presumably something dirlookup_bybath() went wrong thus ceratain folders weren't searched. Fixes bug #479. --- NEWS | 2 ++ etc/afpd/catsearch.c | 68 ++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/NEWS b/NEWS index 9c5472cc..94f6649a 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,8 @@ Changes in 3.0.2 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. Changes in 3.0.1 diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 71843e2c..946644fb 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -29,6 +29,9 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#include +#include +#include #include #include #include @@ -109,12 +112,8 @@ struct scrit { * */ struct dsitem { -// struct dir *dir; /* Structure describing this directory */ -// cnid_t did; /* CNID of this directory */ - int pidx; /* Parent's dsitem structure index. */ - int checked; /* Have we checked this directory ? */ - int path_len; - char *path; /* absolute UNIX path to this directory */ + cnid_t ds_did; /* CNID of this directory */ + int ds_checked; /* Have we checked this directory ? */ }; @@ -131,7 +130,6 @@ static void clearstack(void) save_cidx = -1; while (dsidx > 0) { dsidx--; - free(dstack[dsidx].path); } } @@ -156,23 +154,8 @@ static int addstack(char *uname, struct dir *dir, int pidx) /* Put new element. Allocate and copy lname and path. */ ds = dstack + dsidx++; -// ds->did = dir->d_did; - ds->pidx = pidx; - ds->checked = 0; - if (pidx >= 0) { - l = dstack[pidx].path_len; - u = strlen(uname) +1; - if (!(ds->path = malloc(l + u + 1) )) - return -1; - memcpy(ds->path, dstack[pidx].path, l); - ds->path[l] = '/'; - memcpy(&ds->path[l+1], uname, u); - ds->path_len = l +u; - } - else { - ds->path = strdup(uname); - ds->path_len = strlen(uname); - } + ds->ds_did = dir->d_did; + ds->ds_checked = 0; return 0; } @@ -187,9 +170,9 @@ static int reducestack(void) } while (dsidx > 0) { - if (dstack[dsidx-1].checked) { + if (dstack[dsidx-1].ds_checked) { dsidx--; - free(dstack[dsidx].path); +// free(dstack[dsidx].path); } else return dsidx - 1; } @@ -521,7 +504,8 @@ static int catsearch(const AFPObj *obj, int num_rounds = NUM_ROUNDS; int cwd = -1; int error; - + int unlen; + if (*pos != 0 && *pos != cur_pos) { result = AFPERR_CATCHNG; goto catsearch_end; @@ -555,20 +539,24 @@ static int catsearch(const AFPObj *obj, start_time = time(NULL); while ((cidx = reducestack()) != -1) { - LOG(log_debug, logtype_afpd, "catsearch: dir: \"%s\"", dstack[cidx].path); + if ((currentdir = dirlookup(vol, dstack[cidx].ds_did)) == NULL) { + result = AFPERR_MISC; + goto catsearch_end; + } + LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath)); - error = lchdir(dstack[cidx].path); + error = lchdir(bdata(currentdir->d_fullpath)); if (!error && dirpos == NULL) dirpos = opendir("."); if (dirpos == NULL) - dirpos = opendir(dstack[cidx].path); + dirpos = opendir(bdata(currentdir->d_fullpath)); if (error || dirpos == NULL) { switch (errno) { case EACCES: - dstack[cidx].checked = 1; + dstack[cidx].ds_checked = 1; continue; case EMFILE: case ENFILE: @@ -583,11 +571,6 @@ static int catsearch(const AFPObj *obj, goto catsearch_end; } - if ((currentdir = dirlookup_bypath(vol, dstack[cidx].path)) == NULL) { - result = AFPERR_MISC; - goto catsearch_end; - } - LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath)); while ((entry = readdir(dirpos)) != NULL) { (*pos)++; @@ -615,12 +598,13 @@ static int catsearch(const AFPObj *obj, goto catsearch_end; } } - if (S_ISDIR(path.st.st_mode)) { + switch (S_IFMT & path.st.st_mode) { + case S_IFDIR: /* here we can short cut ie if in the same loop the parent dir wasn't in the cache ALL dirsearch_byname will fail. */ - int unlen = strlen(path.u_name); + unlen = strlen(path.u_name); path.d_dir = dircache_search_by_name(vol, currentdir, path.u_name, @@ -641,8 +625,12 @@ static int catsearch(const AFPObj *obj, result = AFPERR_MISC; goto catsearch_end; } - } else { + break; + case S_IFREG: path.d_dir = currentdir; + break; + default: + continue; } ccr = crit_check(vol, &path); @@ -674,7 +662,7 @@ static int catsearch(const AFPObj *obj, } /* while ((entry=readdir(dirpos)) != NULL) */ closedir(dirpos); dirpos = NULL; - dstack[cidx].checked = 1; + dstack[cidx].ds_checked = 1; } /* while (current_idx = reducestack()) != -1) */ /* We have finished traversing our tree. Return EOF here. */ From b5dfea886c4b3177c5506f3d694f149ee51a8e3e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 10:29:01 +0100 Subject: [PATCH 062/117] Revert c7683d5aae3d154250df531a5d34e4a464b5ced2 'valid users' option, cf #472. --- NEWS | 2 -- libatalk/util/netatalk_conf.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 94f6649a..cb28553f 100644 --- a/NEWS +++ b/NEWS @@ -10,8 +10,6 @@ Changes in 3.0.2 Fixes bug #474. * FIX: Fix _device-info service type registered with dns-sd API * FIX: Fix pathname bug for FCE modified event. -* FIX: "valid users" options and friends only use ',' as field delimiter. - Fixes bug #472. * FIX: Remove length limitation of options like "valid users". Fixes bug #473. * FIX: Dont copy our metadata EA in copyfile(). diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 12b76665..338394e1 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -402,7 +402,7 @@ static char *volxlate(const AFPObj *obj, * check access list * * this function wants something of the following form: - * "@group,name,name2,@group2,name3". + * "@group,name,name2,@group2,name3" or "@group name name2 @group2 name3" * A NULL argument allows everybody to have access. * We return three things: * -1: no list @@ -420,7 +420,7 @@ static int accessvol(const AFPObj *obj, const char *args, const char *name) EC_NULL_LOG( names = strdup(args) ); - if ((p = strtok(names, ",")) == NULL) /* nothing, return okay */ + if ((p = strtok(names, ", ")) == NULL) /* nothing, return okay */ EC_EXIT_STATUS(-1); while (p) { From 27452b5a10240b87e8a35c04d845a1159eab0f4a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 10:42:47 +0100 Subject: [PATCH 063/117] Add a missing conditional compilation ifdef --- libatalk/dsi/dsi_tcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libatalk/dsi/dsi_tcp.c b/libatalk/dsi/dsi_tcp.c index 2dc5e15d..fd9de4a0 100644 --- a/libatalk/dsi/dsi_tcp.c +++ b/libatalk/dsi/dsi_tcp.c @@ -117,8 +117,10 @@ void dsi_free(DSI *dsi) free(dsi->buffer); dsi->buffer = NULL; +#ifdef USE_ZEROCONF free(dsi->bonjourname); dsi->bonjourname = NULL; +#endif } static struct itimerval itimer; From 787f660cf2694bdb04356d5c76b2d5754e09f755 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 10:56:33 +0100 Subject: [PATCH 064/117] Add utility function strtok_quote() --- include/atalk/util.h | 1 + libatalk/util/unix.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/atalk/util.h b/include/atalk/util.h index ad2709a4..30aba481 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -184,6 +184,7 @@ extern int daemonize(int nochdir, int noclose); extern int run_cmd(const char *cmd, char **cmd_argv); extern char *realpath_safe(const char *path); extern const char *basename_safe(const char *path); +extern char *strtok_quote (char *s, const char *delim); /****************************************************************** * cnid.c diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 6dce0857..bde1a7ca 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -386,3 +386,41 @@ const char *basename_safe(const char *path) strlcpy(buf, path, MAXPATHLEN); return basename(buf); } + +/** + * extended strtok allows the quoted strings + * modified strtok.c in glibc 2.0.6 + **/ +char *strtok_quote(char *s, const char *delim) +{ + static char *olds = NULL; + char *token; + + if (s == NULL) + s = olds; + + /* Scan leading delimiters. */ + s += strspn (s, delim); + if (*s == '\0') + return NULL; + + /* Find the end of the token. */ + token = s; + + if (token[0] == '\"') { + token++; + s = strpbrk (token, "\""); + } else { + s = strpbrk (token, delim); + } + + if (s == NULL) { + /* This token finishes the string. */ + olds = strchr (token, '\0'); + } else { + /* Terminate the token and make OLDS point past it. */ + *s = '\0'; + olds = s + 1; + } + return token; +} From d99f64619a4242c5d4c3792f7b36adc976c13e31 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 13:03:28 +0100 Subject: [PATCH 065/117] Fix volume loading in afpd session Due to the changes in 59ba70c884ca7356e28873fccab7d3611369e6cc (SIGHUP support), volumes were not reloaded in the afpd session child. --- etc/afpd/afp_config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index 3d9aff81..61bbf684 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -54,11 +54,12 @@ void configfree(AFPObj *obj, DSI *dsi) /* Master afpd reloading config */ auth_unload(); if (! (obj->options.flags & OPTION_NOZEROCONF)) { - unload_volumes(obj); zeroconf_deregister(); } } + unload_volumes(obj); + /* Master and child releasing unneeded DSI handles */ for (p = obj->dsi; p; p = q) { q = p->next; From 31bda62b05fe69efe7d54188c74dcee936064f4d Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 6 Dec 2012 13:06:14 +0100 Subject: [PATCH 066/117] Add support for quoting in '[in]valid users' option As the option should allow spaces in names, but we use comma and space as field delimiter, add support for quoting names. Fixes bug #472. --- NEWS | 2 ++ libatalk/util/netatalk_conf.c | 11 +++++++---- man/man5/afp.conf.5.tmpl | 24 +++++++++++++++--------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index cb28553f..9ae8ad59 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ Changes in 3.0.2 * 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. Changes in 3.0.1 ================ diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 338394e1..01c6cb97 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -401,8 +401,11 @@ static char *volxlate(const AFPObj *obj, /*! * check access list * - * this function wants something of the following form: - * "@group,name,name2,@group2,name3" or "@group name name2 @group2 name3" + * this function wants a string consisting of names seperated by comma + * or space. Names may be quoted within a pair of quotes. Groups are + * denoted by a leading @ symbol. + * Example: + * user1 user2, user3, @group1 @group2, @group3 "user name1", "@group name1" * A NULL argument allows everybody to have access. * We return three things: * -1: no list @@ -420,7 +423,7 @@ static int accessvol(const AFPObj *obj, const char *args, const char *name) EC_NULL_LOG( names = strdup(args) ); - if ((p = strtok(names, ", ")) == NULL) /* nothing, return okay */ + if ((p = strtok_quote(names, ", ")) == NULL) /* nothing, return okay */ EC_EXIT_STATUS(-1); while (p) { @@ -429,7 +432,7 @@ static int accessvol(const AFPObj *obj, const char *args, const char *name) EC_EXIT_STATUS(1); } else if (strcasecmp(p, name) == 0) /* it's a user name */ EC_EXIT_STATUS(1); - p = strtok(NULL, ", "); + p = strtok_quote(NULL, ", "); } EC_CLEANUP: diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index e0ba2649..d2bbf43a 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -2,12 +2,12 @@ .\" Title: afp.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 22 Nov 2012 +.\" Date: 06 Dez 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "AFP\&.CONF" "5" "22 Nov 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "AFP\&.CONF" "5" "06 Dez 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -699,7 +699,6 @@ sasl .RS 4 SASL\&. Not yet supported ! .RE -.sp .RE .PP ldap auth dn = \fIdn\fR \fB(G)\fR @@ -775,7 +774,6 @@ ms\-guid .RS 4 Binary objectGUID from Active Directory .RE -.sp .RE .PP ldap group attr = \fIdn\fR \fB(G)\fR @@ -811,9 +809,19 @@ Useful for Time Machine: limits the reported volume size, thus preventing Time M This is an approimated calculation taking into accout the contents of Time Machine sparsebundle images\&. Therefor you MUST NOT use this volume to store other content when using this option, because it would NOT be accounted\&. The calculation works by reading the band size from the Info\&.plist XML file of the sparsebundle, reading the bands/ directory counting the number of band files, and then multiplying one with the other\&. .RE .PP -valid users = \fIusers/groups\fR \fB(V)\fR +valid users = \fIuser @group\fR \fB(V)\fR .RS 4 -The allow option allows the users and groups that access a share to be specified\&. Users and groups are specified, delimited by spaces or commas\&. Groups are designated by a @ prefix\&. Example: "valid users = user1 user2 @group" +The allow option allows the users and groups that access a share to be specified\&. Users and groups are specified, delimited by spaces or commas\&. Groups are designated by a @ prefix\&. Names may be quoted in order to allow for spaces in names\&. Example: +.sp +.if n \{\ +.RS 4 +.\} +.nf +valid users = user "user 2" @group \(lq@group 2" +.fi +.if n \{\ +.RE +.\} .RE .PP invalid users = \fIusers/groups\fR \fB(V)\fR @@ -914,7 +922,6 @@ is for files only, is for directories only\&. Don\'t use with "\fBunix priv = no\fR"\&. .PP \fBExample.\ \&Volume for a collaborative workgroup\fR - .sp .if n \{\ .RS 4 @@ -926,7 +933,6 @@ file perm = 0660 directory perm = .if n \{\ .RE .\} -.sp .RE .PP @@ -1111,7 +1117,7 @@ The option will allow you to select another volume encoding\&. E\&.g\&. for western users another useful setting could be vol charset ISO\-8859\-15\&. \fBafpd\fR will accept any -\fB iconv \fR(1) +\fBiconv\fR(1) provided charset\&. If a character cannot be converted from the \fBmac charset\fR to the selected From 622aff39328f4d55e41865d68eba630c7f751d7e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 7 Dec 2012 10:02:25 +0100 Subject: [PATCH 067/117] Fix make distcheck --- test/afpd/test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/afpd/test.c b/test/afpd/test.c index 1731ddc1..b25ec4dd 100644 --- a/test/afpd/test.c +++ b/test/afpd/test.c @@ -67,7 +67,7 @@ int main(int argc, char **argv) TEST_int( afp_config_parse(&obj, NULL), 0); TEST_int( configinit(&obj), 0); TEST( cnid_init() ); - TEST( load_volumes(&obj, NULL) ); + TEST( load_volumes(&obj) ); TEST_int( dircache_init(8192), 0); obj.afp_version = 32; From 3343c2d8c60d0f8ceea24db14d42eada625e7631 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 11 Dec 2012 15:58:17 +0100 Subject: [PATCH 068/117] Remove dequoting of double quotes in the iniparser, conflicts with strtok_quote() --- libatalk/iniparser/iniparser.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libatalk/iniparser/iniparser.c b/libatalk/iniparser/iniparser.c index 6e89472b..5c741d25 100644 --- a/libatalk/iniparser/iniparser.c +++ b/libatalk/iniparser/iniparser.c @@ -8,6 +8,10 @@ */ /*---------------------------- Includes ------------------------------------*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include @@ -474,8 +478,7 @@ static line_status iniparser_line( strcpy(section, strstrip(section)); strcpy(section, section); sta = LINE_SECTION ; - } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 - || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 + } else if (sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { /* Usual key=value, with or without comments */ strcpy(key, strstrip(key)); From 7d260cdde7b048b1bb7bb61ea396ac9c3ce677de Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 11 Dec 2012 13:42:12 +0100 Subject: [PATCH 069/117] Fix a possible crash when searching on large volumes catsearch() used dirlookup() to lookup directories, but then it didn't use movecwd() to cd into them, only lchdir(). This resulted in curdir not being updated. Then, while processing entries of directory and adding them to the dircache, in case the dircache hit its maximum size limit, dircache eviction would take place. The dircache eviction will remove a fixed size number of directories from the cache, but for every entry to be freed it will ensure that it's nor curdir. Unfortunately as catsearch didn't update that, the directory that catsearch was working on was freed, which of course resulted in access of invalid ressouces and possible crashes. The fix is to just use movecwd() instead of lchdir()ing directly. --- etc/afpd/catsearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 946644fb..1a2b8989 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -545,7 +545,7 @@ static int catsearch(const AFPObj *obj, } LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath)); - error = lchdir(bdata(currentdir->d_fullpath)); + error = movecwd(vol, currentdir); if (!error && dirpos == NULL) dirpos = opendir("."); From 0213d16eeacedc3e012798b808c8db27506f9a27 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 17 Dec 2012 15:39:00 +0100 Subject: [PATCH 070/117] Install functional PAM config file to PAM include directory Install a PAM config file which includes the 'other' service. Fixes bug #481. --- NEWS | 2 ++ macros/pam-check.m4 | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/NEWS b/NEWS index 9ae8ad59..12291fc2 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ Changes in 3.0.2 * 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. + Fixed bug #481. Changes in 3.0.1 ================ diff --git a/macros/pam-check.m4 b/macros/pam-check.m4 index 6bc40cba..1f40646b 100644 --- a/macros/pam-check.m4 +++ b/macros/pam-check.m4 @@ -98,6 +98,13 @@ AC_DEFUN([AC_NETATALK_PATH_PAM], [ PAM_ACCOUNT=system PAM_PASSWORD=system PAM_SESSION=system + dnl Solaris 11+ + elif test -f "$pampath/other" ; then + PAM_DIRECTIVE=include + PAM_AUTH=${PAMDIR}etc/pam.d/other + PAM_ACCOUNT=${PAMDIR}etc/pam.d/other + PAM_PASSWORD=${PAMDIR}etc/pam.d/other + PAM_SESSION=${PAMDIR}etc/pam.d/other dnl Fallback else PAM_DIRECTIVE=required From 4d29a9862f560191795249625545c37c939a33b1 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 7 Dec 2012 18:32:13 +0100 Subject: [PATCH 071/117] Remove special arg used by dbd of dbd_add() and dbd_lookup() --- etc/cnid_dbd/dbd.h | 4 +-- etc/cnid_dbd/dbd_add.c | 22 ++++++------ etc/cnid_dbd/dbd_lookup.c | 71 +++++++++++++++++---------------------- etc/cnid_dbd/main.c | 4 +-- 4 files changed, 45 insertions(+), 56 deletions(-) diff --git a/etc/cnid_dbd/dbd.h b/etc/cnid_dbd/dbd.h index bfa60954..7b8da1ca 100644 --- a/etc/cnid_dbd/dbd.h +++ b/etc/cnid_dbd/dbd.h @@ -14,8 +14,8 @@ extern int add_cnid(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply); extern int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply); -extern int dbd_add(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int nolookup); -extern int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int roflag); +extern int dbd_add(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *); +extern int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *); extern int dbd_get(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *); extern int dbd_resolve(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *); extern int dbd_update(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *); diff --git a/etc/cnid_dbd/dbd_add.c b/etc/cnid_dbd/dbd_add.c index 36c08568..e6e5e501 100644 --- a/etc/cnid_dbd/dbd_add.c +++ b/etc/cnid_dbd/dbd_add.c @@ -123,7 +123,7 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply) /* ------------------------ */ /* We need a nolookup version for `dbd` */ -int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int nolookup) +int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) { rply->namelen = 0; @@ -131,18 +131,16 @@ int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, in ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); /* See if we have an entry already and return it if yes */ - if (! nolookup) { - if (dbd_lookup(dbd, rqst, rply, 0) < 0) { - LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): error in dbd_lookup", - ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - return -1; - } + if (dbd_lookup(dbd, rqst, rply) < 0) { + LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): error in dbd_lookup", + ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); + return -1; + } - if (rply->result == CNID_DBD_RES_OK) { - /* Found it. rply->cnid is the correct CNID now. */ - LOG(log_debug, logtype_cnid, "dbd_add: dbd_lookup success --> CNID: %u", ntohl(rply->cnid)); - return 1; - } + if (rply->result == CNID_DBD_RES_OK) { + /* Found it. rply->cnid is the correct CNID now. */ + LOG(log_debug, logtype_cnid, "dbd_add: dbd_lookup success --> CNID: %u", ntohl(rply->cnid)); + return 1; } LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): {adding to database ...}", diff --git a/etc/cnid_dbd/dbd_lookup.c b/etc/cnid_dbd/dbd_lookup.c index 6169738b..0ab85f99 100644 --- a/etc/cnid_dbd/dbd_lookup.c +++ b/etc/cnid_dbd/dbd_lookup.c @@ -130,7 +130,7 @@ to be safe we must assign new CNIDs to both files. * up the database if there's a problem. */ -int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int roflag) +int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) { unsigned char *buf; DBT key, devdata, diddata; @@ -211,16 +211,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, LOG(log_debug, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): type mismatch for devino", rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - if (! roflag) { - rqst->cnid = id_devino; - rc = dbd_delete(dbd, rqst, rply, DBIF_CNID); - rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO); - rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME); - if (rc < 0) { - LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for devino", - rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - return -1; - } + rqst->cnid = id_devino; + rc = dbd_delete(dbd, rqst, rply, DBIF_CNID); + rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO); + rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME); + if (rc < 0) { + LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for devino", + rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); + return -1; } } @@ -230,16 +228,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, LOG(log_debug, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): type mismatch for didname", rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - if (! roflag) { - rqst->cnid = id_didname; - rc = dbd_delete(dbd, rqst, rply, DBIF_CNID); - rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO); - rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME); - if (rc < 0) { - LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for didname", - rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - return -1; - } + rqst->cnid = id_didname; + rc = dbd_delete(dbd, rqst, rply, DBIF_CNID); + rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DEVINO); + rc += dbd_delete(dbd, rqst, rply, DBIF_IDX_DIDNAME); + if (rc < 0) { + LOG(log_error, logtype_cnid, "dbd_lookup(name:'%s', did:%u, dev/ino:0x%llx/0x%llx): error deleting type mismatch for didname", + rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); + return -1; } } @@ -262,15 +258,14 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, ntohl(rqst->did), rqst->name, ntohl(id_didname), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino, ntohl(id_devino)); - if (! roflag) { - rqst->cnid = id_devino; - if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) - return -1; + rqst->cnid = id_devino; + if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) + return -1; + + rqst->cnid = id_didname; + if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) + return -1; - rqst->cnid = id_didname; - if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) - return -1; - } rply->result = CNID_DBD_RES_NOTFOUND; return 1; } @@ -282,11 +277,9 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, LOG(log_debug, logtype_cnid, "dbd_lookup: server side mv (with resource fork)"); update = 1; } else { - if ( ! roflag) { - rqst->cnid = id_devino; - if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) - return -1; - } + rqst->cnid = id_devino; + if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) + return -1; rply->result = CNID_DBD_RES_NOTFOUND; return 1; } @@ -295,17 +288,15 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, if ( ! devino) { LOG(log_debug, logtype_cnid, "dbd_lookup(DID:%u/'%s',0x%llx/0x%llx): CNID resolve problem: changed dev/ino", ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - if ( ! roflag) { - rqst->cnid = id_didname; - if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) - return -1; - } + rqst->cnid = id_didname; + if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) + return -1; rply->result = CNID_DBD_RES_NOTFOUND; return 1; } /* This is also a catch all if we've forgot to catch some possibility with the preceding ifs*/ - if (!update || roflag) { + if (!update) { rply->result = CNID_DBD_RES_NOTFOUND; return 1; } diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index df29d151..784ac422 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -145,7 +145,7 @@ static int loop(struct db_param *dbp) ret = 1; break; case CNID_DBD_OP_ADD: - ret = dbd_add(dbd, &rqst, &rply, 0); + ret = dbd_add(dbd, &rqst, &rply); break; case CNID_DBD_OP_GET: ret = dbd_get(dbd, &rqst, &rply); @@ -154,7 +154,7 @@ static int loop(struct db_param *dbp) ret = dbd_resolve(dbd, &rqst, &rply); break; case CNID_DBD_OP_LOOKUP: - ret = dbd_lookup(dbd, &rqst, &rply, 0); + ret = dbd_lookup(dbd, &rqst, &rply); break; case CNID_DBD_OP_UPDATE: ret = dbd_update(dbd, &rqst, &rply); From 4913dbbc5b69642dacbe7302fc25d25f47e9c00c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 7 Dec 2012 18:33:32 +0100 Subject: [PATCH 072/117] Rewrite dbd to use CNID IPC instead of opening the db directly In order to fix buf #447 (race condition between dbd and cnid_dbd) dbd must be converted to work over the network IPC channel with cnid_dbd instead of directly working on the BerkeleyDB CNID database. Add CNID db IPC command for wiping the db --- etc/cnid_dbd/cmd_dbd.c | 347 +++++++----------------- etc/cnid_dbd/cmd_dbd.h | 19 +- etc/cnid_dbd/cmd_dbd_scanvol.c | 433 +++++------------------------- etc/cnid_dbd/main.c | 93 +++++-- include/atalk/cnid.h | 2 + include/atalk/cnid_dbd_private.h | 1 + libatalk/cnid/cdb/cnid_cdb_open.c | 2 +- libatalk/cnid/cnid.c | 12 + libatalk/cnid/dbd/cnid_dbd.c | 53 +++- libatalk/cnid/dbd/cnid_dbd.h | 2 +- libatalk/cnid/last/cnid_last.c | 3 +- libatalk/cnid/tdb/cnid_tdb_open.c | 3 +- 12 files changed, 307 insertions(+), 663 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd.c b/etc/cnid_dbd/cmd_dbd.c index eb53af79..8a12bfad 100644 --- a/etc/cnid_dbd/cmd_dbd.c +++ b/etc/cnid_dbd/cmd_dbd.c @@ -27,65 +27,29 @@ #include #include -#include #include #include #include +#include #include "cmd_dbd.h" -#include "dbd.h" -#include "dbif.h" -#include "db_param.h" -#include "pack.h" -#define DBOPTIONS (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN) +enum dbd_cmd {dbd_scan, dbd_rebuild}; -int nocniddb = 0; /* Dont open CNID database, only scan filesystem */ +/* Global variables */ volatile sig_atomic_t alarmed; /* flags for signals */ -int db_locked; /* have we got the fcntl lock on lockfile ? */ - -static DBD *dbd; -static int verbose; /* Logging flag */ -static int exclusive; /* Exclusive volume access */ -static struct db_param db_param = { - NULL, /* Volume dirpath */ - 1, /* bdb logfile autoremove */ - 64 * 1024, /* bdb cachesize (64 MB) */ - DEFAULT_MAXLOCKS, /* maxlocks */ - DEFAULT_MAXLOCKOBJS, /* maxlockobjs */ - 0, /* flush_interval */ - 0, /* flush_frequency */ - 0, /* usock_file */ - -1, /* fd_table_size */ - -1, /* idle_timeout */ - -1 /* max_vols */ -}; -static char dbpath[MAXPATHLEN+1]; /* Path to the dbd database */ -/* - Provide some logging - */ -void dbd_log(enum logtype lt, char *fmt, ...) -{ - int len; - static char logbuffer[1024]; - va_list args; +/* Local variables */ +static dbd_flags_t flags; - if ( (lt == LOGSTD) || (verbose == 1)) { - va_start(args, fmt); - len = vsnprintf(logbuffer, 1023, fmt, args); - va_end(args); - logbuffer[1023] = 0; +/*************************************************************************** + * Local functions + ***************************************************************************/ - printf("%s\n", logbuffer); - } -} - -/* - SIGNAL handling: - catch SIGINT and SIGTERM which cause clean exit. Ignore anything else. +/* + * SIGNAL handling: + * catch SIGINT and SIGTERM which cause clean exit. Ignore anything else. */ - static void sig_handler(int signo) { alarmed = 1; @@ -128,99 +92,75 @@ static void set_signal(void) static void usage (void) { - printf("dbd (Netatalk %s)\n" - "Usage: dbd [-CeFtvx] -d [-i] | -s [-c|-n]| -r [-c|-f] | -u \n" - "dbd can dump, scan, reindex and rebuild Netatalk dbd CNID databases.\n" - "dbd must be run with appropiate permissions i.e. as root.\n\n" - "Main commands are:\n" - " -d Dump CNID database\n" - " Option: -i dump indexes too\n\n" + printf("Usage: dbd [-cfFstvV] \n" + "dbd scans or reindex Netatalk CNID databases of AFP volumes.\n" + "dbd must be run with appropiate permissions i.e. as root.\n" + "By default dbd rebuilds the CNID database of the volume.\n\n" + "Options:\n" " -s Scan volume:\n" - " Options: -c Don't check .AppleDouble stuff, only ckeck orphaned.\n" - " -n Don't open CNID database, skip CNID checks.\n\n" - " -r Rebuild volume:\n" - " Options: -c Don't create .AppleDouble stuff, only cleanup orphaned.\n" - " -f wipe database and rebuild from IDs stored in AppleDouble\n" - " metadata file or EA. Implies -e.\n\n" - " -u Upgrade:\n" - " Opens the database which triggers any necessary upgrades,\n" - " then closes and exits.\n\n" - "General options:\n" - " -C convert from adouble:v2 to adouble:ea (use with -r)\n" + " -c convert from adouble:v2 to adouble:ea (use with -r)\n" " -F location of the afp.conf config file\n" - " -e only work on inactive volumes and lock them (exclusive)\n" - " -x rebuild indexes (just for completeness, mostly useless!)\n" + " -f delete and recreate CNID database\n" " -t show statistics while running\n" - " -v verbose\n\n" - , VERSION + " -v verbose\n" + " -V show version info\n\n" ); } -int main(int argc, char **argv) +/*************************************************************************** + * Global functions + ***************************************************************************/ + +void dbd_log(enum logtype lt, char *fmt, ...) { - int c, lockfd, ret = -1; - int dump=0, scan=0, rebuild=0, prep_upgrade=0, rebuildindexes=0, dumpindexes=0, force=0; - dbd_flags_t flags = 0; - char *volpath; - int cdir; - AFPObj obj = { 0 }; - struct vol *vol; + int len; + static char logbuffer[1024]; + va_list args; - if (geteuid() != 0) { - usage(); - exit(EXIT_FAILURE); + if ( (lt == LOGSTD) || (flags & DBD_FLAGS_VERBOSE)) { + va_start(args, fmt); + len = vsnprintf(logbuffer, 1023, fmt, args); + va_end(args); + logbuffer[1023] = 0; + + printf("%s\n", logbuffer); } - /* Inhereting perms in ad_mkdir etc requires this */ - ad_setfuid(0); +} + +int main(int argc, char **argv) +{ + EC_INIT; + int dbd_cmd = dbd_rebuild; + int cdir = -1; + AFPObj obj = { 0 }; + struct vol *vol = NULL; + const char *volpath = NULL; - while ((c = getopt(argc, argv, ":cCdefFinrstuvx")) != -1) { + int c; + while ((c = getopt(argc, argv, ":cfF:stvV")) != -1) { switch(c) { case 'c': - flags |= DBD_FLAGS_CLEANUP; - break; - case 'C': flags |= DBD_FLAGS_V2TOEA; break; - case 'd': - dump = 1; + case 'f': + flags |= DBD_FLAGS_FORCE; break; - case 'i': - dumpindexes = 1; + case 'F': + obj.cmdlineconfigfile = strdup(optarg); break; case 's': - scan = 1; + dbd_cmd = dbd_scan; flags |= DBD_FLAGS_SCAN; break; - case 'n': - nocniddb = 1; /* FIXME: this could/should be a flag too for consistency */ - break; - case 'r': - rebuild = 1; - break; case 't': flags |= DBD_FLAGS_STATS; break; - case 'u': - prep_upgrade = 1; - break; case 'v': - verbose = 1; - break; - case 'e': - exclusive = 1; - flags |= DBD_FLAGS_EXCL; - break; - case 'x': - rebuildindexes = 1; - break; - case 'f': - force = 1; - exclusive = 1; - flags |= DBD_FLAGS_FORCE | DBD_FLAGS_EXCL; - break; - case 'F': - obj.cmdlineconfigfile = strdup(optarg); + flags |= DBD_FLAGS_VERBOSE; break; + case 'V': + printf("dbd %s\n", VERSION); + exit(0); case ':': case '?': usage(); @@ -229,16 +169,18 @@ int main(int argc, char **argv) } } - if ((dump + scan + rebuild + prep_upgrade) != 1) { + if ( (optind + 1) != argc ) { usage(); exit(EXIT_FAILURE); } + volpath = argv[optind]; - if ( (optind + 1) != argc ) { + if (geteuid() != 0) { usage(); exit(EXIT_FAILURE); } - volpath = argv[optind]; + /* Inhereting perms in ad_mkdir etc requires this */ + ad_setfuid(0); setvbuf(stdout, (char *) NULL, _IONBF, 0); @@ -257,11 +199,14 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + /* Initialize CNID subsystem */ + cnid_init(); + /* Setup logging. Should be portable among *NIXes */ - if (!verbose) - setuplog("default:info", "/dev/tty"); + if (flags & DBD_FLAGS_VERBOSE) + setuplog("default:note, cnid:debug", "/dev/tty"); else - setuplog("default:debug", "/dev/tty"); + setuplog("default:note", "/dev/tty"); if (load_volumes(&obj) != 0) { dbd_log( LOGSTD, "Couldn't load volumes"); @@ -278,7 +223,20 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - pack_setvol(vol); + /* open volume */ + if (STRCMP(vol->v_cnidscheme, != , "dbd")) { + dbd_log(LOGSTD, "\"%s\" isn't a \"dbd\" CNID volume", vol->v_path); + exit(EXIT_FAILURE); + } + if ((vol->v_cdb = cnid_open(vol->v_path, + 0000, + "dbd", + flags, + vol->v_cnidserver, + vol->v_cnidport)) == NULL) { + dbd_log(LOGSTD, "Cant initialize CNID database connection for %s", vol->v_path); + exit(EXIT_FAILURE); + } if (vol->v_adouble == AD_VERSION_EA) dbd_log( LOGDEBUG, "adouble:ea volume"); @@ -301,145 +259,28 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - /* Enuser dbpath is there, create if necessary */ - struct stat st; - if (stat(vol->v_dbpath, &st) != 0) { - if (errno != ENOENT) { - dbd_log( LOGSTD, "Can't stat dbpath \"%s\": %s", vol->v_dbpath, strerror(errno)); - exit(EXIT_FAILURE); - } - if ((mkdir(vol->v_dbpath, 0755)) != 0) { - dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", vol->v_dbpath, strerror(errno)); - exit(EXIT_FAILURE); - } - } - - /* Put "/.AppleDB" at end of volpath, get path from volinfo file */ - if ( (strlen(vol->v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) { - dbd_log( LOGSTD, "Volume pathname too long"); - exit(EXIT_FAILURE); - } - strncpy(dbpath, vol->v_dbpath, MAXPATHLEN - strlen("/.AppleDB")); - strcat(dbpath, "/.AppleDB"); - - /* Check or create dbpath */ - int dbdirfd = open(dbpath, O_RDONLY); - if (dbdirfd == -1 && errno == ENOENT) { - if (errno == ENOENT) { - if ((mkdir(dbpath, 0755)) != 0) { - dbd_log( LOGSTD, "Can't create .AppleDB for \"%s\": %s", dbpath, strerror(errno)); - exit(EXIT_FAILURE); - } - } else { - dbd_log( LOGSTD, "Somethings wrong with .AppleDB for \"%s\", giving up: %s", dbpath, strerror(errno)); - exit(EXIT_FAILURE); - } - } else { - close(dbdirfd); - } - - /* Get db lock */ - if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1) - goto exit_noenv; - if (db_locked != LOCK_EXCL) { - dbd_log(LOGDEBUG, "Database is in use, acquiring shared lock"); - /* Couldn't get exclusive lock, try shared lock if -e wasn't requested */ - if (exclusive) { - dbd_log(LOGSTD, "Database is in use and exlusive was requested"); - goto exit_noenv; - } - if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) - goto exit_noenv; - } - - /* Check if -f is requested and wipe db if yes */ - if ((flags & DBD_FLAGS_FORCE) && rebuild) { - char cmd[8 + MAXPATHLEN]; - if ((db_locked = get_lock(LOCK_FREE, NULL)) != 0) - goto exit_noenv; - - snprintf(cmd, 8 + MAXPATHLEN, "rm -rf \"%s\"", dbpath); - dbd_log( LOGDEBUG, "Removing old database of volume: '%s'", volpath); - system(cmd); - if ((mkdir(dbpath, 0755)) != 0) { - dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", dbpath, strerror(errno)); - exit(EXIT_FAILURE); - } - dbd_log( LOGDEBUG, "Removed old database."); - if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1) - goto exit_noenv; - } - - /* - Lets start with the BerkeleyDB stuff - */ - if ( ! nocniddb) { - if ((dbd = dbif_init(dbpath, "cnid2.db")) == NULL) - goto exit_noenv; - - if (dbif_env_open(dbd, - &db_param, - (db_locked == LOCK_EXCL) ? (DBOPTIONS | DB_RECOVER) : DBOPTIONS) < 0) { - dbd_log( LOGSTD, "error opening database!"); - goto exit_noenv; - } - - if (db_locked == LOCK_EXCL) - dbd_log( LOGDEBUG, "Finished recovery."); - - if (dbif_open(dbd, NULL, rebuildindexes) < 0) { - dbif_close(dbd); - goto exit_failure; - } - - /* Prepare upgrade ? We're done */ - if (prep_upgrade) { - (void)dbif_txn_close(dbd, 1); - goto cleanup; + if (flags & DBD_FLAGS_FORCE) { + if (cnid_wipe(vol->v_cdb) != 0) { + dbd_log( LOGSTD, "Failed to wipe CNID db"); + EC_FAIL; } } - /* Downgrade db lock if not running exclusive */ - if (!exclusive && (db_locked == LOCK_EXCL)) { - if (get_lock(LOCK_UNLOCK, NULL) != 0) - goto exit_failure; - if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) - goto exit_failure; - } - /* Now execute given command scan|rebuild|dump */ - if (dump && ! nocniddb) { - if (dbif_dump(dbd, dumpindexes) < 0) { - dbd_log( LOGSTD, "Error dumping database"); - } - } else if ((rebuild && ! nocniddb) || scan) { - if (cmd_dbd_scanvol(dbd, vol, flags) < 0) { + switch (dbd_cmd) { + case dbd_scan: + case dbd_rebuild: + if (cmd_dbd_scanvol(vol, flags) < 0) { dbd_log( LOGSTD, "Error repairing database."); } + break; } -cleanup: - /* Cleanup */ - dbd_log(LOGDEBUG, "Closing db"); - if (! nocniddb) { - if (dbif_close(dbd) < 0) { - dbd_log( LOGSTD, "Error closing database"); - goto exit_failure; - } - } - -exit_success: - ret = 0; - -exit_failure: - if (dbif_env_remove(dbpath) < 0) { - dbd_log( LOGSTD, "Error removing BerkeleyDB database environment"); - ret++; - } - get_lock(0, NULL); +EC_CLEANUP: + if (vol) + cnid_close(vol->v_cdb); -exit_noenv: - if ((fchdir(cdir)) < 0) + if (cdir != -1 && (fchdir(cdir) < 0)) dbd_log(LOGSTD, "fchdir: %s", strerror(errno)); if (ret == 0) diff --git a/etc/cnid_dbd/cmd_dbd.h b/etc/cnid_dbd/cmd_dbd.h index efec636b..9fcb3f4e 100644 --- a/etc/cnid_dbd/cmd_dbd.h +++ b/etc/cnid_dbd/cmd_dbd.h @@ -12,29 +12,18 @@ typedef unsigned int dbd_flags_t; #define DBD_FLAGS_SCAN (1 << 0) #define DBD_FLAGS_FORCE (1 << 1) -#define DBD_FLAGS_EXCL (1 << 2) -#define DBD_FLAGS_CLEANUP (1 << 3) /* Dont create AD stuff, but cleanup orphaned */ -#define DBD_FLAGS_STATS (1 << 4) -#define DBD_FLAGS_V2TOEA (1 << 5) /* Convert adouble:v2 to adouble:ea */ +#define DBD_FLAGS_STATS (1 << 2) +#define DBD_FLAGS_V2TOEA (1 << 3) /* Convert adouble:v2 to adouble:ea */ +#define DBD_FLAGS_VERBOSE (1 << 4) #define ADv2_DIRNAME ".AppleDouble" #define DIR_DOT_OR_DOTDOT(a) \ ((strcmp(a, ".") == 0) || (strcmp(a, "..") == 0)) -#define STRCMP(a,b,c) \ - (strcmp(a,c) b 0) - -extern int nocniddb; /* Dont open CNID database, only scan filesystem */ -extern int db_locked; /* have we got the fcntl lock on lockfd ? */ extern volatile sig_atomic_t alarmed; extern void dbd_log(enum logtype lt, char *fmt, ...); -extern int cmd_dbd_scanvol(DBD *dbd, struct vol *vol, dbd_flags_t flags); +extern int cmd_dbd_scanvol(struct vol *vol, dbd_flags_t flags); -/* - Functions for querying the database which couldn't be reused from the existing - funcs pool of dbd_* for one reason or another -*/ -extern int cmd_dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply); #endif /* CMD_DBD_H */ diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index dcbd4c74..37012f27 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -29,12 +29,13 @@ #include #include #include -#include +//#include #include #include #include #include #include +#include #include "cmd_dbd.h" #include "dbif.h" @@ -48,7 +49,7 @@ static struct vol *myvol; static char cwdbuf[MAXPATHLEN+1]; -static DBD *dbd; +static struct vol *vol; static DBD *dbd_rebuild; static dbd_flags_t dbd_flags; static char stamp[CNID_DEV_LEN]; @@ -65,6 +66,7 @@ static struct cnid_dbd_rqst rqst; static struct cnid_dbd_rply rply; static jmp_buf jmp; static char pname[MAXPATHLEN] = "../"; +static char cnidResBuf[12 + MAXPATHLEN + 1]; /* Taken form afpd/desktop.c @@ -189,43 +191,13 @@ static int update_cnid(cnid_t did, const struct stat *sp, const char *oldname, c int ret; cnid_t id; - /* Prepare request data */ - memset(&rqst, 0, sizeof(struct cnid_dbd_rqst)); - memset(&rply, 0, sizeof(struct cnid_dbd_rply)); - rqst.did = did; - rqst.cnid = 0; - if ( ! (myvol->v_flags & AFPVOL_NODEV)) - rqst.dev = sp->st_dev; - rqst.ino = sp->st_ino; - rqst.type = S_ISDIR(sp->st_mode) ? 1 : 0; - rqst.name = (char *)oldname; - rqst.namelen = strlen(oldname); - /* Query the database */ - ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0); - if (dbif_txn_close(dbd, ret) != 0) - return -1; - if (rply.result != CNID_DBD_RES_OK) + if ((id = cnid_lookup(vol->v_cdb, sp, did, (char *)oldname, strlen(oldname))) == CNID_INVALID) + /* not in db, no need to update */ return 0; - id = rply.cnid; - - /* Prepare request data */ - memset(&rqst, 0, sizeof(struct cnid_dbd_rqst)); - memset(&rply, 0, sizeof(struct cnid_dbd_rply)); - rqst.did = did; - rqst.cnid = id; - if ( ! (myvol->v_flags & AFPVOL_NODEV)) - rqst.dev = sp->st_dev; - rqst.ino = sp->st_ino; - rqst.type = S_ISDIR(sp->st_mode) ? 1 : 0; - rqst.name = (char *)newname; - rqst.namelen = strlen(newname); /* Update the database */ - ret = dbd_update(dbd, &rqst, &rply); - if (dbif_txn_close(dbd, ret) != 0) - return -1; - if (rply.result != CNID_DBD_RES_OK) + if (cnid_update(vol->v_cdb, id, sp, did, (char *)newname, strlen(newname)) < 0) return -1; return 0; @@ -258,9 +230,6 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n return 0; } - if (dbd_flags & DBD_FLAGS_CLEANUP) - return 0; - if (S_ISDIR(st->st_mode)) adflags |= ADFLAGS_DIR; @@ -422,9 +391,6 @@ static int check_addir(int volroot) struct adouble ad; char *mname = NULL; - if (dbd_flags & DBD_FLAGS_CLEANUP) - return 0; - if (myvol->v_adouble == AD_VERSION_EA) return 0; @@ -644,31 +610,17 @@ static int read_addir(void) static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok) { int ret, adflags = ADFLAGS_HF; - cnid_t db_cnid, ad_cnid; + cnid_t db_cnid, ad_cnid, tmpid; struct adouble ad; adflags = ADFLAGS_HF | (S_ISDIR(st->st_mode) ? ADFLAGS_DIR : 0); - /* Force checkout every X items */ - static int cnidcount = 0; - cnidcount++; - if (cnidcount > 10000) { - cnidcount = 0; - if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) { - dbd_log(LOGSTD, "Error checkpointing!"); - return CNID_INVALID; - } - } - /* Get CNID from ad-file */ - ad_cnid = 0; + ad_cnid = CNID_INVALID; if (ADFILE_OK) { ad_init(&ad, myvol); if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) { - if (dbd_flags & DBD_FLAGS_CLEANUP) - return CNID_INVALID; - if (myvol->v_adouble != AD_VERSION_EA) { dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); return CNID_INVALID; @@ -676,7 +628,6 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi dbd_log( LOGDEBUG, "File without meta EA: \"%s/%s\"", cwdbuf, name); adfile_ok = 1; } else { - if (dbd_flags & DBD_FLAGS_FORCE) { ad_cnid = ad_forcegetid(&ad); /* This ensures the changed stamp is written */ @@ -694,128 +645,26 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi } /* Get CNID from database */ - - /* Prepare request data */ - memset(&rqst, 0, sizeof(struct cnid_dbd_rqst)); - memset(&rply, 0, sizeof(struct cnid_dbd_rply)); - rqst.did = did; - rqst.cnid = ad_cnid; - if ( ! (myvol->v_flags & AFPVOL_NODEV)) - rqst.dev = st->st_dev; - rqst.ino = st->st_ino; - rqst.type = S_ISDIR(st->st_mode)?1:0; - rqst.name = (char *)name; - rqst.namelen = strlen(name); - - /* Query the database */ - ret = dbd_lookup(dbd, &rqst, &rply, (dbd_flags & DBD_FLAGS_SCAN) ? 1 : 0); - if (dbif_txn_close(dbd, ret) != 0) + if ((db_cnid = cnid_add(vol->v_cdb, st, did, (char *)name, strlen(name), ad_cnid)) == CNID_INVALID) return CNID_INVALID; - if (rply.result == CNID_DBD_RES_OK) { - db_cnid = rply.cnid; - } else if (rply.result == CNID_DBD_RES_NOTFOUND) { - if ( ! (dbd_flags & DBD_FLAGS_FORCE)) - dbd_log( LOGSTD, "No CNID for '%s/%s' in database", cwdbuf, name); - db_cnid = 0; - } else { - dbd_log( LOGSTD, "Fatal error resolving '%s/%s'", cwdbuf, name); - db_cnid = 0; - } - /* Compare results from both CNID searches */ - if (ad_cnid && db_cnid && (ad_cnid == db_cnid)) { - /* Everything is fine */ - return db_cnid; - } else if (ad_cnid && db_cnid && (ad_cnid != db_cnid)) { + /* Compare CNID from db and adouble file */ + if (ad_cnid != db_cnid && adfile_ok == 0) { /* Mismatch, overwrite ad file with value from db */ - dbd_log( LOGSTD, "CNID mismatch for '%s/%s', db: %u, ad-file: %u", cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid)); - if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - dbd_log(LOGSTD, "Updating AppleDouble file for '%s/%s' with CNID: %u from database", - cwdbuf, name, ntohl(db_cnid)); - ad_init(&ad, myvol); - if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) { - dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", - cwdbuf, name, strerror(errno)); - return CNID_INVALID; - } - ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); - ad_flush(&ad); - ad_close(&ad, ADFLAGS_HF); - } - return db_cnid; - } else if (ad_cnid && (db_cnid == 0)) { - /* in ad-file but not in db */ - if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - /* Ensure the cnid from the ad-file is not already occupied by another file */ - dbd_log(LOGDEBUG, "Checking whether CNID %u from ad-file is occupied", - ntohl(ad_cnid)); - - rqst.cnid = ad_cnid; - ret = dbd_resolve(dbd, &rqst, &rply); - if (rply.result == CNID_DBD_RES_OK) { - /* Occupied! Choose another, update ad-file */ - ret = dbd_add(dbd, &rqst, &rply, 1); - if (dbif_txn_close(dbd, ret) != 0) - return CNID_INVALID; - db_cnid = rply.cnid; - dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid)); - - if (ADFILE_OK && ( ! (dbd_flags & DBD_FLAGS_SCAN))) { - dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file", - cwdbuf, name, ntohl(db_cnid)); - ad_init(&ad, myvol); - if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) { - dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", - cwdbuf, name, strerror(errno)); - return CNID_INVALID; - } - ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); - ad_flush(&ad); - ad_close(&ad, ADFLAGS_HF); - } - return db_cnid; - } - - dbd_log(LOGDEBUG, "CNID rebuild add '%s/%s' with CNID from ad-file %u", - cwdbuf, name, ntohl(ad_cnid)); - rqst.cnid = ad_cnid; - ret = dbd_rebuild_add(dbd, &rqst, &rply); - if (dbif_txn_close(dbd, ret) != 0) - return CNID_INVALID; - } - return ad_cnid; - } else if ((db_cnid == 0) && (ad_cnid == 0)) { - /* No CNID at all, we clearly have to allocate a fresh one... */ - /* Note: the next test will use this new CNID too! */ - if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - /* add to db */ - ret = dbd_add(dbd, &rqst, &rply, 1); - if (dbif_txn_close(dbd, ret) != 0) - return CNID_INVALID; - db_cnid = rply.cnid; - dbd_log(LOGSTD, "New CNID for '%s/%s': %u", cwdbuf, name, ntohl(db_cnid)); - } - } - - if ((ad_cnid == 0) && db_cnid) { - /* in db but zeroID in ad-file, write it to ad-file */ - if (ADFILE_OK && ! (dbd_flags & DBD_FLAGS_SCAN)) { - dbd_log(LOGSTD, "Writing CNID data for '%s/%s' to AppleDouble file", - cwdbuf, name, ntohl(db_cnid)); - ad_init(&ad, myvol); - if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) { - dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", - cwdbuf, name, strerror(errno)); - return CNID_INVALID; - } - ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); - ad_flush(&ad); - ad_close(&ad, ADFLAGS_HF); + dbd_log(LOGSTD, "CNID mismatch for '%s/%s', CNID db: %u, ad-file: %u", + cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid)); + ad_init(&ad, myvol); + if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) { + dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", + cwdbuf, name, strerror(errno)); + return CNID_INVALID; } - return db_cnid; + ad_setid( &ad, st->st_dev, st->st_ino, db_cnid, did, stamp); + ad_flush(&ad); + ad_close(&ad, ADFLAGS_HF); } - return CNID_INVALID; + return db_cnid; } /* @@ -939,30 +788,28 @@ static int dbd_readdir(int volroot, cnid_t did) update_cnid(did, &st, ep->d_name, name); } - if ( ! nocniddb) { - /* Check CNIDs */ - cnid = check_cnid(name, did, &st, adfile_ok); + /* Check CNIDs */ + cnid = check_cnid(name, did, &st, adfile_ok); - /* Now add this object to our rebuild dbd */ - if (cnid && dbd_rebuild) { - static uint count = 0; - rqst.cnid = rply.cnid; - ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply); - if (dbif_txn_close(dbd_rebuild, ret) != 0) - return -1; - if (rply.result != CNID_DBD_RES_OK) { - dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db", - cnid, cwdbuf, name); + /* Now add this object to our rebuild dbd */ + if (cnid && dbd_rebuild) { + static uint count = 0; + rqst.cnid = rply.cnid; + ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply); + if (dbif_txn_close(dbd_rebuild, ret) != 0) + return -1; + if (rply.result != CNID_DBD_RES_OK) { + dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db", + cnid, cwdbuf, name); + return -1; + } + count++; + if (count == 10000) { + if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) { + dbd_log(LOGSTD, "Error checkpointing!"); return -1; } - count++; - if (count == 10000) { - if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) { - dbd_log(LOGSTD, "Error checkpointing!"); - return -1; - } - count = 0; - } + count = 0; } } @@ -973,7 +820,7 @@ static int dbd_readdir(int volroot, cnid_t did) /************************************************************************** Recursion **************************************************************************/ - if (S_ISDIR(st.st_mode) && (cnid || nocniddb)) { /* If we have no cnid for it we cant recur */ + if (S_ISDIR(st.st_mode) && cnid) { /* If we have no cnid for it we cant enter recursion */ strcat(cwdbuf, "/"); strcat(cwdbuf, name); dbd_log( LOGDEBUG, "Entering directory: %s", cwdbuf); @@ -1050,174 +897,39 @@ static int scanvol(struct vol *vol, dbd_flags_t flags) return 0; } -/* - Remove all CNIDs from dbd that are not in dbd_rebuild -*/ -static void delete_orphaned_cnids(DBD *dbd, DBD *dbd_rebuild, dbd_flags_t flags) -{ - int ret = 0, deleted = 0; - cnid_t dbd_cnid = 0, rebuild_cnid = 0; - struct cnid_dbd_rqst rqst; - struct cnid_dbd_rply rply; - - /* jump over rootinfo key */ - if ( dbif_idwalk(dbd, &dbd_cnid, 0) != 1) - return; - if ( dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0) != 1) - return; - - /* Get first id from dbd_rebuild */ - if ((dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1) - return; - - /* Start main loop through dbd: get CNID from dbd */ - while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) { - /* Check if we got a termination signal */ - if (alarmed) - longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */ - - if (deleted > 1000) { - deleted = 0; - if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0) { - dbd_log(LOGSTD, "Error checkpointing!"); - goto cleanup; - } - } - - /* This should be the normal case: CNID is in both dbs */ - if (dbd_cnid == rebuild_cnid) { - /* Get next CNID from rebuild db */ - if ((ret = dbif_idwalk(dbd_rebuild, &rebuild_cnid, 0)) == -1) { - /* Some error */ - goto cleanup; - } else if (ret == 0) { - /* end of rebuild_cnid, delete all remaining CNIDs from dbd */ - while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) { - dbd_log(LOGSTD, "Orphaned CNID in database: %u", dbd_cnid); - if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - rqst.cnid = htonl(dbd_cnid); - if ((ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID)) == -1) { - dbd_log(LOGSTD, "Error deleting CNID %u", dbd_cnid); - (void)dbif_txn_abort(dbd); - goto cleanup; - } - - if (dbif_txn_close(dbd, ret) != 0) - return; - deleted++; - } - /* Check if we got a termination signal */ - if (alarmed) - longjmp(jmp, 1); /* this jumps back to cmd_dbd_scanvol() */ - } - return; - } else - /* Normal case (ret=1): continue while loop */ - continue; - } - - if (dbd_cnid < rebuild_cnid) { - /* CNID is orphaned -> delete */ - dbd_log(LOGSTD, "One orphaned CNID in database: %u.", dbd_cnid); - if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { - rqst.cnid = htonl(dbd_cnid); - if ((ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID)) == -1) { - dbd_log(LOGSTD, "Error deleting CNID %u", dbd_cnid); - (void)dbif_txn_abort(dbd); - goto cleanup; - } - if (dbif_txn_close(dbd, ret) != 0) - return; - deleted++; - } - continue; - } - - if (dbd_cnid > rebuild_cnid) { - dbif_idwalk(dbd, NULL, 1); /* Close cursor */ - dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */ - (void)dbif_txn_close(dbd, 2); - (void)dbif_txn_close(dbd_rebuild, 2); - dbd_log(LOGSTD, "Ghost CNID: %u. This is fatal! Dumping rebuild db:\n", rebuild_cnid); - dbif_dump(dbd_rebuild, 0); - dbd_log(LOGSTD, "Send this dump and a `dbd -d ...` dump to the Netatalk Dev team!"); - goto cleanup; - } - } /* while ((dbif_idwalk(dbd, &dbd_cnid, 0)) == 1) */ - -cleanup: - dbif_idwalk(dbd, NULL, 1); /* Close cursor */ - dbif_idwalk(dbd_rebuild, NULL, 1); /* Close cursor */ - return; -} - -static const char *get_tmpdb_path(void) -{ - pid_t pid = getpid(); - static char path[MAXPATHLEN]; - snprintf(path, MAXPATHLEN, "/tmp/tmpdb-dbd.%u", pid); - if (mkdir(path, 0755) != 0) - return NULL; - return path; -} - /* Main func called from cmd_dbd.c */ -int cmd_dbd_scanvol(DBD *dbd_ref, struct vol *vol, dbd_flags_t flags) +int cmd_dbd_scanvol(struct vol *vol_in, dbd_flags_t flags) { int ret = 0; - struct db_param db_param = { 0 }; - const char *tmpdb_path = NULL; - - /* Set cachesize for in-memory rebuild db */ - db_param.cachesize = 64 * 1024; /* 64 MB */ - db_param.maxlocks = DEFAULT_MAXLOCKS; - db_param.maxlockobjs = DEFAULT_MAXLOCKOBJS; - db_param.logfile_autoremove = 1; - /* Make it accessible for all funcs */ - dbd = dbd_ref; + /* Make vol accessible for all funcs */ + vol = vol_in; /* We only support unicode volumes ! */ if (vol->v_volcharset != CH_UTF8) { - dbd_log( LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8); + dbd_log(LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8); return -1; } - /* Get volume stamp */ - dbd_getstamp(dbd, &rqst, &rply); - if (rply.result != CNID_DBD_RES_OK) { - ret = -1; + /* + * Get CNID database stamp, cnid_getstamp() passes the buffer, + * then cnid_resolve() actually gets the value from the db + */ + cnid_getstamp(vol->v_cdb, stamp, sizeof(stamp)); + cnid_t rootid = 0; + if (cnid_resolve(vol->v_cdb, &rootid, cnidResBuf, sizeof(cnidResBuf)) == NULL) { + dbd_log(LOGSTD, "error resolving rootinfo key"); goto exit; } - memcpy(stamp, rply.name, CNID_DEV_LEN); - - /* temporary rebuild db, used with -re rebuild to delete unused CNIDs, not used with -f */ - if (! nocniddb && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE)) { - tmpdb_path = get_tmpdb_path(); - if (NULL == (dbd_rebuild = dbif_init(tmpdb_path, "cnid2.db"))) { - ret = -1; - goto exit; - } - - if (dbif_env_open(dbd_rebuild, - &db_param, - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN) < 0) { - dbd_log(LOGSTD, "error opening tmp database!"); - goto exit; - } - - if (0 != (dbif_open(dbd_rebuild, NULL, 0))) { - ret = -1; - goto exit; - } - if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) { - ret = -1; - goto exit; - } +#if 0 + if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) { + ret = -1; + goto exit; } +#endif if (setjmp(jmp) != 0) { ret = 0; /* Got signal, jump from dbd_readdir */ @@ -1231,30 +943,5 @@ int cmd_dbd_scanvol(DBD *dbd_ref, struct vol *vol, dbd_flags_t flags) } exit: - if (! nocniddb) { - if (dbif_txn_close(dbd, ret == 0 ? 1 : 0) != 0) - ret = -1; - if (dbd_rebuild) - if (dbif_txn_close(dbd_rebuild, ret == 0 ? 1 : 0) != 0) - ret = -1; - if ((ret == 0) && dbd_rebuild && (flags & DBD_FLAGS_EXCL) && !(flags & DBD_FLAGS_FORCE)) - /* We can only do this in exclusive mode, otherwise we might delete CNIDs added from - other clients in between our pass 1 and 2 */ - delete_orphaned_cnids(dbd, dbd_rebuild, flags); - } - - if (dbd_rebuild) { - dbd_log(LOGDEBUG, "Closing tmp db"); - dbif_close(dbd_rebuild); - - if (tmpdb_path) { - char cmd[8 + MAXPATHLEN]; - snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/*", tmpdb_path); - dbd_log( LOGDEBUG, "Removing temp database '%s'", tmpdb_path); - system(cmd); - snprintf(cmd, 8 + MAXPATHLEN, "rmdir %s", tmpdb_path); - system(cmd); - } - } return ret; } diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index 784ac422..e2a24d48 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -43,6 +43,8 @@ static DBD *dbd; static int exit_sig = 0; static int db_locked; +static bstring dbpath; +static struct db_param *dbp; static void sig_exit(int signo) { @@ -81,6 +83,74 @@ static void block_sigs_onoff(int block) #define min(a,b) ((a)<(b)?(a):(b)) #endif +static int delete_db(void) +{ + EC_INIT; + int cwd = -1; + + EC_NEG1( cwd = open(".", O_RDONLY) ); + + chdir(bdata(dbpath)); + system("rm -f cnid2.db lock log.* __db.*"); + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { + LOG(log_error, logtype_cnid, "main: fatal db lock error"); + EC_FAIL; + } + +EC_CLEANUP: + if (cwd != -1) + fchdir(cwd); + EC_EXIT; +} + +static int wipe_db(void) +{ + EC_INIT; + DBT key, data; + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + key.data = ROOTINFO_KEY; + key.size = ROOTINFO_KEYLEN; + + if (dbif_get(dbd, DBIF_CNID, &key, &data, 0) <= 0) { + LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error getting rootinfo record"); + EC_FAIL; + } + + EC_NEG1_LOG( dbif_close(dbd) ); + EC_NEG1_LOG( dbif_env_remove(bdata(dbpath)) ); + EC_ZERO_LOG( delete_db() ); + + /* Get db lock */ + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { + LOG(log_error, logtype_cnid, "main: fatal db lock error"); + EC_FAIL; + } + + EC_NULL_LOG( dbd = dbif_init(bdata(dbpath), "cnid2.db") ); + + /* Only recover if we got the lock */ + EC_NEG1_LOG( dbif_env_open(dbd, dbp, DBOPTIONS | DB_RECOVER) ); + + LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment"); + + EC_NEG1_LOG( dbif_open(dbd, dbp, 0) ); + + memset(&key, 0, sizeof(key)); + key.data = ROOTINFO_KEY; + key.size = ROOTINFO_KEYLEN; + + if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) != 0) { + LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error writing rootinfo key"); + EC_FAIL; + } + +EC_CLEANUP: + EC_EXIT; +} + static int loop(struct db_param *dbp) { struct cnid_dbd_rqst rqst; @@ -171,6 +241,9 @@ static int loop(struct db_param *dbp) case CNID_DBD_OP_SEARCH: ret = dbd_search(dbd, &rqst, &rply); break; + case CNID_DBD_OP_WIPE: + ret = wipe_db(); + break; default: LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op); ret = -1; @@ -274,14 +347,12 @@ static void set_signal(void) int main(int argc, char *argv[]) { EC_INIT; - struct db_param *dbp; int delete_bdb = 0; int ctrlfd = -1, clntfd = -1; char *logconfig; AFPObj obj = { 0 }; struct vol *vol; char *volpath = NULL; - bstring dbpath; while (( ret = getopt( argc, argv, "dF:l:p:t:vV")) != -1 ) { switch (ret) { @@ -327,26 +398,14 @@ int main(int argc, char *argv[]) switch_to_user(bdata(dbpath)); /* Get db lock */ - if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) == -1) { + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { LOG(log_error, logtype_cnid, "main: fatal db lock error"); EC_FAIL; } - if (db_locked != LOCK_EXCL) { - /* Couldn't get exclusive lock, try shared lock */ - if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD) { - LOG(log_error, logtype_cnid, "main: fatal db lock error"); - EC_FAIL; - } - } - if (delete_bdb && (db_locked == LOCK_EXCL)) { + if (delete_bdb) { LOG(log_warning, logtype_cnid, "main: too many CNID db opening attempts, wiping the slate clean"); - chdir(bdata(dbpath)); - system("rm -f cnid2.db lock log.* __db.*"); - if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { - LOG(log_error, logtype_cnid, "main: fatal db lock error"); - EC_FAIL; - } + EC_ZERO( delete_db() ); } set_signal(); diff --git a/include/atalk/cnid.h b/include/atalk/cnid.h index 2d3aa062..ba0b62fa 100644 --- a/include/atalk/cnid.h +++ b/include/atalk/cnid.h @@ -69,6 +69,7 @@ struct _cnid_db { const char *, size_t, cnid_t); int (*cnid_find) (struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen); + int (*cnid_wipe) (struct _cnid_db *cdb); }; typedef struct _cnid_db cnid_db; @@ -123,6 +124,7 @@ cnid_t cnid_rebuild_add(struct _cnid_db *cdb, const struct stat *st, const cnid_ char *name, const size_t len, cnid_t hint); int cnid_find (struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen); +int cnid_wipe (struct _cnid_db *cdb); void cnid_close (struct _cnid_db *db); #endif diff --git a/include/atalk/cnid_dbd_private.h b/include/atalk/cnid_dbd_private.h index d7484e42..b61f7a8c 100644 --- a/include/atalk/cnid_dbd_private.h +++ b/include/atalk/cnid_dbd_private.h @@ -25,6 +25,7 @@ #define CNID_DBD_OP_GETSTAMP 0x0b #define CNID_DBD_OP_REBUILD_ADD 0x0c #define CNID_DBD_OP_SEARCH 0x0d +#define CNID_DBD_OP_WIPE 0x0e #define CNID_DBD_RES_OK 0x00 #define CNID_DBD_RES_NOTFOUND 0x01 diff --git a/libatalk/cnid/cdb/cnid_cdb_open.c b/libatalk/cnid/cdb/cnid_cdb_open.c index 056420da..757d1b0d 100644 --- a/libatalk/cnid/cdb/cnid_cdb_open.c +++ b/libatalk/cnid/cdb/cnid_cdb_open.c @@ -144,7 +144,7 @@ static struct _cnid_db *cnid_cdb_new(const char *volpath) cdb->cnid_close = cnid_cdb_close; cdb->cnid_getstamp = cnid_cdb_getstamp; cdb->cnid_rebuild_add = cnid_cdb_rebuild_add; - + cdb->cnid_wipe = NULL; return cdb; } diff --git a/libatalk/cnid/cnid.c b/libatalk/cnid/cnid.c index 0a977e6a..7cf3af16 100644 --- a/libatalk/cnid/cnid.c +++ b/libatalk/cnid/cnid.c @@ -338,3 +338,15 @@ cnid_t ret; unblock_signal(cdb->flags); return ret; } + +/* --------------- */ +int cnid_wipe(struct _cnid_db *cdb) +{ + int ret = 0; + + block_signal(cdb->flags); + if (cdb->cnid_wipe) + ret = cdb->cnid_wipe(cdb); + unblock_signal(cdb->flags); + return ret; +} diff --git a/libatalk/cnid/dbd/cnid_dbd.c b/libatalk/cnid/dbd/cnid_dbd.c index 32be8f47..b654740a 100644 --- a/libatalk/cnid/dbd/cnid_dbd.c +++ b/libatalk/cnid/dbd/cnid_dbd.c @@ -456,7 +456,7 @@ static struct _cnid_db *cnid_dbd_new(const char *volpath) 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; } @@ -994,6 +994,57 @@ int cnid_dbd_delete(struct _cnid_db *cdb, const cnid_t id) } } +int cnid_dbd_wipe(struct _cnid_db *cdb) +{ + CNID_private *db; + struct cnid_dbd_rqst rqst; + struct cnid_dbd_rply rply; + + if (!cdb || !(db = cdb->_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"); + + 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 (dbd_rpc(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; +} + struct _cnid_module cnid_dbd_module = { "dbd", diff --git a/libatalk/cnid/dbd/cnid_dbd.h b/libatalk/cnid/dbd/cnid_dbd.h index fdba4c04..69ff5a64 100644 --- a/libatalk/cnid/dbd/cnid_dbd.h +++ b/libatalk/cnid/dbd/cnid_dbd.h @@ -32,7 +32,7 @@ extern int cnid_dbd_update (struct _cnid_db *, cnid_t, const struct stat extern int cnid_dbd_delete (struct _cnid_db *, const cnid_t); extern cnid_t cnid_dbd_rebuild_add(struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t); - +extern int cnid_dbd_wipe (struct _cnid_db *cdb); /* FIXME: These functions could be static in cnid_dbd.c */ #endif /* include/atalk/cnid_dbd.h */ diff --git a/libatalk/cnid/last/cnid_last.c b/libatalk/cnid/last/cnid_last.c index 5903d03f..fd92cc5a 100644 --- a/libatalk/cnid/last/cnid_last.c +++ b/libatalk/cnid/last/cnid_last.c @@ -139,7 +139,8 @@ static struct _cnid_db *cnid_last_new(const char *volpath) cdb->cnid_resolve = cnid_last_resolve; cdb->cnid_update = cnid_last_update; cdb->cnid_close = cnid_last_close; - + cdb->cnid_wipe = NULL; + return cdb; } diff --git a/libatalk/cnid/tdb/cnid_tdb_open.c b/libatalk/cnid/tdb/cnid_tdb_open.c index d02ef0bc..889cea1e 100644 --- a/libatalk/cnid/tdb/cnid_tdb_open.c +++ b/libatalk/cnid/tdb/cnid_tdb_open.c @@ -56,7 +56,8 @@ static struct _cnid_db *cnid_tdb_new(const char *volpath) cdb->cnid_resolve = cnid_tdb_resolve; cdb->cnid_update = cnid_tdb_update; cdb->cnid_close = cnid_tdb_close; - + cdb->cnid_wipe = NULL; + return cdb; } From 7254571ea7fec6db8febb344018e8c4e8ea345e8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 Dec 2012 14:55:41 +0100 Subject: [PATCH 073/117] Ignore db stamp when reading CNID from adouble file The db stamp (which is the ctime of the cnid2.db file stored in the db at creation time) may change when running `dbd -f` or when deleting the CNID db manually. But we don't want to reassing CNIDs in this case (changed stamp) we really want to keep it. --- libatalk/adouble/ad_attr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libatalk/adouble/ad_attr.c b/libatalk/adouble/ad_attr.c index e5fe323f..43d798bb 100644 --- a/libatalk/adouble/ad_attr.c +++ b/libatalk/adouble/ad_attr.c @@ -117,25 +117,22 @@ int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint } /* ----------------------------- */ -uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp) +uint32_t ad_getid (struct adouble *adp, const dev_t st_dev, const ino_t st_ino , const cnid_t did, const void *stamp _U_) { uint32_t aint = 0; dev_t dev; ino_t ino; cnid_t a_did; - char temp[ADEDLEN_PRIVSYN]; if (adp) { if (sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)) { memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t)); memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t)); - memcpy(temp, ad_entry(adp, ADEID_PRIVSYN), sizeof(temp)); memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t)); if (((adp->ad_options & ADVOL_NODEV) || (dev == st_dev)) && ino == st_ino - && (!did || a_did == did) - && (memcmp(stamp, temp, sizeof(temp)) == 0) ) { + && (!did || a_did == did) ) { memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint)); if (adp->ad_vers == AD_VERSION2) return aint; From 06c0bfaea7c9db5d404813efd23bf06c49c2bc4f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 Dec 2012 15:04:24 +0100 Subject: [PATCH 074/117] Use ad_getid() instead of ad_forcegetid() ad_getid() now ignores the db stamp when reading the CNID, so we can simply use it instead of using ad_forcegetid(). --- etc/cnid_dbd/cmd_dbd_scanvol.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 37012f27..68300b6c 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -628,15 +628,8 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi dbd_log( LOGDEBUG, "File without meta EA: \"%s/%s\"", cwdbuf, name); adfile_ok = 1; } else { - if (dbd_flags & DBD_FLAGS_FORCE) { - ad_cnid = ad_forcegetid(&ad); - /* This ensures the changed stamp is written */ - ad_setid( &ad, st->st_dev, st->st_ino, ad_cnid, did, stamp); - ad_flush(&ad); - } else - ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, 0, stamp); - - if (ad_cnid == 0) + ad_cnid = ad_getid(&ad, st->st_dev, st->st_ino, 0, stamp); + if (ad_cnid == CNID_INVALID) dbd_log( LOGSTD, "Bad CNID in adouble file of '%s/%s'", cwdbuf, name); else dbd_log( LOGDEBUG, "CNID from .AppleDouble file for '%s/%s': %u", cwdbuf, name, ntohl(ad_cnid)); From 83416b7b2b6651e76ad20960822249dceb55644a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 10 Dec 2012 18:38:07 +0100 Subject: [PATCH 075/117] Restructure opening and deleting the CNID dbs and CNID wraparound support If opening the db fails, delete it and recreate a new empty one. Add handling of CNID overflow, ie when the last used CNID reaches its maximum (UINT32_MAX), wrap around to CNID_START. This then neccesites a modification to get_id() where we used to just increment the last used CNID counter and use that as next CNID. Now we need to ensure that it isn't already used in the db and keep searching for an used in case it is in a loop. Move locking function back to main.c, as it's only used by cnid_dbd. Modify dbd_add() such that it can add an entry with the CNID passed in from the client, the CNID hint read from the adouble file. Invalidate CNID hint in case lookup detected a problem --- etc/cnid_dbd/dbd_add.c | 71 +++++++---- etc/cnid_dbd/dbd_lookup.c | 3 + etc/cnid_dbd/dbif.c | 109 ++--------------- etc/cnid_dbd/dbif.h | 4 - etc/cnid_dbd/main.c | 247 ++++++++++++++++++++++++++------------ 5 files changed, 226 insertions(+), 208 deletions(-) diff --git a/etc/cnid_dbd/dbd_add.c b/etc/cnid_dbd/dbd_add.c index e6e5e501..db9c6cc2 100644 --- a/etc/cnid_dbd/dbd_add.c +++ b/etc/cnid_dbd/dbd_add.c @@ -74,7 +74,7 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply) { static cnid_t id; static char buf[ROOTINFO_DATALEN]; - DBT rootinfo_key, rootinfo_data; + DBT rootinfo_key, rootinfo_data, key, data; int rc; cnid_t hint; @@ -83,41 +83,57 @@ int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply) rootinfo_key.data = ROOTINFO_KEY; rootinfo_key.size = ROOTINFO_KEYLEN; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + if (id == 0) { - if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) < 0) { + if ((rc = dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) != 1) { rply->result = CNID_DBD_RES_ERR_DB; return -1; } - if (rc == 0) { - /* no rootinfo key yet */ - memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN); + memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN); + memcpy(&hint, buf + CNID_TYPE_OFS, sizeof(hint)); + id = ntohl(hint); + if (id < CNID_START - 1) id = CNID_START - 1; - } else { - memcpy(buf, (char *)rootinfo_data.data, ROOTINFO_DATALEN); - memcpy(&hint, buf + CNID_TYPE_OFS, sizeof(hint)); - id = ntohl(hint); - if (id < CNID_START - 1) - id = CNID_START - 1; - } } - /* If we've hit the max CNID allowed, we return an error. CNID - * needs to be recycled before proceding. */ - if (++id == CNID_INVALID) { - rply->result = CNID_DBD_RES_ERR_MAX; - return -1; + cnid_t trycnid, tmp; + + while (true) { + if (rply->cnid != CNID_INVALID) { + trycnid = ntohl(rply->cnid); + rply->cnid = CNID_INVALID; + } else { + if (++id == CNID_INVALID) + id = CNID_START; + trycnid = id; + } + tmp = htonl(trycnid); + key.data = &tmp; + key.size = sizeof(cnid_t); + rc = dbif_get(dbd, DBIF_CNID, &key, &data, 0); + if (rc == 0) { + break; + } else if (rc == -1) { + rply->result = CNID_DBD_RES_ERR_DB; + return -1; + } } - rootinfo_data.data = buf; - rootinfo_data.size = ROOTINFO_DATALEN; - hint = htonl(id); - memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint)); + if (trycnid == id) { + rootinfo_data.data = buf; + rootinfo_data.size = ROOTINFO_DATALEN; + hint = htonl(id); + memcpy(buf + CNID_TYPE_OFS, &hint, sizeof(hint)); - if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) { - rply->result = CNID_DBD_RES_ERR_DB; - return -1; + if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) { + rply->result = CNID_DBD_RES_ERR_DB; + return -1; + } } - rply->cnid = hint; + + rply->cnid = htonl(trycnid); return 0; } @@ -146,7 +162,10 @@ int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) LOG(log_debug, logtype_cnid, "dbd_add(did:%u, '%s', dev/ino:0x%llx/0x%llx): {adding to database ...}", ntohl(rqst->did), rqst->name, (unsigned long long)rqst->dev, (unsigned long long)rqst->ino); - + if (rqst->cnid) { + /* rqst->cnid is the cnid "hint"/backup from the adouble file */ + rply->cnid = rqst->cnid; + } if (get_cnid(dbd, rply) < 0) { if (rply->result == CNID_DBD_RES_ERR_MAX) { LOG(log_error, logtype_cnid, "dbd_add: FATAL: CNID database has reached its limit."); diff --git a/etc/cnid_dbd/dbd_lookup.c b/etc/cnid_dbd/dbd_lookup.c index 0ab85f99..44e46620 100644 --- a/etc/cnid_dbd/dbd_lookup.c +++ b/etc/cnid_dbd/dbd_lookup.c @@ -120,6 +120,7 @@ to be safe we must assign new CNIDs to both files. #include #include +#include #include "pack.h" #include "dbif.h" @@ -281,6 +282,7 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) return -1; rply->result = CNID_DBD_RES_NOTFOUND; + rqst->cnid = CNID_INVALID; /* invalidate CNID hint */ return 1; } } @@ -292,6 +294,7 @@ int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) if (dbd_delete(dbd, rqst, rply, DBIF_CNID) < 0) return -1; rply->result = CNID_DBD_RES_NOTFOUND; + rqst->cnid = CNID_INVALID; /* invalidate CNID hint */ return 1; } diff --git a/etc/cnid_dbd/dbif.c b/etc/cnid_dbd/dbif.c index b21f259b..3dae61cd 100644 --- a/etc/cnid_dbd/dbif.c +++ b/etc/cnid_dbd/dbif.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "db_param.h" #include "dbif.h" @@ -88,13 +89,11 @@ static int dbif_stamp(DBD *dbd, void *buffer, int size) static int dbif_init_rootinfo(DBD *dbd, int version) { DBT key, data; - uint32_t v; + uint32_t uint32; char buf[ROOTINFO_DATALEN]; LOG(log_debug, logtype_cnid, "Setting CNID database version to %u", version); - v = version; - v = htonl(v); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); @@ -104,7 +103,13 @@ static int dbif_init_rootinfo(DBD *dbd, int version) data.size = ROOTINFO_DATALEN; memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN); - memcpy(buf + CNID_DID_OFS, &v, sizeof(v)); + + uint32 = htonl(CNID_START - 1); + memcpy(buf + CNID_TYPE_OFS, &uint32, sizeof(uint32)); + + uint32 = htonl(version); + memcpy(buf + CNID_DID_OFS, &uint32, sizeof(uint32)); + if (dbif_stamp(dbd, buf + CNID_DEV_OFS, CNID_DEV_LEN) < 0) return -1; @@ -326,97 +331,6 @@ static int dbif_logautorem(DBD *dbd) return ret; } -/*! - * Get lock on db lock file - * - * @args cmd (r) lock command: - * LOCK_FREE: close lockfd - * LOCK_UNLOCK: unlock lockm keep lockfd open - * LOCK_EXCL: F_WRLCK on lockfd - * LOCK_SHRD: F_RDLCK on lockfd - * @args dbpath (r) path to lockfile, only used on first call, - * later the stored fd is used - * @returns LOCK_FREE/LOCK_UNLOCK return 0 on success, -1 on error - * LOCK_EXCL/LOCK_SHRD return LOCK_EXCL or LOCK_SHRD respectively on - * success, 0 if the lock couldn't be acquired, -1 on other errors - */ -int get_lock(int cmd, const char *dbpath) -{ - static int lockfd = -1; - int ret; - char lockpath[PATH_MAX]; - struct stat st; - - LOG(log_debug, logtype_cnid, "get_lock(%s, \"%s\")", - cmd == LOCK_EXCL ? "LOCK_EXCL" : - cmd == LOCK_SHRD ? "LOCK_SHRD" : - cmd == LOCK_FREE ? "LOCK_FREE" : - cmd == LOCK_UNLOCK ? "LOCK_UNLOCK" : "UNKNOWN" , dbpath ? dbpath : ""); - - switch (cmd) { - case LOCK_FREE: - if (lockfd == -1) - return -1; - close(lockfd); - lockfd = -1; - return 0; - - case LOCK_UNLOCK: - if (lockfd == -1) - return -1; - return unlock(lockfd, 0, SEEK_SET, 0); - - case LOCK_EXCL: - case LOCK_SHRD: - if (lockfd == -1) { - if ( (strlen(dbpath) + strlen(LOCKFILENAME+1)) > (PATH_MAX - 1) ) { - LOG(log_error, logtype_cnid, ".AppleDB pathname too long"); - return -1; - } - strncpy(lockpath, dbpath, PATH_MAX - 1); - strcat(lockpath, "/"); - strcat(lockpath, LOCKFILENAME); - - if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0644)) < 0) { - LOG(log_error, logtype_cnid, "Error opening lockfile: %s", strerror(errno)); - return -1; - } - - if ((stat(dbpath, &st)) != 0) { - LOG(log_error, logtype_cnid, "Error statting lockfile: %s", strerror(errno)); - return -1; - } - - if ((chown(lockpath, st.st_uid, st.st_gid)) != 0) { - LOG(log_error, logtype_cnid, "Error inheriting lockfile permissions: %s", - strerror(errno)); - return -1; - } - } - - if (cmd == LOCK_EXCL) - ret = write_lock(lockfd, 0, SEEK_SET, 0); - else - ret = read_lock(lockfd, 0, SEEK_SET, 0); - - if (ret != 0) { - if (cmd == LOCK_SHRD) - LOG(log_error, logtype_cnid, "Volume CNID db is locked, try again..."); - return 0; - } - - LOG(log_debug, logtype_cnid, "get_lock: got %s lock", - cmd == LOCK_EXCL ? "LOCK_EXCL" : "LOCK_SHRD"); - return cmd; - - default: - return -1; - } /* switch(cmd) */ - - /* deadc0de, never get here */ - return -1; -} - /* --------------- */ DBD *dbif_init(const char *envhome, const char *filename) { @@ -813,11 +727,6 @@ int dbif_env_remove(const char *path) LOG(log_debug, logtype_cnid, "Trying to remove BerkeleyDB environment"); - if (get_lock(LOCK_EXCL, path) != LOCK_EXCL) { - LOG(log_debug, logtype_cnid, "CNID db \"%s\" in use, not removing BerkeleyDB environment", path); - return 0; - } - if (NULL == (dbd = dbif_init(path, "cnid2.db"))) return -1; diff --git a/etc/cnid_dbd/dbif.h b/etc/cnid_dbd/dbif.h index 8c71de36..a6c88a98 100644 --- a/etc/cnid_dbd/dbif.h +++ b/etc/cnid_dbd/dbif.h @@ -64,7 +64,6 @@ #define DBIF_IDX_DIDNAME 2 #define DBIF_IDX_NAME 3 -/* get_lock cmd and return value */ #define LOCKFILENAME "lock" #define LOCK_FREE 0 #define LOCK_UNLOCK 1 @@ -91,9 +90,6 @@ typedef struct { db_table db_table[DBIF_DB_CNT]; } DBD; -/* Functions */ -extern int get_lock(int cmd, const char *dbpath); - extern DBD *dbif_init(const char *envhome, const char *dbname); extern int dbif_env_open(DBD *dbd, struct db_param *dbp, uint32_t dbenv_oflags); extern int dbif_open(DBD *dbd, struct db_param *dbp, int reindex); diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index e2a24d48..72df4078 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "db_param.h" #include "dbif.h" @@ -45,6 +46,7 @@ static int exit_sig = 0; static int db_locked; static bstring dbpath; static struct db_param *dbp; +static struct vol *vol; static void sig_exit(int signo) { @@ -79,72 +81,198 @@ static void block_sigs_onoff(int block) of the cnid_dbd_rply structure contains further details. */ -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif + +/*! + * Get lock on db lock file + * + * @args cmd (r) lock command: + * LOCK_FREE: close lockfd + * LOCK_UNLOCK: unlock lockm keep lockfd open + * LOCK_EXCL: F_WRLCK on lockfd + * LOCK_SHRD: F_RDLCK on lockfd + * @args dbpath (r) path to lockfile, only used on first call, + * later the stored fd is used + * @returns LOCK_FREE/LOCK_UNLOCK return 0 on success, -1 on error + * LOCK_EXCL/LOCK_SHRD return LOCK_EXCL or LOCK_SHRD respectively on + * success, 0 if the lock couldn't be acquired, -1 on other errors + */ +static int get_lock(int cmd, const char *dbpath) +{ + static int lockfd = -1; + int ret; + char lockpath[PATH_MAX]; + struct stat st; + + LOG(log_debug, logtype_cnid, "get_lock(%s, \"%s\")", + cmd == LOCK_EXCL ? "LOCK_EXCL" : + cmd == LOCK_SHRD ? "LOCK_SHRD" : + cmd == LOCK_FREE ? "LOCK_FREE" : + cmd == LOCK_UNLOCK ? "LOCK_UNLOCK" : "UNKNOWN", + dbpath ? dbpath : ""); + + switch (cmd) { + case LOCK_FREE: + if (lockfd == -1) + return -1; + close(lockfd); + lockfd = -1; + return 0; + + case LOCK_UNLOCK: + if (lockfd == -1) + return -1; + return unlock(lockfd, 0, SEEK_SET, 0); + + case LOCK_EXCL: + case LOCK_SHRD: + if (lockfd == -1) { + if ( (strlen(dbpath) + strlen(LOCKFILENAME+1)) > (PATH_MAX - 1) ) { + LOG(log_error, logtype_cnid, ".AppleDB pathname too long"); + return -1; + } + strncpy(lockpath, dbpath, PATH_MAX - 1); + strcat(lockpath, "/"); + strcat(lockpath, LOCKFILENAME); + + if ((lockfd = open(lockpath, O_RDWR | O_CREAT, 0644)) < 0) { + LOG(log_error, logtype_cnid, "Error opening lockfile: %s", strerror(errno)); + return -1; + } + + if ((stat(dbpath, &st)) != 0) { + LOG(log_error, logtype_cnid, "Error statting lockfile: %s", strerror(errno)); + return -1; + } + + if ((chown(lockpath, st.st_uid, st.st_gid)) != 0) { + LOG(log_error, logtype_cnid, "Error inheriting lockfile permissions: %s", + strerror(errno)); + return -1; + } + } + + if (cmd == LOCK_EXCL) + ret = write_lock(lockfd, 0, SEEK_SET, 0); + else + ret = read_lock(lockfd, 0, SEEK_SET, 0); + + if (ret != 0) { + if (cmd == LOCK_SHRD) + LOG(log_error, logtype_cnid, "Volume CNID db is locked, try again..."); + return 0; + } + + LOG(log_debug, logtype_cnid, "get_lock: got %s lock", + cmd == LOCK_EXCL ? "LOCK_EXCL" : "LOCK_SHRD"); + return cmd; + + default: + return -1; + } /* switch(cmd) */ + + /* deadc0de, never get here */ + return -1; +} + +static int open_db(void) +{ + EC_INIT; + + /* Get db lock */ + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { + LOG(log_error, logtype_cnid, "main: fatal db lock error"); + EC_FAIL; + } + + if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db"))) + EC_FAIL; + + /* Only recover if we got the lock */ + if (dbif_env_open(dbd, dbp, DBOPTIONS | DB_RECOVER) < 0) + EC_FAIL; + + LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment"); + + if (dbif_open(dbd, dbp, 0) < 0) + EC_FAIL; + + LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases"); + +EC_CLEANUP: + if (ret != 0) { + if (dbd) { + (void)dbif_close(dbd); + dbd = NULL; + } + } + + EC_EXIT; +} static int delete_db(void) { EC_INIT; int cwd = -1; + EC_ZERO( get_lock(LOCK_FREE, bdata(dbpath)) ); EC_NEG1( cwd = open(".", O_RDONLY) ); - chdir(bdata(dbpath)); system("rm -f cnid2.db lock log.* __db.*"); + if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { LOG(log_error, logtype_cnid, "main: fatal db lock error"); EC_FAIL; } + LOG(log_warning, logtype_cnid, "Recreated CNID BerkeleyDB databases of volume \"%s\"", vol->v_localname); + EC_CLEANUP: if (cwd != -1) fchdir(cwd); EC_EXIT; } -static int wipe_db(void) + +/** + * Close dbd if open, delete it, reopen + * + * Also tries to copy the rootinfo key, that would allow for keeping the db stamp + * and last used CNID + **/ +static int reinit_db(void) { EC_INIT; DBT key, data; + bool copyRootInfo; - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); + if (dbd) { + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); - key.data = ROOTINFO_KEY; - key.size = ROOTINFO_KEYLEN; + key.data = ROOTINFO_KEY; + key.size = ROOTINFO_KEYLEN; - if (dbif_get(dbd, DBIF_CNID, &key, &data, 0) <= 0) { - LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error getting rootinfo record"); - EC_FAIL; + if (dbif_get(dbd, DBIF_CNID, &key, &data, 0) <= 0) { + LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error getting rootinfo record"); + copyRootInfo = false; + } else { + copyRootInfo = true; + } + (void)dbif_close(dbd); } - EC_NEG1_LOG( dbif_close(dbd) ); - EC_NEG1_LOG( dbif_env_remove(bdata(dbpath)) ); EC_ZERO_LOG( delete_db() ); + EC_ZERO_LOG( open_db() ); - /* Get db lock */ - if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { - LOG(log_error, logtype_cnid, "main: fatal db lock error"); - EC_FAIL; - } - - EC_NULL_LOG( dbd = dbif_init(bdata(dbpath), "cnid2.db") ); - - /* Only recover if we got the lock */ - EC_NEG1_LOG( dbif_env_open(dbd, dbp, DBOPTIONS | DB_RECOVER) ); + if (copyRootInfo == true) { + memset(&key, 0, sizeof(key)); + key.data = ROOTINFO_KEY; + key.size = ROOTINFO_KEYLEN; - LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment"); - - EC_NEG1_LOG( dbif_open(dbd, dbp, 0) ); - - memset(&key, 0, sizeof(key)); - key.data = ROOTINFO_KEY; - key.size = ROOTINFO_KEYLEN; - - if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) != 0) { - LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error writing rootinfo key"); - EC_FAIL; + if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) != 0) { + LOG(log_error, logtype_cnid, "dbif_copy_rootinfokey: Error writing rootinfo key"); + EC_FAIL; + } } EC_CLEANUP: @@ -180,7 +308,7 @@ static int loop(struct db_param *dbp) dbp->flush_interval, timebuf); while (1) { - timeout = min(time_next_flush, time_last_rqst +dbp->idle_timeout); + timeout = MIN(time_next_flush, time_last_rqst + dbp->idle_timeout); if (timeout > now) timeout -= now; else @@ -242,7 +370,7 @@ static int loop(struct db_param *dbp) ret = dbd_search(dbd, &rqst, &rply); break; case CNID_DBD_OP_WIPE: - ret = wipe_db(); + ret = reinit_db(); break; default: LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op); @@ -351,12 +479,12 @@ int main(int argc, char *argv[]) int ctrlfd = -1, clntfd = -1; char *logconfig; AFPObj obj = { 0 }; - struct vol *vol; char *volpath = NULL; while (( ret = getopt( argc, argv, "dF:l:p:t:vV")) != -1 ) { switch (ret) { case 'd': + /* this is now just ignored, as we do it automatically anyway */ delete_bdb = 1; break; case 'F': @@ -397,17 +525,6 @@ int main(int argc, char *argv[]) switch_to_user(bdata(dbpath)); - /* Get db lock */ - if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { - LOG(log_error, logtype_cnid, "main: fatal db lock error"); - EC_FAIL; - } - - if (delete_bdb) { - LOG(log_warning, logtype_cnid, "main: too many CNID db opening attempts, wiping the slate clean"); - EC_ZERO( delete_db() ); - } - set_signal(); /* SIGINT and SIGTERM are always off, unless we are in pselect */ @@ -417,37 +534,11 @@ int main(int argc, char *argv[]) EC_FAIL; LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file"); - if (NULL == (dbd = dbif_init(bdata(dbpath), "cnid2.db"))) - EC_FAIL; - - /* Only recover if we got the lock */ - if (dbif_env_open(dbd, - dbp, - (db_locked == LOCK_EXCL) ? DBOPTIONS | DB_RECOVER : DBOPTIONS) < 0) - EC_FAIL; - LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment"); - - if (dbif_open(dbd, dbp, 0) < 0) { - ret = -1; - goto close_db; - } - - LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases"); - - /* Downgrade db lock */ - if (db_locked == LOCK_EXCL) { - if (get_lock(LOCK_UNLOCK, NULL) != 0) { - ret = -1; - goto close_db; - } - - if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD) { - ret = -1; - goto close_db; - } + if (open_db() != 0) { + LOG(log_error, logtype_cnid, "Failed to open CNID database for volume \"%s\"", vol->v_localname); + EC_ZERO_LOG( reinit_db() ); } - if (comm_init(dbp, ctrlfd, clntfd) < 0) { ret = -1; goto close_db; From 5fada3c18c7829183ab4f6fd634ab614ba5a99bb Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 11 Dec 2012 10:39:38 +0100 Subject: [PATCH 076/117] Get the db stamp in cnid_get_stamp() Previously we actually intersected the IPC call to get the db stamp in transmit() when the firt actual CNID IPC function is executed. Drop the check for changed db stamps. Add a simple function for the get stamp IPC stuff. --- etc/cnid_dbd/cmd_dbd_scanvol.c | 12 ----- libatalk/cnid/dbd/cnid_dbd.c | 87 +++++++++++++--------------------- 2 files changed, 34 insertions(+), 65 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 68300b6c..19b3ebc6 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -911,18 +911,6 @@ int cmd_dbd_scanvol(struct vol *vol_in, dbd_flags_t flags) * then cnid_resolve() actually gets the value from the db */ cnid_getstamp(vol->v_cdb, stamp, sizeof(stamp)); - cnid_t rootid = 0; - if (cnid_resolve(vol->v_cdb, &rootid, cnidResBuf, sizeof(cnidResBuf)) == NULL) { - dbd_log(LOGSTD, "error resolving rootinfo key"); - goto exit; - } - -#if 0 - if (0 != (dbif_copy_rootinfokey(dbd, dbd_rebuild))) { - ret = -1; - goto exit; - } -#endif if (setjmp(jmp) != 0) { ret = 0; /* Got signal, jump from dbd_readdir */ diff --git a/libatalk/cnid/dbd/cnid_dbd.c b/libatalk/cnid/dbd/cnid_dbd.c index b654740a..d0d5ae67 100644 --- a/libatalk/cnid/dbd/cnid_dbd.c +++ b/libatalk/cnid/dbd/cnid_dbd.c @@ -356,47 +356,18 @@ static int transmit(CNID_private *db, struct cnid_dbd_rqst *rqst, struct cnid_db 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->db_dir); } if (!dbd_rpc(db, rqst, rply)) { LOG(log_maxdebug, logtype_cnid, "transmit: {done}"); @@ -531,6 +502,32 @@ void cnid_dbd_close(struct _cnid_db *cdb) return; } +/** + * Get the db stamp + **/ +static int cnid_dbd_stamp(CNID_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) @@ -706,7 +703,9 @@ char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t le 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; @@ -718,8 +717,8 @@ int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len) } db->client_stamp = buffer; db->stamp_size = len; - memset(buffer,0, len); - return 0; + + return cnid_dbd_stamp(db); } /* ---------------------- */ @@ -1024,25 +1023,7 @@ int cnid_dbd_wipe(struct _cnid_db *cdb) } LOG(log_debug, logtype_cnid, "cnid_dbd_wipe: ok"); - 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 (dbd_rpc(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; + return cnid_dbd_stamp(db); } From 590b1ecf6788b93a69222c962c968f32afaf6faf Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 19 Dec 2012 17:15:37 +0100 Subject: [PATCH 077/117] Update news --- NEWS | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 12291fc2..76e845c2 100644 --- a/NEWS +++ b/NEWS @@ -6,21 +6,20 @@ Changes in 3.0.2 * UPD: ignore volumes with duplicated volumes paths. * 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: 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: 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. - Fixed bug #481. +* 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. Changes in 3.0.1 ================ From 2ca8b94ca99cd894eb055a3e80b34ab6951bed52 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 21 Dec 2012 15:14:00 +0100 Subject: [PATCH 078/117] Fix an error parsing afp.conf in the iniparser Netatalk didn't start when the last line of the config file afp.conf wasn't terminated by a newline. Fixes bug #476. --- NEWS | 2 ++ libatalk/iniparser/iniparser.c | 8 -------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 76e845c2..3dce155f 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ Changes in 3.0.2 * 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. Changes in 3.0.1 ================ diff --git a/libatalk/iniparser/iniparser.c b/libatalk/iniparser/iniparser.c index 5c741d25..c0514d96 100644 --- a/libatalk/iniparser/iniparser.c +++ b/libatalk/iniparser/iniparser.c @@ -574,14 +574,6 @@ dictionary * iniparser_load(const char * ininame) len = (int)strlen(line)-1; if (len==0) continue; - /* Safety check against buffer overflows */ - if (line[len]!='\n') { - LOG(log_error, logtype_default, "iniparser: input line too long in \"%s\" (lineno: %d)", - ininame, lineno); - dictionary_del(dict); - fclose(in); - return NULL ; - } /* Get rid of \n and spaces at end of line */ while ((len>=0) && ((line[len]=='\n') || (isspace(line[len])))) { From 3d8d8cc23f7bffe243b43aa46417cb4378a8f896 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 27 Dec 2012 12:44:43 +0100 Subject: [PATCH 079/117] Add dev to log message and print type as string --- libatalk/cnid/dbd/cnid_dbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libatalk/cnid/dbd/cnid_dbd.c b/libatalk/cnid/dbd/cnid_dbd.c index d0d5ae67..3f0278ae 100644 --- a/libatalk/cnid/dbd/cnid_dbd.c +++ b/libatalk/cnid/dbd/cnid_dbd.c @@ -563,8 +563,8 @@ cnid_t cnid_dbd_add(struct _cnid_db *cdb, const struct stat *st, 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) { From cbb01a0e4a5474a70936f32e3231bb6336b31998 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 27 Dec 2012 12:45:22 +0100 Subject: [PATCH 080/117] Several fixes Allow the usage of -r option. Fix flags argument to cnid_open(). Update usage. --- etc/cnid_dbd/cmd_dbd.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd.c b/etc/cnid_dbd/cmd_dbd.c index 8a12bfad..31d74e6c 100644 --- a/etc/cnid_dbd/cmd_dbd.c +++ b/etc/cnid_dbd/cmd_dbd.c @@ -92,13 +92,14 @@ static void set_signal(void) static void usage (void) { - printf("Usage: dbd [-cfFstvV] \n" - "dbd scans or reindex Netatalk CNID databases of AFP volumes.\n" - "dbd must be run with appropiate permissions i.e. as root.\n" - "By default dbd rebuilds the CNID database of the volume.\n\n" + printf("Usage: dbd [-cfFstvV] \n\n" + "dbd scans all file and directories of AFP volumes, updating the\n" + "CNID database of the volume. dbd must be run with appropiate\n" + "permissions i.e. as root.\n\n" "Options:\n" - " -s Scan volume:\n" - " -c convert from adouble:v2 to adouble:ea (use with -r)\n" + " -s scan volume: treat the volume as read only and don't\n" + " perform any filesystem modifications\n" + " -c convert from adouble:v2 to adouble:ea\n" " -F location of the afp.conf config file\n" " -f delete and recreate CNID database\n" " -t show statistics while running\n" @@ -137,7 +138,7 @@ int main(int argc, char **argv) const char *volpath = NULL; int c; - while ((c = getopt(argc, argv, ":cfF:stvV")) != -1) { + while ((c = getopt(argc, argv, ":cfF:rstvV")) != -1) { switch(c) { case 'c': flags |= DBD_FLAGS_V2TOEA; @@ -148,6 +149,9 @@ int main(int argc, char **argv) case 'F': obj.cmdlineconfigfile = strdup(optarg); break; + case 'r': + /* the default */ + break; case 's': dbd_cmd = dbd_scan; flags |= DBD_FLAGS_SCAN; @@ -231,7 +235,7 @@ int main(int argc, char **argv) if ((vol->v_cdb = cnid_open(vol->v_path, 0000, "dbd", - flags, + vol->v_flags & AFPVOL_NODEV ? CNID_FLAG_NODEV : 0, vol->v_cnidserver, vol->v_cnidport)) == NULL) { dbd_log(LOGSTD, "Cant initialize CNID database connection for %s", vol->v_path); From 860aea4f5b98969bc61f9e5316735b5a69dd4533 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 27 Dec 2012 12:54:27 +0100 Subject: [PATCH 081/117] Remove dupicate variable myvol, use vol instead --- etc/cnid_dbd/cmd_dbd_scanvol.c | 138 ++++++++++++++------------------- 1 file changed, 60 insertions(+), 78 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 19b3ebc6..99156aa9 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -29,13 +29,13 @@ #include #include #include -//#include #include #include #include #include #include #include +#include #include "cmd_dbd.h" #include "dbif.h" @@ -47,7 +47,6 @@ #define ADFILE_OK (adfile_ok == 0) -static struct vol *myvol; static char cwdbuf[MAXPATHLEN+1]; static struct vol *vol; static DBD *dbd_rebuild; @@ -85,22 +84,22 @@ static char *utompath(char *upath) u = upath; outlen = strlen(upath); - if ((myvol->v_casefold & AFPVOL_UTOMUPPER)) + if ((vol->v_casefold & AFPVOL_UTOMUPPER)) flags |= CONV_TOUPPER; - else if ((myvol->v_casefold & AFPVOL_UTOMLOWER)) + else if ((vol->v_casefold & AFPVOL_UTOMLOWER)) flags |= CONV_TOLOWER; - if ((myvol->v_flags & AFPVOL_EILSEQ)) { + if ((vol->v_flags & AFPVOL_EILSEQ)) { flags |= CONV__EILSEQ; } /* convert charsets */ - if ((size_t)-1 == ( outlen = convert_charset(myvol->v_volcharset, + if ((size_t)-1 == ( outlen = convert_charset(vol->v_volcharset, CH_UTF8_MAC, - myvol->v_maccharset, + vol->v_maccharset, u, outlen, mpath, MAXPATHLEN, &flags)) ) { dbd_log( LOGSTD, "Conversion from %s to %s for %s failed.", - myvol->v_volcodepage, myvol->v_maccodepage, u); + vol->v_volcodepage, vol->v_maccodepage, u); return NULL; } @@ -126,12 +125,12 @@ static char *mtoupath(char *mpath) } /* set conversion flags */ - if ((myvol->v_casefold & AFPVOL_MTOUUPPER)) + if ((vol->v_casefold & AFPVOL_MTOUUPPER)) flags |= CONV_TOUPPER; - else if ((myvol->v_casefold & AFPVOL_MTOULOWER)) + else if ((vol->v_casefold & AFPVOL_MTOULOWER)) flags |= CONV_TOLOWER; - if ((myvol->v_flags & AFPVOL_EILSEQ)) { + if ((vol->v_flags & AFPVOL_EILSEQ)) { flags |= CONV__EILSEQ; } @@ -142,11 +141,11 @@ static char *mtoupath(char *mpath) outlen = MAXPATHLEN; if ((size_t)-1 == (outlen = convert_charset(CH_UTF8_MAC, - myvol->v_volcharset, - myvol->v_maccharset, + vol->v_volcharset, + vol->v_maccharset, m, inplen, u, outlen, &flags)) ) { dbd_log( LOGSTD, "conversion from UTF8-MAC to %s for %s failed.", - myvol->v_volcodepage, mpath); + vol->v_volcodepage, mpath); return NULL; } @@ -215,10 +214,10 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n *newname = NULL; - if (myvol->v_adouble == AD_VERSION_EA) { + if (vol->v_adouble == AD_VERSION_EA) { if (!(dbd_flags & DBD_FLAGS_V2TOEA)) return 0; - if (ad_convert(fname, st, myvol, newname) != 0) { + if (ad_convert(fname, st, vol, newname) != 0) { switch (errno) { case ENOENT: break; @@ -233,7 +232,7 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n if (S_ISDIR(st->st_mode)) adflags |= ADFLAGS_DIR; - adname = myvol->ad_path(fname, adflags); + adname = vol->ad_path(fname, adflags); if ((ret = access( adname, F_OK)) != 0) { if (errno != ENOENT) { @@ -249,7 +248,7 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n return -1; /* Create ad file */ - ad_init(&ad, myvol); + ad_init(&ad, vol); if ((ret = ad_open(&ad, fname, adflags | ADFLAGS_CREATE | ADFLAGS_RDWR, 0666)) != 0) { dbd_log( LOGSTD, "Error creating AppleDouble file '%s/%s': %s", @@ -269,7 +268,7 @@ static int check_adfile(const char *fname, const struct stat *st, const char **n chmod(adname, st->st_mode); #endif } else { - ad_init(&ad, myvol); + ad_init(&ad, vol); if (ad_open(&ad, fname, adflags | ADFLAGS_RDONLY) != 0) { dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s'", cwdbuf, fname); return -1; @@ -338,7 +337,7 @@ static int check_eafiles(const char *fname) struct stat st; char *eaname; - if ((ret = ea_open(myvol, fname, EA_RDWR, &ea)) != 0) { + if ((ret = ea_open(vol, fname, EA_RDWR, &ea)) != 0) { if (errno == ENOENT) return 0; dbd_log(LOGSTD, "Error calling ea_open for file: %s/%s, removing EA files", cwdbuf, fname); @@ -391,7 +390,7 @@ static int check_addir(int volroot) struct adouble ad; char *mname = NULL; - if (myvol->v_adouble == AD_VERSION_EA) + if (vol->v_adouble == AD_VERSION_EA) return 0; /* Check for ad-dir */ @@ -404,10 +403,10 @@ static int check_addir(int volroot) } /* Check for ".Parent" */ - if ( (adpar_ok = access(myvol->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) { + if ( (adpar_ok = access(vol->ad_path(".", ADFLAGS_DIR), F_OK)) != 0) { if (errno != ENOENT) { dbd_log(LOGSTD, "Access error on '%s/%s': %s", - cwdbuf, myvol->ad_path(".", ADFLAGS_DIR), strerror(errno)); + cwdbuf, vol->ad_path(".", ADFLAGS_DIR), strerror(errno)); return -1; } dbd_log(LOGSTD, "Missing .AppleDouble/.Parent for '%s'", cwdbuf); @@ -426,7 +425,7 @@ static int check_addir(int volroot) } /* Create ad dir and set name */ - ad_init(&ad, myvol); + ad_init(&ad, vol); if (ad_open(&ad, ".", ADFLAGS_HF | ADFLAGS_DIR | ADFLAGS_CREATE | ADFLAGS_RDWR, 0777) != 0) { dbd_log( LOGSTD, "Error creating AppleDouble dir in %s: %s", cwdbuf, strerror(errno)); @@ -447,7 +446,7 @@ static int check_addir(int volroot) return -1; } chown(ADv2_DIRNAME, st.st_uid, st.st_gid); - chown(myvol->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid); + chown(vol->ad_path(".", ADFLAGS_DIR), st.st_uid, st.st_gid); } return 0; @@ -466,7 +465,7 @@ static int check_eafile_in_adouble(const char *name) char *namep, *namedup = NULL; /* Check if this is an AFPVOL_EA_AD vol */ - if (myvol->v_vfs_ea == AFPVOL_EA_AD) { + if (vol->v_vfs_ea == AFPVOL_EA_AD) { /* Does the filename contain "::EA" ? */ namedup = strdup(name); if ((namep = strstr(namedup, "::EA")) == NULL) { @@ -525,7 +524,7 @@ static int read_addir(void) struct stat st; if ((chdir(ADv2_DIRNAME)) != 0) { - if (myvol->v_adouble == AD_VERSION_EA) { + if (vol->v_adouble == AD_VERSION_EA) { return 0; } dbd_log(LOGSTD, "Couldn't chdir to '%s/%s': %s", @@ -618,10 +617,10 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi /* Get CNID from ad-file */ ad_cnid = CNID_INVALID; if (ADFILE_OK) { - ad_init(&ad, myvol); + ad_init(&ad, vol); if (ad_open(&ad, name, adflags | ADFLAGS_RDWR) != 0) { - if (myvol->v_adouble != AD_VERSION_EA) { + if (vol->v_adouble != AD_VERSION_EA) { dbd_log( LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); return CNID_INVALID; } @@ -646,7 +645,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi /* Mismatch, overwrite ad file with value from db */ dbd_log(LOGSTD, "CNID mismatch for '%s/%s', CNID db: %u, ad-file: %u", cwdbuf, name, ntohl(db_cnid), ntohl(ad_cnid)); - ad_init(&ad, myvol); + ad_init(&ad, vol); if (ad_open(&ad, name, adflags | ADFLAGS_HF | ADFLAGS_RDWR) != 0) { dbd_log(LOGSTD, "Error opening AppleDouble file for '%s/%s': %s", cwdbuf, name, strerror(errno)); @@ -721,7 +720,7 @@ static int dbd_readdir(int volroot, cnid_t did) if (STRCMP(ep->d_name, == , ADv2_DIRNAME)) continue; - if (!myvol->vfs->vfs_validupath(myvol, ep->d_name)) { + if (!vol->vfs->vfs_validupath(vol, ep->d_name)) { dbd_log(LOGDEBUG, "Ignoring \"%s\"", ep->d_name); continue; } @@ -807,7 +806,7 @@ static int dbd_readdir(int volroot, cnid_t did) } /* Check EA files */ - if (myvol->v_vfs_ea == AFPVOL_EA_AD) + if (vol->v_vfs_ea == AFPVOL_EA_AD) check_eafiles(name); /************************************************************************** @@ -840,7 +839,7 @@ static int dbd_readdir(int volroot, cnid_t did) /* Use results of previous checks */ - if ((myvol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) { + if ((vol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) { if (rmdir(ADv2_DIRNAME) != 0) { switch (errno) { case ENOENT: @@ -855,55 +854,25 @@ static int dbd_readdir(int volroot, cnid_t did) return ret; } -static int scanvol(struct vol *vol, dbd_flags_t flags) -{ - struct stat st; - - /* Make this stuff accessible from all funcs easily */ - myvol = vol; - dbd_flags = flags; - - /* Run with umask 0 */ - umask(0); - - strcpy(cwdbuf, myvol->v_path); - chdir(myvol->v_path); - - if ((myvol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) { - if (lstat(".", &st) != 0) - return -1; - if (ad_convert(".", &st, vol, NULL) != 0) { - switch (errno) { - case ENOENT: - break; - default: - dbd_log(LOGSTD, "Conversion error for \"%s\": %s", myvol->v_path, strerror(errno)); - break; - } - } - } - - /* Start recursion */ - if (dbd_readdir(1, htonl(2)) < 0) /* 2 = volumeroot CNID */ - return -1; - - return 0; -} - /* Main func called from cmd_dbd.c */ int cmd_dbd_scanvol(struct vol *vol_in, dbd_flags_t flags) { - int ret = 0; + EC_INIT; + struct stat st; + + /* Run with umask 0 */ + umask(0); /* Make vol accessible for all funcs */ vol = vol_in; + dbd_flags = flags; /* We only support unicode volumes ! */ if (vol->v_volcharset != CH_UTF8) { dbd_log(LOGSTD, "Not a Unicode volume: %s, %u != %u", vol->v_volcodepage, vol->v_volcharset, CH_UTF8); - return -1; + EC_FAIL; } /* @@ -913,16 +882,29 @@ int cmd_dbd_scanvol(struct vol *vol_in, dbd_flags_t flags) cnid_getstamp(vol->v_cdb, stamp, sizeof(stamp)); if (setjmp(jmp) != 0) { - ret = 0; /* Got signal, jump from dbd_readdir */ - goto exit; + EC_EXIT_STATUS(0); /* Got signal, jump from dbd_readdir */ } - /* scanvol */ - if ((scanvol(vol, flags)) != 0) { - ret = -1; - goto exit; + strcpy(cwdbuf, vol->v_path); + chdir(vol->v_path); + + if ((vol->v_adouble == AD_VERSION_EA) && (dbd_flags & DBD_FLAGS_V2TOEA)) { + if (lstat(".", &st) != 0) + EC_FAIL; + if (ad_convert(".", &st, vol, NULL) != 0) { + switch (errno) { + case ENOENT: + break; + default: + dbd_log(LOGSTD, "Conversion error for \"%s\": %s", vol->v_path, strerror(errno)); + break; + } + } } -exit: - return ret; + /* Start recursion */ + EC_NEG1( dbd_readdir(1, htonl(2)) ); /* 2 = volumeroot CNID */ + +EC_CLEANUP: + EC_EXIT; } From e1664ced64355e533cfd7d46a498635c5ddbd58c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 27 Dec 2012 12:55:00 +0100 Subject: [PATCH 082/117] Import manpage from XML --- man/man1/dbd.1 | 112 +++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 84 deletions(-) diff --git a/man/man1/dbd.1 b/man/man1/dbd.1 index d36189f1..97d71935 100644 --- a/man/man1/dbd.1 +++ b/man/man1/dbd.1 @@ -1,13 +1,22 @@ '\" t .\" Title: dbd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 14 Sep 2012 +.\" Generator: DocBook XSL Stylesheets v1.78.0 +.\" Date: 28 Dez 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "DBD" "1" "14 Sep 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "DBD" "1" "28 Dez 2012" "Netatalk 3.0" "Netatalk 3.0" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -22,115 +31,50 @@ dbd \- CNID database maintenance .SH "SYNOPSIS" .HP \w'\fBdbd\fR\fB\fR\ 'u -\fBdbd\fR\fB\fR [\-evx] {\-d\ [\-i] | \-s\ [\-c|\-n] | \-r\ [\-c|\-f|\-C] | \-u} \fIvolumepath\fR +\fBdbd\fR\fB\fR [\-fsv] \fIvolumepath\fR .SH "DESCRIPTION" .PP \fBdbd\fR -can dump, scan, reindex and rebuild -\fINetatalk\fR -dbd CNID databases\&. It must be run with appropiate permissions i\&.e\&. as root\&. -\fBdbd\fR -\fB\-s|\-r\fR -can be run on active volumes, but -\fBdbd \-rf\fR, which wipes the db before rebuilding it, checks and enforces that the chosen volume is not in use\&. -.SH "COMMANDS" -.PP -\-d -.RS 4 -Dump CNID database\&. With -\fB\-i \fRdump indexes too\&. -.RE -.PP -\-s -.RS 4 -Scan volume: -.sp -Compare CNIDs in database with volume, test if \&.AppleDouble directories exist, test if AppleDouble files exist, report orphaned AppleDouble files, report directories inside \&.AppleDouble directories, check name encoding, heck for orphaned CNIDs in database (requires -\fB\-e\fR)\&. -.sp -Options: -.PP -\-c -.RS 4 -Don\'t check \&.AppleDouble stuff, only check orphaned\&. -.RE -.PP -\-n -.RS 4 -Don\'t open CNID database, skip CNID checks, only traverse filesystem -.RE -.RE -.PP -\-r -.RS 4 -Rebuild volume: -.sp -Sync CNIDSs from database with volume, ensure \&.AppleDouble directories exist, ensure AppleDouble files exist, delete orphaned AppleDouble files, report directories inside \&.AppleDouble directories, check name encoding by roundtripping, delete orphaned CNIDs in database (requires -\fB\-e\fR)\&. -.sp -Options: -.PP -\-C -.RS 4 -Converts volume from adouble:v2 to adouble:ea -.RE +scans all file and directories of AFP volumes, updating the CNID database of the volume\&. It must be run with appropiate permissions i\&.e\&. as root\&.\&. +.SH "OPTIONS" .PP \-c .RS 4 -Don\'t create \&.AppleDouble stuff, only cleanup orphaned\&. +convert from adouble:v2 to adouble:ea .RE .PP \-f .RS 4 -Wipe database and rebuild from IDs stored in AppleDouble files, only available for volumes without -\fBnocnidcache\fR -option\&. Implies -\fB\-e\fR\&. -.RE +delete and recreate CNID database .RE .PP -\-u +\-F .RS 4 -Upgrade: -.sp -Opens the database which triggers any necessary upgrades, then closes and exits\&. +location of the afp\&.conf config file .RE -.SH "OPTIONS" .PP -\-e +\-s .RS 4 -Only work on inactive volumes and lock them (exclusive) +scan volume: treat the volume as read only and don\*(Aqt perform any filesystem modifications .RE .PP -\-x +\-t .RS 4 -Rebuild indexes (just for completeness, mostly useless!) +show statistics while running .RE .PP \-v .RS 4 verbose .RE -.SH "WARNING" -.PP -In order to be able to run -\fB\-rf\fR -reconstructing the CNIDs in the database from the -\fIAppleDouble\fR -files, make sure you\'ve run a -\fB\-r\fR -rebuild sometimes before, where the CNIDs then would have been synched between database and -\fIAppleDouble\fR -files\&. .PP -Also be careful about the option -\fBnocnidcache\fR\&. Avoid this option if at all possible, because if prevents you from being able to use -\fB\-f\fR\&. +\-V +.RS 4 +display version info +.RE .SH "CNID BACKGROUND" .PP -The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID db will not know and not reflect that change\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&. The mechanisms to resolve such inconsistencies may fail sometimes, though, as this is not an easy task to accomplish\&. E\&.g\&. if several names in the path to the file or directory have changed, things may go wrong\&. -.PP -If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\'t changed\&. +The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID database will not reflect that change\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&. .SH "SEE ALSO" .PP \fBcnid_metad\fR(8), From acb180395693ed05a4e6a1edb6796c8e6f644a72 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 14 Nov 2012 16:02:41 +0100 Subject: [PATCH 083/117] Configurable symlink behaviour 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". In order to provide a somewhat consistent interface, add an API of o* function wrappers for filesytem related functions. These functions take an an additonal option arg (hence the o) which tells the functions whether symlinks shall be followed or not. --- NEWS | 6 +++ etc/afpd/acls.c | 2 +- etc/afpd/catsearch.c | 6 +-- etc/afpd/desktop.c | 6 +-- etc/afpd/directory.c | 24 +++++----- etc/afpd/enumerate.c | 4 +- etc/afpd/file.c | 63 ++++++++++++++----------- etc/afpd/filedir.c | 8 ++-- etc/afpd/fork.c | 2 +- etc/afpd/fork.h | 4 +- etc/afpd/ofork.c | 16 +++---- etc/afpd/quota.c | 13 +++--- etc/afpd/unix.c | 11 ++--- include/atalk/acl.h | 3 ++ include/atalk/adouble.h | 3 ++ include/atalk/unix.h | 3 +- include/atalk/util.h | 8 +++- include/atalk/volume.h | 3 +- libatalk/acl/Makefile.am | 2 +- libatalk/adouble/ad_open.c | 13 ++++-- libatalk/util/netatalk_conf.c | 4 ++ libatalk/util/unix.c | 87 ++++++++++++++++++++++++++++++++++- libatalk/vfs/ea_ad.c | 14 +++--- libatalk/vfs/unix.c | 30 +----------- libatalk/vfs/vfs.c | 28 +++++------ man/man5/afp.conf.5.tmpl | 78 ++++++++++++++++++------------- 26 files changed, 272 insertions(+), 169 deletions(-) diff --git a/NEWS b/NEWS index 3dce155f..5768657e 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,12 @@ Changes in 3.0.2 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". Changes in 3.0.1 ================ diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index 305ef06f..b14beb6f 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -1380,7 +1380,7 @@ static int check_acl_access(const AFPObj *obj, } #endif - EC_ZERO_LOG_ERR(lstat(path, &st), AFPERR_PARAM); + EC_ZERO_LOG_ERR(ostat(path, &st, vol_syml_opt(vol)), AFPERR_PARAM); is_dir = !strcmp(path, "."); diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 1a2b8989..09e3ff52 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -194,7 +194,7 @@ static struct adouble *adl_lkup(struct vol *vol, struct path *path, struct adoub isdir = S_ISDIR(path->st.st_mode); - if (!isdir && (of = of_findname(path))) { + if (!isdir && (of = of_findname(vol, path))) { adp = of->of_ad; } else { ad_init(&ad, vol); @@ -583,7 +583,7 @@ static int catsearch(const AFPObj *obj, memset(&path, 0, sizeof(path)); path.u_name = entry->d_name; - if (of_stat(&path) != 0) { + if (of_stat(vol, &path) != 0) { switch (errno) { case EACCES: case ELOOP: @@ -777,7 +777,7 @@ static int catsearch_db(const AFPObj *obj, path.u_name = name; path.m_name = utompath(vol, name, cnid, utf8_encoding(vol->v_obj)); - if (of_stat(&path) != 0) { + if (of_stat(vol, &path) != 0) { switch (errno) { case EACCES: case ELOOP: diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index c437b7e6..f34729cc 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -830,7 +830,7 @@ static int ad_addcomment(const AFPObj *obj, struct vol *vol, struct path *path, } isadir = path_isadir(path); - if (isadir || !(of = of_findname(path))) { + if (isadir || !(of = of_findname(vol, path))) { ad_init(&ad, vol); adp = &ad; } else @@ -905,7 +905,7 @@ static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t upath = path->u_name; isadir = path_isadir(path); - if (isadir || !(of = of_findname(path))) { + if (isadir || !(of = of_findname(vol, path))) { ad_init(&ad, vol); adp = &ad; } else @@ -982,7 +982,7 @@ static int ad_rmvcomment(const AFPObj *obj, struct vol *vol, struct path *path) } isadir = path_isadir(path); - if (isadir || !(of = of_findname(path))) { + if (isadir || !(of = of_findname(vol, path))) { ad_init(&ad, vol); adp = &ad; } else diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 46670e96..d617ea8f 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -134,7 +134,7 @@ static int netatalk_mkdir(const struct vol *vol, const char *name) } /* ------------------- */ -static int deletedir(int dirfd, char *dir) +static int deletedir(const struct vol *vol, int dirfd, char *dir) { char path[MAXPATHLEN + 1]; DIR *dp; @@ -165,11 +165,11 @@ static int deletedir(int dirfd, char *dir) break; } strcpy(path + len, de->d_name); - if (lstatat(dirfd, path, &st)) { + if (ostatat(dirfd, path, &st, vol_syml_opt(vol))) { continue; } if (S_ISDIR(st.st_mode)) { - err = deletedir(dirfd, path); + err = deletedir(vol, dirfd, path); } else { err = netatalk_unlinkat(dirfd, path); } @@ -231,7 +231,7 @@ static int copydir(struct vol *vol, struct dir *ddir, int dirfd, char *src, char } strcpy(spath + slen, de->d_name); - if (lstatat(dirfd, spath, &st) == 0) { + if (ostatat(dirfd, spath, &st, vol_syml_opt(vol)) == 0) { if (strlen(de->d_name) > drem) { err = AFPERR_PARAM; break; @@ -253,7 +253,7 @@ static int copydir(struct vol *vol, struct dir *ddir, int dirfd, char *src, char } /* keep the same time stamp. */ - if (lstatat(dirfd, src, &st) == 0) { + if (ostatat(dirfd, src, &st, vol_syml_opt(vol)) == 0) { ut.actime = ut.modtime = st.st_mtime; utime(dst, &ut); } @@ -643,7 +643,7 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did) LOG(log_debug, logtype_afpd, "dirlookup(did: %u): stating \"%s\"", ntohl(did), cfrombstr(fullpath)); - if (lstat(cfrombstr(fullpath), &st) != 0) { /* 5a */ + if (ostat(cfrombstr(fullpath), &st, vol_syml_opt(vol)) != 0) { /* 5a */ switch (errno) { case ENOENT: afp_errno = AFPERR_NOOBJ; @@ -1181,7 +1181,7 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath) * and thus call continue which should terminate the while loop because * len = 0. Ok? */ - if (of_stat(&ret) != 0) { /* 9 */ + if (of_stat(vol, &ret) != 0) { /* 9 */ /* * ret.u_name doesn't exist, might be afp_createfile|dir * that means it should have been the last part @@ -1299,7 +1299,7 @@ int movecwd(const struct vol *vol, struct dir *dir) LOG(log_debug, logtype_afpd, "movecwd(to: did: %u, \"%s\")", ntohl(dir->d_did), cfrombstr(dir->d_fullpath)); - if ((ret = lchdir(cfrombstr(dir->d_fullpath))) != 0 ) { + if ((ret = ochdir(cfrombstr(dir->d_fullpath), vol_syml_opt(vol))) != 0 ) { LOG(log_debug, logtype_afpd, "movecwd(\"%s\"): %s", cfrombstr(dir->d_fullpath), strerror(errno)); if (ret == 1) { @@ -2174,7 +2174,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ return err; } - if (of_stat(s_path) < 0) { + if (of_stat(vol, s_path) < 0) { return AFPERR_MISC; } @@ -2240,10 +2240,10 @@ int renamedir(struct vol *vol, /* this needs to copy and delete. bleah. that means we have * to deal with entire directory hierarchies. */ if ((err = copydir(vol, newparent, dirfd, src, dst)) < 0) { - deletedir(-1, dst); + deletedir(vol, -1, dst); return err; } - if ((err = deletedir(dirfd, src)) < 0) + if ((err = deletedir(vol, dirfd, src)) < 0) return err; break; default : @@ -2622,7 +2622,7 @@ int afp_opendir(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return path_error(path, AFPERR_NOOBJ); } - if ( !path->st_valid && of_stat(path ) < 0 ) { + if ( !path->st_valid && of_stat(vol, path) < 0 ) { return( AFPERR_NOOBJ ); } if ( path->st_errno ) { diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index c3b3acb4..80141e80 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -284,7 +284,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) { sd.sd_last = sd.sd_buf; /* if dir was in the cache we don't have the inode */ - if (( !o_path->st_valid && lstat( ".", &o_path->st ) < 0 ) || + if (( !o_path->st_valid && ostat(".", &o_path->st, vol_syml_opt(vol)) < 0 ) || (ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) { LOG(log_error, logtype_afpd, "enumerate: loop error: %s (%d)", strerror(errno), errno); @@ -355,7 +355,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, s_path.u_name = (char *)convname; } - if (of_stat( &s_path) < 0 ) { + if (of_stat(vol, &s_path) < 0 ) { /* so the next time it won't try to stat it again * another solution would be to invalidate the cache with * sd.sd_did = 0 but if it's not ENOENT error it will start again diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 8036c300..963268fe 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -100,7 +100,7 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a } } - if (islink){ + if (islink && !vol_syml_opt(vol)) { uint16_t linkflag; memcpy(&linkflag, (char *)data + FINDERINFO_FRFLAGOFF, 2); linkflag |= htons(FINDERINFO_ISALIAS); @@ -685,7 +685,7 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, ad_init(&ad, vol); /* if upath is deleted we already in trouble anyway */ - if ((of = of_findname(s_path))) { + if ((of = of_findname(vol, s_path))) { if (creatf) return AFPERR_BUSY; else @@ -839,6 +839,9 @@ int setfilparams(const AFPObj *obj, struct vol *vol, uint32_t cdate,bdate; u_char finder_buf[32]; int symlinked = S_ISLNK(path->st.st_mode); + int fp; + ssize_t len; + char symbuf[MAXPATHLEN+1]; #ifdef DEBUG LOG(log_debug9, logtype_afpd, "begin setfilparams:"); @@ -880,29 +883,33 @@ int setfilparams(const AFPObj *obj, struct vol *vol, break; case FILPBIT_FINFO : change_mdate = 1; - memcpy(finder_buf, buf, 32 ); - if (memcmp(buf, "slnkrhap", 8) == 0 && !S_ISLNK(path->st.st_mode)) { - int fp; - ssize_t len; - int erc=1; - char buf[PATH_MAX+1]; - if ((fp = open(path->u_name, O_RDONLY)) >= 0) { - if ((len = read(fp, buf, PATH_MAX+1))) { - if (unlink(path->u_name) == 0) { - buf[len] = 0; - erc = symlink(buf, path->u_name); - if (!erc) - of_stat(path); - } - } - close(fp); + if (memcmp(buf,"slnkrhap",8) == 0 + && !(S_ISLNK(path->st.st_mode)) + && !(vol->v_flags & AFPVOL_FOLLOWSYM)) { + /* request to turn this into a symlink */ + if ((fp = open(path->u_name, O_RDONLY)) == -1) { + err = AFPERR_MISC; + goto setfilparam_done; } - if (erc != 0) { - err=AFPERR_BITMAP; + len = read(fp, symbuf, MAXPATHLEN); + close(fp); + if (!(len > 0)) { + err = AFPERR_MISC; goto setfilparam_done; } + if (unlink(path->u_name) != 0) { + err = AFPERR_MISC; + goto setfilparam_done; + } + symbuf[len] = 0; + if (symlink(symbuf, path->u_name) != 0) { + err = AFPERR_MISC; + goto setfilparam_done; + } + of_stat(vol, path); symlinked = 1; } + memcpy(finder_buf, buf, 32 ); buf += 32; break; case FILPBIT_UNIXPR : @@ -1695,7 +1702,7 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data) cnid_t did = param->did; cnid_t aint; - if ( lstat(de->d_name, &path.st) < 0 ) + if (ostat(de->d_name, &path.st, vol_syml_opt(vol)) < 0) return 0; /* update or add to cnid */ @@ -1720,7 +1727,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir) } /* FIXME use of_statdir ? */ - if (lstat(name, &st)) { + if (ostat(name, &st, vol_syml_opt(vol))) { return -1; } @@ -1799,7 +1806,7 @@ int afp_resolveid(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ memset(&path, 0, sizeof(path)); path.u_name = upath; - if ( of_stat(&path) < 0 ) { + if (of_stat(vol, &path) < 0 ) { #ifdef ESTALE /* with nfs and our working directory is deleted */ if (errno == ESTALE) { @@ -1894,7 +1901,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } err = AFP_OK; - if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) { + if ((movecwd(vol, dir) < 0) || (ostat(upath, &st, vol_syml_opt(vol)) < 0)) { switch (errno) { case EACCES: case EPERM: @@ -1930,7 +1937,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } /* ------------------------------ */ -static struct adouble *find_adouble(const AFPObj *obj, struct vol *vol, struct path *path, struct ofork **of, struct adouble *adp) +static struct adouble *find_adouble(const AFPObj *obj, const struct vol *vol, struct path *path, struct ofork **of, struct adouble *adp) { int ret; @@ -1957,7 +1964,7 @@ static struct adouble *find_adouble(const AFPObj *obj, struct vol *vol, struct p return NULL; } - if ((*of = of_findname(path))) { + if ((*of = of_findname(vol, path))) { /* reuse struct adouble so it won't break locks */ adp = (*of)->of_ad; } @@ -2136,10 +2143,10 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U if (did) cnid_delete(vol->v_cdb, did); - if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || + if ((did && ( (crossdev && ostat(upath, &srcst, vol_syml_opt(vol)) < 0) || cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0)) || - (sid && ( (crossdev && lstat(p, &destst) < 0) || + (sid && ( (crossdev && ostat(p, &destst, vol_syml_opt(vol)) < 0) || cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0)) ) { switch (errno) { diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index 9a897d1b..543db0dc 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -346,7 +346,7 @@ static int moveandrename(struct vol *vol, if ( !isdir ) { path.st_valid = 1; path.st_errno = errno; - if (of_findname(&path)) { + if (of_findname(vol, &path)) { rc = AFPERR_EXIST; /* was AFPERR_BUSY; */ } else { rc = renamefile(vol, curdir, sdir_fd, oldunixname, upath, newname, adp ); @@ -536,7 +536,7 @@ int afp_delete(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size fce_register(FCE_DIR_DELETE, fullpathname(cfrombstr(dname)), NULL, fce_dir); bdestroy(dname); } - } else if (of_findname(s_path)) { + } else if (of_findname(vol, s_path)) { rc = AFPERR_BUSY; } else { /* it's a file st_valid should always be true @@ -703,8 +703,8 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U if (!isdir && !vol_unix_priv(vol)) { int admode = ad_mode("", 0777) | vol->v_fperm; - setfilmode(upath, admode, NULL, vol->v_umask); - vol->vfs->vfs_setfilmode(vol, upath, admode, NULL); + setfilmode(vol, upath, admode, path->st_valid ? &path->st : NULL); + vol->vfs->vfs_setfilmode(vol, upath, admode, path->st_valid ? &path->st : NULL); } setvoltime(obj, vol ); } diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 54e1c149..5af91207 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -317,7 +317,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si } } - if ((opened = of_findname(s_path))) { + if ((opened = of_findname(vol, s_path))) { adsame = opened->of_ad; } diff --git a/etc/afpd/fork.h b/etc/afpd/fork.h index d7120e47..5b63601f 100644 --- a/etc/afpd/fork.h +++ b/etc/afpd/fork.h @@ -59,13 +59,13 @@ extern struct ofork *of_alloc (struct vol *, struct dir *, struct stat *); extern void of_dealloc (struct ofork *); extern struct ofork *of_find (const uint16_t); -extern struct ofork *of_findname (struct path *); +extern struct ofork *of_findname (const struct vol *vol, struct path *); extern int of_rename (const struct vol *, struct ofork *, struct dir *, const char *, struct dir *, const char *); extern int of_flush (const struct vol *); -extern int of_stat (struct path *); +extern int of_stat (const struct vol *vol, struct path *); extern int of_statdir (struct vol *vol, struct path *); extern int of_closefork (const AFPObj *obj, struct ofork *ofork); extern void of_closevol (const AFPObj *obj, const struct vol *vol); diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 3f5a42b0..cf77d490 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -228,14 +228,14 @@ struct ofork *of_find(const uint16_t ofrefnum ) } /* -------------------------- */ -int of_stat(struct path *path) +int of_stat(const struct vol *vol, struct path *path) { int ret; path->st_errno = 0; path->st_valid = 1; - if ((ret = lstat(path->u_name, &path->st)) < 0) { + if ((ret = ostat(path->u_name, &path->st, vol_syml_opt(vol))) < 0) { LOG(log_debug, logtype_afpd, "of_stat('%s/%s': %s)", cfrombstr(curdir->d_fullpath), path->u_name, strerror(errno)); path->st_errno = errno; @@ -274,7 +274,7 @@ int of_statdir(struct vol *vol, struct path *path) if (*path->m_name) { /* not curdir */ - return of_stat (path); + return of_stat(vol, path); } path->st_errno = 0; path->st_valid = 1; @@ -286,7 +286,7 @@ int of_statdir(struct vol *vol, struct path *path) LOG(log_debug, logtype_afpd, "of_statdir: stating: '%s'", pathname); - if (!(ret = lstat(pathname, &path->st))) + if (!(ret = ostat(pathname, &path->st, vol_syml_opt(vol)))) return 0; path->st_errno = errno; @@ -297,7 +297,7 @@ int of_statdir(struct vol *vol, struct path *path) return -1; path->st_errno = 0; - if ((ret = lstat(cfrombstr(path->d_dir->d_u_name), &path->st)) < 0) + if ((ret = ostat(cfrombstr(path->d_dir->d_u_name), &path->st, vol_syml_opt(vol))) < 0) path->st_errno = errno; } @@ -305,13 +305,13 @@ int of_statdir(struct vol *vol, struct path *path) } /* -------------------------- */ -struct ofork *of_findname(struct path *path) +struct ofork *of_findname(const struct vol *vol, struct path *path) { struct ofork *of; struct file_key key; if (!path->st_valid) { - of_stat(path); + of_stat(vol, path); } if (path->st_errno) @@ -444,7 +444,7 @@ struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble * struct ofork *of; struct adouble *adp; - if ((of = of_findname(path))) { + if ((of = of_findname(vol, path))) { adp = of->of_ad; } else { ad_init(ad, vol); diff --git a/etc/afpd/quota.c b/etc/afpd/quota.c index 6903a216..5aa7f3f3 100644 --- a/etc/afpd/quota.c +++ b/etc/afpd/quota.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "auth.h" #include "volume.h" @@ -370,7 +371,7 @@ mountp( char *file, int *nfs) dev_t devno; static struct mnttab mnt; - if ( lstat( file, &sb ) < 0 ) { + if (stat(file, &sb) < 0) { return( NULL ); } devno = sb.st_dev; @@ -381,14 +382,14 @@ mountp( char *file, int *nfs) while ( getmntent( mtab, &mnt ) == 0 ) { /* local fs */ - if ( (lstat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) { + if ( (stat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) { fclose( mtab ); return mnt.mnt_mountp; } /* check for nfs. we probably should use * strcmp(mnt.mnt_fstype, MNTTYPE_NFS), but that's not as fast. */ - if ((lstat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) && + if ((stat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) && strchr(mnt.mnt_special, ':')) { *nfs = 1; fclose( mtab ); @@ -458,7 +459,7 @@ special(char *file, int *nfs) struct mntent *mnt; int found=0; - if ( lstat( file, &sb ) < 0 ) { + if (stat(file, &sb) < 0 ) { return( NULL ); } devno = sb.st_dev; @@ -469,14 +470,14 @@ special(char *file, int *nfs) while (( mnt = getmntent( mtab )) != NULL ) { /* check for local fs */ - if ( (lstat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) { + if ( (stat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) { found = 1; break; } /* check for an nfs mount entry. the alternative is to use * strcmp(mnt->mnt_type, MNTTYPE_NFS) instead of the strchr. */ - if ((lstat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) && + if ((stat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) && strchr(mnt->mnt_fsname, ':')) { *nfs = 1; found = 1; diff --git a/etc/afpd/unix.c b/etc/afpd/unix.c index 16562f3b..31086bb6 100644 --- a/etc/afpd/unix.c +++ b/etc/afpd/unix.c @@ -158,7 +158,7 @@ void accessmode(const AFPObj *obj, const struct vol *vol, char *path, struct mac ma->ma_user = ma->ma_owner = ma->ma_world = ma->ma_group = 0; if (!st) { - if (lstat(path, &sb) != 0) + if (ostat(path, &sb, vol_syml_opt(vol)) != 0) return; st = &sb; } @@ -207,7 +207,7 @@ mode_t mtoumode(struct maccess *ma) int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode) { if (!path->st_valid) { - of_stat(path); + of_stat(vol, path); } if (path->st_errno) { @@ -216,7 +216,7 @@ int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode) mode |= vol->v_fperm; - if (setfilmode( path->u_name, mode, &path->st, vol->v_umask) < 0) + if (setfilmode(vol, path->u_name, mode, &path->st) < 0) return -1; /* we need to set write perm if read set for resource fork */ return vol->vfs->vfs_setfilmode(vol, path->u_name, mode, &path->st); @@ -249,7 +249,7 @@ int setdirunixmode(const struct vol *vol, const char *name, mode_t mode) /* ----------------------------- */ int setfilowner(const struct vol *vol, const uid_t uid, const gid_t gid, struct path* path) { - if (lchown(path->u_name, uid, gid) < 0 && errno != EPERM) { + if (ochown( path->u_name, uid, gid, vol_syml_opt(vol)) < 0 && errno != EPERM ) { LOG(log_debug, logtype_afpd, "setfilowner: chown %d/%d %s: %s", uid, gid, path->u_name, strerror(errno)); return -1; @@ -271,7 +271,7 @@ int setfilowner(const struct vol *vol, const uid_t uid, const gid_t gid, struct * co-opting some bits. */ int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const gid_t gid) { - if (lchown(name, uid, gid ) < 0 && errno != EPERM ) { + if (ochown(name, uid, gid, vol_syml_opt(vol)) < 0 && errno != EPERM ) { LOG(log_debug, logtype_afpd, "setdirowner: chown %d/%d %s: %s", uid, gid, fullpathname(name), strerror(errno) ); } @@ -281,4 +281,3 @@ int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const return( 0 ); } - diff --git a/include/atalk/acl.h b/include/atalk/acl.h index 95aa0753..810be707 100644 --- a/include/atalk/acl.h +++ b/include/atalk/acl.h @@ -21,6 +21,8 @@ #ifdef HAVE_ACLS +#define O_NETATALK_ACL (O_NOFOLLOW << 1) + #ifdef HAVE_SOLARIS_ACLS #include @@ -51,6 +53,7 @@ extern int remove_acl_vfs(const char *name); #else /* HAVE_ACLS=no */ +#define O_NETATALK_ACL #define chmod_acl chmod #endif /* HAVE_ACLS */ diff --git a/include/atalk/adouble.h b/include/atalk/adouble.h index 384486ea..6e76e51b 100644 --- a/include/atalk/adouble.h +++ b/include/atalk/adouble.h @@ -247,6 +247,7 @@ struct adouble { #define ADVOL_NODEV (1 << 0) #define ADVOL_UNIXPRIV (1 << 2) /* adouble unix priv */ #define ADVOL_INVDOTS (1 << 3) /* dot files (.DS_Store) are invisible) */ +#define ADVOL_FOLLO_SYML (1 << 4) /* lock flags */ #define ADLOCK_CLR (0) @@ -369,6 +370,8 @@ struct adouble { #define ad_ref(ad) (ad)->ad_refcount++ #define ad_unref(ad) --((ad)->ad_refcount) +#define ad_get_syml_opt(ad) (((ad)->ad_options & ADVOL_FOLLO_SYML) ? 0 : O_NOFOLLOW) + /* ad_flush.c */ extern int ad_rebuild_adouble_header_v2(struct adouble *); extern int ad_rebuild_adouble_header_ea(struct adouble *); diff --git a/include/atalk/unix.h b/include/atalk/unix.h index 01997e94..067572ed 100644 --- a/include/atalk/unix.h +++ b/include/atalk/unix.h @@ -30,14 +30,13 @@ extern int netatalk_unlink(const char *name); extern int netatalk_unlinkat(int dirfd, const char *name); extern int statat(int dirfd, const char *path, struct stat *st); -extern int lstatat(int dirfd, const char *path, struct stat *st); extern DIR *opendirat(int dirfd, const char *path); /* rmdir ENOENT not an error */ extern int netatalk_rmdir(int dirfd, const char *name); extern int netatalk_rmdir_all_errors(int dirfd, const char *name); -extern int setfilmode(const char *, mode_t, struct stat *, mode_t); +extern int setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st); extern int dir_rx_set(mode_t mode); extern int unix_rename(int sfd, const char *oldpath, int dfd, const char *newpath); extern int copy_file(int sfd, const char *src, const char *dst, mode_t mode); diff --git a/include/atalk/util.h b/include/atalk/util.h index 30aba481..e278872b 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -178,7 +179,6 @@ extern int recv_fd(int fd, int nonblocking); extern const char *getcwdpath(void); extern const char *fullpathname(const char *); extern char *stripped_slashes_basename(char *p); -extern int lchdir(const char *dir); extern void randombytes(void *buf, int n); extern int daemonize(int nochdir, int noclose); extern int run_cmd(const char *cmd, char **cmd_argv); @@ -186,6 +186,12 @@ extern char *realpath_safe(const char *path); extern const char *basename_safe(const char *path); extern char *strtok_quote (char *s, const char *delim); +extern int ochdir(const char *dir, int options); +extern int ostat(const char *path, struct stat *buf, int options); +extern int ostatat(int dirfd, const char *path, struct stat *st, int options); +extern int ochown(const char *path, uid_t owner, gid_t group, int options); +extern int ochmod(const char *path, mode_t mode, const struct stat *st, int options); + /****************************************************************** * cnid.c *****************************************************************/ diff --git a/include/atalk/volume.h b/include/atalk/volume.h index e7f87724..b185f994 100644 --- a/include/atalk/volume.h +++ b/include/atalk/volume.h @@ -132,6 +132,7 @@ struct vol { #define AFPVOL_ACLS (1 << 24) /* Volume supports ACLS */ #define AFPVOL_SEARCHDB (1 << 25) /* Use fast CNID db search instead of filesystem */ #define AFPVOL_NONETIDS (1 << 26) /* signal the client it shall do privelege mapping */ +#define AFPVOL_FOLLOWSYM (1 << 27) /* follow symlinks on the server, default is not to */ /* Extended Attributes vfs indirection */ #define AFPVOL_EA_NONE 0 /* No EAs */ @@ -190,6 +191,6 @@ struct vol { #define vol_nodev(vol) (((vol)->v_flags & AFPVOL_NODEV) ? 1 : 0) #define vol_unix_priv(vol) ((vol)->v_obj->afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV)) #define vol_inv_dots(vol) (((vol)->v_flags & AFPVOL_INV_DOTS) ? 1 : 0) - +#define vol_syml_opt(vol) (((vol)->v_flags & AFPVOL_FOLLOWSYM) ? 0 : O_NOFOLLOW) #endif diff --git a/libatalk/acl/Makefile.am b/libatalk/acl/Makefile.am index 0e75ee9e..1013f46c 100644 --- a/libatalk/acl/Makefile.am +++ b/libatalk/acl/Makefile.am @@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libacl.la libacl_la_SOURCES = cache.c unix.c uuid.c libacl_la_CFLAGS = libacl_la_LDFLAGS = -libacl_la_LIBADD = +libacl_la_LIBADD = @ACL_LIBS@ if HAVE_LDAP libacl_la_SOURCES += ldap.c ldap_config.c diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index 4f3a832c..e66929f2 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -808,6 +808,9 @@ static int ad2openflags(const struct adouble *ad, int adfile, int adflags) if (adflags & ADFLAGS_TRUNC) oflags |= O_TRUNC; + if (!(ad->ad_options & ADVOL_FOLLO_SYML)) + oflags |= O_NOFOLLOW; + return oflags; } @@ -841,7 +844,7 @@ static int ad_open_df(const char *path, int adflags, mode_t mode, struct adouble goto EC_CLEANUP; } - oflags = O_NOFOLLOW | ad2openflags(ad, ADFLAGS_DF, adflags); + oflags = ad2openflags(ad, ADFLAGS_DF, adflags); admode = mode; if ((adflags & ADFLAGS_CREATE)) { @@ -929,7 +932,7 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou } ad_p = ad->ad_ops->ad_path(path, adflags); - oflags = O_NOFOLLOW | ad2openflags(ad, ADFLAGS_HF, adflags); + oflags = ad2openflags(ad, ADFLAGS_HF, adflags); LOG(log_debug, logtype_ad,"ad_open_hf_v2(\"%s\"): open flags: %s", fullpathname(path), openflags2logstr(oflags)); nocreatflags = oflags & ~(O_CREAT | O_EXCL); @@ -1041,7 +1044,7 @@ static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble ad_meta_fileno(ad), ad->ad_mdp->adf_refcount, ad_reso_fileno(ad), ad->ad_rfp->adf_refcount); - oflags = O_NOFOLLOW | (ad2openflags(ad, ADFLAGS_DF, adflags) & ~(O_CREAT | O_TRUNC)); + oflags = ad2openflags(ad, ADFLAGS_DF, adflags) & ~(O_CREAT | O_TRUNC); if (ad_meta_fileno(ad) == AD_SYMLINK) goto EC_CLEANUP; @@ -1221,7 +1224,7 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble LOG(log_debug, logtype_ad, "ad_open_rf(\"%s\"): BEGIN", fullpathname(path)); - oflags = O_NOFOLLOW | (ad2openflags(ad, ADFLAGS_RF, adflags) & ~O_CREAT); + oflags = ad2openflags(ad, ADFLAGS_RF, adflags) & ~O_CREAT; if (ad_reso_fileno(ad) != -1) { /* the file is already open, but we want write access: */ @@ -1500,7 +1503,7 @@ int ad_stat(const char *path, struct stat *stbuf) p = ad_dir(path); if (!p) return -1; - return lstat( p, stbuf ); + return stat( p, stbuf ); } /* ---------------- diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 01c6cb97..824c69f9 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -773,6 +773,8 @@ static struct vol *creatvol(AFPObj *obj, #endif if (!getoption_bool(obj->iniconfig, section, "convert appledouble", preset, 1)) volume->v_flags |= AFPVOL_NOV2TOEACONV; + if (getoption_bool(obj->iniconfig, section, "follow symlinks", preset, 0)) + volume->v_flags |= AFPVOL_FOLLOWSYM; if (getoption_bool(obj->iniconfig, section, "preexec close", preset, 0)) volume->v_preexec_close = 1; @@ -800,6 +802,8 @@ static struct vol *creatvol(AFPObj *obj, volume->v_ad_options |= ADVOL_UNIXPRIV; if ((volume->v_flags & AFPVOL_INV_DOTS)) volume->v_ad_options |= ADVOL_INVDOTS; + if ((volume->v_flags & AFPVOL_FOLLOWSYM)) + volume->v_ad_options |= ADVOL_FOLLO_SYML; /* Mac to Unix conversion flags*/ if ((volume->v_flags & AFPVOL_EILSEQ)) diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index bde1a7ca..a74ca80b 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -228,20 +228,103 @@ char *stripped_slashes_basename(char *p) return (strrchr(p, '/') ? strrchr(p, '/') + 1 : p); } +/********************************************************************************* + * chdir(), chmod(), chown(), stat() wrappers taking an additional option. + * Currently the only used options are O_NOFOLLOW, used to switch between symlink + * behaviour, and O_NETATALK_ACL for ochmod() indicating chmod_acl() shall be + * called which does special ACL handling depending on the filesytem + *********************************************************************************/ + +int ostat(const char *path, struct stat *buf, int options) +{ + if (options & O_NOFOLLOW) + return lstat(path, buf); + else + return stat(path, buf); +} + +int ochown(const char *path, uid_t owner, gid_t group, int options) +{ + if (options & O_NOFOLLOW) + return lchown(path, owner, group); + else + return chown(path, owner, group); +} + +/*! + * chmod() wrapper for symlink and ACL handling + * + * @param path (r) path + * @param mode (r) requested mode + * @param sb (r) stat() of path or NULL + * @param option (r) O_NOFOLLOW | O_NETATALK_ACL + * + * Options description: + * O_NOFOLLOW: don't chmod() symlinks, do nothing, return 0 + * O_NETATALK_ACL: call chmod_acl() instead of chmod() + */ +int ochmod(const char *path, mode_t mode, const struct stat *st, int options) +{ + struct stat sb; + + if (!st) { + if (lstat(path, &sb) != 0) + return -1; + st = &sb; + } + + if (options & O_NOFOLLOW) + if (S_ISLNK(st->st_mode)) + return 0; + + if (options & O_NETATALK_ACL) { + return chmod_acl(path, mode); + } else { + return chmod(path, mode); + } +} + +/* + * @brief ostat/fsstatat multiplexer + * + * ostatat mulitplexes ostat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored. + * + * @param dirfd (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD + * @param path (r) pathname + * @param st (rw) pointer to struct stat + */ +int ostatat(int dirfd, const char *path, struct stat *st, int options) +{ +#ifdef HAVE_ATFUNCS + if (dirfd == -1) + dirfd = AT_FDCWD; + return fstatat(dirfd, path, st, (options & O_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0); +#else + return ostat(path, st, options); +#endif + + /* DEADC0DE */ + return -1; +} + /*! * @brief symlink safe chdir replacement * - * Only chdirs to dir if it doesn't contain symlinks. + * Only chdirs to dir if it doesn't contain symlinks or if symlink checking + * is disabled * * @returns 1 if a path element is a symlink, 0 otherwise, -1 on syserror */ -int lchdir(const char *dir) +int ochdir(const char *dir, int options) { char buf[MAXPATHLEN+1]; char cwd[MAXPATHLEN+1]; char *test; int i; + if (!(options & O_NOFOLLOW)) + return chdir(dir); + /* dir is a canonical path (without "../" "./" "//" ) but may end with a / diff --git a/libatalk/vfs/ea_ad.c b/libatalk/vfs/ea_ad.c index cdc7c828..e229d7be 100644 --- a/libatalk/vfs/ea_ad.c +++ b/libatalk/vfs/ea_ad.c @@ -906,7 +906,7 @@ int ea_close(struct ea * restrict ea) if (ea->ea_count == 0) { /* Check if EA header exists and remove it */ eaname = ea_path(ea, NULL, 0); - if ((lstatat(ea->dirfd, eaname, &st)) == 0) { + if ((statat(ea->dirfd, eaname, &st)) == 0) { if ((netatalk_unlinkat(ea->dirfd, eaname)) != 0) { LOG(log_error, logtype_afpd, "ea_close('%s'): unlink: %s", eaname, strerror(errno)); @@ -1583,7 +1583,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN) } } - if ((lchown(ea_path(&ea, NULL, 0), uid, gid)) != 0) { + if ((ochown(ea_path(&ea, NULL, 0), uid, gid, vol_syml_opt(vol))) != 0) { switch (errno) { case EPERM: case EACCES: @@ -1600,7 +1600,7 @@ int ea_chown(VFS_FUNC_ARGS_CHOWN) ret = AFPERR_MISC; goto exit; } - if ((lchown(eaname, uid, gid)) != 0) { + if ((ochown(eaname, uid, gid, vol_syml_opt(vol))) != 0) { switch (errno) { case EPERM: case EACCES: @@ -1644,7 +1644,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE) } /* Set mode on EA header file */ - if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno)); switch (errno) { case EPERM: @@ -1663,7 +1663,7 @@ int ea_chmod_file(VFS_FUNC_ARGS_SETFILEMODE) ret = AFPERR_MISC; goto exit; } - if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_file('%s'): %s", eaname, strerror(errno)); switch (errno) { case EPERM: @@ -1712,7 +1712,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE) } /* Set mode on EA header */ - if ((setfilmode(ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, ea_path(&ea, NULL, 0), ea_header_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", ea_path(&ea, NULL, 0), strerror(errno)); switch (errno) { case EPERM: @@ -1742,7 +1742,7 @@ int ea_chmod_dir(VFS_FUNC_ARGS_SETDIRUNIXMODE) ret = AFPERR_MISC; goto exit; } - if ((setfilmode(eaname, ea_mode(mode), NULL, vol->v_umask)) != 0) { + if ((setfilmode(vol, eaname, ea_mode(mode), NULL)) != 0) { LOG(log_error, logtype_afpd, "ea_chmod_dir('%s'): %s", eaname, strerror(errno)); switch (errno) { case EPERM: diff --git a/libatalk/vfs/unix.c b/libatalk/vfs/unix.c index 1c0556d9..40f14fb5 100644 --- a/libatalk/vfs/unix.c +++ b/libatalk/vfs/unix.c @@ -33,7 +33,7 @@ int dir_rx_set(mode_t mode) } /* --------------------- */ -int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) +int setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st) { struct stat sb; mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO; /* rwx for owner group and other, by default */ @@ -44,12 +44,9 @@ int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) st = &sb; } - if (S_ISLNK(st->st_mode)) - return 0; /* we don't want to change link permissions */ - mode |= st->st_mode & ~mask; /* keep other bits from previous mode */ - if ( chmod_acl( name, mode & ~v_umask ) < 0 && errno != EPERM ) { + if (ochmod(name, mode & ~vol->v_umask, st, vol_syml_opt(vol) | O_NETATALK_ACL) < 0 && errno != EPERM ) { return -1; } return 0; @@ -334,29 +331,6 @@ int statat(int dirfd, const char *path, struct stat *st) return -1; } -/* - * @brief lstat/fsstatat multiplexer - * - * lstatat mulitplexes lstat and fstatat. If we dont HAVE_ATFUNCS, dirfd is ignored. - * - * @param dirfd (r) Only used if HAVE_ATFUNCS, ignored else, -1 gives AT_FDCWD - * @param path (r) pathname - * @param st (rw) pointer to struct stat - */ -int lstatat(int dirfd, const char *path, struct stat *st) -{ -#ifdef HAVE_ATFUNCS - if (dirfd == -1) - dirfd = AT_FDCWD; - return (fstatat(dirfd, path, st, AT_SYMLINK_NOFOLLOW)); -#else - return (lstat(path, st)); -#endif - - /* DEADC0DE */ - return -1; -} - /* * @brief opendir wrapper for *at semantics support * diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 8495d8c2..85704976 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -49,11 +49,11 @@ struct perm { gid_t gid; }; -typedef int (*rf_loop)(struct dirent *, char *, void *, int , mode_t ); +typedef int (*rf_loop)(const struct vol *, struct dirent *, char *, void *, int); /* ----------------------------- */ static int -for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int flag, mode_t v_umask) +for_each_adouble(const char *from, const char *name, rf_loop fn, const struct vol *vol, void *data, int flag) { char buf[ MAXPATHLEN + 1]; char *m; @@ -79,7 +79,7 @@ for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int } strlcat(buf, de->d_name, sizeof(buf)); - if (fn && (ret = fn(de, buf, data, flag, v_umask))) { + if (fn && (ret = fn(vol, de, buf, data, flag))) { closedir(dp); return ret; } @@ -127,7 +127,7 @@ static int RF_renamedir_adouble(VFS_FUNC_ARGS_RENAMEDIR) } /* ----------------- */ -static int deletecurdir_adouble_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask) +static int deletecurdir_adouble_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) { struct stat st; int err; @@ -150,20 +150,20 @@ static int RF_deletecurdir_adouble(VFS_FUNC_ARGS_DELETECURDIR) /* delete stray .AppleDouble files. this happens to get .Parent files as well. */ - if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, NULL, 1, vol->v_umask))) + if ((err = for_each_adouble("deletecurdir", ".AppleDouble", deletecurdir_adouble_loop, vol, NULL, 1))) return err; return netatalk_rmdir(-1, ".AppleDouble" ); } /* ----------------- */ -static int adouble_setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) +static int adouble_setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat *st) { - return setfilmode(name, ad_hf_mode(mode), st, v_umask); + return setfilmode(vol, name, ad_hf_mode(mode), st); } static int RF_setfilmode_adouble(VFS_FUNC_ARGS_SETFILEMODE) { - return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask); + return adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_HF ), mode, st); } /* ----------------- */ @@ -177,7 +177,7 @@ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE) return -1; } - if (adouble_setfilmode(vol->ad_path(name, ADFLAGS_DIR ), mode, st, vol->v_umask) < 0) + if (adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_DIR ), mode, st) < 0) return -1; if (!dir_rx_set(mode)) { @@ -188,18 +188,18 @@ static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE) } /* ----------------- */ -static int setdirmode_adouble_loop(struct dirent *de _U_, char *name, void *data, int flag, mode_t v_umask) +static int setdirmode_adouble_loop(const struct vol *vol, struct dirent *de _U_, char *name, void *data, int flag) { mode_t hf_mode = *(mode_t *)data; struct stat st; - if ( stat( name, &st ) < 0 ) { + if (ostat(name, &st, vol_syml_opt(vol)) < 0 ) { if (flag) return 0; LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s", name, strerror(errno) ); } else if (!S_ISDIR(st.st_mode)) { - if (setfilmode(name, hf_mode , &st, v_umask) < 0) { + if (setfilmode(vol, name, hf_mode, &st) < 0) { /* FIXME what do we do then? */ } } @@ -257,7 +257,7 @@ static int RF_renamefile_adouble(VFS_FUNC_ARGS_RENAMEFILE) if (errno == ENOENT) { struct adouble ad; - if (lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ + if (ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */ return 0; /* We are here because : @@ -643,7 +643,7 @@ static int RF_renamefile_ea(VFS_FUNC_ARGS_RENAMEFILE) struct stat st; err = errno; - if (errno == ENOENT && lstatat(dirfd, adsrc, &st)) /* source has no ressource fork, */ + if (errno == ENOENT && ostatat(dirfd, adsrc, &st, vol_syml_opt(vol))) /* source has no ressource fork, */ return 0; errno = err; return -1; diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index d2bbf43a..4a41167b 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: afp.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 06 Dez 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AFP\&.CONF" "5" "06 Dez 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -113,7 +122,7 @@ parameter means that not the whole user home will be shared but the subdirectory option\&. It should be a regex which matches the parent directory of the user homes\&. Parameters denoted by a (H) belong to volume sections\&. The optional parameter \fBhome name\fR can be used to change the AFP volume name which -\fI$u\'s home\fR +\fI$u\*(Aqs home\fR by default\&. See below under VARIABLE SUBSTITUTIONS\&. .PP The following example illustrates this\&. Given all user home directories are stored under @@ -167,7 +176,7 @@ if you specify an unknown variable, it will not get converted\&. .sp -1 .IP " 2." 4.2 .\} -if you specify a known variable, but that variable doesn\'t have a value, it will get ignored\&. +if you specify a known variable, but that variable doesn\*(Aqt have a value, it will get ignored\&. .RE .PP The variables which can be used for substitutions are: @@ -179,7 +188,7 @@ basename .PP $c .RS 4 -client\'s ip address +client\*(Aqs ip address .RE .PP $d @@ -204,7 +213,7 @@ hostname .PP $i .RS 4 -client\'s ip, without port +client\*(Aqs ip, without port .RE .PP $s @@ -310,7 +319,7 @@ With OS X Apple introduced the AFP3 protocol\&. One of the big changes was, that .PP To be able to serve AFP3 and older clients at the same time, \fBafpd\fR -needs to be able to convert between UTF\-8 and Mac charsets\&. Even OS X clients partly still rely on the mac charset\&. As there\'s no way, +needs to be able to convert between UTF\-8 and Mac charsets\&. Even OS X clients partly still rely on the mac charset\&. As there\*(Aqs no way, \fBafpd\fR can detect the codepage a pre AFP3 client uses, you have to specify it using the \fBmac charset\fR @@ -318,12 +327,12 @@ option\&. The default is MacRoman, which should be fine for most western users\& .PP As \fBafpd\fR -needs to interact with UNIX operating system as well, it need\'s to be able to convert from UTF8\-MAC / Mac charset to the UNIX charset\&. By default +needs to interact with UNIX operating system as well, it need\*(Aqs to be able to convert from UTF8\-MAC / Mac charset to the UNIX charset\&. By default \fBafpd\fR uses \fIUTF8\fR\&. You can set the UNIX charset using the \fBunix charset\fR -option\&. If you\'re using extended characters in the configuration files for +option\&. If you\*(Aqre using extended characters in the configuration files for \fBafpd\fR, make sure your terminal matches the \fBunix charset\fR\&. .PP @@ -366,7 +375,7 @@ Sets the minimum password length, if supported by the UAM .PP advertise ssh = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR .RS 4 -Allows old Mac OS X clients (10\&.3\&.3\-10\&.4) to automagically establish a tunneled AFP connection through SSH\&. If this option is set, the server\'s answers to client\'s FPGetSrvrInfo requests contain an additional entry\&. It depends on both client\'s settings and a correctly configured and running +Allows old Mac OS X clients (10\&.3\&.3\-10\&.4) to automagically establish a tunneled AFP connection through SSH\&. If this option is set, the server\*(Aqs answers to client\*(Aqs FPGetSrvrInfo requests contain an additional entry\&. It depends on both client\*(Aqs settings and a correctly configured and running \fBsshd\fR(8) on the server to let things work\&. .if n \{\ @@ -381,7 +390,7 @@ on the server to let things work\&. \fBNote\fR .ps -1 .br -Setting this option is not recommended since globally encrypting AFP connections via SSH will increase the server\'s load significantly\&. On the other hand, Apple\'s client side implementation of this feature in MacOS X versions prior to 10\&.3\&.4 contained a security flaw\&. +Setting this option is not recommended since globally encrypting AFP connections via SSH will increase the server\*(Aqs load significantly\&. On the other hand, Apple\*(Aqs client side implementation of this feature in MacOS X versions prior to 10\&.3\&.4 contained a security flaw\&. .sp .5v .RE .RE @@ -437,7 +446,7 @@ Sets the maximum number of clients that can simultaneously connect to the server .PP server quantum = \fInumber\fR \fB(G)\fR .RS 4 -This specifies the DSI server quantum\&. The default value is 303840\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\'re absolutely sure, what you\'re doing +This specifies the DSI server quantum\&. The default value is 303840\&. The maximum value is 0xFFFFFFFFF, the minimum is 32000\&. If you specify a value that is out of range, the default value will be set\&. Do not change this value unless you\*(Aqre absolutely sure, what you\*(Aqre doing .RE .PP sleep time = \fInumber\fR \fB(G)\fR @@ -477,7 +486,7 @@ Allows users of a certain group to be seen as the superuser when they log in\&. .PP afp read locks = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR .RS 4 -Whether to apply locks to the byte region read in FPRead calls\&. The AFP spec mandates this, but it\'s not really in line with UNIX semantics and is a performance hug\&. +Whether to apply locks to the byte region read in FPRead calls\&. The AFP spec mandates this, but it\*(Aqs not really in line with UNIX semantics and is a performance hug\&. .RE .PP basedir regex = \fIregex\fR \fB(H)\fR @@ -488,7 +497,7 @@ Regular expression which matches the parent directory of the user homes\&. In th .PP close vol = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR .RS 4 -Whether to close volumes possibly opened by clients when they\'re removed from the configuration and the configuration is reloaded\&. +Whether to close volumes possibly opened by clients when they\*(Aqre removed from the configuration and the configuration is reloaded\&. .RE .PP cnid server = \fIipaddress[:port]\fR \fB(G)/(V)\fR @@ -516,7 +525,7 @@ Specifies the user that guests should use (default is "nobody")\&. The name shou home name = \fIname\fR \fB(H)\fR .RS 4 AFP user home volume name\&. The default is -\fIusers\'s home\fR\&. +\fIusers\*(Aqs home\fR\&. .RE .PP keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR @@ -584,7 +593,7 @@ vol preset = \fIname\fR \fB(G)/(V)\fR .RS 4 Use section \fBname\fR -as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\'s section)\&. +as option preset for all volumes (when set in the [Global] section) or for one volume (when set in that volume\*(Aqs section)\&. .RE .SS "Logging Options" .PP @@ -665,16 +674,16 @@ Specify the number of tickles to send before timing out a connection\&. The defa .PP client polling = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR .RS 4 -With this option enabled, afpd won\'t advertise that it is capable of server notifications, so that connected clients poll the server every 10 seconds to detect changes in opened server windows\&. -\fINote\fR: Depending on the number of simultaneously connected clients and the network\'s speed, this can lead to a significant higher load on your network! +With this option enabled, afpd won\*(Aqt advertise that it is capable of server notifications, so that connected clients poll the server every 10 seconds to detect changes in opened server windows\&. +\fINote\fR: Depending on the number of simultaneously connected clients and the network\*(Aqs speed, this can lead to a significant higher load on your network! .sp Do not use this option any longer as present Netatalk correctly supports server notifications, allowing connected clients to update folder listings in case another client changed the contents\&. .RE .SS "Options for ACL handling" .PP -For a basic mode of operation there\'s nothing to configure\&. afpd reads ACLs on the fly, calculating effective permissions and returning the calculated permissions via the so called UARights permission bits\&. On a Mac the Finder uses these bits to adjust permission in Finder windows\&. For example folder whos UNIX mode would only result in in read\-only permissions for a user will not be displayed with a read\-only icon and the user will be able to write to the folder given the folder has an ACL giving the user write access\&. +For a basic mode of operation there\*(Aqs nothing to configure\&. afpd reads ACLs on the fly, calculating effective permissions and returning the calculated permissions via the so called UARights permission bits\&. On a Mac the Finder uses these bits to adjust permission in Finder windows\&. For example folder whos UNIX mode would only result in in read\-only permissions for a user will not be displayed with a read\-only icon and the user will be able to write to the folder given the folder has an ACL giving the user write access\&. .PP -However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\'s a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involed as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\'s or gid\'s\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&. +However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\*(Aqs a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involed as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\*(Aqs or gid\*(Aqs\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&. .PP Netatalk can query a directory server using LDAP queries\&. Either the directory server already provides an UUID attribute for user and groups (Active Directory, Open Directory) or you reuse an unused attribute (or add a new one) to you directory server (eg OpenLDAP)\&. .PP @@ -784,7 +793,7 @@ Name of the LDAP attribute with the groups short name\&. .SS "Parameters" .PP The section name defines the volume name which is the name that appears in the Chooser or the "connect to server" dialog on Macintoshes to represent the appropriate share\&. No two volumes may have the same name\&. The volume name cannot contain the -\':\' +\*(Aq:\*(Aq character\&. The volume name is mangled if it is very long\&. Mac charset volume name is limited to 27 characters\&. UTF8\-MAC volume name is limited to volnamelen parameter\&. .PP path = \fIPATH\fR \fB(V)\fR @@ -792,7 +801,7 @@ path = \fIPATH\fR \fB(V)\fR The path name must be a fully qualified path name, or a path name using either the ~ shell shorthand or any of the substitution variables, which are listed below\&. .sp The volume name is the name that appears in the Chooser ot the "connect to server" dialog on Macintoshes to represent the appropriate share\&. If volumename is unspecified, the last component of pathname is used\&. No two volumes may have the same name\&. If there are spaces in the name, it should be in quotes (i\&.e\&. "File Share")\&. The volume name cannot contain the -\':\' +\*(Aq:\*(Aq character\&. The volume name is mangled if it is very long\&. Mac charset volume name is limited to 27 characters\&. UTF8\-MAC volume name is limited to volnamelen parameter\&. .RE .PP @@ -919,7 +928,7 @@ Add(or) with the client requested permissions: \fBfile perm\fR is for files only, \fBdirectory perm\fR -is for directories only\&. Don\'t use with "\fBunix priv = no\fR"\&. +is for directories only\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&. .PP \fBExample.\ \&Volume for a collaborative workgroup\fR .sp @@ -938,7 +947,7 @@ file perm = 0660 directory perm = .PP umask = \fImode\fR \fB(V)\fR .RS 4 -set perm mask\&. Don\'t use with "\fBunix priv = no\fR"\&. +set perm mask\&. Don\*(Aqt use with "\fBunix priv = no\fR"\&. .RE .PP preexec = \fIcommand\fR \fB(V)\fR @@ -973,7 +982,7 @@ Allows certain users and groups to have read/write access to a share\&. This fol .PP veto files = \fIvetoed names\fR \fB(V)\fR .RS 4 -hide files and directories,where the path matches one of the \'/\' delimited vetoed names\&. The veto string must always be terminated with a \'/\', eg\&. "veto1/", "veto1/veto2/"\&. +hide files and directories,where the path matches one of the \*(Aq/\*(Aq delimited vetoed names\&. The veto string must always be terminated with a \*(Aq/\*(Aq, eg\&. "veto1/", "veto1/veto2/"\&. .RE .SS "Volume options" .PP @@ -995,11 +1004,16 @@ Whether automatic conversion from \fBappledouble = v2\fR to \fBappledouble = ea\fR -is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\'s recommdable to run +is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\*(Aqs recommdable to run \fBdbd\fR on volumes and do the conversion with that\&. Then this option can be set to no\&. .RE .PP +follow symlinks = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR +.RS 4 +The default setting is false thus symlinks are not followed on the server\&. This is the same behaviour as OS X\*(Aqs 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\*(Aqt do any checks for "wide symlinks"\&. +.RE +.PP invisible dots = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR .RS 4 make dot files invisible\&. @@ -1055,7 +1069,7 @@ and .RE .SH "CNID BACKENDS" .PP -The AFP protocol mostly refers to files and directories by ID and not by name\&. Netatalk needs a way to store these ID\'s in a persistent way, to achieve this several different CNID backends are available\&. The CNID Databases are by default located in the +The AFP protocol mostly refers to files and directories by ID and not by name\&. Netatalk needs a way to store these ID\*(Aqs in a persistent way, to achieve this several different CNID backends are available\&. The CNID Databases are by default located in the :STATEDIR:/netatalk/CNID/(volumename)/\&.AppleDB/ directory\&. .PP @@ -1082,7 +1096,7 @@ processes communicate with the daemon for database reads and updates\&. If built .PP last .RS 4 -This backend is an exception, in terms of ID persistency\&. ID\'s are only valid for the current session\&. This is basically what +This backend is an exception, in terms of ID persistency\&. ID\*(Aqs are only valid for the current session\&. This is basically what \fBafpd\fR did in the 1\&.5 (and 1\&.6) versions\&. This backend is still available, as it is useful for e\&.g\&. sharing cdroms\&. Starting with Netatalk 3\&.0, it becomes the \fIread only mode\fR @@ -1097,20 +1111,20 @@ now relies heavily on a persistent ID database\&. Aliases will likely not work a .PP Even though \fB\&./configure \-\-help\fR -might show that there are other CNID backends available, be warned those are likely broken or mainly used for testing\&. Don\'t use them unless you know what you\'re doing, they may be removed without further notice from future versions\&. +might show that there are other CNID backends available, be warned those are likely broken or mainly used for testing\&. Don\*(Aqt use them unless you know what you\*(Aqre doing, they may be removed without further notice from future versions\&. .SH "CHARSET OPTIONS" .PP With OS X Apple introduced the AFP3 protocol\&. One of the most important changes was that AFP3 uses unicode names encoded as UTF\-8 decomposed\&. Previous AFP/OS versions used codepages, like MacRoman, MacCentralEurope, etc\&. .PP \fBafpd\fR needs a way to preserve extended macintosh characters, or characters illegal in unix filenames, when saving files on a unix filesystem\&. Earlier versions used the the so called CAP encoding\&. An extended character (>0x7F) would be converted to a :xx sequence, e\&.g\&. the Apple Logo (MacRoman: 0xF0) was saved as -:f0\&. Some special characters will be converted as to :xx notation as well\&. \'/\' will be encoded to +:f0\&. Some special characters will be converted as to :xx notation as well\&. \*(Aq/\*(Aq will be encoded to :2f, if \fBusedots\fR -is not specified, a leading dot \'\&.\' will be encoded as +is not specified, a leading dot \*(Aq\&.\*(Aq will be encoded as :2e\&. .PP -This version now uses UTF\-8 as the default encoding for names\&. \'/\' will be converted to \':\'\&. +This version now uses UTF\-8 as the default encoding for names\&. \*(Aq/\*(Aq will be converted to \*(Aq:\*(Aq\&. .PP The \fBvol charset\fR @@ -1126,7 +1140,7 @@ to the selected will convert the UTF\-8 character to \fBmac charset\fR -first\&. If this conversion fails, you\'ll receive a \-50 error on the mac\&. +first\&. If this conversion fails, you\*(Aqll receive a \-50 error on the mac\&. .PP \fINote\fR: Whenever you can, please stick with the default UTF\-8 volume format\&. .SH "SEE ALSO" From 41d41bdfd9132328f70f27ea09b04783a0650c05 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sun, 30 Dec 2012 09:56:20 +0100 Subject: [PATCH 084/117] Set charset names --- bin/misc/netacnv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/misc/netacnv.c b/bin/misc/netacnv.c index e42c76b5..d82d0073 100644 --- a/bin/misc/netacnv.c +++ b/bin/misc/netacnv.c @@ -70,6 +70,9 @@ int main(int argc, char **argv) } string = argv[optind]; + set_charset_name(CH_UNIX, "UTF8"); + set_charset_name(CH_MAC, "MAC_ROMAN"); + if ( (charset_t) -1 == (from = add_charset(f ? f : "UTF8-MAC")) ) { fprintf( stderr, "Setting codepage %s as from codepage failed\n", f ? f : "UTF8-MAC"); return (-1); From fcd58ba83962ceb8bfede0bad55df6f10ceb9b8c Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 2 Jan 2013 11:53:32 +0100 Subject: [PATCH 085/117] strdup optarg and add -m option for specifying the Mac charset --- bin/misc/netacnv.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/bin/misc/netacnv.c b/bin/misc/netacnv.c index d82d0073..e9721cea 100644 --- a/bin/misc/netacnv.c +++ b/bin/misc/netacnv.c @@ -39,29 +39,32 @@ int main(int argc, char **argv) { int opt; uint16_t flags = 0; - char *string; + char *string, *macName = MACCHARSET; char *f = NULL, *t = NULL; charset_t from, to, mac; - while ((opt = getopt(argc, argv, ":o:f:t:")) != -1) { + while ((opt = getopt(argc, argv, "m::o:f:t:")) != -1) { switch(opt) { + case 'm': + macName = strdup(optarg); + break; case 'o': for (int i = 0; i < sizeof(flag_map)/sizeof(struct flag_map) - 1; i++) if ((strcmp(flag_map[i].flagname, optarg)) == 0) flags |= flag_map[i].flag; break; case 'f': - f = optarg; + f = strdup(optarg); break; case 't': - t = optarg; + t = strdup(optarg); break; } } if ((optind + 1) != argc) { - printf("Usage: test [-o [...]] [-f ] [-t ] \n"); - printf("Defaults: -f: UTF8-MAC , -t: UTF8 \n"); + printf("Usage: test [-o [...]] [-f ] [-t ] [-m legacy Mac charset] \n"); + printf("Defaults: -f: UTF8-MAC, -t: UTF8, -m MAC_ROMAN\n"); printf("Available conversion options:\n"); for (int i = 0; i < (sizeof(flag_map)/sizeof(struct flag_map) - 1); i++) { printf("%s\n", flag_map[i].flagname); @@ -71,7 +74,7 @@ int main(int argc, char **argv) string = argv[optind]; set_charset_name(CH_UNIX, "UTF8"); - set_charset_name(CH_MAC, "MAC_ROMAN"); + set_charset_name(CH_MAC, macName); if ( (charset_t) -1 == (from = add_charset(f ? f : "UTF8-MAC")) ) { fprintf( stderr, "Setting codepage %s as from codepage failed\n", f ? f : "UTF8-MAC"); @@ -83,7 +86,7 @@ int main(int argc, char **argv) return (-1); } - if ( (charset_t) -1 == (mac = add_charset(MACCHARSET)) ) { + if ( (charset_t) -1 == (mac = add_charset(macName)) ) { fprintf( stderr, "Setting codepage %s as Mac codepage failed\n", MACCHARSET); return (-1); } From 792549050b6b4ee345e59c59daf559fb8590a88e Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 2 Jan 2013 12:07:36 +0100 Subject: [PATCH 086/117] Simple fix, remove doubled colon from getopt string --- bin/misc/netacnv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/misc/netacnv.c b/bin/misc/netacnv.c index e9721cea..5e664b1e 100644 --- a/bin/misc/netacnv.c +++ b/bin/misc/netacnv.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) char *f = NULL, *t = NULL; charset_t from, to, mac; - while ((opt = getopt(argc, argv, "m::o:f:t:")) != -1) { + while ((opt = getopt(argc, argv, "m:o:f:t:")) != -1) { switch(opt) { case 'm': macName = strdup(optarg); From f0087cb672350d53ba16a1df8654815a4b5d9841 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 2 Jan 2013 13:36:16 +0100 Subject: [PATCH 087/117] Fix several VFS inconsistencies acb180395693ed05a4e6a1edb6796c8e6f644a72 left several for_each_adouble() calls broken. --- libatalk/vfs/vfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 85704976..53b53064 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -218,7 +218,7 @@ static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE) return -1; } - if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, &hf_mode, 0, vol->v_umask)) + if (for_each_adouble("setdirmode", adouble_p, setdirmode_adouble_loop, vol, &hf_mode, 0)) return -1; if (!dir_rx_set(mode)) { @@ -487,7 +487,7 @@ static int RF_renamedir_ea(VFS_FUNC_ARGS_RENAMEDIR) } /* Returns 1 if the entry is NOT an ._ file */ -static int deletecurdir_ea_osx_chkifempty_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_) +static int deletecurdir_ea_osx_chkifempty_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) { if (de->d_name[0] != '.' || de->d_name[0] == '_') return 1; @@ -495,7 +495,7 @@ static int deletecurdir_ea_osx_chkifempty_loop(struct dirent *de, char *name, vo return 0; } -static int deletecurdir_ea_osx_loop(struct dirent *de, char *name, void *data _U_, int flag _U_, mode_t v_umask _U_) +static int deletecurdir_ea_osx_loop(const struct vol *vol, struct dirent *de, char *name, void *data _U_, int flag _U_) { int ret; @@ -515,7 +515,7 @@ static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR) /* first check if there's really no other file besides files starting with ._ */ if ((err = for_each_adouble("deletecurdir_ea_osx", ".", deletecurdir_ea_osx_chkifempty_loop, - NULL, 0, 0)) != 0) { + vol, NULL, 0)) != 0) { if (err == 1) return AFPERR_DIRNEMPT; return AFPERR_MISC; @@ -524,7 +524,7 @@ static int RF_deletecurdir_ea(VFS_FUNC_ARGS_DELETECURDIR) /* Now delete orphaned ._ files */ if ((err = for_each_adouble("deletecurdir_ea_osx", ".", deletecurdir_ea_osx_loop, - NULL, 0, 0)) != 0) + vol, NULL, 0)) != 0) return err; #endif @@ -542,7 +542,7 @@ static int RF_setdirunixmode_ea(VFS_FUNC_ARGS_SETDIRUNIXMODE) static int RF_setfilmode_ea(VFS_FUNC_ARGS_SETFILEMODE) { #ifndef HAVE_EAFD - return adouble_setfilmode(vol->ad_path(name, ADFLAGS_HF ), mode, st, vol->v_umask); + return adouble_setfilmode(vol, vol->ad_path(name, ADFLAGS_HF ), mode, st); #endif return 0; } From 13bebcc1ecba3d0d187168d5c321d4bbdd3a898e Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Tue, 1 Jan 2013 21:57:58 +0100 Subject: [PATCH 088/117] Fix for adflags --- etc/afpd/file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 963268fe..e33b0e3a 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -604,7 +604,7 @@ int getfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct pat struct adouble ad, *adp; int opened = 0; int rc; - int flags; + int flags; /* uninitialized ok */ LOG(log_debug, logtype_afpd, "getfilparams(\"%s\")", path->u_name); @@ -640,7 +640,9 @@ int getfilparams(const AFPObj *obj, struct vol *vol, uint16_t bitmap, struct pat } } rc = getmetadata(obj, vol, bitmap, path, dir, buf, buflen, adp); - ad_close(adp, ADFLAGS_HF | flags); + + if (opened) + ad_close(adp, ADFLAGS_HF | flags); return( rc ); } From d5e184ceaaa8d805d89baf6f7da006bfcb84bf4e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 16:07:15 +0100 Subject: [PATCH 089/117] Initialize CopyRootInfo in reinit_db Spotted by cppcheck, from Riccardo Magliocchetti. --- etc/cnid_dbd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index 72df4078..edbe60f8 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -243,7 +243,7 @@ static int reinit_db(void) { EC_INIT; DBT key, data; - bool copyRootInfo; + bool copyRootInfo = false; if (dbd) { memset(&key, 0, sizeof(key)); From 3bff0d45274b4d8b79501729e3511e306981d628 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:07:50 +0100 Subject: [PATCH 090/117] Fix O_NETATALK_ACL define in case ACL headers are not found Spotted by cppcheck, from Riccardo Magliocchetti. --- include/atalk/acl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/atalk/acl.h b/include/atalk/acl.h index 810be707..d30a25c1 100644 --- a/include/atalk/acl.h +++ b/include/atalk/acl.h @@ -53,7 +53,7 @@ extern int remove_acl_vfs(const char *name); #else /* HAVE_ACLS=no */ -#define O_NETATALK_ACL +#define O_NETATALK_ACL 0 #define chmod_acl chmod #endif /* HAVE_ACLS */ From aa6ddafcff28b21dbd3328839fedbfab1b5b5498 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:09:51 +0100 Subject: [PATCH 091/117] Check for memcpy and don't redefine if found Spotted by cppcheck, from Riccardo Magliocchetti. --- configure.ac | 2 +- libatalk/util/ftw.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 116c3fa5..bfb578ca 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ AC_CHECK_MEMBERS(struct tm.tm_gmtoff,,, [#include ]) dnl these tests have been comfirmed to be needed in 2011 AC_CHECK_FUNCS(backtrace_symbols dirfd getusershell pread pwrite pselect) -AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen) +AC_CHECK_FUNCS(setlinebuf strlcat strlcpy strnlen mempcpy) AC_CHECK_FUNCS(mmap utime getpagesize) dnl needed by tbd dnl search for necessary libraries diff --git a/libatalk/util/ftw.c b/libatalk/util/ftw.c index 3a32c12e..f0ac17f1 100644 --- a/libatalk/util/ftw.c +++ b/libatalk/util/ftw.c @@ -45,7 +45,9 @@ #include +#ifndef HAVE_MEMPCPY #define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) +#endif #define NDEBUG 1 #include From 4ebe4dc02550b9ccf667076c6e3843bffb3d57c4 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:28:37 +0100 Subject: [PATCH 092/117] Forward declate struct vol --- include/atalk/unix.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/atalk/unix.h b/include/atalk/unix.h index 067572ed..d3378ccb 100644 --- a/include/atalk/unix.h +++ b/include/atalk/unix.h @@ -26,6 +26,8 @@ #define NETATALK_DIOSZ_STACK 65536 #define NETATALK_DIOSZ_HEAP (1024*1024) +struct vol; + /* vfs/unix.c */ extern int netatalk_unlink(const char *name); extern int netatalk_unlinkat(int dirfd, const char *name); From 60325ac322e9ddcee581609498c0ebaebcfdf1b7 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:39:30 +0100 Subject: [PATCH 093/117] Use mkstemp instead of mktemp --- etc/afpd/file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/etc/afpd/file.c b/etc/afpd/file.c index e33b0e3a..7f0e234a 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -2111,11 +2111,13 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U * NOTE: the temp file will be in the dest file's directory. it * will also be inaccessible from AFP. */ memcpy(temp, APPLETEMP, sizeof(APPLETEMP)); - if (!mktemp(temp)) { + int fd; + if ((fd = mkstemp(temp)) == -1) { err = AFPERR_MISC; goto err_exchangefile; } - + close(fd); + if (crossdev) { /* FIXME we need to close fork for copy, both s_of and d_of are null */ ad_close(adsp, ADFLAGS_HF); From 1c6730bd451c9531bb9b91d59e14e51f80d6dd67 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:42:06 +0100 Subject: [PATCH 094/117] Fix function definition, return type is pid_t --- libatalk/dsi/dsi_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libatalk/dsi/dsi_tcp.c b/libatalk/dsi/dsi_tcp.c index fd9de4a0..f73147a8 100644 --- a/libatalk/dsi/dsi_tcp.c +++ b/libatalk/dsi/dsi_tcp.c @@ -125,7 +125,7 @@ void dsi_free(DSI *dsi) static struct itimerval itimer; /* accept the socket and do a little sanity checking */ -static int dsi_tcp_open(DSI *dsi) +static pid_t dsi_tcp_open(DSI *dsi) { pid_t pid; SOCKLEN_T len; From 7e64456933e84c6be8371c7256e4d617ff004f99 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:46:45 +0100 Subject: [PATCH 095/117] Include config.h --- libatalk/iniparser/dictionary.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libatalk/iniparser/dictionary.c b/libatalk/iniparser/dictionary.c index b44796bb..bfa84058 100644 --- a/libatalk/iniparser/dictionary.c +++ b/libatalk/iniparser/dictionary.c @@ -19,6 +19,10 @@ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include From f7bc5da583ce693b60b35f9f17eee6c109f200d5 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:49:21 +0100 Subject: [PATCH 096/117] Remove const from path --- include/atalk/util.h | 2 +- libatalk/util/unix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/atalk/util.h b/include/atalk/util.h index e278872b..08c37394 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -190,7 +190,7 @@ extern int ochdir(const char *dir, int options); extern int ostat(const char *path, struct stat *buf, int options); extern int ostatat(int dirfd, const char *path, struct stat *st, int options); extern int ochown(const char *path, uid_t owner, gid_t group, int options); -extern int ochmod(const char *path, mode_t mode, const struct stat *st, int options); +extern int ochmod(char *path, mode_t mode, const struct stat *st, int options); /****************************************************************** * cnid.c diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index a74ca80b..7c80e22d 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -263,7 +263,7 @@ int ochown(const char *path, uid_t owner, gid_t group, int options) * O_NOFOLLOW: don't chmod() symlinks, do nothing, return 0 * O_NETATALK_ACL: call chmod_acl() instead of chmod() */ -int ochmod(const char *path, mode_t mode, const struct stat *st, int options) +int ochmod(char *path, mode_t mode, const struct stat *st, int options) { struct stat sb; From f5e0aac2a8fc50167b447d3b7767e774aed1a793 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 18:51:36 +0100 Subject: [PATCH 097/117] Add copyright and license and config.h --- bin/misc/logger_test.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/bin/misc/logger_test.c b/bin/misc/logger_test.c index 585c1583..cf932114 100644 --- a/bin/misc/logger_test.c +++ b/bin/misc/logger_test.c @@ -1,3 +1,21 @@ +/* + Copyright (c) 2009 Frank Lahm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + #include #include From bd3b0cfd7c0c51048ff898e5e1b121f8a3dd1126 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 2 Jan 2013 19:18:32 +0100 Subject: [PATCH 098/117] Fix several warnings, remove const --- etc/afpd/file.c | 2 +- etc/afpd/unix.c | 2 +- etc/afpd/unix.h | 2 +- etc/uams/uams_dhx2_pam.c | 2 +- etc/uams/uams_dhx_pam.c | 2 +- etc/uams/uams_pam.c | 2 +- libatalk/vfs/unix.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 7f0e234a..c2a1413d 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1939,7 +1939,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } /* ------------------------------ */ -static struct adouble *find_adouble(const AFPObj *obj, const struct vol *vol, struct path *path, struct ofork **of, struct adouble *adp) +static struct adouble *find_adouble(const AFPObj *obj, struct vol *vol, struct path *path, struct ofork **of, struct adouble *adp) { int ret; diff --git a/etc/afpd/unix.c b/etc/afpd/unix.c index 31086bb6..7c904628 100644 --- a/etc/afpd/unix.c +++ b/etc/afpd/unix.c @@ -224,7 +224,7 @@ int setfilunixmode (const struct vol *vol, struct path* path, mode_t mode) /* --------------------- */ -int setdirunixmode(const struct vol *vol, const char *name, mode_t mode) +int setdirunixmode(const struct vol *vol, char *name, mode_t mode) { LOG(log_debug, logtype_afpd, "setdirunixmode('%s', mode:%04o) {v_dperm:%04o}", fullpathname(name), mode, vol->v_dperm); diff --git a/etc/afpd/unix.h b/etc/afpd/unix.h index 73a515b2..3b3c281b 100644 --- a/etc/afpd/unix.h +++ b/etc/afpd/unix.h @@ -213,7 +213,7 @@ extern int uquota_getvolspace (const AFPObj *obj, struct vol *, VolSpace *, VolS extern struct afp_options default_options; -extern int setdirunixmode (const struct vol *, const char *, mode_t); +extern int setdirunixmode (const struct vol *, char *, mode_t); extern int setdirmode (const struct vol *, const char *, mode_t); extern int setdirowner (const struct vol *, const char *, const uid_t, const gid_t); extern int setfilunixmode (const struct vol *, struct path*, const mode_t); diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index 0de4b5ce..cb1c507d 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -136,7 +136,7 @@ static int dh_params_generate (unsigned int bits) { * echo off means password. */ static int PAM_conv (int num_msg, - const struct pam_message **msg, + struct pam_message **msg, struct pam_response **resp, void *appdata_ptr _U_) { int count = 0; diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 4c7d87c0..dbe24a20 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -80,7 +80,7 @@ static char *PAM_password; * echo off means password. */ static int PAM_conv (int num_msg, - const struct pam_message **msg, + struct pam_message **msg, struct pam_response **resp, void *appdata_ptr _U_) { int count = 0; diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index 6f15ac0a..c3762c94 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -54,7 +54,7 @@ extern UAM_MODULE_EXPORT void append(struct papfile *, const char *, int); * echo off means password. */ static int PAM_conv (int num_msg, - const struct pam_message **msg, + struct pam_message **msg, struct pam_response **resp, void *appdata_ptr _U_) { diff --git a/libatalk/vfs/unix.c b/libatalk/vfs/unix.c index 40f14fb5..f414bf59 100644 --- a/libatalk/vfs/unix.c +++ b/libatalk/vfs/unix.c @@ -46,7 +46,7 @@ int setfilmode(const struct vol *vol, const char *name, mode_t mode, struct stat mode |= st->st_mode & ~mask; /* keep other bits from previous mode */ - if (ochmod(name, mode & ~vol->v_umask, st, vol_syml_opt(vol) | O_NETATALK_ACL) < 0 && errno != EPERM ) { + if (ochmod((char *)name, mode & ~vol->v_umask, st, vol_syml_opt(vol) | O_NETATALK_ACL) < 0 && errno != EPERM ) { return -1; } return 0; From 62162892f6ad3de6b638075f6a926ef3e49d0816 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Wed, 2 Jan 2013 19:38:57 +0100 Subject: [PATCH 099/117] On the hunt for fixing all warnings --- etc/uams/uams_dhx2_pam.c | 4 ++++ etc/uams/uams_dhx_pam.c | 4 ++++ etc/uams/uams_pam.c | 4 ++++ macros/netatalk.m4 | 2 +- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/etc/uams/uams_dhx2_pam.c b/etc/uams/uams_dhx2_pam.c index cb1c507d..76e9143f 100644 --- a/etc/uams/uams_dhx2_pam.c +++ b/etc/uams/uams_dhx2_pam.c @@ -136,7 +136,11 @@ static int dh_params_generate (unsigned int bits) { * echo off means password. */ static int PAM_conv (int num_msg, +#ifdef LINUX + const struct pam_message **msg, +#else struct pam_message **msg, +#endif struct pam_response **resp, void *appdata_ptr _U_) { int count = 0; diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index dbe24a20..66ccc014 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -80,7 +80,11 @@ static char *PAM_password; * echo off means password. */ static int PAM_conv (int num_msg, +#ifdef LINUX + const struct pam_message **msg, +#else struct pam_message **msg, +#endif struct pam_response **resp, void *appdata_ptr _U_) { int count = 0; diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index c3762c94..1bbb1cd9 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -54,7 +54,11 @@ extern UAM_MODULE_EXPORT void append(struct papfile *, const char *, int); * echo off means password. */ static int PAM_conv (int num_msg, +#ifdef LINUX + const struct pam_message **msg, +#else struct pam_message **msg, +#endif struct pam_response **resp, void *appdata_ptr _U_) { diff --git a/macros/netatalk.m4 b/macros/netatalk.m4 index 51dbdcab..d7a8c8b6 100644 --- a/macros/netatalk.m4 +++ b/macros/netatalk.m4 @@ -359,7 +359,7 @@ fi 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) From 0ddd261b7196e47482d874b937ece0fb7d523dc0 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 3 Jan 2013 13:17:48 +0100 Subject: [PATCH 100/117] Comparison, not assignment --- etc/netatalk/netatalk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/netatalk/netatalk.c b/etc/netatalk/netatalk.c index bbae394c..5d71355e 100644 --- a/etc/netatalk/netatalk.c +++ b/etc/netatalk/netatalk.c @@ -146,7 +146,7 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) if (pid == afpd_pid) afpd_pid = -1; - else if (pid = cnid_metad_pid) + else if (pid == cnid_metad_pid) cnid_metad_pid = -1; else LOG(log_error, logtype_afpd, "Bad pid: %d", pid); From 4e9103b8f614e81a66f4c21511cc8b97f25111c9 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 3 Jan 2013 13:19:41 +0100 Subject: [PATCH 101/117] Add correct copyright and license --- etc/netatalk/netatalk.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/etc/netatalk/netatalk.c b/etc/netatalk/netatalk.c index 5d71355e..23659fe5 100644 --- a/etc/netatalk/netatalk.c +++ b/etc/netatalk/netatalk.c @@ -1,8 +1,16 @@ -/* - * Copyright (c) 1990,1993 Regents of The University of Michigan. - * All Rights Reserved. See COPYRIGHT. - */ - +/* + Copyright (c) 2012 Frank Lahm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ From 3a43b6ca05ec2b8f0494f8619a82d25204b7b457 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 3 Jan 2013 13:27:20 +0100 Subject: [PATCH 102/117] Fix compiler diagnostics --- bin/ad/ad_cp.c | 28 ++----------- bin/ad/ad_mv.c | 32 --------------- bin/ad/ad_set.c | 3 +- bin/misc/fce.c | 14 +------ etc/afpd/acls.c | 13 +++--- etc/afpd/afp_dsi.c | 6 +-- etc/afpd/catsearch.c | 3 +- etc/afpd/desktop.c | 15 +++---- etc/afpd/dircache.c | 1 - etc/afpd/directory.c | 3 +- etc/afpd/fce_api.c | 6 +-- etc/afpd/file.c | 1 - etc/afpd/fork.c | 6 +-- etc/afpd/hash.c | 15 ++++--- etc/afpd/main.c | 4 +- etc/afpd/status.c | 9 ++-- etc/afpd/volume.c | 3 -- etc/cnid_dbd/cmd_dbd_scanvol.c | 54 ++---------------------- etc/cnid_dbd/cnid_metad.c | 47 ++------------------- etc/cnid_dbd/main.c | 4 +- etc/netatalk/netatalk.c | 6 +-- etc/uams/uams_dhx_pam.c | 18 ++++---- etc/uams/uams_gss.c | 2 - libatalk/acl/cache.c | 2 - libatalk/acl/ldap.c | 2 +- libatalk/acl/uuid.c | 1 - libatalk/adouble/ad_conv.c | 3 +- libatalk/adouble/ad_flush.c | 3 -- libatalk/adouble/ad_lock.c | 1 - libatalk/adouble/ad_open.c | 6 ++- libatalk/adouble/ad_read.c | 1 - libatalk/adouble/ad_write.c | 2 - libatalk/bstring/bstradd.c | 3 +- libatalk/cnid/tdb/cnid_tdb_add.c | 8 ++-- libatalk/cnid/tdb/cnid_tdb_delete.c | 4 +- libatalk/cnid/tdb/cnid_tdb_get.c | 2 +- libatalk/cnid/tdb/cnid_tdb_lookup.c | 6 +-- libatalk/cnid/tdb/cnid_tdb_open.c | 4 +- libatalk/cnid/tdb/cnid_tdb_resolve.c | 2 +- libatalk/cnid/tdb/cnid_tdb_update.c | 10 ++--- libatalk/dsi/dsi_getsess.c | 2 +- libatalk/iniparser/iniparser.c | 1 - libatalk/tdb/io.c | 1 - libatalk/tdb/tdb_private.h | 17 ++------ libatalk/unicode/util_unistr.c | 12 +++--- libatalk/util/netatalk_conf.c | 61 +++++++++++++--------------- libatalk/util/server_child.c | 3 +- libatalk/util/server_ipc.c | 2 - libatalk/util/server_lock.c | 2 - libatalk/vfs/unix.c | 3 -- libatalk/vfs/vfs.c | 2 - 51 files changed, 122 insertions(+), 337 deletions(-) diff --git a/bin/ad/ad_cp.c b/bin/ad/ad_cp.c index ef995ce8..239936dc 100644 --- a/bin/ad/ad_cp.c +++ b/bin/ad/ad_cp.c @@ -95,36 +95,14 @@ static volatile sig_atomic_t alarmed; static int badcp, rval; static int ftw_options = FTW_MOUNT | FTW_PHYS | FTW_ACTIONRETVAL; -static char *netatalk_dirs[] = { - ".AppleDouble", - ".AppleDB", - ".AppleDesktop", - NULL -}; - /* Forward declarations */ static int copy(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf); static int ftw_copy_file(const struct FTW *, const char *, const struct stat *, int); static int ftw_copy_link(const struct FTW *, const char *, const struct stat *, int); static int setfile(const struct stat *, int); -static int preserve_dir_acls(const struct stat *, char *, char *); +// static int preserve_dir_acls(const struct stat *, char *, char *); static int preserve_fd_acls(int, int); -/* - Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" - Returns pointer to name or NULL. -*/ -static const char *check_netatalk_dirs(const char *name) -{ - int c; - - for (c=0; netatalk_dirs[c]; c++) { - if ((strcmp(name, netatalk_dirs[c])) == 0) - return netatalk_dirs[c]; - } - return NULL; -} - static void upfunc(void) { did = pdid; @@ -953,9 +931,9 @@ static int preserve_fd_acls(int source_fd, int dest_fd) return (0); } +#if 0 static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest_dir) { -#if 0 acl_t (*aclgetf)(const char *, acl_type_t); int (*aclsetf)(const char *, acl_type_t, acl_t); struct acl *aclp; @@ -1037,6 +1015,6 @@ static int preserve_dir_acls(const struct stat *fs, char *source_dir, char *dest return (1); } acl_free(acl); -#endif return (0); } +#endif diff --git a/bin/ad/ad_mv.c b/bin/ad/ad_mv.c index 7f592dd2..72698f73 100644 --- a/bin/ad/ad_mv.c +++ b/bin/ad/ad_mv.c @@ -50,31 +50,9 @@ static int fflg, iflg, nflg, vflg; static afpvol_t svolume, dvolume; static cnid_t did, pdid; static volatile sig_atomic_t alarmed; -static char *netatalk_dirs[] = { - ".AppleDouble", - ".AppleDB", - ".AppleDesktop", - NULL -}; static int copy(const char *, const char *); static int do_move(const char *, const char *); -static void preserve_fd_acls(int source_fd, int dest_fd, const char *source_path, - const char *dest_path); -/* - Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" - Returns pointer to name or NULL. -*/ -static const char *check_netatalk_dirs(const char *name) -{ - int c; - - for (c=0; netatalk_dirs[c]; c++) { - if ((strcmp(name, netatalk_dirs[c])) == 0) - return netatalk_dirs[c]; - } - return NULL; -} /* SIGNAL handling: @@ -242,7 +220,6 @@ int ad_mv(int argc, char *argv[], AFPObj *obj) } } -exit: closevol(&dvolume); return rval; } @@ -465,12 +442,3 @@ static int copy(const char *from, const char *to) } return 0; } - -static void -preserve_fd_acls(int source_fd, - int dest_fd, - const char *source_path, - const char *dest_path) -{ - ; -} diff --git a/bin/ad/ad_set.c b/bin/ad/ad_set.c index d41d5222..af825093 100644 --- a/bin/ad/ad_set.c +++ b/bin/ad/ad_set.c @@ -140,7 +140,6 @@ static void change_label(char *path, afpvol_t *vol, const struct stat *st, struc static void change_attributes(char *path, afpvol_t *vol, const struct stat *st, struct adouble *ad, char *new_attributes) { - char *FinderInfo; uint16_t AFPattributes; ad_getattr(ad, &AFPattributes); @@ -256,7 +255,7 @@ static void change_flags(char *path, afpvol_t *vol, const struct stat *st, struc int ad_set(int argc, char **argv, AFPObj *obj) { - int c, firstarg; + int c; afpvol_t vol; struct stat st; int adflags = 0; diff --git a/bin/misc/fce.c b/bin/misc/fce.c index b80f6a14..23101bfb 100644 --- a/bin/misc/fce.c +++ b/bin/misc/fce.c @@ -30,16 +30,6 @@ static char *fce_ev_names[] = { "FCE_DIR_CREATE" }; -// get sockaddr, IPv4 or IPv6: -static void *get_in_addr(struct sockaddr *sa) -{ - if (sa->sa_family == AF_INET) { - return &(((struct sockaddr_in*)sa)->sin_addr); - } - - return &(((struct sockaddr_in6*)sa)->sin6_addr); -} - static int unpack_fce_packet(unsigned char *buf, struct fce_packet *packet) { unsigned char *p = buf; @@ -77,8 +67,6 @@ int main(void) struct sockaddr_storage their_addr; char buf[MAXBUFLEN]; socklen_t addr_len; - char s[INET6_ADDRSTRLEN]; - uint64_t tmsize; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 @@ -129,7 +117,7 @@ int main(void) exit(1); } - unpack_fce_packet(buf, &packet); + unpack_fce_packet((unsigned char *)buf, &packet); if (memcmp(packet.magic, FCE_PACKET_MAGIC, sizeof(packet.magic)) == 0) { diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index b14beb6f..5cab99fe 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -629,6 +629,7 @@ static int posix_acls_to_uaperms(const AFPObj *obj, const char *path, struct sta EC_EXIT; } +#if 0 /*! * Add entries of one acl to another acl * @@ -651,6 +652,7 @@ static int acl_add_acl(acl_t *aclp, const acl_t acl) EC_CLEANUP: EC_EXIT; } +#endif /*! * Map Darwin ACE rights to POSIX 1e perm @@ -1261,7 +1263,6 @@ static int set_acl(const struct vol *vol, acl_entry_t entry; acl_tag_t tag; int entry_id = ACL_FIRST_ENTRY; - int has_def_acl = 0; /* flags to indicate if the object has a minimal default acl and/or an extended * default acl. */ @@ -1355,7 +1356,6 @@ static int check_acl_access(const AFPObj *obj, int ret; uint32_t allowed_rights = 0; char *username = NULL; - uuidtype_t uuidtype; struct stat st; bstring parent = NULL; int is_dir; @@ -1577,10 +1577,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner user UUID"); if (NULL == (pw = getpwuid(s_path->st.st_uid))) { LOG(log_debug, logtype_afpd, "afp_getacl: local uid: %u", s_path->st.st_uid); - localuuid_from_id(rbuf, UUID_USER, s_path->st.st_uid); + localuuid_from_id((unsigned char *)rbuf, UUID_USER, s_path->st.st_uid); } else { LOG(log_debug, logtype_afpd, "afp_getacl: got uid: %d, name: %s", s_path->st.st_uid, pw->pw_name); - if ((ret = getuuidfromname(pw->pw_name, UUID_USER, rbuf)) != 0) + if ((ret = getuuidfromname(pw->pw_name, UUID_USER, (unsigned char *)rbuf)) != 0) return AFPERR_MISC; } rbuf += UUID_BINSIZE; @@ -1592,10 +1592,10 @@ int afp_getacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size LOG(log_debug, logtype_afpd, "afp_getacl: client requested files owner group UUID"); if (NULL == (gr = getgrgid(s_path->st.st_gid))) { LOG(log_debug, logtype_afpd, "afp_getacl: local gid: %u", s_path->st.st_gid); - localuuid_from_id(rbuf, UUID_GROUP, s_path->st.st_gid); + localuuid_from_id((unsigned char *)rbuf, UUID_GROUP, s_path->st.st_gid); } else { LOG(log_debug, logtype_afpd, "afp_getacl: got gid: %d, name: %s", s_path->st.st_gid, gr->gr_name); - if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, rbuf)) != 0) + if ((ret = getuuidfromname(gr->gr_name, UUID_GROUP, (unsigned char *)rbuf)) != 0) return AFPERR_MISC; } rbuf += UUID_BINSIZE; @@ -1727,7 +1727,6 @@ int afp_setacl(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct stat *st, struct maccess *ma) { EC_INIT; - uint32_t rights = 0; if ( ! (obj->options.flags & OPTION_ACL2MACCESS) || ! (vol->v_flags & AFPVOL_ACLS)) diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 11e54627..8e1f90d2 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -143,8 +143,6 @@ static void afp_dsi_die(int sig) /* SIGQUIT handler */ static void ipc_reconnect_handler(int sig _U_) { - DSI *dsi = (DSI *)AFPobj->dsi; - if (reconnect_ipc(AFPobj) != 0) { LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect"); afp_dsi_close(AFPobj); @@ -626,7 +624,7 @@ void afp_over_dsi(AFPObj *obj) LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function)); err = (*afp_switch[function])(obj, - dsi->commands, dsi->cmdlen, + (char *)dsi->commands, dsi->cmdlen, (char *)&dsi->data, &dsi->datalen); LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s", @@ -667,7 +665,7 @@ void afp_over_dsi(AFPObj *obj) LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function)); err = (*afp_switch[function])(obj, - dsi->commands, dsi->cmdlen, + (char *)dsi->commands, dsi->cmdlen, (char *)&dsi->data, &dsi->datalen); LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s", diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 09e3ff52..9ffea6e2 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -137,7 +137,6 @@ static void clearstack(void) static int addstack(char *uname, struct dir *dir, int pidx) { struct dsitem *ds; - size_t l, u; struct dsitem *tmpds = NULL; /* check if we have some space on stack... */ @@ -551,7 +550,7 @@ static int catsearch(const AFPObj *obj, dirpos = opendir("."); if (dirpos == NULL) - dirpos = opendir(bdata(currentdir->d_fullpath)); + dirpos = opendir(cfrombstr(currentdir->d_fullpath)); if (error || dirpos == NULL) { switch (errno) { diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index f34729cc..9ba96bc5 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "volume.h" @@ -61,7 +62,7 @@ int setdeskmode(const struct vol *vol, const mode_t mode) bstring dtpath = bfromcstr(vol->v_dbpath); bcatcstr(dtpath, "/" APPLEDESKTOP); - EC_NEG1( chdir(bdata(dtpath)) ); + EC_NEG1( chdir(cfrombstr(dtpath)) ); if (( desk = opendir( "." )) == NULL ) { if ( chdir( wd ) < 0 ) { @@ -138,7 +139,7 @@ int setdeskowner(const struct vol *vol, uid_t uid, gid_t gid) bstring dtpath = bfromcstr(vol->v_dbpath); bcatcstr(dtpath, "/" APPLEDESKTOP); - EC_NEG1( chdir(bdata(dtpath)) ); + EC_NEG1( chdir(cfrombstr(dtpath)) ); if (( desk = opendir( "." )) == NULL ) { if ( chdir( wd ) < 0 ) { @@ -182,7 +183,7 @@ int setdeskowner(const struct vol *vol, uid_t uid, gid_t gid) LOG(log_error, logtype_afpd, "setdeskowner: chdir %s: %s", wd, strerror(errno) ); EC_FAIL; } - if (chown(bdata(dtpath), uid, gid ) < 0 && errno != EPERM ) { + if (chown(cfrombstr(dtpath), uid, gid ) < 0 && errno != EPERM ) { LOG(log_error, logtype_afpd, "setdeskowner: chown %s: %s", fullpathname(".AppleDouble"), strerror(errno) ); } @@ -203,11 +204,11 @@ static void create_appledesktop_folder(const struct vol * vol) dtpath = bfromcstr(vol->v_dbpath); bcatcstr(dtpath, "/" APPLEDESKTOP); - if (lstat(bdata(dtpath), &st) != 0) { + if (lstat(cfrombstr(dtpath), &st) != 0) { become_root(); - if (lstat(bdata(olddtpath), &st) == 0) { + if (lstat(cfrombstr(olddtpath), &st) == 0) { cmd_argv[0] = "mv"; cmd_argv[1] = bdata(olddtpath); cmd_argv[2] = bdata(dtpath); @@ -215,10 +216,10 @@ static void create_appledesktop_folder(const struct vol * vol) if (run_cmd("mv", cmd_argv) != 0) { LOG(log_error, logtype_afpd, "moving .AppleDesktop from \"%s\" to \"%s\" failed", bdata(olddtpath), bdata(dtpath)); - mkdir(bdata(dtpath), 0777); + mkdir(cfrombstr(dtpath), 0777); } } else { - mkdir(bdata(dtpath), 0777); + mkdir(cfrombstr(dtpath), 0777); } unbecome_root(); diff --git a/etc/afpd/dircache.c b/etc/afpd/dircache.c index 7cd08f6f..37af45fa 100644 --- a/etc/afpd/dircache.c +++ b/etc/afpd/dircache.c @@ -434,7 +434,6 @@ struct dir *dircache_search_by_name(const struct vol *vol, int dircache_add(const struct vol *vol, struct dir *dir) { - struct dir *cdir = NULL; struct dir key; hnode_t *hn; diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index d617ea8f..9a4fc64e 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -912,7 +912,7 @@ struct dir *dir_add(struct vol *vol, const struct dir *dir, struct path *path, i void dir_free_invalid_q(void) { struct dir *dir; - while (dir = (struct dir *)dequeue(invalid_dircache_entries)) + while ((dir = (struct dir *)dequeue(invalid_dircache_entries))) dir_free(dir); } @@ -2200,7 +2200,6 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ ad_flush(&ad); ad_close(&ad, ADFLAGS_HF); -createdir_done: memcpy( rbuf, &dir->d_did, sizeof( uint32_t )); *rbuflen = sizeof( uint32_t ); setvoltime(obj, vol ); diff --git a/etc/afpd/fce_api.c b/etc/afpd/fce_api.c index 5f6b70ba..49dd3cd7 100644 --- a/etc/afpd/fce_api.c +++ b/etc/afpd/fce_api.c @@ -68,7 +68,7 @@ static unsigned long fce_ev_enabled = (1 << FCE_DIR_CREATE); #define MAXIOBUF 1024 -static char iobuf[MAXIOBUF]; +static unsigned char iobuf[MAXIOBUF]; static const char *skip_files[] = { ".DS_Store", @@ -165,7 +165,6 @@ static ssize_t build_fce_packet( struct fce_packet *packet, const char *path, in { size_t pathlen = 0; ssize_t data_len = 0; - uint64_t *t; /* Set content of packet */ memcpy(packet->magic, FCE_PACKET_MAGIC, sizeof(packet->magic) ); @@ -229,7 +228,6 @@ static void send_fce_event(const char *path, int event) static bool first_event = true; struct fce_packet packet; - void *data = &packet; static uint32_t event_id = 0; /* the unique packet couter to detect packet/data loss. Going from 0xFFFFFFFF to 0x0 is a valid increment */ time_t now = time(NULL); @@ -490,7 +488,7 @@ void shortsleep( unsigned int us ) } int main( int argc, char*argv[] ) { - int c,ret; + int c; char *port = FCE_DEFAULT_PORT_STRING; char *host = "localhost"; diff --git a/etc/afpd/file.c b/etc/afpd/file.c index c2a1413d..f62e05ee 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -751,7 +751,6 @@ int afp_createfile(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, ad_close(&ad, ADFLAGS_DF|ADFLAGS_HF ); fce_register(FCE_FILE_CREATE, fullpathname(upath), NULL, fce_file); -createfile_done: curdir->d_offcnt++; setvoltime(obj, vol ); diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 5af91207..2d59b5da 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -251,7 +251,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si struct stat *st; uint16_t bshort; struct path *s_path; - struct stat xxx; ibuf++; fork = *ibuf++; @@ -734,8 +733,6 @@ int afp_bytelock_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t static int read_file(const struct ofork *ofork, int eid, off_t offset, char *rbuf, size_t *rbuflen) { ssize_t cc; - int eof = 0; - char *p, *q; cc = ad_read(ofork->of_ad, eid, offset, rbuf, *rbuflen); if ( cc < 0 ) { @@ -1052,7 +1049,6 @@ static ssize_t write_file(struct ofork *ofork, int eid, off_t offset, char *rbuf, size_t rbuflen) { - char *p, *q; ssize_t cc; LOG(log_debug, logtype_afpd, "write_file(off: %ju, size: %zu)", @@ -1091,7 +1087,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s uint16_t ofrefnum; ssize_t cc; DSI *dsi = obj->dsi; - char *rcvbuf = dsi->commands; + char *rcvbuf = (char *)dsi->commands; size_t rcvbuflen = dsi->server_quantum; /* figure out parameters */ diff --git a/etc/afpd/hash.c b/etc/afpd/hash.c index b7471ccb..f1e30685 100644 --- a/etc/afpd/hash.c +++ b/etc/afpd/hash.c @@ -58,7 +58,6 @@ static const char rcsid[] = "$Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp static hnode_t *hnode_alloc(void *context); static void hnode_free(hnode_t *node, void *context); static hash_val_t hash_fun_default(const void *key); -static hash_val_t hash_fun2(const void *key); static int hash_comp_default(const void *key1, const void *key2); int hash_val_t_bit; @@ -850,6 +849,13 @@ static hash_val_t hash_fun_default(const void *key) +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif +static int hash_comp_default(const void *key1, const void *key2) +{ + return strcmp(key1, key2); +} + +#ifdef KAZLIB_TEST_MAIN + static hash_val_t hash_fun2(const void *key) { int len, rem; @@ -897,13 +903,6 @@ static hash_val_t hash_fun2(const void *key) return hash; } -static int hash_comp_default(const void *key1, const void *key2) -{ - return strcmp(key1, key2); -} - -#ifdef KAZLIB_TEST_MAIN - #include #include #include diff --git a/etc/afpd/main.c b/etc/afpd/main.c index 106f725c..0e0a858e 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -210,8 +210,6 @@ static int setlimits(void) int main(int ac, char **av) { - fd_set rfds; - void *ipc; struct sigaction sv; sigset_t sigs; int ret; @@ -428,7 +426,7 @@ int main(int ac, char **av) switch (polldata[i].fdtype) { case LISTEN_FD: - if (child = dsi_start(&obj, (DSI *)polldata[i].data, server_children)) { + if ((child = dsi_start(&obj, (DSI *)polldata[i].data, server_children))) { /* Add IPC fd to select fd set */ fdset_add_fd(obj.options.connections + AFP_LISTENERS + FDSET_SAFETY, &fdset, diff --git a/etc/afpd/status.c b/etc/afpd/status.c index f42bf5ec..caa74d5d 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -95,7 +95,7 @@ static void status_flags(char *data, 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; @@ -364,7 +364,6 @@ static size_t status_directorynames(char *data, data += offset; char *DirectoryNamesCount = data++; - char *DirectoryNames = data; size_t size = sizeof(uint8_t); *DirectoryNamesCount = 0; @@ -441,7 +440,7 @@ static size_t status_directorynames(char *data, } krb5_unparse_name(context, entry.principal, &principal); - krb5_kt_free_entry(context, &entry); + krb5_free_keytab_entry_contents(context, &entry); append_directoryname(&data, offset, @@ -501,7 +500,7 @@ static size_t status_utf8servername(char *data, int *nameoffset, 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); @@ -645,7 +644,7 @@ void set_signature(struct afp_options *options) { char *servername_conf; int header = 0; char buf[1024], *p; - FILE *fp = NULL, *randomp; + FILE *fp = NULL; size_t len; char *server_tmp; diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 172584d8..844444ba 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -152,7 +152,6 @@ static int get_tm_used(struct vol * restrict vol) DIR *dir = NULL; const struct dirent *entry; const char *p; - struct stat st; long int links; time_t now = time(NULL); @@ -212,7 +211,6 @@ static int getvolspace(const AFPObj *obj, struct vol *vol, { int spaceflag, rc; uint32_t maxsize; - VolSpace used; #ifndef NO_QUOTA_SUPPORT VolSpace qfree, qtotal; #endif @@ -663,7 +661,6 @@ int afp_openvol(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t { struct stat st; char *volname; - char *p; struct vol *volume; struct dir *dir; diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 99156aa9..48deb5f0 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -65,7 +65,6 @@ static struct cnid_dbd_rqst rqst; static struct cnid_dbd_rply rply; static jmp_buf jmp; static char pname[MAXPATHLEN] = "../"; -static char cnidResBuf[12 + MAXPATHLEN + 1]; /* Taken form afpd/desktop.c @@ -106,52 +105,6 @@ static char *utompath(char *upath) return(m); } -/* - Taken form afpd/desktop.c -*/ -static char *mtoupath(char *mpath) -{ - static char upath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */ - char *m, *u; - size_t inplen; - size_t outlen; - u_int16_t flags = 0; - - if (!mpath) - return NULL; - - if ( *mpath == '\0' ) { - return( "." ); - } - - /* set conversion flags */ - if ((vol->v_casefold & AFPVOL_MTOUUPPER)) - flags |= CONV_TOUPPER; - else if ((vol->v_casefold & AFPVOL_MTOULOWER)) - flags |= CONV_TOLOWER; - - if ((vol->v_flags & AFPVOL_EILSEQ)) { - flags |= CONV__EILSEQ; - } - - m = mpath; - u = upath; - - inplen = strlen(m); - outlen = MAXPATHLEN; - - if ((size_t)-1 == (outlen = convert_charset(CH_UTF8_MAC, - vol->v_volcharset, - vol->v_maccharset, - m, inplen, u, outlen, &flags)) ) { - dbd_log( LOGSTD, "conversion from UTF8-MAC to %s for %s failed.", - vol->v_volcodepage, mpath); - return NULL; - } - - return( upath ); -} - /* Check for netatalk special folders e.g. ".AppleDB" or ".AppleDesktop" Returns pointer to name or NULL. @@ -187,7 +140,6 @@ static const char *check_special_dirs(const char *name) */ static int update_cnid(cnid_t did, const struct stat *sp, const char *oldname, const char *newname) { - int ret; cnid_t id; /* Query the database */ @@ -608,8 +560,8 @@ static int read_addir(void) */ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfile_ok) { - int ret, adflags = ADFLAGS_HF; - cnid_t db_cnid, ad_cnid, tmpid; + int adflags = ADFLAGS_HF; + cnid_t db_cnid, ad_cnid; struct adouble ad; adflags = ADFLAGS_HF | (S_ISDIR(st->st_mode) ? ADFLAGS_DIR : 0); @@ -667,7 +619,7 @@ static cnid_t check_cnid(const char *name, cnid_t did, struct stat *st, int adfi */ static int dbd_readdir(int volroot, cnid_t did) { - int cwd, ret = 0, adfile_ok, addir_ok, encoding_ok; + int cwd, ret = 0, adfile_ok, addir_ok; cnid_t cnid = 0; const char *name; DIR *dp; diff --git a/etc/cnid_dbd/cnid_metad.c b/etc/cnid_dbd/cnid_metad.c index 2fc1e8de..18e063da 100644 --- a/etc/cnid_dbd/cnid_metad.c +++ b/etc/cnid_dbd/cnid_metad.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -286,7 +287,6 @@ static int maybe_start_dbd(const AFPObj *obj, char *dbdpn, const char *volpath) static int set_dbdir(const char *dbdir, const char *vpath) { EC_INIT; - int status; struct stat st; bstring oldpath, newpath; char *cmd_argv[4]; @@ -301,7 +301,7 @@ static int set_dbdir(const char *dbdir, const char *vpath) EC_FAIL; } - if (lstat(bdata(oldpath), &st) == 0 && lstat(bdata(newpath), &st) != 0 && errno == ENOENT) { + if (lstat(cfrombstr(oldpath), &st) == 0 && lstat(cfrombstr(newpath), &st) != 0 && errno == ENOENT) { /* There's an .AppleDB in the volume root, we move it */ cmd_argv[0] = "mv"; cmd_argv[1] = bdata(oldpath); @@ -315,7 +315,7 @@ static int set_dbdir(const char *dbdir, const char *vpath) } - if (lstat(bdata(newpath), &st) < 0 && mkdir(bdata(newpath), 0755 ) < 0) { + if (lstat(cfrombstr(newpath), &st) < 0 && mkdir(cfrombstr(newpath), 0755 ) < 0) { LOG(log_error, logtype_cnid, "set_dbdir: mkdir failed for %s", bdata(newpath)); EC_FAIL; } @@ -326,44 +326,6 @@ static int set_dbdir(const char *dbdir, const char *vpath) EC_EXIT; } -/* ------------------ */ -static uid_t user_to_uid (char *username) -{ - struct passwd *this_passwd; - - /* check for anything */ - if ( !username || strlen ( username ) < 1 ) return 0; - - /* grab the /etc/passwd record relating to username */ - this_passwd = getpwnam ( username ); - - /* return false if there is no structure returned */ - if (this_passwd == NULL) return 0; - - /* return proper uid */ - return this_passwd->pw_uid; - -} - -/* ------------------ */ -static gid_t group_to_gid ( char *group) -{ - struct group *this_group; - - /* check for anything */ - if ( !group || strlen ( group ) < 1 ) return 0; - - /* grab the /etc/groups record relating to group */ - this_group = getgrnam ( group ); - - /* return false if there is no structure returned */ - if (this_group == NULL) return 0; - - /* return proper gid */ - return this_group->gr_gid; - -} - /* ------------------ */ static void catch_child(int sig _U_) { @@ -471,7 +433,6 @@ int main(int argc, char *argv[]) int cc; uid_t uid = 0; gid_t gid = 0; - int err = 0; int debug = 0; int ret; sigset_t set; @@ -508,7 +469,7 @@ int main(int argc, char *argv[]) (void)setlimits(); host = iniparser_getstrdup(obj.iniconfig, INISEC_GLOBAL, "cnid listen", "localhost:4700"); - if (port = strrchr(host, ':')) + if ((port = strrchr(host, ':'))) *port++ = 0; else port = DEFAULTPORT; diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index edbe60f8..767e1e3c 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -216,7 +217,7 @@ static int delete_db(void) EC_ZERO( get_lock(LOCK_FREE, bdata(dbpath)) ); EC_NEG1( cwd = open(".", O_RDONLY) ); - chdir(bdata(dbpath)); + chdir(cfrombstr(dbpath)); system("rm -f cnid2.db lock log.* __db.*"); if ((db_locked = get_lock(LOCK_EXCL, bdata(dbpath))) != LOCK_EXCL) { @@ -477,7 +478,6 @@ int main(int argc, char *argv[]) EC_INIT; int delete_bdb = 0; int ctrlfd = -1, clntfd = -1; - char *logconfig; AFPObj obj = { 0 }; char *volpath = NULL; diff --git a/etc/netatalk/netatalk.c b/etc/netatalk/netatalk.c index 23659fe5..9ac72c5a 100644 --- a/etc/netatalk/netatalk.c +++ b/etc/netatalk/netatalk.c @@ -52,7 +52,6 @@ static void kill_childs(int sig, ...); /* static variables */ static AFPObj obj; -static sig_atomic_t got_chldsig; static pid_t afpd_pid = -1, cnid_metad_pid = -1; static uint afpd_restarts, cnid_metad_restarts; static struct event_base *base; @@ -134,7 +133,7 @@ static void sighup_cb(evutil_socket_t fd, short what, void *arg) /* SIGCHLD callback */ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) { - int status, i; + int status; pid_t pid; LOG(log_debug, logtype_afpd, "Got SIGCHLD event"); @@ -167,8 +166,6 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) /* timer callback */ static void timer_cb(evutil_socket_t fd, short what, void *arg) { - static int i = 0; - if (in_shutdown) return; @@ -252,7 +249,6 @@ static void usage(void) int main(int argc, char **argv) { - const char *configfile = NULL; int c, ret, debug = 0; sigset_t blocksigs; struct timeval tv; diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 66ccc014..8b879f06 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -197,7 +197,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_, DH *dh; /* get the client's public key */ - if (!(bn = BN_bin2bn(ibuf, KEYSIZE, NULL))) { + if (!(bn = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) { /* Log Entry */ LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM No Public Key -- %s", strerror(errno)); @@ -259,10 +259,10 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_, } /* figure out the key. store the key in rbuf for now. */ - i = DH_compute_key(rbuf, bn, dh); + i = DH_compute_key((unsigned char *)rbuf, bn, dh); /* set the key */ - CAST_set_key(&castkey, i, rbuf); + CAST_set_key(&castkey, i, (unsigned char *)rbuf); /* session id. it's just a hashed version of the object pointer. */ sessid = dhxhash(obj); @@ -271,7 +271,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_, *rbuflen += sizeof(sessid); /* public key */ - BN_bn2bin(dh->pub_key, rbuf); + BN_bn2bin(dh->pub_key, (unsigned char *)rbuf); rbuf += KEYSIZE; *rbuflen += KEYSIZE; @@ -305,7 +305,7 @@ static int dhx_setup(void *obj, char *ibuf, size_t ibuflen _U_, #endif /* 0 */ /* encrypt using cast */ - CAST_cbc_encrypt(rbuf, rbuf, CRYPTBUFLEN, &castkey, msg2_iv, + CAST_cbc_encrypt((unsigned char *)rbuf, (unsigned char *)rbuf, CRYPTBUFLEN, &castkey, msg2_iv, CAST_ENCRYPT); *rbuflen += CRYPTBUFLEN; BN_free(bn); @@ -440,13 +440,13 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd, hostname = NULL; } - CAST_cbc_encrypt(ibuf, rbuf, CRYPT2BUFLEN, &castkey, + CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)rbuf, CRYPT2BUFLEN, &castkey, msg3_iv, CAST_DECRYPT); memset(&castkey, 0, sizeof(castkey)); /* check to make sure that the random number is the same. we * get sent back an incremented random number. */ - if (!(bn1 = BN_bin2bn(rbuf, KEYSIZE, NULL))) + if (!(bn1 = BN_bin2bn((unsigned char *)rbuf, KEYSIZE, NULL))) return AFPERR_PARAM; if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) { @@ -617,13 +617,13 @@ static int pam_changepw(void *obj, char *username, } /* grab the client's nonce, old password, and new password. */ - CAST_cbc_encrypt(ibuf, ibuf, CHANGEPWBUFLEN, &castkey, + CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)ibuf, CHANGEPWBUFLEN, &castkey, msg3_iv, CAST_DECRYPT); memset(&castkey, 0, sizeof(castkey)); /* check to make sure that the random number is the same. we * get sent back an incremented random number. */ - if (!(bn1 = BN_bin2bn(ibuf, KEYSIZE, NULL))) { + if (!(bn1 = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) { /* Log Entry */ LOG(log_info, logtype_uams, "uams_dhx_pam.c :PAM: Random Number Not the same or not incremented-- %s", strerror(errno)); diff --git a/etc/uams/uams_gss.c b/etc/uams/uams_gss.c index f8cfc1af..29ea36c0 100644 --- a/etc/uams/uams_gss.c +++ b/etc/uams/uams_gss.c @@ -318,8 +318,6 @@ static int do_gss_auth(void *obj, cleanup_client_name: gss_release_name(&status, &client_name); - -cleanup_context: gss_release_buffer(&status, &authenticator_buff); gss_delete_sec_context(&status, &context, NULL); diff --git a/libatalk/acl/cache.c b/libatalk/acl/cache.c index bc9806d9..15eea478 100644 --- a/libatalk/acl/cache.c +++ b/libatalk/acl/cache.c @@ -46,7 +46,6 @@ static cacheduser_t *uuidcache[256]; /* indexed by hash of uuid */ void uuidcache_dump(void) { int i; - int ret = 0; cacheduser_t *entry; char timestr[200]; struct tm *tmp = NULL; @@ -301,7 +300,6 @@ int add_cachebyuuid( uuidp_t inuuid, const char *inname, uuidtype_t type, const char *name = NULL; unsigned char *uuid = NULL; cacheduser_t *cacheduser = NULL; - cacheduser_t *entry; unsigned char hash; /* allocate mem and copy values */ diff --git a/libatalk/acl/ldap.c b/libatalk/acl/ldap.c index 44caae83..f04c5aef 100644 --- a/libatalk/acl/ldap.c +++ b/libatalk/acl/ldap.c @@ -347,7 +347,7 @@ int ldap_getnamefromuuid( const char *uuidstr, char **name, uuidtype_t *type) { int i = 0; int s = 0; char c; - while(c = uuidstr[i]) { + while ((c = uuidstr[i])) { if((c >='a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9')) { diff --git a/libatalk/acl/uuid.c b/libatalk/acl/uuid.c index b71c13e6..c1bc065f 100644 --- a/libatalk/acl/uuid.c +++ b/libatalk/acl/uuid.c @@ -209,7 +209,6 @@ int getuuidfromname( const char *name, uuidtype_t type, unsigned char *uuid) { add_cachebyname(name, uuid, mytype, 0); } -cleanup: #ifdef HAVE_LDAP if (uuid_string) free(uuid_string); #endif diff --git a/libatalk/adouble/ad_conv.c b/libatalk/adouble/ad_conv.c index 329790bb..ff0eebcc 100644 --- a/libatalk/adouble/ad_conv.c +++ b/libatalk/adouble/ad_conv.c @@ -57,7 +57,6 @@ static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struc EC_INIT; struct adouble adv2; struct adouble adea; - const char *adpath; int adflags; uint32_t ctime, mtime, afpinfo = 0; char *emptyad; @@ -199,7 +198,7 @@ static int ad_conv_dehex(const char *path, const struct stat *sp, const struct v { EC_INIT; static char buf[MAXPATHLEN]; - const char *adpath, *p; + const char *p; int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0; bstring newpath = NULL; diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index d8fbacf6..50fd8bae 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -59,7 +59,6 @@ int ad_rebuild_adouble_header_v2(struct adouble *ad) uint32_t temp; uint16_t nent; char *buf, *nentp; - int len; LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_v2"); @@ -105,7 +104,6 @@ int ad_rebuild_adouble_header_ea(struct adouble *ad) uint32_t temp; uint16_t nent; char *buf, *nentp; - int len; LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_ea"); @@ -153,7 +151,6 @@ static int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf) uint32_t temp; uint16_t nent; char *buf; - int len; LOG(log_debug, logtype_ad, "ad_rebuild_adouble_header_osx"); diff --git a/libatalk/adouble/ad_lock.c b/libatalk/adouble/ad_lock.c index 6e159cdd..173adc4c 100644 --- a/libatalk/adouble/ad_lock.c +++ b/libatalk/adouble/ad_lock.c @@ -630,7 +630,6 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off) uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits) { uint16_t ret = 0; - struct ad_fd *adf; off_t off; off_t len; diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index e66929f2..5205b9e2 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -108,7 +108,9 @@ static int ad_mkrf(const char *path); static int ad_header_read(const char *path, struct adouble *ad, const struct stat *hst); static int ad_header_upgrade(struct adouble *ad, const char *name); +#ifdef HAVE_EAFD static int ad_mkrf_ea(const char *path); +#endif static int ad_header_read_ea(const char *path, struct adouble *ad, const struct stat *hst); static int ad_header_upgrade_ea(struct adouble *ad, const char *name); static int ad_reso_size(const char *path, int adflags, struct adouble *ad); @@ -691,11 +693,13 @@ static int ad_mkrf(const char *path) return 0; } +#ifdef HAVE_EAFD static int ad_mkrf_ea(const char *path _U_) { AFP_PANIC("ad_mkrf_ea: dont use"); return 0; } +#endif static int ad_mkrf_osx(const char *path _U_) { @@ -1033,7 +1037,6 @@ static int ad_open_hf_v2(const char *path, int adflags, mode_t mode, struct adou static int ad_open_hf_ea(const char *path, int adflags, int mode, struct adouble *ad) { EC_INIT; - ssize_t rforklen; int oflags; int opened = 0; @@ -1216,7 +1219,6 @@ static int ad_open_rf_ea(const char *path, int adflags, int mode, struct adouble int oflags; int opened = 0; int closeflags = adflags & (ADFLAGS_DF | ADFLAGS_HF); - ssize_t rlen; #ifndef HAVE_EAFD const char *rfpath; struct stat st; diff --git a/libatalk/adouble/ad_read.c b/libatalk/adouble/ad_read.c index ed7c0cb4..852a6e96 100644 --- a/libatalk/adouble/ad_read.c +++ b/libatalk/adouble/ad_read.c @@ -62,7 +62,6 @@ ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset) ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, const size_t buflen) { ssize_t cc; - ssize_t rlen; off_t r_off = 0; /* We're either reading the data fork (and thus the data file) diff --git a/libatalk/adouble/ad_write.c b/libatalk/adouble/ad_write.c index 6e8a0190..a807c1de 100644 --- a/libatalk/adouble/ad_write.c +++ b/libatalk/adouble/ad_write.c @@ -52,7 +52,6 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha EC_INIT; struct stat st; ssize_t cc; - size_t roundup; off_t r_off; if (ad_data_fileno(ad) == AD_SYMLINK) { @@ -94,7 +93,6 @@ ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const cha return -1; /* we don't know how to write if it's not a ressource or data fork */ } -EC_CLEANUP: if (ret != 0) return ret; return( cc ); diff --git a/libatalk/bstring/bstradd.c b/libatalk/bstring/bstradd.c index 7b59b2e8..c78fd0e0 100644 --- a/libatalk/bstring/bstradd.c +++ b/libatalk/bstring/bstradd.c @@ -77,7 +77,6 @@ */ bstring brefcstr (char *str) { bstring b; - int i; size_t j; if (str == NULL) @@ -90,7 +89,7 @@ bstring brefcstr (char *str) { b->slen = (int) j; b->mlen = -1; - b->data = str; + b->data = (unsigned char *)str; return b; } diff --git a/libatalk/cnid/tdb/cnid_tdb_add.c b/libatalk/cnid/tdb/cnid_tdb_add.c index fcb43fa2..3203eda9 100644 --- a/libatalk/cnid/tdb/cnid_tdb_add.c +++ b/libatalk/cnid/tdb/cnid_tdb_add.c @@ -93,7 +93,7 @@ static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data } /* did/name database */ - altkey.dptr = (char *) data->dptr +CNID_DID_OFS; + altkey.dptr = data->dptr +CNID_DID_OFS; altkey.dsize = data->dsize -CNID_DID_OFS; if (tdb_store(db->tdb_didname, altkey, altdata, TDB_REPLACE)) { goto abort; @@ -112,7 +112,7 @@ static cnid_t get_cnid(struct _cnid_tdb_private *db) memset(&rootinfo_key, 0, sizeof(rootinfo_key)); memset(&data, 0, sizeof(data)); - rootinfo_key.dptr = ROOTINFO_KEY; + rootinfo_key.dptr = (unsigned char *)ROOTINFO_KEY; rootinfo_key.dsize = ROOTINFO_KEYLEN; tdb_chainlock(db->tdb_didname, rootinfo_key); @@ -136,7 +136,7 @@ static cnid_t get_cnid(struct _cnid_tdb_private *db) } memset(&data, 0, sizeof(data)); - data.dptr = (char *)&hint; + data.dptr = (unsigned char *)&hint; data.dsize = sizeof(hint); if (tdb_store(db->tdb_didname, rootinfo_key, data, TDB_REPLACE)) { goto cleanup; @@ -181,7 +181,7 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st, memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); - key.dptr = (char *)&hint; + key.dptr = (unsigned char *)&hint; key.dsize = sizeof(cnid_t); if ((data.dptr = make_tdb_data(cdb->flags, lstp, did, name, len)) == NULL) { LOG(log_error, logtype_default, "tdb_add: Path name is too long"); diff --git a/libatalk/cnid/tdb/cnid_tdb_delete.c b/libatalk/cnid/tdb/cnid_tdb_delete.c index aa801e58..e7bf6f71 100644 --- a/libatalk/cnid/tdb/cnid_tdb_delete.c +++ b/libatalk/cnid/tdb/cnid_tdb_delete.c @@ -26,7 +26,7 @@ int cnid_tdb_delete(struct _cnid_db *cdb, const cnid_t id) memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); - key.dptr = (char *)&id; + key.dptr = (unsigned char *)&id; key.dsize = sizeof(cnid_t); data = tdb_fetch(db->tdb_cnid, key); if (!data.dptr) @@ -40,7 +40,7 @@ int cnid_tdb_delete(struct _cnid_db *cdb, const cnid_t id) key.dsize = CNID_DEVINO_LEN; tdb_delete(db->tdb_devino, key); - key.dptr = (char *)data.dptr +CNID_DID_OFS; + key.dptr = data.dptr +CNID_DID_OFS; key.dsize = data.dsize -CNID_DID_OFS; tdb_delete(db->tdb_didname, key); diff --git a/libatalk/cnid/tdb/cnid_tdb_get.c b/libatalk/cnid/tdb/cnid_tdb_get.c index 8321d04e..4e7f638d 100644 --- a/libatalk/cnid/tdb/cnid_tdb_get.c +++ b/libatalk/cnid/tdb/cnid_tdb_get.c @@ -26,7 +26,7 @@ cnid_t cnid_tdb_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t l buf += sizeof(did); memcpy(buf, name, len); *(buf + len) = '\0'; /* Make it a C-string. */ - key.dptr = start; + key.dptr = (unsigned char *)start; key.dsize = CNID_DID_LEN + len + 1; data = tdb_fetch(db->tdb_didname, key); if (!data.dptr) diff --git a/libatalk/cnid/tdb/cnid_tdb_lookup.c b/libatalk/cnid/tdb/cnid_tdb_lookup.c index f095cd54..c95631af 100644 --- a/libatalk/cnid/tdb/cnid_tdb_lookup.c +++ b/libatalk/cnid/tdb/cnid_tdb_lookup.c @@ -25,7 +25,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did, return 0; } - if ((buf = make_tdb_data(cdb->flags, st, did, name, len)) == NULL) { + if ((buf = (char *)make_tdb_data(cdb->flags, st, did, name, len)) == NULL) { LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long"); return 0; } @@ -42,7 +42,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did, memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN); memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN); - key.dptr = buf +CNID_DEVINO_OFS; + key.dptr = (unsigned char *)buf + CNID_DEVINO_OFS; key.dsize = CNID_DEVINO_LEN; cniddata = tdb_fetch(db->tdb_devino, key); if (!cniddata.dptr) { @@ -66,7 +66,7 @@ cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did, } /* did/name now */ - key.dptr = buf + CNID_DID_OFS; + key.dptr = (unsigned char *)buf + CNID_DID_OFS; key.dsize = CNID_DID_LEN + len + 1; cniddata = tdb_fetch(db->tdb_didname, key); if (!cniddata.dptr) { diff --git a/libatalk/cnid/tdb/cnid_tdb_open.c b/libatalk/cnid/tdb/cnid_tdb_open.c index 889cea1e..0aee5b4d 100644 --- a/libatalk/cnid/tdb/cnid_tdb_open.c +++ b/libatalk/cnid/tdb/cnid_tdb_open.c @@ -125,14 +125,14 @@ struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args) * to change the format in any way. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); - key.dptr = DBVERSION_KEY; + key.dptr = (unsigned char *)DBVERSION_KEY; key.dsize = DBVERSION_KEYLEN; data = tdb_fetch(db->tdb_didname, key); if (!data.dptr) { uint32_t version = htonl(DBVERSION); - data.dptr = (char *)&version; + data.dptr = (unsigned char *)&version; data.dsize = sizeof(version); if (tdb_store(db->tdb_didname, key, data, TDB_REPLACE)) { LOG(log_error, logtype_default, "tdb_open: Error putting new version"); diff --git a/libatalk/cnid/tdb/cnid_tdb_resolve.c b/libatalk/cnid/tdb/cnid_tdb_resolve.c index 5e831222..7e80f385 100644 --- a/libatalk/cnid/tdb/cnid_tdb_resolve.c +++ b/libatalk/cnid/tdb/cnid_tdb_resolve.c @@ -19,7 +19,7 @@ char *cnid_tdb_resolve(struct _cnid_db *cdb, cnid_t * id, void *buffer, size_t l if (!cdb || !(db = cdb->_private) || !id || !(*id)) { return NULL; } - key.dptr = (char *)id; + key.dptr = (unsigned char *)id; key.dsize = sizeof(cnid_t); data = tdb_fetch(db->tdb_cnid, key); if (data.dptr) diff --git a/libatalk/cnid/tdb/cnid_tdb_update.c b/libatalk/cnid/tdb/cnid_tdb_update.c index d367334e..6d23b109 100644 --- a/libatalk/cnid/tdb/cnid_tdb_update.c +++ b/libatalk/cnid/tdb/cnid_tdb_update.c @@ -38,7 +38,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, free(altdata.dptr); if (data.dptr) { - key.dptr = (char *)data.dptr +CNID_DID_OFS; + key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS; key.dsize = data.dsize - CNID_DID_OFS; tdb_delete(db->tdb_didname, key); @@ -49,7 +49,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, /* search by did/name */ data.dptr = make_tdb_data(cdb->flags, st, did, name, len); data.dsize = CNID_HEADER_LEN + len + 1; - key.dptr = (char *)data.dptr +CNID_DID_OFS; + key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS; key.dsize = data.dsize - CNID_DID_OFS; altdata = tdb_fetch(db->tdb_didname, key); if (altdata.dptr) { @@ -76,7 +76,7 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, memcpy(data.dptr, &id, sizeof(id)); /* Update the old CNID with the new info. */ - key.dptr = (char *) &id; + key.dptr = (unsigned char *) &id; key.dsize = sizeof(id); if (tdb_store(db->tdb_cnid, key, data, TDB_REPLACE)) { goto update_err; @@ -85,13 +85,13 @@ int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, /* Put in a new dev/ino mapping. */ key.dptr = data.dptr +CNID_DEVINO_OFS; key.dsize = CNID_DEVINO_LEN; - altdata.dptr = (char *) &id; + altdata.dptr = (unsigned char *) &id; altdata.dsize = sizeof(id); if (tdb_store(db->tdb_devino, key, altdata, TDB_REPLACE)) { goto update_err; } /* put in a new did/name mapping. */ - key.dptr = (char *) data.dptr +CNID_DID_OFS; + key.dptr = (unsigned char *) data.dptr +CNID_DID_OFS; key.dsize = data.dsize -CNID_DID_OFS; if (tdb_store(db->tdb_didname, key, altdata, TDB_REPLACE)) { diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index d5b855a8..39c93bf5 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -36,7 +36,7 @@ int dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval, afp_child_t **childp) { pid_t pid; - unsigned int ipc_fds[2]; + int ipc_fds[2]; afp_child_t *child; if (socketpair(PF_UNIX, SOCK_STREAM, 0, ipc_fds) < 0) { diff --git a/libatalk/iniparser/iniparser.c b/libatalk/iniparser/iniparser.c index c0514d96..93e14b6b 100644 --- a/libatalk/iniparser/iniparser.c +++ b/libatalk/iniparser/iniparser.c @@ -532,7 +532,6 @@ dictionary * iniparser_load(const char * ininame) char line [ASCIILINESZ+1] ; char section [ASCIILINESZ+1] ; char key [ASCIILINESZ+1] ; - char tmp [ASCIILINESZ+1] ; char val [ASCIILINESZ+1] ; int last=0 ; diff --git a/libatalk/tdb/io.c b/libatalk/tdb/io.c index d549715f..55bc9818 100644 --- a/libatalk/tdb/io.c +++ b/libatalk/tdb/io.c @@ -25,7 +25,6 @@ License along with this library; if not, see . */ - #include "tdb_private.h" /* check for an out of bounds access - if it is out of bounds then diff --git a/libatalk/tdb/tdb_private.h b/libatalk/tdb/tdb_private.h index 41389c41..de5dd02b 100644 --- a/libatalk/tdb/tdb_private.h +++ b/libatalk/tdb/tdb_private.h @@ -23,15 +23,9 @@ License along with this library; if not, see . */ -#if 0 -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "system/shmem.h" -#include "system/select.h" -#include "system/wait.h" -#include "tdb.h" -#endif +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ #include #include @@ -50,6 +44,7 @@ #include #include #include +#include #ifndef __STRING #define __STRING(x) #x @@ -78,10 +73,6 @@ typedef uint32_t tdb_len_t; typedef uint32_t tdb_off_t; -#ifndef offsetof -#define offsetof(t,f) ((unsigned int)&((t *)0)->f) -#endif - #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) diff --git a/libatalk/unicode/util_unistr.c b/libatalk/unicode/util_unistr.c index ce3355df..0eba9a3c 100644 --- a/libatalk/unicode/util_unistr.c +++ b/libatalk/unicode/util_unistr.c @@ -291,12 +291,12 @@ int strcasecmp_w(const ucs2_t *a, const ucs2_t *b) while (*a && *b) { if ((0xD800 <= *a) && (*a < 0xDC00)) { - if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret; + if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret; a++; b++; if (!(*a && *b)) return (tolower_w(*a) - tolower_w(*b)); /* avoid buffer over run */ } else { - if (ret = tolower_w(*a) - tolower_w(*b)) return ret; + if ((ret = tolower_w(*a) - tolower_w(*b))) return ret; } a++; b++; @@ -317,13 +317,13 @@ int strncasecmp_w(const ucs2_t *a, const ucs2_t *b, size_t len) while ((n < len) && *a && *b) { if ((0xD800 <= *a) && (*a < 0xDC00)) { - if (ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1])) return ret; + if ((ret = tolower_sp((uint32_t)*a << 16 | (uint32_t)a[1]) - tolower_sp((uint32_t)*b << 16 | (uint32_t)b[1]))) return ret; a++; b++; n++; if (!((n < len) && *a && *b)) return (tolower_w(*a) - tolower_w(*b)); } else { - if (ret = tolower_w(*a) - tolower_w(*b)) return ret; + if ((ret = tolower_w(*a) - tolower_w(*b))) return ret; } a++; b++; @@ -607,7 +607,7 @@ size_t precompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen) base_sp = ((uint32_t)base << 16) | (uint32_t)comb; do { comb_sp = ((uint32_t)in[1] << 16) | (uint32_t)in[2]; - if (result_sp = do_precomposition_sp(base_sp, comb_sp)) { + if ((result_sp = do_precomposition_sp(base_sp, comb_sp))) { base_sp = result_sp; i += 4; in +=2; @@ -641,7 +641,7 @@ size_t precompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen) } /* Binary Search for BMP */ - else if (result = do_precomposition(base, comb)) { + else if ((result = do_precomposition(base, comb))) { base = result; } diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 824c69f9..46d6f766 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -51,6 +51,7 @@ #include #include #include +#include #define VOLPASSLEN 8 #ifndef UUID_PRINTABLE_STRING_LENGTH @@ -513,13 +514,11 @@ static int hostaccessvol(const AFPObj *obj, const char *volname, const char *arg */ static const char *getoption(const dictionary *conf, const char *vol, const char *opt, const char *defsec, const char *defval) { - EC_INIT; const char *result; if ((!(result = iniparser_getstring(conf, vol, opt, NULL))) && (defsec != NULL)) result = iniparser_getstring(conf, defsec, opt, NULL); -EC_CLEANUP: if (result == NULL) result = defval; return result; @@ -538,13 +537,11 @@ static const char *getoption(const dictionary *conf, const char *vol, const char */ static int getoption_bool(const dictionary *conf, const char *vol, const char *opt, const char *defsec, int defval) { - EC_INIT; int result; if (((result = iniparser_getboolean(conf, vol, opt, -1)) == -1) && (defsec != NULL)) result = iniparser_getboolean(conf, defsec, opt, -1); -EC_CLEANUP: if (result == -1) result = defval; return result; @@ -639,14 +636,14 @@ static struct vol *creatvol(AFPObj *obj, volume->v_vfs_ea = AFPVOL_EA_AUTO; volume->v_umask = obj->options.umask; - if (val = getoption(obj->iniconfig, section, "password", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "password", preset, NULL))) EC_NULL( volume->v_password = strdup(val) ); - if (val = getoption(obj->iniconfig, section, "veto files", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "veto files", preset, NULL))) EC_NULL( volume->v_veto = strdup(val) ); /* vol charset is in [G] and [V] */ - if (val = getoption(obj->iniconfig, section, "vol charset", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "vol charset", preset, NULL))) { if (strcasecmp(val, "UTF-8") == 0) { val = strdup("UTF8"); } @@ -656,7 +653,7 @@ static struct vol *creatvol(AFPObj *obj, EC_NULL( volume->v_volcodepage = strdup(obj->options.volcodepage) ); /* mac charset is in [G] and [V] */ - if (val = getoption(obj->iniconfig, section, "mac charset", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "mac charset", preset, NULL))) { if (strncasecmp(val, "MAC", 3) != 0) { LOG(log_warning, logtype_afpd, "Is '%s' really mac charset? ", val); } @@ -671,41 +668,41 @@ static struct vol *creatvol(AFPObj *obj, if(tmpname[i] == '/') tmpname[i] = ':'; bstring dbpath; - EC_NULL_LOG( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") ); - EC_NULL_LOG( dbpath = bformat("%s/%s/", val, tmpname) ); - EC_NULL_LOG( volume->v_dbpath = strdup(bdata(dbpath)) ); + EC_NULL( val = iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "vol dbpath", _PATH_STATEDIR "CNID/") ); + EC_NULL( dbpath = bformat("%s/%s/", val, tmpname) ); + EC_NULL( volume->v_dbpath = strdup(cfrombstr(dbpath)) ); bdestroy(dbpath); - if (val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "cnid scheme", preset, NULL))) EC_NULL( volume->v_cnidscheme = strdup(val) ); else volume->v_cnidscheme = strdup(DEFAULT_CNID_SCHEME); - if (val = getoption(obj->iniconfig, section, "umask", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "umask", preset, NULL))) volume->v_umask = (int)strtol(val, NULL, 8); - if (val = getoption(obj->iniconfig, section, "directory perm", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "directory perm", preset, NULL))) volume->v_dperm = (int)strtol(val, NULL, 8); - if (val = getoption(obj->iniconfig, section, "file perm", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "file perm", preset, NULL))) volume->v_fperm = (int)strtol(val, NULL, 8); - if (val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "vol size limit", preset, NULL))) volume->v_limitsize = (uint32_t)strtoul(val, NULL, 10); - if (val = getoption(obj->iniconfig, section, "preexec", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "preexec", preset, NULL))) EC_NULL( volume->v_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) ); - if (val = getoption(obj->iniconfig, section, "postexec", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "postexec", preset, NULL))) EC_NULL( volume->v_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) ); - if (val = getoption(obj->iniconfig, section, "root preexec", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "root preexec", preset, NULL))) EC_NULL( volume->v_root_preexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) ); - if (val = getoption(obj->iniconfig, section, "root postexec", preset, NULL)) + if ((val = getoption(obj->iniconfig, section, "root postexec", preset, NULL))) EC_NULL( volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, val, pwd, path, name) ); - if (val = getoption(obj->iniconfig, section, "appledouble", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "appledouble", preset, NULL))) { if (strcmp(val, "v2") == 0) volume->v_adouble = AD_VERSION2; else if (strcmp(val, "ea") == 0) @@ -714,10 +711,10 @@ static struct vol *creatvol(AFPObj *obj, volume->v_adouble = AD_VERSION; } - if (val = getoption(obj->iniconfig, section, "cnid server", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "cnid server", preset, NULL))) { EC_NULL( p = strdup(val) ); volume->v_cnidserver = p; - if (q = strrchr(val, ':')) { + if ((q = strrchr(val, ':'))) { *q++ = 0; volume->v_cnidport = strdup(q); } else { @@ -729,7 +726,7 @@ static struct vol *creatvol(AFPObj *obj, volume->v_cnidport = strdup(obj->options.Cnid_port); } - if (val = getoption(obj->iniconfig, section, "ea", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "ea", preset, NULL))) { if (strcasecmp(val, "ad") == 0) volume->v_vfs_ea = AFPVOL_EA_AD; else if (strcasecmp(val, "sys") == 0) @@ -738,7 +735,7 @@ static struct vol *creatvol(AFPObj *obj, volume->v_vfs_ea = AFPVOL_EA_NONE; } - if (val = getoption(obj->iniconfig, section, "casefold", preset, NULL)) { + if ((val = getoption(obj->iniconfig, section, "casefold", preset, NULL))) { if (strcasecmp(val, "tolower") == 0) volume->v_casefold = AFPVOL_UMLOWER; else if (strcasecmp(val, "toupper") == 0) @@ -981,9 +978,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) char volname[AFPVOL_U8MNAMELEN + 1]; char path[MAXPATHLEN + 1], tmp[MAXPATHLEN + 1]; const char *preset, *default_preset, *p, *basedir; - char *q, *u; int i; - struct passwd *pw; regmatch_t match[1]; LOG(log_debug, logtype_afpd, "readvolfile: BEGIN"); @@ -1034,7 +1029,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) continue; } - if (p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) { + if ((p = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) { strlcat(tmp, "/", MAXPATHLEN); strlcat(tmp, p, MAXPATHLEN); } @@ -1075,7 +1070,7 @@ static int readvolfile(AFPObj *obj, const struct passwd *pwent) free(realvolpath); } -EC_CLEANUP: +// EC_CLEANUP: EC_EXIT; } @@ -1538,7 +1533,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) p++; EC_NULL_LOG( user = strdup(p) ); - if (prw = strchr(user, '/')) + if ((prw = strchr(user, '/'))) *prw++ = 0; if (prw != 0) subpath = prw; @@ -1548,7 +1543,7 @@ struct vol *getvolbypath(AFPObj *obj, const char *path) strlcat(tmpbuf, "/", MAXPATHLEN); /* (6) */ - if (subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL)) { + if ((subpathconfig = iniparser_getstring(obj->iniconfig, INISEC_HOMES, "path", NULL))) { /* if (!subpath || strncmp(subpathconfig, subpath, strlen(subpathconfig)) != 0) { EC_FAIL; @@ -1615,8 +1610,8 @@ int afp_config_parse(AFPObj *AFPObj, char *processname) EC_INIT; dictionary *config; struct afp_options *options = &AFPObj->options; - int i, c; - const char *p, *tmp; + int c; + const char *p; char *q, *r; char val[MAXVAL]; diff --git a/libatalk/util/server_child.c b/libatalk/util/server_child.c index ada3e610..547d68d9 100644 --- a/libatalk/util/server_child.c +++ b/libatalk/util/server_child.c @@ -135,7 +135,7 @@ afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, int fork = (server_child_fork *) children->fork + forkid; /* if we already have an entry. just return. */ - if (child = resolve_child(fork->table, pid)) + if ((child = resolve_child(fork->table, pid))) goto exit; if ((child = calloc(1, sizeof(afp_child_t))) == NULL) @@ -262,7 +262,6 @@ int server_child_transfer_session(server_child *children, EC_INIT; server_child_fork *fork; struct server_child_data *child; - int i; fork = (server_child_fork *) children->fork + forkid; if ((child = resolve_child(fork->table, pid)) == NULL) { diff --git a/libatalk/util/server_ipc.c b/libatalk/util/server_ipc.c index d40e3a49..815c58d8 100644 --- a/libatalk/util/server_ipc.c +++ b/libatalk/util/server_ipc.c @@ -267,8 +267,6 @@ int ipc_server_read(server_child *children, int fd) LOG(log_debug, logtype_afpd, "ipc_server_read(%s): pid: %u", ipc_cmd_str[ipc.command], ipc.child_pid); - int afp_socket; - switch (ipc.command) { case IPC_DISCOLDSESSION: diff --git a/libatalk/util/server_lock.c b/libatalk/util/server_lock.c index 0251eada..6ae817e5 100644 --- a/libatalk/util/server_lock.c +++ b/libatalk/util/server_lock.c @@ -126,9 +126,7 @@ int check_lockfile(const char *program, const char *pidfile) */ int create_lockfile(const char *program, const char *pidfile) { - char buf[10]; FILE *pf; - pid_t pid; int mask; if (check_lockfile(program, pidfile) != 0) diff --git a/libatalk/vfs/unix.c b/libatalk/vfs/unix.c index f414bf59..bc90c75a 100644 --- a/libatalk/vfs/unix.c +++ b/libatalk/vfs/unix.c @@ -166,9 +166,6 @@ int copy_file(int dirfd, const char *src, const char *dst, mode_t mode) int ret = 0; int sfd = -1; int dfd = -1; - ssize_t cc; - size_t buflen; - char filebuf[NETATALK_DIOSZ_STACK]; #ifdef HAVE_ATFUNCS if (dirfd == -1) diff --git a/libatalk/vfs/vfs.c b/libatalk/vfs/vfs.c index 53b53064..3dd3ebb4 100644 --- a/libatalk/vfs/vfs.c +++ b/libatalk/vfs/vfs.c @@ -170,7 +170,6 @@ static int RF_setfilmode_adouble(VFS_FUNC_ARGS_SETFILEMODE) static int RF_setdirunixmode_adouble(VFS_FUNC_ARGS_SETDIRUNIXMODE) { const char *adouble = vol->ad_path(name, ADFLAGS_DIR ); - int dropbox = vol->v_flags; if (dir_rx_set(mode)) { if (chmod_acl(ad_dir(adouble), (DIRBITS | mode) & ~vol->v_umask) < 0 ) @@ -208,7 +207,6 @@ static int setdirmode_adouble_loop(const struct vol *vol, struct dirent *de _U_, static int RF_setdirmode_adouble(VFS_FUNC_ARGS_SETDIRMODE) { - int dropbox = vol->v_flags; mode_t hf_mode = ad_hf_mode(mode); const char *adouble = vol->ad_path(name, ADFLAGS_DIR ); const char *adouble_p = ad_dir(adouble); From 042dcb4dca04c526463a98c0c07a15608911d42f Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 3 Jan 2013 13:42:22 +0100 Subject: [PATCH 103/117] Remove MAP_FILE --- libatalk/tdb/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libatalk/tdb/io.c b/libatalk/tdb/io.c index 55bc9818..88ff7acc 100644 --- a/libatalk/tdb/io.c +++ b/libatalk/tdb/io.c @@ -211,7 +211,7 @@ void tdb_mmap(struct tdb_context *tdb) if (!(tdb->flags & TDB_NOMMAP)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); + MAP_SHARED, tdb->fd, 0); /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! From 8f261a8e2af6dd60b124ae8dfd02c1300c427474 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 3 Jan 2013 13:44:59 +0100 Subject: [PATCH 104/117] rights was removed in warnings cleanup --- etc/afpd/acls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index 5cab99fe..55a1e3ae 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -1736,6 +1736,7 @@ int acltoownermode(const AFPObj *obj, const struct vol *vol, char *path, struct getcwdpath(), path, ma->ma_user); #ifdef HAVE_SOLARIS_ACLS + uint32_t rights = 0; EC_ZERO_LOG(solaris_acl_rights(obj, path, st, &rights)); LOG(log_maxdebug, logtype_afpd, "rights: 0x%08x", rights); From 167e0c276e771987ffdad5eb7d81821c4d9a69a0 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 3 Jan 2013 18:34:48 +0100 Subject: [PATCH 105/117] Remove 'duplicated volumes paths' --- NEWS | 1 - 1 file changed, 1 deletion(-) diff --git a/NEWS b/NEWS index 5768657e..08481d64 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,6 @@ 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. -* UPD: ignore volumes with duplicated volumes paths. * 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. From 9f957894d9a60f32adc56edddf72fa767ded8219 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 4 Jan 2013 15:46:34 +0100 Subject: [PATCH 106/117] Remove CVS keywords --- bin/cnid/cnid2_create.in | 1 - bin/megatron/asingle.c | 1 - bin/megatron/asingle.h | 1 - bin/megatron/hqx.c | 1 - bin/megatron/hqx.h | 1 - bin/megatron/macbin.c | 1 - bin/megatron/macbin.h | 1 - bin/megatron/megatron.h | 1 - bin/megatron/nad.c | 1 - bin/megatron/nad.h | 1 - bin/megatron/updcrc.c | 1 - bin/megatron/updcrc.h | 1 - etc/afpd/afp_util.c | 1 - etc/afpd/afs.c | 1 - etc/afpd/appl.c | 1 - etc/afpd/extattrs.h | 1 - etc/afpd/hash.c | 2 -- etc/afpd/hash.h | 1 - etc/afpd/mangle.h | 1 - etc/afpd/nfsquota.c | 1 - etc/afpd/quota.c | 1 - etc/afpd/switch.h | 1 - etc/afpd/uam.c | 1 - etc/afpd/uid.c | 1 - etc/afpd/uid.h | 1 - etc/cnid_dbd/db_param.c | 1 - etc/cnid_dbd/dbd_dbcheck.c | 1 - etc/cnid_dbd/dbd_delete.c | 1 - etc/cnid_dbd/dbd_get.c | 1 - etc/cnid_dbd/dbd_getstamp.c | 1 - etc/cnid_dbd/dbd_lookup.c | 1 - etc/cnid_dbd/dbd_rebuild_add.c | 1 - etc/cnid_dbd/dbd_resolve.c | 1 - etc/cnid_dbd/usockfd.h | 1 - etc/uams/uams_dhx2_passwd.c | 1 - etc/uams/uams_dhx_pam.c | 1 - etc/uams/uams_guest.c | 1 - etc/uams/uams_pam.c | 1 - etc/uams/uams_pgp.c | 1 - etc/uams/uams_randnum.c | 1 - include/atalk/dictionary.h | 3 --- include/atalk/hash.h | 1 - include/atalk/iniparser.h | 2 -- libatalk/acl/cache.h | 1 - libatalk/adouble/ad_size.c | 1 - libatalk/bstring/bstradd.c | 1 - libatalk/cnid/cdb/cnid_cdb_close.c | 1 - libatalk/cnid/cdb/cnid_cdb_delete.c | 1 - libatalk/cnid/cdb/cnid_cdb_meta.c | 1 - libatalk/cnid/cdb/cnid_cdb_meta.h | 1 - libatalk/cnid/cdb/cnid_cdb_nextid.c | 1 - libatalk/cnid/cdb/cnid_cdb_rebuild_add.c | 1 - libatalk/cnid/cdb/cnid_cdb_resolve.c | 1 - libatalk/cnid/cnid_init.c | 1 - libatalk/cnid/last/cnid_last.c | 1 - libatalk/cnid/tdb/cnid_tdb_close.c | 1 - libatalk/cnid/tdb/cnid_tdb_delete.c | 1 - libatalk/cnid/tdb/cnid_tdb_nextid.c | 1 - libatalk/cnid/tdb/cnid_tdb_resolve.c | 1 - libatalk/compat/getusershell.c | 1 - libatalk/compat/mktemp.c | 1 - libatalk/compat/rquota_xdr.c | 1 - libatalk/dsi/dsi_attn.c | 1 - libatalk/dsi/dsi_close.c | 1 - libatalk/dsi/dsi_getsess.c | 1 - libatalk/dsi/dsi_getstat.c | 1 - libatalk/dsi/dsi_tickle.c | 1 - libatalk/dsi/dsi_write.c | 1 - libatalk/iniparser/dictionary.c | 3 --- libatalk/unicode/charsets/mac_roman.h | 1 - libatalk/util/gettok.c | 1 - libatalk/util/locking.c | 1 - libatalk/util/module.c | 1 - macros/afs-check.m4 | 1 - macros/grep-check.m4 | 1 - macros/pam-check.m4 | 1 - macros/perl-check.m4 | 1 - macros/ps-check.m4 | 1 - macros/quota-check.m4 | 1 - macros/ssl-check.m4 | 1 - macros/tcp-wrappers.m4 | 1 - test/afpd/afpfunc_helpers.c | 1 - test/afpd/afpfunc_helpers.h | 1 - test/afpd/subtests.h | 1 - test/afpd/test.h | 1 - 85 files changed, 91 deletions(-) diff --git a/bin/cnid/cnid2_create.in b/bin/cnid/cnid2_create.in index e81ff1f3..c3e3ffd6 100755 --- a/bin/cnid/cnid2_create.in +++ b/bin/cnid/cnid2_create.in @@ -3,7 +3,6 @@ # # Upgrade version 1 CNID databases to version 2 # -# $Id: cnid2_create.in,v 1.2 2005-04-28 20:49:19 bfernhomberg Exp $ # # Copyright (C) Joerg Lenneis 2003 # All Rights Reserved. See COPYING. diff --git a/bin/megatron/asingle.c b/bin/megatron/asingle.c index 73e4ffaa..9ba3918b 100644 --- a/bin/megatron/asingle.c +++ b/bin/megatron/asingle.c @@ -1,5 +1,4 @@ /* - * $Id: asingle.c,v 1.14 2010-01-27 21:27:53 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/bin/megatron/asingle.h b/bin/megatron/asingle.h index c041ccaa..769d58cd 100644 --- a/bin/megatron/asingle.h +++ b/bin/megatron/asingle.h @@ -1,5 +1,4 @@ /* - * $Id: asingle.h,v 1.4 2010-01-27 21:27:53 didg Exp $ */ #ifndef _ASINGLE_H diff --git a/bin/megatron/hqx.c b/bin/megatron/hqx.c index da2f71cf..923ddbd1 100644 --- a/bin/megatron/hqx.c +++ b/bin/megatron/hqx.c @@ -1,5 +1,4 @@ /* - * $Id: hqx.c,v 1.18 2010-01-27 21:27:53 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/bin/megatron/hqx.h b/bin/megatron/hqx.h index 38730d05..b656f0b6 100644 --- a/bin/megatron/hqx.h +++ b/bin/megatron/hqx.h @@ -1,5 +1,4 @@ /* - * $Id: hqx.h,v 1.3 2010-01-27 21:27:53 didg Exp $ */ #ifndef _HQX_H diff --git a/bin/megatron/macbin.c b/bin/megatron/macbin.c index 51b7ac5f..986aac92 100644 --- a/bin/megatron/macbin.c +++ b/bin/megatron/macbin.c @@ -1,5 +1,4 @@ /* - * $Id: macbin.c,v 1.15 2010-01-27 21:27:53 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/bin/megatron/macbin.h b/bin/megatron/macbin.h index d216b1b9..a1c5a3a1 100644 --- a/bin/megatron/macbin.h +++ b/bin/megatron/macbin.h @@ -1,5 +1,4 @@ /* - * $Id: macbin.h,v 1.4 2010-01-27 21:27:53 didg Exp $ */ #ifndef _MACBIN_H diff --git a/bin/megatron/megatron.h b/bin/megatron/megatron.h index c9aa8cee..421a26af 100644 --- a/bin/megatron/megatron.h +++ b/bin/megatron/megatron.h @@ -1,5 +1,4 @@ /* - * $Id: megatron.h,v 1.5 2009-10-14 01:38:28 didg Exp $ */ #ifndef _MEGATRON_H diff --git a/bin/megatron/nad.c b/bin/megatron/nad.c index 9d0b64bf..abe4541c 100644 --- a/bin/megatron/nad.c +++ b/bin/megatron/nad.c @@ -1,5 +1,4 @@ /* - * $Id: nad.c,v 1.18 2010-01-27 21:27:53 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/bin/megatron/nad.h b/bin/megatron/nad.h index 9fa85684..f69e7323 100644 --- a/bin/megatron/nad.h +++ b/bin/megatron/nad.h @@ -1,5 +1,4 @@ /* - * $Id: nad.h,v 1.5 2010-01-27 21:27:53 didg Exp $ */ #ifndef _NAD_H diff --git a/bin/megatron/updcrc.c b/bin/megatron/updcrc.c index d327571d..ca199c8a 100644 --- a/bin/megatron/updcrc.c +++ b/bin/megatron/updcrc.c @@ -1,5 +1,4 @@ /* - * $Id: updcrc.c,v 1.5 2009-10-13 22:55:36 didg Exp $ * * updcrc(3), crc(1) - calculate crc polynomials * diff --git a/bin/megatron/updcrc.h b/bin/megatron/updcrc.h index 0b6039e5..75c38388 100644 --- a/bin/megatron/updcrc.h +++ b/bin/megatron/updcrc.h @@ -1,5 +1,4 @@ /* - * $Id: updcrc.h,v 1.1 2009-10-13 22:55:36 didg Exp $ */ #ifndef _UPDCRC_H diff --git a/etc/afpd/afp_util.c b/etc/afpd/afp_util.c index a8282c22..b7bc00f8 100644 --- a/etc/afpd/afp_util.c +++ b/etc/afpd/afp_util.c @@ -1,5 +1,4 @@ /* - * $Id: afp_util.c,v 1.10 2010-01-23 14:44:42 franklahm Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * Copyright (c) 1990,1993 Regents of The University of Michigan. diff --git a/etc/afpd/afs.c b/etc/afpd/afs.c index f11d77eb..efe2ab63 100644 --- a/etc/afpd/afs.c +++ b/etc/afpd/afs.c @@ -1,5 +1,4 @@ /* - * $Id: afs.c,v 1.18 2009-10-15 10:43:13 didg Exp $ * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. */ diff --git a/etc/afpd/appl.c b/etc/afpd/appl.c index 3cba16e0..04dd92d6 100644 --- a/etc/afpd/appl.c +++ b/etc/afpd/appl.c @@ -1,5 +1,4 @@ /* - * $Id: appl.c,v 1.18.4.1 2010-02-01 10:56:08 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. diff --git a/etc/afpd/extattrs.h b/etc/afpd/extattrs.h index 64e8482d..68e65905 100644 --- a/etc/afpd/extattrs.h +++ b/etc/afpd/extattrs.h @@ -1,5 +1,4 @@ /* - $Id: extattrs.h,v 1.3 2009-10-15 10:43:13 didg Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/etc/afpd/hash.c b/etc/afpd/hash.c index f1e30685..4861e811 100644 --- a/etc/afpd/hash.c +++ b/etc/afpd/hash.c @@ -14,7 +14,6 @@ * into proprietary software; there is no requirement for such software to * contain a copyright notice related to this source. * - * $Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $ * $Name: $ */ #define NDEBUG @@ -26,7 +25,6 @@ #include "hash.h" #ifdef KAZLIB_RCSID -static const char rcsid[] = "$Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $"; #endif #define INIT_BITS 6 diff --git a/etc/afpd/hash.h b/etc/afpd/hash.h index dcac14b6..886344eb 100644 --- a/etc/afpd/hash.h +++ b/etc/afpd/hash.h @@ -14,7 +14,6 @@ * into proprietary software; there is no requirement for such software to * contain a copyright notice related to this source. * - * $Id: hash.h,v 1.2 2009-10-02 09:32:40 franklahm Exp $ * $Name: $ */ diff --git a/etc/afpd/mangle.h b/etc/afpd/mangle.h index dce7e616..18d6fcd9 100644 --- a/etc/afpd/mangle.h +++ b/etc/afpd/mangle.h @@ -1,5 +1,4 @@ /* - * $Id: mangle.h,v 1.7 2009-10-13 22:55:37 didg Exp $ * */ diff --git a/etc/afpd/nfsquota.c b/etc/afpd/nfsquota.c index b250c166..50440ab4 100644 --- a/etc/afpd/nfsquota.c +++ b/etc/afpd/nfsquota.c @@ -1,5 +1,4 @@ /* - * $Id: nfsquota.c,v 1.13 2009-10-13 22:55:37 didg Exp $ * * parts of this are lifted from the bsd quota program and are * therefore under the following copyright: diff --git a/etc/afpd/quota.c b/etc/afpd/quota.c index 5aa7f3f3..614a7f95 100644 --- a/etc/afpd/quota.c +++ b/etc/afpd/quota.c @@ -1,5 +1,4 @@ /* - * $Id: quota.c,v 1.35 2010-04-03 07:11:35 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. diff --git a/etc/afpd/switch.h b/etc/afpd/switch.h index 2f94ac88..1cc50d01 100644 --- a/etc/afpd/switch.h +++ b/etc/afpd/switch.h @@ -1,5 +1,4 @@ /* - * $Id: switch.h,v 1.4 2009-10-15 10:43:13 didg Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. diff --git a/etc/afpd/uam.c b/etc/afpd/uam.c index 625cf6a5..208c9ff2 100644 --- a/etc/afpd/uam.c +++ b/etc/afpd/uam.c @@ -1,5 +1,4 @@ /* - * $Id: uam.c,v 1.35 2009-11-08 01:15:31 didg Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. diff --git a/etc/afpd/uid.c b/etc/afpd/uid.c index e26e6d1f..a3e4d597 100644 --- a/etc/afpd/uid.c +++ b/etc/afpd/uid.c @@ -1,5 +1,4 @@ /* - * $Id: uid.c,v 1.14 2005-04-28 20:49:45 bfernhomberg Exp $ * code: jeff@univrel.pr.uconn.edu * * These functions are abstracted here, so that all calls for resolving diff --git a/etc/afpd/uid.h b/etc/afpd/uid.h index 647cbd8d..87745147 100644 --- a/etc/afpd/uid.h +++ b/etc/afpd/uid.h @@ -1,5 +1,4 @@ /* - * $Id: uid.h,v 1.6 2002-08-30 19:32:41 didg Exp $ * code: jeff@univrel.pr.uconn.edu */ diff --git a/etc/cnid_dbd/db_param.c b/etc/cnid_dbd/db_param.c index c89f8e5c..3c8c102f 100644 --- a/etc/cnid_dbd/db_param.c +++ b/etc/cnid_dbd/db_param.c @@ -1,5 +1,4 @@ /* - * $Id: db_param.c,v 1.9 2009-11-23 19:04:14 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * Copyright (c) Frank Lahm 2009 diff --git a/etc/cnid_dbd/dbd_dbcheck.c b/etc/cnid_dbd/dbd_dbcheck.c index e621704f..98ce2210 100644 --- a/etc/cnid_dbd/dbd_dbcheck.c +++ b/etc/cnid_dbd/dbd_dbcheck.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_dbcheck.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/dbd_delete.c b/etc/cnid_dbd/dbd_delete.c index a4a3ca63..f34a9d50 100644 --- a/etc/cnid_dbd/dbd_delete.c +++ b/etc/cnid_dbd/dbd_delete.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_delete.c,v 1.5 2009-07-12 09:21:34 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/dbd_get.c b/etc/cnid_dbd/dbd_get.c index 0ef71b19..c1c7bb8c 100644 --- a/etc/cnid_dbd/dbd_get.c +++ b/etc/cnid_dbd/dbd_get.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_get.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/dbd_getstamp.c b/etc/cnid_dbd/dbd_getstamp.c index 197a6db1..ffba3972 100644 --- a/etc/cnid_dbd/dbd_getstamp.c +++ b/etc/cnid_dbd/dbd_getstamp.c @@ -1,6 +1,5 @@ /* - * $Id: dbd_getstamp.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/dbd_lookup.c b/etc/cnid_dbd/dbd_lookup.c index 44e46620..f77b9fc2 100644 --- a/etc/cnid_dbd/dbd_lookup.c +++ b/etc/cnid_dbd/dbd_lookup.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_lookup.c,v 1.18 2010-01-19 14:57:11 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * Copyright (C) Frank Lahm 2009 diff --git a/etc/cnid_dbd/dbd_rebuild_add.c b/etc/cnid_dbd/dbd_rebuild_add.c index 562838b3..f1bf7aca 100644 --- a/etc/cnid_dbd/dbd_rebuild_add.c +++ b/etc/cnid_dbd/dbd_rebuild_add.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_rebuild_add.c,v 1.4 2009-12-23 10:18:48 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2005 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/dbd_resolve.c b/etc/cnid_dbd/dbd_resolve.c index bb3561ca..53407757 100644 --- a/etc/cnid_dbd/dbd_resolve.c +++ b/etc/cnid_dbd/dbd_resolve.c @@ -1,5 +1,4 @@ /* - * $Id: dbd_resolve.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/cnid_dbd/usockfd.h b/etc/cnid_dbd/usockfd.h index ee4d4327..27bde63c 100644 --- a/etc/cnid_dbd/usockfd.h +++ b/etc/cnid_dbd/usockfd.h @@ -1,5 +1,4 @@ /* - * $Id: usockfd.h,v 1.5 2009-11-05 14:38:07 franklahm Exp $ * * Copyright (C) Joerg Lenneis 2003 * All Rights Reserved. See COPYING. diff --git a/etc/uams/uams_dhx2_passwd.c b/etc/uams/uams_dhx2_passwd.c index c4a322ad..a2737d0f 100644 --- a/etc/uams/uams_dhx2_passwd.c +++ b/etc/uams/uams_dhx2_passwd.c @@ -1,5 +1,4 @@ /* - * $Id: uams_dhx2_passwd.c,v 1.8 2010-03-30 10:25:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 8b879f06..bc19c785 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -1,5 +1,4 @@ /* - * $Id: uams_dhx_pam.c,v 1.33 2010-03-30 10:25:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) diff --git a/etc/uams/uams_guest.c b/etc/uams/uams_guest.c index 00f90ece..82ee43ef 100644 --- a/etc/uams/uams_guest.c +++ b/etc/uams/uams_guest.c @@ -1,5 +1,4 @@ /* - * $Id: uams_guest.c,v 1.18 2009-11-08 01:07:17 didg Exp $ * * (c) 2001 (see COPYING) */ diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index 1bbb1cd9..b490c2ee 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -1,5 +1,4 @@ /* - * $Id: uams_pam.c,v 1.24 2010-03-30 10:25:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) diff --git a/etc/uams/uams_pgp.c b/etc/uams/uams_pgp.c index 9b9c1d80..6a299440 100644 --- a/etc/uams/uams_pgp.c +++ b/etc/uams/uams_pgp.c @@ -1,5 +1,4 @@ /* - * $Id: uams_pgp.c,v 1.12 2009-10-15 11:39:48 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) diff --git a/etc/uams/uams_randnum.c b/etc/uams/uams_randnum.c index 301fdd0f..22687fcc 100644 --- a/etc/uams/uams_randnum.c +++ b/etc/uams/uams_randnum.c @@ -1,5 +1,4 @@ /* - * $Id: uams_randnum.c,v 1.21 2010-03-30 10:25:49 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) diff --git a/include/atalk/dictionary.h b/include/atalk/dictionary.h index 7a910524..b28d736e 100644 --- a/include/atalk/dictionary.h +++ b/include/atalk/dictionary.h @@ -4,7 +4,6 @@ @file dictionary.h @author N. Devillard @date Sep 2007 - @version $Revision: 1.12 $ @brief Implements a dictionary for string variables. This module implements a simple dictionary object, i.e. a list @@ -14,10 +13,8 @@ /*--------------------------------------------------------------------------*/ /* - $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ $Author: ndevilla $ $Date: 2007-11-23 21:37:00 $ - $Revision: 1.12 $ */ #ifndef _DICTIONARY_H_ diff --git a/include/atalk/hash.h b/include/atalk/hash.h index 14cddf66..0a75e4f6 100644 --- a/include/atalk/hash.h +++ b/include/atalk/hash.h @@ -14,7 +14,6 @@ * into proprietary software; there is no requirement for such software to * contain a copyright notice related to this source. * - * $Id: hash.h,v 1.2 2009-11-19 10:37:44 franklahm Exp $ * $Name: $ */ diff --git a/include/atalk/iniparser.h b/include/atalk/iniparser.h index 0eefa4cb..8f94c5ca 100644 --- a/include/atalk/iniparser.h +++ b/include/atalk/iniparser.h @@ -10,8 +10,6 @@ /*--------------------------------------------------------------------------*/ /* - $Id: iniparser.h,v 1.26 2011-03-02 20:15:13 ndevilla Exp $ - $Revision: 1.26 $ */ #ifndef _INIPARSER_H_ diff --git a/libatalk/acl/cache.h b/libatalk/acl/cache.h index 11731a26..8e33004a 100644 --- a/libatalk/acl/cache.h +++ b/libatalk/acl/cache.h @@ -1,5 +1,4 @@ /* - $Id: cache.h,v 1.1 2009-02-02 11:55:01 franklahm Exp $ Copyright (c) 2008,2009 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/libatalk/adouble/ad_size.c b/libatalk/adouble/ad_size.c index 337ff6ed..6b4ed96d 100644 --- a/libatalk/adouble/ad_size.c +++ b/libatalk/adouble/ad_size.c @@ -1,5 +1,4 @@ /* - * $Id: ad_size.c,v 1.8 2010-02-26 14:13:16 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/bstring/bstradd.c b/libatalk/bstring/bstradd.c index c78fd0e0..98e1a155 100644 --- a/libatalk/bstring/bstradd.c +++ b/libatalk/bstring/bstradd.c @@ -1,5 +1,4 @@ /* - $Id: bstradd.c,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/libatalk/cnid/cdb/cnid_cdb_close.c b/libatalk/cnid/cdb/cnid_cdb_close.c index 92f8ce68..d34a418b 100644 --- a/libatalk/cnid/cdb/cnid_cdb_close.c +++ b/libatalk/cnid/cdb/cnid_cdb_close.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_close.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/cnid/cdb/cnid_cdb_delete.c b/libatalk/cnid/cdb/cnid_cdb_delete.c index 1d14640a..ace358aa 100644 --- a/libatalk/cnid/cdb/cnid_cdb_delete.c +++ b/libatalk/cnid/cdb/cnid_cdb_delete.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_delete.c,v 1.4 2009-10-29 13:38:16 didg Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. diff --git a/libatalk/cnid/cdb/cnid_cdb_meta.c b/libatalk/cnid/cdb/cnid_cdb_meta.c index 9184264a..f88a9e29 100644 --- a/libatalk/cnid/cdb/cnid_cdb_meta.c +++ b/libatalk/cnid/cdb/cnid_cdb_meta.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_meta.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. diff --git a/libatalk/cnid/cdb/cnid_cdb_meta.h b/libatalk/cnid/cdb/cnid_cdb_meta.h index cf9d905a..e8a4bdd0 100644 --- a/libatalk/cnid/cdb/cnid_cdb_meta.h +++ b/libatalk/cnid/cdb/cnid_cdb_meta.h @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_meta.h,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $ */ #define CNID_META_CNID_LEN 4 diff --git a/libatalk/cnid/cdb/cnid_cdb_nextid.c b/libatalk/cnid/cdb/cnid_cdb_nextid.c index 60141c3b..ba14bd8e 100644 --- a/libatalk/cnid/cdb/cnid_cdb_nextid.c +++ b/libatalk/cnid/cdb/cnid_cdb_nextid.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_nextid.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/cnid/cdb/cnid_cdb_rebuild_add.c b/libatalk/cnid/cdb/cnid_cdb_rebuild_add.c index be2db102..4620782e 100644 --- a/libatalk/cnid/cdb/cnid_cdb_rebuild_add.c +++ b/libatalk/cnid/cdb/cnid_cdb_rebuild_add.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_rebuild_add.c,v 1.6 2009-11-20 17:22:11 didg Exp $ * * All Rights Reserved. See COPYRIGHT. * diff --git a/libatalk/cnid/cdb/cnid_cdb_resolve.c b/libatalk/cnid/cdb/cnid_cdb_resolve.c index 6c16ce7e..63ed9f8a 100644 --- a/libatalk/cnid/cdb/cnid_cdb_resolve.c +++ b/libatalk/cnid/cdb/cnid_cdb_resolve.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_cdb_resolve.c,v 1.5 2009-10-29 13:38:16 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/cnid/cnid_init.c b/libatalk/cnid/cnid_init.c index 7cc108d3..75fc5db3 100644 --- a/libatalk/cnid/cnid_init.c +++ b/libatalk/cnid/cnid_init.c @@ -1,6 +1,5 @@ /* - * $Id: cnid_init.c,v 1.3 2009-10-13 22:55:37 didg Exp $ * * Copyright (c) 2003 the Netatalk Team * Copyright (c) 2003 Rafal Lewczuk diff --git a/libatalk/cnid/last/cnid_last.c b/libatalk/cnid/last/cnid_last.c index fd92cc5a..cc2ae1c7 100644 --- a/libatalk/cnid/last/cnid_last.c +++ b/libatalk/cnid/last/cnid_last.c @@ -1,6 +1,5 @@ /* - * $Id: cnid_last.c,v 1.5 2010-03-31 09:47:32 franklahm Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. diff --git a/libatalk/cnid/tdb/cnid_tdb_close.c b/libatalk/cnid/tdb/cnid_tdb_close.c index cbe89a6e..c5001816 100644 --- a/libatalk/cnid/tdb/cnid_tdb_close.c +++ b/libatalk/cnid/tdb/cnid_tdb_close.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_tdb_close.c,v 1.3 2009-11-21 13:38:11 didg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/cnid/tdb/cnid_tdb_delete.c b/libatalk/cnid/tdb/cnid_tdb_delete.c index e7bf6f71..a16a9951 100644 --- a/libatalk/cnid/tdb/cnid_tdb_delete.c +++ b/libatalk/cnid/tdb/cnid_tdb_delete.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_tdb_delete.c,v 1.4 2009-11-20 19:25:05 didg Exp $ * * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. diff --git a/libatalk/cnid/tdb/cnid_tdb_nextid.c b/libatalk/cnid/tdb/cnid_tdb_nextid.c index 8aefa42b..8e7b1261 100644 --- a/libatalk/cnid/tdb/cnid_tdb_nextid.c +++ b/libatalk/cnid/tdb/cnid_tdb_nextid.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_tdb_nextid.c,v 1.2 2005-04-28 20:50:02 bfernhomberg Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/cnid/tdb/cnid_tdb_resolve.c b/libatalk/cnid/tdb/cnid_tdb_resolve.c index 7e80f385..851f9e55 100644 --- a/libatalk/cnid/tdb/cnid_tdb_resolve.c +++ b/libatalk/cnid/tdb/cnid_tdb_resolve.c @@ -1,5 +1,4 @@ /* - * $Id: cnid_tdb_resolve.c,v 1.4 2009-11-22 14:14:05 franklahm Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/libatalk/compat/getusershell.c b/libatalk/compat/getusershell.c index 2716bb8f..481978b9 100644 --- a/libatalk/compat/getusershell.c +++ b/libatalk/compat/getusershell.c @@ -1,5 +1,4 @@ /* - * $Id: getusershell.c,v 1.4 2003-02-17 01:51:08 srittau Exp $ * * Copyright (c) 1985 Regents of the University of California. * All rights reserved. diff --git a/libatalk/compat/mktemp.c b/libatalk/compat/mktemp.c index ddbfe2d5..8faae193 100644 --- a/libatalk/compat/mktemp.c +++ b/libatalk/compat/mktemp.c @@ -1,5 +1,4 @@ /* - * $Id: mktemp.c,v 1.4 2003-02-17 01:51:08 srittau Exp $ * * Copyright (c) 1987 Regents of the University of California. * All rights reserved. diff --git a/libatalk/compat/rquota_xdr.c b/libatalk/compat/rquota_xdr.c index 03dd3bb6..eb73c975 100644 --- a/libatalk/compat/rquota_xdr.c +++ b/libatalk/compat/rquota_xdr.c @@ -1,5 +1,4 @@ /* - * $Id: rquota_xdr.c,v 1.4 2003-02-17 01:51:08 srittau Exp $ * * taken from the quota-1.55 used on linux. here's the bsd copyright: * diff --git a/libatalk/dsi/dsi_attn.c b/libatalk/dsi/dsi_attn.c index 5a60c24d..80757712 100644 --- a/libatalk/dsi/dsi_attn.c +++ b/libatalk/dsi/dsi_attn.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_attn.c,v 1.8 2009-10-25 06:13:11 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/dsi/dsi_close.c b/libatalk/dsi/dsi_close.c index 80bee3fe..892b982e 100644 --- a/libatalk/dsi/dsi_close.c +++ b/libatalk/dsi/dsi_close.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_close.c,v 1.4 2003-03-12 15:07:06 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index 39c93bf5..cde5def7 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_getsess.c,v 1.7 2005-04-28 20:50:02 bfernhomberg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/dsi/dsi_getstat.c b/libatalk/dsi/dsi_getstat.c index aec872ab..dac4f76b 100644 --- a/libatalk/dsi/dsi_getstat.c +++ b/libatalk/dsi/dsi_getstat.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_getstat.c,v 1.4 2005-09-07 15:27:29 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/dsi/dsi_tickle.c b/libatalk/dsi/dsi_tickle.c index 40d0c0ad..a283d40b 100644 --- a/libatalk/dsi/dsi_tickle.c +++ b/libatalk/dsi/dsi_tickle.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_tickle.c,v 1.8 2009-10-25 06:13:11 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/dsi/dsi_write.c b/libatalk/dsi/dsi_write.c index 1cf25e64..65a479e1 100644 --- a/libatalk/dsi/dsi_write.c +++ b/libatalk/dsi/dsi_write.c @@ -1,5 +1,4 @@ /* - * $Id: dsi_write.c,v 1.5 2009-10-20 04:31:41 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All rights reserved. See COPYRIGHT. diff --git a/libatalk/iniparser/dictionary.c b/libatalk/iniparser/dictionary.c index bfa84058..f1ff8156 100644 --- a/libatalk/iniparser/dictionary.c +++ b/libatalk/iniparser/dictionary.c @@ -3,7 +3,6 @@ @file dictionary.c @author N. Devillard @date Sep 2007 - @version $Revision: 1.27 $ @brief Implements a dictionary for string variables. This module implements a simple dictionary object, i.e. a list @@ -13,8 +12,6 @@ /*--------------------------------------------------------------------------*/ /* - $Id: dictionary.c,v 1.27 2007-11-23 21:39:18 ndevilla Exp $ - $Revision: 1.27 $ */ /*--------------------------------------------------------------------------- Includes diff --git a/libatalk/unicode/charsets/mac_roman.h b/libatalk/unicode/charsets/mac_roman.h index bf3a5bca..5d2c72e6 100644 --- a/libatalk/unicode/charsets/mac_roman.h +++ b/libatalk/unicode/charsets/mac_roman.h @@ -1,6 +1,5 @@ /* - * $Id: mac_roman.h,v 1.2 2005-04-28 20:50:04 bfernhomberg Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/libatalk/util/gettok.c b/libatalk/util/gettok.c index fd48db68..4859fec0 100644 --- a/libatalk/util/gettok.c +++ b/libatalk/util/gettok.c @@ -1,5 +1,4 @@ /* - * $Id: gettok.c,v 1.6 2009-10-13 22:55:37 didg Exp $ * * Copyright (c) 1990,1994 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. diff --git a/libatalk/util/locking.c b/libatalk/util/locking.c index 2d5b913e..0b473b60 100644 --- a/libatalk/util/locking.c +++ b/libatalk/util/locking.c @@ -1,5 +1,4 @@ /* - $Id: locking.c,v 1.4 2010-01-05 19:05:52 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/libatalk/util/module.c b/libatalk/util/module.c index 1e370373..b6514765 100644 --- a/libatalk/util/module.c +++ b/libatalk/util/module.c @@ -1,5 +1,4 @@ /* - * $Id: module.c,v 1.5 2003-02-17 02:03:12 srittau Exp $ */ #ifdef HAVE_CONFIG_H diff --git a/macros/afs-check.m4 b/macros/afs-check.m4 index 799cfa26..48925d88 100644 --- a/macros/afs-check.m4 +++ b/macros/afs-check.m4 @@ -1,4 +1,3 @@ -dnl $Id: afs-check.m4,v 1.4 2005-08-11 20:15:35 didg Exp $ dnl Autoconf macro to check whether AFS support should be enabled AC_DEFUN([AC_NETATALK_AFS_CHECK], [ diff --git a/macros/grep-check.m4 b/macros/grep-check.m4 index d2a5544a..8eb5864d 100644 --- a/macros/grep-check.m4 +++ b/macros/grep-check.m4 @@ -1,5 +1,4 @@ dnl Autoconf macro to check for the existence of grep -dnl $Id: grep-check.m4,v 1.2 2002-02-14 18:02:04 jmarcus Exp $ AC_DEFUN([AC_PROG_GREP], [ AC_REQUIRE([AC_EXEEXT])dnl diff --git a/macros/pam-check.m4 b/macros/pam-check.m4 index 1f40646b..17a92898 100644 --- a/macros/pam-check.m4 +++ b/macros/pam-check.m4 @@ -1,4 +1,3 @@ -dnl $Id: pam-check.m4,v 1.6 2010-01-11 13:06:02 franklahm Exp $ dnl PAM finding macro AC_DEFUN([AC_NETATALK_PATH_PAM], [ diff --git a/macros/perl-check.m4 b/macros/perl-check.m4 index 7ad755b9..6ae7ea6f 100644 --- a/macros/perl-check.m4 +++ b/macros/perl-check.m4 @@ -1,5 +1,4 @@ dnl Autoconf macro to check for the existence of Perl -dnl $Id: perl-check.m4,v 1.4 2002-03-12 11:03:49 srittau Exp $ AC_DEFUN([AC_PROG_PERL], [ AC_REQUIRE([AC_EXEEXT])dnl diff --git a/macros/ps-check.m4 b/macros/ps-check.m4 index 3f47b85f..75d5c953 100644 --- a/macros/ps-check.m4 +++ b/macros/ps-check.m4 @@ -1,5 +1,4 @@ dnl Autoconf macro to check for the existence of ps -dnl $Id: ps-check.m4,v 1.2 2002-02-14 18:02:04 jmarcus Exp $ AC_DEFUN([AC_PROG_PS], [ AC_REQUIRE([AC_EXEEXT])dnl diff --git a/macros/quota-check.m4 b/macros/quota-check.m4 index b7e0c3a2..703c3568 100644 --- a/macros/quota-check.m4 +++ b/macros/quota-check.m4 @@ -1,4 +1,3 @@ -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. diff --git a/macros/ssl-check.m4 b/macros/ssl-check.m4 index 8d9c1b6c..8a58142b 100644 --- a/macros/ssl-check.m4 +++ b/macros/ssl-check.m4 @@ -1,4 +1,3 @@ -dnl $Id: ssl-check.m4,v 1.14 2008-11-22 12:07:26 didg Exp $ dnl Autoconf macro to check for SSL or OpenSSL AC_DEFUN([AC_NETATALK_CRYPT], [ diff --git a/macros/tcp-wrappers.m4 b/macros/tcp-wrappers.m4 index 55b0f8c1..76b75a09 100644 --- a/macros/tcp-wrappers.m4 +++ b/macros/tcp-wrappers.m4 @@ -1,4 +1,3 @@ -dnl $Id: tcp-wrappers.m4,v 1.4 2008-08-11 20:44:03 didg Exp $ AC_DEFUN([AC_NETATALK_TCP_WRAPPERS], [ check=maybe diff --git a/test/afpd/afpfunc_helpers.c b/test/afpd/afpfunc_helpers.c index 4387bdfc..92347f1c 100644 --- a/test/afpd/afpfunc_helpers.c +++ b/test/afpd/afpfunc_helpers.c @@ -1,5 +1,4 @@ /* - $Id: afpfunc_helpers.c,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/test/afpd/afpfunc_helpers.h b/test/afpd/afpfunc_helpers.h index 2a0fcd23..933f7f61 100644 --- a/test/afpd/afpfunc_helpers.h +++ b/test/afpd/afpfunc_helpers.h @@ -1,5 +1,4 @@ /* - $Id: afpfunc_helpers.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/test/afpd/subtests.h b/test/afpd/subtests.h index ee32144a..2a190eae 100644 --- a/test/afpd/subtests.h +++ b/test/afpd/subtests.h @@ -1,5 +1,4 @@ /* - $Id: subtests.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify diff --git a/test/afpd/test.h b/test/afpd/test.h index 382a5bd5..98d0c1ba 100644 --- a/test/afpd/test.h +++ b/test/afpd/test.h @@ -1,5 +1,4 @@ /* - $Id: test.h,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify From 06a9f8968af760355d141327a3ae04ef587fc370 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Mon, 31 Dec 2012 14:50:50 +0100 Subject: [PATCH 107/117] Consolidate all Netatalk specific conversion in pull_charset_flags() Netatalk specific conversion like '/' <-> ':' and CAP de-/encoding was performed partially in pull_charset_flags() and push_charset_flags(). The resulting code was unmaintainable and as a result it failed to to the proper conversion of ':' to '/' for an UTF8 -> UTF8-MAC conversion. Moving all Netatalk specific conversion to pull_charset_flags() we can now easily do the necessary conversion in one place. * ":xx" CAP sequences are decoded if CONV_UNESCAPEHEX is used * ':' and '/' are CAP encoded if CONV_ESCAPEHEX is used * ':' is converted to '/' only for a conversion whos target charset is UTF8-MAC and whos source charset is NOT UTF8-MAC * '/' is converted to ':' only for a conversion whos source charset is UTF8-MAC and whos target charset is NOT UTF8-MAC * a leading '.' is CAP encoded if CONV_ESCAPEDOTS is used This consolidation obsoletes both CONV_ALLOW_COLON and CONV_ALLOW_SLASH conversion options. --- bin/misc/netacnv.c | 1 - include/atalk/unicode.h | 2 - libatalk/unicode/charcnv.c | 238 +++++++++++++++++----------------- libatalk/util/netatalk_conf.c | 8 +- libatalk/vfs/ea_ad.c | 2 +- 5 files changed, 122 insertions(+), 129 deletions(-) diff --git a/bin/misc/netacnv.c b/bin/misc/netacnv.c index 5e664b1e..70c822d8 100644 --- a/bin/misc/netacnv.c +++ b/bin/misc/netacnv.c @@ -21,7 +21,6 @@ struct flag_map { struct flag_map flag_map[] = { flag(CONV_ESCAPEHEX), - flag(CONV_ALLOW_COLON), flag(CONV_UNESCAPEHEX), flag(CONV_ESCAPEDOTS), flag(CONV_IGNORE), diff --git a/include/atalk/unicode.h b/include/atalk/unicode.h index f842ce09..75a970b6 100644 --- a/include/atalk/unicode.h +++ b/include/atalk/unicode.h @@ -56,8 +56,6 @@ typedef struct { #define CONV_DECOMPOSE (1<<7) /* precompose */ #define CONV_FORCE (1<<8) /* force convertion */ #define CONV__EILSEQ (1<<9) /* ignore EILSEQ, replace with IGNORE_CHAR (try USC2) */ -#define CONV_ALLOW_COLON (1<<10) /* Allow ':' in name. Needed for Extended Attributes */ -#define CONV_ALLOW_SLASH (1<<11) /* Allow '/' in name. Needed for volume name */ /* conversion return flags */ #define CONV_REQMANGLE (1<<14) /* mangling of returned name is required */ diff --git a/libatalk/unicode/charcnv.c b/libatalk/unicode/charcnv.c index d72848e9..4e772e16 100644 --- a/libatalk/unicode/charcnv.c +++ b/libatalk/unicode/charcnv.c @@ -703,7 +703,7 @@ char * debug_out ( char * seq, size_t len) * for e.g. HFS cdroms. */ -static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const char *src, size_t srclen, char* dest, size_t destlen, uint16_t *flags) +static size_t pull_charset_flags (charset_t from_set, charset_t to_set, charset_t cap_set, const char *src, size_t srclen, char* dest, size_t destlen, uint16_t *flags) { const uint16_t option = (flags ? *flags : 0); size_t i_len, o_len; @@ -712,6 +712,7 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c char* outbuf = dest; atalk_iconv_t descriptor; atalk_iconv_t descriptor_cap; + char escch; /* 150210: uninitialized OK, depends on j */ if (srclen == (size_t)-1) srclen = strlen(src) + 1; @@ -727,10 +728,30 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c i_len=srclen; o_len=destlen; + if ((option & CONV_ESCAPEDOTS) && i_len >= 2 && inbuf[0] == '.') { + if (o_len < 6) { + errno = E2BIG; + goto end; + } + ucs2_t ucs2 = ':'; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + ucs2 = '2'; + memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + ucs2 = 'e'; + memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + outbuf += 6; + o_len -= 6; + inbuf++; + i_len--; + *flags |= CONV_REQESCAPE; + } + while (i_len > 0) { for (j = 0; j < i_len; ++j) - if (inbuf[j] == ':') + if (inbuf[j] == ':' || inbuf[j] == '/') { + escch = inbuf[j]; break; + } j = i_len - j; i_len -= j; @@ -760,48 +781,108 @@ static size_t pull_charset_flags (charset_t from_set, charset_t cap_set, const c } if (j) { - /* we have a ':' */ + /* we have a ':' or '/' */ i_len = j, j = 0; - if ((option & CONV_UNESCAPEHEX)) { - /* treat it as a CAP hex encoded char */ - char h[MAXPATHLEN]; - size_t hlen = 0; - - while (i_len >= 3 && inbuf[0] == ':' && - isxdigit(inbuf[1]) && isxdigit(inbuf[2])) { - h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]); - inbuf += 3; - i_len -= 3; - } - if (hlen) { - const char *h_buf = h; - if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) { - i_len += hlen * 3; - inbuf -= hlen * 3; - if (errno == EILSEQ && (option & CONV_IGNORE)) { + if (escch == ':') { + if ((option & CONV_UNESCAPEHEX)) { + /* treat it as a CAP hex encoded char */ + char h[MAXPATHLEN]; + size_t hlen = 0; + + while (i_len >= 3 && inbuf[0] == ':' && + isxdigit(inbuf[1]) && isxdigit(inbuf[2])) { + h[hlen++] = (hextoint(inbuf[1]) << 4) | hextoint(inbuf[2]); + inbuf += 3; + i_len -= 3; + } + if (hlen) { + const char *h_buf = h; + if (atalk_iconv(descriptor_cap, &h_buf, &hlen, &outbuf, &o_len) == (size_t)-1) { + i_len += hlen * 3; + inbuf -= hlen * 3; + if (errno == EILSEQ && (option & CONV_IGNORE)) { + *flags |= CONV_REQMANGLE; + return destlen - o_len; + } + goto end; + } + } else { + /* We have an invalid :xx sequence */ + errno = EILSEQ; + if ((option & CONV_IGNORE)) { *flags |= CONV_REQMANGLE; return destlen - o_len; } goto end; } - } else { - /* We have an invalid :xx sequence */ - errno = EILSEQ; - if ((option & CONV_IGNORE)) { - *flags |= CONV_REQMANGLE; - return destlen - o_len; + } else if (option & CONV_ESCAPEHEX) { + if (o_len < 6) { + errno = E2BIG; + goto end; } - goto end; + ucs2_t ucs2 = ':'; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + ucs2 = '3'; + memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + ucs2 = 'a'; + memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + outbuf += 6; + o_len -= 6; + inbuf++; + i_len--; + } else if (to_set == CH_UTF8_MAC || to_set == CH_MAC) { + /* convert to a '/' */ + ucs2_t slash = 0x002f; + memcpy(outbuf, &slash, sizeof(ucs2_t)); + outbuf += 2; + o_len -= 2; + inbuf++; + i_len--; + } else { + /* keep as ':' */ + ucs2_t ucs2 = 0x003a; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + outbuf += 2; + o_len -= 2; + inbuf++; + i_len--; } } else { - /* a ':' that we just convert to a '/' */ - ucs2_t slash = 0x002f; - memcpy(outbuf, &slash, sizeof(ucs2_t)); - outbuf += 2; - o_len -= 2; - inbuf++; - i_len--; + /* '/' */ + if (option & CONV_ESCAPEHEX) { + if (o_len < 6) { + errno = E2BIG; + goto end; + } + ucs2_t ucs2 = ':'; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + ucs2 = '2'; + memcpy(outbuf + sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + ucs2 = 'f'; + memcpy(outbuf + 2 * sizeof(ucs2_t), &ucs2, sizeof(ucs2_t)); + outbuf += 6; + o_len -= 6; + inbuf++; + i_len--; + } else if ((from_set == CH_UTF8_MAC || from_set == CH_MAC) + && (to_set != CH_UTF8_MAC || to_set != CH_MAC)) { + /* convert to ':' */ + ucs2_t ucs2 = 0x003a; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + outbuf += 2; + o_len -= 2; + inbuf++; + i_len--; + } else { + /* keep as '/' */ + ucs2_t ucs2 = 0x002f; + memcpy(outbuf, &ucs2, sizeof(ucs2_t)); + outbuf += 2; + o_len -= 2; + inbuf++; + i_len--; + } } } } @@ -834,7 +915,6 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src char* outbuf = (char*)dest; atalk_iconv_t descriptor; atalk_iconv_t descriptor_cap; - char escch; /* 150210: uninitialized OK, depends on j */ descriptor = conv_handles[CH_UCS2][to_set]; descriptor_cap = conv_handles[CH_UCS2][cap_set]; @@ -847,42 +927,7 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src i_len=srclen; o_len=destlen; - if ((option & CONV_ESCAPEDOTS) && - i_len >= 2 && SVAL(inbuf, 0) == 0x002e) { /* 0x002e = . */ - if (o_len < 3) { - errno = E2BIG; - goto end; - } - *outbuf++ = ':'; - *outbuf++ = '2'; - *outbuf++ = 'e'; - o_len -= 3; - inbuf += 2; - i_len -= 2; - *flags |= CONV_REQESCAPE; - } - while (i_len >= 2) { - for (i = 0; i < i_len; i += 2) { - ucs2_t c = SVAL(inbuf, i); - switch (c) { - case 0x003a: /* 0x003a = ':' */ - if ( ! (option & CONV_ALLOW_COLON)) { - errno = EILSEQ; - goto end; - } - escch = c; - j = i_len - i; - i_len = i; - break; - case 0x002f: /* 0x002f = '/' */ - if (option & CONV_ALLOW_SLASH) break; - escch = c; - j = i_len - i; - i_len = i; - break; - } - } while (i_len > 0 && atalk_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len) == (size_t)-1) { if (errno == EILSEQ) { @@ -931,57 +976,8 @@ static size_t push_charset_flags (charset_t to_set, charset_t cap_set, char* src } goto end; } + } /* while (i_len >= 2) */ - if (j) { - /* we have a ':' or '/' */ - i_len = j, j = 0; - - if ((option & CONV_ESCAPEHEX)) { - /* CAP hex encode it */ - if (o_len < 3) { - errno = E2BIG; - goto end; - } - switch (escch) { - case '/': - *outbuf++ = ':'; - *outbuf++ = '2'; - *outbuf++ = 'f'; - break; - case ':': - *outbuf++ = ':'; - *outbuf++ = '3'; - *outbuf++ = 'a'; - break; - default: - /* - * THIS SHOULD NEVER BE REACHED !!! - * As a safety net I put in a ' ' here - */ - *outbuf++ = ':'; - *outbuf++ = '2'; - *outbuf++ = '0'; - break; - } - o_len -= 3; - inbuf += 2; - i_len -= 2; - } else { - switch (escch) { - case '/': - case ':': - *outbuf++ = ':'; - break; - default: /* should never be reached */ - *outbuf++ = ' '; - break; - } - o_len--; - inbuf += 2; - i_len -= 2; - } - } - } if (i_len > 0) errno = EINVAL; end: return (i_len + j == 0 || (option & CONV_FORCE)) ? destlen - o_len : (size_t)-1; @@ -1001,7 +997,7 @@ size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_cha lazy_initialize_conv(); /* convert from_set to UCS2 */ - if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, cap_charset, src, src_len, + if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, to_set, cap_charset, src, src_len, (char *) buffer, sizeof(buffer) -2, flags)) ) { LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from_set)); return (size_t) -1; diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index 46d6f766..b1ca02d1 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -826,7 +826,7 @@ static struct vol *creatvol(AFPObj *obj, /* Unicode Volume Name */ /* Firstly convert name from unixcharset to UTF8-MAC */ - flags = CONV_IGNORE | CONV_ALLOW_SLASH; + flags = CONV_IGNORE; tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags); if (tmpvlen <= 0) { strcpy(tmpname, "???"); @@ -836,7 +836,7 @@ static struct vol *creatvol(AFPObj *obj, /* Do we have to mangle ? */ if ( (flags & CONV_REQMANGLE) || (tmpvlen > obj->options.volnamelen)) { if (tmpvlen + suffixlen > obj->options.volnamelen) { - flags = CONV_FORCE | CONV_ALLOW_SLASH; + flags = CONV_FORCE; tmpvlen = convert_charset(obj->options.unixcharset, CH_UTF8_MAC, 0, name, vlen, tmpname, obj->options.volnamelen - suffixlen, &flags); tmpname[tmpvlen >= 0 ? tmpvlen : 0] = 0; } @@ -852,7 +852,7 @@ static struct vol *creatvol(AFPObj *obj, /* Maccharset Volume Name */ /* Firsty convert name from unixcharset to maccharset */ - flags = CONV_IGNORE | CONV_ALLOW_SLASH; + flags = CONV_IGNORE; tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, name, vlen, tmpname, AFPVOL_U8MNAMELEN, &flags); if (tmpvlen <= 0) { strcpy(tmpname, "???"); @@ -862,7 +862,7 @@ static struct vol *creatvol(AFPObj *obj, /* Do we have to mangle ? */ if ( (flags & CONV_REQMANGLE) || (tmpvlen > AFPVOL_MACNAMELEN)) { if (tmpvlen + suffixlen > AFPVOL_MACNAMELEN) { - flags = CONV_FORCE | CONV_ALLOW_SLASH; + flags = CONV_FORCE; tmpvlen = convert_charset(obj->options.unixcharset, obj->options.maccharset, 0, diff --git a/libatalk/vfs/ea_ad.c b/libatalk/vfs/ea_ad.c index e229d7be..19c23e06 100644 --- a/libatalk/vfs/ea_ad.c +++ b/libatalk/vfs/ea_ad.c @@ -79,7 +79,7 @@ static char *mtoupath(const struct vol *vol, const char *mpath) char *u; size_t inplen; size_t outlen; - uint16_t flags = CONV_ESCAPEHEX | CONV_ALLOW_COLON; + uint16_t flags = CONV_ESCAPEHEX; if (!mpath) return NULL; From 3cef230828867e4d2f3014d8677b5b02b7e13caa Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 12 Jan 2013 13:39:59 +0100 Subject: [PATCH 108/117] Import from Docbook --- man/man5/afp.conf.5.tmpl | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index 4a41167b..e4bc04d7 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -2,12 +2,12 @@ .\" Title: afp.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.0 -.\" Date: 06 Dez 2012 +.\" Date: 12 Jan 2013 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "AFP\&.CONF" "5" "06 Dez 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "AFP\&.CONF" "5" "12 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -88,9 +88,9 @@ option is considered a \fIvol preset\fR which can be selected in other volume sections via the \fBvol preset\fR -option and constitutes defaults for the volume\&. For any option speficied both in a preset +option and constitutes defaults for the volume\&. For any option specified both in a preset \fIand\fR -in a volume section the volume section setting completly substitutes the preset option\&. +in a volume section the volume section setting completely substitutes the preset option\&. .PP The access rights granted by the server are masked by the access rights granted to the specified or guest UNIX user by the host system\&. The server does not grant more access than the host system grants\&. .PP @@ -117,7 +117,7 @@ Parameters in this section apply to the server as a whole\&. Parameters denoted This section enable sharing of the UNIX server user home directories\&. Specifying an optional \fBpath\fR parameter means that not the whole user home will be shared but the subdirectory -\fBpath\fR\&. It is neccessary to define the +\fBpath\fR\&. It is necessary to define the \fBbasedir regex\fR option\&. It should be a regex which matches the parent directory of the user homes\&. Parameters denoted by a (H) belong to volume sections\&. The optional parameter \fBhome name\fR @@ -255,9 +255,9 @@ k5 keytab = \fIpath\fR \fB(G)\fR, k5 service = \fIservice\fR \fB(G)\fR, k5 realm These are required if the server supports the Kerberos 5 authentication UAM\&. .RE .PP -nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPERATOR\fR \fB(G)\fR +nt domain = \fIDOMAIN\fR \fB(G)\fR, nt separator = \fISEPARATOR\fR \fB(G)\fR .RS 4 -Use for eg\&. winbind authentication, prepends both strings before the username from login and then tries to authenticate with the result through the availabel and active UAM authentication modules\&. +Use for eg\&. winbind authentication, prepends both strings before the username from login and then tries to authenticate with the result through the available and active UAM authentication modules\&. .RE .PP save password = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR @@ -349,7 +349,7 @@ unix charset = \fICHARSET\fR \fB(G)\fR Specifies the servers unix charset, e\&.g\&. \fIISO\-8859\-15\fR or -\fIEUC\-JP\fR\&. This is used to convert strings to/from the systems locale, e\&.g\&. for authenthication, server messages and volume names\&. If +\fIEUC\-JP\fR\&. This is used to convert strings to/from the systems locale, e\&.g\&. for authentication, server messages and volume names\&. If \fILOCALE\fR is set, the systems locale is used\&. Defaults to \fIUTF8\fR\&. @@ -395,7 +395,7 @@ Setting this option is not recommended since globally encrypting AFP connections .RE .RE .PP -afp listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR +afp listen = \fIip address[:port] [ip address[:port] \&.\&.\&.]\fR \fB(G)\fR .RS 4 Specifies the IP address that the server should advertise \fBand\fR @@ -409,7 +409,7 @@ Allows a different TCP port to be used for AFP\&. The default is 548\&. Also set option\&. .RE .PP -cnid listen = \fIip address[:port] [ip adress[:port] \&.\&.\&.]\fR \fB(G)\fR +cnid listen = \fIip address[:port] [ip address[:port] \&.\&.\&.]\fR \fB(G)\fR .RS 4 Specifies the IP address that the CNID server should listen on\&. The default is \fBlocalhost:4700\fR\&. @@ -435,7 +435,7 @@ Specifies a fully\-qualified domain name, with an optional port\&. This is disca .PP hostname = \fIname\fR \fB(G)\fR .RS 4 -Use this instead of the result from calling hostname for dertermening which IP address to advertise, therfore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by +Use this instead of the result from calling hostname for determining which IP address to advertise, therfore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by \fBafp listen\fR\&. .RE .PP @@ -530,7 +530,7 @@ AFP user home volume name\&. The default is .PP keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR .RS 4 -Enable "Continuous AFP Service"\&. This means restarting AFP and CNID service daemons master processes, but keeping the AFP session processes\&. This can be used to install (most) updates to Netatalk without interruping active AFP sessions\&. Existing AFP sessions will still run the version from before updating, but new AFP sessions will run the updated code\&. After enabling this option when sending SIGQUIT to the +Enable "Continuous AFP Service"\&. This means restarting AFP and CNID service daemons master processes, but keeping the AFP session processes\&. This can be used to install (most) updates to Netatalk without interrupting active AFP sessions\&. Existing AFP sessions will still run the version from before updating, but new AFP sessions will run the updated code\&. After enabling this option when sending SIGQUIT to the \fInetatalk\fR service controller process, the AFP and CNID daemons will exit and then the service controller will restart them\&. AFP session processes are notified of the master afpd shutdown, they will then sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. The IPC channel between the AFP master service daemon and the AFP session child is used for keeping session state of AFP sessions in the AFP master process\&. The session state is needed when AFP clients experience eg network outages and try to reconnect to the AFP server\&. .RE @@ -566,7 +566,7 @@ Use share reservations on Solaris\&. Solaris CIFS server uses this too, so this .PP vol dbpath = \fIpath\fR \fB(G)\fR .RS 4 -Sets the database information to be stored in path\&. You have to specifiy a writable location, even if the volume is read only\&. The default is +Sets the database information to be stored in path\&. You have to specify a writable location, even if the volume is read only\&. The default is :STATEDIR:/netatalk/CNID/\&. .RE .PP @@ -586,7 +586,7 @@ Max length of UTF8\-MAC volume name for Mac OS X\&. Note that Hangul is especial .RE .\} .sp -Mac OS 9 and earlier are not influenced by this, because Maccharset volume name is always limitted to 27 bytes\&. +Mac OS 9 and earlier are not influenced by this, because Maccharset volume name is always limited to 27 bytes\&. .RE .PP vol preset = \fIname\fR \fB(G)/(V)\fR @@ -599,7 +599,7 @@ as option preset for all volumes (when set in the [Global] section) or for one v .PP log file = \fIlogfile\fR \fB(G)\fR .RS 4 -If not specified Netatalk logs to syslogs daemon facilify\&. Otherwise it logs to +If not specified Netatalk logs to syslogs daemon facility\&. Otherwise it logs to \fBlogfile\fR\&. .RE .PP @@ -640,7 +640,7 @@ fce listener = \fIhost[:port]\fR \fB(G)\fR Enables sending FCE events to the specified \fIhost\fR, default \fIport\fR -is 12250 if not specified\&. Specifying mutliple listeners is done by having this option once for each of them\&. +is 12250 if not specified\&. Specifying multiple listeners is done by having this option once for each of them\&. .RE .PP fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR @@ -656,7 +656,7 @@ Coalesce FCE events\&. .PP fce holdfmod = \fIseconds\fR \fB(G)\fR .RS 4 -This determines the time delay in seconds which is always waited if another file modification for the same file is done by a client before sending an FCE file modification event (fmod)\&. For example saving a file in Photoshop would generate multiple events by itself because the application is opening, modifying and closing a file mutliple times for every "save"\&. Defautl: 60 seconds\&. +This determines the time delay in seconds which is always waited if another file modification for the same file is done by a client before sending an FCE file modification event (fmod)\&. For example saving a file in Photoshop would generate multiple events by itself because the application is opening, modifying and closing a file multiple times for every "save"\&. Default: 60 seconds\&. .RE .SS "Debug Parameters" .PP @@ -765,7 +765,7 @@ Name of the LDAP attribute with the users short name\&. .PP ldap uuid string = \fISTRING\fR \fB(G)\fR .RS 4 -Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a seperator\&. +Format of the uuid string in the directory\&. A series of x and \-, where every x denotes a value 0\-9a\-f and every \- is a separator\&. .sp Default: xxxxxxxx\-xxxx\-xxxx\-xxxx\-xxxxxxxxxxxx .RE @@ -815,7 +815,7 @@ vol size limit = \fIsize in MiB\fR \fB(V)\fR .RS 4 Useful for Time Machine: limits the reported volume size, thus preventing Time Machine from using the whole real disk space for backup\&. Example: "vol size limit = 1000" would limit the reported disk space to 1 GB\&. \fBIMPORTANT: \fR -This is an approimated calculation taking into accout the contents of Time Machine sparsebundle images\&. Therefor you MUST NOT use this volume to store other content when using this option, because it would NOT be accounted\&. The calculation works by reading the band size from the Info\&.plist XML file of the sparsebundle, reading the bands/ directory counting the number of band files, and then multiplying one with the other\&. +This is an approximated calculation taking into account the contents of Time Machine sparsebundle images\&. Therefor you MUST NOT use this volume to store other content when using this option, because it would NOT be accounted\&. The calculation works by reading the band size from the Info\&.plist XML file of the sparsebundle, reading the bands/ directory counting the number of band files, and then multiplying one with the other\&. .RE .PP valid users = \fIuser @group\fR \fB(V)\fR @@ -869,10 +869,10 @@ auto Try \fBsys\fR (by setting an EA on the shared directory itself), fallback to -\fBad\fR\&. Requires writeable volume for perfoming test\&. "\fBread only = yes\fR" overwrites +\fBad\fR\&. Requires writeable volume for performing test\&. "\fBread only = yes\fR" overwrites \fBauto\fR with -\fBnone\fR\&. Use explicit "\fBea = sys|ad\fR" for read\-only volumes where appropiate\&. +\fBnone\fR\&. Use explicit "\fBea = sys|ad\fR" for read\-only volumes where appropriate\&. .RE .PP sys @@ -1056,7 +1056,7 @@ Whether to stat volume path when enumerating volumes list, useful for automounti .PP time machine = \fIBOOLEAN\fR (default: \fIno\fR) \fB(V)\fR .RS 4 -Whether to enable Time Machine suport for this volume\&. +Whether to enable Time Machine support for this volume\&. .RE .PP unix priv = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(V)\fR From 4f6fbcfc5f685bfd67a69e014eb18df4d984ae36 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Mon, 17 Dec 2012 10:49:51 +0100 Subject: [PATCH 109/117] Check for KerberosV API funcs krb5_free_keytab_entry_contents and krb5_kt_free_entry --- etc/afpd/status.c | 6 +++++- macros/netatalk.m4 | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/etc/afpd/status.c b/etc/afpd/status.c index caa74d5d..33939abe 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -440,8 +440,12 @@ static size_t status_directorynames(char *data, } krb5_unparse_name(context, entry.principal, &principal); +#ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS krb5_free_keytab_entry_contents(context, &entry); - +#endif +#ifdef HAVE_KRB5_KT_FREE_ENTRY + krb5_kt_free_entry(context, &entry); +#endif append_directoryname(&data, offset, &size, diff --git a/macros/netatalk.m4 b/macros/netatalk.m4 index d7a8c8b6..e77aac53 100644 --- a/macros/netatalk.m4 +++ b/macros/netatalk.m4 @@ -585,7 +585,7 @@ save_CFLAGS="$CFLAGS" 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" ]) From e6b251426c1061adc716f95b938bb7c53f3bc54a Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 14 Jan 2013 15:13:12 +0100 Subject: [PATCH 110/117] Automatic AppleDouble conversion to EAs failing for directories of_stat() need be called before calling ad_convert() in order to have a valid struct stat of the element to be converted. Fixes bug #486. --- NEWS | 2 ++ etc/afpd/enumerate.c | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 08481d64..c2572250 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,8 @@ Changes in 3.0.2 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. Changes in 3.0.1 ================ diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index 80141e80..0c3c0576 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -346,15 +346,9 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, sd.sd_last += len + 1; continue; } - memset(&s_path, 0, sizeof(s_path)); - /* conversions on the fly */ - const char *convname; + memset(&s_path, 0, sizeof(s_path)); s_path.u_name = sd.sd_last; - if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0 && convname) { - s_path.u_name = (char *)convname; - } - if (of_stat(vol, &s_path) < 0 ) { /* so the next time it won't try to stat it again * another solution would be to invalidate the cache with @@ -366,6 +360,12 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, continue; } + /* conversions on the fly */ + const char *convname; + if (ad_convert(sd.sd_last, &s_path.st, vol, &convname) == 0 && convname) { + s_path.u_name = (char *)convname; + } + /* Fixup CNID db if ad_convert resulted in a rename (then convname != NULL) */ if (convname) { s_path.id = cnid_lookup(vol->v_cdb, &s_path.st, curdir->d_did, sd.sd_last, strlen(sd.sd_last)); From dc9bec26418d607ca4b74d6ba8d77c83c90c7c2b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Jan 2013 11:00:58 +0100 Subject: [PATCH 111/117] Fix conditional Fix conditional compilation checks introduced in 4f6fbcfc5f685bfd67a69e014eb18df4d984ae36. --- etc/afpd/status.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/etc/afpd/status.c b/etc/afpd/status.c index 33939abe..35e08849 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -442,8 +442,7 @@ static size_t status_directorynames(char *data, krb5_unparse_name(context, entry.principal, &principal); #ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS krb5_free_keytab_entry_contents(context, &entry); -#endif -#ifdef HAVE_KRB5_KT_FREE_ENTRY +#elif defined(HAVE_KRB5_KT_FREE_ENTRY) krb5_kt_free_entry(context, &entry); #endif append_directoryname(&data, From 34bc8054459a248ec45324af9356e52f1ba83973 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Wed, 16 Jan 2013 17:34:32 +0100 Subject: [PATCH 112/117] Fix extension mapping Extension mapping did only work for files with a valid metadata EA. Fixed in #487. --- etc/afpd/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/afpd/file.c b/etc/afpd/file.c index f62e05ee..153f1325 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -92,6 +92,7 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a } else { memcpy(data, ufinderi, ADEDLEN_FINDERI); + chk_ext = 1; if (vol_inv_dots(vol) && *upath == '.') { /* make it invisible */ uint16_t ashort; From a90f92de343681c030d7b47994611ae643ad014e Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Sat, 19 Jan 2013 18:28:40 +0100 Subject: [PATCH 113/117] Multiple fixes and new manpage extmap.conf --- man/man1/ad.1 | 24 ++++++---- man/man1/afpldaptest.1.tmpl | 11 ++++- man/man1/afppasswd.1 | 13 ++++- man/man1/apple_dump.1 | 15 ++++-- man/man1/asip-status.pl.1.tmpl | 15 ++++-- man/man1/dbd.1 | 6 +-- man/man1/hqx2bin.1 | 2 +- man/man1/macbinary.1 | 2 +- man/man1/macusers.1 | 11 ++++- man/man1/megatron.1 | 19 ++++++-- man/man1/netatalk-config.1 | 11 ++++- man/man1/single2bin.1 | 2 +- man/man1/unbin.1 | 2 +- man/man1/unhex.1 | 2 +- man/man1/uniconv.1.tmpl | 27 +++++++---- man/man1/unsingle.1 | 2 +- man/man5/Makefile.am | 4 +- man/man5/afp.conf.5.tmpl | 54 ++++++++++++++------- man/man5/afp_signature.conf.5.tmpl | 11 ++++- man/man5/afp_voluuid.conf.5.tmpl | 11 ++++- man/man5/extmap.conf.5.tmpl | 77 ++++++++++++++++++++++++++++++ man/man8/afpd.8.tmpl | 25 ++++++++-- man/man8/cnid_dbd.8.tmpl | 33 +++++++------ man/man8/cnid_metad.8.tmpl | 13 ++++- man/man8/netatalk.8.tmpl | 11 ++++- 25 files changed, 319 insertions(+), 84 deletions(-) create mode 100644 man/man5/extmap.conf.5.tmpl diff --git a/man/man1/ad.1 b/man/man1/ad.1 index 4d85e8be..20b14364 100644 --- a/man/man1/ad.1 +++ b/man/man1/ad.1 @@ -1,7 +1,7 @@ '\" t .\" Title: ad .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 02 Sep 2011 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AD" "1" "02 Sep 2011" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -28,10 +37,10 @@ ad \- Netatalk compatible UNIX file utility suite\&. .SH "DESCRIPTION" .PP \fBad\fR -is a UNIX file utlity suite with Netatalk compatibity\&. AppleDouble +is a UNIX file utility suite with Netatalk compatibility\&. AppleDouble files in \&.AppleDouble -directories and the CNID databases are updated as appropiate\&. +directories and the CNID databases are updated as appropriate\&. .SH "AVAILABLE COMMANDS" .HP \w'\fBad\ ls\fR\ 'u \fBad ls\fR [\-dRl\ [u]] {file|dir\ [\&.\&.\&.]} @@ -110,7 +119,7 @@ AFP Attributes: l = No delete (f/d) o = No copy (f) -Note: any letter appearing in uppercase means the flag is set but it\'s a directory for which the flag is not allowed\&. +Note: any letter appearing in uppercase means the flag is set but it\*(Aqs a directory for which the flag is not allowed\&. .fi .if n \{\ .RE @@ -121,7 +130,7 @@ Copy files and directories\&. .PP In the first synopsis form, the cp utility copies the contents of the source_file to the target_file\&. In the second synopsis form, the contents of each named source_file is copied to the destination target_directory\&. The names of the files themselves are not changed\&. If cp detects an attempt to copy a file to itself, the copy will fail\&. .PP -Netatalk AFP volumes are detected by means of their "\&.AppleDesktop" directory which is located in their volume root\&. When a copy targetting an AFP volume is detected, its CNID database daemon is connected and all copies will also go through the CNID database\&. AppleDouble files are also copied and created as needed when the target is an AFP volume\&. +Netatalk AFP volumes are detected by means of their "\&.AppleDesktop" directory which is located in their volume root\&. When a copy targeting an AFP volume is detected, its CNID database daemon is connected and all copies will also go through the CNID database\&. AppleDouble files are also copied and created as needed when the target is an AFP volume\&. .PP Options: .PP @@ -137,7 +146,7 @@ For each existing destination pathname, remove it and create a new file, without .PP \-i .RS 4 -Cause cp to write a prompt to the standard error output before copying a file that would overwrite an existing file\&. If the response from the standard input begins with the character \'y\' or \'Y\', the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.) +Cause cp to write a prompt to the standard error output before copying a file that would overwrite an existing file\&. If the response from the standard input begins with the character \*(Aqy\*(Aq or \*(AqY\*(Aq, the file copy is attempted\&. (The \-i option overrides any pre\- vious \-f or \-n options\&.) .RE .PP \-n @@ -192,7 +201,6 @@ source or destination is not an AFP volume source AFP volume != destination AFP volume .RE .sp -.RE the files are copied and removed from the source\&. .PP Options: @@ -204,7 +212,7 @@ Do not prompt for confirmation before overwriting the destination path\&. (The \ .PP \-i .RS 4 -Cause mv to write a prompt to standard error before moving a file that would overwrite an existing file\&. If the response from the standard input begins with the character `y\' or `Y\', the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.) +Cause mv to write a prompt to standard error before moving a file that would overwrite an existing file\&. If the response from the standard input begins with the character `y\*(Aq or `Y\*(Aq, the move is attempted\&. (The \-i option overrides any previous \-f or \-n options\&.) .RE .PP \-n diff --git a/man/man1/afpldaptest.1.tmpl b/man/man1/afpldaptest.1.tmpl index 1d4fbd7e..5c4c67f4 100644 --- a/man/man1/afpldaptest.1.tmpl +++ b/man/man1/afpldaptest.1.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: afpldaptest .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 22 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AFPLDAPTEST" "1" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation diff --git a/man/man1/afppasswd.1 b/man/man1/afppasswd.1 index 860eb693..60d640c0 100644 --- a/man/man1/afppasswd.1 +++ b/man/man1/afppasswd.1 @@ -1,7 +1,7 @@ '\" t .\" Title: afppasswd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 22 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AFPPASSWD" "1" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -45,7 +54,7 @@ can either be called by root with parameters, or can be called by local system u .PP With this utility you can only change the passwords used by two specific UAMs\&. As they provide only weak password encryption, the use of the "Randnum exchange" and "2\-Way Randnum exchange" UAMs is deprecated unless one has to support very old AFP clients, that can not deal with the more secure "DHCAST128" and "DHX2" UAM instead\&. Please compare with the Authentication chapter -inside Netatalk\'s documentation\&. +inside Netatalk\*(Aqs documentation\&. .sp .5v .RE .SH "EXAMPLE" diff --git a/man/man1/apple_dump.1 b/man/man1/apple_dump.1 index 37e9f6e6..f8676fda 100644 --- a/man/man1/apple_dump.1 +++ b/man/man1/apple_dump.1 @@ -1,7 +1,7 @@ '\" t .\" Title: apple_dump .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 16 Jul 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "APPLE_DUMP" "1" "16 Jul 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -92,9 +101,9 @@ Show version and exit .RE .SH "NOTE" .PP -There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump examins whether file or directory, a parent directory is \&.AppleDouble, filename is \&._*, filename is \&.Parent, and so on\&. +There is no way to detect whether FinderInfo is FileInfo or DirInfo\&. By default, apple_dump examines whether file or directory, a parent directory is \&.AppleDouble, filename is \&._*, filename is \&.Parent, and so on\&. .PP -If setting option \-e, \-f or \-d, assume FinderInfo and doesn\'t look for another file\&. +If setting option \-e, \-f or \-d, assume FinderInfo and doesn\*(Aqt look for another file\&. .SH "SEE ALSO" .PP \fBad\fR(1), diff --git a/man/man1/asip-status.pl.1.tmpl b/man/man1/asip-status.pl.1.tmpl index 4de42c58..735f8eb7 100644 --- a/man/man1/asip-status.pl.1.tmpl +++ b/man/man1/asip-status.pl.1.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: asip-status.pl .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 24 Jul 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "ASIP\-STATUS\&.PL" "1" "24 Jul 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -30,9 +39,9 @@ asip-status.pl \- Queries AFP servers for their capabilities .SH "DESCRIPTION" .PP \fBasip\-status\&.pl\fR -is a perl script that sends a FPGetSrvrInfo request to an AFP server at HOSTNAME:PORT and displays the results, namely "Machine type", the server\'s name, supported AFP versions, UAMs and AFP flags, the "server signature" and the network addresses, the server provides AFP services on\&. +is a perl script that sends a FPGetSrvrInfo request to an AFP server at HOSTNAME:PORT and displays the results, namely "Machine type", the server\*(Aqs name, supported AFP versions, UAMs and AFP flags, the "server signature" and the network addresses, the server provides AFP services on\&. .PP -When you don\'t supply :PORT, then the default AFP port, 548, will be used\&. +When you don\*(Aqt supply :PORT, then the default AFP port, 548, will be used\&. .SH "OPTIONS" .PP \fB\-d\fR diff --git a/man/man1/dbd.1 b/man/man1/dbd.1 index 97d71935..214b31d3 100644 --- a/man/man1/dbd.1 +++ b/man/man1/dbd.1 @@ -2,12 +2,12 @@ .\" Title: dbd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.0 -.\" Date: 28 Dez 2012 +.\" Date: 28 Dec 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "DBD" "1" "28 Dez 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "DBD" "1" "28 Dec 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -35,7 +35,7 @@ dbd \- CNID database maintenance .SH "DESCRIPTION" .PP \fBdbd\fR -scans all file and directories of AFP volumes, updating the CNID database of the volume\&. It must be run with appropiate permissions i\&.e\&. as root\&.\&. +scans all file and directories of AFP volumes, updating the CNID database of the volume\&. It must be run with appropriate permissions i\&.e\&. as root\&.\&. .SH "OPTIONS" .PP \-c diff --git a/man/man1/hqx2bin.1 b/man/man1/hqx2bin.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/hqx2bin.1 +++ b/man/man1/hqx2bin.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man1/macbinary.1 b/man/man1/macbinary.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/macbinary.1 +++ b/man/man1/macbinary.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man1/macusers.1 b/man/man1/macusers.1 index ea823a0b..6da607b7 100644 --- a/man/man1/macusers.1 +++ b/man/man1/macusers.1 @@ -1,7 +1,7 @@ '\" t .\" Title: macusers .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 13 Oct 2011 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "MACUSERS" "1" "13 Oct 2011" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation diff --git a/man/man1/megatron.1 b/man/man1/megatron.1 index dfd37d04..300bd4fd 100644 --- a/man/man1/megatron.1 +++ b/man/man1/megatron.1 @@ -1,7 +1,7 @@ '\" t .\" Title: megatron .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 02 Sep 2011 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "MEGATRON" "1" "02 Sep 2011" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -50,7 +59,7 @@ the \fBnetatalk\fR Apple Filing Protocol (AppleShare) server\&. BinHex, MacBinary, and AppleSingle are commonly used formats for transferring Macintosh files between machines via email or file transfer protocols\&. \fBmegatron\fR -uses its name to determine what type of tranformation is being asked of it\&. +uses its name to determine what type of transformation is being asked of it\&. .PP If \fBmegatron\fR @@ -59,7 +68,7 @@ is called as , \fBunbin\fR or -\fBunsingle\fR, it tries to convert file(s) from BinHex, MacBinary, or AppleSingle into AppleDouble format\&. BinHex is the format most often used to send Macintosh files by e\-mail\&. Usually these files have an extension of "\&.hqx"\&. MacBinary is the format most often used by terminal emulators "on the fly" when transferring Macintosh files in binary mode\&. MacBinary files often have an extension of "\&.bin"\&. Some Macintosh LAN\-based email packages use uuencoded AppleSingle format to "attach" or "enclose" files in email\&. AppleSingle files don\'t have a standard filename extension\&. +\fBunsingle\fR, it tries to convert file(s) from BinHex, MacBinary, or AppleSingle into AppleDouble format\&. BinHex is the format most often used to send Macintosh files by e\-mail\&. Usually these files have an extension of "\&.hqx"\&. MacBinary is the format most often used by terminal emulators "on the fly" when transferring Macintosh files in binary mode\&. MacBinary files often have an extension of "\&.bin"\&. Some Macintosh LAN\-based email packages use uuencoded AppleSingle format to "attach" or "enclose" files in email\&. AppleSingle files don\*(Aqt have a standard filename extension\&. .PP If \fBmegatron\fR @@ -68,7 +77,7 @@ is called as \fBsingle2bin\fR, or \fBmacbinary\fR, it will try to convert the file(s) from BinHex, AppleSingle, or AppleDouble into MacBinary\&. This last translation may be useful in moving Macintosh files from your \fBafpd\fR -server to some other machine when you can\'t copy them from the server using a Macintosh for some reason\&. +server to some other machine when you can\*(Aqt copy them from the server using a Macintosh for some reason\&. .PP If \fBmegatron\fR @@ -77,7 +86,7 @@ is called with any other name, it uses the default translation, namely .PP If no source file is given, or if \fIsourcefile\fR -is `\fB\-\fR\', and if the conversion is from a BinHex or MacBinary file, +is `\fB\-\fR\*(Aq, and if the conversion is from a BinHex or MacBinary file, \fBmegatron\fR will read from standard input\&. .PP diff --git a/man/man1/netatalk-config.1 b/man/man1/netatalk-config.1 index 43ebcb7b..7208ce26 100644 --- a/man/man1/netatalk-config.1 +++ b/man/man1/netatalk-config.1 @@ -1,7 +1,7 @@ '\" t .\" Title: netatalk-config .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 09 June 2001 .\" Manual: The Netatalk Project .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "NETATALK\-CONFIG" "1" "09 June 2001" "Netatalk 3.0" "The Netatalk Project" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation diff --git a/man/man1/single2bin.1 b/man/man1/single2bin.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/single2bin.1 +++ b/man/man1/single2bin.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man1/unbin.1 b/man/man1/unbin.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/unbin.1 +++ b/man/man1/unbin.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man1/unhex.1 b/man/man1/unhex.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/unhex.1 +++ b/man/man1/unhex.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man1/uniconv.1.tmpl b/man/man1/uniconv.1.tmpl index 729d35ed..fabf30c6 100644 --- a/man/man1/uniconv.1.tmpl +++ b/man/man1/uniconv.1.tmpl @@ -1,13 +1,22 @@ '\" t .\" Title: uniconv .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 23 Mar 2012 +.\" Generator: DocBook XSL Stylesheets v1.78.0 +.\" Date: 19 Jan 2013 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "UNICONV" "1" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "UNICONV" "1" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -42,7 +51,7 @@ CNID backend used on this volume, usually cdb or dbd\&. Should match the backend .PP \-d .RS 4 -don\'t HEX encode leading dots (:2e), equivalent to +don\*(Aqt HEX encode leading dots (:2e), equivalent to \fBuse dots = yes\fR in \fBafp.conf\fR(5) @@ -65,7 +74,7 @@ Macintosh client codepage, required for HEX encoded volumes\&. Defaults to "MAC_ .PP \-n .RS 4 -"dry run", don\'t do any real changes +"dry run", don\*(Aqt do any real changes .RE .PP \-t @@ -95,9 +104,11 @@ recommended to do a "dry run" first and to check the output for conversion error should \fInot\fR be running while you change the volume encoding\&. Remember to change -\fBvolcodepage\fR +\fBunix charset\fR +or +\fBvol charset\fR in -\fBAppleVolumes.default\fR(5) +\fBafp.conf\fR(5) to the new codepage, before restarting afpd\&. .PP In case of @@ -120,7 +131,7 @@ cannot handle iso\-8859\&.adapted anymore\&. .PP The CNID backends maintains name to ID mappings\&. If you change a filename outside afpd(8) (shell, samba), the CNID db, i\&.e\&. the DIDNAME index, gets inconsistent\&. Netatalk tries to recover from such inconsistencies as gracefully as possible\&. The mechanisms to resolve such inconsistencies may fail sometimes, though, as this is not an easy task to accomplish\&. I\&.e\&. if several names in the path to the file or directory have changed, things may go wrong\&. .PP -If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\'t changed\&. +If you change a lot of filenames at once, chances are higher that the afpds fallback mechanisms fail, i\&.e\&. files will be assigned new IDs, even though the file hasn\*(Aqt changed\&. \fBuniconv\fR therefore updates the CNID entry for each file/directory directly after it changes the name to avoid inconsistencies\&. The two supported backends for volumes, dbd and cdb, use the same CNID db format\&. Therefore, you \fIcould\fR diff --git a/man/man1/unsingle.1 b/man/man1/unsingle.1 index 40dd5c2a..42ffb541 100644 --- a/man/man1/unsingle.1 +++ b/man/man1/unsingle.1 @@ -1 +1 @@ -.so man1/megatron.1 +.so megatron.1 diff --git a/man/man5/Makefile.am b/man/man5/Makefile.am index fd2edf6c..e9066c8b 100644 --- a/man/man5/Makefile.am +++ b/man/man5/Makefile.am @@ -14,8 +14,8 @@ SUFFIXES = .tmpl . -e "s@:COMPILED_BACKENDS:@${compiled_backends}@g" \ <$< >$@ -GENERATED_MANS = afp.conf.5 afp_signature.conf.5 afp_voluuid.conf.5 -TEMPLATE_FILES = afp.conf.5.tmpl afp_signature.conf.5.tmpl afp_voluuid.conf.5.tmpl +GENERATED_MANS = afp.conf.5 afp_signature.conf.5 afp_voluuid.conf.5 extmap.conf.5 +TEMPLATE_FILES = afp.conf.5.tmpl afp_signature.conf.5.tmpl afp_voluuid.conf.5.tmpl extmap.conf.5.tmpl NONGENERATED_MANS = man_MANS = $(GENERATED_MANS) $(NONGENERATED_MANS) diff --git a/man/man5/afp.conf.5.tmpl b/man/man5/afp.conf.5.tmpl index e4bc04d7..9f9d007b 100644 --- a/man/man5/afp.conf.5.tmpl +++ b/man/man5/afp.conf.5.tmpl @@ -2,12 +2,12 @@ .\" Title: afp.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.0 -.\" Date: 12 Jan 2013 +.\" Date: 19 Jan 2013 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "AFP\&.CONF" "5" "12 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" +.TH "AFP\&.CONF" "5" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -132,8 +132,9 @@ The following example illustrates this\&. Given all user home directories are st .RS 4 .\} .nf - [Homes] path = afp\-data basedir regex = /home - + [Homes] + path = afp\-data + basedir regex = /home .fi .if n \{\ .RE @@ -143,6 +144,24 @@ For a user \fIjohn\fR this results in an AFP home volume with a path of /home/john/afp\-data\&. +.PP +If +\fBbasedir regex\fR +contains symlink, set the canonicalized absolute path\&. When +/home +links to +/usr/home: +.sp +.if n \{\ +.RS 4 +.\} +.nf + [Homes] + basedir regex = /usr/home +.fi +.if n \{\ +.RE +.\} .SH "PARAMETERS" .PP Parameters define the specific attributes of sections\&. @@ -435,7 +454,7 @@ Specifies a fully\-qualified domain name, with an optional port\&. This is disca .PP hostname = \fIname\fR \fB(G)\fR .RS 4 -Use this instead of the result from calling hostname for determining which IP address to advertise, therfore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by +Use this instead of the result from calling hostname for determining which IP address to advertise, therefore the hostname is resolved to an IP which is the advertised\&. This is NOT used for listening and it is also overwritten by \fBafp listen\fR\&. .RE .PP @@ -491,7 +510,9 @@ Whether to apply locks to the byte region read in FPRead calls\&. The AFP spec m .PP basedir regex = \fIregex\fR \fB(H)\fR .RS 4 -Regular expression which matches the parent directory of the user homes\&. In the simple case this is just a path ie +Regular expression which matches the parent directory of the user homes\&. If +\fBbasedir regex\fR +contains symlink, you must set the canonicalized absolute path\&. In the simple case this is just a path ie \fBbasedir regex = /home\fR .RE .PP @@ -514,7 +535,7 @@ Default size is 8192, maximum size is 131072\&. Given value is rounded up to nea .PP extmap file = \fIpath\fR \fB(G)\fR .RS 4 -Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/AppleVolumes\&.system)\&. +Sets the path to the file which defines file extension type/creator mappings\&. (default is :ETCDIR:/extmap\&.conf)\&. .RE .PP guest account = \fIname\fR \fB(G)\fR @@ -525,7 +546,7 @@ Specifies the user that guests should use (default is "nobody")\&. The name shou home name = \fIname\fR \fB(H)\fR .RS 4 AFP user home volume name\&. The default is -\fIusers\*(Aqs home\fR\&. +\fIuser\*(Aqs home\fR\&. .RE .PP keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR @@ -633,7 +654,7 @@ Both logtype and loglevels are case insensitive\&. .RE .SS "Filesystem Change Events (FCE)" .PP -Netatalk includes a nifty filesystem change event mechanism where afpd processes notfiy interested listeners about certain filesytem event by UDP network datagrams\&. +Netatalk includes a nifty filesystem change event mechanism where afpd processes notify interested listeners about certain filesystem event by UDP network datagrams\&. .PP fce listener = \fIhost[:port]\fR \fB(G)\fR .RS 4 @@ -645,7 +666,7 @@ is 12250 if not specified\&. Specifying multiple listeners is done by having thi .PP fce events = \fIfmod,fdel,ddel,fcre,dcre,tmsz\fR \fB(G)\fR .RS 4 -Speficies which FCE events are active, default is +Specifies which FCE events are active, default is \fIfmod,fdel,ddel,fcre,dcre\fR\&. .RE .PP @@ -683,7 +704,7 @@ Do not use this option any longer as present Netatalk correctly supports server .PP For a basic mode of operation there\*(Aqs nothing to configure\&. afpd reads ACLs on the fly, calculating effective permissions and returning the calculated permissions via the so called UARights permission bits\&. On a Mac the Finder uses these bits to adjust permission in Finder windows\&. For example folder whos UNIX mode would only result in in read\-only permissions for a user will not be displayed with a read\-only icon and the user will be able to write to the folder given the folder has an ACL giving the user write access\&. .PP -However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\*(Aqs a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involed as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\*(Aqs or gid\*(Aqs\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&. +However, neither in Finder "Get Info" windows nor in Terminal will you be able to see the ACLs, that\*(Aqs a result of how ACLs in OS X are designed\&. If you want to be able to display ACLs on the client, things get more involved as you must then setup both client and server to be part on a authentication domain (directory service, eg LDAP, OpenDirectory)\&. The reason is, that in OS X ACLs are bound to UUIDs, not just uid\*(Aqs or gid\*(Aqs\&. Therefor afpd must be able to map every filesystem uid and gid to a UUID so that it can return the server side ACLs which are bound to UNIX uid and gid mapped to OS X UUIDs\&. Get it? Read on\&. .PP Netatalk can query a directory server using LDAP queries\&. Either the directory server already provides an UUID attribute for user and groups (Active Directory, Open Directory) or you reuse an unused attribute (or add a new one) to you directory server (eg OpenLDAP)\&. .PP @@ -869,7 +890,7 @@ auto Try \fBsys\fR (by setting an EA on the shared directory itself), fallback to -\fBad\fR\&. Requires writeable volume for performing test\&. "\fBread only = yes\fR" overwrites +\fBad\fR\&. Requires writable volume for performing test\&. "\fBread only = yes\fR" overwrites \fBauto\fR with \fBnone\fR\&. Use explicit "\fBea = sys|ad\fR" for read\-only volumes where appropriate\&. @@ -1004,7 +1025,7 @@ Whether automatic conversion from \fBappledouble = v2\fR to \fBappledouble = ea\fR -is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\*(Aqs recommdable to run +is performed when accessing filesystems from clients\&. This is generally useful, but costs some performance\&. It\*(Aqs recommendable to run \fBdbd\fR on volumes and do the conversion with that\&. Then this option can be set to no\&. .RE @@ -1075,9 +1096,9 @@ directory\&. .PP cdb .RS 4 -"Concurrent database", backend is based on Oracle Berkely DB\&. With this backend several +"Concurrent database", backend is based on Oracle Berkley DB\&. With this backend several \fBafpd\fR -deamons access the CNID database directly\&. Berkeley DB locking is used to synchronize access, if more than one +daemons access the CNID database directly\&. Berkeley DB locking is used to synchronize access, if more than one \fBafpd\fR process is active for a volume\&. The drawback is, that the crash of a single \fBafpd\fR @@ -1117,7 +1138,7 @@ might show that there are other CNID backends available, be warned those are lik With OS X Apple introduced the AFP3 protocol\&. One of the most important changes was that AFP3 uses unicode names encoded as UTF\-8 decomposed\&. Previous AFP/OS versions used codepages, like MacRoman, MacCentralEurope, etc\&. .PP \fBafpd\fR -needs a way to preserve extended macintosh characters, or characters illegal in unix filenames, when saving files on a unix filesystem\&. Earlier versions used the the so called CAP encoding\&. An extended character (>0x7F) would be converted to a :xx sequence, e\&.g\&. the Apple Logo (MacRoman: 0xF0) was saved as +needs a way to preserve extended Macintosh characters, or characters illegal in unix filenames, when saving files on a unix filesystem\&. Earlier versions used the the so called CAP encoding\&. An extended character (>0x7F) would be converted to a :xx sequence, e\&.g\&. the Apple Logo (MacRoman: 0xF0) was saved as :f0\&. Some special characters will be converted as to :xx notation as well\&. \*(Aq/\*(Aq will be encoded to :2f, if \fBusedots\fR @@ -1148,4 +1169,5 @@ first\&. If this conversion fails, you\*(Aqll receive a \-50 error on the mac\&. \fBafpd\fR(8), \fBafppasswd\fR(5), \fBafp_signature.conf\fR(5), +\fBextmap.conf\fR(5), \fBcnid_metad\fR(8) diff --git a/man/man5/afp_signature.conf.5.tmpl b/man/man5/afp_signature.conf.5.tmpl index 54e2267f..2f5fe403 100644 --- a/man/man5/afp_signature.conf.5.tmpl +++ b/man/man5/afp_signature.conf.5.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: afp_signature.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 23 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AFP_SIGNATURE\&.CONF" "5" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation diff --git a/man/man5/afp_voluuid.conf.5.tmpl b/man/man5/afp_voluuid.conf.5.tmpl index 8d3626d0..a9fb2ddf 100644 --- a/man/man5/afp_voluuid.conf.5.tmpl +++ b/man/man5/afp_voluuid.conf.5.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: afp_voluuid.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 23 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "AFP_VOLUUID\&.CONF" "5" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation diff --git a/man/man5/extmap.conf.5.tmpl b/man/man5/extmap.conf.5.tmpl new file mode 100644 index 00000000..9c6679fa --- /dev/null +++ b/man/man5/extmap.conf.5.tmpl @@ -0,0 +1,77 @@ +'\" t +.\" Title: extmap.conf +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.78.0 +.\" Date: 19 Jan 2013 +.\" Manual: Netatalk 3.0 +.\" Source: Netatalk 3.0 +.\" Language: English +.\" +.TH "EXTMAP\&.CONF" "5" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +extmap.conf \- Configuration file used by afpd(8) to specify file name extension mappings\&. +.SH "SYNOPSIS" +.HP \w'\fB:ETCDIR:/extmap\&.conf\fR\fB\fR\ 'u +\fB:ETCDIR:/extmap\&.conf\fR\fB\fR +.SH "DESCRIPTION" +.PP + +:ETCDIR:/extmap\&.conf +is the configuration file used by +\fBafpd\fR +to specify file name extension mappings\&. +.PP +The configuration lines are composed like: +.PP +\&.extension +\fI[ type [ creator ] ]\fR +.PP +Any line beginning with a hash (\(lq#\(rq) character is ignored\&. The leading\-dot lines specify file name extension mappings\&. The extension \*(Aq\&.\*(Aq sets the default creator and type for otherwise untyped Unix files\&. +.SH "EXAMPLES" +.PP +\fBExample.\ \&Extension is jpg. Type is "JPEG". Creator is "ogle".\fR +.sp +.if n \{\ +.RS 4 +.\} +.nf +\&.jpg "JPEG" "ogle" +.fi +.if n \{\ +.RE +.\} +.PP +\fBExample.\ \&Extension is lzh. Type is "LHA ". Creator is not defined.\fR +.sp +.if n \{\ +.RS 4 +.\} +.nf +\&.lzh "LHA " +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP +\fBafp.conf\fR(5), +\fBafpd\fR(8) diff --git a/man/man8/afpd.8.tmpl b/man/man8/afpd.8.tmpl index 3a913925..9f09a64b 100644 --- a/man/man8/afpd.8.tmpl +++ b/man/man8/afpd.8.tmpl @@ -1,13 +1,22 @@ '\" t .\" Title: afpd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 23 Mar 2012 +.\" Generator: DocBook XSL Stylesheets v1.78.0 +.\" Date: 19 Jan 2013 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 .\" Language: English .\" -.TH "AFPD" "8" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" +.TH "AFPD" "8" "19 Jan 2013" "Netatalk 3.0" "Netatalk 3.0" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -64,7 +73,7 @@ Specifies the configuration file to use\&. (Defaults to .RE .SH "SIGNALS" .PP -To shut down a user\'s +To shut down a user\*(Aqs \fBafpd\fR process it is recommended that \fBSIGKILL (\-9)\fR @@ -105,7 +114,7 @@ to a child \fBafpd\fR enables \fImax_debug\fR -logging for this process\&. The log is sent to fhe file +logging for this process\&. The log is sent to the file /tmp/afpd\&.PID\&.XXXXXX\&. Sending another \fBSIGINT\fR will revert to the original log settings\&. @@ -142,6 +151,11 @@ list of server signature list of UUID for Time Machine volume .RE .PP +:ETCDIR:/extmap\&.conf +.RS 4 +file name extension mapping +.RE +.PP :ETCDIR:/msg/message\&.pid .RS 4 contains messages to be sent to users\&. @@ -153,4 +167,5 @@ contains messages to be sent to users\&. \fBafp.conf\fR(5), \fBafp_signature.conf\fR(5), \fBafp_voluuid.conf\fR(5), +\fBextmap.conf\fR(5), \fBdbd\fR(1)\&. diff --git a/man/man8/cnid_dbd.8.tmpl b/man/man8/cnid_dbd.8.tmpl index 347921ef..b5d8bc5d 100644 --- a/man/man8/cnid_dbd.8.tmpl +++ b/man/man8/cnid_dbd.8.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: cnid_dbd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 01 Jan 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "CNID_DBD" "8" "01 Jan 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -49,7 +58,7 @@ per netatalk volume\&. .PP \fBcnid_dbd\fR uses the -\fBBerkleley DB\fR +\fBBerkeley DB\fR database library and uses transactionally protected updates\&. The \fBdbd\fR backend with transactions will avoid corruption of the CNID database even if the system crashes unexpectedly\&. @@ -60,7 +69,7 @@ inherits the effective userid and groupid from on startup, which is normally caused by \fBafpd\fR serving a netatalk volume to a client\&. It changes to the -\fBBerkleley DB\fR +\fBBerkeley DB\fR database home directory \fIdbdir\fR that is associated with the volume\&. If the userid inherited from @@ -83,25 +92,19 @@ via the filedescriptor can be configured to run forever or to exit after a period of inactivity\&. If \fBcnid_dbd\fR receives a TERM or an INT signal it will exit cleanly after flushing dirty database buffers to disk and closing -\fBBerkleley DB\fR +\fBBerkeley DB\fR database environments\&. It is safe to terminate \fBcnid_dbd\fR this way, it will be restarted when necessary\&. Other signals are not handled and will cause an immediate exit, possibly leaving the CNID database in an inconsistent state (no transactions) or losing recent updates during recovery (transactions)\&. .PP The -\fBBerkleley DB\fR +\fBBerkeley DB\fR database subsystem will create files named log\&.xxxxxxxxxx in the database home directory -\fIdbdir\fR, where xxxxxxxxxx is a monotonically increasing integer\&. These files contain ithe transactional database changes\&. They will be removed regularily, unless the +\fIdbdir\fR, where xxxxxxxxxx is a monotonically increasing integer\&. These files contain the transactional database changes\&. They will be removed regularly, unless the \fBlogfile_autoremove\fR option is specified in the \fIdb_param\fR configuration file (see below) with a value of 0 (default 1)\&. -.PP -Do not use -\fBcnid_dbd\fR -for databases on NFS mounted file systems\&. It makes the whole point of securing database changes properly moot\&. Use the dbdir: Option in the appropriate -\fBAppleVolumes\fR -configuration file to put the database onto a local disk\&. .SH "OPTIONS" .PP \fB\-v, \-V\fR @@ -121,7 +124,7 @@ on startup\&. If the file does not exist or a parameter is not listed, suitable .RS 4 If set to 0, unused Berkeley DB transactional logfiles (log\&.xxxxxxxxxx in the database home directory) are not removed on startup of \fBcnid_dbd\fR -and on a reqular basis\&. Default: 1\&. +and on a regular basis\&. Default: 1\&. .RE .PP \fBcachesize\fR @@ -132,7 +135,7 @@ process grabs that much memory on top of its normal memory footprint\&. It can b \fBdb_stat\fR utility with the \fB\-m\fR -option that comes with Berkely DB can help you determine wether you need to change this value\&. The default is pretty conservative so that a large percentage of requests should be satisfied from the cache directly\&. If memory is not a bottleneck on your system you might want to leave it at that value\&. The +option that comes with Berkley DB can help you determine ether you need to change this value\&. The default is pretty conservative so that a large percentage of requests should be satisfied from the cache directly\&. If memory is not a bottleneck on your system you might want to leave it at that value\&. The \fBBerkeley DB Tutorial and Reference Guide\fR has a section \fBSelecting a cache size\fR @@ -178,7 +181,7 @@ exits\&. Default: 600\&. Set this to 0 to disable the timeout\&. .PP Note that the first version to appear \fIafter\fR -Netatalk 2\&.1 ie Netatalk 2\&.1\&.1, will support BerkeleyDB updates on the fly without manual intervention\&. In other words Netatalk 2\&.1 does contain code to prepare the BerkeleyDB database for upgrades and to upgrade it in case it has been prepared before\&. That means it can\'t upgrade a 2\&.0\&.x version because that one didn\'t prepare the database\&. +Netatalk 2\&.1 ie Netatalk 2\&.1\&.1, will support BerkeleyDB updates on the fly without manual intervention\&. In other words Netatalk 2\&.1 does contain code to prepare the BerkeleyDB database for upgrades and to upgrade it in case it has been prepared before\&. That means it can\*(Aqt upgrade a 2\&.0\&.x version because that one didn\*(Aqt prepare the database\&. .PP In order to update between older Netatalk releases using different BerkeleyDB library versions, follow this steps: .sp diff --git a/man/man8/cnid_metad.8.tmpl b/man/man8/cnid_metad.8.tmpl index f96778f1..4007a7ca 100644 --- a/man/man8/cnid_metad.8.tmpl +++ b/man/man8/cnid_metad.8.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: cnid_metad .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 23 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "CNID_METAD" "8" "23 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation @@ -62,7 +71,7 @@ Show version and exit\&. .PP \fBcnid_metad\fR does not block or catch any signals apart from SIGPIPE\&. It will therefore exit on most signals received\&. This will also cause all instances of -\fBcnid_dbd\'s\fR +\fBcnid_dbd\*(Aqs\fR started by that \fBcnid_metad\fR to exit gracefully\&. Since state about and IPC access to the subprocesses is only maintained in memory by diff --git a/man/man8/netatalk.8.tmpl b/man/man8/netatalk.8.tmpl index 61cfffe3..88cb179e 100644 --- a/man/man8/netatalk.8.tmpl +++ b/man/man8/netatalk.8.tmpl @@ -1,7 +1,7 @@ '\" t .\" Title: netatalk .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] -.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Generator: DocBook XSL Stylesheets v1.78.0 .\" Date: 22 Mar 2012 .\" Manual: Netatalk 3.0 .\" Source: Netatalk 3.0 @@ -9,6 +9,15 @@ .\" .TH "NETATALK" "8" "22 Mar 2012" "Netatalk 3.0" "Netatalk 3.0" .\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation From 536285d234458f7ff8fee148c7e4a047f43ee064 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 21 Jan 2013 15:06:39 +0100 Subject: [PATCH 114/117] dbd failed to convert appledouble files of symlinks dbd simply skipped symlinks, fix this by possibly deleting the appledouble file but still skip the CNID checks. Also remove left-over rebuild db stuff which isn't used anymore since the large dbd rewrite at 4913dbbc5b69642dacbe7302fc25d25f47e9c00c. Fixes #490. --- etc/cnid_dbd/cmd_dbd_scanvol.c | 47 +++++++++------------------------- libatalk/adouble/ad_conv.c | 7 +++-- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/etc/cnid_dbd/cmd_dbd_scanvol.c b/etc/cnid_dbd/cmd_dbd_scanvol.c index 48deb5f0..b9fbf3e8 100644 --- a/etc/cnid_dbd/cmd_dbd_scanvol.c +++ b/etc/cnid_dbd/cmd_dbd_scanvol.c @@ -49,7 +49,6 @@ static char cwdbuf[MAXPATHLEN+1]; static struct vol *vol; -static DBD *dbd_rebuild; static dbd_flags_t dbd_flags; static char stamp[CNID_DEV_LEN]; static char *netatalk_dirs[] = { @@ -686,10 +685,8 @@ static int dbd_readdir(int volroot, cnid_t did) switch (st.st_mode & S_IFMT) { case S_IFREG: case S_IFDIR: - break; case S_IFLNK: - dbd_log(LOGDEBUG, "Ignoring symlink %s/%s", cwdbuf, ep->d_name); - continue; + break; default: dbd_log(LOGSTD, "Bad filetype: %s/%s", cwdbuf, ep->d_name); if ( ! (dbd_flags & DBD_FLAGS_SCAN)) { @@ -726,41 +723,21 @@ static int dbd_readdir(int volroot, cnid_t did) if (ADDIR_OK) adfile_ok = check_adfile(ep->d_name, &st, &name); - if (name == NULL) { - name = ep->d_name; - } else { - update_cnid(did, &st, ep->d_name, name); - } + if (!S_ISLNK(st.st_mode)) { + if (name == NULL) { + name = ep->d_name; + } else { + update_cnid(did, &st, ep->d_name, name); + } - /* Check CNIDs */ - cnid = check_cnid(name, did, &st, adfile_ok); + /* Check CNIDs */ + cnid = check_cnid(name, did, &st, adfile_ok); - /* Now add this object to our rebuild dbd */ - if (cnid && dbd_rebuild) { - static uint count = 0; - rqst.cnid = rply.cnid; - ret = dbd_rebuild_add(dbd_rebuild, &rqst, &rply); - if (dbif_txn_close(dbd_rebuild, ret) != 0) - return -1; - if (rply.result != CNID_DBD_RES_OK) { - dbd_log( LOGSTD, "Fatal error adding CNID: %u for '%s/%s' to in-memory rebuild-db", - cnid, cwdbuf, name); - return -1; - } - count++; - if (count == 10000) { - if (dbif_txn_checkpoint(dbd_rebuild, 0, 0, 0) < 0) { - dbd_log(LOGSTD, "Error checkpointing!"); - return -1; - } - count = 0; - } + /* Check EA files */ + if (vol->v_vfs_ea == AFPVOL_EA_AD) + check_eafiles(name); } - /* Check EA files */ - if (vol->v_vfs_ea == AFPVOL_EA_AD) - check_eafiles(name); - /************************************************************************** Recursion **************************************************************************/ diff --git a/libatalk/adouble/ad_conv.c b/libatalk/adouble/ad_conv.c index ff0eebcc..a9fae763 100644 --- a/libatalk/adouble/ad_conv.c +++ b/libatalk/adouble/ad_conv.c @@ -173,9 +173,12 @@ static int ad_conv_v22ea(const char *path, const struct stat *sp, const struct v become_root(); - EC_ZERO( ad_conv_v22ea_hf(path, sp, vol) ); - EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) ); + if (ad_conv_v22ea_hf(path, sp, vol) != 0) + goto delete; + if (ad_conv_v22ea_rf(path, sp, vol) != 0) + goto delete; +delete: EC_NULL( adpath = ad_path(path, adflags) ); LOG(log_debug, logtype_ad,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"", path, fullpathname(adpath)); From 2ba57d55b47828f0fca910695de660c29e08cad0 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 21 Jan 2013 17:50:04 +0100 Subject: [PATCH 115/117] Update NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index c2572250..154eccf2 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,8 @@ Changes in 3.0.2 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 ================ From 3937572ed09c7fa3a8842e4d5c0057ccaa13f562 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Mon, 21 Jan 2013 18:10:34 +0100 Subject: [PATCH 116/117] Set version to 3.0.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index abbd04ee..d9c62ed9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.1dev \ No newline at end of file +3.0.2 \ No newline at end of file From ca0b818edb7a3115ad02645db1d42bd1eb4be8dc Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Mon, 21 Jan 2013 18:16:01 +0100 Subject: [PATCH 117/117] Add 3.0.2 ABI file and set library version --- libatalk/Makefile.am | 7 +- libatalk/libatalk-3.0.2.abi | 565 ++++++++++++++++++++++++++++++++++++ 2 files changed, 569 insertions(+), 3 deletions(-) create mode 100644 libatalk/libatalk-3.0.2.abi diff --git a/libatalk/Makefile.am b/libatalk/Makefile.am index fb0e7456..732aeea8 100644 --- a/libatalk/Makefile.am +++ b/libatalk/Makefile.am @@ -18,7 +18,7 @@ # current+1:0:0 # -VERSION_INFO = 2:0:0 +VERSION_INFO = 3:0:0 # History: VERSION_INFO # @@ -29,7 +29,7 @@ VERSION_INFO = 2:0:0 # 3.0.0-beta2 1:0:0 # 3.0 1:0:0 # 3.0.1 2:0:0 -# 3.0.2 3:0:1 +# 3.0.2 3:0:0 SUBDIRS = acl adouble bstring compat cnid dsi iniparser tdb util unicode vfs @@ -92,5 +92,6 @@ endif EXTRA_DIST = \ libatalk-3.0beta1.abi \ libatalk-3.0beta2.abi \ + libatalk-3.0.abi \ libatalk-3.0.1.abi \ - libatalk-3.0.abi + libatalk-3.0.2.abi diff --git a/libatalk/libatalk-3.0.2.abi b/libatalk/libatalk-3.0.2.abi new file mode 100644 index 00000000..8e73229c --- /dev/null +++ b/libatalk/libatalk-3.0.2.abi @@ -0,0 +1,565 @@ +acl_ldap_freeconfig: void (void) +acl_ldap_readconfig: int (dictionary *) +ad_close: int (struct adouble *, int) +ad_convert: int (const char *, const struct stat *, const struct vol *, const char **) +ad_copy_header: int (struct adouble *, struct adouble *) +add_cachebyname: int (const char *, const uuidp_t, const uuidtype_t, const long unsigned int) +add_cachebyuuid: int (uuidp_t, const char *, uuidtype_t, const long unsigned int) +add_charset: charset_t (const char *) +ad_dir: char *(const char *) +ad_dtruncate: int (struct adouble *, const off_t) +adflags2logstr: const char *(int) +ad_flush: int (struct adouble *) +ad_forcegetid: uint32_t (struct adouble *) +adf_pread: ssize_t (struct ad_fd *, void *, size_t, off_t) +adf_pwrite: ssize_t (struct ad_fd *, const void *, size_t, off_t) +ad_getattr: int (const struct adouble *, uint16_t *) +ad_getdate: int (const struct adouble *, unsigned int, uint32_t *) +ad_getentryoff: off_t (const struct adouble *, int) +ad_getfuid: uid_t (void) +ad_getid: uint32_t (struct adouble *, const dev_t, const ino_t, const cnid_t, const void *) +ad_hf_mode: mode_t (mode_t) +ad_init: void (struct adouble *, const struct vol *) +ad_init_old: void (struct adouble *, int, int) +ad_lock: int (struct adouble *, uint32_t, int, off_t, off_t, int) +ad_metadata: int (const char *, int, struct adouble *) +ad_metadataat: int (int, const char *, int, struct adouble *) +ad_mkdir: int (const char *, mode_t) +ad_mode: int (const char *, mode_t) +ad_open: int (struct adouble *, const char *, int, ...) +ad_openat: int (struct adouble *, int, const char *, int, ...) +ad_openforks: uint16_t (struct adouble *, uint16_t) +ad_path: const char *(const char *, int) +ad_path_ea: const char *(const char *, int) +ad_path_osx: const char *(const char *, int) +ad_read: ssize_t (struct adouble *, const uint32_t, off_t, char *, const size_t) +ad_readfile_init: int (const struct adouble *, const int, off_t *, const int) +ad_rebuild_adouble_header_ea: int (struct adouble *) +ad_rebuild_adouble_header_v2: int (struct adouble *) +ad_refresh: int (const char *, struct adouble *) +ad_rtruncate: int (struct adouble *, const off_t) +ad_setattr: int (const struct adouble *, const uint16_t) +ad_setdate: int (struct adouble *, unsigned int, uint32_t) +ad_setfuid: int (const uid_t) +ad_setid: int (struct adouble *, const dev_t, const ino_t, const uint32_t, const cnid_t, const void *) +ad_setname: int (struct adouble *, const char *) +ad_size: off_t (const struct adouble *, const uint32_t) +ad_stat: int (const char *, struct stat *) +ad_testlock: int (struct adouble *, int, const off_t) +ad_tmplock: int (struct adouble *, uint32_t, int, off_t, off_t, int) +ad_unlock: void (struct adouble *, const int, int) +ad_valid_header_osx: int (const char *) +ad_write: ssize_t (struct adouble *, uint32_t, off_t, int, const char *, size_t) +afp_config_free: void (AFPObj *) +afp_config_parse: int (AFPObj *, char *) +allow_severity: 5 +apply_ip_mask: void (struct sockaddr *, int) +atalk_iconv: size_t (atalk_iconv_t, const char **, size_t *, char **, size_t *) +atalk_iconv_close: int (atalk_iconv_t) +atalk_iconv_open: atalk_iconv_t (const char *, const char *) +atalk_register_charset: int (struct charset_functions *) +balloc: int (bstring, int) +ballocmin: int (bstring, int) +basename_safe: const char *(const char *) +bassign: int (bstring, const_bstring) +bassignblk: int (bstring, const void *, int) +bassigncstr: int (bstring, const char *) +bassignformat: int (bstring, const char *, ...) +bassigngets: int (bstring, bNgetc, void *, char) +bassignmidstr: int (bstring, const_bstring, int, int) +bcatblk: int (bstring, const void *, int) +bcatcstr: int (bstring, const char *) +bconcat: int (bstring, const_bstring) +bconchar: int (bstring, char) +bcstrfree: int (char *) +bdelete: int (bstring, int, int) +bdestroy: int (bstring) +become_root: void (void) +bfindreplace: int (bstring, const_bstring, const_bstring, int) +bfindreplacecaseless: int (bstring, const_bstring, const_bstring, int) +bformat: bstring (const char *, ...) +bformata: int (bstring, const char *, ...) +bfromcstr: bstring (const char *) +bfromcstralloc: bstring (int, const char *) +bgetsa: int (bstring, bNgetc, void *, char) +bgetstream: bstring (bNgetc, void *, char) +binchr: int (const_bstring, int, const_bstring) +binchrr: int (const_bstring, int, const_bstring) +binsert: int (bstring, int, const_bstring, unsigned char) +binsertch: int (bstring, int, int, unsigned char) +binstr: int (const_bstring, int, const_bstring) +binstrcaseless: int (const_bstring, int, const_bstring) +binstrr: int (const_bstring, int, const_bstring) +binstrrcaseless: int (const_bstring, int, const_bstring) +biseq: int (const_bstring, const_bstring) +biseqcaseless: int (const_bstring, const_bstring) +biseqcstr: int (const_bstring, const char *) +biseqcstrcaseless: int (const_bstring, const char *) +bisstemeqblk: int (const_bstring, const void *, int) +bisstemeqcaselessblk: int (const_bstring, const void *, int) +bjoin: bstring (const struct bstrList *, const_bstring) +bjoinInv: bstring (const struct bstrList *, const_bstring) +blk2bstr: bstring (const void *, int) +bltrimws: int (bstring) +bmidstr: bstring (const_bstring, int, int) +bninchr: int (const_bstring, int, const_bstring) +bninchrr: int (const_bstring, int, const_bstring) +bpattern: int (bstring, int) +bread: bstring (bNread, void *) +breada: int (bstring, bNread, void *) +brefcstr: bstring (char *) +breplace: int (bstring, int, int, const_bstring, unsigned char) +brtrimws: int (bstring) +bsbufflength: int (struct bStream *, int) +bsclose: void *(struct bStream *) +bseof: int (const struct bStream *) +bsetstr: int (bstring, int, const_bstring, unsigned char) +bsopen: struct bStream *(bNread, void *) +bspeek: int (bstring, const struct bStream *) +bsplit: struct bstrList *(const_bstring, unsigned char) +bsplitcb: int (const_bstring, unsigned char, int, int (*)(void *, int, int), void *) +bsplits: struct bstrList *(const_bstring, const_bstring) +bsplitscb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *) +bsplitstr: struct bstrList *(const_bstring, const_bstring) +bsplitstrcb: int (const_bstring, const_bstring, int, int (*)(void *, int, int), void *) +bsread: int (bstring, struct bStream *, int) +bsreada: int (bstring, struct bStream *, int) +bsreadln: int (bstring, struct bStream *, char) +bsreadlna: int (bstring, struct bStream *, char) +bsreadlns: int (bstring, struct bStream *, const_bstring) +bsreadlnsa: int (bstring, struct bStream *, const_bstring) +bssplitscb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *) +bssplitstrcb: int (struct bStream *, const_bstring, int (*)(void *, int, const_bstring), void *) +bstr2cstr: char *(const_bstring, char) +bstrchrp: int (const_bstring, int, int) +bstrcmp: int (const_bstring, const_bstring) +bstrcpy: bstring (const_bstring) +bstricmp: int (const_bstring, const_bstring) +bstrListAlloc: int (struct bstrList *, int) +bstrListAllocMin: int (struct bstrList *, int) +bstrListCreate: struct bstrList *(void) +bstrListCreateMin: struct bstrList *(int) +bstrListDestroy: int (struct bstrList *) +bstrListPop: bstring (struct bstrList *) +bstrListPush: int (struct bstrList *, bstring) +bstrncmp: int (const_bstring, const_bstring, int) +bstrnicmp: int (const_bstring, const_bstring, int) +bstrrchrp: int (const_bstring, int, int) +bsunread: int (struct bStream *, const_bstring) +btolower: int (bstring) +btoupper: int (bstring) +btrimws: int (bstring) +btrunc: int (bstring, int) +bunrefcstr: int (bstring) +bvcformata: int (bstring, int, const char *, struct __va_list_tag *) +charset_decompose: size_t (charset_t, char *, size_t, char *, size_t) +charset_mac_centraleurope: {name = "MAC_CENTRALEUROPE", kTextEncoding = 29, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_chinese_simp: {name = "MAC_CHINESE_SIMP", kTextEncoding = 25, pull = , push = , flags = 85, iname = "EUC-CN", prev = 0x0, next = 0x0} +charset_mac_chinese_trad: {name = "MAC_CHINESE_TRAD", kTextEncoding = 2, pull = , push = , flags = 85, iname = "BIG-5", prev = 0x0, next = 0x0} +charset_mac_cyrillic: {name = "MAC_CYRILLIC", kTextEncoding = 7, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_greek: {name = "MAC_GREEK", kTextEncoding = 6, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_hebrew: {name = "MAC_HEBREW", kTextEncoding = 5, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_japanese: {name = "MAC_JAPANESE", kTextEncoding = 1, pull = , push = , flags = 85, iname = "SHIFT_JIS", prev = 0x0, next = 0x0} +charset_mac_korean: {name = "MAC_KOREAN", kTextEncoding = 3, pull = , push = , flags = 85, iname = "EUC-KR", prev = 0x0, next = 0x0} +charset_mac_roman: {name = "MAC_ROMAN", kTextEncoding = 0, pull = , push = , flags = 21, iname = 0x0, prev = 0x0, next = 0x0} +charset_mac_turkish: {name = "MAC_TURKISH", kTextEncoding = 35, pull = , push = , flags = 17, iname = 0x0, prev = 0x0, next = 0x0} +charset_precompose: size_t (charset_t, char *, size_t, char *, size_t) +charset_strlower: size_t (charset_t, const char *, size_t, char *, size_t) +charset_strupper: size_t (charset_t, const char *, size_t, char *, size_t) +charset_to_ucs2_allocate: size_t (charset_t, uint16_t **, const char *) +charset_to_utf8_allocate: size_t (charset_t, char **, const char *) +charset_utf8: {name = "UTF8", kTextEncoding = 134217987, pull = , push = , flags = 22, iname = 0x0, prev = 0x0, next = 0x0} +charset_utf8_mac: {name = "UTF8-MAC", kTextEncoding = 134217987, pull = , push = , flags = 27, iname = 0x0, prev = 0x0, next = 0x0} +check_lockfile: int (const char *, const char *) +cjk_char_pull: size_t (uint16_t, uint16_t *, const uint32_t *) +cjk_char_push: size_t (uint16_t, uint8_t *) +cjk_compose: uint16_t (uint16_t, uint16_t, const uint32_t *, size_t) +cjk_compose_seq: uint16_t (const uint16_t *, size_t *, const uint32_t *, size_t) +cjk_generic_pull: size_t (size_t (*)(uint16_t *, const uint8_t *, size_t *), void *, char **, size_t *, char **, size_t *) +cjk_generic_push: size_t (size_t (*)(uint8_t *, const uint16_t *, size_t *), void *, char **, size_t *, char **, size_t *) +cjk_lookup: uint16_t (uint16_t, const cjk_index_t *, const uint16_t *) +cnid_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, const char *, const size_t, cnid_t) +cnid_close: void (struct _cnid_db *) +cnid_dbd_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_dbd_close: void (struct _cnid_db *) +cnid_dbd_delete: int (struct _cnid_db *, const cnid_t) +cnid_dbd_find: int (struct _cnid_db *, const char *, size_t, void *, size_t) +cnid_dbd_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_dbd_getstamp: int (struct _cnid_db *, void *, const size_t) +cnid_dbd_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_dbd_module: {name = "dbd", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0} +cnid_dbd_open: struct _cnid_db *(struct cnid_open_args *) +cnid_dbd_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_dbd_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_dbd_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_dbd_wipe: int (struct _cnid_db *) +cnid_delete: int (struct _cnid_db *, cnid_t) +cnid_find: int (struct _cnid_db *, const char *, size_t, void *, size_t) +cnid_get: cnid_t (struct _cnid_db *, const cnid_t, char *, const size_t) +cnid_getstamp: int (struct _cnid_db *, void *, const size_t) +cnid_init: void (void) +cnid_last_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_last_close: void (struct _cnid_db *) +cnid_last_delete: int (struct _cnid_db *, const cnid_t) +cnid_last_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_last_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_last_module: {name = "last", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 0} +cnid_last_open: struct _cnid_db *(struct cnid_open_args *) +cnid_last_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_last_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_lookup: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t) +cnid_open: struct _cnid_db *(const char *, mode_t, char *, int, const char *, const char *) +cnid_rebuild_add: cnid_t (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t) +cnid_register: void (struct _cnid_module *) +cnid_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_tdb_add: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t, cnid_t) +cnid_tdb_close: void (struct _cnid_db *) +cnid_tdb_delete: int (struct _cnid_db *, const cnid_t) +cnid_tdb_get: cnid_t (struct _cnid_db *, cnid_t, const char *, size_t) +cnid_tdb_lookup: cnid_t (struct _cnid_db *, const struct stat *, cnid_t, const char *, size_t) +cnid_tdb_module: {name = "tdb", db_list = {next = 0x0, prev = 0x0}, cnid_open = 0, flags = 12} +cnid_tdb_open: struct _cnid_db *(struct cnid_open_args *) +cnid_tdb_resolve: char *(struct _cnid_db *, cnid_t *, void *, size_t) +cnid_tdb_update: int (struct _cnid_db *, cnid_t, const struct stat *, cnid_t, const char *, size_t) +cnid_update: int (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, const size_t) +cnid_wipe: int (struct _cnid_db *) +compare_ip: int (const struct sockaddr *, const struct sockaddr *) +convert_charset: size_t (charset_t, charset_t, charset_t, const char *, size_t, char *, size_t, uint16_t *) +convert_string: size_t (charset_t, charset_t, const void *, size_t, void *, size_t) +convert_string_allocate: size_t (charset_t, charset_t, const void *, size_t, char **) +copy_ea: int (const char *, int, const char *, const char *, mode_t) +copy_file: int (int, const char *, const char *, mode_t) +copy_file_fd: int (int, int) +copy_fork: int (int, struct adouble *, struct adouble *) +create_lockfile: int (const char *, const char *) +daemonize: int (int, int) +decompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *) +deny_severity: 3 +dequeue: void *(q_t *) +_diacasemap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 233, 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 198, 183, 184, 184, 186, 187, 188, 189, 174, 175, 192, 193, 194, 195, 196, 197, 198, 199...} +_dialowermap: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 132, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, 176, 177, 178, 179, 180, 181, 198, 183, 185, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199...} +dictionary_del: void (dictionary *) +dictionary_dump: void (dictionary *, FILE *) +dictionary_get: const char *(const dictionary *, const char *, const char *, const char *) +dictionary_hash: unsigned int (char *) +dictionary_new: dictionary *(int) +dictionary_set: int (dictionary *, char *, char *, char *) +dictionary_unset: void (dictionary *, char *, char *) +dir_rx_set: int (mode_t) +dsi_attention: int (DSI *, AFPUserBytes) +dsi_close: void (DSI *) +dsi_cmdreply: int (DSI *, const int) +dsi_disconnect: int (DSI *) +dsi_free: void (DSI *) +dsi_getsession: int (DSI *, server_child *, int, afp_child_t **) +dsi_getstatus: void (DSI *) +dsi_init: DSI *(AFPObj *, const char *, const char *, const char *) +dsi_opensession: void (DSI *) +dsi_read: ssize_t (DSI *, void *, const size_t) +dsi_readdone: void (DSI *) +dsi_readinit: ssize_t (DSI *, void *, const size_t, const size_t, const int) +dsi_stream_read: size_t (DSI *, void *, const size_t) +dsi_stream_read_file: ssize_t (DSI *, const int, off_t, const size_t, const int) +dsi_stream_receive: int (DSI *) +dsi_stream_send: int (DSI *, void *, size_t) +dsi_stream_write: ssize_t (DSI *, void *, const size_t, int) +dsi_tcp_init: int (DSI *, const char *, const char *, const char *) +dsi_tickle: int (DSI *) +dsi_write: size_t (DSI *, void *, const size_t) +dsi_writeflush: void (DSI *) +dsi_writeinit: size_t (DSI *, void *, const size_t) +ea_chmod_dir: int (const struct vol *, const char *, mode_t, struct stat *) +ea_chmod_file: int (const struct vol *, const char *, mode_t, struct stat *) +ea_chown: int (const struct vol *, const char *, uid_t, gid_t) +ea_close: int (struct ea *) +ea_copyfile: int (const struct vol *, int, const char *, const char *) +ea_deletefile: int (const struct vol *, int, const char *) +ea_open: int (const struct vol *, const char *, eaflags_t, struct ea *) +ea_openat: int (const struct vol *, int, const char *, eaflags_t, struct ea *) +ea_path: char *(const struct ea *, const char *, int) +ea_renamefile: int (const struct vol *, int, const char *, const char *) +enqueue: qnode_t *(q_t *, void *) +fault_setup: void (void (*)(void *)) +fdset_add_fd: void (int, struct pollfd **, struct polldata **, int *, int *, int, enum fdtype, void *) +fdset_del_fd: void (struct pollfd **, struct polldata **, int *, int *, int) +find_charset_functions: struct charset_functions *(const char *) +_fini: +free_charset_names: void (void) +freeifacelist: void (char **) +fullpathname: const char *(const char *) +getcwdpath: const char *(void) +getdefextmap: struct extmap *(void) +get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int) +get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *) +getextmap: struct extmap *(const char *) +getifacelist: char **(void) +getip_port: unsigned int (const struct sockaddr *) +getip_string: const char *(const struct sockaddr *) +getnamefromuuid: int (const uuidp_t, char **, uuidtype_t *) +getuuidfromname: int (const char *, uuidtype_t, unsigned char *) +getvolbyname: struct vol *(const char *) +getvolbypath: struct vol *(AFPObj *, const char *) +getvolbyvid: struct vol *(const uint16_t) +getvolumes: struct vol *(void) +gmem: int (gid_t, int, gid_t *) +iniparser_dump: void (const dictionary *, FILE *) +iniparser_dump_ini: void (const dictionary *, FILE *) +iniparser_find_entry: int (const dictionary *, const char *) +iniparser_freedict: void (dictionary *) +iniparser_getboolean: int (const dictionary *, const char *, const char *, int) +iniparser_getdouble: double (const dictionary *, const char *, const char *, double) +iniparser_getint: int (const dictionary *, const char *, const char *, int) +iniparser_getnsec: int (const dictionary *) +iniparser_getsecname: const char *(const dictionary *, int) +iniparser_getstrdup: char *(const dictionary *, const char *, const char *, const char *) +iniparser_getstring: const char *(const dictionary *, const char *, const char *, const char *) +iniparser_load: dictionary *(const char *) +iniparser_set: int (dictionary *, char *, char *, char *) +iniparser_unset: void (dictionary *, char *, char *) +_init: +init_iconv: void (void) +initline: void (int, char *) +initvol_vfs: void (struct vol *) +ipc_child_write: int (int, uint16_t, int, void *) +ipc_client_uds: int (const char *) +ipc_server_read: int (server_child *, int) +ipc_server_uds: int (const char *) +islower_sp: int (uint32_t) +islower_w: int (uint16_t) +isupper_sp: int (uint32_t) +isupper_w: int (uint16_t) +ldap_auth_dn: 0x0 +ldap_auth_method: 0 +ldap_auth_pw: 0x0 +ldap_config_valid: 0 +ldap_getnamefromuuid: int (const char *, char **, uuidtype_t *) +ldap_getuuidfromname: int (const char *, uuidtype_t, char **) +ldap_group_attr: 0x0 +ldap_groupbase: 0x0 +ldap_groupscope: 0 +ldap_name_attr: 0x0 +ldap_prefs: {{pref = 0x0, name = "ldap server", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth method", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap auth dn", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap auth pw", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap userbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap userscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupbase", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap groupscope", strorint = 1, intfromarray = 1, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uuid string", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap name attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap group attr", strorint = 0, intfromarray = 0, valid = -1, valid_save = -1}, {pref = 0x0, name = "ldap uid attr", strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}, {pref = 0x0, name = "ldap uuid encoding", strorint = 1, intfromarray = 1, valid = 0, valid_save = 0}, {pref = 0x0, name = 0x0, strorint = 0, intfromarray = 0, valid = 0, valid_save = 0}} +ldap_server: 0x0 +ldap_uid_attr: 0x0 +ldap_userbase: 0x0 +ldap_userscope: 0 +ldap_uuid_attr: 0x0 +ldap_uuid_encoding: 0 +ldap_uuid_string: 0x0 +list_eas: int (const struct vol *, char *, size_t *, const char *, int) +load_charset: int (struct vol *) +load_volumes: int (AFPObj *) +localuuid_from_id: void (unsigned char *, uuidtype_t, unsigned int) +lock_reg: int (int, int, int, off_t, int, off_t) +log_config: {inited = false, syslog_opened = false, console = false, processname = '\0' , syslog_facility = 0, syslog_display_options = 0} +make_log_entry: void (enum loglevels, enum logtypes, const char *, int, char *, ...) +make_tdb_data: unsigned char *(uint32_t, const struct stat *, const cnid_t, const char *, const size_t) +mb_generic_pull: size_t (int (*)(uint16_t *, const unsigned char *), void *, char **, size_t *, char **, size_t *) +mb_generic_push: size_t (int (*)(unsigned char *, uint16_t), void *, char **, size_t *, char **, size_t *) +netatalk_panic: void (const char *) +netatalk_rmdir: int (int, const char *) +netatalk_rmdir_all_errors: int (int, const char *) +netatalk_unlink: int (const char *) +netatalk_unlinkat: int (int, const char *) +nftw: int (const char *, nftw_func_t, dir_notification_func_t, int, int) +ochdir: int (const char *, int) +ochmod: int (char *, mode_t, const struct stat *, int) +ochown: int (const char *, uid_t, gid_t, int) +opendirat: DIR *(int, const char *) +openflags2logstr: const char *(int) +ostat: int (const char *, struct stat *, int) +ostatat: int (int, const char *, struct stat *, int) +parseline: int (int, char *) +posix_chmod: int (const char *, mode_t) +posix_fchmod: int (int, mode_t) +precompose_w: size_t (uint16_t *, size_t, uint16_t *, size_t *) +prefs_array: {{pref = "ldap auth method", valuestring = "none", value = 0}, {pref = "ldap auth method", valuestring = "simple", value = 128}, {pref = "ldap auth method", valuestring = "sasl", value = 163}, {pref = "ldap userscope", valuestring = "base", value = 0}, {pref = "ldap userscope", valuestring = "one", value = 1}, {pref = "ldap userscope", valuestring = "sub", value = 2}, {pref = "ldap groupscope", valuestring = "base", value = 0}, {pref = "ldap groupscope", valuestring = "one", value = 1}, {pref = "ldap groupscope", valuestring = "sub", value = 2}, {pref = "ldap uuid encoding", valuestring = "ms-guid", value = 1}, {pref = "ldap uuid encoding", valuestring = "string", value = 0}, {pref = 0x0, valuestring = 0x0, value = 0}} +prequeue: qnode_t *(q_t *, void *) +queue_destroy: void (q_t *, void (*)(void *)) +queue_init: q_t *(void) +randombytes: void (void *, int) +readt: ssize_t (int, void *, const size_t, int, int) +realpath_safe: char *(const char *) +reconnect_ipc: int (AFPObj *) +recv_fd: int (int, int) +rel_path_in_vol: bstring (const char *, const char *) +remove_acl_vfs: int (const char *) +remove_ea: int (const struct vol *, const char *, const char *, int) +run_cmd: int (const char *, char **) +search_cachebyname: int (const char *, uuidtype_t *, unsigned char *) +search_cachebyuuid: int (uuidp_t, char **, uuidtype_t *) +send_fd: int (int, int) +server_child_add: afp_child_t *(server_child *, int, pid_t, int) +server_child_alloc: server_child *(const int, const int) +server_child_free: void (server_child *) +server_child_kill: void (server_child *, int, int) +server_child_kill_one_by_id: void (server_child *, int, pid_t, uid_t, uint32_t, char *, uint32_t) +server_child_remove: int (server_child *, const int, pid_t) +server_child_setup: void (server_child *, const int, void (*)(const pid_t)) +server_child_transfer_session: int (server_child *, int, pid_t, uid_t, int, uint16_t) +server_lock: pid_t (char *, char *, int) +server_reset_signal: void (void) +set_charset_name: int (charset_t, const char *) +set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int) +setfilmode: int (const struct vol *, const char *, mode_t, struct stat *) +setnonblock: int (int, int) +set_processname: void (const char *) +setuplog: void (const char *, const char *) +statat: int (int, const char *, struct stat *) +strcasechr_sp: uint16_t *(const uint16_t *, uint32_t) +strcasechr_w: uint16_t *(const uint16_t *, uint16_t) +strcasecmp_w: int (const uint16_t *, const uint16_t *) +strcasestr_w: uint16_t *(const uint16_t *, const uint16_t *) +strcat_w: uint16_t *(uint16_t *, const uint16_t *) +strchr_w: uint16_t *(const uint16_t *, uint16_t) +strcmp_w: int (const uint16_t *, const uint16_t *) +strdiacasecmp: int (const char *, const char *) +strdup_w: uint16_t *(const uint16_t *) +stripped_slashes_basename: char *(char *) +strlcat: size_t (char *, const char *, size_t) +strlcpy: size_t (char *, const char *, size_t) +strlen_w: size_t (const uint16_t *) +strlower_w: int (uint16_t *) +strncasecmp_w: int (const uint16_t *, const uint16_t *, size_t) +strncat_w: uint16_t *(uint16_t *, const uint16_t *, const size_t) +strncmp_w: int (const uint16_t *, const uint16_t *, size_t) +strncpy_w: uint16_t *(uint16_t *, const uint16_t *, const size_t) +strndiacasecmp: int (const char *, const char *, size_t) +strndup_w: uint16_t *(const uint16_t *, size_t) +strnlen_w: size_t (const uint16_t *, size_t) +strstr_w: uint16_t *(const uint16_t *, const uint16_t *) +strtok_quote: char *(char *, const char *) +strupper_w: int (uint16_t *) +sys_ea_copyfile: int (const struct vol *, int, const char *, const char *) +sys_fgetxattr: ssize_t (int, const char *, void *, size_t) +sys_fsetxattr: int (int, const char *, const void *, size_t, int) +sys_ftruncate: int (int, off_t) +sys_get_eacontent: int (const struct vol *, char *, size_t *, const char *, int, const char *, int) +sys_get_easize: int (const struct vol *, char *, size_t *, const char *, int, const char *) +sys_getxattr: ssize_t (const char *, const char *, void *, size_t) +sys_getxattrfd: int (int, const char *, int, ...) +sys_lgetxattr: ssize_t (const char *, const char *, void *, size_t) +sys_list_eas: int (const struct vol *, char *, size_t *, const char *, int) +sys_listxattr: ssize_t (const char *, char *, size_t) +sys_llistxattr: ssize_t (const char *, char *, size_t) +sys_lremovexattr: int (const char *, const char *) +sys_lsetxattr: int (const char *, const char *, const void *, size_t, int) +sys_remove_ea: int (const struct vol *, const char *, const char *, int) +sys_removexattr: int (const char *, const char *) +sys_sendfile: ssize_t (int, int, off_t *, size_t) +sys_set_ea: int (const struct vol *, const char *, const char *, const char *, size_t, int) +sys_setxattr: int (const char *, const char *, const void *, size_t, int) +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) +tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_brlock: int (struct tdb_context *, tdb_off_t, int, int, int, size_t) +tdb_brlock_upgrade: int (struct tdb_context *, tdb_off_t, size_t) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_convert: void *(void *, uint32_t) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_expand: int (struct tdb_context *, tdb_off_t) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_io_init: void (struct tdb_context *) +tdb_lock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_mmap: void (struct tdb_context *) +tdb_munmap: int (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: {dptr = 0x0, dsize = 0} +tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +_tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_lock: int (struct tdb_context *, int) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_recover: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_unlock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_unlock_record: int (struct tdb_context *, tdb_off_t) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) +tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) +tolower_sp: uint32_t (uint32_t) +tolower_w: uint16_t (uint16_t) +toupper_sp: uint32_t (uint32_t) +toupper_w: uint16_t (uint16_t) +type_configs: {{set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}, {set = false, syslog = false, fd = -1, level = log_none, display_options = 0}} +ucs2_to_charset: size_t (charset_t, const uint16_t *, char *, size_t) +ucs2_to_charset_allocate: size_t (charset_t, char **, const uint16_t *) +unbecome_root: void (void) +unix_rename: int (int, const char *, int, const char *) +unix_strlower: size_t (const char *, size_t, char *, size_t) +unix_strupper: size_t (const char *, size_t, char *, size_t) +unload_volumes: void (AFPObj *) +utf8_charlen: size_t (char *) +utf8_decompose: size_t (char *, size_t, char *, size_t) +utf8_precompose: size_t (char *, size_t, char *, size_t) +utf8_strlen_validate: size_t (char *) +utf8_strlower: size_t (const char *, size_t, char *, size_t) +utf8_strupper: size_t (const char *, size_t, char *, size_t) +utf8_to_charset_allocate: size_t (charset_t, char **, const char *) +uuid_bin2string: const char *(const unsigned char *) +uuidcache_dump: void (void) +uuid_string2bin: void (const char *, unsigned char *) +uuidtype: {"", "USER", "GROUP", "LOCAL"} +volume_free: void (struct vol *) +volume_unlink: void (struct vol *) +writet: ssize_t (int, void *, const size_t, int, int)