0

I have never used stat() before and am not sure what is going wrong.

I have a server program that takes a GET request and parses out the file path. I also have a client program in the same directory that sends the GET request. The server program is taking the GET request and parsing out the file path correctly. The path to the directory where both programs are is: ~/asimes2/hw2/

If I have the client program send: GET /Makefile HTTP/1.0\r\n\r\n

Then the server program receives the same thing. I have two printf()s to confirm I am parsing the file path correctly and to see the full path. It outputs:

File path = '/Makefile'
Full path = '~/asimes2/hw2/Makefile'
NOT FOUND!

Makefile does exist in ~/asimes/hw2. Here is the code:

// Alex: Parse the PATH from the GET request using httpGet
char* filePath, * pathStart = strchr(httpGet, '/');
if (pathStart != NULL) {
    // Alex: Increment to the first '/'
    httpGet += (int)(pathStart-httpGet);

    // Alex: Assuming " HTTP" is not a part of the PATH, this finds the end of the PATH
    char* pathEnd = strstr(httpGet, " HTTP");
    if (pathEnd != NULL) {
        int endLoc = (int)(pathEnd-httpGet);
        filePath = (char*)malloc((endLoc+1)*sizeof(char));
        strncpy(filePath, httpGet, endLoc);
        filePath[endLoc] = '\0';
    }
    else errorMessageExit("The GET request was not formatted as expected");
}
else errorMessageExit("The GET request was not formatted as expected");
printf("File path = '%s'\n", filePath);

char* fullPath = (char*)malloc((14+strlen(filePath))*sizeof(char));
strcpy(fullPath, "~/asimes2/hw2");
strcat(fullPath, filePath);
printf("Full path = '%s'\n", fullPath);

struct stat fileStat;
if (stat(fullPath, &fileStat) == -1) printf("NOT FOUND!\n");
else printf("HOORAY\n");
asimes
  • 5,749
  • 5
  • 39
  • 76

2 Answers2

3

My answer only addresses your issue with the file name.

The shell interprets this: ~/asimes2/hw2/Makefile

It's not a valid filename to pass to stat() with the ~

You should be able replace the leading ~ with something link /home/ or wherever the actual home directory is.

Try this:

char* fullPath = malloc((80+strlen(filePath))*sizeof(char));
strcpy(fullPath, "/home/ubuntu/asimes2/hw2");
strcat(fullPath, filePath);
printf("Full path = '%s'\n", fullPath);
dcaswell
  • 3,137
  • 2
  • 26
  • 25
  • I tried `/asimes2/hw2/Makefile` and `asimes2/hw2/Makefile` but neither works – asimes Sep 09 '13 at 05:21
  • Where is the makefile, and what is the exact value of fullpath? – dcaswell Sep 09 '13 at 05:22
  • Result of `ls` in the directory: `ubuntu@ip-10-171-4-112:~/asimes2/hw2$ ls hw2 hw2.c Makefile testClient testClient.c WWW` – asimes Sep 09 '13 at 05:23
  • When you type `echo ~` what is displayed. – dcaswell Sep 09 '13 at 05:26
  • So set fullpath to /home/ubuntu/asimes2/hw2/makefile. First test it and make sure that that returns the file. And obviously fullpath needs to be much larger than 14+strlen(filePath)) – dcaswell Sep 09 '13 at 05:27
2

You need to glob pathnames, see glob(7). You could perhaps use wordexp(3) to expand the ~, $ etc...

HTTP servers usually have some configurable document root, perhaps /var/www. Then the URL pathname /Makefile is transformed to /var/www/Makefile

You should perhaps use some HTTP server library like libonion

And you should use errno at least for debugging purposes on syscall failure, so code

  if (stat(fullPath, &fileStat) == -1) 
      printf("%s NOT FOUND! %s\n", fullPath, strerror(errno));

Perhaps chroot(2) might interest you. And read Advanced Linux Programming!

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thank you, I ended up following along user814064's explanation, same idea (my full path was incorrect). The idea is to make all of these things ourselves, it is for a class – asimes Sep 09 '13 at 05:31
  • I don't know Windows, I never used it, never coded for it (and I'm coding since 1975) and don't know its API. – Basile Starynkevitch Sep 09 '13 at 05:33