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
194 result = repalloc(mem, size);
220 ereport(ERROR, (errmsg_internal(
"%s", errmsg)));
234 ereport(NOTICE, (errmsg_internal(
"%s", msg)));
248 ereport(DEBUG1, (errmsg_internal(
"%s", msg)));
256 snprintf(optname, 128,
"postgis.%s", varname);
258 optvalue = GetConfigOptionByName(optname, NULL,
true);
259 if (optvalue && strlen(optvalue) == 0)
272 #if POSTGIS_GDAL_VERSION < 20300
282 const char * gdaloption;
283 const char *
const gdaloptions[] = {
290 "aws_secret_access_key",
293 "aws_virtual_hosting",
296 "gs_secret_access_key",
299 "goa2_client_secret",
300 "cpl_curl_enable_vsimem",
304 "gdal_http_connecttimeout",
306 "gdal_http_header_file",
307 "gdal_http_low_speed_time",
308 "gdal_http_low_speed_limit",
309 "gdal_http_max_retry",
312 "gdal_http_proxyuserpwd",
313 "gdal_http_retry_delay",
316 "gdal_http_unsafessl",
317 "gdal_http_useragent",
318 "gdal_disable_readdir_on_open",
323 "cpl_vsil_curl_use_head",
324 "cpl_vsil_curl_use_s3_redirect",
325 "cpl_vsil_curl_max_ranges",
326 "cpl_vsil_curl_use_cache",
327 "cpl_vsil_curl_allowed_filename",
328 "cpl_vsil_curl_allowed_extensions",
329 "cpl_vsil_curl_slow_get_size",
334 const char *
const * gdaloptionsptr = gdaloptions;
337 while((gdaloption = *gdaloptionsptr++))
354 CPLXMLNode *root, *optNode;
355 const char *xml = VSIGetFileSystemOptions(vsiname);
358 root = CPLParseXMLString(xml);
360 elog(ERROR,
"%s: Unable to read options for VSI %s", __func__, vsiname);
363 optNode = CPLSearchXMLNode(root,
"Option");
365 CPLDestroyXMLNode(root);
366 elog(ERROR,
"%s: Unable to find <Option> in VSI XML %s", __func__, vsiname);
371 const char *option = CPLGetXMLValue(optNode,
"name", NULL);
373 char *optionstr = pstrdup(option);
374 char *ptr = optionstr;
379 *ptr = tolower(*ptr);
382 elog(DEBUG4,
"GDAL %s option: %s", vsiname, optionstr);
385 optNode = optNode->psNext;
387 CPLDestroyXMLNode(root);
393 const char * vsiname;
394 const char *
const vsilist[] = {
406 const char *
const * vsilistptr = vsilist;
409 while((vsiname = *vsilistptr++))
424 const char *found = NULL;
427 memset(olist, 0,
sizeof(olist));
428 if (!newval || !*newval)
430 newoptions = pstrdup(*newval);
436 elog(DEBUG5,
"%s: processing VSI options: %s", __func__, newoptions);
439 if (olist_sz % 2 != 0)
442 for (i = 0; i < olist_sz; i += 2)
447 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);
653 bool boot_postgis_enable_outdb_rasters =
false;
654 MemoryContext old_context;
660 old_context = MemoryContextSwitchTo(TopMemoryContext);
679 "boot_postgis_gdal_enabled_drivers = %s",
693 elog(ERROR,
"_PG_init: Cannot process environmental variable: POSTGIS_ENABLE_OUTDB_RASTERS");
697 if (strcmp(env,
"1") == 0)
698 boot_postgis_enable_outdb_rasters =
true;
705 "boot_postgis_enable_outdb_rasters = %s",
706 boot_postgis_enable_outdb_rasters ?
"TRUE" :
"FALSE"
710 pg_install_lwgeom_handlers();
718 if ( postgis_guc_find_option(
"postgis.gdal_datapath") )
723 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_datapath");
727 DefineCustomStringVariable(
728 "postgis.gdal_datapath",
729 "Path to GDAL data files.",
730 "Physical path to directory containing GDAL data files (sets the GDAL_DATA config option).",
741 if ( postgis_guc_find_option(
"postgis.gdal_enabled_drivers") )
746 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_enabled_drivers");
750 DefineCustomStringVariable(
751 "postgis.gdal_enabled_drivers",
752 "Enabled GDAL drivers.",
753 "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).",
764 if ( postgis_guc_find_option(
"postgis.enable_outdb_rasters") )
769 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.enable_outdb_rasters");
773 DefineCustomBoolVariable(
774 "postgis.enable_outdb_rasters",
775 "Enable Out-DB raster bands",
776 "If true, rasters can access data located outside the database",
778 boot_postgis_enable_outdb_rasters,
788 if ( postgis_guc_find_option(
"postgis.gdal_cpl_debug") )
793 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_cpl_debug");
797 DefineCustomBoolVariable(
798 "postgis.gdal_cpl_debug",
799 "Enable GDAL debugging messages",
800 "GDAL debug messages will be sent at the PgSQL debug log level",
811 if ( postgis_guc_find_option(
"postgis.gdal_vsi_options") )
813 elog(WARNING,
"'%s' is already set and cannot be changed until you reconnect",
"postgis.gdal_vsi_options");
817 DefineCustomStringVariable(
818 "postgis.gdal_vsi_options",
819 "VSI config options",
820 "Set the config options to be used when opening /vsi/ network files",
832 MemoryContextSwitchTo(old_context);
839 MemoryContext old_context = MemoryContextSwitchTo(TopMemoryContext);
841 elog(NOTICE,
"Goodbye from PostGIS Raster %s", POSTGIS_VERSION);
853 MemoryContextSwitchTo(old_context);
char result[OUT_DOUBLE_BUFFER_SIZE]
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...
void rtpg_gdal_set_cpl_debug(bool value, void *extra)
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 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 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 bool gdal_cpl_debug
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)