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