/***********************************************************/
/*                                                         */
/*        registry.h  - Bad Seal registry functions        */
/*                                                         */
/*                          version 0.3                    */
/*                                                         */
/*                    Copyright (C) 2001                   */
/*          by Kostas Michalopoulos aka Bad Sector         */
/*                                                         */
/* WWW: http://www.badseal.org/                            */
/* e-mail: michalopoylos@hotmail.com                       */
/*                                                         */
/***********************************************************/

#ifndef __REGISTRY_H_INCLUDED__
#define __REGISTRY_H_INCLUDED__

/* Default registry file. Default is badseal.reg and this value is
 recommended for all SEAL/BadSeal programs for better compatibility
 between versions and distributions. */

#define default_registry_file "badseal.reg"

/* Key types */
#define KT_UNKNOWN      0   // unknown key type (not loaded or error)
#define KT_NODATA       1   // doesn't contain data
#define KT_BYTE         2   // 8 bit unsigned integer
#define KT_SMALL        3   // 16 bit integer
#define KT_INTEGER      4   // 32 bit integer
#define KT_BIG          5   // 64 bit integer
#define KT_FLOAT        6   // 32 bit float point number (real)
#define KT_STRING       7   // null terminated string (up to 255 characters)
#define KT_DATA       127   // data (up to 256 bytes)
#define KT_LINK       254   // link to another key   - not implemented yet
#define KT_DELETED    255   // deleted key

/* error codes that functions can return */
#define RE_UNKOWN               0   // unknown error
#define RE_SUCCESS              1   // no error
#define RE_KEY_NOT_FOUND        2   // key not found
#define RE_PATH_NOT_FOUND       3   // path in registry not found
#define RE_READ_ONLY_KEY        4   // tried to write on a read-only key
#define RE_NO_KEY_SPECIFIED     5   // no key has specified
#define RE_ROOT_KEY_SPECIFIED   6   // tried to write/delete a root key

/* standard keys */
#define KEY_USERS       "USERS"     // Settings depending on user
#define KEY_CURRENT     "CURRENT"   // Use this if you want to save a setting
                                    // for your program.
#define KEY_GLOBAL      "GLOBAL"    // Global settings for all users
#define KEY_CONFIG      "CONFIG"    // SEAL configuration
#define KEY_SOFTWARE    "SOFTWARE"  // Place for SEAL software
#define KEY_SYSTEM      "SYSTEM"    // System place (includes seal/kernel info)

/* t_registry_key struct is key record in registry file */
typedef struct t_registry_key
{
  char name[128];       // name
  int type;             // type
  char data[256];       // data (depends on type)
  int size;             // size in bytes

  int parent;           // parent's position
  int child;            // first child's position (if no childs, then child = -1)
  int prev;             // previus child of parent
  int next;             // next child of parent

  char reserved[102];   // reserved for future use
} t_registry_key;

/* t_registry_get_info is used from get_data_and_type function */
typedef struct t_registry_get_info
{
  char data[256];       // key data
  int type;             // key type
  int size;             // key size in bytes
  int err;              // if any error occurs (check it always)
  char reserved[32];    // reserved for future use
} t_registry_get_info;

/* t_registry_search is used from reg_find_first and reg_find_next */
typedef struct t_registry_search *p_registry_search;
typedef struct t_registry_search
{
  t_registry_key key;   // key info
  char *parent_name;    // key's parent name (the place where we're searching)
    /* note: for stability reasons, reg_find_first allocates memory to store
    parent_name's value. This memory is freed when reg_find_next reaches at
    the end. However sometimes you need only the first child or you don't
    need all childs. In that case you have to free this value by yourself */
  char *name;           // full key path (Warning! Must be FREED after use)
  int pos;              // key's position
  char reserved[32];    // reserved for future use
} t_registry_search;

/* just if you want to know registry file's name */
extern char *registry_file;


/***********************
*  Registry functions  *
***********************/

/*
Combines path and key and returns the result.
Example:
    key_in_path("system/seal", "distribution")

    returns "system/seal/distribution"

you must free allocated memory after
*/
char *key_in_path(char *path, char *key);

/*
Returns 1 (true) if key exists, else 0 (false).
*/
int key_exists(char *key);

/*
Creates a new key named `name' in `path'. if 'use_links' is 1 then
uses links for finding path. F.e.

key 'current' is defined as link to 'users/default'. if you want to
create a key in 'current' you must enable links or you'll just waste
disk space because created key will not be visible.

If success returns RE_SUCCESS
*/
int create_key_ex(char *path, char *name, int use_links);

/*
Like create_key_ex but always uses links.
*/
int create_key(char *path, char *name);

/*
Creates a new link named `name' to a key `dest'. Link key is created
in `path'
*/
int create_link_key(char *path, char *name, char *dest);

/*
Changes/sets the data of key `key' to `data' and it's type to `type'.
`size' is the size of `data' in bytes.
*/
int set_data_and_type(char *key, int type, void *data, int size);

/*
Sets key `key''s data to `str' and it's type to KT_STRING
*/
int set_key(char *key, char *str);

/*
Sets key `key''s data to `b' and it's type to KT_BYTE
*/
int set_key_byte(char *key, unsigned char b);

/*
Sets key `key''s data to `s' and it's type to KT_SMALL
*/
int set_key_small(char *key, short s);

/*
Sets key `key''s data to `i' and it's type to KT_INTEGER
*/
int set_key_integer(char *key, long i);

/*
Sets key `key''s data to `big' and it's type to KT_BIG
*/
int set_key_big(char *key, long long big);

/*
Sets key `key''s data to `f' and it's type to KT_FLOAT
*/
int set_key_float(char *key, float f);

/*
Sets key `key''s data to `data', it's type to KT_DATA and it's size to `size'
*/
int set_key_data(char *key, void *data, int size);

/*
Returns data, type and size from key `key'.
*/
t_registry_get_info get_data_and_type(char *key);

/*
Returns key `key''s value as string
*/
char *get_key(char *key);

/*
Returns key `key''s value as byte (char)
*/
char get_key_byte(char *key);

/*
Returns key `key''s value as small (short)
*/
short get_key_small(char *key);

/*
Returns key `key''s value as integer (long)
*/
long get_key_integer(char *key);

/*
Returns key `key''s value as big integer (long long)
*/
long long get_key_big(char *key);

/*
Returns key `key''s value as float
*/
float get_key_float(char *key);

/*
Returns key `key''s value as data
*/
void *get_key_data(char *key);

/*
Returns key `key''s size (usually used with get_key_data)
*/
int get_key_size(char *key);

/*
Deletes key `key' and it's childs.
*/
int delete_key(char *key);

/*
With reg_find_next is used to return all childs of key `path'. Returns 0
if no key found or there are no childs. Information about current key
is stored in `info'.
*/
int reg_find_first(char *path, p_registry_search info);

/*
See reg_find_first for info about using those two functions.
*/
int reg_find_next(p_registry_search info);

#endif

