Initial revision
[sw-tools] / src / sw_rsh.h
1 /* -*-c-*-
2 *
3 * $Id: sw_rsh.h,v 1.1 1999/06/02 16:53:33 mdw Exp $
4 *
5 * [Run remote commands *
6 * (c) 1999 EBI
7 */
8
9 /*----- Licensing notice --------------------------------------------------*
10 *
11 * This file is part of sw-tools.
12 *
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.
17 *
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.
22 *
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.
26 */
27
28 /*----- Revision history --------------------------------------------------*
29 *
30 * $Log: sw_rsh.h,v $
31 * Revision 1.1 1999/06/02 16:53:33 mdw
32 * Initial revision
33 *
34 */
35
36 #ifndef SW_RSH_H
37 #define SW_RSH_H
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /*----- Protocol definition -----------------------------------------------*
44 *
45 * There's a trivial packet protocol used to squeeze various bits of
46 * information down the `rsh' or `ssh' connection. Each packet has a three
47 * octet header consisting of a two-octet length and a single octet type.
48 * The length is the length of the packet payload, not including the header
49 * (which is fetched separately). The type determines what happens with the
50 * payload.
51 *
52 * There are six packet types defined so far. These are:
53 *
54 * * `args' -- contains a sequence of null-terminated arguments. The list
55 * stops when there's no more data in the packet. (The normal
56 * null-terminated-list-of-null-terminated-strings doesn't allow empty
57 * arguments, which are perfectly valid.)
58 *
59 * * `env' -- contains a sequence of null-terminated environment variable
60 * assignments of the form `VAR=VALUE'.
61 *
62 * * `dir' -- contains a null-terminated path to a current directory.
63 *
64 * * `go' -- contains no data. Means `execute the command now'.
65 *
66 * * `data' -- contains data produced by the command.
67 *
68 * * `status' -- contains command exit status. If this is a single octet
69 * then that octet is the exit status; otherwise, it's a null-terminated
70 * signal name.
71 *
72 * The first four packets are sent from the client to the server; the last
73 * two are sent the other way. The first three packets may be sent in any
74 * order, and some may be omitted. (This doesn't happen in the current
75 * implementation.)
76 *
77 * The command was already sent as the `--remote' argument to the remote
78 * `sw'.
79 *
80 * (There's also a fake packet type used for representing eof on the stream.
81 * This should never be seen on the wire -- it's only for internal use.)
82 */
83
84 /*----- Data structures ---------------------------------------------------*/
85
86 /* --- Packet type codes --- */
87
88 enum {
89 PKTYPE_EOF, /* Fake end-of-file condition */
90 PKTYPE_ARGS, /* Argument array */
91 PKTYPE_ENV, /* Environment array */
92 PKTYPE_DIR, /* Current directory */
93 PKTYPE_GO, /* You have all you need to know */
94 PKTYPE_DATA, /* Here's some data */
95 PKTYPE_STATUS, /* My job ended: here's why */
96 PKTYPE_BOGUS /* Bogus packet type */
97 };
98
99 #define PKMAX 4096 /* Maximum packet size */
100
101 /* --- A `remote context' --- *
102 *
103 * Describes everything there is to know about a remotely executing job.
104 *
105 * Note that `fdin' and `fdout' are identical on the local side, and
106 * (potentially) different on the remote side. Be careful!
107 */
108
109 typedef struct sw_remote {
110 int fdin, fdout; /* File descriptors */
111 size_t sz; /* Size of data in buffer */
112 char buf[PKMAX + 1]; /* Input buffer (handy for output) */
113 } sw_remote;
114
115 /* --- A remote command definition --- *
116 *
117 * Like normal user commands, these are linked into a list. See `sw.h' for
118 * the nitty-gritty. The magic link macro is called @RCMD_LINK@.
119 */
120
121 typedef struct rcmd {
122 struct rcmd *next;
123 const char *name;
124 void (*rcmd)(sw_remote */*r*/, char */*argv*/[], char */*env*/[]);
125 } rcmd;
126
127 /*----- Packet interface --------------------------------------------------*/
128
129 /* --- @pksend@ --- *
130 *
131 * Arguments: @sw_remote@ = pointer to the remote block
132 * @int type@ = packet type to send
133 * @const void *p@ = pointer to packet data
134 * @size_t sz@ = size of data to send
135 *
136 * Returns: Zero if it worked, nonzero otherwise.
137 *
138 * Use: Sends a data packet. If the type is `data', then `sz' may be
139 * arbitrarily large and is divided into small eenough chunks.
140 * Otherwise it's an error to send a packet that's too big.
141 */
142
143 extern int pksend(sw_remote */*r*/, int /*type*/,
144 const void */*p*/, size_t /*sz*/);
145
146 /* --- @pkrecv@ --- *
147 *
148 * Arguments: @sw_remote *r@ = remote block
149 *
150 * Returns: Packet type received, or @-1@ for an error.
151 *
152 * Use: Receives a packet from the remote host. The packet data is
153 * placed in the block's buffer, the block's packet length is
154 * diddled appropriately.
155 */
156
157 extern int pkrecv(sw_remote */*r*/);
158
159 /*----- Error reporting and exit statuses --------------------------------*/
160
161 /* --- @swexit@ --- *
162 *
163 * Arguments: @sw_remote *r@ = remote context
164 * @int status@ = exit status to return
165 *
166 * Returns: Doesn't.
167 *
168 * Use: Reports the exit status via packet protocol and quits.
169 */
170
171 extern void swexit(sw_remote */*r*/, int /*status*/);
172
173 /* --- @swsignal@ --- *
174 *
175 * Arguments: @sw_remote *r@ = remote context
176 * @int sig@ = signal ocurrence to return
177 *
178 * Returns: Doesn't.
179 *
180 * Use: Reports a signalled-to-death status via packet protocol and
181 * quits.
182 */
183
184 extern void swsignal(sw_remote */*r*/, int /*sig*/);
185
186 /* --- @swwait@ --- *
187 *
188 * Arguments: @sw_remote *r@ = remote context
189 * @int status@ = status answer from @wait@(2)
190 *
191 * Returns: Doesn't.
192 *
193 * Use: Reports a child's demise appropriately, and quits.
194 */
195
196 extern void swwait(sw_remote */*r*/, int /*status*/);
197
198 /* --- @swvprintf@ --- *
199 *
200 * Arguments: @sw_remote *r@ = remote context
201 * @const char *format@ = format string
202 * @va_list ap@ = things to format
203 *
204 * Returns: ---
205 *
206 * Use: Writes a string to the remote end. This is the low-level bit
207 * of @swprintf@.
208 */
209
210 extern void swvprintf(sw_remote */*r*/,
211 const char */*format*/, va_list /*ap*/);
212
213 /* --- @swprintf@ --- *
214 *
215 * Arguments: @sw_remote *r@ = remote context
216 * @const char *format@ = format string
217 * @...@ = other arguments
218 *
219 * Returns: ---
220 *
221 * Use: Writes a string to the remote end.
222 */
223
224 extern void swprintf(sw_remote */*r*/, const char */*format*/, ...);
225
226 /* --- @swdie@ --- *
227 *
228 * Arguments: @sw_remote *r@ = remote context
229 * @int status@ = exit status to report
230 * @const char *format@ = format string to fill in
231 * @...@ = other arguments
232 *
233 * Returns: Doesn't.
234 *
235 * Use: Reports a message and quits.
236 */
237
238 extern void swdie(sw_remote */*r*/, int /*status*/,
239 const char */*format*/, ...);
240
241 /*----- Remote invocation -------------------------------------------------*/
242
243 /* --- @swrsh_remote@ --- *
244 *
245 * Arguments: @const char *cmd@ = the command to perform
246 *
247 * Returns: Doesn't. Reports an exit status through packet protocol and
248 * quits.
249 *
250 * Use: Handles the remote end of a remote job invokation.
251 */
252
253 extern void swrsh_remote(const char */*cmd*/);
254
255 /*----- Starting remote jobs ----------------------------------------------*/
256
257 /* --- @swrsh@ --- *
258 *
259 * Arguments: @sw_remote *r@ = remote process block to look after
260 * @const char *host@ = host to run on (0 for this one)
261 * @const char *cmd@ = remote command to run
262 * @char *argv[]@ = arguments to pass on
263 *
264 * Returns: Zero if it worked, nonzero if not.
265 *
266 * Use: Runs a command on a remote host. The argument array is
267 * mangled to come out OK at the far end. The environment and
268 * current directory are also passed along, and pop out the
269 * other end unmolested.
270 */
271
272 extern int swrsh(sw_remote */*r*/, const char */*host*/,
273 const char */*cmd*/, char */*argv*/[]);
274
275 /*----- Subcommands -------------------------------------------------------*/
276
277 extern void rsw_rsh(sw_remote */*r*/, char */*argv*/[], char */*env*/[]);
278 extern int sw_rsh(int /*argc*/, char */*argv*/[]);
279
280 #ifdef CMD_LINK
281 static cmd cmd_rsh = {
282 CMD_LINK, "rsh", sw_rsh,
283 "rsh HOST|ARCH COMMAND [ARGS...]\n\
284 Runs the COMMAND on the remote host HOST (or one which supports\n\
285 architecture ARCH), passing it the given ARGS. Note that the\n\
286 command and arguments aren't subject to shell expansions on the\n\
287 remote site (unlike with `rsh'). Environment variables are passed\n\
288 on to the remote command, as is the current directory. The\n\
289 environment variable `SW_RSH' contains the name of a remote-shell\n\
290 program to start up the remote command (`rsh' and `ssh' work\n\
291 well); " RSH " is used by default. The magic hostname `-'\n\
292 refers to the local machine, as does the current host's\n\
293 architecture name. In these cases, the command is run directly.\n"
294 };
295 # undef CMD_LINK
296 # define CMD_LINK &cmd_rsh
297 #endif
298
299 #ifdef RCMD_LINK
300 static rcmd rcmd_rsh = { RCMD_LINK, "rsh", rsw_rsh };
301 # undef RCMD_LINK
302 # define RCMD_LINK &rcmd_rsh
303 #endif
304
305 /*----- That's all, folks -------------------------------------------------*/
306
307 #ifdef __cplusplus
308 }
309 #endif
310
311 #endif