/*****************************************************************************
 * Filename:    options.h                                                    *
 * Description: Declaration of configuration structures                      *
 * Copyright:   2009 by Alexander Motzkau                                    *
 *****************************************************************************/

#ifndef __OPTIONS_H__
#define __OPTIONS_H__

#include <unistd.h>

struct storage_entry
{
    char *name;
    char *cipher;
    unsigned long size; /* 0 -> autodetect */
    unsigned long start;
    
    struct storage_entry *next;
};

struct storage
{
    char *device;
    struct storage_entry *entries;
    
    struct storage *next;
};

struct storage_block
{
    struct storage* device;
    struct storage_entry* entry;

    struct storage_block* next;
};

enum on_state
{
    on_success, on_failure, os_always
};

enum on_mode
{
    on_map, on_mount, om_always, on_remove
};

enum bool
{
    false = 0, true = 1
};

enum tristate
{
    t_false = 0, t_true = 1, t_unspecified = 2
};

enum keytype
{
    ref, composite, passphrase, file, program, literal
};

enum nlmode
{
    nl_unchanged, nl_add, nl_remove
};

enum ttytype
{
    current, fixed, vt, xterm
};

struct command
{
    enum on_state on_state;
    enum on_mode on_mode;
    enum bool ignore_status;
    enum bool needtty;
    char *uid;
    char *gid;
    
    char *cmd;
    
    struct command *next;
};

struct key
{
    char *id;
    enum keytype type;
    unsigned int len; /* 0 -> default (256 bits) */
    
    struct key *next;
    struct key *subkeys;
    
    char *algo;
    char *value;

    struct command *preexec;
    struct command *postexec;

    enum bool ignore_status;
    enum bool needtty;
    enum nlmode newline;
    char *uid;
    char *gid;
    
    int retry;
    int vt100reserve;

    void *result;
    int resultlen; /* key length in bytes */
};

struct access
{
    enum bool allow;
    char *uid;
    char *gid;
    
    struct access *next;
    struct access *subrules;
};

struct map_options
{
    enum tristate fsck;
    enum tristate mount;
    enum tristate ro;

    unsigned long mode;

    char *uid;
    char *gid;
};

struct map
{
    char *name;
    char *dname;

    struct map_options opts;

    char *point;
    char *fs;
    char *options;
    
    struct command *preexec;
    struct command *postexec;
    
    struct key *key;
    struct access *access;
    
    enum bool done; /* set by action.c */
    
    struct map *next;
};

struct call
{
    char *action;
    char *filename;
    
    struct map_options overrides;

    struct call *next;
};

struct action
{
    char *name;
    
    struct command *preexec;
    struct command *postexec;
    
    struct key *key;
    struct access *access;
    
    struct map *mappings;
    struct call *calls;
    
    enum bool done;
    
    struct action *next;
};

struct tty
{
    enum ttytype type;
        
    struct command *preexec;
    struct command *postexec;
    
    char *dev;
    char *cmd;
    char *display;
    char *authority;
    
    int min;
    
    struct tty *next;
};

struct configuration
{
    struct tty *ttys;
    struct action *actions;
    struct storage *storage;
    struct access *access;
    
    void *action_tree;
    void *storage_tree;
    void *key_tree;
    
    struct key* keys_in_tree; /* Just for memory management. */
    
    enum bool fsck;
    enum bool mount;
    
    enum on_mode mode; /* Set by main(). */
    enum bool noenc;   /* Set by main(). */
    enum bool suid;    /* Set by main() if running with setuid bit. */
    enum bool sgid;    /* Set by main() if running with setgid bit. */
    uid_t caller_uid;  /* Set by main() if running with setuid bit. */
    gid_t caller_gid;  /* Set by main() if running with setgid bit. */
    uid_t priv_uid;    /* Set by main() if running with setuid bit. */
    gid_t priv_gid;    /* Set by main() if running with setgid bit. */
};

enum bool complete_config(struct configuration* config);

struct action* find_action(char *name, struct configuration* config);
struct storage_block* find_storage(char *name, struct configuration* config);
struct key* find_key(char *name, struct configuration* config);
struct key* insert_key(struct key* key, struct configuration* config);
enum bool check_access_list(struct access* ac, struct configuration* config, enum bool default_result);
struct map_options* copy_map_options(struct map_options* co);

void free_entry(struct storage_entry* entry);
void free_storage(struct storage* storage);
void free_key(struct key *key);
void free_command(struct command *cmd);
void free_access(struct access *ac);
void free_map(struct map *map);
void free_map_options(struct map_options* opt);
void free_call(struct call *call);
void free_action(struct action* act);
void free_tty(struct tty* tty);
void free_config(struct configuration *config);
#endif
