command.c 5.17 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

/* 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
do_command_die_on_null(struct command *s,
		       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
114
struct lsh_object *
115
116
117
118
119
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
120
121
122

/* GABA:
   (class
123
124
     (name collect_state_1)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
125
     (vars
126
       (info object collect_info_2)
Niels Möller's avatar
Niels Möller committed
127
128
129
130
131
       (a object lsh_object)))
*/

/* GABA:
   (class
132
133
     (name collect_state_2)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
134
     (vars
135
136
       (info object collect_info_3)
       (a object lsh_object)
Niels Möller's avatar
Niels Möller committed
137
138
       (b object lsh_object)))
*/
139

Niels Möller's avatar
Niels Möller committed
140
141
/* GABA:
   (class
142
143
     (name collect_state_3)
     (super command_simple)
Niels Möller's avatar
Niels Möller committed
144
     (vars
145
146
147
       (info object collect_info_4)
       (a object lsh_object)
       (b object lsh_object)
Niels Möller's avatar
Niels Möller committed
148
149
150
       (c object lsh_object)))
*/

151
152
153
static struct lsh_object *
do_collect_2(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
154
{
155
156
  CAST(collect_state_1, self, s);
  return self->info->f(self->info, self->a, x);
Niels Möller's avatar
Niels Möller committed
157
158
}

159
160
161
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
162
{
163
164
165
166
167
168
  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
169
  
170
  return &self->super.super.super;
Niels Möller's avatar
Niels Möller committed
171
172
173
}

static struct lsh_object *
174
175
do_collect_3(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
176
{
177
178
  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
179
180
}

181
182
183
184
struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
		     struct lsh_object *a,
		     struct lsh_object *b)
185
{
186
187
188
189
  NEW(collect_state_2, self);
  self->info = info->next;
  self->a = a;
  self->b = b;
Niels Möller's avatar
Niels Möller committed
190
  
191
192
193
194
  self->super.call_simple = do_collect_3;
  self->super.super.call = do_call_simple_command;
  
  return &self->super.super.super;
195
}
Niels Möller's avatar
Niels Möller committed
196

197
198
199
static struct lsh_object *
do_collect_4(struct command_simple *s,
	     struct lsh_object *x)
Niels Möller's avatar
Niels Möller committed
200
{
201
202
203
  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
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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
221
222
}