12 #include <curl/curl.h>
13 #include <curl/easy.h>
20 static z_stream stream
;
25 static size_t fwrite_sha1_file(void *ptr
, size_t eltsize
, size_t nmemb
,
28 size_t size
= eltsize
* nmemb
;
31 ssize_t retval
= write(local
, ptr
+ posn
, size
- posn
);
35 } while (posn
< size
);
37 stream
.avail_in
= size
;
40 stream
.next_out
= expn
;
41 stream
.avail_out
= sizeof(expn
);
42 zret
= inflate(&stream
, Z_SYNC_FLUSH
);
43 SHA1_Update(&c
, expn
, sizeof(expn
) - stream
.avail_out
);
44 } while (stream
.avail_in
&& zret
== Z_OK
);
48 int fetch(unsigned char *sha1
)
50 char *hex
= sha1_to_hex(sha1
);
51 char *filename
= sha1_file_name(sha1
);
56 if (has_sha1_file(sha1
)) {
60 local
= open(filename
, O_WRONLY
| O_CREAT
| O_EXCL
, 0666);
63 return error("Couldn't open %s\n", filename
);
65 memset(&stream
, 0, sizeof(stream
));
71 curl_easy_setopt(curl
, CURLOPT_FILE
, NULL
);
72 curl_easy_setopt(curl
, CURLOPT_WRITEFUNCTION
, fwrite_sha1_file
);
74 url
= xmalloc(strlen(base
) + 50);
76 posn
= url
+ strlen(base
);
77 strcpy(posn
, "objects/");
82 strcpy(posn
, hex
+ 2);
84 curl_easy_setopt(curl
, CURLOPT_URL
, url
);
86 /*printf("Getting %s\n", hex);*/
88 if (curl_easy_perform(curl
))
89 return error("Couldn't get %s for %s\n", url
, hex
);
93 SHA1_Final(real_sha1
, &c
);
94 if (zret
!= Z_STREAM_END
) {
96 return error("File %s (%s) corrupt\n", hex
, url
);
98 if (memcmp(sha1
, real_sha1
, 20)) {
100 return error("File %s has bad hash\n", hex
);
106 int main(int argc
, char **argv
)
112 while (arg
< argc
&& argv
[arg
][0] == '-') {
113 if (argv
[arg
][1] == 't') {
115 } else if (argv
[arg
][1] == 'c') {
117 } else if (argv
[arg
][1] == 'a') {
124 if (argc
< arg
+ 2) {
125 usage("http-pull [-c] [-t] [-a] commit-id url");
128 commit_id
= argv
[arg
];
131 curl_global_init(CURL_GLOBAL_ALL
);
133 curl
= curl_easy_init();
140 curl_global_cleanup();