- if (of_stat( path ) != 0 ) {
- if (!(vol->v_flags & AFPVOL_CASEINSEN))
- return NULL;
- else if(caseenumerate(vol, path, dir) != 0)
- return(NULL);
- }
-
- if (!S_ISDIR(path->st.st_mode)) {
- return( NULL );
- }
-
- /* mac name is always with the right encoding (from cname()) */
- if (( dir = adddir( vol, dir, path)) == NULL ) {
- return( NULL );
- }
-
- path->d_dir = dir;
- if ( movecwd( vol, dir ) < 0 ) {
- return( NULL );
- }
-
- return( dir );
-}
-
-/* -------------------------
- appledouble mkdir afp error code.
-*/
-static int netatalk_mkdir(const char *name)
-{
- if (ad_mkdir(name, DIRBITS | 0777) < 0) {
- switch ( errno ) {
- case ENOENT :
- return( AFPERR_NOOBJ );
- case EROFS :
- return( AFPERR_VLOCK );
- case EPERM:
- case EACCES :
- return( AFPERR_ACCESS );
- case EEXIST :
- return( AFPERR_EXIST );
- case ENOSPC :
- case EDQUOT :
- return( AFPERR_DFULL );
- default :
- return( AFPERR_PARAM );
- }
- }
- return AFP_OK;
-}
-
-/* ------------------- */
-static int deletedir(int dirfd, char *dir)
-{
- char path[MAXPATHLEN + 1];
- DIR *dp;
- struct dirent *de;
- struct stat st;
- size_t len;
- int err = AFP_OK;
- size_t remain;
-
- if ((len = strlen(dir)) +2 > sizeof(path))
- return AFPERR_PARAM;
-
- /* already gone */
- if ((dp = opendirat(dirfd, dir)) == NULL)
- return AFP_OK;
-
- strcpy(path, dir);
- strcat(path, "/");
- len++;
- remain = sizeof(path) -len -1;
- while ((de = readdir(dp)) && err == AFP_OK) {
- /* skip this and previous directory */
- if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
- continue;
-
- if (strlen(de->d_name) > remain) {
- err = AFPERR_PARAM;
- break;
- }
- strcpy(path + len, de->d_name);
- if (lstatat(dirfd, path, &st)) {
- continue;
- }
- if (S_ISDIR(st.st_mode)) {
- err = deletedir(dirfd, path);
- } else {
- err = netatalk_unlinkat(dirfd, path);
- }
- }
- closedir(dp);
-
- /* okay. the directory is empty. delete it. note: we already got rid
- of .AppleDouble. */
- if (err == AFP_OK) {
- err = netatalk_rmdir(dirfd, dir);
- }
- return err;
-}
-
-/* do a recursive copy. */
-static int copydir(const struct vol *vol, int dirfd, char *src, char *dst)
-{
- char spath[MAXPATHLEN + 1], dpath[MAXPATHLEN + 1];
- DIR *dp;
- struct dirent *de;
- struct stat st;
- struct utimbuf ut;
- size_t slen, dlen;
- size_t srem, drem;
- int err;
-
- /* doesn't exist or the path is too long. */
- if (((slen = strlen(src)) > sizeof(spath) - 2) ||
- ((dlen = strlen(dst)) > sizeof(dpath) - 2) ||
- ((dp = opendirat(dirfd, src)) == NULL))
- return AFPERR_PARAM;
-
- /* try to create the destination directory */
- if (AFP_OK != (err = netatalk_mkdir(dst)) ) {
- closedir(dp);
- return err;