GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-a277d8547c
dbmscap.c
Go to the documentation of this file.
1 /*!
2  \file lib/db/dbmi_base/dbmscap.c
3 
4  \brief DBMI Library (base) - DBmscap management
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 Joel Jones (CERL/UIUC), Radim Blazek
13  */
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <dirent.h>
19 #include <unistd.h>
20 #include <grass/dbmi.h>
21 #include <grass/gis.h>
22 
23 static char *dbmscap_files[] = {"/etc/dbmscap",
24  "/lib/dbmscap",
25  "/usr/lib/dbmscap",
26  "/usr/local/lib/dbmscap",
27  "/usr/local/dbmi/lib/dbmscap",
28  NULL};
29 
30 static void add_entry(dbDbmscap **list, char *name, char *startup,
31  char *comment);
32 
33 static char *dbmscap_filename(int err_flag)
34 {
35  char *file;
36  int i;
37 
38  file = getenv("DBMSCAP");
39  if (file)
40  return file;
41 
42  for (i = 0; (file = dbmscap_files[i]); i++) {
43  if (access(file, 0) == 0)
44  return file;
45  }
46  if (err_flag)
47  db_error("DBMSCAP not set");
48 
49  return ((char *)NULL);
50 }
51 
52 /*!
53  \brief Get dbmscap file name
54 
55  \return pointer to string with file name
56  */
57 const char *db_dbmscap_filename(void)
58 {
59  return dbmscap_filename(1);
60 }
61 
62 /*!
63  \brief Check dbms
64 
65  \return 1 if true
66  \return 0 if false
67  */
68 int db_has_dbms(void)
69 {
70  return (dbmscap_filename(0) != NULL);
71 }
72 
73 /*!
74  \brief Copy dbmscap entry
75 
76  \param dst destination
77  \param src source
78  */
80 {
81  strcpy(dst->driverName, src->driverName);
82  strcpy(dst->comment, src->comment);
83  strcpy(dst->startup, src->startup);
84 }
85 
86 /*!
87  \brief Read dbmscap
88 
89  dbmscap file was used in grass5.0 but it is not used in
90  grass5.7 until we find it necessary. All code for dbmscap
91  file is commented here.
92 
93  Instead of in dbmscap file db_read_dbmscap() searches
94  for available dbmi drivers in $(GISBASE)/driver/db/
95 
96  \return pointer to dbDbmscap
97  */
99 {
100  /*
101  FILE *fd;
102  char *file;
103  char name[1024];
104  char startup[1024];
105  char comment[1024];
106  int line;
107  */
108  char *dirpath = NULL;
109  DIR *dir;
110  struct dirent *ent;
111 
112  dbDbmscap *list = NULL;
113 
114  /* START OF OLD CODE FOR dbmscap FILE - NOT USED, BUT KEEP IT FOR FUTURE */
115 #if 0
116  /* get the full name of the dbmscap file */
117 
119  if (file == NULL)
120  return (dbDbmscap *) NULL;
121 
122 
123  /* open the dbmscap file */
124 
125  fd = fopen(file, "r");
126  if (fd == NULL) {
127  db_syserror(file);
128  return (dbDbmscap *) NULL;
129  }
130 
131 
132  /* find all valid entries
133  * blank lines and lines with # as first non blank char are ignored
134  * format is:
135  * driver name:startup command:comment
136  */
137 
138  for (line = 1; fgets(buf, sizeof buf, fd); line++) {
139  if (sscanf(buf, "%1s", comment) != 1 || *comment == '#')
140  continue;
141  if (sscanf(buf, "%[^:]:%[^:]:%[^:\n]", name, startup, comment) == 3)
142  add_entry(&list, name, startup, comment);
143  else if (sscanf(buf, "%[^:]:%[^:\n]", name, startup) == 2)
144  add_entry(&list, name, startup, "");
145  else {
146  fprintf(stderr, "%s: line %d: invalid entry\n", file, line);
147  fprintf(stderr, "%d:%s\n", line, buf);
148  }
149  if (list == NULL)
150  break;
151  }
152  fclose(fd);
153 #endif
154  /* END OF OLD CODE FOR dbmscap FILE */
155 
156  /* START OF NEW CODE FOR SEARCH IN $(GISBASE)/driver/db/ */
157 
158  /* opend db drivers directory */
159 #ifdef _WIN32
160  size_t len = (strlen("\\driver\\db\\") + strlen(G_gisbase()) + 1);
161  dirpath = G_malloc(len);
162  snprintf(dirpath, len, "%s\\driver\\db\\", G_gisbase());
163  G_convert_dirseps_to_host(dirpath);
164 #else
165  G_asprintf(&dirpath, "%s/driver/db/", G_gisbase());
166 #endif
167 
168  G_debug(2, "dbDbmscap(): opendir [%s]", dirpath);
169  dir = opendir(dirpath);
170  if (dir == NULL) {
171  db_syserror("Cannot open drivers directory");
172  return (dbDbmscap *)NULL;
173  }
174  G_free(dirpath);
175 
176  /* read all drivers */
177  while ((ent = readdir(dir))) {
178  char *name;
179 
180  if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..") == 0))
181  continue;
182 
183 #ifdef _WIN32
184  /* skip manifest files on Windows */
185  if (strstr(ent->d_name, ".manifest"))
186  continue;
187 #endif
188 
189  /* Remove '.exe' from name (windows extension) */
190  name = G_str_replace(ent->d_name, ".exe", "");
191 
192 #ifdef _WIN32
193  len = strlen("\\driver\\db\\") + strlen(G_gisbase()) +
194  strlen(ent->d_name) + 1;
195  dirpath = G_malloc(len);
196  snprintf(dirpath, len, "%s\\driver\\db\\%s", G_gisbase(), ent->d_name);
197  G_convert_dirseps_to_host(dirpath);
198 #else
199  G_asprintf(&dirpath, "%s/driver/db/%s", G_gisbase(), ent->d_name);
200 #endif
201  add_entry(&list, name, dirpath, "");
202  G_free(name);
203  G_free(dirpath);
204  }
205 
206  closedir(dir);
207 
208  return list;
209 }
210 
211 static int cmp_entry(dbDbmscap *a, dbDbmscap *b)
212 {
213  return (*a->driverName && *b->driverName
214  ? strcmp(a->driverName, b->driverName)
215  : 0);
216 }
217 
218 static void add_entry(dbDbmscap **list, char *name, char *startup,
219  char *comment)
220 {
221  /* add an entry to the list, so that the list remains ordered (by
222  * driverName) */
223 
224  dbDbmscap *head, *cur, *tail;
225 
226  cur = (dbDbmscap *)db_malloc(sizeof(dbDbmscap));
227  if (cur == NULL) {
228  *list = NULL;
229  return;
230  /* out of memory */
231  }
232  cur->next = NULL;
233 
234  /* copy each item to the dbmscap structure */
235  strcpy(cur->driverName, name);
236  strcpy(cur->startup, startup);
237  strcpy(cur->comment, comment);
238 
239  /* find the last entry that is less than cur */
240  tail = head = *list;
241  while (tail && tail->next && cmp_entry(tail->next, cur) < 0)
242  tail = tail->next;
243 
244  /* handle the first call (head == NULL) */
245  if (tail && cmp_entry(tail, cur) < 0) {
246  /* insert right after tail */
247  cur->next = tail->next;
248  tail->next = cur;
249  }
250  else {
251  /* insert at first position */
252  cur->next = head;
253  head = cur;
254  }
255 
256  *list = head;
257 }
258 
259 /*!
260  \brief Free dbmscap
261 
262  \param list pointer to dbDbmscap
263  */
265 {
266  dbDbmscap *next, *cur;
267 
268  for (cur = list; cur; cur = next) {
269  next = cur->next;
270  db_free(cur);
271  }
272 }
#define NULL
Definition: ccmath.h:32
void db_copy_dbmscap_entry(dbDbmscap *dst, dbDbmscap *src)
Copy dbmscap entry.
Definition: dbmscap.c:79
void db_free_dbmscap(dbDbmscap *list)
Free dbmscap.
Definition: dbmscap.c:264
const char * db_dbmscap_filename(void)
Get dbmscap file name.
Definition: dbmscap.c:57
int db_has_dbms(void)
Check dbms.
Definition: dbmscap.c:68
dbDbmscap * db_read_dbmscap(void)
Read dbmscap.
Definition: dbmscap.c:98
void db_free(void *)
Free allocated memory.
void db_error(const char *)
Report error message.
void db_syserror(const char *)
Report system error.
void * db_malloc(int)
Allocate memory.
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
char * G_str_replace(const char *, const char *, const char *)
Replace all occurrences of old_str in buffer with new_str.
Definition: strings.c:189
#define G_malloc(n)
Definition: defs/gis.h:94
int G_asprintf(char **, const char *,...) __attribute__((format(printf
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:39
int G_debug(int, const char *,...) __attribute__((format(printf
char * G_convert_dirseps_to_host(char *)
Converts directory separator characters in a string to the native host separator character (/ on Unix...
Definition: paths.c:83
struct DIR DIR
Definition: dirent.h:18
#define file
char * dst
Definition: lz4.h:981
const char * src
Definition: lz4.h:989
DIR * opendir(const char *name)
Definition: msvc/dirent.c:15
int closedir(DIR *dir)
Definition: msvc/dirent.c:54
struct dirent * readdir(DIR *dir)
Definition: msvc/dirent.c:75
const char * name
Definition: named_colr.c:6
#define strcpy
Definition: parson.c:62
double b
Definition: r_raster.c:39
struct list * list
Definition: read_list.c:24
Definition: dbmi.h:152
char comment[256]
Definition: dbmi.h:155
char startup[256]
Definition: dbmi.h:154
char driverName[256]
Definition: dbmi.h:153
struct _dbmscap * next
Definition: dbmi.h:156
Definition: dirent.h:20
char * d_name
Definition: dirent.h:21
Definition: manage.h:4
#define access
Definition: unistd.h:7