- /*
- * This should probably be split into several routines.
- * It could also probably be made more efficient (punting most
- * of the argument marshalling stuff by doing I/O directly
- * from the strings. Anyone for a scatter/gather sms_send_data?
- *
- * that would look a lot like the uio stuff in the kernel.. hmm.
- */
-
- /*
- * Marshall the entire data right now..
- * We are sending the version number,
- * total request size, request number,
- * argument count, and then each argument.
- * At least for now, each argument is a string, which is
- * sent as a count of bytes followed by the bytes
- * (including the trailing '\0'), padded
- * to a longword boundary.
- */
-
- sms_size = 4 * sizeof(long);
-
- argl = (int *)malloc(sizeof(int) * arg->argc);
-
- /*
- * For each argument, figure out how much space is needed.
- */
-
- for (i = arg->argc; i; --i) {
- argl[i] = len = strlen(arg->argv[i]) + 1;
- sms_size += sizeof(long) + len;
- sms_size = sizeof(long) * howmany(sms_size, sizeof(long));
- }
-
- arg->flattened = buf = db_alloc(sms_size);
-
- bzero(arg->flattened, sms_size);
-
- arg->size = sms_size;
-
- /*
- * This is gross. Any better suggestions, anyone?
- * It should work on the RT's, since malloc is guaranteed to
- * return a pointer which is aligned correctly for any data.
- */
-
- ((long *)buf)[0] = htonl(SMS_VERSION_1);
- ((long *)buf)[1] = htonl(sms_size);
- ((long *)buf)[2] = htonl(arg->procno);
- ((long *)buf)[3] = htonl(arg->argc);
-
- /*
- * bp is a pointer into the point in the buffer to put
- * the next argument.
- */
-
- bp = (char *)(&(long *)buf[4])
- for (i = arg->argc; i; --i) {
- len = argl[i];
- *((long *)bp) = htonl(len);
- bp += sizeof(long);
- bcopy(arg->argv[i], bp, len);
- bp += sizeof(long) * howmany(len, sizeof(long));
+ int status;
+
+ CHECK_CONNECTED;
+
+ status = mr_send(_mr_conn, params);
+ if (status == MR_SUCCESS)
+ status = mr_receive(_mr_conn, reply);
+
+ if (status)
+ mr_disconnect();
+
+ return status;
+}
+
+int mr_send(int fd, struct mr_params *params)
+{
+ u_long length, written;
+ int i, *argl;
+ char *buf, *p;
+
+ length = 16; /* length + version + opcode/status + argc */
+
+ if (params->mr_argl)
+ {
+ argl = params->mr_argl;
+ for (i = 0; i < params->mr_argc; i++)
+ length += 8 + argl[i];
+ }
+ else
+ {
+ argl = malloc(params->mr_argc * sizeof(int));
+ if (params->mr_argc && !argl)
+ return ENOMEM;
+ for (i = 0; i < params->mr_argc; i++)
+ {
+ argl[i] = strlen(params->mr_argv[i]) + 1;
+ length += 8 + argl[i];