unlink.c 1.9 KB

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