Follow upstream changes -- Bytestring updates
[git-darcs-import.git] / src / win32 / send_email.c
blob22830a456a86f9603c9e229cdd5615598da1ee71
3 #include <windows.h>
4 #include <mapi.h>
5 #include <stdio.h>
7 #include "send_email.h"
9 typedef struct sMapiFuns {
10 LPMAPILOGON logon;
11 LPMAPISENDMAIL sendmail;
12 LPMAPIRESOLVENAME resolve;
13 LPMAPIFREEBUFFER free_buf;
14 LPMAPILOGOFF logoff;
15 HMODULE dll;
16 } MapiFuns;
19 int load_dll(const char* name, MapiFuns* funs);
20 void free_dll(MapiFuns* funs);
22 void get_recipient(MapiFuns* funs, const char *name, ULONG recipClass, MapiRecipDesc *desc, lpMapiRecipDesc *desc_lookup);
24 int send_email(const char *sendname,
25 const char *recvname,
26 const char *ccname,
27 const char *subj,
28 const char *body,
29 const char *path)
31 FLAGS flags;
32 MapiMessage msg;
33 ULONG send_res;
34 MapiRecipDesc orig;
35 MapiRecipDesc recips[2];
36 MapiRecipDesc *orig_lookup, *recip_lookup, *cc_lookup;
37 int num_recip = 1, return_code = -1;
38 MapiFileDesc attachment;
39 MapiFileTagExt file_type;
40 const char *filename;
41 char *attachment_path = 0;
42 MapiFuns funs;
44 if(load_dll("mapistub.dll", &funs) || load_dll("mapi32.dll", &funs)) {
45 return_code=0;
46 } else {
47 fprintf(stderr, "Unable to load mapistub.dll or mapi32.dll: Bailing out. \n");
48 return_code=-1;
51 if(return_code==0) {
52 LHANDLE session;
53 /* logon seems to be necessary for outlook express, sometimes,
54 and doesn't seem to hurt, otherwise.
56 funs.logon(0, 0, 0, MAPI_LOGON_UI, 0, &session);
59 orig_lookup = recip_lookup = cc_lookup = NULL;
61 get_recipient(&funs, sendname, MAPI_ORIG, &orig, &orig_lookup);
62 get_recipient(&funs, recvname, MAPI_TO, &recips[0], &recip_lookup);
64 if (ccname && strlen(ccname) > 0) {
65 get_recipient(&funs, ccname, MAPI_CC, &recips[1], &cc_lookup);
66 num_recip++;
69 memset(&msg, 0, sizeof(msg));
70 msg.lpOriginator = &orig;
71 msg.lpRecips = recips;
72 msg.lpszMessageType = "text/plain";
73 msg.lpszNoteText = (LPSTR) body;
74 msg.lpszSubject = (LPSTR)subj;
75 msg.nRecipCount = num_recip;
76 msg.flFlags = 0;
78 if (path) {
79 attachment_path = strdup(path);
80 /* convert / to \ (thunderbird doesn't like /) */
81 char *p = attachment_path;
82 while ((p = strchr(p, '/')))
83 *p = '\\';
85 /* find filename */
86 filename = strrchr(attachment_path, '\\');
87 if (filename == 0)
88 filename = attachment_path;
89 else
90 filename++;
92 memset(&attachment, 0, sizeof(attachment));
93 attachment.nPosition = -1;
94 attachment.lpszPathName = (LPTSTR)attachment_path;
95 attachment.lpszFileName = (LPTSTR)filename;
97 attachment.lpFileType = &file_type;
99 memset(&file_type, 0, sizeof(file_type));
100 file_type.lpTag = "text/plain";
101 file_type.cbTag = sizeof(file_type.lpTag);
103 msg.nFileCount = 1;
104 msg.lpFiles = &attachment;
107 flags = 0;
108 send_res = funs.sendmail(0, 0, &msg, flags, 0);
110 if (send_res == SUCCESS_SUCCESS)
111 return_code = 0;
112 else {
113 return_code=-1;
114 if(send_res==MAPI_E_USER_ABORT) fprintf(stderr, "MAPI error: User aborted.\n");
115 else if(send_res== MAPI_E_FAILURE) fprintf(stderr, "MAPI error: Generic error.\n");
116 else if(send_res== MAPI_E_LOGIN_FAILURE) fprintf(stderr, "MAPI error: Login failure.\n");
117 else if(send_res== MAPI_E_DISK_FULL) fprintf(stderr, "MAPI error: Disk full.\n");
118 else if(send_res== MAPI_E_INSUFFICIENT_MEMORY) fprintf(stderr, "MAPI error: Insufficient memory.\n");
119 else if(send_res== MAPI_E_ACCESS_DENIED) fprintf(stderr, "MAPI error: Access denied.\n");
120 else if(send_res== MAPI_E_TOO_MANY_SESSIONS) fprintf(stderr, "MAPI error: Too many sessions\n");
121 else if(send_res== MAPI_E_TOO_MANY_FILES) fprintf(stderr, "MAPI error: Too many files.\n");
122 else if(send_res== MAPI_E_TOO_MANY_RECIPIENTS) fprintf(stderr, "MAPI error: Too many recipients.\n");
123 else if(send_res== MAPI_E_ATTACHMENT_NOT_FOUND) fprintf(stderr, "MAPI error: Attachment not found.\n");
124 else if(send_res== MAPI_E_ATTACHMENT_OPEN_FAILURE) fprintf(stderr, "MAPI error: Failed to open attachment.\n");
125 else if(send_res== MAPI_E_ATTACHMENT_WRITE_FAILURE) fprintf(stderr, "MAPI error: Failed to write attachment.\n");
126 else if(send_res== MAPI_E_UNKNOWN_RECIPIENT) fprintf(stderr, "MAPI error: Unknown recipient\n");
127 else if(send_res== MAPI_E_BAD_RECIPTYPE) fprintf(stderr, "MAPI error: Bad type of recipent.\n");
128 else if(send_res== MAPI_E_NO_MESSAGES) fprintf(stderr, "MAPI error: No messages.\n");
129 else if(send_res== MAPI_E_INVALID_MESSAGE) fprintf(stderr, "MAPI error: Invalid message.\n");
130 else if(send_res== MAPI_E_TEXT_TOO_LARGE) fprintf(stderr, "MAPI error: Text too large.\n");
131 else if(send_res== MAPI_E_INVALID_SESSION) fprintf(stderr, "MAPI error: Invalid session.\n");
132 else if(send_res== MAPI_E_TYPE_NOT_SUPPORTED) fprintf(stderr, "MAPI error: Type not supported.\n");
133 else if(send_res== MAPI_E_AMBIGUOUS_RECIP) fprintf(stderr, "MAPI error: Ambigious recipient.\n");
134 else if(send_res== MAPI_E_MESSAGE_IN_USE) fprintf(stderr, "MAPI error: Messag in use.\n");
135 else if(send_res== MAPI_E_NETWORK_FAILURE) fprintf(stderr, "MAPI error: Network failure.\n");
136 else if(send_res== MAPI_E_INVALID_EDITFIELDS) fprintf(stderr, "MAPI error: Invalid editfields\n");
137 else if(send_res== MAPI_E_INVALID_RECIPS) fprintf(stderr, "MAPI error: Invalid recipient(s)\n");
138 else if(send_res== MAPI_E_NOT_SUPPORTED) fprintf(stderr, "MAPI error: Operation not supported.\n");
139 else fprintf(stderr, "MAPISendMail returned %ld\n", send_res);
143 if (orig_lookup) funs.free_buf(orig_lookup);
144 if (recip_lookup) funs.free_buf(recip_lookup);
145 if (cc_lookup) funs.free_buf(cc_lookup);
146 if (attachment_path) free(attachment_path);
148 funs.logoff(session, 0, 0, 0);
150 free_dll(&funs);
151 return return_code;
154 void get_recipient(MapiFuns* funs, const char *name, ULONG recipClass, MapiRecipDesc *desc, lpMapiRecipDesc *desc_lookup) {
155 ULONG ret = funs->resolve(0, 0, (LPSTR) name, 0, 0, desc_lookup);
156 if (ret == SUCCESS_SUCCESS) {
157 memcpy(desc, *desc_lookup, sizeof(MapiRecipDesc));
158 } else {
159 /* Default to something sensible if MAPIResolveName is not supported
160 * by the mail client (thunderbird)
162 memset(desc, 0, sizeof(MapiRecipDesc));
163 desc->lpszName = (LPSTR)name;
164 desc->lpszAddress = (LPSTR)name;
165 desc->lpEntryID = 0;
166 desc->ulEIDSize = 0;
168 desc->ulRecipClass = recipClass;
172 int load_dll(const char* name, MapiFuns* funs) {
173 funs->dll = 0;
174 funs->dll = LoadLibrary(name);
175 if(funs->dll!=NULL) {
176 /* We try first loading by easy name, then by ordinal, and then by other names seen */
177 funs->logon = (LPMAPILOGON) GetProcAddress(funs->dll, "MAPILogon");
178 if(funs->logon==NULL)
179 funs->logon = (LPMAPILOGON) GetProcAddress(funs->dll, (LPCSTR)209);
181 funs->logoff = (LPMAPILOGOFF) GetProcAddress(funs->dll, "MAPILogOff");
182 if(funs->logoff==NULL)
183 funs->logoff = (LPMAPILOGOFF) GetProcAddress(funs->dll, (LPCSTR)210);
185 funs->resolve = (LPMAPIRESOLVENAME) GetProcAddress(funs->dll, "MAPIResolveName");
186 if(funs->resolve==NULL)
187 funs->resolve = (LPMAPIRESOLVENAME) GetProcAddress(funs->dll, (LPCSTR)219);
189 funs->free_buf = (LPMAPIFREEBUFFER) GetProcAddress(funs->dll, "MAPIFreeBuffer");
190 if(funs->free_buf==NULL)
191 funs->free_buf = (LPMAPIFREEBUFFER) GetProcAddress(funs->dll, (LPCSTR)16);
192 if(funs->free_buf==NULL)
193 funs->free_buf = (LPMAPIFREEBUFFER) GetProcAddress(funs->dll, "MAPIFreeBuffer@4");
195 funs->sendmail = (LPMAPISENDMAIL) GetProcAddress(funs->dll, "MAPISendMail");
196 if(funs->sendmail==NULL)
197 funs->sendmail = (LPMAPISENDMAIL) GetProcAddress(funs->dll, (LPCSTR)211);
199 return
200 funs->dll!=NULL
201 && funs->logon!=NULL
202 && funs->logoff!=NULL
203 && funs->resolve!=NULL
204 && funs->free_buf!=NULL
205 && funs->sendmail!=NULL;
207 void free_dll(MapiFuns* funs) {
208 if(funs->dll!=NULL) FreeLibrary(funs->dll);
209 funs->dll=NULL;