ben 98/05/02 16:25:48
Modified: src/main http_core.c http_request.c src/os/win32 util_win32.c Log: Deal with UNCs vaguely correctly on Win32. Revision Changes Path 1.189 +1 -0 apache-1.3/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_core.c,v retrieving revision 1.188 retrieving revision 1.189 diff -u -r1.188 -r1.189 --- http_core.c 1998/04/29 06:32:09 1.188 +++ http_core.c 1998/05/02 23:25:46 1.189 @@ -710,6 +710,7 @@ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); if (err != NULL) return err; + arg=ap_os_canonical_filename (cmd->pool, arg); if (!ap_is_directory (arg)) { if (cmd->server->is_virtual) { fprintf (stderr, "Warning: DocumentRoot [%s] does not exist\n", arg); 1.121 +3 -3 apache-1.3/src/main/http_request.c Index: http_request.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_request.c,v retrieving revision 1.120 retrieving revision 1.121 diff -u -r1.120 -r1.121 --- http_request.c 1998/05/02 18:44:06 1.120 +++ http_request.c 1998/05/02 23:25:46 1.121 @@ -188,20 +188,20 @@ #ifdef WIN32 /* If the path is x:/, then convert it to x:/., coz that's what stat needs to work properly */ - if(strlen(path) == 3) - { + if(strlen(path) == 3 && path[1] == ':') { strcpy(buf,path); buf[3]='.'; buf[4]='\0'; path=buf; end=buf+4; - } + } #endif /* Advance over trailing slashes ... NOT part of filename */ for (cp = end; cp > path && cp[-1] == '/'; --cp) continue; + while (cp > path) { 1.15 +56 -3 apache-1.3/src/os/win32/util_win32.c Index: util_win32.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/os/win32/util_win32.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- util_win32.c 1998/05/02 18:44:07 1.14 +++ util_win32.c 1998/05/02 23:25:48 1.15 @@ -17,6 +17,13 @@ assert(n); assert(n < sizeof buf); + /* If we have \\machine\share, convert to \\machine\share\ */ + if (buf[0] == '\\' && buf[1] == '\\') { + char *s=strchr(buf+2,'\\'); + if(s && !strchr(s+1,'\\')) + strcat(s+1,"\\"); + } + if (!strchr(buf, '*') && !strchr(buf, '?')) { h = FindFirstFile(buf, &d); if(h != INVALID_HANDLE_VALUE) @@ -28,7 +35,19 @@ if (szFilePart < buf+3) { strcpy(szCanon, buf); - szCanon[2] = '/'; + if(szCanon[0] != '\\') { /* a \ at the start means it is UNC, otherwise it is x: */ + assert(isalpha(szCanon[0])); + assert(szCanon[1] == ':'); + szCanon[2] = '/'; + } + else { + char *s; + + assert(szCanon[1] == '\\'); + for(s=szCanon ; *s ; ++s) + if(*s == '\\') + *s='/'; + } return; } if (szFilePart != buf+3) { @@ -54,11 +73,22 @@ } } +/* UNC requires backslashes, hence the conversion before canonicalisation. Not sure how + * many backslashes (could be that \\machine\share\some/path/is/ok for example). For now, do + * them all. + */ API_EXPORT(char *) ap_os_canonical_filename(pool *pPool, const char *szFile) { char buf[HUGE_STRING_LEN]; + char b2[HUGE_STRING_LEN]; + char *s; - sub_canonical_filename(buf, szFile); + strcpy(b2,szFile); + for(s=b2 ; *s ; ++s) + if(*s == '/') + *s='\\'; + + sub_canonical_filename(buf, b2); buf[0]=tolower(buf[0]); if (*szFile && szFile[strlen(szFile)-1] == '/' && buf[strlen(buf)-1] != '/') @@ -68,13 +98,36 @@ } /* Win95 doesn't like trailing /s. NT and Unix don't mind. This works - * around the problem + * around the problem. + * Errr... except if it is UNC and we are referring to the root of the UNC, we MUST have + * a trailing \ and we can't use /s. Jeez. Not sure if this refers to all UNCs or just roots, + * but I'm going to fix it for all cases for now. (Ben) */ #undef stat API_EXPORT(int) os_stat(const char *szPath, struct stat *pStat) { int n; + + ap_assert(szPath[1] == ':' || szPath[1] == '/'); // we are dealing with either UNC or a drive + + if(szPath[0] == '/') { + char buf[_MAX_PATH]; + char *s; + int nSlashes=0; + + ap_assert(strlen(szPath) < _MAX_PATH); + strcpy(buf,szPath); + for(s=buf ; *s ; ++s) + if(*s == '/') { + *s='\\'; + ++nSlashes; + } + if(nSlashes == 3) /* then we need to add one more to get \\machine\share\ */ + *s++='\\'; + *s='\0'; + return stat(buf,pStat); + } n = strlen(szPath); if(szPath[n-1] == '\\' || szPath[n-1] == '/') {