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 * or Kari Hurtta *****************************************************************************/ #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 #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 : "", 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: */