3 * $Id: sw_rsh.h,v 1.3 2004/04/08 01:52:19 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.
35 /*----- Protocol definition -----------------------------------------------*
37 * There's a trivial packet protocol used to squeeze various bits of
38 * information down the `rsh' or `ssh' connection. Each packet has a three
39 * octet header consisting of a two-octet length and a single octet type.
40 * The length is the length of the packet payload, not including the header
41 * (which is fetched separately). The type determines what happens with the
44 * There are six packet types defined so far. These are:
46 * * `args' -- contains a sequence of null-terminated arguments. The list
47 * stops when there's no more data in the packet. (The normal
48 * null-terminated-list-of-null-terminated-strings doesn't allow empty
49 * arguments, which are perfectly valid.)
51 * * `env' -- contains a sequence of null-terminated environment variable
52 * assignments of the form `VAR=VALUE'.
54 * * `dir' -- contains a null-terminated path to a current directory.
56 * * `go' -- contains no data. Means `execute the command now'.
58 * * `data' -- contains data produced by the command.
60 * * `status' -- contains command exit status. If this is a single octet
61 * then that octet is the exit status; otherwise, it's a null-terminated
64 * The first four packets are sent from the client to the server; the last
65 * two are sent the other way. The first three packets may be sent in any
66 * order, and some may be omitted. (This doesn't happen in the current
69 * The command was already sent as the `--remote' argument to the remote
72 * (There's also a fake packet type used for representing eof on the stream.
73 * This should never be seen on the wire -- it's only for internal use.)
76 /*----- Data structures ---------------------------------------------------*/
78 /* --- Packet type codes --- */
81 PKTYPE_EOF, /* Fake end-of-file condition */
82 PKTYPE_ARGS, /* Argument array */
83 PKTYPE_ENV, /* Environment array */
84 PKTYPE_DIR, /* Current directory */
85 PKTYPE_GO, /* You have all you need to know */
86 PKTYPE_DATA, /* Here's some data */
87 PKTYPE_STATUS, /* My job ended: here's why */
88 PKTYPE_BOGUS /* Bogus packet type */
91 #define PKMAX 4096 /* Maximum packet size */
93 /* --- A `remote context' --- *
95 * Describes everything there is to know about a remotely executing job.
97 * Note that `fdin' and `fdout' are identical on the local side, and
98 * (potentially) different on the remote side. Be careful!
101 typedef struct sw_remote {
102 int fdin, fdout; /* File descriptors */
103 size_t sz; /* Size of data in buffer */
104 char buf[PKMAX + 1]; /* Input buffer (handy for output) */
107 /* --- A remote command definition --- *
109 * Like normal user commands, these are linked into a list. See `sw.h' for
110 * the nitty-gritty. The magic link macro is called @RCMD_LINK@.
113 typedef struct rcmd {
116 void (*rcmd)(sw_remote */*r*/, char */*argv*/[], char */*env*/[]);
119 /*----- Packet interface --------------------------------------------------*/
121 /* --- @pksend@ --- *
123 * Arguments: @sw_remote@ = pointer to the remote block
124 * @int type@ = packet type to send
125 * @const void *p@ = pointer to packet data
126 * @size_t sz@ = size of data to send
128 * Returns: Zero if it worked, nonzero otherwise.
130 * Use: Sends a data packet. If the type is `data', then `sz' may be
131 * arbitrarily large and is divided into small enough chunks.
132 * Otherwise it's an error to send a packet that's too big.
135 extern int pksend(sw_remote */*r*/, int /*type*/,
136 const void */*p*/, size_t /*sz*/);
138 /* --- @pkrecv@ --- *
140 * Arguments: @sw_remote *r@ = remote block
142 * Returns: Packet type received, or @-1@ for an error.
144 * Use: Receives a packet from the remote host. The packet data is
145 * placed in the block's buffer, the block's packet length is
146 * diddled appropriately.
149 extern int pkrecv(sw_remote */*r*/);
151 /*----- Error reporting and exit statuses --------------------------------*/
153 /* --- @swexit@ --- *
155 * Arguments: @sw_remote *r@ = remote context
156 * @int status@ = exit status to return
160 * Use: Reports the exit status via packet protocol and quits.
163 extern void swexit(sw_remote */*r*/, int /*status*/);
165 /* --- @swsignal@ --- *
167 * Arguments: @sw_remote *r@ = remote context
168 * @int sig@ = signal ocurrence to return
172 * Use: Reports a signalled-to-death status via packet protocol and
176 extern void swsignal(sw_remote */*r*/, int /*sig*/);
178 /* --- @swwait@ --- *
180 * Arguments: @sw_remote *r@ = remote context
181 * @int status@ = status answer from @wait@(2)
185 * Use: Reports a child's demise appropriately, and quits.
188 extern void swwait(sw_remote */*r*/, int /*status*/);
190 /* --- @swvprintf@ --- *
192 * Arguments: @sw_remote *r@ = remote context
193 * @const char *format@ = format string
194 * @va_list ap@ = things to format
198 * Use: Writes a string to the remote end. This is the low-level bit
202 extern void swvprintf(sw_remote */*r*/,
203 const char */*format*/, va_list /*ap*/);
205 /* --- @swprintf@ --- *
207 * Arguments: @sw_remote *r@ = remote context
208 * @const char *format@ = format string
209 * @...@ = other arguments
213 * Use: Writes a string to the remote end.
216 extern void swprintf(sw_remote */*r*/, const char */*format*/, ...);
220 * Arguments: @sw_remote *r@ = remote context
221 * @int status@ = exit status to report
222 * @const char *format@ = format string to fill in
223 * @...@ = other arguments
227 * Use: Reports a message and quits.
230 extern void swdie(sw_remote */*r*/, int /*status*/,
231 const char */*format*/, ...);
233 /*----- Remote invocation -------------------------------------------------*/
235 /* --- @swrsh_remote@ --- *
237 * Arguments: @const char *cmd@ = the command to perform
239 * Returns: Doesn't. Reports an exit status through packet protocol and
242 * Use: Handles the remote end of a remote job invokation.
245 extern void swrsh_remote(const char */*cmd*/);
247 /*----- Starting remote jobs ----------------------------------------------*/
251 * Arguments: @sw_remote *r@ = remote process block to look after
252 * @const char *host@ = host to run on (0 for this one)
253 * @const char *cmd@ = remote command to run
254 * @char *argv[]@ = arguments to pass on
256 * Returns: Zero if it worked, nonzero if not.
258 * Use: Runs a command on a remote host. The argument array is
259 * mangled to come out OK at the far end. The environment and
260 * current directory are also passed along, and pop out the
261 * other end unmolested.
264 extern int swrsh(sw_remote */*r*/, const char */*host*/,
265 const char */*cmd*/, char */*argv*/[]);
267 /*----- Subcommands -------------------------------------------------------*/
269 extern void rsw_rsh(sw_remote */*r*/, char */*argv*/[], char */*env*/[]);
270 extern int sw_rsh(int /*argc*/, char */*argv*/[]);
273 static cmd cmd_rsh = {
274 CMD_LINK, "rsh", sw_rsh,
275 "rsh HOST|ARCH COMMAND [ARGS...]\n\
276 Runs the COMMAND on the remote host HOST (or one which supports\n\
277 architecture ARCH), passing it the given ARGS. Note that the\n\
278 command and arguments aren't subject to shell expansions on the\n\
279 remote site (unlike with `rsh'). Environment variables are passed\n\
280 on to the remote command, as is the current directory. The\n\
281 environment variable `SW_RSH' contains the name of a remote-shell\n\
282 program to start up the remote command (`rsh' and `ssh' work\n\
283 well); " RSH " is used by default. The magic hostname `-'\n\
284 refers to the local machine, as does the current host's\n\
285 architecture name. In these cases, the command is run directly.\n"
288 # define CMD_LINK &cmd_rsh
292 static rcmd rcmd_rsh = { RCMD_LINK, "rsh", rsw_rsh };
294 # define RCMD_LINK &rcmd_rsh
297 /*----- That's all, folks -------------------------------------------------*/