static char rcsid[] = "@(#)$Id: imap.c,v 1.2 2006/06/25 10:41:05 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.2 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

#include "def_url.h"
#include "s_me.h"

DEBUG_VAR(Debug,__FILE__,"url");

#define URL_imap_magic		0xEC08

struct url_imap {

    unsigned short        magic;     /* URL_imap_magic */

    struct string       * params;
    struct string       * query;
};

#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif

S_(uh_init_url uh_init_imap)
static void uh_init_imap  P_((struct url *url));
static void uh_init_imap(url)
     struct url *url;
{
    url->u.imap = safe_malloc (sizeof (*  url->u.imap));

    /* bzero is defined hdrs/defs.h */
    bzero((void *)url->u.imap,sizeof (* url->u.imap));

    url->u.imap->magic = URL_imap_magic;

    url->u.imap->params = NULL;    
    url->u.imap->query  = NULL;    
}

S_(uh_free_url uh_free_imap)
static void uh_free_imap  P_((struct url *url));
static void uh_free_imap(url)
     struct url *url;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_free_imap",
	      "bad  magic number",0);

    if (url->u.imap->params)
	free_string(& (url->u.imap->params));
    if (url->u.imap->query)
	free_string(& (url->u.imap->query));

    url->u.imap->magic = 0;  /* Invalidate */
    free(url->u.imap);
    url->u.imap = NULL;
}


S_(uh_parse_url_not_path  uh_parse_imap_not_path)
static int uh_parse_imap_not_path  P_((struct url *url, 
					     struct string *scheme_pesifix,
					     struct header_errors **header_error));

static int uh_parse_imap_not_path(url,scheme_pesifix,header_error)
     struct url *url;
     struct string *scheme_pesifix;
     struct header_errors **header_error;
{

    /* Should not be called */

    return 0;
}

S_(uh_dup_url_not_path uh_dup_imap_not_path)
static int uh_dup_imap_not_path  P_((struct url *url,
				       struct url *source));
static int uh_dup_imap_not_path(url,source)
     struct url *url;
     struct url *source;
{
    /* Should not be called */

    return 0;
}


S_(uh_parse_url_params uh_parse_imap_params)
static int uh_parse_imap_params  P_((struct url *url, 
				     struct string *scheme_pesifix,
				     struct header_errors **header_error));
static int uh_parse_imap_params(url,scheme_pesifix,header_error)
     struct url *url;
     struct string *scheme_pesifix;
     struct header_errors **header_error;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_parse_imap_params",
	      "bad  magic number",0);

    /* Params are currently not supported */

    url->u.imap->params = dup_string(scheme_pesifix);

    return 1;
}



S_(uh_dup_url_params uh_dup_imap_params)
static int uh_dup_imap_params  P_((struct url *url,
				   struct url *source));
static int uh_dup_imap_params(url,source)
     struct url *url;
     struct url *source;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_dup_imap_params",
	      "bad  magic number (url)",0);

    if (URL_imap_magic != source->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_dup_imap_params",
	      "bad  magic number (source)",0);

    /* Params are currently not supported */
    
    if (source->u.imap->params)
	url->u.imap->params = dup_string(source->u.imap->params);

    return 1;
}


S_(uh_parse_url_query uh_parse_imap_query)
static int uh_parse_imap_query  P_((struct url *url, 
					  struct string *scheme_pesifix,
					  struct header_errors **
					  header_error));
static int uh_parse_imap_query(url,scheme_pesifix,header_error)
     struct url *url;
     struct string *scheme_pesifix;
     struct header_errors **header_error;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_parse_imap_query",
	      "bad  magic number",0);


    /* query is currently not supported */
    url->u.imap->query = dup_string(scheme_pesifix);

    return 1;
}

S_(uh_dup_url_query uh_dup_imap_query)
static int uh_dup_imap_query  P_((struct url *url,
				       struct url *source));
static int uh_dup_imap_query(url,source)
     struct url *url;
     struct url *source;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_dup_imap_query",
	      "bad  magic number (url)",0);

    if (URL_imap_magic != source->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_dup_imap_query",
	      "bad  magic number (source)",0);

    /* query is currently not supported */
    if (source->u.imap->query)
	url->u.imap->query = dup_string(source->u.imap->query);

    return 1;
}


S_(uh_set_mailing_headers_from_url uh_set_mailing_headers_from_imap)
static int uh_set_mailing_headers_from_imap P_((struct mailing_headers *hdrs,
						  const struct url *url,
						  struct mailer_info 
						  *mailer_info));
static int uh_set_mailing_headers_from_imap(hdrs,url,mailer_info)
     struct mailing_headers *hdrs;
     CONST struct url *url;
     struct mailer_info  *mailer_info;
{

    /* Should not be called */

    return 0;
}


S_(uh_get_body_string_from_url uh_get_body_string_from_imap)
static CONST struct string * uh_get_body_string_from_imap P_((CONST struct 
								url *url,
								int *errors));
static CONST struct string * uh_get_body_string_from_imap(url,errors)
     const struct url *url;
     int *errors;
{
    /* Should not be called */

    return NULL;
}

S_(uh_not_path_to_raw_url uh_not_path_to_raw_imap)
static struct string * uh_not_path_to_raw_imap P_((const struct url *url));
static struct string * uh_not_path_to_raw_imap(url) 
     CONST struct url *url;
{
    /* Should not be called */
  
    return NULL;
}


S_(uh_params_to_raw_url uh_params_to_raw_imap)
static int uh_params_to_raw_imap P_((const struct url *url, 
				       struct string **result));
static int uh_params_to_raw_imap(url,result)
     CONST struct url *url; 
     struct string **result;
{
    *result = NULL;

    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_params_to_raw_imap",
	      "bad magic number",0);

    /* Params are currently not supported */
    if (url->u.imap->params)
	*result = dup_string(url->u.imap->params);

    return 1;
}


S_(uh_query_to_raw_url uh_query_to_raw_imap)
static int uh_query_to_raw_imap P_((const struct url *url, 
				      struct string **result));
static int uh_query_to_raw_imap(url,result)
     CONST struct url *url; 
     struct string **result;
{
    *result = NULL;

    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_query_to_raw_imap",
	      "bad magic number",0);

    /* Query is not currently supported */

     if (url->u.imap->query)
	*result = dup_string(url->u.imap->query);

    return 1;
}

S_(uh_get_folder_from_url uh_get_folder_from_imap)
static struct folder_info * uh_get_folder_from_imap P_((const struct url *url,
							verify_remote_url_f *verify_remote));
static struct folder_info * uh_get_folder_from_imap(url,verify_remote)
     const struct url *url;
     verify_remote_url_f verify_remote;
{
    struct folder_browser * browser = NULL;
    struct folder_info    * ret = NULL;

#ifdef REMOTE_MBX

    browser = get_browser_from_host_url(url,&URL_imap,verify_remote);

    if (!browser) {
	DPRINT(Debug,11,(&Debug,
			 "uh_get_folder_from_imap: Failed to get browser\n"));

	goto fail;
    }

    if (! browser_select_url_path(browser,url,&URL_imap)) {

	DPRINT(Debug,11,(&Debug,
			 "uh_get_folder_from_imap: Failed to select folder\n"));


	goto fail;
    }

    ret = folder_from_dir_item(browser);

    if (!ret) {
	DPRINT(Debug,11,(&Debug,
			 "uh_get_folder_from_imap: Failed to get folder\n"));
    }

 fail:

    if (browser)
	free_dir (& browser);

#endif

    return ret;
}

S_(uh_get_url_type uh_get_imap_type)
static enum url_type uh_get_imap_type P_((const struct url *url));
static enum url_type uh_get_imap_type(url)
     CONST struct url *url;
{
    if (URL_imap_magic != url->u.imap->magic)
	panic("URL PANIC",__FILE__,__LINE__,"uh_get_imap_type",
	      "bad magic number",0);
    
#ifdef REMOTE_MBX

    if (! url->host)
	return url_unknown;

    /* Params are currently not supported */
    if (url->u.imap->params)
	return url_unknown;

    /* Query is not currently supported */
    if (url->u.imap->query)
	return url_unknown;

    if (url->path) {
	int len = url_path_len(url->path);
	int i;
	CONST struct url_path_elem *x1;

	/* Is refering folder (mailbox)? */

	/* 1) Check path elements */
	for (i = 0; i < len-1; i++) {
	    CONST struct url_path_elem *x = get_url_path_element(url->path,i);
	    if (!x)
		return url_unknown;

	    if (! x->trailing_slash)
		return url_unknown;
	}

	if (len < 1)
	    return url_unknown;

	/* 2) Last element must not end to / */

	x1 = get_url_path_element(url->path,len-1);

	if (x1->trailing_slash)
	    return url_mailbox_list;     /* Not supported */

	return url_mailbox;
    }

    /* If there is not path, it is whole imap server */

    return url_mailbox_list;    /* Not supported */

#else

    /* If remote mailboxes are not supported, then 
       imap urls can not be supported ...
    */

    return url_unknown;

#endif
}


struct url_handler URL_imap_handler = {
    URL_handler_magic,
    URLFLAG_common|URLFLAG_username|URLFLAG_port|URLFLAG_path|
    URLFLAG_params|URLFLAG_query,
    url_unknown,
    uh_init_imap,
    uh_free_imap,
    uh_parse_imap_not_path,
    uh_dup_imap_not_path,
    uh_parse_imap_params,
    uh_dup_imap_params,
    uh_parse_imap_query,
    uh_dup_imap_query,
    uh_set_mailing_headers_from_imap,
    uh_get_body_string_from_imap,
    uh_not_path_to_raw_imap,
    uh_params_to_raw_imap,
    uh_query_to_raw_imap,
    uh_get_folder_from_imap,
    uh_get_imap_type
};

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */



syntax highlighted by Code2HTML, v. 0.9.1