2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
27 * $TOG: RFCEnvelope.C /main/7 1998/04/06 13:27:59 mgreess $
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement bertween
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
35 * Sun's specific written approval. This documment and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
44 #ifndef I_HAVE_NO_IDENT
47 #include <EUSCompat.h>
52 #include <sys/utsname.h>
54 #include <DtMail/DtMail.hh>
56 #include <DtMail/Threads.hh>
57 #include <DtMail/IO.hh>
58 #include "str_utils.h"
60 unsigned long RFCEnvelopeSignature = 0x55fd23ef;
62 // This constant defines how big the parsed header structure starts.
63 // it will grow dynamically over time if need be. The guess here is
64 // that most messages will have about 32 headers so we won't have
65 // to grow very often, but we also aren't wasting a lot of space.
67 static const int INITIAL_HEADER_COUNT = 32;
69 static const int NAME_MASK = 0x1;
70 static const int VALUE_MASK = 0x2;
72 RFCEnvelope::RFCEnvelope(DtMailEnv & error,
73 DtMail::Message * parent,
76 : DtMail::Envelope(error, parent), _parsed_headers(INITIAL_HEADER_COUNT)
83 _header_lock = MutexInit();
89 _object_signature = RFCEnvelopeSignature;
90 //fix for the defect 177527
91 _use_reply_to=DTM_TRUE;
94 RFCEnvelope::~RFCEnvelope(void)
96 if (_object_signature == RFCEnvelopeSignature) {
97 MutexLock lock_scope(_obj_mutex);
98 if (_object_signature == RFCEnvelopeSignature) {
99 for (int hdr = 0; hdr < _parsed_headers.length(); hdr++) {
100 ParsedHeader * hdrp = _parsed_headers[hdr];
101 delete _parsed_headers[hdr];
103 _object_signature = 0;
109 RFCEnvelope::getFirstHeader(DtMailEnv & error,
111 DtMailValueSeq & value)
113 MutexLock lock_header(_header_lock);
117 if (_parsed_headers.length() == 0) {
118 return(NULL); // No headers.
121 DtMailHeaderHandle handle = _parsed_headers[0];
123 *name = (char *)malloc(_parsed_headers[0]->name_len + 1);
124 strncpy(*name, _parsed_headers[0]->name_start, _parsed_headers[0]->name_len);
125 (*name)[_parsed_headers[0]->name_len] = 0;
127 makeValue(error, *_parsed_headers[0], value);
133 RFCEnvelope::getNextHeader(DtMailEnv & error,
134 DtMailHeaderHandle last,
136 DtMailValueSeq & value)
138 MutexLock lock_header(_header_lock);
143 error.setError(DTME_BadArg);
147 int slot = _parsed_headers.indexof((ParsedHeader *)last);
153 if (slot >= _parsed_headers.length()) {
157 ParsedHeader * hdr = _parsed_headers[slot];
159 *name = (char *)malloc(hdr->name_len + 1);
160 strncpy(*name, hdr->name_start, hdr->name_len);
161 (*name)[hdr->name_len] = 0;
163 makeValue(error, *hdr, value);
169 const char * abstract;
170 const char ** transports;
173 static const char * DtMailMessageToMap[] = {
174 "To", "Apparently-To", "Resent-To", NULL
177 static const char * DtMailMessageSenderMap[] = {
178 "Reply-To", "From", "Return-Path", "Resent-From", NULL
181 static const char * DtMailMessageCcMap[] = {
185 static const char * DtMailMessageBccMap[] = {
189 static const char * DtMailMessageReceivedTimeMap[] = {
193 static const char * DtMailMessageSentTimeMap[] = {
197 static const char * DtMailMessageIdMap[] = {
201 static const char * DtMailMessageSubjectMap[] = {
205 static const char * DtMailMessageContentLengthMap[] = {
206 "Content-Length", NULL
209 static const char * DtMailMessageStatusMap[] = {
210 "Status", "X-Status", NULL
213 static const char * DtMailMessageV3charsetMap[] = {
214 "X-Sun-Charset", NULL
217 static const char * DtMailMessageContentTypeMap[] = {
221 static const AbstractMap abstract_map[] = {
222 { DtMailMessageTo, DtMailMessageToMap },
223 { DtMailMessageSender, DtMailMessageSenderMap },
224 { DtMailMessageCc, DtMailMessageCcMap },
225 { DtMailMessageBcc, DtMailMessageBccMap },
226 { DtMailMessageReceivedTime, DtMailMessageReceivedTimeMap },
227 { DtMailMessageSentTime, DtMailMessageSentTimeMap },
228 { DtMailMessageMessageId, DtMailMessageIdMap },
229 { DtMailMessageSubject, DtMailMessageSubjectMap },
230 { DtMailMessageContentLength, DtMailMessageContentLengthMap },
231 { DtMailMessageStatus, DtMailMessageStatusMap },
232 { DtMailMessageV3charset, DtMailMessageV3charsetMap },
233 { DtMailMessageContentType, DtMailMessageContentTypeMap },
238 RFCEnvelope::getHeader(DtMailEnv & error,
240 const DtMailBoolean abstract,
241 DtMailValueSeq & value)
243 MutexLock lock_header(_header_lock);
247 // If we are not in the abstract space, then simply get the
248 // transport header and return.
250 if (abstract == DTM_FALSE) {
251 getTransportHeader(error, name, value);
254 // We need to handle reply to's with special care. We may
255 // need to strip the sender from the list.
257 if (strcmp(name, DtMailMessageToReply) == 0) {
258 makeReply(error, DtMailMessageTo, value);
262 if (strcmp(name, DtMailMessageCcReply) == 0) {
263 makeReply(error, DtMailMessageCc, value);
267 // Okay, we need to work out what the transport name
268 // might be. We do this by first finding the abstract
269 // name in the abstract->transport mapping table.
272 for (abs = 0; abstract_map[abs].abstract; abs++) {
273 if (strcmp(abstract_map[abs].abstract, name) == 0) {
278 // If we didn't find the abstract name, then feed it through
279 // as a transport name. This is useful behavior so intermediates
280 // like the RFCMailBox::getMessageSummary method can always
281 // assume abstract names, but allow its client to specify transport
284 if (!abstract_map[abs].abstract) {
285 getTransportHeader(error, name, value);
289 // Now we need to go through the list of transport names until
290 // we find a match. The first match is taken because the map
291 // should be ordered based on preference.
293 for (int trans = 0; abstract_map[abs].transports[trans]; trans++) {
294 getTransportHeader(error,
295 abstract_map[abs].transports[trans],
297 // If the abstract is DtMailMessageSender we need do something
298 // special. If the request is for displaying the sender's
299 // name or e-mail address in the msg list scrolled window in the
300 // RMW, we should return the "From" value instead of the
301 // "Reply-To" value. Otherwise, we should return the Reply-To
302 // value (such as "Reply to sender")
304 if (error.isNotSet()) { // Found one!
305 if(!getUseReplyTo() &&
306 strcmp(abstract_map[abs].transports[trans],"Reply-To") == 0)
317 // If this isn't a request for the sender ("From"), then
318 // we don't have a known value for the header. Bail!
320 if (strcmp(DtMailMessageSender, name) &&
321 strcmp(DtMailMessageReceivedTime, name)) {
322 error.setError(DTME_NoObjectValue);
326 if (strncmp(_parsed_headers[0]->name_start, "From", 4) == 0) {
327 if (strcmp(DtMailMessageSender, name) == 0) {
328 parseUnixFrom(error, *_parsed_headers[0], value);
330 else if (strcmp(DtMailMessageReceivedTime, name) == 0) {
331 parseUnixDate(error, *_parsed_headers[0], value);
335 error.setError(DTME_NoObjectValue);
345 RFCEnvelope::setHeader(DtMailEnv & error,
347 const DtMailBoolean replace,
350 MutexLock lock_header(_header_lock);
352 RFCMessage * msg = (RFCMessage *)_parent;
356 // First we need to see if we have this header. We are
357 // only interested in the first occurance.
360 const char * real_name;
362 // Find the header if it currently exists
364 int slot = lookupHeader(name);
366 // Determine if the value is really empty (just blanks)
368 DtMailBoolean valueIsEmpty = DTM_TRUE;
369 for (const char *cv = val; *cv; cv++) {
370 if (!isspace((unsigned char)*cv)) {
371 valueIsEmpty = DTM_FALSE;
376 // If the value to be set is empty (only spaces), then treat this
377 // set header request specially - either toss it if requesting to
378 // append an empty header, or remove an existing header if requesting
379 // to set an empty header
381 if (valueIsEmpty == DTM_TRUE) {
383 // The header was not found and the value is empty -
384 // Just return as there was no header to set anyway
387 if (replace == DTM_TRUE) {
388 // The header was found and replacement was requested
389 // but the value is empty - request to replace existing
390 // header with empty header - treat as a remove header request
392 removeHeader(error, name);
395 // The header was found, replacement is not requested, and the
396 // value is empty - request to append empty header - toss
401 if (slot < 0 || replace == DTM_FALSE) {
402 // Need to create a new header entry for this one.
404 hdr = new ParsedHeader;
405 slot = _parsed_headers.append(hdr);
406 real_name = mapName(name);
407 _dirty = 1; // new entry: header dirty
410 hdr = _parsed_headers[slot];
414 // First, see if we need to do something about the name.
416 if (!hdr->name_start) {
417 hdr->alloc_mask |= NAME_MASK;
418 hdr->name_start = strdup(real_name);
419 hdr->name_len = strlen(real_name);
420 _header_len += hdr->name_len;
421 _dirty = 1; // new name: header dirty
424 // Clean up the existing value if need be.
426 if (hdr->value_start) {
427 if ( (strlen(val) != hdr->value_len)
428 || (strncmp(hdr->value_start, val, hdr->value_len)!=0) ) // has value changed??
429 _dirty = 1; // yes: header dirty
430 if (hdr->alloc_mask & VALUE_MASK) {
431 free((char *)hdr->value_start);
433 hdr->value_start = NULL;
434 _header_len -= hdr->value_len;
438 _dirty = 1; // new value: header dirty
440 hdr->value_start = strdup(val);
441 hdr->value_len = strlen(hdr->value_start);
442 _header_len += hdr->value_len + 1;
443 hdr->alloc_mask |= VALUE_MASK;
446 msg->markDirty(_dirty);
451 RFCEnvelope::removeHeader(DtMailEnv & error, const char * name)
453 MutexLock lock_header(_header_lock);
457 // Remove all versions of this header.
459 int slot = lookupHeader(name);
461 _parsed_headers.remove(slot);
462 slot = lookupHeader(name);
465 RFCMessage * msg = (RFCMessage *)_parent;
478 RFCEnvelope::adjustHeaderLocation(char * headerStart, int headerLength)
480 MutexLock lock_header(_header_lock);
483 // reparse headers in their new location
484 // destroy current headers
486 for (int hdr = 0; hdr < _parsed_headers.length(); hdr++) {
487 ParsedHeader * hdrp = _parsed_headers[hdr];
488 delete _parsed_headers[hdr];
489 _parsed_headers.remove(hdr);
493 // parse headers from scratch
494 _header_text = headerStart;
495 _header_len = headerLength;
499 // We must adjust the offset of every header in the parsed header
500 // structure. For those headers values that have been malloc()ed
501 // (e.g. NAME_MASK or VALUE_MASK are set), dont have to do anything
502 // as they are deallocated only when the header is destroyed.
504 for (int hdr = 0; hdr < _parsed_headers.length(); hdr++) {
505 ParsedHeader * h = _parsed_headers[hdr];
506 if (!(h->alloc_mask & NAME_MASK)) {
507 h->name_start = (h->name_start - _header_text) + headerStart;
509 if (!(h->alloc_mask & VALUE_MASK)) {
510 h->value_start = (h->value_start - _header_text) + headerStart;
513 _header_text = headerStart;
520 RFCEnvelope::writeHeaders(char * new_loc)
522 MutexLock lock_header(_header_lock);
524 // Copy the headers to the new region
526 char * cur_loc = new_loc;
528 for (int hdr = 0; hdr < _parsed_headers.length(); hdr++) {
529 ParsedHeader * h = _parsed_headers[hdr];
531 const char * new_name = cur_loc;
532 memcpy(cur_loc, h->name_start, h->name_len);
533 cur_loc += h->name_len;
534 if (!first || strncmp(h->name_start, "From", h->name_len) != 0) {
542 const char * new_value = cur_loc;
543 memcpy(cur_loc, h->value_start, h->value_len);
544 cur_loc += h->value_len;
546 // Insert a trailing crlf if necessary. We need this so that when
547 // we write into the file, the header lines are as in RFC822 format.
548 if (*(cur_loc - 1) != '\n') {
558 RFCEnvelope::unixFrom(DtMailEnv & error, int & length)
560 ParsedHeader * hdr = _parsed_headers[0];
561 const char * ufrom = NULL;
566 if (strncmp(hdr->name_start, "From ", 5) == 0) {
567 ufrom = hdr->name_start;
568 length = (hdr->value_start + hdr->value_len) - hdr->name_start + 1;
571 error.setError(DTME_NoObjectValue);
578 RFCEnvelope::parseHeaders(void)
580 // Now we actually parse the headers. Each header either ends with
581 // a new line, or is continued if the next line begins with white
584 ParsedHeader * hdr = new ParsedHeader;
585 for (const char * scan = _header_text; scan < (_header_text + _header_len);) {
586 if ((scan == _header_text) && (strncmp(scan, "From ", 5) == 0)) {
587 // Unix "From" line. This header has a different structure.
588 // It is "From user@host <date>". It does not have a colon
589 // like all other RFC headers so we have to parse it specially.
591 hdr->name_start = scan;
594 // Look for the first non-blank after the "From ".
596 for (scan += 4; *scan && isspace((unsigned char)*scan); scan++) {
600 hdr->value_start = scan;
602 // Find the new line.
603 for (; *scan && *scan != '\n'; scan++) {
607 hdr->value_len = scan - hdr->value_start;
608 if (*(scan - 1) == '\r') {
613 _parsed_headers.append(hdr);
614 hdr = new ParsedHeader;
618 // We should be at the start of a header. Let's look for a ":". If
619 // we find any white space first, then we have a problem.
621 hdr->name_start = scan;
622 for (;*scan && *scan != ':'; scan++) {
623 if (isspace((unsigned char)*scan)) {
629 // Find the next new line, and try again.
631 for (;*scan && *scan != '\n'; scan++) {
638 hdr->name_len = scan - hdr->name_start;
640 // Look for the first non-blank after the colon.
642 for (scan += 1; scan < (_header_text + _header_len)
643 && *scan != '\n' && isspace((unsigned char)*scan); scan++) {
649 hdr->value_start = scan;
651 _parsed_headers.append(hdr);
652 hdr = new ParsedHeader;
657 // Okay, now we want scan looking for a new line that is
658 // not followed immediately by white space. That will give
659 // us the end of the header.
661 hdr->value_start = scan;
662 for (;scan < (_header_text + _header_len); scan++) {
663 if (*scan == '\n' && !isspace((unsigned char)*(scan + 1))) {
668 hdr->value_len = scan - hdr->value_start;
669 if (*(scan - 1) == '\r') {
674 _parsed_headers.append(hdr);
675 hdr = new ParsedHeader;
684 RFCEnvelope::getTransportHeader(DtMailEnv & error,
686 DtMailValueSeq & value)
690 // First, let's try to find out how many times the header
691 // appears. It may appear 1, many, or not at all.
694 for (int hdr = 0; hdr < _parsed_headers.length(); hdr++) {
695 // We need to lock the object until we are done.
697 MutexLock lock_header(_parsed_headers[hdr]->mutex);
699 // Make sure we have a header!
701 if (!_parsed_headers[hdr]->name_start ||
702 !_parsed_headers[hdr]->value_start) {
706 // Unix From doesn't count. We only use it as a fall back.
707 // It will always appear as the first header, if it appears
711 strncmp(_parsed_headers[hdr]->name_start, "From ", 5) == 0) {
715 if (matchName(*_parsed_headers[hdr], name) == DTM_TRUE) {
716 // If the header exists, make sure it has a value.
717 if (_parsed_headers[hdr]->value_len > 0)
722 if (appears == 0) { // Not here!
723 error.setError(DTME_NoObjectValue);
727 // Second pass, find the headers and convert the values to the
731 for (int val = 0; val < _parsed_headers.length(); val++) {
733 strncmp(_parsed_headers[val]->name_start, "From ", 5) == 0) {
737 if (matchName(*_parsed_headers[val], name) == DTM_TRUE) {
738 RFCValue * new_value = new RFCValue(_parsed_headers[val]->value_start,
739 _parsed_headers[val]->value_len, _parent->session());
740 value.append(new_value);
748 RFCEnvelope::parseUnixFrom(DtMailEnv & error,
749 const ParsedHeader & hdr,
750 DtMailValueSeq & value)
754 // The value_start will point to the beginning of the address.
755 // The Unix From header doesn't maintain all of the strange
756 // quoting behavior so spaces don't appear.
759 for (end = hdr.value_start; *end && !isspace((unsigned char)*end); end++) {
763 int size = end - hdr.value_start;
765 RFCValue * new_value = new RFCValue(hdr.value_start, size, _parent->session());
766 value.append(new_value);
772 RFCEnvelope::parseUnixDate(DtMailEnv & error,
773 const ParsedHeader & hdr,
774 DtMailValueSeq & value)
778 // The value_start will point to the beginning of the address.
779 // The Unix From header doesn't maintain all of the strange
780 // quoting behavior so spaces don't appear.
783 for (end = hdr.value_start; end < (hdr.value_start + hdr.value_len)
784 && !isspace((unsigned char)*end); end++) {
788 // Now end points at the white space between the sender and
789 // the date it arrived.
791 for (; end < (hdr.value_start + hdr.value_len) &&
792 isspace((unsigned char)*end); end++) {
796 // Now we are at the start of the date.
798 int size = (hdr.value_start + hdr.value_len) - end;
800 RFCValue * new_value = new RFCValue(end, size, _parent->session());
801 value.append(new_value);
807 RFCEnvelope::makeValue(DtMailEnv & error,
808 const ParsedHeader & hdr,
809 DtMailValueSeq & value)
813 RFCValue * new_value = new RFCValue(hdr.value_start, hdr.value_len, _parent->session());
814 value.append(new_value);
818 RFCEnvelope::matchName(const ParsedHeader & hdr, const char * name)
820 if (hdr.name_len != strlen(name)) {
824 if (strncasecmp(hdr.name_start, name, hdr.name_len) == 0) {
832 RFCEnvelope::lookupHeader(const char * name, DtMailBoolean real_only)
834 // Look for the name in real space.
837 int len = strlen(name);
838 for (hdr = 0; hdr < _parsed_headers.length(); hdr++) {
839 if (_parsed_headers[hdr]->name_start &&
840 strncasecmp(_parsed_headers[hdr]->name_start, name, len) == 0) {
845 if (real_only == DTM_TRUE) {
849 for (const AbstractMap * abs = abstract_map; abs->abstract; abs++) {
850 if (strcmp(abs->abstract, name) == 0) {
851 for (int trans = 0; abs->transports[trans]; trans++) {
852 int slot = lookupHeader(abs->transports[trans], DTM_TRUE);
864 RFCEnvelope::makeReply(DtMailEnv & error,
866 DtMailValueSeq & value)
870 // We have an abstract name. We need to loop through the
871 // transport headers, gathering up the values.
874 for (abs = 0; abstract_map[abs].abstract; abs++) {
875 if (strcmp(abstract_map[abs].abstract, name) == 0) {
880 if (!abstract_map[abs].abstract) {
881 error.setError(DTME_NoObjectValue);
884 // Now we need to go through the list of transport names until
885 // we find a match. The first match is taken because the map
886 // should be ordered based on preference.
888 DtMailBoolean found = DTM_FALSE;
889 DtMailValueSeq lvalue;
890 for (int trans = 0; abstract_map[abs].transports[trans]; trans++) {
891 getTransportHeader(error,
892 abstract_map[abs].transports[trans],
894 if (error.isNotSet()) { // Found one!
901 if (found == DTM_FALSE) {
902 error.setError(DTME_NoObjectValue);
906 if (_parent == NULL) {
907 // We're done. Copy the values from one to the other.
909 for (int nc = 0; nc < lvalue.length(); nc++) {
910 RFCValue * new_value = new RFCValue(*(lvalue[nc]), strlen(*(lvalue[nc])), _parent->session());
911 value.append(new_value);
916 DtMail::MailRc * mailrc = _parent->session()->mailRc(error);
918 // If metoo is set, then we are also done.
922 mailrc->getValue(lerror, "metoo", &mval);
923 if (lerror.isNotSet()) {
924 for (int nc = 0; nc < lvalue.length(); nc++) {
925 RFCValue * new_value = new RFCValue(*(lvalue[nc]), strlen(*(lvalue[nc])), _parent->session());
926 value.append(new_value);
931 // Finally, the point of being here! We need to build a new
932 // value that has the user stripped from the reply list. This
933 // includes any alternates the user has specified.
936 GetPasswordEntry(pw);
937 struct utsname uname_val;
940 char * my_addr = new char[strlen(pw.pw_name) + strlen(uname_val.nodename) + 5];
941 strcpy(my_addr, pw.pw_name);
942 strcat(my_addr, "@");
943 strcat(my_addr, uname_val.nodename);
945 DtMailAddressSeq alts;
946 DtMailValueAddress * me = new DtMailValueAddress(my_addr,
948 DtMailAddressDefault);
951 // Fetch the alternates, if any and add them to the list to strip.
953 const char * others = mailrc->getAlternates(lerror);
955 RFCTransport::arpaPhrase(others, alts);
958 // Finally, we need to see if the user wants us to ignore the host
959 // component of the address when stripping.
961 DtMailBoolean allnet = DTM_FALSE;
962 mailrc->getValue(lerror, "allnet", &mval);
963 if (lerror.isNotSet()) {
967 DtMailAddressSeq keepers;
969 for (int nc = 0; nc < lvalue.length(); nc++) {
970 DtMailAddressSeq * cur_val = lvalue[nc]->toAddress();
971 for (int naddr = 0; naddr < cur_val->length(); naddr++) {
972 if (metooAddr(*(*cur_val)[naddr], alts, allnet) == DTM_FALSE) {
973 DtMailValueAddress * kaddr = new DtMailValueAddress(*(*cur_val)[naddr]);
974 keepers.append(kaddr);
979 // Finally, let's build a single string from the remaining list and
980 // set the value to that string.
983 for (int cstr = 0; cstr < keepers.length(); cstr++) {
984 DtMailValueAddress * addr = keepers[cstr];
985 max_len += strlen(addr->dtm_address) + 3;
989 char * str_addr = new char[max_len];
991 for (int copy = 0; copy < keepers.length(); copy++) {
992 DtMailValueAddress * addr = keepers[copy];
993 strcat(str_addr, addr->dtm_address);
994 if (copy != (keepers.length() - 1)) {
995 strcat(str_addr, ", ");
999 RFCValue * new_val = new RFCValue(str_addr, strlen(str_addr), _parent->session());
1000 value.append(new_val);
1006 striphosts(char * addr)
1010 if ((cp = strrchr(addr,'!')) != NULL)
1015 * Now strip off all Internet-type
1018 if ((cp2 = strchr(cp, '%')) == NULL)
1019 cp2 = strchr(cp, '@');
1026 RFCEnvelope::metooAddr(DtMailValueAddress & addr,
1027 DtMailAddressSeq & alts,
1028 DtMailBoolean allnet)
1030 char * str_addr_buf = strdup(addr.dtm_address);
1031 char * str_addr = str_addr_buf;
1034 str_addr = striphosts(str_addr_buf);
1037 for (int nalt = 0; nalt < alts.length(); nalt++) {
1038 char * cmp_addr_buf = strdup(alts[nalt]->dtm_address);
1039 char * cmp_addr = cmp_addr_buf;
1042 cmp_addr = striphosts(cmp_addr_buf);
1045 if (strcasecmp(str_addr, cmp_addr) == 0) {
1059 // This method attempts to map an abstract name to a transport name.
1060 // When multiple transport names exist, the first is always used.
1063 RFCEnvelope::mapName(const char * name)
1065 for (const AbstractMap * abs = abstract_map; abs->abstract; abs++) {
1066 if (strcmp(name, abs->abstract) == 0) {
1067 return(abs->transports[0]);
1071 // Must be a real name.
1076 RFCEnvelope::ParsedHeader::ParsedHeader(void)
1078 mutex = MutexInit();
1086 RFCEnvelope::ParsedHeader::~ParsedHeader(void)
1088 MutexLock lock_scope(mutex);
1090 if (alloc_mask & NAME_MASK) {
1091 free((char *)name_start);
1094 if (alloc_mask & VALUE_MASK) {
1095 free((char *)value_start);
1098 lock_scope.unlock_and_destroy();