Wednesday, 22 February 2012

Construct your own telnet or FTP

Here i present a simple telnet construction tutorial and also how it can be used also to transfer files between server and client or a simple ftp server client implementation.With codes.

A telnet is something like a medium through which you can connect to a server and execute instructions from your system ,on the server.Here you are remotely transferring instruction which gets executed in the server as though you were directly interacting with the server.

I intend to implement the same with additional features of downloading or uploading files from and to the server.
An attempt for simplifying the process is made.The logic is this
The instruction from client to server and the response is transferred through sockets,  (Please refer to my sockets tutorial) tutorial

The Program should also resolve between whether the instruction is to be executed in the client system or the server also sockets allow data transaction in character stream form,so how to transfer files ?

For transferring files read and write commands are used which reads and writes to a data entity pointed by a file descriptor thus the file is converted into bytes and it is this bytes which gets transferred from server to client or the other way round,This allows you to transfer not only text files but also executable,audio,video,images and so on.

ok check out the server side and client side codes and lets go through them server side and the client side

Lets see the programs but before that you may want to check out the sockets tutorials mentioned earlier.

First thing you may want to observe in the server side is that signal handlers like  sigaction ,SIGCHLD are used these are to ensure that the termination of child process is successful and it may not result in zombie process ,there exist two sockets one for listening and the other is for transferring data ,all the child process handle the socket meant for transferring data.

Also for every write in server there should be a corresponding read in the client or vice verse,Here the client first transfers the data to the socket which contain the telnet commands ,observe the command change directory or cd is identified separately and instead of a system call ,a chdir() function is used this is because
in case a system call is used the subsequent commands such as say ls would reveal that the directory has actually not changed however the usage of the chdir solves the problem.


For FTP file transfer open command opens the file the name being indicated by the source and returns a file descriptor inhandle which is used by the read function to read the file and store the content into the buffer which then can be passed to the client by a simple send function.The while loop ensures that this process is repeated until the complete file is transferred .

The corresponding client side will do the opposite that is ,it will wait until the complete data is received by using the recv and write commands.Also in the client side locally system call is executed for all the instruction beginning with l ie lls is ls for client lps,ldate etc all do the same for client side.

now back to the server side,notice the

strcat(buf, " > a.txt 2>a.txt");
    system(buf);


here the system call will store the result of the command onto a file a.txt and 2>a,txt also indicates that error message if any can also be stored onto this file.
This file is then transferred to the client where the client can then display the result.

thats about it

how to run the program ?
This intended for linux based system
1.compile your program by using
gcc server.c -o s
gcc client.c -o c

then open two terminals in one execute ./s   and in other  ./c ip or ./c 127.0.0.1  for local host   thats both client and server in your machine

then password for client is woo
once you are in you can use ls,ps,date, get filename  (file should be in server folder and you are getting it),put filename(file is in client folder and you are uploading to server folder)

importantly your server and client should be in different folders...

also once the files are uploaded or downloaded  you may want to enter the
chmod +r filename to read it
in case they are executables  use after the previous command chmod +x filename


Monday, 13 February 2012

client side program for FTP / telnet service

 #include <stdio.h>
#include <string.h>
 #include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include<string.h>
#include <netdb.h>
 #include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define O_BINARY 0
    int main(int argc, char *argv[])

    { int po = 3490 ; // the port client will be connecting to
 int siz = 300 ;  // max number of bytes we can get at once

     char buffer[ 300 ], target [ 128 ] ;
     int inhandle, outhandle, bytes ;


    int sockfd, numbytes,new_fd,i,j,k;

    char buf[siz],*ch,tempc[30],tmp[30],pwd[30];

    struct hostent *he;

      // connector’s address information

    struct sockaddr_in their_addr;

   // if no command line argument supplied
if(argc < 2)

    {

        fprintf(stderr, "clien: %s id\n", argv[0]);

     

        exit(1);

    }
   

  

  

   

   // get the host info,server ip
    if((he=gethostbyname(argv[1])) == NULL)

    {

        perror("IP error");
        exit(1);

    }

    else

        printf("IP%s\n", argv[1]);

   

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

        perror("no socket created");

        exit(1);

    }

    else

        printf("socket is goin strong yahoo!!\n");

   

    // host byte order

    their_addr.sin_family = AF_INET;
  // short, network byte order
  
    printf("server ip %s port id %d...\n", argv[1], po);

    their_addr.sin_port = htons(po);

    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 
 
// zero the rest of the struct

    memset(&(their_addr.sin_zero), '\0', 8);

   

    if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)

    {

        perror("connection error ,too bad try again!!");

        exit(1);

    }

    else

        printf("Server pinged,you are good to go\n");
 printf("State thy password and ye shall pass\n");
gets(pwd);
if(strcmp(pwd,"woo")!=0)
{printf("Thou shall not pass\n");
exit(0);
}
else
{printf("Welcome");
system("date");
}
a:
while(1)
{  
    printf("$: ");

        for(k=0;k<siz;k++)
           buf[k]='\0';
  
  
    gets(buf);
    fflush(stdin);
  
if(buf[0]=='l' && buf[1]!='s')
{
for(k=0;k<30;k++)
        {
            tempc[k] = buf[k + 1];

        }
system(tempc);
goto a;
}

if(buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't')
{printf("Good Bye !!");

system("date");
  close(sockfd);
exit(0);
}
    else
{









    if(buf[0] == 'g' && buf[1] == 'e' && buf[2] == 't' && buf[3] == ' ')
    {
         printf ( "\nEnter target file name" ) ;
         gets ( target ) ;//target is locally used ,the file copied is stored by the target content name
  

outhandle = open ( target, O_CREAT | O_BINARY | O_WRONLY,
                 S_IWRITE ) ;




            i=send(sockfd, buf, siz-2, 0);//send file name
j=0;

printf("receiving...\n");
        do
        {
j++;
if(j%300 == 0)
printf("..");
        numbytes = recv(sockfd, buffer, 298,0);
      
                      write ( outhandle, buffer, numbytes ) ;
               

        }while(numbytes > 2);
printf("enjoy your data");
        close(outhandle);
goto a;


    }

 if(buf[0]=='p' && buf[1]=='u' && buf[2]=='t' && buf[3]== ' ' )
{for(k=0;k<30;k++)
tmp[k] = buf[k+4];

 i=send(sockfd, buf, siz-2, 0);
 inhandle = open ( tmp, O_RDONLY | O_BINARY ) ;
             if ( inhandle == -1 )
             {
                    puts ( "Cannot open file" ) ;
                    exit(0) ;
               }
j=0;
do
        {

j++;
if(j%300==0)
printf("..");

bytes = read ( inhandle, buffer, 298 );
            
            i=send(sockfd, buffer, bytes, 0);
      
          }while ( bytes ==298);
printf("\ndata transfered\n");
close(inhandle);
goto a;
}




    i=send(sockfd, buf, siz-2, 0);


    do
    {
        numbytes = recv(sockfd, buf, siz-2, 0);
        buf[298] = '\0';
        printf("%s",buf);

    }while(numbytes ==298);



}


  


  
}


    printf("Closing socket\n");

    close(sockfd);

    return 0;

    }

Sunday, 12 February 2012

FTP or telnet ,server side codes

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
   
#include <fcntl.h>

#include <sys/stat.h>



  
/* how many pending connections queue will hold */
  
    #define BACKLOG 10

     #define O_BINARY 0 // needed for the functions read and write

    void sigchld_handler(int s)

    {

        while(wait(NULL) > 0);

    }

    

    int main(int argc, char *argv[ ])

    {  /* listen on sock_fd, new connection on new_fd */
int siz=300;int po=3490; /* the port users will be connecting to */



    FILE *fp;

    char buffer[ 300 ], source [ 128 ], target [ 128 ] ;

    int inhandle, outhandle, bytes ;

    char buf[siz],rxstring[30],ch,tempc[30],tempc1[30];

    int sockfd, new_fd,i,numbytes,j,k;

 
/* my address information */
    struct sockaddr_in my_addr;

   
  /* connector’s address information */
    struct sockaddr_in their_addr;

    int sin_size;

    struct sigaction sa;

    int yes = 1;

    

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

        perror("Socket error");

        exit(1);

    }

   

    

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
exit(1);

  
    

  /* host byte order */

    my_addr.sin_family = AF_INET;

    /* short, network byte order */
    my_addr.sin_port = htons(po);

    /* automatically fill with my IP */

    my_addr.sin_addr.s_addr = INADDR_ANY;

    

    printf("Server  %s and port %d...\n", inet_ntoa(my_addr.sin_addr), po);

    
  /* zero the rest of the struct */
   

    memset(&(my_addr.sin_zero), '\0', 8);

    

    if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
exit(1);


    

    if(listen(sockfd, BACKLOG) == -1)
exit(1);

 

   

    

      /* clean all the dead processes */

    sa.sa_handler = sigchld_handler;

    sigemptyset(&sa.sa_mask);

    sa.sa_flags = SA_RESTART;

    

    if(sigaction(SIGCHLD, &sa, NULL) == -1)
exit(1);

   // loop to accept client requests
    while(1)

    {

    sin_size = sizeof(struct sockaddr_in);

    if((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
continue;

  else

      

    printf("Server pinged from %s\n", inet_ntoa(their_addr.sin_addr));

      /* this is the child process */

  
    if(!fork())

    {
   /* child doesn’t need the listener */
      
       close(sockfd);
a:
while(1)
{

    numbytes = recv(new_fd, buf, siz-2, 0);


    if(numbytes > 0)
    {
//Client-The recv() is OK.
    if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' ' )
    {
               for(k=0;k<25;k++)
        {
            tempc[k] = buf[k + 3];

        }



        chdir(tempc);
       
    }



    else if(buf[0] == 'g' && buf[1] == 'e' && buf[2] == 't' && buf[3] == ' ')
    {
   
        for(k=0;k<30;k++)
            source[k] = buf[k+4];
             inhandle = open ( source, O_RDONLY | O_BINARY ) ;
             if ( inhandle == -1 )
             {
                    puts ( "Cannot open file" ) ;
                    exit(0) ;
               }


        do
        {



bytes = read ( inhandle, buffer, 298 );
           

            i=send(new_fd, buffer, bytes, 0);
      
          }while ( bytes ==298);



    close(inhandle);   
goto a;

    }

else if(buf[0] == 'p' && buf[1] == 'u' && buf[2] == 't' && buf[3] == ' ')
{
for(k=0;k<30;k++)
rxstring[k]=buf[k+4];

outhandle = open ( rxstring, O_CREAT | O_BINARY | O_WRONLY,
                 S_IWRITE ) ;

do
        {

        bytes = recv(new_fd, buffer, 298,0);
       
                      write ( outhandle, buffer, bytes ) ;
                

        }while(bytes == 298);

strcpy(tempc1,"chmod +r ");
strcat(tempc1,rxstring);
system(rxstring);

        close(outhandle);
goto a;

}
else
{
    strcat(buf, " > a.txt 2>a.txt");
    system(buf);






        fp=fopen("a.txt","r");



    k=0;
    while ( 1 )
    {    k++;
         ch = fgetc ( fp ) ;
         if ( ch == EOF )   
         {
               buf[k-1] = ch;
           i=send(new_fd, buf, k, 0);
               break ;
         }
         else
         {
        if(k <= 298)
               buf[k-1] = ch;
        else
           i=send(new_fd, buf, k, 0);
         }


    }
           i=send(new_fd, buf, 0, 0);


    fclose(fp);
}
  }



}//Client-Received
       if(i == -1)

            perror("Server send error ");

       close(new_fd);

       exit(0);

    }

   
    


//redundant for parent process
    close(new_fd);
//printf("Server-new socket, new_fd closed successfully...\n");
  
    }

    return 0;

    }

Saturday, 11 February 2012

command line programming in c

There are methods to interact with a program in command line itself,by command line i mean the terminal by which the program can be executed.Is it possible to supply arguments to a program in the command line ?
YES !,


we first learn to compile and run a program using gcc

say you have a program hello.c


to compile we use                       gcc -c hello.c or a simple gcc hello.c would do


The above command creates a default object file by the name a.out so if you wanna execute the program you need to      ./a.out and hit enter

but if you want to give your name to the object file then you can do so by
gcc hello.c -o yourname
the program then can be run by  just  ./yourname





NOW FOR THE COMMAND LINE ARGUMENT PASSING

lets say you made a object file name by using   gcc prog.c -o name

now to pass arguments to this program prog from the command line ,The prog program would have


int main(int argc,char * argv[])
{   .......
    ........
    ........
}

int argc indicate how many arguments are passed and argv will store the arguments

that is if you want to pass a alist of arguments to your prog program with object name then


          ./name prog.c 25 wow! 56.78 this$is$a$string

now observe the syntax i wrote ./object (name of the program ie prog.c) (argument list)

the argument list is seperated by integers and the first is an integer .2nd a string ,3rd a float and the 4th is a string but i have used delimiters such as $ to indicate space..and its your job to replace the $ with space inside the program.
you could have used any other delimiter apart from $

now inside the program the argc is holding value 5

and argv[0] = "prog.c"
argv[1] = 25
argv[2] ="wow!"
and so on

Thats about it ,this provides a simple enough usage of command line argument passing

Tuesday, 7 February 2012

anatomy of Operating system

The operating system is used for maintaining and managing the resource of the system,something like an administrator maintaining the resources.
There typically exists two spaces for usage namely the kernel and user space,this allows the OS to differentiate between reliable and non reliable processes.The reliable process being the system processes which are run in kernel mode ,thus these processes have access to hardware and various resources.
The user processes such as those which you use,like a browser for instance are in user space as these are not reliable.They may contain malicious codes or may contain bugs.These user processes are run in user space (There exist separate virtual memory for user and kernel modes processes) Thus eventually for these user processes to run they need to be mapped to kernel processes .There exist various schemes of mapping wherein many user processes can be mapped to a single kernel process or they may be mapped to many kernel processes.
The kernel is just the core constituent of the  OS ,This provides to each of the application which may contain multiple threads (threads are something like a small process or small app) thus each user application can only run when the kernel provides these threads.
However what would happen if the user thread (an application is composed of set of small threads each doing some stuff as was earlier declared) gets blocked (if a thread requires access to resources say a printer but if the resource is being used by another ,then it got to wait or get blocked) ?
The kernel by means of a mechanism termed the "upcall" will indicate to the user application that a thread is being blocked and also allows the kernel thread which was mapped to the user thread ,to be used for some other user thread which can be run!
The reason of kernel and user space is ,to reiterate it safeguards the resources so that the OS can allow all privileges to the recognised and reliable processes which are termed the kernel processes and those which it is not sure of is implemented in the userspace
Generally all the system process such as scheduler,dispatcher etc are the kernel processes and the normal applications such as the time display,GUI apps etc are the user processes.




so in summary for a easier understanding of operating system ,consider the existence of two domains ,the usersmode and the kernel mode..All the important ,reliable processes which are responsible for critical system performance are kept as kernel processes and those which are not are the user processes .
Thus if a user process becomes unstable then it just gets hanged and you may need to do the alt+ctrl+del to kill it.But if any of the kernel process gets corrupted then you the whole operating system come to a halt and the only option is to reboot and install a new OS !!!!
so to avoid all the user process to directly get hold of hardware the OS will map the user process to kernel process and this kernel process actually runs in the system.