~ubuntu-branches/ubuntu/trusty/lebiniou/trusty

« back to all changes in this revision

Viewing changes to plugins/stable/output/erlang/erlang.c

  • Committer: Package Import Robot
  • Author(s): Olivier Girondel
  • Date: 2011-10-22 21:04:28 UTC
  • mfrom: (6.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20111022210428-98wk8rbx1mj3wuzo
Tags: 3.13-1
* New upstream release 3.13.
* Put all library flags in LIBS instead of LDFLAGS. (Closes: #647100)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
18
18
 */
19
19
 
20
 
#include "context.h"
21
 
 
22
 
#if HAVE_ARPA_INET_H
23
 
#include <arpa/inet.h>
24
 
#endif
25
 
 
26
 
 
27
 
#define PROTOCOL     '6'
 
20
#include "erlang.h"
 
21
 
 
22
 
 
23
#define PROTOCOL     '7'
28
24
#define MAX_PROTOCOL PROTOCOL
29
25
 
30
26
char proto = PROTOCOL;
46
42
#define IN_FD      3
47
43
#define OUT_FD     4
48
44
 
49
 
/* commands */
50
 
#define CMD_CHAR  'C'
51
 
#define STOP_CHAR 'S'
52
 
 
53
45
FILE *in = NULL, *out = NULL;
54
46
 
55
47
 
59
51
extern void v4(const Context_t *);
60
52
extern void v5(const Context_t *);
61
53
extern void v6(const Context_t *);
62
 
 
 
54
extern void v7(const Context_t *);
 
55
 
 
56
 
 
57
uint32_t last_colormap;
 
58
uint32_t last_picture;
 
59
uint32_t last_sequence;
 
60
 
 
61
char send_colormap_update;
 
62
char send_picture_update;
 
63
char send_sequence_update;
 
64
 
 
65
 
 
66
static int set_nonblocking(int);
63
67
 
64
68
void
65
69
create(__attribute__ ((unused)) Context_t *ctx)
66
70
{
67
71
  int flags;
68
72
  char *env;
 
73
  int ret;
69
74
 
 
75
#if 0
70
76
  in = fdopen(IN_FD, "r");
71
77
  if (NULL == in)
72
78
    xperror("fdopen");
74
80
    flags = 0;
75
81
  if (-1 == fcntl(IN_FD, F_SETFL, flags | O_NONBLOCK))
76
82
    xperror("fcntl");
 
83
#else
 
84
  ret = set_nonblocking(IN_FD); /* FIXME do something with ret */
 
85
#endif
77
86
 
 
87
#if 0
78
88
  out = fdopen(OUT_FD, "w");
79
89
  if (NULL == out)
80
90
    xperror("fdopen");
 
91
#endif
81
92
 
82
93
  env = getenv("BINIOU_ERLANG_PROTO");
83
94
  if (NULL != env) {
90
101
      proto = v;
91
102
    }
92
103
  }
 
104
 
 
105
  last_colormap = last_picture = last_sequence = 0;
93
106
}
94
107
 
95
108
 
98
111
{
99
112
  if (fclose(in) != 0)
100
113
    xperror("fclose");
 
114
#if 0
101
115
  if (fclose(out) != 0)
102
116
    xperror("fclose");
 
117
#endif
103
118
}
104
119
 
105
120
 
117
132
}
118
133
 
119
134
 
120
 
/* did we receive a stop from the erlang side ? */
121
 
/* or, process a command */
122
 
static int
123
 
done(Context_t *ctx)
124
 
{
125
 
  u_long pkt_size, pkt_size2;
126
 
  char cmd[4] = "XXXX";
 
135
static int
 
136
set_nonblocking(int fd)
 
137
{
 
138
  int flags;
 
139
 
 
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)))
 
144
    flags = 0;
 
145
  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
 
146
#else
 
147
  /* Otherwise, use the old way of doing it */
 
148
  flags = 1;
 
149
  return ioctl(fd, FIOBIO, &flags);
 
150
#endif
 
151
}
 
152
 
 
153
 
 
154
int
 
155
read_exact(u_char *buf, const int len)
 
156
{
 
157
  int i, got = 0;
 
158
 
 
159
  do {
 
160
    if ((i = read(IN_FD, buf+got, len-got)) <= 0)
 
161
      return i;
 
162
    got += i;
 
163
  } while (got < len);
 
164
 
 
165
  return len;
 
166
}
 
167
 
 
168
 
 
169
int
 
170
write_exact(const u_char *buf, const int len)
 
171
{
 
172
  int i, wrote = 0;
 
173
 
 
174
  do {
 
175
    if ((i = write(OUT_FD, buf+wrote, len-wrote)) <= 0)
 
176
      return i;
 
177
    wrote += i;
 
178
  } while (wrote < len);
 
179
 
 
180
  return len;
 
181
}
 
182
 
 
183
 
 
184
static void
 
185
create_or_skip_sequence(const uint32_t id)
 
186
{
 
187
  Sequence_t *seq = Sequences_find(id);
 
188
}
 
189
 
 
190
 
 
191
/* Process any command coming from the erlang side */
 
192
static int
 
193
command(Context_t *ctx)
 
194
{
 
195
  uint32_t pkt_size, pkt_size2;
 
196
  u_char cmd[BUFLEN+1];
127
197
  size_t res;
128
198
 
129
 
  res = fread((void *)&pkt_size, sizeof(u_long), 1, in);
130
 
  if (0 == res)
 
199
  res = read_exact((u_char *)&pkt_size, sizeof(uint32_t));
 
200
  if (-1 == res)
131
201
    return 0;
132
202
 
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__);
 
206
 
 
207
  memset((void *)&cmd, 0, BUFLEN*sizeof(u_char));
 
208
  res = read_exact((u_char *)&cmd, sizeof(u_char)*pkt_size2);
137
209
 
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");
141
 
      return 1;
142
 
    }
 
213
      return -1;
 
214
    } else
 
215
      xerror("Unknown 1-byte command %d\n", cmd[0]);
143
216
 
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];
151
224
      
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);
154
 
 
155
 
      return 0;
156
 
    }
 
226
      return 1;
 
227
    } else
 
228
      xerror("Unknown 4-bytes command %d\n", cmd[0]);
 
229
 
 
230
  if (6 == res) /* set picture/colormap/sequence */
 
231
    if (UPDATE_CHAR == cmd[0]) {
 
232
      uint32_t *id, id2;
 
233
 
 
234
      id = (uint32_t *)&cmd[2];
 
235
      id2 = ntohl(*id);
 
236
 
 
237
      switch (cmd[1]) {
 
238
      case UPDATE_COLORMAP_CHAR:
 
239
        ctx->sm->next->cmap_id = id2;
 
240
        Context_set_colormap(ctx);
 
241
        last_colormap = id2;
 
242
        send_colormap_update = 0;
 
243
        break;
 
244
 
 
245
      case UPDATE_PICTURE_CHAR:
 
246
        ctx->sm->next->picture_id = id2;
 
247
        Context_set_picture(ctx);
 
248
        last_picture = id2;
 
249
        send_picture_update = 0;
 
250
        break;
 
251
 
 
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);
 
256
          last_sequence = id2;
 
257
          send_sequence_update = send_colormap_update = send_picture_update = 0;
 
258
        }
 
259
        break;
 
260
 
 
261
      default:
 
262
        xerror("Wrong 6-byte command\n");
 
263
        break;
 
264
      }
 
265
 
 
266
      return 1;
 
267
    } else
 
268
      xerror("Unknown 6-byte command %d\n", cmd[0]);
157
269
 
158
270
  xerror("Got wrong packet length from erlang: %li\n", pkt_size2);
159
271
 
165
277
run(Context_t *ctx)
166
278
{
167
279
  uint32_t total, total2;
168
 
 
169
 
  if (done(ctx)) {
170
 
    char c = STOP_CHAR;
 
280
  int res;
 
281
 
 
282
  send_colormap_update =
 
283
    send_picture_update =
 
284
    send_sequence_update = 1;
 
285
 
 
286
  do
 
287
    res = command(ctx);
 
288
  while (res == 1);
 
289
 
 
290
  if (res == -1) {
 
291
    u_char c = STOP_CHAR;
 
292
    int ret;
171
293
    
172
294
    ctx->running = 0;
173
295
 
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));
179
301
 
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));
182
304
  } else {
183
305
    switch (proto) {
184
306
    case '1':
205
327
      v6(ctx);
206
328
      break;
207
329
 
 
330
    case '7':
 
331
      v7(ctx);
 
332
      break;
 
333
 
208
334
    default:
209
335
      xerror("Unknown protocol version\n");
210
336
      break;