2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

snapshot-20010501

This commit is contained in:
Wietse Venema
2001-05-01 00:00:00 -05:00
committed by Viktor Dukhovni
parent fc7670eff8
commit 6d2c0a5a12
38 changed files with 369 additions and 190 deletions

View File

@@ -5050,11 +5050,11 @@ Apologies for any names omitted.
20010411
Compatibility: the SMTP server now replies with 550 instead
of 503 when it receives the DATA command without having
received a valid recipient address. This is needed for the
Sendmail client-side pipelining implementation. Problem
reported by Lutz Jaenicke. File: smtpd/smtpd.c.
Bugfix: the SMTP server now replies with 550 instead of
503 when it receives the DATA command without having received
a valid recipient address. This is needed for the Sendmail
client-side pipelining implementation. Problem reported by
Lutz Jaenicke. File: smtpd/smtpd.c.
Cleanup: shut up if chattr fails on Reiserfs and other file
systems that do not support the respective attributes.
@@ -5080,9 +5080,10 @@ Apologies for any names omitted.
20010426
Workaround: the SMTP server did not really parse invalid
addresses such as <first last <user@domain>> well. I
thought this was taken care of years ago. File: smtpd/smtpd.c.
Bugfix: the SMTP server did not parse invalid MAIL FROM or
RCPT TO addresses such as <first last <user@domain>> the
way it was supposed to do. I thought this was taken care
of years ago. File: smtpd/smtpd.c.
20010427
@@ -5095,4 +5096,26 @@ Apologies for any names omitted.
Feature: the Postfix SMTP client now by default randomly
shuffles destination IP addresses of equal preference.
File: smtp/smtp_addr.c. Based on an idea by Aleph1.
Specify "smtp_randomize_addresses = no" to disable.
Shuffling code by Elias Levy @ SecurityFocus.com Files:
dns/dns_rr.c, smtp/smtp_addr.c.
20010501
Bugfix: The SMTP server's 550 in reply to DATA should be
a 554 response. And it wasn't Sendmail. Claus Assman.
Bugfix: the INSTALL.sh test for non-interactive upgrade
broke rooted installations that specify settings via the
environment. Simon Mudd.
Bugfix: mailq output is now really flushed one message at
a time. File: sendmail/sendmail.c.
Feature: "postsuper -d queueID" deletes one message queue
file; "postsuper -d -" reads zero or more queue IDs from
standard input. In order to make this operation usable
with a running Postfix mail system, some routines were made
more tolerant for sudden queue file disappearances. Files:
postsuper/postsuper.c, global/deliver_request.c,
*qmgr/qmgr_move.c.

View File

@@ -166,15 +166,17 @@ test -f $CONFIG_DIRECTORY/main.cf && {
done
}
test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf || {
test -t 0 || {
echo Non-interactive install needs the $CONFIG_DIRECTORY/install.cf 1>&2
echo file from a previous Postfix installation. 1>&2
echo 1>&2
echo Use interactive installation instead. 1>&2
exit 1
}
}
if [ -f $CONFIG_DIRECTORY/install.cf ]
then
. $CONFIG_DIRECTORY/install.cf
elif [ ! -t 0 -a -z "$install_root" ]
then
echo Non-interactive install needs the $CONFIG_DIRECTORY/install.cf 1>&2
echo file from a previous Postfix installation. 1>&2
echo 1>&2
echo Use interactive installation instead. 1>&2
exit 1
fi
# Override default settings.

View File

@@ -9,7 +9,7 @@ MASTER(8) MASTER(8)
master - Postfix master process
<b>SYNOPSIS</b>
<b>master</b> [<b>-c</b> <i>config_dir</i>] [<b>-D</b>] [<b>-t</b>] [<b>-v</b>]
<b>master</b> [<b>-c</b> <i>config_dir</i>] [<b>-e</b> <i>exit_time</i>] [<b>-D</b>] [<b>-t</b>] [<b>-v</b>]
<b>DESCRIPTION</b>
The <b>master</b> daemon is the resident process that runs Post-
@@ -37,6 +37,11 @@ MASTER(8) MASTER(8)
in the named directory instead of the default con-
figuration directory.
<b>-e</b> <i>exit_time</i>
Terminate the master process after <i>exit_time</i> sec-
onds. Child processes terminate at their conve-
nience.
<b>-D</b> After initialization, run a debugger on the master
process. The debugging command is specified with
the <b>debugger</b><i>_</i><b>command</b> in the <b>main.cf</b> global configu-
@@ -54,11 +59,6 @@ MASTER(8) MASTER(8)
Signals:
<b>SIGHUP</b> Upon receipt of a <b>HUP</b> signal (e.g., after <b>postfix</b>
<b>reload</b>), the master process re-reads its configura-
tion files. If a service has been removed from the
<b>master.cf</b> file, its running processes are termi-
nated immediately. Otherwise, running processes
are allowed to terminate as soon as is convenient,
@@ -71,6 +71,11 @@ MASTER(8) MASTER(8)
MASTER(8) MASTER(8)
<b>reload</b>), the master process re-reads its configura-
tion files. If a service has been removed from the
<b>master.cf</b> file, its running processes are termi-
nated immediately. Otherwise, running processes
are allowed to terminate as soon as is convenient,
so that changes in configuration settings affect
only new service requests.
@@ -119,11 +124,6 @@ MASTER(8) MASTER(8)
<b>daemon</b><i>_</i><b>directory</b>
Directory with Postfix daemon programs.
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue. This is
also the root directory of Postfix daemons that run
chrooted.
@@ -137,6 +137,11 @@ MASTER(8) MASTER(8)
MASTER(8) MASTER(8)
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue. This is
also the root directory of Postfix daemons that run
chrooted.
<b>Resource</b> <b>controls</b>
<b>default</b><i>_</i><b>process</b><i>_</i><b>limit</b>
Default limit for the number of simultaneous child
@@ -188,11 +193,6 @@ MASTER(8) MASTER(8)
3

View File

@@ -9,7 +9,7 @@ POSTSUPER(1) POSTSUPER(1)
postsuper - Postfix super intendent
<b>SYNOPSIS</b>
<b>postsuper</b> [<b>-p</b>] [<b>-s</b>] [<b>-v</b>] [<i>directory</i> <i>...</i>]
<b>postsuper</b> [<b>-d</b> <i>queue_id</i>] [<b>-p</b>] [<b>-s</b>] [<b>-v</b>] [<i>directory</i> <i>...</i>]
<b>DESCRIPTION</b>
The <b>postsuper</b> command does small maintenance jobs on the
@@ -25,40 +25,40 @@ POSTSUPER(1) POSTSUPER(1)
Options:
<b>-s</b> Structure check. Move queue files that are in the
<b>-d</b> Delete one message queue file with the named queue
ID. Specify multiple <b>-d</b> options to delete multiple
queue files by name.
Alternatively, if a <i>queue_id</i> of <b>-</b> is specified, the
program reads queue IDs from standard input.
This operation can be performed safely while the
mail system is running, although the queue manager
may issue warnings when a file suddenly disappears.
The exit status is zero if at least one of the
named message queue files was found.
<b>-s</b> Structure check. Move queue files that are in the
wrong place in the file system hierarchy and remove
subdirectories that are no longer needed. File
rearrangements are necessary after a change in the
subdirectories that are no longer needed. File
rearrangements are necessary after a change in the
<b>hash</b><i>_</i><b>queue</b><i>_</i><b>names</b> and/or <b>hash</b><i>_</i><b>queue</b><i>_</i><b>depth</b> configura-
tion parameters. It is highly recommended to run
tion parameters. It is highly recommended to run
this check once before Postfix startup.
<b>-p</b> Purge stale files (files that are left over after
<b>-p</b> Purge stale files (files that are left over after
system or software crashes).
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
tiple <b>-v</b> options make the software increasingly
tiple <b>-v</b> options make the software increasingly
verbose.
<b>DIAGNOSTICS</b>
Problems are reported to the standard error stream and to
Problems are reported to the standard error stream and to
<b>syslogd</b>.
<b>CONFIGURATION</b> <b>PARAMETERS</b>
See the Postfix <b>main.cf</b> file for syntax details and for
default values.
<b>hash</b><i>_</i><b>queue</b><i>_</i><b>depth</b>
Number of subdirectory levels for hashed queues.
<b>hash</b><i>_</i><b>queue</b><i>_</i><b>names</b>
The names of queues that are organized into multi-
ple levels of subdirectories.
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
software.
See the Postfix <b>main.cf</b> file for syntax details and for
@@ -71,6 +71,19 @@ POSTSUPER(1) POSTSUPER(1)
POSTSUPER(1) POSTSUPER(1)
default values.
<b>hash</b><i>_</i><b>queue</b><i>_</i><b>depth</b>
Number of subdirectory levels for hashed queues.
<b>hash</b><i>_</i><b>queue</b><i>_</i><b>names</b>
The names of queues that are organized into multi-
ple levels of subdirectories.
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
Wietse Venema
IBM T.J. Watson Research
@@ -101,19 +114,6 @@ POSTSUPER(1) POSTSUPER(1)

View File

@@ -283,7 +283,7 @@ SMTPD(8) SMTPD(8)
nasty relay loopholes involving trusted backup MX
hosts.
<b>restriction</b><i>_</i><b>classes</b>
<b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
Declares the name of zero or more parameters that
contain a list of UCE restrictions. The names of
these parameters can then be used instead of the

View File

@@ -175,17 +175,18 @@ case "$SYSTEM.$RELEASE" in
echo "See the RELEASE_NOTES file for more information." 1>&2
exit 1
fi
# See where GDBM's ndbm.h include file sits. XXX verify that
# gdbm links in by default (i.e. NO -lgdbm is needed).
# See where GDBM's ndbm.h include file sits.
if [ -f /usr/include/gdbm-ndbm.h ]
then
CCARGS="$CCARGS -DHAS_DBM -DPATH_NDBM_H=\\\"<gdbm-ndbm.h>\\\""
GDBM_LIBS=gdbm
elif [ -f /usr/include/gdbm/ndbm.h ]
then
CCARGS="$CCARGS -DHAS_DBM -DPATH_NDBM_H=\\\"<gdbm/ndbm.h>\\\""
GDBM_LIBS=gdbm
fi
SYSLIBS="-ldb"
for name in nsl resolv
for name in nsl resolv $GDBM_LIBS
do
test -f /usr/lib/lib$name.a && SYSLIBS="$SYSLIBS -l$name"
done

View File

@@ -9,7 +9,8 @@ Postfix super intendent
.na
.nf
.fi
\fBpostsuper\fR [\fB-p\fR] [\fB-s\fR] [\fB-v\fR] [\fIdirectory ...\fR]
\fBpostsuper\fR [\fB-d \fIqueue_id\fR] [\fB-p\fR]
[\fB-s\fR] [\fB-v\fR] [\fIdirectory ...\fR]
.SH DESCRIPTION
.ad
.fi
@@ -23,6 +24,17 @@ By default, \fBpostsuper\fR performs the operations requested with the
nor directories. Use of this command is restricted to the super-user.
Options:
.IP \fB-d \fIqueue_id\fR
Delete one message queue file with the named queue ID. Specify
multiple \fB-d\fR options to delete multiple queue files by name.
.sp
Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified, the
program reads queue IDs from standard input.
.sp
This operation can be performed safely while the mail system is
running, although the queue manager may issue warnings when a
file suddenly disappears. The exit status is zero if at least one
of the named message queue files was found.
.IP \fB-s\fR
Structure check. Move queue files that are in the wrong place
in the file system hierarchy and remove subdirectories that are

View File

@@ -9,7 +9,8 @@ Postfix master process
.na
.nf
.fi
\fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
\fBmaster\fR [\fB-c \fIconfig_dir\fR] [\fB-e \fIexit_time\fR]
[\fB-D\fR] [\fB-t\fR] [\fB-v\fR]
.SH DESCRIPTION
.ad
.fi
@@ -34,6 +35,9 @@ Options:
.IP "\fB-c \fIconfig_dir\fR"
Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in
the named directory instead of the default configuration directory.
.IP "\fB-e \fIexit_time\fR"
Terminate the master process after \fIexit_time\fR seconds. Child
processes terminate at their convenience.
.IP \fB-D\fR
After initialization, run a debugger on the master process. The
debugging command is specified with the \fBdebugger_command\fR in

View File

@@ -196,7 +196,7 @@ and what clients may issue \fBETRN\fR commands.
Allow untrusted clients to specify addresses with sender-specified
routing. Enabling this opens up nasty relay loopholes involving
trusted backup MX hosts.
.IP \fBrestriction_classes\fR
.IP \fBsmtpd_restriction_classes\fR
Declares the name of zero or more parameters that contain a
list of UCE restrictions. The names of these parameters can
then be used instead of the restriction lists that they represent.

View File

@@ -81,6 +81,7 @@ dns_rr.o: dns_rr.c
dns_rr.o: ../../include/sys_defs.h
dns_rr.o: ../../include/msg.h
dns_rr.o: ../../include/mymalloc.h
dns_rr.o: ../../include/myrand.h
dns_rr.o: dns.h
dns_rr.o: ../../include/vstring.h
dns_rr.o: ../../include/vbuf.h

View File

@@ -105,6 +105,7 @@ extern void dns_rr_free(DNS_RR *);
extern DNS_RR *dns_rr_copy(DNS_RR *);
extern DNS_RR *dns_rr_append(DNS_RR *, DNS_RR *);
extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
extern DNS_RR *dns_rr_shuffle(DNS_RR *);
/*
* dns_lookup.c

View File

@@ -26,6 +26,9 @@
/* DNS_RR *dns_rr_sort(list, compar)
/* DNS_RR *list
/* int (*compar)(DNS_RR *, DNS_RR *);
/*
/* DNS_RR *dns_rr_shuffle(list)
/* DNS_RR *list;
/* DESCRIPTION
/* The routines in this module maintain memory for DNS resource record
/* information, and maintain lists of DNS resource records.
@@ -49,6 +52,8 @@
/* dns_rr_sort() sorts a list of resource records into ascending
/* order according to a user-specified criterion. The result is the
/* sorted list.
/*
/* dns_rr_shuffle() randomly permutes a list of resource records.
/* LICENSE
/* .ad
/* .fi
@@ -70,6 +75,7 @@
#include <msg.h>
#include <mymalloc.h>
#include <myrand.h>
/* DNS library. */
@@ -193,3 +199,47 @@ DNS_RR *dns_rr_sort(DNS_RR *list, int (*compar) (DNS_RR *, DNS_RR *))
dns_rr_sort_user = saved_user;
return (list);
}
/* dns_rr_shuffle - shuffle resource record list */
DNS_RR *dns_rr_shuffle(DNS_RR *list)
{
DNS_RR **rr_array;
DNS_RR *rr;
int len;
int i;
int r;
/*
* Build linear array with pointers to each list element.
*/
for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
/* void */ ;
rr_array = (DNS_RR **) mymalloc(len * sizeof(*rr_array));
for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
rr_array[len] = rr;
/*
* Shuffle resource records.
*/
for (i = 0; i < len; i++) {
r = myrand() % len;
rr = rr_array[i];
rr_array[i] = rr_array[r];
rr_array[r] = rr;
}
/*
* Fix the links.
*/
for (i = 0; i < len - 1; i++)
rr_array[i]->next = rr_array[i + 1];
rr_array[i]->next = 0;
list = rr_array[0];
/*
* Cleanup.
*/
myfree((char *) rr_array);
return (list);
}

View File

@@ -85,6 +85,7 @@
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
/* Utility library. */
@@ -230,8 +231,12 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
request->fp =
mail_queue_open(request->queue_name, request->queue_id, O_RDWR, 0);
if (request->fp == 0)
msg_fatal("open %s %s: %m", request->queue_name, request->queue_id);
if (request->fp == 0) {
if (errno != ENOENT)
msg_fatal("open %s %s: %m", request->queue_name, request->queue_id);
msg_warn("open %s %s: %m", request->queue_name, request->queue_id);
return (-1);
}
if (msg_verbose)
msg_info("%s: file %s", myname, VSTREAM_PATH(request->fp));
if (myflock(vstream_fileno(request->fp), INTERNAL_LOCK, DELIVER_LOCK_MODE) < 0)

View File

@@ -7,12 +7,10 @@
/* #include <mail_conf.h>
/*
/* int get_mail_conf_bool(name, defval)
/* const char *path;
/* const char *name;
/* int defval;
/*
/* int get_mail_conf_bool_fn(name, defval)
/* const char *path;
/* const char *name;
/* int (*defval)();
/*

View File

@@ -699,7 +699,7 @@ extern bool var_smtp_never_ehlo;
#define DEF_SMTP_BIND_ADDR ""
extern char *var_smtp_bind_addr;
#define VAR_SMTP_RAND_ADDR "smtp_randomize_address"
#define VAR_SMTP_RAND_ADDR "smtp_randomize_addresses"
#define DEF_SMTP_RAND_ADDR 1
extern bool var_smtp_rand_addr;

View File

@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "Snapshot-20010429"
#define DEF_MAIL_VERSION "Snapshot-20010501"
extern char *var_mail_version;
/* LICENSE

View File

@@ -279,7 +279,9 @@ int deliver_alias(LOCAL_STATE state, USER_ATTR usr_attr,
"alias database unavailable") :
deliver_token_string(state, usr_attr, expansion, &alias_count));
#if 0
if (state.msg_attr.owner == 0 && alias_count > 10)
if (var_ownreq_special
&& strncmp("owner-", state.msg_attr.sender, 6) != 0
&& alias_count > 10)
msg_warn("mailing list \"%s\" needs an \"owner-%s\" alias",
name, name);
#endif

View File

@@ -121,6 +121,8 @@ master_ent.o: ../../include/argv.h
master_ent.o: ../../include/stringops.h
master_ent.o: ../../include/readlline.h
master_ent.o: ../../include/inet_addr_list.h
master_ent.o: ../../include/inet_util.h
master_ent.o: ../../include/inet_addr_host.h
master_ent.o: ../../include/mail_proto.h
master_ent.o: ../../include/iostuff.h
master_ent.o: ../../include/mail_params.h

View File

@@ -24,8 +24,13 @@ typedef struct MASTER_SERV {
int *listen_fd; /* incoming requests */
int listen_fd_count; /* nr of descriptors */
union {
struct INET_ADDR_LIST *inet;
} addr_list;
struct {
char *port; /* inet listen port */
struct INET_ADDR_LIST *addr;/* inet listen address */
} inet_ep;
#define MASTER_INET_ADDRLIST(s) ((s)->endpoint.inet_ep.addr)
#define MASTER_INET_PORT(s) ((s)->endpoint.inet_ep.port)
} endpoint;
int max_proc; /* upper bound on # processes */
char *path; /* command pathname */
struct ARGV *args; /* argument vector */

View File

@@ -276,20 +276,21 @@ MASTER_SERV *get_master_ent()
if (STR_SAME(transport, MASTER_XPORT_NAME_INET)) {
serv->type = MASTER_SERV_TYPE_INET;
atmp = inet_parse(name, &host, &port);
if (host && *host) {
if (*host) {
serv->flags |= MASTER_FLAG_INETHOST;/* host:port */
serv->addr_list.inet =
(INET_ADDR_LIST *) mymalloc(sizeof(*serv->addr_list.inet));
inet_addr_list_init(serv->addr_list.inet);
inet_addr_host(serv->addr_list.inet, host);
serv->listen_fd_count = serv->addr_list.inet->used;
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);
serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
} else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
serv->addr_list.inet = 0; /* wild-card */
MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
serv->listen_fd_count = 1;
} else {
serv->addr_list.inet = own_inet_addr_list(); /* virtual */
serv->listen_fd_count = serv->addr_list.inet->used;
MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
}
MASTER_INET_PORT(serv) = mystrdup(port);
myfree(atmp);
} else if (STR_SAME(transport, MASTER_XPORT_NAME_UNIX)) {
serv->type = MASTER_SERV_TYPE_UNIX;
@@ -463,8 +464,12 @@ void free_master_ent(MASTER_SERV *serv)
/*
* Undo what get_master_ent() created.
*/
if (serv->flags & MASTER_FLAG_INETHOST)
inet_addr_list_free(serv->addr_list.inet);
if (serv->flags & MASTER_FLAG_INETHOST) {
inet_addr_list_free(MASTER_INET_ADDRLIST(serv));
myfree((char *) MASTER_INET_ADDRLIST(serv));
}
if (serv->type == MASTER_SERV_TYPE_INET)
myfree(MASTER_INET_PORT(serv));
myfree(serv->name);
myfree(serv->path);
argv_free(serv->args);

View File

@@ -107,15 +107,16 @@ void master_listen_init(MASTER_SERV *serv)
* bound to specific interface addresses.
*/
case MASTER_SERV_TYPE_INET:
if (serv->addr_list.inet == 0) { /* wild-card */
if (MASTER_INET_ADDRLIST(serv) == 0) { /* wild-card */
serv->listen_fd[0] =
inet_listen(serv->name, serv->max_proc > var_proc_limit ?
inet_listen(MASTER_INET_PORT(serv),
serv->max_proc > var_proc_limit ?
serv->max_proc : var_proc_limit, NON_BLOCKING);
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
} else { /* virtual */
} else { /* virtual or host:port */
for (n = 0; n < serv->listen_fd_count; n++) {
end_point = concatenate(inet_ntoa(serv->addr_list.inet->addrs[n]),
":", serv->name, (char *) 0);
end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
":", MASTER_INET_PORT(serv), (char *) 0);
serv->listen_fd[n]
= inet_listen(end_point, serv->max_proc > var_proc_limit ?
serv->max_proc : var_proc_limit, NON_BLOCKING);

View File

@@ -35,6 +35,7 @@
#include <sys/stat.h>
#include <string.h>
#include <utime.h>
#include <errno.h>
/* Utility library. */
@@ -73,12 +74,21 @@ void qmgr_move(const char *src_queue, const char *dst_queue,
if (time_stamp > 0) {
tbuf.actime = tbuf.modtime = time_stamp;
path = mail_queue_path((VSTRING *) 0, src_queue, queue_id);
if (utime(path, &tbuf) < 0)
msg_fatal("%s: update %s time stamps: %m", myname, path);
if (utime(path, &tbuf) < 0) {
if (errno != ENOENT)
msg_fatal("%s: update %s time stamps: %m", myname, path);
msg_warn("%s: update %s time stamps: %m", myname, path);
continue;
}
}
if (mail_queue_rename(queue_id, src_queue, dst_queue)) {
if (errno != ENOENT)
msg_fatal("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
msg_warn("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
continue;
}
if (mail_queue_rename(queue_id, src_queue, dst_queue))
msg_fatal("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
if (msg_verbose)
msg_info("%s: moved %s from %s to %s",
myname, queue_id, src_queue, dst_queue);

View File

@@ -65,6 +65,7 @@ postalias.o: ../../include/readlline.h
postalias.o: ../../include/stringops.h
postalias.o: ../../include/split_at.h
postalias.o: ../../include/get_hostname.h
postalias.o: ../../include/vstring_vstream.h
postalias.o: ../../include/tok822.h
postalias.o: ../../include/resolve_clnt.h
postalias.o: ../../include/mail_conf.h

View File

@@ -64,6 +64,7 @@ postmap.o: ../../include/msg_vstream.h
postmap.o: ../../include/readlline.h
postmap.o: ../../include/stringops.h
postmap.o: ../../include/split_at.h
postmap.o: ../../include/vstring_vstream.h
postmap.o: ../../include/mail_conf.h
postmap.o: ../../include/mail_params.h
postmap.o: ../../include/mkmap.h

View File

@@ -5,7 +5,8 @@
/* Postfix super intendent
/* SYNOPSIS
/* .fi
/* \fBpostsuper\fR [\fB-p\fR] [\fB-s\fR] [\fB-v\fR] [\fIdirectory ...\fR]
/* \fBpostsuper\fR [\fB-d \fIqueue_id\fR] [\fB-p\fR]
/* [\fB-s\fR] [\fB-v\fR] [\fIdirectory ...\fR]
/* DESCRIPTION
/* The \fBpostsuper\fR command does small maintenance jobs on the named
/* Postfix queue directories (default: all).
@@ -17,6 +18,17 @@
/* nor directories. Use of this command is restricted to the super-user.
/*
/* Options:
/* .IP \fB-d \fIqueue_id\fR
/* Delete one message queue file with the named queue ID. Specify
/* multiple \fB-d\fR options to delete multiple queue files by name.
/* .sp
/* Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified, the
/* program reads queue IDs from standard input.
/* .sp
/* This operation can be performed safely while the mail system is
/* running, although the queue manager may issue warnings when a
/* file suddenly disappears. The exit status is zero if at least one
/* of the named message queue files was found.
/* .IP \fB-s\fR
/* Structure check. Move queue files that are in the wrong place
/* in the file system hierarchy and remove subdirectories that are
@@ -76,6 +88,7 @@
#include <safe.h>
#include <set_ugid.h>
#include <argv.h>
#include <vstring_vstream.h>
/* Global library. */
@@ -91,6 +104,7 @@
#define ACTION_STRUCT (1<<0) /* fix file organization */
#define ACTION_PURGE (1<<1) /* purge old temp files */
#define ACTION_DELETE (1<<2) /* delete named queue file(s) */
#define ACTION_DEFAULT (ACTION_STRUCT | ACTION_PURGE)
@@ -121,6 +135,57 @@ static struct queue_info queue_info[] = {
0,
};
/* delete_one - delete one message instance and all its associated files */
static int delete_one(const char *queue_id)
{
const char *msg_queue_names[] = {
MAIL_QUEUE_INCOMING, /* twice, to avoid */
MAIL_QUEUE_ACTIVE, /* missing a file while */
MAIL_QUEUE_DEFERRED, /* it is being renamed */
MAIL_QUEUE_INCOMING, /* this is not 100% */
MAIL_QUEUE_ACTIVE, /* foolproof but adequate */
MAIL_QUEUE_DEFERRED,
0,
};
const char **cpp;
VSTRING *msg_path = vstring_alloc(100);
int found = 0;
/*
* Do not delete defer or bounce logfiles, because we could lose a race
* and delete a defer/bounce logfile from a message that reuses the queue
* ID.
*/
for (cpp = msg_queue_names; *cpp != 0; cpp++) {
(void) mail_queue_path(msg_path, *cpp, queue_id);
if (unlink(STR(msg_path)) == 0) {
found = 1;
if (msg_verbose)
msg_info("removed file %s", STR(msg_path));
break;
} else if (errno != ENOENT) {
msg_warn("remove file %s: %m", STR(msg_path));
}
}
vstring_free(msg_path);
return (found);
}
/* delete_stream - delete queue IDs given on stream */
static int delete_stream(VSTREAM *fp)
{
VSTRING *buf = vstring_alloc(20);
int found = 0;
while (vstring_get_nonl(buf, fp) != VSTREAM_EOF)
found |= delete_one(STR(buf));
vstring_free(buf);
return (found);
}
/* super - check queue file location and clean up */
static void super(char **queues, int action)
@@ -286,6 +351,7 @@ int main(int argc, char **argv)
int action = 0;
char **queues;
int c;
int found = 0;
/*
* Defaults.
@@ -356,11 +422,18 @@ int main(int argc, char **argv)
/*
* Parse JCL.
*/
while ((c = GETOPT(argc, argv, "spv")) > 0) {
while ((c = GETOPT(argc, argv, "d:spv")) > 0) {
switch (c) {
default:
msg_fatal("usage: %s [-s (fix structure)] [-p (purge stale files)]",
msg_fatal("usage: %s [-d queue_id] [-p (purge stale files)] [-s (fix structure)]",
argv[0]);
case 'd':
if (strcmp(optarg, "-") == 0)
found |= delete_stream(VSTREAM_IN);
else
found |= delete_one(optarg);
action |= ACTION_DELETE;
break;
case 's':
action |= ACTION_STRUCT;
break;
@@ -384,7 +457,8 @@ int main(int argc, char **argv)
else
queues = argv + optind;
super(queues, action);
if (action & ~ACTION_DELETE)
super(queues, action & ~ACTION_DELETE);
exit(0);
exit((action & ACTION_DELETE) ? !found : 0);
}

View File

@@ -35,6 +35,7 @@
#include <sys/stat.h>
#include <string.h>
#include <utime.h>
#include <errno.h>
/* Utility library. */
@@ -73,12 +74,21 @@ void qmgr_move(const char *src_queue, const char *dst_queue,
if (time_stamp > 0) {
tbuf.actime = tbuf.modtime = time_stamp;
path = mail_queue_path((VSTRING *) 0, src_queue, queue_id);
if (utime(path, &tbuf) < 0)
msg_fatal("%s: update %s time stamps: %m", myname, path);
if (utime(path, &tbuf) < 0) {
if (errno != ENOENT)
msg_fatal("%s: update %s time stamps: %m", myname, path);
msg_warn("%s: update %s time stamps: %m", myname, path);
continue;
}
}
if (mail_queue_rename(queue_id, src_queue, dst_queue)) {
if (errno != ENOENT)
msg_fatal("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
msg_warn("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
continue;
}
if (mail_queue_rename(queue_id, src_queue, dst_queue))
msg_fatal("%s: rename %s from %s to %s: %m",
myname, queue_id, src_queue, dst_queue);
if (msg_verbose)
msg_info("%s: moved %s from %s to %s",
myname, queue_id, src_queue, dst_queue);

View File

@@ -517,12 +517,10 @@ static void show_queue(void)
signal(SIGPIPE, SIG_DFL);
if ((showq = mail_connect(MAIL_CLASS_PUBLIC, MAIL_SERVICE_SHOWQ, BLOCKING)) != 0) {
while ((n = vstream_fread(showq, buf, sizeof(buf))) > 0)
if (vstream_fwrite(VSTREAM_OUT, buf, n) != n)
if (vstream_fwrite(VSTREAM_OUT, buf, n) != n
|| vstream_fflush(VSTREAM_OUT) != 0)
msg_fatal("write error: %m");
if (vstream_fflush(VSTREAM_OUT))
msg_fatal("write error: %m");
if (vstream_fclose(showq))
msg_warn("close: %m");
}

View File

@@ -91,6 +91,7 @@ smtp_addr.o: ../../include/vbuf.h
smtp_addr.o: ../../include/mymalloc.h
smtp_addr.o: ../../include/inet_addr_list.h
smtp_addr.o: ../../include/stringops.h
smtp_addr.o: ../../include/myrand.h
smtp_addr.o: ../../include/mail_params.h
smtp_addr.o: ../../include/own_inet_addr.h
smtp_addr.o: ../../include/dns.h

View File

@@ -128,20 +128,6 @@ static void smtp_print_addr(char *what, DNS_RR *addr_list)
msg_info("end %s address list", what);
}
/* smtp_rand_addr - randomize equal-preference resource records */
static int smtp_rand_addr(DNS_RR *a, DNS_RR *b)
{
int diff;
/*
* XXX Equal-preference records are made to appear different. The bogus
* difference is not consistent from one call to the next. Code based on
* an idea by Aleph1.
*/
return ((diff = a->pref - b->pref != 0) ? diff : (myrand() & 1) ? -1 : 1);
}
/* smtp_addr_one - address lookup for one host name */
static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
@@ -377,8 +363,10 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself)
}
}
}
if (addr_list && var_smtp_rand_addr)
addr_list = dns_rr_sort(addr_list, smtp_rand_addr);
if (addr_list && addr_list->next && var_smtp_rand_addr) {
addr_list = dns_rr_shuffle(addr_list);
addr_list = dns_rr_sort(addr_list, smtp_compare_pref);
}
break;
case DNS_NOTFOUND:
addr_list = smtp_host_addr(name, why);
@@ -404,8 +392,8 @@ DNS_RR *smtp_host_addr(char *host, VSTRING *why)
*/
#define PREF0 0
addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why);
if (addr_list && var_smtp_rand_addr)
addr_list = dns_rr_sort(addr_list, smtp_rand_addr);
if (addr_list && addr_list->next && var_smtp_rand_addr)
addr_list = dns_rr_shuffle(addr_list);
if (msg_verbose)
smtp_print_addr(host, addr_list);
return (addr_list);

View File

@@ -834,7 +834,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "503 Error: need RCPT command");
} else {
smtpd_chat_reply(state, "550 Error: no valid recipients");
smtpd_chat_reply(state, "554 Error: no valid recipients");
}
return (-1);
}

View File

@@ -24,6 +24,10 @@
/* SMTPD_STATE *state;
/* char *recipient;
/*
/* char *smtpd_check_rcptmap(state, recipient)
/* SMTPD_STATE *state;
/* char *recipient;
/*
/* char *smtpd_check_etrn(state, destination)
/* SMTPD_STATE *state;
/* char *destination;
@@ -172,6 +176,12 @@
/* Restrictions on the recipient address that is sent with the RCPT
/* TO command.
/* .PP
/* smtpd_check_rcptmap() validates the recipient address provided
/* with an RCPT TO request. Relevant configuration parameters:
/* .IP local_recipients_map
/* Tables of user names (not addresses) that exist in $mydestination.
/* Mail for local users not in these tables is rejected.
/* .PP
/* smtpd_check_etrn() validates the domain name provided with the
/* ETRN command, and other client-provided information. Relevant
/* configuration parameters:

View File

@@ -111,12 +111,12 @@ rcpt foo@porcupine.org
#
# MX backup
#
mydestination spike.porcupine.org,localhost.porcupine.org
inet_interfaces 168.100.189.2,127.0.0.1
recipient_restrictions permit_mx_backup,reject
rcpt wietse@wzv.win.tue.nl
rcpt wietse@trouble.org
rcpt wietse@porcupine.org
#mydestination spike.porcupine.org,localhost.porcupine.org
#inet_interfaces 168.100.189.2,127.0.0.1
#recipient_restrictions permit_mx_backup,reject
#rcpt wietse@wzv.win.tue.nl
#rcpt wietse@trouble.org
#rcpt wietse@porcupine.org
#
# Deferred restrictions
#

View File

@@ -47,8 +47,6 @@ OK
>>> client foo 123.123.123.123
OK
>>> helo foo.
./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <foo.>: Helo command rejected: Host not found
450 <foo.>: Helo command rejected: Host not found
>>> helo foo
@@ -66,9 +64,6 @@ OK
>>> helo_restrictions reject_invalid_hostname,reject_unknown_hostname
OK
>>> helo 123.123.123.123
./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
./smtpd_check: warning: valid_hostname: numeric hostname: 123.123.123.123
./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <123.123.123.123>: Helo command rejected: Host not found
450 <123.123.123.123>: Helo command rejected: Host not found
>>> helo_restrictions permit_naked_ip_address,reject_invalid_hostname,reject_unknown_hostname
@@ -186,8 +181,8 @@ OK
>>> client spike.porcupine.org 168.100.189.2
OK
>>> client foo 127.0.0.2
./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
>>> #
>>> # Hybrids
>>> #
@@ -215,7 +210,6 @@ OK
./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <bad.domain>: Helo command rejected: match bad.domain; from=<foo@friend.bad.domain> to=<foo@porcupine.org>
554 <bad.domain>: Helo command rejected: match bad.domain
>>> helo 131.155.210.17
./smtpd_check: warning: valid_hostname: numeric hostname: 131.155.210.17
OK
>>> rcpt foo@porcupine.org
OK
@@ -234,19 +228,12 @@ OK
>>> #
>>> # MX backup
>>> #
>>> mydestination spike.porcupine.org,localhost.porcupine.org
OK
>>> inet_interfaces 168.100.189.2,127.0.0.1
OK
>>> recipient_restrictions permit_mx_backup,reject
OK
>>> rcpt wietse@wzv.win.tue.nl
OK
>>> rcpt wietse@trouble.org
./smtpd_check: reject: RCPT from foo[131.155.210.17]: 554 <wietse@trouble.org>: Recipient address rejected: Access denied; from=<foo@friend.bad.domain> to=<wietse@trouble.org>
554 <wietse@trouble.org>: Recipient address rejected: Access denied
>>> rcpt wietse@porcupine.org
OK
>>> #mydestination spike.porcupine.org,localhost.porcupine.org
>>> #inet_interfaces 168.100.189.2,127.0.0.1
>>> #recipient_restrictions permit_mx_backup,reject
>>> #rcpt wietse@wzv.win.tue.nl
>>> #rcpt wietse@trouble.org
>>> #rcpt wietse@porcupine.org
>>> #
>>> # Deferred restrictions
>>> #
@@ -316,68 +303,52 @@ OK
>>> helo [1.2.3.4]
OK
>>> helo [321.255.255.255]
./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[321.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
501 <[321.255.255.255]>: Helo command rejected: invalid ip address
>>> helo [0.255.255.255]
./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[0.255.255.255]>: Helo command rejected: invalid ip address; from=<foo>
501 <[0.255.255.255]>: Helo command rejected: invalid ip address
>>> helo [1.2.3.321]
./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.321]>: Helo command rejected: invalid ip address; from=<foo>
501 <[1.2.3.321]>: Helo command rejected: invalid ip address
>>> helo [1.2.3]
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3]>: Helo command rejected: invalid ip address; from=<foo>
501 <[1.2.3]>: Helo command rejected: invalid ip address
>>> helo [1.2.3.4.5]
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address; from=<foo>
501 <[1.2.3.4.5]>: Helo command rejected: invalid ip address
>>> helo [1..2.3.4]
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1..2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
501 <[1..2.3.4]>: Helo command rejected: invalid ip address
>>> helo [.1.2.3.4]
./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[.1.2.3.4]>: Helo command rejected: invalid ip address; from=<foo>
501 <[.1.2.3.4]>: Helo command rejected: invalid ip address
>>> helo [1.2.3.4.5.]
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address; from=<foo>
501 <[1.2.3.4.5.]>: Helo command rejected: invalid ip address
>>> helo 1.2.3.4
OK
>>> helo 321.255.255.255
./smtpd_check: warning: valid_hostaddr: invalid octet value: 321.255.255.255
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <321.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
501 <321.255.255.255>: Helo command rejected: invalid ip address
>>> helo 0.255.255.255
./smtpd_check: warning: valid_hostaddr: bad initial octet value: 0.255.255.255
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <0.255.255.255>: Helo command rejected: invalid ip address; from=<foo>
501 <0.255.255.255>: Helo command rejected: invalid ip address
>>> helo 1.2.3.321
./smtpd_check: warning: valid_hostaddr: invalid octet value: 1.2.3.321
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.321>: Helo command rejected: invalid ip address; from=<foo>
501 <1.2.3.321>: Helo command rejected: invalid ip address
>>> helo 1.2.3
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3>: Helo command rejected: invalid ip address; from=<foo>
501 <1.2.3>: Helo command rejected: invalid ip address
>>> helo 1.2.3.4.5
./smtpd_check: warning: valid_hostaddr: invalid octet count: 1.2.3.4.5
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5>: Helo command rejected: invalid ip address; from=<foo>
501 <1.2.3.4.5>: Helo command rejected: invalid ip address
>>> helo 1..2.3.4
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1..2.3.4
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1..2.3.4>: Helo command rejected: invalid ip address; from=<foo>
501 <1..2.3.4>: Helo command rejected: invalid ip address
>>> helo .1.2.3.4
./smtpd_check: warning: valid_hostaddr: misplaced dot: .1.2.3.4
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <.1.2.3.4>: Helo command rejected: invalid ip address; from=<foo>
501 <.1.2.3.4>: Helo command rejected: invalid ip address
>>> helo 1.2.3.4.5.
./smtpd_check: warning: valid_hostaddr: misplaced dot: 1.2.3.4.5.
./smtpd_check: reject: HELO from foo[131.155.210.17]: 501 <1.2.3.4.5.>: Helo command rejected: invalid ip address; from=<foo>
501 <1.2.3.4.5.>: Helo command rejected: invalid ip address

View File

@@ -47,8 +47,6 @@ OK
>>> client foo 123.123.123.123
OK
>>> helo foo.
./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
./smtpd_check: warning: valid_hostname: misplaced delimiter: foo.
./smtpd_check: reject: HELO from foo[123.123.123.123]: 450 <foo.>: Helo command rejected: Host not found
450 <foo.>: Helo command rejected: Host not found
>>> helo foo
@@ -174,8 +172,8 @@ OK
>>> client spike.porcupine.org 168.100.189.2
OK
>>> client foo 127.0.0.2
./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
554 Service unavailable; [127.0.0.2] blocked using rbl.maps.vix.com, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>; from=<foo@friend.bad.domain>
554 Service unavailable; [127.0.0.2] blocked using blackholes.mail-abuse.org, reason: Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
>>> #
>>> # unknown sender/recipient domain
>>> #

View File

@@ -810,6 +810,7 @@ printable.o: vbuf.h
rand_sleep.o: rand_sleep.c
rand_sleep.o: sys_defs.h
rand_sleep.o: msg.h
rand_sleep.o: myrand.h
rand_sleep.o: iostuff.h
read_wait.o: read_wait.c
read_wait.o: sys_defs.h

View File

@@ -17,11 +17,14 @@
/* mysrand() performs initialization. This call may be skipped.
/*
/* myrand() returns a pseudo-random number in the range [0, RAND_MAX].
/* If mysrand() was not called, it is invoked with the process ID.
/* If mysrand() was not called, it is invoked with the process ID
/* ex-or-ed with the time of day in seconds.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* WARNING
/* Do not use this code for generating unpredictable numbers.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
@@ -34,6 +37,7 @@
#include <sys_defs.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
/* Utility library. */
@@ -54,6 +58,6 @@ void mysrand(int seed)
int myrand(void)
{
if (myrand_initdone == 0)
mysrand(getpid());
mysrand(getpid() ^ time((time_t *) 0));
return (rand());
}

View File

@@ -6,7 +6,7 @@
/* SYNOPSIS
/* #include <sane_fsops.h>
/*
/* int sane_link(old, new)
/* int sane_link(from, to)
/* const char *from;
/* const char *to;
/* DESCRIPTION

View File

@@ -10,7 +10,7 @@
/* int fd;
/* DESCRIPTION
/* writable() asks the kernel if the specified file descriptor
/* is writable, i.e. a read operation would not block.
/* is writable, i.e. a write operation would not block.
/*
/* Arguments:
/* .IP fd