では、早速プログラムを見てみましょう。
リソース・スクリプトに変更はありません
encode, convtobaseという2つの自作関数が増えました。 いずれも第237章で出てきたものの流用です。// mail06.cpp #ifndef STRICT #define STRICT #endif #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #define ID_EDIT 100 #define ID_STATUS 101 #include <windows.h> #include <winsock2.h> #include <windowsx.h> #include <commctrl.h> #include <stdio.h> #include <stdlib.h> #include <mbstring.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MySettingProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyPopSetProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyNewMailProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); void MySnd(HWND, char *, char *, char *); void MyRcv(HWND, HWND, HWND, HWND); int GetMailSize(char *); void MyJisToSJis(char *, char *); void MySJisToJis(char *, char *); void GetSubject(char *, char *); void GetFrom(char *, char *); void GetDate(char *, char *); void GetString(char *, char *); void decode(char *, char *); char charconv(char); void InsertColumn(HWND); void InsertItem(HWND, int, int, char *); void ShowContents(HWND, HWND, HWND, int); void MyPopConnect(HWND, HWND); void MyPopDisconnect(HWND); void encode(char *, char *); char convtobase(char); char szClassName[] = "mail06"; //ウィンドウクラス char szStr[1024], szStrRcv[1024 * 50], szResult[1024 * 50]; char szServerName[256], szFrom[256], szReplyTo[256];//SMTP char szPopServer[256], szUserName[64], szPass[64];//POP3 HINSTANCE hInst; SOCKET s; //ソケット(POP3用) BOOL bPOP = NULL; //POP3接続中かどうか
WinMain, InitApp, InitInstance, WndProcの各関数に変更はありません。
「Subject:」を送信する前に、MySJisToJisとencode関数でbase64エンコードを 行っています。ただこれだけです。void MySnd(HWND hStatus, char *lpszTo, char *lpszSubject, char *lpszMail) { WSADATA wsaData; LPHOSTENT lpHost; LPSERVENT lpServ; SOCKET s; int iProtocolPort; SOCKADDR_IN sockadd; char *seps = "\r", *token; if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { MessageBox(NULL, "エラーです", "Error", MB_OK); return; } if (strcmp(szServerName, "") == 0) { MessageBox(NULL, "サーバーアドレスを入力してください。", "サーバー", MB_OK); DialogBox(hInst, "MYDLG", hStatus, (DLGPROC)MyDlgProc); strcpy(szServerName, szStr); } lpHost = gethostbyname(szServerName); if (lpHost == NULL) { wsprintf(szStr, "%sが見つかりません", szServerName); MessageBox(NULL, szStr, "Error", MB_OK); return; } s = socket(PF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { MessageBox(NULL, "ソケットをオープンできません", "Error", MB_OK); return; } lpServ = getservbyname("mail", NULL); if (lpServ == NULL) { MessageBox(NULL, "ポート指定がされていないので、デフォルトを使います", "OK", MB_OK); iProtocolPort = htons(IPPORT_SMTP); } else { iProtocolPort = lpServ->s_port; } sockadd.sin_family = AF_INET; sockadd.sin_port = iProtocolPort; sockadd.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list); if (connect(s, (PSOCKADDR)&sockadd, sizeof(sockadd))) { MessageBox(NULL, "サーバーソケットに接続失敗", "Error", MB_OK); return; } memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); strcpy(szStr, "HELO "); strcat(szStr, szServerName); strcat(szStr, "\r\n"); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); if (strcmp(szFrom, "") == 0) { MessageBox(NULL, "差出人メールアドレスを入力してください", "差出人", MB_OK); DialogBox(hInst, "MYDLG", hStatus, (DLGPROC)MyDlgProc); strcpy(szFrom, szStr); } wsprintf(szStr, "MAIL FROM : <%s>\r\n", szFrom); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); wsprintf(szStr, "RCPT TO :<%s>\r\n", lpszTo); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); strcpy(szStr, "DATA\r\n"); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); strcpy(szStr, "X-Mailer: Nekodemo_Wakaru-Mailer\r\n"); send(s, szStr, strlen(szStr), 0); if (strcmp(szReplyTo, "") != 0) { wsprintf(szStr, "Reply-To: %s\r\n", szReplyTo); send(s, szStr, strlen(szStr), 0); } MySJisToJis(lpszSubject, szStr); encode(szStr, lpszSubject); wsprintf(szStr, "Subject: %s \r\n", lpszSubject); send(s, szStr, strlen(szStr), 0); //ここでもう一度「\r\n」を送信しておかないと //本文に日本語を使う場合1行目が文字化けします strcpy(szStr, "\r\n"); send(s, szStr, strlen(szStr), 0); token = strtok(lpszMail, seps); while (token != NULL) { if (token[0] == '\n') { strcpy(szStr, token + 1); } else { strcpy(szStr, token); } strcat(szStr, "\r\n"); send(s, szStr, strlen(szStr), 0); token = strtok(NULL, seps); } strcpy(szStr, ".\r\n"); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); strcpy(szStr, "QUIT\r\n"); send(s, szStr, strlen(szStr), 0); memset(szStrRcv, '\0', sizeof(szStrRcv)); recv(s, szStrRcv, sizeof(szStrRcv), 0); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)szStrRcv); closesocket(s); WSACleanup(); SendMessage(hStatus, SB_SETTEXT, 0 | 0, (LPARAM)"通信を終了しました"); return; }
MyDlgProc, MySettingProc, MyPopSetProc, MyRcv, GetMailSize, MyNewMailProc, MySJisToJis, GetSubject, GetFrom, GetDate, GetString, decode, charconv, InsertColumn, InsertItem, ShowContents, MyPopConnect, MyPopDisconnect の各関数に変更はありません
lpszOrgをbase64にエンコードしてlpszDestに出力する関数です。 すでに第237章で同じものを作っています。void encode(char *lpszOrg, char *lpszDest) { int i = 0, iR = 16; strcpy(lpszDest, "=?ISO-2022-JP?B?"); while (1) { if (lpszOrg[i] == '\0') { break; } lpszDest[iR] = convtobase((lpszOrg[i]) >> 2); if (lpszOrg[i + 1] == '\0') { lpszDest[iR + 1] = convtobase(((lpszOrg[i] & 0x3) << 4) ); lpszDest[iR + 2] = '='; lpszDest[iR + 3] = '='; lpszDest[iR + 4] = '\0'; break; } lpszDest[iR + 1] = convtobase(((lpszOrg[i] & 0x3) << 4) + ((lpszOrg[i + 1]) >> 4)); if (lpszOrg[i + 2] == '\0') { lpszDest[iR + 2] = convtobase((lpszOrg[i + 1] & 0xf) << 2); lpszDest[iR + 3] = '='; lpszDest[iR + 4] = '\0'; break; } lpszDest[iR + 2] = convtobase(((lpszOrg[i + 1] & 0xf) << 2) + ((lpszOrg[i + 2]) >> 6)); lpszDest[iR + 3] = convtobase(lpszOrg[i + 2] & 0x3f); lpszDest[iR + 4] = '\0'; i += 3; iR += 4; } strcat(lpszDest, "?="); return; }
これも説明は第237章を見てください。 今回は簡単でした。char convtobase(char c) { if (c <= 0x19) return c + 'A'; if (c >= 0x1a && c <= 0x33) return c - 0x1a + 'a'; if (c >= 0x34 && c <= 0x3d) return c - 0x34 + '0'; if (c == 0x3e) return '+'; if (c == 0x3f) return '/'; return '='; }
Update 09/Nov/1999 By Y.Kumei