
/*****************************************************************************
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  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.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/*****************************************************************************
**
**  File:    scan_record.h
**  Date:    March 15, 2002
**
**  Author:  Brian Wotring
**  Purpose: common structures for dealing with scan data.
**
******************************************************************************/

#ifndef SCAN_RECORD_H_
#define SCAN_RECORD_H_


#define SCAN_RECORD_TYPE_UNKNOWN	0x0000
#define SCAN_RECORD_TYPE_UNIX1		0x0001
#define SCAN_RECORD_TYPE_UNIX2		0x0002
#define SCAN_RECORD_TYPE_WIN32		0x0003
#define SCAN_RECORD_TYPE_WINNT		0x0004



/* wrapper around windows file attribute flags. */

#define WIN32_FILE_ATTR_ARCHIVE        1 << 0
#define WIN32_FILE_ATTR_COMPRESSED     1 << 1
#define WIN32_FILE_ATTR_DIRECTORY      1 << 2
#define WIN32_FILE_ATTR_ENCRYPTED      1 << 3
#define WIN32_FILE_ATTR_HIDDEN         1 << 4
#define WIN32_FILE_ATTR_NORMAL         1 << 5
#define WIN32_FILE_ATTR_NOT_INDEXED    1 << 6
#define WIN32_FILE_ATTR_OFFLINE        1 << 7
#define WIN32_FILE_ATTR_READONLY       1 << 8
#define WIN32_FILE_ATTR_REPARSE_POINT  1 << 9
#define WIN32_FILE_ATTR_SPARSE_FILE    1 << 10
#define WIN32_FILE_ATTR_SYSTEM         1 << 11
#define WIN32_FILE_ATTR_TEMPORARY      1 << 12

struct attr_keywords
{
    char *word;
    int  type;
};

static struct attr_keywords win32_attr_descriptions[] =
{
    { "archive", WIN32_FILE_ATTR_ARCHIVE },
    { "compressed", WIN32_FILE_ATTR_COMPRESSED },
    { "directory", WIN32_FILE_ATTR_DIRECTORY },
    { "encrypted", WIN32_FILE_ATTR_ENCRYPTED },
    { "hidden", WIN32_FILE_ATTR_HIDDEN },
    { "normal", WIN32_FILE_ATTR_NORMAL },
    { "not_indexed", WIN32_FILE_ATTR_NOT_INDEXED },
    { "offline", WIN32_FILE_ATTR_OFFLINE },
    { "readonly", WIN32_FILE_ATTR_READONLY },
    { "reparse_point", WIN32_FILE_ATTR_REPARSE_POINT },
    { "sparse", WIN32_FILE_ATTR_SPARSE_FILE },
    { "system", WIN32_FILE_ATTR_SYSTEM },
    { "temporary", WIN32_FILE_ATTR_TEMPORARY },
    { NULL, 0 }
};


/* used to peek at type from message payloads. */

typedef struct SCAN_RECORD
{
    osi_uint16 type;

} SCAN_RECORD;

typedef struct SCAN_RECORD_UNIX1
{
    osi_uint16 type;
    osi_uint16 filter;

    char path[MAX_PATH_LENGTH+1];

    unsigned char checksum[MAX_CHECKSUM_LENGTH+1];
    osi_uint16 checksum_algorithm;

    char permissions_string[PERMISSIONS_STRING_LENGTH+1];

    char user[USERNAME_LENGTH+1];
    char group[GROUPNAME_LENGTH+1];

    osi_uint64 device;
    osi_uint64 inode;
    osi_uint64 permissions;
    osi_uint64 links;
    osi_uint64 uid;
    osi_uint64 gid;
    osi_uint64 mtime;
    osi_uint64 atime;
    osi_uint64 ctime;
    osi_uint64 device_type;
    osi_uint64 bytes;
    osi_uint64 blocks;
    osi_uint64 block_size;

} SCAN_RECORD_UNIX1;


typedef struct SCAN_RECORD_UNIX2
{
    osi_uint16 type;
    char path[MAX_PATH_LENGTH+1];

} SCAN_RECORD_UNIX2;


typedef struct SCAN_RECORD_WIN32
{
    osi_uint16 type;
    char path[MAX_PATH_LENGTH+1];

} SCAN_RECORD_WIN32;

typedef struct SCAN_RECORD_WINNT
{
    osi_uint16 type;
    osi_uint16 filter;

    char path[MAX_PATH_LENGTH+1];

    unsigned char checksum[MAX_CHECKSUM_LENGTH+1];
    osi_uint16 checksum_algorithm;

    char owner[USERNAME_LENGTH+1];
    char owner_sid[SID_LENGTH+1];

    char group[GROUPNAME_LENGTH+1];
    char group_sid[SID_LENGTH+1];

    osi_uint64 mtime;
    osi_uint64 atime;
    osi_uint64 ctime;

    osi_uint64 bytes;
    osi_uint64 device;
    osi_uint64 attributes;

} SCAN_RECORD_WINNT;


typedef struct SCAN_RESULTS
{
    osi_uint32 files_encountered;
    osi_uint32 files_scanned;

    osi_uint32 symlinks_encountered;
    osi_uint32 symlinks_followed;

    osi_uint32 files_unreadable;
    osi_uint32 directories_unreadable;
    osi_uint32 symlinks_unreadable;

    osi_uint32 start_time;
    osi_uint32 stop_time;
    
    osi_uint16 record_type;
    
} OSI_SCAN_RESULTS;

/* scan record functions. */

SCAN_RECORD * initialize_scan_record( SCAN_RECORD *scan_record,
                                      osi_uint16 type );

/* convert appropriate fields to and from network byte order. */

void wrap_scan_record( SCAN_RECORD *scan_record );
void unwrap_scan_record( SCAN_RECORD *scan_record );

void wrap_scan_results( OSI_SCAN_RESULTS *scan_results );
void unwrap_scan_results( OSI_SCAN_RESULTS *scan_results );

int pack_scan_record( SCAN_RECORD *scan_record, unsigned char *buffer,
                      int buffer_size );

osi_bool unpack_scan_record( SCAN_RECORD *scan_record,
                             const unsigned char *buffer, int buffer_size );

void print_scan_record( SCAN_RECORD *scan_record );
void print_scan_results( OSI_SCAN_RESULTS *scan_results );

int determine_scan_record_size( SCAN_RECORD *scan_record );
int determine_scan_record_size_from_type( int type );

char * get_scan_record_path( SCAN_RECORD *scan_record );
char * get_scan_record_name_from_type( osi_uint16 type );

void get_win32_file_attr_delta_string( osi_uint64 before, osi_uint64 after,
                                       char *buffer, int buffer_size );


#endif


