diff options
Diffstat (limited to 'protocols/YAMN/src/proto')
-rw-r--r-- | protocols/YAMN/src/proto/md5.c | 259 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/md5.h | 27 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/netclient.h | 22 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/netlib.cpp | 271 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/netlib.h | 55 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3.cpp | 370 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3.h | 66 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3comm.cpp | 1563 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3comm.h | 97 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3opt.cpp | 1556 | ||||
-rw-r--r-- | protocols/YAMN/src/proto/pop3/pop3opt.h | 40 |
11 files changed, 4326 insertions, 0 deletions
diff --git a/protocols/YAMN/src/proto/md5.c b/protocols/YAMN/src/proto/md5.c new file mode 100644 index 0000000000..280fcdeaae --- /dev/null +++ b/protocols/YAMN/src/proto/md5.c @@ -0,0 +1,259 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */
+//#include <string.h> /* for memcpy() */ +#if defined(_WIN64) + typedef unsigned __int64 size_t; +#else + typedef unsigned int size_t; +#endif +void * __cdecl memcpy(void *, const void *, size_t);
+void * __cdecl memset(void *, int, size_t);
+#include "md5.h" + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif diff --git a/protocols/YAMN/src/proto/md5.h b/protocols/YAMN/src/proto/md5.h new file mode 100644 index 0000000000..e264f686db --- /dev/null +++ b/protocols/YAMN/src/proto/md5.h @@ -0,0 +1,27 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef __alpha +typedef unsigned int uint32; +#else +typedef unsigned long uint32; +#endif + +struct MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/protocols/YAMN/src/proto/netclient.h b/protocols/YAMN/src/proto/netclient.h new file mode 100644 index 0000000000..2414dbdef1 --- /dev/null +++ b/protocols/YAMN/src/proto/netclient.h @@ -0,0 +1,22 @@ +#ifndef __CLIENT_H
+#define __CLIENT_H
+
+class CNetClient
+{
+public:
+ CNetClient(): Stopped(FALSE) {}
+ virtual void Connect(const char* servername,const int port)=0;
+ virtual void Send(const char *query)=0;
+ virtual char* Recv(char *buf=NULL,int buflen=65536)=0;
+ virtual void Disconnect()=0;
+ virtual BOOL Connected()=0;
+ virtual void SSLify()=0;
+
+ BOOL Stopped;
+ int Rcv;
+ DWORD NetworkError;
+ DWORD SystemError;
+ BOOL ifTLSed;
+};
+
+#endif
diff --git a/protocols/YAMN/src/proto/netlib.cpp b/protocols/YAMN/src/proto/netlib.cpp new file mode 100644 index 0000000000..b7c1864ffa --- /dev/null +++ b/protocols/YAMN/src/proto/netlib.cpp @@ -0,0 +1,271 @@ +/*
+ * This code implements communication based on Miranda netlib library
+ *
+ * (c) majvan 2002-2004
+ */
+
+#include "..\yamn.h"
+#include "m_netlib.h"
+#include "netlib.h"
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+BOOL SSLLoaded=FALSE;
+HANDLE hNetlibUser=NULL;
+
+extern PVOID TLSCtx;
+extern PVOID SSLCtx;
+
+void __stdcall SSL_DebugLog(const char *fmt, ...)
+{
+ char str[ 4096 ];
+ va_list vararg;
+
+ va_start( vararg, fmt );
+ int tBytes = _vsnprintf( str, sizeof(str)-1, fmt, vararg );
+ if ( tBytes == 0 )
+ return;
+
+ if ( tBytes > 0 )
+ str[ tBytes ] = 0;
+ else
+ str[ sizeof(str)-1 ] = 0;
+
+ CallService(MS_NETLIB_LOG, (WPARAM)hNetlibUser, (LPARAM)str);
+ va_end( vararg );
+}
+
+HANDLE RegisterNLClient(const char *name)
+{
+ static NETLIBUSER nlu={0};
+ char desc[128];
+
+ sprintf(desc, Translate("%s connection"),name);
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Register PROXY support>");
+#endif
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS;
+ nlu.szDescriptiveName=desc;
+ nlu.szSettingsModule=(char *)name;
+ hNetlibUser=(HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu);
+
+#ifdef DEBUG_COMM
+ if (NULL==hNetlibUser)
+ DebugLog(CommFile,"<error></Register PROXY support>\n");
+ else
+ DebugLog(CommFile,"</Register PROXY support>\n");
+#endif
+ return hNetlibUser;
+}
+
+//Move connection to SSL
+void CNLClient::SSLify() throw(DWORD){
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Staring SSL...");
+#endif
+ int socket = CallService(MS_NETLIB_GETSOCKET, (WPARAM)hConnection, 0);
+ if (socket != INVALID_SOCKET)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Staring netlib core SSL");
+#endif
+ if (CallService(MS_NETLIB_STARTSSL, (WPARAM)hConnection, 0))
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Netlib core SSL started");
+#endif
+ isTLSed = true;
+ SSLLoaded = TRUE;
+ return;
+ }
+ }
+
+ //ssl could not be created
+ throw NetworkError = (DWORD)ESSL_CREATESSL;
+}
+
+//Connects to the server through the sock
+//if not success, exception is throwed
+void CNLClient::Connect(const char* servername,const int port) throw(DWORD)
+{
+ NETLIBOPENCONNECTION nloc;
+
+ NetworkError=SystemError=0;
+ isTLSed = false;
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<connect>\n");
+#endif
+ try
+ {
+ nloc.cbSize=sizeof(NETLIBOPENCONNECTION);
+ nloc.szHost=servername;
+ nloc.wPort=port;
+ nloc.flags=0;
+ if (NULL==(hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)hNetlibUser,(LPARAM)&nloc)))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_CONNECT;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</connect>\n");
+#endif
+ return;
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></connect>\n");
+#endif
+ throw;
+ }
+}
+
+//Performs a simple query
+// query- command to send
+int CNLClient::LocalNetlib_Send(HANDLE hConn,const char *buf,int len,int flags) {
+ if (isTLSed)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("SSL send: %s", buf);
+#endif
+ }
+
+ NETLIBBUFFER nlb={(char*)buf,len,flags};
+ return CallService(MS_NETLIB_SEND,(WPARAM)hConn,(LPARAM)&nlb);
+}
+
+void CNLClient::Send(const char *query) throw(DWORD)
+{
+ unsigned int Sent;
+
+ if (NULL==query)
+ return;
+ if (hConnection==NULL)
+ return;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<send>%s",query);
+#endif
+ try
+ {
+ if ((SOCKET_ERROR==(Sent=LocalNetlib_Send(hConnection,query,(int)strlen(query),MSG_DUMPASTEXT))) || Sent!=(unsigned int)strlen(query))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_SEND;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</send>\n");
+#endif
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></send>\n");
+#endif
+ throw;
+ }
+}
+
+//Reads data from socket
+// buf- buffer where to store max. buflen of received characters
+// if buf is NULL, creates buffer of buflen size
+// buf is NULL by default
+//You need free() returned buffer, which can be allocated in this function
+//if not success, exception is throwed
+
+int CNLClient::LocalNetlib_Recv(HANDLE hConn,char *buf,int len,int flags) {
+ NETLIBBUFFER nlb={buf,len,flags};
+ int iReturn = CallService(MS_NETLIB_RECV,(WPARAM)hConn,(LPARAM)&nlb);
+ if (isTLSed)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("SSL recv: %s", buf);
+#endif
+ }
+
+ return iReturn;
+}
+
+char* CNLClient::Recv(char *buf,int buflen) throw(DWORD)
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<reading>");
+#endif
+ try
+ {
+ if (buf==NULL)
+ buf=(char *)malloc(sizeof(char)*(buflen+1));
+ if (buf==NULL)
+ throw NetworkError=(DWORD)ENL_RECVALLOC;
+
+ if (!isTLSed)
+ {
+ NETLIBSELECT nls;
+ memset(&nls, 0, sizeof(NETLIBSELECT));
+ nls.cbSize = sizeof(NETLIBSELECT);
+ nls.dwTimeout = 60000;
+ nls.hReadConns[0] = hConnection;
+ switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls))
+ {
+ case SOCKET_ERROR:
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError = (DWORD) ENL_RECV;
+ case 0: // time out!
+ free(buf);
+ throw NetworkError = (DWORD) ENL_TIMEOUT;
+ }
+ }
+
+ ZeroMemory(buf,buflen);
+ if (SOCKET_ERROR==(Rcv=LocalNetlib_Recv(hConnection,buf,buflen,MSG_DUMPASTEXT)))
+ {
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_RECV;
+ }
+ if (!Rcv)
+ {
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_RECV;
+ }
+#ifdef DEBUG_COMM
+ *(buf+Rcv)=0; //end the buffer to write it to file
+ DebugLog(CommFile,"%s",buf);
+ DebugLog(CommFile,"</reading>\n");
+#endif
+ return(buf);
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></reading>\n");
+#endif
+ throw;
+ }
+}
+
+//Closes netlib connection
+void CNLClient::Disconnect()
+{
+ Netlib_CloseHandle(hConnection);
+ hConnection=(HANDLE)NULL;
+}
+
+//Uninitializes netlib library
+void UnregisterNLClient()
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Unregister PROXY support>");
+#endif
+
+ Netlib_CloseHandle(hNetlibUser);
+ hNetlibUser=(HANDLE)NULL;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</Unregister PROXY support>\n");
+#endif
+}
diff --git a/protocols/YAMN/src/proto/netlib.h b/protocols/YAMN/src/proto/netlib.h new file mode 100644 index 0000000000..90ad3613a5 --- /dev/null +++ b/protocols/YAMN/src/proto/netlib.h @@ -0,0 +1,55 @@ +#ifndef __NETLIB_H
+#define __NETLIB_H
+
+#include "netclient.h"
+
+#pragma warning( disable : 4290 )
+
+class CNLClient: public CNetClient
+{
+public:
+ CNLClient(): hConnection(NULL) {}
+ void Connect(const char* servername,const int port) throw(DWORD);
+ void Send(const char *query) throw(DWORD);
+ char* Recv(char *buf=NULL,int buflen=65536) throw(DWORD);
+ void Disconnect();
+ void SSLify()throw(DWORD);
+
+ inline BOOL Connected() {return hConnection!=NULL;}
+
+protected:
+ HANDLE hConnection;
+ BOOL isTLSed;
+ int LocalNetlib_Send(HANDLE hConn,const char *buf,int len,int flags);
+ int LocalNetlib_Recv(HANDLE hConn,char *buf,int len,int flags);
+};
+
+void SSL_DebugLog(const char *fmt, ...);
+
+enum
+{
+ ENL_WINSOCKINIT=1, //error initializing socket //only wsock
+ ENL_GETHOSTBYNAME, //DNS error //only wsock
+ ENL_CREATESOCKET, //error creating socket //only wsock
+ ENL_CONNECT, //cannot connect to server
+ ENL_SEND, //cannot send data
+ ENL_RECV, //cannot receive data
+ ENL_RECVALLOC, //cannot allocate memory for received data
+ ENL_TIMEOUT, //timed out during recv
+};
+
+enum
+{
+ ESSL_NOTLOADED=1, //OpenSSL is not loaded
+ ESSL_WINSOCKINIT, //WinSock 2.0 init failed
+ ESSL_GETHOSTBYNAME, //DNS error
+ ESSL_CREATESOCKET, //error creating socket
+ ESSL_SOCKETCONNECT, //error connecting with socket
+ ESSL_CREATESSL, //error creating SSL session structure
+ ESSL_SETSOCKET, //error connect socket with SSL session for bidirect I/O space
+ ESSL_CONNECT, //cannot connect to server
+ ESSL_SEND, //cannot send data
+ ESSL_RECV, //cannot receive data
+ ESSL_RECVALLOC, //cannot allocate memory for received data
+};
+#endif
diff --git a/protocols/YAMN/src/proto/pop3/pop3.cpp b/protocols/YAMN/src/proto/pop3/pop3.cpp new file mode 100644 index 0000000000..05e85d7156 --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3.cpp @@ -0,0 +1,370 @@ +/* + * This code implements basics of POP3 protocol + * + * (c) majvan 2002-2004 + */ +/* This was made from the libspopc project + * copyright c 2002 Benoit Rouits <brouits@free.fr> + * released under the terms of GNU LGPL + * (GNU Lesser General Public Licence). + * libspopc offers simple API for a pop3 client (MTA). + * See RFC 1725 for pop3 specifications. + * more information on http://brouits.free.fr/libspopc/ + */ +/* + * This file is not original and is changed by majvan <om3tn@psg.sk> + * for mail checker purpose. Please see original web page to + * obtain the original. I rewrote it in C++, but good ideas were, + * I think, unchanged. + * + * Note that this file was not designed to work under Unix. It's + * needed to add Unix-specific features. I was interested only in + * Windows for my project. majvan + * + */ + +#pragma warning( disable : 4290 ) + +#include "..\..\yamn.h" +#include "pop3.h" + +extern "C" { +#include "../md5.h" +} + +extern void __stdcall SSL_DebugLog( const char *fmt, ... ); + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +//Connects to the server through the netlib +//if not success, exception is throwed +//returns welcome string returned by server +//sets AckFlag +char *CPop3Client::Connect(const char* servername,const int port,BOOL UseSSL, BOOL NoTLS) +{ + char *temp = 0; + if (Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + if (NetClient!=NULL) + delete NetClient; + SSL=UseSSL; + NetClient=new CNLClient; + +#ifdef DEBUG_DECODE + DebugLog(DecodeFile,"Connect:servername: %s port:%d\n",servername,port); +#endif + POP3Error=EPOP3_CONNECT; + NetClient->Connect(servername,port); + POP3Error=0; + + if (SSL) + { + try { NetClient->SSLify(); } + catch (...) + { + NetClient->Disconnect(); + return NULL; + } + } + + temp = RecvRest(NetClient->Recv(),POP3_SEARCHACK); + extern BOOL SSLLoaded; + if (!NoTLS & !(SSL)) { + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + NetClient->Send("STLS\r\n"); + free(temp); + temp=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if (AckFlag==POP3_FOK){ // Ok, we are going to tls + try { + NetClient->SSLify(); + } catch (...) { + NetClient->Disconnect(); + return NULL; + } +// temp = RecvRest(NetClient->Recv(),POP3_SEARCHACK); + } + } +// SSL_DebugLog("Received: %s",temp); + return temp; +} + +//Receives data to the end of packet +// prev- previous data read (appends to this string next received data) +// mode- mode of packet. +// Packet can end with ack state (+OK or -ERR): set mode to POP3_SEARCHACK +// If packet ends with '.' (end of string), set mode to POP3_SEARCHDOT +// size- received data are stored to memory, but if length of data is more than allocated memory, function allocates +// new memory. New allocated memory has allocated size more bytes +// This value can be selectable: if you think it is better to reallocate by 1kB size, select size to 1024, +// default is 128. You do not need to use this parameter +char* CPop3Client::RecvRest(char* prev,int mode,int size) +{ + int SizeRead=0; + int SizeLeft=size-NetClient->Rcv; + int RcvAll=NetClient->Rcv; + char *LastString,*PrevString=prev; + + AckFlag=0; + + while(((mode==POP3_SEARCHDOT) && !SearchFromEnd(PrevString+RcvAll-1,RcvAll-3,POP3_SEARCHDOT) && !SearchFromStart(PrevString,2,POP3_SEARCHERR)) || //we are looking for dot or -err phrase + ((mode==POP3_SEARCHACK) && (!SearchFromStart(PrevString,RcvAll-3,mode) || !((RcvAll>3) && SearchFromEnd(PrevString+RcvAll-1,1,POP3_SEARCHNL))))) //we are looking for +ok or -err phrase ended with newline + { //if not found + if (NetClient->Stopped) //check if we can work with this POP3 client session + { + if (PrevString!=NULL) + free(PrevString); + throw POP3Error=(DWORD)EPOP3_STOPPED; + } + if (SizeLeft==0) //if block is full + { + SizeRead+=size; + SizeLeft=size; + LastString=NetClient->Recv(NULL,SizeLeft); + PrevString=(char *)realloc(PrevString,sizeof(char)*(SizeRead+size)); + if (PrevString==NULL) + throw POP3Error=(DWORD)EPOP3_RESTALLOC; + memcpy(PrevString+SizeRead,LastString,size); + free(LastString); + } + else + NetClient->Recv(PrevString+RcvAll,SizeLeft); //to Rcv stores received bytes + SizeLeft=SizeLeft-NetClient->Rcv; + RcvAll+=NetClient->Rcv; +// printf("[Read: %s]\n",PrevString); + } + NetClient->Rcv=RcvAll; //at the end, store the number of all bytes, no the number of last received bytes + return PrevString; +} + +// CPop3Client::SearchFromEnd +// returns 1 if substring DOTLINE or ENDLINE found from end in bs bytes +// if you need to add condition for mode, insert it into switch statement +BOOL CPop3Client::SearchFromEnd(char *end,int bs,int mode) +{ + while(bs>=0) + { + switch(mode) + { + case POP3_SEARCHDOT: + if (DOTLINE(end)) + return 1; + break; + case POP3_SEARCHNL: + if (ENDLINE(end)) + return 1; + break; + } + end--; + bs--; + } + return 0; +} + +//Finds for a occurence of some pattern in string +// returns 1 if substring OKLINE, ERRLINE or any of them found from start in bs bytes +//call only this function to retrieve ack status (+OK or -ERR), because it sets flag AckFlag +//if you need to add condition for mode, insert it into switch statement +BOOL CPop3Client::SearchFromStart(char *start,int bs,int mode) +{ + while(bs>=0) + { + switch(mode) + { + case POP3_SEARCHOK: + if (OKLINE(start)) + { + AckFlag=POP3_FOK; + return 1; + } + break; + case POP3_SEARCHERR: + if (ERRLINE(start)) + { + AckFlag=POP3_FERR; + return 1; + } + break; + case POP3_SEARCHACK: + if (ACKLINE(start)) + { + OKLINE(start) ? AckFlag=POP3_FOK : AckFlag=POP3_FERR; + return 1; + } + break; + } + start++; + bs--; + } + return 0; +} + +//Performs "USER" pop query and returns server response +//sets AckFlag +char* CPop3Client::User(char* name) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + char *Result; + + sprintf(query,"USER %s\r\n",name); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if (AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADUSER; + POP3Error=0; + return Result; +} + +//Performs "PASS" pop query and returns server response +//sets AckFlag +char* CPop3Client::Pass(char* pw) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + char *Result; + + sprintf(query,"PASS %s\r\n",pw); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if (AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADPASS; + return Result; +} + +//Performs "APOP" pop query and returns server response +//sets AckFlag +char* CPop3Client::APOP(char* name, char* pw, char* timestamp) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[512]; + char *Result; + unsigned char digest[16]; + char hexdigest[40]; + + if (timestamp==NULL) + throw POP3Error=(DWORD)EPOP3_APOP; + MD5Context ctx; + MD5Init(&ctx); + MD5Update(&ctx,(const unsigned char *)timestamp,(unsigned int)strlen(timestamp)); + MD5Update(&ctx,(const unsigned char *)pw,(unsigned int)strlen(pw)); + MD5Final(digest,&ctx); + hexdigest[0]='\0'; + for (int i=0; i<16; i++) { + char tmp[4]; + sprintf(tmp, "%02x", digest[i]); + strcat(hexdigest, tmp); + } + sprintf(query,"APOP %s %s\r\n",name, hexdigest); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if (AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADUSER; + return Result; +} + +//Performs "QUIT" pop query and returns server response +//sets AckFlag +char* CPop3Client::Quit() +{ + char query[]="QUIT\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} + +//Performs "STAT" pop query and returns server response +//sets AckFlag +char* CPop3Client::Stat() +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[]="STAT\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} + +//Performs "LIST" pop query and returns server response +//sets AckFlag +char* CPop3Client::List() +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[]="LIST\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "TOP" pop query and returns server response +//sets AckFlag +char* CPop3Client::Top(int nr, int lines) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + sprintf(query,"TOP %d %d\r\n",nr,lines); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "UIDL" pop query and returns server response +//sets AckFlag +char* CPop3Client::Uidl(int nr) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + if (nr) + { + sprintf(query,"UIDL %d\r\n",nr); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); + } + sprintf(query,"UIDL\r\n"); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "DELE" pop query and returns server response +//sets AckFlag +char* CPop3Client::Dele(int nr) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + sprintf(query,"DELE %d\r\n",nr); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} +//Performs "RETR" pop query and returns server response +//sets AckFlag +char* CPop3Client::Retr(int nr) +{ + if (NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + sprintf(query,"RETR %d\r\n",nr); + NetClient->Send(query); + RecvRest(NetClient->Recv(),POP3_SEARCHACK); + return NetClient->Recv(); +}
\ No newline at end of file diff --git a/protocols/YAMN/src/proto/pop3/pop3.h b/protocols/YAMN/src/proto/pop3/pop3.h new file mode 100644 index 0000000000..1f7f2ea737 --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3.h @@ -0,0 +1,66 @@ +#ifndef __POP3_H
+#define __POP3_H
+
+#include "../../debug.h"
+#include "../netlib.h" //NetLib client
+
+#define DOTLINE(s) ((((s)[-2]=='\r') || ((s)[-2]=='\n')) && ((s)[-1]=='.') && (((s)[0]=='\r') || ((s)[0]=='\n') || ((s)[0]=='\0'))) // be careful, it's different to ESR's pop3.c ;-)
+#define ENDLINE(s) (((s)[0]=='\r') || ((s)[0]=='\n')) //endline
+#define OKLINE(s) (((s)[0]=='+') && (((s)[1]=='o') || ((s)[1]=='O')) && (((s)[2]=='k') || ((s)[2]=='K'))) // +OK
+#define ERRLINE(s) (((s)[0]=='-') && (((s)[1]=='e') || ((s)[1]=='E')) && (((s)[2]=='r') || ((s)[2]=='R')) && (((s)[3]=='r') || ((s)[3]=='R'))) // -ERR
+#define ACKLINE(s) (OKLINE(s) || ERRLINE(s))
+
+#define POP3_SEARCHDOT 1
+#define POP3_SEARCHACK 2
+#define POP3_SEARCHOK 3
+#define POP3_SEARCHERR 4
+#define POP3_SEARCHNL 5
+
+#define POP3_FOK 1
+#define POP3_FERR 2
+
+class CPop3Client
+{
+public:
+ CPop3Client(): NetClient(NULL), Stopped(FALSE) {}
+ ~CPop3Client() {if (NetClient!=NULL) delete NetClient;}
+
+ char* Connect(const char* servername,const int port=110,BOOL UseSSL=FALSE, BOOL NoTLS=FALSE);
+ char* RecvRest(char* prev,int mode,int size=65536);
+ char* User(char* name);
+ char* Pass(char* pw);
+ char* APOP(char* name, char* pw, char* timestamp);
+ char* Quit();
+ char* Stat();
+ char* List();
+ char* Top(int nr, int lines=0);
+ char* Uidl(int nr=0);
+ char* Dele(int nr);
+ char* Retr(int nr);
+
+ unsigned char AckFlag;
+ BOOL SSL;
+ BOOL Stopped;
+
+ DWORD POP3Error;
+ class CNetClient *NetClient; //here the network layout is defined (TCP or SSL+TCP etc.)
+private:
+ BOOL SearchFromEnd(char *end,int bs,int mode);
+ BOOL SearchFromStart(char *end,int bs,int mode);
+};
+
+enum
+{
+ EPOP3_QUEUEALLOC=1, //memory allocation
+ EPOP3_STOPPED, //stop account
+ EPOP3_CONNECT, //cannot connect to server
+ EPOP3_RESTALLOC, //cannot allocate memory for received data
+ EPOP3_BADUSER, //cannot login because USER command failed
+ EPOP3_BADPASS, //cannot login because PASS command failed
+ EPOP3_APOP, //server does not send timestamp for APOP auth
+ EPOP3_STAT,
+ EPOP3_LIST,
+ EPOP3_UIDL,
+};
+
+#endif
diff --git a/protocols/YAMN/src/proto/pop3/pop3comm.cpp b/protocols/YAMN/src/proto/pop3/pop3comm.cpp new file mode 100644 index 0000000000..954f1b5860 --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3comm.cpp @@ -0,0 +1,1563 @@ +/*
+ * This code implements POP3 server checking for new mail and so on.
+ * There's function SynchroPOP3 in this file- for checking and synchronising POP3 account
+ * and DeleteMailsPOP3- for deleting mails from POP3 server
+ *
+ * Note this file acts as main file for internal plugin.
+ *
+ * (c) majvan 2002-2004
+ * 18/08
+*/
+
+
+#pragma warning( disable : 4290 )
+#include "../../yamn.h"
+#include "../../main.h"
+#include "pop3.h"
+#include "pop3comm.h" //all we need for POP3 account (POP3 account= YAMN account + some more POP3 specified members)
+#include <m_netlib.h> //socket thorugh proxy functions
+
+#define ERRORSTR_MAXLEN 1024 //in wide-chars
+
+//--------------------------------------------------------------------------------------------------
+
+HANDLE hNetLib = NULL;
+PSCOUNTER CPOP3Account::AccountWriterSO = NULL;
+
+//Creates new CPOP3Account structure
+HACCOUNT WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN Plugin,DWORD CAccountVersion);
+
+//Deletes CPOP3Account structure
+void WINAPI DeletePOP3Account(HACCOUNT Which);
+
+//Sets stop flag to account
+void WINAPI StopPOP3Account(HACCOUNT Which);
+
+//Function registers standard functions for YAMN
+int RegisterPOP3Plugin(WPARAM,LPARAM);
+
+//Unloads all variables created on heap (delete[])
+DWORD WINAPI UnLoadPOP3(void *);
+
+//Function writes POP3 accounts using YAMN exported functions
+DWORD WINAPI WritePOP3Accounts();
+
+//Function stores plugin's data for account to file
+DWORD WINAPI WritePOP3Options(HANDLE,HACCOUNT);
+
+//Function reads plugin's data for account from file
+DWORD WINAPI ReadPOP3Options(HACCOUNT,char **,char *);
+
+//Creates new mail for an account
+HYAMNMAIL WINAPI CreatePOP3Mail(HACCOUNT Account,DWORD CMimeMailVersion);
+
+//Function does all needed work when connection failed or any error occured
+//Creates structure containing error code, closes internet session, runs "bad connect" function
+static void PostErrorProc(HPOP3ACCOUNT ActualAccount,void *ParamToBadConnect,DWORD POP3PluginParam,BOOL UseSSL);
+
+//Checks POP3 account and stores all info to account. It deletes old mails=> synchro
+// WhichTemp- pointer to strucure containing needed information
+DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp);
+
+//Deletes mails from POP3 server
+// WhichTemp- structure containing needed information (queued messages to delete)
+//Function deletes from memory queue in WhichTemp structure
+DWORD WINAPI DeleteMailsPOP3(struct DeleteParam *WhichTemp);
+
+//Function makes readable message about error. It sends it back to YAMN, so YAMN then
+//can show it to the message window
+TCHAR* WINAPI GetErrorString(DWORD Code);
+
+//Function deletes string allocated in GetErrorString
+void WINAPI DeleteErrorString(LPVOID String);
+
+//Extracts info from result of POP3's STAT command
+// stream- source string
+// len- length of source string
+// mboxsize- adreess to integer, that receives size of mailbox
+// mails- adreess to integer, that receives number of mails
+void ExtractStat(char *stream,int len,int *mboxsize,int *mails);
+
+//Extracts mail ID on mailbox
+// stream- source string
+// len- length of source string
+// queue- address of first message, where first ID will be stored
+void ExtractUIDL(char *stream,int len,HYAMNMAIL queue);
+
+//Extracts mail size on mailbox
+// stream- source string
+// len- length of source string
+// queue- address of first message, where size of message #1 will be stored
+void ExtractList(char *stream,int len,HYAMNMAIL queue);
+
+void ExtractMail(char *stream,int len,HYAMNMAIL queue);
+
+YAMNExportedFcns *pYAMNFcn = NULL;
+MailExportedFcns *pYAMNMailFcn = NULL;
+
+YAMN_PROTOIMPORTFCN POP3ProtocolFunctions =
+{
+ CreatePOP3Account,
+ DeletePOP3Account,
+ StopPOP3Account,
+ WritePOP3Options,
+ ReadPOP3Options,
+ SynchroPOP3,
+ SynchroPOP3,
+ SynchroPOP3,
+ DeleteMailsPOP3,
+ GetErrorString,
+ NULL,
+ DeleteErrorString,
+ WritePOP3Accounts,
+ NULL,
+ UnLoadPOP3,
+};
+
+YAMN_MAILIMPORTFCN POP3MailFunctions =
+{
+ CreatePOP3Mail,
+ NULL,
+ NULL,
+ NULL,
+};
+
+PYAMN_VARIABLES pYAMNVar = NULL;
+HYAMNPROTOPLUGIN POP3Plugin = NULL;
+
+YAMN_PROTOREGISTRATION POP3ProtocolRegistration =
+{
+ "POP3 protocol (internal)",
+ YAMN_VERSION_C,
+ "© 2002-2004 majvan | 2005-2007 tweety, yb",
+ "Mail notifier and browser for Miranda NG. Included POP3 protocol.",
+ "francois.mean@skynet.be",
+ "http://miranda-ng.org/",
+};
+
+static TCHAR *FileName = NULL;
+
+HANDLE RegisterNLClient(const char *name);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+CPOP3Account::CPOP3Account()
+{
+//NOTE! This constructor constructs CAccount structure. If your plugin is not internal,
+//you will need these constructors. All you need is in Account.cpp. Just copy to your source code
+//constructor and destructor of CAccount.
+ UseInternetFree=CreateEvent(NULL,FALSE,TRUE,NULL);
+ InternetQueries=new SCOUNTER;
+ AbilityFlags=YAMN_ACC_BROWSE | YAMN_ACC_POPUP;
+
+ SetAccountStatus((HACCOUNT)this,TranslateT("Disconnected"));
+}
+
+CPOP3Account::~CPOP3Account()
+{
+ CloseHandle(UseInternetFree);
+ if (InternetQueries!=NULL)
+ delete InternetQueries;
+}
+
+HACCOUNT WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN Plugin,DWORD CAccountVersion)
+{
+//First, we should check whether CAccountVersion matches.
+//But this is internal plugin, so YAMN's CAccount structure and our CAccount structure are
+//the same, so we do not need to test version. Otherwise, if CAccount version does not match
+//in your plugin, you should return NULL, like this:
+// if (CAccountVersion!=YAMN_ACCOUNTVERSION) return NULL;
+
+//Now it is needed to construct our POP3 account and return its handle
+ return (HACCOUNT)new struct CPOP3Account();
+}
+
+void WINAPI DeletePOP3Account(HACCOUNT Which)
+{
+ delete (HPOP3ACCOUNT)Which;
+}
+
+void WINAPI StopPOP3Account(HACCOUNT Which)
+{
+ ((HPOP3ACCOUNT)Which)->Client.Stopped=TRUE;
+ if (((HPOP3ACCOUNT)Which)->Client.NetClient!=NULL) //we should inform also network client. Usefull only when network client implements this feature
+ ((HPOP3ACCOUNT)Which)->Client.NetClient->Stopped=TRUE;
+}
+
+//This function is like main function for POP3 internal protocol
+int RegisterPOP3Plugin(WPARAM,LPARAM)
+{
+
+ //Get YAMN variables we can use
+ if (NULL==(pYAMNVar=(PYAMN_VARIABLES)CallService(MS_YAMN_GETVARIABLES,(WPARAM)YAMN_VARIABLESVERSION,(LPARAM)0)))
+ return 0;
+
+ //We have to get pointers to YAMN exported functions: allocate structure and fill it
+ if (NULL==(pYAMNFcn=new struct YAMNExportedFcns))
+ {UnLoadPOP3(0); return 0;}
+
+ //Register new pop3 user in netlib
+ if (NULL==(hNetLib=RegisterNLClient("YAMN-POP3")))
+ {UnLoadPOP3(0); return 0;}
+
+ pYAMNFcn->SetProtocolPluginFcnImportFcn=(YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETPROTOCOLPLUGINFCNIMPORTID,(LPARAM)0);
+ pYAMNFcn->WaitToWriteFcn=(YAMN_WAITTOWRITEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOWRITEID,(LPARAM)0);
+ pYAMNFcn->WriteDoneFcn=(YAMN_WRITEDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WRITEDONEID,(LPARAM)0);
+ pYAMNFcn->WaitToReadFcn=(YAMN_WAITTOREADFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOREADID,(LPARAM)0);
+ pYAMNFcn->ReadDoneFcn=(YAMN_READDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_READDONEID,(LPARAM)0);
+ pYAMNFcn->SCGetNumberFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCGETNUMBERID,(LPARAM)0);
+ pYAMNFcn->SCIncFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCINCID,(LPARAM)0);
+ pYAMNFcn->SCDecFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCDECID,(LPARAM)0);
+ pYAMNFcn->SetStatusFcn=(YAMN_SETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETSTATUSID,(LPARAM)0);
+ pYAMNFcn->GetStatusFcn=(YAMN_GETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_GETSTATUSID,(LPARAM)0);
+
+ if (NULL==(pYAMNMailFcn=new struct MailExportedFcns))
+ {UnLoadPOP3(0); return 0;}
+
+ pYAMNMailFcn->SynchroMessagesFcn=(YAMN_SYNCHROMIMEMSGSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SYNCHROMIMEMSGSID,(LPARAM)0);
+ pYAMNMailFcn->TranslateHeaderFcn=(YAMN_TRANSLATEHEADERFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_TRANSLATEHEADERID,(LPARAM)0);
+ pYAMNMailFcn->AppendQueueFcn=(YAMN_APPENDQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_APPENDQUEUEID,(LPARAM)0);
+ pYAMNMailFcn->DeleteMessagesToEndFcn=(YAMN_DELETEMIMEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEQUEUEID,(LPARAM)0);
+ pYAMNMailFcn->DeleteMessageFromQueueFcn=(YAMN_DELETEMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEMESSAGEID,(LPARAM)0);
+ pYAMNMailFcn->FindMessageByIDFcn=(YAMN_FINDMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_FINDMIMEMESSAGEID,(LPARAM)0);
+ pYAMNMailFcn->CreateNewDeleteQueueFcn=(YAMN_CREATENEWDELETEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_CREATENEWDELETEQUEUEID,(LPARAM)0);
+
+ //set static variable
+ if (CPOP3Account::AccountWriterSO==NULL) {
+ if (NULL==(CPOP3Account::AccountWriterSO=new SCOUNTER))
+ {UnLoadPOP3(0); return 0;}
+ }
+
+ //First, we register this plugin
+ //it is quite impossible this function returns zero (failure) as YAMN and internal plugin structre versions are the same
+ POP3ProtocolRegistration.Name = Translate("POP3 protocol (internal)");
+ POP3ProtocolRegistration.Description = Translate("Mail notifier and browser for Miranda NG. Included POP3 protocol.");
+ if (NULL==(POP3Plugin=(HYAMNPROTOPLUGIN)CallService(MS_YAMN_REGISTERPROTOPLUGIN,(WPARAM)&POP3ProtocolRegistration,(LPARAM)YAMN_PROTOREGISTRATIONVERSION)))
+ return 0;
+
+ //Next we set our imported functions for YAMN
+ if (!SetProtocolPluginFcnImport(POP3Plugin,&POP3ProtocolFunctions,YAMN_PROTOIMPORTFCNVERSION,&POP3MailFunctions,YAMN_MAILIMPORTFCNVERSION))
+ return 0;
+
+ //Then, we read all mails for accounts.
+ //You must first register account, before using this function as YAMN must use CreatePOP3Account function to add new accounts
+ //But if CreatePOP3Account is not implemented (equals to NULL), YAMN creates account as YAMN's standard HACCOUNT
+ if (FileName) CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName, 0); //shoud not happen (only for secure)
+ FileName = (TCHAR *)CallService(MS_YAMN_GETFILENAME,(WPARAM)_T("pop3"), 0);
+
+ switch(CallService(MS_YAMN_READACCOUNTS,(WPARAM)POP3Plugin,(LPARAM)FileName)) {
+ case EACC_FILEVERSION:
+ MessageBox(NULL,TranslateT("Found new version of account book, not compatible with this version of YAMN."),TranslateT("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ FileName = NULL;
+ return 0;
+ case EACC_FILECOMPATIBILITY:
+ MessageBox(NULL,TranslateT("Error reading account file. Account file corrupted."),TranslateT("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ FileName = NULL;
+ return 0;
+ case EACC_ALLOC:
+ MessageBox(NULL,TranslateT("Memory allocation error while data reading"),TranslateT("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ FileName = NULL;
+ return 0;
+ case EACC_SYSTEM:
+ if (ERROR_FILE_NOT_FOUND!=GetLastError())
+ {
+ TCHAR temp[1024] = {0};
+ mir_sntprintf(temp, SIZEOF(temp), _T("%s\n%s"),TranslateT("Reading file error. File already in use?"),FileName);
+ MessageBox(NULL,temp,TranslateT("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ FileName = NULL;
+ return 0;
+ }
+ break;
+ }
+ //HookEvent(ME_OPT_INITIALISE,POP3OptInit);
+
+ HACCOUNT Finder;
+ HANDLE hContact;
+ DBVARIANT dbv;
+ char *szProto;
+
+ for (Finder=POP3Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ {
+ Finder->hContact = NULL;
+ hContact = db_find_first();
+ while(hContact)
+ {
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (szProto != NULL && strcmp(szProto, YAMN_DBMODULE)==0)
+ {
+ if (!DBGetContactSettingString(hContact,YAMN_DBMODULE,"Id",&dbv)) {
+ if ( strcmp( dbv.pszVal, Finder->Name) == 0) {
+ Finder->hContact = hContact;
+ DBWriteContactSettingWord(Finder->hContact, YAMN_DBMODULE, "Status", ID_STATUS_ONLINE);
+ DBWriteContactSettingString(Finder->hContact, "CList", "StatusMsg", Translate("No new mail message"));
+ if ((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ DBDeleteContactSetting(Finder->hContact, "CList", "Hidden");
+
+ if (!(Finder->Flags & YAMN_ACC_ENA) || !(Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ DBWriteContactSettingByte(Finder->hContact, "CList", "Hidden", 1);
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ hContact = db_find_next(hContact);
+ }
+
+ if (Finder->hContact == NULL && (Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT)) {
+ //No account contact found, have to create one
+ Finder->hContact =(HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)Finder->hContact,(LPARAM)YAMN_DBMODULE);
+ DBWriteContactSettingString(Finder->hContact,YAMN_DBMODULE,"Id",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,YAMN_DBMODULE,"Nick",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,"Protocol","p",YAMN_DBMODULE);
+ DBWriteContactSettingWord(Finder->hContact, YAMN_DBMODULE, "Status", YAMN_STATUS);
+ }
+ }
+
+ return 0;
+}
+
+DWORD WINAPI UnLoadPOP3(void *)
+{
+ //pYAMNVar is only a pointr, no need delete or free
+ if (hNetLib) {
+ Netlib_CloseHandle(hNetLib); hNetLib = NULL;}
+ if (CPOP3Account::AccountWriterSO) {
+ delete CPOP3Account::AccountWriterSO; CPOP3Account::AccountWriterSO = NULL;}
+ if (pYAMNMailFcn) {
+ delete pYAMNMailFcn; pYAMNMailFcn = NULL;}
+ if (pYAMNFcn) {
+ delete pYAMNFcn; pYAMNFcn = NULL;}
+ if (FileName) {
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0); FileName = NULL;}
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UnLoadPOP3:done\n");
+ #endif
+ return 1;
+}
+
+DWORD WINAPI WritePOP3Accounts()
+{
+ DWORD ReturnValue = CallService(MS_YAMN_WRITEACCOUNTS,(WPARAM)POP3Plugin,(LPARAM)FileName);
+ if (ReturnValue == EACC_SYSTEM) {
+ TCHAR temp[1024] = {0};
+ mir_sntprintf(temp, SIZEOF(temp), _T("%s\n%s"), TranslateT("Error while copying data to disk occured. File in use?"), FileName );
+ MessageBox(NULL, temp, TranslateT("POP3 plugin- write file error"), MB_OK );
+ }
+
+ return ReturnValue;
+}
+
+DWORD WINAPI WritePOP3Options(HANDLE File,HACCOUNT Which)
+{
+ DWORD WrittenBytes;
+ DWORD Ver=POP3_FILEVERSION;
+
+ if ((!WriteFile(File,(char *)&Ver,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&((HPOP3ACCOUNT)Which)->CP,sizeof(WORD),&WrittenBytes,NULL)))
+ return EACC_SYSTEM;
+ return 0;
+}
+
+DWORD WINAPI ReadPOP3Options(HACCOUNT Which,char **Parser,char *End)
+{
+ DWORD Ver;
+#ifdef DEBUG_FILEREAD
+ TCHAR Debug[256];
+#endif
+ Ver=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD);
+ if (*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+ if (Ver!=POP3_FILEVERSION)
+ return EACC_FILECOMPATIBILITY;
+
+ ((HPOP3ACCOUNT)Which)->CP=*(WORD *)(*Parser);
+ (*Parser)+=sizeof(WORD);
+ if (*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("CodePage: %d, remaining %d chars"),((HPOP3ACCOUNT)Which)->CP,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ return 0;
+}
+
+HYAMNMAIL WINAPI CreatePOP3Mail(HACCOUNT Account,DWORD MailDataVersion)
+{
+ HYAMNMAIL NewMail;
+//First, we should check whether MAILDATA matches.
+//But this is internal plugin, so YAMN's MAILDATA structure and our MAILDATA structure are
+//the same, so we do not need to test version. Otherwise, if MAILDATA version does not match
+//in your plugin, you should return NULL, like this:
+// if (MailDataVersion!=YAMN_MAILDATAVERSION) return NULL;
+
+//Now it is needed to construct our POP3 account and return its handle
+ if (NULL==(NewMail=new YAMNMAIL))
+ return NULL;
+
+ if (NULL==(NewMail->MailData=new MAILDATA))
+ {
+ delete NewMail;
+ return NULL;
+ }
+ NewMail->MailData->CP=((HPOP3ACCOUNT)Account)->CP;
+ return (HYAMNMAIL)NewMail;
+}
+
+static void SetContactStatus(HACCOUNT account, int status){
+ if ((account->hContact) && (account->NewMailN.Flags & YAMN_ACC_CONT)) {
+ DBWriteContactSettingWord(account->hContact, YAMN_DBMODULE, "Status", status);
+ }
+}
+
+static void PostErrorProc(HPOP3ACCOUNT ActualAccount,void *ParamToBadConnection,DWORD POP3PluginParam,BOOL UseSSL)
+{
+ char *DataRX;
+
+//We create new structure, that we pass to bad connection dialog procedure. This procedure next calls YAMN imported fuction
+//from POP3 protocol to determine the description of error. We can describe error from our error code structure, because later,
+//when YAMN calls our function, it passes us our error code. This is pointer to structure for POP3 protocol in fact.
+ PPOP3_ERRORCODE ErrorCode;
+
+//We store status before we do Quit(), because quit can destroy our errorcode status
+ if (NULL!=(ErrorCode=new POP3_ERRORCODE))
+ {
+ ErrorCode->SSL=UseSSL;
+ ErrorCode->AppError=ActualAccount->SystemError;
+ ErrorCode->POP3Error=ActualAccount->Client.POP3Error;
+ ErrorCode->NetError=ActualAccount->Client.NetClient->NetworkError;
+ ErrorCode->SystemError=ActualAccount->Client.NetClient->SystemError;
+ }
+
+ if (POP3PluginParam==(DWORD)NULL) //if it was normal YAMN call (force check or so on)
+ {
+ try
+ {
+ DataRX=ActualAccount->Client.Quit();
+ if (DataRX!=NULL)
+ free(DataRX);
+ }
+ catch(...)
+ {
+ }
+//We always close connection if error occured
+ try
+ {
+ ActualAccount->Client.NetClient->Disconnect();
+ }
+ catch(...)
+ {
+ }
+
+ SetAccountStatus(ActualAccount,TranslateT("Disconnected"));
+
+//If we cannot allocate memory, do nothing
+ if (ErrorCode==NULL)
+ {
+ SetEvent(ActualAccount->UseInternetFree);
+ return;
+ }
+ }
+ else //else it was called from POP3 plugin, probably error when deleting old mail (POP3 synchro calls POP3 delete)
+ if (ErrorCode==NULL)
+ return;
+
+ if ((ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP))
+ {
+ YAMN_BADCONNECTIONPARAM cp={(HANDLE)0,ActualAccount,(UINT_PTR)ErrorCode,ParamToBadConnection};
+
+ CallService(MS_YAMN_BADCONNECTION,(WPARAM)&cp,(LPARAM)YAMN_BADCONNECTIONVERSION);
+ }
+ if (POP3PluginParam==(DWORD)NULL) //if it was normal YAMN call
+ SetEvent(ActualAccount->UseInternetFree);
+}
+
+//Checks POP3 account and synchronizes it
+DWORD WINAPI SynchroPOP3(struct CheckParam * WhichTemp)
+{
+ HPOP3ACCOUNT ActualAccount;
+ CPop3Client *MyClient;
+ HYAMNMAIL NewMails=NULL,MsgQueuePtr=NULL;
+ char* DataRX=NULL,*Temp;
+ int mboxsize,msgs,i;
+ SYSTEMTIME now;
+ LPVOID YAMNParam;
+ DWORD CheckFlags;
+ BOOL UsingInternet=FALSE;
+ struct {
+ char *ServerName;
+ DWORD ServerPort;
+ char *ServerLogin;
+ char *ServerPasswd;
+ DWORD Flags;
+ DWORD NFlags;
+ DWORD NNFlags;
+ } ActualCopied;
+
+ //First, we should compare our version of CheckParam structure, but here it is not needed, because YAMN and internal plugin
+ //have the same version. But your plugin should do that in this way:
+ // if (((struct CheckParam *)WhichTemp)->Ver!=YAMN_CHECKVERSION)
+ // {
+ // SetEvent(((struct CheckParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN
+ // return (DWORD)-1; //ok, but we should return value.
+ // //When our plugin returns e.g. 0xFFFFFFFF (=-1, this is only our plugin value, YAMN does nothing with return value,
+ // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn. We know problem occured in YAMN incompatibility
+ // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
+ // }
+
+ ActualAccount=(HPOP3ACCOUNT)WhichTemp->AccountParam; //copy address of structure from calling thread to stack of this thread
+ YAMNParam=WhichTemp->BrowserParam;
+ CheckFlags=WhichTemp->Flags;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCInc(ActualAccount->UsingThreads);
+ //Unblock YAMN, signal that we have copied all parameters from YAMN thread stack
+ if (INVALID_HANDLE_VALUE!=WhichTemp->ThreadRunningEV)
+ SetEvent(WhichTemp->ThreadRunningEV);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read wait\n");
+ #endif
+ if (WAIT_OBJECT_0!=WaitToRead(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read wait failed\n");
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read enter\n");
+ #endif
+ MyClient=&ActualAccount->Client;
+ //Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes.
+ ActualCopied.ServerName = _strdup(ActualAccount->Server->Name);
+ ActualCopied.ServerPort=ActualAccount->Server->Port;
+ ActualCopied.Flags=ActualAccount->Flags;
+ ActualCopied.ServerLogin=_strdup(ActualAccount->Server->Login);
+ ActualCopied.ServerPasswd=_strdup(ActualAccount->Server->Passwd);
+ ActualCopied.NFlags=ActualAccount->NewMailN.Flags;
+ ActualCopied.NNFlags=ActualAccount->NoNewMailN.Flags;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read done\n");
+ #endif
+ ReadDone(ActualAccount);
+
+ SCInc(ActualAccount->InternetQueries); //increment counter, that there is one more thread waiting for connection
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-wait\n");
+ #endif
+ WaitForSingleObject(ActualAccount->UseInternetFree,INFINITE); //wait until we can use connection
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-enter\n");
+ #endif
+ SCDec(ActualAccount->InternetQueries);
+
+ //OK, we enter the "use internet" section. But after we start communication, we can test if we did not enter the "use internet" section only for the reason,
+ //that previous thread release the internet section because this account has stop signal (we stop account and there are 2 threads: one communicating,
+ //the second one waiting for network access- the first one ends because we want to stop account, this one is released, but should be stopped as well).
+ if (!ActualAccount->AbleToWork)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:stop signal-InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:stop signal-Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+ UsingInternet=TRUE;
+
+ GetLocalTime(&now);
+ ActualAccount->SystemError=0; //now we can use internet for this socket. First, clear errorcode.
+ try
+ {
+ SetContactStatus(ActualAccount,ID_STATUS_OCCUPIED);
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"<--------Communication-------->\n");
+ #endif
+ // if we are already connected, we have open session (another thread left us open session), so we don't need to login
+ // note that connected state without logging cannot occur, because if we close session, we always close socket too (we must close socket is the right word :))
+ if ((MyClient->NetClient==NULL) || !MyClient->NetClient->Connected())
+ {
+ SetAccountStatus(ActualAccount,TranslateT("Connecting to server"));
+
+ DataRX=MyClient->Connect(ActualCopied.ServerName,ActualCopied.ServerPort,ActualCopied.Flags & YAMN_ACC_SSL23,ActualCopied.Flags & YAMN_ACC_NOTLS);
+ char *timestamp=NULL;
+
+ if (DataRX!=NULL)
+ {
+ if (ActualCopied.Flags & YAMN_ACC_APOP)
+ {
+ char *lpos=strchr(DataRX,'<');
+ char *rpos=strchr(DataRX,'>');
+ if (lpos && rpos && rpos>lpos) {
+ int sz=(int)(rpos-lpos+2);
+ timestamp=new char[sz];
+ memcpy(timestamp, lpos, sz-1);
+ timestamp[sz-1]='\0';
+ }
+ }
+ free(DataRX);
+ DataRX=NULL;
+ }
+
+ SetAccountStatus(ActualAccount,TranslateT("Entering POP3 account"));
+
+ if (ActualCopied.Flags & YAMN_ACC_APOP)
+ {
+ DataRX=MyClient->APOP(ActualCopied.ServerLogin,ActualCopied.ServerPasswd,timestamp);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ delete[] timestamp;
+ } else {
+ DataRX=MyClient->User(ActualCopied.ServerLogin);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ DataRX=MyClient->Pass(ActualCopied.ServerPasswd);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ }
+ SetAccountStatus(ActualAccount,TranslateT("Searching for new mail message"));
+
+ DataRX=MyClient->Stat();
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<--------Account checking-------->\n");
+ DebugLog(DecodeFile,"<Extracting stat>\n");
+ #endif
+ ExtractStat(DataRX,MyClient->NetClient->Rcv,&mboxsize,&msgs);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<MailBoxSize>%d</MailBoxSize>\n",mboxsize);
+ DebugLog(DecodeFile,"<Msgs>%d</Msgs>\n",msgs);
+ DebugLog(DecodeFile,"</Extracting stat>\n");
+ #endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ for (i=0;i<msgs;i++)
+ {
+ if (!i)
+ MsgQueuePtr=NewMails=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ else
+ {
+ MsgQueuePtr->Next=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ if (MsgQueuePtr==NULL)
+ {
+ ActualAccount->SystemError=EPOP3_QUEUEALLOC;
+ throw (DWORD)ActualAccount->SystemError;
+ }
+ }
+
+ if (msgs)
+ {
+ DataRX=MyClient->List();
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting list>\n");
+ #endif
+ ExtractList(DataRX,MyClient->NetClient->Rcv,NewMails);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting list>\n");
+ #endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting UIDL>\n");
+ #endif
+ DataRX=MyClient->Uidl();
+ ExtractUIDL(DataRX,MyClient->NetClient->Rcv,NewMails);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting UIDL>\n");
+ #endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if (WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+ throw (DWORD)(ActualAccount->SystemError=EACC_STOPPED);
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ ActualAccount->LastChecked=now;
+ for (MsgQueuePtr=(HYAMNMAIL)ActualAccount->Mails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next){
+ if (MsgQueuePtr->Flags&YAMN_MSG_BODYREQUESTED){
+ HYAMNMAIL NewMsgsPtr=NULL;
+ for (NewMsgsPtr=(HYAMNMAIL)NewMails;NewMsgsPtr!=NULL;NewMsgsPtr=NewMsgsPtr->Next){
+ if (!strcmp(MsgQueuePtr->ID,NewMsgsPtr->ID)) {
+ TCHAR accstatus[512];
+ wsprintf(accstatus,TranslateT("Reading body %s"),NewMsgsPtr->ID);
+ SetAccountStatus(ActualAccount,accstatus);
+ DataRX=MyClient->Top(MsgQueuePtr->Number,100);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Reading body>\n");
+ DebugLog(DecodeFile,"<Header>%s</Header>\n",DataRX);
+ #endif
+ if (DataRX!=NULL)
+ {
+ Temp=DataRX;
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
+
+ if (OKLINE(DataRX))
+ for (Temp=DataRX;(Temp<DataRX+MyClient->NetClient->Rcv) && (!ENDLINE(Temp));Temp++);
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
+ }
+ else
+ continue;
+ //delete all the headers of the old mail MsgQueuePtr->MailData->TranslatedHeader
+ struct CMimeItem *TH = MsgQueuePtr->MailData->TranslatedHeader;
+ if (TH) for (;MsgQueuePtr->MailData->TranslatedHeader!=NULL;)
+ {
+ TH=TH->Next;
+ if (MsgQueuePtr->MailData->TranslatedHeader->name!=NULL)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->name;
+ if (MsgQueuePtr->MailData->TranslatedHeader->value!=NULL)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->value;
+ delete MsgQueuePtr->MailData->TranslatedHeader;
+ MsgQueuePtr->MailData->TranslatedHeader=TH;
+ }
+
+ TranslateHeader(Temp,MyClient->NetClient->Rcv-(Temp-DataRX),&MsgQueuePtr->MailData->TranslatedHeader);
+
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Reading body>\n");
+ #endif
+ MsgQueuePtr->Flags|=YAMN_MSG_BODYRECEIVED;
+
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&ActualAccount->Mails,NULL,(HYAMNMAIL *)&NewMails,NULL); //we get only new mails on server!
+// NewMails=NULL;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+ for (MsgQueuePtr=(HYAMNMAIL)ActualAccount->Mails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next){
+ if ((MsgQueuePtr->Flags&YAMN_MSG_BODYREQUESTED) && (MsgQueuePtr->Flags&YAMN_MSG_BODYRECEIVED)) {
+ MsgQueuePtr->Flags&=~YAMN_MSG_BODYREQUESTED;
+ if (MsgQueuePtr->MsgWindow){
+ SendMessage(MsgQueuePtr->MsgWindow,WM_YAMN_CHANGECONTENT,0,0);
+ }
+ }
+ }
+
+ for (msgs=0,MsgQueuePtr=NewMails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next,msgs++); //get number of new mails
+
+ try
+ {
+ TCHAR accstatus[512];
+
+ for (i=0,MsgQueuePtr=NewMails;MsgQueuePtr!=NULL;i++)
+ {
+ BOOL autoretr = (ActualAccount->Flags & YAMN_ACC_BODY)!=0;
+ DataRX=MyClient->Top(MsgQueuePtr->Number,autoretr?100:0);
+ wsprintf(accstatus,TranslateT("Reading new mail messages (%d%% done)"),100*i/msgs);
+ SetAccountStatus(ActualAccount,accstatus);
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<New mail>\n");
+ DebugLog(DecodeFile,"<Header>%s</Header>\n",DataRX);
+ #endif
+ if (DataRX!=NULL)
+ {
+ Temp=DataRX;
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
+
+ if (OKLINE(DataRX))
+ for (Temp=DataRX;(Temp<DataRX+MyClient->NetClient->Rcv) && (!ENDLINE(Temp));Temp++);
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
+ }
+ else
+ continue;
+
+ TranslateHeader(Temp,MyClient->NetClient->Rcv-(Temp-DataRX),&MsgQueuePtr->MailData->TranslatedHeader);
+
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</New mail>\n");
+ #endif
+ MsgQueuePtr->Flags|=YAMN_MSG_NORMALNEW;
+ if (autoretr) MsgQueuePtr->Flags|=YAMN_MSG_BODYRECEIVED;
+
+ //We are going to filter mail. Warning!- we must not be in read access neither write access to mails when calling this service
+ //This is done, because the "NewMails" queue is not synchronised. It is because it is new queue. Only this thread uses new queue yet, it is not
+ //connected to account mail queue.
+ // CallService(MS_YAMN_FILTERMAIL,(WPARAM)ActualAccount,(LPARAM)MsgQueuePtr);
+ FilterMailSvc((WPARAM)ActualAccount,(LPARAM)MsgQueuePtr);
+
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+
+ //MsgQueuePtr->MailData->Body=MyClient->Retr(MsgQueuePtr->Number);
+
+ MsgQueuePtr=MsgQueuePtr->Next;
+
+ }
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</--------Account checking-------->\n");
+ #endif
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if (WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+ throw (DWORD)ActualAccount->SystemError==EACC_STOPPED;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ if (ActualAccount->Mails==NULL)
+ ActualAccount->Mails=NewMails;
+ else
+ {
+ ActualAccount->LastMail=ActualAccount->LastChecked;
+ AppendQueue((HYAMNMAIL)ActualAccount->Mails,NewMails);
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+
+ // we are going to delete mails having SPAM flag level3 and 4 (see m_mails.h) set
+ {
+ struct DeleteParam ParamToDeleteMails={YAMN_DELETEVERSION,INVALID_HANDLE_VALUE,ActualAccount,YAMNParam,(void *)POP3_DELETEFROMCHECK};
+
+ // Delete mails from server. Here we should not be in write access for account's mails
+ DeleteMailsPOP3(&ParamToDeleteMails);
+ }
+
+ // if there is no waiting thread for internet connection close it
+ // else leave connection open
+ if (0==SCGetNumber(ActualAccount->InternetQueries))
+ {
+ DataRX=MyClient->Quit();
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ MyClient->NetClient->Disconnect();
+
+ SetAccountStatus(ActualAccount,TranslateT("Disconnected"));
+ }
+
+ UsingInternet=FALSE;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+
+ ActualAccount->LastSChecked=ActualAccount->LastChecked;
+ ActualAccount->LastSynchronised=ActualAccount->LastChecked;
+ }
+ catch(...)
+ {
+ throw; //go to the main exception handling
+ }
+
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualCopied.NFlags,ActualCopied.NNFlags,YAMNParam};
+
+ if (CheckFlags & YAMN_FORCECHECK)
+ Param.nnflags|=YAMN_ACC_POP; //if force check, show popup anyway and if mailbrowser was opened, do not close
+ Param.nnflags|= YAMN_ACC_MSGP; //do not close browser if already open
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+ SetContactStatus(ActualAccount,ActualAccount->isCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ }
+ #ifdef DEBUG_COMM
+ catch(DWORD ErrorCode)
+ #else
+ catch(DWORD)
+ #endif
+ {
+ if (ActualAccount->Client.POP3Error==EPOP3_STOPPED)
+ ActualAccount->SystemError=EACC_STOPPED;
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"ERROR: %x\n",ErrorCode);
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if (WAIT_OBJECT_0==MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ ActualAccount->LastChecked=now;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+
+ DeleteMIMEQueue(ActualAccount,NewMails);
+
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ switch(ActualAccount->SystemError)
+ {
+ case EACC_QUEUEALLOC:
+ case EACC_STOPPED:
+ ActualAccount->Client.NetClient->Disconnect();
+ break;
+ default:
+ PostErrorProc(ActualAccount,YAMNParam,(DWORD)NULL,MyClient->SSL); //it closes internet connection too
+ }
+
+ if (UsingInternet) //if our thread still uses internet
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ SetContactStatus(ActualAccount,ID_STATUS_NA);
+ }
+ free(ActualCopied.ServerName);
+ free(ActualCopied.ServerLogin);
+ free(ActualCopied.ServerPasswd);
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"</--------Communication-------->\n");
+ #endif
+// WriteAccounts();
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+}
+
+DWORD WINAPI DeleteMailsPOP3(struct DeleteParam *WhichTemp)
+{
+ HPOP3ACCOUNT ActualAccount;
+ LPVOID YAMNParam;
+ UINT_PTR POP3PluginParam;
+ CPop3Client *MyClient;
+ HYAMNMAIL DeleteMails,NewMails=NULL,MsgQueuePtr;
+ char* DataRX=NULL;
+ int mboxsize,msgs,i;
+ BOOL UsingInternet=FALSE;
+ struct {
+ char *ServerName;
+ DWORD ServerPort;
+ char *ServerLogin;
+ char *ServerPasswd;
+ DWORD Flags;
+ DWORD NFlags;
+ DWORD NNFlags;
+ } ActualCopied;
+
+ //First, we should compare our version of DeleteParam structure, but here it is not needed, because YAMN and internal plugin
+ //have the same version. But your plugin should do that in this way:
+ // if (((struct DeleteParam *)WhichTemp)->Ver!=YAMN_DELETEVERSION)
+ // {
+ // SetEvent(((struct DeleteParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN
+ // return (DWORD)-1; //ok, but we should return value.
+ // //When our plugin returns e.g. 0xFFFFFFFF (this is only our plugin value, YAMN does nothing with return value,
+ // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn), we know problem occured in YAMN incompatibility
+ // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
+ // }
+
+ ActualAccount=(HPOP3ACCOUNT)((struct DeleteParam *)WhichTemp)->AccountParam; //copy address of structure from calling thread to stack of this thread
+ YAMNParam=((struct DeleteParam *)WhichTemp)->BrowserParam;
+ POP3PluginParam=(UINT_PTR)((struct DeleteParam *)WhichTemp)->CustomParam;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCInc(ActualAccount->UsingThreads);
+ if (INVALID_HANDLE_VALUE!=WhichTemp->ThreadRunningEV)
+ SetEvent(WhichTemp->ThreadRunningEV);
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read wait\n");
+#endif
+ if (WAIT_OBJECT_0!=WaitToRead(ActualAccount))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read wait failed\n");
+#endif
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read enter\n");
+#endif
+ if (NULL==(DeleteMails=(HYAMNMAIL)CreateNewDeleteQueue((HYAMNMAIL)ActualAccount->Mails))) //if there's no mail for deleting, return
+ {
+ if (POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,YAMN_ACC_MSGP,YAMN_ACC_MSGP,YAMNParam}; //Just update the window
+
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+
+ return NO_MAIL_FOR_DELETE;
+ }
+ MyClient=&(ActualAccount->Client);
+
+//Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes.
+ ActualCopied.ServerName=_strdup(ActualAccount->Server->Name);
+ ActualCopied.ServerPort=ActualAccount->Server->Port;
+ ActualCopied.Flags=ActualAccount->Flags;
+ ActualCopied.ServerLogin=_strdup(ActualAccount->Server->Login);
+ ActualCopied.ServerPasswd=_strdup(ActualAccount->Server->Passwd);
+ ActualCopied.NFlags=ActualAccount->NewMailN.Flags;
+ ActualCopied.NNFlags=ActualAccount->NoNewMailN.Flags;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount);
+
+ SCInc(ActualAccount->InternetQueries); //This is POP3-internal SCOUNTER, we set another thread wait for this account to be connected to inet
+ if (POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-wait\n");
+#endif
+ WaitForSingleObject(ActualAccount->UseInternetFree,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-enter\n");
+#endif
+ }
+ SCDec(ActualAccount->InternetQueries);
+ UsingInternet=TRUE;
+
+ try
+ {
+ SetContactStatus(ActualAccount,ID_STATUS_OCCUPIED);
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<--------Communication-------->\n");
+#endif
+ if ((MyClient->NetClient==NULL) || !MyClient->NetClient->Connected())
+ {
+ SetAccountStatus(ActualAccount,TranslateT("Connecting to server"));
+
+ DataRX=MyClient->Connect(ActualCopied.ServerName,ActualCopied.ServerPort,ActualCopied.Flags & YAMN_ACC_SSL23,ActualCopied.Flags & YAMN_ACC_NOTLS);
+
+ char *timestamp=NULL;
+ if (DataRX!=NULL) {
+ if (ActualAccount->Flags & YAMN_ACC_APOP) {
+ char *lpos=strchr(DataRX,'<');
+ char *rpos=strchr(DataRX,'>');
+ if (lpos && rpos && rpos>lpos) {
+ int sz=(int)(rpos-lpos+2);
+ timestamp=new char[sz];
+ memcpy(timestamp, lpos, sz-1);
+ timestamp[sz-1]='\0';
+ }
+ }
+ free(DataRX);
+ DataRX=NULL;
+ }
+ SetAccountStatus(ActualAccount,TranslateT("Entering POP3 account"));
+
+ if (ActualAccount->Flags & YAMN_ACC_APOP)
+ {
+ DataRX=MyClient->APOP(ActualCopied.ServerLogin,ActualCopied.ServerPasswd,timestamp);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ delete[] timestamp;
+ } else {
+ DataRX=MyClient->User(ActualCopied.ServerLogin);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ DataRX=MyClient->Pass(ActualCopied.ServerPasswd);
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ }
+
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<--------Deleting requested mails-------->\n");
+#endif
+ if (POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not need to get mails on server as we have already it from check function
+ {
+ SetAccountStatus(ActualAccount,TranslateT("Deleting requested mails"));
+
+ DataRX=MyClient->Stat();
+
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting stat>\n");
+#endif
+ ExtractStat(DataRX,MyClient->NetClient->Rcv,&mboxsize,&msgs);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<MailBoxSize>%d</MailBoxSize>\n",mboxsize);
+ DebugLog(DecodeFile,"<Msgs>%d</Msgs>\n",msgs);
+ DebugLog(DecodeFile,"</Extracting stat>\n");
+#endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ for (i=0;i<msgs;i++)
+ {
+ if (!i)
+ MsgQueuePtr=NewMails=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ else
+ {
+ MsgQueuePtr->Next=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ if (MsgQueuePtr==NULL)
+ {
+ ActualAccount->SystemError=EPOP3_QUEUEALLOC;
+ throw (DWORD)ActualAccount->SystemError;
+ }
+ }
+
+ if (msgs)
+ {
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting UIDL>\n");
+#endif
+ DataRX=MyClient->Uidl();
+ ExtractUIDL(DataRX,MyClient->NetClient->Rcv,NewMails);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting UIDL>\n");
+#endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+// we get "new mails" on server (NewMails will contain all mails on server not found in DeleteMails)
+// but also in DeleteMails we get only those, which are still on server with their responsable numbers
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&DeleteMails,NULL,(HYAMNMAIL *)&NewMails,NULL);
+ }
+ }
+ else
+ SetAccountStatus(ActualAccount,TranslateT("Deleting spam"));
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write wait\n");
+#endif
+ if (WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write wait failed\n");
+#endif
+ throw (DWORD)EACC_STOPPED;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write enter\n");
+#endif
+ if (msgs || POP3_DELETEFROMCHECK==POP3PluginParam)
+ {
+ try
+ {
+ HYAMNMAIL Temp;
+
+ for (i=0,MsgQueuePtr=DeleteMails;MsgQueuePtr!=NULL;i++)
+ {
+ if (!(MsgQueuePtr->Flags & YAMN_MSG_VIRTUAL)) //of course we can only delete real mails, not virtual
+ {
+ DataRX=MyClient->Dele(MsgQueuePtr->Number);
+ Temp=MsgQueuePtr->Next;
+ if (POP3_FOK==MyClient->AckFlag) //if server answers that mail was deleted
+ {
+ DeleteMIMEMessage((HYAMNMAIL *)&DeleteMails,MsgQueuePtr);
+ HYAMNMAIL DeletedMail=FindMIMEMessageByID((HYAMNMAIL)ActualAccount->Mails,MsgQueuePtr->ID);
+ if ((MsgQueuePtr->Flags & YAMN_MSG_MEMDELETE)) //if mail should be deleted from memory (or disk)
+ {
+ DeleteMIMEMessage((HYAMNMAIL *)&ActualAccount->Mails,DeletedMail); //remove from queue
+ CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)POP3Plugin,(LPARAM)DeletedMail);
+ }
+ else //else mark it only as "deleted mail"
+ {
+ DeletedMail->Flags |= (YAMN_MSG_VIRTUAL | YAMN_MSG_DELETED);
+ DeletedMail->Flags &= ~(YAMN_MSG_NEW | YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE); //clear "new mail"
+ }
+ delete MsgQueuePtr->MailData;
+ delete[] MsgQueuePtr->ID;
+ delete MsgQueuePtr;
+ }
+ MsgQueuePtr=Temp;
+
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ else
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ }
+ catch(...) //if any exception in the code where we have write-access to account occured, don't forget to leave write-access
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write done\n");
+#endif
+ MsgsWriteDone(ActualAccount);
+ throw; //and go to the main exception handling
+ }
+
+ if (NewMails!=NULL)
+// in ActualAccount->Mails we have all mails stored before calling this function
+// in NewMails we have all mails not found in DeleteMails (in other words: we performed new ID checking and we
+// stored all mails found on server, then we deleted the ones we wanted to delete in this function
+// and NewMails queue now contains actual state of mails on server). But we will not use NewMails as actual state, because NewMails does not contain header data (subject, from...)
+// We perform deleting from ActualAccount->Mails: we remove from original queue (ActualAccount->Mails) all deleted mails
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&ActualAccount->Mails,NULL,(HYAMNMAIL *)&NewMails,NULL);
+// Now ActualAccount->Mails contains all mails when calling this function except the ones, we wanted to delete (these are in DeleteMails)
+// And in NewMails we have new mails (if any)
+ else if (POP3_DELETEFROMCHECK!=POP3PluginParam)
+ {
+ DeleteMIMEQueue(ActualAccount,(HYAMNMAIL)ActualAccount->Mails);
+ ActualAccount->Mails=NULL;
+ }
+ }
+ else
+ {
+ DeleteMIMEQueue(ActualAccount,(HYAMNMAIL)ActualAccount->Mails);
+ ActualAccount->Mails=NULL;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write done\n");
+#endif
+ MsgsWriteDone(ActualAccount);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</--------Deleting requested mails-------->\n");
+#endif
+
+// TODO: now, we have in NewMails new mails. If NewMails is not NULL, we found some new mails, so Checking for new mail should be performed
+// now, we do not call CheckPOP3
+
+// if there is no waiting thread for internet connection close it
+// else leave connection open
+// if this functin was called from SynchroPOP3, then do not try to disconnect
+ if (POP3_DELETEFROMCHECK!=POP3PluginParam)
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualCopied.NFlags,YAMN_ACC_MSGP,YAMNParam};
+
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+
+ if (0==SCGetNumber(ActualAccount->InternetQueries))
+ {
+ DataRX=MyClient->Quit();
+ if (DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ MyClient->NetClient->Disconnect();
+
+ SetAccountStatus(ActualAccount,TranslateT("Disconnected"));
+ }
+
+ UsingInternet=FALSE;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-done\n");
+#endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ SetContactStatus(ActualAccount,ActualAccount->isCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ }
+#ifdef DEBUG_COMM
+ catch(DWORD ErrorCode)
+#else
+ catch(DWORD)
+#endif
+ {
+ if (ActualAccount->Client.POP3Error==EPOP3_STOPPED)
+ ActualAccount->SystemError=EACC_STOPPED;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"ERROR %x\n",ErrorCode);
+#endif
+ if (DataRX!=NULL)
+ free(DataRX);
+ switch(ActualAccount->SystemError)
+ {
+ case EACC_QUEUEALLOC:
+ case EACC_STOPPED:
+ ActualAccount->Client.NetClient->Disconnect();
+ break;
+ default:
+ PostErrorProc(ActualAccount,YAMNParam,POP3PluginParam,MyClient->SSL); //it closes internet connection too
+ }
+
+ if (UsingInternet && (POP3_DELETEFROMCHECK!=POP3PluginParam)) //if our thread still uses internet and it is needed to release internet
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+#endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ }
+
+ free(ActualCopied.ServerName);
+ free(ActualCopied.ServerLogin);
+ free(ActualCopied.ServerPasswd);
+
+ DeleteMIMEQueue(ActualAccount,NewMails);
+ DeleteMIMEQueue(ActualAccount,DeleteMails);
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</--------Communication-------->\n");
+#endif
+// WriteAccounts();
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+}
+
+void ExtractStat(char *stream,int len,int *mboxsize,int *mails)
+{
+ char *finder=stream;
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ if (ACKLINE(finder))
+ {
+ while(!WS(finder)) finder++;
+ while(WS(finder)) finder++;
+ }
+ if (1!=sscanf(finder,"%d",mails))
+ throw (DWORD)EPOP3_STAT;
+ while(!WS(finder)) finder++;
+ while(WS(finder)) finder++;
+ if (1!=sscanf(finder,"%d",mboxsize))
+ throw (DWORD)EPOP3_STAT;
+}
+void ExtractMail(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr=queue;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if (DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n");
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if (1!=sscanf(finder,"%d",&msgnr))
+ throw (DWORD)EPOP3_UIDL;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+// for (i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+// if (i!=msgnr)
+// throw (DWORD)EPOP3_UIDL;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ while(!WS(finderend) && !ENDLINE(finderend)) finderend++;
+ queueptr->ID=new char[finderend-finder+1];
+ for (i=0;finder!=finderend;finder++,i++)
+ queueptr->MailData->Body[i]=*finder;
+ queueptr->MailData->Body[i]=0; //ends string
+ queueptr->Number=msgnr;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<ID>%s</ID>\n",queueptr->MailData->Body);
+ DebugLog(DecodeFile,"</Message>\n");
+ #endif
+ queueptr=queueptr->Next;
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+void ExtractUIDL(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr=queue;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if (DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n");
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if (1!=sscanf(finder,"%d",&msgnr))
+ throw (DWORD)EPOP3_UIDL;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+// for (i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+// if (i!=msgnr)
+// throw (DWORD)EPOP3_UIDL;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ while(!WS(finderend) && !ENDLINE(finderend)) finderend++;
+ queueptr->ID=new char[finderend-finder+1];
+ for (i=0;finder!=finderend;finder++,i++)
+ queueptr->ID[i]=*finder;
+ queueptr->ID[i]=0; //ends string
+ queueptr->Number=msgnr;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<ID>%s</ID>\n",queueptr->ID);
+ DebugLog(DecodeFile,"</Message>\n");
+ #endif
+ queueptr=queueptr->Next;
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+void ExtractList(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if (DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n",NULL,0);
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if (1!=sscanf(finder,"%d",&msgnr)) //message nr.
+ throw (DWORD)EPOP3_LIST;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+
+ for (i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+ if (i!=msgnr)
+ throw (DWORD)EPOP3_LIST;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ if (1!=sscanf(finder,"%d",&queueptr->MailData->Size))
+ throw (DWORD)EPOP3_LIST;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",queueptr->MailData->Size);
+ #endif
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+TCHAR* WINAPI GetErrorString(DWORD Code)
+{
+ static TCHAR *POP3Errors[]=
+ {
+ LPGENT("Memory allocation error."), //memory allocation
+ LPGENT("Account is about to be stopped."), //stop account
+ LPGENT("Cannot connect to POP3 server."),
+ LPGENT("Cannot allocate memory for received data."),
+ LPGENT("Cannot login to POP3 server."),
+ LPGENT("Bad user or password."),
+ LPGENT("Server does not support APOP authorization."),
+ LPGENT("Error while executing POP3 command."),
+ LPGENT("Error while executing POP3 command."),
+ LPGENT("Error while executing POP3 command."),
+ };
+
+ static TCHAR *NetlibErrors[]=
+ {
+ LPGENT("Cannot connect to server with NetLib."),
+ LPGENT("Cannot send data."),
+ LPGENT("Cannot receive data."),
+ LPGENT("Cannot allocate memory for received data."),
+ };
+
+ static TCHAR *SSLErrors[]=
+ {
+ LPGENT("OpenSSL not loaded."),
+ LPGENT("Windows socket 2.0 init failed."),
+ LPGENT("DNS lookup error."),
+ LPGENT("Error while creating base socket."),
+ LPGENT("Error connecting to server with socket."),
+ LPGENT("Error while creating SSL structure."),
+ LPGENT("Error connecting socket with SSL."),
+ LPGENT("Server rejected connection with SSL."),
+ LPGENT("Cannot write SSL data."),
+ LPGENT("Cannot read SSL data."),
+ LPGENT("Cannot allocate memory for received data."),
+ };
+
+ TCHAR *ErrorString = new TCHAR[ERRORSTR_MAXLEN];
+ POP3_ERRORCODE *ErrorCode=(POP3_ERRORCODE *)(UINT_PTR)Code;
+
+ mir_sntprintf(ErrorString, ERRORSTR_MAXLEN, TranslateT("Error %d-%d-%d-%d:"),ErrorCode->AppError,ErrorCode->POP3Error,ErrorCode->NetError,ErrorCode->SystemError);
+ if (ErrorCode->POP3Error)
+ mir_sntprintf(ErrorString, ERRORSTR_MAXLEN, _T("%s\n%s"),ErrorString,TranslateTS(POP3Errors[ErrorCode->POP3Error-1]));
+ if (ErrorCode->NetError) {
+ if (ErrorCode->SSL)
+ mir_sntprintf(ErrorString, ERRORSTR_MAXLEN, _T("%s\n%s"),ErrorString, TranslateTS(SSLErrors[ErrorCode->NetError-1]));
+ else
+ mir_sntprintf(ErrorString, ERRORSTR_MAXLEN, _T("%s\n%s"),ErrorString, TranslateTS(NetlibErrors[ErrorCode->NetError-4]));
+ }
+
+ return ErrorString;
+}
+
+void WINAPI DeleteErrorString(LPVOID String)
+{
+ delete (char *)String;
+}
diff --git a/protocols/YAMN/src/proto/pop3/pop3comm.h b/protocols/YAMN/src/proto/pop3/pop3comm.h new file mode 100644 index 0000000000..c7eb01b5a1 --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3comm.h @@ -0,0 +1,97 @@ +#ifndef __POP3COMM_H
+#define __POP3COMM_H
+
+#include <windows.h>
+#include "pop3.h"
+
+#include "m_protoplugin.h"
+//We can use synchro.h because this is internal plugin. If you use external plugin,
+//and you want to use SO for your plugin, you can use YAMN's SO.
+//All you need is to include synchro.h and use YAMN's exported synchronization functions.
+#include "m_synchro.h"
+
+//For mail exported functions defintions
+#include "m_mails.h"
+
+#include "../../debug.h"
+
+#define POP3_FILEVERSION 1 //Version of aditional information stored in book file
+
+typedef struct CPOP3Account: public CAccount
+{
+// We can use SCOUNTER structure, because this is internal plugin.
+// This SO is used to determine if any POP3 account is in "write access" mode
+ static PSCOUNTER AccountWriterSO;
+
+// It is usefull to have client structure in account. With this structure we have access to account's socket.
+// This is related to InternetQueries and UseInternetFree
+// This member should be synchronized with UseInternetFree
+ class CPop3Client Client;
+
+// This member is usefull for MIME headers. It is default codepage, if no other codepage found
+ WORD CP; //access only through AccountAccessSO
+
+// In this memeber last error code is stored
+ DWORD SystemError; //access through UseInternetFree
+
+// We use only counter from this object and it is # of threads waiting to work on internet.
+// We use event UseInternet to access critical sections.
+// It is usefull in 2 ways: we have mutual exclusion that only one thread works with account on internet.
+// Thread, which has done its work with account on internet can close socket, but it is not needed, when any other
+// thread wants to work (e.g. we have deleted mails, but when deleting, another thread wants to check new mail, so
+// we delete all needed mails and check if there's thread that wants to work. If yes, we do not need to quit session,
+// we leave socket open, and leave internet. Another thread then start checking and does not connect, does not send
+// user and password... because socket is open- it continues)
+ PSCOUNTER InternetQueries;
+ HANDLE UseInternetFree;
+
+ CPOP3Account();
+ ~CPOP3Account();
+
+} POP3ACCOUNT,*HPOP3ACCOUNT;
+
+typedef struct POP3LayeredError
+{
+ BOOL SSL;
+ DWORD AppError;
+ DWORD POP3Error;
+ DWORD NetError;
+ DWORD SystemError;
+} POP3_ERRORCODE,*PPOP3_ERRORCODE;
+
+struct YAMNExportedFcns
+{
+ YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN SetProtocolPluginFcnImportFcn;
+ YAMN_WAITTOWRITEFCN WaitToWriteFcn;
+ YAMN_WRITEDONEFCN WriteDoneFcn;
+ YAMN_WAITTOREADFCN WaitToReadFcn;
+ YAMN_READDONEFCN ReadDoneFcn;
+ YAMN_SCMANAGEFCN SCGetNumberFcn;
+ YAMN_SCMANAGEFCN SCIncFcn;
+ YAMN_SCMANAGEFCN SCDecFcn;
+ YAMN_SETSTATUSFCN SetStatusFcn;
+ YAMN_GETSTATUSFCN GetStatusFcn;
+};
+
+struct MailExportedFcns
+{
+ YAMN_SYNCHROMIMEMSGSFCN SynchroMessagesFcn;
+ YAMN_TRANSLATEHEADERFCN TranslateHeaderFcn;
+ YAMN_APPENDQUEUEFCN AppendQueueFcn;
+ YAMN_DELETEMIMEQUEUEFCN DeleteMessagesToEndFcn;
+ YAMN_DELETEMIMEMESSAGEFCN DeleteMessageFromQueueFcn;
+ YAMN_FINDMIMEMESSAGEFCN FindMessageByIDFcn;
+ YAMN_CREATENEWDELETEQUEUEFCN CreateNewDeleteQueueFcn;
+};
+
+enum
+{
+ EACC_QUEUEALLOC=1, //memory allocation
+ EACC_STOPPED, //stop account
+};
+
+#define NO_MAIL_FOR_DELETE 1
+
+#define POP3_DELETEFROMCHECK 1
+
+#endif
diff --git a/protocols/YAMN/src/proto/pop3/pop3opt.cpp b/protocols/YAMN/src/proto/pop3/pop3opt.cpp new file mode 100644 index 0000000000..1a265a0800 --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3opt.cpp @@ -0,0 +1,1556 @@ +/*
+ * This code implements POP3 options window handling
+ *
+ * (c) majvan 2002-2003
+*/
+
+#include "../../yamn.h"
+#include "../../main.h"
+#include "pop3comm.h"
+#include "pop3opt.h"
+
+//--------------------------------------------------------------------------------------------------
+
+static BOOL Check0,Check1,Check2,Check3,Check4,Check5,Check6,Check7,Check8,Check9;
+static char DlgInput[MAX_PATH];
+
+void CheckMenuItems();
+
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR CALLBACK DlgProcYAMNOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hDlg);
+ CheckDlgButton(hDlg,IDC_CHECKTTB,DBGetContactSettingByte(NULL,YAMN_DBMODULE,YAMN_TTBFCHECK,1) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_LONGDATE,(optDateTime&SHOWDATELONG) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_SMARTDATE,(optDateTime&SHOWDATENOTODAY) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_NOSECONDS,(optDateTime&SHOWDATENOSECONDS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_MAINMENU,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWMAINMENU, 1));
+ CheckDlgButton(hDlg,IDC_YAMNASPROTO,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWASPROTO, 1));
+ CheckDlgButton(hDlg,IDC_CLOSEONDELETE,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_CLOSEDELETE, 0));
+ break;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_YAMNASPROTO:
+ case IDC_MAINMENU:
+ case IDC_CHECKTTB:
+ case IDC_CLOSEONDELETE:
+ case IDC_LONGDATE:
+ case IDC_SMARTDATE:
+ case IDC_NOSECONDS:
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch(((LPNMHDR)lParam)->code) {
+ case PSN_APPLY:
+ DBWriteContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWASPROTO, IsDlgButtonChecked(hDlg,IDC_YAMNASPROTO));
+ DBWriteContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWMAINMENU, IsDlgButtonChecked(hDlg,IDC_MAINMENU));
+ DBWriteContactSettingByte(NULL, YAMN_DBMODULE, YAMN_CLOSEDELETE, IsDlgButtonChecked(hDlg,IDC_CLOSEONDELETE));
+ DBWriteContactSettingByte(NULL, YAMN_DBMODULE, YAMN_TTBFCHECK, IsDlgButtonChecked(hDlg,IDC_CHECKTTB));
+
+ AddTopToolbarIcon(0, 0);
+ CheckMenuItems();
+
+ optDateTime = 0;
+ if (IsDlgButtonChecked(hDlg,IDC_LONGDATE))optDateTime |= SHOWDATELONG;
+ if (IsDlgButtonChecked(hDlg,IDC_SMARTDATE))optDateTime |= SHOWDATENOTODAY;
+ if (IsDlgButtonChecked(hDlg,IDC_NOSECONDS))optDateTime |= SHOWDATENOSECONDS;
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_DBTIMEOPTIONS,optDateTime);
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcPluginOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hDlg);
+ break;
+
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_COMBOPLUGINS:
+ if (wNotifyCode==CBN_SELCHANGE)
+ {
+ HWND hCombo=GetDlgItem(hDlg,IDC_COMBOPLUGINS);
+ PYAMN_PROTOPLUGINQUEUE PParser;
+ PYAMN_FILTERPLUGINQUEUE FParser;
+ int index,id;
+
+ if (CB_ERR==(index=SendMessage(hCombo,CB_GETCURSEL,0,0)))
+ break;
+ id=SendMessage(hCombo,CB_GETITEMDATA,(WPARAM)index,(LPARAM)0);
+ EnterCriticalSection(&PluginRegCS);
+ for (PParser=FirstProtoPlugin;PParser!=NULL;PParser=PParser->Next)
+ if (id==(INT_PTR)PParser->Plugin)
+ {
+ SetDlgItemTextA(hDlg,IDC_STVER,PParser->Plugin->PluginInfo->Ver);
+ SetDlgItemTextA(hDlg,IDC_STDESC,PParser->Plugin->PluginInfo->Description == NULL ? "" : PParser->Plugin->PluginInfo->Description);
+ SetDlgItemTextA(hDlg,IDC_STCOPY,PParser->Plugin->PluginInfo->Copyright == NULL ? "" : PParser->Plugin->PluginInfo->Copyright);
+ SetDlgItemTextA(hDlg,IDC_STMAIL,PParser->Plugin->PluginInfo->Email == NULL ? "" : PParser->Plugin->PluginInfo->Email);
+ SetDlgItemTextA(hDlg,IDC_STWWW,PParser->Plugin->PluginInfo->WWW == NULL ? "" : PParser->Plugin->PluginInfo->WWW);
+ break;
+ }
+ for (FParser=FirstFilterPlugin;FParser!=NULL;FParser=FParser->Next)
+ if (id==(INT_PTR)FParser->Plugin)
+ {
+ SetDlgItemTextA(hDlg,IDC_STVER,FParser->Plugin->PluginInfo->Ver);
+ SetDlgItemTextA(hDlg,IDC_STDESC,FParser->Plugin->PluginInfo->Description == NULL ? "" : FParser->Plugin->PluginInfo->Description);
+ SetDlgItemTextA(hDlg,IDC_STCOPY,FParser->Plugin->PluginInfo->Copyright == NULL ? "" : FParser->Plugin->PluginInfo->Copyright);
+ SetDlgItemTextA(hDlg,IDC_STMAIL,FParser->Plugin->PluginInfo->Email == NULL ? "" : FParser->Plugin->PluginInfo->Email);
+ SetDlgItemTextA(hDlg,IDC_STWWW,FParser->Plugin->PluginInfo->WWW == NULL ? "" : FParser->Plugin->PluginInfo->WWW);
+ break;
+ }
+ LeaveCriticalSection(&PluginRegCS);
+ }
+ break;
+ case IDC_STWWW:
+ {
+ char str[1024];
+ GetDlgItemTextA(hDlg,IDC_STWWW,str,SIZEOF(str));
+ CallService(MS_UTILS_OPENURL,1,(LPARAM)str);
+ break;
+ }
+
+ }
+ break;
+ }
+ case WM_SHOWWINDOW:
+ if (TRUE==(BOOL)wParam) {
+ PYAMN_PROTOPLUGINQUEUE PParser;
+ PYAMN_FILTERPLUGINQUEUE FParser;
+ int index;
+
+ EnterCriticalSection(&PluginRegCS);
+ for (PParser = FirstProtoPlugin; PParser != NULL; PParser = PParser->Next) {
+ index = SendDlgItemMessageA(hDlg,IDC_COMBOPLUGINS,CB_ADDSTRING,0,(LPARAM)PParser->Plugin->PluginInfo->Name);
+ index = SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETITEMDATA,(WPARAM)index,(LPARAM)PParser->Plugin);
+ }
+ for (FParser = FirstFilterPlugin; FParser != NULL; FParser = FParser->Next) {
+ index = SendDlgItemMessageA(hDlg,IDC_COMBOPLUGINS,CB_ADDSTRING,0,(LPARAM)FParser->Plugin->PluginInfo->Name);
+ index = SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETITEMDATA,(WPARAM)index,(LPARAM)FParser->Plugin);
+ }
+
+ LeaveCriticalSection(&PluginRegCS);
+ SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETCURSEL,(WPARAM)0,(LPARAM)0);
+ SendMessage(hDlg,WM_COMMAND,MAKELONG(IDC_COMBOPLUGINS,CBN_SELCHANGE),(LPARAM)NULL);
+ break;
+ }
+ else { //delete all items in combobox
+ int cbn=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_GETCOUNT,(WPARAM)0,(LPARAM)0);
+ for (int i=0;i<cbn;i++)
+ SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_DELETESTRING,(WPARAM)0,(LPARAM)0);
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+
+int YAMNOptInitSvc(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp={0};
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = YAMNVar.hInst;
+ odp.pszGroup = LPGEN("Network");
+ odp.pszTitle = LPGEN("YAMN");
+ odp.flags = ODPF_BOLDGROUPS;
+
+ odp.pszTab = LPGEN("Accounts");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POP3ACCOUNTOPT);
+ odp.pfnDlgProc = DlgProcPOP3AccOpt;
+ Options_AddPage(wParam, &odp);
+
+ odp.pszTab = LPGEN("General");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_YAMNOPT);
+ odp.pfnDlgProc = DlgProcYAMNOpt;
+ Options_AddPage(wParam, &odp);
+
+ odp.pszTab = LPGEN("Plugins");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_PLUGINOPT);
+ odp.pfnDlgProc = DlgProcPluginOpt;
+ Options_AddPage(wParam, &odp);
+
+ if ( ServiceExists(MS_POPUP_ADDPOPUPEX)) {
+ odp.pszGroup = LPGEN("PopUps");
+ odp.pszTab = LPGEN("YAMN");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POP3ACCOUNTPOPUP);
+ odp.pfnDlgProc = DlgProcPOP3AccPopup;
+ Options_AddPage(wParam, &odp);
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+BOOL DlgEnableAccountStatus(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST0),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST1),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST2),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST3),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST4),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST5),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST6),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST7),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST8),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ return TRUE;
+}
+BOOL DlgEnableAccountPopup(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOPN),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOP1),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITFPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKAPOP),(BOOL)wParam);
+ return TRUE;
+}
+
+BOOL DlgEnableAccount(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECK),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITSERVER),wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNAME),wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPORT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITLOGIN),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPASS),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITINTERVAL),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSND),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKMSG),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKICO),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKAPP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKKBN),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPP),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPPPARAM),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNMSGP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFSND),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFMSG),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFICO),(BOOL)wParam);
+ /*EnableWindow(GetDlgItem(hDlg,IDC_CHECKST0),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST1),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST2),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST3),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST4),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST5),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST6),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST7),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST8),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);*/
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSTART),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFORCE),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_COMBOCP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_STTIMELEFT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNRESET),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEFAULT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNSTATUS),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSSL),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNOTLS),(IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_UNCHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_AUTOBODY),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNICK),(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNOEVENT),(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED) && wParam);
+ return TRUE;
+}
+BOOL DlgShowAccountStatus(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+
+ if ((DWORD)wParam==M_SHOWACTUAL)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ CheckDlgButton(hDlg,IDC_CHECKST0,ActualAccount->StatusFlags & YAMN_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,ActualAccount->StatusFlags & YAMN_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,ActualAccount->StatusFlags & YAMN_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,ActualAccount->StatusFlags & YAMN_ACC_ST3 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,ActualAccount->StatusFlags & YAMN_ACC_ST4 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,ActualAccount->StatusFlags & YAMN_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,ActualAccount->StatusFlags & YAMN_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,ActualAccount->StatusFlags & YAMN_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,ActualAccount->StatusFlags & YAMN_ACC_ST8 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,ActualAccount->StatusFlags & YAMN_ACC_ST9 ? BST_CHECKED : BST_UNCHECKED);
+ ReadDone(ActualAccount);
+ }
+ else
+ {
+ CheckDlgButton(hDlg,IDC_CHECKST0,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,BST_CHECKED);
+ }
+ return TRUE;
+}
+BOOL DlgShowAccountPopup(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+
+ if ((DWORD)wParam==M_SHOWACTUAL)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,ActualAccount->NewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,ActualAccount->NoNewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,ActualAccount->BadConnectN.PopUpTime,FALSE);
+
+
+ CheckDlgButton(hDlg,IDC_CHECKPOP,ActualAccount->NewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,ActualAccount->NewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,ActualAccount->BadConnectN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,ActualAccount->Flags & YAMN_ACC_POPN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,ActualAccount->Flags & YAMN_ACC_POPN ? BST_UNCHECKED : BST_CHECKED);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read done\n");
+ #endif
+ ReadDone(ActualAccount);
+ }
+ else //default
+ {
+
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,0,FALSE);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,BST_CHECKED);
+ }
+ return TRUE;
+}
+BOOL DlgShowAccount(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+ int i;
+
+ if ((DWORD)wParam==M_SHOWACTUAL)
+ {
+ TCHAR accstatus[256];
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ DlgSetItemText(hDlg, IDC_EDITSERVER, ActualAccount->Server->Name);
+ DlgSetItemText(hDlg, IDC_EDITNAME, ActualAccount->Name);
+ DlgSetItemText(hDlg, IDC_EDITLOGIN, ActualAccount->Server->Login);
+ DlgSetItemText(hDlg, IDC_EDITPASS, ActualAccount->Server->Passwd);
+ DlgSetItemTextW(hDlg, IDC_EDITAPP, ActualAccount->NewMailN.App);
+ DlgSetItemTextW(hDlg, IDC_EDITAPPPARAM, ActualAccount->NewMailN.AppParam);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,ActualAccount->Server->Port,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITINTERVAL,ActualAccount->Interval/60,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,ActualAccount->NewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,ActualAccount->NoNewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,ActualAccount->BadConnectN.PopUpTime,FALSE);
+ for (i=0;i<=CPLENSUPP;i++)
+ if ((i<CPLENSUPP) && (CodePageNamesSupp[i].CP==ActualAccount->CP))
+ {
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)i,(LPARAM)0);
+ break;
+ }
+ if (i==CPLENSUPP)
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+
+ CheckDlgButton(hDlg,IDC_CHECK,ActualAccount->Flags & YAMN_ACC_ENA ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSND,ActualAccount->NewMailN.Flags & YAMN_ACC_SND ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKMSG,ActualAccount->NewMailN.Flags & YAMN_ACC_MSG ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKICO,ActualAccount->NewMailN.Flags & YAMN_ACC_ICO ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,ActualAccount->NewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,ActualAccount->NewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPP,ActualAccount->NewMailN.Flags & YAMN_ACC_APP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKKBN,ActualAccount->NewMailN.Flags & YAMN_ACC_KBN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNMSGP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFSND,ActualAccount->BadConnectN.Flags & YAMN_ACC_SND ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFMSG,ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFICO,ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,ActualAccount->BadConnectN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,ActualAccount->Flags & YAMN_ACC_POPN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,ActualAccount->Flags & YAMN_ACC_POPN ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSSL,ActualAccount->Flags & YAMN_ACC_SSL23 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNOTLS,ActualAccount->Flags & YAMN_ACC_NOTLS ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPOP,ActualAccount->Flags & YAMN_ACC_APOP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_AUTOBODY,ActualAccount->Flags & YAMN_ACC_BODY ? BST_CHECKED : BST_UNCHECKED);
+ /*CheckDlgButton(hDlg,IDC_CHECKST0,ActualAccount->StatusFlags & YAMN_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,ActualAccount->StatusFlags & YAMN_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,ActualAccount->StatusFlags & YAMN_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,ActualAccount->StatusFlags & YAMN_ACC_ST3 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,ActualAccount->StatusFlags & YAMN_ACC_ST4 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,ActualAccount->StatusFlags & YAMN_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,ActualAccount->StatusFlags & YAMN_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,ActualAccount->StatusFlags & YAMN_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,ActualAccount->StatusFlags & YAMN_ACC_ST8 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,ActualAccount->StatusFlags & YAMN_ACC_ST9 ? BST_CHECKED : BST_UNCHECKED);*/
+ Check0=ActualAccount->StatusFlags & YAMN_ACC_ST0;
+ Check1=ActualAccount->StatusFlags & YAMN_ACC_ST1;
+ Check2=ActualAccount->StatusFlags & YAMN_ACC_ST2;
+ Check3=ActualAccount->StatusFlags & YAMN_ACC_ST3;
+ Check4=ActualAccount->StatusFlags & YAMN_ACC_ST4;
+ Check5=ActualAccount->StatusFlags & YAMN_ACC_ST5;
+ Check6=ActualAccount->StatusFlags & YAMN_ACC_ST6;
+ Check7=ActualAccount->StatusFlags & YAMN_ACC_ST7;
+ Check8=ActualAccount->StatusFlags & YAMN_ACC_ST8;
+ Check9=ActualAccount->StatusFlags & YAMN_ACC_ST9;
+ CheckDlgButton(hDlg,IDC_CHECKSTART,ActualAccount->StatusFlags & YAMN_ACC_STARTS ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFORCE,ActualAccount->StatusFlags & YAMN_ACC_FORCE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACT,ActualAccount->NewMailN.Flags & YAMN_ACC_CONT ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACTNICK,ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACTNOEVENT,ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT ? BST_CHECKED : BST_UNCHECKED);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read done\n");
+#endif
+ GetAccountStatus(ActualAccount,accstatus);
+ SetDlgItemText(hDlg,IDC_STSTATUS,accstatus);
+ ReadDone(ActualAccount);
+ }
+ else //default
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITSERVER,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITNAME,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITLOGIN,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITPASS,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITAPP,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITAPPPARAM,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,110,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITINTERVAL,30,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,0,FALSE);
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+ CheckDlgButton(hDlg,IDC_CHECK,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSND,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKMSG,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKICO,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPP,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFSND,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFMSG,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFICO,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,BST_CHECKED);
+ /*CheckDlgButton(hDlg,IDC_CHECKST0,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,BST_CHECKED);*/
+ CheckDlgButton(hDlg,IDC_CHECKSTART,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFORCE,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSSL,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNOTLS,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPOP,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_AUTOBODY,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACT,BST_CHECKED);
+
+ SetDlgItemText(hDlg,IDC_STSTATUS,TranslateT("No account selected"));
+ }
+ return TRUE;
+}
+
+BOOL DlgShowAccountColors(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read wait\n");
+#endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read enter\n");
+#endif
+ if (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NewMailN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NewMailN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+ if (ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPFB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->BadConnectN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPFT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->BadConnectN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPFB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPFT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+ if (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPNB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NoNewMailN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPNT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NoNewMailN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPNB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPNT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ return TRUE;
+}
+
+BOOL DlgSetItemText(HWND hDlg, WPARAM wParam,const char* str)
+{
+ if (str == NULL)
+ SetDlgItemTextA(hDlg, wParam, "");
+ else
+ SetDlgItemTextA(hDlg, wParam, str);
+ return TRUE;
+}
+
+BOOL DlgSetItemTextW(HWND hDlg,WPARAM wParam,const WCHAR* str)
+{
+ if (str == NULL)
+ SetDlgItemTextW(hDlg, wParam, L"");
+ else
+ SetDlgItemTextW(hDlg, wParam, str);
+ return TRUE;
+}
+
+INT_PTR CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ static HPOP3ACCOUNT ActualAccount;
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput);
+ if (ActualAccount != NULL)
+ {
+ DlgShowAccountStatus(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccountStatus(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ }
+ else
+ {
+ CheckDlgButton(hDlg,IDC_CHECKST0,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,BST_CHECKED);
+ }
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ break;
+ }
+ case WM_COMMAND:
+ {
+
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ Check0 = (IsDlgButtonChecked(hDlg,IDC_CHECKST0)==BST_CHECKED);
+ Check1 = (IsDlgButtonChecked(hDlg,IDC_CHECKST1)==BST_CHECKED);
+ Check2 = (IsDlgButtonChecked(hDlg,IDC_CHECKST2)==BST_CHECKED);
+ Check3 = (IsDlgButtonChecked(hDlg,IDC_CHECKST3)==BST_CHECKED);
+ Check4 = (IsDlgButtonChecked(hDlg,IDC_CHECKST4)==BST_CHECKED);
+ Check5 = (IsDlgButtonChecked(hDlg,IDC_CHECKST5)==BST_CHECKED);
+ Check6 = (IsDlgButtonChecked(hDlg,IDC_CHECKST6)==BST_CHECKED);
+ Check7 = (IsDlgButtonChecked(hDlg,IDC_CHECKST7)==BST_CHECKED);
+ Check8 = (IsDlgButtonChecked(hDlg,IDC_CHECKST8)==BST_CHECKED);
+ Check9 = (IsDlgButtonChecked(hDlg,IDC_CHECKST9)==BST_CHECKED);
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_CHANGESTATUSOPTION,(WPARAM)0,(LPARAM)0);
+ EndDialog(hDlg,0);
+ DestroyWindow(hDlg);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hDlg,0);
+ DestroyWindow(hDlg);
+ break;
+
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcPOP3AccOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ BOOL Changed=FALSE;
+ INT_PTR Result;
+ static BOOL InList=FALSE;
+ static HPOP3ACCOUNT ActualAccount;
+ static UCHAR ActualStatus;
+// static struct CPOP3Options POP3Options;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i;
+
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read wait\n");
+ #endif
+ WaitToReadSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read enter\n");
+ #endif
+
+ for (ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if (ActualAccount->Name != NULL)
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read done\n");
+ #endif
+ ReadDoneSO(POP3Plugin->AccountBrowserSO);
+ SendDlgItemMessage(hDlg, IDC_COMBOCP, CB_ADDSTRING, 0, (LPARAM)TranslateT("Default"));
+ for (i=1; i < CPLENSUPP; i++) {
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[i].CP,0,&info);
+ size_t len = lstrlen(info.CodePageName+7);
+ info.CodePageName[len+6]=0;
+ SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_ADDSTRING,0,(LPARAM)(info.CodePageName+7));
+ }
+
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+ ActualAccount=NULL;
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ }
+
+ case WM_SHOWWINDOW:
+ if ( wParam == FALSE) {
+ WindowList_Remove(pYAMNVar->MessageWnds,hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,(LPARAM)0);
+ }
+ else WindowList_Add(pYAMNVar->MessageWnds,hDlg,NULL);
+ return TRUE;
+
+ case WM_YAMN_CHANGESTATUS:
+ if ((HPOP3ACCOUNT)wParam == ActualAccount) {
+ TCHAR accstatus[256];
+ GetAccountStatus(ActualAccount,accstatus);
+ SetDlgItemText(hDlg,IDC_STSTATUS,accstatus);
+ return TRUE;
+ }
+ break;
+
+ case WM_YAMN_CHANGESTATUSOPTION:
+ Changed=TRUE;
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return TRUE;
+
+ case WM_YAMN_CHANGETIME:
+ if ((HPOP3ACCOUNT)wParam == ActualAccount) {
+ TCHAR Text[256];
+ mir_sntprintf(Text,SIZEOF(Text),TranslateT("Time left to next check [s]: %d"),(DWORD)lParam);
+ SetDlgItemText(hDlg,IDC_STTIMELEFT,Text);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+ case IDC_COMBOACCOUNT:
+ switch( HIWORD(wParam)) {
+ case CBN_EDITCHANGE :
+ ActualAccount=NULL;
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+
+ if (GetDlgItemTextA(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput)))
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ else
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ break;
+
+ case CBN_KILLFOCUS:
+ GetDlgItemTextA(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput));
+ if (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))) {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ if (lstrlenA(DlgInput))
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ else
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+ else {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+ }
+ break;
+
+ case CBN_SELCHANGE:
+ if (CB_ERR!=(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_GETLBTEXT,(WPARAM)Result,(LPARAM)DlgInput);
+
+ if ((Result==CB_ERR) || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput)))) {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ }
+ else {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+ }
+ break;
+ }
+ break;
+
+ case IDC_COMBOCP:
+ {
+ int sel = SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0);
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[sel].CP,0,&info);
+ DlgSetItemTextT(hDlg, IDC_STSTATUS, info.CodePageName);
+ }
+ case IDC_CHECK:
+ case IDC_CHECKSND:
+ case IDC_CHECKMSG:
+ case IDC_CHECKICO:
+ case IDC_CHECKFSND:
+ case IDC_CHECKFMSG:
+ case IDC_CHECKFICO:
+ case IDC_CHECKST0:
+ case IDC_CHECKST1:
+ case IDC_CHECKST2:
+ case IDC_CHECKST3:
+ case IDC_CHECKST4:
+ case IDC_CHECKST5:
+ case IDC_CHECKST6:
+ case IDC_CHECKST7:
+ case IDC_CHECKST8:
+ case IDC_CHECKST9:
+ case IDC_CHECKSTART:
+ case IDC_CHECKFORCE:
+ case IDC_EDITAPPPARAM:
+ case IDC_CHECKAPOP:
+ case IDC_AUTOBODY:
+ case IDC_CHECKCONTACTNICK:
+ case IDC_CHECKCONTACTNOEVENT:
+ case IDC_CHECKNOTLS:
+ Changed=TRUE;
+ break;
+
+ case IDC_CHECKCONTACT:
+ Changed=IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNICK),Changed);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNOEVENT),Changed);
+ Changed=TRUE;
+ break;
+
+ case IDC_CHECKSSL:
+ {
+ BOOL SSLC = (IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_CHECKED);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,SSLC ? 995 : 110,FALSE);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNOTLS),SSLC?0:1);
+ }
+ Changed=TRUE;
+ break;
+
+ case IDC_CPB:
+ case IDC_CPT:
+ case IDC_CPFB:
+ case IDC_CPFT:
+ case IDC_CPNB:
+ case IDC_CPNT:
+ if (HIWORD(wParam)!=CPN_COLOURCHANGED)
+ break;
+
+ case IDC_CHECKKBN:
+ Changed=TRUE;
+ break;
+
+ case IDC_CHECKAPP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPP),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPPPARAM),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ break;
+
+ case IDC_BTNSTATUS:
+ DialogBoxParamW(pYAMNVar->hInst,MAKEINTRESOURCEW(IDD_CHOOSESTATUSMODES),hDlg,DlgProcPOP3AccStatusOpt,NULL);
+ break;
+
+ case IDC_BTNADD:
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ DlgSetItemTextT(hDlg, IDC_EDITNAME, TranslateT("New Account"));
+ {
+ int index = SendDlgItemMessage(hDlg, IDC_COMBOACCOUNT, CB_ADDSTRING, 0, (LPARAM)TranslateT("New Account"));
+ if ( index != CB_ERR && index != CB_ERRSPACE )
+ SendDlgItemMessage(hDlg, IDC_COMBOACCOUNT, CB_SETCURSEL, index, (LPARAM)TranslateT("New Account"));
+ }
+ break;
+
+ case IDC_BTNAPP:
+ {
+ TCHAR filter[MAX_PATH];
+ mir_sntprintf(filter, SIZEOF(filter), _T("%s (*.exe;*.bat;*.cmd;*.com)%c*.exe;*.bat;*.cmd;*.com%c%s (*.*)%c*.*%c"),
+ TranslateT("Executables"), 0, 0, TranslateT("All Files"), 0, 0);
+
+ OPENFILENAME OFNStruct = { 0 };
+ OFNStruct.lStructSize = sizeof(OPENFILENAME);
+ OFNStruct.hwndOwner = hDlg;
+ OFNStruct.lpstrFilter= filter;
+ OFNStruct.nFilterIndex=1;
+ OFNStruct.nMaxFile=MAX_PATH;
+ OFNStruct.lpstrFile=new TCHAR[MAX_PATH];
+ OFNStruct.lpstrFile[0]=(TCHAR)0;
+ OFNStruct.lpstrTitle=TranslateT("Select executable used for notification");
+ OFNStruct.Flags=OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
+ if (!GetOpenFileName(&OFNStruct))
+ {
+ if (CommDlgExtendedError())
+ MessageBox(hDlg,_T("Dialog box error"),_T("Failed"),MB_OK);
+ }
+ else DlgSetItemTextT(hDlg, IDC_EDITAPP, OFNStruct.lpstrFile);
+ delete[] OFNStruct.lpstrFile;
+ }
+ break;
+
+ case IDC_BTNDEFAULT:
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ break;
+
+ case IDC_BTNDEL:
+ GetDlgItemTextA(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput));
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ if ((CB_ERR==(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))))
+ return TRUE;
+
+ if (IDOK!=MessageBox(hDlg,TranslateT("Do you really want to delete this account?"),TranslateT("Delete account confirmation"),MB_OKCANCEL | MB_ICONWARNING))
+ return TRUE;
+
+ DlgSetItemTextT(hDlg, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use."));
+
+ if (ActualAccount->hContact != NULL)
+ CallService(MS_DB_CONTACT_DELETE,(WPARAM)(HANDLE) ActualAccount->hContact, 0);
+
+ CallService(MS_YAMN_DELETEACCOUNT,(WPARAM)POP3Plugin,(LPARAM)ActualAccount);
+
+ //We can consider our account as deleted.
+
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_DELETESTRING,(WPARAM)Result,0);
+ DlgSetItemText(hDlg,(WPARAM)IDC_COMBOACCOUNT,(LPARAM)NULL);
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,0);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ break;
+
+ case IDC_BTNRESET:
+ if (ActualAccount != NULL)
+ ActualAccount->TimeLeft=ActualAccount->Interval;
+ return 1;
+ }
+
+ if (HIWORD(wParam) == EN_CHANGE)
+ Changed = TRUE;
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY ) {
+ char Text[MAX_PATH];
+ WCHAR TextW[MAX_PATH];
+ BOOL Translated,NewAcc=FALSE,Check,CheckMsg,CheckSnd,CheckIco,CheckApp, CheckAPOP;
+ BOOL CheckNMsgP,CheckFMsg,CheckFSnd,CheckFIco;
+ BOOL CheckKBN, CheckContact,CheckContactNick,CheckContactNoEvent;
+ BOOL CheckSSL, CheckABody, CheckNoTLS;
+ //BOOL Check0,Check1,Check2,Check3,Check4,Check5,Check6,Check7,Check8,Check9,
+ BOOL CheckStart,CheckForce;
+ size_t Length,index;
+ UINT Port,Interval;
+
+ if ( GetDlgItemTextA(hDlg,IDC_COMBOACCOUNT, Text, sizeof(Text))) {
+ Check = (IsDlgButtonChecked(hDlg,IDC_CHECK)==BST_CHECKED);
+ CheckSSL = (IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_CHECKED);
+ CheckNoTLS = (IsDlgButtonChecked(hDlg,IDC_CHECKNOTLS)==BST_CHECKED);
+ CheckAPOP = (IsDlgButtonChecked(hDlg,IDC_CHECKAPOP)==BST_CHECKED);
+
+ CheckABody = (IsDlgButtonChecked(hDlg,IDC_AUTOBODY)==BST_CHECKED);
+ CheckMsg = (IsDlgButtonChecked(hDlg,IDC_CHECKMSG)==BST_CHECKED);
+ CheckSnd = (IsDlgButtonChecked(hDlg,IDC_CHECKSND)==BST_CHECKED);
+ CheckIco = (IsDlgButtonChecked(hDlg,IDC_CHECKICO)==BST_CHECKED);
+
+ CheckApp = (IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ CheckKBN = (IsDlgButtonChecked(hDlg,IDC_CHECKKBN)==BST_CHECKED);
+ CheckContact = (IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED);
+ CheckContactNick = (IsDlgButtonChecked(hDlg,IDC_CHECKCONTACTNICK)==BST_CHECKED);
+ CheckContactNoEvent = (IsDlgButtonChecked(hDlg,IDC_CHECKCONTACTNOEVENT)==BST_CHECKED);
+
+ CheckFSnd = (IsDlgButtonChecked(hDlg,IDC_CHECKFSND)==BST_CHECKED);
+ CheckFMsg = (IsDlgButtonChecked(hDlg,IDC_CHECKFMSG)==BST_CHECKED);
+ CheckFIco = (IsDlgButtonChecked(hDlg,IDC_CHECKFICO)==BST_CHECKED);
+
+ CheckNMsgP = (IsDlgButtonChecked(hDlg,IDC_CHECKNMSGP)==BST_CHECKED);
+
+ Port = GetDlgItemInt(hDlg, IDC_EDITPORT, &Translated, FALSE);
+ if ( !Translated ) {
+ MessageBox(hDlg,TranslateT("This is not a valid number value"),TranslateT("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITPORT));
+ break;
+ }
+ Interval = GetDlgItemInt(hDlg,IDC_EDITINTERVAL,&Translated,FALSE);
+ if ( !Translated ) {
+ MessageBox(hDlg,TranslateT("This is not a valid number value"),TranslateT("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITINTERVAL));
+ break;
+ }
+
+ GetDlgItemTextA(hDlg, IDC_EDITAPP, Text, sizeof(Text));
+ if (CheckApp && !(Length = strlen(Text))) {
+ MessageBox(hDlg,TranslateT("Please select application to run"),TranslateT("Input error"),MB_OK);
+ break;
+ }
+
+ GetDlgItemTextA(hDlg, IDC_COMBOACCOUNT, Text, sizeof(Text));
+ if ( !( Length = strlen(Text))) {
+ GetDlgItemTextA(hDlg,IDC_EDITNAME, Text, sizeof(Text));
+ if ( !(Length = strlen( Text )))
+ break;
+ }
+
+ DlgSetItemTextT(hDlg, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use."));
+
+ if (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)Text))) {
+ NewAcc=TRUE;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write wait\n");
+ #endif
+ WaitToWriteSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write enter\n");
+ #endif
+ if (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)POP3Plugin,(LPARAM)YAMN_ACCOUNTVERSION))) {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+ MessageBox(hDlg,TranslateT("Cannot allocate memory space for new account"),TranslateT("Memory error"),MB_OK);
+ break;
+ }
+ }
+ else {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write wait\n");
+ #endif
+ //We have to get full access to AccountBrowser, so other iterating thrads cannot get new account until new account is right set
+ WaitToWriteSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write enter\n");
+ #endif
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write wait\n");
+ #endif
+ if (WAIT_OBJECT_0!=WaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write wait failed\n");
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write enter\n");
+ #endif
+
+ GetDlgItemTextA(hDlg, IDC_EDITNAME, Text, sizeof(Text));
+ if ( !(Length = strlen( Text )))
+ break;
+ if (NULL != ActualAccount->Name)
+ delete[] ActualAccount->Name;
+ ActualAccount->Name = new char[ strlen(Text)+1];
+ strcpy(ActualAccount->Name,Text);
+
+ GetDlgItemTextA(hDlg,IDC_EDITSERVER,Text,sizeof(Text));
+ if (NULL!=ActualAccount->Server->Name)
+ delete[] ActualAccount->Server->Name;
+ ActualAccount->Server->Name=new char[ strlen(Text)+1];
+ strcpy(ActualAccount->Server->Name,Text);
+
+ GetDlgItemTextA(hDlg,IDC_EDITLOGIN,Text,sizeof(Text));
+ if (NULL!=ActualAccount->Server->Login)
+ delete[] ActualAccount->Server->Login;
+ ActualAccount->Server->Login=new char[ strlen(Text)+1];
+ strcpy(ActualAccount->Server->Login,Text);
+
+ GetDlgItemTextA(hDlg,IDC_EDITPASS,Text,sizeof(Text));
+ if (NULL!=ActualAccount->Server->Passwd)
+ delete[] ActualAccount->Server->Passwd;
+ ActualAccount->Server->Passwd=new char[ strlen(Text)+1];
+ strcpy(ActualAccount->Server->Passwd,Text);
+
+ GetDlgItemTextW(hDlg,IDC_EDITAPP,TextW,SIZEOF(TextW));
+ if (NULL!=ActualAccount->NewMailN.App)
+ delete[] ActualAccount->NewMailN.App;
+ ActualAccount->NewMailN.App=new WCHAR[wcslen(TextW)+1];
+ wcscpy(ActualAccount->NewMailN.App,TextW);
+
+ GetDlgItemTextW(hDlg,IDC_EDITAPPPARAM,TextW,SIZEOF(TextW));
+ if (NULL!=ActualAccount->NewMailN.AppParam)
+ delete[] ActualAccount->NewMailN.AppParam;
+ ActualAccount->NewMailN.AppParam=new WCHAR[wcslen(TextW)+1];
+ wcscpy(ActualAccount->NewMailN.AppParam,TextW);
+
+ ActualAccount->Server->Port=Port;
+ ActualAccount->Interval=Interval*60;
+
+ if (CB_ERR==(index=SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0)))
+ index = CPDEFINDEX;
+ ActualAccount->CP = CodePageNamesSupp[index].CP;
+
+ if (NewAcc)
+ ActualAccount->TimeLeft=Interval*60;
+
+ CheckStart = (IsDlgButtonChecked(hDlg,IDC_CHECKSTART)==BST_CHECKED);
+ CheckForce = (IsDlgButtonChecked(hDlg,IDC_CHECKFORCE)==BST_CHECKED);
+
+ ActualAccount->Flags=
+ (Check ? YAMN_ACC_ENA : 0) |
+ (CheckSSL ? YAMN_ACC_SSL23 : 0) |
+ (CheckNoTLS ? YAMN_ACC_NOTLS : 0) |
+ (CheckAPOP ? YAMN_ACC_APOP : 0) |
+ (CheckABody ? YAMN_ACC_BODY : 0) |
+ (ActualAccount->Flags & YAMN_ACC_POPN);
+
+ ActualAccount->StatusFlags=
+ (Check0 ? YAMN_ACC_ST0 : 0) |
+ (Check1 ? YAMN_ACC_ST1 : 0) |
+ (Check2 ? YAMN_ACC_ST2 : 0) |
+ (Check3 ? YAMN_ACC_ST3 : 0) |
+ (Check4 ? YAMN_ACC_ST4 : 0) |
+ (Check5 ? YAMN_ACC_ST5 : 0) |
+ (Check6 ? YAMN_ACC_ST6 : 0) |
+ (Check7 ? YAMN_ACC_ST7 : 0) |
+ (Check8 ? YAMN_ACC_ST8 : 0) |
+ (Check9 ? YAMN_ACC_ST9 : 0) |
+ (CheckStart ? YAMN_ACC_STARTS : 0) |
+ (CheckForce ? YAMN_ACC_FORCE : 0);
+
+ ActualAccount->NewMailN.Flags=
+ (CheckSnd ? YAMN_ACC_SND : 0) |
+ (CheckMsg ? YAMN_ACC_MSG : 0) |
+ (CheckIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckApp ? YAMN_ACC_APP : 0) |
+ (CheckKBN ? YAMN_ACC_KBN : 0) |
+ (CheckContact ? YAMN_ACC_CONT : 0) |
+ (CheckContactNick ? YAMN_ACC_CONTNICK : 0) |
+ (CheckContactNoEvent ? YAMN_ACC_CONTNOEVENT : 0) |
+ YAMN_ACC_MSGP; //this is default: when new mail arrives and window was displayed, leave it displayed.
+
+ ActualAccount->NoNewMailN.Flags=
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckNMsgP ? YAMN_ACC_MSGP : 0);
+
+ ActualAccount->BadConnectN.Flags=
+ (CheckFSnd ? YAMN_ACC_SND : 0) |
+ (CheckFMsg ? YAMN_ACC_MSG : 0) |
+ (CheckFIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write done\n");
+ #endif
+ WriteDone(ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+
+ index = SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
+
+ HPOP3ACCOUNT temp = ActualAccount;
+
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_RESETCONTENT,0,(LPARAM)0);
+ if (POP3Plugin->FirstAccount!=NULL)
+ for (ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if (ActualAccount->Name!=NULL)
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+
+ ActualAccount = temp;
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_SETCURSEL,(WPARAM)index,(LPARAM)ActualAccount->Name);
+
+ WritePOP3Accounts();
+ RefreshContact();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ if (Changed)
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcPOP3AccPopup(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ BOOL Changed=FALSE;
+ static BOOL InList=FALSE;
+ static HPOP3ACCOUNT ActualAccount;
+ static UCHAR ActualStatus;
+// static struct CPOP3Options POP3Options;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ DlgShowAccountPopup(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ //DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read wait\n");
+ #endif
+ WaitToReadSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read enter\n");
+ #endif
+ if (POP3Plugin->FirstAccount!=NULL)
+ for (ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if (ActualAccount->Name!=NULL)
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read done\n");
+ #endif
+ ReadDoneSO(POP3Plugin->AccountBrowserSO);
+ ActualAccount=NULL;
+
+
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ }
+
+ case WM_SHOWWINDOW:
+ if ((BOOL)wParam==FALSE)
+ {
+ WindowList_Remove(pYAMNVar->MessageWnds,hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,(LPARAM)0);
+ }
+ else
+ {
+ WindowList_Add(pYAMNVar->MessageWnds,hDlg,NULL);
+
+ int index = SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
+ HPOP3ACCOUNT temp = ActualAccount;
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_RESETCONTENT,0,(LPARAM)0);
+
+ if (POP3Plugin->FirstAccount!=NULL)
+ for (ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if (ActualAccount->Name!=NULL)
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+
+ ActualAccount = temp;
+
+ if (ActualAccount != NULL)
+ {
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_SETCURSEL,(WPARAM)index,(LPARAM)ActualAccount->Name);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ }
+ else
+ {
+ DlgShowAccountPopup(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ LONG Result;
+ case IDC_COMBOACCOUNT:
+ switch(wNotifyCode)
+ {
+
+ case CBN_KILLFOCUS:
+ GetDlgItemTextA(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput));
+ if (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput)))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ if (lstrlenA(DlgInput))
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ else
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ }
+ break;
+ case CBN_SELCHANGE:
+ if (CB_ERR!=(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ SendDlgItemMessageA(hDlg,IDC_COMBOACCOUNT,CB_GETLBTEXT,(WPARAM)Result,(LPARAM)DlgInput);
+ if ((Result==CB_ERR) || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ }
+ break;
+ }
+ break;
+ case IDC_COMBOCP:
+ {
+ int sel = SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0);
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[sel].CP,0,&info);
+ DlgSetItemTextT(hDlg, IDC_STSTATUS, info.CodePageName);
+ }
+ case IDC_RADIOPOPN:
+ case IDC_RADIOPOP1:
+ Changed=TRUE;
+ break;
+ case IDC_CPB:
+ case IDC_CPT:
+ case IDC_CPFB:
+ case IDC_CPFT:
+ case IDC_CPNB:
+ case IDC_CPNT:
+ if (HIWORD(wParam)!=CPN_COLOURCHANGED)
+ break;
+ case IDC_CHECKCOL:
+ case IDC_CHECKFCOL:
+ case IDC_CHECKNCOL:
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ Changed=TRUE;
+ break;
+
+ case IDC_PREVIEW:
+ {
+ POPUPDATAT Tester;
+ POPUPDATAT TesterF;
+ POPUPDATAT TesterN;
+ BOOL TesterC = (IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED);
+ BOOL TesterFC = (IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED);
+ BOOL TesterNC = (IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED);
+
+ ZeroMemory(&Tester,sizeof(Tester));
+ ZeroMemory(&TesterF,sizeof(TesterF));
+ ZeroMemory(&TesterF,sizeof(TesterN));
+ Tester.lchContact=NULL;
+ TesterF.lchContact=NULL;
+ TesterN.lchContact=NULL;
+ Tester.lchIcon=g_LoadIconEx(2);
+ TesterF.lchIcon=g_LoadIconEx(3);
+ TesterN.lchIcon=g_LoadIconEx(1);
+
+ lstrcpyn(Tester.lptzContactName,TranslateT("Account Test"),MAX_CONTACTNAME);
+ lstrcpyn(TesterF.lptzContactName,TranslateT("Account Test (failed)"),MAX_CONTACTNAME);
+ lstrcpyn(TesterN.lptzContactName,TranslateT("Account Test"),MAX_CONTACTNAME);
+ lstrcpyn(Tester.lptzText,TranslateT("You have N new mail messages"),MAX_SECONDLINE);
+ lstrcpyn(TesterF.lptzText,TranslateT("Connection failed message"),MAX_SECONDLINE);
+ lstrcpyn(TesterN.lptzText,TranslateT("No new mail message"),MAX_SECONDLINE);
+ if (TesterC)
+ {
+ Tester.colorBack=SendDlgItemMessage(hDlg,IDC_CPB,CPM_GETCOLOUR,0,0);
+ Tester.colorText=SendDlgItemMessage(hDlg,IDC_CPT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ Tester.colorBack=GetSysColor(COLOR_BTNFACE);
+ Tester.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ if (TesterFC)
+ {
+ TesterF.colorBack=SendDlgItemMessage(hDlg,IDC_CPFB,CPM_GETCOLOUR,0,0);
+ TesterF.colorText=SendDlgItemMessage(hDlg,IDC_CPFT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ TesterF.colorBack=GetSysColor(COLOR_BTNFACE);
+ TesterF.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ if (TesterNC)
+ {
+ TesterN.colorBack=SendDlgItemMessage(hDlg,IDC_CPNB,CPM_GETCOLOUR,0,0);
+ TesterN.colorText=SendDlgItemMessage(hDlg,IDC_CPNT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ TesterN.colorBack=GetSysColor(COLOR_BTNFACE);
+ TesterN.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ Tester.PluginWindowProc=NULL;
+ TesterF.PluginWindowProc=NULL;
+ TesterN.PluginWindowProc=NULL;
+ Tester.PluginData=NULL;
+ TesterF.PluginData=NULL;
+ TesterN.PluginData=NULL;
+
+ if (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED)
+ PUAddPopUpT(&Tester);
+ if (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED)
+ PUAddPopUpT(&TesterF);
+ if (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED)
+ PUAddPopUpT(&TesterN);
+ Changed=TRUE;
+ }
+ break;
+ case IDC_CHECKKBN:
+ Changed=TRUE;
+ break;
+ case IDC_CHECKPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCOL),IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOPN),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOP1),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ break;
+ case IDC_CHECKFPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFCOL),IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITFPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED));
+ break;
+ case IDC_CHECKNPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNCOL),IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED));
+ break;
+
+ }
+ if (HIWORD(wParam)==EN_CHANGE)
+ Changed=TRUE;
+ break;
+ }
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCHAR Text[MAX_PATH];
+ BOOL Translated,NewAcc=FALSE,CheckPopup,CheckPopupW;
+ BOOL CheckNPopup,CheckNPopupW,CheckFPopup,CheckFPopupW;
+ BOOL CheckPopN;
+ UINT Time,TimeN,TimeF;
+
+ if (GetDlgItemText(hDlg,IDC_COMBOACCOUNT,Text,sizeof(Text)/sizeof(TCHAR)))
+ {
+ CheckPopup = (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ CheckPopupW = (IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED);
+
+ CheckFPopup = (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ CheckFPopupW = (IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED);
+
+ CheckNPopup = (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ CheckNPopupW = (IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED);
+
+ CheckPopN = (IsDlgButtonChecked(hDlg,IDC_RADIOPOPN)==BST_CHECKED);
+
+
+ Time=GetDlgItemInt(hDlg,IDC_EDITPOPS,&Translated,FALSE);
+ if (!Translated)
+ {
+ MessageBox(hDlg,TranslateT("This is not a valid number value"),TranslateT("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITPOPS));
+ break;
+ }
+ TimeN=GetDlgItemInt(hDlg,IDC_EDITNPOPS,&Translated,FALSE);
+ if (!Translated)
+ {
+ MessageBox(hDlg,TranslateT("This is not a valid number value"),TranslateT("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITNPOPS));
+ break;
+ }
+ TimeF=GetDlgItemInt(hDlg,IDC_EDITFPOPS,&Translated,FALSE);
+ if (!Translated)
+ {
+ MessageBox(hDlg,TranslateT("This is not a valid number value"),TranslateT("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITFPOPS));
+ break;
+ }
+
+
+ DlgSetItemTextT(hDlg, IDC_STTIMELEFT, TranslateT("Please wait while no account is in use."));
+
+ ActualAccount->Flags=
+ (ActualAccount->Flags & YAMN_ACC_ENA) |
+ (ActualAccount->Flags & YAMN_ACC_SSL23) |
+ (ActualAccount->Flags & YAMN_ACC_NOTLS) |
+ (ActualAccount->Flags & YAMN_ACC_APOP) |
+ (ActualAccount->Flags & YAMN_ACC_BODY) |
+ (CheckPopN ? YAMN_ACC_POPN : 0);
+
+ ActualAccount->NewMailN.Flags=
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_SND) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_ICO) |
+ (CheckPopup ? YAMN_ACC_POP : 0) |
+ (CheckPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_APP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONT) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT) |
+ YAMN_ACC_MSGP;
+
+ ActualAccount->NoNewMailN.Flags=
+ (CheckNPopup ? YAMN_ACC_POP : 0) |
+ (CheckNPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP);
+
+ ActualAccount->BadConnectN.Flags=
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_SND) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) |
+ (CheckFPopup ? YAMN_ACC_POP : 0) |
+ (CheckFPopupW ? YAMN_ACC_POPC : 0);
+
+ ActualAccount->NewMailN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPB,CPM_GETCOLOUR,0,0);
+ ActualAccount->NewMailN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPT,CPM_GETCOLOUR,0,0);
+ ActualAccount->NewMailN.PopUpTime=Time;
+
+ ActualAccount->NoNewMailN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPNB,CPM_GETCOLOUR,0,0);
+ ActualAccount->NoNewMailN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPNT,CPM_GETCOLOUR,0,0);
+ ActualAccount->NoNewMailN.PopUpTime=TimeN;
+
+ ActualAccount->BadConnectN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPFB,CPM_GETCOLOUR,0,0);
+ ActualAccount->BadConnectN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPFT,CPM_GETCOLOUR,0,0);
+ ActualAccount->BadConnectN.PopUpTime=TimeF;
+
+
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write done\n");
+ #endif
+ WriteDone(ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+// if (0==WritePOP3Accounts())
+// Beep(500,100);
+ WritePOP3Accounts();
+ RefreshContact();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ if (Changed)
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return FALSE;
+}
+
diff --git a/protocols/YAMN/src/proto/pop3/pop3opt.h b/protocols/YAMN/src/proto/pop3/pop3opt.h new file mode 100644 index 0000000000..6a678284fa --- /dev/null +++ b/protocols/YAMN/src/proto/pop3/pop3opt.h @@ -0,0 +1,40 @@ +#ifndef __OPTIONS_H
+#define __OPTIONS_H
+
+#define M_SHOWACTUAL 0
+#define M_SHOWDEFAULT 1
+
+
+//Enables account in options
+BOOL DlgEnableAccount(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets dialog controls to match current account
+BOOL DlgShowAccount(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets colors to match colors of actual account
+BOOL DlgShowAccountColors(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcPOP3AccOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcYAMNOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcPOP3AccPopup(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Initializes POP3 options for Miranda
+int POP3OptInit(WPARAM wParam,LPARAM lParam);
+
+//Sets dialog item text
+BOOL DlgSetItemText(HWND hDlg,WPARAM wParam,const char*);
+BOOL DlgSetItemTextW(HWND hDlg,WPARAM wParam,const WCHAR*);
+
+
+#define DlgSetItemTextT DlgSetItemTextW
+
+
+#endif
|