132 #include <postgres.h>
134 #include "utils/guc.h"
135 #include "utils/memutils.h"
137 #include "../../postgis_config.h"
138 #include "lwgeom_pg.h"
146 # define __attribute__ (x)
160 #define RT_MSG_MAXLEN 256
187 result = repalloc(mem, size);
213 ereport(ERROR, (errmsg_internal(
"%s", errmsg)));
227 ereport(NOTICE, (errmsg_internal(
"%s", msg)));
241 ereport(DEBUG1, (errmsg_internal(
"%s", msg)));
249 snprintf(optname, 128,
"postgis.%s", varname);
251 optvalue = GetConfigOptionByName(optname, NULL,
true);
252 if (optvalue && strlen(optvalue) == 0)
265 #if POSTGIS_GDAL_VERSION < 23
275 const char * gdaloption;
276 const char *
const gdaloptions[] = {
283 "aws_secret_access_key",
286 "aws_virtual_hosting",
289 "gs_secret_access_key",
292 "goa2_client_secret",
293 "cpl_curl_enable_vsimem",
297 "gdal_http_connecttimeout",
299 "gdal_http_header_file",
300 "gdal_http_low_speed_time",
301 "gdal_http_low_speed_limit",
302 "gdal_http_max_retry",
305 "gdal_http_proxyuserpwd",
306 "gdal_http_retry_delay",
309 "gdal_http_unsafessl",
310 "gdal_http_useragent",
311 "gdal_disable_readdir_on_open",
316 "cpl_vsil_curl_use_head",
317 "cpl_vsil_curl_use_s3_redirect",
318 "cpl_vsil_curl_max_ranges",
319 "cpl_vsil_curl_use_cache",
320 "cpl_vsil_curl_allowed_filename",
321 "cpl_vsil_curl_allowed_extensions",
322 "cpl_vsil_curl_slow_get_size",
327 const char *
const * gdaloptionsptr = gdaloptions;
330 while((gdaloption = *gdaloptionsptr++))
347 CPLXMLNode *root, *optNode;
348 const char *xml = VSIGetFileSystemOptions(vsiname);
351 root = CPLParseXMLString(xml);
353 elog(ERROR,
"%s: Unable to read options for VSI %s", __func__, vsiname);
356 optNode = CPLSearchXMLNode(root,
"Option");
358 CPLDestroyXMLNode(root);
359 elog(ERROR,
"%s: Unable to find <Option> in VSI XML %s", __func__, vsiname);
364 const char *option = CPLGetXMLValue(optNode,
"name", NULL);
366 char *optionstr = pstrdup(option);
367 char *ptr = optionstr;
372 *ptr = tolower(*ptr);
375 elog(DEBUG4,
"GDAL %s option: %s", vsiname, optionstr);
378 optNode = optNode->psNext;
380 CPLDestroyXMLNode(root);
386 const char * vsiname;
387 const char *
const vsilist[] = {
399 const char *
const * vsilistptr = vsilist;
402 while((vsiname = *vsilistptr++))
417 const char *found = NULL;
420 memset(olist, 0,
sizeof(olist));
421 if (!newval || !*newval)
423 newoptions = pstrdup(*newval);
429 elog(DEBUG5,
"%s: processing VSI options: %s", __func__, newoptions);
432 if (olist_sz % 2 != 0)
435 for (i = 0; i < olist_sz; i += 2)
440 elog(WARNING,
"'%s' is not a legal VSI network file option", olist[i]);
479 CPLSetConfigOption(
"GDAL_DATA", newpath);
490 char **enabled_drivers_array = NULL;
491 uint32_t enabled_drivers_count = 0;
492 bool *enabled_drivers_found = NULL;
493 char *gdal_skip = NULL;
502 if (enabled_drivers == NULL)
505 elog(DEBUG4,
"Enabling GDAL drivers: %s", enabled_drivers);
509 GDALDestroyDriverManager();
510 CPLSetConfigOption(
"GDAL_SKIP", NULL);
515 enabled_drivers_array =
rtpg_strsplit(enabled_drivers,
" ", &enabled_drivers_count);
516 enabled_drivers_found = palloc(
sizeof(
bool) * enabled_drivers_count);
517 memset(enabled_drivers_found,
FALSE,
sizeof(
bool) * enabled_drivers_count);
523 for (i = 0; i < enabled_drivers_count; i++) {
525 enabled_drivers_found[i] =
TRUE;
531 for (i = 0; i < enabled_drivers_count; i++) {
533 enabled_drivers_found[i] =
TRUE;
538 else if (strstr(enabled_drivers,
GDAL_VSICURL) != NULL) {
539 for (i = 0; i < enabled_drivers_count; i++) {
540 if (strstr(enabled_drivers_array[i],
GDAL_VSICURL) != NULL) {
541 enabled_drivers_found[i] =
TRUE;
549 uint32_t drv_count = 0;
555 for (i = 0; i < drv_count; i++) {
560 if (strstr(enabled_drivers, drv_set[i].short_name) != NULL) {
562 for (j = 0; j < enabled_drivers_count; j++) {
564 if (strcmp(enabled_drivers_array[j], drv_set[i].short_name) == 0) {
565 enabled_drivers_found[j] =
TRUE;
577 if (gdal_skip == NULL) {
578 gdal_skip = palloc(
sizeof(
char) * (strlen(drv_set[i].short_name) + 1));
582 gdal_skip = repalloc(
585 strlen(gdal_skip) + 1 + strlen(drv_set[i].short_name) + 1
588 strcat(gdal_skip,
" ");
590 strcat(gdal_skip, drv_set[i].short_name);
593 for (i = 0; i < drv_count; i++) {
594 pfree(drv_set[i].short_name);
595 pfree(drv_set[i].long_name);
596 pfree(drv_set[i].create_options);
598 if (drv_count) pfree(drv_set);
602 for (i = 0; i < enabled_drivers_count; i++) {
603 if (enabled_drivers_found[i])
607 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_DISABLE_ALL, enabled_drivers_array[i]);
609 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_ENABLE_ALL, enabled_drivers_array[i]);
611 elog(WARNING,
"Unknown GDAL driver: %s", enabled_drivers_array[i]);
619 GDALDestroyDriverManager();
623 CPLSetConfigOption(
"GDAL_SKIP", gdal_skip);
624 if (gdal_skip != NULL) pfree(gdal_skip);
629 pfree(enabled_drivers_array);
630 pfree(enabled_drivers_found);
645 bool boot_postgis_enable_outdb_rasters =
false;
646 MemoryContext old_context;
652 old_context = MemoryContextSwitchTo(TopMemoryContext);
671 "boot_postgis_gdal_enabled_drivers = %s",
685 elog(ERROR,
"_PG_init: Cannot process environmental variable: POSTGIS_ENABLE_OUTDB_RASTERS");
689 if (strcmp(env,
"1") == 0)
690 boot_postgis_enable_outdb_rasters =
true;
697 "boot_postgis_enable_outdb_rasters = %s",
698 boot_postgis_enable_outdb_rasters ?
"TRUE" :
"FALSE"
702 pg_install_lwgeom_handlers();
710 if ( postgis_guc_find_option(
"postgis.gdal_datapath") )
715 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_datapath");
719 DefineCustomStringVariable(
720 "postgis.gdal_datapath",
721 "Path to GDAL data files.",
722 "Physical path to directory containing GDAL data files (sets the GDAL_DATA config option).",
733 if ( postgis_guc_find_option(
"postgis.gdal_enabled_drivers") )
738 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_enabled_drivers");
742 DefineCustomStringVariable(
743 "postgis.gdal_enabled_drivers",
744 "Enabled GDAL drivers.",
745 "List of enabled GDAL drivers by short name. To enable/disable all drivers, use 'ENABLE_ALL' or 'DISABLE_ALL' (sets the GDAL_SKIP config option).",
756 if ( postgis_guc_find_option(
"postgis.enable_outdb_rasters") )
761 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.enable_outdb_rasters");
765 DefineCustomBoolVariable(
766 "postgis.enable_outdb_rasters",
767 "Enable Out-DB raster bands",
768 "If true, rasters can access data located outside the database",
770 boot_postgis_enable_outdb_rasters,
779 if ( postgis_guc_find_option(
"postgis.gdal_vsi_options") )
781 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_vsi_options");
785 DefineCustomStringVariable(
786 "postgis.gdal_vsi_options",
787 "VSI config options",
788 "Set the config options to be used when opening /vsi/ network files",
800 MemoryContextSwitchTo(old_context);
807 MemoryContext old_context;
809 old_context = MemoryContextSwitchTo(TopMemoryContext);
821 MemoryContextSwitchTo(old_context);
char result[OUT_DOUBLE_BUFFER_SIZE]
int rt_util_gdal_register_all(int force_register_all)
rt_gdaldriver rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc)
Returns a set of available GDAL drivers.
void rt_set_handlers_options(rt_allocator allocator, rt_reallocator reallocator, rt_deallocator deallocator, rt_message_handler error_handler, rt_message_handler info_handler, rt_message_handler warning_handler, rt_options options_handler)
size_t option_list_length(char **olist)
Returns the total number of keys and values in the list.
void option_list_parse(char *input, char **olist)
option_list is a null-terminated list of strings, where every odd string is a key and every even stri...
char * rtpg_trim(const char *input)
char ** rtpg_strsplit(const char *str, const char *delimiter, uint32_t *n)
static char * rt_pg_options(const char *varname)
static char * env_postgis_enable_outdb_rasters
static void * rt_pg_alloc(size_t size)
static char * gdal_vsi_options
static void rt_pg_vsi_load_options(const char *vsiname, stringlist_t *s)
static void rtpg_assignHookGDALDataPath(const char *newpath, void *extra)
static void rt_pg_error(const char *fmt, va_list ap) __attribute__((format(printf
bool enable_outdb_rasters
static void rt_pg_notice(const char *fmt, va_list ap) __attribute__((format(printf
static bool rt_pg_vsi_check_options(char **newval, void **extra, GucSource source)
stringlist_t * vsi_option_stringlist
static void rt_pg_vsi_load_all_options(void)
static char * env_postgis_gdal_enabled_drivers
static char * boot_postgis_gdal_enabled_drivers
static void rtpg_assignHookGDALEnabledDrivers(const char *enabled_drivers, void *extra)
static void * rt_pg_realloc(void *mem, size_t size)
static void rt_pg_free(void *ptr)
char * gdal_enabled_drivers
static void rtpg_assignHookEnableOutDBRasters(bool enable, void *extra)
static void rt_pg_debug(const char *fmt, va_list ap) __attribute__((format(printf
static char * gdal_datapath
#define POSTGIS_RT_DEBUG(level, msg)
#define POSTGIS_RT_DEBUGF(level, msg,...)
const char * stringlist_find(stringlist_t *s, const char *key)
void stringlist_add_string_nosort(stringlist_t *s, const char *string)
void stringlist_sort(stringlist_t *s)
stringlist_t * stringlist_create(void)