httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@hyperreal.org
Subject cvs commit: apache-apr/apr/file_io/beos pipe.c dir.c fileacc.c filedup.c fileio.h filestat.c open.c readwrite.c seek.c
Date Mon, 17 May 1999 18:31:41 GMT
rbb         99/05/17 11:31:40

  Modified:    apr/file_io/beos dir.c fileacc.c filedup.c fileio.h
                        filestat.c open.c readwrite.c seek.c
  Added:       apr/file_io/beos pipe.c
  Log:
  Update the file I/O stuff for BeOS.
  Submitted by:  David Reid
  
  Revision  Changes    Path
  1.3       +112 -15   apache-apr/apr/file_io/beos/dir.c
  
  Index: dir.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/dir.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- dir.c	1999/05/10 14:36:20	1.2
  +++ dir.c	1999/05/17 18:31:27	1.3
  @@ -53,34 +53,47 @@
    *
    */
   
  -#include "apr_file_io.h"
   #include <errno.h>
   #include <string.h>
   #include <dirent.h>
  -#include <stdio.h>
  -/*#include <sys/stat.h> */
  +#include <sys/stat.h>
  +#include "fileio.h"
  +#include "apr_file_io.h"
  +#include "apr_lib.h"
  +
  +ap_status_t dir_cleanup(void *thedir)
  +{
  +	struct dir_t *dir = thedir;
  +	if (closedir(dir->dirstruct) ==0) {
  +        return APR_SUCCESS;
  +    }
  +    else {
  +        return APR_FAILURE;
  +    }
  +} 
   
  -ap_dir_t *ap_opendir(const char *dirname)
  +struct dir_t *ap_opendir(ap_context_t *cont, const char *dirname)
   {
  -    ap_dir_t *thedir = (ap_dir_t *)malloc(sizeof(ap_dir_t));
  +    struct dir_t *thedir = (ap_dir_t *)ap_palloc(cont->pool,sizeof(ap_dir_t));
  +
       thedir->dirname = strdup(dirname);
       thedir->dirstruct = opendir(dirname);
  +    thedir->entry = NULL;
   
       if (thedir->dirstruct == NULL) {
           free(thedir);
           return NULL;
       }    
       else {
  +    	ap_register_cleanup(cont->pool, (void*)thedir, dir_cleanup, NULL);
           return thedir;
       }
   }
   
  -ap_status_t ap_closedir(ap_dir_t *thedir)
  +ap_status_t ap_closedir(ap_context_t *cont, struct dir_t *thedir)
   {
  -    if (closedir(thedir->dirstruct) == 0) {
  -        free(thedir->dirname);
  -        free(thedir);
  -        thedir = NULL;
  +    if (dir_cleanup(thedir) == APR_SUCCESS) {
  +        ap_kill_cleanup(cont->pool, thedir, dir_cleanup);
           return APR_SUCCESS;
       }
       else {
  @@ -88,18 +101,22 @@
       }
   } 
   
  -ap_dirent_t *ap_readdir(ap_dir_t *thedir)
  +ap_status_t ap_readdir(ap_context_t *cont, struct dir_t *thedir)
   {
  -    return readdir(thedir->dirstruct);
  +    thedir->entry = readdir(thedir->dirstruct);
  + 	if (thedir->entry == NULL){
  + 		return APR_FAILURE;
  +    }
  +    return APR_SUCCESS;
   }
   
  -ap_status_t ap_rewinddir(ap_dir_t *thedir)
  +ap_status_t ap_rewinddir(ap_context_t *cont, struct dir_t *thedir)
   {
       rewinddir(thedir->dirstruct);
       return APR_SUCCESS;
   }
   
  -ap_status_t ap_make_dir(const char *path, ap_fileperms_t mode)
  +ap_status_t ap_make_dir(ap_context_t *cont, const char *path, ap_fileperms_t mode)
   {
       if (mkdir(path, mode) == 0) {
           return APR_SUCCESS;
  @@ -109,7 +126,7 @@
       }
   }
   
  -ap_status_t ap_remove_dir(const char *path)
  +ap_status_t ap_remove_dir(ap_context_t *cont, const char *path)
   {
       if (rmdir(path) == 0) {
           return APR_SUCCESS;
  @@ -118,3 +135,83 @@
           return APR_FAILURE;
       }
   }
  +
  +ap_ssize_t ap_dir_entry_size(ap_context_t *context, ap_dir_t *thedir) 
  +{ 
  +    struct stat filestat; 
  +    char *fname = NULL;    
  + 
  +    if (thedir->entry == NULL) { 
  +        errno = ENOFILE; 
  +        return -1; 
  +    } 
  +    fname = ap_pstrcat(context->pool, thedir->dirname, "/", 
  +                       thedir->entry->d_name, NULL); 
  +    if (stat(fname, &filestat) == -1) { 
  +        errno = ENOSTAT; 
  +        return -1; 
  +    } 
  +    
  +    return filestat.st_size; 
  +} 
  + 
  +time_t ap_dir_entry_mtime(ap_context_t *context, ap_dir_t *thedir) 
  +{ 
  +    struct stat filestat; 
  +    char *fname = NULL; 
  + 
  +    if (thedir->entry == NULL) { 
  +        errno = ENOFILE; 
  +        return -1; 
  +    } 
  + 
  +    fname = ap_pstrcat(context->pool, thedir->dirname, "/", 
  +                       thedir->entry->d_name, NULL); 
  +    if (stat(fname, &filestat) == -1) { 
  +        errno = ENOSTAT; 
  +        return -1; 
  +    } 
  +    
  +    return filestat.st_mtime; 
  +} 
  + 
  +ap_filetype_e ap_dir_entry_ftype(ap_context_t *context, ap_dir_t *thedir) 
  +{ 
  +    struct stat filestat; 
  +    char *fname = NULL; 
  + 
  +    if (thedir->entry == NULL) { 
  +        errno = ENOFILE; 
  +        return -1; 
  +    } 
  + 
  +    fname = ap_pstrcat(context->pool, thedir->dirname, "/", 
  +                       thedir->entry->d_name, NULL); 
  +    if (stat(fname, &filestat) == -1) { 
  +        errno = ENOSTAT; 
  +        return -1; 
  +    } 
  + 
  +    if (S_ISREG(filestat.st_mode)) 
  +        return APR_REG;    
  +    if (S_ISDIR(filestat.st_mode)) 
  +        return APR_DIR;    
  +    if (S_ISCHR(filestat.st_mode)) 
  +        return APR_CHR;    
  +    if (S_ISBLK(filestat.st_mode)) 
  +        return APR_BLK;    
  +    if (S_ISFIFO(filestat.st_mode)) 
  +        return APR_PIPE;    
  +    if (S_ISLNK(filestat.st_mode)) 
  +        return APR_LNK;    
  +    /*if (S_ISSOCK(filestat.st_mode)) 
  +        return APR_SOCK;*/    
  +} 
  + 
  +char * ap_get_dir_filename(ap_context_t * context, ap_dir_t *thedir) 
  +{ 
  +    char *name = (char *)ap_palloc(context->pool, strlen(thedir->entry->d_name));

  +    name = ap_pstrdup(context->pool, thedir->entry->d_name); 
  +    return name; 
  +} 
  + 
  
  
  
  1.3       +32 -14    apache-apr/apr/file_io/beos/fileacc.c
  
  Index: fileacc.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/fileacc.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- fileacc.c	1999/05/10 14:36:20	1.2
  +++ fileacc.c	1999/05/17 18:31:29	1.3
  @@ -53,25 +53,16 @@
    *
    */
   
  -#include "apr_file_io.h"
  -#include "apr_general.h"
   #include <errno.h>
   #include <string.h>
  +#include "fileio.h"
  +#include "apr_file_io.h"
  +#include "apr_general.h"
   
  -/* A file to put ALL of the accessor functions for ap_file_t types. */
  +/* A file to put ALL of the accessor functions for struct file_t types. */
   
  -ap_status_t ap_valid_file(ap_file_t *thefile) 
  +char * ap_get_filename(ap_context_t *cont, struct file_t *thefile)
   {
  -    if (thefile != NULL && thefile->filedes > 0) {
  -        return APR_SUCCESS;
  -    }
  -    else {
  -        return APR_FAILURE;
  -    }
  -}
  -
  -char * ap_get_filename(ap_file_t *thefile)
  -{
       if (thefile != NULL) {
           return thefile->fname;
       }
  @@ -80,4 +71,31 @@
       }
   }
   
  +mode_t get_fileperms(ap_fileperms_t mode) 
  +{ 
  +    mode_t rv = 0; 
  + 
  +    if (mode & APR_UREAD) 
  +        rv |= S_IRUSR; 
  +    if (mode & APR_UWRITE) 
  +        rv |= S_IWUSR; 
  +    if (mode & APR_UEXECUTE) 
  +        rv |= S_IXUSR; 
  + 
  +    if (mode & APR_GREAD) 
  +        rv |= S_IRGRP; 
  +    if (mode & APR_GWRITE) 
  +        rv |= S_IWGRP; 
  +    if (mode & APR_GEXECUTE) 
  +        rv |= S_IXGRP; 
  +
  +    if (mode & APR_WREAD) 
  +        rv |= S_IROTH; 
  +    if (mode & APR_WWRITE) 
  +        rv |= S_IWOTH; 
  +    if (mode & APR_WEXECUTE) 
  +        rv |= S_IXOTH; 
  + 
  +    return rv; 
  +} 
   
  
  
  
  1.3       +5 -2      apache-apr/apr/file_io/beos/filedup.c
  
  Index: filedup.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/filedup.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- filedup.c	1999/05/10 14:36:20	1.2
  +++ filedup.c	1999/05/17 18:31:30	1.3
  @@ -53,12 +53,14 @@
    *
    */
   
  +#include <strings.h>
  +#include "fileio.h"
   #include "apr_file_io.h"
   #include "apr_general.h"
   
  -ap_file_t *ap_dupfile(ap_file_t *old_file)
  +struct file_t *ap_dupfile(ap_context_t *cont, struct file_t *old_file)
   {
  -    ap_file_t * new_file = (ap_file_t *)malloc(sizeof(ap_file_t));
  +    struct file_t * new_file = (struct file_t *)ap_palloc(cont->pool,sizeof(struct file_t));
       
       if (new_file == NULL) {
           errno = ENOMEM;
  @@ -74,5 +76,6 @@
       old_file->atime = new_file->atime;    
       old_file->mtime = new_file->mtime;
       old_file->ctime = new_file->ctime;
  +    ap_register_cleanup(cont->pool, (void *)new_file, file_cleanup, NULL);
   }
   
  
  
  
  1.2       +15 -16    apache-apr/apr/file_io/beos/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/fileio.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- fileio.h	1999/04/23 14:50:33	1.1
  +++ fileio.h	1999/05/17 18:31:30	1.2
  @@ -62,20 +62,13 @@
   #include <time.h>
   #include <dirent.h>
   #include <sys/uio.h>
  +#include "apr_general.h"
  +#include "apr_file_io.h"
  +#include "apr_errno.h"
   
  -#define UREAD		S_IRUSR
  -#define UWRITE		S_IWUSR
  -#define UEXECUTE	S_IXUSR
  +#define ENOFILE B_ENTRY_NOT_FOUND
   
  -#define GREAD		S_IRGRP
  -#define GWRITE		S_IWGRP
  -#define GEXECUTE	S_IXGRP
  -
  -#define WREAD		S_IROTH
  -#define WWRITE		S_IWOTH
  -#define WEXECUTE	S_IXOTH
  -
  -typedef struct file_t {
  +struct file_t {
       int filedes;
       char * fname;
       int buffered;
  @@ -86,14 +79,20 @@
       time_t atime;    
       time_t mtime;
       time_t ctime;
  -} file_t;
  +};
   
  -typedef struct dir_t {
  +struct dir_t {
       char *dirname;
       DIR *dirstruct;
  -} dir_t;
  +    struct dirent *entry;
  +};
   
   typedef mode_t			fileperms_t;
  -typedef struct iovec	iovec_t;
  +struct iovec_t {
  +	struct iovec *iovec;
  +};
  +
  +ap_status_t file_cleanup(void*);
  +mode_t get_fileperms(ap_fileperms_t);
   
   #endif /* ! FILE_IO_H */
  
  
  
  1.3       +4 -6      apache-apr/apr/file_io/beos/filestat.c
  
  Index: filestat.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/filestat.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- filestat.c	1999/05/10 14:36:20	1.2
  +++ filestat.c	1999/05/17 18:31:31	1.3
  @@ -53,11 +53,12 @@
    *
    */
   
  -#include "apr_file_io.h"
  +#include "fileio.h"
   #include "apr_general.h"
  +#include "apr_file_io.h"
   #include "apr_errno.h"
   
  -ap_status_t ap_getfileinfo(char * fname, ap_file_t *thefile)
  +ap_status_t ap_getfileinfo(ap_context_t *cont, char * fname, struct file_t *thefile)
   {
       struct stat info;
       int rv = stat(fname, &info);
  @@ -78,7 +79,7 @@
       }
   }
   
  -ap_status_t ap_updatefileinfo(ap_file_t *thefile)
  +ap_status_t ap_updatefileinfo(ap_context_t *cont, struct file_t *thefile)
   {
       struct stat info;
       int rv = fstat(thefile->filedes, &info);
  @@ -98,6 +99,3 @@
           return APR_FAILURE;
       }
   }
  -
  -
  -
  
  
  
  1.4       +26 -14    apache-apr/apr/file_io/beos/open.c
  
  Index: open.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/open.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- open.c	1999/05/10 14:36:20	1.3
  +++ open.c	1999/05/17 18:31:32	1.4
  @@ -54,21 +54,36 @@
    */
   
   
  -/* BeOS port by David Reid 23 Feb 1999 */
  +// BeOS port by David Reid 23 Feb 1999
   
  -#include "apr_file_io.h"
  -#include "apr_general.h"
   #include <errno.h>
   #include <support/SupportDefs.h>
   #include <kernel/OS.h>
   #include <stdlib.h>
   #include <unistd.h>
   #include <stdio.h>
  +#include "fileio.h"
  +#include "apr_file_io.h"
  +#include "apr_general.h"
  +#include "apr_lib.h"
   
  -ap_file_t *ap_open(char *fname, ap_int32_t flag,  ap_fileperms_t mode)
  +ap_status_t file_cleanup(void *thefile)
   {
  +    struct file_t *file = thefile;
  +    if (close(file->filedes) == 0) {
  +        file->filedes = -1;
  +        return APR_SUCCESS;
  +    }
  +    else {
  +        return APR_FAILURE;
  +	/* Are there any error conditions other than EINTR or EBADF? */
  +    }
  +}
  +
  +ap_file_t *ap_open(ap_context_t *cont, char *fname, ap_int32_t flag,  ap_fileperms_t mode)
  +{
       int oflags = 0;
  -    ap_file_t *dafile = (ap_file_t *)malloc(sizeof(ap_file_t));
  +    struct file_t *dafile = (struct file_t *)ap_palloc(cont->pool, sizeof(struct file_t));
       struct stat info;
   
       if ((flag & APR_READ) && (flag & APR_WRITE)) {
  @@ -109,12 +124,11 @@
       
       if (dafile->filedes < 0) {
           dafile->filedes = -1;
  -        free(dafile->fname);
  -		free (dafile);
           return NULL;
       }
   
  -    if (ap_updatefileinfo(dafile) == APR_SUCCESS) {
  +    if (ap_updatefileinfo(cont, dafile) == APR_SUCCESS) {
  +		ap_register_cleanup(cont->pool, (void *)dafile, file_cleanup, NULL);
   		return dafile;
       }
       else {
  @@ -125,12 +139,10 @@
       }
   }
   
  -ap_status_t ap_close(ap_file_t * file)
  +ap_status_t ap_close(ap_context_t *cont, struct file_t * file)
   {
  -    if (close(file->filedes) == 0) {
  -        file->filedes = -1;
  -        free(file->fname);
  -        free(file);
  +    if (file_cleanup(file) == APR_SUCCESS) {
  +        ap_kill_cleanup(cont->pool, file, file_cleanup);
           return APR_SUCCESS;
       }
       else {
  @@ -139,7 +151,7 @@
       }
   }
   
  -ap_status_t ap_remove_file(char *path) 
  +ap_status_t ap_remove_file(ap_context_t *cont, char *path) 
   { 
       if (unlink(path) == 0) { 
           return APR_SUCCESS; 
  
  
  
  1.4       +8 -8      apache-apr/apr/file_io/beos/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/readwrite.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- readwrite.c	1999/05/10 14:36:21	1.3
  +++ readwrite.c	1999/05/17 18:31:32	1.4
  @@ -53,13 +53,14 @@
    *
    */
   
  +#include <errno.h>
  +#include <unistd.h>
  +#include "fileio.h"
   #include "apr_file_io.h"
   #include "apr_general.h"
   #include "apr_errno.h"
  -#include <errno.h>
  -#include <unistd.h>
   
  -ap_ssize_t ap_read(ap_file_t *thefile, void *buf, ap_ssize_t nbytes)
  +ap_ssize_t ap_read(ap_context_t *cont, struct file_t *thefile, void *buf, ap_ssize_t nbytes)
   {
       ap_size_t rv;
   
  @@ -73,14 +74,14 @@
       return rv;
   }
   
  -ap_ssize_t ap_write(ap_file_t *thefile, void * buf, ap_ssize_t nbytes)
  +ap_ssize_t ap_write(ap_context_t *cont, struct file_t *thefile, void * buf, ap_ssize_t
nbytes)
   {
       ap_size_t rv;
       struct stat info;
   
       if (thefile->filedes < 0) {
           errno = EBADF;
  -        return -1;
  +        return APR_FAILURE;
       }
   
       rv = write(thefile->filedes, buf, nbytes);
  @@ -94,14 +95,13 @@
       return rv;
   }	
   
  -ap_ssize_t ap_writev(ap_file_t *thefile,const ap_iovec_t *vec, ap_ssize_t iocnt)
  +ap_ssize_t ap_writev(ap_context_t *cont, struct file_t *thefile, const struct iovec_t *vec,
ap_ssize_t iocnt)
   {
   	ap_ssize_t bytes;
  -	if ((bytes = writev(thefile->filedes, vec, iocnt)) < 0){
  +	if ((bytes = writev(thefile->filedes, vec->iovec, iocnt)) < 0){
   		return APR_FAILURE;
   	}
   	else {
   		return bytes;
   	}
   }
  -
  
  
  
  1.3       +3 -2      apache-apr/apr/file_io/beos/seek.c
  
  Index: seek.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/apr/file_io/beos/seek.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- seek.c	1999/05/10 14:36:21	1.2
  +++ seek.c	1999/05/17 18:31:33	1.3
  @@ -53,11 +53,12 @@
    *
    */
   
  -#include "apr_file_io.h"
   #include <errno.h>
   #include <string.h>
  +#include "fileio.h"
  +#include "apr_file_io.h"
   
  -ap_off_t ap_seek(ap_file_t *thefile, ap_off_t offset, ap_seek_where_t where)
  +ap_off_t ap_seek(ap_context_t *cont, struct file_t *thefile, ap_off_t offset, ap_seek_where_t
where)
   {
       return lseek(thefile->filedes, offset, where);
   }
  
  
  
  1.1                  apache-apr/apr/file_io/beos/pipe.c
  
  Index: pipe.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1999 The Apache Group.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #include <errno.h>
  #include <string.h>
  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include "fileio.h"
  #include "apr_file_io.h"
  #include "apr_general.h"
  
  ap_status_t ap_create_pipe(ap_context_t *cont, struct file_t *in, struct file_t *out)
  {
      int filedes[2];
      if (pipe(filedes) == -1) {
          return APR_FAILURE;
      }
      
      in->filedes = filedes[0];
      in->fname = strdup("PIPE");
  
      out->filedes = filedes[1];
      out->fname = strdup("PIPE");
  
      return APR_SUCCESS;
  }
  
  char *ap_create_namedpipe(ap_context_t *cont, char *dirpath, ap_fileperms_t perm)
  {
      char *tmp;
      mode_t mode = get_fileperms(perm);
      tmp = tempnam(dirpath, NULL);
      if (mkfifo(tmp, mode) == -1) {
          free(tmp);
          return NULL;
      }
      return tmp;
  } 
  
  
  

Mime
View raw message