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]);
480 CPLSetConfigOption(
"GDAL_DATA", newpath);
491 char **enabled_drivers_array = NULL;
492 uint32_t enabled_drivers_count = 0;
493 bool *enabled_drivers_found = NULL;
494 char *gdal_skip = NULL;
503 if (enabled_drivers == NULL)
506 elog(DEBUG4,
"Enabling GDAL drivers: %s", enabled_drivers);
510 GDALDestroyDriverManager();
511 CPLSetConfigOption(
"GDAL_SKIP", NULL);
516 enabled_drivers_array =
rtpg_strsplit(enabled_drivers,
" ", &enabled_drivers_count);
517 enabled_drivers_found = palloc(
sizeof(
bool) * enabled_drivers_count);
518 memset(enabled_drivers_found,
FALSE,
sizeof(
bool) * enabled_drivers_count);
524 for (i = 0; i < enabled_drivers_count; i++) {
526 enabled_drivers_found[i] =
TRUE;
532 for (i = 0; i < enabled_drivers_count; i++) {
534 enabled_drivers_found[i] =
TRUE;
539 else if (strstr(enabled_drivers,
GDAL_VSICURL) != NULL) {
540 for (i = 0; i < enabled_drivers_count; i++) {
541 if (strstr(enabled_drivers_array[i],
GDAL_VSICURL) != NULL) {
542 enabled_drivers_found[i] =
TRUE;
550 uint32_t drv_count = 0;
556 for (i = 0; i < drv_count; i++) {
561 if (strstr(enabled_drivers, drv_set[i].short_name) != NULL) {
563 for (j = 0; j < enabled_drivers_count; j++) {
565 if (strcmp(enabled_drivers_array[j], drv_set[i].short_name) == 0) {
566 enabled_drivers_found[j] =
TRUE;
578 if (gdal_skip == NULL) {
579 gdal_skip = palloc(
sizeof(
char) * (strlen(drv_set[i].short_name) + 1));
583 gdal_skip = repalloc(
586 strlen(gdal_skip) + 1 + strlen(drv_set[i].short_name) + 1
589 strcat(gdal_skip,
" ");
591 strcat(gdal_skip, drv_set[i].short_name);
594 for (i = 0; i < drv_count; i++) {
595 pfree(drv_set[i].short_name);
596 pfree(drv_set[i].long_name);
597 pfree(drv_set[i].create_options);
599 if (drv_count) pfree(drv_set);
603 for (i = 0; i < enabled_drivers_count; i++) {
604 if (enabled_drivers_found[i])
608 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_DISABLE_ALL, enabled_drivers_array[i]);
610 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_ENABLE_ALL, enabled_drivers_array[i]);
612 elog(WARNING,
"Unknown GDAL driver: %s", enabled_drivers_array[i]);
620 GDALDestroyDriverManager();
624 CPLSetConfigOption(
"GDAL_SKIP", gdal_skip);
625 if (gdal_skip != NULL) pfree(gdal_skip);
630 pfree(enabled_drivers_array);
631 pfree(enabled_drivers_found);
646 bool boot_postgis_enable_outdb_rasters =
false;
647 MemoryContext old_context;
653 old_context = MemoryContextSwitchTo(TopMemoryContext);
672 "boot_postgis_gdal_enabled_drivers = %s",
686 elog(ERROR,
"_PG_init: Cannot process environmental variable: POSTGIS_ENABLE_OUTDB_RASTERS");
690 if (strcmp(env,
"1") == 0)
691 boot_postgis_enable_outdb_rasters =
true;
698 "boot_postgis_enable_outdb_rasters = %s",
699 boot_postgis_enable_outdb_rasters ?
"TRUE" :
"FALSE"
703 pg_install_lwgeom_handlers();
711 if ( postgis_guc_find_option(
"postgis.gdal_datapath") )
716 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_datapath");
720 DefineCustomStringVariable(
721 "postgis.gdal_datapath",
722 "Path to GDAL data files.",
723 "Physical path to directory containing GDAL data files (sets the GDAL_DATA config option).",
734 if ( postgis_guc_find_option(
"postgis.gdal_enabled_drivers") )
739 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_enabled_drivers");
743 DefineCustomStringVariable(
744 "postgis.gdal_enabled_drivers",
745 "Enabled GDAL drivers.",
746 "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).",
757 if ( postgis_guc_find_option(
"postgis.enable_outdb_rasters") )
762 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.enable_outdb_rasters");
766 DefineCustomBoolVariable(
767 "postgis.enable_outdb_rasters",
768 "Enable Out-DB raster bands",
769 "If true, rasters can access data located outside the database",
771 boot_postgis_enable_outdb_rasters,
780 if ( postgis_guc_find_option(
"postgis.gdal_vsi_options") )
782 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_vsi_options");
786 DefineCustomStringVariable(
787 "postgis.gdal_vsi_options",
788 "VSI config options",
789 "Set the config options to be used when opening /vsi/ network files",
801 MemoryContextSwitchTo(old_context);
808 MemoryContext old_context;
810 old_context = MemoryContextSwitchTo(TopMemoryContext);
822 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
static 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)
static 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)