]>
Commit | Line | Data |
---|---|---|
d48be35c | 1 | #include "git-compat-util.h" |
8ea40cc5 | 2 | #include "test-tool.h" |
74e70029 | 3 | #include "pkt-line.h" |
545f7b50 | 4 | #include "sideband.h" |
d48be35c | 5 | #include "write-or-die.h" |
eaa82f8e | 6 | #include "parse-options.h" |
74e70029 BW |
7 | |
8 | static void pack_line(const char *line) | |
9 | { | |
10 | if (!strcmp(line, "0000") || !strcmp(line, "0000\n")) | |
11 | packet_flush(1); | |
12 | else if (!strcmp(line, "0001") || !strcmp(line, "0001\n")) | |
13 | packet_delim(1); | |
14 | else | |
15 | packet_write_fmt(1, "%s", line); | |
16 | } | |
17 | ||
18 | static void pack(int argc, const char **argv) | |
19 | { | |
20 | if (argc) { /* read from argv */ | |
21 | int i; | |
22 | for (i = 0; i < argc; i++) | |
23 | pack_line(argv[i]); | |
24 | } else { /* read from stdin */ | |
25 | char line[LARGE_PACKET_MAX]; | |
26 | while (fgets(line, sizeof(line), stdin)) { | |
27 | pack_line(line); | |
28 | } | |
29 | } | |
30 | } | |
31 | ||
64f0109f ÆAB |
32 | static void pack_raw_stdin(void) |
33 | { | |
34 | struct strbuf sb = STRBUF_INIT; | |
35 | ||
36 | if (strbuf_read(&sb, 0, 0) < 0) | |
37 | die_errno("failed to read from stdin"); | |
38 | packet_write(1, sb.buf, sb.len); | |
39 | strbuf_release(&sb); | |
40 | } | |
41 | ||
74e70029 BW |
42 | static void unpack(void) |
43 | { | |
44 | struct packet_reader reader; | |
45 | packet_reader_init(&reader, 0, NULL, 0, | |
46 | PACKET_READ_GENTLE_ON_EOF | | |
47 | PACKET_READ_CHOMP_NEWLINE); | |
48 | ||
49 | while (packet_reader_read(&reader) != PACKET_READ_EOF) { | |
50 | switch (reader.status) { | |
51 | case PACKET_READ_EOF: | |
52 | break; | |
53 | case PACKET_READ_NORMAL: | |
54 | printf("%s\n", reader.line); | |
55 | break; | |
56 | case PACKET_READ_FLUSH: | |
57 | printf("0000\n"); | |
58 | break; | |
59 | case PACKET_READ_DELIM: | |
60 | printf("0001\n"); | |
61 | break; | |
0181b600 DL |
62 | case PACKET_READ_RESPONSE_END: |
63 | printf("0002\n"); | |
64 | break; | |
74e70029 BW |
65 | } |
66 | } | |
67 | } | |
68 | ||
eaa82f8e | 69 | static void unpack_sideband(int argc, const char **argv) |
4bcd37d3 BW |
70 | { |
71 | struct packet_reader reader; | |
eaa82f8e JX |
72 | int options = PACKET_READ_GENTLE_ON_EOF; |
73 | int chomp_newline = 1; | |
74 | int reader_use_sideband = 0; | |
75 | const char *const unpack_sideband_usage[] = { | |
76 | "test_tool unpack_sideband [options...]", NULL | |
77 | }; | |
78 | struct option cmd_options[] = { | |
79 | OPT_BOOL(0, "reader-use-sideband", &reader_use_sideband, | |
80 | "set use_sideband bit for packet reader (Default: off)"), | |
81 | OPT_BOOL(0, "chomp-newline", &chomp_newline, | |
82 | "chomp newline in packet (Default: on)"), | |
83 | OPT_END() | |
84 | }; | |
85 | ||
86 | argc = parse_options(argc, argv, "", cmd_options, unpack_sideband_usage, | |
87 | 0); | |
88 | if (argc > 0) | |
89 | usage_msg_opt(_("too many arguments"), unpack_sideband_usage, | |
90 | cmd_options); | |
91 | ||
92 | if (chomp_newline) | |
93 | options |= PACKET_READ_CHOMP_NEWLINE; | |
94 | packet_reader_init(&reader, 0, NULL, 0, options); | |
95 | reader.use_sideband = reader_use_sideband; | |
4bcd37d3 BW |
96 | |
97 | while (packet_reader_read(&reader) != PACKET_READ_EOF) { | |
98 | int band; | |
99 | int fd; | |
100 | ||
101 | switch (reader.status) { | |
102 | case PACKET_READ_EOF: | |
103 | break; | |
104 | case PACKET_READ_NORMAL: | |
eaa82f8e JX |
105 | /* |
106 | * When the "use_sideband" field of the reader is turned | |
107 | * on, sideband packets other than the payload have been | |
108 | * parsed and consumed in packet_reader_read(), and only | |
109 | * the payload arrives here. | |
110 | */ | |
111 | if (reader.use_sideband) { | |
112 | write_or_die(1, reader.line, reader.pktlen - 1); | |
113 | break; | |
114 | } | |
115 | ||
4bcd37d3 BW |
116 | band = reader.line[0] & 0xff; |
117 | if (band < 1 || band > 2) | |
84370e36 | 118 | continue; /* skip non-sideband packets */ |
4bcd37d3 BW |
119 | fd = band; |
120 | ||
121 | write_or_die(fd, reader.line + 1, reader.pktlen - 1); | |
122 | break; | |
123 | case PACKET_READ_FLUSH: | |
124 | return; | |
125 | case PACKET_READ_DELIM: | |
0181b600 | 126 | case PACKET_READ_RESPONSE_END: |
4bcd37d3 BW |
127 | break; |
128 | } | |
129 | } | |
130 | } | |
131 | ||
17e7dbbc JS |
132 | static int send_split_sideband(void) |
133 | { | |
eaa82f8e JX |
134 | const char *foo = "Foo.\n"; |
135 | const char *bar = "Bar.\n"; | |
17e7dbbc JS |
136 | const char *part1 = "Hello,"; |
137 | const char *primary = "\001primary: regular output\n"; | |
138 | const char *part2 = " world!\n"; | |
139 | ||
eaa82f8e JX |
140 | /* Each sideband message has a trailing newline character. */ |
141 | send_sideband(1, 2, foo, strlen(foo), LARGE_PACKET_MAX); | |
142 | send_sideband(1, 2, bar, strlen(bar), LARGE_PACKET_MAX); | |
143 | ||
144 | /* | |
145 | * One sideband message is divided into part1 and part2 | |
146 | * by the primary message. | |
147 | */ | |
17e7dbbc JS |
148 | send_sideband(1, 2, part1, strlen(part1), LARGE_PACKET_MAX); |
149 | packet_write(1, primary, strlen(primary)); | |
150 | send_sideband(1, 2, part2, strlen(part2), LARGE_PACKET_MAX); | |
151 | packet_response_end(1); | |
152 | ||
eaa82f8e JX |
153 | /* |
154 | * We use unpack_sideband() to consume packets. A flush packet | |
155 | * is required to end parsing. | |
156 | */ | |
157 | packet_flush(1); | |
158 | ||
17e7dbbc JS |
159 | return 0; |
160 | } | |
161 | ||
162 | static int receive_sideband(void) | |
163 | { | |
712b0377 | 164 | return recv_sideband("sideband", 0, 1); |
17e7dbbc JS |
165 | } |
166 | ||
8ea40cc5 | 167 | int cmd__pkt_line(int argc, const char **argv) |
74e70029 BW |
168 | { |
169 | if (argc < 2) | |
170 | die("too few arguments"); | |
171 | ||
172 | if (!strcmp(argv[1], "pack")) | |
173 | pack(argc - 2, argv + 2); | |
64f0109f ÆAB |
174 | else if (!strcmp(argv[1], "pack-raw-stdin")) |
175 | pack_raw_stdin(); | |
74e70029 BW |
176 | else if (!strcmp(argv[1], "unpack")) |
177 | unpack(); | |
4bcd37d3 | 178 | else if (!strcmp(argv[1], "unpack-sideband")) |
eaa82f8e | 179 | unpack_sideband(argc - 1, argv + 1); |
17e7dbbc JS |
180 | else if (!strcmp(argv[1], "send-split-sideband")) |
181 | send_split_sideband(); | |
182 | else if (!strcmp(argv[1], "receive-sideband")) | |
183 | receive_sideband(); | |
74e70029 BW |
184 | else |
185 | die("invalid argument '%s'", argv[1]); | |
186 | ||
187 | return 0; | |
188 | } |