libclamav/fmap.h
34c71837
 /*
  *  Copyright (C) 2009 Sourcefire, Inc.
  *
  *  Authors: aCaB <acab@clamav.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
  */
 
c124d71a
 #ifndef __FMAP_H
 #define __FMAP_H
34c71837
 
b28a0d6f
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
ce0c204a
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
b1948471
 #include <time.h>
d2bfc86a
 #include <string.h>
cceea458
 #include "cltypes.h"
d2bfc86a
 #include "clamav.h"
cceea458
 
d2bfc86a
 struct cl_fmap;
 typedef cl_fmap_t fmap_t;
 
 struct cl_fmap {
448f2ee9
     /* handle interface */
     void *handle;
     clcb_pread pread_cb;
 
     /* internal */
cceea458
     time_t mtime;
     unsigned int pages;
     unsigned int hdrsz;
     unsigned int pgsz;
     unsigned int paged;
6372c0dc
     unsigned short aging;
448f2ee9
     unsigned short dont_cache_flag;
2672a22a
     unsigned short handle_is_fd;
448f2ee9
 
     /* memory interface */
2672a22a
     const void *data;
448f2ee9
 
     /* common interface */
87f76399
     size_t offset;/* file offset */
     size_t nested_offset;/* buffer offset for nested scan*/
     size_t real_len;/* amount of data mapped from file, starting at offset */
     size_t len;/* length of data accessible via current fmap */
 
     /* real_len = nested_offset + len
      * file_offset = offset + nested_offset + need_offset
      * maximum offset, length accessible via fmap API: len
      * offset in cached buffer: nested_offset + need_offset
      *
      * This allows to scan a portion of an already mapped file without dumping
      * to disk and remapping (for uncompressed archives for example) */
d2bfc86a
 
     /* vtable for implementation */
     void        (*unmap)(fmap_t*);
     const void* (*need)(fmap_t*, size_t at, size_t len, int lock);
     const void* (*need_offstr)(fmap_t*, size_t at, size_t len_hint);
     const void* (*gets)(fmap_t*, char *dst, size_t *at, size_t max_len);
     void        (*unneed_off)(fmap_t*, size_t at, size_t len);
b0fc218f
 #ifdef _WIN32
8618abc1
     HANDLE fh;
     HANDLE mh;
ee1b2a6c
 #endif
cf069964
     uint32_t placeholder_for_bitmap;
d2bfc86a
 };
34c71837
 
49cc1e3c
 fmap_t *fmap(int fd, off_t offset, size_t len);
a0c38197
 fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty);
d2bfc86a
 
 static inline void funmap(fmap_t *m)
 {
     m->unmap(m);
 }
 
 static inline const void *fmap_need_off(fmap_t *m, size_t at, size_t len)
 {
     return m->need(m, at, len, 1);
 }
 
 static inline const void *fmap_need_off_once(fmap_t *m, size_t at, size_t len)
 {
     return m->need(m, at, len, 0);
 }
 
81e57728
 static inline size_t fmap_ptr2off(const fmap_t *m, const void *ptr)
 {
caa00029
     return (m->data ?
81e57728
 	  (const char*)ptr - (const char*)m->data
caa00029
 	 :(const char*)ptr - (const char*)m - m->hdrsz) - m->nested_offset;
81e57728
 }
 
f304dc68
 static inline const void *fmap_need_ptr(fmap_t *m, const void *ptr, size_t len)
d2bfc86a
 {
81e57728
     return m->need(m, fmap_ptr2off(m, ptr), len, 1);
d2bfc86a
 }
 
f304dc68
 static inline const void *fmap_need_ptr_once(fmap_t *m, const void *ptr, size_t len)
d2bfc86a
 {
81e57728
     return m->need(m, fmap_ptr2off(m, ptr), len, 0);
d2bfc86a
 }
 
 static inline void fmap_unneed_off(fmap_t *m, size_t at, size_t len)
 {
     m->unneed_off(m, at, len);
 }
 
f304dc68
 static inline void fmap_unneed_ptr(fmap_t *m, const void *ptr, size_t len)
d2bfc86a
 {
81e57728
     fmap_unneed_off(m, fmap_ptr2off(m, ptr), len);
d2bfc86a
 }
 
 static inline int fmap_readn(fmap_t *m, void *dst, size_t at, size_t len)
 {
     const void *src;
 
dcab4a6c
     if(at == m->len || !len)
d2bfc86a
 	return 0;
     if(at > m->len)
 	return -1;
     if(len > m->len - at)
 	len = m->len - at;
     src = fmap_need_off_once(m, at, len);
     if(!src)
 	return -1;
     memcpy(dst, src, len);
     return len;
 }
 
f304dc68
 static inline const void *fmap_need_str(fmap_t *m, const void *ptr, size_t len_hint)
d2bfc86a
 {
81e57728
     return m->need_offstr(m, fmap_ptr2off(m, ptr), len_hint);
d2bfc86a
 }
 
 static inline const void *fmap_need_offstr(fmap_t *m, size_t at, size_t len_hint)
 {
     return m->need_offstr(m, at, len_hint);
 }
 
 static inline const void *fmap_gets(fmap_t *m, char *dst, size_t *at, size_t max_len) {
     return m->gets(m, dst, at, max_len);
 }
944febe9
 
 static inline const void *fmap_need_off_once_len(fmap_t *m, size_t at, size_t len, size_t *lenout)
 {
4c30fd8a
     const void *p;
944febe9
     if(at >= m->len) {
 	*lenout = 0;
e2f1541c
 	return (void*)0xE0F00000;/* EOF, not read error */
944febe9
     }
     if(len > m->len - at)
 	len = m->len - at;
4c30fd8a
     p = fmap_need_off_once(m, at, len);
d2bfc86a
     *lenout = p ? len : 0;
4c30fd8a
     return p;
944febe9
 }
 
 static inline const void *fmap_need_ptr_once_len(fmap_t *m, const void *ptr, size_t len, size_t *lenout)
 {
81e57728
     return fmap_need_off_once_len(m, fmap_ptr2off(m, ptr), len, lenout);
944febe9
 }
 
d2bfc86a
 /* deprecated */
b4d884d9
 int fmap_fd(fmap_t *m);
 
c124d71a
 #endif