3 * $Id: sw_rsh.h,v 1.2 1999/09/24 13:16:39 mdw Exp $
5 * [Run remote commands *
9 /*----- Licensing notice --------------------------------------------------*
11 * This file is part of sw-tools.
13 * sw-tools is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * sw-tools is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with sw-tools; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /*----- Revision history --------------------------------------------------*
31 * Revision 1.2 1999/09/24 13:16:39 mdw
32 * Fix typo in comment.
34 * Revision 1.1.1.1 1999/06/02 16:53:33 mdw
46 /*----- Protocol definition -----------------------------------------------*
48 * There's a trivial packet protocol used to squeeze various bits of
49 * information down the `rsh' or `ssh' connection. Each packet has a three
50 * octet header consisting of a two-octet length and a single octet type.
51 * The length is the length of the packet payload, not including the header
52 * (which is fetched separately). The type determines what happens with the
55 * There are six packet types defined so far. These are:
57 * * `args' -- contains a sequence of null-terminated arguments. The list
58 * stops when there's no more data in the packet. (The normal
59 * null-terminated-list-of-null-terminated-strings doesn't allow empty
60 * arguments, which are perfectly valid.)
62 * * `env' -- contains a sequence of null-terminated environment variable
63 * assignments of the form `VAR=VALUE'.
65 * * `dir' -- contains a null-terminated path to a current directory.
67 * * `go' -- contains no data. Means `execute the command now'.
69 * * `data' -- contains data produced by the command.
71 * * `status' -- contains command exit status. If this is a single octet
72 * then that octet is the exit status; otherwise, it's a null-terminated
75 * The first four packets are sent from the client to the server; the last
76 * two are sent the other way. The first three packets may be sent in any
77 * order, and some may be omitted. (This doesn't happen in the current
80 * The command was already sent as the `--remote' argument to the remote
83 * (There's also a fake packet type used for representing eof on the stream.
84 * This should never be seen on the wire -- it's only for internal use.)
87 /*----- Data structures ---------------------------------------------------*/
89 /* --- Packet type codes --- */
92 PKTYPE_EOF
, /* Fake end-of-file condition */
93 PKTYPE_ARGS
, /* Argument array */
94 PKTYPE_ENV
, /* Environment array */
95 PKTYPE_DIR
, /* Current directory */
96 PKTYPE_GO
, /* You have all you need to know */
97 PKTYPE_DATA
, /* Here's some data */
98 PKTYPE_STATUS
, /* My job ended: here's why */
99 PKTYPE_BOGUS
/* Bogus packet type */
102 #define PKMAX 4096 /* Maximum packet size */
104 /* --- A `remote context' --- *
106 * Describes everything there is to know about a remotely executing job.
108 * Note that `fdin' and `fdout' are identical on the local side, and
109 * (potentially) different on the remote side. Be careful!
112 typedef struct sw_remote
{
113 int fdin
, fdout
; /* File descriptors */
114 size_t sz
; /* Size of data in buffer */
115 char buf
[PKMAX
+ 1]; /* Input buffer (handy for output) */
118 /* --- A remote command definition --- *
120 * Like normal user commands, these are linked into a list. See `sw.h' for
121 * the nitty-gritty. The magic link macro is called @RCMD_LINK@.
124 typedef struct rcmd
{
127 void (*rcmd
)(sw_remote */
*r*/
, char */
*argv*/
[], char */
*env*/
[]);
130 /*----- Packet interface --------------------------------------------------*/
132 /* --- @pksend@ --- *
134 * Arguments: @sw_remote@ = pointer to the remote block
135 * @int type@ = packet type to send
136 * @const void *p@ = pointer to packet data
137 * @size_t sz@ = size of data to send
139 * Returns: Zero if it worked, nonzero otherwise.
141 * Use: Sends a data packet. If the type is `data', then `sz' may be
142 * arbitrarily large and is divided into small enough chunks.
143 * Otherwise it's an error to send a packet that's too big.
146 extern int pksend(sw_remote */
*r*/
, int /*type*/,
147 const void */
*p*/
, size_t /*sz*/);
149 /* --- @pkrecv@ --- *
151 * Arguments: @sw_remote *r@ = remote block
153 * Returns: Packet type received, or @-1@ for an error.
155 * Use: Receives a packet from the remote host. The packet data is
156 * placed in the block's buffer, the block's packet length is
157 * diddled appropriately.
160 extern int pkrecv(sw_remote */
*r*/
);
162 /*----- Error reporting and exit statuses --------------------------------*/
164 /* --- @swexit@ --- *
166 * Arguments: @sw_remote *r@ = remote context
167 * @int status@ = exit status to return
171 * Use: Reports the exit status via packet protocol and quits.
174 extern void swexit(sw_remote */
*r*/
, int /*status*/);
176 /* --- @swsignal@ --- *
178 * Arguments: @sw_remote *r@ = remote context
179 * @int sig@ = signal ocurrence to return
183 * Use: Reports a signalled-to-death status via packet protocol and
187 extern void swsignal(sw_remote */
*r*/
, int /*sig*/);
189 /* --- @swwait@ --- *
191 * Arguments: @sw_remote *r@ = remote context
192 * @int status@ = status answer from @wait@(2)
196 * Use: Reports a child's demise appropriately, and quits.
199 extern void swwait(sw_remote */
*r*/
, int /*status*/);
201 /* --- @swvprintf@ --- *
203 * Arguments: @sw_remote *r@ = remote context
204 * @const char *format@ = format string
205 * @va_list ap@ = things to format
209 * Use: Writes a string to the remote end. This is the low-level bit
213 extern void swvprintf(sw_remote */
*r*/
,
214 const char */
*format*/
, va_list /*ap*/);
216 /* --- @swprintf@ --- *
218 * Arguments: @sw_remote *r@ = remote context
219 * @const char *format@ = format string
220 * @...@ = other arguments
224 * Use: Writes a string to the remote end.
227 extern void swprintf(sw_remote */
*r*/
, const char */
*format*/
, ...);
231 * Arguments: @sw_remote *r@ = remote context
232 * @int status@ = exit status to report
233 * @const char *format@ = format string to fill in
234 * @...@ = other arguments
238 * Use: Reports a message and quits.
241 extern void swdie(sw_remote */
*r*/
, int /*status*/,
242 const char */
*format*/
, ...);
244 /*----- Remote invocation -------------------------------------------------*/
246 /* --- @swrsh_remote@ --- *
248 * Arguments: @const char *cmd@ = the command to perform
250 * Returns: Doesn't. Reports an exit status through packet protocol and
253 * Use: Handles the remote end of a remote job invokation.
256 extern void swrsh_remote(const char */
*cmd*/
);
258 /*----- Starting remote jobs ----------------------------------------------*/
262 * Arguments: @sw_remote *r@ = remote process block to look after
263 * @const char *host@ = host to run on (0 for this one)
264 * @const char *cmd@ = remote command to run
265 * @char *argv[]@ = arguments to pass on
267 * Returns: Zero if it worked, nonzero if not.
269 * Use: Runs a command on a remote host. The argument array is
270 * mangled to come out OK at the far end. The environment and
271 * current directory are also passed along, and pop out the
272 * other end unmolested.
275 extern int swrsh(sw_remote */
*r*/
, const char */
*host*/
,
276 const char */
*cmd*/
, char */
*argv*/
[]);
278 /*----- Subcommands -------------------------------------------------------*/
280 extern void rsw_rsh(sw_remote */
*r*/
, char */
*argv*/
[], char */
*env*/
[]);
281 extern int sw_rsh(int /*argc*/, char */
*argv*/
[]);
284 static cmd cmd_rsh
= {
285 CMD_LINK
, "rsh", sw_rsh
,
286 "rsh HOST|ARCH COMMAND [ARGS...]\n\
287 Runs the COMMAND on the remote host HOST (or one which supports\n\
288 architecture ARCH), passing it the given ARGS. Note that the\n\
289 command and arguments aren't subject to shell expansions on the\n\
290 remote site (unlike with `rsh'). Environment variables are passed\n\
291 on to the remote command, as is the current directory. The\n\
292 environment variable `SW_RSH' contains the name of a remote-shell\n\
293 program to start up the remote command (`rsh' and `ssh' work\n\
294 well); " RSH
" is used by default. The magic hostname `-'\n\
295 refers to the local machine, as does the current host's\n\
296 architecture name. In these cases, the command is run directly.\n"
299 # define CMD_LINK &cmd_rsh
303 static rcmd rcmd_rsh
= { RCMD_LINK
, "rsh", rsw_rsh
};
305 # define RCMD_LINK &rcmd_rsh
308 /*----- That's all, folks -------------------------------------------------*/