apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject cvs commit: apr/file_io/win32 filestat.c dir.c
Date Mon, 29 Jan 2001 06:21:42 GMT
wrowe       01/01/28 22:21:42

  Modified:    .        STATUS CHANGES
               include/arch/win32 fileio.h
               file_io/win32 filestat.c dir.c
  Log:
    Refactor out the 'extras' [not returned by the atomic get info call]
    and implement protections.  The only bit missing, according to testfile.c
    are the dir_read/stat inode/dev/nlink fields [these are in getfileinfo]
  
  Revision  Changes    Path
  1.33      +22 -5     apr/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/apr/STATUS,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- STATUS	2001/01/28 17:23:22	1.32
  +++ STATUS	2001/01/29 06:21:36	1.33
  @@ -1,5 +1,5 @@
   APACHE PORTABLE RUNTIME (APR) LIBRARY STATUS:			-*-text-*-
  -Last modified at [$Date: 2001/01/28 17:23:22 $]
  +Last modified at [$Date: 2001/01/29 06:21:36 $]
   
   Release:
   
  @@ -15,11 +15,18 @@
   
   RELEASE SHOWSTOPPERS:
   
  +    * Unix apr_stat/lstat/getfileinfo were very fast hacks, needs review.
  +        Will suggests: Unix is looking pretty good.  Ignore APR_FINFO_NAME
  +        issues for b1, I've noted that issue below.
   
  +    * OS2 apr_stat/lstat/getfileinfo/dir_read were very fast hacks, need
  +        cleanup, toggle messy (APR_INCOMPLETE) result when appropriate.
  +
   RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
   
  -    * Unix, OS2 apr_stat/lstat/getfileinfo were very fast hacks.  These
  -      need to be fleshed out.
  +    * Solve Win32 APR_CHR, APR_BLK, etc for Win32 apr_stat without 
  +        GetFileType?  How about inode/dev/nlink?
  +        Status: Will's WIP
   
       * SysV semaphore support isn't usable by Apache when started as
         root because we don't have a way to allow the semaphore to be
  @@ -30,9 +37,9 @@
   
       * Build scripts do not recognise AIX 4.2.1 pthreads
   
  -    * Win32: Implement ap_shm_ functions 
  +    * Win32: Implement apr_shm_ functions 
   
  -    * Bill says we need a new procattr, APR_CREATE_SUSPENDED (or
  +    * FirstBill says we need a new procattr, APR_CREATE_SUSPENDED (or
         something similar) to direct ap_create_process to create the
         process suspended. We also need a call to wake up the suspended 
         process This may not be able to be implemented everywhere though.
  @@ -111,3 +118,13 @@
   
   Stuff waiting for code thawing after Beta 1:
   
  +    * Implement APR_FINFO_ICASE/APR_FINFO_NAME for stat'ish calls.
  +        Can wait till after b1, will be required to eliminate canonical
  +        and add that functionallity in-line with directory_walk, which
  +        is _not_ planned for 2.0b1, but immediately afterwards.  It's
  +        required to complete Apache/WinNT's Unicode schema as well.
  +        Note: Will doesn't like his original APR_FINFO_ICASE definition.
  +
  +    * Identify and implement those protection bits that have general 
  +        usefulness, perhaps hidden, generic read-only [immutable],
  +        effective current user permissions, etc.
  
  
  
  1.53      +2 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- CHANGES	2001/01/28 23:52:47	1.52
  +++ CHANGES	2001/01/29 06:21:37	1.53
  @@ -1,5 +1,7 @@
   Changes with APR b1  
   
  +  *) Implement WinNT Unix'ish permissions. [William Rowe]
  +
     *) Corrected an OS2'ism of apr_get_home_directory.  OS2 now returns the
        proper directory, including the user's name.
   
  
  
  
  1.44      +12 -0     apr/include/arch/win32/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- fileio.h	2001/01/27 22:25:11	1.43
  +++ fileio.h	2001/01/29 06:21:39	1.44
  @@ -140,6 +140,18 @@
                              | APR_FINFO_CTIME | APR_FINFO_ATIME \
                              | APR_FINFO_MTIME | APR_FINFO_SIZE)
   
  +/* Sneak the Readonly bit through finfo->protection for internal use _only_ */
  +#define APR_FREADONLY 0x10000000 
  +
  +/* Private function that extends apr_stat/lstat/getfileinfo/dir_read */
  +apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, 
  +                        apr_int32_t wanted, int whatfile, 
  +                        apr_oslevel_e os_level);
  +
  +/* whatfile types for the ufile arg */
  +#define MORE_OF_HANDLE 0
  +#define MORE_OF_FSPEC  1
  +#define MORE_OF_WFSPEC 2
   
   /* quick run-down of fields in windows' apr_file_t structure that may have 
    * obvious uses.
  
  
  
  1.43      +226 -177  apr/file_io/win32/filestat.c
  
  Index: filestat.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/win32/filestat.c,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- filestat.c	2001/01/28 22:33:26	1.42
  +++ filestat.c	2001/01/29 06:21:40	1.43
  @@ -69,14 +69,216 @@
       return APR_SUCCESS;
   }
   
  +static apr_gid_t worldid = NULL;
  +
  +static void free_world(void)
  +{
  +    if (worldid) {
  +        FreeSid(worldid);
  +        worldid = NULL;
  +    }
  +}
  +
  +/* Left bit shifts from World scope to given scope */
  +typedef enum prot_scope_e {
  +    prot_scope_world = 0,
  +    prot_scope_group = 4,
  +    prot_scope_user =  8
  +} prot_scope_e;
  +
  +static apr_fileperms_t convert_prot(ACCESS_MASK acc, prot_scope_e scope)
  +{
  +    /* These choices are based on the single filesystem bit that controls
  +     * the given behavior.  They are -not- recommended for any set protection
  +     * function, such a function should -set- use GENERIC_READ/WRITE/EXECUTE
  +     */
  +    apr_fileperms_t prot;
  +    if (acc & FILE_EXECUTE)
  +        prot |= APR_WEXECUTE;
  +    if (acc & FILE_WRITE_DATA)
  +        prot |= APR_WWRITE;
  +    if (acc & FILE_READ_DATA)
  +        prot |= APR_WREAD;
  +    return (prot << scope);
  +}
  +
  +static void resolve_prot(apr_finfo_t *finfo, apr_int32_t wanted, PACL dacl)
  +{
  +    TRUSTEE ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID};
  +    ACCESS_MASK acc;
  +    if ((wanted & APR_FINFO_WPROT) && !worldid) {
  +        SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_WORLD_SID_AUTHORITY;
  +        if (AllocateAndInitializeSid(&SIDAuth, 1, SECURITY_WORLD_RID,
  +                                     0, 0, 0, 0, 0, 0, 0, &worldid))
  +            atexit(free_world);
  +        else
  +            worldid = NULL;
  +    }
  +    if ((wanted & APR_FINFO_UPROT) && (finfo->valid & APR_FINFO_USER))
{
  +        ident.TrusteeType = TRUSTEE_IS_USER;
  +        ident.ptstrName = finfo->user;
  +        if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
  +            finfo->protection |= convert_prot(acc, prot_scope_user);
  +            finfo->valid |= APR_FINFO_UPROT;
  +        }
  +    }
  +    if ((wanted & APR_FINFO_GPROT) && (finfo->valid & APR_FINFO_GROUP))
{
  +        ident.TrusteeType = TRUSTEE_IS_GROUP;
  +        ident.ptstrName = finfo->group;
  +        if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
  +            finfo->protection |= convert_prot(acc, prot_scope_group);
  +            finfo->valid |= APR_FINFO_GPROT;
  +        }
  +    }
  +    if ((wanted & APR_FINFO_WPROT) && (worldid)) {
  +        ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  +        ident.ptstrName = worldid;
  +        if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
  +            finfo->protection |= convert_prot(acc, prot_scope_world);
  +            finfo->valid |= APR_FINFO_WPROT;
  +        }
  +    }
  +}
  +
  +static int resolve_ident(apr_finfo_t *finfo, const char *fname,
  +                            apr_int32_t wanted, apr_pool_t *cont)
  +{
  +    apr_file_t *thefile = NULL;
  +    apr_status_t rv;
  +    /* 
  +     * NT5 (W2K) only supports symlinks in the same manner as mount points.
  +     * This code should eventually take that into account, for now treat
  +     * every reparse point as a symlink...
  +     *
  +     * We must open the file with READ_CONTROL if we plan to retrieve the
  +     * user, group or permissions.
  +     */
  +    
  +    if ((rv = apr_open(&thefile, fname, 
  +                       ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0)
  +                     | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
  +                           ? APR_READCONTROL : 0),
  +                       APR_OS_DEFAULT, cont)) == APR_SUCCESS) {
  +        rv = apr_getfileinfo(finfo, wanted, thefile);
  +        finfo->filehand = NULL;
  +        apr_close(thefile);
  +    }
  +    else if (APR_STATUS_IS_EACCES(rv) && (wanted & (APR_FINFO_PROT 
  +                                                  | APR_FINFO_OWNER))) {
  +        /* We have a backup plan.  Perhaps we couldn't grab READ_CONTROL?
  +         * proceed without asking for that permission...
  +         */
  +        if ((rv = apr_open(&thefile, fname, 
  +                           ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0),
  +                           APR_OS_DEFAULT, cont)) == APR_SUCCESS) {
  +            rv = apr_getfileinfo(finfo, wanted & ~(APR_FINFO_PROT 
  +                                                 | APR_FINFO_OWNER),
  +                                 thefile);
  +            finfo->filehand = NULL;
  +            apr_close(thefile);
  +        }
  +    }
  +    if (rv != APR_SUCCESS && rv != APR_INCOMPLETE)
  +        return (rv);
  +    /* We picked up this case above and had opened the link's properties */
  +    if (wanted & APR_FINFO_LINK)
  +        finfo->valid |= APR_FINFO_LINK;
  +    finfo->fname = thefile->fname;
  +
  +    return rv;
  +}
  +
  +apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, apr_int32_t wanted, 
  +                        int whatfile, apr_oslevel_e os_level)
  +{
  +    PSID user = NULL, grp = NULL;
  +    PACL dacl = NULL;
  +    apr_status_t rv;
  +
  +    if (whatfile == MORE_OF_WFSPEC)
  +        (apr_wchar_t*)ufile;
  +    else if (whatfile == MORE_OF_FSPEC)
  +        (char*)ufile;
  +    else if (whatfile == MORE_OF_HANDLE)
  +        (HANDLE)ufile;
  +
  +    if ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
  +            && os_level >= APR_WIN_NT)
  +    {
  +        SECURITY_INFORMATION sinf = 0;
  +        PSECURITY_DESCRIPTOR pdesc = NULL;
  +        if (wanted & (APR_FINFO_USER | APR_FINFO_UPROT))
  +            sinf |= OWNER_SECURITY_INFORMATION;
  +        if (wanted & (APR_FINFO_GROUP | APR_FINFO_GPROT))
  +            sinf |= GROUP_SECURITY_INFORMATION;
  +        if (wanted & APR_FINFO_PROT)
  +            sinf |= DACL_SECURITY_INFORMATION;
  +        if (whatfile == MORE_OF_WFSPEC)
  +            rv = GetNamedSecurityInfoW((apr_wchar_t*)ufile, 
  +                                 SE_FILE_OBJECT, sinf,
  +                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
  +                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
  +                                 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
  +                                 NULL, &pdesc);
  +        else if (whatfile == MORE_OF_FSPEC)
  +            rv = GetNamedSecurityInfoA((char*)ufile, 
  +                                 SE_FILE_OBJECT, sinf,
  +                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
  +                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
  +                                 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
  +                                 NULL, &pdesc);
  +        else if (whatfile == MORE_OF_HANDLE)
  +            rv = GetSecurityInfo((HANDLE)ufile, 
  +                                 SE_FILE_OBJECT, sinf,
  +                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
  +                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
  +                                 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
  +                                 NULL, &pdesc);
  +        if (rv == ERROR_SUCCESS)
  +            apr_register_cleanup(finfo->cntxt, pdesc, free_localheap, 
  +                                 apr_null_cleanup);
  +        else
  +            user = grp = dacl = NULL;
  +
  +        if (user) {
  +            finfo->user = user;
  +            finfo->valid |= APR_FINFO_USER;
  +        }
  +
  +        if (grp) {
  +            finfo->group = grp;
  +            finfo->valid |= APR_FINFO_GROUP;
  +        }
  +
  +        if (dacl) {
  +            /* Retrieved the discresionary access list */
  +            resolve_prot(finfo, wanted, dacl);
  +        }
  +    }
  +
  +    if (!(finfo->valid & APR_FINFO_UPROT)) {
  +        /* Read, write execute for owner.  In the Win32 environment, 
  +         * anything readable is executable (well, not entirely 100% true, 
  +         * but I'm looking for some obvious logic that would help us here.)
  +         */
  +        if (finfo->protection & APR_FREADONLY) {
  +            finfo->protection |= S_IREAD | S_IEXEC;
  +        }
  +        else {
  +            finfo->protection |= S_IREAD | S_IWRITE | S_IEXEC;
  +        }
  +        finfo->valid |= APR_FINFO_UPROT;
  +    }    
  +
  +    return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);
  +}
  +
  +
   APR_DECLARE(apr_status_t) apr_getfileinfo(apr_finfo_t *finfo, apr_int32_t wanted,
                                             apr_file_t *thefile)
   {
       BY_HANDLE_FILE_INFORMATION FileInformation;
       apr_oslevel_e os_level;
  -    PSID user = NULL, grp = NULL;
  -    PACL dacl = NULL;
  -    apr_status_t rv;
   
       if (!GetFileInformationByHandle(thefile->filehand, &FileInformation)) {
           return apr_get_os_error();
  @@ -134,60 +336,12 @@
           }
       }
       
  +    if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  +        finfo->protection = APR_FREADONLY;
   
  -    if ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
  -            && !apr_get_oslevel(thefile->cntxt, &os_level)
  -            && os_level >= APR_WIN_NT) {
  -        SECURITY_INFORMATION sinf = 0;
  -        PSECURITY_DESCRIPTOR pdesc = NULL;
  -        if (wanted & (APR_FINFO_USER | APR_FINFO_UPROT))
  -            sinf |= OWNER_SECURITY_INFORMATION;
  -        if (wanted & (APR_FINFO_GROUP | APR_FINFO_GPROT))
  -            sinf |= GROUP_SECURITY_INFORMATION;
  -        if (wanted & APR_FINFO_PROT)
  -            sinf |= DACL_SECURITY_INFORMATION;
  -        rv = GetSecurityInfo(thefile->filehand, SE_FILE_OBJECT, sinf,
  -                             ((wanted & APR_FINFO_USER) ? &user : NULL),
  -                             ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
  -                             ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
  -                             NULL, &pdesc);
  -        if (rv == ERROR_SUCCESS)
  -            apr_register_cleanup(thefile->cntxt, pdesc, free_localheap, 
  -                                 apr_null_cleanup);
  -    }
  +    if (wanted &= ~finfo->valid)
  +        return more_finfo(finfo, thefile->filehand, wanted, MORE_OF_HANDLE, os_level);
   
  -    if (user) {
  -        finfo->user = user;
  -        finfo->valid |= APR_FINFO_USER;
  -    }
  -
  -    if (grp) {
  -        finfo->group = grp;
  -        finfo->valid |= APR_FINFO_GROUP;
  -    }
  -
  -    if (dacl) {
  -        /* Retrieved the discresionary access list */
  -        
  -    }
  -    else {
  -        /* Read, write execute for owner.  In the Win32 environment, 
  -         * anything readable is executable (well, not entirely 100% true, 
  -         * but I'm looking for some obvious logic that would help us here.)
  -         * TODO: The real permissions come from the DACL
  -         */
  -        if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
  -            finfo->protection |= S_IREAD | S_IEXEC;
  -        }
  -        else {
  -            finfo->protection |= S_IREAD | S_IWRITE | S_IEXEC;
  -        }
  -        finfo->valid |= APR_FINFO_UPROT;
  -    }    
  -    
  -    if (wanted & ~finfo->valid)
  -        return APR_INCOMPLETE;
  -
       return APR_SUCCESS;
   }
   
  @@ -197,63 +351,17 @@
       return APR_ENOTIMPL;
   }
   
  -static int stat_with_handle(apr_finfo_t *finfo, const char *fname,
  -                            apr_int32_t wanted, apr_pool_t *cont)
  -{
  -    apr_file_t *thefile = NULL;
  -    apr_status_t rv;
  -    /* 
  -     * NT5 (W2K) only supports symlinks in the same manner as mount points.
  -     * This code should eventually take that into account, for now treat
  -     * every reparse point as a symlink...
  -     *
  -     * We must open the file with READ_CONTROL if we plan to retrieve the
  -     * user, group or permissions.
  -     */
  -    
  -    if ((rv = apr_open(&thefile, fname, 
  -                       ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0)
  -                     | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER))
  -                           ? APR_READCONTROL : 0),
  -                       APR_OS_DEFAULT, cont)) == APR_SUCCESS) {
  -        rv = apr_getfileinfo(finfo, wanted, thefile);
  -        finfo->filehand = NULL;
  -        apr_close(thefile);
  -    }
  -    else if (APR_STATUS_IS_EACCES(rv) && (wanted & (APR_FINFO_PROT 
  -                                                  | APR_FINFO_OWNER))) {
  -        /* We have a backup plan.  Perhaps we couldn't grab READ_CONTROL?
  -         * proceed without asking for that permission...
  -         */
  -        if ((rv = apr_open(&thefile, fname, 
  -                           ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0),
  -                           APR_OS_DEFAULT, cont)) == APR_SUCCESS) {
  -            rv = apr_getfileinfo(finfo, wanted & ~(APR_FINFO_PROT 
  -                                                 | APR_FINFO_OWNER),
  -                                 thefile);
  -            finfo->filehand = NULL;
  -            apr_close(thefile);
  -        }
  -    }
  -    if (rv != APR_SUCCESS && rv != APR_INCOMPLETE)
  -        return (rv);
  -    /* We picked up this case above and had opened the link's properties */
  -    if (wanted & APR_FINFO_LINK)
  -        finfo->valid |= APR_FINFO_LINK;
  -    finfo->fname = thefile->fname;
  -
  -    return rv;
  -}
  -
   APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
                                      apr_int32_t wanted, apr_pool_t *cont)
   {
  -    /* The WIN32_FILE_ATTRIBUTE_DATA is a subset of this structure
  +#ifdef APR_HAS_UNICODE_FS
  +    apr_wchar_t wfname[APR_PATH_MAX];
  +#endif
  +    /*
  +     * The WIN32_FILE_ATTRIBUTE_DATA is a subset of this structure
        */
       WIN32_FIND_DATA FileInformation;
       apr_oslevel_e os_level;
  -    PSID user = NULL, grp = NULL;
  -    PACL dacl = NULL;
   
       if (apr_get_oslevel(cont, &os_level))
           os_level = APR_WIN_95;
  @@ -265,9 +373,9 @@
       if (strlen(fname) >= APR_PATH_MAX) {
           return APR_ENAMETOOLONG;
       }
  +
   #ifdef APR_HAS_UNICODE_FS
  -    else if (os_level >= APR_WIN_NT) {
  -        apr_wchar_t wfname[APR_PATH_MAX];
  +    if (os_level >= APR_WIN_NT) {
           apr_status_t rv;
           if (rv = utf8_to_unicode_path(wfname, sizeof(wfname) 
                                               / sizeof(apr_wchar_t), fname))
  @@ -276,27 +384,10 @@
                                     &FileInformation)) {
               return apr_get_os_error();
           }
  -        if (wanted & (APR_FINFO_PROT | APR_FINFO_OWNER)) {
  -            SECURITY_INFORMATION sinf = 0;
  -            PSECURITY_DESCRIPTOR pdesc = NULL;
  -            if (wanted & (APR_FINFO_USER | APR_FINFO_UPROT))
  -                sinf |= OWNER_SECURITY_INFORMATION;
  -            if (wanted & (APR_FINFO_GROUP | APR_FINFO_GPROT))
  -                sinf |= GROUP_SECURITY_INFORMATION;
  -            if (wanted & APR_FINFO_PROT)
  -                sinf |= DACL_SECURITY_INFORMATION;
  -            rv = GetNamedSecurityInfoW(wfname, SE_FILE_OBJECT, sinf,
  -                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
  -                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
  -                                 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
  -                                 NULL, &pdesc);
  -            if (rv == ERROR_SUCCESS)
  -                apr_register_cleanup(cont, pdesc, free_localheap, 
  -                                     apr_null_cleanup);
  -        }
       }
  +    else 
   #endif
  -    else if (os_level >= APR_WIN_98) {
  +      if (os_level >= APR_WIN_98) {
           if (!GetFileAttributesExA(fname, GetFileExInfoStandard, 
                                    &FileInformation)) {
               return apr_get_os_error();
  @@ -353,40 +444,18 @@
            */
           finfo->filetype = APR_REG;
       }
  -
  -    if (user) {
  -        finfo->user = user;
  -        finfo->valid |= APR_FINFO_USER;
  -    }
   
  -    if (grp) {
  -        finfo->group = grp;
  -        finfo->valid |= APR_FINFO_GROUP;
  -    }
  +    if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  +        finfo->protection = APR_FREADONLY;
   
  -    if (dacl) {
  -        /* Retrieved the discresionary access list, provide some real answers
  -         */
  -        
  -    }
  -    else {
  -        /* Read, write execute for owner
  -         * In the Win32 environment, anything readable is executable
  -         * (not entirely 100% true, but the dacl is -expensive-!)
  -         */
  -        if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
  -            finfo->protection |= S_IREAD | S_IEXEC;
  -        }
  -        else {
  -            finfo->protection |= S_IREAD | S_IWRITE | S_IEXEC;
  -        }
  -        /* Lying through our teeth */
  -        finfo->valid |= APR_FINFO_UPROT;
  +    if (wanted &= ~finfo->valid) {
  +#ifdef APR_HAS_UNICODE_FS
  +        if (os_level >= APR_WIN_NT)
  +            return more_finfo(finfo, wfname, wanted, MORE_OF_WFSPEC, os_level);
  +#endif
  +        return more_finfo(finfo, fname, wanted, MORE_OF_FSPEC, os_level);
       }
   
  -    if (wanted & ~finfo->valid)
  -        return APR_INCOMPLETE;
  -
       return APR_SUCCESS;
   }
   
  @@ -395,23 +464,3 @@
   {
       return apr_stat(finfo, fname, wanted & APR_FINFO_LINK, cont);
   }
  -
  -#if 0
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(cont, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        WIN32_FIND_DATAW FileInformation;
  -        HANDLE hFind;
  -        apr_wchar_t *wname;
  -        if (strchr(fspec, '*') || strchr(fspec, '?'))
  -            return APR_ENOENT;
  -        wname = utf8_to_unicode_path(fspec, cont);
  -        if (!wname)
  -            return APR_ENAMETOOLONG;
  -        hFind = FindFirstFileW(wname, &FileInformation);
  -        if (hFind == INVALID_HANDLE_VALUE)
  -            return apr_get_os_error();
  -    	else
  -            FindClose(hFind);
  -        *fname = unicode_to_utf8_path(FileInformation.cFileName, cont);
  -#endif
  \ No newline at end of file
  
  
  
  1.50      +36 -23    apr/file_io/win32/dir.c
  
  Index: dir.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/win32/dir.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- dir.c	2001/01/28 04:03:11	1.49
  +++ dir.c	2001/01/29 06:21:40	1.50
  @@ -152,11 +152,11 @@
        */
   #if APR_HAS_UNICODE_FS
       apr_oslevel_e os_level;
  +    apr_wchar_t *eos, wdirname[APR_PATH_MAX];
       if (!apr_get_oslevel(thedir->cntxt, &os_level) && os_level >= APR_WIN_NT)
       {
           if (thedir->dirhand == INVALID_HANDLE_VALUE) 
           {
  -            apr_wchar_t *eos, wdirname[APR_PATH_MAX];
               apr_status_t rv;
               if (rv = utf8_to_unicode_path(wdirname, sizeof(wdirname) 
                                                        / sizeof(apr_wchar_t), 
  @@ -170,6 +170,7 @@
               if (thedir->dirhand == INVALID_HANDLE_VALUE) {
                   return apr_get_os_error();
               }
  +            eos[0] = '\0';
           }
           else if (!FindNextFileW(thedir->dirhand, thedir->w.entry)) {
               return apr_get_os_error();
  @@ -211,22 +212,6 @@
           }
           fname = thedir->n.entry->cFileName;
       }
  -    if (wanted & ~APR_FINFO_WIN32_DIR) {
  -        char fspec[APR_PATH_MAX];
  -        int dirlen = strlen(thedir->dirname);
  -        if (dirlen >= sizeof(fspec))
  -            dirlen = sizeof(fspec) - 1;
  -        apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));
  -        apr_cpystrn(fspec + dirlen, fname, sizeof(fspec) - dirlen);
  -        rv = apr_stat(finfo, fspec, wanted, thedir->cntxt);
  -        if (rv == APR_SUCCESS || rv == APR_INCOMPLETE) {
  -            finfo->valid |= APR_FINFO_NAME;
  -            finfo->name = fname;
  -            finfo->fname = fspec;
  -            rv = (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
  -        }
  -        return rv;
  -    }
   
       memset(finfo, '\0', sizeof(*finfo));
       finfo->name = fname;
  @@ -261,8 +246,41 @@
       finfo->size = (apr_off_t)thedir->n.entry->nFileSizeLow;
       if (finfo->size < 0 || FileInformation.nFileSizeHigh)
           finfo->size = 0x7fffffff;
  +#endif
  +
  +    if (thedir->n.entry->dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  +        finfo->protection = APR_FREADONLY;
  +
  +    if (wanted &= ~finfo->valid) {
  +        /* Go back and get more_info if we can't answer the whole inquiry
  +         */
  +#if APR_HAS_UNICODE_FS
  +        if (os_level >= APR_WIN_NT) {
  +            /* Almost all our work is done.  Tack on the wide file name
  +             * to the end of the wdirname (already / delimited)
  +             */
  +            wcscpy(eos, thedir->w.entry->cFileName);
  +            return more_finfo(finfo, wdirname, wanted, MORE_OF_WFSPEC, os_level);
  +        }
  +        else {
  +            /* Don't waste stack space on a second buffer, the one we set
  +             * aside for the wide directory name is twice what we need.
  +             */
  +            char *fspec = (char*)wdirname;
  +#else /* !APR_HAS_UNICODE_FS */
  +        {
  +            char fspec[APR_PATH_MAX];
   #endif
  -    return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
  +            int dirlen = strlen(thedir->dirname);
  +            if (dirlen >= sizeof(fspec))
  +                dirlen = sizeof(fspec) - 1;
  +            apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));
  +            apr_cpystrn(fspec + dirlen, fname, sizeof(fspec) - dirlen);
  +            return more_finfo(finfo, fspec, wanted, MORE_OF_FSPEC, os_level);
  +        }
  +    }
  +
  +    return APR_SUCCESS;
   }
   
   APR_DECLARE(apr_status_t) apr_dir_rewind(apr_dir_t *dir)
  @@ -323,11 +341,6 @@
           }
       return APR_SUCCESS;
   }
  -
  -
  -
  -
  -
   
   APR_DECLARE(apr_status_t) apr_get_os_dir(apr_os_dir_t **thedir,
                                            apr_dir_t *dir)
  
  
  

Mime
View raw message