/* INET STREAM listen.c */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#include <netinet/in.h>

extern int errno;

static void printaddr (t)
char *t;
{
printf("addr %u.%u.%u.%u\n", t[0]&0xFF, t[1]&0xFF, t[2]&0xFF, t[3]&0xFF);
} /* printaddr */

int main (argc, argv)
int argc;
char *argv[];
{
char *buf;			/* receive buffer */
int size;			/* size of receive buffer */
int rcv;			/* recvfrom() return status */
int listeningSD;		/* listening socket descriptor */
int connectedSD;		/* connected socket descriptor */
char *port_name = "4100";
int lname;			/* length of socket name */
int lfrom_name;			/* length of socket name */
struct sockaddr_in name;
struct sockaddr_in from_name;

int ch;				/* for getopt() */
extern char *optarg;		/* for getopt() */
extern int optind;		/* for getopt() */

size = 8 * 1024;

while ((ch = getopt(argc, argv, "r:p:")) != EOF)
  switch (ch)
    {
    case 'p': port_name = optarg; break;
    case 'r': size=1024*atoi(optarg); break;
    }

if (! (buf = malloc(size)))
  {
  fprintf(stderr, "No space.\n");
  exit(2);
  }

/*  */
/* Create socket from which to read */
listeningSD = socket(AF_INET, SOCK_STREAM, 0);
if (listeningSD == -1)
  { perror("opening socket"); exit(1); }
else
  printf("socket %d created\n", listeningSD);

/* Create name */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = htons(atoi(port_name));
/*  */
/* Attach name */
if (bind(listeningSD, (struct sockaddr *) (&name), sizeof(name)) == -1)
  { perror("binding name to socket"); exit(1); }
/* Find assigned port value and print it out */
lname = sizeof(name);
if (getsockname(listeningSD, (struct sockaddr *) (&name), &lname))
  { perror("getting socket name"); exit(1); }
printf("Socket has port #%d\n", ntohs(name.sin_port));

/*  */
if (listen(listeningSD, 5) == -1)
  { perror("listen failed"); exit(1); }
lfrom_name = sizeof(from_name);
/*  */
if ((connectedSD =
  accept(listeningSD, (struct sockaddr *) (&from_name), &lfrom_name)) == -1)
  { perror("accept"); exit(1); }
close(listeningSD);


/* Read from the socket */
  /*  */
  rcv = recv(connectedSD, buf, size, 0);
  if (rcv == -1) { perror("recvfrom"); exit(1); }
  else
    {
    printf("%d characters received from ", rcv);
    printaddr(&from_name.sin_addr);
    }


free(buf);
close(connectedSD);
exit(0);
} /* main */