]> andersk Git - moira.git/blame - lib/mr_call.c
Initial revision
[moira.git] / lib / mr_call.c
CommitLineData
ca401c43 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 *
8 * $Log$
52795f45 9 * Revision 1.4 1987-06-04 01:32:18 wesommer
10 * Renamed gdb calls.
ca401c43 11 *
52795f45 12 * Revision 1.3 87/06/01 03:33:54 wesommer
13 * Added destroy_reply.
14 *
39dad676 15 * Revision 1.2 87/05/31 22:03:37 wesommer
16 * Fixed numerous bugs; still shaky.
17 *
ca401c43 18 */
19
20#ifndef lint
21static char *rcsid_sms_call_c = "$Header$";
22#endif lint
23
24#include "sms_private.h"
25
e2a67c78 26/*
27 * GDB operations to send and recieve RPC requests and replies.
28 */
29
ca401c43 30static sms_abort_send() {}
31static sms_abort_recv() {}
32
33/*
34 * This doesn't get called until after the actual buffered write completes.
35 * In a non-preflattening version of this, this would then queue the
36 * write of the next bunch of data.
37 */
38
52795f45 39sms_cont_send(op, hcon, arg)
e2a67c78 40 OPERATION op;
41 HALF_CONNECTION hcon;
ca401c43 42 struct sms_params *arg;
e2a67c78 43{
ca401c43 44 op->result = OP_SUCCESS;
45 db_free(arg->sms_flattened, arg->sms_size);
46#ifdef notdef
47 db_free(arg, sizeof(struct sms_params));
48#endif notdef
49 return OP_COMPLETE;
50}
51
52sms_start_send(op, hcon, arg)
53 OPERATION op;
54 HALF_CONNECTION hcon;
55 register struct sms_params *arg;
56{
57 int sms_size, i, len;
58 int *argl;
59 char *buf, *bp;
60
e2a67c78 61 /*
62 * This should probably be split into several routines.
63 * It could also probably be made more efficient (punting most
ca401c43 64 * of the argument marshalling stuff) by doing I/O directly
e2a67c78 65 * from the strings. Anyone for a scatter/gather sms_send_data?
66 *
67 * that would look a lot like the uio stuff in the kernel.. hmm.
68 */
69
70 /*
71 * Marshall the entire data right now..
72 * We are sending the version number,
73 * total request size, request number,
74 * argument count, and then each argument.
75 * At least for now, each argument is a string, which is
76 * sent as a count of bytes followed by the bytes
77 * (including the trailing '\0'), padded
78 * to a longword boundary.
79 */
80
81 sms_size = 4 * sizeof(long);
82
ca401c43 83 argl = (int *)malloc(sizeof(int) * arg->sms_argc);
e2a67c78 84
85 /*
86 * For each argument, figure out how much space is needed.
87 */
88
ca401c43 89 for (i = 0; i < arg->sms_argc; ++i) {
90 if (arg->sms_argl)
91 argl[i] = len = arg->sms_argl[i];
92 else
93 argl[i] = len = strlen(arg->sms_argv[i]) + 1;
e2a67c78 94 sms_size += sizeof(long) + len;
ca401c43 95 sms_size += sizeof(long) * howmany(sms_size, sizeof(long));
e2a67c78 96 }
97
ca401c43 98 arg->sms_flattened = buf = db_alloc(sms_size);
e2a67c78 99
ca401c43 100 bzero(arg->sms_flattened, sms_size);
e2a67c78 101
ca401c43 102 arg->sms_size = sms_size;
e2a67c78 103
104 /*
105 * This is gross. Any better suggestions, anyone?
106 * It should work on the RT's, since malloc is guaranteed to
107 * return a pointer which is aligned correctly for any data.
108 */
109
ca401c43 110 ((long *)buf)[0] = htonl(sms_size);
111 ((long *)buf)[1] = htonl(SMS_VERSION_1);
112 ((long *)buf)[2] = htonl(arg->sms_procno);
113 ((long *)buf)[3] = htonl(arg->sms_argc);
e2a67c78 114
115 /*
116 * bp is a pointer into the point in the buffer to put
117 * the next argument.
118 */
119
ca401c43 120 bp = (char *)(((long *)buf) + 4);
121
122 for (i = 0; i<arg->sms_argc; ++i) {
e2a67c78 123 len = argl[i];
124 *((long *)bp) = htonl(len);
125 bp += sizeof(long);
ca401c43 126 bcopy(arg->sms_argv[i], bp, len);
e2a67c78 127 bp += sizeof(long) * howmany(len, sizeof(long));
128 }
ca401c43 129 op->fcn.cont = sms_cont_send;
130 arg->sms_size = sms_size;
e2a67c78 131
ca401c43 132 if (gdb_send_data(hcon, arg->sms_flattened, sms_size) == OP_COMPLETE)
133 return sms_cont_send(op, hcon, arg);
e2a67c78 134 else return OP_RUNNING;
135}
136
52795f45 137sms_cont_recv(op, hcon, argp)
ca401c43 138 OPERATION op;
139 HALF_CONNECTION hcon;
140 sms_params **argp;
141{
142 int done = FALSE;
143 char *cp;
144 int *ip;
145 int i;
146 register sms_params *arg = *argp;
147
148 while (!done) {
149 switch (arg->sms_state) {
150 case S_RECV_START:
151 arg->sms_state = S_RECV_DATA;
152 if (gdb_receive_data(hcon, (caddr_t)&arg->sms_size,
153 sizeof(long)) == OP_COMPLETE)
154 continue;
155 done = TRUE;
156 break;
157 case S_RECV_DATA:
158 /* Should validate that length is reasonable */
159 arg->sms_size = ntohl(arg->sms_size);
160 arg->sms_flattened = db_alloc(arg->sms_size);
161 arg->sms_state = S_DECODE_DATA;
162 bcopy((caddr_t)&arg->sms_size, arg->sms_flattened, sizeof(long));
163
164 if (gdb_receive_data(hcon,
165 arg->sms_flattened + sizeof(long),
166 arg->sms_size - sizeof(long))
167 == OP_COMPLETE)
168 continue;
169 done = TRUE;
170 break;
171 case S_DECODE_DATA:
172 cp = arg->sms_flattened;
173 ip = (int *) cp;
174 /* we already got the overall length.. */
175 for(i=1; i <4; i++) ip[i] = ntohl(ip[i]);
176 if (ip[1] != SMS_VERSION_1)
177 arg->sms_status = SMS_VERSION_MISMATCH;
178 else arg->sms_status = ip[2];
179 arg->sms_argc = ip[3];
180 cp += 4 * sizeof(int);
181 arg->sms_argv=(char **)db_alloc(arg->sms_argc *sizeof(char **));
182 arg->sms_argl=(int *)db_alloc(arg->sms_argc *sizeof(int *));
183
184 for (i = 0; i<arg->sms_argc; ++i) {
185 int nlen = ntohl(* (int *) cp);
186 cp += sizeof (long);
187 arg->sms_argv[i] = (char *)db_alloc(nlen);
188 bcopy(cp, arg->sms_argv[i], nlen);
189 arg->sms_argl[i]=nlen;
190 cp += sizeof(long) *
191 howmany(nlen, sizeof(long));
192 }
193 return OP_COMPLETE;
194 }
195 }
196 return OP_RUNNING;
197}
198
e2a67c78 199
ca401c43 200sms_start_recv(op, hcon, argp)
e2a67c78 201 OPERATION op;
202 HALF_CONNECTION hcon;
ca401c43 203 struct sms_params **argp;
e2a67c78 204{
ca401c43 205 register sms_params *arg = *argp;
206 if (!arg) {
207 *argp = arg = (sms_params *)db_alloc(sizeof(sms_params));
52795f45 208 arg->sms_argl = NULL;
209 arg->sms_argv = NULL;
210 arg->sms_flattened = NULL;
ca401c43 211 }
212 arg->sms_state = S_RECV_START;
213 op->fcn.cont = sms_cont_recv;
214 return sms_cont_recv(op, hcon, argp);
e2a67c78 215}
216
ca401c43 217sms_do_call(parms, reply)
218 struct sms_params *parms;
219 struct sms_params **reply;
220{
221 if (!_sms_conn)
222 return SMS_NOT_CONNECTED;
223
224 if (!_sms_send_op)
225 _sms_send_op = create_operation();
226
227 if (!_sms_recv_op)
228 _sms_recv_op = create_operation();
e2a67c78 229
52795f45 230 initialize_operation(_sms_send_op, sms_start_send, parms,
231 sms_abort_send);
232 queue_operation(_sms_conn, CON_OUTPUT, _sms_send_op);
ca401c43 233
52795f45 234 initialize_operation(_sms_recv_op, sms_start_recv, reply,
235 sms_abort_recv);
236 queue_operation(_sms_conn, CON_INPUT, _sms_recv_op);
ca401c43 237
238 /* Block until operation done. */
52795f45 239 complete_operation(_sms_send_op);
240 complete_operation(_sms_recv_op);
ca401c43 241 /* Look at results */
242 if (OP_STATUS(_sms_recv_op) != OP_COMPLETE) {
243 return SMS_ABORTED;
244 }
245 return 0;
246}
247
39dad676 248sms_destroy_reply(reply)
249 sms_params *reply;
ca401c43 250{
39dad676 251 int i;
252 if (reply) {
253 if (reply->sms_argl)
254 free(reply->sms_argl);
255 reply->sms_argl = NULL;
256 if (reply->sms_flattened)
257 free(reply->sms_flattened);
258 reply->sms_flattened = NULL;
259 if (reply->sms_argv) {
260 for (i=0; i<reply->sms_argc; i++) {
261 if (reply->sms_argv[i])
262 free (reply->sms_argv[i]);
263 reply->sms_argv[i] = NULL;
264 }
265 free(reply->sms_argv);
266 }
267 reply->sms_argv = NULL;
268 free(reply);
269 }
ca401c43 270}
39dad676 271
This page took 0.126259 seconds and 5 git commands to generate.