diff src/context.cpp @ 92:505e77188317

optimize verification step, cleanup documentation
author carl
date Wed, 21 Sep 2005 08:00:08 -0700
parents ca46fafc6621
children e107ade3b1c0
line wrap: on
line diff
--- a/src/context.cpp	Sun Sep 18 10:46:31 2005 -0700
+++ b/src/context.cpp	Wed Sep 21 08:00:08 2005 -0700
@@ -65,8 +65,10 @@
 
 
 int SMTP::writer() {
-	// log("writer() sees buffer with %s", buffer);
-	// log("writer() sees error %d", (int)error);
+	#ifdef VERIFY_DEBUG
+		log("writer() sees buffer with %s", buffer);
+		log("writer() sees error %d", (int)error);
+	#endif
 	int rs = 0;
 	if (!error) {
 		int len = strlen(buffer);
@@ -90,7 +92,9 @@
 int SMTP::reader() {
 	// read some bytes terminated by lf or end of buffer.
 	// we may have a multi line response or part thereof in the buffer.
-	// log("reader() sees error %d", (int)error);
+	#ifdef VERIFY_DEBUG
+		log("reader() sees error %d", (int)error);
+	#endif
 	if (error) return 0;
 	int len = maxlen-1; // room for null terminator
 	while (pending < len) {
@@ -107,7 +111,9 @@
 		}
 	}
 	buffer[pending] = '\0';
-	// log("reader() sees buffer with %s", buffer);
+	#ifdef VERIFY_DEBUG
+		log("reader() sees buffer with %s", buffer);
+	#endif
 	return pending;
 }
 
@@ -134,8 +140,10 @@
 	buffer[pending] = '\0';
 	while (true) {
 		int r = read_line();
-		// log("read_response() sees line with %s", buffer);
-		// log("read_response() sees line length %d", r);
+		#ifdef VERIFY_DEBUG
+			log("read_response() sees line with %s", buffer);
+			log("read_response() sees line length %d", r);
+		#endif
 		if (r == 0) return 0;	// failed to read any bytes
 		if ((r > 4) && (buffer[3] == '-')) {
 			flush_line(r);
@@ -168,17 +176,24 @@
 
 
 int SMTP::rset() {
-	return cmd("RSET");
+	int rc = cmd("RSET");
+	efrom[0] = '\0';
+	return rc;
 }
 
 
 int SMTP::from(char *f) {
+	if (strncmp(efrom, f, maxlen)) {
+		rset();
+		strncpy(efrom, f, maxlen);
 	init();
 	append("MAIL FROM:<");
 	append(f);
 	append(">");
 	return cmd(NULL);
 }
+	return 250; // pretend it worked
+}
 
 
 int SMTP::rcpt(char *t) {
@@ -191,27 +206,32 @@
 
 
 int SMTP::quit() {
-	int rc = cmd("QUIT");
+	return cmd("QUIT");
+}
+
+
+void SMTP::closefd() {
 	shutdown(fd, SHUT_RDWR);
 	close(fd);
-	return rc;
 }
 
 
-//	void SMTP::log(char *m, int v) {
-//		char buf[maxlen];
-//		snprintf(buf, maxlen, m, v);
-//		my_syslog(buf);
-//	}
-//
-//
-//	void SMTP::log(char *m, char *v) {
-//		char buf[maxlen];
-//		snprintf(buf, maxlen, m, v);
-//		my_syslog(buf);
-//	}
-//
-//
+#ifdef VERIFY_DEBUG
+	void SMTP::log(char *m, int v) {
+		char buf[maxlen];
+		snprintf(buf, maxlen, m, v);
+		my_syslog(buf);
+	}
+
+
+	void SMTP::log(char *m, char *v) {
+		char buf[maxlen];
+		snprintf(buf, maxlen, m, v);
+		my_syslog(buf);
+	}
+#endif
+
+
 VERIFY::VERIFY(char *h) {
 	host	 = h;
 	last_err = 0;
@@ -222,47 +242,49 @@
 void VERIFY::closer() {
 	bool ok = true;
 	while (ok) {
-		int fd = 0;
+		SMTP *conn = NULL;
 		pthread_mutex_lock(&mutex);
-			if (sockets.empty()) {
+			if (connections.empty()) {
 				ok = false;
 			}
 			else {
-				time_t t = times.front();
+				conn = connections.front();
 				time_t now = time(NULL);
-				if ((now - t) > maxage) {
-					// this socket is ancient, remove it
-					fd = sockets.front();
-					times.pop_front();
-					sockets.pop_front();
+				if ((now - conn->get_stamp()) > maxage) {
+					// this connection is ancient, remove it
+					connections.pop_front();
 				}
 				else {
 					ok = false;
+					conn = NULL;
 				}
 			}
 		pthread_mutex_unlock(&mutex);
-		if (fd) {
-			SMTP s(fd);
-			s.quit();	// closes the fd
-			// s.log("closer() closes ancient %d", fd);
+		// avoid doing this work inside the mutex lock
+		if (conn) {
+			#ifdef VERIFY_DEBUG
+				conn->log("closer() closes ancient %d", conn->get_fd());
+			#endif
+			delete conn;
 		}
 	}
 }
 
 
-int  VERIFY::get_socket() {
-	int sock = NULL_SOCKET;
+SMTP* VERIFY::get_connection() {
+	SMTP *conn = NULL;
 	pthread_mutex_lock(&mutex);
-		if (!sockets.empty()) {
-			sock = sockets.front();
-			times.pop_front();
-			sockets.pop_front();
-			// SMTP::log("get_socket() %d from cache", sock);
+		if (!connections.empty()) {
+			conn = connections.front();
+			connections.pop_front();
+			#ifdef VERIFY_DEBUG
+				conn->log("get_connection() %d from cache", conn->get_fd());
+			#endif
 		}
 	pthread_mutex_unlock(&mutex);
-
-	if (sock == NULL_SOCKET) {
+	if (conn) return conn;
 		time_t now = time(NULL);
+	int sock = NULL_SOCKET;
 		if ((now - last_err) > ERROR_SOCKET_TIME) {
 			// nothing recent, maybe this time it will work
 			hostent *h = gethostbyname(host);
@@ -286,30 +308,32 @@
 			else last_err = now;
 		}
 		if (sock != NULL_SOCKET) {
-			SMTP s(sock);
-			if (s.helo() != 250) {
-				put_socket(sock, true);
-				sock = NULL_SOCKET;
+		conn = new SMTP(sock);
+		#ifdef VERIFY_DEBUG
+			conn->log("get_connection() %d new socket", conn->get_fd());
+		#endif
+		if (conn->helo() == 250) return conn;
+		delete conn;
 			}
-		}
-	}
-	return sock;
+	return NULL;
 }
 
 
-void VERIFY::put_socket(int fd, bool err) {
-	if (err) {
-		// SMTP::log("put_socket() %d with error, close it", fd);
-		shutdown(fd, SHUT_RDWR);
-		close(fd);
+void VERIFY::put_connection(SMTP *conn) {
+	if (conn->err()) {
+		#ifdef VERIFY_DEBUG
+			conn->log("put_socket() %d with error, close it", conn->get_fd());
+		#endif
+		delete conn;
 		last_err = time(NULL);
 	}
 	else {
-		// SMTP::log("put_socket() %d", fd);
+		#ifdef VERIFY_DEBUG
+			conn->log("put_socket() %d", conn->get_fd());
+		#endif
+		conn->now();
 		pthread_mutex_lock(&mutex);
-			time_t now = time(NULL);
-			times.push_back(now);
-			sockets.push_back(fd);
+			connections.push_back(conn);
 		pthread_mutex_unlock(&mutex);
 	}
 }
@@ -317,20 +341,23 @@
 
 bool VERIFY::ok(char *from, char *to) {
 	if (host == token_myhostname) return true;
-	int fd = get_socket();
-	if (fd == NULL_SOCKET) return true; // cannot verify right now, we have socket errors
-	SMTP s(fd);
-	s.rset();
+	SMTP *conn = get_connection();
+	if (!conn) return true;    // cannot verify right now, we have socket errors
 	int rc;
-	rc = s.from(from);
-	// s.log("verify::ok from sees %d", rc);
+	rc = conn->from(from);
+	#ifdef VERIFY_DEBUG
+		conn->log("verify::ok() from sees %d", rc);
+	#endif
 	if (rc != 250) {
-		put_socket(fd, s.err());
+		conn->rset();
+		put_connection(conn);
 		return (rc >= 500) ? false : true;
 	}
-	rc = s.rcpt(to);
-	// s.log("verify::ok rcpt sees %d", rc);
-	put_socket(fd, s.err());
+	rc = conn->rcpt(to);
+	#ifdef VERIFY_DEBUG
+		conn->log("verify::ok() rcpt sees %d", rc);
+	#endif
+	put_connection(conn);
 	return (rc >= 500) ? false : true;
 }