rshd control string

My host environment is Linux and SCO systems talking to a remote SCO box. Authentication has been configured, I can do rcmd or rsh between the systems. I am trying to use rsh facility of remote unix box and I don't want to use system call to rsh or rcmd. Instead, I am trying to open 514 port directly from my code and send a comand to it. My understaning is that to achieve that I need to form a control string in the following fashion:

 
\0local_user\0remote_user\0command\0

My program sends the string to the host, but gets nothing back.

Please see my code below. Just a note - to make sure code has no problems I targeted port 13 (time) and it worked, so I assume the problem is in the control string.

 
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#define MAXSIZE 512
const   char    *ip_addr        = "192.168.1.2";
const   int     srvr_port       = 514;
main(int argc, char *argv[])
{
  int                   sd = 0;
  int                   rc, cnt, len, actually_sent;
  char                  msg[MAXSIZE] = "\0";
  char                  ch = '\0';
  char                  *p = NULL;
  struct sockaddr_in    saddr;
        sd = socket(AF_INET, SOCK_STREAM, 0);
        if(sd == -1)
        {
                printf("Socket descriptor not allocated\n");
                return(1);
        }
        memset(&saddr, 0, sizeof(saddr));
        saddr.sin_family        = AF_INET;
        saddr.sin_addr.s_addr   = inet_addr(ip_addr);
        saddr.sin_port          = htons(srvr_port);
        rc = connect(sd, (struct sockaddr *)&saddr, sizeof(saddr));
        if(rc == -1)
        {
                printf("connect err=%i <%s>\n", errno, sys_errlist[errno]);
                return(1);
        }
 
        sprintf(msg, "%i%s%i%s%i%s%i",
                        0,
                        "xuser",        0,
                        "xuser",        0,
                        "pwd",          0);
        len = 1 + 5 + 1 + 5 + 1 + 3 + 1;
        p = msg;
        actually_sent = cnt = 0;
        while(actually_sent < len)
        {
                rc = send(sd, p, len - actually_sent, 0);
                if(rc == -1)
                {
                        printf("send err %i <%s>\n", errno, sys_errlist[errno]);
                        return(1);
                }
                else
                {
                        actually_sent += rc;
                        p += rc;
                }
        }
        printf("sent %i bytes OK\n", actually_sent);
        cnt = ch = rc = 0;
        memset(msg, 0, sizeof(msg));
        for(    rc = recv(sd, &ch, 1, 0);
                (rc == 1 || (rc == -1 && errno == EWOULDBLOCK)) &&
                cnt < MAXSIZE - 1;
                rc = recv(sd, &ch, 1, 0))
        {
                *(msg + cnt) = ch;
                cnt++;
                printf("[%c] (%x)\n", ch, ch);
                if(ch == '\n')
                        break;
        }
        printf("rc=%i, errno=%i\n", rc, errno);
        printf("recv cnt=%i <%s>\n", cnt, msg);
        shutdown(sd, 0);
        return(0);
}

response from my program:

sent 17 bytes OK
rc=0, errno=0
recv cnt=0 <>

Again, authentication is OK, I can do rsh 192.168.1.2 -l xuser pwd no problem.

Any pointers would be appreciated.

What happens if you change your "%i"s in your format string to "%c" instead? It looks like you're currently printing 0x30 instead of 0x00 for the "\0"s.

You are absolutely correct, those need to be '\0'. I changed the code accordingly, but I still get exactly same result.
I added string printout before I send it:

 
[] (0)
[x] (78)
 (75)
 (73)
[e] (65)
[r] (72)
[] (0)
[x] (78)
 (75)
 (73)
[e] (65)
[r] (72)
[] (0)
[p] (70)
[w] (77)
[d] (64)
[] (0)
sent 17 bytes OK
rc=0, errno=0
recv cnt=0 <>

It looks like the server is still waiting on something.

Do you have root access on the client machine? If so, you might try dumping all the network traffic to a file (tcpdump) and then connect via rlogin and view the dump file to see what is actually being sent.