open.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*!
  2. * \file gis/open.c
  3. *
  4. * \brief GIS Library - Open file functions
  5. *
  6. * (C) 1999-2009 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public
  9. * License (>=v2). Read the file COPYING that comes with GRASS
  10. * for details.
  11. *
  12. * \author USACERL and many others
  13. */
  14. #include <grass/config.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <fcntl.h>
  18. #include <grass/gis.h>
  19. #include <grass/glocale.h>
  20. /*!
  21. \brief Lowest level open routine.
  22. Opens the file <i>name</i> in <i>element</i> ("cell", etc.) in mapset <i>mapset</i>
  23. according to the i/o <i>mode</i>.
  24. - mode = 0 (read) will look for <i>name</i> in <i>mapset</i> and
  25. open the file for read only the file must exist
  26. - mode = 1 (write) will create an empty file <i>name</i> in the
  27. current mapset and open the file for write only
  28. <i>mapset</i> ignored
  29. - mode = 2 (read and write) will open a file in the current mapset
  30. for reading and writing creating a new file if
  31. necessary <i>mapset</i> ignored
  32. \param element database element name
  33. \param name map file name
  34. \param mapset mapset containing map <i>name</i>
  35. \param mode r/w mode 0=read, 1=write, 2=read/write
  36. \return open file descriptor (int)
  37. \return -1 could not open
  38. */
  39. static int G__open(const char *element,
  40. const char *name, const char *mapset, int mode)
  41. {
  42. char path[GPATH_MAX];
  43. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  44. G__check_gisinit();
  45. /* READ */
  46. if (mode == 0) {
  47. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  48. if (*mapset && strcmp(xmapset, mapset) != 0) {
  49. G_warning(_("G__open(read): mapset <%s> doesn't match xmapset <%s>"),
  50. mapset, xmapset);
  51. return -1;
  52. }
  53. name = xname;
  54. mapset = xmapset;
  55. }
  56. else if (!mapset || !*mapset)
  57. mapset = G_find_file2(element, name, mapset);
  58. if (!mapset)
  59. return -1;
  60. G__file_name(path, element, name, mapset);
  61. return open(path, 0);
  62. }
  63. /* WRITE */
  64. if (mode == 1 || mode == 2) {
  65. mapset = G_mapset();
  66. if (G_name_is_fully_qualified(name, xname, xmapset)) {
  67. if (strcmp(xmapset, mapset) != 0) {
  68. G_warning(_("G__open(write): xmapset <%s> != G_mapset() <%s>"),
  69. xmapset, mapset);
  70. return -1;
  71. }
  72. name = xname;
  73. }
  74. if (G_legal_filename(name) == -1)
  75. return -1;
  76. G__file_name(path, element, name, mapset);
  77. if (mode == 1 || access(path, 0) != 0) {
  78. G__make_mapset_element(element);
  79. close(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666));
  80. }
  81. return open(path, mode);
  82. }
  83. return -1;
  84. }
  85. /*!
  86. \brief Open a new database file
  87. Creates <i>name</i> in the current mapset and opens it
  88. for write only.
  89. The database file <i>name</i> under the <i>element</i> in the
  90. current mapset is created and opened for writing (but not reading).
  91. The UNIX open() routine is used to open the file. If the file does
  92. not exist, -1 is returned. Otherwise the file is positioned at the
  93. end of the file and the file descriptor from the open() is returned.
  94. \param element database element name
  95. \param name map file name
  96. \return open file descriptor (int)
  97. \return -1 could not open
  98. */
  99. int G_open_new(const char *element, const char *name)
  100. {
  101. return G__open(element, name, G_mapset(), 1);
  102. }
  103. /*!
  104. \brief Open a database file for reading
  105. The database file <i>name</i> under the <i>element</i> in the
  106. specified <i>mapset</i> is opened for reading (but not for writing).
  107. The UNIX open() routine is used to open the file. If the file does
  108. not exist, -1 is returned. Otherwise the file descriptor from the
  109. open() is returned.
  110. \param element database element name
  111. \param name map file name
  112. \param mapset mapset containing map <i>name</i>
  113. \return open file descriptor (int)
  114. \return -1 could not open
  115. */
  116. int G_open_old(const char *element, const char *name, const char *mapset)
  117. {
  118. return G__open(element, name, mapset, 0);
  119. }
  120. /*!
  121. \brief Open a database file for update
  122. The database file <i>name</i> under the <i>element</i> in the
  123. current mapset is opened for reading and writing. The UNIX open()
  124. routine is used to open the file. If the file does not exist, -1 is
  125. returned. Otherwise the file is positioned at the end of the file
  126. and the file descriptor from the open() is returned.
  127. \param element database element name
  128. \param name map file name
  129. \return open file descriptor (int)
  130. \return -1 could not open
  131. */
  132. int G_open_update(const char *element, const char *name)
  133. {
  134. int fd;
  135. fd = G__open(element, name, G_mapset(), 2);
  136. if (fd >= 0)
  137. lseek(fd, 0L, SEEK_END);
  138. return fd;
  139. }
  140. /*!
  141. \brief Open a new database file
  142. The database file <i>name</i> under the <i>element</i> in the
  143. current mapset is created and opened for writing (but not reading).
  144. The UNIX fopen() routine, with "w" write mode, is used to open the
  145. file. If the file does not exist, the NULL pointer is
  146. returned. Otherwise the file is positioned at the end of the file
  147. and the file descriptor from the fopen() is returned.
  148. \param element database element name
  149. \param name map file name
  150. \return open file descriptor (FILE *)
  151. \return NULL could not open
  152. */
  153. FILE *G_fopen_new(const char *element, const char *name)
  154. {
  155. int fd;
  156. fd = G__open(element, name, G_mapset(), 1);
  157. if (fd < 0)
  158. return (FILE *) 0;
  159. return fdopen(fd, "w");
  160. }
  161. /*!
  162. \brief Open a database file for reading
  163. The database file <i>name</i> under the <i>element</i> in the
  164. specified <i>mapset</i> is opened for reading (but not for writing).
  165. The UNIX fopen() routine, with "r" read mode, is used to open the
  166. file. If the file does not exist, the NULL pointer is
  167. returned. Otherwise the file descriptor from the fopen() is
  168. returned.
  169. \param element database element name
  170. \param name map file name
  171. \param mapset mapset name containing map <i>name</i>
  172. \return open file descriptor (FILE *)
  173. \return NULL could not open
  174. */
  175. FILE *G_fopen_old(const char *element, const char *name, const char *mapset)
  176. {
  177. int fd;
  178. fd = G__open(element, name, mapset, 0);
  179. if (fd < 0)
  180. return (FILE *) NULL;
  181. return fdopen(fd, "r");
  182. }
  183. /*!
  184. \brief Open a database file for update (append mode)
  185. The database file <i>name</i> under the <i>element</i> in the
  186. current mapset is opened for for writing. The UNIX fopen() routine,
  187. with "a" append mode, is used to open the file. If the file does not
  188. exist, the NULL pointer is returned. Otherwise the file descriptor
  189. from the fopen() is returned.
  190. \param element database element name
  191. \param name map file name
  192. \return open file descriptor (FILE *)
  193. \return NULL could not open
  194. */
  195. FILE *G_fopen_append(const char *element, const char *name)
  196. {
  197. int fd;
  198. fd = G__open(element, name, G_mapset(), 2);
  199. if (fd < 0)
  200. return (FILE *) 0;
  201. lseek(fd, 0L, SEEK_END);
  202. return fdopen(fd, "a");
  203. }
  204. /*!
  205. \brief Open a database file for update (r+ mode)
  206. The database file <i>name</i> under the <i>element</i> in the
  207. current mapset is opened for for writing. The UNIX fopen() routine,
  208. with "r+" append mode, is used to open the file. If the file does not
  209. exist, the NULL pointer is returned. Otherwise the file descriptor
  210. from the fopen() is returned.
  211. \param element database element name
  212. \param name map file name
  213. \return open file descriptor (FILE *)
  214. \return NULL
  215. */
  216. FILE *G_fopen_modify(const char *element, const char *name)
  217. {
  218. int fd;
  219. fd = G__open(element, name, G_mapset(), 2);
  220. if (fd < 0)
  221. return (FILE *) 0;
  222. lseek(fd, 0L, SEEK_END);
  223. return fdopen(fd, "r+");
  224. }