@@ -46,7 +46,7 @@ static int64 sendDir(char *path, int basepathlen, bool sizeonly);
4646static void sendFile (char * readfilename ,char * tarfilename ,
4747struct stat * statbuf );
4848static void sendFileWithContent (const char * filename ,const char * content );
49- static void _tarWriteHeader (const char * filename ,char * linktarget ,
49+ static void _tarWriteHeader (const char * filename ,const char * linktarget ,
5050struct stat * statbuf );
5151static void send_int8_string (StringInfoData * buf ,int64 intval );
5252static void SendBackupHeader (List * tablespaces );
@@ -117,17 +117,19 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
117117snprintf (fullpath ,sizeof (fullpath ),"pg_tblspc/%s" ,de -> d_name );
118118
119119#if defined(HAVE_READLINK )|| defined(WIN32 )
120- rllen = readlink (fullpath ,linkpath ,sizeof (linkpath )- 1 );
120+ rllen = readlink (fullpath ,linkpath ,sizeof (linkpath ));
121121if (rllen < 0 )
122122{
123123ereport (WARNING ,
124- (errmsg ("could not read symbolic link \"%s\": %m" ,fullpath )));
124+ (errmsg ("could not read symbolic link \"%s\": %m" ,
125+ fullpath )));
125126continue ;
126127}
127128else if (rllen >=sizeof (linkpath ))
128129{
129130ereport (WARNING ,
130- (errmsg ("symbolic link \"%s\" target is too long" ,fullpath )));
131+ (errmsg ("symbolic link \"%s\" target is too long" ,
132+ fullpath )));
131133continue ;
132134}
133135linkpath [rllen ]= '\0' ;
@@ -139,9 +141,9 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
139141tablespaces = lappend (tablespaces ,ti );
140142#else
141143/*
142- * If the platform does not have symbolic links, it should not be possible
143- * to have tablespaces - clearly somebody else created them. Warn about it
144- * and ignore.
144+ * If the platform does not have symbolic links, it should not be
145+ *possible to have tablespaces - clearly somebody else created
146+ *them. Warn about it and ignore.
145147 */
146148ereport (WARNING ,
147149(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
@@ -635,24 +637,45 @@ sendDir(char *path, int basepathlen, bool sizeonly)
635637continue ;/* don't recurse into pg_xlog */
636638}
637639
640+ /* Allow symbolic links in pg_tblspc only */
641+ if (strcmp (path ,"./pg_tblspc" )== 0 &&
638642#ifndef WIN32
639- if ( S_ISLNK (statbuf .st_mode ) && strcmp ( path , "./pg_tblspc" ) == 0 )
643+ S_ISLNK (statbuf .st_mode )
640644#else
641- if ( pgwin32_is_junction (pathbuf ) && strcmp ( path , "./pg_tblspc" ) == 0 )
645+ pgwin32_is_junction (pathbuf )
642646#endif
647+ )
643648{
644- /* Allow symbolic links in pg_tblspc */
649+ #if defined( HAVE_READLINK ) || defined( WIN32 )
645650char linkpath [MAXPGPATH ];
651+ int rllen ;
646652
647- MemSet ( linkpath , 0 ,sizeof (linkpath ));
648- if (readlink ( pathbuf , linkpath , sizeof ( linkpath ) - 1 ) == -1 )
653+ rllen = readlink ( pathbuf , linkpath ,sizeof (linkpath ));
654+ if (rllen < 0 )
649655ereport (ERROR ,
650656(errcode_for_file_access (),
651657errmsg ("could not read symbolic link \"%s\": %m" ,
652658pathbuf )));
659+ if (rllen >=sizeof (linkpath ))
660+ ereport (ERROR ,
661+ (errmsg ("symbolic link \"%s\" target is too long" ,
662+ pathbuf )));
663+ linkpath [rllen ]= '\0' ;
664+
653665if (!sizeonly )
654666_tarWriteHeader (pathbuf + basepathlen + 1 ,linkpath ,& statbuf );
655667size += 512 ;/* Size of the header just added */
668+ #else
669+ /*
670+ * If the platform does not have symbolic links, it should not be
671+ * possible to have tablespaces - clearly somebody else created
672+ * them. Warn about it and ignore.
673+ */
674+ ereport (WARNING ,
675+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
676+ errmsg ("tablespaces are not supported on this platform" )));
677+ continue ;
678+ #endif /* HAVE_READLINK */
656679}
657680else if (S_ISDIR (statbuf .st_mode ))
658681{
@@ -800,7 +823,8 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf)
800823
801824
802825static void
803- _tarWriteHeader (const char * filename ,char * linktarget ,struct stat * statbuf )
826+ _tarWriteHeader (const char * filename ,const char * linktarget ,
827+ struct stat * statbuf )
804828{
805829char h [512 ];
806830int lastSum = 0 ;
@@ -848,7 +872,7 @@ _tarWriteHeader(const char *filename, char *linktarget, struct stat * statbuf)
848872{
849873/* Type - Symbolic link */
850874sprintf (& h [156 ],"2" );
851- strcpy (& h [157 ],linktarget );
875+ sprintf (& h [157 ], "%.99s" ,linktarget );
852876}
853877else if (S_ISDIR (statbuf -> st_mode ))
854878/* Type - directory */