🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: es.comp.os.unix
1 messages
1 total messages Started by Vinicio Flores Mon, 04 Jul 2011 04:44
Creating an FTP Client
#178
Author: Vinicio Flores
Date: Mon, 04 Jul 2011 04:44
333 lines
8747 bytes
Can you tell me what I have to know if I want to write a FTP Client??
And can you tell me how can I do it??

And if you have a good UNIX sockets howto to give, please give me 
one!!!!

I am working under GNU/Linux , I want to implement it using Sockets
Thank you!!!

Here I put the files:

/** MAIN FILE  -- cnet.c **/

/* 
 * A simple client to open connection
 * to servers and comunicate with
 * them.
 */

#ifndef _CNET_H
#include "cnet.h"
#endif

int main(argc, argv)
     int argc;
     char **argv;
{
  // If the user no input the needed
  // arguments
  if(argc != 3)
    handle_err(NEED_ARGC);

  // The struct where I will
  // save the socket 
  // connection data
  struct sock_client *sock = malloc ( sizeof(struct sock_client));
  // The client address struct
  struct sockaddr_in serv_addr;
  // Information about the server
  struct hostent *server;

  // The read and write streams
  // to FTP server
  FILE *cout, *cin;

  Buffer cbuff;

  // The message that
  // I will send
  String sended = "Hello World, I am connected to this server\n\r";

  // Convert the third argument 
  // to an integer number to
  // get the port number
  sock->n_port = atoi( *(argv + 2) );

  // Creates socket
  sock->sockfd = socket(AF_INET, SOCK_STREAM, 0);

  // Check if the creation of socket fails or is done...
  if(sock->sockfd == SYS_ERR)
    handle_err(OPENSOCK_ERR);

  // Initializes structs to zero
  memset(&serv_addr, 0, sizeof(serv_addr));

  // Get the host by its name
  server = gethostbyname( *(argv + 1) );

  // If cannot resolve host ...
  if(!server) 			// You can do a server == 
NULL but is more beauty to use !server and the GCC won't cry
    handle_err(GETHOST_ERR);

  // Fill the server address struct
  serv_addr.sin_addr = *((struct in_addr *)server->h_addr );
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(sock->n_port);

  // The server address length
  sock->addrlen = sizeof(serv_addr);

  // Get the remote ip address
  sock->ip = inet_ntoa(serv_addr.sin_addr);

  // Print the IP Address
  setcolor(FOREBLUE);
  cprintf("IP Address: ");

  setattr(BOLD);
  setcolor(FOREGREEN);

  cprintf("%s\033[0m\n", sock->ip);

  // Connect to the server and check if connect fails 
  if( (sock->con = connect(sock->sockfd, (struct sockaddr *)&serv_addr, 
sock->addrlen) ) == SYS_ERR)
    handle_err(CONNECT_ERR);

  /* Send a message to the server, this is so
   * trivial, only for funny!!! :-)
   */
  sock->bytes_wrote = write(sock->sockfd, sended, strlen(sended));

  // If cannot send message
  if(sock->bytes_wrote == SYS_ERR)
    handle_err(WRITE_ERR);

   // Read data from server
  sock->bytes_read = recv(sock->sockfd, sock->buffer, MAX_SIZE, 0);

  // If read fails ...
  if(sock->bytes_read == SYS_ERR)
    handle_err(READ_ERR);

  sock->buffer[sock->bytes_read] == '\0';
  // Print the server welcome message
  write(STDOUT_FILENO, sock->buffer, MAX_SIZE);

  cin = fdopen(sock->sockfd, "r");

  fgets(cbuff, MAX_SIZE, cin);
  fputs(cbuff, stdout);

  // Ask for USER
  setattr(BOLD);
  setcolor(FOREYELLOW);
  cprintf("USER: ");
  setattr(NORMAL);
  setattr(BOLD);
  fgets(sock->user, MAX_SIZE, stdin);

  // Ask for Password
  setattr(BOLD);
  setcolor(FOREYELLOW);
  cprintf("PASS: ");
  setattr(NORMAL);
  setattr(BOLD);
  fgets(sock->pass, MAX_SIZE, stdin);

  // Send USER to FTP server
  send(sock->sockfd, sock->user, MAX_SIZE, 0);
  // Send PASS to FTP Server
  send(sock->sockfd, sock->pass, MAX_SIZE, 0);

  // Close socket
  close(sock->sockfd);

  // Set the original terminal's status
  setattr(NORMAL);
  normvideo();

  return 0;
}


/** cnet.h -- global header **/

/* A simple client to open connection                                          
 * to servers and comunicate with them, 
 * like telnet.                                                                 
 */

#ifndef _CNET_H
#define _CNET_H

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

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

#ifndef _TTK_H
#include <ttk.h>
#endif

#define VERSION         0.2
#define COPYLEFT        "\nCopyleft (C) Vinicio Flores\nAll rights 
reversed\n\rThis program is free software, it is licensed under the GNU 
GPL\n\rRead LICENSE for more information\n\r"
#define CRAP            "\nYou can do with it all that you want, join 
us and share the software\n"

/* The max size of a memory buffer */

#define MAX_SIZE       800

#define SYS_ERR       -1    // The error value that an UNIX system call 
returns

// Boolean types and other data types
typedef enum  { false, true } bool;

typedef char *String;
typedef char Buffer[MAX_SIZE];

typedef unsigned char byte;
typedef unsigned char octet;
typedef unsigned short word;
typedef unsigned int dword;

/* Some error values 
 * of diferent system calls
 */

#define NEED_ARGC      0x00
#define OPENSOCK_ERR   0x01 
#define CONNECT_ERR    0x02
#define GETHOST_ERR    0x03
#define READ_ERR       0x04
#define WRITE_ERR      0x05


struct sock_client
{
  int sockfd;
  int bytes_read, bytes_wrote;
  int con;
  int n_port;
  Buffer buffer;
  socklen_t addrlen;
  String ip;
  Buffer user, pass;
};

/* Routines to handle errors */

extern void handle_err(int);

#endif // _CNET_H


/** Some routines used by cnet **/

/* Some routines used by cnet */

#ifndef _CNET_H
#include "cnet.h"
#endif

/* Handle and process common errors */
void handle_err(int n_error)
{
  switch(n_error)
    {
    case OPENSOCK_ERR:
      perror("Error while opening socket");
      exit(OPENSOCK_ERR);
      break;
    case CONNECT_ERR:
      perror("Error while trying to connect to server");
      exit(CONNECT_ERR);    
      break;
    case NEED_ARGC:
      reset();
      setattr(REVERSE);
      setcolor(FORERED);
      cprintf("Cnet v%3.1f\n", VERSION);
      setattr(NORMAL);
      setattr(BOLD);
      setcolor(FORECYAN);
      cprintf("Usage: ");
      setattr(NORMAL);
      cprintf("cnet <hostname> <n_port> Example(");
      setattr(UNDERLINE);
      cprintf("cnet ftp.gnu.org 21");
      setattr(NORMAL);
      cprintf(")\n");
      normvideo();

      setattr(BOLD|REVERSE);
      cprintf("\nAbout Cnet \n");

      setattr(NORMAL);

      cprintf("\t\tCnet is a terminal-based program that connects to a 
server, like Telnet\n\r");
      cprintf("\t\tCnet aims to be an enhanced and minimalistic telnet 
program\n\r");
      cprintf("\t\tThis is an alpha release and maybe it will not work 
properly, please download the cnet source code and work on it\n\r");
      cprintf("%s%s\n\r", COPYLEFT, CRAP);

      exit(NEED_ARGC);
      break;
    case GETHOST_ERR:
      setcolor(FORERED);
      cprintf("Error, no such host\n");
      setattr(NORMAL);
      normvideo();
      exit(GETHOST_ERR);
      break;
    case READ_ERR:
      perror("Read error");
      setattr(NORMAL);
      normvideo();
      exit(READ_ERR);
      break;
    case WRITE_ERR:
      perror("Write error");
      exit(WRITE_ERR);
      break;
    }
}

// And here is the Makefile

# Makefile for cnet

CFLAGS=-O -O2 -O3 -g -Wall -lttk -DMONOLITH -fwhole-program -Ofast -
fcommon -Werror

BINARY=cnet
CC=gcc

all:
	$(CC) -c *.c
	$(CC) -o $(BINARY) *.o $(CFLAGS)

clean:
	rm *.o $(BINARY)

install:
	cp cnet /usr/bin

PS: Please tell me what can I do more here!!!!
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads