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

/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Möller
 *
 * 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
Niels Möller's avatar
Niels Möller committed
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 23 24 25 26
 */

#ifndef LSH_COMMAND_H_INCLUDED
#define LSH_COMMAND_H_INCLUDED

27
#include "lsh.h"
28

29
#include "exception.h"
Niels Möller's avatar
Niels Möller committed
30
#include "list.h"
31
/* #include "io.h" */
Niels Möller's avatar
Niels Möller committed
32 33 34

#include <stdarg.h>

35
#define GABA_DECLARE
36
#include "command.h.x"
37
#undef GABA_DECLARE
38 39 40 41

/* Continuation based command execution. A command can take one object
 * as argument, and returns one object. */

42
/* GABA:
43 44 45
   (class
     (name command_continuation)
     (vars
46
       (c method void "struct lsh_object *result")))
Niels Möller's avatar
Niels Möller committed
47 48
*/

49
/* GABA:
50 51 52
   (class
     (name command)
     (vars
53 54 55
       (call method void "struct lsh_object *arg"
                         "struct command_continuation *c"
			 "struct exception_handler *e")))
56 57
*/

58
/* GABA:
59 60 61 62
   (class
     (name command_simple)
     (super command)
     (vars
63 64
       ; Like call, but returns the value immediately rather than
       ; using a continuation function.
65 66 67
       (call_simple method "struct lsh_object *" "struct lsh_object *")))
*/

68 69
#define COMMAND_CALL(f, a, c, e) \
  ((f)->call((f), (struct lsh_object *) (a), (c), (e)))
70 71 72

#define COMMAND_RETURN(r, v) ((r)->c((r), (struct lsh_object *) (v)))

73
#define COMMAND_SIMPLE_CALL(f, a) \
74
  ((f)->call_simple((f), (struct lsh_object *)(a)))
75

Niels Möller's avatar
Niels Möller committed
76 77 78 79 80 81
#define STATIC_COMMAND(f) { STATIC_HEADER, f }

#define STATIC_COMMAND_SIMPLE(f) \
{ STATIC_COMMAND(do_call_simple_command), f}


82
#define DEFINE_COMMAND_SIMPLE(cname, ARG)		\
83
static struct lsh_object *				\
84
do_simple_##cname(struct command_simple *,		\
85 86 87 88 89 90 91
		  struct lsh_object *a);		\
							\
struct command_simple cname =				\
STATIC_COMMAND_SIMPLE(do_simple_##cname);		\
							\
static struct lsh_object *				\
do_simple_##cname(struct command_simple *s UNUSED,	\
92
		  struct lsh_object *ARG)
93

94
#define DEFINE_COMMAND(cname, ARG, CC, EXC)	\
95 96
static void					\
do_##cname(struct command *s UNUSED,		\
97 98 99
	   struct lsh_object *ARG,		\
           struct command_continuation *CC,	\
           struct exception_handler *EXC);	\
100 101 102 103 104 105
						\
struct command cname =				\
STATIC_COMMAND(do_##cname);			\
						\
static void					\
do_##cname(struct command *s UNUSED,		\
106 107 108
	   struct lsh_object *ARG,		\
           struct command_continuation *CC,	\
           struct exception_handler *EXC)
109 110


111 112 113 114
void do_call_simple_command(struct command *s,
			    struct lsh_object *arg,
			    struct command_continuation *c,
			    struct exception_handler *e);
115

116
struct command *make_parallell_progn(struct object_list *body);
Niels Möller's avatar
Niels Möller committed
117
extern struct command_simple progn_command;
118

119 120
extern struct command_continuation discard_continuation;

Niels Möller's avatar
Niels Möller committed
121 122
#define CONTINUATION_USED_P(c) ((c) != &discard_continuation)

123
/* GABA:
124 125 126 127
   (class
     (name command_frame)
     (super command_continuation)
     (vars
128 129 130 131 132 133
       (up object command_continuation)
       (e object exception_handler)))
*/

/* Used when the execution context must be saved for later use.
 *
134 135
 * Primarily used in channel_commands.c.
 */
136 137 138 139 140 141
/* GABA:
   (class
     (name command_context)
     (vars
       (c object command_continuation)
       (e object exception_handler)))
142 143
*/

144 145 146 147
struct command_context *
make_command_context(struct command_continuation *c,
		     struct exception_handler *e);

148 149 150 151 152 153 154 155 156 157 158
/* catch command,
 *
 * (catch handler body x)
 */

/* GABA:
   (class
     (name catch_command)
     (super command_simple)
     (vars
       (mask . UINT32)
159 160 161 162 163 164
       (value . UINT32)

       ; Ignore return values from body. This means that the catch
       ; will return *only* if some exception is raised. Useful for
       ; reading until some EOF exception ir raised.
       (ignore_value . int))) */
165

Niels Möller's avatar
Niels Möller committed
166 167 168 169 170 171 172 173 174
struct catch_handler_info *
make_catch_handler_info(UINT32 mask, UINT32 value,
			int ignore_value,
			struct command *handler);

struct command *
make_catch_apply(struct catch_handler_info *info,
		 struct command *body);

175 176 177 178
struct lsh_object *
do_catch_simple(struct command_simple *s,
		struct lsh_object *a);

179 180
#define STATIC_CATCH_COMMAND(m, v, i) \
{ STATIC_COMMAND_SIMPLE(do_catch_simple), (m), (v), (i) }
181 182


183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/* GABA:
   (class
     (name catch_report_collect)
     (super command_simple)
     (vars
       (info object report_exception_info)))
*/

struct command *
make_catch_report_apply(struct report_exception_info *info,
			struct command *body);

struct lsh_object *
do_catch_report_collect(struct command_simple *s,
			struct lsh_object *a);

#define STATIC_CATCH_REPORT(i) \
{ STATIC_COMMAND_SIMPLE(do_catch_report_collect), i }

       
203 204 205 206 207 208 209 210 211 212 213
/* Commands that need to collect some arguments before actually doing
 * anything. */

/* The collect_info_n classes keeps track about what to do whith the
 * next argument. As long as we collect arguments without doing
 * anything, the f field in collect_info_n will point to the
 * constructor make_collect_state_n. */
/* GABA:
   (class
     (name collect_info_4)
     (vars
214
       ; No next field
215 216
       (f method "struct lsh_object *"
                 "struct lsh_object *" "struct lsh_object *"
217
		 "struct lsh_object *" "struct lsh_object *")))
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
*/

/* GABA:
   (class
     (name collect_info_3)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *" "struct lsh_object *"
		  "struct lsh_object *")
       (next object collect_info_4)))
*/

/* GABA:
   (class
     (name collect_info_2)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *" "struct lsh_object *")
       (next object collect_info_3)))
*/

/* GABA:
   (class
     (name collect_info_1)
     (super command_simple)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *")
       (next object collect_info_2)))
*/

249 250 251
struct lsh_object *
do_collect_1(struct command_simple *s, struct lsh_object *a);

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
struct lsh_object *
make_collect_state_1(struct collect_info_1 *info,
		     struct lsh_object *a);

struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
		     struct lsh_object *a,
		     struct lsh_object *b);

struct lsh_object *
make_collect_state_3(struct collect_info_3 *info,
		     struct lsh_object *a,
		     struct lsh_object *b,
		     struct lsh_object *c);

267 268 269 270
#define STATIC_COLLECT_1(next) \
{ { { STATIC_HEADER, do_call_simple_command }, do_collect_1}, \
  make_collect_state_1, next }

271
#if 0
272 273 274
#define STATIC_COLLECT_1_FINAL(f) \
{ { { STATIC_HEADER, do_call_simple_command }, do_collect_1}, \
  f, NULL }
275
#endif
276

277 278 279 280 281 282 283 284 285 286 287 288
#define STATIC_COLLECT_2(next) \
{ STATIC_HEADER, make_collect_state_2, next }

#define STATIC_COLLECT_2_FINAL(f) \
{ STATIC_HEADER, f, NULL }

#define STATIC_COLLECT_3(next) \
{ STATIC_HEADER, make_collect_state_3, next }

#define STATIC_COLLECT_3_FINAL(f) \
{ STATIC_HEADER, f, NULL }

289 290 291
extern struct command_simple command_unimplemented;
#define COMMAND_UNIMPLEMENTED (&command_unimplemented.super.super)

292
extern struct command command_die_on_null;
293

Niels Möller's avatar
Niels Möller committed
294

295
#if DEBUG_TRACE
Niels Möller's avatar
Niels Möller committed
296 297 298
struct command *make_trace(const char *name, struct command *real);
struct lsh_object *collect_trace(const char *name, struct lsh_object *real);

299 300
#define MAKE_TRACE collect_trace
#else /* !DEBUG_TRACE */
Niels Möller's avatar
Niels Möller committed
301
#define MAKE_TRACE(name, real) (real)
302
#endif /* !DEBUG_TRACE */
Niels Möller's avatar
Niels Möller committed
303

Niels Möller's avatar
Niels Möller committed
304
struct command_continuation *
305 306
make_once_continuation(const char *msg,
		       struct command_continuation *up);
Niels Möller's avatar
Niels Möller committed
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325


/* Delayed application. This is just a convenient way to record how to
 * apply a function, at some later time. Currently used only by
 * server_userauth.c. */

/* GABA:
   (class
     (name delayed_apply)
     (super command_context)
     (vars
       (f object command)
       (a object lsh_object)))
*/

struct delayed_apply *
make_delayed_apply(struct command *f,
		   struct lsh_object *a);

Niels Möller's avatar
Niels Möller committed
326
#define FORCE_APPLY(d, c, e) COMMAND_CALL((d)->f, (d)->a, (c), (e))
Niels Möller's avatar
Niels Möller committed
327 328 329 330 331

struct command_continuation *
make_delay_continuation(struct command *f,
			struct command_continuation *c);

332 333
/* Useful clobal commands */
#define PROG1 (&command_K.super.super)
334
#define PROGN (&progn_command.super.super)
Niels Möller's avatar
Niels Möller committed
335

336 337
/* The GABA_* macros are used by automatically generated evaluation code */

338
struct command_continuation *
339 340 341
make_apply(struct command *f,
	   struct command_continuation *c, struct exception_handler *e);

Niels Möller's avatar
Niels Möller committed
342 343
struct lsh_object *gaba_apply(struct lsh_object *f,
			      struct lsh_object *x);
344

345
#define GABA_APPLY gaba_apply
346

347 348 349
extern struct command_simple command_I;
#define GABA_VALUE_I (&command_I.super.super)
#define GABA_APPLY_I_1(x) (x)
350

Niels Möller's avatar
Niels Möller committed
351
extern struct command_simple command_K;
352 353 354 355 356
struct command *make_command_K_1(struct lsh_object *x);

#define GABA_VALUE_K (&command_K.super.super)
#define GABA_APPLY_K_1(x) ((struct lsh_object *) make_command_K_1(x))

357
extern struct collect_info_1 command_S;
358
extern struct collect_info_2 collect_info_S_2; 
359

360 361
struct command *make_command_S_2(struct command *f,
				 struct command *g);
362

363 364 365 366
struct lsh_object *collect_S_2(struct collect_info_2 *info,
			       struct lsh_object *f,
			       struct lsh_object *g);

Niels Möller's avatar
Niels Möller committed
367
#define GABA_VALUE_S (&command_S.super.super.super)
368
#define GABA_APPLY_S_1(f) (make_collect_state_1(&command_S, (f)))
369
#define GABA_APPLY_S_2(f, g) (collect_S_2(&collect_info_S_2, (f), (g)))
370 371 372

extern struct collect_info_1 command_Sp;
extern struct collect_info_2 collect_info_Sp_2;
373
extern struct collect_info_3 collect_info_Sp_3;
374

Niels Möller's avatar
Niels Möller committed
375 376 377 378
struct command *make_command_Sp_3(struct command *c,
				  struct command *f,
				  struct command *g);

379 380 381 382 383
struct lsh_object *collect_Sp_3(struct collect_info_3 *info,
				struct lsh_object *c,
				struct lsh_object *f,
				struct lsh_object *g);

384
#define GABA_VALUE_Sp (&command_Sp.super.super.super)
385 386 387
#define GABA_APPLY_Sp_1(c) (make_collect_state_1(&command_Sp, (c)))
#define GABA_APPLY_Sp_2(c, f) \
  (make_collect_state_2(&collect_info_Sp_2, (c), (f)))
388
#define GABA_APPLY_Sp_3(c, f, g) (collect_Sp_3(&collect_info_Sp_3, (c), (f), (g)))
389 390

extern struct collect_info_1 command_B;
391
extern struct collect_info_2 collect_info_B_2; 
392 393 394 395 396 397 398

struct command *make_command_B_2(struct command *f,
				 struct command *g);
struct lsh_object *collect_B_2(struct collect_info_2 *info,
			       struct lsh_object *f,
			       struct lsh_object *g);

399
#define GABA_VALUE_B (&command_B.super.super.super)
400
#define GABA_APPLY_B_1(f) (make_collect_state_1(&command_B, (f)))
401
#define GABA_APPLY_B_2(f, g) (collect_B_2(&collect_info_B_2, (f), (g)))
402 403 404 405 406 407 408 409 410 411 412 413 414

extern struct collect_info_1 command_Bp;
extern struct collect_info_2 collect_info_Bp_2;
extern struct collect_info_3 collect_info_Bp_3;

struct command *make_command_Bp_3(struct command *c,
				  struct command *f,
				  struct command *g);
struct lsh_object *collect_Bp_3(struct collect_info_3 *info,
				struct lsh_object *c,
				struct lsh_object *f,
				struct lsh_object *g);

415
#define GABA_VALUE_Bp (&command_Bp.super.super.super)
416 417 418
#define GABA_APPLY_Bp_1(c) (make_collect_state_1(&command_Bp, (c)))
#define GABA_APPLY_Bp_2(c, f) \
  (make_collect_state_2(&collect_info_Bp_2, (c), (f)))
419
#define GABA_APPLY_Bp_3(c, f, g) (collect_Bp_3(&collect_info_Bp_3, (c), (f), (g)))
420 421

extern struct collect_info_1 command_C;
422
extern struct collect_info_2 collect_info_C_2; 
423 424 425 426 427 428 429 430 431

struct command *
make_command_C_2(struct command *f,
		 struct lsh_object *y);
struct lsh_object *
collect_C_2(struct collect_info_2 *info,
	    struct lsh_object *f,
	    struct lsh_object *y);

Niels Möller's avatar
Niels Möller committed
432
#define GABA_VALUE_C (&command_C.super.super.super)
433
#define GABA_APPLY_C_1(f) (make_collect_state_1(&command_C, (f)))
434
#define GABA_APPLY_C_2(f, y) (collect_C_2(&collect_info_C_2, (f), (y)))
435 436 437

extern struct collect_info_1 command_Cp;
extern struct collect_info_2 collect_info_Cp_2;
438
extern struct collect_info_3 collect_info_Cp_3;
439 440 441 442 443 444 445 446 447 448 449

struct command *
make_command_Cp_3(struct command *c,
		  struct command *f,
		  struct lsh_object *y);
struct lsh_object *
collect_Cp_3(struct collect_info_3 *info,
	     struct lsh_object *c,
	     struct lsh_object *f,
	     struct lsh_object *y);

450
#define GABA_VALUE_Cp (&command_Cp.super.super.super)
451 452 453
#define GABA_APPLY_Cp_1(c) (make_collect_state_1(&command_Cp, (c)))
#define GABA_APPLY_Cp_2(c, f) \
  (make_collect_state_2(&collect_info_Cp_2, (c), (f)))
454
#define GABA_APPLY_Cp_3(c, f, y) (collect_Cp_3(&collect_info_Cp_3, (c), (f), (y)))
455
     
456 457

#endif /* LSH_COMMAND_H_INCLUDED */