GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-6c790bf5c0
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;
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 __MINGW32__
160  dirpath = G_malloc(strlen("\\driver\\db\\") + strlen(G_gisbase()) + 1);
161  sprintf(dirpath, "%s\\driver\\db\\", G_gisbase());
162  G_convert_dirseps_to_host(dirpath);
163 #else
164  G_asprintf(&dirpath, "%s/driver/db/", G_gisbase());
165 #endif
166 
167  G_debug(2, "dbDbmscap(): opendir [%s]", dirpath);
168  dir = opendir(dirpath);
169  if (dir == NULL) {
170  db_syserror("Cannot open drivers directory");
171  return (dbDbmscap *)NULL;
172  }
173  G_free(dirpath);
174 
175  /* read all drivers */
176  while ((ent = readdir(dir))) {
177  char *name;
178 
179  if ((strcmp(ent->d_name, ".") == 0) || (strcmp(ent->d_name, "..") == 0))
180  continue;
181 
182 #ifdef __MINGW32__
183  /* skip manifest files on Windows */
184  if (strstr(ent->d_name, ".manifest"))
185  continue;
186 #endif
187 
188  /* Remove '.exe' from name (windows extension) */
189  name = G_str_replace(ent->d_name, ".exe", "");
190 
191 #ifdef __MINGW32__
192  dirpath = G_malloc(strlen("\\driver\\db\\") + strlen(G_gisbase()) +
193  strlen(ent->d_name) + 1);
194  sprintf(dirpath, "%s\\driver\\db\\%s", G_gisbase(), ent->d_name);
195  G_convert_dirseps_to_host(dirpath);
196 #else
197  G_asprintf(&dirpath, "%s/driver/db/%s", G_gisbase(), ent->d_name);
198 #endif
199  add_entry(&list, name, dirpath, "");
200  G_free(name);
201  G_free(dirpath);
202  }
203 
204  closedir(dir);
205 
206  return list;
207 }
208 
209 static int cmp_entry(dbDbmscap *a, dbDbmscap *b)
210 {
211  return (*a->driverName && *b->driverName
212  ? strcmp(a->driverName, b->driverName)
213  : 0);
214 }
215 
216 static void add_entry(dbDbmscap **list, char *name, char *startup,
217  char *comment)
218 {
219  /* add an entry to the list, so that the list remains ordered (by
220  * driverName) */
221 
222  dbDbmscap *head, *cur, *tail;
223 
224  cur = (dbDbmscap *)db_malloc(sizeof(dbDbmscap));
225  if (cur == NULL) {
226  *list = NULL;
227  return;
228  /* out of memory */
229  }
230  cur->next = NULL;
231 
232  /* copy each item to the dbmscap structure */
233  strcpy(cur->driverName, name);
234  strcpy(cur->startup, startup);
235  strcpy(cur->comment, comment);
236 
237  /* find the last entry that is less than cur */
238  tail = head = *list;
239  while (tail && tail->next && cmp_entry(tail->next, cur) < 0)
240  tail = tail->next;
241 
242  /* handle the first call (head == NULL) */
243  if (tail && cmp_entry(tail, cur) < 0) {
244  /* insert right after tail */
245  cur->next = tail->next;
246  tail->next = cur;
247  }
248  else {
249  /* insert at first position */
250  cur->next = head;
251  head = cur;
252  }
253 
254  *list = head;
255 }
256 
257 /*!
258  \brief Free dbmscap
259 
260  \param list pointer to dbDbmscap
261  */
263 {
264  dbDbmscap *next, *cur;
265 
266  for (cur = list; cur; cur = next) {
267  next = cur->next;
268  db_free(cur);
269  }
270 }
#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:262
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
#define file
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: manage.h:4