3
0

unlink.c 1.9 KB

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