11#include "http.h"
22#include "pack.h"
33#include "sideband.h"
4+ #include "run-command.h"
45
56int data_received ;
67int active_requests ;
@@ -914,47 +915,67 @@ int http_fetch_ref(const char *base, struct ref *ref)
914915}
915916
916917/* Helpers for fetching packs */
917- static int fetch_pack_index (unsigned char * sha1 , const char * base_url )
918+ static char * fetch_pack_index (unsigned char * sha1 , const char * base_url )
918919{
919- int ret = 0 ;
920- char * hex = xstrdup (sha1_to_hex (sha1 ));
921- char * filename ;
922- char * url = NULL ;
920+ char * url , * tmp ;
923921 struct strbuf buf = STRBUF_INIT ;
924922
925- if (has_pack_index (sha1 )) {
926- ret = 0 ;
927- goto cleanup ;
928- }
929-
930923 if (http_is_verbose )
931- fprintf (stderr , "Getting index for pack %s\n" , hex );
924+ fprintf (stderr , "Getting index for pack %s\n" , sha1_to_hex ( sha1 ) );
932925
933926 end_url_with_slash (& buf , base_url );
934- strbuf_addf (& buf , "objects/pack/pack-%s.idx" , hex );
927+ strbuf_addf (& buf , "objects/pack/pack-%s.idx" , sha1_to_hex ( sha1 ) );
935928 url = strbuf_detach (& buf , NULL );
936929
937- filename = sha1_pack_index_name (sha1 );
938- if (http_get_file (url , filename , 0 ) != HTTP_OK )
939- ret = error ("Unable to get pack index %s\n" , url );
930+ strbuf_addf (& buf , "%s.temp" , sha1_pack_index_name (sha1 ));
931+ tmp = strbuf_detach (& buf , NULL );
932+
933+ if (http_get_file (url , tmp , 0 ) != HTTP_OK ) {
934+ error ("Unable to get pack index %s\n" , url );
935+ free (tmp );
936+ tmp = NULL ;
937+ }
940938
941- cleanup :
942- free (hex );
943939 free (url );
944- return ret ;
940+ return tmp ;
945941}
946942
947943static int fetch_and_setup_pack_index (struct packed_git * * packs_head ,
948944 unsigned char * sha1 , const char * base_url )
949945{
950946 struct packed_git * new_pack ;
947+ char * tmp_idx = NULL ;
948+ int ret ;
951949
952- if (fetch_pack_index (sha1 , base_url ))
950+ if (has_pack_index (sha1 )) {
951+ new_pack = parse_pack_index (sha1 , NULL );
952+ if (!new_pack )
953+ return -1 ; /* parse_pack_index() already issued error message */
954+ goto add_pack ;
955+ }
956+
957+ tmp_idx = fetch_pack_index (sha1 , base_url );
958+ if (!tmp_idx )
953959 return -1 ;
954960
955- new_pack = parse_pack_index (sha1 );
956- if (!new_pack )
961+ new_pack = parse_pack_index (sha1 , tmp_idx );
962+ if (!new_pack ) {
963+ unlink (tmp_idx );
964+ free (tmp_idx );
965+
957966 return -1 ; /* parse_pack_index() already issued error message */
967+ }
968+
969+ ret = verify_pack_index (new_pack );
970+ if (!ret ) {
971+ close_pack_index (new_pack );
972+ ret = move_temp_to_file (tmp_idx , sha1_pack_index_name (sha1 ));
973+ }
974+ free (tmp_idx );
975+ if (ret )
976+ return -1 ;
977+
978+ add_pack :
958979 new_pack -> next = * packs_head ;
959980 * packs_head = new_pack ;
960981 return 0 ;
@@ -1018,37 +1039,62 @@ void release_http_pack_request(struct http_pack_request *preq)
10181039
10191040int finish_http_pack_request (struct http_pack_request * preq )
10201041{
1021- int ret ;
10221042 struct packed_git * * lst ;
1043+ struct packed_git * p = preq -> target ;
1044+ char * tmp_idx ;
1045+ struct child_process ip ;
1046+ const char * ip_argv [8 ];
10231047
1024- preq -> target -> pack_size = ftell ( preq -> packfile );
1048+ close_pack_index ( p );
10251049
1026- if (preq -> packfile != NULL ) {
1027- fclose (preq -> packfile );
1028- preq -> packfile = NULL ;
1029- preq -> slot -> local = NULL ;
1030- }
1031-
1032- ret = move_temp_to_file (preq -> tmpfile , preq -> filename );
1033- if (ret )
1034- return ret ;
1050+ fclose (preq -> packfile );
1051+ preq -> packfile = NULL ;
1052+ preq -> slot -> local = NULL ;
10351053
10361054 lst = preq -> lst ;
1037- while (* lst != preq -> target )
1055+ while (* lst != p )
10381056 lst = & ((* lst )-> next );
10391057 * lst = (* lst )-> next ;
10401058
1041- if (verify_pack (preq -> target ))
1059+ tmp_idx = xstrdup (preq -> tmpfile );
1060+ strcpy (tmp_idx + strlen (tmp_idx ) - strlen (".pack.temp" ),
1061+ ".idx.temp" );
1062+
1063+ ip_argv [0 ] = "index-pack" ;
1064+ ip_argv [1 ] = "-o" ;
1065+ ip_argv [2 ] = tmp_idx ;
1066+ ip_argv [3 ] = preq -> tmpfile ;
1067+ ip_argv [4 ] = NULL ;
1068+
1069+ memset (& ip , 0 , sizeof (ip ));
1070+ ip .argv = ip_argv ;
1071+ ip .git_cmd = 1 ;
1072+ ip .no_stdin = 1 ;
1073+ ip .no_stdout = 1 ;
1074+
1075+ if (run_command (& ip )) {
1076+ unlink (preq -> tmpfile );
1077+ unlink (tmp_idx );
1078+ free (tmp_idx );
1079+ return -1 ;
1080+ }
1081+
1082+ unlink (sha1_pack_index_name (p -> sha1 ));
1083+
1084+ if (move_temp_to_file (preq -> tmpfile , sha1_pack_name (p -> sha1 ))
1085+ || move_temp_to_file (tmp_idx , sha1_pack_index_name (p -> sha1 ))) {
1086+ free (tmp_idx );
10421087 return -1 ;
1043- install_packed_git ( preq -> target );
1088+ }
10441089
1090+ install_packed_git (p );
1091+ free (tmp_idx );
10451092 return 0 ;
10461093}
10471094
10481095struct http_pack_request * new_http_pack_request (
10491096 struct packed_git * target , const char * base_url )
10501097{
1051- char * filename ;
10521098 long prev_posn = 0 ;
10531099 char range [RANGE_HEADER_SIZE ];
10541100 struct strbuf buf = STRBUF_INIT ;
@@ -1063,9 +1109,8 @@ struct http_pack_request *new_http_pack_request(
10631109 sha1_to_hex (target -> sha1 ));
10641110 preq -> url = strbuf_detach (& buf , NULL );
10651111
1066- filename = sha1_pack_name (target -> sha1 );
1067- snprintf (preq -> filename , sizeof (preq -> filename ), "%s" , filename );
1068- snprintf (preq -> tmpfile , sizeof (preq -> tmpfile ), "%s.temp" , filename );
1112+ snprintf (preq -> tmpfile , sizeof (preq -> tmpfile ), "%s.temp" ,
1113+ sha1_pack_name (target -> sha1 ));
10691114 preq -> packfile = fopen (preq -> tmpfile , "a" );
10701115 if (!preq -> packfile ) {
10711116 error ("Unable to open local file %s for pack" ,
@@ -1100,7 +1145,6 @@ struct http_pack_request *new_http_pack_request(
11001145 return preq ;
11011146
11021147abort :
1103- free (filename );
11041148 free (preq -> url );
11051149 free (preq );
11061150 return NULL ;
@@ -1155,7 +1199,6 @@ struct http_object_request *new_http_object_request(const char *base_url,
11551199 freq -> localfile = -1 ;
11561200
11571201 filename = sha1_file_name (sha1 );
1158- snprintf (freq -> filename , sizeof (freq -> filename ), "%s" , filename );
11591202 snprintf (freq -> tmpfile , sizeof (freq -> tmpfile ),
11601203 "%s.temp" , filename );
11611204
@@ -1184,8 +1227,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
11841227 }
11851228
11861229 if (freq -> localfile < 0 ) {
1187- error ("Couldn't create temporary file %s for %s : %s" ,
1188- freq -> tmpfile , freq -> filename , strerror (errno ));
1230+ error ("Couldn't create temporary file %s: %s" ,
1231+ freq -> tmpfile , strerror (errno ));
11891232 goto abort ;
11901233 }
11911234
@@ -1232,8 +1275,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
12321275 prev_posn = 0 ;
12331276 lseek (freq -> localfile , 0 , SEEK_SET );
12341277 if (ftruncate (freq -> localfile , 0 ) < 0 ) {
1235- error ("Couldn't truncate temporary file %s for %s : %s" ,
1236- freq -> tmpfile , freq -> filename , strerror (errno ));
1278+ error ("Couldn't truncate temporary file %s: %s" ,
1279+ freq -> tmpfile , strerror (errno ));
12371280 goto abort ;
12381281 }
12391282 }
@@ -1309,7 +1352,7 @@ int finish_http_object_request(struct http_object_request *freq)
13091352 return -1 ;
13101353 }
13111354 freq -> rename =
1312- move_temp_to_file (freq -> tmpfile , freq -> filename );
1355+ move_temp_to_file (freq -> tmpfile , sha1_file_name ( freq -> sha1 ) );
13131356
13141357 return freq -> rename ;
13151358}
0 commit comments