Diff
Logged in as anonymous

Differences From Artifact [48b0e1b904]:

To Artifact [3f2e34fec5]:


58
59
60
61
62
63
64
65


66
67
68


69
70
71

72
73

74
75
76
77
78
79
80
58
59
60
61
62
63
64

65
66
67


68
69
70
71

72
73

74
75
76
77
78
79
80
81







-
+
+

-
-
+
+


-
+

-
+







	relay: bool,
	tg: Arc<TelegramTransport>,
	fields: HashSet<String>,
	address: Regex,
}

impl MailServer {
	/// Main asynchronous entry point for the application.
	/// Initializes the mail server: sets up the Telegram API client and
	/// validates all required configuration values.
	///
	/// Parses command-line arguments, loads configuration, and starts the SMTP
	/// server.
	/// # Arguments
	/// * `settings` - Parsed application configuration.
	///
	/// # Errors
	/// Returns an error if configuration is invalid, files are inaccessible, or
	/// Returns an error if required configuration values are missing or invalid.
	/// server fails to start.
	pub fn new(settings: config::Config) -> Result<MailServer> {
	pub fn new (settings: config::Config) -> Result<MailServer> {
		let api_key = settings.get_string("api_key")
			.context("[smtp2tg.toml] missing \"api_key\" parameter.\n")?;
		let mut recipients = HashMap::new();
		for (name, value) in settings.get_table("recipients")
			.expect("[smtp2tg.toml] missing table \"recipients\".\n")
		{
			let value = value.into_int()
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
120
121
122
123
124
125
126

127
128
129
130
131
132
133

134



135
136
137
138
139
140
141







-
+






-
+
-
-
-







		})
	}

	/// Retrieves the Telegram chat ID for a given email address, checks that
	/// used domain is allowed.
	///
	/// # Arguments
	/// * `name_str` - Email address or username to look up.
	/// * `name` - Email address or username to look up.
	///
	/// # Returns
	/// * `Result<ChatPeerId>` - Telegram chat ID for the address, or default if
	///   not found.
	pub fn get_id (&self, name: &str) -> Result<&ChatPeerId> {
		if self.address.is_match(name) {
			match self.tg.get(name) {
			Ok(self.tg.get(name).unwrap_or(&self.tg.default))
				Ok(addr) => Ok(addr),
				Err(_) => Ok(&self.tg.default),
			}
		} else {
			bail!("Doesn't look like address from one of our domains.");
		}
	}

	/// Attempt to deliver one message
	async fn relay_mail (&self) -> Result<()> {
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
288
289
290
291
292
293
294

295
296
297







298



299
300
301
302
303
304
305







-
+


-
-
-
-
-
-
-
+
-
-
-







	/// Just deny plain auth
	fn auth_plain (&mut self, _authorization_id: &str, _authentication_id: &str, _password: &str) -> Response {
		INVALID_CREDENTIALS
	}

	/// Verify whether address is deliverable
	fn rcpt (&mut self, to: &str) -> Response {
		if self.relay {
		if self.relay || self.get_id(to).is_ok() {
			OK
		} else {
			match self.get_id(to) {
				Ok(_) => OK,
				Err(_) => {
					if self.relay {
						OK
					} else {
						NO_MAILBOX
			NO_MAILBOX
					}
				}
			}
		}
	}

	/// Save headers we need
	fn data_start (&mut self, _domain: &str, from: &str, _is8bit: bool, to: &[String]) -> Response {
		self.headers = Some(SomeHeaders{
			from: from.to_string(),