SUBDIRS = nls
-sbin_PROGRAMS = afpd
+sbin_PROGRAMS = afpd cnid_dump
afpd_SOURCES = unix.c ofork.c main.c switch.c auth.c volume.c directory.c \
file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
afpd_LDADD = $(top_builddir)/libatalk/libatalk.la
afpd_LDFLAGS = -export-dynamic
+cnid_dump_LDADD = $(top_builddir)/libatalk/libatalk.la
+
noinst_HEADERS = auth.h codepage.h afp_config.h desktop.h directory.h file.h \
filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
uam_auth.h uid.h unix.h volume.h
/*
- * $Id: afs.c,v 1.14 2003-01-08 15:01:32 didg Exp $
+ * $Id: afs.c,v 1.15 2003-01-24 07:08:42 didg Exp $
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
}
if ( *path->m_name != '\0' ) {
*rbuflen = 0;
- return( AFPERR_BITMAP );
+ return (path_isadir( path))? afp_errno: AFPERR_BITMAP;
}
vi.in_size = 0;
}
if ( *path->m_name != '\0' ) {
*rbuflen = 0;
- return afp_errno;
+ return (path_isadir( path))? afp_errno: AFPERR_BITMAP;
}
if ((int)ibuf & 1 ) {
/*
- * $Id: appl.c,v 1.10 2003-01-12 14:39:58 didg Exp $
+ * $Id: appl.c,v 1.11 2003-01-24 07:08:42 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
return afp_errno;
}
- if ( *path->m_name == '\0' ) {
+ if ( path_isadir(path) ) {
return( AFPERR_BADTYPE );
}
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
return afp_errno;
}
- if ( *path->m_name == '\0' ) {
+ if ( path_isadir(path) ) {
return( AFPERR_BADTYPE );
}
return( AFPERR_NOITEM );
}
- if ( *path->m_name == '\0' || path->st_errno ) {
+ if ( path_isadir(path) || path->st_errno ) {
*rbuflen = 0;
return( AFPERR_NOITEM );
}
/*
- * $Id: desktop.c,v 1.21 2003-01-12 14:39:58 didg Exp $
+ * $Id: desktop.c,v 1.22 2003-01-24 07:08:42 didg Exp $
*
* See COPYRIGHT.
*
int clen;
u_int32_t did;
u_int16_t vid;
+ int isadir;
*rbuflen = 0;
ibuf += 2;
return AFPERR_ACCESS;
}
- if (*path->m_name == '\0' || !(of = of_findname(path))) {
+ isadir = path_isadir(path);
+ if (isadir || !(of = of_findname(path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
adp = of->of_ad;
if (ad_open( upath , vol_noadouble(vol) |
- (( *path->m_name == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+ (( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
O_RDWR|O_CREAT, 0666, adp) < 0 ) {
return( AFPERR_ACCESS );
}
struct dir *dir;
struct ofork *of;
struct path *s_path;
- char *path, *upath;
+ char *upath;
u_int32_t did;
u_int16_t vid;
-
+ int isadir;
+
*rbuflen = 0;
ibuf += 2;
}
upath = s_path->u_name;
- path = s_path->m_name;
-
- if (*path == '\0' || !(of = of_findname(s_path))) {
+ isadir = path_isadir(s_path);
+ if (isadir || !(of = of_findname(s_path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
adp = of->of_ad;
if ( ad_open( upath,
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+ ( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
O_RDONLY, 0666, adp) < 0 ) {
return( AFPERR_NOITEM );
}
struct dir *dir;
struct ofork *of;
struct path *s_path;
- char *path, *upath;
+ char *upath;
u_int32_t did;
u_int16_t vid;
+ int isadir;
*rbuflen = 0;
ibuf += 2;
}
upath = s_path->u_name;
- path = s_path->m_name;
if (check_access(upath, OPENACC_WR ) < 0) {
return AFPERR_ACCESS;
}
- if (path == '\0' || !(of = of_findname(s_path))) {
+ isadir = path_isadir(s_path);
+ if (isadir || !(of = of_findname(s_path))) {
memset(&ad, 0, sizeof(ad));
adp = &ad;
} else
adp = of->of_ad;
if ( ad_open( upath,
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
+ (isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
O_RDWR, 0, adp) < 0 ) {
switch ( errno ) {
case ENOENT :
/*
- * $Id: directory.c,v 1.57 2003-01-21 09:58:58 didg Exp $
+ * $Id: directory.c,v 1.58 2003-01-24 07:08:42 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return NULL;
}
+/* ------------------- */
+#ifdef ATACC
+int path_isadir(struct path *o_path)
+{
+ return o_path->m_name == '\0' || /* we are in a it */
+ !o_path->st_valid || /* in cache but we can't chdir in it */
+ (!o_path->st_errno && S_ISDIR(o_path->st.st_mode)); /* not in cache an can't chdir */
+}
+#endif
+
+/* ------------------- */
+struct dir *
+ dirsearch_byname( cdir, name )
+ struct dir *cdir;
+ const char *name;
+{
+struct dir *dir;
+
+ if (!strcmp(name, "."))
+ return cdir;
+ dir = cdir->d_child;
+ while (dir) {
+ if ( strcmp( dir->d_u_name, name ) == 0 ) {
+ break;
+ }
+ dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
+ }
+ return dir;
+}
+
/* -----------------------------------------
* if did is not in the cache resolve it with cnid
*
char *mpath;
ret = dirsearch(vol, did);
- if (ret != NULL)
+ if (ret != NULL || afp_errno == AFPERR_PARAM)
return ret;
id = did;
{
if (curdir == dir) {
/* v_root can't be deleted */
- if (movecwd(vol, vol->v_root) < 0)
- printf("Yuup cant change dir to v_root\n");
+ if (movecwd(vol, vol->v_root) < 0) {
+ LOG(log_error, logtype_afpd, "cname can't chdir to : %s", vol->v_root);
+ }
}
/* FIXME */
dirchildremove(dir->d_parent, dir);
}
/* -------------------------------------------------- */
-/* XXX: this needs to be changed to handle path types
+/* cname
return
if it's a filename:
in extenddir:
compute unix name
- stat the file
- return mac name
+ stat the file or errno
+ return
+ filename
+ curdir: filename parent directory
+
if it's a dirname:
not in the cache
in extenddir
compute unix name
- stat the dir
+ stat the dir or errno
+ return
+ if chdir error
+ dirname
+ curdir: dir parent directory
+ sinon
+ dirname: ""
+ curdir: dir
in the cache
-
- u_name can be
- XXXX u_name can be an alias on m_name if the m_name is
- a valid unix name.
-
+ return
+ if chdir error
+ dirname
+ curdir: dir parent directory
+ else
+ dirname: ""
+ curdir: dir
+
*/
struct path *
cname( vol, dir, cpath )
ret.st_valid = 0;
for ( ;; ) {
if ( len == 0 ) {
- if ( !extend && movecwd( vol, dir ) < 0 ) {
+ if (movecwd( vol, dir ) < 0 ) {
/* it's tricky:
movecwd failed some of dir path are not there anymore.
FIXME Is it true with other errors?
so we remove dir from the cache
*/
- if (dir->d_did == DIRDID_ROOT_PARENT)
- return NULL;
- if (afp_errno == AFPERR_ACCESS)
- return NULL;
+ if (dir->d_did == DIRDID_ROOT_PARENT)
+ return NULL;
+ if (afp_errno == AFPERR_ACCESS) {
+ if ( movecwd( vol, dir->d_parent ) < 0 ) {
+ return NULL;
+ }
+ ret.m_name = dir->d_m_name;
+ ret.u_name = dir->d_u_name;
+ return &ret;
+ }
dir_invalidate(vol, dir);
return NULL;
/* dir is not valid anymore
we delete dir from the cache and abort.
*/
- if ( dir->d_did != DIRDID_ROOT_PARENT &&
- (afp_errno != AFPERR_ACCESS)) {
- dir_invalidate(vol, dir);
- }
+ if ( dir->d_did == DIRDID_ROOT_PARENT)
+ return NULL;
+ if (afp_errno == AFPERR_ACCESS)
+ return NULL;
+ dir_invalidate(vol, dir);
return NULL;
}
cdir = extenddir( vol, dir, &ret );
return afp_errno;
}
+ /* FIXME access error or not a file */
if ( *path->m_name != '\0' ) {
- return( AFPERR_BADTYPE ); /* not a directory */
+ return (path_isadir( path))? afp_errno:AFPERR_BADTYPE ;
}
/*
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
if (NULL == ( dir = dirlookup( vol, did )) ) {
- return( AFPERR_NOOBJ );
+ return afp_errno; /* was AFPERR_NOOBJ */
}
if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
return afp_errno;
}
- /* FIXME check done elswhere? cname was able to move curdir to it! */
+ /* cname was able to move curdir to it! */
if (*s_path->m_name == '\0')
return AFPERR_EXIST;
}
if ( *path->m_name != '\0' ) {
- return( AFPERR_BADTYPE ); /* not a directory */
+ return (path_isadir(path))? afp_errno:AFPERR_BADTYPE ;
}
if ( !path->st_valid && of_stat(path ) < 0 ) {
/*
- * $Id: directory.h,v 1.8 2003-01-08 15:01:34 didg Exp $
+ * $Id: directory.h,v 1.9 2003-01-24 07:08:42 didg Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
struct stat st;
};
+#ifndef ATACC
+static __inline__ int path_isadir(struct path *o_path)
+{
+ return o_path->m_name == '\0' || /* we are in a it */
+ !o_path->st_valid || /* in cache but we can't chdir in it */
+ (!o_path->st_errno && S_ISDIR(o_path->st.st_mode)); /* not in cache an can't chdir */
+}
+#else
+extern int path_isadir(struct path *o_path);
+#endif
+
/* child addition/removal macros */
#define dirchildadd(a, b) do { \
if (!(a)->d_child) \
extern void dirfree __P((struct dir *));
extern struct dir *dirsearch __P((const struct vol *, u_int32_t));
extern struct dir *dirlookup __P((const struct vol *, u_int32_t));
+extern struct dir *dirsearch_byname __P((struct dir *,const char *));
extern struct dir *adddir __P((struct vol *, struct dir *,
struct path *));
/*
- * $Id: enumerate.c,v 1.32 2003-01-21 07:55:07 didg Exp $
+ * $Id: enumerate.c,v 1.33 2003-01-24 07:08:42 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
- someone else have moved the directory.
- it's a symlink inside the share.
- it's an ID reused, the old directory was deleted but not
- the cnid record and the server reused the inode for
+ the cnid record and the server've reused the inode for
the new dir.
for HASH (we should get ride of HASH)
- someone else have moved the directory.
if (NULL == ( dir = dirlookup( vol, did )) ) {
*rbuflen = 0;
- return( AFPERR_NODIR );
+ return (afp_errno == AFPERR_NOOBJ)?AFPERR_NODIR:afp_errno;
}
memcpy( &fbitmap, ibuf, sizeof( fbitmap ));
header *=sizeof( u_char );
maxsz = min(maxsz, *rbuflen);
+ o_path = cname( vol, dir, &ibuf );
- if (NULL == ( o_path = cname( vol, dir, &ibuf )) ) {
- *rbuflen = 0;
- return( AFPERR_NODIR );
- }
+ if (afp_errno == AFPERR_NOOBJ)
+ afp_errno = AFPERR_NODIR;
+ *rbuflen = 0;
+ if (NULL == o_path ) {
+ return afp_errno;
+ }
if ( *o_path->m_name != '\0') {
- *rbuflen = 0;
- return( AFPERR_BADTYPE );
+ /* it's a file or it's a dir and extendir() was unable to chdir in it */
+ return (path_isadir(o_path))? afp_errno:AFPERR_BADTYPE ;
}
data = rbuf + 3 * sizeof( u_int16_t );
*/
if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) {
sd.sd_last = sd.sd_buf;
- if ( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) {
+ /* if dir was in the cache we don't have the inode */
+ if (( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) ||
+ (ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0)
+ {
switch (errno) {
case EACCES:
return AFPERR_ACCESS;
}
}
curdir->ctime = o_path->st.st_ctime; /* play safe */
- if ((ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) {
- *rbuflen = 0;
- switch (errno) {
- case EACCES:
- return AFPERR_ACCESS;
- case ENOTDIR:
- return AFPERR_BADTYPE;
- case ENOMEM:
- return AFPERR_MISC;
- default:
- return AFPERR_NODIR;
- }
- }
curdir->offcnt = ret;
*sd.sd_last = 0;
len = *(sd.sd_last)++;
if ( len == 0 ) {
sd.sd_did = 0; /* invalidate sd struct to force re-read */
- *rbuflen = 0;
return( AFPERR_NOOBJ );
}
sd.sd_last += len + 1;
sd.sd_last += len + 1;
continue;
}
- dir = curdir->d_child;
- s_path.m_name = NULL;
- while (dir) {
- if ( strcmp( dir->d_u_name, s_path.u_name ) == 0 ) {
- break;
- }
- dir = (dir == curdir->d_child->d_prev) ? NULL : dir->d_next;
- }
+ dir = dirsearch_byname(curdir, s_path.u_name);
if (!dir) {
s_path.m_name = utompath(vol, s_path.u_name);
if ((dir = adddir( vol, curdir, &s_path)) == NULL) {
- *rbuflen = 0;
return AFPERR_MISC;
}
}
-
+ else {
+ s_path.m_name = NULL;
+ }
if (( ret = getdirparams(vol, dbitmap, &s_path, dir,
data + header , &esz )) != AFP_OK ) {
- *rbuflen = 0;
return( ret );
}
s_path.m_name = utompath(vol, s_path.u_name);
if (( ret = getfilparams(vol, fbitmap, &s_path, curdir,
data + header , &esz )) != AFP_OK ) {
- *rbuflen = 0;
return( ret );
}
}
*/
if ( maxsz < sz + esz + header) {
if (first) { /* maxsz can't hold a single reply */
- *rbuflen = 0;
return AFPERR_PARAM;
}
sd.sd_last = start;
}
if ( actcnt == 0 ) {
- *rbuflen = 0;
sd.sd_did = 0; /* invalidate sd struct to force re-read */
return( AFPERR_NOOBJ );
}
/*
- * $Id: file.c,v 1.76 2003-01-21 10:09:13 didg Exp $
+ * $Id: file.c,v 1.77 2003-01-24 07:08:42 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
memcpy(&did, ibuf, sizeof( did ));
ibuf += sizeof( did );
if (NULL == ( dir = dirlookup( vol, did )) ) {
- return( AFPERR_NOOBJ );
+ return afp_errno; /* was AFPERR_NOOBJ */
}
memcpy(&bitmap, ibuf, sizeof( bitmap ));
return afp_errno;
}
- if ( *s_path->m_name == '\0' ) {
+ if (path_isadir(s_path)) {
return( AFPERR_BADTYPE ); /* it's a directory */
}
if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
return afp_errno;
}
- if ( *s_path->m_name == '\0' ) {
+ if ( path_isadir(s_path) ) {
return( AFPERR_BADTYPE );
}
return AFPERR_DENYCONF;
p = ctoupath( vol, curdir, newname );
+ if (!p) {
+ return AFPERR_PARAM;
+
+ }
#ifdef FORCE_UIDGID
/* FIXME svid != dvid && dvid's user can't read svid */
#endif
return afp_errno;
}
if ( *s_path->m_name != '\0' ) {
- return( AFPERR_BADTYPE ); /* not a directory. AFPERR_PARAM? */
+ return (path_isadir( s_path))? AFPERR_PARAM:AFPERR_BADTYPE ;
}
/* one of the handful of places that knows about the path type */
}
if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_PARAM );
+ return afp_errno; /* was AFPERR_PARAM */
}
- if ( *s_path->m_name == '\0' ) {
+ if ( path_isadir(s_path) ) {
return( AFPERR_BADTYPE );
}
}
if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
- return( AFPERR_PARAM );
+ return afp_errno; /* was AFPERR_PARAM */
}
- if ( *path->m_name == '\0' ) {
+ if ( path_isadir(path) ) {
return( AFPERR_BADTYPE ); /* it's a dir */
}
strcpy(spath, path->m_name);
strcpy(supath, upath); /* this is for the cnid changing */
p = absupath( vol, sdir, upath);
+ if (!p) {
+ /* pathname too long */
+ return AFPERR_PARAM ;
+ }
/* look for the source cnid. if it doesn't exist, don't worry about
* it. */
return( AFPERR_PARAM );
}
- if ( *path->m_name == '\0' ) {
+ if ( path_isadir(path) ) {
return( AFPERR_BADTYPE );
}
/*
- * $Id: filedir.c,v 1.39 2003-01-21 09:58:58 didg Exp $
+ * $Id: filedir.c,v 1.40 2003-01-24 07:08:43 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
buflen = 0;
if (S_ISDIR(st->st_mode)) {
if (dbitmap) {
- if (*s_path->m_name != '\0') {
- /* the dir wasn't in the cache and we weren't able to chdir in it.
- */
- return AFPERR_ACCESS;
- }
- ret = getdirparams(vol, dbitmap, s_path, curdir,
+ dir = dirsearch_byname(curdir, s_path->u_name);
+ if (!dir)
+ return AFPERR_NOOBJ;
+
+ ret = getdirparams(vol, dbitmap, s_path, dir,
rbuf + 3 * sizeof( u_int16_t ), &buflen );
if (ret != AFP_OK )
return( ret );
id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
#endif /* CNID_DB */
p = ctoupath( vol, sdir, oldname );
+ if (!p) {
+ return AFPERR_PARAM; /* pathname too long */
+ }
path.st_valid = 0;
path.u_name = p;
if ((opened = of_findname(&path))) {
id = sdir->d_did; /* we already have the CNID */
#endif /* CNID_DB */
p = ctoupath( vol, sdir->d_parent, oldname );
+ if (!p) {
+ return AFPERR_PARAM;
+ }
adflags = ADFLAGS_DIR;
}
/*
sdir = curdir;
newname = obj->newtmp;
oldname = obj->oldtmp;
+ isdir = path_isadir(path);
if ( *path->m_name != '\0' ) {
strcpy(oldname, path->m_name); /* an extra copy for of_rename */
+ if (isdir) {
+ /* curdir parent dir, need to move sdir back
+ * FIXME search by unix name or mac name?
+ */
+ sdir = dirsearch_byname(curdir, path->u_name);
+ if (!sdir)
+ return AFPERR_NOOBJ;
+ }
}
else {
if ( sdir->d_parent == NULL ) { /* root directory */
if ( movecwd( vol, sdir->d_parent ) < 0 ) {
return afp_errno;
}
- isdir = 1;
strcpy(oldname, sdir->d_m_name);
}
}
upath = s_path->u_name;
- if ( *s_path->m_name == '\0' ) {
- rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
+ if ( path_isadir( s_path) ) {
+ if (*s_path->m_name != '\0') {
+ rc = AFPERR_ACCESS;
+ }
+ else {
+ rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
+ }
} else if (of_findname(s_path)) {
rc = AFPERR_BUSY;
} else if (AFP_OK == (rc = deletefile( upath, 1))) {
len = strlen( u );
p -= len;
strncpy( p, u, len );
- for ( d = dir; d->d_parent; d = d->d_parent ) {
- *--p = '/';
+ if (dir) for ( d = dir; d->d_parent; d = d->d_parent ) {
u = d->d_u_name;
len = strlen( u );
+ if (p -len -1 < path) {
+ /* FIXME
+ rather rare so LOG error and/or client message ?
+ */
+ return NULL;
+ }
+ *--p = '/';
p -= len;
strncpy( p, u, len );
}
- *--p = '/';
len = strlen( vol->v_path );
+ if (p -len -1 < path) {
+ return NULL;
+ }
+ *--p = '/';
p -= len;
strncpy( p, vol->v_path, len );
{
struct vol *vol;
struct dir *sdir, *ddir;
- int isdir = 0;
+ int isdir;
char *oldname, *newname;
struct path *path;
int did;
/* source pathname */
if (NULL == ( path = cname( vol, sdir, &ibuf )) ) {
- return( AFPERR_NOOBJ );
+ return afp_errno;
}
sdir = curdir;
newname = obj->newtmp;
oldname = obj->oldtmp;
+
+ isdir = path_isadir(path);
if ( *path->m_name != '\0' ) {
- /* not a directory */
+ if (isdir) {
+ sdir = dirsearch_byname(curdir, path->u_name);
+ if (!sdir)
+ return AFPERR_NOOBJ;
+ }
strcpy(oldname, path->m_name); /* an extra copy for of_rename */
} else {
- isdir = 1;
strcpy(oldname, sdir->d_m_name);
}
return( AFPERR_NOOBJ );
}
if ( *path->m_name != '\0' ) {
- return( AFPERR_BADTYPE );
+ return (path_isadir(path))?afp_errno:AFPERR_BADTYPE;
}
/* one more place where we know about path type */