main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /****************************************************************************
  2. *
  3. * MODULE: g.mapsets
  4. * AUTHOR(S): Michael Shapiro (CERL),
  5. * Greg Koerper (ManTech Environmental Technology) (original contributors),
  6. * Glynn Clements <glynn gclements.plus.com>
  7. * Hamish Bowman <hamish_b yahoo.com>,
  8. * Markus Neteler <neteler itc.it>,
  9. * Moritz Lennert <mlennert club.worldonline.be>,
  10. * Martin Landa <landa.martin gmail.com>,
  11. * Huidae Cho <grass4u gmail.com>
  12. * PURPOSE: set current mapset path
  13. * COPYRIGHT: (C) 1994-2009, 2012 by the GRASS Development Team
  14. *
  15. * This program is free software under the GNU General
  16. * Public License (>=v2). Read the file COPYING that
  17. * comes with GRASS for details.
  18. *
  19. *****************************************************************************/
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <grass/gis.h>
  24. #include <grass/spawn.h>
  25. #include <grass/glocale.h>
  26. #include "local_proto.h"
  27. #define OP_UKN 0
  28. #define OP_SET 1
  29. #define OP_ADD 2
  30. #define OP_REM 3
  31. static void append_mapset(char **, const char *);
  32. int main(int argc, char *argv[])
  33. {
  34. int n, i;
  35. int skip;
  36. const char *cur_mapset, *mapset;
  37. char **ptr;
  38. char **tokens;
  39. int no_tokens;
  40. FILE *fp;
  41. char path_buf[GPATH_MAX];
  42. char *path, *fs;
  43. int operation, nchoices;
  44. char **mapset_name;
  45. int nmapsets;
  46. struct GModule *module;
  47. struct _opt {
  48. struct Option *mapset, *op, *fs;
  49. struct Flag *print, *list, *dialog;
  50. } opt;
  51. G_gisinit(argv[0]);
  52. module = G_define_module();
  53. G_add_keyword(_("general"));
  54. G_add_keyword(_("settings"));
  55. G_add_keyword(_("search path"));
  56. module->label = _("Modifies/prints the user's current mapset search path.");
  57. module->description = _("Affects the user's access to data existing "
  58. "under the other mapsets in the current location.");
  59. opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
  60. opt.mapset->required = YES;
  61. opt.mapset->multiple = YES;
  62. opt.mapset->description = _("Name(s) of existing mapset(s) to add/remove or set");
  63. opt.op = G_define_option();
  64. opt.op->key = "operation";
  65. opt.op->type = TYPE_STRING;
  66. opt.op->required = YES;
  67. opt.op->multiple = NO;
  68. opt.op->options = "set,add,remove";
  69. opt.op->description = _("Operation to be performed");
  70. opt.op->answer = "add";
  71. opt.fs = G_define_standard_option(G_OPT_F_SEP);
  72. opt.fs->label = _("Field separator for printing (-l and -p flags)");
  73. opt.fs->answer = "space";
  74. opt.fs->guisection = _("Print");
  75. opt.list = G_define_flag();
  76. opt.list->key = 'l';
  77. opt.list->description = _("List all available mapsets in alphabetical order");
  78. opt.list->guisection = _("Print");
  79. opt.list->suppress_required = YES;
  80. opt.print = G_define_flag();
  81. opt.print->key = 'p';
  82. opt.print->description = _("Print mapsets in current search path");
  83. opt.print->guisection = _("Print");
  84. opt.print->suppress_required = YES;
  85. opt.dialog = G_define_flag();
  86. opt.dialog->key = 's';
  87. opt.dialog->description = _("Launch mapset selection GUI dialog");
  88. opt.dialog->suppress_required = YES;
  89. path = NULL;
  90. mapset_name = NULL;
  91. nmapsets = nchoices = 0;
  92. if (G_parser(argc, argv))
  93. exit(EXIT_FAILURE);
  94. operation = OP_UKN;
  95. if (opt.mapset->answer && opt.op->answer) {
  96. switch(opt.op->answer[0]) {
  97. case 's':
  98. operation = OP_SET;
  99. break;
  100. case 'a':
  101. operation = OP_ADD;
  102. break;
  103. case 'r':
  104. operation = OP_REM;
  105. break;
  106. default:
  107. G_fatal_error(_("Unknown operation '%s'"), opt.op->answer);
  108. break;
  109. }
  110. }
  111. fs = G_option_to_separator(opt.fs);
  112. /* list available mapsets */
  113. if (opt.list->answer) {
  114. if (opt.print->answer)
  115. G_warning(_("Flag -%c ignored"), opt.print->key);
  116. if (opt.dialog->answer)
  117. G_warning(_("Flag -%c ignored"), opt.dialog->key);
  118. if (opt.mapset->answer)
  119. G_warning(_("Option <%s> ignored"), opt.mapset->key);
  120. mapset_name = get_available_mapsets(&nmapsets);
  121. list_available_mapsets((const char **)mapset_name, nmapsets, fs);
  122. exit(EXIT_SUCCESS);
  123. }
  124. if (opt.print->answer) {
  125. if (opt.dialog->answer)
  126. G_warning(_("Flag -%c ignored"), opt.dialog->key);
  127. if (opt.mapset->answer)
  128. G_warning(_("Option <%s> ignored"), opt.mapset->key);
  129. list_accessible_mapsets(fs);
  130. exit(EXIT_SUCCESS);
  131. }
  132. /* show GUI dialog */
  133. if (opt.dialog->answer) {
  134. if (opt.mapset->answer)
  135. G_warning(_("Option <%s> ignored"), opt.mapset->key);
  136. sprintf(path_buf, "%s/gui/wxpython/modules/mapsets_picker.py", G_gisbase());
  137. G_spawn(getenv("GRASS_PYTHON"), "mapsets_picker.py", path_buf, NULL);
  138. exit(EXIT_SUCCESS);
  139. }
  140. cur_mapset = G_mapset();
  141. /* modify search path */
  142. if (operation == OP_SET) {
  143. int cur_found;
  144. cur_found = FALSE;
  145. for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) {
  146. mapset = substitute_mapset(*ptr);
  147. if (G_mapset_permissions(mapset) < 0)
  148. G_fatal_error(_("Mapset <%s> not found"), mapset);
  149. if (strcmp(mapset, cur_mapset) == 0)
  150. cur_found = TRUE;
  151. nchoices++;
  152. append_mapset(&path, mapset);
  153. }
  154. if (!cur_found)
  155. G_warning(_("Current mapset (<%s>) must always included in the search path"),
  156. cur_mapset);
  157. }
  158. else if (operation == OP_ADD) {
  159. /* add to existing search path */
  160. const char *oldname;
  161. if (path) {
  162. G_free(path);
  163. path = NULL;
  164. }
  165. /* read existing mapsets from SEARCH_PATH */
  166. for (n = 0; (oldname = G_get_mapset_name(n)); n++)
  167. append_mapset(&path, oldname);
  168. /* fetch and add new mapsets from param list */
  169. for (ptr = opt.mapset->answers; *ptr != NULL; ptr++) {
  170. mapset = substitute_mapset(*ptr);
  171. if (G_is_mapset_in_search_path(mapset)) {
  172. G_message(_("Mapset <%s> already in the path"), mapset);
  173. continue;
  174. }
  175. if (G_mapset_permissions(mapset) < 0)
  176. G_fatal_error(_("Mapset <%s> not found"), mapset);
  177. else
  178. G_verbose_message(_("Mapset <%s> added to search path"),
  179. mapset);
  180. nchoices++;
  181. append_mapset(&path, mapset);
  182. }
  183. }
  184. else if (operation == OP_REM) {
  185. /* remove from existing search path */
  186. const char *oldname;
  187. int found;
  188. if (path) {
  189. G_free(path);
  190. path = NULL;
  191. }
  192. /* read existing mapsets from SEARCH_PATH */
  193. for (n = 0; (oldname = G_get_mapset_name(n)); n++) {
  194. found = FALSE;
  195. for (ptr = opt.mapset->answers; *ptr && !found; ptr++)
  196. mapset = substitute_mapset(*ptr);
  197. if (strcmp(oldname, mapset) == 0)
  198. found = TRUE;
  199. if (found) {
  200. if (strcmp(oldname, cur_mapset) == 0)
  201. G_warning(_("Current mapset (<%s>) must always included in the search path"),
  202. cur_mapset);
  203. else
  204. G_verbose_message(_("Mapset <%s> removed from search path"),
  205. oldname);
  206. continue;
  207. }
  208. nchoices++;
  209. append_mapset(&path, oldname);
  210. }
  211. }
  212. /* stuffem sets nchoices */
  213. if (nchoices == 0) {
  214. G_important_message(_("Search path not modified"));
  215. if (path)
  216. G_free(path);
  217. if (nmapsets) {
  218. for(nmapsets--; nmapsets >= 0; nmapsets--)
  219. G_free(mapset_name[nmapsets]);
  220. G_free(mapset_name);
  221. }
  222. exit(EXIT_SUCCESS);
  223. }
  224. /* note I'm assuming that mapsets cannot have ' 's in them */
  225. tokens = G_tokenize(path, " ");
  226. fp = G_fopen_new("", "SEARCH_PATH");
  227. if (!fp)
  228. G_fatal_error(_("Unable to open SEARCH_PATH for write"));
  229. /*
  230. * make sure current mapset is specified in the list if not add it
  231. * to the head of the list
  232. */
  233. skip = 0;
  234. for (n = 0; n < nchoices; n++)
  235. if (strcmp(cur_mapset, tokens[n]) == 0) {
  236. skip = 1;
  237. break;
  238. }
  239. if (!skip) {
  240. fprintf(fp, "%s\n", cur_mapset);
  241. }
  242. /*
  243. * output the list, removing duplicates
  244. */
  245. no_tokens = G_number_of_tokens(tokens);
  246. for (n = 0; n < no_tokens; n++) {
  247. skip = 0;
  248. for (i = n; i < no_tokens; i++) {
  249. if (i != n) {
  250. if (strcmp(tokens[i], tokens[n]) == 0)
  251. skip = 1;
  252. }
  253. }
  254. if (!skip)
  255. fprintf(fp, "%s\n", tokens[n]);
  256. }
  257. fclose(fp);
  258. G_free_tokens(tokens);
  259. if (path)
  260. G_free(path);
  261. if (nmapsets) {
  262. for(nmapsets--; nmapsets >= 0; nmapsets--)
  263. G_free(mapset_name[nmapsets]);
  264. G_free(mapset_name);
  265. }
  266. exit(EXIT_SUCCESS);
  267. }
  268. void append_mapset(char **path, const char *mapset)
  269. {
  270. int len = (*path == NULL ? 0 : strlen(*path));
  271. *path = (char *)G_realloc(*path, len + strlen(mapset) + 2);
  272. if (!len)
  273. *path[0] = '\0';
  274. strcat(*path, mapset);
  275. strcat(*path, " ");
  276. return;
  277. }