3 * ========================================================================
4 * Copyright 2006-2009 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
19 mapi_global_s
*ms_global
= NULL
;
20 #define SIZEOF_20KBUF (20480)
21 char tmp_20k_buf
[SIZEOF_20KBUF
];
23 void mm_searched (MAILSTREAM
*stream
,unsigned long number
);
24 void mm_exists (MAILSTREAM
*stream
,unsigned long number
);
25 void mm_expunged (MAILSTREAM
*stream
,unsigned long number
);
26 void mm_flags (MAILSTREAM
*stream
,unsigned long number
);
27 void mm_notify (MAILSTREAM
*stream
,char *string
,long errflg
);
28 void mm_list (MAILSTREAM
*stream
,int delimiter
,char *name
,long attributes
);
29 void mm_lsub (MAILSTREAM
*stream
,int delimiter
,char *name
,long attributes
);
30 void mm_status (MAILSTREAM
*stream
,char *mailbox
,MAILSTATUS
*status
);
31 void mm_log (char *string
,long errflg
);
32 void mm_dlog (char *string
);
33 int fetch_recursively(BODY
*body
, long msgno
, char *prefix
,
34 PART
*part
, long flags
, FLAGS MAPIflags
,
36 LRESULT CALLBACK
Login(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
);
37 void mm_login (NETMBX
*mb
,char *user
,char *pwd
,long trial
);
38 void mm_critical (MAILSTREAM
*stream
);
39 void mm_nocritical (MAILSTREAM
*stream
);
40 long mm_diskerror (MAILSTREAM
*stream
,long errcode
,long serious
);
41 void mm_fatal (char *string
);
42 lpMapiFileDesc
new_mapi_file_desc(int arraysize
);
43 void free_mapi_file_desc(lpMapiFileDesc lpmfd
, int arraysize
);
45 void free_file_s(file_s
*fs
);
46 void init_prcvars(mapi_global_s
*nmg
);
47 void init_prcfeats(mapi_global_s
*nmg
);
48 void expand_env_vars(mapi_global_s
*nmg
);
49 void init_fcc_folder(mapi_global_s
*nmg
);
50 void init_pmapi_registry_vars(mapi_global_s
*nmg
);
51 void init_pmapi_vars(mapi_global_s
*nmg
);
52 char *copy_remote_to_local(char *pinerc
, sessionlist_s
*cs
);
53 int read_pinerc(mapi_global_s
*nmg
, sessionlist_s
*cs
,
54 char *prc
, char *pineconf
, char *pinercex
, int depth
);
55 void free_mapi_global(mapi_global_s
*nmg
);
56 MAILSTREAM
*first_open(sessionlist_s
*cs
);
57 int lookup_file_mime_type(char *fn
, BODY
*body
);
58 int LookupMIMEFileExt(char *val
, char *mime_type
, DWORD
*vallen
);
59 int in_passfile(sessionlist_s
*cs
);
60 int set_text_data(BODY
*body
, char *txt
);
61 int get_suggested_directory(char *dir
);
62 int get_suggested_file_ext(char *file_ext
, PART
*part
, DWORD
*file_extlen
);
65 int UnderlineSpace(char *s
);
66 int GetOutlookVersion();
67 char *pmapi_generate_message_id();
68 SENDSTREAM
*mapi_smtp_open(sessionlist_s
*cs
, char **servers
, long options
);
69 char *encode_mailto_addr_keyval(lpMapiRecipDesc lpmr
);
70 char *encode_mailto_keyval(char *key
, char* val
);
73 void mm_searched (MAILSTREAM
*stream
,unsigned long number
)
76 fprintf(ms_global
->dfd
, "IMAP mm_searched: not implemented\r\n");
81 void mm_exists (MAILSTREAM
*stream
,unsigned long number
)
84 fprintf(ms_global
->dfd
, "IMAP mm_exists: not implemented\r\n");
89 void mm_expunged (MAILSTREAM
*stream
,unsigned long number
)
92 fprintf(ms_global
->dfd
, "IMAP mm_expunged: not implemented\r\n");
97 void mm_flags (MAILSTREAM
*stream
,unsigned long number
)
100 fprintf(ms_global
->dfd
, "IMAP mm_flags: number is %d\r\n", number
);
105 void mm_notify (MAILSTREAM
*stream
,char *string
,long errflg
)
111 fprintf(nmg
->dfd
, "IMAP mm_notify:%s %s\r\n",
112 (errflg
== NIL
? "" :
113 (errflg
== WARN
? " WARN:":
114 (errflg
== ERROR
? " ERROR:":
115 (errflg
== PARSE
? " PARSE:":" BYE:")))), string
);
120 void mm_list (MAILSTREAM
*stream
,int delimiter
,char *name
,long attributes
)
123 fprintf(ms_global
->dfd
, "IMAP mm_list: not implemented\r\n");
128 void mm_lsub (MAILSTREAM
*stream
,int delimiter
,char *name
,long attributes
)
131 fprintf(ms_global
->dfd
, "IMAP mm_lsub: not implemented\r\n");
136 void mm_status (MAILSTREAM
*stream
,char *mailbox
,MAILSTATUS
*status
)
139 fprintf(ms_global
->dfd
, "IMAP mm_status: not implemented\r\n");
144 void mm_log (char *string
,long errflg
)
147 fprintf(ms_global
->dfd
, "IMAP mm_log:%s %s\r\n",
148 (errflg
== NIL
? "" :
149 (errflg
== WARN
? " WARN:":
150 (errflg
== ERROR
? " ERROR:":
151 (errflg
== PARSE
? " PARSE:":" BYE:")))), string
);
155 ErrorBox("ERROR: %s", string
);
158 void mm_dlog (char *string
)
164 now
= time((time_t *)0);
165 tm_now
= localtime(&now
);
167 fprintf(ms_global
->dfd
, "IMAP %2.2d:%2.2d:%2.2d %d/%d: %s\r\n",
168 tm_now
->tm_hour
, tm_now
->tm_min
, tm_now
->tm_sec
,
169 tm_now
->tm_mon
+1, tm_now
->tm_mday
, string
);
174 int fetch_recursively(BODY
*body
, long msgno
, char *prefix
, PART
*part
,
175 long flags
, FLAGS MAPIflags
, sessionlist_s
*cs
)
182 unsigned long declen
, numwritten
;
184 char tmp
[64], file_ext
[64], filename
[1024], dir
[1024];
185 DWORD file_extlen
= 64;
187 unsigned long tmpattlen
;
191 if(body
&& body
->type
== TYPEMULTIPART
){
192 part
= body
->nested
.part
;
193 fetch_recursively(&part
->body
, msgno
, prefix
, part
,
194 flags
, MAPIflags
, cs
);
199 sprintf(tmp
, "%s%s%d", prefix
, (*prefix
? "." : ""), num
);
200 if(part
&& part
->body
.type
== TYPEMULTIPART
){
201 subpart
= part
->body
.nested
.part
;
202 fetch_recursively(&subpart
->body
, msgno
, tmp
,
203 subpart
, flags
, MAPIflags
, cs
);
206 tmpatt
= mail_fetch_body(cs
->open_stream
, msgno
,
207 tmp
, &tmpattlen
, flags
);
208 if(strcmp(tmp
, "1") == 0){
209 if(((part
&& part
->body
.type
== TYPETEXT
) ||
210 (!part
&& body
->type
== TYPETEXT
)) &&
211 !(MAPIflags
& MAPI_BODY_AS_FILE
)){
212 if(cs
->lpm
->lpszNoteText
){
213 fs_give((void **)&cs
->lpm
->lpszNoteText
);
214 cs
->lpm
->lpszNoteText
= NULL
;
216 cs
->lpm
->lpszNoteText
= mstrdup(tmpatt
);
220 cs
->lpm
->lpszNoteText
= mstrdup("");
221 if(MAPIflags
& MAPI_SUPPRESS_ATTACH
)
224 if(tmpatt
&& part
&& part
->body
.encoding
== ENCBASE64
){
225 decf
= rfc822_base64(tmpatt
, tmpattlen
, &declen
);
228 else if(tmpatt
&& part
&& part
->body
.encoding
== ENCQUOTEDPRINTABLE
){
229 decf
= rfc822_qprint(tmpatt
, tmpattlen
, &declen
);
234 decf
= mstrdup(tmpatt
);
241 get_suggested_directory(dir
);
242 tmplen
= strlen(dir
);
243 if(dir
[tmplen
- 1] != '\\'){
245 dir
[tmplen
+1] = '\0';
248 get_suggested_file_ext(file_ext
,part
, &file_extlen
);
250 sprintf(filename
, "%smapiapp%d%s", dir
, nmg
->attach_no
,
253 }while (_access(filename
, 00) != -1);
254 attfd
= fopen(filename
, "wb");
257 fprintf(nmg
->dfd
,"preparing to write attachment to %s\r\n",
259 numwritten
= fwrite(decf
, sizeof(char), declen
, attfd
);
261 fs_give((void **)&decf
);
263 tfs
->filename
= mstrdup(filename
);
267 for(tfs2
= cs
->fs
; tfs2
->next
; tfs2
= tfs2
->next
);
273 fprintf(nmg
->dfd
,"Failure in opening %s for attachment\r\n",
278 }while(part
&& (part
= part
->next
));
283 int fetch_structure_and_attachments(long msgno
, long flags
,
284 FLAGS MAPIflags
, sessionlist_s
*cs
)
289 MESSAGECACHE
*elt
= NULL
;
292 int num
= 0, restore_seen
= 0, file_count
= 0, i
;
293 unsigned long recips
;
294 char tmp
[1024]; /* don't know how much space we'll need */
297 env
= mail_fetch_structure(cs
->open_stream
, msgno
, &body
, flags
);
298 if(env
== NULL
|| body
== NULL
){
300 fprintf(nmg
->dfd
, "mail_fetch_structure returned %p for env and %p for body\r\n", env
, body
);
301 return MAPI_E_FAILURE
;
305 fprintf(nmg
->dfd
, "global lpm is set when it SHOULDN'T be! Freeing\r\n");
306 if(free_mbuffer(cs
->lpm
))
307 free_MapiMessage(cs
->lpm
, 1);
310 cs
->lpm
= new_MapiMessage(1);
311 if(env
->subject
) cs
->lpm
->lpszSubject
= mstrdup(env
->subject
);
313 elt
= mail_elt(cs
->open_stream
, msgno
);
314 mail_parse_date(elt
, env
->date
);
315 sprintf(tmp
, "%d/%s%d/%s%d %s%d:%s%d",
316 elt
->year
+BASEYEAR
, (elt
->month
< 10) ? "0": "",
317 elt
->month
, (elt
->day
< 10) ? "0":"", elt
->day
,
318 (elt
->hours
< 10) ? "0":"", elt
->hours
,
319 (elt
->minutes
< 10) ? "0":"", elt
->minutes
);
320 cs
->lpm
->lpszDateReceived
= mstrdup(tmp
);
323 cs
->lpm
->lpOriginator
= new_MapiRecipDesc(1);
324 if(env
->from
->personal
)
325 cs
->lpm
->lpOriginator
->lpszName
= mstrdup(env
->from
->personal
);
326 if(env
->from
->mailbox
&& env
->from
->host
){
327 /* don't know if these could ever be empty */
328 sprintf(tmp
, "%s@%s", env
->from
->mailbox
, env
->from
->host
);
329 cs
->lpm
->lpOriginator
->lpszAddress
= mstrdup(tmp
);
331 cs
->lpm
->lpOriginator
->ulRecipClass
= MAPI_ORIG
;
333 if(env
->to
|| env
->cc
|| env
->bcc
){ /* should always be true */
356 cs
->lpm
->nRecipCount
= recips
;
357 cs
->lpm
->lpRecips
= new_MapiRecipDesc(recips
);
362 cs
->lpm
->lpRecips
[recips
].ulRecipClass
= MAPI_TO
;
364 cs
->lpm
->lpRecips
[recips
].lpszName
= mstrdup(addr
->personal
);
365 if(addr
->mailbox
&& addr
->host
){
366 sprintf(tmp
, "%s@%s", addr
->mailbox
, addr
->host
);
367 cs
->lpm
->lpRecips
[recips
].lpszAddress
= mstrdup(tmp
);
376 cs
->lpm
->lpRecips
[recips
].ulRecipClass
= MAPI_CC
;
378 cs
->lpm
->lpRecips
[recips
].lpszName
= mstrdup(addr
->personal
);
379 if(addr
->mailbox
&& addr
->host
){
380 sprintf(tmp
, "%s@%s", addr
->mailbox
, addr
->host
);
381 cs
->lpm
->lpRecips
[recips
].lpszAddress
= mstrdup(tmp
);
390 cs
->lpm
->lpRecips
[recips
].ulRecipClass
= MAPI_BCC
;
392 cs
->lpm
->lpRecips
[recips
].lpszName
= mstrdup(addr
->personal
);
393 if(addr
->mailbox
&& addr
->host
){
394 sprintf(tmp
, "%s@%s", addr
->mailbox
, addr
->host
);
395 cs
->lpm
->lpRecips
[recips
].lpszAddress
= mstrdup(tmp
);
404 /* gotta remember to unflag \Seen if we just want a peek */
405 sprintf(tmp
, "%d", msgno
);
406 mail_fetch_flags(cs
->open_stream
, tmp
, NIL
);
407 elt
= mail_elt(cs
->open_stream
, msgno
);
410 fprintf(nmg
->dfd
, "Message has not been seen, and a PEEK is requested\r\n");
414 fprintf(nmg
->dfd
, "Message has already been marked seen\r\n");
416 if(!(MAPIflags
& MAPI_ENVELOPE_ONLY
))
417 fetch_recursively(body
, msgno
, "", NULL
, flags
, MAPIflags
, cs
);
419 for(tfs
= cs
->fs
; tfs
; tfs
= tfs
->next
)
421 cs
->lpm
->lpFiles
= new_mapi_file_desc(file_count
);
422 for(i
= 0, tfs
= cs
->fs
; i
< file_count
&& tfs
; i
++, tfs
= tfs
->next
){
423 cs
->lpm
->lpFiles
[i
].lpszPathName
= mstrdup(tfs
->filename
);
425 cs
->lpm
->nFileCount
= file_count
;
430 elt
= mail_elt(cs
->open_stream
, msgno
);
431 if(!elt
->seen
&& MSDEBUG
)
432 fprintf(nmg
->dfd
, "Fetched body and Message still isn't seen\r\n");
434 fprintf(nmg
->dfd
, "Message has been seen, clearing flag\r\n");
436 mail_flag(cs
->open_stream
, tmp
, "\\SEEN", NIL
);
437 elt
= mail_elt(cs
->open_stream
, msgno
);
439 fprintf(nmg
->dfd
, "After calling mail_flag(), elt->seen is %s\r\n",
440 elt
->seen
? "SET" : "UNSET");
443 return SUCCESS_SUCCESS
;
446 LRESULT CALLBACK
Login(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
454 SetDlgItemText(hDlg
, IDC_SERVER
, nmg
->tmpmbxptr
);
455 if(/*nmg->flags.mapi_logon_ui &&*/ in_passfile(nmg
->cs
)){
456 SetDlgItemText(hDlg
, IDC_LOGIN
, nmg
->cs
->dlge
.edit1
);
457 SetDlgItemText(hDlg
, IDC_PASSWORD
, nmg
->cs
->dlge
.edit2
);
460 SetDlgItemText(hDlg
, IDC_LOGIN
,
461 (*nmg
->cs
->mb
->user
) ? nmg
->cs
->mb
->user
462 : nmg
->prcvars
[USER_ID
]->val
.p
);
465 if(LOWORD(wParam
) == IDOK
){
466 nmg
->cs
->flags
.dlg_cancel
= 0;
467 GetDlgItemText(hDlg
, IDC_LOGIN
, nmg
->cs
->dlge
.edit1
, EDITLEN
);
468 GetDlgItemText(hDlg
, IDC_PASSWORD
, nmg
->cs
->dlge
.edit2
, EDITLEN
);
469 EndDialog(hDlg
, LOWORD(wParam
));
472 else if(LOWORD(wParam
) == IDCANCEL
){
473 nmg
->cs
->flags
.dlg_cancel
= 1;
474 EndDialog(hDlg
, LOWORD(wParam
));
482 void mm_login (NETMBX
*mb
,char *user
,char *pwd
,long trial
)
485 pw_cache_s
*tpwc
, *dpwc
;
490 if(!nmg
->cs
->flags
.dlg_cancel
){
491 for(tpwc
= nmg
->cs
->pwc
; tpwc
; tpwc
= tpwc
->next
){
492 if(tpwc
->validpw
&& strcmp(tpwc
->host
, mb
->host
) == 0)
496 strcpy(user
, tpwc
->user
);
497 strcpy(pwd
, tpwc
->pwd
);
500 /* else if(!nmg->cs->flags.check_stream) { */
501 else if(nmg
->cs
->flags
.mapi_logon_ui
|| !nmg
->pmapi_strict_no_dialog
) {
504 nmg
->tmpmbxptr
= mb
->host
;
506 DialogBox(nmg
->mhinst
, MAKEINTRESOURCE(IDD_DIALOG1
),
507 nmg
->cs
->mhwnd
, (DLGPROC
)Login
);
509 nmg
->tmpmbxptr
= NULL
;
510 if(!nmg
->cs
->flags
.dlg_cancel
){
511 strcpy(user
, nmg
->cs
->dlge
.edit1
);
512 strcpy(pwd
, nmg
->cs
->dlge
.edit2
);
515 if(tpwc
->validpw
== 0){
518 if(dpwc
== nmg
->cs
->pwc
)
519 nmg
->cs
->pwc
= dpwc
->next
;
520 fs_give((void **)&dpwc
);
525 if(nmg
->cs
->pwc
== NULL
){
526 nmg
->cs
->pwc
= (pw_cache_s
*)fs_get(sizeof(pw_cache_s
));
530 for(tpwc
= nmg
->cs
->pwc
; tpwc
->next
; tpwc
= tpwc
->next
);
531 tpwc
->next
= (pw_cache_s
*)fs_get(sizeof(pw_cache_s
));
534 memset(tpwc
, 0, sizeof(pw_cache_s
));
535 strncpy(tpwc
->user
, nmg
->cs
->dlge
.edit1
, EDITLEN
- 1);
536 strncpy(tpwc
->pwd
, nmg
->cs
->dlge
.edit2
, EDITLEN
- 1);
537 strncpy(tpwc
->host
, mb
->host
, EDITLEN
- 1);
544 void mm_critical (MAILSTREAM
*stream
)
547 fprintf(ms_global
->dfd
, "IMAP mm_critical: not implemented\r\n");
552 void mm_nocritical (MAILSTREAM
*stream
)
555 fprintf(ms_global
->dfd
, "IMAP mm_nocritical: not implemented\r\n");
560 long mm_diskerror (MAILSTREAM
*stream
,long errcode
,long serious
)
563 fprintf(ms_global
->dfd
, "IMAP mm_diskerror: not implemented\r\n");
569 void mm_fatal (char *string
)
572 fprintf(ms_global
->dfd
, "IMAP mm_fatal: %s\r\n", string
);
577 sessionlist_s
*new_sessionlist()
581 cs
= (sessionlist_s
*)fs_get(sizeof(sessionlist_s
));
582 memset(cs
, 0, sizeof(sessionlist_s
));
583 cs
->session_number
= ms_global
->next_session
++;
588 sessionlist_s
*free_sessionlist_node(sessionlist_s
*cs
)
594 if(cs
->currently_open
)
595 fs_give((void **)&cs
->currently_open
);
599 if(free_mbuffer(cs
->lpm
))
600 free_MapiMessage(cs
->lpm
, 1);
603 fs_give((void **)&cs
);
608 sessionlist_s
*get_session(unsigned long num
)
610 mapi_global_s
*nmg
= ms_global
;
613 ts
= nmg
->sessionlist
;
614 while(ts
&& ts
->session_number
!= num
) ts
= ts
->next
;
619 void *mm_cache (MAILSTREAM *stream,unsigned long msgno,long op){}
621 mapi_global_s
*new_mapi_global()
626 nmg
= (mapi_global_s
*)fs_get(sizeof(mapi_global_s
));
627 memset(nmg
, 0, sizeof(mapi_global_s
));
628 for(i
=0; i
< NUMPRCVARS
; i
++){
629 nmg
->prcvars
[i
] = (rc_entry_s
*)fs_get(sizeof(rc_entry_s
));
630 memset(nmg
->prcvars
[i
], 0, sizeof(rc_entry_s
));
632 for(i
=0; i
< NUMPRCFEATS
; i
++){
633 nmg
->prcfeats
[i
] = (rc_feat_s
*)fs_get(sizeof(rc_feat_s
));
634 memset(nmg
->prcfeats
[i
], 0, sizeof(rc_feat_s
));
636 nmg
->next_session
= 1;
641 int InitPineSpecific(sessionlist_s
*cs
)
643 mapi_global_s
*nmg
= ms_global
;
645 if(nmg
->inited
) return 0;
646 init_prcvars(ms_global
);
647 init_prcfeats(ms_global
);
648 init_pmapi_registry_vars(ms_global
);
649 if(read_pinerc(ms_global
, cs
, ms_global
->pinerc
,
650 ms_global
->pineconf
, ms_global
->pinercex
, 0) == -1)
652 expand_env_vars(ms_global
);
653 init_fcc_folder(ms_global
);
654 msprint1("Fcc folder defined: %s", ms_global
->fccfolder
);
655 init_pmapi_vars(ms_global
);
661 new_mbuffer(void *buf
, int arraysize
, BufType type
)
663 MBUFFER_LIST_S
*tlist
, *tlist2
;
664 mapi_global_s
*nmg
= ms_global
;
666 tlist
= (MBUFFER_LIST_S
*)fs_get(sizeof(MBUFFER_LIST_S
));
667 memset(tlist
, 0, sizeof(MBUFFER_LIST_S
));
669 tlist
->arraysize
= arraysize
;
673 nmg
->mapi_bufs
= tlist
;
675 for(tlist2
= nmg
->mapi_bufs
; tlist2
->next
; tlist2
= tlist2
->next
);
676 tlist2
->next
= tlist
;
683 free_mbuffer(void *buf
)
685 MBUFFER_LIST_S
*tlist
, *pre_tlist
= NULL
;
686 mapi_global_s
*nmg
= ms_global
;
687 sessionlist_s
*session
;
689 for(tlist
= nmg
->mapi_bufs
; tlist
&& tlist
->buf
!= buf
; pre_tlist
= tlist
, tlist
= tlist
->next
);
691 msprint1("ERROR: buf %p not found in list!\r\n", buf
);
694 if(tlist
== nmg
->mapi_bufs
)
695 nmg
->mapi_bufs
= tlist
->next
;
697 pre_tlist
->next
= tlist
->next
;
698 switch (tlist
->type
) {
700 free_MapiRecipDesc(tlist
->buf
, tlist
->arraysize
);
703 for(session
= nmg
->sessionlist
; session
; session
= session
->next
){
704 if(session
->lpm
== tlist
->buf
)
707 free_MapiMessage(tlist
->buf
, tlist
->arraysize
);
710 fs_give((void **)&tlist
);
715 new_MapiRecipDesc(int arraysize
)
717 lpMapiRecipDesc lpmrd
;
718 mapi_global_s
*nmg
= ms_global
;
720 lpmrd
= (MapiRecipDesc
*)fs_get(arraysize
*sizeof(MapiRecipDesc
));
721 memset(lpmrd
, 0, arraysize
*sizeof(MapiRecipDesc
));
722 new_mbuffer((void *)lpmrd
, arraysize
, RecipDesc
);
727 free_MapiRecipDesc(lpMapiRecipDesc buf
, int arraysize
)
731 for(i
= 0; i
< arraysize
; i
++){
733 fs_give((void **)&buf
[i
].lpszName
);
734 if(buf
[i
].lpszAddress
)
735 fs_give((void **)&buf
[i
].lpszAddress
);
737 fs_give((void **)&buf
);
741 new_MapiMessage(int arraysize
)
744 mapi_global_s
*nmg
= ms_global
;
746 lpmm
= (lpMapiMessage
)fs_get(arraysize
*sizeof(MapiMessage
));
747 memset(lpmm
, 0, arraysize
*sizeof(MapiMessage
));
748 new_mbuffer((void *)lpmm
, arraysize
, Message
);
753 free_MapiMessage(lpMapiMessage buf
, int arraysize
)
757 for(i
= 0; i
< arraysize
; i
++){
758 if(buf
[i
].lpszSubject
)
759 fs_give((void **)&buf
[i
].lpszSubject
);
760 if(buf
[i
].lpszNoteText
)
761 fs_give((void **)&buf
[i
].lpszNoteText
);
762 if(buf
[i
].lpszMessageType
)
763 fs_give((void **)&buf
[i
].lpszMessageType
);
764 if(buf
[i
].lpszDateReceived
)
765 fs_give((void **)&buf
[i
].lpszDateReceived
);
766 if(buf
[i
].lpszConversationID
)
767 fs_give((void **)&buf
[i
].lpszConversationID
);
768 if(buf
[i
].lpOriginator
){
769 if(free_mbuffer(buf
[i
].lpOriginator
))
770 free_MapiRecipDesc(buf
[i
].lpOriginator
, 1);
773 if(free_mbuffer(buf
[i
].lpRecips
))
774 free_MapiRecipDesc(buf
[i
].lpRecips
, buf
[i
].nRecipCount
);
777 free_mapi_file_desc(buf
[i
].lpFiles
, buf
[i
].nFileCount
);
779 fs_give((void **)&buf
);
782 lpMapiFileDesc
new_mapi_file_desc(int arraysize
)
784 lpMapiFileDesc lpmfd
;
786 lpmfd
= (MapiFileDesc
*)fs_get(arraysize
* sizeof (MapiFileDesc
));
787 memset(lpmfd
, 0, arraysize
* sizeof(MapiFileDesc
));
791 void free_mapi_file_desc(lpMapiFileDesc lpmfd
, int arraysize
)
795 if(lpmfd
== NULL
) return;
797 for(i
= 0; i
< arraysize
; i
++){
798 if(lpmfd
[i
].lpszPathName
)
799 fs_give((void **)&lpmfd
[i
].lpszPathName
);
800 if(lpmfd
[i
].lpszFileName
)
801 fs_give((void **)&lpmfd
[i
].lpszFileName
);
802 /* NOTE: if lpFileType gets used, free it here */
804 fs_give((void **)&lpmfd
);
811 tmp_fs
= (file_s
*)fs_get(sizeof(file_s
));
812 memset(tmp_fs
, 0, sizeof(file_s
));
816 void free_file_s(file_s
*fs
)
818 if(fs
== NULL
) return;
820 free_file_s(fs
->next
);
822 fs_give((void **)&fs
->filename
);
823 fs_give((void **)&fs
);
827 init_prcvars(mapi_global_s
*nmg
)
831 nmg
->prcvars
[USER_ID
]->var
= mstrdup("user-id");
832 nmg
->prcvars
[PERSONAL_NAME
]->var
= mstrdup("personal-name");
833 nmg
->prcvars
[USER_DOMAIN
]->var
= mstrdup("user-domain");
834 nmg
->prcvars
[SMTP_SERVER
]->var
= mstrdup("smtp-server");
835 nmg
->prcvars
[SMTP_SERVER
]->islist
= 1;
836 nmg
->prcvars
[INBOX_PATH
]->var
= mstrdup("inbox-path");
837 nmg
->prcvars
[FEATURE_LIST
]->var
= mstrdup("feature-list");
838 nmg
->prcvars
[FEATURE_LIST
]->islist
= 1;
839 nmg
->prcvars
[CHARACTER_SET
]->var
= mstrdup("character-set");
840 nmg
->prcvars
[FOLDER_COLLECTIONS
]->var
= mstrdup("folder-collections");
841 nmg
->prcvars
[FOLDER_COLLECTIONS
]->islist
= 1;
842 nmg
->prcvars
[PMAPI_SEND_BEHAVIOR
]->var
= mstrdup("pmapi-send-behavior");
843 nmg
->prcvars
[PMAPI_SEND_BEHAVIOR
]->ispmapivar
= 1;
844 nmg
->prcvars
[DEFAULT_FCC
]->var
= mstrdup("default-fcc");
845 nmg
->prcvars
[PMAPI_SUPPRESS_DIALOGS
]->var
= mstrdup("pmapi-suppress-dialogs");
846 nmg
->prcvars
[PMAPI_SUPPRESS_DIALOGS
]->ispmapivar
= 1;
847 nmg
->prcvars
[PMAPI_STRICT_NO_DIALOG
]->var
= mstrdup("pmapi-strict-no-dialog");
848 nmg
->prcvars
[PMAPI_STRICT_NO_DIALOG
]->ispmapivar
= 1;
852 init_prcfeats(mapi_global_s
*nmg
)
854 nmg
->prcfeats
[ENABLE8BIT
]->var
= mstrdup("enable-8bit-esmtp-negotiation");
857 void init_fcc_folder(mapi_global_s
*nmg
)
859 char *fcc
, **fc
, *desc
= NULL
, *col
= NULL
, *tfcc
, *p
, *p2
;
862 if(!nmg
->prcvars
[DEFAULT_FCC
]->val
.p
)
863 nmg
->prcvars
[DEFAULT_FCC
]->val
.p
= cpystr("sent-mail");
864 fcc
= nmg
->prcvars
[DEFAULT_FCC
]->val
.p
;
865 if(!fcc
|| !(*fcc
)) return;
866 if(strcmp(fcc
, "\"\"") == 0) return;
867 if((*fcc
== '{') || (isalpha(fcc
[0]) && (fcc
[1] == ':'))
868 || ((fcc
[0] == '\\') && (fcc
[1] == '\\'))){
869 nmg
->fccfolder
= cpystr(fcc
);
872 fc
= nmg
->prcvars
[FOLDER_COLLECTIONS
]->val
.l
;
873 if(!fc
|| !fc
[0] || !fc
[0][0]) return;
874 get_pair(fc
[i
], &desc
, &col
, 0, 0);
876 fs_give((void **)&desc
);
879 p
= strrchr(col
, '[');
880 p2
= strrchr(col
, ']');
881 if((p2
< p
) || (!p
)){
883 fs_give((void **)&col
);
886 tfcc
= (char *)fs_get((strlen(col
) + strlen(fcc
) + 1) * sizeof(char));
889 sprintf(tfcc
, "%s%s%s", col
, fcc
, p2
);
890 nmg
->fccfolder
= tfcc
;
892 fs_give((void **)&col
);
895 void init_pmapi_registry_vars(mapi_global_s
*nmg
)
899 DWORD keyDataSize
= 1024;
903 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
904 "Software\\University of Washington\\Alpine\\1.0\\PmapiOpts",
907 &hKey
) != ERROR_SUCCESS
)
910 for(i
= 0; i
< NUMPRCVARS
; i
++){
911 if(nmg
->prcvars
[i
]->ispmapivar
&& nmg
->prcvars
[i
]->islist
== 0){
913 if((RegQueryValueEx(hKey
, nmg
->prcvars
[i
]->var
, 0, &keyDataType
,
914 keyData
, &keyDataSize
) == ERROR_SUCCESS
)
915 && keyDataType
== REG_SZ
){
916 if(nmg
->prcvars
[i
]->val
.p
)
917 fs_give((void **)&nmg
->prcvars
[i
]->val
.p
);
918 nmg
->prcvars
[i
]->val
.p
= mstrdup(keyData
);
926 void init_pmapi_vars(mapi_global_s
*nmg
)
930 if(b
= nmg
->prcvars
[PMAPI_SEND_BEHAVIOR
]->val
.p
){
931 if(_stricmp(b
, "always-prompt") == 0)
932 nmg
->pmapi_send_behavior
= PMSB_ALWAYS_PROMPT
;
933 else if(_stricmp(b
, "always-send") == 0)
934 nmg
->pmapi_send_behavior
= PMSB_ALWAYS_SEND
;
935 else if(_stricmp(b
, "never-send") == 0)
936 nmg
->pmapi_send_behavior
= PMSB_NEVER_SEND
;
939 nmg
->pmapi_send_behavior
= PMSB_ALWAYS_PROMPT
;
940 if(b
= nmg
->prcvars
[PMAPI_SUPPRESS_DIALOGS
]->val
.p
){
941 if(_stricmp(b
, "yes") == 0)
942 nmg
->pmapi_suppress_dialogs
= PMSD_YES
;
943 else if(_stricmp(b
, "prompt") == 0)
944 nmg
->pmapi_suppress_dialogs
= PMSD_PROMPT
;
945 else if(_stricmp(b
, "no") == 0)
946 nmg
->pmapi_suppress_dialogs
= PMSD_NO
;
949 nmg
->pmapi_suppress_dialogs
= PMSD_NO
;
950 if(b
= nmg
->prcvars
[PMAPI_STRICT_NO_DIALOG
]->val
.p
){
951 if(_stricmp(b
, "yes") == 0)
952 nmg
->pmapi_strict_no_dialog
= 1;
955 nmg
->pmapi_strict_no_dialog
= 0;
958 char *copy_remote_to_local(char *pinerc
, sessionlist_s
*cs
)
960 mapi_global_s
*nmg
= ms_global
;
961 char *tmptext
, dir
[1024], filename
[1024];
962 unsigned long tmptextlen
, i
= 0, numwritten
;
965 if(nmg
->cs
) return NULL
;
966 if(!(cs
->open_stream
= mapi_mail_open(cs
, NULL
, pinerc
,
967 ms_global
->debug
? OP_DEBUG
: NIL
))){
968 ErrorBox("Couldn't open %s for reading as remote pinerc", pinerc
);
972 nmg
->tmpmbxptr
= NULL
;
973 tmptext
= mail_fetch_body(cs
->open_stream
, cs
->open_stream
->nmsgs
,
974 "1", &tmptextlen
, NIL
);
976 get_suggested_directory(dir
);
978 sprintf(filename
, "%s%smapipinerc%d", dir
,
979 dir
[strlen(dir
)-1] == '\\' ? "" : "\\", i
);
981 }while (_access(filename
, 00) != -1);
982 if(prcfd
= fopen(filename
, "wb")){
984 fprintf(ms_global
->dfd
,"preparing to write pinerc to %s\r\n",
986 numwritten
= fwrite(tmptext
, sizeof(char), tmptextlen
, prcfd
);
990 ErrorBox("Couldn't open temp file %s for writing", filename
);
991 mail_close_full(cs
->open_stream
, NIL
);
994 cs
->open_stream
= mail_close_full(cs
->open_stream
, NIL
);
995 return(mstrdup(filename
));
998 int read_pinerc(mapi_global_s
*nmg
, sessionlist_s
*cs
,
999 char *prc
, char *pineconf
, char *pinercex
, int depth
)
1002 int i
, varnum
, j
, varlen
, create_local
= 0, k
;
1003 char line
[BUFLEN
], *local_pinerc
, *p
;
1005 if(nmg
== NULL
) return -1;
1008 "read_pinerc called: prc: %s, pineconf: %s, pinercex: %s, depth: %d\r\n",
1009 prc
? prc
: "NULL", pineconf
? pineconf
: "NULL",
1010 pinercex
? pinercex
: "NULL", depth
);
1014 fprintf(nmg
->dfd
, "Recursively calling read_pinerc for pineconf\r\n");
1015 read_pinerc(nmg
, cs
, pineconf
, NULL
, NULL
, 1);
1018 ErrorBox("No value found for %s. Try running Alpine.", "pinerc");
1019 DEBUG_WRITE("No value found for %s\r\n","pinerc");
1025 fprintf(ms_global
->dfd
, "REMOTE PINERC: %s\r\n", prc
);
1026 if(!(local_pinerc
= copy_remote_to_local(prc
, cs
))){
1028 fprintf(nmg
->dfd
, "Couldn't copy remote pinerc to local\r\n");
1034 if(!(local_pinerc
= mstrdup(prc
))){
1035 ErrorBox("Couldn't fs_get for %s","pinerc");
1040 fprintf(nmg
->dfd
, "Preparing to open local pinerc %s\r\n", local_pinerc
);
1041 prcfd
= fopen(local_pinerc
, "r");
1043 DEBUG_WRITE("Couldn't open %s\r\n","pinerc");
1045 ErrorBox("Couldn't open %s\r\n","pinerc");
1047 fs_give((void **)&local_pinerc
);
1050 DEBUG_WRITE("Opened %s for reading\r\n", "pinerc");
1051 for(i
= 0; i
< NUMPRCVARS
&& nmg
->prcvars
[i
]->var
; i
++);
1053 while(fgets(line
, BUFLEN
, prcfd
)){
1055 while(isspace(line
[j
])) j
++;
1056 if(line
[j
] != '#' && line
[j
] != '\0'){
1057 for(i
= 0; i
< varnum
; i
++){
1058 varlen
= strlen(nmg
->prcvars
[i
]->var
);
1059 if(_strnicmp(nmg
->prcvars
[i
]->var
, line
+j
, varlen
)==0){
1062 /* we found a match in the pinerc */
1064 if(nmg
->prcvars
[i
]->islist
){
1065 while(isspace(line
[j
])) j
++;
1066 if(line
[j
] != '\0'){
1067 STRLIST_S
*strl
= NULL
, *tl
, *tln
;
1069 if(nmg
->prcvars
[i
]->val
.l
){
1070 for(k
= 0; nmg
->prcvars
[i
]->val
.l
[k
]; k
++)
1071 fs_give((void **)&nmg
->prcvars
[i
]->val
.l
[k
]);
1072 fs_give((void **)&nmg
->prcvars
[i
]->val
.l
);
1074 strl
= (STRLIST_S
*)fs_get(sizeof(STRLIST_S
));
1075 memset(strl
, 0, sizeof(STRLIST_S
));
1078 while(isspace(line
[j
])) j
++;
1079 if(p
= strchr(line
+j
, ','))
1081 if(tl
!= strl
|| tl
->str
){
1082 tl
->next
= (STRLIST_S
*)fs_get(sizeof(STRLIST_S
));
1084 memset(tl
, 0, sizeof(STRLIST_S
));
1086 varlen
= strlen(line
+j
);
1087 while(isspace((line
+j
)[varlen
- 1])){
1089 (line
+j
)[varlen
] = '\0';
1091 tl
->str
= mstrdup(line
+j
);
1094 while(isspace(line
[j
])) j
++;
1096 fgets(line
, BUFLEN
, prcfd
);
1103 for(tl
= strl
, k
= 0; tl
; tl
= tl
->next
, k
++);
1104 nmg
->prcvars
[i
]->val
.l
= (char **)fs_get((k
+1)*sizeof(char *));
1105 for(tl
= strl
, k
= 0; tl
; tl
= tln
, k
++){
1106 nmg
->prcvars
[i
]->val
.l
[k
] = tl
->str
;
1108 fs_give((void **)&tl
);
1110 nmg
->prcvars
[i
]->val
.l
[k
] = NULL
;
1114 while(isspace(line
[j
])) j
++;
1115 if(line
[j
] != '\0'){
1116 varlen
= strlen(line
+j
);
1117 while(isspace((line
+j
)[varlen
-1])){
1119 (line
+j
)[varlen
] = '\0';
1121 if(nmg
->prcvars
[i
]->val
.p
) fs_give((void **)&nmg
->prcvars
[i
]->val
.p
);
1122 nmg
->prcvars
[i
]->val
.p
= (char *)fs_get((varlen
+ 1)*sizeof(char));
1123 strncpy(nmg
->prcvars
[i
]->val
.p
, line
+j
, varlen
);
1124 nmg
->prcvars
[i
]->val
.p
[varlen
] = '\0';
1136 "Recursively calling read_pinerc for exceptions\r\n");
1137 read_pinerc(nmg
, cs
, pinercex
, NULL
, NULL
, 1);
1142 for(i
= 0; nmg
->prcvars
[FEATURE_LIST
]->val
.l
1143 && nmg
->prcvars
[FEATURE_LIST
]->val
.l
[i
]; i
++){
1144 for(j
= 0; j
< NUMPRCFEATS
; j
++){
1145 if(strcmp(nmg
->prcfeats
[j
]->var
, nmg
->prcvars
[FEATURE_LIST
]->val
.l
[i
]) == 0)
1146 nmg
->prcfeats
[j
]->is_set
= 1;
1147 else if((strncmp("no-", nmg
->prcvars
[FEATURE_LIST
]->val
.l
[i
], 3) == 0)
1148 && (strcmp(nmg
->prcfeats
[j
]->var
,
1149 nmg
->prcvars
[FEATURE_LIST
]->val
.l
[i
] + 3) == 0)){
1150 nmg
->prcfeats
[j
]->is_set
= 0;
1154 if(create_local
&& local_pinerc
){
1156 fprintf(nmg
->dfd
, "Removing %s\r\n", local_pinerc
);
1157 _unlink(local_pinerc
);
1160 fs_give((void **)&local_pinerc
);
1162 fprintf(nmg
->dfd
, "Current pinerc settings:\r\n");
1163 for(i
= 0; i
< varnum
; i
++){
1164 fprintf(nmg
->dfd
, "%s:", nmg
->prcvars
[i
]->var
);
1165 if(!nmg
->prcvars
[i
]->islist
)
1166 fprintf(nmg
->dfd
, " %s\r\n",
1167 nmg
->prcvars
[i
]->val
.p
? nmg
->prcvars
[i
]->val
.p
: " NOT DEFINED");
1169 if(!nmg
->prcvars
[i
]->val
.l
)
1170 fprintf(nmg
->dfd
, " NOT DEFINED\r\n");
1172 for(j
= 0; nmg
->prcvars
[i
]->val
.l
[j
]; j
++)
1173 fprintf(nmg
->dfd
, "\t%s\r\n",
1174 nmg
->prcvars
[i
]->val
.l
[j
]);
1182 void expand_env_vars(mapi_global_s
*nmg
)
1184 int i
, j
, check_reg
= 0, islist
;
1185 DWORD keyDataSize
= 1024, keyDataType
;
1186 char *p1
, *p2
, *p3
, keyData
[1024], *newstr
, **valstrp
;
1190 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
1191 "Software\\University of Washington\\Alpine\\1.0\\PmapiOpts\\Env",
1194 &hKey
) == ERROR_SUCCESS
)
1196 for(i
= 0; i
< NUMPRCVARS
; i
++){
1197 islist
= nmg
->prcvars
[i
]->islist
;
1198 for(j
= 0; islist
? (int)(nmg
->prcvars
[i
]->val
.l
&& nmg
->prcvars
[i
]->val
.l
[j
])
1200 valstrp
= islist
? &nmg
->prcvars
[i
]->val
.l
[j
] : &nmg
->prcvars
[i
]->val
.p
;
1201 if(*valstrp
== NULL
) continue;
1202 while((p1
= strstr(*valstrp
, "${")) && (p2
= strchr(p1
, '}'))){
1203 msprint1("%s -> ", *valstrp
);
1206 if((p3
= getenv(p1
+2)) && *p3
)
1208 else if(check_reg
&& (keyDataSize
= 1024)
1209 && (RegQueryValueEx(hKey
, p1
+2, 0, &keyDataType
,
1210 keyData
, &keyDataSize
) == ERROR_SUCCESS
)
1211 && keyDataType
== REG_SZ
)
1213 newstr
= (char *)fs_get(sizeof(char)*(strlen(*valstrp
)
1214 + strlen(p3
? p3
: "") + strlen(p2
+1) + 1));
1216 strcpy(newstr
, *valstrp
);
1217 strcat(newstr
, p3
&& *p3
? p3
: "");
1218 strcat(newstr
, p2
+ 1);
1219 fs_give((void **)valstrp
);
1221 msprint1(" %s\r\n", *valstrp
);
1229 void free_mapi_global(mapi_global_s
*nmg
)
1235 fs_give((void **)&nmg
->pineExe
);
1237 fs_give((void **)&nmg
->pineExeAlt
);
1239 fs_give((void **)&nmg
->pinerc
);
1241 fs_give((void **)&nmg
->pineconf
);
1243 fs_give((void **)&nmg
->pinercex
);
1245 fs_give((void **)&nmg
->fccfolder
);
1247 fs_give((void **)&nmg
->attachDir
);
1248 for(i
= 0; i
< NUMPRCFEATS
; i
++){
1249 if(nmg
->prcfeats
[i
]->var
)
1250 fs_give((void **)&nmg
->prcfeats
[i
]->var
);
1251 fs_give((void **)&nmg
->prcfeats
[i
]);
1253 for(i
= 0; i
< NUMPRCVARS
; i
++){
1254 if(nmg
->prcvars
[i
]->var
)
1255 fs_give((void **)&nmg
->prcvars
[i
]->var
);
1256 if(nmg
->prcvars
[i
]->islist
){
1257 if(nmg
->prcvars
[i
]->val
.l
){
1258 for(j
= 0; nmg
->prcvars
[i
]->val
.l
[j
]; j
++)
1259 fs_give((void **)&nmg
->prcvars
[i
]->val
.l
[j
]);
1260 fs_give((void **)&nmg
->prcvars
[i
]->val
.l
);
1264 if(nmg
->prcvars
[i
]->val
.p
)
1265 fs_give((void **)&nmg
->prcvars
[i
]->val
.p
);
1267 fs_give((void **)&nmg
->prcvars
[i
]);
1269 for(ts
= nmg
->sessionlist
; ts
;){
1271 ts
->open_stream
= mail_close_full(ts
->open_stream
, NIL
);
1272 ts
= free_sessionlist_node(ts
);
1275 fs_give((void **)&nmg
->debugFile
);
1276 if(nmg
->debug
&& nmg
->dfd
)
1279 fs_give((void **)&nmg
);
1282 MAILSTREAM
*first_open(sessionlist_s
*cs
)
1284 mapi_global_s
*nmg
= ms_global
;
1285 /* cs->mhwnd = (HWND)ulUIParam;
1286 * if(flFlags & MAPI_LOGON_UI)
1287 * cs->flags.mapi_logon_ui = TRUE;
1289 /* if someone is logging in right now, return failure */
1290 if(nmg
->cs
) return NULL
;
1292 fprintf(nmg
->dfd
, "Opening mailbox for the first time\r\n");
1293 if(nmg
->prcvars
[INBOX_PATH
]->val
.p
== NULL
){
1294 ErrorBox("No value set for %s!", "inbox");
1297 cs
->open_stream
= mapi_mail_open(cs
, cs
->open_stream
, nmg
->prcvars
[INBOX_PATH
]->val
.p
,
1298 nmg
->debug
? OP_DEBUG
: NIL
);
1299 /* cs->flags.mapi_logon_ui = FALSE; */
1300 if(cs
->open_stream
){
1301 if(cs
->currently_open
){
1302 fs_give((void **)&cs
->currently_open
);
1303 cs
->currently_open
= NULL
;
1305 cs
->currently_open
= mstrdup(nmg
->prcvars
[INBOX_PATH
]->val
.p
);
1307 mail_debug(cs
->open_stream
);
1309 fprintf(nmg
->dfd
, "returning SUCCESS_SUCCESS\r\n");
1312 return cs
->open_stream
;
1314 else if(cs
->flags
.dlg_cancel
){
1316 fprintf(nmg
->dfd
, "returning MAPI_E_FAILURE\r\n");
1322 cs
->dlge
.edit1
[0] = '\0';
1323 cs
->dlge
.edit2
[0] = '\0';
1324 if(cs
->currently_open
){
1325 fs_give((void **)&cs
->currently_open
);
1326 cs
->currently_open
= NULL
;
1329 fprintf(nmg
->dfd
, "returning MAPI_E_FAILURE\r\n");
1337 mapi_smtp_open(sessionlist_s
*cs
, char **servers
, long options
)
1339 mapi_global_s
*nmg
= ms_global
;
1340 SENDSTREAM
*newstream
;
1341 pw_cache_s
*tpwc
, *dpwc
;
1344 nmg
->tmpmbxptr
= NULL
;
1345 nmg
->cs
->flags
.dlg_cancel
= 0;
1346 newstream
= smtp_open(servers
, options
);
1348 nmg
->tmpmbxptr
= NULL
;
1350 if(newstream
){ /* if open stream, valid password */
1351 for(tpwc
= cs
->pwc
; tpwc
; tpwc
= tpwc
->next
)
1355 for(tpwc
= cs
->pwc
, dpwc
= NULL
; tpwc
; dpwc
= tpwc
, tpwc
= tpwc
->next
){
1356 if(tpwc
->validpw
== 0){
1358 cs
->pwc
= tpwc
->next
;
1360 dpwc
->next
= tpwc
->next
;
1361 fs_give((void **)&tpwc
);
1369 mapi_mail_open(sessionlist_s
*cs
, MAILSTREAM
*stream
, char *name
, long options
)
1371 MAILSTREAM
*newstream
;
1372 mapi_global_s
*nmg
= ms_global
;
1373 pw_cache_s
*tpwc
, *dpwc
;
1376 nmg
->tmpmbxptr
= name
;
1377 nmg
->cs
->flags
.dlg_cancel
= 0;
1378 newstream
= mail_open(stream
, name
, options
);
1379 nmg
->tmpmbxptr
= NULL
;
1382 if(newstream
){ /* if open stream, valid password */
1383 for(tpwc
= cs
->pwc
; tpwc
; tpwc
= tpwc
->next
)
1389 if(tpwc
->validpw
== 0){
1393 cs
->pwc
= dpwc
->next
;
1394 fs_give((void **)&dpwc
);
1405 MAILSTREAM
*check_mailstream(sessionlist_s
*cs
)
1411 if(!cs
->open_stream
){
1412 return(first_open(cs
));
1414 cs
->flags
.check_stream
= TRUE
;
1415 if(!mail_ping(cs
->open_stream
)){
1416 if(nmg
->cs
) return NULL
;
1417 cs
->open_stream
= mapi_mail_open(cs
, cs
->open_stream
,
1418 cs
->currently_open
? cs
->currently_open
:
1419 nmg
->prcvars
[INBOX_PATH
]->val
.p
,
1420 nmg
->debug
? OP_DEBUG
: NIL
);
1421 if(!cs
->open_stream
){
1422 fs_give((void **)&cs
->currently_open
);
1423 cs
->currently_open
= NULL
;
1424 cs
->dlge
.edit1
[0] = '\0';
1425 cs
->dlge
.edit2
[0] = '\0';
1426 cs
->flags
.check_stream
= FALSE
;
1430 cs
->flags
.check_stream
= FALSE
;
1431 return cs
->open_stream
;
1434 /* pretty much changes a string to an integer,
1435 * but if it is not a valid message number, then 0 is returned
1437 unsigned long convert_to_msgno(char *msgid
)
1439 unsigned long place_holder
= 1, msgno
= 0;
1442 len
= strlen(msgid
);
1443 for(i
= 0; i
< len
; i
++){
1444 if(msgid
[len
-1-i
] - '0' < 0 || msgid
[len
-1-i
] - '0' > 9)
1446 msgno
+= (msgid
[len
- 1 - i
] - '0')*place_holder
;
1454 * Lookup file's mimetype by its file extension
1456 * body - body in which to store new type, subtype
1458 * A mime type is ALWAYS set
1460 * Returns 0 if the file extension was found and mimetype was set accordingly
1463 int lookup_file_mime_type(char *fn
, BODY
*body
)
1465 char *p
, subkey
[1024], val
[1024];
1466 DWORD dtype
, vallen
= 1024;
1471 fs_give((void **)&body
->subtype
);
1472 if((p
= strrchr(fn
, '.')) && p
[1]){
1473 sprintf(subkey
, "%.1020s", p
);
1474 if(RegOpenKeyEx(HKEY_CLASSES_ROOT
, subkey
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
){
1475 if(RegQueryValueEx(hKey
, "Content Type", NULL
, &dtype
, val
, &vallen
) == ERROR_SUCCESS
){
1477 if((p
= strrchr(val
, '/')) && p
[1]){
1479 body
->subtype
= mstrdup(p
);
1480 for(i
=0; (i
<= TYPEMAX
) && body_types
[i
] && _stricmp(val
, body_types
[i
]); i
++);
1483 else if(!body_types
[i
])
1484 body_types
[i
] = mstrdup(val
);
1491 body
->type
= TYPEAPPLICATION
;
1492 body
->subtype
= "octet-stream";
1496 int LookupMIMEFileExt(char *val
, char *mime_type
, DWORD
*vallen
)
1500 LONG rv
= !ERROR_SUCCESS
;
1503 sprintf(subkey
, "MIME\\Database\\Content Type\\%s", mime_type
);
1504 if(RegOpenKeyEx(HKEY_CLASSES_ROOT
, subkey
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
){
1505 rv
= RegQueryValueEx(hKey
,"extension",NULL
, &dtype
, val
, vallen
);
1513 * xlate_out() - xlate_out the given character
1522 if((c
>= FIRSTCH
) && (c
<= LASTCH
)){
1523 xch
= c
- (dti
= xlate_key
);
1524 xch
+= (xch
< FIRSTCH
-TABSZ
) ? 2*TABSZ
: (xch
< FIRSTCH
) ? TABSZ
: 0;
1525 dti
= (xch
- FIRSTCH
) + dti
;
1526 dti
-= (dti
>= 2*TABSZ
) ? 2*TABSZ
: (dti
>= TABSZ
) ? TABSZ
: 0;
1534 /* return TRUE if the pwd is found, FALSE if not */
1535 int in_passfile(sessionlist_s
*cs
)
1538 char *tf
, *tp
, *ui
[4], tmp
[1024], *dir
;
1544 if(*nmg
->pinerc
== '{')
1549 /* if(nmg->flags.passfile_checked) return FALSE; */
1550 if(!(tf
= (char *)fs_get(sizeof(char)*(strlen(dir
) + strlen("pine.pwd") + 1)))){
1551 /* nmg->flags.passfile_checked = TRUE; */
1555 if(tp
= strrchr(tf
, '\\')){
1557 strcpy(tp
, "pine.pwd");
1559 else /* don't know when this will ever happen */
1560 strcpy(tf
, "pine.pwd");
1561 if(_access(tf
, 00) == 0){
1563 fprintf(nmg
->dfd
,"found %s for passwords\r\n", tf
);
1564 if(!(tfd
= fopen(tf
,"r"))){
1565 fs_give((void **)&tf
);
1566 /* nmg->flags.passfile_checked = TRUE; */
1570 for(n
= 0; fgets(tmp
, 1024, tfd
); n
++){
1571 /*** do any necessary DEcryption here ***/
1573 for(i
= 0; tmp
[i
]; i
++)
1574 tmp
[i
] = xlate_out(tmp
[i
]);
1576 if(i
&& tmp
[i
-1] == '\n')
1577 tmp
[i
-1] = '\0'; /* blast '\n' */
1579 ui
[0] = ui
[1] = ui
[2] = ui
[3] = NULL
;
1580 for(i
= 0, j
= 0; tmp
[i
] && j
< 4; j
++){
1581 for(ui
[j
] = &tmp
[i
]; tmp
[i
] && tmp
[i
] != '\t'; i
++)
1588 if(ui
[0] && ui
[1] && ui
[2]){
1589 if(strcmp(ui
[2], cs
->mb
->host
) == 0){
1590 if((cs
->mb
->altflag
&& ui
[3] && *ui
[3] == '1')
1591 || (!cs
->mb
->altflag
&& (!ui
[3] || (*ui
[3] == '0')))){
1592 if(strcmp(ui
[1], *cs
->mb
->user
? cs
->mb
->user
1593 : nmg
->prcvars
[USER_ID
]->val
.p
) == 0){
1595 strcpy(cs
->dlge
.edit1
, *cs
->mb
->user
? cs
->mb
->user
1596 : nmg
->prcvars
[USER_ID
]->val
.p
);
1597 strcpy(cs
->dlge
.edit2
, ui
[0]);
1599 fs_give((void **)&tf
);
1600 /* nmg->flags.passfile_checked = TRUE; */
1608 fs_give((void **)&tf
);
1612 fs_give((void **)&tf
);
1613 /* nmg->flags.passfile_checked = TRUE; */
1616 /* nmg->flags.passfile_checked = TRUE; */
1620 int get_suggested_directory(char *dir
)
1624 if(tmpdir
= getenv("TEMP")){
1625 strcpy(dir
, tmpdir
);
1628 else if(tmpdir
= getenv("TMP")){
1629 strcpy(dir
, tmpdir
);
1632 else if(ms_global
&& ms_global
->attachDir
){
1633 strcpy(dir
, ms_global
->attachDir
);
1636 else{ /* should NEVER get here */
1637 strcpy(dir
, "C:\\");
1644 /* return TRUE if file_ext is modified, FALSE if not */
1645 int get_suggested_file_ext(char *file_ext
, PART
*part
, DWORD
*file_extlen
)
1647 char mime_type
[1024], *tmp_ext
;
1648 int rv
= !ERROR_SUCCESS
;
1651 if(part
->body
.subtype
){
1652 sprintf(mime_type
, "%s/%s", body_types
[part
->body
.type
], part
->body
.subtype
);
1653 rv
= LookupMIMEFileExt(file_ext
, mime_type
, file_extlen
);
1655 if(rv
== ERROR_SUCCESS
)
1658 param
= part
->body
.parameter
;
1659 while(param
&& (_stricmp("NAME", param
->attribute
)))
1660 param
= param
->next
;
1662 if(part
->body
.type
== TYPEMESSAGE
){
1663 /* don't try to recurse through attached messages yet */
1664 strcpy(file_ext
, ".txt");
1668 tmp_ext
= strrchr(param
->value
, (int)'.');
1669 if(!tmp_ext
) return FALSE
;
1670 strcpy(file_ext
, tmp_ext
);
1675 /* return -1 for failure */
1681 if((ms_global
= new_mapi_global()) == NULL
) return -1;
1684 * if debug file exists, turn on debugging mode
1686 if(ms_global
->debug
== 1) /* debug file already initialized, somehow */
1688 get_suggested_directory(path
);
1689 if(path
[strlen(path
-1)] != '\\')
1691 strcat(path
, "mapi_debug.txt");
1692 if(_access(path
, 00) == 0){
1693 ms_global
->debug
= 1;
1696 get_suggested_directory(path
);
1697 if(path
[strlen(path
-1)] != '\\')
1699 strcat(path
, "mapisend");
1700 if(_access(path
, 00) == 0){
1701 ms_global
->debug
= 1;
1705 if(ms_global
->debug
){
1706 ms_global
->dfd
= fopen(path
, "wb");
1707 if(!ms_global
->dfd
){
1708 ErrorBox("MAPISendMail: debug off: can't open debug file %.200s",
1710 ms_global
->debug
= 0; /* can't open the file, turn off debugging */
1712 else if(ms_global
->debug
== 1){
1713 ms_global
->debugFile
= (char *)fs_get((1+strlen(path
))*sizeof(char));
1714 strcpy(ms_global
->debugFile
, path
);
1718 if(ms_global
->debug
&& (ms_global
->dfd
== NULL
))
1719 ms_global
->debug
= 0;
1721 return ms_global
->debug
;
1727 BYTE pineKeyData
[1024];
1728 DWORD pineKeyDataSize
;
1729 DWORD pineKeyDataType
;
1730 char *defPath
= "c:\\pine\\pine.exe";
1731 char *pineExe
= strrchr(defPath
, '\\')+1;
1732 char *freepineExe
= NULL
;
1733 char *defAttachDir
= "c:\\tmp";
1737 * get name of and path to pine.exe from registry
1741 "SOFTWARE\\University of Washington\\Alpine\\1.0",
1744 &pineKey
) == ERROR_SUCCESS
) {
1745 pineKeyDataSize
= sizeof(pineKeyData
);
1746 if (RegQueryValueEx(
1752 &pineKeyDataSize
) == ERROR_SUCCESS
) {
1753 freepineExe
= (char *)fs_get((pineKeyDataSize
+ 1) * sizeof(char));
1754 if ((pineExe
= freepineExe
) != NULL
) {
1755 strcpy(pineExe
, pineKeyData
);
1758 ErrorBox("MAPISendMail: can't fs_get %d bytes for pineExe",
1763 fprintf(ms_global
->dfd
,"pine.exe pineKeyDataSize: %d\r\n", pineKeyDataSize
);
1764 fprintf(ms_global
->dfd
,"pine.exe pineKeyData: %s\r\n", pineKeyData
);
1767 pineKeyDataSize
= sizeof(pineKeyData
);
1768 if (RegQueryValueEx(
1774 &pineKeyDataSize
) == ERROR_SUCCESS
) {
1775 ms_global
->pineExe
= (char *)fs_get(sizeof(char)*(pineKeyDataSize
+strlen(pineExe
)));
1776 if (ms_global
->pineExe
) {
1777 strncpy(ms_global
->pineExe
, pineKeyData
, pineKeyDataSize
);
1778 strcat(ms_global
->pineExe
, pineExe
);
1781 ErrorBox("MAPISendMail: can't fs_get %d bytes for av[0]",
1786 fprintf(ms_global
->dfd
,"pine.exe pineKeyDataSize: %d\r\n", pineKeyDataSize
);
1787 fprintf(ms_global
->dfd
,"pine.exe pineKeyData: %s\r\n", pineKeyData
);
1790 RegCloseKey(pineKey
);
1792 if(!ms_global
->pineExe
){
1793 ms_global
->pineExe
= (char *)fs_get((1+strlen(defPath
))*sizeof(char));
1794 if(!ms_global
->pineExe
){
1795 ErrorBox("Couldn't fs_get for %s","pineExe");
1799 strcpy(ms_global
->pineExe
, defPath
);
1803 ms_global
->pineExeAlt
= freepineExe
;
1805 ms_global
->pineExeAlt
= (char *)fs_get((strlen(strrchr(defPath
, '\\')+1)+1)*sizeof(char));
1806 if(!ms_global
->pineExeAlt
){
1807 ErrorBox("Couldn't fs_get for %s","pineExeAlt");
1811 strcpy(ms_global
->pineExeAlt
, strrchr(defPath
, '\\')+1);
1815 * get path to pinerc from registry
1819 "Software\\University of Washington\\Alpine\\1.0",
1822 &pineKey
) == ERROR_SUCCESS
) {
1823 pineKeyDataSize
= sizeof(pineKeyData
);
1824 if( RegQueryValueEx(
1830 &pineKeyDataSize
) == ERROR_SUCCESS
) {
1831 if(*pineKeyData
!= '{' || ms_global
->pineExe
)
1832 ms_global
->attachDir
= (char *)fs_get(sizeof(char)*(*pineKeyData
== '{' ?
1833 pineKeyDataSize
+ 1 :
1834 strlen(ms_global
->pineExe
)+1));
1835 ms_global
->pinerc
= (char *)fs_get(pineKeyDataSize
);
1836 if(ms_global
->attachDir
){
1838 if(*pineKeyData
!= '{'){
1839 strncpy(ms_global
->attachDir
, pineKeyData
, pineKeyDataSize
);
1840 ms_global
->attachDir
[pineKeyDataSize
] = '\0';
1843 strcpy(ms_global
->attachDir
, ms_global
->pineExe
);
1844 p
= strrchr(ms_global
->attachDir
, '\\');
1847 if(ms_global
->pinerc
)
1848 strncpy(ms_global
->pinerc
, pineKeyData
, pineKeyDataSize
);
1850 ErrorBox("MAPISendMail: can't fs_get %d bytes for pinercPath",
1855 fprintf(ms_global
->dfd
, "pinerc pineKeyDataSize: %d\r\n", pineKeyDataSize
);
1856 fprintf(ms_global
->dfd
, "pinerc pineKeyData: %s\r\n", pineKeyData
);
1857 fprintf(ms_global
->dfd
, "attachDir: %s\r\n",
1858 ms_global
->attachDir
? ms_global
->attachDir
:
1862 pineKeyDataSize
= sizeof(pineKeyData
);
1863 if( RegQueryValueEx(
1869 &pineKeyDataSize
) == ERROR_SUCCESS
){
1870 ms_global
->pineconf
= mstrdup(pineKeyData
);
1871 msprint1("ms_global->pineconf: %s (due to Registry setting)\r\n", ms_global
->pineconf
);
1873 RegCloseKey(pineKey
);
1876 if(ms_global
->attachDir
== NULL
){
1877 if(ms_global
->attachDir
= (char *)fs_get((strlen(defAttachDir
)+1)*sizeof(char)))
1878 strcpy(ms_global
->attachDir
, defAttachDir
);
1880 ErrorBox("Can't find TEMP directory for %s!","attachments");
1884 if(penv
= getenv("PINERC")){
1885 if(ms_global
->pinerc
)
1886 fs_give((void **)&ms_global
->pinerc
);
1887 if(ms_global
->pinerc
= (char *)fs_get((strlen(penv
)+1)*sizeof(char)))
1888 strcpy(ms_global
->pinerc
, penv
);
1890 ErrorBox("Couldn't fs_get for %s", "pinerc");
1892 if(penv
= getenv("PINECONF")){
1893 if(ms_global
->pineconf
)
1894 fs_give((void **)&ms_global
->pineconf
);
1895 if(ms_global
->pineconf
= (char *)fs_get((strlen(penv
)+1)*sizeof(char)))
1896 strcpy(ms_global
->pineconf
, penv
);
1898 ErrorBox("Couldn't fs_get for %s", "pineconf");
1903 if(penv
= getenv("PINERCEX")){
1904 if(ms_global
->pinercex
)
1905 fs_give((void **)&ms_global
->pinercex
);
1906 if(ms_global
->pinercex
= mstrdup(penv
))
1907 strcpy(ms_global
->pinercex
, penv
);
1909 ErrorBox("Couldn't fs_get for %s", "pinercex");
1912 fprintf(ms_global
->dfd
,"ms_global->pineExe: %s\r\n",
1913 (ms_global
->pineExe
) ? ms_global
->pineExe
: "NULL");
1914 fprintf(ms_global
->dfd
,"ms_global->pineExeAlt: %s\r\n",
1915 ms_global
->pineExeAlt
? ms_global
->pineExeAlt
: "NULL");
1916 fprintf(ms_global
->dfd
,"ms_global->attachDir: %s\r\n",
1917 ms_global
->attachDir
? ms_global
->attachDir
: "NULL");
1918 fprintf(ms_global
->dfd
,"ms_global->pinerc: %s\r\n",
1919 ms_global
->pinerc
? ms_global
->pinerc
: "NULL");
1920 fprintf(ms_global
->dfd
,"ms_global->pineconf: %s\r\n",
1921 ms_global
->pinerc
? ms_global
->pineconf
: "NULL");
1922 fprintf(ms_global
->dfd
,"ms_global->pinercex: %s\r\n",
1923 ms_global
->pinerc
? ms_global
->pinercex
: "NULL");
1928 BOOL APIENTRY
DllMain(
1930 DWORD ul_reason_being_called
,
1933 switch(ul_reason_being_called
){
1934 case DLL_THREAD_ATTACH
:
1938 case DLL_PROCESS_ATTACH
:
1940 ms_global
= new_mapi_global();
1941 if(!ms_global
) return 0;
1942 ms_global
->attached
++;
1943 ms_global
->mhinst
= hInst
;
1944 if(InitDebug() == -1){
1945 ErrorBox("Mapi32.dll could not %s", "initialize");
1948 if(MSDEBUG
&& ms_global
->attached
<= 1){
1951 extern char datestamp
[], hoststamp
[];
1953 now
= time((time_t *)0);
1954 tm_now
= localtime(&now
);
1955 fprintf(ms_global
->dfd
, "pmapi32.dll for Alpine Version 2.26\r\n");
1956 fprintf(ms_global
->dfd
, " Build date: %s\r\n", datestamp
);
1957 fprintf(ms_global
->dfd
,
1958 " please report all bugs to chappa@gmx.com\r\n");
1960 fprintf(ms_global
->dfd
,
1961 "Created: %2.2d:%2.2d:%2.2d %d/%d/%d\r\n",
1962 tm_now
->tm_hour
, tm_now
->tm_min
, tm_now
->tm_sec
,
1963 tm_now
->tm_mon
+1, tm_now
->tm_mday
, tm_now
->tm_year
+1900);
1965 fprintf(ms_global
->dfd
, "\r\n\r\n");
1967 DEBUG_WRITE("%s called. Debug initialized (in DllMain)\r\n",
1968 ul_reason_being_called
== DLL_PROCESS_ATTACH
?
1969 "DLL_PROCESS_ATTACH":"DLL_THREAD_ATTACH");
1971 #include "../c-client-dll/linkage.c"
1973 case DLL_PROCESS_DETACH
:
1974 case DLL_THREAD_DETACH
:
1975 DEBUG_WRITE("\r\n%s called\r\n",
1976 ul_reason_being_called
== DLL_PROCESS_DETACH
?
1977 "DLL_PROCESS_DETACH" : "DLL_THREAD_DETACH");
1978 ms_global
->attached
--;
1979 /* if(ms_global->open_stream)
1980 * ms_global->open_stream = mail_close_full(ms_global->open_stream, NIL);
1982 if(ms_global
->attached
<= 0 &&
1983 ul_reason_being_called
== DLL_PROCESS_DETACH
){
1985 fprintf(ms_global
->dfd
,
1986 "detaching last thread/process. freeing mapi global struct\r\n");
1987 free_mapi_global(ms_global
);
1994 static char *V
="\r\n@(#) Alpine Simple Mapi Library Ver. 1.3\r\n";
1997 UnderlineSpace(char *s
)
2001 if(p
= strrchr(s
, '\\'))
2011 * Given source file name and destination directory, make a binary copy
2012 * of the file and return the full name of the copy (mangled as necessary
2013 * to avoid conflicts). The return value will be a fs_get'd string
2016 TmpCopy(char *srcFile
, int is_pinerc
)
2018 char *dstName
; /* constructed and fs_get'd full output pathname */
2019 char *srcTail
; /* last component of source pathname */
2020 char *srcExt
; /* extension, if any, of srcTail */
2022 int i
, cnt
, c
, len
, spc
= 0;
2026 ErrorBox("TmpCopy: srcFile is %s", "NULL");
2030 len
= strlen(srcFile
);
2031 for(i
= 0; i
< len
; i
++){
2032 if(srcFile
[i
] == ' ') spc
= 1;
2034 if(spc
== 0) return mstrdup(srcFile
);
2037 get_suggested_directory(dstDir
);
2039 ErrorBox("TmpCopy: dstDir is %s", "NULL");
2043 dstName
= (char *)fs_get(sizeof(char)*(strlen(srcFile
) + 5 +
2044 max(strlen(dstDir
), strlen(PINERC_FILE
))));
2046 if (dstName
== NULL
) {
2047 ErrorBox("TmpCopy: can't fs_get space %d bytes for dstName",
2048 strlen(srcFile
)+5+max(strlen(dstDir
),strlen(PINERC_FILE
)));
2053 srcTail
= strrchr(srcFile
, '\\');
2059 srcExt
= strrchr(srcTail
, '.');
2061 sfd
= fopen(srcFile
, "rb");
2063 ErrorBox("TmpCopy: can't open %.200s for reading", srcFile
);
2064 fs_give((void **)&dstName
);
2068 i
= sprintf(dstName
, "%s%s%s", dstDir
,
2069 dstDir
[strlen(dstDir
)-1] == '\\' ? "" : "\\",
2071 UnderlineSpace(dstName
);
2072 for (cnt
= 0; cnt
< 1000; ++cnt
) {
2073 int handle
= _open(dstName
, _O_CREAT
|_O_EXCL
, _S_IREAD
|_S_IWRITE
);
2075 if (_close(handle
)) /* this shouldn't be able to happen */
2076 ErrorBox("TmpCopy: _close of new %.200s failed", dstName
);
2077 dfd
= fopen(dstName
, "wb");
2081 sprintf(dstName
+i
-strlen(srcExt
), "%03d%s", cnt
, srcExt
);
2083 sprintf(dstName
+i
, "%03d", cnt
);
2086 ErrorBox("TmpCopy: can't create anything like %.200s", dstName
);
2088 fs_give((void **)&dstName
);
2092 else{ /* is_pinerc */
2093 i
= sprintf(dstName
, "%s%s%s", dstDir
,
2094 dstDir
[strlen(dstDir
)-1] == '\\' ? "" : "\\",
2096 dfd
= fopen(dstName
, "wb");
2098 ErrorBox("Couldn't create temp %s for pine", "pinerc");
2099 fs_give((void **)&dstName
);
2102 sfd
= fopen(srcFile
, "rb");
2104 ErrorBox("TmpCopy: can't open %.200s for reading", srcFile
);
2106 fs_give((void **)&dstName
);
2111 while(feof(sfd
) == 0) {
2116 ErrorBox("TmpCopy: write error on %.200s", dstName
);
2117 fs_give((void **)&dstName
);
2122 ErrorBox("TmpCopy: read error on %.200s", srcFile
);
2123 fs_give((void **)&dstName
);
2128 ErrorBox("TmpCopy: fclose error on %.200s", srcFile
);
2131 ErrorBox("TmpCopy: fclose error on %.200s", dstName
);
2137 int send_documents(char *files
, char sep
)
2139 int ac
, i
, tmplen
, j
;
2140 char **av
, *tmpfiles
, *file
, *tmpfree
;
2145 tmplen
= strlen(files
);
2146 tmpfiles
= (char *)fs_get(sizeof(char)*(tmplen
+ 1));
2147 strcpy(tmpfiles
,files
);
2148 for(i
= 0; i
<= tmplen
; i
++){
2149 if(files
[i
] == sep
|| files
[i
] == '\0')
2152 ac
+= 2; /* just for safe measure */
2153 av
= (char **)fs_get(ac
* sizeof(char *));
2155 av
[1] = mstrdup("-p");
2156 /* copy pinerc to temp directory just in case it too
2157 * has spaces in its directory
2159 if(tmpfree
= TmpCopy(nmg
->pinerc
, IS_PINERC
)){
2160 av
[2] = quote(tmpfree
);
2161 fs_give((void **)&tmpfree
);
2164 av
[2] = quote(nmg
->pinerc
);
2166 for(i
= 0, j
= 3, file
= tmpfiles
; i
<= tmplen
; i
++){
2167 if(tmpfiles
[i
] == sep
|| i
== tmplen
){
2169 if(i
- (file
- tmpfiles
) > 1){
2170 tmpfree
= TmpCopy(file
, NOT_PINERC
);
2172 av
[j
++] = mstrdup("-attach_and_delete");
2173 av
[j
++] = quote(tmpfree
);
2174 fs_give((void **)&tmpfree
);
2180 av
[0] = quote(nmg
->pineExe
);
2182 fprintf(ms_global
->dfd
, "spawning %s (else %s):\r\n",
2183 ms_global
->pineExe
, ms_global
->pineExeAlt
);
2184 fprintf(nmg
->dfd
, " av:\r\n");
2185 for(i
= 0; av
[i
]; i
++)
2186 fprintf(nmg
->dfd
, " av[%d]: %s\r\n", i
, av
[i
]);
2189 /* clean up quote()'s */
2190 if (_spawnvp(_P_NOWAIT
, ms_global
->pineExe
, av
) == -1 &&
2191 _spawnvp(_P_NOWAIT
, ms_global
->pineExeAlt
, av
) == -1){
2192 ErrorBox("MAPISendMail: _spawnvp of %s failed", ms_global
->pineExe
);
2194 fprintf(ms_global
->dfd
, "_spawnvp %s and %s failed\r\n",
2195 ms_global
->pineExe
,ms_global
->pineExeAlt
);
2196 return(MAPI_E_FAILURE
);
2198 for(i
= 0; av
[i
]; i
++)
2199 fs_give((void **)&av
[i
]);
2200 fs_give((void **)&av
);
2201 return SUCCESS_SUCCESS
;
2205 message_structure_to_mailto_url(lpMapiMessage lpm
)
2207 char **keyvals
, **keyvalp
, *url
;
2209 unsigned long i
, url_len
= 0;
2214 keyvallen
= lpm
->nRecipCount
+ 4; /* subject + body + from + recips + NULL */
2215 keyvals
= (char **)fs_get(keyvallen
* sizeof(char *));
2218 for(i
= 0; i
< lpm
->nRecipCount
; i
++)
2219 *keyvalp
++ = encode_mailto_addr_keyval(&lpm
->lpRecips
[i
]);
2220 if(lpm
->lpszSubject
)
2221 *keyvalp
++ = encode_mailto_keyval("subject", lpm
->lpszSubject
);
2222 if(lpm
->lpOriginator
)
2223 *keyvalp
++ = encode_mailto_addr_keyval(lpm
->lpOriginator
);
2224 if(lpm
->lpszNoteText
)
2225 *keyvalp
++ = encode_mailto_keyval("body", lpm
->lpszNoteText
);
2228 if(*keyvals
== NULL
){
2229 fs_give((void **)&keyvals
);
2233 url_len
= keyvallen
+ 10; /* mailto url extra chars */
2234 for(keyvalp
= keyvals
; *keyvalp
; keyvalp
++)
2235 url_len
+= strlen(*keyvalp
);
2237 url
= (char *)fs_get(url_len
* sizeof(char));
2238 sprintf(url
, "mailto:?");
2239 for(keyvalp
= keyvals
; *keyvalp
; keyvalp
++){
2240 strcat(url
, *keyvalp
);
2243 fs_give((void **)&(*keyvalp
));
2245 fs_give((void **)&keyvals
);
2250 encode_mailto_addr_keyval(lpMapiRecipDesc lpmr
)
2252 ADDRESS
*adr
= NULL
;
2253 char *addr
, *retstr
;
2256 adr
= mapirecip2address(lpmr
);
2257 addr
= (char *)fs_get((size_t)est_size(adr
));
2259 rfc822_write_address(addr
, adr
);
2260 mail_free_address(&adr
);
2262 retstr
= encode_mailto_keyval(lpmr
->ulRecipClass
== MAPI_CC
? "cc"
2263 : (lpmr
->ulRecipClass
== MAPI_BCC
? "bcc"
2264 : (lpmr
->ulRecipClass
== MAPI_ORIG
? "from"
2267 fs_give((void **)&addr
);
2274 * Hex conversion aids from alpine.h
2276 #define HEX_ARRAY "0123456789ABCDEF"
2277 #define HEX_CHAR1(C) HEX_ARRAY[((C) & 0xf0) >> 4]
2278 #define HEX_CHAR2(C) HEX_ARRAY[(C) & 0xf]
2280 /* strings.c macros */
2281 #define C2XPAIR(C, S) { \
2282 *(S)++ = HEX_CHAR1(C); \
2283 *(S)++ = HEX_CHAR2(C); \
2286 #define RFC1738_SAFE "$-_.+" /* "safe" */
2287 #define RFC1738_EXTRA "!*'()," /* "extra" */
2289 /* adapted from rfc1738_encode_mailto */
2291 encode_mailto_keyval(char *key
, char* val
)
2293 char *d
, *ret
= NULL
, *v
= val
;
2296 ret
= (char *)fs_get(sizeof(char) * (strlen(key
) + (3*strlen(val
)) + 2));
2298 d
= ret
+ strlen(key
);
2301 if(isalnum((unsigned char)*v
)
2302 || strchr(RFC1738_SAFE
, *v
)
2303 || strchr(RFC1738_EXTRA
, *v
))
2318 send_msg_nodlg(LHANDLE lhSession
, ULONG ulUIParam
, lpMapiMessage lpMessage
,
2319 FLAGS flFlags
, ULONG ulReserved
)
2322 int tsession
= 0, orig_in_recip
= 0;
2323 unsigned long i
, orig_index
;
2324 ADDRESS
*tadr
= NULL
, *tadr2
= NULL
;
2325 ENVELOPE
*env
= NULL
;
2327 mapi_global_s
*nmg
= ms_global
;
2328 SENDSTREAM
*sending_stream
= NULL
;
2334 if(nmg
->pmapi_send_behavior
== PMSB_NEVER_SEND
)
2335 return MAPI_E_USER_ABORT
;
2336 else if(nmg
->pmapi_send_behavior
== PMSB_ALWAYS_PROMPT
){
2337 if(MessageBox(NULL
, "Really Send Message?", "pmapi32.dll", MB_YESNO
|MB_ICONQUESTION
) == IDNO
)
2338 return MAPI_E_USER_ABORT
;
2340 if((flFlags
& MAPI_NEW_SESSION
) || lhSession
== 0){
2341 cs
= new_sessionlist();
2345 cs
= get_session(lhSession
);
2347 return MAPI_E_INVALID_SESSION
;
2349 cs
->flags
.mapi_logon_ui
= (flFlags
& MAPI_LOGON_UI
) || (flFlags
& MAPI_DIALOG
) ? 1 : 0;
2350 if(InitPineSpecific(cs
) == -1){
2351 rv
= MAPI_E_LOGIN_FAILURE
;
2354 msprint("Preparing to Send Message with no dialogs...\r\n");
2355 /* Make an envelope */
2356 env
= (ENVELOPE
*)fs_get(sizeof(ENVELOPE
));
2357 memset(env
, 0, sizeof(ENVELOPE
));
2358 if(lpMessage
->lpszSubject
){
2359 p
= rfc1522_encode(tmp_20k_buf
, SIZEOF_20KBUF
, lpMessage
->lpszSubject
,
2360 nmg
->prcvars
[CHARACTER_SET
]->val
.p
);
2361 env
->subject
= mstrdup(p
);
2363 fprintf(ms_global
->dfd
, " Subject: %s\r\n", env
->subject
);
2366 * Since it is "DateReceived", I think the right thing to do is ignore it,
2367 * since we're sending, not receiving.
2369 rfc822_date(tmp_20k_buf
);
2370 env
->date
= mstrdup(tmp_20k_buf
);
2371 msprint1(" Date: %s\r\n", env
->date
);
2372 env
->message_id
= pmapi_generate_message_id();
2373 msprint1(" Message-Id: %s\r\n", env
->message_id
);
2375 for(i
= 0; i
< lpMessage
->nRecipCount
; i
++){
2376 if((&lpMessage
->lpRecips
[i
])->ulRecipClass
== MAPI_ORIG
){
2382 if(lpMessage
->lpOriginator
|| orig_in_recip
){
2383 if((env
->from
= mapirecip2address(lpMessage
->lpOriginator
2384 ? lpMessage
->lpOriginator
2385 : (&lpMessage
->lpRecips
[orig_index
])))
2387 rv
= MAPI_E_INVALID_RECIPS
;
2391 sprintf(tmp_20k_buf
, "%.100s <%.100s@%.100s>", env
->from
->personal
? env
->from
->personal
2392 : "", env
->from
->mailbox
? env
->from
->mailbox
: "",
2393 env
->from
->host
? env
->from
->host
: "");
2394 msprint1("From: %s\r\n", tmp_20k_buf
);
2397 else if(nmg
->prcvars
[USER_ID
]->val
.p
&& nmg
->prcvars
[USER_DOMAIN
]->val
.p
){
2399 * judgment call: I guess we'll try to generate the from header if it's not
2402 env
->from
= mail_newaddr();
2403 if(nmg
->prcvars
[PERSONAL_NAME
]->val
.p
){
2404 p
= rfc1522_encode(tmp_20k_buf
, SIZEOF_20KBUF
, nmg
->prcvars
[PERSONAL_NAME
]->val
.p
,
2405 nmg
->prcvars
[CHARACTER_SET
]->val
.p
);
2406 env
->from
->personal
= mstrdup(p
);
2408 env
->from
->mailbox
= mstrdup(nmg
->prcvars
[USER_ID
]->val
.p
);
2409 env
->from
->host
= mstrdup(nmg
->prcvars
[USER_DOMAIN
]->val
.p
);
2411 sprintf(tmp_20k_buf
, "%.100s <%.100s@%.100s>", env
->from
->personal
? env
->from
->personal
2412 : "", env
->from
->mailbox
? env
->from
->mailbox
: "",
2413 env
->from
->host
? env
->from
->host
: "");
2414 msprint1("From: %s\r\n", tmp_20k_buf
);
2417 for(i
= 0; i
< lpMessage
->nRecipCount
; i
++){
2418 if((tadr
= mapirecip2address(&lpMessage
->lpRecips
[i
])) == NULL
){
2419 rv
= MAPI_E_INVALID_RECIPS
;
2422 switch (lpMessage
->lpRecips
[i
].ulRecipClass
) {
2428 for(tadr2
= env
->to
; tadr2
->next
; tadr2
= tadr2
->next
);
2437 for(tadr2
= env
->cc
; tadr2
->next
; tadr2
= tadr2
->next
);
2446 for(tadr2
= env
->bcc
; tadr2
->next
; tadr2
= tadr2
->next
);
2452 rv
= MAPI_E_INVALID_RECIPS
;
2457 sprintf(tmp_20k_buf
, "%.100s <%.100s@%.100s>", tadr
->personal
? tadr
->personal
2458 : "", tadr
->mailbox
? tadr
->mailbox
: "",
2459 tadr
->host
? tadr
->host
: "");
2460 msprint1("%s\r\n", tmp_20k_buf
);
2463 /* Now we have an envelope, let's make us a body */
2464 if(lpMessage
->lpszNoteText
== NULL
)
2465 msprint("Empty Message Text\r\n");
2466 body
= mail_newbody();
2467 if(lpMessage
->nFileCount
){
2470 unsigned long fsize
, n
;
2474 msprint1("Number of files to be Attached: %d\r\n", (void *)lpMessage
->nFileCount
);
2475 body
->type
= TYPEMULTIPART
;
2476 body
->nested
.part
= mail_newbody_part();
2477 p
= body
->nested
.part
;
2478 set_text_data(&p
->body
, lpMessage
->lpszNoteText
? lpMessage
->lpszNoteText
2481 for(i
= 0; i
< lpMessage
->nFileCount
; i
++){
2482 p
->next
= mail_newbody_part();
2484 p
->body
.encoding
= ENCBINARY
;
2485 if(lpMessage
->lpFiles
[i
].lpszPathName
== NULL
)
2486 return(MAPI_E_FAILURE
);
2487 if(lpMessage
->lpFiles
[i
].lpszFileName
== NULL
2488 || lpMessage
->lpFiles
[i
].lpszFileName
[0] == '\0'){
2489 fn
= strrchr(lpMessage
->lpFiles
[i
].lpszPathName
, '\\');
2491 fn
= lpMessage
->lpFiles
[i
].lpszPathName
;
2496 fn
= lpMessage
->lpFiles
[i
].lpszFileName
;
2497 if(lookup_file_mime_type(fn
, &p
->body
) && (fn
== lpMessage
->lpFiles
[i
].lpszFileName
))
2498 lookup_file_mime_type(lpMessage
->lpFiles
[i
].lpszPathName
, &p
->body
);
2499 msprint1(" Attaching file %s;", lpMessage
->lpFiles
[i
].lpszPathName
);
2500 if(_stat(lpMessage
->lpFiles
[i
].lpszPathName
, &sbuf
))
2501 return(MAPI_E_FAILURE
);
2502 fsize
= sbuf
.st_size
;
2503 if((sfd
= fopen(lpMessage
->lpFiles
[i
].lpszPathName
, "rb")) == NULL
)
2504 return(MAPI_E_FAILURE
);
2505 p
->body
.contents
.text
.data
= fs_get((fsize
+1)*sizeof(char));
2508 while(feof(sfd
) == 0){
2509 p
->body
.contents
.text
.data
[n
++] = c
;
2512 fs_resize((void **)&p
->body
.contents
.text
.data
, (fsize
+1)*sizeof(char));
2517 p
->body
.contents
.text
.data
[n
] = '\0';
2518 p
->body
.contents
.text
.size
= n
;
2519 msprint1(" File size: %d\r\n", (void *)n
);
2521 p
->body
.parameter
= mail_newbody_parameter();
2522 p
->body
.parameter
->attribute
= mstrdup("name");
2523 p
->body
.parameter
->value
= mstrdup(fn
);
2525 p
->body
.disposition
.type
= mstrdup("attachment");
2526 p
->body
.disposition
.parameter
= mail_newbody_parameter();
2527 p
->body
.disposition
.parameter
->attribute
= mstrdup("filename");
2528 p
->body
.disposition
.parameter
->value
= mstrdup(fn
);
2533 set_text_data(body
, lpMessage
->lpszNoteText
? lpMessage
->lpszNoteText
2535 msprint1(" Message Body size: %d\r\n", (void *)body
->contents
.text
.size
);
2539 now
= time((time_t *)0);
2540 tm_now
= localtime(&now
);
2541 fprintf(ms_global
->dfd
, "%2.2d:%2.2d:%2.2d %d/%d/%d ",
2542 tm_now
->tm_hour
, tm_now
->tm_min
, tm_now
->tm_sec
,
2543 tm_now
->tm_mon
+1, tm_now
->tm_mday
, tm_now
->tm_year
+1900);
2545 if(nmg
->prcvars
[SMTP_SERVER
]->val
.l
&& nmg
->prcvars
[SMTP_SERVER
]->val
.l
[0]
2546 && nmg
->prcvars
[SMTP_SERVER
]->val
.l
[0][0]){
2548 fprintf(ms_global
->dfd
, "Preparing to open SMTP connection (%s ...)\r\n",
2549 nmg
->prcvars
[SMTP_SERVER
]->val
.l
[0]);
2552 sending_stream
= mapi_smtp_open(cs
, nmg
->prcvars
[SMTP_SERVER
]->val
.l
,
2553 nmg
->prcfeats
[ENABLE8BIT
]->is_set
? SOP_8BITMIME
: NIL
);
2556 rv
= MAPI_E_FAILURE
;
2558 fprintf(ms_global
->dfd
, "Error! No SMTP server defined!\r\n");
2562 if(!sending_stream
){
2563 rv
= MAPI_E_FAILURE
;
2565 fprintf(ms_global
->dfd
, "Couldn't open SMTP connection!\r\n");
2569 if(!smtp_mail(sending_stream
, "MAIL", env
, body
)){
2571 fprintf(ms_global
->dfd
, "Attempt to Send Failed\r\n");
2573 rv
= MAPI_E_FAILURE
;
2577 fprintf(ms_global
->dfd
, "Message SENT!\r\n");
2580 msprint("No fcc defined\r\n");
2581 else { /* Now try to write to fcc */
2583 MAILSTREAM
*fccstream
;
2586 msprint1("FCCing to %s\r\n", nmg
->fccfolder
);
2587 sb
= (STRBUFFER_S
*)fs_get(sizeof(STRBUFFER_S
));
2588 sb
->buf
= (char *)fs_get(20000*sizeof(char));
2590 sb
->increment
= 20000;
2591 sb
->bufsize
= 20000;
2592 rfc822_output(tmp_20k_buf
, env
, body
, pmapi_soutr
, sb
, 1);
2593 INIT(&msg
, mail_string
, (void *)sb
->buf
, sb
->cur_bytes
);
2594 fccstream
= mapi_mail_open(cs
, NULL
, nmg
->fccfolder
, ms_global
->debug
? OP_DEBUG
: NIL
);
2596 if(mail_append(fccstream
, nmg
->fccfolder
, &msg
) == NIL
)
2597 msprint1("Fcc to %s failed\r\n", nmg
->fccfolder
);
2599 msprint1("Fcc to %s SUCCEEDED\r\n", nmg
->fccfolder
);
2600 mail_close(fccstream
);
2603 msprint1("Open of %s failed, abandoning FCC\r\n", nmg
->fccfolder
);
2605 fs_give((void **)&sb
->buf
);
2607 fs_give((void **)&sb
);
2609 if((flFlags
& MAPI_LOGON_UI
) || (flFlags
& MAPI_DIALOG
))
2610 MessageBox(NULL
, "Message SENT!\r\n", "pmapi32.dll", MB_OK
|MB_ICONINFORMATION
);
2611 rv
= SUCCESS_SUCCESS
;
2613 smtp_close(sending_stream
);
2616 mail_free_envelope(&env
);
2618 mail_free_body(&body
);
2620 fs_give((void **)&cs
);
2625 set_text_data(BODY
*body
, char *txt
)
2631 for(p
= txt
; *p
; p
++)
2635 body
->contents
.text
.data
= mstrdup(txt
);
2636 body
->contents
.text
.size
= strlen(txt
);
2638 body
->encoding
= ENC8BIT
;
2639 if(!body
->parameter
)
2640 pm
= body
->parameter
= mail_newbody_parameter();
2642 for(pm
= body
->parameter
; pm
->next
; pm
= pm
->next
);
2643 pm
->next
= mail_newbody_parameter();
2646 pm
->attribute
= mstrdup("charset");
2647 if(ms_global
->prcvars
[CHARACTER_SET
]->val
.p
)
2648 pm
->value
= mstrdup(ms_global
->prcvars
[CHARACTER_SET
]->val
.p
);
2650 pm
->value
= mstrdup("X-UNKNOWN");
2656 pmapi_soutr(STRBUFFER_S
*s
, char *str
)
2660 if(s
->cur_bytes
>= s
->bufsize
){
2661 fs_resize((void **)&s
->buf
, s
->bufsize
+ s
->increment
);
2662 s
->bufsize
+= s
->increment
;
2664 for(i
= 0; str
[i
]; i
++){
2665 s
->buf
[s
->cur_bytes
++] = str
[i
];
2666 if(s
->cur_bytes
>= s
->bufsize
){
2667 fs_resize((void **)&s
->buf
, s
->bufsize
+ s
->increment
);
2668 s
->bufsize
+= s
->increment
;
2671 s
->buf
[s
->cur_bytes
] = '\0';
2676 mapirecip2address(lpMapiRecipDesc lpmrd
)
2678 ADDRESS
*adr
= NULL
;
2679 static char *fakedomain
= "@", *p
;
2680 mapi_global_s
*nmg
= ms_global
;
2682 if(!lpmrd
->lpszAddress
)
2684 rfc822_parse_adrlist(&adr
, _strnicmp(lpmrd
->lpszAddress
, "SMTP:", 5) == 0
2685 ? lpmrd
->lpszAddress
+ 5 : lpmrd
->lpszAddress
,
2686 nmg
->prcvars
[USER_DOMAIN
]->val
.p
2687 ? nmg
->prcvars
[USER_DOMAIN
]->val
.p
: fakedomain
);
2690 if(adr
->next
|| adr
->error
){
2691 mail_free_address(&adr
);
2695 if(lpmrd
->lpszName
&& adr
->personal
)
2696 fs_give((void **)&adr
->personal
);
2697 if(lpmrd
->lpszName
){
2698 p
= rfc1522_encode(tmp_20k_buf
, SIZEOF_20KBUF
, lpmrd
->lpszName
,
2699 nmg
->prcvars
[CHARACTER_SET
]->val
.p
);
2700 adr
->personal
= mstrdup(p
);
2706 * given a fs_get'd string, return a newly fs_get'd quoted copy
2711 char *new, *newp
, *oldp
;
2712 int newSize
= strlen(old
)*2+3;
2714 if (!old
) return mstrdup(old
);
2715 if(!strchr(old
, ' ')) return mstrdup(old
);
2717 newp
= new = (char *)fs_get(sizeof(char)*newSize
); /* worst case */
2719 ErrorBox("quote: fs_get of %d bytes failed", newSize
);
2724 for (oldp
=old
; *oldp
; ++oldp
) {
2726 case '"': *newp
++ = '\\'; /* fall through */
2727 default : *newp
++ = *oldp
;
2736 int GetPCPineVersion(int *major
, int *minor
, int *minorminor
)
2749 fprintf(ms_global
->dfd
, "%s", str
);
2755 msprint1(char *str
, void *arg1
)
2758 fprintf(ms_global
->dfd
, str
, arg1
);
2764 msprint_message_structure(lpMapiMessage lpm
)
2769 msprint1("lpMapiMessage: %p\r\n", lpm
);
2772 msprint1(" ulReserved: %d\r\n", (void *)lpm
->ulReserved
);
2773 msprint1(" lpszSubsect: %s\r\n", lpm
->lpszSubject
? lpm
->lpszSubject
: "(NULL)");
2774 msprint1(" lpszNoteText size: %d\r\n", lpm
->lpszNoteText
2775 ? (void *)strlen(lpm
->lpszNoteText
) : (void *)0);
2776 if(lpm
->lpszNoteText
)
2777 msprint1("\tleading text: %.10s\r\n", lpm
->lpszNoteText
);
2778 msprint1(" lpszMessageType: %s\r\n", lpm
->lpszMessageType
? lpm
->lpszMessageType
: "(NULL)");
2779 msprint1(" lpszDateReceived: %s\r\n", lpm
->lpszDateReceived
? lpm
->lpszDateReceived
: "(NULL)");
2780 msprint1(" lpszConversationID: %s\r\n", lpm
->lpszConversationID
? lpm
->lpszConversationID
: "(NULL)");
2781 msprint1(" flFlags: %d\r\n", (void *)lpm
->flFlags
);
2782 msprint(" Originator:\r\n");
2783 msprint_recipient_structure(lpm
->lpOriginator
, 0);
2784 msprint1(" nRecipCount: %d\r\n", (void *)lpm
->nRecipCount
);
2785 for(i
= 0; i
< lpm
->nRecipCount
; i
++)
2786 msprint_recipient_structure(&lpm
->lpRecips
[i
], 1);
2787 msprint1(" nFileCount: %d\r\n", (void *)lpm
->nFileCount
);
2788 for(i
= 0; i
< lpm
->nFileCount
; i
++)
2789 msprint_file_structure(&lpm
->lpFiles
[i
]);
2796 msprint_recipient_structure(lpMapiRecipDesc lmrd
, int mapi_orig_is_unexpected
)
2799 msprint1(" lpMapiRecipDesc: %p\r\n", (void *)lmrd
);
2802 msprint1(" ulReserved: %d\r\n", (void *)lmrd
->ulReserved
);
2803 msprint1(" ulRecipClass: %s\r\n", lmrd
->ulRecipClass
== MAPI_ORIG
? "MAPI_ORIG"
2804 : lmrd
->ulRecipClass
== MAPI_TO
? "MAPI_TO" : lmrd
->ulRecipClass
== MAPI_CC
2805 ? "MAPI_CC" : "MAPI_BCC");
2806 if(mapi_orig_is_unexpected
&& lmrd
->ulRecipClass
== MAPI_ORIG
){
2807 msprint(" # NOTE: it is seemingly strange behavior that a MAPI client would use\r\n # MAPI_ORIG instead of the lpOriginator. This may result in unexpected behavior.\r\n");
2809 msprint1(" lpszName: %s\r\n", lmrd
->lpszName
? lmrd
->lpszName
: "(NULL)");
2810 msprint1(" lpszAddress: %s\r\n", lmrd
->lpszAddress
? lmrd
->lpszAddress
: "(NULL)");
2811 msprint1(" ulEIDSize: %p\r\n", (void *)lmrd
->ulEIDSize
);
2812 msprint1(" lpEntryID: %p\r\n", (void *)lmrd
->lpEntryID
);
2819 msprint_file_structure(lpMapiFileDesc lmfd
)
2822 msprint1(" lpMapiFileDesc: %p\r\n", (void *)lmfd
);
2825 msprint1(" ulReserved: %d\r\n", (void *)lmfd
->ulReserved
);
2826 msprint1(" flFlags: %d\r\n", (void *)lmfd
->flFlags
);
2827 msprint1(" nPosition: %d\r\n", (void *)lmfd
->nPosition
);
2828 msprint1(" lpszPathName: %s\r\n", lmfd
->lpszPathName
? lmfd
->lpszPathName
: "(NULL)");
2829 msprint1(" lpszFileName: %s\r\n", lmfd
->lpszFileName
? lmfd
->lpszFileName
: "(NULL)");
2830 msprint1(" lpFileType: %p\r\n", (void *)lmfd
->lpFileType
);
2836 char *mstrdup(char *old
)
2840 tmp
= fs_get((strlen(old
)+1) * sizeof(char));
2852 for(; a
; a
= a
->next
){
2854 /* two times personal for possible quoting */
2855 cnt
+= 2 * (a
->personal
? strlen(a
->personal
) : 0);
2856 cnt
+= (a
->mailbox
? strlen(a
->mailbox
) : 0);
2857 cnt
+= (a
->adl
? strlen(a
->adl
) : 0);
2858 cnt
+= (a
->host
? strlen(a
->host
) : 0);
2862 * possible single space between fullname and addr
2863 * left and right brackets
2865 * possible : for route addr
2868 * So I really think that adding 7 is enough. Instead, I'll add 10.
2873 return(max(cnt
, 50)); /* just making sure */
2876 void ErrorBoxFunc(char *msg
)
2879 fprintf(ms_global
->dfd
,"ErrorBox: %s\r\n", msg
);
2880 fclose(ms_global
->dfd
);
2881 ms_global
->dfd
= fopen(ms_global
->debugFile
, "ab");
2882 if(!ms_global
->dfd
){
2883 MessageBox(NULL
, "debug file problems! Debugging turned off.",
2885 MB_OK
|MB_ICONERROR
);
2886 ms_global
->debug
= 0;
2887 fs_give((void **)&ms_global
->debugFile
);
2888 ms_global
->debugFile
= NULL
;
2891 MessageBox(NULL
, msg
, "mapi32.dll", MB_OK
|MB_ICONERROR
);
2894 /*----------------------------------------------------------------------
2895 This was borrowed from reply.c, and modified
2896 Generate a unique message id string.
2898 Args: ps -- The usual pine structure
2900 Result: Alloc'd unique string is returned
2902 Uniqueness is guaranteed by using the host name, process id, date to the
2903 second and a single unique character
2904 *----------------------------------------------------------------------*/
2906 pmapi_generate_message_id()
2908 static short osec
= 0, cnt
= 0;
2913 now
= time((time_t *)0);
2914 now_x
= localtime(&now
);
2915 id
= (char *)fs_get(128 * sizeof(char));
2917 if(now_x
->tm_sec
== osec
){
2921 osec
= now_x
->tm_sec
;
2923 sprintf(id
,"<Pmapi32.%04d%02d%02d%02d%02d%02d%X.%d@%.50s>",
2924 (now_x
->tm_year
) + 1900, now_x
->tm_mon
+ 1,
2925 now_x
->tm_mday
, now_x
->tm_hour
, now_x
->tm_min
, now_x
->tm_sec
,
2926 cnt
, getpid(), mylocalhost());