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