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