main.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /****************************************************************
  2. *
  3. * MODULE: g.mapset
  4. *
  5. * AUTHOR(S): Radim Blazek
  6. * Joel Pitt, joel.pitt@gmail.com
  7. *
  8. * PURPOSE: Change current mapset, optionally adding it
  9. * if the mapset does not exist.
  10. *
  11. * COPYRIGHT: (C) 2004, 2010-2011 by the GRASS Development Team
  12. *
  13. * This program is free software under the
  14. * GNU General Public License (>=v2).
  15. * Read the file COPYING that comes with GRASS
  16. * for details.
  17. *
  18. **************************************************************/
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <grass/gis.h>
  24. #include <grass/glocale.h>
  25. #include <grass/spawn.h>
  26. int main(int argc, char *argv[])
  27. {
  28. int ret;
  29. struct GModule *module;
  30. struct {
  31. struct Option *gisdbase, *location, *mapset;
  32. } opt;
  33. struct {
  34. struct Flag *add, *list, *curr;
  35. } flag;
  36. const char *gisdbase_old, *location_old, *mapset_old;
  37. const char *gisdbase_new, *location_new, *mapset_new;
  38. const char *gis_lock;
  39. char *mapset_old_path, *mapset_new_path;
  40. char *lock_prog;
  41. const char *shell;
  42. char path[GPATH_MAX];
  43. G_gisinit(argv[0]);
  44. module = G_define_module();
  45. G_add_keyword(_("general"));
  46. G_add_keyword(_("settings"));
  47. module->label = _("Changes/reports current mapset.");
  48. module->description = _("Optionally create new mapset or list available mapsets in given location.");
  49. opt.mapset = G_define_standard_option(G_OPT_M_MAPSET);
  50. opt.mapset->required = YES;
  51. opt.mapset->description = _("Name of mapset where to switch");
  52. opt.mapset->guisection = _("Mapset");
  53. opt.mapset->gisprompt = "new,mapset,mapset";
  54. opt.location = G_define_standard_option(G_OPT_M_LOCATION);
  55. opt.location->guisection = _("Mapset");
  56. opt.gisdbase = G_define_standard_option(G_OPT_M_DBASE);
  57. opt.gisdbase->guisection = _("Mapset");
  58. flag.add = G_define_flag();
  59. flag.add->key = 'c';
  60. flag.add->description = _("Create mapset if it doesn't exist");
  61. flag.add->answer = FALSE;
  62. flag.add->guisection = _("Create");
  63. flag.list = G_define_flag();
  64. flag.list->key = 'l';
  65. flag.list->suppress_required = YES;
  66. flag.list->description = _("List available mapsets and exit");
  67. flag.list->guisection = _("Print");
  68. flag.curr = G_define_flag();
  69. flag.curr->key = 'p';
  70. flag.curr->suppress_required = YES;
  71. flag.curr->description = _("Print current mapset and exit");
  72. flag.curr->guisection = _("Print");
  73. if (G_parser(argc, argv))
  74. exit(EXIT_FAILURE);
  75. /* Store original values */
  76. gisdbase_old = G_getenv_nofatal("GISDBASE");
  77. location_old = G_getenv_nofatal("LOCATION_NAME");
  78. mapset_old = G_getenv_nofatal("MAPSET");
  79. if (flag.curr->answer) {
  80. fprintf(stdout, "%s\n", mapset_old);
  81. exit(EXIT_SUCCESS);
  82. }
  83. G_asprintf(&mapset_old_path, "%s/%s/%s", gisdbase_old, location_old,
  84. mapset_old);
  85. /* New values */
  86. if (opt.gisdbase->answer)
  87. gisdbase_new = opt.gisdbase->answer;
  88. else
  89. gisdbase_new = gisdbase_old;
  90. if (opt.location->answer)
  91. location_new = opt.location->answer;
  92. else
  93. location_new = location_old;
  94. if (flag.list->answer) {
  95. char **ms;
  96. int nmapsets;
  97. G_setenv_nogisrc("LOCATION_NAME", location_new);
  98. G_setenv_nogisrc("GISDBASE", gisdbase_new);
  99. ms = G_get_available_mapsets();
  100. for (nmapsets = 0; ms[nmapsets]; nmapsets++) {
  101. if (G_mapset_permissions(ms[nmapsets]) > 0) {
  102. fprintf(stdout, "%s ", ms[nmapsets]);
  103. }
  104. }
  105. fprintf(stdout, "\n");
  106. exit(EXIT_SUCCESS);
  107. }
  108. mapset_new = opt.mapset->answer;
  109. G_asprintf(&mapset_new_path, "%s/%s/%s", gisdbase_new, location_new,
  110. mapset_new);
  111. /* TODO: this should be checked better (repeated '/' etc.) */
  112. if (strcmp(mapset_old_path, mapset_new_path) == 0) {
  113. G_warning(_("<%s> is already the current mapset"), mapset_new);
  114. exit(EXIT_SUCCESS);
  115. }
  116. /* Check if the mapset exists and user is owner */
  117. G_debug(2, "check : %s", mapset_new_path);
  118. ret = G_mapset_permissions2(gisdbase_new, location_new, mapset_new);
  119. switch (ret) {
  120. case 0:
  121. G_fatal_error(_("You don't have permission to use the mapset <%s>"),
  122. mapset_new);
  123. break;
  124. case -1:
  125. if (flag.add->answer == TRUE) {
  126. G_debug(2, "Mapset <%s> doesn't exist, attempting to create it",
  127. mapset_new);
  128. if (G_make_mapset(gisdbase_new, location_new, mapset_new) != 0)
  129. G_fatal_error(_("Unable to create new mapset <%s>"), mapset_new);
  130. }
  131. else
  132. G_fatal_error(_("Mapset <%s> does not exist. Use -c flag to create it."),
  133. mapset_new);
  134. break;
  135. default:
  136. break;
  137. }
  138. /* Check if the mapset is in use */
  139. gis_lock = getenv("GIS_LOCK");
  140. if (!gis_lock)
  141. G_fatal_error(_("Unable to read GIS_LOCK environment variable"));
  142. G_asprintf(&lock_prog, "%s/etc/lock", G_gisbase());
  143. sprintf(path, "%s/.gislock", mapset_new_path);
  144. G_debug(2, "%s", path);
  145. ret = G_spawn(lock_prog, lock_prog, path, gis_lock, NULL);
  146. G_debug(2, "lock result = %d", ret);
  147. G_free(lock_prog);
  148. /* Warning: the value returned by system() is not that returned by exit() in executed program
  149. * e.g. exit(1) -> 256 (multiplied by 256) */
  150. if (ret != 0) {
  151. /* .gislock does not exist */
  152. if (access(path, F_OK) != 0)
  153. G_fatal_error(_("Lock file of mapset <%s> cannot be checked"),
  154. mapset_new);
  155. else
  156. G_fatal_error(_("There appears to be an active GRASS session in selected mapset <%s>"),
  157. mapset_new);
  158. }
  159. /* Clean temporary directory */
  160. sprintf(path, "%s/etc/clean_temp", G_gisbase());
  161. G_verbose_message(_("Cleaning up temporary files..."));
  162. G_spawn(path, "clean_temp", NULL);
  163. /* Reset variables */
  164. G_setenv("GISDBASE", gisdbase_new);
  165. G_setenv("LOCATION_NAME", location_new);
  166. G_setenv("MAPSET", mapset_new);
  167. /* Remove old lock */
  168. sprintf(path, "%s/.gislock", mapset_old_path);
  169. remove(path);
  170. G_free(mapset_old_path);
  171. shell = getenv("SHELL");
  172. /* For bash and zsh, we support switching of history, tcsh not (yet). */
  173. if (shell && (strstr(shell, "bash") || strstr(shell, "zsh"))) {
  174. G_important_message(_("Mapset switched."));
  175. }
  176. else {
  177. G_important_message(_("Mapset switched. Your shell continues "
  178. "to use the history for the old mapset"));
  179. }
  180. if (shell && strstr(shell, "tcsh")) {
  181. G_important_message(_("You can switch the history by commands:\n"
  182. "history -S; history -L %s/.history; setenv histfile=%s/.history"),
  183. mapset_new_path, mapset_new_path);
  184. }
  185. G_verbose_message(_("Your current mapset is <%s>"), mapset_new);
  186. G_free(mapset_new_path);
  187. return (EXIT_SUCCESS);
  188. }