2 * ========================================================================
3 * Copyright 2006 University of Washington
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
16 ULONG FAR PASCAL
MAPISendMail(
19 lpMapiMessage lpMessage
,
24 int ac
= 0, rv
= 0, can_suppress_dialog
= 0, has_recips
= 0;
25 char **av
, *tmpfree
, *url
;
28 fprintf(ms_global
->dfd
, "\r\nIn MAPISendMail\r\n");
29 fprintf(ms_global
->dfd
, " MAPI_DIALOG is %s set\r\n",
30 flFlags
& MAPI_DIALOG
? "" : "NOT");
31 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %s set\r\n",
32 flFlags
& MAPI_LOGON_UI
? "" : "NOT");
33 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %s set\r\n",
34 flFlags
& MAPI_NEW_SESSION
? "" : "NOT");
35 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
38 msprint_message_structure(lpMessage
);
40 url
= message_structure_to_mailto_url(lpMessage
);
42 for(i
= 0; i
< lpMessage
->nRecipCount
; i
++){
43 if((&lpMessage
->lpRecips
[i
])->ulRecipClass
!= MAPI_ORIG
)
46 if((flFlags
& MAPI_DIALOG
) && has_recips
&&
47 (lpMessage
->lpszSubject
48 || lpMessage
->lpszNoteText
49 || lpMessage
->nFileCount
)){
50 if(ms_global
->pmapi_suppress_dialogs
== PMSD_YES
)
51 can_suppress_dialog
= 1;
52 else if(ms_global
->pmapi_suppress_dialogs
== PMSD_PROMPT
){
53 if(MessageBox(NULL
, "Edit Message Before Sending?", "pmapi32.dll", MB_YESNO
|MB_ICONQUESTION
) == IDNO
)
54 can_suppress_dialog
= 1;
57 if(can_suppress_dialog
||
58 ((flFlags
& MAPI_DIALOG
) == 0)){
59 rv
= send_msg_nodlg(lhSession
, ulUIParam
, lpMessage
, flFlags
, ulReserved
);
63 if (lpMessage
== NULL
){
64 /* lpMessage->lpFiles == NULL ||
65 lpMessage->lpFiles->lpszPathName == NULL) */
66 /* this old code checked to see that there were attachments */
67 /* I think it should be all right for there not to be attachments */
69 ErrorBox("MAPISendMail: %s pointer in lpMessage argument", "NULL");
74 * allocate space for spawn's argv array:
75 * 2 for each of the nFileCount attachments
76 * +4 for the -p pinerc, and av[0] and trailing NULL
80 int avSize
= (6+2*lpMessage
->nFileCount
)*sizeof(*av
);
81 av
= (char **)fs_get(avSize
);
83 ErrorBox("MAPISendMail: fs_get of %d bytes for av failed", (avSize
));
84 return MAPI_E_FAILURE
;
89 * establish a default path to the pine executable which will
90 * probably be replaced with a value from the registry
92 if(ms_global
&& ms_global
->pineExe
){
93 av
[ac
++] = quote(ms_global
->pineExe
);
95 ErrorBox("Cannot fs_get for %s","pine");
96 return MAPI_E_FAILURE
;
99 else return MAPI_E_FAILURE
;
100 if(ms_global
->pinerc
){
101 av
[ac
++] = mstrdup("-p");
102 if(tmpfree
= TmpCopy(ms_global
->pinerc
, IS_PINERC
)){
103 av
[ac
++] = quote(tmpfree
);
104 fs_give((void **)&tmpfree
);
107 av
[ac
++] = quote(ms_global
->pinerc
);
110 av
[ac
++] = mstrdup("-url");
115 * make a temporary copy of each attachment in attachDir,
116 * add the new filename (suitably quoted) to pine's argument list
118 for (i
=0; i
< lpMessage
->nFileCount
; ++i
) {
119 char *oldPath
= lpMessage
->lpFiles
[i
].lpszPathName
;
120 char *newCopy
, *tmpfree
;
121 tmpfree
= TmpCopy(oldPath
, NOT_PINERC
);
123 return MAPI_E_ATTACHMENT_NOT_FOUND
;
124 newCopy
= quote(tmpfree
);
125 fs_give((void **)&tmpfree
);
127 av
[ac
++] = mstrdup("-attach_and_delete");
132 fprintf(ms_global
->dfd
, "TmpCopy returned null\r\n");
135 fprintf(ms_global
->dfd
,"Attachment %d: old path: %s\r\n--\r\n",
137 fprintf(ms_global
->dfd
,">>: %s\r\n--\r\n",ms_global
->attachDir
);
138 fprintf(ms_global
->dfd
,">>: tmp path: %s\r\n--\r\n",
139 (newCopy
?newCopy
:"NULL"));
145 fprintf(ms_global
->dfd
, "spawning %s (else %s):\r\n",
146 ms_global
->pineExe
, ms_global
->pineExeAlt
);
147 for (i
=0; av
[i
]; ++i
)
148 fprintf(ms_global
->dfd
, "av[%d] = %s\r\n", i
, av
[i
]);
152 if (_spawnvp(_P_NOWAIT
, ms_global
->pineExe
, av
) == -1 &&
153 _spawnvp(_P_NOWAIT
, ms_global
->pineExeAlt
, av
) == -1)
155 ErrorBox("MAPISendMail: _spawnvp of %s failed", ms_global
->pineExe
);
156 if(MSDEBUG
) fprintf(ms_global
->dfd
, "_spawnvp %s and %s failed\r\n",
157 ms_global
->pineExe
,ms_global
->pineExeAlt
);
158 return(MAPI_E_FAILURE
);
162 * close and free allocated resources
164 if (av
[0]) fs_give((void **)&av
[0]);
165 for (i
=1; av
[i
]; i
++) {
166 if (av
[i
]) fs_give((void **)&av
[i
]);
168 fs_give((void **)&av
);
170 return SUCCESS_SUCCESS
;
174 ULONG FAR PASCAL
MAPILogon(
176 LPTSTR lpszProfileName
,
180 LPLHANDLE lplhSession
)
182 mapi_global_s
*nmg
= ms_global
;
187 fprintf(ms_global
->dfd
, "\r\nIn MAPILogon\r\n");
188 fprintf(ms_global
->dfd
, " MAPI_FORCE_DOWNLOAD is %s set\r\n",
189 flFlags
& MAPI_FORCE_DOWNLOAD
? "" : "NOT");
190 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %s set\r\n",
191 flFlags
& MAPI_NEW_SESSION
? "" : "NOT");
192 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %s set\r\n",
193 flFlags
& MAPI_LOGON_UI
? "" : "NOT");
194 fprintf(ms_global
->dfd
, " MAPI_PASSWORD_UI is %s set\r\n",
195 flFlags
& MAPI_PASSWORD_UI
? "" : "NOT");
196 fprintf(ms_global
->dfd
, " ulUIParam is %p\r\n", ulUIParam
);
198 fprintf(ms_global
->dfd
, " profile name is %s\r\n", lpszProfileName
);
199 fprintf(ms_global
->dfd
, " lplhSession is %p\r\n", lplhSession
);
201 fprintf(ms_global
->dfd
, " session number is %p\r\n", *lplhSession
);
202 fclose(ms_global
->dfd
);
203 ms_global
->dfd
= fopen(ms_global
->debugFile
, "ab");
205 ms_global
->debug
= 0;
206 ErrorBox("Problem with debug file %s! Debugging turned off",
207 ms_global
->debugFile
);
208 fs_give((void **)&ms_global
->debugFile
);
209 ms_global
->debugFile
= NULL
;
213 if(lplhSession
== NULL
){
216 "lplhSession is a NULL pointer, returning MAPI_E_FAILURE\r\n");
218 return MAPI_E_FAILURE
;
220 if((flFlags
& MAPI_NEW_SESSION
) || !nmg
->sessionlist
){
221 cs
= new_sessionlist();
222 *lplhSession
= cs
->session_number
;
224 if(nmg
->sessionlist
== NULL
)
225 nmg
->sessionlist
= cs
;
227 ts
= nmg
->sessionlist
;
228 while(ts
->next
) ts
= ts
->next
;
233 if(!*lplhSession
) *lplhSession
= nmg
->sessionlist
->session_number
;
235 cs
= get_session(*lplhSession
);
237 return MAPI_E_INVALID_SESSION
;
239 cs
->flags
.mapi_logon_ui
= ((flFlags
& MAPI_LOGON_UI
) || (flFlags
& MAPI_PASSWORD_UI
))
241 if((flFlags
& MAPI_LOGON_UI
) || (flFlags
& MAPI_PASSWORD_UI
))
242 if(InitPineSpecific(cs
) == -1) return MAPI_E_FAILURE
;
246 "lplhSession is returning %p for session handle\r\n", *lplhSession
);
249 return SUCCESS_SUCCESS
;
252 ULONG FAR PASCAL
MAPILogoff (
261 fprintf(ms_global
->dfd
, "\r\nIn MAPILogoff\r\n");
262 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
266 cs
= get_session(lhSession
);
267 if(!cs
) return MAPI_E_INVALID_SESSION
;
268 if(!cs
->open_stream
) return SUCCESS_SUCCESS
;
269 cs
->open_stream
= mail_close_full(cs
->open_stream
, 0);
270 cs
->open_stream
= NULL
;
271 if(cs
->currently_open
){
272 fs_give((void **)&cs
->currently_open
);
273 cs
->currently_open
= NULL
;
275 cs
->dlge
.edit1
[0] = '\0';
276 cs
->dlge
.edit2
[0] = '\0';
277 /* ms_global->flags.passfile_checked = FALSE; */
278 return SUCCESS_SUCCESS
;
281 ULONG FAR PASCAL
MAPIFindNext (
284 LPSTR lpszMessageType
,
285 LPSTR lpszSeedMessageID
,
290 mapi_global_s
*nmg
= ms_global
;
292 char tmp
[1024], tmpseq
[1024];
294 unsigned long tmp_msgno
, i
, cur_msg
= 0;
298 fprintf(nmg
->dfd
, "\r\nMAPIFindNext Called\r\n");
299 fprintf(ms_global
->dfd
, " MAPI_GUARANTEE_FIFO is %s set\r\n",
300 flFlags
& MAPI_GUARANTEE_FIFO
? "" : "NOT");
301 fprintf(ms_global
->dfd
, " MAPI_LONG_MSGID is %s set\r\n",
302 flFlags
& MAPI_LONG_MSGID
? "" : "NOT");
303 fprintf(ms_global
->dfd
, " MAPI_MAPI_UNREAD_ONLY is %s set\r\n",
304 flFlags
& MAPI_UNREAD_ONLY
? "" : "NOT");
305 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
306 fprintf(ms_global
->dfd
, " ulUIParam is %d\r\n", ulUIParam
);
307 fprintf(ms_global
->dfd
, "message type is %s\r\n",
308 lpszMessageType
? lpszMessageType
: "NOT SET");
309 fprintf(ms_global
->dfd
, "seed message id is %s\r\n",
310 lpszSeedMessageID
? lpszSeedMessageID
: "NOT SET");
314 cs
= get_session(lhSession
);
317 fprintf(ms_global
->dfd
, "Session number %p is invalid\r\n", lhSession
);
318 return MAPI_E_INVALID_SESSION
;
321 if(InitPineSpecific(cs
) == -1) return MAPI_E_FAILURE
;
323 if(!check_mailstream(cs
))
324 return MAPI_E_FAILURE
;
325 if(lpszSeedMessageID
== NULL
|| *lpszSeedMessageID
== '\0')
328 cur_msg
= convert_to_msgno(lpszSeedMessageID
);
330 if(flFlags
& MAPI_UNREAD_ONLY
){
331 if(cur_msg
+ 1 > cs
->open_stream
->nmsgs
)
332 return MAPI_E_NO_MESSAGES
;
333 tmp_msgno
= cur_msg
+1;
335 while(!msg_found
&& tmp_msgno
<= cs
->open_stream
->nmsgs
){
336 sprintf(tmp
, "%d", tmp_msgno
);
338 if(tmp_msgno
+1 <= cs
->open_stream
->nmsgs
){
339 sprintf(tmp
,":%d", min(cs
->open_stream
->nmsgs
,tmp_msgno
+100));
342 mail_fetch_flags(cs
->open_stream
, tmpseq
, NIL
);
344 i
<= (unsigned long)min(cs
->open_stream
->nmsgs
,tmp_msgno
+100);
346 telt
= mail_elt(cs
->open_stream
, i
);
350 fprintf(nmg
->dfd
, "msgno %d is the next UNREAD message after %d",
356 if(i
== cs
->open_stream
->nmsgs
){
358 fprintf(nmg
->dfd
,"No UNREAD messages found after %d\r\n",
360 return MAPI_E_NO_MESSAGES
;
367 else return MAPI_E_NO_MESSAGES
;
370 if(cur_msg
+1 > cs
->open_stream
->nmsgs
)
371 return MAPI_E_NO_MESSAGES
;
375 sprintf(lpszMessageID
,"%d", cur_msg
);
378 fprintf(nmg
->dfd
, " Next message found is %d\r\n", cur_msg
);
379 return SUCCESS_SUCCESS
;
383 ULONG FAR PASCAL
MAPIReadMail(
389 lpMapiMessage FAR
*lppMessage
)
391 mapi_global_s
*nmg
= ms_global
;
393 unsigned long msgno
= 0, flags
;
397 fprintf(nmg
->dfd
, "\r\nIn MAPIReadMail\r\n");
398 fprintf(nmg
->dfd
, " MAPI_PEEK is %s\r\n",
399 flFlags
& MAPI_PEEK
? "TRUE":"FALSE");
400 fprintf(nmg
->dfd
, " MAPI_BODY_AS_FILE is %s\r\n",
401 flFlags
& MAPI_BODY_AS_FILE
? "TRUE":"FALSE");
402 fprintf(nmg
->dfd
, " MAPI_ENVELOPE_ONLY is %s\r\n",
403 flFlags
& MAPI_ENVELOPE_ONLY
? "TRUE":"FALSE");
404 fprintf(nmg
->dfd
, " MAPI_SUPPRESS_ATTACH is %s\r\n",
405 flFlags
& MAPI_SUPPRESS_ATTACH
? "TRUE":"FALSE");
406 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
410 cs
= get_session(lhSession
);
413 fprintf(ms_global
->dfd
, "Session number %p is invalid\r\n", lhSession
);
414 return MAPI_E_INVALID_SESSION
;
417 if(InitPineSpecific(cs
) == -1) return MAPI_E_FAILURE
;
419 if(!check_mailstream(cs
))
420 return MAPI_E_FAILURE
;
422 msgno
= convert_to_msgno(lpszMessageID
);
426 fprintf(nmg
->dfd
, "Invalid Message ID: %s\r\n", lpszMessageID
);
427 return MAPI_E_INVALID_MESSAGE
;
431 fprintf(nmg
->dfd
, "lpszMessageID: %s, converted msgno: %d\r\n",
432 lpszMessageID
, msgno
);
435 if(flFlags
& MAPI_PEEK
)
439 rv
= fetch_structure_and_attachments(msgno
, flags
, flFlags
, cs
);
440 if(rv
== MAPI_E_FAILURE
)
442 else if(rv
== SUCCESS_SUCCESS
){
443 *lppMessage
= cs
->lpm
;
450 ULONG FAR PASCAL
MAPIAddress(
457 lpMapiRecipDesc lpRecips
,
460 LPULONG lpnNewRecips
,
461 lpMapiRecipDesc FAR
* lppNewRecips
)
464 fprintf(ms_global
->dfd
, "\r\nIn MAPIAddress\r\n");
465 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %s set\r\n",
466 flFlags
& MAPI_LOGON_UI
? "" : "NOT");
467 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %s set\r\n",
468 flFlags
& MAPI_NEW_SESSION
? "" : "NOT");
469 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
472 return MAPI_E_NOT_SUPPORTED
;
475 ULONG FAR PASCAL
MAPIDeleteMail(
478 LPTSTR lpszMessageID
,
483 fprintf(ms_global
->dfd
, "\r\nIn MAPIDeleteMail\r\n");
484 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
487 return MAPI_E_NOT_SUPPORTED
;
490 ULONG FAR PASCAL
MAPIDetails(
493 lpMapiRecipDesc lpRecip
,
498 fprintf(ms_global
->dfd
, "\r\nIn MAPIDetails\r\n");
499 fprintf(ms_global
->dfd
, " MAPI_NO_MODIFY is %s set\r\n",
500 flFlags
& MAPI_AB_NOMODIFY
? "" : "NOT");
501 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %s set\r\n",
502 flFlags
& MAPI_LOGON_UI
? "" : "NOT");
503 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %s set\r\n",
504 flFlags
& MAPI_NEW_SESSION
? "" : "NOT");
505 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
508 return MAPI_E_NOT_SUPPORTED
;
511 ULONG FAR PASCAL
MAPIFreeBuffer(
514 mapi_global_s
*nmg
= ms_global
;
517 fprintf(nmg
->dfd
, "\r\nMAPIFreeBuffer called, buffer is %p\r\n", pv
);
521 return SUCCESS_SUCCESS
;
524 ULONG FAR PASCAL
MAPIResolveName(
530 lpMapiRecipDesc FAR
* lppRecip
)
532 mapi_global_s
*nmg
= ms_global
;
533 sessionlist_s
*cs
, *tsession
;
534 static char *fakedomain
= "@";
535 ADDRESS
*adrlist
= NULL
;
536 char *adrstr
, *tadrstr
, *tadrstrbuf
;
539 fprintf(ms_global
->dfd
, "\r\nIn MAPIResolveName\r\n");
540 fprintf(ms_global
->dfd
, " MAPI_NO_MODIFY is %sset\r\n",
541 flFlags
& MAPI_AB_NOMODIFY
? "" : "NOT ");
542 fprintf(ms_global
->dfd
, " MAPI_DIALOG is %sset\r\n",
543 flFlags
& MAPI_DIALOG
? "" : "NOT ");
544 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %sset\r\n",
545 flFlags
& MAPI_LOGON_UI
? "" : "NOT ");
546 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %sset\r\n",
547 flFlags
& MAPI_NEW_SESSION
? "" : "NOT ");
548 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
549 fprintf(ms_global
->dfd
, " String to Resolve is %s\r\n", lpszName
);
553 if((flFlags
& MAPI_NEW_SESSION
) || lhSession
== 0)
554 tsession
= cs
= new_sessionlist();
556 cs
= get_session(lhSession
);
559 fprintf(ms_global
->dfd
, "Session number %p is invalid\r\n", lhSession
);
560 return MAPI_E_INVALID_SESSION
;
563 cs
->flags
.mapi_logon_ui
= (flFlags
& MAPI_LOGON_UI
) ? 1 : 0;
564 if(InitPineSpecific(cs
) == -1) return MAPI_E_FAILURE
;
565 tadrstrbuf
= tadrstr
= mstrdup(lpszName
);
566 removing_leading_and_trailing_white_space(tadrstr
);
567 if(_strnicmp(tadrstr
, "SMTP:", 5) == 0){
569 if(tadrstr
[0] == '(' && tadrstr
[strlen(tadrstr
) - 1] == ')'){
570 tadrstr
[strlen(tadrstr
)-1] = '\0';
572 removing_leading_and_trailing_white_space(tadrstr
);
575 rfc822_parse_adrlist(&adrlist
, tadrstr
,
576 nmg
->prcvars
[USER_DOMAIN
]->val
.p
? nmg
->prcvars
[USER_DOMAIN
]->val
.p
578 fs_give((void **)&tadrstrbuf
);
579 if(!adrlist
|| adrlist
->next
){ /* I guess there aren't supposed to be multiple addresses, */
580 /* which is pretty lame */
581 mail_free_address(&adrlist
);
583 fs_give((void **)&tsession
);
584 msprint("Returning MAPI_E_AMBIGUOUS_RECIPIENT\r\n");
585 return MAPI_E_AMBIGUOUS_RECIPIENT
;
587 if(!adrlist
->host
|| *adrlist
->host
== '@'){
588 mail_free_address(&adrlist
);
590 fs_give((void **)&tsession
);
591 msprint("Returning MAPI_E_AMBIGUOUS_RECIPIENT\r\n");
592 return MAPI_E_AMBIGUOUS_RECIPIENT
;
595 (*lppRecip
) = new_MapiRecipDesc(1);
596 if(adrlist
->personal
){
597 (*lppRecip
)->lpszName
= mstrdup(adrlist
->personal
);
598 adrlist
->personal
= NULL
;
600 adrstr
= (char *)fs_get((8 + strlen(adrlist
->mailbox
) + strlen(adrlist
->host
)) * sizeof(char));
601 sprintf(adrstr
, "SMTP:%s@%s", adrlist
->mailbox
, adrlist
->host
);
602 (*lppRecip
)->lpszAddress
= adrstr
;
604 /* The spec says it's a recipient, so set the thing to MAPI_TO */
605 (*lppRecip
)->ulRecipClass
= MAPI_TO
;
607 mail_free_address(&adrlist
);
608 msprint1(" Returning with name: %s\r\n", (*lppRecip
)->lpszName
? (*lppRecip
)->lpszName
: "(no name)");
609 msprint1(" address: %s\r\n", (*lppRecip
)->lpszAddress
? (*lppRecip
)->lpszAddress
: "(no address)");
610 msprint(" ulRecipClass: MAPI_TO\r\n");
611 msprint("Returning SUCCESS_SUCCESS\r\n");
612 return SUCCESS_SUCCESS
;
615 ULONG FAR PASCAL
MAPISaveMail(
618 lpMapiMessage lpMessage
,
621 LPTSTR lpszMessageID
)
624 fprintf(ms_global
->dfd
, "\r\nIn MAPISaveMail\r\n");
625 fprintf(ms_global
->dfd
, " MAPI_LOGON_UI is %s set\r\n",
626 flFlags
& MAPI_LOGON_UI
? "" : "NOT");
627 fprintf(ms_global
->dfd
, " MAPI_LONG_MSGID is %s set\r\n",
628 flFlags
& MAPI_LONG_MSGID
? "" : "NOT");
629 fprintf(ms_global
->dfd
, " MAPI_NEW_SESSION is %s set\r\n",
630 flFlags
& MAPI_NEW_SESSION
? "" : "NOT");
631 fprintf(ms_global
->dfd
, " session number is %p\r\n", lhSession
);
634 return MAPI_E_NOT_SUPPORTED
;
637 ULONG FAR PASCAL
MAPISendDocuments(
639 LPTSTR lpszDelimChar
,
640 LPTSTR lpszFullPaths
,
641 LPTSTR lpszFileNames
,
645 fprintf(ms_global
->dfd
, "\r\nIn MAPISendDocuments\r\n");
646 fprintf(ms_global
->dfd
, " lpszDelimChar: %c\r\n", *lpszDelimChar
);
647 fprintf(ms_global
->dfd
, " lpszFullPaths: %s\r\n", lpszFullPaths
);
648 fprintf(ms_global
->dfd
, " lpszFileNames: %s\r\n", lpszFileNames
);
652 return send_documents(lpszFullPaths
, *lpszDelimChar
);