@@ -47,7 +47,7 @@ static int64 sendDir(char *path, int basepathlen, bool sizeonly);
4747static void sendFile (char * readfilename ,char * tarfilename ,
4848struct stat * statbuf );
4949static void sendFileWithContent (const char * filename ,const char * content );
50- static void _tarWriteHeader (const char * filename ,char * linktarget ,
50+ static void _tarWriteHeader (const char * filename ,const char * linktarget ,
5151struct stat * statbuf );
5252static void send_int8_string (StringInfoData * buf ,int64 intval );
5353static void SendBackupHeader (List * tablespaces );
@@ -118,17 +118,19 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
118118snprintf (fullpath ,sizeof (fullpath ),"pg_tblspc/%s" ,de -> d_name );
119119
120120#if defined(HAVE_READLINK )|| defined(WIN32 )
121- rllen = readlink (fullpath ,linkpath ,sizeof (linkpath )- 1 );
121+ rllen = readlink (fullpath ,linkpath ,sizeof (linkpath ));
122122if (rllen < 0 )
123123{
124124ereport (WARNING ,
125- (errmsg ("could not read symbolic link \"%s\": %m" ,fullpath )));
125+ (errmsg ("could not read symbolic link \"%s\": %m" ,
126+ fullpath )));
126127continue ;
127128}
128129else if (rllen >=sizeof (linkpath ))
129130{
130131ereport (WARNING ,
131- (errmsg ("symbolic link \"%s\" target is too long" ,fullpath )));
132+ (errmsg ("symbolic link \"%s\" target is too long" ,
133+ fullpath )));
132134continue ;
133135}
134136linkpath [rllen ]= '\0' ;
@@ -140,9 +142,9 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
140142tablespaces = lappend (tablespaces ,ti );
141143#else
142144/*
143- * If the platform does not have symbolic links, it should not be possible
144- * to have tablespaces - clearly somebody else created them. Warn about it
145- * and ignore.
145+ * If the platform does not have symbolic links, it should not be
146+ *possible to have tablespaces - clearly somebody else created
147+ *them. Warn about it and ignore.
146148 */
147149ereport (WARNING ,
148150(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
@@ -641,24 +643,45 @@ sendDir(char *path, int basepathlen, bool sizeonly)
641643continue ;/* don't recurse into pg_xlog */
642644}
643645
646+ /* Allow symbolic links in pg_tblspc only */
647+ if (strcmp (path ,"./pg_tblspc" )== 0 &&
644648#ifndef WIN32
645- if ( S_ISLNK (statbuf .st_mode ) && strcmp ( path , "./pg_tblspc" ) == 0 )
649+ S_ISLNK (statbuf .st_mode )
646650#else
647- if ( pgwin32_is_junction (pathbuf ) && strcmp ( path , "./pg_tblspc" ) == 0 )
651+ pgwin32_is_junction (pathbuf )
648652#endif
653+ )
649654{
650- /* Allow symbolic links in pg_tblspc */
655+ #if defined( HAVE_READLINK ) || defined( WIN32 )
651656char linkpath [MAXPGPATH ];
657+ int rllen ;
652658
653- MemSet ( linkpath , 0 ,sizeof (linkpath ));
654- if (readlink ( pathbuf , linkpath , sizeof ( linkpath ) - 1 ) == -1 )
659+ rllen = readlink ( pathbuf , linkpath ,sizeof (linkpath ));
660+ if (rllen < 0 )
655661ereport (ERROR ,
656662(errcode_for_file_access (),
657663errmsg ("could not read symbolic link \"%s\": %m" ,
658664pathbuf )));
665+ if (rllen >=sizeof (linkpath ))
666+ ereport (ERROR ,
667+ (errmsg ("symbolic link \"%s\" target is too long" ,
668+ pathbuf )));
669+ linkpath [rllen ]= '\0' ;
670+
659671if (!sizeonly )
660672_tarWriteHeader (pathbuf + basepathlen + 1 ,linkpath ,& statbuf );
661673size += 512 ;/* Size of the header just added */
674+ #else
675+ /*
676+ * If the platform does not have symbolic links, it should not be
677+ * possible to have tablespaces - clearly somebody else created
678+ * them. Warn about it and ignore.
679+ */
680+ ereport (WARNING ,
681+ (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
682+ errmsg ("tablespaces are not supported on this platform" )));
683+ continue ;
684+ #endif /* HAVE_READLINK */
662685}
663686else if (S_ISDIR (statbuf .st_mode ))
664687{
@@ -806,7 +829,8 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf)
806829
807830
808831static void
809- _tarWriteHeader (const char * filename ,char * linktarget ,struct stat * statbuf )
832+ _tarWriteHeader (const char * filename ,const char * linktarget ,
833+ struct stat * statbuf )
810834{
811835char h [512 ];
812836int lastSum = 0 ;
@@ -854,7 +878,7 @@ _tarWriteHeader(const char *filename, char *linktarget, struct stat * statbuf)
854878{
855879/* Type - Symbolic link */
856880sprintf (& h [156 ],"2" );
857- strcpy (& h [157 ],linktarget );
881+ sprintf (& h [157 ], "%.99s" ,linktarget );
858882}
859883else if (S_ISDIR (statbuf -> st_mode ))
860884/* Type - directory */