[neomutt-devel] any interest in neomutt headless or as a library?

Mike Marchywka marchywka at hotmail.com
Mon Jul 20 16:28:20 CEST 2020

sorry, wrong reply address :)
It looks like the indentations got pulled from the code but
otherwise ok. I use a lot of my own macros and typedefs
in the c++ code it may not be clear. 

I've been debating about dumping to github or something
but there is a lot of bad code in the overall code base :)

Curious though if people have specific issues with fetchmail
or mail processing code. I'm just writing my own because
I originally wanted to download my hotmail but now it
is nice to adapt for using email exchanges for remote data
transfer and control and monitoring.

From: Mike Marchywka <marchywka at hotmail.com>
Sent: Monday, July 20, 2020 9:30 AM
To: Richard Russon
Subject: Re: [neomutt-devel] any interest in neomutt headless or as a library?

On Mon, Jul 20, 2020 at 01:59:59PM +0100, Richard Russon wrote:
> Hi Mike,
> > I'm trying to replace "fetchmail" and integrate with my own mail processing logic.
> Sounds fun
> > any interest in neomutt headless or as a library?
> Not directly, but I _have_ spent over four years breaking apart
> dependencies so that this might be possible.
> Upstream Mutt's code has two libraries.
> NeoMutt has twenty-six :-)
> > I ... hacked it up to implement partial functionality without curses ...
> See: https://github.com/neomutt/test-library
> Especially: test_conn.c and test_smtp.c
> They link against the libraries, without the need for NeoMutt's main().
> > This was easy

I wanted to preserve main for several reasons, the library does
actually require it be renamed but IIRC main.c was the only file
to change for that build due to the rename.

I changed the observers and tacked this in when in my mode,

     struct MuttWindow *dlg = index_pager_init();
      notify_observer_add(NeoMutt->notify, mjm_dlg_index_observer, dlg);
if (mjm_init_only) return 0;
 return shutdown_loop(&cls,&mml); //   cls.rc = 0;

For external usage, I have this,

int mutt_main_server(const char * config, char * envp[])
int argc=4;
char ** argv =malloc(4*sizeof(char*));
int rc= main_lib(argc,argv,envp);
int rc= main(argc,argv,envp);

return rc;


> You're welcome :-)
> > I had to hack up main() pretty significantly ...
> Urgh.  main() *is* still a mess.
> NeoMutt always does _some_ GUI initialisaion because there are still
> some GUI dependencies deep within the code.  We're working on it, though.

I ran into this trying to update the read flag on an imap server,

diff index.c ../orig/index.c
< if (!Colors) return;

> > ... not start curses, but then drop into my own readline based
> > command interpreter ... only good for debugging.
> Sounds useful
> > linking the shared object to my c++ code "mikemail" it appeared
> > to read and send from an imap account
> That's great
> So... Let's see the code.
> If it looks useful, are you prepared to help integrate it?
> (I'll happily make time to mentor)

It will take some cleanup to distribute but if I know someone is interested
I can start on that. Right now I'm letting this sit for a little but
you can see how I called it from my c++ app,
( note a lot of macro and utility classes but the flow should
be apparent ),

void cmd_mutt_proc(Cip & cip , LocalVar & lv )
const StrTy config=cip.p1;
const IdxTy flags=myatoi(cip.p2);
const bool unread_only=Bit(flags,0);
const bool reset_on_fail=Bit(flags,1);
const bool server_update=!Bit(flags,2);
const StrTy fn=cip.wif(3);
if (cip.help())
Ss ss;
ss<<cip.cmd()<<" cmd_mutt_proc "<<CRLF;

MyMsgMap & m=m_messages;
MuttInterface mi;
int i=0;
int rc=mutt_main_server(config.c_str(),0);
if (rc!=0)
MM_ERR(" failed to open mutt "<<MMPR(rc))
struct Email ** elist= mutt_email_list(unread_only?1:0);
if (elist!=0)
std::map<IdxTy,IdxTy> serial;
while (elist[i]!=0)
MyMsg msg;
// StrTy account(){ return  m_user+StrTy(";")+m_host+StrTy(";")+m_folder; }

} // i
IdxTy mflags=0;
/MyMsgMap & m=m_messages; // def?m_messages:m_messages_map[mbox];
MailProc & mp= m_proc_map[fn];
const int idx=elist[k]->index;
const MyMsg & msg=m[idx];
const IdxTy prc=mp.proc(msg,mflags);
if (server_update) {
if (prc==0) set_read_flag(elist[k]);
else if (reset_on_fail) reset_read_flag(elist[k]);
char * subj="subect";
char * text=" message text";
char ** lto= new char*[2];
lto[0]="marchywka at hotmail.com";
// the reply function fails but sending new messag ok
//int rcs=mjm_send_via_mutt(lto,subj, text,0,elist[k]);
int rcs=mjm_send_via_mutt(lto,subj, text,0,0);



MM_ERR("free "<<MMPR(i))
} // cmd_mutt_proc

> Cheers,
>     Rich / FlatCap


mike marchywka
306 charles cox
canton GA 30115
USA, Earth
marchywka at hotmail.com
ORCID: 0000-0001-9237-455X

More information about the neomutt-devel mailing list