fetch-pack: Use a strbuf to compose the want list
[git/jrn.git] / remote-curl.c
blob2faf1c634415d139f15c4829937e0460be31dc1d
1 #include "cache.h"
2 #include "remote.h"
3 #include "strbuf.h"
4 #include "walker.h"
5 #include "http.h"
6 #include "exec_cmd.h"
8 static struct ref *get_refs(struct walker *walker, const char *url)
10 struct strbuf buffer = STRBUF_INIT;
11 char *data, *start, *mid;
12 char *ref_name;
13 char *refs_url;
14 int i = 0;
15 int http_ret;
17 struct ref *refs = NULL;
18 struct ref *ref = NULL;
19 struct ref *last_ref = NULL;
21 refs_url = xmalloc(strlen(url) + 11);
22 sprintf(refs_url, "%s/info/refs", url);
24 http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
25 switch (http_ret) {
26 case HTTP_OK:
27 break;
28 case HTTP_MISSING_TARGET:
29 die("%s not found: did you run git update-server-info on the"
30 " server?", refs_url);
31 default:
32 http_error(refs_url, http_ret);
33 die("HTTP request failed");
36 data = buffer.buf;
37 start = NULL;
38 mid = data;
39 while (i < buffer.len) {
40 if (!start) {
41 start = &data[i];
43 if (data[i] == '\t')
44 mid = &data[i];
45 if (data[i] == '\n') {
46 data[i] = 0;
47 ref_name = mid + 1;
48 ref = xmalloc(sizeof(struct ref) +
49 strlen(ref_name) + 1);
50 memset(ref, 0, sizeof(struct ref));
51 strcpy(ref->name, ref_name);
52 get_sha1_hex(start, ref->old_sha1);
53 if (!refs)
54 refs = ref;
55 if (last_ref)
56 last_ref->next = ref;
57 last_ref = ref;
58 start = NULL;
60 i++;
63 strbuf_release(&buffer);
65 ref = alloc_ref("HEAD");
66 if (!walker->fetch_ref(walker, ref) &&
67 !resolve_remote_symref(ref, refs)) {
68 ref->next = refs;
69 refs = ref;
70 } else {
71 free(ref);
74 strbuf_release(&buffer);
75 free(refs_url);
76 return refs;
79 int main(int argc, const char **argv)
81 struct remote *remote;
82 struct strbuf buf = STRBUF_INIT;
83 const char *url;
84 struct walker *walker = NULL;
86 git_extract_argv0_path(argv[0]);
87 setup_git_directory();
88 if (argc < 2) {
89 fprintf(stderr, "Remote needed\n");
90 return 1;
93 remote = remote_get(argv[1]);
95 if (argc > 2) {
96 url = argv[2];
97 } else {
98 url = remote->url[0];
101 do {
102 if (strbuf_getline(&buf, stdin, '\n') == EOF)
103 break;
104 if (!prefixcmp(buf.buf, "fetch ")) {
105 char *obj = buf.buf + strlen("fetch ");
106 if (!walker)
107 walker = get_http_walker(url, remote);
108 walker->get_all = 1;
109 walker->get_tree = 1;
110 walker->get_history = 1;
111 walker->get_verbosely = 0;
112 walker->get_recover = 0;
113 if (walker_fetch(walker, 1, &obj, NULL, NULL))
114 die("Fetch failed.");
115 printf("\n");
116 fflush(stdout);
117 } else if (!strcmp(buf.buf, "list")) {
118 struct ref *refs;
119 struct ref *posn;
120 if (!walker)
121 walker = get_http_walker(url, remote);
122 refs = get_refs(walker, url);
123 for (posn = refs; posn; posn = posn->next) {
124 if (posn->symref)
125 printf("@%s %s\n", posn->symref, posn->name);
126 else
127 printf("%s %s\n", sha1_to_hex(posn->old_sha1), posn->name);
129 printf("\n");
130 fflush(stdout);
131 } else if (!strcmp(buf.buf, "capabilities")) {
132 printf("fetch\n");
133 printf("\n");
134 fflush(stdout);
135 } else {
136 return 1;
138 strbuf_reset(&buf);
139 } while (1);
140 return 0;