133 #include "postgres.h"
135 #include "libpq/pqsignal.h"
136 #include "utils/guc.h"
137 #include "utils/builtins.h"
138 #include "utils/memutils.h"
139 #include "utils/elog.h"
142 #include "postgis_config.h"
144 #include "lwgeom_pg.h"
154 # define __attribute__ (x)
168 #define RT_MSG_MAXLEN 256
195 result = repalloc(mem, size);
221 ereport(ERROR, (errmsg_internal(
"%s", errmsg)));
235 ereport(NOTICE, (errmsg_internal(
"%s", msg)));
249 ereport(DEBUG1, (errmsg_internal(
"%s", msg)));
257 snprintf(optname, 128,
"postgis.%s", varname);
259 optvalue = GetConfigOptionByName(optname, NULL,
true);
260 if (optvalue && strlen(optvalue) == 0)
273 #if POSTGIS_GDAL_VERSION < 23
283 const char * gdaloption;
284 const char *
const gdaloptions[] = {
291 "aws_secret_access_key",
294 "aws_virtual_hosting",
297 "gs_secret_access_key",
300 "goa2_client_secret",
301 "cpl_curl_enable_vsimem",
305 "gdal_http_connecttimeout",
307 "gdal_http_header_file",
308 "gdal_http_low_speed_time",
309 "gdal_http_low_speed_limit",
310 "gdal_http_max_retry",
313 "gdal_http_proxyuserpwd",
314 "gdal_http_retry_delay",
317 "gdal_http_unsafessl",
318 "gdal_http_useragent",
319 "gdal_disable_readdir_on_open",
324 "cpl_vsil_curl_use_head",
325 "cpl_vsil_curl_use_s3_redirect",
326 "cpl_vsil_curl_max_ranges",
327 "cpl_vsil_curl_use_cache",
328 "cpl_vsil_curl_allowed_filename",
329 "cpl_vsil_curl_allowed_extensions",
330 "cpl_vsil_curl_slow_get_size",
335 const char *
const * gdaloptionsptr = gdaloptions;
338 while((gdaloption = *gdaloptionsptr++))
355 CPLXMLNode *root, *optNode;
356 const char *xml = VSIGetFileSystemOptions(vsiname);
359 root = CPLParseXMLString(xml);
361 elog(ERROR,
"%s: Unable to read options for VSI %s", __func__, vsiname);
364 optNode = CPLSearchXMLNode(root,
"Option");
366 CPLDestroyXMLNode(root);
367 elog(ERROR,
"%s: Unable to find <Option> in VSI XML %s", __func__, vsiname);
372 const char *option = CPLGetXMLValue(optNode,
"name", NULL);
374 char *optionstr = pstrdup(option);
375 char *ptr = optionstr;
380 *ptr = tolower(*ptr);
383 elog(DEBUG4,
"GDAL %s option: %s", vsiname, optionstr);
386 optNode = optNode->psNext;
388 CPLDestroyXMLNode(root);
394 const char * vsiname;
395 const char *
const vsilist[] = {
407 const char *
const * vsilistptr = vsilist;
410 while((vsiname = *vsilistptr++))
425 const char *found = NULL;
428 memset(olist, 0,
sizeof(olist));
429 if (!newval || !*newval)
431 newoptions = pstrdup(*newval);
437 elog(DEBUG5,
"%s: processing VSI options: %s", __func__, newoptions);
440 if (olist_sz % 2 != 0)
443 for (i = 0; i < olist_sz; i += 2)
448 elog(WARNING,
"'%s' is not a legal VSI network file option", olist[i]);
487 CPLSetConfigOption(
"GDAL_DATA", newpath);
498 char **enabled_drivers_array = NULL;
499 uint32_t enabled_drivers_count = 0;
500 bool *enabled_drivers_found = NULL;
501 char *gdal_skip = NULL;
510 if (enabled_drivers == NULL)
513 elog(DEBUG4,
"Enabling GDAL drivers: %s", enabled_drivers);
517 GDALDestroyDriverManager();
518 CPLSetConfigOption(
"GDAL_SKIP", NULL);
523 enabled_drivers_array =
rtpg_strsplit(enabled_drivers,
" ", &enabled_drivers_count);
524 enabled_drivers_found = palloc(
sizeof(
bool) * enabled_drivers_count);
525 memset(enabled_drivers_found,
FALSE,
sizeof(
bool) * enabled_drivers_count);
531 for (i = 0; i < enabled_drivers_count; i++) {
533 enabled_drivers_found[i] =
TRUE;
539 for (i = 0; i < enabled_drivers_count; i++) {
541 enabled_drivers_found[i] =
TRUE;
546 else if (strstr(enabled_drivers,
GDAL_VSICURL) != NULL) {
547 for (i = 0; i < enabled_drivers_count; i++) {
548 if (strstr(enabled_drivers_array[i],
GDAL_VSICURL) != NULL) {
549 enabled_drivers_found[i] =
TRUE;
557 uint32_t drv_count = 0;
563 for (i = 0; i < drv_count; i++) {
568 if (strstr(enabled_drivers, drv_set[i].short_name) != NULL) {
570 for (j = 0; j < enabled_drivers_count; j++) {
572 if (strcmp(enabled_drivers_array[j], drv_set[i].short_name) == 0) {
573 enabled_drivers_found[j] =
TRUE;
585 if (gdal_skip == NULL) {
586 gdal_skip = palloc(
sizeof(
char) * (strlen(drv_set[i].short_name) + 1));
590 gdal_skip = repalloc(
593 strlen(gdal_skip) + 1 + strlen(drv_set[i].short_name) + 1
596 strcat(gdal_skip,
" ");
598 strcat(gdal_skip, drv_set[i].short_name);
601 for (i = 0; i < drv_count; i++) {
602 pfree(drv_set[i].short_name);
603 pfree(drv_set[i].long_name);
604 pfree(drv_set[i].create_options);
606 if (drv_count) pfree(drv_set);
610 for (i = 0; i < enabled_drivers_count; i++) {
611 if (enabled_drivers_found[i])
615 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_DISABLE_ALL, enabled_drivers_array[i]);
617 elog(WARNING,
"%s set. Ignoring GDAL driver: %s",
GDAL_ENABLE_ALL, enabled_drivers_array[i]);
619 elog(WARNING,
"Unknown GDAL driver: %s", enabled_drivers_array[i]);
627 GDALDestroyDriverManager();
631 CPLSetConfigOption(
"GDAL_SKIP", gdal_skip);
632 if (gdal_skip != NULL) pfree(gdal_skip);
637 pfree(enabled_drivers_array);
638 pfree(enabled_drivers_found);
658 static void interruptCallback() {
659 if (UNBLOCKED_SIGNAL_QUEUE())
660 pgwin32_dispatch_queued_signals();
685 (*coreIntHandler)(sig);
695 bool boot_postgis_enable_outdb_rasters =
false;
696 MemoryContext old_context;
702 GEOS_interruptRegisterCallback(interruptCallback);
711 old_context = MemoryContextSwitchTo(TopMemoryContext);
730 "boot_postgis_gdal_enabled_drivers = %s",
744 elog(ERROR,
"_PG_init: Cannot process environmental variable: POSTGIS_ENABLE_OUTDB_RASTERS");
748 if (strcmp(env,
"1") == 0)
749 boot_postgis_enable_outdb_rasters =
true;
756 "boot_postgis_enable_outdb_rasters = %s",
757 boot_postgis_enable_outdb_rasters ?
"TRUE" :
"FALSE"
761 pg_install_lwgeom_handlers();
769 if ( postgis_guc_find_option(
"postgis.gdal_datapath") )
774 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_datapath");
778 DefineCustomStringVariable(
779 "postgis.gdal_datapath",
780 "Path to GDAL data files.",
781 "Physical path to directory containing GDAL data files (sets the GDAL_DATA config option).",
792 if ( postgis_guc_find_option(
"postgis.gdal_enabled_drivers") )
797 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_enabled_drivers");
801 DefineCustomStringVariable(
802 "postgis.gdal_enabled_drivers",
803 "Enabled GDAL drivers.",
804 "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).",
815 if ( postgis_guc_find_option(
"postgis.enable_outdb_rasters") )
820 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.enable_outdb_rasters");
824 DefineCustomBoolVariable(
825 "postgis.enable_outdb_rasters",
826 "Enable Out-DB raster bands",
827 "If true, rasters can access data located outside the database",
829 boot_postgis_enable_outdb_rasters,
838 if ( postgis_guc_find_option(
"postgis.gdal_vsi_options") )
840 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_vsi_options");
844 DefineCustomStringVariable(
845 "postgis.gdal_vsi_options",
846 "VSI config options",
847 "Set the config options to be used when opening /vsi/ network files",
859 MemoryContextSwitchTo(old_context);
866 MemoryContext old_context = MemoryContextSwitchTo(TopMemoryContext);
868 elog(NOTICE,
"Goodbye from PostGIS Raster %s", POSTGIS_VERSION);
883 MemoryContextSwitchTo(old_context);
char result[OUT_DOUBLE_BUFFER_SIZE]
void lwgeom_request_interrupt(void)
Request interruption of any running code.
lwinterrupt_callback * lwgeom_register_interrupt_callback(lwinterrupt_callback *)
This library is the generic geometry handling section of PostGIS.
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 void handleInterrupt(int sig)
static char * env_postgis_enable_outdb_rasters
static void * rt_pg_alloc(size_t size)
static char * gdal_vsi_options
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)
static pqsigfunc coreIntHandler
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)