From: <[EMAIL PROTECTED]>
Sent: Friday, January 19, 2001 12:46 PM

> 
> ++1.  If you get Windows working, I'll do Unix when you are done.

How about the other way around?

Here's the proof-of-concept on unix;  I don't promise it's complete,
and don't promise it compiles, but it underscores the concept.

Windows is obviously much trickier... I'm working that up now, repleat
with the open a file from an apr_finfo_t (of course, we already get
stats from an open apr_file_t).  Since both apr_finfo_t and apr_file_t
will capture a filename, they are -interchangable-.

One thing I don't like, looking at this, is that we pass 'our own'
apr_finfo_t structure, which means it is just as likely to be passed
on the stack.  That's not healthy for later opening the file from the
apr_finfo_t, yet we have 'resolved' not to actually copy these filenames.
I imagine it really ought to be one or the other, we do or we don't
copy the name, therefore we musn't or must allocate an apr_finfo_t from
the pool.

Bill

Index: include/apr_file_info.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_info.h,v
retrieving revision 1.1
diff -u -r1.1 apr_file_info.h
--- include/apr_file_info.h 2001/01/19 17:29:44 1.1
+++ include/apr_file_info.h 2001/01/20 01:02:55
@@ -136,14 +136,40 @@
 
 typedef struct apr_finfo_t        apr_finfo_t;
 
+#define APR_FINFO_LINK   0x00000001
+#define APR_FINFO_MTIME  0x00000010
+#define APR_FINFO_CTIME  0x00000020
+#define APR_FINFO_ATIME  0x00000040
+#define APR_FINFO_SIZE   0x00000100
+#define APR_FINFO_ASIZE  0x00000200
+#define APR_FINFO_CSIZE  0x00000400
+#define APR_FINFO_DEV    0x00001000
+#define APR_FINFO_INODE  0x00002000
+#define APR_FINFO_TYPE   0x00008000
+#define APR_FINFO_USER   0x00010000 
+#define APR_FINFO_GROUP  0x00020000 
+#define APR_FINFO_UPROT  0x00100000 
+#define APR_FINFO_GPROT  0x00200000
+#define APR_FINFO_WPROT  0x00400000
+#define APR_FINFO_ICASE  0x01000000  /*  if dev is case insensitive */
+#define APR_FINFO_FCASE  0x02000000  /*  filename in proper case */
+
+#define APR_FINFO_MIN    0x00008170  /*  minimal: type, dates and size */
+#define APR_FINFO_IDENT  0x00003000  /*  dev and inode */
+#define APR_FINFO_OWNER  0x00030000  /*  user and group */
+#define APR_FINFO_PROT   0x00700000  /*  all protections */
+
 /**
  * The file information structure.  This is analogous to the POSIX
  * stat structure.
  */
 struct apr_finfo_t {
-    /** The access permissions of the file.  Currently this mimics Unix
-     *  access rights.
-     */
+    /** Allocates memory and closes lingering handles in the specified pool */
+    apr_pool_t *cntxt;
+    /** The bitmask describing valid fields of this apr_finfo_t structure 
+     *  including all available 'wanted' fields and potentially more */
+    apr_int32_t valid;
+    /** The access permissions of the file.  Mimics Unix access rights. */
     apr_fileperms_t protection;
     /** The type of file.  One of APR_NOFILE, APR_REG, APR_DIR, APR_CHR, 
      *  APR_BLK, APR_PIPE, APR_LNK, APR_SOCK 
@@ -153,18 +179,28 @@
     apr_uid_t user;
     /** The group id that owns the file */
     apr_gid_t group;
-    /** The inode of the file.  (Not portable?) */
+    /** The inode of the file. */
     apr_ino_t inode;
-    /** The id of the device the file is on.  (Not portable?) */
+    /** The id of the device the file is on. */
     apr_dev_t device;
     /** The size of the file */
     apr_off_t size;
+    /** The space allocated for the file */
+    apr_off_t csize;
+    /** The storage size consumed by the file */
+    apr_off_t csize;
     /** The time the file was last accessed */
     apr_time_t atime;
     /** The time the file was last modified */
     apr_time_t mtime;
     /** The time the file was last changed */
     apr_time_t ctime;
+    /** The full pathname of the file */
+    char *filespec;
+    /** The file's name alone, in filesystem case */
+    char *filename;
+    /** The file's handle, if accessed (can be submitted to apr_duphandle) */
+    apr_file_t *filehand;
 };
 
 /**
@@ -173,11 +209,12 @@
  * @param finfo Where to store the information about the file, which is
  * never touched if the call fails.
  * @param fname The name of the file to stat.
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ 
values 
  * @param cont the pool to use to allocate the new file. 
- * @deffunc apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, 
apr_pool_t *cont)
+ * @deffunc apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, 
apr_int32_t wanted, apr_pool_t *cont)
  */ 
 APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
-                                   apr_pool_t *cont);
+                                   apr_int32_t wanted, apr_pool_t *cont);
 
 /**
  * get the specified file's stats.  The file is specified by filename, 
@@ -186,11 +223,14 @@
  * @param finfo Where to store the information about the file, which is
  * never touched if the call fails.
  * @param fname The name of the file to stat.
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ 
values 
  * @param cont the pool to use to allocate the new file. 
- * @deffunc apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, 
apr_pool_t *cont)
+ * @deffunc apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, 
apr_int32_t wanted, apr_pool_t *cont)
+ * @tip This function is depreciated, it's equivilant to calling apr_stat with 
+ * the wanted flag value APR_FINFO_LINK
  */ 
 APR_DECLARE(apr_status_t) apr_lstat(apr_finfo_t *finfo, const char *fname,
-                                    apr_pool_t *cont);
+                                    apr_int32_t wanted, apr_pool_t *cont);
 
 /**
  * Open the specified directory.
Index: include/apr_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_io.h,v
retrieving revision 1.87
diff -u -r1.87 apr_file_io.h
--- include/apr_file_io.h 2001/01/19 17:29:44 1.87
+++ include/apr_file_io.h 2001/01/20 01:02:55
@@ -521,10 +521,12 @@
 /**
  * get the specified file's stats.
  * @param finfo Where to store the information about the file.
+ * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ 
values 
  * @param thefile The file to get information about.
- * @deffunc apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t 
*thefile)
+ * @deffunc apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_int32_t 
wanted, apr_file_t *thefile)
  */ 
-APR_DECLARE(apr_status_t) apr_getfileinfo(apr_finfo_t *finfo,
+APR_DECLARE(apr_status_t) apr_getfileinfo(apr_finfo_t *finfo, 
+                                          apr_int32_t wanted,
                                           apr_file_t *thefile);
 
 #ifdef __cplusplus
Index: file_io/unix/filestat.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filestat.c,v
retrieving revision 1.33
diff -u -r1.33 filestat.c
--- file_io/unix/filestat.c 2000/11/14 06:40:03 1.33
+++ file_io/unix/filestat.c 2001/01/20 01:02:55
@@ -55,6 +55,7 @@
 #include "fileio.h"
 #include "apr_file_io.h"
 #include "apr_general.h"
+#include "apr_strings.h"
 #include "apr_errno.h"
 
 static apr_filetype_e filetype_from_mode(int mode)
@@ -80,11 +81,14 @@
     return type;
 }
 
-apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_file_t *thefile)
+apr_status_t apr_getfileinfo(apr_finfo_t *finfo, apr_int32_t wanted,
+                             apr_file_t *thefile)
 {
     struct stat info;
 
     if (fstat(thefile->filedes, &info) == 0) {
+        finfo->cntxt = thefile->cntxt;
+        finfo->valid = APR_FINFO_MIN| APR_FINFO_IDENT | APR_FINFO_OWNER | 
APR_FINFO_PROT;
         finfo->protection = apr_unix_mode2perms(info.st_mode);
         finfo->filetype = filetype_from_mode(info.st_mode);
         finfo->user = info.st_uid;
@@ -92,9 +96,18 @@
         finfo->size = info.st_size;
         finfo->inode = info.st_ino;
         finfo->device = info.st_dev;
+        finfo->nlinks = info.st_nlink;
         apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime);
         apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime);
         apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime);
+        finfo->filepath = thefile->fname;
+        if (wanted & APR_FINFO_CSIZE) {
+            finfo->csize = info.st_blocks * 512;
+            finfo->valid |= APR_FINFO_CSIZE;
+        }
+        if (finfo->filetype = APR_LNK)
+            finfo->valid |= APR_FINFO_LINK
+        }
         return APR_SUCCESS;
     }
     else {
@@ -111,11 +124,20 @@
     return APR_SUCCESS;
 }
 
-apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont)
+apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname,
+                      apr_int32_t wanted, apr_pool_t *cont)
 {
     struct stat info;
+    int srv;
 
-    if (stat(fname, &info) == 0) {
+    if (wanted & APR_FINFO_LINK)
+        srv = lstat(fname, &info);
+    else
+        srv = stat(fname,info);
+
+    if (srv == 0) {
+        finfo->cntxt = cont;
+        finfo->valid = APR_FINFO_MIN| APR_FINFO_IDENT | APR_FINFO_OWNER | 
APR_FINFO_PROT;
         finfo->protection = apr_unix_mode2perms(info.st_mode);
         finfo->filetype = filetype_from_mode(info.st_mode);
         finfo->user = info.st_uid;
@@ -123,9 +145,18 @@
         finfo->size = info.st_size;
         finfo->inode = info.st_ino;
         finfo->device = info.st_dev;
+        finfo->nlinks = info.st_nlink;
         apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime);
         apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime);
         apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime);
+        finfo->filepath = fname;
+        if (wanted & APR_FINFO_CSIZE) {
+            finfo->csize = info.st_blocks * 512;
+            finfo->valid |= APR_FINFO_CSIZE;
+        }
+        if (finfo->filetype = APR_LNK)
+            finfo->valid |= APR_FINFO_LINK
+        }
         return APR_SUCCESS;
     }
     else {
@@ -163,24 +194,12 @@
     }
 }
 
-apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname, apr_pool_t *cont)
+/* Perhaps this becomes nothing but a macro?
+ */
+apr_status_t apr_lstat(apr_finfo_t *finfo, const char *fname,
+                      apr_int32_t wanted, apr_pool_t *cont)
 {
-    struct stat info;
+    return apr_stat(finfo, fname, wanted | APR_FINFO_LINK, cont);
+}
 
-    if (lstat(fname, &info) == 0) {
-        finfo->protection = apr_unix_mode2perms(info.st_mode);
-        finfo->filetype = filetype_from_mode(info.st_mode);
-        finfo->user = info.st_uid;
-        finfo->group = info.st_gid;
-        finfo->size = info.st_size;
-        finfo->inode = info.st_ino;
-        finfo->device = info.st_dev;
-        apr_ansi_time_to_apr_time(&finfo->atime, info.st_atime);
-        apr_ansi_time_to_apr_time(&finfo->mtime, info.st_mtime);
-        apr_ansi_time_to_apr_time(&finfo->ctime, info.st_ctime);
-        return APR_SUCCESS;
-    }
-    else {
-        return errno;
-    }
 }


Reply via email to