<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "router.h"
#include "datacontainer.h"
#include "memorymanager.h"
#include "diskfile.h" 
#include "client.h"
#include "og_enums.h" 

//PUBLIC METHODS
static int            executeOperation(client *this);
static int            getFiles(client *this);

//PRIVATE METHODS
static int            establishConnection(client *this);
static int            prepareFileRequestString(client *this);
static uint32_t       calculateFileRequestStringBytesize(client *this);
static int            sendRequestString(client *this);
static int            getIncomingFile(client *this, char* fileName);



/************ OBJECT CONSTRUCTOR ******************/

/*    
 * newClient returns a client object on success and NULL on failure, the client object is already connected to onionAddress on onionPort, and the file request string
 * is already constructed.  
 * 
 */
client *newClient(char *torBindAddress, char *torPort, char *onionAddress, char *onionPort, char *operation, char *dirPath, char **fileNames, uint32_t fileCount)
{
  client *this; 
  
  if(torBindAddress == NULL || torPort == NULL || onionAddress == NULL || onionPort == NULL || operation == NULL || dirPath == NULL || *fileNames == NULL){
    printf("Error: Something was NULL that shouldn't have been\n");
    return NULL; 
  }

  //allocate memory for the client object
  this = secureAllocate(sizeof(struct client));
  if(this == NULL){
   printf("Error: Failed to instantiate a client\n");
   return NULL; 
  }
 
  //initialize the client properties
  this->router           = newRouter();
  this->torBindAddress   = torBindAddress;
  this->torPort          = torPort;
  this->onionAddress     = onionAddress;
  this->onionPort        = onionPort;
  this->operation        = operation;
  this->dirPath          = dirPath;  
  this->fileNames        = fileNames; 
  this->fileCount        = fileCount; 
  
  
  //initialize the client public methods
  this->getFiles         = &getFiles;
  this->executeOperation = &executeOperation;

  
  //prepare the file request string
  if( !prepareFileRequestString(this) ){
    printf("Error: Failed to instantiate a client\n");
    return NULL; 
  }
     
     
  //connect client to the hidden service
  if( !establishConnection(this) ){
    printf("Error: Failed to instantiate a client\n");
    return NULL; 
  }
  

  return this; 
}





/************ PUBLIC METHODS ******************/


/*
 * executeOperation returns 0 on error and 1 on success, this decides what to do based on the operation property of the client object
 * right now the only possible operation is --get which gets files from the server
 */
static int executeOperation(client *this)
{
  if( this == NULL ){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0; 
  }
  
  //carry out the operation, if the operation isn't valid return 0 because it's an error (this is redundantly checked, also in controller.c) 
  if  (   !strcmp(this->operation, "--get")  ) return this->getFiles(this);
  else                                         return 0;  
}


/*
 * getFiles returns 0 on error and 1 on success, it sends the server the file request string, then goes through each file name 
 * and writes it to the disk with the data received from the server for that file name
 */
static int getFiles(client *this)
{
  int           currentFile;
  uint32_t      fileCount; 
  
  if( this == NULL ){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0;
  }
  
  //send the server the request string
  if( !sendRequestString(this) ){
    printf("Error: Failed to send server request string\n");
    return 0;
  }
    
  //get the files from the server
  for(fileCount = this->fileCount, currentFile = 0; fileCount--; currentFile++){ 
    if( !getIncomingFile(this, this->fileNames[currentFile]) ){
      printf("Error: Failed to get file\n");
      return 0; 
    }
  }
  
  return 1; 
}



/************* PRIVATE METHODS ****************/ 



/*
 * getIncomingFile returns NULL on error and a dataContainer with the received file on success
 */ 
static int getIncomingFile(client *this, char* fileName)
{
  dataContainer *incomingFileChunk;
  uint32_t      incomingFileBytesize;
  diskFile      *diskFile;
  uint64_t      bytesToGet; 
  
  
  if(this == NULL){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0; 
  }
  
  
  //first we open a new diskFile to write the file to
  diskFile = newDiskFile(this->dirPath, fileName, "w");
  if(diskFile == NULL){
    printf("Error: Failed to create file on disk, aborting\n");
    return 0;
  }
  
  

  //then the server sends us the incoming files bytesize
  incomingFileBytesize = this->router->getIncomingBytesize(this->router); 
  if(incomingFileBytesize == -1){
    printf("Error: Failed to get incoming file bytesize, aborting\n");
    return 0;
  }
  
   
  //next we get the incoming file from the server in incomingFileChunkBytesize chunks, until there are no more chunks
  
  for(bytesToGet = 0 ; incomingFileBytesize ; incomingFileBytesize -=  bytesToGet){
    
    //if the remainder of the file is less than or equal to FILE_CHUNK_BYTESIZE then get all of it. Otherwise get FILE_CHUNK_BYTESIZE of it
    if       ( incomingFileBytesize <= FILE_CHUNK_BYTESIZE ) bytesToGet = incomingFileBytesize;
    else if  ( incomingFileBytesize >  FILE_CHUNK_BYTESIZE ) bytesToGet = FILE_CHUNK_BYTESIZE % incomingFileBytesize;
        
    //get up to FILE_CHUNK_BYTESIZE bytes of the file
    incomingFileChunk = this->router->receive(this->router,  bytesToGet);
    if(incomingFileChunk == NULL){
      printf("Error: Failed to receive data, aborting\n");
      return 0; 
    }
        
    //then write it to the disk
    if( !diskFile->diskFileWrite(diskFile, incomingFileChunk) ){<commit_msg>we don't need to specify else if there because it's always else<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "router.h"
#include "datacontainer.h"
#include "memorymanager.h"
#include "diskfile.h" 
#include "client.h"
#include "og_enums.h" 

//PUBLIC METHODS
static int            executeOperation(client *this);
static int            getFiles(client *this);

//PRIVATE METHODS
static int            establishConnection(client *this);
static int            prepareFileRequestString(client *this);
static uint32_t       calculateFileRequestStringBytesize(client *this);
static int            sendRequestString(client *this);
static int            getIncomingFile(client *this, char* fileName);



/************ OBJECT CONSTRUCTOR ******************/

/*    
 * newClient returns a client object on success and NULL on failure, the client object is already connected to onionAddress on onionPort, and the file request string
 * is already constructed.  
 * 
 */
client *newClient(char *torBindAddress, char *torPort, char *onionAddress, char *onionPort, char *operation, char *dirPath, char **fileNames, uint32_t fileCount)
{
  client *this; 
  
  if(torBindAddress == NULL || torPort == NULL || onionAddress == NULL || onionPort == NULL || operation == NULL || dirPath == NULL || *fileNames == NULL){
    printf("Error: Something was NULL that shouldn't have been\n");
    return NULL; 
  }

  //allocate memory for the client object
  this = secureAllocate(sizeof(struct client));
  if(this == NULL){
   printf("Error: Failed to instantiate a client\n");
   return NULL; 
  }
 
  //initialize the client properties
  this->router           = newRouter();
  this->torBindAddress   = torBindAddress;
  this->torPort          = torPort;
  this->onionAddress     = onionAddress;
  this->onionPort        = onionPort;
  this->operation        = operation;
  this->dirPath          = dirPath;  
  this->fileNames        = fileNames; 
  this->fileCount        = fileCount; 
  
  
  //initialize the client public methods
  this->getFiles         = &getFiles;
  this->executeOperation = &executeOperation;

  
  //prepare the file request string
  if( !prepareFileRequestString(this) ){
    printf("Error: Failed to instantiate a client\n");
    return NULL; 
  }
     
     
  //connect client to the hidden service
  if( !establishConnection(this) ){
    printf("Error: Failed to instantiate a client\n");
    return NULL; 
  }
  

  return this; 
}





/************ PUBLIC METHODS ******************/


/*
 * executeOperation returns 0 on error and 1 on success, this decides what to do based on the operation property of the client object
 * right now the only possible operation is --get which gets files from the server
 */
static int executeOperation(client *this)
{
  if( this == NULL ){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0; 
  }
  
  //carry out the operation, if the operation isn't valid return 0 because it's an error (this is redundantly checked, also in controller.c) 
  if  (   !strcmp(this->operation, "--get")  ) return this->getFiles(this);
  else                                         return 0;  
}


/*
 * getFiles returns 0 on error and 1 on success, it sends the server the file request string, then goes through each file name 
 * and writes it to the disk with the data received from the server for that file name
 */
static int getFiles(client *this)
{
  int           currentFile;
  uint32_t      fileCount; 
  
  if( this == NULL ){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0;
  }
  
  //send the server the request string
  if( !sendRequestString(this) ){
    printf("Error: Failed to send server request string\n");
    return 0;
  }
    
  //get the files from the server
  for(fileCount = this->fileCount, currentFile = 0; fileCount--; currentFile++){ 
    if( !getIncomingFile(this, this->fileNames[currentFile]) ){
      printf("Error: Failed to get file\n");
      return 0; 
    }
  }
  
  return 1; 
}



/************* PRIVATE METHODS ****************/ 



/*
 * getIncomingFile returns NULL on error and a dataContainer with the received file on success
 */ 
static int getIncomingFile(client *this, char* fileName)
{
  dataContainer *incomingFileChunk;
  uint32_t      incomingFileBytesize;
  diskFile      *diskFile;
  uint64_t      bytesToGet; 
  
  
  if(this == NULL){
    printf("Error: Something was NULL that shouldn't have been\n");
    return 0; 
  }
  
  
  //first we open a new diskFile to write the file to
  diskFile = newDiskFile(this->dirPath, fileName, "w");
  if(diskFile == NULL){
    printf("Error: Failed to create file on disk, aborting\n");
    return 0;
  }
  
  

  //then the server sends us the incoming files bytesize
  incomingFileBytesize = this->router->getIncomingBytesize(this->router); 
  if(incomingFileBytesize == -1){
    printf("Error: Failed to get incoming file bytesize, aborting\n");
    return 0;
  }
  
   
  //next we get the incoming file from the server in incomingFileChunkBytesize chunks, until there are no more chunks
  
  for(bytesToGet = 0 ; incomingFileBytesize ; incomingFileBytesize -=  bytesToGet){
    
    //if the remainder of the file is less than or equal to FILE_CHUNK_BYTESIZE then get all of it. Otherwise get FILE_CHUNK_BYTESIZE of it
    if       ( incomingFileBytesize <= FILE_CHUNK_BYTESIZE ) bytesToGet = incomingFileBytesize;
    else                                                     bytesToGet = FILE_CHUNK_BYTESIZE % incomingFileBytesize; 
        
    //get up to FILE_CHUNK_BYTESIZE bytes of the file
    incomingFileChunk = this->router->receive(this->router,  bytesToGet);
    if(incomingFileChunk == NULL){
      printf("Error: Failed to receive data, aborting\n");
      return 0; 
    }
        
    //then write it to the disk
    if( !diskFile->diskFileWrite(diskFile, incomingFileChunk) ){
{'fraction_non_alphanumeric': 0.1089727357136828, 'fraction_numerical': 0.004726935089052081, 'mean_word_length': 3.0340483486550904, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1496092', 'n_tokens_mistral': 3564, 'n_tokens_neox': 3376, 'n_words': 1166}