user2904415
user2904415

Reputation: 11

segmentation fault on end of function

below you can find my full code (yes, I've changed this to make it buildeable for tests and short)

It basically has to read file /var/log/messages and write on teste.txt only the IP addresses it finds It works well, but it never print the "parte 8\n" after run the function (check function main()) It always run the code well, print everything, except what has after function

#include <stdio.h>
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h> // htons e inet_addr
#ifndef __FAVOR_BSD
#   define __FAVOR_BSD
#endif
#include <netinet/udp.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>

#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <stdlib.h>
#include <string.h> 
#include <arpa/inet.h>

#define RANDOM() (int) random() % 255 +1

char * RetornaStringEntreStrings( char * primString, char * segString, char * stringao)
{
    char * posPrim = strstr(stringao, primString);
    if(posPrim <= 0)
    {
        return "";
    }
    posPrim += strlen(primString);

    char * posSeg = strstr(posPrim, segString);

    char * retorno;
    memcpy(retorno, posPrim, posSeg-posPrim);
    retorno[posSeg-posPrim] = 0;
    return retorno;
}

int ExisteIPnoArquivo(char *ip, char *arquivoNome)
{
    FILE *arquivo = fopen(arquivoNome, "r");
    char buffer[128];

    if(arquivo != NULL)
    {
        while(fgets(buffer, 128, arquivo))
        {
            if(strcmp(ip, buffer) == 0)
            {
                fclose(arquivo);
                return 1;
            }
        }
        fclose(arquivo); 
        return 0;
    }
    else
        printf("Nao foi possivel abrir o arquivo.\n");

    return 0;
}

void EscreverArquivo(char * string, char * arquivoNome)
{
    FILE *arquivo = fopen(arquivoNome, "a+");

    if(arquivo == NULL)
    {
        printf("Erro na abertura do arquivo!");
    }
    else
    {
        fprintf(arquivo, "%s", string);
        fclose(arquivo);
    }
}

void SalvarLogsArquivo(char * arquivoNome)
{
    FILE *arquivo = fopen("/var/log/messages", "r");
    char buffer[512];

    // testa se o arquivo foi aberto com sucesso
    if(arquivo != NULL)
    {
        while(fgets(buffer, 512, arquivo))
        {
            char * IP = RetornaStringEntreStrings("SRC=", " ", buffer);
            if(strlen(IP) < 7)
                continue;

            strcat(IP, "\n");
            if(ExisteIPnoArquivo(IP, arquivoNome) == 0)
            {
                printf("Adicionando IP: %s", IP);
                EscreverArquivo(IP, arquivoNome);
            }
            else
                printf("IP ja encontrado: %s", IP);
        }
        fclose(arquivo); // libera o ponteiro para o arquivo
    }
    else
        printf("Nao foi possivel abrir o arquivo.");

    printf("End of Function (segmentation fault below will happen below)\n");
}


int main() 
{
    SalvarLogsArquivo("teste.txt");
    printf("After function, it doesn't run cuz it gets segmentation fault before\n");
}

Upvotes: 0

Views: 515

Answers (2)

Bernhard
Bernhard

Reputation: 364

In your function RetornaStringEntreStrings() you copy data to an uninitialized pointer which might segfault (in general it's undefined behavior):

 char * retorno;
 memcpy(retorno, posPrim, posSeg-posPrim);

Upvotes: 2

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

This is the cause

char * retorno;
memcpy(retorno, posPrim, posSeg-posPrim);

You didn't allocate memory for retorno, you need to with malloc(). Example

retorno = malloc(posSeg - posPrim + 1);
if (retorno != NULL)
{
    memcpy(retorno, posPrim, posSeg - posPrim);
    retorno[posSeg - posPrim] - '\0';
}

Upvotes: 4

Related Questions