REPOST: Deliver 1.00 patch #1
Chip Salzenberg
chip at ateng.ateng.com
Tue Nov 29 03:25:52 AEST 1988
This is an offical patch for deliver 1.00. Please apply it.
Patch number: 1
Date: 13 Oct 1988
Priority: MEDIUM
Changes:
A new command line option "-n" allows delivery to users' default
mailboxes without executing any delivery files. This option is very
useful for invoking deliver recursively -- that is, when deliver is
called in a delivery file.
Also, miscellaneous bug fixes, especially in message output.
Index: patchlevel.h
Prereq: 0
***************
*** 1 ****
! #define PATCHLEVEL 0
--- 1 ----
! #define PATCHLEVEL 1
Index: deliver.8
***************
*** 1,8 ****
! .\" $Header: deliver.8,v 1.3 88/09/14 19:41:44 network Exp $
.\"
.\" Man page for deliver.
.\"
.\" $Log: deliver.8,v $
.\" Revision 1.3 88/09/14 19:41:44 network
.\" Portability to System V and BSD.
.\" General fixup.
--- 1,14 ----
! .\" $Header: deliver.8,v 1.5 88/10/13 13:44:03 network Exp $
.\"
.\" Man page for deliver.
.\"
.\" $Log: deliver.8,v $
+ .\" Revision 1.5 88/10/13 13:44:03 network
+ .\" patch1: rework the whole man page.
+ .\"
+ .\" Revision 1.4 88/10/13 12:18:43 network
+ .\" patch1: add "-n" option, and general bug fixes.
+ .\"
.\" Revision 1.3 88/09/14 19:41:44 network
.\" Portability to System V and BSD.
.\" General fixup.
***************
*** 25,102 ****
The
.I deliver
program collects a mail message from the standard input and delivers it.
! It is intended to take over the delivery of all local mail, a job which
! is usually handled by
.I /bin/mail
! (that's
.I /usr/lib/mail/mail.local
! on Xenix systems).
.PP
- A mail system which uses
.I deliver
! becomes very flexible in its handling of local mail delivery. All files
used to control
.I deliver
! are shell scripts. Thus anything you can express in a shell script can
! be used to control mail delivery.
! .PP
! .I deliver
! was designed for use in two environments. If your Unix system uses
! .I smail(8)
! to handle incoming mail, then you can change the LMAIL macro to call
! .I deliver.
! Or, if you have a Xenix system,
! .I deliver
! can be used as a direct replacement for
! .IR /usr/lib/mail/mail.local.
! (If you are using
! .I smail
! under Xenix, either of these approaches will work.)
! .I deliver
! can also be used with
! .I sendmail
! or
! .I smail
! version 3, through the use of
! .I .forward
! files.
! .PP
! By default,
! .I deliver
! deposits mail in the system mailbox for the named user(s). However,
! .I deliver
! is useful specifically because of its ability to vary its behavior
! depending on the recipient(s) and content of mail messages.
! .PP
! When
! .I deliver
! starts execution, it interprets its arguments in one of three ways. If the
! .B \-b
! (mailbox) option was specified, then all arguments are interpreted as
! mailbox pathnames. Otherwise, if a system delivery file exists,
! .I deliver
! executes it with all of deliver's arguments, interpreting the output as
! described below; this procedure gives the postmaster control over delivery
! to non-existent user names. If
! .I deliver
! cannot find a system delivery file, it interprets all its arguments as
! user names.
! .PP
! After executing the system delivery file (if any),
! .I deliver
! looks in its list of destinations for valid user names without explicitly
! named mailboxes. If any of those users have user delivery files in their
! home directories,
! .I deliver
! executes each delivery file with the name of the user for its only argument.
! .bp
.SH OPTIONS
.TP
.B \-b
! Interpret all arguments as mailboxes instead of addresses.
.TP
.B \-A
! Print the resolved addresses; don't deliver to any mailboxes. Note that
.I deliver
still collects a message from the standard input, since delivery files may
do different things depending on message content. For simple testing,
--- 31,70 ----
The
.I deliver
program collects a mail message from the standard input and delivers it.
! It is intended to take over the delivery of all local mail, a job usually
! handled by
.I /bin/mail
! (System V),
! .I /usr/lib/sendmail
! (BSD), or
.I /usr/lib/mail/mail.local
! (Xenix).
.PP
.I deliver
! introduces flexibility in the handling of local mail delivery. All files
used to control
.I deliver
! are Bourne shell scripts. Thus anything that can be called by a shell
! script can be used to control mail delivery.
.SH OPTIONS
.TP
.B \-b
! Interpret all arguments as mailbox filenames instead of addresses. Note
! that the user running
! .I deliver
! must have write permissions on the given mailbox files. He may also need
! write permissions on their parent directories, depending on the existence
! of the mailbox file and the local locking protocol.
.TP
+ .B \-n
+ Interpret arguments as addresses, but do not run any delivery files; simply
+ deliver the message to the mailbox(es) of the given user(s). This option is
+ most useful when
+ .I deliver
+ is executed recursively, since it prevents further recursion.
+ .TP
.B \-A
! Print resolved addresses; do not deliver the message. Note that
.I deliver
still collects a message from the standard input, since delivery files may
do different things depending on message content. For simple testing,
***************
*** 132,144 ****
(in each user's home directory).
For security reasons, this option disables setuid privileges.
.PP
! All command line options are put into environment variables, which
.I deliver
! examines on startup; thus all flags are propagated when
.I deliver
is invoked recursively.
! .bp
! .SH DELIVERY FILES
Delivery files are shell scripts. They are executed by
.I deliver
to control delivery to users. Note that delivery files do
--- 100,189 ----
(in each user's home directory).
For security reasons, this option disables setuid privileges.
.PP
! All command line options are put into environment variables, examined by
.I deliver
! on startup; thus all flags are propagated when
.I deliver
is invoked recursively.
! .SH ENVIRONMENT
! For mail systems based on
! .I smail
! 2.x, the LMAIL (local mailer) macro can be changed to call
! .I deliver.
! For mail systems based on
! .I smail
! 3.x or
! .I sendmail,
! a similar arrangement may be made; or individual users can invoke
! .I deliver
! by mentioning it in their
! .I .forward
! files.
! .PP
! For Xenix systems,
! .I deliver
! may be used as a direct replacement for
! .IR /usr/lib/mail/mail.local.
! .PP
! For stock Unix systems, it may be possible to make
! .I /bin/rmail
! a link to
! .I deliver;
! however, this configuration has not been tested and is not recommended.
! Any postmaster motivated enough to install
! .I deliver,
! and who wants something better than the standard
! .I /bin/rmail,
! should install
! .I smail.
! .SH OPERATION
! By default,
! .I deliver
! deposits mail in the system mailbox for the named user(s). Also, as a
! necessity for use with
! .I smail
! 2.x,
! .I deliver
! also understands UUCP-style bang addresses well enough to forward the
! message correctly, using
! .I uux.
! .PP
! However, this basic behavior only scratches the surface: the usefulness of
! .I deliver
! derives from its flexibility; its behavior can be made to depend on the
! recipient(s), content or any other aspect of mail messages.
! .PP
! When
! .I deliver
! starts execution, it interprets its arguments in one of three ways. If the
! .B \-b
! (mailbox) option was specified, then all arguments are interpreted as
! mailbox pathnames. Otherwise, if a system delivery file exists and the
! .B \-n
! (no delivery files) option was not specified,
! .I deliver
! executes the system delivery file with all of deliver's arguments
! as its arguments.
! .I deliver
! interprets the delivery file's output as described below. This procedure
! gives the postmaster control over delivery to non-existent hosts and users.
! If the
! .B \-n
! option is specified or if there is no system delivery file,
! .I deliver
! interprets all its arguments as mail addresses.
! .PP
! After possibly executing the system delivery file,
! .I deliver
! looks in its list of destinations for valid user names without explicitly
! named mailboxes. If any of the named users have user delivery files in
! their home directories, and if the
! .B \-n
! option was not specified,
! .I deliver
! executes each user delivery file with the name of the given user as its
! only argument.
! .SH "DELIVERY FILES"
Delivery files are shell scripts. They are executed by
.I deliver
to control delivery to users. Note that delivery files do
***************
*** 159,164 ****
--- 204,224 ----
one argument: the name of the user in whose home directory the file is
found.
.PP
+ Recursive execution of
+ .I deliver
+ is useful, especially with the
+ .B \-b
+ (mailbox) and
+ .B \-n
+ (no delivery files) flags. For example, a user may wish to transform a
+ message body before it is stored in a mailbox. This may be done with a user
+ delivery file and recursive execution of
+ .I deliver.
+ For example, the following user delivery file translates all incoming
+ message bodies to lower case, and stores them in the user's default mailbox:
+ .TP
+ (cat $HEADER; tr '[A-Z]' '[a-z]' <$BODY) | deliver -n "$1"
+ .PP
When
.I deliver
executes a delivery file, it sets several environment variables, listed
***************
*** 167,177 ****
.I deliver;
therefore, all command line options automatically propagate when
.I deliver
! is run recursively (within a delivery file). Recursive execution of
.I deliver
! is quite useful, especially with the
! .B \-b
! (mailbox) flag.
.TP
.B DELFLAGS
The command line flags, if any, specified on the
--- 227,236 ----
.I deliver;
therefore, all command line options automatically propagate when
.I deliver
! is run recursively (within a delivery file). The environment variable
! names set and used by
.I deliver
! are:
.TP
.B DELFLAGS
The command line flags, if any, specified on the
***************
*** 185,191 ****
The user delivery filename.
.TP
.B HOSTNAME
! The local host name, either the actual hostname or a name specified with the
.B \-h
option to
.I deliver.
--- 244,250 ----
The user delivery filename.
.TP
.B HOSTNAME
! The local host name, either the real hostname or a name specified with the
.B \-h
option to
.I deliver.
***************
*** 216,229 ****
When
.I deliver
executes a delivery file, it expects that delivery file to explicitly name
! all users (and, optionally, mailboxes) which should receive the message.
! If a delivery file does not name any users in its output, then the message
! will not be delivered to anyone whose mail delivery is controlled by that
! delivery file.
.PP
! Therefore, a user delivery file which contains only "exit" will keep the
! given user from receiving any mail. A system delivery file which contains
! only "exit" will cause
.B all
mail to disappear. So be careful!
.PP
--- 275,288 ----
When
.I deliver
executes a delivery file, it expects that delivery file to explicitly name
! all users (and, optionally, mailboxes) where the message should be
! delivered. If a delivery file does not name any users in its output, then
! the message will not be delivered to anyone whose mail delivery is
! controlled by that delivery file.
.PP
! Therefore, a user delivery file containing only "exit" will keep the given
! user from receiving any mail. A system delivery file containing only "exit"
! will cause
.B all
mail to disappear. So be careful!
.PP
***************
*** 232,240 ****
.I deliver
is setuid root -- which it should be for normal operation -- then the system
delivery file is executed as root. Be
! .I very careful
! about its permissions and its contents! If you are not careful, it can
! easily become a security hole.
.PP
.B NOTE 3:
All user delivery files are executed in the context of the user in whose
--- 291,299 ----
.I deliver
is setuid root -- which it should be for normal operation -- then the system
delivery file is executed as root. Be
! .I "very careful"
! about its permissions and its contents! Carelessness here can easily
! create a security problem.
.PP
.B NOTE 3:
All user delivery files are executed in the context of the user in whose
***************
*** 290,302 ****
.br
/etc/systemid system name (Xenix only)
.SH SUPPORT
! Enhancements, enhancement requests, trouble reports, etc.,
! should be sent to
! .sp
! .ce
! bugs-deliver at ateng.UUCP.
! .sp
.SH "SEE ALSO"
.IR uux (1),
.IR smail (8),
! .IR mail (1)
--- 349,359 ----
.br
/etc/systemid system name (Xenix only)
.SH SUPPORT
! Enhancements, enhancement requests, trouble reports, etc., should be mailed
! to <bugs-deliver at ateng.com>; or for UUCP-only sites,
! <uunet!ateng!bugs-deliver>.
.SH "SEE ALSO"
+ .IR mail (1),
.IR uux (1),
.IR smail (8),
! .IR sendmail (8)
Index: deliver.h
***************
*** 1,8 ****
! /* $Header: deliver.h,v 1.3 88/09/14 19:41:50 network Exp $
*
* General pull-it-together include file.
*
* $Log: deliver.h,v $
* Revision 1.3 88/09/14 19:41:50 network
* Portability to System V and BSD.
* General fixup.
--- 1,11 ----
! /* $Header: deliver.h,v 1.4 88/10/13 12:19:18 network Exp $
*
* General pull-it-together include file.
*
* $Log: deliver.h,v $
+ * Revision 1.4 88/10/13 12:19:18 network
+ * patch1: add "-n" option, and general bug fixes.
+ *
* Revision 1.3 88/09/14 19:41:50 network
* Portability to System V and BSD.
* General fixup.
***************
*** 30,35 ****
--- 33,39 ----
extern int verbose; /* Print debugging messages? */
extern int dryrun; /* Are we making a dry run? */
+ extern int rundfiles; /* Run delivery files at all? */
extern int printaddrs; /* Address resolution only? */
extern int leavetemps; /* Leave temp files for later perusal */
extern int boxdelivery; /* Args are mailboxes, not addresses */
Index: dfile.c
***************
*** 1,8 ****
! /* $Header: dfile.c,v 1.2 88/08/25 15:23:56 network Exp $
*
* Filter destination(s) through delivery file(s).
*
* $Log: dfile.c,v $
* Revision 1.2 88/08/25 15:23:56 network
* Add third parameter to do_dfile(), so that if the delivery file cannot
* be executed, the given destination can be recorded as an error.
--- 1,11 ----
! /* $Header: dfile.c,v 1.3 88/10/13 12:19:22 network Exp $
*
* Filter destination(s) through delivery file(s).
*
* $Log: dfile.c,v $
+ * Revision 1.3 88/10/13 12:19:22 network
+ * patch1: add "-n" option, and general bug fixes.
+ *
* Revision 1.2 88/08/25 15:23:56 network
* Add third parameter to do_dfile(), so that if the delivery file cannot
* be executed, the given destination can be recorded as an error.
***************
*** 29,47 ****
struct stat st;
/*
! * If there is no global delivery file, then take all the named
! * addresses verbatim and return.
*/
if (stat(sys_deliver, &st) == -1)
{
if (verbose)
! message("%s: no system delivery file\n",
! progname);
! for (a = 0; a < dac; ++a)
! (void) dest(dav[a], (char *) NULL);
! return;
}
/*
--- 32,58 ----
struct stat st;
/*
! * If we've been asked not to run delivery files, forget it.
*/
+ if (!rundfiles)
+ {
+ if (verbose)
+ message("system delivery file disabled\n");
+
+ return -1;
+ }
+
+ /*
+ * If there is no global delivery file, forget it.
+ */
+
if (stat(sys_deliver, &st) == -1)
{
if (verbose)
! message("no system delivery file\n");
! return -1;
}
/*
***************
*** 94,99 ****
--- 105,112 ----
(void) do_dfile(eff_ct, fav, (DEST *)NULL);
free((char *) fav);
+
+ return 0;
}
/*----------------------------------------------------------------------
***************
*** 106,111 ****
--- 119,137 ----
int nfound;
/*
+ * If we've been asked not to run delivery files, forget it.
+ */
+
+ if (!rundfiles)
+ {
+ if (verbose)
+ message("user delivery files disabled\n");
+
+ return -1;
+ }
+
+
+ /*
* Continue to loop through all addresses until no destination
* that needs expanding can be found.
*/
***************
*** 123,128 ****
--- 149,156 ----
}
}
} while (nfound > 0);
+
+ return 0;
}
/*----------------------------------------------------------------------
***************
*** 155,161 ****
|| (st.st_mode & S_IFMT) != S_IFDIR)
{
if (verbose)
! message("%s: home directory %s is missing!\n",
ct->name, ct->home);
return;
}
--- 183,189 ----
|| (st.st_mode & S_IFMT) != S_IFDIR)
{
if (verbose)
! message("user %s: home directory %s is missing!\n",
ct->name, ct->home);
return;
}
***************
*** 163,169 ****
if (st.st_mode & 02)
{
if (verbose)
! message("%s: home directory is writable to the world!\n",
ct->name);
return;
}
--- 191,197 ----
if (st.st_mode & 02)
{
if (verbose)
! message("user %s: home directory is writable to the world!\n",
ct->name);
return;
}
Index: main.c
***************
*** 1,8 ****
! /* $Header: main.c,v 1.5 88/09/14 20:00:03 network Exp $
*
* A program to deliver local mail with some flexibility.
*
* $Log: main.c,v $
* Revision 1.5 88/09/14 20:00:03 network
* Add version string, including patchlevel.
*
--- 1,11 ----
! /* $Header: main.c,v 1.6 88/10/13 12:19:27 network Exp $
*
* A program to deliver local mail with some flexibility.
*
* $Log: main.c,v $
+ * Revision 1.6 88/10/13 12:19:27 network
+ * patch1: add "-n" option, and general bug fixes.
+ *
* Revision 1.5 88/09/14 20:00:03 network
* Add version string, including patchlevel.
*
***************
*** 43,48 ****
--- 46,52 ----
int verbose = FALSE;
int dryrun = FALSE;
+ int rundfiles = TRUE;
int printaddrs = FALSE;
int leavetemps = FALSE;
int boxdelivery = FALSE;
***************
*** 77,83 ****
char **argv;
{
char *p;
! int u, c, errcount, insecure;
/* Make sure that stdout and stderr are interleaved correctly */
--- 81,87 ----
char **argv;
{
char *p;
! int u, c, errcount;
/* Make sure that stdout and stderr are interleaved correctly */
***************
*** 90,96 ****
/* What version of the program is this? */
! sprintf(version + strlen(version), ".%02d", PATCHLEVEL);
/* Figure out the name of this host */
--- 94,100 ----
/* What version of the program is this? */
! (void) sprintf(version + strlen(version), ".%02d", PATCHLEVEL);
/* Figure out the name of this host */
***************
*** 120,125 ****
--- 124,132 ----
printaddrs = TRUE;
dryrun = TRUE;
break;
+ case 'n':
+ rundfiles = FALSE;
+ break;
case 't':
leavetemps = TRUE;
break;
***************
*** 137,143 ****
/* Parse command line arguments */
! while ((c = getopt(argc, argv, "vdAtbs:u:r:h:")) != EOF)
{
switch (c)
{
--- 144,150 ----
/* Parse command line arguments */
! while ((c = getopt(argc, argv, "vdAntbs:u:r:h:")) != EOF)
{
switch (c)
{
***************
*** 152,157 ****
--- 159,167 ----
printaddrs = TRUE;
dryrun = TRUE;
break;
+ case 'n':
+ rundfiles = FALSE;
+ break;
case 't':
leavetemps = TRUE;
break;
***************
*** 179,185 ****
if (optind >= argc)
{
! message("%s: no recipients specified\n", progname);
usage();
}
--- 189,195 ----
if (optind >= argc)
{
! error("no recipients specified\n");
usage();
}
***************
*** 202,208 ****
if (eff_uid != real_uid && eff_uid != 0)
{
! message("%s: if setuid, must be setuid root\n");
leave(1);
}
--- 212,218 ----
if (eff_uid != real_uid && eff_uid != 0)
{
! error("if setuid, must be setuid root\n");
leave(1);
}
***************
*** 213,219 ****
if (setgid(eff_gid = real_gid) == -1
|| setuid(eff_uid = real_uid) == -1)
{
! syserr("%s: can't renounce setuid privileges");
leave(1);
}
}
--- 223,229 ----
if (setgid(eff_gid = real_gid) == -1
|| setuid(eff_uid = real_uid) == -1)
{
! syserr("can't renounce setuid privileges");
leave(1);
}
}
***************
*** 306,330 ****
else
{
! /*
! * Run all destinations though the system delivery file.
! * If sys_dfile() doesn't find one, it will call dest()
! * on each address.
! */
! sys_dfile(argc - optind, argv + optind);
! if (verbose)
! dumpdests("after running system delivery file");
/*
* Run each user destination through his delivery file.
*/
! user_dfiles();
!
! if (verbose)
! dumpdests("after running user delivery files");
}
/*
--- 316,353 ----
else
{
! /* Run all destinations though the system delivery file. */
! if (sys_dfile(argc - optind, argv + optind) >= 0)
! {
! if (verbose)
! dumpdests("after running system delivery file");
! }
! else
! {
! int a;
! /*
! * System delivery file is missing or ignored.
! * Use the argument list verbatim.
! */
+ for (a = optind; a < argc; ++a)
+ (void) dest(argv[a], (char *) NULL);
+
+ if (verbose)
+ dumpdests("as taken from argument list");
+ }
+
/*
* Run each user destination through his delivery file.
*/
! if (user_dfiles() >= 0)
! {
! if (verbose)
! dumpdests("after running user delivery files");
! }
}
/*
***************
*** 365,376 ****
usage()
{
! message("Usage: %s [-b][-A][-d][-v][-t][-r from][-h host] args\n", progname);
message("-b All arguments are mailbox filenames.\n");
message(" (Default: arguments are user names.)\n");
message("-A Resolve addresses but do not deliver.\n");
message("-d Be verbose but do not deliver.\n");
message("-v Be verbose and deliver.\n");
message("-t Do not remote temp files before exiting.\n");
message("-r from Specify the address to appear in the \"From \" line.\n");
message("-h host Specify the host name.\n");
--- 388,400 ----
usage()
{
! message("Usage: %s [-b][-A][-d][-v][-n][-t][-r from][-h host] args\n", progname);
message("-b All arguments are mailbox filenames.\n");
message(" (Default: arguments are user names.)\n");
message("-A Resolve addresses but do not deliver.\n");
message("-d Be verbose but do not deliver.\n");
message("-v Be verbose and deliver.\n");
+ message("-n Do not run any delivery files.\n");
message("-t Do not remote temp files before exiting.\n");
message("-r from Specify the address to appear in the \"From \" line.\n");
message("-h host Specify the host name.\n");
Index: subs.c
***************
*** 1,8 ****
! /* $Header: subs.c,v 1.3 88/09/14 19:42:33 network Exp $
*
* Miscellaneous subroutines.
*
* $Log: subs.c,v $
* Revision 1.3 88/09/14 19:42:33 network
* Portability to System V and BSD.
* General fixup.
--- 1,11 ----
! /* $Header: subs.c,v 1.4 88/10/13 12:20:34 network Exp $
*
* Miscellaneous subroutines.
*
* $Log: subs.c,v $
+ * Revision 1.4 88/10/13 12:20:34 network
+ * patch1: add "-n" option, and general bug fixes.
+ *
* Revision 1.3 88/09/14 19:42:33 network
* Portability to System V and BSD.
* General fixup.
***************
*** 94,100 ****
nomem()
{
! message("%s: out of memory\n", progname);
leave(1);
}
--- 97,103 ----
nomem()
{
! error("out of memory\n");
leave(1);
}
Index: sysdep.c
***************
*** 1,4 ****
! /* $Header: sysdep.c,v 1.3 88/09/14 20:00:24 network Exp $
*
* Routines which are (or might well be) system-dependant.
* I've put the message routines here since you may need to use
--- 1,4 ----
! /* $Header: sysdep.c,v 1.4 88/10/13 12:20:39 network Exp $
*
* Routines which are (or might well be) system-dependant.
* I've put the message routines here since you may need to use
***************
*** 5,10 ****
--- 5,13 ----
* the ANSI <stdarg.h> instead of <varargs.h>.
*
* $Log: sysdep.c,v $
+ * Revision 1.4 88/10/13 12:20:39 network
+ * patch1: add "-n" option, and general bug fixes.
+ *
* Revision 1.3 88/09/14 20:00:24 network
* Fix type of gethostname() for BSD.
*
***************
*** 195,201 ****
g = va_arg(ap, int);
h = va_arg(ap, int);
! printf(fmt, a,b,c,d,e,f,g,h);
}
vfprintf(fp, fmt, ap)
--- 198,204 ----
g = va_arg(ap, int);
h = va_arg(ap, int);
! (void) printf(fmt, a,b,c,d,e,f,g,h);
}
vfprintf(fp, fmt, ap)
***************
*** 214,220 ****
g = va_arg(ap, int);
h = va_arg(ap, int);
! fprintf(fp, fmt, a,b,c,d,e,f,g,h);
}
vsprintf(s, fmt, ap)
--- 217,223 ----
g = va_arg(ap, int);
h = va_arg(ap, int);
! (void) fprintf(fp, fmt, a,b,c,d,e,f,g,h);
}
vsprintf(s, fmt, ap)
***************
*** 233,239 ****
g = va_arg(ap, int);
h = va_arg(ap, int);
! sprintf(s, fmt, a,b,c,d,e,f,g,h);
}
#endif /* HAS_VPRINTF */
--- 236,242 ----
g = va_arg(ap, int);
h = va_arg(ap, int);
! (void) sprintf(s, fmt, a,b,c,d,e,f,g,h);
}
#endif /* HAS_VPRINTF */
--
Chip Salzenberg <chip at ateng.com> or <uunet!ateng!chip>
A T Engineering Me? Speak for my company? Surely you jest!
Beware of programmers carrying screwdrivers.
More information about the Comp.sources.bugs
mailing list