1

So I posted my code below (sorry, I know it is long), but I'm getting a segmentation fault when I try to do any operation using the tm struct. I have no idea why I'm getting this seg fault, I'm pretty sure I had it working before, but now I just can't get it to work. If anyone has any idea how to get rid of the seg fault that would be wonderful. The seg fault comes in the first of the nested if statements towards the lower middle of the block of code, its after the long block of if-else's.

Thanks so much!

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <assert.h>


int main(){

int sockfd, clifd, status, monthModifiedi, newer;
struct sockaddr_in addr;
//char buf[1024] = "HEAD httpserver.c HTTP/1.1\nHost: www.reddit.com";
char buf[1024];
struct stat statBuf;
char *message, *filePath, *domain, *monthModified, *dayModified, *hourModified, *minuteModified, *secondModified, *yearModified;
FILE *pFile;
struct tm *tm;
time_t time;

//instantiate
strcpy(buf,"HEAD /httpserver.c HTTP/1.1\nHost: www.reddit.com\nIf-Modified-Since: Thu Mar 28 02:20:08 2013");

printf("%s\n\n", buf);

//parse buffer
message = strtok(buf, " ");
filePath = strtok(NULL, " ");
domain = strtok(NULL, "\n");
domain = strtok(NULL, " "); //domain will be overwritten with actual doman, this is filler
domain = strtok(NULL, " \n");
monthModified = strtok(NULL, " ");

printf("%s\n", filePath);
if(stat(filePath, &statBuf) == 0){
    tm = localtime(&statBuf.st_mtime);
    //time = &statBuf.st_mtime;
}

//newer will keep this value of 2 if there is no conditional GET request
newer = 2;

//If it is a conditional GET request
if(strcmp(monthModified, "If-Modified-Since:") == 0){

    monthModified = strtok(NULL, " ");
    monthModified = strtok(NULL, " ");
  dayModified = strtok(NULL, " ");
  hourModified = strtok(NULL, " :");
  minuteModified = strtok(NULL,":");
  secondModified = strtok(NULL,": ");
  yearModified = strtok(NULL, " ");

    //Turns string version of month to numeric value
    if(strcmp(monthModified,"Jan") ==0)
        monthModifiedi = 1;
    else if(strcmp(monthModified,"Feb")==0)
        monthModifiedi = 2;
    else if(strcmp(monthModified,"Mar") ==0)
        monthModifiedi = 3;
    else if(strcmp(monthModified,"Apr") ==0)
        monthModifiedi = 4;
    else if(strcmp(monthModified,"May") ==0)
        monthModifiedi = 5;
    else if(strcmp(monthModified,"Jun") ==0)
        monthModifiedi = 6;
    else if(strcmp(monthModified,"Jul") ==0)
        monthModifiedi = 7;
    else if(strcmp(monthModified,"Aug") ==0)
        monthModifiedi = 8;
    else if(strcmp(monthModified, "Sep") ==0)
        monthModifiedi = 9;
    else if(strcmp(monthModified,"Oct") ==0)
        monthModifiedi = 10;
    else if(strcmp(monthModified, "Nov") ==0)
        monthModifiedi = 11;
    else if(strcmp(monthModified,"Dec") ==0)
        monthModifiedi = 12;

    //Determines if file has been modified since date requested from client
    newer = 0;
    if(atoi(yearModified) > (*tm).tm_year)
        if(monthModifiedi > (*tm).tm_mon)
            if(atoi(dayModified) > (*tm).tm_mday)
                if(atoi(hourModified) > (*tm).tm_hour)
                    if(atoi(minuteModified) > (*tm).tm_min)
                        if(atoi(secondModified) > (*tm).tm_sec)
                            newer = 1;
}

printf("Value of newer: %i", newer);
printf("Message: %s Filename: %s Domain: %s monthModified: %i dayModified: %s hourModified: %s minuteModified: %s secondModified: %s yearModified: %s\n", message, filePath, domain, monthModifiedi, dayModified, hourModified, minuteModified, secondModified, yearModified);

if(message == "GET"){
    if ((pFile = fopen(filePath, "w")) == NULL){
        message = "HTTP/1.1 404 Not Found\n\r";
        send(clifd, message, strlen(message), 0);
    }
    // If not conditinal request, or if file has been modified
    else if(newer == 2 || newer == 1){
        message = "HTTP/1.1 200 OK\n\r", pFile;
        send(clifd, message, strlen(message), 0);
    }
    // If file has not been modified
    else{
        message = "HTTP/1.1 304 Not Modified\n\r";
        send(clifd, message, strlen(message),0);
    }
}
else if(message == "HEAD"){
    if ((pFile = fopen(filePath, "w")) == NULL){
        message = "HTTP/1.1 404 Not Found\n\r";
        send(clifd, message, strlen(message), 0);
    }
    else{
        message = "HTTP/1.1 200 OK\n\r";
        send(clifd, message, strlen(message), 0);
    }
}

return 0;
}
intA
  • 2,513
  • 12
  • 41
  • 66

2 Answers2

1

What's the return value of stat?

if(stat(filePath, &statBuf) == 0){
    tm = localtime(&statBuf.st_mtime);
    //time = &statBuf.st_mtime;
}

You only initialize tm if stat is successful but if it was not you access it anyway without checking.

Dave Rager
  • 8,002
  • 3
  • 33
  • 52
1

The problem is not with tm itself, but with the filePath. Most likely you don't have a file in the root directory named /httpserver.c. This causes the assignment

tm = localtime(&statBuf.st_mtime);

to be skipped and tm points to arbitrary memory.

From the string, I guess this should be a HTTP HEAD request. To test for the correct file, you must prepend the document root to the name of the requested URI.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • You can protect against this (obviously) by taking appropriate action if the file is not found, but also by initializing tm to NULL when it's declared. That way you will at least get predictable results in case of a failure. – Hew Wolff Apr 10 '13 at 23:31
  • But I do. If I remove the leading slash then it would be looking in the same directory this code is in, correct? I removed the slash and there is a file httpserver.c in the directory. Still nothing – intA Apr 10 '13 at 23:38
  • @Skytbest When you remove the leading slash, `stat` looks in the current directory of the process, not in the directory of the source. You can put a debug print statement in the `if` branch, to see whether it does the assignment or skips it. – Olaf Dietsche Apr 10 '13 at 23:43