1 /* 2 * unlink.c --- delete links in a ext2fs directory 3 * 4 * Copyright (C) 1993, 1994, 1997 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Library 8 * General Public License, version 2. 9 * %End-Header% 10 */ 11 12 #include "config.h" 13 #include <stdio.h> 14 #include <string.h> 15 #if HAVE_UNISTD_H 16 #include <unistd.h> 17 #endif 18 19 #include "ext2_fs.h" 20 #include "ext2fs.h" 21 22 struct link_struct { 23 const char *name; 24 int namelen; 25 ext2_ino_t inode; 26 int flags; 27 struct ext2_dir_entry *prev; 28 int done; 29 }; 30 31 #ifdef __TURBOC__ 32 #pragma argsused 33 #endif 34 static int unlink_proc(struct ext2_dir_entry *dirent, 35 int offset, 36 int blocksize EXT2FS_ATTR((unused)), 37 char *buf EXT2FS_ATTR((unused)), 38 void *priv_data) 39 { 40 struct link_struct *ls = (struct link_struct *) priv_data; 41 struct ext2_dir_entry *prev; 42 43 prev = ls->prev; 44 ls->prev = dirent; 45 46 if (ls->name) { 47 if (ext2fs_dirent_name_len(dirent) != ls->namelen) 48 return 0; 49 if (strncmp(ls->name, dirent->name, ext2fs_dirent_name_len(dirent))) 50 return 0; 51 } 52 if (!(ls->flags & EXT2FS_UNLINK_FORCE) && ls->inode) { 53 if (dirent->inode != ls->inode) 54 return 0; 55 } else { 56 if (!dirent->inode) 57 return 0; 58 } 59 60 if (offset) 61 prev->rec_len += dirent->rec_len; 62 else 63 dirent->inode = 0; 64 ls->done++; 65 return DIRENT_ABORT|DIRENT_CHANGED; 66 } 67 68 #ifdef __TURBOC__ 69 #pragma argsused 70 #endif 71 errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, 72 const char *name, ext2_ino_t ino, 73 int flags) 74 { 75 errcode_t retval; 76 struct link_struct ls; 77 78 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 79 80 if (!name && !ino) 81 return EXT2_ET_INVALID_ARGUMENT; 82 83 if (!(fs->flags & EXT2_FLAG_RW)) 84 return EXT2_ET_RO_FILSYS; 85 86 ls.name = name; 87 ls.namelen = name ? strlen(name) : 0; 88 ls.inode = ino; 89 ls.flags = flags; 90 ls.done = 0; 91 ls.prev = 0; 92 93 retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY, 94 0, unlink_proc, &ls); 95 if (retval) 96 return retval; 97 98 return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE; 99 } 100