mirror of
https://github.com/ChronosX88/psyced.git
synced 2024-12-05 00:22:19 +00:00
Merge branch 'master' of git://git.psyced.org/git/psyced
This commit is contained in:
commit
d42ab3594f
13
CHANGESTODO
13
CHANGESTODO
@ -86,6 +86,15 @@ ________________________________________________________________________
|
||||
? should /load inform that errors go to the console?
|
||||
|
||||
- the ~0 bug
|
||||
i found a reliable way to reproduce this ~0 uni problem
|
||||
- start psyced
|
||||
- connect with a native psyc client
|
||||
- kill psyced while the client is connected
|
||||
- start psyced again
|
||||
- connect with native psyc client
|
||||
it will give you this ~0 uni then
|
||||
until you connect with a telnet client
|
||||
but it works again after you connect & disconnect w/ a telnet client
|
||||
________________________________________________________________________
|
||||
:_group psyc://psyced.org/@welcome
|
||||
:_source_identification psyc://xxx.no-ip.org/~xxx
|
||||
@ -3976,3 +3985,7 @@ usercmd
|
||||
be negative, like -5.
|
||||
user
|
||||
- psyc client _examine was falling thru to _HTML output, added return;
|
||||
=== 201001 ============================================================
|
||||
jabber/active
|
||||
+ handle dialback timeouts, thx fip
|
||||
|
||||
|
@ -843,6 +843,9 @@ _failure_unsuccessful_delivery_resolve
|
||||
_failure_unsuccessful_delivery_self
|
||||
|Die Adresse [_host] zeigt auf [_source_origin], ist dort aber nicht vorgesehen.
|
||||
|
||||
_failure_unsuccessful_delivery_timeout_dialback
|
||||
|Konnte kein XMPP dialback zu [_host] herstellen um [_method_relay] an [_source] auszuliefern.
|
||||
|
||||
_failure_unavailable_service
|
||||
|Solch ein Dienst wird hier derzeit nicht angeboten.
|
||||
|
||||
|
@ -664,6 +664,9 @@ _failure_unsuccessful_delivery_resolve
|
||||
_failure_unsuccessful_delivery_self
|
||||
|The [_host] address points to [_source_origin] which however wasn't instructed to handle that.
|
||||
|
||||
_failure_unsuccessful_delivery_timeout_dialback
|
||||
|Could not establish an XMPP dialback to [_host] to deliver a [_method_relay] to [_source].
|
||||
|
||||
_failure_unavailable_service_version
|
||||
|Requesting version from [_nick_target] is not possible.
|
||||
|
||||
|
@ -72,6 +72,7 @@ start_dialback() {
|
||||
dialback_outgoing = 1;
|
||||
emit(sprintf("<db:result to='%s' from='%s'>%s</db:result>",
|
||||
hostname, source_host, key));
|
||||
call_out(120, #'connect_failure, "_timeout_dialback", "no dialback response received, timeout");
|
||||
}
|
||||
|
||||
process_dialback_queue() {
|
||||
@ -364,6 +365,7 @@ jabberMsg(XMLNode node) {
|
||||
* we are originating server and are informed of the result
|
||||
*/
|
||||
dialback_outgoing = 0;
|
||||
remove_call_out(#'connect_failure);
|
||||
if (node["@type"] == "valid") {
|
||||
#ifdef LOG_XMPP_AUTH
|
||||
D0( log_file("XMPP_AUTH", "\n%O auth dialback", ME); )
|
||||
|
@ -621,6 +621,21 @@ int greater_user(object a, object b) { return file_name(a) > file_name(b); }
|
||||
object* sorted_users() { return sort_array(users(), #'greater_user; }
|
||||
#endif
|
||||
|
||||
volatile mixed mailer;
|
||||
|
||||
// simple SMTP interface.. used from person:logAppend - why target?
|
||||
// assumes that mailto: rcpt has already been checked with legal_mailto() !
|
||||
int smtp_sendmsg(string target, string method, string data,
|
||||
mapping vars, string source, string rcpt, string loginurl) {
|
||||
#ifdef SMTP_PATH
|
||||
unless (mailer) mailer = SMTP_PATH "outgoing" -> load();
|
||||
return mailer -> enqueue(target, method, data, vars, source, rcpt,
|
||||
loginurl);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int xmpp_sendmsg(mixed target, string mc, mixed data, mapping vars,
|
||||
mixed source, array(mixed) u, int showingLog, string otarget) {
|
||||
string tmp;
|
||||
|
360
world/net/smtp/outgoing.c
Normal file
360
world/net/smtp/outgoing.c
Normal file
@ -0,0 +1,360 @@
|
||||
// outgoing mail queue for psyced.
|
||||
|
||||
// i *could* rewrite this to use net/spool.c
|
||||
// but then i'd have such a mess in my room
|
||||
|
||||
#include <net.h>
|
||||
#include <text.h>
|
||||
virtual inherit NET_PATH "output";
|
||||
|
||||
#define MAX_SPOOL 23
|
||||
#define SPOOL_FILE DATA_PATH "mail_queue"
|
||||
|
||||
#if defined(DEBUG) && DEBUG > 1
|
||||
# define QUEUE_POLL_TIME 9
|
||||
# define COLLECT_TIME 15
|
||||
# define CONNECT_RETRY 99
|
||||
#else
|
||||
# define QUEUE_POLL_TIME 33
|
||||
# define COLLECT_TIME 60 * 2
|
||||
# define CONNECT_RETRY 60 * 7
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_MAIL_SENDER
|
||||
# define DEFAULT_MAIL_SENDER "psyc-daemon@" SERVER_HOST
|
||||
#endif
|
||||
#ifndef DEFAULT_MAIL_SENDER_NAME
|
||||
# define DEFAULT_MAIL_SENDER_NAME "PSYC server on " SERVER_HOST
|
||||
#endif
|
||||
#ifndef DEFAULT_MAIL_SUBJECT
|
||||
# define DEFAULT_MAIL_SUBJECT "Messages for [_target]"
|
||||
#endif
|
||||
|
||||
#ifndef SMTP_RELAY
|
||||
# define SMTP_RELAY "127.0.0.1"
|
||||
#endif
|
||||
|
||||
#define S_OFF 0
|
||||
#define S_CONN 101
|
||||
#define S_READY 102
|
||||
#define S_SOML 103
|
||||
#define S_FROM 104
|
||||
#define S_TO 105
|
||||
#define S_DATA 106
|
||||
#define S_MESS 107
|
||||
#define S_DONE 108
|
||||
|
||||
#define FILE_FORMAT 0
|
||||
#define Q_SOURCE 0
|
||||
#define Q_METHOD 1
|
||||
#define Q_DATA 2
|
||||
#define Q_VARS 3
|
||||
#define Q_TARGET 4
|
||||
#define Q_URL_LOGIN 5
|
||||
//#define Q_SENDER 99
|
||||
|
||||
mapping spool;
|
||||
int time_of_connect_attempt;
|
||||
int file_format;
|
||||
|
||||
#ifdef Q_SENDER
|
||||
static string sndr;
|
||||
#else
|
||||
# define sndr DEFAULT_MAIL_SENDER
|
||||
#endif
|
||||
static string rcpt, target;
|
||||
static int state;
|
||||
|
||||
#ifdef OFFLINE
|
||||
# define mwrite(TEXT) D(TEXT)
|
||||
#else
|
||||
# if defined(DEBUG) && DEBUG > 1
|
||||
mwrite(str) { log_file("SENDMAIL", str); emit(str); }
|
||||
# else
|
||||
# define mwrite(TEXT) emit(TEXT)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
reset(a) {
|
||||
// if (a) {
|
||||
#ifndef OFFLINE
|
||||
P2(("RESET: saving mail queue into "+ SPOOL_FILE +"\n"))
|
||||
save_object(SPOOL_FILE);
|
||||
#endif
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
create() {
|
||||
#ifdef DEFAULT_LAYOUT
|
||||
sTextPath (DEFAULT_LAYOUT, DEFLANG, "smtp");
|
||||
#else
|
||||
sTextPath (0, 0, "smtp");
|
||||
#endif
|
||||
unless (spool) {
|
||||
restore_object(SPOOL_FILE);
|
||||
if (file_format != FILE_FORMAT) spool = 0;
|
||||
}
|
||||
D2( if (spool) log_file("SENDMAIL", "*** Restored spool %O\n",
|
||||
spool && m_indices(spool) ); )
|
||||
file_format = FILE_FORMAT;
|
||||
if (spool) qjack(1);
|
||||
}
|
||||
|
||||
load() { return ME; }
|
||||
|
||||
static connect() {
|
||||
#ifndef OFFLINE
|
||||
if (interactive()) return 1;
|
||||
// could this be using net/connect?
|
||||
if (time() > time_of_connect_attempt + CONNECT_RETRY) {
|
||||
int res;
|
||||
|
||||
time_of_connect_attempt = time();
|
||||
save_object(SPOOL_FILE);
|
||||
D1( D("SMTP: attempting connect to "+SMTP_RELAY+"\n"); )
|
||||
if (res = net_connect(SMTP_RELAY, 25)) {
|
||||
D0(D("SMTP connect error #"+ res
|
||||
+" to " SMTP_RELAY ".\n");)
|
||||
log_file("SENDMAIL", "*** No connect ("+res+") at "+
|
||||
ctime(time())+"\n");
|
||||
return 0;
|
||||
}
|
||||
state=S_CONN;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// called from smtp_sendmsg()
|
||||
// this doesn't support the user's aliases, but doing so pretty
|
||||
// much means a major architectural change.. or a dirty ->aliasresolve()
|
||||
enqueue(target, method, data, vars, source, rcpt, urllogin) {
|
||||
int i = 0;
|
||||
|
||||
// gets checked in /set and mailto:
|
||||
#ifdef BRAIN
|
||||
// but we check again since brain has old user files
|
||||
// with unchecked adresses
|
||||
unless (rcpt = legal_mailto(rcpt)) return 0;
|
||||
#endif
|
||||
PT(("smtp/enqueue: from %O to %O (%O)\n", source, target, rcpt))
|
||||
unless (spool) {
|
||||
spool = ([]);
|
||||
call_out("qjack", COLLECT_TIME, 1);
|
||||
}
|
||||
if (spool[rcpt]) {
|
||||
i = spool[rcpt][1]++;
|
||||
if (i >= MAX_SPOOL) return 0;
|
||||
spool[rcpt][i] = ({
|
||||
source, method, data, vars, target, urllogin });
|
||||
} else {
|
||||
spool[rcpt] = allocate(MAX_SPOOL);
|
||||
spool[rcpt][1] = 3;
|
||||
if (objectp(target)) target = psyc_name(target);
|
||||
spool[rcpt][2] = ({
|
||||
source, method, data, vars, target, urllogin });
|
||||
}
|
||||
spool[rcpt][0] = COLLECT_TIME + time();
|
||||
return connect();
|
||||
}
|
||||
|
||||
qjack(arg) {
|
||||
unless (spool) return;
|
||||
if (arg) call_out("qjack", QUEUE_POLL_TIME, arg+1);
|
||||
|
||||
#ifndef OFFLINE
|
||||
unless (interactive()) return connect();
|
||||
D2( D("jacking Q: "+ state + ", idle "+ query_idle(ME) + "\n"); )
|
||||
unless (state == S_READY) return 0;
|
||||
#endif
|
||||
foreach(rcpt : spool) {
|
||||
if (spool[rcpt][0] < time()) {
|
||||
#ifdef OFFLINE
|
||||
rendermsg(rcpt);
|
||||
done();
|
||||
#else
|
||||
target = spool[rcpt][2][Q_TARGET];
|
||||
// if (objectp(target)) target = psyc_name(target);
|
||||
# ifdef Q_SENDER
|
||||
// do we want them to downgrade communication to email?
|
||||
sndr = spool[rcpt][2][Q_SENDER];
|
||||
unless (sndr) sndr = DEFAULT_MAIL_SENDER;
|
||||
# endif
|
||||
mwrite("SOML FROM: <"+sndr+">\n");
|
||||
state = S_SOML;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
D2( D("nothing ready yet\n"); )
|
||||
}
|
||||
|
||||
static done() {
|
||||
unless (spool) return;
|
||||
m_delete(spool, rcpt);
|
||||
if (sizeof(spool) == 0) spool = 0;
|
||||
#ifndef OFFLINE
|
||||
D2( save_object(SPOOL_FILE); )
|
||||
#endif
|
||||
}
|
||||
|
||||
static abort(code, msg) {
|
||||
done(); // we cannot risk to have this person block outgoing mail
|
||||
#ifdef PRO_PATH
|
||||
sendmsg(query_monitor_unl(), "_error_transaction_mail_monitor",
|
||||
"Received [_code_smtp] '[_text_smtp]' while delivering to [_recipient_mailto] ([_recipient]).", ([
|
||||
"_code_smtp": code, "_text_smtp": msg,
|
||||
"_recipient_mailto" : "mailto:"+rcpt,
|
||||
"_recipient" : target ]) );
|
||||
#endif
|
||||
mwrite("QUIT\n"); // restart mailer connection (not necessary?)
|
||||
state=S_DONE;
|
||||
}
|
||||
|
||||
parse(str) {
|
||||
int code;
|
||||
string msg;
|
||||
|
||||
input_to(#'parse);
|
||||
if (str) {
|
||||
D2( log_file("SENDMAIL", "« "+ str+"\n"); )
|
||||
if (sscanf(str, "%d%t%s", code, msg) !=2)
|
||||
sscanf(str, "%d",code);
|
||||
}
|
||||
if (!code) code=250; // is this smart?
|
||||
|
||||
switch(state) {
|
||||
case S_CONN:
|
||||
state=S_READY;
|
||||
mwrite("HELO " SERVER_HOST "\n");
|
||||
break;
|
||||
case S_READY:
|
||||
if (code!=250) abort(code, msg);
|
||||
else qjack(0);
|
||||
break;
|
||||
case S_SOML:
|
||||
if (code!=250) {
|
||||
P3(("SOML to %O returns %s\n", query_ip_number(), str))
|
||||
state = S_FROM;
|
||||
mwrite("MAIL FROM: <"+sndr+">\n");
|
||||
break;
|
||||
}
|
||||
// else we were successful, so let's fall thru
|
||||
P0(("Yoohoo! %O is a mailer who understands SOML!\n",
|
||||
query_ip_number()))
|
||||
case S_FROM:
|
||||
state=S_TO;
|
||||
if (code!=250) abort(code, msg);
|
||||
else mwrite("RCPT TO: <"+rcpt+">\n");
|
||||
break;
|
||||
case S_TO:
|
||||
state=S_DATA;
|
||||
if (code!=250) abort(code, msg);
|
||||
else mwrite("DATA\n");
|
||||
break;
|
||||
case S_DATA:
|
||||
state=S_MESS;
|
||||
if (code!=354) abort(code, msg);
|
||||
else rendermsg(rcpt);
|
||||
break;
|
||||
case S_MESS:
|
||||
state=S_READY;
|
||||
if (code!=250) abort(code, msg);
|
||||
done();
|
||||
break;
|
||||
case S_DONE:
|
||||
// 221 2.0.0 fly.symlynX.com closing connection
|
||||
state=S_OFF;
|
||||
break;
|
||||
case S_OFF:
|
||||
remove_interactive(ME);
|
||||
D2(D("SMTP had to force connection close: "+str+"\n");)
|
||||
break;
|
||||
default:
|
||||
D2(D("SMTP should not get here: "+state+"\n");)
|
||||
}
|
||||
}
|
||||
|
||||
w(string mc, string data, mapping vars, mixed source) {
|
||||
string output, nick = 0;
|
||||
string template = T(mc, "");
|
||||
|
||||
// source can be 0
|
||||
if (stringp(source) && mappingp(vars)) nick = psyctext(
|
||||
T("_MISC_identification_remote",
|
||||
"<[_source]> [_nick]"), ([
|
||||
"_source":source,
|
||||
"_nick": (vars["_nick_verbatim"] || vars["_nick"])
|
||||
]));
|
||||
output = psyctext( template, vars, data, source, nick );
|
||||
P3(("SMTP:w(%O,%O,%O,%O) - %O\n", mc,data,vars,source, template))
|
||||
if (template == "") output += abbrev("_prefix", mc) ? " " : "\n";
|
||||
return output;
|
||||
}
|
||||
|
||||
// TODO: to be formally correct all umlauts in the header would have to
|
||||
// be escaped with that ugly embedded encoding trick. do we care?
|
||||
rendermsg(rcpt) {
|
||||
string m, t2;
|
||||
int i, l, o, t;
|
||||
|
||||
mwrite("From: " DEFAULT_MAIL_SENDER " ("
|
||||
DEFAULT_MAIL_SENDER_NAME ")\n");
|
||||
l = spool[rcpt][1];
|
||||
if (l > MAX_SPOOL) {
|
||||
o = l - MAX_SPOOL;
|
||||
mwrite("X-Amount-Messages-Omitted: "+ o +"\n");
|
||||
l = MAX_SPOOL;
|
||||
}
|
||||
for (i=2; i<l; i++) {
|
||||
unless (m) {
|
||||
// m = spool[rcpt][i][Q_DATA];
|
||||
m = w( spool[rcpt][i][Q_METHOD],
|
||||
spool[rcpt][i][Q_DATA],
|
||||
spool[rcpt][i][Q_VARS],
|
||||
spool[rcpt][i][Q_SOURCE] );
|
||||
mwrite("To: "+rcpt+" ("+ target +")\n");
|
||||
// psyc_name(spool[rcpt][i][Q_TARGET])
|
||||
t = index(m, '\n');
|
||||
// PP(("smtp-out: %d == %d ? %s", t, strlen(m), m));
|
||||
#ifdef SEND_FIRST_MSG_AS_SUBJECT
|
||||
if (t+1 == strlen(m)) mwrite("Subject: "+m);
|
||||
else mwrite("Subject: "+m[..t]);
|
||||
#endif
|
||||
} else
|
||||
m += w( spool[rcpt][i][Q_METHOD],
|
||||
spool[rcpt][i][Q_DATA],
|
||||
spool[rcpt][i][Q_VARS],
|
||||
spool[rcpt][i][Q_SOURCE] );
|
||||
//m += "\n" + spool[rcpt][i][Q_DATA];
|
||||
//D("m is -"+m+"-\n");
|
||||
unless (t2) t2 = spool[rcpt][i][Q_URL_LOGIN];
|
||||
}
|
||||
// mwrite("Date:\t"+mctime(time())+"\n");
|
||||
// mwrite("X-Mailer: psycMUVE eMail Gateway\n");
|
||||
// mwrite("X-Chatter: "+src->qName()+"\n");
|
||||
//write("Reply-To: "+sndr+"."+lower_case(CHATNAME)+"@"+SMTP_RELAY+"\n");
|
||||
|
||||
if (o) m += w("_warning_omitted_messages",
|
||||
"[_amount_messages_omitted] messages omitted.",
|
||||
([ "_amount_messages_omitted" : o ]) );
|
||||
#ifdef DEFAULT_URL_LOGIN
|
||||
# ifndef _flag_disable_mail_signature
|
||||
m += "\n--\n"+ w( "_info_mail_signature", "Reply by E-Mail is not possible. Please log in:\n[_URL_login]",
|
||||
([ "_URL_login": (t2 || DEFAULT_URL_LOGIN) ]) ) + "\n";
|
||||
# endif
|
||||
#endif
|
||||
t2 = "Content-Type: text/plain; charset=" SYSTEM_CHARSET "\n"
|
||||
#ifndef SEND_FIRST_MSG_AS_SUBJECT
|
||||
"Subject: "+ w("_info_mail_subject", DEFAULT_MAIL_SUBJECT,
|
||||
([ "_target": target || rcpt || ME ]) ) +
|
||||
#endif
|
||||
"Content-Length: "+( strlen(m) )+"\n"
|
||||
"\n"+ m +".\n";
|
||||
mwrite(t2);
|
||||
}
|
||||
|
||||
logon() { input_to(#'parse); }
|
||||
|
6
world/net/smtp/user.c
Normal file
6
world/net/smtp/user.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <net.h>
|
||||
#include <user.h>
|
||||
|
||||
qScheme() { return "smtp"; }
|
||||
|
||||
// useless object for now
|
Loading…
Reference in New Issue
Block a user