// File: Cristian-Castillo[P]Multithreaded-HTTP-Server/./httpserver_definitions.cpp
// Function: f_void_put_module(char*, char*, int)
void *f_void_put_module(char *buffer,char *file_name,int clientSocket){

            struct http_node *child, content_len_mem;
            struct http_object *http_ptr,http_mem_location;
            http_ptr = &http_mem_location;
            child = &content_len_mem;
            http_ptr->file_name = file_name;
            http_ptr->client_connect = clientSocket;
            http_ptr->buffer = buffer;
            http_ptr->master_key = lock_put;

            int content_length;
            char *char_parse_content = strtok(buffer,"\n");
          
            while(char_parse_content != NULL){
                 sscanf(char_parse_content,"Content-Length: %d",&content_length);
                 char_parse_content = strtok (NULL, "\n");
            }
            free(&char_parse_content);

            /* Redundency */
            if(Redundency == 1){
                f_make_copy(file_name, content_length, clientSocket);
                return NULL;
            }

            http_ptr->content_length = content_length;

            /* Reset the buffer so that child procees may reuse */
            memset(http_ptr->buffer,'\0',HEADER_BUFFER); 
            
            http_ptr->key_fd = open(http_ptr->file_name,O_CREAT | O_WRONLY | O_TRUNC,0664);

            if(http_ptr->key_fd == -1 ){
                pthread_mutex_lock(&http_ptr->master_key);
                {
                    f_void_client_error_not_found(http_ptr->client_connect);return NULL;
                    close(http_ptr->key_fd);
                }
                pthread_mutex_unlock(&http_ptr->master_key);
                return NULL;
            }

            /* ---------------------------- Content Length = 0 ------------------------------------------- */

            if(http_ptr->content_length == 0){ 

                pthread_mutex_lock(&http_ptr->master_key);
                {
                    f_client_req_created(http_ptr->client_connect);
                    close(http_ptr->key_fd); return NULL;
                }
                pthread_mutex_unlock(&http_ptr->master_key);
            }
 
            if(http_ptr->content_length > 0){
         
            /* ---------------------------- Content Length = n -------------------------------------------- */
           
                char *buff = (char*)malloc(http_ptr->content_length*sizeof(char*));
             
                pthread_mutex_lock(&http_ptr->master_key);
                {
                        http_ptr->write_bytes = 0;
                        while((http_ptr->recv_bytes = read(http_ptr->client_connect,buff,http_ptr->content_length)) >= 0){
                            http_ptr->write_bytes += write(http_ptr->key_fd,buff,http_ptr->recv_bytes);
                            if(http_ptr->write_bytes == http_ptr->content_length)break;
                        }
                }
                pthread_mutex_unlock(&http_ptr->master_key);

                if(http_ptr->write_bytes == http_ptr->content_length){
                    
                    pthread_mutex_lock(&http_ptr->master_key);
                    {
                        f_client_req_created(http_ptr->client_connect);
                        free(buff);
                        close(http_ptr->key_fd);
                    }
                    pthread_mutex_unlock(&http_ptr->master_key);
                    return NULL;
                }
                else{

                    pthread_mutex_lock(&http_ptr->master_key);
                    {
                        f_void_intr_error(clientSocket);
                        free(buff);
                        close(http_ptr->key_fd);
                    }
                    pthread_mutex_unlock(&http_ptr->master_key);
                    return NULL;
                }
            }
            /*------------------------- Content Length = ? -> Assume 16 Kib allottted Buffer ---------------------------------*/
            else{ 

                char *buff = (char*)malloc(THREAD_BUFFER*sizeof(char*));
                
                 pthread_mutex_lock(&http_ptr->master_key);
                {
                        http_ptr->write_bytes = 0;

                        while((http_ptr->recv_bytes = read(http_ptr->client_connect,buff,THREAD_BUFFER)) >= 0){
                            http_ptr->write_bytes += write(http_ptr->key_fd,buff,http_ptr->recv_bytes);
                            if(http_ptr->write_bytes == http_ptr->recv_bytes)break;
                        }
                }
                pthread_mutex_unlock(&http_ptr->master_key);

                if(http_ptr->write_bytes == http_ptr->recv_bytes){
                    
                    pthread_mutex_lock(&http_ptr->master_key);
                    {
                        f_client_req_created(http_ptr->client_connect);
                        free(buff);
                        close(http_ptr->key_fd);
                    }
                    pthread_mutex_unlock(&http_ptr->master_key);
                    return NULL;
                }
                else{

                    pthread_mutex_lock(&http_ptr->master_key);
                    {
                        f_void_intr_error(clientSocket);
                        free(buff);
                        close(http_ptr->key_fd);
                    }
                    pthread_mutex_unlock(&http_ptr->master_key);
                    return NULL;
                }
            }
            return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x8d80
leaq -0xb8(%rbp), %rax
movq %rax, -0x38(%rbp)
leaq -0x2c(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movl -0x1c(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
leaq 0x48013(%rip), %rsi     # 0x4f8c8
movl $0x28, %edx
callq 0x53e0
movq -0x10(%rbp), %rdi
leaq 0x2dd2b(%rip), %rsi     # 0x355f5
callq 0x5740
movq %rax, -0xc8(%rbp)
cmpq $0x0, -0xc8(%rbp)
je 0x7915
movq -0xc8(%rbp), %rdi
leaq 0x2dfac(%rip), %rsi     # 0x3589a
leaq -0xbc(%rbp), %rdx
movb $0x0, %al
callq 0x5460
xorl %eax, %eax
movl %eax, %edi
leaq 0x2dcee(%rip), %rsi     # 0x355f5
callq 0x5740
movq %rax, -0xc8(%rbp)
jmp 0x78d6
leaq -0xc8(%rbp), %rdi
callq 0x5560
cmpl $0x1, 0x48088(%rip)     # 0x4f9b0
jne 0x7949
movq -0x18(%rbp), %rdi
movl -0xbc(%rbp), %esi
movl -0x1c(%rbp), %edx
callq 0x69e0
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movl -0xbc(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x34(%rax)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
xorl %esi, %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x5260
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1b4, %edx            # imm = 0x1B4
movb $0x0, %al
callq 0x5380
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x38(%rbp), %rax
cmpl $-0x1, 0x2c(%rax)
jne 0x79bb
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
callq 0x6470
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movq -0x38(%rbp), %rax
cmpl $0x0, 0x34(%rax)
jne 0x79f7
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
callq 0x68a0
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
callq 0x58b0
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movq -0x38(%rbp), %rax
cmpl $0x0, 0x34(%rax)
jle 0x7b56
movq -0x38(%rbp), %rax
movslq 0x34(%rax), %rdi
shlq $0x3, %rdi
callq 0x5640
movq %rax, -0xd0(%rbp)
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
movq -0xd0(%rbp), %rsi
movq -0x38(%rbp), %rax
movslq 0x34(%rax), %rdx
callq 0x56b0
movq -0x38(%rbp), %rcx
movq %rax, 0x48(%rcx)
cmpq $0x0, %rax
jl 0x7aa2
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
movq -0xd0(%rbp), %rsi
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rdx
callq 0x5170
movq %rax, %rcx
movq -0x38(%rbp), %rax
addq 0x40(%rax), %rcx
movq %rcx, 0x40(%rax)
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x38(%rbp), %rcx
movslq 0x34(%rcx), %rcx
cmpq %rcx, %rax
jne 0x7aa0
jmp 0x7aa2
jmp 0x7a36
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x38(%rbp), %rcx
movslq 0x34(%rcx), %rcx
cmpq %rcx, %rax
jne 0x7b0f
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
callq 0x68a0
movq -0xd0(%rbp), %rdi
callq 0x5560
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
callq 0x58b0
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movl -0x1c(%rbp), %edi
callq 0x64a0
movq -0xd0(%rbp), %rdi
callq 0x5560
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
callq 0x58b0
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movl $0x20000, %edi          # imm = 0x20000
callq 0x5640
movq %rax, -0xd8(%rbp)
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
movq -0xd8(%rbp), %rsi
movl $0x4000, %edx           # imm = 0x4000
callq 0x56b0
movq -0x38(%rbp), %rcx
movq %rax, 0x48(%rcx)
cmpq $0x0, %rax
jl 0x7be6
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
movq -0xd8(%rbp), %rsi
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rdx
callq 0x5170
movq %rax, %rcx
movq -0x38(%rbp), %rax
addq 0x40(%rax), %rcx
movq %rcx, 0x40(%rax)
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x38(%rbp), %rcx
cmpq 0x48(%rcx), %rax
jne 0x7be4
jmp 0x7be6
jmp 0x7b80
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x38(%rbp), %rcx
cmpq 0x48(%rcx), %rax
jne 0x7c4d
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edi
callq 0x68a0
movq -0xd8(%rbp), %rdi
callq 0x5560
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
callq 0x58b0
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq $0x0, -0x8(%rbp)
jmp 0x7c8f
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x56d0
movl -0x1c(%rbp), %edi
callq 0x64a0
movq -0xd8(%rbp), %rdi
callq 0x5560
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %edi
callq 0x58b0
movq -0x38(%rbp), %rdi
addq $0x58, %rdi
callq 0x53b0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)