7 #include "send_email.h"
9 typedef struct sMapiFuns
{
11 LPMAPISENDMAIL sendmail
;
12 LPMAPIRESOLVENAME resolve
;
13 LPMAPIFREEBUFFER free_buf
;
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
,
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
;
41 char *attachment_path
= 0;
44 if(load_dll("mapistub.dll", &funs
) || load_dll("mapi32.dll", &funs
)) {
47 fprintf(stderr
, "Unable to load mapistub.dll or mapi32.dll: Bailing out. \n");
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
);
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
;
79 attachment_path
= strdup(path
);
80 /* convert / to \ (thunderbird doesn't like /) */
81 char *p
= attachment_path
;
82 while ((p
= strchr(p
, '/')))
86 filename
= strrchr(attachment_path
, '\\');
88 filename
= attachment_path
;
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
);
104 msg
.lpFiles
= &attachment
;
108 send_res
= funs
.sendmail(0, 0, &msg
, flags
, 0);
110 if (send_res
== SUCCESS_SUCCESS
)
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);
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
));
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
;
168 desc
->ulRecipClass
= recipClass
;
172 int load_dll(const char* name
, MapiFuns
* funs
) {
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);
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
);