/* -*- C -*-
* POP3Lite - 3lite POP3 Daemon
* Copyright (C) 2000, 2001 Gergely Nagy <8@free.bsd.hu>
*
* This file is part of POP3Lite.
*
* POP3Lite 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.
*
* POP3Lite 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
*/
/*
* $Id: pop3lite.h.in,v 1.9 2001/01/12 16:02:59 algernon Exp $
*/
#ifndef __POP3LITE_H__
#define __POP3LITE_H__ 1
#include <glib.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define POP3LITE_VERSION "0.2.4a"
/**
* Some convenience macros
**/
#define P3L_GET_OPTION(opt) (GList *) g_hash_table_lookup ( control->config, opt )
#define P3L_GET_NTH_OPTION(opt,n) (char *) g_list_nth_data ( P3L_GET_OPTION(opt), n )
#define P3L_GET_FIRST_OPTION(opt) P3L_GET_NTH_OPTION ( opt, 0 )
#define P3L_GET_DATA(key) (char *) g_hash_table_lookup ( control->data, key )
#define P3L_CALL_HOOK(type,hook) (* (type) g_hash_table_lookup ( control->hooks, hook ) )
#define P3L_CMD_EXISTS(hash,cmd) ( g_hash_table_lookup ( control->hash, cmd ) != NULL )
#define P3L_HOOK_EXISTS(hook) P3L_CMD_EXISTS ( hooks, hook )
#define p3l_clear(str) \
do { \
register char *__xx__; \
if ( ( __xx__ = (str) ) ) \
while ( *__xx__ ) \
*__xx__++ = '\0'; \
} while ( 0 )
/**
* POP3Code: Used in conjunction with p3l_respond.
*
* + POP3_NOTHING: No POP3 status indicator (+OK, -ERR) is sent,
* only the message.
* + POP3_ANSWERED: Same as POP3_NOTHING, but has a different meaning
* when dealing with inheritance.
* + POP3_OK: An +OK indicator is sent before the message.
* + POP3_OK_HIDDEN: This is the same as POP3_OK, but the indicator
* won't be sent. Useful for functions which call their previous
* version. (Eg, when a function falls back to something)
* + POP3_OK_EXIT: Same as POP3_OK, but exit immediately after
* sending the message.
* + POP3_ERR: Send an +ERR indicator before the message
* + POP3_FATAL: Same as POP3_ERR, but exit immediately after
* sending the message.
**/
typedef enum
{
POP3_NOTHING,
POP3_ANSWERED,
POP3_OK,
POP3_OK_HIDDEN,
POP3_OK_EXIT,
POP3_ERR,
POP3_FATAL
} POP3Code;
/**
* POP3State: the actual state of the POP3 Session
* + POP3_STATE_AUTH: authentication state.
* + POP3_STATE_TRANS: transaction state.
* + POP3_STATE_UPDATE: update state.
**/
typedef enum
{
POP3_STATE_AUTH,
POP3_STATE_TRANS,
POP3_STATE_UPDATE
} POP3State;
/**
* AuthResult: result of authentication
*
* + AUTH_RESULT_OK: success
* + AUTH_RESULT_FAIL: auth. failed, reason unspecified
* + AUTH_RESULT_FAIL_USER: wrong username
* + AUTH_RESULT_FAIL_PASS: wrong password
**/
typedef enum
{
AUTH_RESULT_OK,
AUTH_RESULT_FAIL,
AUTH_RESULT_FAIL_USER,
AUTH_RESULT_FAIL_PASS
} AuthResult;
/**
* CommandResponse: every command implementation returns this.
*
* Each and every function that implements a POP3 command, MUST
* return a variable of this type. This allows a command to
* call another and be sure that the other doesn't send
* anything. (In most cases, eg RETR is an exception)
**/
typedef struct _CommandResponse CommandResponse;
struct _CommandResponse
{
POP3Code code;
char *message;
};
/**
* UserInfo: information about a user
*
* This is mainly used by the auth abstraction layer.
**/
typedef struct _UserInfo UserInfo;
struct _UserInfo
{
char *name;
uid_t uid;
gid_t gid;
char *gecos;
char *home;
char *shell;
long expire;
};
/** Pre-declarations to be used by the hooks **/
typedef struct _P3LControl P3LControl;
typedef struct _SysControl SysControl;
/***********************************************
* P3LControl & SysControl function prototypes *
***********************************************/
/**
* P3LHook_get_mailbox: GET-MAILBOX hook
* @control: the main control struct
*
* This hook is used to retrieve the FILENAME (or equivalent, if it is
* not a file) of the mailbox.
*
* Returns: a newly allocated string containing the result, or NULL on
* failure.
**/
typedef char *(*P3LHook_get_mailbox) ( P3LControl *control );
/**
* P3LControl_greeting: Send the initial greeting.
* @control: the main control struct
*
* This special hook is responsible for sending the initial POP3
* greeting.
*
* Returns: +OK [Greeting] in a CommandResponse
**/
typedef CommandResponse *(*P3LControl_greeting) ( P3LControl *control );
/**
* P3LControl_send_response: send POP3 Response
* @control: the main control struct
* @code: POP3 response code
* @message: the message itself
*
* This hook is used to send almost all server responses.
*
* Returns: nothing, this is an end-point.
**/
typedef void (*P3LControl_send_response) ( P3LControl *control,
POP3Code code, const char *message );
/**
* P3LControl_send_raw: send RAW data to the client
* @control: the main control struct
* @data: the data to send
* @size: size of the data to send
*
* This is used to send raw data to the client, ideally, the
* send_response hook should call it only. Except for the RETR/TOP/etc
* commands, which return multiline input.
*
* Returns: nothing, this is an end-point.
**/
typedef void (*P3LControl_send_raw) ( P3LControl *control, const gpointer data,
size_t size );
/**
* P3LControl_trans_init: Initialise TRANSACTION state
* @control: the main control struct
*
* This hook should initialise the transaction state, by locking the
* mailbox, preparing uidls, etc. When this is called, the user is
* authenticated, and the privileges are (hopefully) dropped.
*
* Returns: +OK [some greeting message] on success, -ERR [reason]
* otherwise.
**/
typedef CommandResponse *(*P3LControl_trans_init) ( P3LControl *control );
/**
* P3LControl_update: handle the UPDATE state
* @control: the main control struct
*
* This one does the really hard job: updating the mailbox. Errors
* should always be fatal in this state.
*
* Returns: +OK [exit message] or -ERR [reason]
**/
typedef CommandResponse *(*P3LControl_update) ( P3LControl *control );
/**
* P3LSysCon_getuinam: Get UserInfo by name
* @control: the main control struct
* @name: the user's name
*
* This hook collects all the information listed in UserInfo about the
* specified user.
*
* Returns: a newly allocated, filled out UserInfo struct.
**/
typedef UserInfo *(*P3LSysCon_getuinam) ( P3LControl *control,
const char *name );
/**
* P3LSysCon_authenticate: Do the effective authentication
* @control: the main control struct
* @name: username
* @pass: password (probably clear-text)
*
* This hook is intended to authenticate the user. This is not a
* command handler, it has nothing to do with the AUTH command. This
* is merely here to separate the authentication mechanism from
* command handling. Be very careful, when you replace this!
*
* Returns: the result of the authentication
**/
typedef AuthResult (*P3LSysCon_authenticate) ( P3LControl *control,
const char *name,
const char *pass );
/**
* P3LSysCon_drop_privileges: drop all possible privileges
* @control: the main control struct
*
* This hook is used to get rid of ALL special privileges. Do not
* change this! The only possible reason you might want to override
* this is when you run POP3Lite on a Non-Unix system.
*
* Returns: nothing.
**/
typedef void (*P3LSysCon_drop_privileges) ( P3LControl *control );
/**
* P3LSysCon_openlog: open the logfile, or facility
* @control: the main control struct
*
* This hook should open the logfile, or tell syslog about the
* program.
*
* Returns: nothing.
**/
typedef void (*P3LSysCon_openlog) ( P3LControl *control );
/**
* P3LSysCon_log: do the actual logging
* @control: the main control struct
* @priority: message priority, see <syslog.h>
* @format: printf-style format string
*
* This hooks does the actual logging.
*
* Returns: nothing
**/
typedef void (*P3LSysCon_log) ( P3LControl *control, int priority,
const char *format, ... );
/**
* P3LSysCon_closelog: close the logfile or facility
* @control: the main control struct
*
* This hook should close the logfile or anything openlog opened.
*
* Returns: nothing
**/
typedef void (*P3LSysCon_closelog) ( P3LControl *control );
/**
* SysControl: system-specific control functions
*
* Change with extreme caution!
**/
struct _SysControl
{
P3LSysCon_getuinam getuinam;
P3LSysCon_authenticate authenticate;
P3LSysCon_drop_privileges drop_privileges;
P3LSysCon_openlog openlog;
P3LSysCon_log log;
P3LSysCon_closelog closelog;
/** A GList of UserInfo structs, serves as a cache **/
GList *users;
/** Miscelleanous system-specific data **/
GHashTable *data;
};
/**
* P3LControl: the main control structure.
*
* The whole POP3Lite session is controlled via this
* structure. See the docs for more info.
**/
struct _P3LControl
{
P3LControl_greeting greeting;
P3LControl_send_response send_response;
P3LControl_send_raw send_raw;
P3LControl_trans_init trans_init;
P3LControl_update update;
/** Commands available in the AUTHENTICATION state **/
GHashTable *auth_commands;
/** Commands available in the TRANSACTION state **/
GHashTable *trans_commands;
/** Misc. capabilities, mainly useful for the CAPA module **/
GHashTable *capabilities;
/** Session-related data, such as the username, etc **/
GHashTable *data;
/** Configuration data, it should NOT be modified **/
GHashTable *config;
/** A table of loaded modules **/
GHashTable *modules;
/** The current state of our session **/
POP3State state;
/** A GList of MessageInfo structs **/
GList *msg_info;
/** System-specific hooks **/
SysControl *system;
/** Misc. hooks, used throughout the daemon **/
GHashTable *hooks;
};
/**
* P3LString: NULL-aware string representation
**/
typedef struct _P3LString P3LString;
struct _P3LString
{
unsigned long length;
char *str;
};
/**
* p3l_module_hook: module_init/module_done definition
* int module_init ( P3LControl *control)
* int module_done ( P3LControl *control)
* Returns 0 on succes, anything else on failure
**/
typedef int (*p3l_module_hook) ( P3LControl *control );
/**
* HandlerInfo: information about a signal handler
*
* This is used by the main SIGALRM handler
**/
typedef struct _HandlerInfo HandlerInfo;
struct _HandlerInfo
{
unsigned int counter;
unsigned int tick_max;
p3l_module_hook hook;
};
/**
* p3l_pop3_command: definition for POP3 Commands
* @control: the main control struct
* @arguments: the arguments as read from the client
*
* Returns: Whatever it likes...
**/
typedef CommandResponse *(*p3l_pop3_command) ( P3LControl *control,
const char *arguments );
/**
* MailInfo: information about a message
*
* Many default commands use this to give information to the user,
* without having to re-read the whole mailbox.
*
* The fields that are driver-independent:
* + virtual_size: the size the message is said to be,
* after replacing the From [...] header with our own
* Received: header. This should be fully independent
* of everything, no matter where the message is read
* from, functions using this (and only this or other
* independent fields) can be left untouched when
* adding a new driver (maildir eg)
* + digest: MD5 digest of the message. Should be
* independent.
* + deleted: deleted state of the message.
*
* The other fields are:
* + driver_data: driver-dependent data
**/
typedef struct _MailInfo MailInfo;
struct _MailInfo
{
size_t virtual_size;
char digest[16];
gboolean deleted;
GHashTable *driver_data;
};
/**
* p3l_received_header: return a POP3Lite header
* @data: control->data
*
* Constructcs a Received: header
*
* Returns: the header, which should be freed
**/
char *p3l_received_header ( GHashTable *data );
/**
* p3l_parse_buffer: replace From [...] with Received:
* @buffer: the mail text
* @data: control->data
* @buffer_size: size of the buffer
* @new_size: pointer where the new size will be placed
*
* Replaces the first line (From [...]) of the message with
* the POP3Lite-specific Received: header. (buffer will be
* freed!)
*
* Returns: the new buffer
**/
char *p3l_parse_buffer ( char *buffer, GHashTable *data,
size_t buffer_size, size_t *new_size );
/**
* p3l_respond: generate a POP3Lite response
* code: response code see %POP3Code abouce
* message: the actual message
*
* Generates a response suitable to be used as the
* return value of POP3 Command implementations.
*
* Returns: the POP3Lite response struct
**/
CommandResponse *p3l_respond ( POP3Code code, const char *message );
/**
* p3l_is_enabled: check if an option is enabled
* @option: the option string
*
* Parses @option, and returns a boolean indicating
* wheter it is enabled or not. (true, yes, on means
* enabled, everything else is disabled)
*
* Returns: a boolean
**/
gboolean p3l_is_enabled ( const char *option );
/**
* bintohex: convert a binary string to hexadecimal
* @ptr: the binary sequence
* @size: length of the sequence
* @checkendian: wheter to check endianness, or not
*
* Converts a binary sequence to its hexadecimal
* representation.
*
* Returns: the hexadecimal representation
**/
const char *bintohex ( const void *ptr, size_t size, const int checkendian );
/**
* p3l_command_replace: replace a command
* @commands: the command table (control->{auth,trans}_commands
* @name: the command name
* @new_command: the new command
*
* Replaces a command in a given table.
*
* Returns: the old command
**/
const gpointer p3l_command_replace ( GHashTable *commands,
const char *name,
gpointer new_command );
/**
* p3l_split_lines: split a buffer into lines
* @buffer: source
* @size: the buffer's size
*
* Splits the buffer into lines. This is NULL-aware, that means,
* that the strings are NOT null terminated, therefore, their
* size must be stored.
*
* Returns: a pointer to a P3LString array
**/
P3LString **p3l_split_lines ( char *buffer, size_t size,
size_t *lines );
/**
* p3l_lock_fd: lock a file
* @fd: file descriptor
* @fn: file name, in case we use lockfile_create
*
* Locks a file.
*
* Returns: 0 on success, -1 otherwise
**/
int p3l_lock_fd ( int fd, char *fn );
/**
* p3l_unlock_fd: unlock a file
* @fd: file descriptor
* @fn: file name, in case we use lockfile_create
*
* Unlocks a file.
*
* Returns: 0 on success, -1 otherwise
**/
int p3l_unlock_fd ( int fd, char *fn );
/**
* p3l_read_file: read the contents of a file
* @fn: filename
* @size: variable to put filesize into
*
* Opens the file and reads its contents.
*
* Returns: the contents, free-able
**/
gpointer p3l_read_file ( const char *filename, size_t *size );
/**
* p3l_read_fd: read the contents of an opened file
* @fd: file descriptor
* @size: variable to put filesize into
*
* Reads the contents of an already opened file.
*
* Returns: the contents, free-able
**/
gpointer p3l_read_fd ( int fd, size_t *size );
/**
* p3l_load_config: loads configuration
* @control: the usual control struct
* @filename: where to load configuration from
* @table: destination
*
* This loads a configuration file.
*
* Returns: nothing
**/
void p3l_load_config ( P3LControl *control, const char *filename,
GHashTable *table );
/**
* p3l_get_peer_name: get the peer's hostname
*
* This one figures out the remote end's hostname.
*
* Returns: the hostname.
**/
char *p3l_get_peer_name ( void );
/**
* p3l_is_numeric: check if a string represents a number
* @str: the string to check
*
* Determines if a string represents a number or not.
*
* Returns: TRUE if it does, FALSE if not.
**/
gboolean p3l_is_numeric ( const char* str );
/**
* p3l_register_alarm: register an alarm hook
* @hook: the hook to run
* @interval: the interval (in seconds) to wait between calls
*
* Installs a new hook to run on SIGALRM.
*
* Returns: nothing.
**/
void p3l_register_alarm ( p3l_module_hook hook, unsigned int interval );
/**
* p3l_get_alarm_hooks: returns the registered SIGALRM hooks
*
* This function returns a GList of HandlerInfo structs of the
* registered SIGALRM hooks.
*
* Returns: the list
**/
GList *p3l_get_alarm_hooks ( void );
/**
* p3l_unregister_alarm: unregister an alarm hook
* @hook: the hook to remove
*
* Removes an registered SIGALRM hook.
*
* Returns: nothing.
**/
void p3l_unregister_alarm ( p3l_module_hook hook );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ! __POP3LITE_H__ */
syntax highlighted by Code2HTML, v. 0.9.1