open.c 7.5 KB

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