123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236openCoreopenAsyncopenAsync_smtpopenCommonletmsgid=Command.Param.Arg_type.createSmtp_spool.Stable.Message_id.V1.of_stringmoduleStatus=structmoduleFormat=structtypet=[`Ascii_table|`Ascii_table_with_max_widthofint|`Exim|`Sexp][@@derivingsexp]letof_string=function|"ascii"->`Ascii_table|"exim"->`Exim|"sexp"->`Sexp|str->Sexp.of_string_conv_exnstr[%of_sexp:t];;letarg_type=Command.Param.Arg_type.createof_stringletparam=Command.Param.(flag"format"(optional_with_default`Ascii_tablearg_type)~doc:" Output format for the spool, valid values include 'ascii', 'exim', 'sexp'");;endletdispatch~formatclient=let%mapstatus=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.statusclient()inprintf"%s\n"(Smtp_spool.Status.to_formatted_string~formatstatus);;letcommand=letopenCommand.Let_syntaxinCommand.configs_or_rpc~summary:"list current contents of the spool"[%map_openletformat=Format.paraminfunction|`Configs(_,spool_config)->letopenDeferred.Let_syntaxinlet%mapstatus=Smtp_spool.status_from_diskspool_config|>Deferred.Or_error.ok_exninprintf"%s\n"(Smtp_spool.Status.to_formatted_string~formatstatus)|`Rpcclient->dispatch~formatclient];;endmoduleCount=structletwhich=Command.Param.(choose_one~if_nothing_chosen:(Default_to`All)[flag"-frozen-only"no_arg~doc:" Only count frozen messages"|>map~f:(funb->Option.some_ifb`Only_frozen);flag"-active-only"no_arg~doc:" Only count active messages"|>map~f:(funb->Option.some_ifb`Only_active)]);;letis_frozen=function|`Frozen->true|`Send_now|`Send_at_|`Sending|`Removed|`Delivered|`Quarantined_->false;;letis_active=function|`Send_now|`Send_at_|`Sending->true|`Frozen|`Removed|`Delivered|`Quarantined_->false;;letdispatch~whichclient=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.statusclient()>>|List.filter~f:(funmessage_info->letstatus=Smtp_spool.Spooled_message_info.statusmessage_infoinmatchwhichwith|`All->true|`Only_frozen->is_frozenstatus|`Only_active->is_activestatus)>>|List.length;;letcommand=letopenCommand.Let_syntaxinCommand.configs_or_rpc~summary:"print total number of messages in the spool"[%map_openletwhich=whichinfunction|`Configs(_,spool_config)->letopenDeferred.Let_syntaxinSmtp_spool.count_from_diskspool_config>>|Or_error.ok_exn>>|printf"%d\n"|`Rpcclient->letopenDeferred.Let_syntaxindispatch~whichclient>>|printf"%d\n"];;endmoduleFreeze=structletmsgids=Command.Param.(anon(sequence("msgid"%:msgid)))letdispatch~msgidsclient=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.freezeclientmsgids>>|Or_error.ok_exn;;letcommand=letopenCommand.Let_syntaxinCommand.rpc~summary:"Freeze messages in the spool"[%map_openletmsgids=msgidsindispatch~msgids];;endmoduleSend=structletretry_intervals=Command.Param.(flag"retry-interval"(listedTime.Span.arg_type)~doc:"SPAN additional retry intervals (order matters)"|>map~f:(List.map~f:Smtp_envelope.Retry_interval.create));;letparam=letopenCommand.Let_syntaxin[%map_openletall=flag"all"no_arg~doc:" force immediate sending of all messages"andfrozen=flag"frozen"no_arg~doc:" force immidiate resending of frozen messages only"andmsgids=anon(sequence("msgid"%:msgid))inmatchmsgidswith|[]whenfrozen->`Frozen_only|[]whenall->`All_messages|[]->failwith"Must specify either msgids or -all or -frozen"|_whenall||frozen->failwith"Can't specify msgids and -all or -frozen"|msgids->`Some_messagesmsgids];;letdispatch?(retry_intervals=[])send_infoclient=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.sendclient(retry_intervals,send_info)>>|Or_error.ok_exn;;letcommand=letopenCommand.Let_syntaxinCommand.rpc~summary:"Force immediate sending of messages"[%map_openletretry_intervals=retry_intervalsandsend_info=paramindispatch~retry_intervalssend_info];;endmoduleRemove=structletmsgids=Command.Param.(anon(sequence("msgid"%:msgid)))letdispatch~msgidsclient=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.removeclientmsgids>>|Or_error.ok_exn;;letcommand=letopenCommand.Let_syntaxinCommand.rpc~summary:"Remove messages in the spool"[%map_openletmsgids=msgidsindispatch~msgids];;endmoduleRecover=structletparam=letopenCommand.Let_syntaxin[%map_openletmsgs=anon(sequence("msg"%:msgid))andquarantine=flag"from-quarantine"no_arg~doc:" recover quarantined messages"andremove=flag"from-remove"no_arg~doc:" recover removed messages"inmatchquarantine,removewith|true,false->{Smtp_spool.Recover_info.msgs;from=`Quarantined}|false,true->{Smtp_spool.Recover_info.msgs;from=`Removed}|_->failwith"Must specify exactly one of -from-quarantine or -from-remove"];;letdispatchrecover_infoclient=Rpc.Rpc.dispatch_exnSmtp_rpc_intf.Spool.recoverclientrecover_info>>|Or_error.ok_exn;;letcommand=letopenCommand.Let_syntaxinCommand.rpc~summary:"recover a removed message back into a frozen state"[%map_openletrecover_info=paramindispatchrecover_info];;endmoduleEvents=structletdispatchclient=let%bindpipe,_=Rpc.Pipe_rpc.dispatch_exnSmtp_rpc_intf.Spool.eventsclient()inPipe.iter_without_pushbackpipe~f:(funevent->printf!"%{sexp:Smtp_spool.Event.t}\n"event);;letcommand=Command.rpc~summary:"view the stream of spool events"(Command.Param.returndispatch);;endletcommand=Command.group~summary:"spool management"["status",Status.command;"count",Count.command;"freeze",Freeze.command;"send",Send.command;"remove",Remove.command;"recover",Recover.command;"events",Events.command];;