/*
- * $Id: directory.c,v 1.83 2006-09-19 23:00:49 didg Exp $
+ * $Id: directory.c,v 1.90 2009-01-30 04:57:42 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define SENTINEL (&sentinel)
static struct dir sentinel = { SENTINEL, SENTINEL, NULL, DIRTREE_COLOR_BLACK,
NULL, NULL, NULL, NULL, NULL, 0, 0,
- 0, 0, NULL, NULL, NULL};
+ 0, 0, NULL, NULL};
static struct dir rootpar = { SENTINEL, SENTINEL, NULL, 0,
NULL, NULL, NULL, NULL, NULL, 0, 0,
- 0, 0, NULL, NULL, NULL};
+ 0, 0, NULL, NULL};
/* (from IM: Toolbox Essentials)
* dirFinderInfo (DInfo) fields:
/* remove the node from the tree. this is just like insertion, but
* different. actually, it has to worry about a bunch of things that
* insertion doesn't care about. */
-static void dir_remove( vol, dir )
-struct vol *vol;
-struct dir *dir;
+static void dir_remove( const struct vol *vol _U_, struct dir *dir)
{
#ifdef REMOVE_NODES
struct ofork *of, *last;
dirfreename(dir);
dir->d_m_name = NULL;
dir->d_u_name = NULL;
- dir->d_m_name_ucs2 = NULL;
#else /* ! REMOVE_NODES */
/* go searching for a node with at most one child */
/* set the node's d_name */
node->d_m_name = save.d_m_name;
node->d_u_name = save.d_u_name;
- node->d_m_name_ucs2 = save.d_m_name_ucs2;
}
if (node->d_color == DIRTREE_COLOR_BLACK)
dir_rmrecolor(vol, leaf);
- if (node->d_m_name_ucs2)
- free(node->d_u_name_ucs2);
if (node->d_u_name != node->d_m_name) {
free(node->d_u_name);
}
return pdir;
}
-#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 u_int32_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 (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, strlen(path->u_name), 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, strlen(de->d_name), 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 */
- memset(cname, 0, sizeof(cname));
- did = 0;
- path->u_name = savepath;
- }
- /* LOG(log_debug, logtype_afpd, "caseenumerate: path on ret: %s", path->u_name); */
- return ret;
-}
-
-
/*
* attempt to extend the current dir. tree to include path
* as a side-effect, movecwd to that point and return the new dir
return NULL;
}
if (of_stat( path ) != 0 ) {
- if (!(vol->v_flags & AFPVOL_CASEINSEN))
- return NULL;
- else if(caseenumerate(vol, path, dir) != 0)
- return(NULL);
+ return NULL;
}
if (!S_ISDIR(path->st.st_mode)) {
LOG(log_error, logtype_afpd, "adddir: malloc: %s", strerror(errno) );
return NULL;
}
- if ((size_t)-1 == convert_string_allocate((utf8_encoding())?CH_UTF8_MAC:vol->v_maccharset, CH_UCS2, path->m_name, strlen(path->m_name), &cdir->d_m_name_ucs2)) {
- LOG(log_error, logtype_afpd, "Couldn't set UCS2 name for %s", name);
- cdir->d_m_name_ucs2 = NULL;
- }
cdir->d_did = id;
dirfreename(edir);
edir->d_m_name = cdir->d_m_name;
edir->d_u_name = cdir->d_u_name;
- edir->d_m_name_ucs2 = cdir->d_m_name_ucs2;
free(cdir);
cdir = edir;
LOG(log_error, logtype_afpd, "adddir: insert %s", edir->d_m_name);
if (dir->d_u_name != dir->d_m_name) {
free(dir->d_u_name);
}
- if (dir->d_m_name_ucs2)
- free(dir->d_m_name_ucs2);
free(dir->d_m_name);
}
return NULL;
}
- dir->d_m_name_ucs2 = NULL;
dir->d_left = dir->d_right = SENTINEL;
dir->d_next = dir->d_prev = dir;
return dir;
0x69232f74U, 0xfead7bb3U, 0xe9089ab6U, 0xf012f6aeU,
};
- const unsigned char *str = k->d_u_name;
+ const unsigned char *str = (unsigned char *)k->d_u_name;
hash_val_t acc = 0;
while (*str) {
struct dir *dir;
char **cpath;
{
- struct dir *cdir, *scdir=NULL;
+ struct dir *cdir;
static char path[ MAXPATHLEN + 1];
static struct path ret;
}
}
if ( !extend ) {
- ucs2_t *tmpname;
- cdir = dir->d_child;
- scdir = NULL;
- if ( cdir && (vol->v_flags & AFPVOL_CASEINSEN) &&
- (size_t)-1 != convert_string_allocate(((ret.m_type == 3)?CH_UTF8_MAC:vol->v_maccharset),
- CH_UCS2, path, strlen(path), (char **)&tmpname) )
- {
- while (cdir) {
- if (!cdir->d_m_name_ucs2) {
- LOG(log_error, logtype_afpd, "cname: no UCS2 name for %s (did %u)!!!", cdir->d_m_name, ntohl(cdir->d_did) );
- /* this shouldn't happen !!!! */
- goto noucsfallback;
- }
-
- if ( strcmp_w( cdir->d_m_name_ucs2, tmpname ) == 0 ) {
- break;
- }
- if ( strcasecmp_w( cdir->d_m_name_ucs2, tmpname ) == 0 ) {
- scdir = cdir;
- }
- cdir = (cdir == dir->d_child->d_prev) ? NULL :cdir->d_next;
- }
- free(tmpname);
- }
- else {
-noucsfallback:
- if (dir->d_did == DIRDID_ROOT_PARENT) {
+ if (dir->d_did == DIRDID_ROOT_PARENT) {
/* root parent has only one child and d_m_name is *NOT* utm (d_u_name)
* d_m_name is the Mac volume name
* d_u_name is the volume unix directory name
*
*/
- cdir = NULL;
- if (!strcmp(vol->v_dir->d_m_name, ret.m_name)) {
+ cdir = NULL;
+ if (!strcmp(vol->v_dir->d_m_name, ret.m_name)) {
cdir = vol->v_dir;
- }
- }
- else {
- cdir = dirsearch_byname(vol, dir, ret.u_name);
}
}
-
- if (cdir == NULL && scdir != NULL) {
- cdir = scdir;
- /* LOG(log_debug, logtype_afpd, "cname: using casediff for %s, (%s = %s)", fullpathname(cdir->d_u_name), cdir->d_m_name, path ); */
+ else {
+ cdir = dirsearch_byname(vol, dir, ret.u_name);
}
if ( cdir == NULL ) {
char *upath;
struct dir *dir;
- int bit, aint, isad = 1;
+ int bit, isad = 1;
int cdate, bdate;
int owner, group;
u_int16_t ashort, bshort;
ma.ma_world = *buf++;
ma.ma_group = *buf++;
ma.ma_owner = *buf++;
- mpriv = mtoumode( &ma ) | vol->v_perm;
+ mpriv = mtoumode( &ma ) | vol->v_dperm;
if (dir_rx_set(mpriv) && setdirmode( vol, upath, mpriv) < 0 ) {
err = set_dir_errors(path, "setdirmode", errno);
bitmap = 0;
change_parent_mdate = 1;
memcpy( &upriv, buf, sizeof( upriv ));
buf += sizeof( upriv );
- upriv = ntohl (upriv) | vol->v_perm;
+ upriv = ntohl (upriv) | vol->v_dperm;
if (dir_rx_set(upriv)) {
/* maybe we are trying to set perms back */
if ( setdirunixmode(vol, upath, upriv) < 0 ) {
ad_setid(&ad, st->st_dev, st->st_ino, dir->d_did, dir->d_parent->d_did, vol->v_stamp);
}
}
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
}
return err;
}
+
+int afp_syncdir(obj, ibuf, ibuflen, rbuf, rbuflen )
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
+{
+ DIR *dp;
+ int dfd;
+ struct vol *vol;
+ struct dir *dir;
+ u_int32_t did;
+ u_int16_t vid;
+
+ *rbuflen = 0;
+ ibuf += 2;
+
+ memcpy( &vid, ibuf, sizeof( vid ));
+ ibuf += sizeof( vid );
+ if (NULL == (vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
+ }
+
+ memcpy( &did, ibuf, sizeof( did ));
+ ibuf += sizeof( did );
+ if (NULL == ( dir = dirlookup( vol, did )) ) {
+ return afp_errno; /* was AFPERR_NOOBJ */
+ }
+
+ if (NULL == ( dp = opendir( "." )) ) {
+ switch( errno ) {
+ case ENOENT :
+ return( AFPERR_NOOBJ );
+ case EACCES :
+ return( AFPERR_ACCESS );
+ default :
+ return( AFPERR_PARAM );
+ }
+ }
+
+ dfd = dirfd( dp );
+ if ( fsync ( dfd ) < 0 ) {
+ LOG(log_error, logtype_afpd, "syncdir(%s): ddir(%d) %s", dir->d_u_name, dfd, strerror(errno) );
+ }
+ closedir(dp);
+
+ return ( AFP_OK );
+}
+
int afp_createdir(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
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);
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
createdir_done:
if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
ad_setname(&ad, newname);
- ad_flush_metadata( &ad);
+ ad_flush( &ad);
ad_close_metadata( &ad);
}
strcpy( dir->d_u_name, dst );
}
- if (dir->d_m_name_ucs2)
- free(dir->d_m_name_ucs2);
-
- dir->d_m_name_ucs2 = NULL;
- if ((size_t)-1 == convert_string_allocate((utf8_encoding())?CH_UTF8_MAC:vol->v_maccharset, CH_UCS2, dir->d_m_name, strlen(dir->d_m_name), (char**)&dir->d_m_name_ucs2))
- dir->d_m_name_ucs2 = NULL;
-
if (( parent = dir->d_parent ) == NULL ) {
return( AFP_OK );
}