static int FuseHFS_rmdir(const char *path) { dprintf("rmdir %s\n", path); if (_readonly) return -EPERM; // convert to hfs path char *hfspath = mkhfspath(path); if (hfspath == NULL) return -ENOENT; // check that file exists hfsdirent ent; if (hfs_stat(NULL, hfspath, &ent) == -1) { free(hfspath); dprintf("rmdir: ENOENT\n"); return -ENOENT; } // check that it's a directory if (!(ent.flags & HFS_ISDIR)) { free(hfspath); dprintf("rmdir: ENOTDIR\n"); return -ENOTDIR; } // delete it if (hfs_rmdir(NULL, hfspath) == -1) { free(hfspath); perror("rmdir(2)"); return -errno; } free(hfspath); return 0; }
/* * nat_rmdir() * * This is the rmdir() entry in the inode_operations structure for * Netatalk directories. The purpose is to delete an existing * directory, given the inode for the parent directory and the name * (and its length) of the existing directory. * * We handle .AppleDouble and call hfs_rmdir() for all other cases. */ static int nat_rmdir(struct inode *parent, const char *name, int len) { struct hfs_cat_entry *entry = HFS_I(parent)->entry; struct hfs_name cname; int error; hfs_nameout(parent, &cname, name, len); if (hfs_streq(&cname, DOT_APPLEDOUBLE)) { if (!HFS_SB(parent->i_sb)->s_afpd) { /* Not in AFPD compatibility mode */ error = -EPERM; } else if (entry->u.dir.files || entry->u.dir.dirs) { /* AFPD compatible, but the directory is not empty */ error = -ENOTEMPTY; } else { /* AFPD compatible, so pretend to succeed */ error = 0; } iput(parent); } else { error = hfs_rmdir(parent, name, len); } return error; }