@@ -230,12 +230,18 @@ pgFileGetCRC(pgFile *file)
230230void
231231pgFileFree (void * file )
232232{
233+ pgFile * file_ptr ;
234+
233235if (file == NULL )
234236return ;
235- free (((pgFile * )file )-> linked );
236- free (((pgFile * )file )-> path );
237- if (((pgFile * )file )-> ptrack_path != NULL )
238- free (((pgFile * )file )-> ptrack_path );
237+
238+ file_ptr = (pgFile * )file ;
239+
240+ if (file_ptr -> linked )
241+ free (file_ptr -> linked );
242+ free (file_ptr -> path );
243+ if (file_ptr -> ptrack_path != NULL )
244+ free (file_ptr -> ptrack_path );
239245free (file );
240246}
241247
@@ -693,6 +699,7 @@ dir_read_file_list(const char *root, const char *file_txt)
693699FILE * fp ;
694700parray * files ;
695701char buf [MAXPGPATH * 2 ];
702+ int line_num = 0 ;
696703
697704fp = fopen (file_txt ,"rt" );
698705if (fp == NULL )
@@ -711,36 +718,55 @@ dir_read_file_list(const char *root, const char *file_txt)
711718unsigned long write_size ;
712719pg_crc32 crc ;
713720unsignedint mode ;/* bit length of mode_t depends on platforms */
714- pgFile * file ;
715- char * ptr ;
721+ pgFile * file ;
722+ char * ptr ;
716723unsignedint is_datafile ;
717- int segno = 0 ;
718-
719- ptr = strstr (buf ,"path" );
720- sscanf (buf ,"path:%s" ,path );
721- ptr = strstr (buf ,"size" );
722- sscanf (buf ,"size:%lu" ,& write_size );
723- ptr = strstr (buf ,"mode" );
724- sscanf (buf ,"mode:%u" ,& mode );
725- ptr = strstr (buf ,"is_datafile" );
726- sscanf (buf ,"is_datafile:%u" ,& is_datafile );
727- ptr = strstr (buf ,"crc" );
728- sscanf (buf ,"crc:%u" ,& crc );
724+ int segno = 0 ;
725+
726+ /* XXX Maybe use better parser function? */
727+ #define GET_VALUE (name ,value ,format ,is_mandatory )\
728+ do {\
729+ if (ptr == NULL && is_mandatory)\
730+ elog(ERROR, "parameter \"%s\" is not found in \"%s\" in %d line",\
731+ name, file_txt, line_num);\
732+ if (ptr)\
733+ sscanf(ptr, format, &value);\
734+ } while (0)
735+
736+ line_num ++ ;
737+
738+ ptr = strstr (buf ,"\"path\"" );
739+ GET_VALUE ("path" ,path ,"\"path\":\"%s\"" , true);
740+
741+ ptr = strstr (buf ,"\"size\"" );
742+ GET_VALUE ("size" ,write_size ,"\"size\":\"%lu\"" , true);
743+
744+ ptr = strstr (buf ,"\"mode\"" );
745+ GET_VALUE ("mode" ,mode ,"\"mode\":\"%u\"" , true);
746+
747+ ptr = strstr (buf ,"\"is_datafile\"" );
748+ GET_VALUE ("is_datafile" ,is_datafile ,"\"is_datafile\":\"%u\"" , true);
749+
750+ ptr = strstr (buf ,"\"crc\"" );
751+ GET_VALUE ("crc" ,crc ,"\"crc\":\"%u\"" , true);
752+
729753/* optional fields */
730- ptr = strstr (buf ,"linked" );
731- if (ptr )
732- sscanf (buf ,"linked:%s" ,linked );
733- ptr = strstr (buf ,"segno" );
734- if (ptr )
735- sscanf (buf ,"segno:%d" ,& segno );
754+ linked [0 ]= '\0' ;
755+ ptr = strstr (buf ,"\"linked\"" );
756+ GET_VALUE ("linked" ,linked ,"\"linked\":\"%s\"" , false);
757+
758+ ptr = strstr (buf ,"\"segno\"" );
759+ GET_VALUE ("segno" ,segno ,"\"segno\":\"%d\"" , false);
760+
736761#ifdef PGPRO_EE
737- ptr = strstr (buf ,"CFS_generation" );
738- sscanf (buf ,"CFS_generation:%lu" ,& generation );
739- ptr = strstr (buf ,"is_partial_copy" );
740- sscanf (buf ,"is_partial_copy:%d" ,& is_partial_copy );
762+ ptr = strstr (buf ,"\"CFS_generation\"" );
763+ GET_VALUE ("CFS_generation" ,generation ,"\"CFS_generation\":\"%lu\"" , true);
764+
765+ sscanf (buf ,"\"CFS_generation\":\"%lu\"" ,& generation );
766+ GET_VALUE ("is_partial_copy" ,is_partial_copy ,"\"is_partial_copy\":\"%d\"" , true);
741767#endif
742768if (root )
743- sprintf (filepath , "%s/%s" ,root ,path );
769+ join_path_components (filepath ,root ,path );
744770else
745771strcpy (filepath ,path );
746772
@@ -750,7 +776,8 @@ dir_read_file_list(const char *root, const char *file_txt)
750776file -> mode = mode ;
751777file -> is_datafile = is_datafile ? true : false;
752778file -> crc = crc ;
753- file -> linked = NULL ;/* TODO Why don't read it? */
779+ if (linked [0 ])
780+ file -> linked = pgut_strdup (linked );
754781file -> segno = segno ;
755782file -> generation = generation ;
756783file -> is_partial_copy = is_partial_copy ;