#include #include #include #include "web.h" struct OptStruct options; /* must be declared somewhere! */ /* ResolveRelative: takes a current directory, and a relative reference, and stores the location of the target filename in 'buf'. Note that a '/' at the start of the path is implicit, and is not included in the result, and should not be included in the input paths (although the reference may start with a '/' to indicate that it is not relative). */ void ResolveRelative(const char * path, const char * ref, char * buf) { char * pPathEnd; const char * iRef; if (*ref == '/') /* not a relative path! */ { strcpy(buf, ref+1); /* we don't want a '/' at the start! */ return; } if (*path == '/') strcpy(buf, path+1); else strcpy(buf, path); for (pPathEnd = buf; *pPathEnd; pPathEnd++) ; /* find end of string */ pPathEnd --; /* make it point to the '/' */ /* process the path, stripping out './', removing one step on '../', and * adding anything else into the buffer. */ iRef = ref; while (*iRef) { pPathEnd[1] = '\0'; if (* iRef == '/') /* skip over it */ { /* '/'s should only be added at end */ iRef ++; /* of a section of path name */ continue; } if (! strncmp(iRef, "./", 2)) /* skip './'s! */ { iRef += 2; continue; } if (! strncmp(iRef, "../", 3)) /* process '../'s! */ { iRef += 3; if (pPathEnd < buf) continue; /* at top already! */ pPathEnd --; /* skip over one '/' */ while (pPathEnd >= buf && *pPathEnd != '/') pPathEnd --; continue; } /* if we get to here, we have to add an element onto the end of the string. */ pPathEnd++; while (*iRef && *iRef != '/') { *pPathEnd = *iRef; pPathEnd++, iRef++; } *pPathEnd = *iRef; if (*iRef) iRef ++; } if (* pPathEnd) /* string not terminated */ { pPathEnd ++; *pPathEnd = (char)0; } } /* GetDirectory - takes a path name and stores in 'buf' the directory name, that is everything up to (and including) the final '/'. */ void GetDirectory (const char *path, char * buf) { char * i, * last; const char * s; s = path; i = buf; last = buf; /* last stores location after last '/' */ while (*s) { *i = *s; if (*s == '/') last = i + 1; i++, s++; } *last = (char)0; /* terminate string after last '/' */ } /* int main(int argc, char ** argv) { char dir [256], result [256]; GetDirectory(argv[1], dir); ResolveRelative(dir,argv[2], result); printf("[%s] [%s]\n", dir, result); return 0; } */ /* CreateFile - creates a file, opening it for writing. If any directories in its name don't exist they are created. If the file already exists, or couldn't be created, it returns NULL. The filename argument may contain directory names, even though the path argument exists - this is simply for convenience. */ FILE * CreateFile (const char * path, const char * host, int port, const char *filename, int bOverwrite) { char name [256]; FILE * tmpf; get_filename(path, host, port, filename, name, 1); if (! bOverwrite) /* check for existance, and don't overwrite...! */ { tmpf = fopen(name, "r"); if (tmpf) /* file exists */ { fclose(tmpf); return NULL; } } if (options.bVerbose >= 4) printf("Creating file: %s\n", name); return fopen(name, "w+"); } int file_exists (const char * path, const char * host, int port, const char *filename) { char name [256]; FILE * tmpf; get_filename(path, host, port, filename, name, 0); tmpf = fopen(name, "r"); if (tmpf) /* file exists */ { fclose(tmpf); return 1; } return 0; } /* test program for the whole lot! int main(int argc, char **argv) { char dir[256], file[256]; FILE * f; if (argc == 1) { puts("Usage: testcreate "); return 1; } GetDirectory(argv[2], dir); ResolveRelative(dir,argv[3],file); f = CreateFile(argv[1], file); if (! f) { puts("Create failed"); return 1; } fclose(f); return 0; } */ void get_filename(const char * path, const char * host, int port, const char *filename, char * name, int create_dirs) { char buf [256], * i, *f; int n; strcpy (name, pszServerRoot); /* make sure there is a '/' between server root and path */ n = strlen(name); if (n && name[n-1] != '/' && path[0] != '/') { strcat (name,"/"); } strcat (name, path); /* make sure there is a '/' between path and filename! */ n = strlen(name); if (n && name[n-1] != '/' && filename[0] != '/') { strcat (name,"/"); } strcat(name, host); sprintf(buf, ":%d/", port); strcat(name, buf); strcat(name, filename); i = buf; f = name; while (* f) { if (create_dirs && *f == '/') /* directory part of path name */ { /* make sure path up to this location is created */ *i = '\0'; if (options.bVerbose >= 4) printf("Making dir: %s\n", buf); mkdir (buf, 0755); } *i = *f; i++, f++; } if (strlen(name) == 0 || name[strlen(name)-1] == '/') { strcat(name, DEFAULT_FILENAME); } }