command.c 7.03 KB
Newer Older
1
/* command.c
Niels Möller's avatar
Niels Möller committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 *
 * $Id$ */

/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Mller
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "command.h"

26
27
#include "connection.h"
#include "io.h"
28
#include "werror.h"
29
30
#include "xalloc.h"

31
32
#include <assert.h>

33
#define GABA_DEFINE
34
#include "command.h.x"
35
#undef GABA_DEFINE
36
37
38

#include "command.c.x"

39
/* GABA:
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
   (class
     (name command_apply)
     (super command_frame)
     (vars
       (f object command)))
*/

static int do_command_apply(struct command_continuation *s,
			    struct lsh_object *value)
{
  CAST(command_apply, self, s);
  return COMMAND_CALL(self->f, value, self->super.up);
}

struct command_continuation *
make_apply(struct command *f, struct command_continuation *c)
{
  NEW(command_apply, res);
  res->f = f;
  res->super.up = c;
  res->super.super.c = do_command_apply;

  return &res->super.super;
}
64

Niels Möller's avatar
Niels Möller committed
65
66
struct lsh_object *gaba_apply(struct lsh_object *f,
			      struct lsh_object *x)
67
68
69
70
71
{
  CAST_SUBTYPE(command_simple, cf, f);
  return COMMAND_SIMPLE(cf, x);
}

72
int do_call_simple_command(struct command *s,
73
74
75
			   struct lsh_object *arg,
			   struct command_continuation *c)
{
76
  CAST_SUBTYPE(command_simple, self, s);
77
78
79
  return COMMAND_RETURN(c, COMMAND_SIMPLE(self, arg));
}

80

81
82
83
84
85
86
/* Unimplemented command */
static int
do_command_unimplemented(struct command *s UNUSED,
			 struct lsh_object *o UNUSED,
			 struct command_continuation *c UNUSED)
{ fatal("command.c: Unimplemented command.\n"); }
Niels Möller's avatar
Niels Möller committed
87

88
89
90
91
static struct lsh_object *
do_command_simple_unimplemented(struct command_simple *s UNUSED,
				struct lsh_object *o UNUSED)
{ fatal("command.c: Unimplemented simple command.\n"); }
Niels Möller's avatar
Niels Möller committed
92

93
94
95
struct command_simple command_unimplemented =
{ { STATIC_HEADER, do_command_unimplemented}, do_command_simple_unimplemented};

96

Niels Möller's avatar
Niels Möller committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* Tracing
 *
 * For now, trace only function entry. */

/* GABA:
   (class
     (name trace_command)
     (super command)
     (vars
       (name . "const char *")
       (real object command)))
*/

static int do_trace_command(struct command *s,
			    struct lsh_object *x,
			    struct command_continuation *c)
{
  CAST(trace_command, self, s);

  trace("Entering %z\n", self->name);
  return COMMAND_CALL(self->real, x, c);
}

struct command *make_trace(const char *name, struct command *real)
{
  NEW(trace_command, self);
  self->super.call = do_trace_command;
  self->name = name;
  self->real = real;

  return &self->super;
}

struct lsh_object *collect_trace(const char *name, struct lsh_object *c)
{
  CAST_SUBTYPE(command, real, c);
  return &make_trace(name, real)->super;
}


137
138
139
140
141
/* Fail if NULL. This commands returns its argument unchanged. Unless
 * it is NULL, in which case it doesn't return at all, but instead
 * returns an LSH_FAIL status to the mainloop. */

static int
Niels Möller's avatar
Niels Möller committed
142
do_command_die_on_null(struct command *s UNUSED,
143
144
145
146
147
148
149
150
151
152
153
		       struct lsh_object *x,
		       struct command_continuation *c)
{
  return x ? COMMAND_RETURN(c, x) : LSH_FAIL | LSH_DIE;
}

struct command command_die_on_null =
{ STATIC_HEADER, do_command_die_on_null};


/* Collecting arguments */
Niels Möller's avatar
Niels Möller committed
154
struct lsh_object *
155
156
157
158
159
do_collect_1(struct command_simple *s, struct lsh_object *a)
{
  CAST(collect_info_1, self, s);
  return self->f(self, a);
}
Niels Möller's avatar
Niels Möller committed
160
161
162

/* GABA:
   (class
163
164
     (name collect_state_1)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
165
     (vars
166
       (info object collect_info_2)
Niels Möller's avatar
Niels Möller committed
167
168
169
170
171
       (a object lsh_object)))
*/

/* GABA:
   (class
172
173
     (name collect_state_2)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
174
     (vars
175
176
       (info object collect_info_3)
       (a object lsh_object)
Niels Möller's avatar
Niels Möller committed
177
178
       (b object lsh_object)))
*/
179

Niels Möller's avatar
Niels Möller committed
180
181
/* GABA:
   (class
182
183
     (name collect_state_3)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
184
     (vars
185
186
187
       (info object collect_info_4)
       (a object lsh_object)
       (b object lsh_object)
Niels Möller's avatar
Niels Möller committed
188
189
190
       (c object lsh_object)))
*/

191
192
193
static struct lsh_object *
do_collect_2(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
194
{
195
196
  CAST(collect_state_1, self, s);
  return self->info->f(self->info, self->a, x);
Niels Möller's avatar
Niels Möller committed
197
198
}

199
200
201
struct lsh_object *
make_collect_state_1(struct collect_info_1 *info,
		     struct lsh_object *a)
Niels Möller's avatar
Niels Möller committed
202
{
203
204
205
206
207
208
  NEW(collect_state_1, self);
  self->info = info->next;
  self->a = a;

  self->super.call_simple = do_collect_2;
  self->super.super.call = do_call_simple_command;
Niels Möller's avatar
Niels Möller committed
209
  
210
  return &self->super.super.super;
Niels Möller's avatar
Niels Möller committed
211
212
213
}

static struct lsh_object *
214
215
do_collect_3(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
216
{
217
218
  CAST(collect_state_2, self, s);
  return self->info->f(self->info, self->a, self->b, x);
Niels Möller's avatar
Niels Möller committed
219
220
}

221
222
223
224
struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
		     struct lsh_object *a,
		     struct lsh_object *b)
225
{
226
227
228
229
  NEW(collect_state_2, self);
  self->info = info->next;
  self->a = a;
  self->b = b;
Niels Möller's avatar
Niels Möller committed
230
  
231
232
233
234
  self->super.call_simple = do_collect_3;
  self->super.super.call = do_call_simple_command;
  
  return &self->super.super.super;
235
}
Niels Möller's avatar
Niels Möller committed
236

237
238
239
static struct lsh_object *
do_collect_4(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
240
{
241
242
243
  CAST(collect_state_3, self, s);
  return self->info->f(self->info, self->a, self->b, self->c, x);
}
Niels Möller's avatar
Niels Möller committed
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
struct lsh_object *
make_collect_state_3(struct collect_info_3 *info,
		     struct lsh_object *a,
		     struct lsh_object *b,
		     struct lsh_object *c)
{
  NEW(collect_state_3, self);
  self->info = info->next;
  self->a = a;
  self->b = b;
  self->c = c;
  
  self->super.call_simple = do_collect_4;
  self->super.super.call = do_call_simple_command;
  
  return &self->super.super.super;
Niels Möller's avatar
Niels Möller committed
261
262
}

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/* GABA:
   (class
     (name parallell_progn)
     (super command)
     (vars
       (body object object_list)))
*/

static int do_parallell_progn(struct command *s,
			      struct lsh_object *x,
			      struct command_continuation *c)
{
  CAST(parallell_progn, self, s);
  unsigned i;
  int res = 0;
  
  for (i=0; i < LIST_LENGTH(self->body) - 1; i++)
    {
      CAST_SUBTYPE(command, command, LIST(self->body)[i]);
      res |= COMMAND_CALL(command, x, NULL);
      if (LSH_CLOSEDP(res))
	return res;
    }
  {
    CAST_SUBTYPE(command, command, LIST(self->body)[i]);
    
    return res | COMMAND_CALL(command, x, c);
  }
}

struct command *make_parallell_progn(struct object_list *body)
{
  assert(LIST_LENGTH(body));
  {
    NEW(parallell_progn, self);
    self->body = body;
    self->super.call = do_parallell_progn;

    return &self->super;
  }
}
Niels Möller's avatar
Niels Möller committed
304
305
306
307
308

static struct lsh_object *do_progn(struct command_simple *s UNUSED,
				   struct lsh_object *x)
{
  CAST(object_list, body, x);
309
  return &make_parallell_progn(body)->super;
Niels Möller's avatar
Niels Möller committed
310
311
312
313
314
}

struct command_simple progn_command =
STATIC_COMMAND_SIMPLE(do_progn);