1
1
#include "http.h"
2
2
#include "pack.h"
3
3
#include "sideband.h"
4
+ #include "run-command.h"
4
5
5
6
int data_received ;
6
7
int active_requests ;
@@ -914,47 +915,67 @@ int http_fetch_ref(const char *base, struct ref *ref)
914
915
}
915
916
916
917
/* 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 )
918
919
{
919
- int ret = 0 ;
920
- char * hex = xstrdup (sha1_to_hex (sha1 ));
921
- char * filename ;
922
- char * url = NULL ;
920
+ char * url , * tmp ;
923
921
struct strbuf buf = STRBUF_INIT ;
924
922
925
- if (has_pack_index (sha1 )) {
926
- ret = 0 ;
927
- goto cleanup ;
928
- }
929
-
930
923
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 ) );
932
925
933
926
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 ) );
935
928
url = strbuf_detach (& buf , NULL );
936
929
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
+ }
940
938
941
- cleanup :
942
- free (hex );
943
939
free (url );
944
- return ret ;
940
+ return tmp ;
945
941
}
946
942
947
943
static int fetch_and_setup_pack_index (struct packed_git * * packs_head ,
948
944
unsigned char * sha1 , const char * base_url )
949
945
{
950
946
struct packed_git * new_pack ;
947
+ char * tmp_idx = NULL ;
948
+ int ret ;
951
949
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 )
953
959
return -1 ;
954
960
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
+
957
966
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 :
958
979
new_pack -> next = * packs_head ;
959
980
* packs_head = new_pack ;
960
981
return 0 ;
@@ -1018,37 +1039,62 @@ void release_http_pack_request(struct http_pack_request *preq)
1018
1039
1019
1040
int finish_http_pack_request (struct http_pack_request * preq )
1020
1041
{
1021
- int ret ;
1022
1042
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 ];
1023
1047
1024
- preq -> target -> pack_size = ftell ( preq -> packfile );
1048
+ close_pack_index ( p );
1025
1049
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 ;
1035
1053
1036
1054
lst = preq -> lst ;
1037
- while (* lst != preq -> target )
1055
+ while (* lst != p )
1038
1056
lst = & ((* lst )-> next );
1039
1057
* lst = (* lst )-> next ;
1040
1058
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 );
1042
1087
return -1 ;
1043
- install_packed_git ( preq -> target );
1088
+ }
1044
1089
1090
+ install_packed_git (p );
1091
+ free (tmp_idx );
1045
1092
return 0 ;
1046
1093
}
1047
1094
1048
1095
struct http_pack_request * new_http_pack_request (
1049
1096
struct packed_git * target , const char * base_url )
1050
1097
{
1051
- char * filename ;
1052
1098
long prev_posn = 0 ;
1053
1099
char range [RANGE_HEADER_SIZE ];
1054
1100
struct strbuf buf = STRBUF_INIT ;
@@ -1063,9 +1109,8 @@ struct http_pack_request *new_http_pack_request(
1063
1109
sha1_to_hex (target -> sha1 ));
1064
1110
preq -> url = strbuf_detach (& buf , NULL );
1065
1111
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 ));
1069
1114
preq -> packfile = fopen (preq -> tmpfile , "a" );
1070
1115
if (!preq -> packfile ) {
1071
1116
error ("Unable to open local file %s for pack" ,
@@ -1100,7 +1145,6 @@ struct http_pack_request *new_http_pack_request(
1100
1145
return preq ;
1101
1146
1102
1147
abort :
1103
- free (filename );
1104
1148
free (preq -> url );
1105
1149
free (preq );
1106
1150
return NULL ;
@@ -1155,7 +1199,6 @@ struct http_object_request *new_http_object_request(const char *base_url,
1155
1199
freq -> localfile = -1 ;
1156
1200
1157
1201
filename = sha1_file_name (sha1 );
1158
- snprintf (freq -> filename , sizeof (freq -> filename ), "%s" , filename );
1159
1202
snprintf (freq -> tmpfile , sizeof (freq -> tmpfile ),
1160
1203
"%s.temp" , filename );
1161
1204
@@ -1184,8 +1227,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
1184
1227
}
1185
1228
1186
1229
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 ));
1189
1232
goto abort ;
1190
1233
}
1191
1234
@@ -1232,8 +1275,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
1232
1275
prev_posn = 0 ;
1233
1276
lseek (freq -> localfile , 0 , SEEK_SET );
1234
1277
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 ));
1237
1280
goto abort ;
1238
1281
}
1239
1282
}
@@ -1309,7 +1352,7 @@ int finish_http_object_request(struct http_object_request *freq)
1309
1352
return -1 ;
1310
1353
}
1311
1354
freq -> rename =
1312
- move_temp_to_file (freq -> tmpfile , freq -> filename );
1355
+ move_temp_to_file (freq -> tmpfile , sha1_file_name ( freq -> sha1 ) );
1313
1356
1314
1357
return freq -> rename ;
1315
1358
}
0 commit comments