119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o/* 219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * unlink.c --- delete links in a ext2fs directory 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * Copyright (C) 1993, 1994, 1997 Theodore Ts'o. 519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 1019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o */ 1119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 1219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <stdio.h> 1319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <string.h> 144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 1519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include <unistd.h> 164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 1719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 18b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 1919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o#include "ext2fs.h" 2019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 2119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'ostruct link_struct { 2219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o const char *name; 2319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o int namelen; 2431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t inode; 2519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o int flags; 264e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o struct ext2_dir_entry *prev; 2719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o int done; 28efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o}; 2919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 303cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#ifdef __TURBOC__ 3131dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o #pragma argsused 323cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#endif 3319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'ostatic int unlink_proc(struct ext2_dir_entry *dirent, 347e5a86a66044c4bf4021d1e2900a8748011f17b5Theodore Ts'o int offset, 35544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o int blocksize EXT2FS_ATTR((unused)), 36544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o char *buf EXT2FS_ATTR((unused)), 37b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data) 3819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o{ 39b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o struct link_struct *ls = (struct link_struct *) priv_data; 404e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o struct ext2_dir_entry *prev; 4119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 424e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o prev = ls->prev; 434e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o ls->prev = dirent; 4419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 454e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (ls->name) { 464e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if ((dirent->name_len & 0xFF) != ls->namelen) 474e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o return 0; 484e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF)) 494e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o return 0; 504e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o } 514e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (ls->inode) { 524e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (dirent->inode != ls->inode) 534e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o return 0; 544e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o } else { 554e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (!dirent->inode) 564e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o return 0; 574e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o } 584e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o 597e5a86a66044c4bf4021d1e2900a8748011f17b5Theodore Ts'o if (offset) 604e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o prev->rec_len += dirent->rec_len; 614e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o else 624e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o dirent->inode = 0; 6319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls->done++; 6419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o return DIRENT_ABORT|DIRENT_CHANGED; 6519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o} 6619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 673cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#ifdef __TURBOC__ 6831dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o #pragma argsused 693cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#endif 7031dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, 7131dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o const char *name, ext2_ino_t ino, 72544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o int flags EXT2FS_ATTR((unused))) 7319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o{ 7419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o errcode_t retval; 7519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o struct link_struct ls; 7619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 7719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 7819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 794e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o if (!name && !ino) 804e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o return EXT2_ET_INVALID_ARGUMENT; 814e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o 8219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (!(fs->flags & EXT2_FLAG_RW)) 8319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o return EXT2_ET_RO_FILSYS; 8419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 8519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls.name = name; 8619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls.namelen = name ? strlen(name) : 0; 8719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls.inode = ino; 8819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls.flags = 0; 8919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ls.done = 0; 904e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o ls.prev = 0; 9119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 92efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY, 934e60fb609b330fb488f2fcbfe9e330b1441201c0Theodore Ts'o 0, unlink_proc, &ls); 9419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (retval) 9519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o return retval; 9619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 9719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE; 9819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o} 9919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o 100