/* pgg.h - general include file for libpgg usage
 *      Copyright (C) 1999 Michael Roth <mroth@gnupg.org>
 *
 * This file is part of PGG (Privacy Guard Glue).
 *
 * PGG is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * PGG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */


#ifndef PGG_INCLUDE_PGG_H_19990604145212
#define PGG_INCLUDE_PGG_H_19990604145212


#ifdef __cplusplus
extern "C" {
#endif


/*
 * PGG object are opaque. The only way to manipulate them is 
 * to use the provided functions.
 */
typedef struct { int dummy; } * PggBuffer;
typedef struct { int dummy; } * PggInput;
typedef struct { int dummy; } * PggExe;
typedef struct { int dummy; } * PggOutopts;
typedef struct { int dummy; } * PggStdio;
typedef struct { int dummy; } * PggOutput;
typedef struct { int dummy; } * PggSymcrypt;
typedef struct { int dummy; } * PggAlgo;
typedef struct { int dummy; } * PggConfig;
typedef struct { int dummy; } * PggPasscache;
typedef struct { int dummy; } * PggSign;
typedef struct { int dummy; } * PggEncrypt;
typedef struct { int dummy; } * PggDecrypt;
typedef struct { int dummy; } * PggVerify;
typedef struct { int dummy; } * PggSiginfo;
typedef struct { int dummy; } * PggPubring;
typedef struct { int dummy; } * PggPubkey;
typedef struct { int dummy; } * PggSecring;
typedef struct { int dummy; } * PggSeckey;


/*
 * These are primary error numbers. They describe error classes.
 */
typedef enum {
    PGG_ERROR_SUCCESS	= 0,		/* Succes, no error at all */
    PGG_ERROR_UNKNOWN,			/* Generic, unknown error */
    PGG_ERROR_ARGUMENT,			/* An argument was invalid */
    PGG_ERROR_OBJECT,			/* An object was wrong */
    PGG_ERROR_GNUPG,			/* Execution of GnuPG failed */
    PGG_ERROR_RESOURCE,			/* No more resources */
    PGG_ERROR_REQUEST,			/* A request couldn't be fullfilled */
    PGG_ERROR_INTERNAL,			/* An internal error occured */
    PGG_ERROR_CRYPT			/* An encrypting/decrypting specific error occured */
} PggError;


/*
 * Sub error codes desribe an error more precisly
 */
typedef enum {
    PGG_SUBERR_NONE = 0,		/* No sub error */
    
    /*
     * Sub codes for encryption or decryption problems: PGG_ERROR_CRYPT
     */
    PGG_SUBERR_PASSPHRASE,		/* A passphrase was wrong or missed */
    PGG_SUBERR_NOPUBKEY,		/* A public key was missed */
    PGG_SUBERR_NOSECKEY,		/* A secret key was missed */
    
    /*
     * Sub codes for request which couldn't be fullfilled: PGG_ERROR_REQUEST
     */
    PGG_SUBERR_NOTFOUND,		/* Something you asked for could not be found (key, ...) */
    PGG_SUBERR_NOTSET,			/* A value the caller asked for was not set */
    PGG_SUBERR_STATE,			/* The state of the object was not suited for the request */
    
    /*
     * Sub error codes for invalid arguments: PGG_ERROR_ARGUMENT
     */
    PGG_SUBERR_NULLPTR,			/* An argument was a forbidden null pointer */
    PGG_SUBERR_RANGE,			/* An index for something was out of valid bounds */
    PGG_SUBERR_TOLARGE,			/* A string or something else was to long or to large */
    PGG_SUBERR_TOSMALL,			/* A string or somthingg else was to short or to small */
    PGG_SUBERR_VALUE,			/* A value was invalid. For example an invalid cipher id or something else */
    
    /*
     * Sub codes for wrong objects: PGG_ERROR_OBJECT
     */
    PGG_SUBERR_NULLOBJ,			/* An object was null */
    PGG_SUBERR_MAGIC,			/* The magic value of an object was wrong (false type casts) */
    PGG_SUBERR_REFCOUNT,		/* The reference counter of an object was 0. This could cause core dumps! */
    
    /*
     * Errors on excuting GnuPG: PGG_ERROR_GNUPG
     */
    PGG_SUBERR_DIED,			/* GnuPG died unexpected */
    PGG_SUBERR_EXECUTE,			/* Gpg binary not executable */
    PGG_SUBERR_UNEXPECTED,		/* An unexpected event/behaviour from GnuPG */
    PGG_SUBERR_RETURNCODE,		/* Unexpected return code */
    
    /*
     * Errors for non available resources: PGG_ERROR_RESOURCE
     */
    PGG_SUBERR_MEMORY,			/* No more memory available */
    PGG_SUBERR_PIPE,			/* No pipe available */
    PGG_SUBERR_PROCESS			/* No process available to create (fork() for example)*/

} PggSuberr;



typedef struct {
    PggError		error;
    PggSuberr		suberr;
} PggErrenv[1];


extern void			pgg_errenv_reset(PggErrenv errenv);
extern PggError			pgg_errenv_get_error(PggErrenv errenv);
extern PggSuberr		pgg_errenv_get_suberr(PggErrenv errenv);
extern void			pgg_errenv_set(PggErrenv errenv, PggError error, PggSuberr suberr);
extern void			pgg_errenv_copy(PggErrenv dest, PggErrenv source);
extern int			pgg_errenv_is_set(PggErrenv errenv);


typedef enum {
    PGG_KEYTYPE_ERROR = -1,
    PGG_KEYTYPE_UNKNOWN = 0,
    PGG_KEYTYPE_RSA,            /* RSA Key */
    PGG_KEYTYPE_DSA,            /* DSA Key, sign only */
    PGG_KEYTYPE_ELGAMAL_E,      /* Elgamal, encrypt only */
    PGG_KEYTYPE_ELGAMAL         /* Elgamal, signing and encrypting */
} Pgg_Keytype;


typedef enum {
    PGG_COMPRESS_ERROR = -1,
    PGG_COMPRESS_USEPREFS,
    PGG_COMPRESS_NONE,
    PGG_COMPRESS_PGPZLIB,
    PGG_COMPRESS_RFCZLIB
} Pgg_Compress;


typedef enum {
    PGG_CIPHER_ERROR = -1,
    PGG_CIPHER_USEPREFS,
    PGG_CIPHER_IDEA,
    PGG_CIPHER_3DES,
    PGG_CIPHER_CAST5,
    PGG_CIPHER_BLOWFISH,
    PGG_CIPHER_TWOFISH
} Pgg_Cipher;


typedef enum {
    PGG_DIGEST_ERROR = -1,
    PGG_DIGEST_USEPREFS,
    PGG_DIGEST_MD5,
    PGG_DIGEST_SHA1,
    PGG_DIGEST_RIPEMD160
} Pgg_Digest;


typedef enum {
    PGG_PACKET_ERROR = -1,
    PGG_PACKET_OPENPGP = 1,
    PGG_PACKET_V3SIGS,
    PGG_PACKET_RFC1991
} Pgg_Packet;


typedef enum {
    PGG_S2K_ERROR = -1,
    PGG_S2K_SIMPLE = 1,
    PGG_S2K_SALTED,
    PGG_S2K_ITERATEDSALTED
} Pgg_S2k;


typedef enum
{
    PGG_TRUST_ERROR = -1,
    PGG_TRUST_UNDEFINED = 0,
    PGG_TRUST_UNKNOWN,
    PGG_TRUST_NONE,
    PGG_TRUST_MARGINAL,
    PGG_TRUST_FULL,
    PGG_TRUST_ULTIMATE
} Pgg_Trust;


typedef enum
{
    PGG_VALIDITY_ERROR = -1,
    PGG_VALIDITY_UNDEFINED = 0,
    PGG_VALIDITY_DISABLED,
    PGG_VALIDITY_REVOKED,
    PGG_VALIDITY_EXPIRED,
    PGG_VALIDITY_UNKNOWN,
    PGG_VALIDITY_NONE,
    PGG_VALIDITY_MARGINAL,
    PGG_VALIDITY_FULL,
    PGG_VALIDITY_ULTIMATE,
} Pgg_Validity;


typedef enum
{
    PGG_SIGN_ERROR = -1,		/* Error indicator */
    PGG_SIGN_NORMAL = 0,		/* Normal mode. Result is a packet including message and signature (default) */
    PGG_SIGN_DETACHED,			/* Detached signature. Output is the signature without the message */
    PGG_SIGN_CLEAR,			/* Clearsign a message. (Used for emails and so on) */
} Pgg_Sign;


typedef enum
{
    PGG_ESCAPE_ERROR = -1,		/* Error indicator */
    PGG_ESCAPE_NONE = 0,		/* Don't alter the input in any way (Default) */
    PGG_ESCAPE_FROM,			/* Escape line beginning with "From " */
    PGG_ESCAPE_NOTDASH 			/* Don't escape dashes. (Special mode for patch files) */
} Pgg_Escape;




extern PggBuffer		pgg_buffer_new(PggErrenv errenv);
extern PggBuffer		pgg_buffer_clone(PggBuffer buf, PggErrenv errenv);
extern void			pgg_buffer_addref(PggBuffer buf, PggErrenv errenv);
extern void			pgg_buffer_release(PggBuffer buf, PggErrenv errenv);

extern void			pgg_buffer_reclaim(PggBuffer buf, PggErrenv errenv);

extern void			pgg_buffer_append(PggBuffer buf, const void * data, long amount, PggErrenv errenv);
extern void			pgg_buffer_insert(PggBuffer buf, long offset, const void * data, long amount, PggErrenv errenv);
extern void			pgg_buffer_delete(PggBuffer buf, long offset, long amount, PggErrenv errenv);
extern void			pgg_buffer_clear(PggBuffer buf, PggErrenv errenv);

extern void			pgg_buffer_set_size(PggBuffer buf, long size, PggErrenv errenv);
extern void			pgg_buffer_set_wipeout(PggBuffer buf, int yesno, PggErrenv errenv);
extern void			pgg_buffer_set_maxsize(PggBuffer buf, long maxsize, PggErrenv errenv);
extern void			pgg_buffer_ensure_capacity(PggBuffer buf, long capacity, PggErrenv errenv);

extern long			pgg_buffer_get_maxsize(PggBuffer buf, PggErrenv errenv);
extern long			pgg_buffer_get_capacity(PggBuffer buf, PggErrenv errenv);
extern long			pgg_buffer_get_size(PggBuffer buf, PggErrenv errenv);
extern void *			pgg_buffer_get_data(PggBuffer buf, PggErrenv errenv);

extern void			pgg_buffer_detach_data(PggBuffer buf, PggErrenv errenv);
extern void			pgg_buffer_atach_data(PggBuffer buf, void * data, long size, PggErrenv errenv);




extern PggInput			pgg_input_new(PggErrenv errenv);
extern PggInput			pgg_input_clone(PggInput in, PggErrenv errenv);
extern void			pgg_input_addref(PggInput in, PggErrenv errenv);
extern void			pgg_input_release(PggInput in, PggErrenv errenv);

extern void			pgg_input_set_filename(PggInput in, const char *filename, PggErrenv errenv);
extern void			pgg_input_set_buffer(PggInput in, PggBuffer buf, PggErrenv errenv);
extern void			pgg_input_set_fd(PggInput in, int fd, PggErrenv errenv);
extern void			pgg_input_set_rawdata(PggInput in, void *data, long amount, PggErrenv errenv);

extern void			pgg_input_open(PggInput in, PggErrenv errenv);
extern long			pgg_input_read(PggInput in, void *data, long amount, PggErrenv errenv);
extern void			pgg_input_close(PggInput in, PggErrenv errenv);




typedef enum {
    PGG_EVENT_ERROR = -1,			/* An error occured */
    PGG_EVENT_NONE = 0,				/* No event at all */
    PGG_EVENT_FINISHED,				/* Execution finished */
    PGG_EVENT_STATUS				/* New status code available */
} Pgg_Event;


typedef enum {
    PGG_STATUS_ERROR = -1,			/* An error occured */
    PGG_STATUS_NONE = 0,			/* No status message at all */
    PGG_STATUS_GOODSIG,
    PGG_STATUS_BADSIG,
    PGG_STATUS_ERRSIG,
    PGG_STATUS_VALIDSIG,
    PGG_STATUS_SIG_ID,
    PGG_STATUS_ENC_TO,
    PGG_STATUS_NODATA,
    PGG_STATUS_TRUST_UNDEFINED,
    PGG_STATUS_TRUST_NEVER,
    PGG_STATUS_TRUST_MARGINAL,
    PGG_STATUS_TRUST_FULLY,
    PGG_STATUS_TRUST_ULTIMATE,
    PGG_STATUS_SIGEXPIRED,
    PGG_STATUS_KEYREVOKED,
    PGG_STATUS_BADARMOR,
    PGG_STATUS_RSA_OR_IDEA,
    PGG_STATUS_SHM_INFO,
    PGG_STATUS_SHM_GET,
    PGG_STATUS_SHM_GET_BOOL,
    PGG_STATUS_SHM_GET_HIDDEN,
    PGG_STATUS_NEED_PASSPHRASE,
    PGG_STATUS_NEED_PASSPHRASE_SYM,
    PGG_STATUS_MISSING_PASSPHRASE,
    PGG_STATUS_BAD_PASSPHRASE,
    PGG_STATUS_GOOD_PASSPHRASE,
    PGG_STATUS_DECRYPTION_FAILED,
    PGG_STATUS_DECRYPTION_OKAY,
    PGG_STATUS_NO_PUBKEY,
    PGG_STATUS_NO_SECKEY,
    PGG_STATUS_UNKNOWN,				/* unknown status message */
} Pgg_Status;


typedef long (*PggExe_ReadCB)(void *opaque, void *data, long amount);
typedef long (*PggExe_WriteCB)(void *opaque, void *data, long amount);


extern PggExe			pgg_exe_new(PggErrenv errenv);
extern PggExe			pgg_exe_clone(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_addref(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_release(PggExe exe, PggErrenv errenv);

extern void 			pgg_exe_set_gpgpath(PggExe exe, const char *gpgpath, PggErrenv errenv);
extern const char *		pgg_exe_get_gpgpath(PggExe exe, PggErrenv errenv);

extern int			pgg_exe_get_return_code(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_start(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_add_arg(PggExe exe, const char *arg, PggErrenv errenv);
extern void			pgg_exe_abort(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_request_status(PggExe exe, PggErrenv errenv);
extern Pgg_Status		pgg_exe_get_status_code(PggExe exe, PggErrenv errenv);
extern const char *		pgg_exe_get_status_arg(PggExe exe, PggErrenv errenv);
extern Pgg_Event		pgg_exe_wait_event(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_request_shm(PggExe exe, PggErrenv errenv);
extern void			pgg_exe_reply_str(PggExe exe, const char * reply, PggErrenv errenv);
extern void			pgg_exe_reply_bool(PggExe exe, int yesno, PggErrenv errenv);

extern void			pgg_exe_set_read_cb(PggExe exe, PggExe_ReadCB cb, void *opaque, PggErrenv errenv);
extern void			pgg_exe_set_write_cb(PggExe exe, PggExe_WriteCB cb, void *opaque, PggErrenv errenv);




#define PGG_OUTOPTS_COMMENT_NONE	((const char *)0)
#define PGG_OUTOPTS_COMMENT_DEFAULT	((const char *)1)

extern PggOutopts		pgg_outopts_new(PggErrenv errenv);
extern PggOutopts		pgg_outopts_clone(PggOutopts oo, PggErrenv errenv);
extern void			pgg_outopts_addref(PggOutopts oo, PggErrenv errenv);
extern void			pgg_outopts_release(PggOutopts oo, PggErrenv errenv);

extern void			pgg_outopts_set_comment(PggOutopts oo, const char *text, PggErrenv errenv);
extern void			pgg_outopts_set_version(PggOutopts oo, int yesno, PggErrenv errenv);
extern void			pgg_outopts_set_armor(PggOutopts oo, int yesno, PggErrenv errenv);

extern const char *		pgg_outopts_get_comment(PggOutopts oo, PggErrenv errenv);
extern int			pgg_outopts_get_version(PggOutopts oo, PggErrenv errenv);
extern int			pgg_outopts_get_armor(PggOutopts oo, PggErrenv errenv);

extern void			pgg_outopts_setup_exe(PggOutopts oo, PggExe exe, PggErrenv errenv);




extern PggStdio			pgg_stdio_new(PggErrenv errenv);
extern PggStdio			pgg_stdio_clone(PggStdio io, PggErrenv errenv);
extern void			pgg_stdio_addref(PggStdio io, PggErrenv errenv);
extern void			pgg_stdio_release(PggStdio io, PggErrenv errenv);

extern void			pgg_stdio_set_input(PggStdio io, PggInput input, PggErrenv errenv);
extern void			pgg_stdio_set_output(PggStdio io, PggOutput output, PggErrenv errenv);
extern void			pgg_stdio_set_outopts(PggStdio io, PggOutopts opts, PggErrenv errenv);
extern void			pgg_stdio_set_textmode(PggStdio io, int yesno, PggErrenv errenv);

extern PggInput			pgg_stdio_get_input(PggStdio io, PggErrenv errenv);
extern PggOutput		pgg_stdio_get_output(PggStdio io, PggErrenv errenv);
extern PggOutopts		pgg_stdio_get_outopts(PggStdio io, PggErrenv errenv);
extern int			pgg_stdio_get_textmode(PggStdio io, PggErrenv errenv);

extern void			pgg_stdio_set_input_filename(PggStdio io, const char *filename, PggErrenv errenv);
extern void			pgg_stdio_set_input_buffer(PggStdio io, PggBuffer buffer, PggErrenv errenv);
extern void			pgg_stdio_set_input_fd(PggStdio io, int fd, PggErrenv errenv);
extern void			pgg_stdio_set_input_rawdata(PggStdio io, void *data, long amount, PggErrenv errenv);

extern void			pgg_stdio_set_output_filename(PggStdio io, const char *filename, PggErrenv errenv);
extern void			pgg_stdio_set_output_buffer(PggStdio io, PggBuffer buffer, PggErrenv errenv);
extern void			pgg_stdio_set_output_fd(PggStdio io, int fd, PggErrenv errenv);

extern void			pgg_stdio_set_output_filename_ascext(PggStdio io, const char *filename, PggErrenv errenv);
extern void			pgg_stdio_set_output_filename_gpgext(PggStdio io, const char *filename, PggErrenv errenv);
extern void			pgg_stdio_set_output_filename_woext(PggStdio io, const char *filename, PggErrenv errenv);

extern void			pgg_stdio_setup_exe(PggStdio io, PggExe exe, PggErrenv errenv);




extern PggOutput		pgg_output_new(PggErrenv errenv);
extern PggOutput		pgg_output_clone(PggOutput out, PggErrenv errenv);
extern void			pgg_output_addref(PggOutput out, PggErrenv errenv);
extern void			pgg_output_release(PggOutput out, PggErrenv errenv);

extern void			pgg_output_set_filename(PggOutput out, const char *filename, PggErrenv errenv);
extern void			pgg_output_set_buffer(PggOutput out, PggBuffer buf, PggErrenv errenv);
extern void			pgg_output_set_fd(PggOutput out, int fd, PggErrenv errenv);

extern void			pgg_output_open(PggOutput out, PggErrenv errenv);
extern long			pgg_output_write(PggOutput out, void *data, long amount, PggErrenv errenv);
extern void			pgg_output_close(PggOutput out, PggErrenv errenv);




extern PggSymcrypt		pgg_symcrypt_new(PggErrenv errenv);
extern PggSymcrypt		pgg_symcrypt_clone(PggSymcrypt sc, PggErrenv errenv);
extern void			pgg_symcrypt_addref(PggSymcrypt sc, PggErrenv errenv);
extern void			pgg_symcrypt_release(PggSymcrypt sc, PggErrenv errenv);

extern void			pgg_symcrypt_set_passphrase(PggSymcrypt sc, const char *passphrase, PggErrenv errenv);
extern void			pgg_symcrypt_set_stdio(PggSymcrypt sc, PggStdio stdio, PggErrenv errenv);
extern void			pgg_symcrypt_set_outopts(PggSymcrypt sc, PggOutopts opts, PggErrenv errenv);
extern void			pgg_symcrypt_set_config(PggSymcrypt sc, PggConfig cfg, PggErrenv errenv);
extern void			pgg_symcrypt_set_algo(PggSymcrypt sc, PggAlgo algo, PggErrenv errenv);

extern void			pgg_symcrypt_encrypt(PggSymcrypt sc, PggErrenv errenv);
extern void			pgg_symcrypt_decrypt(PggSymcrypt sc, PggErrenv errenv);




extern PggAlgo			pgg_algo_new(PggErrenv errenv);
extern PggAlgo			pgg_algo_clone(PggAlgo algo, PggErrenv errenv);
extern void			pgg_algo_addref(PggAlgo algo, PggErrenv errenv);
extern void			pgg_algo_release(PggAlgo algo, PggErrenv errenv);

extern void			pgg_algo_set_cipher(PggAlgo algo, Pgg_Cipher cipher, PggErrenv errenv);
extern void			pgg_algo_set_digest(PggAlgo algo, Pgg_Digest digest, PggErrenv errenv);
extern void			pgg_algo_set_compress(PggAlgo algo, Pgg_Compress compress, PggErrenv errenv);
extern void			pgg_algo_set_packet(PggAlgo algo, Pgg_Packet packet, PggErrenv errenv);
extern void			pgg_algo_set_s2k(PggAlgo algo, Pgg_S2k mode, PggErrenv errenv);
extern void			pgg_algo_set_s2k_cipher(PggAlgo algo, Pgg_Cipher cipher, PggErrenv errenv);
extern void			pgg_algo_set_s2k_digest(PggAlgo algo, Pgg_Digest digest, PggErrenv errenv);

extern Pgg_Cipher		pgg_algo_get_cipher(PggAlgo algo, PggErrenv errenv);
extern Pgg_Digest		pgg_algo_get_digest(PggAlgo algo, PggErrenv errenv);
extern Pgg_Compress		pgg_algo_get_compress(PggAlgo algo, PggErrenv errenv);
extern Pgg_Packet		pgg_algo_get_packet(PggAlgo algo, PggErrenv errenv);
extern Pgg_S2k			pgg_algo_get_s2k(PggAlgo algo, PggErrenv errenv);
extern Pgg_Cipher		pgg_algo_get_s2k_cipher(PggAlgo algo, PggErrenv errenv);
extern Pgg_Digest		pgg_algo_get_s2k_digest(PggAlgo algo, PggErrenv errenv);

extern void			pgg_algo_setup_exe(PggAlgo algo, PggExe exe, PggErrenv errenv);




extern PggConfig		pgg_config_new(PggErrenv errenv);
extern PggConfig		pgg_config_clone(PggConfig cfg, PggErrenv errenv);
extern void			pgg_config_release(PggConfig cfg, PggErrenv errenv);
extern void			pgg_config_addref(PggConfig cfg, PggErrenv errenv);

extern const char *		pgg_config_get_gpgpath(PggConfig cfg, PggErrenv errenv);
extern void			pgg_config_set_gpgpath(PggConfig cfg, const char *gpgpath, PggErrenv errenv);
extern int			pgg_config_search_gpg(PggConfig cfg, const char * path, PggErrenv errenv);

extern void			pgg_config_set_configfile(PggConfig cfg, const char * configfile, PggErrenv errenv);
extern const char *		pgg_config_get_configfile(PggConfig cfg, PggErrenv errenv);

extern void			pgg_config_set_public_keyring(PggConfig cfg, const char * public_keyring, PggErrenv errenv);
extern const char *		pgg_config_get_public_keyring(PggConfig cfg, PggErrenv errenv);
extern void			pgg_config_set_secret_keyring(PggConfig cfg, const char * secret_keyring, PggErrenv errenv);
extern const char *		pgg_config_get_secret_keyring(PggConfig cfg, PggErrenv errenv);
extern void			pgg_config_set_trustdb(PggConfig cfg, const char * trustdb, PggErrenv errenv);
extern const char *		pgg_config_get_trustdb(PggConfig cfg, PggErrenv errenv);

extern void			pgg_config_setup_exe(PggConfig cfg, PggExe exe, PggErrenv errenv);




typedef enum
{
    PGG_PASSCACHE_POLICY_ERROR = -1,		/* error indicator */
    PGG_PASSCACHE_POLICY_REFRESH,		/* using a passphrase refreshes its timeout */
    PGG_PASSCACHE_POLICY_TIMEOUT		/* fixed timeout, no refreshing of passphrase timeouts */
} PggPasscache_Policy;


typedef enum
{
    PGG_PASSCACHE_CMD_INIT,			/* Called when the callback is attached to a PggPasscache object */
    PGG_PASSCACHE_CMD_PASSPHRASE,		/* Request to fill the passcache with the passphrase of the given keyid in `arg' */
    PGG_PASSCACHE_CMD_SYM_PASSPHRASE,		/* Request for a passphrase for a symmetrically encrypted message */
    PGG_PASSCACHE_CMD_RELEASE			/* The callback is detached from a PggPasscache object */
} PggPasscache_CbCmd;


typedef int (*PggPasscache_Cb)(PggPasscache pc, PggPasscache_CbCmd cmd, const char *arg);


extern PggPasscache		pgg_passcache_new(PggErrenv errenv);
extern PggPasscache		pgg_passcache_clone(PggPasscache pc, PggErrenv errenv);
extern void			pgg_passcache_addref(PggPasscache pc, PggErrenv errenv);
extern void			pgg_passcache_release(PggPasscache pc, PggErrenv errenv);

extern void			pgg_passcache_set_timeout(PggPasscache pc, long seconds, PggErrenv errenv);
extern long			pgg_passcache_get_timeout(PggPasscache pc, PggErrenv errenv);

extern void			pgg_passcache_set_policy(PggPasscache pc, PggPasscache_Policy policy, PggErrenv errenv);
extern PggPasscache_Policy	pgg_passcache_get_policy(PggPasscache pc, PggErrenv errenv);

extern void			pgg_passcache_clear(PggPasscache pc, PggErrenv errenv);
extern void			pgg_passcache_expire(PggPasscache pc, PggErrenv errenv);

extern void			pgg_passcache_set_callback(PggPasscache pc, PggPasscache_Cb callback, PggErrenv errenv);

extern void			pgg_passcache_set_passphrase(PggPasscache pc, const char * keyid, const char *passphrase, PggErrenv errenv);
extern void			pgg_passcache_rem_passphrase(PggPasscache pc, const char * keyid, PggErrenv errenv);
extern const char *		pgg_passcache_get_passphrase(PggPasscache pc, const char * keyid, PggErrenv errenv);

extern void			pgg_passcache_set_sym_passphrase(PggPasscache pc, const char * sym_passphrase, PggErrenv errenv);
extern const char *		pgg_passcache_get_sym_passphrase(PggPasscache pc, PggErrenv errenv);




extern PggSign			pgg_sign_new(PggErrenv errenv);
extern PggSign			pgg_sign_clone(PggSign sign, PggErrenv errenv);
extern void			pgg_sign_addref(PggSign sign, PggErrenv errenv);
extern void			pgg_sign_release(PggSign sign, PggErrenv errenv);

extern void			pgg_sign_set_signer(PggSign sign, const char *signer, PggErrenv errenv);
extern const char *		pgg_sign_get_signer(PggSign sign, PggErrenv errenv);

extern void			pgg_sign_set_escape(PggSign sign, Pgg_Escape escape, PggErrenv errenv);
extern Pgg_Escape		pgg_sign_get_escape(PggSign sign, PggErrenv);

extern void			pgg_sign_set_mode(PggSign sign, Pgg_Sign mode, PggErrenv errenv);
extern Pgg_Sign			pgg_sign_get_mode(PggSign sign, PggErrenv);

extern void			pgg_sign_set_stdio(PggSign sign, PggStdio stdio, PggErrenv errenv);
extern PggStdio			pgg_sign_get_stdio(PggSign sign, PggErrenv errenv);

extern void			pgg_sign_set_passcache(PggSign sign, PggPasscache passcache, PggErrenv errenv);
extern PggPasscache		pgg_sign_get_passcache(PggSign sign, PggErrenv errenv);

extern void			pgg_sign_set_algo(PggSign sign, PggAlgo algo, PggErrenv errenv);
extern PggAlgo			pgg_sign_get_algo(PggSign sign, PggErrenv);

extern void			pgg_sign_set_config(PggSign sign, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_sign_get_config(PggSign sign, PggErrenv errenv);

extern void			pgg_sign_execute(PggSign sign, PggErrenv errenv);




extern PggEncrypt		pgg_encrypt_new(PggErrenv errenv);
extern PggEncrypt		pgg_encrypt_clone(PggEncrypt encrypt, PggErrenv errenv);
extern void			pgg_encrypt_addref(PggEncrypt encrypt, PggErrenv errenv);
extern void			pgg_encrypt_release(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_set_sign(PggEncrypt encrypt, int yesno, PggErrenv errenv);
extern int			pgg_encrypt_get_sign(PggEncrypt encrypt, PggErrenv errenv);
extern void			pgg_encrypt_set_signer(PggEncrypt encrypt, const char *signer, PggErrenv errenv);
extern const char *		pgg_encrypt_get_signer(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_add_recipient(PggEncrypt encrypt, const char *recipient, PggErrenv errenv);
extern int			pgg_encrypt_get_recipient_count(PggEncrypt encrypt, PggErrenv errenv);
extern const char *		pgg_encrypt_get_recipient(PggEncrypt encrypt, int index, PggErrenv errenv);
extern void			pgg_encrypt_rem_recipient(PggEncrypt encrypt, int index, PggErrenv errenv);

extern void			pgg_encrypt_set_noencryptto(PggEncrypt encrypt, int yesno, PggErrenv errenv);
extern int			pgg_encrypt_get_noencryptto(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_set_stdio(PggEncrypt encrypt, PggStdio stdio, PggErrenv errenv);
extern PggStdio			pgg_encrypt_get_stdio(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_set_passcache(PggEncrypt encrypt, PggPasscache passcache, PggErrenv errenv);
extern PggPasscache		pgg_encrypt_get_passcache(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_set_algo(PggEncrypt encrypt, PggAlgo algo, PggErrenv errenv);
extern PggAlgo			pgg_encrypt_get_algo(PggEncrypt encrypt, PggErrenv);

extern void			pgg_encrypt_set_config(PggEncrypt encrypt, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_encrypt_get_config(PggEncrypt encrypt, PggErrenv errenv);

extern void			pgg_encrypt_execute(PggEncrypt encrypt, PggErrenv errenv);




extern PggDecrypt		pgg_decrypt_new(PggErrenv errenv);
extern PggDecrypt		pgg_decrypt_clone(PggDecrypt decrypt, PggErrenv errenv);
extern void			pgg_decrypt_addref(PggDecrypt decrypt, PggErrenv errenv);
extern void			pgg_decrypt_release(PggDecrypt decrypt, PggErrenv errenv);

extern void			pgg_decrypt_set_stdio(PggDecrypt decrypt, PggStdio stdio, PggErrenv errenv);
extern PggStdio			pgg_decrypt_get_stdio(PggDecrypt decrypt, PggErrenv errenv);

extern void			pgg_decrypt_set_siginfo(PggDecrypt decrypt, PggSiginfo siginfo, PggErrenv errenv);
extern PggSiginfo		pgg_decrypt_get_siginfo(PggDecrypt decrypt, PggErrenv errenv);

extern void			pgg_decrypt_set_passcache(PggDecrypt decrypt, PggPasscache passcache, PggErrenv errenv);
extern PggPasscache		pgg_decrypt_get_passcache(PggDecrypt decrypt, PggErrenv errenv);

extern void			pgg_decrypt_set_config(PggDecrypt decrypt, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_decrypt_get_config(PggDecrypt decrypt, PggErrenv errenv);

extern void			pgg_decrypt_execute(PggDecrypt decrypt, PggErrenv errenv);




extern PggVerify		pgg_verify_new(PggErrenv errenv);
extern PggVerify		pgg_verify_clone(PggVerify verify, PggErrenv errenv);
extern void			pgg_verify_addref(PggVerify verify, PggErrenv errenv);
extern void			pgg_verify_release(PggVerify verify, PggErrenv errenv);

extern void			pgg_verify_set_data(PggVerify verify, PggInput data, PggErrenv errenv);
extern void			pgg_verify_set_signature(PggVerify verify, PggInput signature, PggErrenv errenv);

extern void			pgg_verify_set_siginfo(PggVerify verify, PggSiginfo siginfo, PggErrenv errenv);
extern PggSiginfo		pgg_verify_get_siginfo(PggVerify verify, PggErrenv errenv);

extern void			pgg_verify_set_config(PggVerify verify, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_verify_get_config(PggVerify verify, PggErrenv errenv);

extern void			pgg_verify_execute(PggVerify verify, PggErrenv errenv);




extern PggSiginfo		pgg_siginfo_new(PggErrenv errenv);
extern PggSiginfo		pgg_siginfo_clone(PggSiginfo siginfo, PggErrenv errenv);
extern void			pgg_siginfo_addref(PggSiginfo siginfo, PggErrenv errenv);
extern void			pgg_siginfo_release(PggSiginfo siginfo, PggErrenv errenv);

extern int			pgg_siginfo_get_goodsig_count(PggSiginfo siginfo, PggErrenv errenv);
extern const char *		pgg_siginfo_get_goodsig_keyid(PggSiginfo siginfo, int index, PggErrenv errenv);
extern const char *		pgg_siginfo_get_goodsig_fingerprint(PggSiginfo siginfo, int index, PggErrenv errenv);
extern const char *		pgg_siginfo_get_goodsig_userid(PggSiginfo siginfo, int index, PggErrenv errenv);
extern unsigned long		pgg_siginfo_get_goodsig_timestamp(PggSiginfo siginfo, int index, PggErrenv errenv);
extern Pgg_Trust		pgg_siginfo_get_goodsig_trust(PggSiginfo siginfo, int index, PggErrenv errenv);

extern int			pgg_siginfo_get_badsig_count(PggSiginfo siginfo, PggErrenv errenv);
extern const char *		pgg_siginfo_get_badsig_keyid(PggSiginfo siginfo, int index, PggErrenv errenv);
extern const char *		pgg_siginfo_get_badsig_userid(PggSiginfo siginfo, int index, PggErrenv errenv);
/* extern unsigned long		pgg_siginfo_get_badsig_timestamp(PggSiginfo siginfo, int index, PggErrenv errenv); */

extern int			pgg_siginfo_get_errsig_count(PggSiginfo siginfo, PggErrenv errenv);
extern const char *		pgg_siginfo_get_errsig_keyid(PggSiginfo siginfo, int index, PggErrenv errenv);
/* extern int 			pgg_siginfo_get_errsig_reason(PggSiginfo siginfo, int index, PggErrenv errenv); */
/* extern int			pgg_siginfo_get_errsig_pubalgo(PggSiginfo siginfo, int index, PggErrenv errenv); */
/* extern int			pgg_sigingo_get_errsig_hashalgo(PggSiginfo siginfo, int index, PggErrenv errenv); */

extern void			pgg_siginfo_reset(PggSiginfo siginfo, PggErrenv errenv);




/*
 * Example how to list the primary UID from keys having "foobar" in an UID:
 *
 *	PggErrenv	local_errenv;
 *	PggPubring	pubring;
 *	PggPubkey	pubkey;
 *	int		key_index;
 *	int		keys_found;
 *	const char *	uid;
 *
 *	pgg_errenv_reset(local_errenv);
 *
 *	pubring = pgg_pubring_new(local_errenv);
 *	pgg_pubring_query(pubring, "foobar", local_errenv);
 *	keys_found = pgg_pubring_get_pubkey_count(pubring, local_errenv);
 *
 *	if (pgg_errenv_is_set(local_errenv)) {
 *		fprintf(stderr, "Error on quering keyring...\n");
 *		abort();
 *	}
 *
 *	if (keys_found == 0) {
 *	    printf("No keys found.\n");
 *	}
 *
 *	for (key_index=0; key_index<keys_found; ++key_index) {
 *	    pubkey = pgg_pubring_get_pubkey(pubring, key_index, local_errenv);
 *	    uid = pgg_pubkey_get_uid(pubkey, 0, local_errenv);
 *
 *	    if (pgg_errenv_is_set(local_errenv)) {
 *		fprintf(stderr, "Error on retrieving UID from found key no.: %d of %d\n", key_index+1, keys_found);
 *		pgg_errenv_reset(local_errenv);
 *	    }
 *	    else {
 *		printf("UID: %s\n", uid);
 *	    }
 *
 *	    pgg_pubkey_release(pubkey, NULL);
 *	}
 *
 *	pgg_pubring_release(pubring, NULL);
 *
 */

extern PggPubring		pgg_pubring_new(PggErrenv errenv);
extern PggPubring		pgg_pubring_clone(PggPubring pubring, PggErrenv errenv);
extern void			pgg_pubring_addref(PggPubring pubring, PggErrenv errenv);
extern void			pgg_pubring_release(PggPubring pubring, PggErrenv errenv);

extern void			pgg_pubring_set_config(PggPubring pubring, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_pubring_get_config(PggPubring pubring, PggErrenv errenv);

extern void			pgg_pubring_reset(PggPubring pubring, PggErrenv errenv);
extern void			pgg_pubring_query(PggPubring pubring, const char * query_string, PggErrenv errenv);
extern void			pgg_pubring_query_all(PggPubring pubring, PggErrenv errenv);

extern int			pgg_pubring_get_pubkey_count(PggPubring pubring, PggErrenv errenv);
extern PggPubkey		pgg_pubring_get_pubkey(PggPubring pubring, int index, PggErrenv errenv);




/*
 * Example how to get infos about a known key:
 *
 *	PggErrenv	local_errenv;
 * 	PggPubkey 	pubkey;
 * 	const char *	primary_uid;
 *
 *	pgg_errenv_reset(local_errenv);
 *
 * 	pubkey = pgg_pubkey_new(local_errenv);
 * 	pgg_pubkey_use_keyid(pubkey, "123445678", local_errenv);
 * 	primary_uid = pgg_pubkey_get_uid(pubkey, 0, local_errenv);
 *
 * 	if (pgg_errenv_is_set(local_errenv)) {
 * 	    fprintf(stderr, "An error....\n");
 * 	else {
 * 	   printf("Primary UID of Key 0x12345678: %s\n", primary_uid);
 * 	}
 * 
 * 	pgg_pubkey_release(pubkey, NULL);
 *
 */
extern PggPubkey		pgg_pubkey_clone(PggPubkey pubkey, PggErrenv errenv);
extern void			pgg_pubkey_addref(PggPubkey pubkey, PggErrenv errenv);
extern void			pgg_pubkey_release(PggPubkey pubkey, PggErrenv errenv);

extern PggConfig		pgg_pubkey_get_config(PggPubkey pubkey, PggErrenv errenv);

extern int			pgg_pubkey_get_uid_count(PggPubkey pubkey, PggErrenv errenv);
extern const char *		pgg_pubkey_get_uid(PggPubkey pubkey, int uid_index, PggErrenv errenv);
extern void			pgg_pubkey_del_uid(PggPubkey pubkey, int uid_index, PggErrenv errenv);

extern int 			pgg_pubkey_get_sig_count(PggPubkey pubkey, int uid_index, PggErrenv errenv);
extern PggPubkey		pgg_pubkey_get_sig(PggPubkey pubkey, int uid_index, int sig_index, PggErrenv errenv);
extern void			pgg_pubkey_del_sig(PggPubkey pubkey, int uid_index, int sig_index, PggErrenv);

extern int			pgg_pubkey_get_ownertrust(PggPubkey pubkey, PggErrenv errenv);
extern void			pgg_pubkey_set_ownertrust(PggPubkey pubkey, int ownertrust, PggErrenv errenv);

extern const char *		pgg_pubkey_get_fingerprint(PggErrenv pubkey, PggErrenv errenv);

extern int			pgg_pubkey_get_subkey_count(PggErrenv pubkey, PggErrenv errenv);
extern Pgg_Keytype		pgg_pubkey_get_subkey_type(PggErrenv pubkey, int subkey_index, PggErrenv errenv);
extern int			pgg_pubkey_get_subkey_bits(PggErrenv pubkey, int subkey_index, PggErrenv errenv);
extern const char *		pgg_pubkey_get_subkey_id(PggErrenv pubkey, int subkey_index, PggErrenv errenv);
extern unsigned long		pgg_pubkey_get_subkey_creationdate(PggErrenv pubkey, int subkey_index, PggErrenv);
extern unsigned long		pgg_pubkey_get_subkey_expirationdate(PggErrenv pubkey, int subkey_index, PggErrenv);
extern Pgg_Validity		pgg_pubkey_get_subkey_validity(PggErrenv pubkey, int subkey_index, PggErrenv);


extern void			pgg_pubkey_sign_all_uids(PggPubkey pubkey, int exportable_sig, PggSeckey seckey, PggErrenv errenv);
extern void			pgg_pubkey_sign_uid(PggPubkey pubkey, int uid_index, int exportable_sig, PggSeckey seckey, PggErrenv errenv);

extern PggSeckey		pgg_pubkey_get_seckey(PggPubkey pubkey, PggErrenv errenv);




/*
 * PggSeckey implements only the additional futures which provides secret
 * keys. All other functionality is found in the corresponding PggPubkey.
 * When you change a secret key the changes will be automatically seen
 * by the corresponding Pubkey.
 *
 * FIXME: Should we realy use two key structures for public and secret
 * keys? Or should we incorporate this in one structure?
 */
#if 0
extern PggSeckey		pgg_seckey_new(PggErrenv errenv);
extern PggSeckey		pgg_seckey_clone(PggSeckey seckey, PggErrenv errenv);
extern void			pgg_seckey_addref(PggSeckey seckey, PggErrenv errenv);
extern void			pgg_seckey_release(PggSeckey seckey, PggErrenv errenv);

extern void			pgg_seckey_set_config(PggSeckey seckey, PggConfig config, PggErrenv errenv);
extern PggConfig		pgg_seckey_get_config(PggSeckey seckey, PggErrenv errenv);

extern void			pgg_seckey_set_keyid(PggSeckey seckey, const char *keyid, PggErrenv errenv);

extern void			pgg_seckey_add_uid(...);
extern void			pgg_seckey_del_uid(...);
extern void			pgg_seckey_revoke_uid(...);

extern void			pgg_seckey_export(...);
extern void			pgg_seckey_gen_revocation_cert(...);

extern void			pgg_seckey_add_subkey(...);
extern void			pgg_seckey_del_subkey(...);
extern void			pgg_seckey_revoke_subkey(...);

extern void			pgg_seckey_set_expirationdate(...);

extern void			pgg_seckey_set_passphrase(...);

extern PggPubkey		pgg_seckey_get_pubkey(PggSeckey seckey, PggErrenv errenv);
#endif



#ifdef __cplusplus
}			/* extern "C" { */
#endif

#endif			/* #ifndef PGG_INCLUDE_PGG_H_19990604145212 */


