static char rcsid[] = "@(#)$Id: remote_mbx.c,v 1.6 2006/06/27 16:56:54 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.6 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* or Kari Hurtta <elm@elmme-mailer.org>
*****************************************************************************/
#include "def_mbox.h"
#include "ss_imp.h"
#ifdef USE_DLOPEN
#include "shared_imp.h"
#endif
#include "s_me.h"
#include "s_elm.h"
DEBUG_VAR(Debug,__FILE__,"net");
#ifdef REMOTE_MBX
/* Seems that h_errno is macro on AIX */
#ifndef h_errno
extern int h_errno;
#endif
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
void set_remote_tempmbox P_((struct folder_info *fh,
struct remote_account *X));
void set_remote_tempmbox(fh,X)
struct folder_info *fh;
struct remote_account *X;
{
char * prefix = "mbox.";
char *tmp;
static int counter = 0;
/* In here we can use temp_dir instead of default_temp because
* that file does not act as session lock ...
*/
if (X->magic != REMOTE_ACCOUNT_magic)
panic("CONNECTION PANIC",__FILE__,__LINE__,
"set_remote_tempmbox",
"Bad magic number",0);
tmp = give_dt_estr_as_str(&temp_dir_e,"tmpdir");
if (!tmp)
tmp = "/tmp/";
elm_sfprintf(fh-> cur_tempfolder,
sizeof fh -> cur_tempfolder,
FRM("%s%s%s.%s.%d.%d"),
tmp,prefix,username,X->host,getpid(),counter++);
DPRINT(Debug,12,(&Debug,
"set_remote_tempmbox: cur_tempfolder=%s\n",
fh-> cur_tempfolder));
}
/* May free X (if succeed) or copy
If make copy of X, then X is zeroed
*/
int make_remote_mbox(fh,X,se,rest,rewrite)
struct folder_info *fh;
struct remote_account *X;
struct service_entry *se;
char * rest;
int rewrite;
{
struct remote_account *status = NULL;
char * imap_only = NULL; /* Flag and name of imap folder ... */
int got;
static struct connection_cache *CX;
if (X->magic != REMOTE_ACCOUNT_magic)
panic("CONNECTION PANIC",__FILE__,__LINE__,
"make_remote_mbox",
"Bad magic number",0);
DPRINT(Debug,10,(&Debug,
"make_remote_mbox: fh=%X, rest=%s, rewrite=%d\n",
fh,rest ? rest : "<NULL>", rewrite));
if (rewrite) {
/* canonify folder name .... */
if (rest) {
/* Inbox is case insensitive */
if (0 == istrcmp(":inbox",rest))
rest = ":INBOX";
imap_only = safe_strdup(rest);
free(fh->cur_folder_sys);
fh->cur_folder_sys = elm_message(FRM("%s@%s%s"),
X->username,
se->official_name,
imap_only);
/* No support of international folder names on here! */
free_string(&(fh->cur_folder_disp));
fh->cur_folder_disp = format_string(FRM("%s@%s%s"),
X->username,
se->official_name,
imap_only);
rest = NULL; /* is no longer valid pointer if
rest was pointing to fh->cur_folder_sys
*/
} else {
free(fh->cur_folder_sys);
fh->cur_folder_sys = elm_message(FRM("%s@%s"),
X->username,se->official_name);
free_string(&(fh->cur_folder_disp));
fh->cur_folder_disp = format_string(FRM("%s@%s"),
X->username,
se->official_name);
}
}
/* Only IMAP connections are cached */
CX = locate_from_cache(X->username,X->host,&IMAP_connection,
0 /* Default port */ );
if (CX) {
if (!imap_only)
imap_only = safe_strdup(":INBOX");
fh -> folder_type = IMAP_MBX;
DPRINT(Debug,8,(&Debug,
"make_remote_mbox: IMAP mailbox (from cache)\n"));
fh->folder_type->init_it(fh);
folder_from_connection(CX,fh);
status = &(fh->p->a.imap_mbx.Ch->C);
if (':' == imap_only[0])
fh->p->a.imap_mbx.folder = safe_strdup(imap_only+1);
else
fh->p->a.imap_mbx.folder = safe_strdup(imap_only);
} else {
PORTS ports[] = { PORT_imap4, PORT_pop3, PORT_end };
PORTS ports_imaponly[] = { PORT_imap4, PORT_end };
if (!connect_remote_account(X,&got,se,
imap_only ? ports_imaponly : ports,
PORT_end))
goto fail;
if (IMAP_SERVICE == se->service)
goto is_imap;
else if (POP_SERVICE == se->service)
goto is_pop;
else switch (got) {
case PORT_pop3:
is_pop:
fh -> folder_type = POP_MBX;
DPRINT(Debug,8,(&Debug,
"make_remote_mbox: POP mailbox (succeed)\n"));
fh->folder_type->init_it(fh);
free_remote_account(&(fh->p->a.pop_mbx.C));
fh->p->a.pop_mbx.C = *X;
zero_remote_account(X); /* Avoid double free */
status = &(fh->p->a.pop_mbx.C);
break;
case PORT_imap4:
is_imap:
if (!imap_only)
imap_only = safe_strdup(":INBOX");
fh -> folder_type = IMAP_MBX;
DPRINT(Debug,8,(&Debug,
"make_remote_mbox: IMAP mailbox (succeed)\n"));
fh->folder_type->init_it(fh);
if (!join_connection(fh->p->a.imap_mbx.Ch,X,CON_greeting))
set_imap_connection_state(fh->p->a.imap_mbx.Ch,IMAP_error);
else
set_imap_connection_state(fh->p->a.imap_mbx.Ch,IMAP_idle);
status = &(fh->p->a.imap_mbx.Ch->C);
if (':' == imap_only[0])
fh->p->a.imap_mbx.folder = safe_strdup(imap_only+1);
else
fh->p->a.imap_mbx.folder = safe_strdup(imap_only);
break;
default:
DPRINT(Debug,8,(&Debug,
"make_remote_mbox: Unknown mailbox type (service=%x, port =%d)\n",
se->service,got));
lib_error(CATGETS(elm_msg_cat, MeSet,MeUnknownRemoteMailboxType,
"Remote mailbox type of %S unknown"),
fh->cur_folder_disp);
status = NULL;
}
}
if (status) {
/* In here we can use temp_dir instead of default_temp because
* that file does not act as session lock ...
*/
set_remote_tempmbox(fh,status);
}
fail:
free_remote_account(X);
if (imap_only)
free(imap_only);
if (status) {
DPRINT(Debug,12,(&Debug,
"make_remote_mbox=1\n"));
return 1;
}
DPRINT(Debug,12,(&Debug,
"make_remote_mbox=0\n"));
return 0;
}
#endif
int remote_folder_type(fh)
struct folder_info *fh;
{
char * rest, *p;
int ret = 0;
#ifdef REMOTE_MBX
struct remote_account X;
struct service_entry *se = NULL;
int z;
#endif
/* Explicite disallow $MAIL to be interpreted as remote mailbox */
if ('/' == fh->cur_folder_sys[0] ||
((p = getenv("MAIL")) && strcmp(fh->cur_folder_sys, p) == 0) ||
0 == access(fh->cur_folder_sys,ACCESS_EXISTS)) {
DPRINT(Debug,8,(&Debug,
"remote_folder_type=0 (file: %s)\n",
fh->cur_folder_sys));
return 0;
}
#ifdef REMOTE_MBX
/* -1 == name not found or bad syntax
0 == not a remote address
1 == name found
*/
if ((z = split_remote_name(fh->cur_folder_sys,&X,&se,&rest,
0 /* Both IMAP and POP are OK */))) {
if (z < 0)
goto clean;
/* May free X (if succeed) or copy */
if (!make_remote_mbox(fh,&X,se,rest,1)) {
clean:
free_remote_account(&X);
fh -> folder_type = NO_NAME;
fh->folder_type->init_it(fh);
}
free_temporary_service_entry(&se);
ret = 1; /* Is 'remote mailbox' ... */
}
#else
DPRINT(Debug,9,(&Debug,
"remote_folder_type: (remote mailboxes are not supported.)\n"));
#endif /* REMOTE_MBX */
DPRINT(Debug,8,(&Debug,
"remote_folder_type=%d\n",ret));
return ret;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1