-3

The goal of this server is to transfer small files, in a relatively simple manner. I have finished the code and it all compiles without error, and when I try to run it, the server side has no problems, but the client side gives an error in the socket binding and a segmentation fault. I was wondering what in the code was causing these problems.

Server:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <string.h>
#include <unistd.h>
#include <crypt.h>
#include <time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <netinet/ip.h>
void timestamp_ss()
{
  time_t current_time;
  char* log_time;

  log_time = ctime(&current_time);
  log_file_ss(log_time);
}
send_data(int sockfd, char info_to_send)
{
  char eof_buffer[4] = "\EOF";
  int sent_data, data_to_send;
  data_to_send = strlen(&info_to_send);

  while(data_to_send > 0)
  {
  sent_data = send(sockfd, &info_to_send, data_to_send, 0);
  if(sent_data == -1)
    perror("There was a problem in the sending of data!");
  data_to_send -= sent_data;
  info_to_send += sent_data;
  }
  send(sockfd, eof_buffer, 4, 0);
}
int recv_data(int sockfd, char *dest_buffer)
{
  #define EoF "\EOF"
  unsigned char *buffer;
  int eof_match = 0, eof_size = 2;

  buffer = dest_buffer;
  while(recv(sockfd, buffer, 1, 0) == 1)
  {
    if(*buffer == EoF[eof_match])
    {
      eof_match++;
      if(eof_match = eof_size)
        {
          *(buffer+1-eof_size) = '\0';
          return strlen(dest_buffer);
        }
        else
        {
          eof_match = 0;
        }
    }
    buffer++;
  }
  return 0;
}
int password_ss(char *password_attempt, char *password_actual)
{
  char key[] = { "ZjQXStSi" };
  char ivec[] = {"7eNP3U1b" };
  char des_dec[] = { "DES_DECRYPT" };
  char des_hw[] = { "DES_HW" };
  int l, i;

  l = strlen(password_attempt);
  i = cbc_crypt(key, password_attempt, l, *des_dec | *des_hw, ivec);
  if(i < 0)
    error_escape("In decryption");

  if(password_attempt == password_actual)
    return 1;
  else
    return 0;
}
int log_file_ss(char *log_message)
{
  char logfile[]= "/Server/log/C-File-Transfer-Server-Log";
  int log_fd, len;

  log_fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT);
  len = strlen(log_message);
  write(log_fd, log_message, len);
}
void file_to_client_ss(int sockfd, struct sockaddr_in *client_addr_ptr)
{
  char file_req_c[128]; 
  char buffer[10000];
  char files[256];
  char pass_attempt[128];
  char *error_403[20] = { "Error 403: Forbidden" };
  char *error_404[25] = { "Error 404: File Not Found" };
  char *pass_path[20] = { "/server/log/PASSWORD" };
  char *pass_req[50] = { "This File Requires A Password, Please Enter It Now" };
  char *no_pass[37] = { "This File Does Not Require A Password" }; 
  char *username;
  char *file_s;
  char *string;
  char *file1_path[26] = { "/server/received_files/r_w" };
  char *file2_path[24] = { "/server/received_files/r" };
  char *file3_path[24] = { "/server/received_files/n" };
  char file_data;
  FILE *cs, *ps;
  int file1, file2, file3, file_test, pass;

  cs = fopen(file_req_c, "r");
  recv_data(sockfd, username);
  chdir("/server/log/PASSWORD");
  ps = fopen(username, "r");
  fread(files, 1, file_size(ps), ps);
  chdir("/server");
  recv_data(sockfd, file_req_c);
  file_test = file_exist(file1_path, file_req_c);
  if(file_test = -1)
  {
    file_test = file_exist(file2_path, file_req_c);
    if(file_test = -1)
    {
        file_test = file_exist(file3_path, file_req_c);
            if(file_test = -1)
            {
                error_escape("Opening file request from client");
            }
            else
            {
                    send_data(sockfd, **pass_req);
                    recv_data(sockfd, pass_attempt);
                    pass = password_ss(pass_attempt, files);
                        if(pass == 0)
                {
                            send_data(sockfd, **error_403);
                            error_escape("Wrong Password");
                }
                    else
                    {
                             if(file_exist(pass_path, username) == 0)
                                send_data(sockfd, *file_req_c);
                    else
                        errror_escape("Error in sending file");
                        }
            }   
       }
      else
      {
        chdir(*file2_path);
        file_data = fread(buffer, 1, file_size(cs), cs);
        send_data(sockfd, **no_pass);
        send_data(sockfd, file_data);
      }     
  }
  else
  {
    chdir(*file1_path);
    file_data = fread(buffer, 1, file_size(cs), cs);
    send_data(sockfd, **no_pass);
    send_data(sockfd, file_data);
  }
}
int file_size(FILE *stream)
{
  off_t file_len; 

  fseek(stream, 0, SEEK_END);
  file_len = ftell(stream);
  fclose(stream);
  return file_len;
}
int file_exist(char *file_path, char *file_name)
{
  DIR *dp;
  FILE *fc;
  struct dirent *ep;

 dp = opendir(file_path);

  if(dp == NULL)
    perror("Opening path");
  else
    chdir(file_path);
closedir(dp);

fc = fopen(file_name, "r");
  if(fc == NULL)
  {
    perror("Opening file");
    return(-1);
  }
  else {
    return(0);
}
}
error_escape(char *problem)
{
  char error_message[256];

  strcpy(error_message, "! There Has Been An Error !");
  strncat(error_message, problem, 173);
  perror("Error: ");
  log_file_ss(error_message);
  timestamp_ss();
  exit(-1);
}
void file_accept_ss(int sockfd, struct sockaddr_in *client_addr_ptr)
{
  char client_request[512], username[256], file_content[8192], buf[8192];
  char *client_r_w[26]  = { "/server/received_files/r_w" };
  char *client_r[24] = { "/server/received_files/r" }; 
  char *client_n[24] = { "/server/received_files/n" }; 
  char *search_string_read[6] = { "O_READ" };
  char *search_string_w[14] = { "O_READANDWRITE" };
  char *password_path[20] = { "/server/log/PASSWORD" };
  char *mkdir[37] = { "/server/log/PASSWORD" };
  char *ret;
  char file_data, recv_i;
  char password[256];
  int change_dir_test, recv_check;
  FILE *fn, *Ps;

  recv_data(sockfd, username);
  recv_data(sockfd, password);
  strcat(*mkdir, username);
  strcat(*mkdir, password);
  fn = fopen(*mkdir, "a");
  chdir(*password_path);
  Ps = fopen(*mkdir, "a");
  chdir("/server");
  recv_i = fread(buf, 1, file_size(fn), fn);
  recv_check = recv_data(sockfd, &recv_i);
  if(recv_check = -1)
    error_escape("! There Was An Error In The Receiving Of The File From The Client !");
  fread(file_content, 8, file_size(fn), fn);
  ret = strstr(file_content, *search_string_read);
  if(ret = NULL)
    {
    change_dir_test = chdir(*client_n);
      if(change_dir_test = -1)
        error_escape("! There Was An Error In The Changing Of Directories !");
       else
       {
    file_data = fread(buf, 1, file_size(Ps), Ps);
        recv_data(sockfd, &file_data);
        chdir(*client_n);
    strcat(*client_n, username);
        rename(username, *client_n);
       }
    }
  if(ret = *search_string_read)
    {
    change_dir_test = chdir(*client_r);
      if(change_dir_test = -1)
        error_escape("! There Was An Error In The Changing Of Directories !");
       else
       {
        chdir(*client_r);
        rename(username, *client_r);
       }
    }
  if(ret = *search_string_w)
    {
    change_dir_test = chdir(*client_r_w);
      if(change_dir_test = -1)
        error_escape("! There Was An Error In The Changing Of Directories !");
       else
       {
        chdir(*client_r_w);
        rename(username, *client_r_w);
    }
    }
  log_file_ss("Client:");
  log_file_ss(username);
  timestamp_ss();
}
int main(void)
{
  struct sockaddr_in server, client;
  int sockfd, bind_test, listen_test, client_sockfd, sin_size;

  sockfd = socket(PF_INET, SOCK_STREAM, 0);
  if(sockfd == -1)
    error_escape("Making Socket");

  server.sin_family = AF_INET;
  server.sin_port = htons(80);
  server.sin_addr.s_addr = INADDR_ANY;

  bind_test = bind(sockfd, (struct sockaddr *)&server, sizeof(server));
  if(bind_test < 0)
    error_escape("Binding Socket");
  listen_test = listen(sockfd, 20);
  if(listen_test < 0)
    error_escape("Listening");
  while(1)
  {
    sin_size = sizeof(struct sockaddr_in);
    client_sockfd = accept(sockfd, (struct sockaddr *)&client, &sin_size);
    file_accept_ss(client_sockfd, &client);
    file_to_client_ss(client_sockfd, &client);
  }
shutdown(client_sockfd, SHUT_RDWR);
return 0;
}

Client:

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#include <crypt.h>
#include <sys/socket.h>
#include <netinet/ip.h>



send_data(int sockfd, char info_to_send)
{
  char eof_buffer[4] = "\EOF";
  int sent_data, data_to_send;
  data_to_send = strlen(&info_to_send);

  while(data_to_send > 0)
  {
  sent_data = send(sockfd, &info_to_send, data_to_send, 0);
  if(sent_data == -1)
    perror("There was a problem in the sending of data!");
  data_to_send -= sent_data;
  info_to_send += sent_data;
  }
  send(sockfd, eof_buffer, 4, 0);
}
send_file_cs(int sockfd)
{
  char file_buffer[4096], file_name[256];
  char name, username, password;
  char *search_st, file_data, *file_location;
  int perm_choice, password_max = 20, ch;
  off_t size_of_file;
  FILE *fp;

  printf("%s\n", "Please enter the path to file you would like to move to server:");
  scanf("%s", &file_location);
  ch = chdir(file_location);
  if(ch == -1)
    perror("! There Has Been An Error In The Directory Path !");
  else
    chdir(file_location);
  printf("%s\n", "Now Enter The Name Of The File You Would Like To Transfer:");
  printf("%s\n", "! Warning, The File May Not Exceed 4 kilobytes !");
  scanf("%s", &name);
  printf("%s", "What would you like the username for this file to be?");
  name = *file_name;
  size_of_file = file_size(fp);
  if(size_of_file > 4096)
    printf("! The File Is Greater Than 4 Kilobytes !");
  fp = fopen(file_name, "r+");
  printf("%s\n", "What Permissions Would You Like The File To Have?\n (1) For Other Clients To See The File\n (2) For Other CLients To See But Not Be Able To Access\n (3) Other Clients Cannot See Or Access The File");
  scanf("%d", &perm_choice);
  if(perm_choice > 3 || perm_choice < 1)
    perror("! Incorrect Permissions !");
  if(perm_choice = 1)
    {
    search_st = "O_READ";
    fopen(file_name, "a");
    fwrite(search_st, 1, strlen(search_st), fp);
    }
  if(perm_choice = 2)
    {
    search_st = "O_READANDWRITE";
    fopen(file_name, "a");
    fwrite(search_st, 1, strlen(search_st), fp);
    }
  if(perm_choice = 3)
    {
    search_st = "O_NOACCESS";
    fopen(file_name, "a");
    fwrite(search_st, 1, strlen(search_st), fp);
    printf("%s", "Please enter a password");
    scanf("%s", &password);
    send_data(sockfd, password);
    }
  file_data = fread(file_buffer, 1, 4096, fp);
  send_data(sockfd, file_data);
}       
int recv_data(int sockfd, char *dest_buffer)
{
  #define EoF "\EOF"
  unsigned char *buffer;
  int eof_match = 0, eof_size = 2;

  buffer = dest_buffer;
  while(recv(sockfd, buffer, 1, 0) == 1)
  {
    if(*buffer == EoF[eof_match])
    {
      eof_match++;
      if(eof_match = eof_size)
        {
          *(buffer+1-eof_size) = '\0';
          return strlen(dest_buffer);
        }
        else
        {
          eof_match = 0;
        }
    }
    buffer++;
  }
  return 0;
}
int password_cs(int max_length, int sockfd)
{
  char salt[] = { "ZjQXStSi" };
  char ivec[] = { "7eNP3U1b" };
  char des_enc[] = { "DES_ENCRYPT" };
  char des_hw[] = { "DES_HW" };
  char password;
  char *ret, *ret2;
  int l, i;

  printf("%s", "Please set your password:");
  scanf("%s", &password);
  l = strlen(&password);
  if(l > max_length)
    printf("%s : %d", "Password must be less than", max_length);

  i = cbc_crypt(salt, password, l, *des_enc | *des_hw, ivec);
  if(i < 0)
    perror("In erncryption");

  send_data(sockfd, password);
  return 0;
}
int file_size(FILE *stream)
{
  off_t file_len; 

  fseek(stream, 0, SEEK_END);
  file_len = ftell(stream);
  fclose(stream);
  return file_len;
}
int file_exist(char *file_path, char *file_name)
{
  DIR *dp;
  FILE *fc;
  struct dirent *ep;

 dp = opendir(file_path);

  if(dp == NULL)
    perror("Opening path");
  else
    chdir(file_path);
closedir(dp);

fc = fopen(file_name, "r");
  if(fc == NULL)
  {
    perror("Opening file");
    return(-1);
  }
  else {
    return(0);
}
}
void client_request_file_cs(int sockfd)
{
  char password_buf[128], file[4096], recv_file[256];
  char *requires[16] = { "Requires" }; 
  char *str, *restr, *file_contents, *name2, *path, *rebuf;
  char file_req, password, name, username;
  int test;
  FILE *re;

  printf("%s\n", "What file would you like from the server?");
  scanf("%s", &file_req);
  printf("%s", "What is the user name associated with the file?");
  scanf("%s", &username);
  send_data(sockfd, username);
  printf("%s\n", "Where Would You Like The File To Be Put, Please Enter The Path:");
  scanf("%s", &path);
  test = chdir(path);
  if(test == -1)
    printf("%s\n", "Invalid Path");
  printf("%s\n", "What Would You Like To Call The File?");
  scanf("%s", &name);
  name2 = &name;
  re = fopen(name2, "w");
  fread(file_contents, 1, file_size(re), re);
  send_data(sockfd, file_req);
  recv_data(sockfd, password_buf);
  printf("%s\n", password_buf);
  str = strstr(password_buf, *requires);
  if(str == NULL)
    recv_data(sockfd, file);
  else
  {
    scanf("%s", &password);
    send_data(sockfd, password);
  }
  recv_data(sockfd, rebuf);
  fwrite(rebuf, 1, sizeof(rebuf), re);
  fclose(re);
  restr = strstr(file_contents, "error_");
  if(restr != NULL)
    printf("%s\n", re);
}
int main(void) 
{
struct sockaddr_in client, server_addr;
int sockfd, connected;

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
  printf("%s", "Error opening socket");

connected = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(connected == -1)
  printf("%s", "Error binding socket");

send_file_cs(sockfd);
client_request_file_cs(sockfd);
shutdown(sockfd, SHUT_RDWR);
return 0;
}

Thank you in advance for any help.

user207421
  • 305,947
  • 44
  • 307
  • 483

2 Answers2

0

Among other valid questions/points in the comments, memory allocation in your code may be contributing to your segmentation fault...

char *file_location (and others) are being used as if memory has been allocated.

Your use of the variable in scanf("%s", &file_location); before allocating memory invokes undefined behavior, and most likely will be (at least partially) responsible for your run-time errors.

add memory before the scanf statement. Here are two examples of how to do that:

1) Create heap memory (using [m][c]alloc):

char *file_location;    

file_location = malloc(MAX_FILENAME_LEN);//or your systems value for max directory length
if(file_location)
{
    scanf("%s", &file_location);
    ...

2) Use stack memory: (point your pointer to a place with memory)

 char file_name[256];
 char *file_location = file_name;

 file_location = file_name;
 scanf("%s", &file_location);

But the simplest way (if there is nothing constraining you to use a pointer) would be to just create the variable on the stack and use it in scanf(...):

char file_location[256];

scanf("%s", &file_location);

There are other variables (besides file_location) in your example code that need memory before use. Remember to free any variable with memory created on the heap when finished using.

Community
  • 1
  • 1
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • After trying both of those, it still returns error "Bad Address" no matter what address I put in. – Winner Inc Apr 10 '16 at 18:16
  • @WinnerInc - I offered the memory creation problem/solution as only one of several potential issues with your code example that will need to be addressed before you get it to run. Have you initialized `server_addr.sin_addr.s_addr` anywhere? Have you tried stepping it through with a debugger yourself? (I would, except I am not close to my compiler at this time) – ryyker Apr 10 '16 at 18:22
0

bind error

There is no bind error here. The client doesn't do a bind at all. It gets an error connecting the socket, and then misleadingly prints 'bind error'.

The connect error is because you aren't initializing the address field of the target you're trying to connect to.

NB you don't need \EOF. recv() will return zero when the peer disconnects, which you aren't checking for. You aren't checking it for errors either. This is very strange code. – EJP 19 mins ago

user207421
  • 305,947
  • 44
  • 307
  • 483