GRASS Programmer's Manual 6.4.1(2011)
|
00001 00017 #include <signal.h> 00018 #include <unistd.h> 00019 #include <stdlib.h> 00020 #include <unistd.h> /* for sleep() */ 00021 #include <string.h> 00022 #include <grass/gis.h> 00023 #include <grass/glocale.h> 00024 00025 #define ENV struct env 00026 00027 ENV { 00028 int loc; 00029 char *name; 00030 char *value; 00031 }; 00032 00033 static ENV *env = NULL; 00034 static ENV *env2 = NULL; 00035 static int count = 0; 00036 static int count2 = 0; 00037 static int init[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00038 static char *gisrc = NULL; 00039 static int varmode = G_GISRC_MODE_FILE; /* where find/store variables */ 00040 00041 static int read_env(int); 00042 static int set_env(const char *, const char *, int); 00043 static int unset_env(const char *, int); 00044 static char *get_env(const char *, int); 00045 static int write_env(int); 00046 static FILE *open_env(const char *, int); 00047 00059 void G_set_gisrc_mode(int mode) 00060 { 00061 varmode = mode; 00062 } 00063 00071 int G_get_gisrc_mode(void) 00072 { 00073 return (varmode); 00074 } 00075 00076 static int read_env(int loc) 00077 { 00078 char buf[200]; 00079 char *name; 00080 char *value; 00081 00082 FILE *fd; 00083 00084 if (loc == G_VAR_GISRC && varmode == G_GISRC_MODE_MEMORY) 00085 return 0; /* don't use file for GISRC */ 00086 00087 if (init[loc]) 00088 return 1; 00089 00090 init[loc] = 1; 00091 00092 if ((fd = open_env("r", loc))) { 00093 while (G_getl2(buf, sizeof buf, fd)) { 00094 for (name = value = buf; *value; value++) 00095 if (*value == ':') 00096 break; 00097 if (*value == 0) 00098 continue; 00099 00100 *value++ = 0; 00101 G_strip(name); 00102 G_strip(value); 00103 if (*name && *value) 00104 set_env(name, value, loc); 00105 } 00106 fclose(fd); 00107 } 00108 00109 return 0; 00110 } 00111 00112 static int set_env(const char *name, const char *value, int loc) 00113 { 00114 int n; 00115 int empty; 00116 char *tv; 00117 00118 /* if value is NULL or empty string, convert into an unsetenv() */ 00119 if (!value || !strlen(value)) { 00120 unset_env(name, loc); 00121 return 0; 00122 } 00123 00124 tv = G_store(value); 00125 G_strip(tv); 00126 if (*tv == 0) { 00127 G_free(tv); 00128 unset_env(name, loc); 00129 return 1; 00130 } 00131 00132 /* 00133 * search the array 00134 * keep track of first empty slot 00135 * and look for name in the environment 00136 */ 00137 empty = -1; 00138 for (n = 0; n < count; n++) 00139 if (!env[n].name) /* mark empty slot found */ 00140 empty = n; 00141 else if (strcmp(env[n].name, name) == 0 && env[n].loc == loc) { 00142 env[n].value = tv; 00143 return 1; 00144 } 00145 00146 /* add name to env: to empty slot if any */ 00147 if (empty >= 0) { 00148 env[empty].loc = loc; 00149 env[empty].name = G_store(name); 00150 env[empty].value = tv; 00151 return 0; 00152 } 00153 00154 /* must increase the env list and add in */ 00155 if ((n = count++)) 00156 env = (ENV *) G_realloc((char *)env, count * sizeof(ENV)); 00157 else 00158 env = (ENV *) G_malloc(sizeof(ENV)); 00159 00160 env[n].loc = loc; 00161 env[n].name = G_store(name); 00162 env[n].value = tv; 00163 00164 return 0; 00165 } 00166 00167 static int unset_env(const char *name, int loc) 00168 { 00169 int n; 00170 00171 for (n = 0; n < count; n++) 00172 if (env[n].name && (strcmp(env[n].name, name) == 0) && 00173 env[n].loc == loc) { 00174 G_free(env[n].name); 00175 env[n].name = 0; 00176 return 1; 00177 } 00178 00179 return 0; 00180 } 00181 00182 static char *get_env(const char *name, int loc) 00183 { 00184 int n; 00185 00186 for (n = 0; n < count; n++) { 00187 if (env[n].name && (strcmp(env[n].name, name) == 0) && 00188 env[n].loc == loc) 00189 return env[n].value; 00190 } 00191 00192 return NULL; 00193 } 00194 00195 static int write_env(int loc) 00196 { 00197 FILE *fd; 00198 int n; 00199 char dummy[2]; 00200 void (*sigint) () 00201 #ifdef SIGQUIT 00202 , (*sigquit) () 00203 #endif 00204 ; 00205 00206 if (loc == G_VAR_GISRC && varmode == G_GISRC_MODE_MEMORY) 00207 return 0; /* don't use file for GISRC */ 00208 00209 /* 00210 * THIS CODE NEEDS TO BE PROTECTED FROM INTERRUPTS 00211 * If interrupted, it can wipe out the GISRC file 00212 */ 00213 sigint = signal(SIGINT, SIG_IGN); 00214 #ifdef SIGQUIT 00215 sigquit = signal(SIGQUIT, SIG_IGN); 00216 #endif 00217 if ((fd = open_env("w", loc))) { 00218 for (n = 0; n < count; n++) 00219 if (env[n].name && env[n].value && env[n].loc == loc 00220 && (sscanf(env[n].value, "%1s", dummy) == 1)) 00221 fprintf(fd, "%s: %s\n", env[n].name, env[n].value); 00222 fclose(fd); 00223 } 00224 00225 signal(SIGINT, sigint); 00226 #ifdef SIGQUIT 00227 signal(SIGQUIT, sigquit); 00228 #endif 00229 00230 return 0; 00231 } 00232 00233 static FILE *open_env(const char *mode, int loc) 00234 { 00235 char buf[1000]; 00236 00237 if (loc == G_VAR_GISRC) { 00238 if (!gisrc) 00239 gisrc = getenv("GISRC"); 00240 00241 if (!gisrc) { 00242 G_fatal_error(_("GISRC - variable not set")); 00243 return (NULL); 00244 } 00245 strcpy(buf, gisrc); 00246 } 00247 else if (loc == G_VAR_MAPSET) { 00248 /* Warning: G_VAR_GISRC must be previously read -> */ 00249 /* TODO: better place ? */ 00250 read_env(G_VAR_GISRC); 00251 00252 sprintf(buf, "%s/%s/VAR", G_location_path(), G_mapset()); 00253 } 00254 00255 return fopen(buf, mode); 00256 } 00257 00267 char *G_getenv(const char *name) 00268 { 00269 char *value; 00270 00271 if ((value = G__getenv(name))) 00272 return value; 00273 00274 G_fatal_error(_("G_getenv(): Variable %s not set"), name); 00275 return NULL; 00276 } 00277 00293 char *G_getenv2(const char *name, int loc) 00294 { 00295 char *value; 00296 00297 if ((value = G__getenv2(name, loc))) 00298 return value; 00299 00300 G_fatal_error(_("%s not set"), name); 00301 return NULL; 00302 } 00303 00312 char *G__getenv(const char *name) 00313 { 00314 if (strcmp(name, "GISBASE") == 0) 00315 return getenv(name); 00316 00317 read_env(G_VAR_GISRC); 00318 00319 return get_env(name, G_VAR_GISRC); 00320 } 00321 00331 char *G__getenv2(const char *name, int loc) 00332 { 00333 if (strcmp(name, "GISBASE") == 0) 00334 return getenv(name); 00335 00336 read_env(loc); 00337 00338 return get_env(name, loc); 00339 } 00340 00352 int G_setenv(const char *name, const char *value) 00353 { 00354 read_env(G_VAR_GISRC); 00355 set_env(name, value, G_VAR_GISRC); 00356 write_env(G_VAR_GISRC); 00357 return 0; 00358 } 00359 00372 int G_setenv2(const char *name, const char *value, int loc) 00373 { 00374 read_env(loc); 00375 set_env(name, value, loc); 00376 write_env(loc); 00377 return 0; 00378 } 00379 00388 int G__setenv(const char *name, const char *value) 00389 { 00390 read_env(G_VAR_GISRC); 00391 set_env(name, value, G_VAR_GISRC); 00392 return 0; 00393 } 00394 00404 int G__setenv2(const char *name, const char *value, int loc) 00405 { 00406 read_env(loc); 00407 set_env(name, value, loc); 00408 return 0; 00409 } 00410 00420 int G_unsetenv(const char *name) 00421 { 00422 read_env(G_VAR_GISRC); 00423 unset_env(name, G_VAR_GISRC); 00424 write_env(G_VAR_GISRC); 00425 00426 return 0; 00427 } 00428 00438 int G_unsetenv2(const char *name, int loc) 00439 { 00440 read_env(loc); 00441 unset_env(name, loc); 00442 write_env(loc); 00443 00444 return 0; 00445 } 00446 00454 int G__write_env(void) 00455 { 00456 if (init[G_VAR_GISRC]) 00457 write_env(G_VAR_GISRC); 00458 00459 return 0; 00460 } 00461 00476 char *G__env_name(int n) 00477 { 00478 int i; 00479 00480 read_env(G_VAR_GISRC); 00481 if (n >= 0) 00482 for (i = 0; i < count; i++) 00483 if (env[i].name && *env[i].name && (n-- == 0)) 00484 return env[i].name; 00485 return NULL; 00486 } 00487 00495 int G__read_env(void) 00496 { 00497 init[G_VAR_GISRC] = 0; 00498 00499 return 0; 00500 } 00501 00509 int G__set_gisrc_file(const char *name) 00510 { 00511 gisrc = NULL; 00512 if (name && *name) 00513 gisrc = G_store(name); 00514 00515 return 0; 00516 } 00517 00525 char *G__get_gisrc_file(void) 00526 { 00527 return gisrc; 00528 } 00529 00537 int G__create_alt_env(void) 00538 { 00539 int i; 00540 00541 /* copy env to env2 */ 00542 env2 = env; 00543 count2 = count; 00544 env = NULL; 00545 count = 0; 00546 00547 for (i = 0; i < count2; i++) 00548 if (env2[count].name) 00549 set_env(env2[count].name, env2[count].value, G_VAR_GISRC); 00550 00551 return 0; 00552 } 00553 00561 int G__switch_env(void) 00562 { 00563 ENV *tmp; 00564 int n; 00565 00566 n = count; 00567 tmp = env; 00568 00569 env = env2; 00570 count = count2; 00571 00572 env2 = tmp; 00573 count2 = n; 00574 00575 return 0; 00576 }