/**************************************************************************** * * MODULE: gis library * AUTHOR(S): Glynn Clements * COPYRIGHT: (C) 2007 Glynn Clements and the GRASS Development Team * * NOTE: Based upon open.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *****************************************************************************/ #include #include #include #include #include #include #include #include "gis_local_proto.h" static int G__open_misc(const char *dir, const char *element, const char *name, const char *mapset, int mode) { int fd; char path[GPATH_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; G__check_gisinit(); /* READ */ if (mode == 0) { if (G_name_is_fully_qualified(name, xname, xmapset)) { if (*mapset && strcmp(xmapset, mapset) != 0) { G_warning(_("G__open_misc(read): mapset <%s> doesn't match xmapset <%s>"), mapset, xmapset); return -1; } name = xname; mapset = xmapset; } mapset = G_find_file2_misc(dir, element, name, mapset); if (!mapset) return -1; G_file_name_misc(path, dir, element, name, mapset); if ((fd = open(path, 0)) < 0) G_warning("G__open_misc(read): Unable to open '%s': %s", path, strerror(errno)); return fd; } /* WRITE */ if (mode == 1 || mode == 2) { mapset = G_mapset(); if (G_name_is_fully_qualified(name, xname, xmapset)) { if (strcmp(xmapset, mapset) != 0) { G_warning(_("G__open_misc(write): xmapset <%s> != G_mapset() <%s>"), xmapset, mapset); return -1; } name = xname; } if (G_legal_filename(name) == -1) return -1; G_file_name_misc(path, dir, element, name, mapset); if (mode == 1 || access(path, 0) != 0) { G__make_mapset_element_misc(dir, name); close(creat(path, 0666)); } if ((fd = open(path, mode)) < 0) G_warning("G__open_misc(write): Unable to open '%s': %s", path, strerror(errno)); return fd; } return -1; } /*! * \brief open a new database misc file * * The database file element under dir/name in the * current mapset is created and opened for writing (but not reading). * The UNIX open( ) routine is used to open the file. If the file does not exist, * -1 is returned. Otherwise the file is positioned at the end of the file and * the file descriptor from the open( ) is returned. * * \param element * \param name * \return int */ int G_open_new_misc(const char *dir, const char *element, const char *name) { return G__open_misc(dir, element, name, G_mapset(), 1); } /*! * \brief open a database misc file for reading * * The database file element under * dir/name in the specified mapset is opened for reading (but * not for writing). * The UNIX open( ) routine is used to open the file. If the file does not exist, * -1 is returned. Otherwise the file descriptor from the open( ) is returned. * * \param element * \param name * \param mapset * \return int */ int G_open_old_misc(const char *dir, const char *element, const char *name, const char *mapset) { return G__open_misc(dir, element, name, mapset, 0); } /*! * \brief open a database misc file for update * * The database file element under dir/name in the * current mapset is opened for reading and writing. * The UNIX open( ) routine is used to open the file. If the file does not exist, * -1 is returned. Otherwise the file is positioned at the end of the file and * the file descriptor from the open( ) is returned. * * \param element * \param name * \return int */ int G_open_update_misc(const char *dir, const char *element, const char *name) { int fd; fd = G__open_misc(dir, element, name, G_mapset(), 2); if (fd >= 0) lseek(fd, 0L, SEEK_END); return fd; } /*! * \brief open a new database misc file * * The database file element under dir/name in the * current mapset is created and opened for writing (but not reading). * The UNIX fopen( ) routine, with "w" write mode, is used to open the file. If * the file does not exist, the NULL pointer is returned. Otherwise the file is * positioned at the end of the file and the file descriptor from the fopen( ) is * returned. * * \param element * \param name * \return FILE * */ FILE *G_fopen_new_misc(const char *dir, const char *element, const char *name) { int fd; fd = G__open_misc(dir, element, name, G_mapset(), 1); if (fd < 0) return (FILE *) 0; return fdopen(fd, "w"); } /*! * \brief open a database misc file for reading * * The database file element under * dir/name in the specified mapset is opened for reading (but * not for writing). * The UNIX fopen( ) routine, with "r" read mode, is used to open the file. If * the file does not exist, the NULL pointer is returned. Otherwise the file * descriptor from the fopen( ) is returned. * * \param element * \param name * \param mapset * \return FILE * */ FILE *G_fopen_old_misc(const char *dir, const char *element, const char *name, const char *mapset) { int fd; fd = G__open_misc(dir, element, name, mapset, 0); if (fd < 0) return (FILE *) 0; return fdopen(fd, "r"); } FILE *G_fopen_append_misc(const char *dir, const char *element, const char *name) { int fd; fd = G__open_misc(dir, element, name, G_mapset(), 2); if (fd < 0) return (FILE *) 0; lseek(fd, 0L, SEEK_END); return fdopen(fd, "a"); } FILE *G_fopen_modify_misc(const char *dir, const char *element, const char *name) { int fd; fd = G__open_misc(dir, element, name, G_mapset(), 2); if (fd < 0) return (FILE *) 0; lseek(fd, 0L, SEEK_END); return fdopen(fd, "r+"); }