GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
login.c
Go to the documentation of this file.
1/*!
2 \file lib/db/dbmi_base/login.c
3
4 \brief DBMI Library (base) - login settings
5
6 (C) 1999-2015 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 <sys/types.h>
19#include <sys/stat.h>
20#include <unistd.h>
21
22#include <grass/gis.h>
23#include <grass/dbmi.h>
24#include <grass/glocale.h>
25
26typedef struct {
27 char *driver;
28 char *database;
29 char *user;
30 char *password;
31 char *host;
32 char *port;
33} DATA;
34
35typedef struct {
36 int n, a;
37 DATA *data;
38} LOGIN;
39
40static const char *login_filename(void)
41{
42 static char *file;
43
44 if (!file) {
45 file = (char *)db_malloc(GPATH_MAX);
46 snprintf(file, GPATH_MAX, "%s%cdblogin", G_config_path(), HOST_DIRSEP);
47 }
48 return file;
49}
50
51static void init_login(LOGIN *login)
52{
53 login->n = 0;
54 login->a = 10;
55
56 login->data = (DATA *)malloc(login->a * sizeof(DATA));
57}
58
59static void add_login(LOGIN *login, const char *dr, const char *db,
60 const char *usr, const char *pwd, const char *host,
61 const char *port, int idx)
62{
63 int login_idx;
64
65 G_debug(
66 3,
67 "add_login(): drv='%s' db='%s' usr='%s' pwd='%s' host='%s', port='%s'",
68 dr, db, usr ? usr : "null", pwd ? pwd : "null", host ? host : "null",
69 port ? port : "null");
70
71 if (login->n == login->a) {
72 login->a += 10;
73 login->data =
74 (DATA *)realloc((void *)login->data, login->a * sizeof(DATA));
75 }
76 if (idx > -1 && idx < login->n) {
77 login_idx = idx;
78 }
79 else {
80 login_idx = login->n;
81 login->n++;
82 }
83 login->data[login_idx].driver = G_store(dr);
84 login->data[login_idx].database = G_store(db);
85 login->data[login_idx].user = G_store(usr ? usr : "");
86 login->data[login_idx].password = G_store(pwd ? pwd : "");
87 login->data[login_idx].host = G_store(host ? host : "");
88 login->data[login_idx].port = G_store(port ? port : "");
89}
90
91/*
92 Read the DB login file if it exists
93 return: -1 error (cannot read file)
94 number of items (0 also if file does not exist)
95 */
96static int read_file(LOGIN *login)
97{
98 int ret;
99 const char *file;
100 FILE *fd;
101 char buf[DB_SQL_MAX];
102 char **tokens;
103
104 login->n = 0;
105 file = login_filename();
106
107 G_debug(3, "read_file(): DB login file = <%s>", file);
108
109 if (access(file, F_OK) != 0) {
110 G_debug(3, "login file does not exist");
111 return 0;
112 }
113
114 fd = fopen(file, "r");
115 if (fd == NULL) {
116 G_warning(_("Unable to read file '%s'"), file);
117 return -1;
118 }
119
120 while (G_getl2(buf, 2000, fd)) {
121 G_chop(buf);
122
123 tokens = G_tokenize(buf, "|");
125
126 if (ret < 2) {
127 G_warning(_("Login file (%s) corrupted (line: %s)"), file, buf);
129 continue;
130 }
131
132 add_login(login, tokens[0], /* driver */
133 tokens[1], /* database */
134 ret > 2 ? tokens[2] : NULL, /* user */
135 ret > 3 ? tokens[3] : NULL, /* password */
136 ret > 4 ? tokens[4] : NULL, /* host */
137 ret > 5 ? tokens[5] : NULL, /* port */
138 -1);
140 }
141
142 fclose(fd);
143
144 return (login->n);
145}
146
147/*
148 Write the DB login file
149 return: -1 error (cannot read file)
150 0 OK
151 */
152static int write_file(LOGIN *login)
153{
154 int i;
155 const char *file;
156 FILE *fd;
157
158 file = login_filename();
159
160 G_debug(3, "write_file(): DB login file = <%s>", file);
161
162 fd = fopen(file, "w");
163 if (fd == NULL) {
164 G_warning(_("Unable to write file '%s'"), file);
165 return -1;
166 }
167
168 /* fchmod is not available on Windows */
169 /* fchmod ( fileno(fd), S_IRUSR | S_IWUSR ); */
170#ifndef _MSC_VER
172#endif
173 for (i = 0; i < login->n; i++) {
174 fprintf(fd, "%s|%s", login->data[i].driver, login->data[i].database);
175 if (login->data[i].user) {
176 fprintf(fd, "|%s", login->data[i].user);
177
178 if (login->data[i].password)
179 fprintf(fd, "|%s", login->data[i].password);
180 }
181 if (login->data[i].host)
182 fprintf(fd, "|%s", login->data[i].host);
183 if (login->data[i].port)
184 fprintf(fd, "|%s", login->data[i].port);
185
186 fprintf(fd, "\n");
187 }
188
189 fclose(fd);
190
191 return 0;
192}
193
194static int set_login(const char *driver, const char *database, const char *user,
195 const char *password, const char *host, const char *port,
196 int overwrite)
197{
198 int i, found;
199 LOGIN login;
200
201 G_debug(3,
202 "db_set_login(): drv=[%s] db=[%s] usr=[%s] pwd=[%s] host=[%s] "
203 "port=[%s]",
204 driver, database, user, password, host, port);
205
206 init_login(&login);
207
208 if (read_file(&login) == -1)
209 return DB_FAILED;
210
211 found = FALSE;
212 for (i = 0; i < login.n; i++) {
213 if (strcmp(login.data[i].driver, driver) == 0 &&
214 strcmp(login.data[i].database, database) == 0) {
215 if (user)
216 login.data[i].user = G_store(user);
217 else
218 login.data[i].user = G_store("");
219
220 if (password)
221 login.data[i].password = G_store(password);
222 else
223 login.data[i].password = G_store("");
224
225 found = TRUE;
226 break;
227 }
228 }
229
230 if (found) {
231 if (overwrite)
232 G_warning(_("DB connection <%s/%s> already exists and will be "
233 "overwritten"),
234 driver, database ? database : "");
235 else
236 G_fatal_error(_("DB connection <%s/%s> already exists. "
237 "Re-run '%s' with '--%s' flag to overwrite "
238 "existing settings."),
239 driver, database ? database : "", G_program_name(),
240 "overwrite");
241 }
242
243 if (!found)
244 add_login(&login, driver, database, user, password, host, port, -1);
245 else
246 add_login(&login, driver, database, user, password, host, port, i);
247
248 if (write_file(&login) == -1)
249 return DB_FAILED;
250
251 return DB_OK;
252}
253
254/*!
255 \brief Set login parameters for driver/database
256
257 \param driver driver name
258 \param database database name
259 \param user user name
260 \param password password string
261 \param host host name
262 \param port
263 \param overwrite TRUE to overwrite existing connections
264
265 \return DB_OK on success
266 \return DB_FAILED on failure
267 */
268int db_set_login2(const char *driver, const char *database, const char *user,
269 const char *password, const char *host, const char *port,
270 int overwrite)
271{
272 return db_set_login(driver, database, user, password, host, port,
273 overwrite);
274}
275
276/*!
277 \brief Set login parameters for driver/database
278
279 \param driver driver name
280 \param database database name
281 \param user user name
282 \param password password string
283 \param host host name
284 \param port
285 \param overwrite TRUE to overwrite existing connections
286
287 \return DB_OK on success
288 \return DB_FAILED on failure
289 */
290int db_set_login(const char *driver, const char *database, const char *user,
291 const char *password, const char *host, const char *port,
292 int overwrite)
293{
294 return set_login(driver, database, user, password, host, port, overwrite);
295}
296
297static int get_login(const char *driver, const char *database,
298 const char **user, const char **password,
299 const char **host, const char **port)
300{
301 int i;
302 LOGIN login;
303
304 G_debug(3, "db_get_login(): drv=[%s] db=[%s]", driver, database);
305
306 *user = NULL;
307 *password = NULL;
308 *host = NULL;
309 *port = NULL;
310
311 init_login(&login);
312
313 if (read_file(&login) == -1)
314 return DB_FAILED;
315
316 for (i = 0; i < login.n; i++) {
317 if (strcmp(login.data[i].driver, driver) == 0 &&
318 (!database || strcmp(login.data[i].database, database) == 0)) {
319 if (login.data[i].user && strlen(login.data[i].user) > 0)
320 *user = G_store(login.data[i].user);
321 else
322 *user = NULL;
323
324 if (login.data[i].password && strlen(login.data[i].password) > 0)
325 *password = G_store(login.data[i].password);
326 else
327 *password = NULL;
328
329 if (login.data[i].host && strlen(login.data[i].host) > 0 && host)
330 *host = G_store(login.data[i].host);
331 else
332 *host = NULL;
333
334 if (login.data[i].port && strlen(login.data[i].port) > 0 && port)
335 *port = G_store(login.data[i].port);
336 else
337 *port = NULL;
338
339 break;
340 }
341 }
342
343 return DB_OK;
344}
345
346/*!
347 \brief Get login parameters for driver/database
348
349 If driver/database is not found, output arguments are set to NULL.
350
351 \param driver driver name
352 \param database database name (can be NULL)
353 \param[out] user name
354 \param[out] password string
355 \param[out] host name
356 \param[out] port
357
358 \return DB_OK on success
359 \return DB_FAILED on failure
360 */
361int db_get_login2(const char *driver, const char *database, const char **user,
362 const char **password, const char **host, const char **port)
363{
364 return db_get_login(driver, database, user, password, host, port);
365}
366
367/*!
368 \brief Get login parameters for driver/database
369
370 If driver/database is not found, output arguments are set to NULL.
371
372 \param driver driver name
373 \param database database name (can be NULL)
374 \param[out] user name
375 \param[out] password string
376 \param[out] host name
377 \param[out] port
378
379 \return DB_OK on success
380 \return DB_FAILED on failure
381 */
382int db_get_login(const char *driver, const char *database, const char **user,
383 const char **password, const char **host, const char **port)
384{
385 return get_login(driver, database, user, password, host, port);
386}
387
388/*!
389 \brief Print all connection settings to file
390
391 \param fd file where to print settings
392
393 \return DB_OK on success
394 \return DB_FAILED on failure
395 */
397{
398 int i;
399 LOGIN login;
400
401 G_debug(3, "db_get_login_dump()");
402
403 init_login(&login);
404 if (read_file(&login) == -1)
405 return DB_FAILED;
406
407 for (i = 0; i < login.n; i++) {
408 fprintf(fd, "%s|%s|%s|%s|%s|%s\n", login.data[i].driver,
409 login.data[i].database, login.data[i].user,
410 login.data[i].password, login.data[i].host, login.data[i].port);
411 }
412
413 return DB_OK;
414}
#define NULL
Definition ccmath.h:32
Main header of GRASS DataBase Management Interface.
#define DB_SQL_MAX
Definition dbmi.h:142
#define DB_FAILED
Definition dbmi.h:72
#define DB_OK
Definition dbmi.h:71
void * db_malloc(int)
Allocate memory.
const char * G_program_name(void)
Return module name.
Definition progrm_nme.c:28
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition getl.c:60
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
char ** G_tokenize(const char *, const char *)
Tokenize string.
Definition gis/token.c:47
void G_free_tokens(char **)
Free memory allocated to tokens.
Definition gis/token.c:197
int G_number_of_tokens(char **)
Return number of tokens.
Definition gis/token.c:178
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition strings.c:332
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:87
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_config_path(void)
Get user's config path directory.
Definition home.c:99
#define GPATH_MAX
Definition gis.h:199
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
#define HOST_DIRSEP
Definition gis.h:240
#define _(str)
Definition glocale.h:10
#define file
int db_get_login2(const char *driver, const char *database, const char **user, const char **password, const char **host, const char **port)
Get login parameters for driver/database.
Definition login.c:361
int db_set_login(const char *driver, const char *database, const char *user, const char *password, const char *host, const char *port, int overwrite)
Set login parameters for driver/database.
Definition login.c:290
int db_get_login_dump(FILE *fd)
Print all connection settings to file.
Definition login.c:396
int db_get_login(const char *driver, const char *database, const char **user, const char **password, const char **host, const char **port)
Get login parameters for driver/database.
Definition login.c:382
int db_set_login2(const char *driver, const char *database, const char *user, const char *password, const char *host, const char *port, int overwrite)
Set login parameters for driver/database.
Definition login.c:268
void * malloc(unsigned)
#define S_IRUSR
Definition stat.h:8
#define S_IWUSR
Definition stat.h:9
#define access
Definition unistd.h:7
#define F_OK
Definition unistd.h:22