3 * Pass an mr_params off to the Moira server and get a reply
5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
12 #include "mr_private.h"
15 #include <netinet/in.h>
24 4-byte total length (including these 4 bytes)
25 4-byte version number (MR_VERSION_2 == 2)
26 4-byte opcode (from client) or status (from server)
29 4-byte len, followed by null-terminated string, padded to 4-byte boundary
30 (the len doesn't include the padding)
33 (followed by more packets if status was MR_MORE_DATA)
35 All numbers are in network byte order.
38 int mr_do_call(struct mr_params *params, struct mr_params *reply)
44 status = mr_send(_mr_conn, params);
45 if (status == MR_SUCCESS)
46 status = mr_receive(_mr_conn, reply);
54 int mr_send(int fd, struct mr_params *params)
56 u_long length, written;
60 length = 16; /* length + version + opcode/status + argc */
64 argl = params->mr_argl;
65 for (i = 0; i < params->mr_argc; i++)
66 length += 8 + argl[i];
70 argl = malloc(params->mr_argc * sizeof(int));
71 if (params->mr_argc && !argl)
73 for (i = 0; i < params->mr_argc; i++)
75 argl[i] = strlen(params->mr_argv[i]) + 1;
76 length += 8 + argl[i];
87 memset(buf, 0, length);
89 putlong(buf + 4, MR_VERSION_2);
90 putlong(buf + 8, params->u.mr_procno);
91 putlong(buf + 12, params->mr_argc);
93 for (i = 0, p = buf + 16; i < params->mr_argc; i++)
96 memcpy(p += 4, params->mr_argv[i], argl[i]);
97 p += argl[i] + (4 - argl[i] % 4) % 4;
100 putlong(buf, length);
102 written = write(fd, buf, length);
104 if (!params->mr_argl)
107 if (written != length)
113 int mr_receive(int fd, struct mr_params *reply)
117 memset(reply, 0, sizeof(struct mr_params));
119 status = mr_cont_receive(fd, reply);
120 while (status == -1);
125 int mr_cont_receive(int fd, struct mr_params *reply)
132 if (!reply->mr_flattened)
136 size = read(fd, lbuf, 4);
138 return size ? MR_ABORTED : MR_NOT_CONNECTED;
139 getlong(lbuf, length);
140 reply->mr_flattened = malloc(length);
141 if (!reply->mr_flattened)
143 memcpy(reply->mr_flattened, lbuf, 4);
144 reply->mr_filled = 4;
149 getlong(reply->mr_flattened, length);
151 more = read(fd, reply->mr_flattened + reply->mr_filled,
152 length - reply->mr_filled);
155 mr_destroy_reply(*reply);
159 reply->mr_filled += more;
161 if (reply->mr_filled != length)
164 getlong(reply->mr_flattened + 4, data);
165 if (data != MR_VERSION_2)
167 mr_destroy_reply(*reply);
168 return MR_VERSION_MISMATCH;
171 getlong(reply->mr_flattened + 8, reply->u.mr_status);
172 getlong(reply->mr_flattened + 12, reply->mr_argc);
173 reply->mr_argv = malloc(reply->mr_argc * sizeof(char *));
174 reply->mr_argl = malloc(reply->mr_argc * sizeof(int));
175 if (reply->mr_argc && (!reply->mr_argv || !reply->mr_argl))
177 mr_destroy_reply(*reply);
181 for (i = 0, p = (char *)reply->mr_flattened + 16; i < reply->mr_argc; i++)
183 getlong(p, reply->mr_argl[i]);
184 reply->mr_argv[i] = p + 4;
185 p += 4 + reply->mr_argl[i] + (4 - reply->mr_argl[i] % 4) % 4;
191 void mr_destroy_reply(mr_params reply)
195 free(reply.mr_flattened);