top .gitignore: ignore .dirstamp files
[fw/openocd] / src / helper / configuration.c
1 /***************************************************************************
2  *   Copyright (C) 2004, 2005 by Dominic Rath                              *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
22  ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "configuration.h"
28 #include "log.h"
29
30 static size_t num_config_files;
31 static char **config_file_names;
32
33 static size_t num_script_dirs;
34 static char **script_search_dirs;
35
36 void add_script_search_dir(const char *dir)
37 {
38         num_script_dirs++;
39         script_search_dirs = realloc(script_search_dirs, (num_script_dirs + 1) * sizeof(char *));
40
41         script_search_dirs[num_script_dirs-1] = strdup(dir);
42         script_search_dirs[num_script_dirs] = NULL;
43
44         LOG_DEBUG("adding %s", dir);
45 }
46
47 void add_config_command(const char *cfg)
48 {
49         num_config_files++;
50         config_file_names = realloc(config_file_names, (num_config_files + 1) * sizeof(char *));
51
52         config_file_names[num_config_files-1] = strdup(cfg);
53         config_file_names[num_config_files] = NULL;
54 }
55
56 /* return full path or NULL according to search rules */
57 char *find_file(const char *file)
58 {
59         FILE *fp = NULL;
60         char **search_dirs = script_search_dirs;
61         char *dir;
62         char const *mode = "r";
63         char *full_path;
64
65         /* Check absolute and relative to current working dir first.
66          * This keeps full_path reporting belowing working. */
67         full_path = alloc_printf("%s", file);
68         fp = fopen(full_path, mode);
69
70         while (!fp) {
71                 free(full_path);
72                 full_path = NULL;
73                 dir = *search_dirs++;
74
75                 if (!dir)
76                         break;
77
78                 full_path = alloc_printf("%s/%s", dir, file);
79                 fp = fopen(full_path, mode);
80         }
81
82         if (fp) {
83                 fclose(fp);
84                 LOG_DEBUG("found %s", full_path);
85                 return full_path;
86         }
87
88         free(full_path);
89
90         return NULL;
91 }
92
93 FILE *open_file_from_path(const char *file, const char *mode)
94 {
95         if (mode[0] != 'r')
96                 return fopen(file, mode);
97         else {
98                 char *full_path = find_file(file);
99                 if (full_path == NULL)
100                         return NULL;
101                 FILE *fp = NULL;
102                 fp = fopen(full_path, mode);
103                 free(full_path);
104                 return fp;
105         }
106 }
107
108 int parse_config_file(struct command_context *cmd_ctx)
109 {
110         int retval;
111         char **cfg;
112
113         if (!config_file_names) {
114                 command_run_line(cmd_ctx, "script openocd.cfg");
115                 return ERROR_OK;
116         }
117
118         cfg = config_file_names;
119
120         while (*cfg) {
121                 retval = command_run_line(cmd_ctx, *cfg);
122                 if (retval != ERROR_OK)
123                         return retval;
124                 cfg++;
125         }
126
127         return ERROR_OK;
128 }
129
130 #ifndef _WIN32
131 #include <pwd.h>
132 #endif
133
134 char *get_home_dir(const char *append_path)
135 {
136         char *home = getenv("HOME");
137
138         if (home == NULL) {
139
140 #ifdef _WIN32
141                 home = getenv("USERPROFILE");
142
143                 if (home == NULL) {
144
145                         char homepath[MAX_PATH];
146                         char *drive = getenv("HOMEDRIVE");
147                         char *path = getenv("HOMEPATH");
148                         if (drive && path) {
149                                 snprintf(homepath, MAX_PATH, "%s/%s", drive, path);
150                                 home = homepath;
151                         }
152                 }
153 #else
154                 struct passwd *pwd = getpwuid(getuid());
155                 if (pwd)
156                         home = pwd->pw_dir;
157
158 #endif
159         }
160
161         if (home == NULL)
162                 return home;
163
164         char *home_path;
165
166         if (append_path)
167                 home_path = alloc_printf("%s/%s", home, append_path);
168         else
169                 home_path = alloc_printf("%s", home);
170
171         return home_path;
172 }