Postfix 2.0 patch 17 catches up on minor bugfixes that were made available in the past three months via the experimental release. - Portability to MacOSX: Bind8 compatibility, core dumps in mailq and postdrop, and changes in netinfo support. - Elimination of some DNS lookup problems in third-party library routines (typically resulting in localhost not being found). - More agressive delivery to sites that defer a lot of mail. - Correction of a few obscure error messages. - Several small documentation fixes. - Minor fixes for robustness problems that no-one has experienced. Prereq: "2.0.16" diff -cr /tmp/postfix-2.0.16/src/global/mail_version.h ./src/global/mail_version.h *** /tmp/postfix-2.0.16/src/global/mail_version.h Fri Sep 12 21:16:51 2003 --- ./src/global/mail_version.h Mon Jan 19 17:27:52 2004 *************** *** 20,29 **** * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20030913" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.16" extern char *var_mail_version; /* --- 20,29 ---- * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20040119" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.17" extern char *var_mail_version; /* diff -cr /tmp/postfix-2.0.16/HISTORY ./HISTORY *** /tmp/postfix-2.0.16/HISTORY Sat Sep 13 21:29:51 2003 --- ./HISTORY Tue Jan 20 10:10:59 2004 *************** *** 7899,7904 **** --- 7899,7961 ---- Safety: set-gid commands don't trust TZ. File: msg_syslog.c. + 20031027 + + Portability: MacOS X Bind8 compatibility. File: makedefs. + + 20031110 + + Cleanup: don't report that $queue_directory/etc/filename + differs from /etc/filename when /etc/filename does not + exist. File: conf/postfix-script. + + 20031126 + + Bugfix: "panic: mymalloc: requested length 0" when master.cf + specified an invalid host name or address. Postfix now + logs more specific information. File: master/master_ent.c. + Reported by several people. + + 20031215 + + Safety: updated mail_queue_id_ok() for long fast flush + logfile names. File: global/mail_queue.c. + + Robustness: save and restore the resolver _res.options + settings before and after DNS lookup, to avoid surprises + in third-party code. This may eliminate some "localhost + not found" problems. File: dns/dns_lookup.c. + + 20031222 + + Cleanup: shaved half the worst-case bits off the cleanup + duplicate address filter footprint. After discussion with + Victor Duchovni. File: cleanup/cleanup_out_recipient.c. + + 20031223 + + Bugfix: restore errno after write failure in SIGCHLD handler. + Leandro Santi. File: master/master_sig.c. + + 20040104 + + Workaround: MacOSX dumps core on the 20030913 TZ censoring + code. We explictly set TZ=UTC, which will produce incorrect + results when "mailq" formatting is moved from the showq + daemon to the postqueue command. File: msg_syslog.c. + + Bugfix: vstring_get() etc. now return VSTREAM_EOF when they + terminate prematurely, instead of returning the last + character stored. This avoids mis-leading warnings. File: + global/vstring_vstream.c. + + 20040115 + + Performance: allow delivery concurrency to increase even + while mail is deferred, as long as the delivery agent does + not report really serious trouble with the destination. + Files: *qmgr/qmgr_deliver.c. + Open problems: Doc: mention the proxy_interfaces parameter everywhere the diff -cr /tmp/postfix-2.0.16/RELEASE_NOTES ./RELEASE_NOTES *** /tmp/postfix-2.0.16/RELEASE_NOTES Tue Apr 15 13:41:55 2003 --- ./RELEASE_NOTES Sun Sep 28 18:46:33 2003 *************** *** 210,216 **** [Obsolete 20021209] The "check_relay_domains" restriction is going away. The SMTP server logs a warning and suggests using the more ! robust "reject_unauth_destination" instead. [Obsolete 20020917] In regexp lookup tables, the form /pattern1/!/pattern2/ is going away. Use the cleaner and more flexible "if !/pattern2/..endif" --- 210,219 ---- [Obsolete 20021209] The "check_relay_domains" restriction is going away. The SMTP server logs a warning and suggests using the more ! robust "reject_unauth_destination" instead. This means that Postfix ! by default no longer grants relay permissions on the basis of the ! client hostname, and that relay clients must be authorized via ! other means such as permit_mynetworks. [Obsolete 20020917] In regexp lookup tables, the form /pattern1/!/pattern2/ is going away. Use the cleaner and more flexible "if !/pattern2/..endif" *************** *** 330,336 **** where inbound mail deliveries could become resource starved in the presence of a high volume of outbound mail. ! [Feature 20021013] The body_checks_max_size parameter limits the amount of text per message body segment (or attachment, if you prefer to use that term) that is subjected to body_checks inspection. The default limit is 50 kbytes. This speeds up the processing of --- 333,339 ---- where inbound mail deliveries could become resource starved in the presence of a high volume of outbound mail. ! [Feature 20021013] The body_checks_size_limit parameter limits the amount of text per message body segment (or attachment, if you prefer to use that term) that is subjected to body_checks inspection. The default limit is 50 kbytes. This speeds up the processing of *************** *** 483,489 **** IP address blacklisting. Based on code by LaMont Jones. The old "reject_maps_rbl" is now implemented as a wrapper around the reject_rbl_client code, and logs a warning that "reject_maps_rbl" ! is going away. [Feature 20020923] "reject_rhsbl_sender rbl.domain.tld" for sender domain blacklisting. Also: reject_rhsbl_client and reject_rhsbl_recipient --- 486,493 ---- IP address blacklisting. Based on code by LaMont Jones. The old "reject_maps_rbl" is now implemented as a wrapper around the reject_rbl_client code, and logs a warning that "reject_maps_rbl" ! is going away. To upgrade, specify "reject_rbl_client domainname" ! once for each domain name that is listed in maps_rbl_domains. [Feature 20020923] "reject_rhsbl_sender rbl.domain.tld" for sender domain blacklisting. Also: reject_rhsbl_client and reject_rhsbl_recipient *************** *** 741,747 **** (for headers of attached email messages except MIME headers). By default, all headers are matched with header_checks. ! [Feature 20021013] The body_checks_max_size parameter limits the amount of text per message body segment (or attachment, if you prefer to use that term) that is subjected to body_checks inspection. The default limit is 50 kbytes. This speeds up the processing of --- 745,751 ---- (for headers of attached email messages except MIME headers). By default, all headers are matched with header_checks. ! [Feature 20021013] The body_checks_size_limit parameter limits the amount of text per message body segment (or attachment, if you prefer to use that term) that is subjected to body_checks inspection. The default limit is 50 kbytes. This speeds up the processing of diff -cr /tmp/postfix-2.0.16/conf/postfix-script ./conf/postfix-script *** /tmp/postfix-2.0.16/conf/postfix-script Sun Jun 29 17:16:16 2003 --- ./conf/postfix-script Tue Jan 20 10:08:50 2004 *************** *** 200,207 **** do test -d $dir && find $dir -type f -print | while read path do ! cmp -s $path /$path || ! $WARN $queue_directory/$path and /$path differ done done --- 200,209 ---- do test -d $dir && find $dir -type f -print | while read path do ! test -e /$path && { ! cmp -s $path /$path || ! $WARN $queue_directory/$path and /$path differ ! } done done diff -cr /tmp/postfix-2.0.16/conf/sample-filter.cf ./conf/sample-filter.cf *** /tmp/postfix-2.0.16/conf/sample-filter.cf Tue Aug 12 12:19:10 2003 --- ./conf/sample-filter.cf Mon Sep 22 09:03:51 2003 *************** *** 159,169 **** # body_checks = regexp:/etc/postfix/body_checks ! # The body_checks_max_size parameter controls how much text in a # message body segment (or attachment, if you prefer to use that # term) is subjected to body_checks inspection. # # By default, only the first 50 kbytes of a message body segment are # inspected with body_checks patterns. # ! body_checks_max_size = 51200 --- 159,169 ---- # body_checks = regexp:/etc/postfix/body_checks ! # The body_checks_size_limit parameter controls how much text in a # message body segment (or attachment, if you prefer to use that # term) is subjected to body_checks inspection. # # By default, only the first 50 kbytes of a message body segment are # inspected with body_checks patterns. # ! body_checks_size_limit = 51200 diff -cr /tmp/postfix-2.0.16/conf/sample-smtpd.cf ./conf/sample-smtpd.cf *** /tmp/postfix-2.0.16/conf/sample-smtpd.cf Tue Aug 12 12:28:46 2003 --- ./conf/sample-smtpd.cf Fri Dec 12 11:34:08 2003 *************** *** 396,402 **** # $virtual_alias_domains, or $virtual_mailbox_domains. # - to destinations matching $relay_domains or subdomain thereof, # except for addresses with sender-specified routing. ! # reject_unauth_destination: reject mail unless it is sent # - to destinations matching $inet_interfaces, $mydestination, # $virtual_alias_domains, or $virtual_mailbox_domains. # - to destinations matching $relay_domains or subdomain thereof, --- 396,402 ---- # $virtual_alias_domains, or $virtual_mailbox_domains. # - to destinations matching $relay_domains or subdomain thereof, # except for addresses with sender-specified routing. ! # *reject_unauth_destination: reject mail unless it is sent # - to destinations matching $inet_interfaces, $mydestination, # $virtual_alias_domains, or $virtual_mailbox_domains. # - to destinations matching $relay_domains or subdomain thereof, diff -cr /tmp/postfix-2.0.16/makedefs ./makedefs *** /tmp/postfix-2.0.16/makedefs Thu Jan 23 08:45:02 2003 --- ./makedefs Wed Nov 5 14:50:15 2003 *************** *** 251,264 **** SYSLIBS="-lresolv -lsocket -lnsl" ;; Rhapsody.5*|Darwin.*) ! SYSTYPE=RHAPSODY5 # Use the native compiler by default : ${CC=cc} - AWK=gawk case $RELEASE in ! 1.[0-3]) ;; *) AWK=awk SYSLIBS=-flat_namespace ;; esac ;; --- 251,268 ---- SYSLIBS="-lresolv -lsocket -lnsl" ;; Rhapsody.5*|Darwin.*) ! SYSTYPE=MACOSX # Use the native compiler by default : ${CC=cc} case $RELEASE in ! 1.[0-3]) AWK=gawk ! ;; ! [2-6].*) AWK=awk ! SYSLIBS=-flat_namespace ! ;; *) AWK=awk SYSLIBS=-flat_namespace + CCARGS="$CCARGS -DBIND_8_COMPAT -DNO_NETINFO" ;; esac ;; diff -cr /tmp/postfix-2.0.16/src/cleanup/cleanup_out_recipient.c ./src/cleanup/cleanup_out_recipient.c *** /tmp/postfix-2.0.16/src/cleanup/cleanup_out_recipient.c Wed Feb 19 15:49:54 2003 --- ./src/cleanup/cleanup_out_recipient.c Mon Jan 5 15:40:19 2004 *************** *** 73,80 **** * onto the same mailbox. The recipient will use our original recipient * message header to figure things out. */ if (cleanup_virt_alias_maps == 0) { ! if (been_here(state->dups, "%s\n%s", orcpt, recip) == 0) { cleanup_out_string(state, REC_TYPE_ORCP, orcpt); cleanup_out_string(state, REC_TYPE_RCPT, recip); state->rcpt_count++; --- 73,83 ---- * onto the same mailbox. The recipient will use our original recipient * message header to figure things out. */ + #define STREQ(x, y) (strcmp((x), (y)) == 0) + if (cleanup_virt_alias_maps == 0) { ! if ((STREQ(orcpt, recip) ? been_here(state->dups, "%s", orcpt) : ! been_here(state->dups, "%s\n%s", orcpt, recip)) == 0) { cleanup_out_string(state, REC_TYPE_ORCP, orcpt); cleanup_out_string(state, REC_TYPE_RCPT, recip); state->rcpt_count++; *************** *** 83,89 **** argv = cleanup_map1n_internal(state, recip, cleanup_virt_alias_maps, cleanup_ext_prop_mask & EXT_PROP_VIRTUAL); for (cpp = argv->argv; *cpp; cpp++) { ! if (been_here(state->dups, "%s\n%s", orcpt, *cpp) == 0) { cleanup_out_string(state, REC_TYPE_ORCP, orcpt); cleanup_out_string(state, REC_TYPE_RCPT, *cpp); state->rcpt_count++; --- 86,93 ---- argv = cleanup_map1n_internal(state, recip, cleanup_virt_alias_maps, cleanup_ext_prop_mask & EXT_PROP_VIRTUAL); for (cpp = argv->argv; *cpp; cpp++) { ! if ((STREQ(orcpt, *cpp) ? been_here(state->dups, "%s", orcpt) : ! been_here(state->dups, "%s\n%s", orcpt, *cpp)) == 0) { cleanup_out_string(state, REC_TYPE_ORCP, orcpt); cleanup_out_string(state, REC_TYPE_RCPT, *cpp); state->rcpt_count++; diff -cr /tmp/postfix-2.0.16/src/dns/dns_lookup.c ./src/dns/dns_lookup.c *** /tmp/postfix-2.0.16/src/dns/dns_lookup.c Sun Dec 8 09:09:11 2002 --- ./src/dns/dns_lookup.c Tue Dec 16 09:27:52 2003 *************** *** 141,146 **** --- 141,147 ---- { HEADER *reply_header; int len; + unsigned long saved_options = _res.options; /* * Initialize the name service. *************** *** 167,172 **** --- 168,174 ---- * only if the name server told us so. */ len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf)); + _res.options = saved_options; if (len < 0) { if (why) vstring_sprintf(why, "Name service error for name=%s type=%s: %s", diff -cr /tmp/postfix-2.0.16/src/global/mail_queue.c ./src/global/mail_queue.c *** /tmp/postfix-2.0.16/src/global/mail_queue.c Thu Apr 24 11:20:06 2003 --- ./src/global/mail_queue.c Sat Jan 3 20:39:27 2004 *************** *** 285,317 **** { const char *cp; ! if (*queue_id == 0 || strlen(queue_id) > 100) return (0); /* ! * OK if in in time+inum form. */ ! for (cp = queue_id; /* void */ ; cp++) { ! if (*cp == 0) ! return (1); ! if (!ISALNUM(*cp)) ! break; ! } ! ! /* ! * BAD if in time.pid form. ! */ ! for (cp = queue_id; /* void */ ; cp++) { ! if (*cp == 0) return (0); ! if (!ISDIGIT(*cp) && *cp != '.') ! break; ! } ! ! /* ! * OK if in valid hostname form. ! */ ! return (valid_hostname(queue_id, DONT_GRIPE)); } /* mail_queue_enter - make mail queue entry with locally-unique name */ --- 285,300 ---- { const char *cp; ! if (*queue_id == 0 || strlen(queue_id) > VALID_HOSTNAME_LEN) return (0); /* ! * OK if in time+inum form or in host_domain_tld form. */ ! for (cp = queue_id; *cp; cp++) ! if (!ISALNUM(*cp) && *cp != '_') return (0); ! return (1); } /* mail_queue_enter - make mail queue entry with locally-unique name */ diff -cr /tmp/postfix-2.0.16/src/master/master_ent.c ./src/master/master_ent.c *** /tmp/postfix-2.0.16/src/master/master_ent.c Wed Jun 18 15:19:46 2003 --- ./src/master/master_ent.c Wed Nov 26 11:16:35 2003 *************** *** 303,309 **** MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *) mymalloc(sizeof(*MASTER_INET_ADDRLIST(serv))); inet_addr_list_init(MASTER_INET_ADDRLIST(serv)); ! inet_addr_host(MASTER_INET_ADDRLIST(serv), host); inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) { --- 303,311 ---- MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *) mymalloc(sizeof(*MASTER_INET_ADDRLIST(serv))); inet_addr_list_init(MASTER_INET_ADDRLIST(serv)); ! if (inet_addr_host(MASTER_INET_ADDRLIST(serv), host) == 0) ! msg_fatal("%s: line %d: bad hostname or network address: %s", ! VSTREAM_PATH(master_fp), master_line, host); inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) { diff -cr /tmp/postfix-2.0.16/src/master/master_sig.c ./src/master/master_sig.c *** /tmp/postfix-2.0.16/src/master/master_sig.c Thu Jul 11 12:42:38 2002 --- ./src/master/master_sig.c Tue Dec 23 15:30:59 2003 *************** *** 121,128 **** --- 121,139 ---- static void master_sigchld(int unused_sig) { + int saved_errno = errno; + + /* + * WARNING WARNING WARNING. + * + * This code runs at unpredictable moments, as a signal handler. Don't put + * any code here other than for setting a global flag, or code that is + * intended to be run within a signal handler. Restore errno in case we + * are interrupting the epilog of a failed system call. + */ if (write(SIG_PIPE_WRITE_FD, "", 1) != 1) msg_warn("write to SIG_PIPE_WRITE_FD failed: %m"); + errno = saved_errno; } /* master_sig_event - called upon return from select() */ diff -cr /tmp/postfix-2.0.16/src/nqmgr/qmgr_deliver.c ./src/nqmgr/qmgr_deliver.c *** /tmp/postfix-2.0.16/src/nqmgr/qmgr_deliver.c Wed Jan 22 16:42:55 2003 --- ./src/nqmgr/qmgr_deliver.c Mon Jan 19 18:09:23 2004 *************** *** 275,281 **** * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ ! if (status == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } --- 275,281 ---- * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ ! if (VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff -cr /tmp/postfix-2.0.16/src/qmgr/qmgr_deliver.c ./src/qmgr/qmgr_deliver.c *** /tmp/postfix-2.0.16/src/qmgr/qmgr_deliver.c Wed Jan 22 16:41:51 2003 --- ./src/qmgr/qmgr_deliver.c Mon Jan 19 18:08:51 2004 *************** *** 270,276 **** * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ ! if (status == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } --- 270,276 ---- * No problems detected. Mark the transport and queue as alive. The queue * itself won't go away before we dispose of the current queue entry. */ ! if (VSTRING_LEN(reason) == 0) { qmgr_transport_unthrottle(transport); qmgr_queue_unthrottle(queue); } diff -cr /tmp/postfix-2.0.16/src/util/match_ops.c ./src/util/match_ops.c *** /tmp/postfix-2.0.16/src/util/match_ops.c Mon Apr 14 10:44:19 2003 --- ./src/util/match_ops.c Sat Sep 13 22:08:15 2003 *************** *** 69,75 **** #endif #ifndef INADDR_NONE ! #define INADDR_NONE 0xffffff #endif /* Utility library. */ --- 69,75 ---- #endif #ifndef INADDR_NONE ! #define INADDR_NONE 0xffffffff #endif /* Utility library. */ diff -cr /tmp/postfix-2.0.16/src/util/msg_syslog.c ./src/util/msg_syslog.c *** /tmp/postfix-2.0.16/src/util/msg_syslog.c Sat Sep 13 21:34:33 2003 --- ./src/util/msg_syslog.c Mon Jan 19 16:54:12 2004 *************** *** 174,180 **** * This scrubbing code is in the wrong place. */ if (unsafe()) ! putenv("TZ="); tzset(); openlog(name, LOG_NDELAY | logopt, facility); if (first_call) { --- 174,180 ---- * This scrubbing code is in the wrong place. */ if (unsafe()) ! putenv("TZ=UTC"); tzset(); openlog(name, LOG_NDELAY | logopt, facility); if (first_call) { diff -cr /tmp/postfix-2.0.16/src/util/sys_defs.h ./src/util/sys_defs.h *** /tmp/postfix-2.0.16/src/util/sys_defs.h Wed Sep 10 20:33:31 2003 --- ./src/util/sys_defs.h Wed Nov 5 15:17:37 2003 *************** *** 98,104 **** --- 98,106 ---- #define NORETURN void #define PRINTFLIKE(x,y) #define SCANFLIKE(x,y) + #ifndef NO_NETINFO #define HAS_NETINFO + #endif #define NATIVE_SENDMAIL_PATH "/usr/sbin/sendmail" #define NATIVE_MAILQ_PATH "/usr/bin/mailq" #define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases" diff -cr /tmp/postfix-2.0.16/src/util/vstring_vstream.c ./src/util/vstring_vstream.c *** /tmp/postfix-2.0.16/src/util/vstring_vstream.c Fri Nov 9 13:48:42 2001 --- ./src/util/vstring_vstream.c Sun Jan 4 17:26:27 2004 *************** *** 95,101 **** break; } VSTRING_TERMINATE(vp); ! return (VSTRING_GET_RESULT(vp)); } /* vstring_get_nonl - read line from file, strip newline */ --- 95,101 ---- break; } VSTRING_TERMINATE(vp); ! return (c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_nonl - read line from file, strip newline */ *************** *** 108,114 **** while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n') VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == '\n' ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_null - read null-terminated string from file */ --- 108,114 ---- while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n') VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == '\n' || c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_null - read null-terminated string from file */ *************** *** 121,127 **** while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0) VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == 0 ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_bound - read line from file, keep newline, up to bound */ --- 121,127 ---- while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0) VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == 0 || c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_bound - read line from file, keep newline, up to bound */ *************** *** 140,146 **** break; } VSTRING_TERMINATE(vp); ! return (VSTRING_GET_RESULT(vp)); } /* vstring_get_nonl_bound - read line from file, strip newline, up to bound */ --- 140,146 ---- break; } VSTRING_TERMINATE(vp); ! return (c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_nonl_bound - read line from file, strip newline, up to bound */ *************** *** 156,162 **** while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n') VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == '\n' ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_null_bound - read null-terminated string from file */ --- 156,162 ---- while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != '\n') VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == '\n' || c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } /* vstring_get_null_bound - read null-terminated string from file */ *************** *** 172,178 **** while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0) VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == 0 ? c : VSTRING_GET_RESULT(vp)); } #ifdef TEST --- 172,178 ---- while (bound-- > 0 && (c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0) VSTRING_ADDCH(vp, c); VSTRING_TERMINATE(vp); ! return (c == 0 || c == VSTREAM_EOF ? c : VSTRING_GET_RESULT(vp)); } #ifdef TEST