GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
manage_signatures.c
Go to the documentation of this file.
1/*!
2 \file lib/imagery/manage_signatures.c
3
4 \brief Imagery Library - Signature file management functions
5
6 SPDX-FileCopyrightText: 2021 Maris Nartiss
7 SPDX-FileCopyrightText: GRASS Development Team
8 SPDX-License-Identifier: GPL-2.0-or-later
9
10 \author Maris Nartiss
11 */
12
13#include <unistd.h>
14#include <string.h>
15
16#include <grass/gis.h>
17#include <grass/imagery.h>
18#include <grass/glocale.h>
19
20/*!
21 \brief Get signature directory
22
23 The directory will be in a form "signatures/<type>".
24
25 \param dir [GNAME_MAX] allocated string buffer
26 \param type I_SIGFILE_TYPE
27 */
29{
30 if (type == I_SIGFILE_TYPE_SIG) {
31 sprintf(dir, "signatures%csig", HOST_DIRSEP);
32 }
33 else if (type == I_SIGFILE_TYPE_SIGSET) {
34 sprintf(dir, "signatures%csigset", HOST_DIRSEP);
35 }
36 else if (type == I_SIGFILE_TYPE_LIBSVM) {
37 sprintf(dir, "signatures%clibsvm", HOST_DIRSEP);
38 }
39 else {
40 G_fatal_error("Programming error: unknown signature file type");
41 }
42}
43
44/*!
45 \brief Make signature dir
46
47 Creates directories for storage of signature files of specified type.
48 E.g. "<location>/<mapset>/signatures/<type>/"
49
50 \param type I_SIGFILE_TYPE
51 */
53{
54 char dir[GNAME_MAX];
55
56 G_make_mapset_object_group("signatures");
57 I_get_signatures_dir(dir, type);
59}
60
61static int list_by_type(I_SIGFILE_TYPE, const char *, int, char ***);
62
63/*!
64 * \brief Remove a signature file
65 *
66 * If removal fails, prints a warning and returns 1.
67 * It is safe to pass fully qualified names.
68 *
69 * \param type I_SIGFILE_TYPE signature type
70 * \param name of signature to remove
71 * \return 0 on success
72 * \return 1 on failure
73 */
75{
77 char dir[GNAME_MAX];
78
79 G_debug(1, "I_signatures_remove(%d, %s);", type, name);
80
81 /* Remove only if file is in the current mapset */
83 strcmp(xmapset, G_mapset()) != 0) {
84 G_warning(_("%s is not in the current mapset (%s)"), name, G_mapset());
85 return 1;
86 }
87 if (I_find_signature2(type, name, G_mapset())) {
88 I_get_signatures_dir(dir, type);
89 if (G_remove(dir, name) == 1) {
90 G_verbose_message(_("%s removed"), name);
91 return 0;
92 }
93 G_warning(_("Unable to remove %s signature"), name);
94 }
95 else
96 G_warning(_("%s is missing"), name);
97 return 1;
98}
99
100/*!
101 * \brief Copy a signature file
102 *
103 * If copy fails, prints warning messages and returns 1.
104 * It is safe to pass fully qualified names.
105 *
106 * \param type I_SIGFILE_TYPE signature type
107 * \param old_name of old signature
108 * \param old_mapset of old signature
109 * \param new_name of new signature
110 * \return 0 on success
111 * \return 1 on failure
112 */
114 const char *old_mapset, const char *new_name)
115{
118 char dir[GNAME_MAX];
119 const char *smapset;
121
122 G_debug(1, "I_signatures_copy(%d, %s@%s, %s);", type, old_name, old_mapset,
123 new_name);
124
125 /* Copy only if mapset of new name is the current mapset */
127 if (strcmp(tmapset, G_mapset()) != 0) {
128 G_warning(_("%s is not in the current mapset (%s)"), new_name,
129 G_mapset());
130 return 1;
131 }
132 }
133 else
135
137 if (!smapset) {
138 G_warning(_("%s is missing"), old_name);
139 return 1;
140 }
142
144
145 I_get_signatures_dir(dir, type);
146 /* Note – we need whole directory not just an element in it thus
147 G_file_name and not G_file_name_misc */
150
153 G_warning(_("Unable to copy <%s> to current mapset as <%s>"), mname,
154 tname);
155 G_free(mname);
156 return 1;
157 }
158 return 0;
159}
160
161/*!
162 * \brief Rename a signature file
163 *
164 * If rename fails, prints warning messages and returns 1.
165 * It is safe to pass fully qualified names.
166 *
167 * \param type I_SIGFILE_TYPE signature type
168 * \param old_name name of old signature
169 * \param new_name name of new signature
170 * \return 0 on success
171 * \return 1 on failure
172 */
174 const char *new_name)
175{
177 char dir[GNAME_MAX];
178 const char *smapset;
180
181 G_debug(1, "I_signatures_rename(%d, %s, %s);", type, old_name, new_name);
182
183 /* Rename only if source and destination mapset is the current mapset */
185 if (strcmp(tmapset, G_mapset()) != 0) {
186 G_warning(_("%s is not in the current mapset (%s)"), old_name,
187 G_mapset());
188 return 1;
189 }
190 }
191 else
194 if (strcmp(tmapset, G_mapset()) != 0) {
195 G_warning(_("%s is not in the current mapset (%s)"), new_name,
196 G_mapset());
197 return 1;
198 }
199 }
200 else
202
204 if (!smapset) {
205 G_warning(_("%s is missing"), old_name);
206 return 1;
207 }
208
209 I_get_signatures_dir(dir, type);
210 /* Note – we need whole directory not just an element in it thus
211 G_file_name and not G_file_name_misc */
214
215 if (G_rename_file(old_path, new_path) != 0) {
216 G_warning(_("Unable to rename <%s> to <%s>"), old_name, new_name);
217 return 1;
218 }
219 return 0;
220}
221
222/*!
223 * \brief Get list of existing signatures by type
224 *
225 * Fills passed list with fully qualified names of existing signatures.
226 *
227 * If no mapset is passed, all mapsets in the search path are used.
228 * If no signatures are found, returns 0 and list is set to NULL.
229 *
230 * The function will assign memory for the list. It is up to callee to
231 * free the memory of each list item and the list itself.
232 *
233 * \param type I_SIGFILE_TYPE signature type
234 * \param mapset optional mapset to search in or NULL
235 * \param out_list pointer to array of found signature strings or NULL if none
236 * found
237 * \return count of signature strings in the array
238 */
239int I_signatures_list_by_type(I_SIGFILE_TYPE type, const char *mapset,
240 char ***out_list)
241{
242 int base = 0;
243
244 *out_list = NULL;
245 if (mapset == NULL) {
246 for (int n = 0; (mapset = G_get_mapset_name(n)); n++) {
247 base += list_by_type(type, mapset, base, out_list);
248 }
249 }
250 else {
251 base += list_by_type(type, mapset, base, out_list);
252 }
253
254 return base;
255}
256
257/*!
258 * \brief Free memory allocated by I_signatures_list_by_type
259 *
260 * Calls G_free for all list items returned by I_signatures_list_by_type()
261 * Sets pointer to NULL to prevent accidental use after free.
262 *
263 * \param int Return value of I_signatures_list_by_type()
264 * \param pointer to array filled by I_signatures_list_by_type()
265 */
266void I_free_signatures_list(int count, char ***list)
267{
268 for (int n = 0; n < count; n++) {
269 G_free((*list)[n]);
270 }
271 G_free(*list);
272 *list = NULL;
273}
274
275static int list_by_type(I_SIGFILE_TYPE type, const char *mapset, int base,
276 char ***out_list)
277{
278 int count = 0;
279 char path[GPATH_MAX];
280 char dir[GNAME_MAX];
281 char **dirlist;
282
283 I_get_signatures_dir(dir, type);
284 G_file_name(path, dir, "", mapset);
285
286 if (access(path, 0) != 0) {
287 return count;
288 }
289
290 dirlist = G_ls2(path, &count);
291 if (count == 0) {
293 return count;
294 }
295
296 /* Make items fully qualified names */
297 int mapset_len = strlen(mapset);
298
299 *out_list = (char **)G_realloc(*out_list, (base + count) * sizeof(char *));
300 for (int i = 0; i < count; i++) {
301 size_t len = (strlen(dirlist[i]) + 1 + mapset_len + 1) * sizeof(char);
302 (*out_list)[base + i] = (char *)G_malloc(len);
303 snprintf((*out_list)[base + i], len, "%s@%s", dirlist[i], mapset);
304 G_free(dirlist[i]);
305 }
307
308 return count;
309}
#define NULL
Definition ccmath.h:32
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition nme_in_mps.c:34
int G_recursive_copy(const char *, const char *)
Copy recursively source directory to destination directory.
Definition copy_dir.c:67
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_realloc(p, n)
Definition defs/gis.h:138
int G_unqualified_name(const char *, const char *, char *, char *)
Returns unqualified map name (without @ mapset)
Definition nme_in_mps.c:132
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_rename_file(const char *, const char *)
Rename a file or a directory in the filesystem.
Definition rename.c:29
#define G_malloc(n)
Definition defs/gis.h:136
int G_make_mapset_object_group(const char *)
Create directory for group of elements of a given type.
Definition mapset_msc.c:73
void void G_verbose_message(const char *,...) __attribute__((format(printf
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition file_name.c:59
char * G_fully_qualified_name(const char *, const char *)
Get fully qualified element name.
Definition nme_in_mps.c:99
int G_remove(const char *, const char *)
Remove a database file.
Definition remove.c:41
const char * G_get_mapset_name(int)
Get name of the n'th mapset from the current mapset search path.
Definition mapset_nme.c:42
char ** G_ls2(const char *, int *)
Stores a sorted directory listing in an array.
Definition ls.c:91
int G_debug(int, const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition gis/mapset.c:31
const char * I_find_signature2(I_SIGFILE_TYPE, const char *, const char *)
Find mapset containing signature (look but don't touch)
#define GMAPSET_MAX
Definition gis.h:194
#define GPATH_MAX
Definition gis.h:196
#define GNAME_MAX
Definition gis.h:193
#define HOST_DIRSEP
Definition gis.h:237
#define _(str)
Definition glocale.h:10
I_SIGFILE_TYPE
Definition imagery.h:193
@ I_SIGFILE_TYPE_LIBSVM
Definition imagery.h:196
@ I_SIGFILE_TYPE_SIGSET
Definition imagery.h:195
@ I_SIGFILE_TYPE_SIG
Definition imagery.h:194
int count
int I_signatures_rename(I_SIGFILE_TYPE type, const char *old_name, const char *new_name)
Rename a signature file.
void I_free_signatures_list(int count, char ***list)
Free memory allocated by I_signatures_list_by_type.
void I_get_signatures_dir(char *dir, I_SIGFILE_TYPE type)
Get signature directory.
int I_signatures_remove(I_SIGFILE_TYPE type, const char *name)
Remove a signature file.
int I_signatures_list_by_type(I_SIGFILE_TYPE type, const char *mapset, char ***out_list)
Get list of existing signatures by type.
int I_signatures_copy(I_SIGFILE_TYPE type, const char *old_name, const char *old_mapset, const char *new_name)
Copy a signature file.
void I_make_signatures_dir(I_SIGFILE_TYPE type)
Make signature dir.
const char * name
Definition named_colr.c:6
Definition manage.h:4
Definition path.h:15
#define access
Definition unistd.h:7