Postfix 19991231 patch 09 fixes a memory corruption problem, and includes a long list of minor bugfixes and robustness improvements that already featured in snapshot releases. - When propagating an address extension to the right-hand side of a virtual or canonical mapping, the cleanup server could access memory that was no longer allocated and die with signal 11. This would happen when the result address length was more than about 100 characters. Credit to Adi Prasaja @ satunet.com for coming up with a small reproducible demo. At 800 lines, the patch is too large for distribution via email. Instead, it is being made available via the the usual FTP servers, primary site: ftp://ftp.porcupine.org/mirrors/postfix-release/official/ Files: postfix-19991231-patch09.gz This patch postfix-19991231-pl09.tar.gz Fully-patched source code postfix-19991231-pl09.tar.gz.sig PGP signature for source code Or, if you use a web browser, ftp://ftp.porcupine.org/mirrors/postfix-release/index.html Happy Postfixing. Wietse Prereq: "Postfix-19991231-pl08" diff -cr ../postfix-19991231-pl08/global/mail_version.h ./global/mail_version.h *** ../postfix-19991231-pl08/global/mail_version.h Sun May 28 18:53:10 2000 --- ./global/mail_version.h Sun Sep 17 09:52:53 2000 *************** *** 15,21 **** * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "Postfix-19991231-pl08" extern char *var_mail_version; /* LICENSE --- 15,21 ---- * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "Postfix-19991231-pl09" extern char *var_mail_version; /* LICENSE diff -cr ../postfix-19991231-pl08/HISTORY ./HISTORY *** ../postfix-19991231-pl08/HISTORY Sun May 28 18:50:49 2000 --- ./HISTORY Sun Sep 17 21:25:53 2000 *************** *** 3639,3648 **** --- 3639,3658 ---- 20000308 + Bugfix: the unused db and dbm "delete" routines would + clobber the per-dictionary flags when called before reading + or writing the table. Files: util/dict_dbm.c, util/dict_db.c. + Lutz Jaenicke @ aet.TU-Cottbus.DE. + Bugfix: the SMTP server would produce a cryptic message when a queue file write error happened before it had written any recipients. Keith Stevenson. File: smtpd/smtpd.c. + Robustness: the db and dbm "delete" routines didn't adjust + to dictionaries with/without one trailing null in lookup + keys and values. Did a complete rewrite of the routines. + Files: util/dict_db.c, util/dict_dbm.c. + 20000311 Portability: HP-UX awk can't handle bare { in regexps *************** *** 3732,3734 **** --- 3742,3828 ---- feature uses the same filtering syntax as the header_checks feature. File: cleanup/cleanup_message.c. See also the conf/sample-filter.cf file. + + 20000617 + + Bugfix: the maildir delivery routine left temporary files + lying around after unsuccessful delivery (problem reported + by Brian Laughton @ Corp.Axxent.Ca). + + 20000621 + + AIX 4.x had POSIX regular expression support all the time + I was working on Postfix. Beter find out late than never. + + 20000623 + + Bugfix: the SMTP server did not reset the so-called junk + command counter after successfull delivery (Mark Hoffman + @ wallst.com). File: smtpd/smtpd.c. + + 20000708 + + Portability: support for NEXT/OPENSTEP requires extra + include file in util/watchdog.c (Masaki Murase). + + 20000718 + + Robustness: make_dirs() now continues when a missing + directory is created by another process. + + 20000726 + + Robustness: added watchdog_pat() routine to keep the watchdog + quiet if a client stays connected for a lot of time. Files: + util/watchdog.[hc], smtpd/smtpd.c. + + 20000729 + + Robustness: if relayhost is specified but the host does + not exist, defer mail instead of bouncing it (which would + lose the mail if the bounce would have to be delivered to + that same non-existent relayhost). Problem reported by + Chris Cooper @ maths.ox.ac.uk. File: smtp/smtp_connect.c. + + 20000821 + + Cleanup: smtpd now replies with 555 when the client sends + unrecognized RCPT TO parameters, as required by RFC 1869 + (problem report by Robert Norris @ its.monash.edu.au). + File: smtpd/smtpd.c. + + 20000905 + + Robustness: the dns client now rejects malformed domain + names rather than depending on the DNS to report that the + name does not exist. Linux returns a rather misleading + server failure code as found out by Patrik Rak. File: + dns/dns_lookup.c. + + 20000913 + + Bugfix: the rmail script did not handle remote UUCP systems + that send a from_ line with unqualified envelope sender. + Reported by Luciano Mannucci. + + Compatibility: don't insert Sender: header lines. Sendmail + has not done so for at least 10 years, if it ever did. + Problem reported by Brad Knowles. File: cleanup/cleanup_message.c. + + 20000916 + + Bugfix: when propagating an address extension in a virtual + or canonical mapping, cleanup accesses memory that is no + longer allocated. This can happen when the result address + length is more than 100 characters. Problem reported by + Adi Prasaja @ satunet.com. File: global/mail_addr_crunch.c. + + Bugfix: fixed a misleading error message when the cleanup + server reaches the queue file size limit. Fix by Robby + Griffin @ MIT.EDU. File: cleanup/cleanup_message.c. + + 20000917 + + Bugfix: postalias -i would complain about duplicate entries + for the Sendmail-compatible @ entry and for the NIS-compatible + YP_LAST_MODIFIED and YP_MASTER_NAME entries. diff -cr ../postfix-19991231-pl08/auxiliary/rmail/rmail ./auxiliary/rmail/rmail *** ../postfix-19991231-pl08/auxiliary/rmail/rmail Mon May 31 10:12:49 1999 --- ./auxiliary/rmail/rmail Sun Sep 17 21:39:44 2000 *************** *** 3,8 **** # Dummy UUCP rmail command for postfix/qmail systems SENDMAIL="/usr/sbin/sendmail" ! IFS=" " read junk from junk exec $SENDMAIL -f "$from" -- "$@" --- 3,13 ---- # Dummy UUCP rmail command for postfix/qmail systems SENDMAIL="/usr/sbin/sendmail" ! IFS=" " read junk from junk junk junk junk junk junk junk relay ! ! case "$from" in ! *[@!]*) ;; ! *) from="$from@$relay";; ! esac exec $SENDMAIL -f "$from" -- "$@" diff -cr ../postfix-19991231-pl08/cleanup/cleanup_message.c ./cleanup/cleanup_message.c *** ../postfix-19991231-pl08/cleanup/cleanup_message.c Sun May 28 21:20:35 2000 --- ./cleanup/cleanup_message.c Sat Sep 16 18:46:47 2000 *************** *** 321,328 **** } /* ! * Add a missing (Resent-)From: header. If a (Resent-)From: header is ! * present, see if we need a (Resent-)Sender: header. */ #define NOT_SPECIAL_SENDER(addr) (*(addr) != 0 \ && strcasecmp(addr, mail_addr_double_bounce()) != 0) --- 321,327 ---- } /* ! * Add a missing (Resent-)From: header. */ #define NOT_SPECIAL_SENDER(addr) (*(addr) != 0 \ && strcasecmp(addr, mail_addr_double_bounce()) != 0) *************** *** 340,354 **** vstring_strcat(cleanup_temp2, ")"); } CLEANUP_OUT_BUF(REC_TYPE_NORM, cleanup_temp2); - } else if ((cleanup_headers_seen & (1 << (cleanup_resent[0] ? - HDR_RESENT_SENDER : HDR_SENDER))) == 0 - && NOT_SPECIAL_SENDER(cleanup_sender)) { - from = (cleanup_resent[0] ? cleanup_resent_from : cleanup_from); - if (from == 0 || strcasecmp(cleanup_sender, from) != 0) { - quote_822_local(cleanup_temp1, cleanup_sender); - cleanup_out_format(REC_TYPE_NORM, "%sSender: %s", - cleanup_resent, vstring_str(cleanup_temp1)); - } } /* --- 339,344 ---- *************** *** 497,507 **** if ((xtra_offset = vstream_ftell(cleanup_dst)) < 0) msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path); if (vstream_fseek(cleanup_dst, mesg_offset, SEEK_SET) < 0) { ! msg_warn("%s: write queue file: %m", cleanup_queue_id); ! if (errno == EFBIG) cleanup_errs |= CLEANUP_STAT_SIZE; ! else cleanup_errs |= CLEANUP_STAT_WRITE; break; } cleanup_out_format(REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, xtra_offset); --- 487,500 ---- if ((xtra_offset = vstream_ftell(cleanup_dst)) < 0) msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path); if (vstream_fseek(cleanup_dst, mesg_offset, SEEK_SET) < 0) { ! if (errno == EFBIG) { ! msg_warn("%s: queue file size limit exceeded", ! cleanup_queue_id); cleanup_errs |= CLEANUP_STAT_SIZE; ! } else { ! msg_warn("%s: write queue file: %m", cleanup_queue_id); cleanup_errs |= CLEANUP_STAT_WRITE; + } break; } cleanup_out_format(REC_TYPE_MESG, REC_TYPE_MESG_FORMAT, xtra_offset); diff -cr ../postfix-19991231-pl08/dns/dns_lookup.c ./dns/dns_lookup.c *** ../postfix-19991231-pl08/dns/dns_lookup.c Fri Nov 26 23:02:29 1999 --- ./dns/dns_lookup.c Sun Sep 17 10:03:01 2000 *************** *** 109,114 **** --- 109,115 ---- #include #include #include + #include /* DNS library. */ *************** *** 429,434 **** --- 430,445 ---- DNS_REPLY reply; int count; int status; + + /* + * The Linux resolver misbehaves when given an invalid domain name. + */ + if (!valid_hostname(name)) { + if (why) + vstring_sprintf(why, "Name service error for %s: invalid name", + name); + return (DNS_NOTFOUND); + } /* * Perform the lookup. Follow CNAME chains, but only up to a diff -cr ../postfix-19991231-pl08/global/mail_addr_crunch.c ./global/mail_addr_crunch.c *** ../postfix-19991231-pl08/global/mail_addr_crunch.c Sun Apr 25 18:05:41 1999 --- ./global/mail_addr_crunch.c Sat Sep 16 18:39:16 2000 *************** *** 88,93 **** --- 88,94 ---- vstring_strcat(canon_addr, extension); } else { VSTRING_SPACE(canon_addr, extlen + 1); + ratsign = strrchr(STR(canon_addr), '@'); memmove(ratsign + extlen, ratsign, strlen(ratsign) + 1); memcpy(ratsign, extension, extlen); VSTRING_SKIP(canon_addr); diff -cr ../postfix-19991231-pl08/local/maildir.c ./local/maildir.c *** ../postfix-19991231-pl08/local/maildir.c Sat Jan 22 16:35:41 2000 --- ./local/maildir.c Sat Sep 16 19:45:32 2000 *************** *** 143,153 **** || sane_link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); } else { - if (unlink(tmpfile) < 0) - msg_warn("remove %s: %m", tmpfile); status = 0; } } } set_eugid(var_owner_uid, var_owner_gid); --- 143,153 ---- || sane_link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); } else { status = 0; } } + if (unlink(tmpfile) < 0) + msg_warn("remove %s: %m", tmpfile); } set_eugid(var_owner_uid, var_owner_gid); diff -cr ../postfix-19991231-pl08/makedefs ./makedefs *** ../postfix-19991231-pl08/makedefs Sat Jan 22 14:04:27 2000 --- ./makedefs Sat Sep 16 19:37:00 2000 *************** *** 145,151 **** case "$CC" in cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w";; esac ! CCARGS="$CCARGS -D_ALL_SOURCE" ;; 3) SYSTYPE=AIX3 # How embarrassing... --- 145,151 ---- case "$CC" in cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w";; esac ! CCARGS="$CCARGS -D_ALL_SOURCE -DHAS_POSIX_REGEXP" ;; 3) SYSTYPE=AIX3 # How embarrassing... diff -cr ../postfix-19991231-pl08/postalias/postalias.c ./postalias/postalias.c *** ../postfix-19991231-pl08/postalias/postalias.c Thu Dec 9 17:21:58 1999 --- ./postalias/postalias.c Sun Sep 17 18:57:28 2000 *************** *** 252,257 **** --- 252,263 ---- } /* + * Update or append sendmail and NIS signatures. + */ + if ((open_flags & O_TRUNC) == 0) + mkmap->dict->flags |= DICT_FLAG_DUP_REPLACE; + + /* * Sendmail compatibility: add the @:@ signature to indicate that the * database is complete. This might be needed by NIS clients running * sendmail. diff -cr ../postfix-19991231-pl08/smtp/smtp_connect.c ./smtp/smtp_connect.c *** ../postfix-19991231-pl08/smtp/smtp_connect.c Wed Mar 8 19:05:13 2000 --- ./smtp/smtp_connect.c Sat Sep 16 19:13:59 2000 *************** *** 359,364 **** --- 359,370 ---- } else { session = smtp_connect_domain(host, port, why); } + if (session == 0 + && smtp_errno == SMTP_FAIL + && strcmp(host, var_relayhost) == 0) { + msg_warn("relayhost configuration problem: %s", var_relayhost); + smtp_errno = SMTP_RETRY; + } myfree(dest_buf); return (session); } diff -cr ../postfix-19991231-pl08/smtpd/smtpd.c ./smtpd/smtpd.c *** ../postfix-19991231-pl08/smtpd/smtpd.c Thu May 11 19:11:58 2000 --- ./smtpd/smtpd.c Sat Sep 16 19:35:28 2000 *************** *** 233,238 **** --- 233,239 ---- #include #include #include + #include /* Global library. */ *************** *** 663,668 **** --- 664,671 ---- static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { char *err; + int narg; + char *arg; /* * Sanity checks. *************** *** 672,678 **** smtpd_chat_reply(state, "503 Error: need MAIL command"); return (-1); } ! if (argc != 3 || strcasecmp(argv[1].strval, "to:") != 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Syntax: RCPT TO:
"); --- 675,681 ---- smtpd_chat_reply(state, "503 Error: need MAIL command"); return (-1); } ! if (argc < 3 || strcasecmp(argv[1].strval, "to:") != 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Syntax: RCPT TO:
"); *************** *** 688,693 **** --- 691,704 ---- smtpd_chat_reply(state, "%s", err); return (-1); } + for (narg = 3; narg < argc; narg++) { + arg = argv[narg].strval; + if (1) { + state->error_mask |= MAIL_ERROR_PROTOCOL; + smtpd_chat_reply(state, "555 Unsupported option: %s", arg); + return (-1); + } + } if (var_smtpd_rcpt_limit && state->rcpt_count >= var_smtpd_rcpt_limit) { state->error_mask |= MAIL_ERROR_POLICY; smtpd_chat_reply(state, "452 Error: too many recipients"); *************** *** 854,859 **** --- 865,871 ---- if (state->err == CLEANUP_STAT_OK) { state->error_count = 0; state->error_mask = 0; + state->junk_cmds = 0; smtpd_chat_reply(state, "250 Ok: queued as %s", state->queue_id); } else if ((state->err & CLEANUP_STAT_BAD) != 0) { state->error_mask |= MAIL_ERROR_SOFTWARE; *************** *** 1119,1124 **** --- 1131,1137 ---- smtpd_chat_reply(state, "421 Error: too many errors"); break; } + watchdog_pat(); smtpd_chat_query(state); if ((argc = smtpd_token(vstring_str(state->buffer), &argv)) == 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; diff -cr ../postfix-19991231-pl08/util/dict_db.c ./util/dict_db.c *** ../postfix-19991231-pl08/util/dict_db.c Tue Aug 31 12:55:15 1999 --- ./util/dict_db.c Sat Sep 16 19:58:09 2000 *************** *** 165,174 **** && (dict->flags & DICT_FLAG_TRY0NULL)) { #ifdef DB_NO_TRAILING_NULL dict->flags &= ~DICT_FLAG_TRY1NULL; - dict->flags |= DICT_FLAG_TRY0NULL; #else dict->flags &= ~DICT_FLAG_TRY0NULL; - dict->flags |= DICT_FLAG_TRY1NULL; #endif } --- 165,172 ---- *************** *** 210,257 **** /* delete one entry from the dictionary */ ! static int dict_db_delete(DICT *dict, const char *key) { DICT_DB *dict_db = (DICT_DB *) dict; DB *db = dict_db->db; DBT db_key; ! int status; int flags = 0; - db_key.data = (void *) key; - db_key.size = strlen(key); - /* ! * If undecided about appending a null byte to key and value, choose a ! * default depending on the platform. */ ! if ((dict->flags & DICT_FLAG_TRY1NULL) ! && (dict->flags & DICT_FLAG_TRY0NULL)) { ! #ifdef DB_NO_TRAILING_NULL ! dict->flags = DICT_FLAG_TRY0NULL; ! #else ! dict->flags = DICT_FLAG_TRY1NULL; ! #endif ! } /* ! * Optionally append a null byte to key and value. */ if (dict->flags & DICT_FLAG_TRY1NULL) { ! db_key.size++; } /* ! * Acquire an exclusive lock. ! */ ! if ((dict->flags & DICT_FLAG_LOCK) && myflock(dict->fd, MYFLOCK_EXCLUSIVE) < 0) ! msg_fatal("%s: lock dictionary: %m", dict_db->path); ! ! /* ! * Do the delete operation. */ ! if ((status = db->del(db, &db_key, flags)) < 0) ! msg_fatal("error deleting %s: %m", dict_db->path); /* * Release the exclusive lock. --- 208,252 ---- /* delete one entry from the dictionary */ ! static int dict_db_delete(DICT *dict, const char *name) { DICT_DB *dict_db = (DICT_DB *) dict; DB *db = dict_db->db; DBT db_key; ! int status = 1; int flags = 0; /* ! * Acquire an exclusive lock. */ ! if ((dict->flags & DICT_FLAG_LOCK) && myflock(dict->fd, MYFLOCK_EXCLUSIVE) < 0) ! msg_fatal("%s: lock dictionary: %m", dict_db->path); /* ! * See if this DB file was written with one null byte appended to key and ! * value. */ if (dict->flags & DICT_FLAG_TRY1NULL) { ! db_key.data = (void *) name; ! db_key.size = strlen(name) + 1; ! if ((status = db->del(db, &db_key, flags)) < 0) ! msg_fatal("error deleting from %s: %m", dict_db->path); ! if (status == 0) ! dict->flags &= ~DICT_FLAG_TRY0NULL; } /* ! * See if this DB file was written with no null byte appended to key and ! * value. */ ! if (status > 0 && (dict->flags & DICT_FLAG_TRY0NULL)) { ! db_key.data = (void *) name; ! db_key.size = strlen(name); ! if ((status = db->del(db, &db_key, flags)) < 0) ! msg_fatal("error deleting from %s: %m", dict_db->path); ! if (status == 0) ! dict->flags &= ~DICT_FLAG_TRY1NULL; ! } /* * Release the exclusive lock. diff -cr ../postfix-19991231-pl08/util/dict_dbm.c ./util/dict_dbm.c *** ../postfix-19991231-pl08/util/dict_dbm.c Sat Sep 4 17:04:04 1999 --- ./util/dict_dbm.c Sat Sep 16 19:56:00 2000 *************** *** 141,150 **** && (dict->flags & DICT_FLAG_TRY0NULL)) { #ifdef DBM_NO_TRAILING_NULL dict->flags &= ~DICT_FLAG_TRY1NULL; - dict->flags |= DICT_FLAG_TRY0NULL; #else dict->flags &= ~DICT_FLAG_TRY0NULL; - dict->flags |= DICT_FLAG_TRY1NULL; #endif } --- 141,148 ---- *************** *** 186,232 **** /* dict_dbm_delete - delete one entry from the dictionary */ ! static int dict_dbm_delete(DICT *dict, const char *key) { DICT_DBM *dict_dbm = (DICT_DBM *) dict; datum dbm_key; ! int status; int flags = 0; - dbm_key.dptr = (void *) key; - dbm_key.dsize = strlen(key); - /* ! * If undecided about appending a null byte to key and value, choose a ! * default depending on the platform. */ ! if ((dict->flags & DICT_FLAG_TRY1NULL) ! && (dict->flags & DICT_FLAG_TRY0NULL)) { ! #ifdef DBM_NO_TRAILING_NULL ! dict->flags = DICT_FLAG_TRY0NULL; ! #else ! dict->flags = DICT_FLAG_TRY1NULL; ! #endif ! } /* ! * Optionally append a null byte to key and value. */ if (dict->flags & DICT_FLAG_TRY1NULL) { ! dbm_key.dsize++; } /* ! * Acquire an exclusive lock. ! */ ! if ((dict->flags & DICT_FLAG_LOCK) && myflock(dict->fd, MYFLOCK_EXCLUSIVE) < 0) ! msg_fatal("%s: lock dictionary: %m", dict_dbm->path); ! ! /* ! * Do the delete operation. */ ! if ((status = dbm_delete(dict_dbm->dbm, dbm_key)) < 0) ! msg_fatal("error deleting %s: %m", dict_dbm->path); /* * Release the exclusive lock. --- 184,235 ---- /* dict_dbm_delete - delete one entry from the dictionary */ ! static int dict_dbm_delete(DICT *dict, const char *name) { DICT_DBM *dict_dbm = (DICT_DBM *) dict; datum dbm_key; ! int status = 1; int flags = 0; /* ! * Acquire an exclusive lock. */ ! if ((dict->flags & DICT_FLAG_LOCK) && myflock(dict->fd, MYFLOCK_EXCLUSIVE) < 0) ! msg_fatal("%s: lock dictionary: %m", dict_dbm->path); /* ! * See if this DBM file was written with one null byte appended to key ! * and value. */ if (dict->flags & DICT_FLAG_TRY1NULL) { ! dbm_key.dptr = (void *) name; ! dbm_key.dsize = strlen(name) + 1; ! dbm_clearerr(dict_dbm->dbm); ! if ((status = dbm_delete(dict_dbm->dbm, dbm_key)) < 0) { ! if (dbm_error(dict_dbm->dbm) != 0) /* fatal error */ ! msg_fatal("error deleting from %s: %m", dict_dbm->path); ! status = 1; /* not found */ ! } else { ! dict->flags &= ~DICT_FLAG_TRY0NULL; /* found */ ! } } /* ! * See if this DBM file was written with no null byte appended to key and ! * value. */ ! if (status > 0 && (dict->flags & DICT_FLAG_TRY0NULL)) { ! dbm_key.dptr = (void *) name; ! dbm_key.dsize = strlen(name); ! dbm_clearerr(dict_dbm->dbm); ! if ((status = dbm_delete(dict_dbm->dbm, dbm_key)) < 0) { ! if (dbm_error(dict_dbm->dbm) != 0) /* fatal error */ ! msg_fatal("error deleting from %s: %m", dict_dbm->path); ! status = 1; /* not found */ ! } else { ! dict->flags &= ~DICT_FLAG_TRY1NULL; /* found */ ! } ! } /* * Release the exclusive lock. diff -cr ../postfix-19991231-pl08/util/make_dirs.c ./util/make_dirs.c *** ../postfix-19991231-pl08/util/make_dirs.c Sat Jan 15 22:02:04 2000 --- ./util/make_dirs.c Sat Sep 16 19:26:34 2000 *************** *** 78,85 **** ret = -1; break; } ! } else if (errno != ENOENT || (ret = mkdir(saved_path, perms)) < 0) ! break; if (saved_ch != 0) *cp = saved_ch; SKIP_WHILE(*cp == '/', cp); --- 78,89 ---- ret = -1; break; } ! } else { ! if (errno != ENOENT) ! break; ! if ((ret = mkdir(saved_path, perms)) < 0 && errno != EEXIST) ! break; ! } if (saved_ch != 0) *cp = saved_ch; SKIP_WHILE(*cp == '/', cp); diff -cr ../postfix-19991231-pl08/util/watchdog.c ./util/watchdog.c *** ../postfix-19991231-pl08/util/watchdog.c Wed Nov 17 20:15:56 1999 --- ./util/watchdog.c Sat Sep 16 19:27:58 2000 *************** *** 19,24 **** --- 19,26 ---- /* /* void watchdog_destroy(watchdog) /* WATCHDOG *watchdog; + /* + /* void watchdog_pat() /* DESCRIPTION /* This module implements watchdog timers that are based on ugly /* UNIX alarm timers. The module is designed to survive systems *************** *** 39,44 **** --- 41,48 ---- /* watchdog_destroy() stops the watchdog timer, and resumes the /* watchdog timer instance that was suspended by watchdog_create(). /* + /* watchdog_pat() pats the watchdog, so it stays quiet. + /* /* Arguments: /* .IP timeout /* The watchdog time limit. When the watchdog timer runs, the *************** *** 77,82 **** --- 81,87 ---- #include #include #include + #include /* Utility library. */ *************** *** 212,217 **** --- 217,234 ---- msg_info("%s: %p", myname, (char *) wp); } + /* watchdog_pat - pat the dog so it stays quiet */ + + void watchdog_pat(void) + { + char *myname = "watchdog_pat"; + + if (watchdog_curr) + watchdog_curr->trip_run = 0; + if (msg_verbose) + msg_info("%s: %p", myname, (char *) watchdog_curr); + } + #ifdef TEST #include *************** *** 223,230 **** msg_verbose = 1; wp = watchdog_create(10, (WATCHDOG_FN) 0, (char *) 0); do { ! watchdog_start(wp); } while (VSTREAM_GETCHAR() != VSTREAM_EOF); watchdog_destroy(wp); } --- 240,248 ---- msg_verbose = 1; wp = watchdog_create(10, (WATCHDOG_FN) 0, (char *) 0); + watchdog_start(wp); do { ! watchdog_pat(); } while (VSTREAM_GETCHAR() != VSTREAM_EOF); watchdog_destroy(wp); } diff -cr ../postfix-19991231-pl08/util/watchdog.h ./util/watchdog.h *** ../postfix-19991231-pl08/util/watchdog.h Thu Nov 4 15:33:07 1999 --- ./util/watchdog.h Sat Sep 16 19:27:58 2000 *************** *** 20,25 **** --- 20,26 ---- extern void watchdog_start(WATCHDOG *); extern void watchdog_stop(WATCHDOG *); extern void watchdog_destroy(WATCHDOG *); + extern void watchdog_pat(void); /* LICENSE /* .ad