[comp.unix.programmer] sockets: char-mode & getpeername ?

hollosi@taiyang.ucsc.edu ( Joseph Hollosi <hollosi@helios.ucsc.edu> ) (06/30/91)

I am writing a server to which I want to connect by a usual
"telnet hostname port" command. Everything works, except two things:

1. how can I read() input which is not terminated by <Return>; it seems,
   that read() doesn't read anything (even I want to read one character only)
   until a line is typed in. ("man telnet" mentions a char-mode, but I want
   to set that from the other side)?
   I think this may be solved by using non-blocking read, but I would prefer
   the blocking version, because it gives you the chance to discover if the
   telnet is broken (killed) on the other side.
2. how can I get the name of machine from where the telnet is initiated;
   I tried getpeername(), but it gave some mess?

Thanks, please reply to <hollosi@helios.ucsc.edu>,
Joseph.

mycroft@kropotki.gnu.ai.mit.edu (Charles Hannum) (07/01/91)

> 1. how can I read() input which is not terminated by <Return>; it seems,
>    that read() doesn't read anything (even I want to read one character only)
>    until a line is typed in. ("man telnet" mentions a char-mode, but I want
>    to set that from the other side)?
>    I think this may be solved by using non-blocking read, but I would prefer
>    the blocking version, because it gives you the chance to discover if the
>    telnet is broken (killed) on the other side.

You need to read RFCs 854 ("Telnet Protocol Specification") and 856
("Telnet Binary Transmission").  To do what you want, your program is
actually going to have to interpret telnet command sequences in the
transmission.  This is VERY tricky business.  You might want to
consider whether or not it's worth the effort.  (If you're just trying
to eliminate password echoing in a MUD, for example, I would say it's
definitely not worth the effort.)

> 2. how can I get the name of machine from where the telnet is initiated;
>    I tried getpeername(), but it gave some mess?

getpeername() will return a sockaddr_in structure.  If you want the
canonical name of the other host, you need to use gethostbyaddr() on
the address returned by getpeername().  i.e.:

  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>

  int fd;
  struct sockaddr_in bar;
  struct hostent *foo;

  if (getpeername(fd, &bar, sizeof(bar)) == -1)
    /* FAILED: couldn't get name (probably not a socket) */
    perror("Where the hell are you?");
  else if (bar.sin_family != AF_INET)
    /* FAILED: not an inet domain socket */
    printf("What network are you using?\n");
  else if (!(foo = gethostbyaddr(bar.sin_addr, sizeof(bar.sin_addr), AF_INET)))
    /* FAILED: couldn't find canonical name */
    printf("Address of connected host is: %s\n", inet_ntoa(bar.sin_addr));
  else
    printf("Name of connected host is: %s\n", foo->h_name);