2 * File: remote.c $XConsortium: remote.c /main/5 1996/06/21 17:34:53 ageorge $
5 * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
7 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
8 * (c) Copyright 1993, 1994 International Business Machines Corp. *
9 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
10 * (c) Copyright 1993, 1994 Novell, Inc. *
13 #include <bms/sbport.h>
14 #include <bms/usersig.h>
17 #include <SPC/spc-proto.h>
18 #include "DtSvcLock.h"
20 /*----------------------------------------------------------------------+*/
21 void remote_channel_class_init(object_clasp t)
22 /*----------------------------------------------------------------------+*/
24 channel_clasp c=(channel_clasp) t;
26 c->new_obj = alloc_channel_object;
28 c->open = open_remote_channel_object;
29 c->close = close_remote_channel_object;
30 c->read = read_remote_channel_object;
31 c->write = write_remote_channel_object;
32 c->reset = reset_remote_channel_object;
33 /* pre_fork & post_fork have no method */
34 c->exec_proc = exec_proc_remote_channel_object;
35 c->signal = signal_remote_channel_object;
36 /* wait_for_termination has no method */
37 c->attach = attach_remote_channel_object;
38 c->add_input = add_input_remote_channel_object;
39 c->input = SPC_Conditional_Packet_Handler;
40 c->remove_logfile = remove_logfile_remote_channel_object;
42 /* New B.00 methods */
44 c->send_eof = send_eof_remote_channel_object;
45 c->set_termio = set_termio_remote_channel_object;
49 static struct remote_channel_class remote_channel_class_struct = {
50 (channel_clasp) &channel_class, /* base class pointer */
51 "remote_channel", /* class name */
52 remote_channel_class_init,/* class initialize function */
53 sizeof(SPC_Channel), /* size */
57 remote_channel_clasp remote_channel_class = &remote_channel_class_struct;
59 /*----------------------------------------------------------------------+*/
60 Wire *get_new_remote_wire(Wire *prevwire)
61 /*----------------------------------------------------------------------+*/
63 Wire *mywire=get_new_wire();
67 mywire->next=prevwire;
73 *** Method definitions for remote channel objects
77 /*----------------------------------------------------------------------+*/
78 SPC_Channel_Ptr open_remote_channel_object(SPC_Channel_Ptr channel,
81 /*----------------------------------------------------------------------+*/
84 SPC_Channel_Ptr result;
89 call_parent_method(channel, open, (channel, iomode, hostname), result);
95 channel->queued_remote_data=Xe_make_queue(NULL);
96 iomode=channel->IOMode;
98 if(IS_SPCIO_STDIN(iomode)) {
99 tmpwire=get_new_remote_wire(tmpwire);
100 channel->wires[STDIN]=tmpwire;
102 if(IS_SPCIO_STDOUT(iomode)) {
103 tmpwire=get_new_remote_wire(tmpwire);
104 channel->wires[STDOUT]=tmpwire;
106 if(IS_SPCIO_STDERR(iomode)) {
107 if(!tmpwire || /* ERRORONLY */
108 IS_SPCIO_SEPARATE(iomode))
109 tmpwire=get_new_remote_wire(tmpwire);
110 channel->wires[STDERR]=tmpwire;
113 channel->wire_list=tmpwire;
115 if(!(channel->connection=SPC_Open_Connection(hostname)))
118 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
119 CHANNEL_OPEN, iomode);
120 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
121 if(retval==SPC_ERROR)
124 sid=channel->connection->sid;
125 channel->file_descs[STDIN]=sid;
126 channel->file_descs[STDOUT]=sid;
127 channel->file_descs[STDERR]=sid;
129 if ((SPC_client_version_number >= SPC_PROTOCOL_VERSION_CDE_BASE) &&
130 (SPC_who_am_i == SPC_I_AM_A_CLIENT)) {
131 channel->wires[STDIN]->master_name = NULL;
132 channel->wires[STDIN]->slave_name = NULL;
133 channel->wires[STDOUT]->master_name = NULL;
134 channel->wires[STDOUT]->slave_name = NULL;
135 channel->wires[STDERR]->master_name = NULL;
136 channel->wires[STDERR]->slave_name = NULL;
139 SPC_Query_Devices(channel);
141 SPC_Query_Logfile(channel);
148 ** Note that the close routines call the parent method AFTER the
149 ** work done for the child method. This is because the parent method
150 ** will do all the deallocation.
154 /*----------------------------------------------------------------------+*/
155 int close_remote_channel_object(SPC_Channel_Ptr channel)
156 /*----------------------------------------------------------------------+*/
162 channel->IOMode |= SPCIO_DELAY_CLOSE;
164 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
166 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
168 call_parent_method(channel, close, (channel), result);
170 if(result==SPC_ERROR)
176 /*----------------------------------------------------------------------+*/
177 int reset_remote_channel_object(SPC_Channel_Ptr channel)
178 /*----------------------------------------------------------------------+*/
184 protocol_request_ptr prot;
186 call_parent_method(channel, reset, (channel), result);
188 if(result==SPC_ERROR)
191 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
193 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
194 if(retval==SPC_ERROR)
197 /* At this point, we know that the remote server has sent us all
198 necessary data (since RESET expects a reply). So, we are safe to
199 flush any queued data on this channel. */
202 if (tmpqueue=channel->queued_remote_data)
204 Xe_for_queue(protocol_request_ptr, prot, tmpqueue) {
205 Xe_delete_queue_element(channel->queued_remote_data, prot);
206 SPC_Free_Protocol_Ptr(prot);
214 /*----------------------------------------------------------------------+*/
215 int exec_proc_remote_channel_object(SPC_Channel_Ptr channel)
216 /*----------------------------------------------------------------------+*/
222 call_parent_method(channel, exec_proc, (channel), result);
224 if(result==SPC_ERROR)
227 call_parent_method(channel, pre_fork, (channel), result);
229 if(result==SPC_ERROR)
232 if((channel->connection->protocol_version > 2) ||
233 IS_SPCIO_FORCE_CONTEXT(channel->IOMode))
234 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
236 channel->path, channel->context_dir,
237 channel->argv, channel->envp);
239 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
241 channel->path, channel->context_dir,
242 channel->argv, channel->envp);
245 tmp_errorno = XeSPCErrorNumber;
246 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
247 if (tmp_errorno != 0)
248 XeSPCErrorNumber = tmp_errorno;
249 _DtSvcProcessUnlock();
250 if(retval==SPC_ERROR)
255 call_parent_method(channel, post_fork, (channel, retval), result);
257 if(result==SPC_ERROR)
263 /*----------------------------------------------------------------------+*/
264 int write_remote_channel_object(SPC_Channel_Ptr channel,
267 /*----------------------------------------------------------------------+*/
271 int lentogo=len, lentowrite;
273 call_parent_method(channel, write, (channel, buffer, len), result);
275 if(result==SPC_ERROR)
280 lentowrite=min(lentogo, SPC_BUFSIZ);
281 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
282 APPLICATION_DATA, buffer, lentowrite);
283 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
285 if(retval==SPC_ERROR)
288 lentogo -= lentowrite;
289 buffer += lentowrite;
296 /*----------------------------------------------------------------------+*/
297 int read_remote_channel_object(SPC_Channel_Ptr channel,
301 /*----------------------------------------------------------------------+*/
305 call_parent_method(channel, read, (channel, connection, buffer, len), result);
307 if(result==SPC_ERROR)
310 if(!IS_SPCIO_DATA(channel->wires[connection]->flags))
313 result=SPC_Read_Remote_Data(channel, connection, buffer, len);
315 /* Got EOF. Yank the data line */
316 SPC_Change_State(channel, connection, 0, -1);
321 /*----------------------------------------------------------------------+*/
322 int signal_remote_channel_object(SPC_Channel_Ptr channel,
324 /*----------------------------------------------------------------------+*/
329 call_parent_method(channel, signal, (channel, sig), result);
331 if(result==SPC_ERROR)
334 if (channel->connection->protocol_version >= 2) {
335 XeString signame = XeSignalToName( sig );
339 SPC_Error(SPC_Bad_Signal_Value, sig);
342 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
343 APPLICATION_SIGNAL, signame);
346 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
347 APPLICATION_SIGNAL, sig);
349 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
354 /*----------------------------------------------------------------------+*/
355 int attach_remote_channel_object(SPC_Channel_Ptr channel,
357 /*----------------------------------------------------------------------+*/
362 call_parent_method(channel, attach, (channel, pid), result);
364 if(result==SPC_ERROR)
367 seqno=SPC_Write_Protocol_Request(channel->connection, channel,
368 CHANNEL_ATTACH, pid);
369 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
370 if(retval==SPC_ERROR)
373 SPC_Flush_Queued_Data(channel);
375 if(!mempf0(channel, pre_fork))
382 /*----------------------------------------------------------------------+*/
383 remove_logfile_remote_channel_object(SPC_Channel_Ptr channel)
384 /*----------------------------------------------------------------------+*/
389 call_parent_method(channel, remove_logfile, (channel), result);
391 if(result==SPC_ERROR)
394 seqno=SPC_Write_Protocol_Request(channel->connection, channel, DELETE_LOGFILE);
395 retval=SPC_Waitfor_Reply(channel->connection, channel, seqno);
396 if(retval==SPC_ERROR)
401 /*----------------------------------------------------------------------+*/
402 int add_input_remote_channel_object(SPC_Channel_Ptr channel,
403 SbInputHandlerProc handler,
405 /*----------------------------------------------------------------------+*/
408 SPC_Connection_Ptr conn=channel->connection;
410 call_parent_method(channel, add_input, (channel, handler, data), result);
412 if(result==SPC_ERROR)
415 if(conn->termination_id != -1)
416 /* We already have a handler, don't need another one */
419 SPC_XtAddInput(channel,
420 &conn->termination_id,
422 channel->class_ptr->input,
428 /*----------------------------------------------------------------------+*/
429 SPC_Debug_Mode(SPC_Channel_Ptr channel,
431 /*----------------------------------------------------------------------+*/
436 if(!channel->connection)
439 retval=SPC_Write_Protocol_Request(channel->connection, channel,
441 seqno=SPC_Waitfor_Reply(channel->connection, channel, retval);
443 if(retval==SPC_ERROR)
449 int send_eof_remote_channel_object(SPC_Channel_Ptr channel)
453 if(!channel->connection)
457 SPC_Write_Protocol_Request(channel->connection, channel, CHANNEL_SEND_EOF);
458 seqno = SPC_Waitfor_Reply(channel->connection, channel, retval);
460 if(retval==SPC_ERROR)
467 int set_termio_remote_channel_object(SPC_Channel_Ptr channel,
470 struct termios *termios)
474 if(!channel->connection)
478 SPC_Write_Protocol_Request(channel->connection, channel,
480 connector, side, termios);
481 seqno = SPC_Waitfor_Reply(channel->connection, channel, retval);
483 if(retval==SPC_ERROR)