Whamcloud - gitweb
libext2fs: Fix ext2fs_iblk_{add,sub}_blocks() when the i_blocks_hi is non-zero
[tools/e2fsprogs.git] / lib / ext2fs / unlink.c
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 <stdio.h>
13 #include <string.h>
14 #if HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif
17
18 #include "ext2_fs.h"
19 #include "ext2fs.h"
20
21 struct link_struct  {
22         const char      *name;
23         int             namelen;
24         ext2_ino_t      inode;
25         int             flags;
26         struct ext2_dir_entry *prev;
27         int             done;
28 };
29
30 #ifdef __TURBOC__
31  #pragma argsused
32 #endif
33 static int unlink_proc(struct ext2_dir_entry *dirent,
34                      int        offset,
35                      int        blocksize EXT2FS_ATTR((unused)),
36                      char       *buf EXT2FS_ATTR((unused)),
37                      void       *priv_data)
38 {
39         struct link_struct *ls = (struct link_struct *) priv_data;
40         struct ext2_dir_entry *prev;
41
42         prev = ls->prev;
43         ls->prev = dirent;
44
45         if (ls->name) {
46                 if ((dirent->name_len & 0xFF) != ls->namelen)
47                         return 0;
48                 if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF))
49                         return 0;
50         }
51         if (ls->inode) {
52                 if (dirent->inode != ls->inode)
53                         return 0;
54         } else {
55                 if (!dirent->inode)
56                         return 0;
57         }
58
59         if (offset)
60                 prev->rec_len += dirent->rec_len;
61         else
62                 dirent->inode = 0;
63         ls->done++;
64         return DIRENT_ABORT|DIRENT_CHANGED;
65 }
66
67 #ifdef __TURBOC__
68  #pragma argsused
69 #endif
70 errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
71                         const char *name, ext2_ino_t ino,
72                         int flags EXT2FS_ATTR((unused)))
73 {
74         errcode_t       retval;
75         struct link_struct ls;
76
77         EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
78
79         if (!name && !ino)
80                 return EXT2_ET_INVALID_ARGUMENT;
81
82         if (!(fs->flags & EXT2_FLAG_RW))
83                 return EXT2_ET_RO_FILSYS;
84
85         ls.name = name;
86         ls.namelen = name ? strlen(name) : 0;
87         ls.inode = ino;
88         ls.flags = 0;
89         ls.done = 0;
90         ls.prev = 0;
91
92         retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
93                                     0, unlink_proc, &ls);
94         if (retval)
95                 return retval;
96
97         return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
98 }
99