remove.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 G__remove(int misc, const char *dir, const char *element,
  23. const char *name);
  24. /*!
  25. * \brief Remove a database file.
  26. *
  27. * The file or directory <i>name</i> under the database <i>element</i>
  28. * directory in the current mapset is removed.
  29. *
  30. * If <i>name</i> is a directory, everything within the directory is
  31. * removed as well.
  32. *
  33. * \param element element name
  34. * \param name file name
  35. *
  36. * \return 0 if <i>name</i> does not exist
  37. * \return 1 if successful
  38. * \return -1 on error
  39. */
  40. int G_remove(const char *element, const char *name)
  41. {
  42. return G__remove(0, NULL, element, name);
  43. }
  44. /*!
  45. * \brief Remove a database misc file.
  46. *
  47. * The file or directory <i>name</i> under the database <i>element</i>
  48. * directory in the current mapset is removed.
  49. *
  50. * If <i>name</i> is a directory, everything within the directory is
  51. * removed as well.
  52. *
  53. * \param element element name
  54. * \param name file name
  55. *
  56. * \return 0 if <i>name</i> does not exist
  57. * \return 1 if successful
  58. * \return -1 on error
  59. */
  60. int G_remove_misc(const char *dir, const char *element, const char *name)
  61. {
  62. return G__remove(1, dir, element, name);
  63. }
  64. static int G__remove(int misc, const char *dir, const char *element,
  65. const char *name)
  66. {
  67. char path[GPATH_MAX];
  68. const char *mapset;
  69. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  70. /* name in mapset legal only if mapset is current mapset */
  71. mapset = G_mapset();
  72. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  73. if (strcmp(mapset, xmapset) != 0)
  74. return -1;
  75. name = xname;
  76. }
  77. if (G_legal_filename(name) < 0)
  78. return -1;
  79. if (misc)
  80. G_file_name_misc(path, dir, element, name, mapset);
  81. else
  82. G_file_name(path, element, name, mapset);
  83. /* if file does not exist, return 0 */
  84. if (access(path, 0) != 0)
  85. return 0;
  86. if (G_recursive_remove(path) == 0)
  87. return 1;
  88. return -1;
  89. }
  90. /*!
  91. \brief Recursively remove all files in given directory
  92. Equivalent to rm -rf path.
  93. \param path path to the directory which should be removed
  94. \return 0 on success
  95. \return -1 on error
  96. */
  97. int G_recursive_remove(const char *path)
  98. {
  99. DIR *dirp;
  100. struct dirent *dp;
  101. struct stat sb;
  102. char path2[GPATH_MAX];
  103. if (G_lstat(path, &sb))
  104. return -1;
  105. if (!S_ISDIR(sb.st_mode))
  106. return remove(path) == 0 ? 0 : -1;
  107. if ((dirp = opendir(path)) == NULL)
  108. return -1;
  109. while ((dp = readdir(dirp)) != NULL) {
  110. if (dp->d_name[0] == '.')
  111. continue;
  112. if (strlen(path) + strlen(dp->d_name) + 2 > sizeof(path2))
  113. continue;
  114. sprintf(path2, "%s/%s", path, dp->d_name);
  115. G_recursive_remove(path2);
  116. }
  117. closedir(dirp);
  118. return rmdir(path) == 0 ? 0 : -1;
  119. }