remove.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*!
  2. * \file lib/gis/remove.c
  3. *
  4. * \brief GIS Library - File remove functions.
  5. *
  6. * (C) 2001-2009 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author Original author CERL
  12. */
  13. #include <grass/config.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <dirent.h>
  21. #include <grass/gis.h>
  22. static int recursive_remove(const char *path);
  23. static int G__remove(int misc, const char *dir, const char *element,
  24. const char *name);
  25. /*!
  26. * \brief Remove a database file.
  27. *
  28. * The file or directory <i>name</i> under the database <i>element</i>
  29. * directory in the current mapset is removed.
  30. *
  31. * If <i>name</i> is a directory, everything within the directory is
  32. * removed as well.
  33. *
  34. * \param element element name
  35. * \param name file name
  36. *
  37. * \return 0 if <i>name</i> does not exist
  38. * \return 1 if successful
  39. * \return -1 on error
  40. */
  41. int G_remove(const char *element, const char *name)
  42. {
  43. return G__remove(0, NULL, element, name);
  44. }
  45. /*!
  46. * \brief Remove a database misc file.
  47. *
  48. * The file or directory <i>name</i> under the database <i>element</i>
  49. * directory in the current mapset is removed.
  50. *
  51. * If <i>name</i> is a directory, everything within the directory is
  52. * removed as well.
  53. *
  54. * \param element element name
  55. * \param name file name
  56. *
  57. * \return 0 if <i>name</i> does not exist
  58. * \return 1 if successful
  59. * \return -1 on error
  60. */
  61. int G_remove_misc(const char *dir, const char *element, const char *name)
  62. {
  63. return G__remove(1, dir, element, name);
  64. }
  65. static int G__remove(int misc, const char *dir, const char *element,
  66. const char *name)
  67. {
  68. char path[GPATH_MAX];
  69. const char *mapset;
  70. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  71. /* name in mapset legal only if mapset is current mapset */
  72. mapset = G_mapset();
  73. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  74. if (strcmp(mapset, xmapset) != 0)
  75. return -1;
  76. name = xname;
  77. }
  78. if (G_legal_filename(name) < 0)
  79. return -1;
  80. if (misc)
  81. G_file_name_misc(path, dir, element, name, mapset);
  82. else
  83. G_file_name(path, element, name, mapset);
  84. /* if file does not exist, return 0 */
  85. if (access(path, 0) != 0)
  86. return 0;
  87. if (recursive_remove(path) == 0)
  88. return 1;
  89. return -1;
  90. }
  91. /* equivalent to rm -rf path */
  92. static int recursive_remove(const char *path)
  93. {
  94. DIR *dirp;
  95. struct dirent *dp;
  96. struct stat sb;
  97. char path2[GPATH_MAX];
  98. if (G_lstat(path, &sb))
  99. return 1;
  100. if (!S_ISDIR(sb.st_mode))
  101. return remove(path) == 0 ? 0 : 1;
  102. if ((dirp = opendir(path)) == NULL)
  103. return 1;
  104. while ((dp = readdir(dirp)) != NULL) {
  105. if (dp->d_name[0] == '.')
  106. continue;
  107. if (strlen(path) + strlen(dp->d_name) + 2 > sizeof(path2))
  108. continue;
  109. sprintf(path2, "%s/%s", path, dp->d_name);
  110. recursive_remove(path2);
  111. }
  112. closedir(dirp);
  113. return rmdir(path) == 0 ? 0 : 1;
  114. }