123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*!
- \file lib/imagery/manage_sinatures.c
- \brief Imagery Library - Signature file management functions
- (C) 2021 by Maris Nartiss and the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- \author Maris Nartiss
- */
- #include <unistd.h>
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/imagery.h>
- #include <grass/glocale.h>
- /*!
- \brief Get signature directory
- The directory will be in a form "signatures/<type>".
- \param dir [GNAME_MAX] allocated string buffer
- \param type I_SIGFILE_TYPE
- */
- void I_get_signatures_dir(char *dir, I_SIGFILE_TYPE type)
- {
- if (type == I_SIGFILE_TYPE_SIG) {
- sprintf(dir, "signatures%csig", HOST_DIRSEP);
- }
- else if (type == I_SIGFILE_TYPE_SIGSET) {
- sprintf(dir, "signatures%csigset", HOST_DIRSEP);
- }
- else {
- G_fatal_error("Programming error: unknown signature file type");
- }
- }
- /*!
- \brief Make signature dir
- Creates directories for storage of signature files of specified type.
- E.g. "<location>/<mapset>/signatures/<type>/"
- \param type I_SIGFILE_TYPE
- */
- void I_make_signatures_dir(I_SIGFILE_TYPE type)
- {
- char dir[GNAME_MAX];
- G_make_mapset_object_group("signatures");
- I_get_signatures_dir(dir, type);
- G_make_mapset_object_group(dir);
- }
- static int list_by_type(I_SIGFILE_TYPE, const char *, int, char ***);
- /*!
- * \brief Remove a signature file
- *
- * If removal fails, prints a warning and returns 1.
- * It is safe to pass fully qualified names.
- *
- * \param type I_SIGFILE_TYPE signature type
- * \param name of signature to remove
- * \return 0 on success
- * \return 1 on failure
- */
- int I_signatures_remove(I_SIGFILE_TYPE type, const char *name)
- {
- char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
- char dir[GNAME_MAX];
- G_debug(1, "I_signatures_remove(%d, %s);", type, name);
- /* Remove only if file is in the current mapset */
- if (G_name_is_fully_qualified(name, xname, xmapset) &&
- strcmp(xmapset, G_mapset()) != 0) {
- G_warning(_("%s is not in the current mapset (%s)"), name,
- G_mapset());
- return 1;
- }
- if (I_find_signature2(type, name, G_mapset())) {
- I_get_signatures_dir(dir, type);
- if (G_remove(dir, name) == 1) {
- G_verbose_message(_("%s removed"), name);
- return 0;
- }
- G_warning(_("Unable to remove %s signature"), name);
- }
- else
- G_warning(_("%s is missing"), name);
- return 1;
- }
- /*!
- * \brief Copy a signature file
- *
- * If copy fails, prints warning messages and returns 1.
- * It is safe to pass fully qualified names.
- *
- * \param type I_SIGFILE_TYPE signature type
- * \param name of old signature
- * \param mapset of old signature
- * \param name of new signature
- * \return 0 on success
- * \return 1 on failure
- */
- int I_signatures_copy(I_SIGFILE_TYPE type, const char *old_name,
- const char *old_mapset, const char *new_name)
- {
- char sname[GNAME_MAX], tname[GNAME_MAX], tmapset[GMAPSET_MAX],
- xmapset[GMAPSET_MAX];
- char dir[GNAME_MAX];
- const char *smapset;
- char old_path[GPATH_MAX], new_path[GPATH_MAX];
- G_debug(1, "I_signatures_copy(%d, %s@%s, %s);", type, old_name,
- old_mapset, new_name);
- /* Copy only if mapset of new name is the current mapset */
- if (G_name_is_fully_qualified(new_name, tname, tmapset)) {
- if (strcmp(tmapset, G_mapset()) != 0) {
- G_warning(_("%s is not in the current mapset (%s)"), new_name,
- G_mapset());
- return 1;
- }
- }
- else
- strcat(tname, new_name);
- smapset = I_find_signature2(type, old_name, old_mapset);
- if (!smapset) {
- G_warning(_("%s is missing"), old_name);
- return 1;
- }
- G_unqualified_name(old_name, NULL, sname, xmapset);
- I_make_signatures_dir(type);
- I_get_signatures_dir(dir, type);
- /* Note – we need whole directory not just an element in it thus
- G_file_name and not G_file_name_misc */
- G_file_name(old_path, dir, sname, smapset);
- G_file_name(new_path, dir, tname, G_mapset());
- if (G_recursive_copy(old_path, new_path) != 0) {
- G_warning(_("Unable to copy <%s> to current mapset as <%s>"),
- G_fully_qualified_name(old_name, smapset), tname);
- return 1;
- }
- return 0;
- }
- /*!
- * \brief Rename a signature file
- *
- * If rename fails, prints warning messages and returns 1.
- * It is safe to pass fully qualified names.
- *
- * \param type I_SIGFILE_TYPE signature type
- * \param name of old signature
- * \param name of new signature
- * \return 0 on success
- * \return 1 on failure
- */
- int I_signatures_rename(I_SIGFILE_TYPE type, const char *old_name,
- const char *new_name)
- {
- char sname[GNAME_MAX], tname[GNAME_MAX], tmapset[GMAPSET_MAX];
- char dir[GNAME_MAX];
- const char *smapset;
- char old_path[GPATH_MAX], new_path[GPATH_MAX];
- G_debug(1, "I_signatures_rename(%d, %s, %s);", type, old_name, new_name);
- /* Rename only if source and destination mapset is the current mapset */
- if (G_name_is_fully_qualified(old_name, sname, tmapset)) {
- if (strcmp(tmapset, G_mapset()) != 0) {
- G_warning(_("%s is not in the current mapset (%s)"), old_name,
- G_mapset());
- return 1;
- }
- }
- else
- strcat(sname, old_name);
- if (G_name_is_fully_qualified(new_name, tname, tmapset)) {
- if (strcmp(tmapset, G_mapset()) != 0) {
- G_warning(_("%s is not in the current mapset (%s)"), new_name,
- G_mapset());
- return 1;
- }
- }
- else
- strcat(tname, new_name);
- smapset = I_find_signature2(type, old_name, tmapset);
- if (!smapset) {
- G_warning(_("%s is missing"), old_name);
- return 1;
- }
- I_get_signatures_dir(dir, type);
- /* Note – we need whole directory not just an element in it thus
- G_file_name and not G_file_name_misc */
- G_file_name(old_path, dir, sname, tmapset);
- G_file_name(new_path, dir, tname, tmapset);
- if (G_rename_file(old_path, new_path) != 0) {
- G_warning(_("Unable to rename <%s> to <%s>"), old_name, new_name);
- return 1;
- }
- return 0;
- }
- /*!
- * \brief Get list of existing signatures by type
- *
- * Fills passed list with fully qualified names of existing signatures.
- *
- * If no mapset is passed, all mapsets in the search path are used.
- * If no signatures are found, returns 0 and list is set to NULL.
- *
- * The function will assign memory for the list. It is up to callee to
- * free the memory of each list item and the list itself.
- *
- * \param type I_SIGFILE_TYPE signature type
- * \param mapset optional mapset to search in or NULL
- * \param pointer to array of found signature strings or NULL if none found
- * \return count of signature strings in the array
- */
- int I_signatures_list_by_type(I_SIGFILE_TYPE type, const char *mapset,
- char ***out_list)
- {
- int base = 0;
- *out_list = NULL;
- if (mapset == NULL) {
- for (int n = 0; (mapset = G_get_mapset_name(n)); n++) {
- base += list_by_type(type, mapset, base, out_list);
- }
- }
- else {
- base += list_by_type(type, mapset, base, out_list);
- }
- return base;
- }
- /*!
- * \brief Free memory allocated by I_signatures_list_by_type
- *
- * Calls G_free for all list items returned by I_signatures_list_by_type()
- * Sets pointer to NULL to prevent accidental use after free.
- *
- * \param int Return value of I_signatures_list_by_type()
- * \param pointer to array filled by I_signatures_list_by_type()
- */
- void I_free_signatures_list(int count, char ***list)
- {
- for (int n = 0; n < count; n++) {
- G_free((*list)[n]);
- }
- G_free(*list);
- *list = NULL;
- }
- static int list_by_type(I_SIGFILE_TYPE type, const char *mapset, int base,
- char ***out_list)
- {
- int count = 0;
- char path[GPATH_MAX];
- char dir[GNAME_MAX];
- char **dirlist;
- I_get_signatures_dir(dir, type);
- G_file_name(path, dir, "", mapset);
- if (access(path, 0) != 0) {
- return count;
- }
- dirlist = G_ls2(path, &count);
- if (count == 0)
- return count;
- /* Make items fully qualified names */
- int mapset_len = strlen(mapset);
- *out_list =
- (char **)G_realloc(*out_list, (base + count) * sizeof(char *));
- for (int i = 0; i < count; i++) {
- (*out_list)[base + i] =
- (char *)G_malloc((strlen(dirlist[i]) + 1 + mapset_len + 1) *
- sizeof(char));
- sprintf((*out_list)[base + i], "%s@%s", dirlist[i], mapset);
- }
- return count;
- }
|