3 #include "run-command.h"
5 static const struct transport_ops rsync_transport
;
7 static int curl_transport_push(struct transport
*transport
, int refspec_nr
, const char **refspec
, int flags
) {
12 argv
= xmalloc((refspec_nr
+ 11) * sizeof(char *));
13 argv
[0] = "http-push";
15 if (flags
& TRANSPORT_PUSH_ALL
)
16 argv
[argc
++] = "--all";
17 if (flags
& TRANSPORT_PUSH_FORCE
)
18 argv
[argc
++] = "--force";
19 argv
[argc
++] = transport
->url
;
21 argv
[argc
++] = *refspec
++;
23 err
= run_command_v_opt(argv
, RUN_GIT_CMD
);
25 case -ERR_RUN_COMMAND_FORK
:
26 error("unable to fork for %s", argv
[0]);
27 case -ERR_RUN_COMMAND_EXEC
:
28 error("unable to exec %s", argv
[0]);
30 case -ERR_RUN_COMMAND_WAITPID
:
31 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID
:
32 case -ERR_RUN_COMMAND_WAITPID_SIGNAL
:
33 case -ERR_RUN_COMMAND_WAITPID_NOEXIT
:
34 error("%s died with strange error", argv
[0]);
39 static const struct transport_ops curl_transport
= {
40 /* set_option */ NULL
,
41 /* push */ curl_transport_push
44 static const struct transport_ops bundle_transport
= {
47 struct git_transport_data
{
50 const char *receivepack
;
53 static int set_git_option(struct transport
*connection
,
54 const char *name
, const char *value
)
56 struct git_transport_data
*data
= connection
->data
;
57 if (!strcmp(name
, TRANS_OPT_RECEIVEPACK
)) {
58 data
->receivepack
= value
;
60 } else if (!strcmp(name
, TRANS_OPT_THIN
)) {
67 static int git_transport_push(struct transport
*transport
, int refspec_nr
, const char **refspec
, int flags
) {
68 struct git_transport_data
*data
= transport
->data
;
74 argv
= xmalloc((refspec_nr
+ 11) * sizeof(char *));
75 argv
[0] = "send-pack";
77 if (flags
& TRANSPORT_PUSH_ALL
)
78 argv
[argc
++] = "--all";
79 if (flags
& TRANSPORT_PUSH_FORCE
)
80 argv
[argc
++] = "--force";
81 if (data
->receivepack
) {
82 char *rp
= xmalloc(strlen(data
->receivepack
) + 16);
83 sprintf(rp
, "--receive-pack=%s", data
->receivepack
);
87 argv
[argc
++] = "--thin";
88 rem
= xmalloc(strlen(transport
->remote
->name
) + 10);
89 sprintf(rem
, "--remote=%s", transport
->remote
->name
);
91 argv
[argc
++] = transport
->url
;
93 argv
[argc
++] = *refspec
++;
95 err
= run_command_v_opt(argv
, RUN_GIT_CMD
);
97 case -ERR_RUN_COMMAND_FORK
:
98 error("unable to fork for %s", argv
[0]);
99 case -ERR_RUN_COMMAND_EXEC
:
100 error("unable to exec %s", argv
[0]);
102 case -ERR_RUN_COMMAND_WAITPID
:
103 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID
:
104 case -ERR_RUN_COMMAND_WAITPID_SIGNAL
:
105 case -ERR_RUN_COMMAND_WAITPID_NOEXIT
:
106 error("%s died with strange error", argv
[0]);
111 static const struct transport_ops git_transport
= {
112 /* set_option */ set_git_option
,
113 /* push */ git_transport_push
116 static int is_local(const char *url
)
118 const char *colon
= strchr(url
, ':');
119 const char *slash
= strchr(url
, '/');
120 return !colon
|| (slash
&& slash
< colon
);
123 static int is_file(const char *url
)
128 return S_ISREG(buf
.st_mode
);
131 struct transport
*transport_get(struct remote
*remote
, const char *url
,
134 struct transport
*ret
= NULL
;
135 if (!prefixcmp(url
, "rsync://")) {
136 ret
= xmalloc(sizeof(*ret
));
138 ret
->ops
= &rsync_transport
;
139 } else if (!prefixcmp(url
, "http://") || !prefixcmp(url
, "https://") ||
140 !prefixcmp(url
, "ftp://")) {
141 ret
= xmalloc(sizeof(*ret
));
142 ret
->ops
= &curl_transport
;
144 } else if (is_local(url
) && is_file(url
)) {
145 ret
= xmalloc(sizeof(*ret
));
147 ret
->ops
= &bundle_transport
;
149 struct git_transport_data
*data
= xcalloc(1, sizeof(*data
));
150 ret
= xcalloc(1, sizeof(*ret
));
153 data
->receivepack
= "git-receive-pack";
154 if (remote
&& remote
->receivepack
)
155 data
->receivepack
= remote
->receivepack
;
156 ret
->ops
= &git_transport
;
159 ret
->remote
= remote
;
161 ret
->fetch
= !!fetch
;
166 int transport_set_option(struct transport
*transport
,
167 const char *name
, const char *value
)
170 if (transport
->ops
->set_option
)
171 ret
= transport
->ops
->set_option(transport
, name
, value
);
173 fprintf(stderr
, "For '%s' option %s cannot be set to '%s'\n",
174 transport
->url
, name
, value
);
176 fprintf(stderr
, "For '%s' option %s is ignored\n",
177 transport
->url
, name
);
181 int transport_push(struct transport
*transport
,
182 int refspec_nr
, const char **refspec
, int flags
)
184 if (!transport
->ops
->push
)
186 return transport
->ops
->push(transport
, refspec_nr
, refspec
, flags
);
189 int transport_disconnect(struct transport
*transport
)
192 if (transport
->ops
->disconnect
)
193 ret
= transport
->ops
->disconnect(transport
);