2 * Copyright (c) 2006 Franck Bui-Huu
9 #include "run-command.h"
11 static const char upload_archive_usage
[] =
12 "git upload-archive <repo>";
14 static const char deadchild
[] =
15 "git upload-archive: archiver died with error";
17 static const char lostchild
[] =
18 "git upload-archive: archiver process was lost";
22 static void prepare_argv(const char **sent_argv
, const char **argv
)
24 const char *arg_cmd
= "argument ";
29 /* put received options in sent_argv[] */
31 sent_argv
[0] = "archive";
32 sent_argv
[1] = "--remote-request";
34 /* This will die if not enough free space in buf */
35 len
= packet_read_line(0, p
, (buf
+ sizeof buf
) - p
);
37 break; /* got a flush */
38 if (sent_argc
> MAX_ARGS
- 2)
39 die("Too many options (>%d)", MAX_ARGS
- 2);
41 if (p
[len
-1] == '\n') {
44 if (len
< strlen(arg_cmd
) ||
45 strncmp(arg_cmd
, p
, strlen(arg_cmd
)))
46 die("'argument' token or flush expected");
48 len
-= strlen(arg_cmd
);
49 memmove(p
, p
+ strlen(arg_cmd
), len
);
50 sent_argv
[sent_argc
++] = p
;
54 sent_argv
[sent_argc
] = NULL
;
57 __attribute__((format (printf
, 1, 2)))
58 static void error_clnt(const char *fmt
, ...)
64 va_start(params
, fmt
);
65 len
= vsprintf(buf
, fmt
, params
);
67 send_sideband(1, 3, buf
, len
, LARGE_PACKET_MAX
);
68 die("sent error to the client: %s", buf
);
71 static ssize_t
process_input(int child_fd
, int band
)
74 ssize_t sz
= read(child_fd
, buf
, sizeof(buf
));
76 if (errno
!= EAGAIN
&& errno
!= EINTR
)
77 error_clnt("read error: %s\n", strerror(errno
));
80 send_sideband(1, band
, buf
, sz
, LARGE_PACKET_MAX
);
84 int cmd_upload_archive(int argc
, const char **argv
, const char *prefix
)
86 const char *sent_argv
[MAX_ARGS
];
87 struct child_process cld
= { sent_argv
};
88 cld
.out
= cld
.err
= -1;
92 usage(upload_archive_usage
);
94 if (!enter_repo(argv
[1], 0))
95 die("'%s' does not appear to be a git repository", argv
[1]);
97 prepare_argv(sent_argv
, argv
);
98 if (start_command(&cld
)) {
100 packet_write(1, "NACK fork failed on the remote side\n");
101 die("upload-archive: %s", strerror(err
));
104 /* parent - read from child, multiplex and send out to fd#1 */
105 packet_write(1, "ACK\n");
109 struct pollfd pfd
[2];
113 pfd
[0].events
= POLLIN
;
115 pfd
[1].events
= POLLIN
;
116 if (poll(pfd
, 2, -1) < 0) {
117 if (errno
!= EINTR
) {
118 error("poll failed resuming: %s",
124 if (pfd
[1].revents
& POLLIN
)
125 /* Status stream ready */
126 if (process_input(pfd
[1].fd
, 2))
128 if (pfd
[0].revents
& POLLIN
)
129 /* Data stream ready */
130 if (process_input(pfd
[0].fd
, 1))
133 if (waitpid(cld
.pid
, &status
, 0) < 0)
134 error_clnt("%s", lostchild
);
135 else if (!WIFEXITED(status
) || WEXITSTATUS(status
) > 0)
136 error_clnt("%s", deadchild
);