Initial public busybox upstream commit
[busybox4maemo] / e2fsprogs / old_e2fsprogs / ext2fs / unlink.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * unlink.c --- delete links in a ext2fs directory
4  *
5  * Copyright (C) 1993, 1994, 1997 Theodore Ts'o.
6  *
7  * %Begin-Header%
8  * This file may be redistributed under the terms of the GNU Public
9  * License.
10  * %End-Header%
11  */
12
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 EXT2FS_ATTR((unused)),
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 ((dirent->name_len & 0xFF) != ls->namelen)
48                         return 0;
49                 if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF))
50                         return 0;
51         }
52         if (ls->inode) {
53                 if (dirent->inode != ls->inode)
54                         return 0;
55         } else {
56                 if (!dirent->inode)
57                         return 0;
58         }
59
60         if (prev)
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 EXT2FS_ATTR((unused)))
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 = 0;
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