find_file.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*!
  2. \file gis/find_file.c
  3. \brief GIS library - Find GRASS data base files
  4. (C) 2001-2009 by the GRASS Development Team
  5. This program is free software under the
  6. GNU General Public License (>=v2).
  7. Read the file COPYING that comes with GRASS
  8. for details.
  9. \author Original author CERL
  10. */
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <grass/gis.h>
  14. #include <grass/glocale.h>
  15. static const char *find_file(int misc, const char *dir,
  16. const char *element, const char *name,
  17. const char *mapset)
  18. {
  19. char path[GPATH_MAX];
  20. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  21. const char *pname, *pmapset;
  22. int n;
  23. if (*name == 0)
  24. return NULL;
  25. *path = 0;
  26. /*
  27. * if name is in the fully qualified format, split it into
  28. * name, mapset (overrides what was in mapset)
  29. */
  30. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  31. pname = xname;
  32. pmapset = xmapset;
  33. }
  34. else {
  35. pname = name;
  36. pmapset = mapset;
  37. }
  38. if (strcmp(element, "vector") == 0 &&
  39. strcasecmp(pmapset, "ogr") == 0) {
  40. /* don't check for virtual OGR mapset */
  41. return G_store(pmapset);
  42. }
  43. /*
  44. * reject illegal names and mapsets
  45. */
  46. if (G_legal_filename(pname) == -1)
  47. return NULL;
  48. if (pmapset && *pmapset && G_legal_filename(pmapset) == -1)
  49. return NULL;
  50. /*
  51. * if no specific mapset is to be searched
  52. * then search all mapsets in the mapset search list
  53. */
  54. if (pmapset == NULL || *pmapset == 0) {
  55. int cnt = 0;
  56. const char *pselmapset = NULL;
  57. for (n = 0; (pmapset = G__mapset_name(n)); n++) {
  58. if (misc)
  59. G_file_name_misc(path, dir, element, pname, pmapset);
  60. else
  61. G_file_name(path, element, pname, pmapset);
  62. if (access(path, 0) == 0) {
  63. if (!pselmapset)
  64. pselmapset = pmapset;
  65. else
  66. G_warning(_("'%s/%s' was found in more mapsets (also found in <%s>)"),
  67. element, pname, pmapset);
  68. cnt++;
  69. }
  70. }
  71. if (cnt > 0) {
  72. /* If the same name exists in more mapsets and print a warning */
  73. if (cnt > 1)
  74. G_warning(_("Using <%s@%s>"),
  75. pname, pselmapset);
  76. return G_store(pselmapset);
  77. }
  78. }
  79. /*
  80. * otherwise just look for the file in the specified mapset.
  81. * since the name may have been qualified, mapset may point
  82. * to the xmapset, so we must should it to
  83. * permanent storage via G_store().
  84. */
  85. else {
  86. if (misc)
  87. G_file_name_misc(path, dir, element, pname, pmapset);
  88. else
  89. G_file_name(path, element, pname, pmapset);
  90. if (access(path, 0) == 0)
  91. return G_store(pmapset);
  92. }
  93. return NULL;
  94. }
  95. static const char *find_file1(
  96. int misc,
  97. const char *dir,
  98. const char *element, char *name, const char *mapset)
  99. {
  100. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  101. const char *pname, *pmapset;
  102. const char *mp;
  103. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  104. pname = xname;
  105. pmapset = xmapset;
  106. }
  107. else {
  108. pname = name;
  109. pmapset = mapset;
  110. }
  111. mp = find_file(misc, dir, element, pname, pmapset);
  112. if (mp && name != pname)
  113. strcpy(name, pname);
  114. return mp;
  115. }
  116. /*!
  117. * \brief Searches for a file from the mapset search list or in a
  118. * specified mapset.
  119. *
  120. * Returns the mapset name where the file was found.
  121. *
  122. * If the user specifies a fully qualified element (<i>name@mapset</i>)
  123. * which exists, then G_find_file() modifies <i>name</i>
  124. * by removing the "@<i>mapset</i>" part.
  125. *
  126. * Rejects all names that begin with "."
  127. *
  128. * If <i>name</i> is of the form nnn in ppp then only mapset ppp
  129. * is searched.
  130. *
  131. * \param element database element (eg, "cell", "cellhd", "colr", etc)
  132. * \param name file name to look for
  133. * \param mapset mapset to search. if mapset is "" will search in mapset search list
  134. *
  135. * \return pointer to a string with name of mapset where file was
  136. * found, or NULL if not found
  137. */
  138. const char *G_find_file(const char *element, char *name, const char *mapset)
  139. {
  140. return find_file1(0, NULL, element, name, mapset);
  141. }
  142. /*!
  143. * \brief Searches for a file from the mapset search list or in a
  144. * specified mapset.
  145. *
  146. * Returns the mapset name where the file was found.
  147. *
  148. * \param dir file directory
  149. * \param element database element (eg, "cell", "cellhd", "colr", etc)
  150. * \param name file name to look for
  151. * \param mapset mapset to search. if mapset is "" will search in mapset search list
  152. *
  153. * \return pointer to a string with name of mapset where file was
  154. * found, or NULL if not found
  155. */
  156. const char *G_find_file_misc(const char *dir,
  157. const char *element, char *name, const char *mapset)
  158. {
  159. return find_file1(1, dir, element, name, mapset);
  160. }
  161. /*!
  162. * \brief Searches for a file from the mapset search list or in a
  163. * specified mapset. (look but don't touch)
  164. *
  165. * Returns the mapset name where the file was found.
  166. *
  167. * Exactly the same as G_find_file() except that if <i>name</i> is in
  168. * the form "<i>name@mapset</i>", and is found, G_find_file2() will
  169. * not alter <i>name</i> by removing the "@<i>mapset</i>" part.
  170. *
  171. * Rejects all names that begin with "."
  172. *
  173. * \param element database element (eg, "cell", "cellhd", "colr", etc)
  174. * \param name file name to look for
  175. * \param mapset mapset to search. if mapset is "" will search in mapset search list
  176. *
  177. * \return pointer to a string with name of mapset where file was
  178. * found, or NULL if not found
  179. */
  180. const char *G_find_file2(const char *element, const char *name, const char *mapset)
  181. {
  182. return find_file(0, NULL, element, name, mapset);
  183. }
  184. /*!
  185. * \brief Searches for a file from the mapset search list or in a
  186. * specified mapset. (look but don't touch)
  187. *
  188. * Returns the mapset name where the file was found.
  189. *
  190. *
  191. * \param dir file directory
  192. * \param element database element (eg, "cell", "cellhd", "colr", etc)
  193. * \param name file name to look for
  194. * \param mapset mapset to search. if mapset is "" will search in mapset search list
  195. *
  196. * \return pointer to a string with name of mapset where file was
  197. * found, or NULL if not found
  198. */
  199. const char *G_find_file2_misc(const char *dir,
  200. const char *element,
  201. const char *name, const char *mapset)
  202. {
  203. return find_file(1, dir, element, name, mapset);
  204. }