59
51
extern void v4(const Context_t *);
60
52
extern void v5(const Context_t *);
61
53
extern void v6(const Context_t *);
54
extern void v7(const Context_t *);
57
uint32_t last_colormap;
58
uint32_t last_picture;
59
uint32_t last_sequence;
61
char send_colormap_update;
62
char send_picture_update;
63
char send_sequence_update;
66
static int set_nonblocking(int);
65
69
create(__attribute__ ((unused)) Context_t *ctx)
70
76
in = fdopen(IN_FD, "r");
120
/* did we receive a stop from the erlang side ? */
121
/* or, process a command */
125
u_long pkt_size, pkt_size2;
126
char cmd[4] = "XXXX";
136
set_nonblocking(int fd)
140
/* If they have O_NONBLOCK, use the Posix way to do it */
141
#if defined(O_NONBLOCK)
142
/* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */
143
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
145
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
147
/* Otherwise, use the old way of doing it */
149
return ioctl(fd, FIOBIO, &flags);
155
read_exact(u_char *buf, const int len)
160
if ((i = read(IN_FD, buf+got, len-got)) <= 0)
170
write_exact(const u_char *buf, const int len)
175
if ((i = write(OUT_FD, buf+wrote, len-wrote)) <= 0)
178
} while (wrote < len);
185
create_or_skip_sequence(const uint32_t id)
187
Sequence_t *seq = Sequences_find(id);
191
/* Process any command coming from the erlang side */
193
command(Context_t *ctx)
195
uint32_t pkt_size, pkt_size2;
196
u_char cmd[BUFLEN+1];
129
res = fread((void *)&pkt_size, sizeof(u_long), 1, in);
199
res = read_exact((u_char *)&pkt_size, sizeof(uint32_t));
133
203
pkt_size2 = ntohl(pkt_size);
134
// printf("erlang: pkt_size2= %d\n", pkt_size2);
135
res = fread((void *)&cmd, sizeof(char), pkt_size2, in);
136
// printf("erlang: got %d bytes\n", res);
204
if (pkt_size2 > BUFLEN)
205
xerror("%s:%d buffer overflow attempt\n", __FILE__, __LINE__);
207
memset((void *)&cmd, 0, BUFLEN*sizeof(u_char));
208
res = read_exact((u_char *)&cmd, sizeof(u_char)*pkt_size2);
138
210
if (1 == res) /* got one byte */
139
211
if (STOP_CHAR == cmd[0]) {
140
212
printf("[i] Erlang port: got STOP_CHAR\n");
215
xerror("Unknown 1-byte command %d\n", cmd[0]);
144
217
if (4 == res) /* got command */
145
218
if (CMD_CHAR == cmd[0]) {
149
222
e.cmd = (enum Command)cmd[2];
150
223
e.arg0 = (enum Arg)cmd[3];
152
printf("[i] Erlang port: got CMD_CHAR: %c (%d %d %d)\n", cmd[0], cmd[1], cmd[2], cmd[3]);
153
225
Context_event(ctx, &e);
228
xerror("Unknown 4-bytes command %d\n", cmd[0]);
230
if (6 == res) /* set picture/colormap/sequence */
231
if (UPDATE_CHAR == cmd[0]) {
234
id = (uint32_t *)&cmd[2];
238
case UPDATE_COLORMAP_CHAR:
239
ctx->sm->next->cmap_id = id2;
240
Context_set_colormap(ctx);
242
send_colormap_update = 0;
245
case UPDATE_PICTURE_CHAR:
246
ctx->sm->next->picture_id = id2;
247
Context_set_picture(ctx);
249
send_picture_update = 0;
252
case UPDATE_SEQUENCE_CHAR:
253
if (id2 != 0) { /* sent by auto-scheme mode */
254
create_or_skip_sequence(id2);
255
Context_set_sequence(ctx, id2);
257
send_sequence_update = send_colormap_update = send_picture_update = 0;
262
xerror("Wrong 6-byte command\n");
268
xerror("Unknown 6-byte command %d\n", cmd[0]);
158
270
xerror("Got wrong packet length from erlang: %li\n", pkt_size2);
175
297
/* send packet size */
176
298
total = sizeof(char);
177
299
total2 = htonl(total);
178
xfwrite((const void *)&total2, sizeof(uint32_t), 1, out);
300
ret = write_exact((const u_char *)&total2, sizeof(uint32_t));
180
302
/* send STOP_CHAR */
181
xfwrite((const void *)&c, sizeof(char), 1, out);
303
ret = write_exact((const u_char *)&c, sizeof(u_char));