#include <atalk/errchk.h>
#include <atalk/globals.h>
#include <atalk/fce_api.h>
+#include <atalk/netatalk_conf.h>
#include "directory.h"
#include "dircache.h"
}
/* ------------------- */
-static int deletedir(int dirfd, char *dir)
+static int deletedir(const struct vol *vol, int dirfd, char *dir)
{
char path[MAXPATHLEN + 1];
DIR *dp;
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);
}
}
/* 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;
}
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;
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 {
}
/* 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);
}
char *t;
cnid_t fileid = 0;
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
if (toUTF8) {
if (dir->d_did == DIRDID_ROOT_PARENT) {
/*
/* duplicate work but we can't reuse all convert_char we did in demangle_osx
* flags weren't the same
*/
- if ( (t = utompath(vol, ret->u_name, fileid, utf8_encoding())) ) {
+ if ( (t = utompath(vol, ret->u_name, fileid, utf8_encoding(vol->v_obj))) ) {
/* at last got our view of mac name */
strcpy(ret->m_name, t);
}
/* If we haven't got it by now, get it */
if (ret->u_name == NULL) {
- if ((ret->u_name = mtoupath(vol, ret->m_name, dir->d_did, utf8_encoding())) == NULL) {
+ if ((ret->u_name = mtoupath(vol, ret->m_name, dir->d_did, utf8_encoding(vol->v_obj))) == NULL) {
afp_errno = AFPERR_PARAM;
return -1;
}
goto exit;
}
- utf8 = utf8_encoding();
+ utf8 = utf8_encoding(vol->v_obj);
maxpath = (utf8) ? MAXPATHLEN - 7 : 255;
/* Get it from the database */
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;
#define ENUMVETO "./../Network Trash Folder/TheVolumeSettingsFolder/TheFindByContentFolder/:2eDS_Store/Contents/Desktop Folder/Trash/Benutzer/"
-int caseenumerate(const struct vol *vol, struct path *path, struct dir *dir)
-{
- DIR *dp;
- struct dirent *de;
- int ret;
- static uint32_t did = 0;
- static char cname[MAXPATHLEN];
- static char lname[MAXPATHLEN];
- ucs2_t u2_path[MAXPATHLEN];
- ucs2_t u2_dename[MAXPATHLEN];
- char *tmp, *savepath;
-
- if (!(vol->v_flags & AFPVOL_CASEINSEN))
- return -1;
-
- if (veto_file(ENUMVETO, path->u_name))
- return -1;
-
- savepath = path->u_name;
-
- /* very simple cache */
- if ( dir->d_did == did && strcmp(lname, path->u_name) == 0) {
- path->u_name = cname;
- path->d_dir = NULL;
- if (of_stat( path ) == 0 ) {
- return 0;
- }
- /* something changed, we cannot stat ... */
- did = 0;
- }
-
- if (NULL == ( dp = opendir( "." )) ) {
- LOG(log_debug, logtype_afpd, "caseenumerate: opendir failed: %s", dir->d_u_name);
- return -1;
- }
-
-
- /* LOG(log_debug, logtype_afpd, "caseenumerate: for %s", path->u_name); */
- if ((size_t) -1 == convert_string(vol->v_volcharset, CH_UCS2, path->u_name, -1, u2_path, sizeof(u2_path)) )
- LOG(log_debug, logtype_afpd, "caseenumerate: conversion failed for %s", path->u_name);
-
- /*LOG(log_debug, logtype_afpd, "caseenumerate: dir: %s, path: %s", dir->d_u_name, path->u_name); */
- ret = -1;
- for ( de = readdir( dp ); de != NULL; de = readdir( dp )) {
- if (NULL == check_dirent(vol, de->d_name))
- continue;
-
- if ((size_t) -1 == convert_string(vol->v_volcharset, CH_UCS2, de->d_name, -1, u2_dename, sizeof(u2_dename)) )
- continue;
-
- if (strcasecmp_w( u2_path, u2_dename) == 0) {
- tmp = path->u_name;
- strlcpy(cname, de->d_name, sizeof(cname));
- path->u_name = cname;
- path->d_dir = NULL;
- if (of_stat( path ) == 0 ) {
- LOG(log_debug, logtype_afpd, "caseenumerate: using dir: %s, path: %s", de->d_name, path->u_name);
- strlcpy(lname, tmp, sizeof(lname));
- did = dir->d_did;
- ret = 0;
- break;
- }
- else
- path->u_name = tmp;
- }
-
- }
- closedir(dp);
-
- if (ret) {
- /* invalidate cache */
- cname[0] = 0;
- did = 0;
- path->u_name = savepath;
- }
- /* LOG(log_debug, logtype_afpd, "caseenumerate: path on ret: %s", path->u_name); */
- return ret;
-}
-
-
/*!
* @brief Construct struct dir
*
return NULL;
}
- if (convert_string_allocate( (utf8_encoding()) ? CH_UTF8_MAC : vol->v_maccharset,
+ if (convert_string_allocate( (utf8_encoding(vol->v_obj)) ? CH_UTF8_MAC : vol->v_maccharset,
CH_UCS2,
m_name,
-1, (char **)&dir->d_m_name_ucs2) == (size_t)-1 ) {
cnid_t id;
struct adouble ad;
struct adouble *adp = NULL;
- bstring fullpath;
+ bstring fullpath = NULL;
AFP_ASSERT(vol);
AFP_ASSERT(dir);
/* Get macname from unixname */
if (path->m_name == NULL) {
- if ((path->m_name = utompath(vol, path->u_name, id, utf8_encoding())) == NULL) {
+ if ((path->m_name = utompath(vol, path->u_name, id, utf8_encoding(vol->v_obj))) == NULL) {
LOG(log_error, logtype_afpd, "dir_add(\"%s\"): can't assign macname", path->u_name);
err = 2;
goto exit;
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);
}
data++;
len = (unsigned char) *data++;
size = 2;
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
ret.m_type = 3;
toUTF8 = 1;
}
break;
case 3:
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
data++;
memcpy(&hint, data, sizeof(hint));
hint = ntohl(hint);
* 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
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) {
* If we aren't the file's owner we can't change its perms when moving it and smb
* nfs,... don't even try.
*/
-#define AFP_CHECK_ACCESS
-
-int check_access(char *path, int mode)
+int check_access(const AFPObj *obj, struct vol *vol, char *path, int mode)
{
-#ifdef AFP_CHECK_ACCESS
struct maccess ma;
char *p;
if (!p)
return -1;
- accessmode(current_vol, p, &ma, curdir, NULL);
+ accessmode(obj, vol, p, &ma, curdir, NULL);
if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
return -1;
if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
return -1;
-#endif
+
return 0;
}
/* --------------------- */
-int file_access(struct path *path, int mode)
+int file_access(const AFPObj *obj, struct vol *vol, struct path *path, int mode)
{
struct maccess ma;
- accessmode(current_vol, path->u_name, &ma, curdir, &path->st);
+ accessmode(obj, vol, path->u_name, &ma, curdir, &path->st);
LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x",
path->u_name, ma.ma_user);
(name, dir) with curdir:name == dir, from afp_enumerate
*/
-int getdirparams(const struct vol *vol,
+int getdirparams(const AFPObj *obj,
+ const struct vol *vol,
uint16_t bitmap, struct path *s_path,
struct dir *dir,
char *buf, size_t *buflen )
if ((s_path->m_name = utompath(vol,
upath,
dir->d_did,
- utf8_encoding())) == NULL) {
+ utf8_encoding(obj))) == NULL) {
LOG(log_error, logtype_afpd,
"getdirparams(\"%s\"): can't assign macname",
cfrombstr(dir->d_fullpath));
break;
case DIRPBIT_ACCESS :
- accessmode(vol, upath, &ma, dir , st);
+ accessmode(obj, vol, upath, &ma, dir , st);
*data++ = ma.ma_user;
*data++ = ma.ma_world;
Just pass back the same basic block for all
directories. <shirsch@ibm.net> */
case DIRPBIT_PDINFO :
- if (afp_version >= 30) { /* UTF8 name */
+ if (obj->afp_version >= 30) { /* UTF8 name */
utf8 = kTextEncodingUTF8;
if (dir->d_m_name) /* root of parent can have a null name */
utf_nameoff = data;
case DIRPBIT_UNIXPR :
/* accessmode may change st_mode with ACLs */
- accessmode(vol, upath, &ma, dir, st);
+ accessmode(obj, vol, upath, &ma, dir, st);
aint = htonl(st->st_uid);
memcpy( data, &aint, sizeof( aint ));
ProDOS information block. Skip over the data and
report nothing amiss. <shirsch@ibm.net> */
case DIRPBIT_PDINFO :
- if (afp_version < 30) {
+ if (vol->v_obj->afp_version < 30) {
buf += 6;
}
else {
case DIRPBIT_FINFO :
if (isad) {
/* Fixes #2802236 */
- uint16_t *fflags = (uint16_t *)(finder_buf + FINDERINFO_FRFLAGOFF);
- *fflags &= htons(~FINDERINFO_ISHARED);
+ uint16_t fflags;
+ memcpy(&fflags, finder_buf + FINDERINFO_FRFLAGOFF, sizeof(uint16_t));
+ fflags &= htons(~FINDERINFO_ISHARED);
+ memcpy(finder_buf + FINDERINFO_FRFLAGOFF, &fflags, sizeof(uint16_t));
/* #2802236 end */
+
if ( dir->d_did == DIRDID_ROOT ) {
/*
* Alright, we admit it, this is *really* sick!
break;
case DIRPBIT_UID : /* What kind of loser mounts as root? */
if ( (dir->d_did == DIRDID_ROOT) &&
- (setdeskowner( ntohl(owner), -1 ) < 0)) {
+ (setdeskowner(vol, ntohl(owner), -1 ) < 0)) {
err = set_dir_errors(path, "setdeskowner", errno);
if (isad && err == AFPERR_PARAM) {
err = AFP_OK; /* ???*/
break;
case DIRPBIT_GID :
if (dir->d_did == DIRDID_ROOT)
- setdeskowner( -1, ntohl(group) );
+ setdeskowner(vol, -1, ntohl(group) );
if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
err = set_dir_errors(path, "setdirowner", errno);
goto setdirparam_done;
case DIRPBIT_ACCESS :
break;
case DIRPBIT_PDINFO :
- if (afp_version >= 30) {
+ if (vol->v_obj->afp_version >= 30) {
err = AFPERR_BITMAP;
goto setdirparam_done;
}
if (err == AFP_OK) {
if (set_maccess == true) {
if (dir->d_did == DIRDID_ROOT) {
- setdeskmode(mpriv);
+ setdeskmode(vol, mpriv);
if (!dir_rx_set(mpriv)) {
/* we can't remove read and search for owner on volume root */
err = AFPERR_ACCESS;
goto setprivdone;
}
}
- if (setdirmode(vol, upath, mpriv) < 0)
+ if (setdirunixmode(vol, upath, mpriv) < 0) {
+ LOG(log_info, logtype_afpd, "setdirparams(\"%s\"): setdirunixmode: %s",
+ fullpathname(upath), strerror(errno));
err = set_dir_errors(path, "setdirmode", errno);
+ }
}
if ((set_upriv == true) && vol_unix_priv(vol)) {
if (dir->d_did == DIRDID_ROOT) {
err = AFPERR_ACCESS;
goto setprivdone;
}
- setdeskowner(-1, ntohl(group));
- setdeskmode(upriv);
+ setdeskowner(vol, -1, ntohl(group));
+ setdeskmode(vol, upriv);
}
if (setdirowner(vol, upath, -1, ntohl(group)) < 0) {
+ LOG(log_info, logtype_afpd, "setdirparams(\"%s\"): setdirowner: %s",
+ fullpathname(upath), strerror(errno));
err = set_dir_errors(path, "setdirowner", errno);
goto setprivdone;
}
-
- if (setdirunixmode(vol, upath, upriv) < 0)
+ if (setdirunixmode(vol, upath, upriv) < 0) {
+ LOG(log_info, logtype_afpd, "setdirparams(\"%s\"): setdirunixmode: %s",
+ fullpathname(upath), strerror(errno));
err = set_dir_errors(path, "setdirunixmode", errno);
+ }
}
}
return err;
}
- if (of_stat(s_path) < 0) {
+ if (of_stat(vol, s_path) < 0) {
return AFPERR_MISC;
}
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);
-createdir_done:
memcpy( rbuf, &dir->d_did, sizeof( uint32_t ));
*rbuflen = sizeof( uint32_t );
setvoltime(obj, vol );
* 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,
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) {
- deletedir(-1, dst);
+ if ((err = copydir(vol, newparent, dirfd, src, dst)) < 0) {
+ deletedir(vol, -1, dst);
return err;
}
- if ((err = deletedir(dirfd, src)) < 0)
+ if ((err = deletedir(vol, dirfd, src)) < 0)
return err;
break;
default :
err = vol->vfs->vfs_deletecurdir(vol);
if (err) {
LOG(log_error, logtype_afpd, "deletecurdir: error deleting .AppleDouble in \"%s\"",
- curdir->d_fullpath);
+ cfrombstr(curdir->d_fullpath));
return err;
}
/* 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;
}
*rbuflen = 0;
if (sfunc >= 3 && sfunc <= 6) {
- if (afp_version < 30) {
+ if (obj->afp_version < 30) {
return( AFPERR_PARAM );
}
utf8 = 1;
case 5 : /* UUID -> username */
case 6 : /* UUID -> groupname */
- if ((afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
+ if ((obj->afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
return AFPERR_PARAM;
LOG(log_debug, logtype_afpd, "afp_mapid: valid UUID request");
uuidtype_t type;
return( AFP_OK );
}
-int afp_mapname(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
+int afp_mapname(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct passwd *pw;
struct group *gr;
ibuf++;
sfunc = (unsigned char) *ibuf++;
*rbuflen = 0;
- LOG(log_debug, logtype_afpd, "afp_mapname: sfunc: %d, afp_version: %d", sfunc, afp_version);
+ LOG(log_debug, logtype_afpd, "afp_mapname: sfunc: %d", sfunc);
switch ( sfunc ) {
case 1 :
case 2 : /* unicode */
- if (afp_version < 30) {
+ if (obj->afp_version < 30) {
return( AFPERR_PARAM );
}
memcpy(&ulen, ibuf, sizeof(ulen));
break;
case 5 : /* username -> UUID */
case 6 : /* groupname -> UUID */
- if ((afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
+ if ((obj->afp_version < 32) || !(obj->options.flags & OPTION_UUID ))
return AFPERR_PARAM;
memcpy(&ulen, ibuf, sizeof(ulen));
len = ntohs(ulen);
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 ) {