<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.darenet.org/skins/common/feed.css?12"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.darenet.org/index.php?action=history&amp;feed=atom&amp;title=ircu_api_-_ircd_snprintf</id>
		<title>ircu api - ircd snprintf - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.darenet.org/index.php?action=history&amp;feed=atom&amp;title=ircu_api_-_ircd_snprintf"/>
		<link rel="alternate" type="text/html" href="http://wiki.darenet.org/index.php?title=ircu_api_-_ircd_snprintf&amp;action=history"/>
		<updated>2026-05-20T06:10:52Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.15.1</generator>

	<entry>
		<id>http://wiki.darenet.org/index.php?title=ircu_api_-_ircd_snprintf&amp;diff=2270&amp;oldid=prev</id>
		<title>Secretagent:&amp;#32;New page: &lt;pre&gt;These functions are intended to be a complete replacement for sprintf and sprintf_irc.  They are a (nearly) complete reimplementation, and of course they're snprintf clones, making it...</title>
		<link rel="alternate" type="text/html" href="http://wiki.darenet.org/index.php?title=ircu_api_-_ircd_snprintf&amp;diff=2270&amp;oldid=prev"/>
				<updated>2008-04-25T04:01:57Z</updated>
		
		<summary type="html">&lt;p&gt;New page: &amp;lt;pre&amp;gt;These functions are intended to be a complete replacement for sprintf and sprintf_irc.  They are a (nearly) complete reimplementation, and of course they&amp;#39;re snprintf clones, making it...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;These functions are intended to be a complete replacement for sprintf&lt;br /&gt;
and sprintf_irc.  They are a (nearly) complete reimplementation, and&lt;br /&gt;
of course they're snprintf clones, making it more difficult for&lt;br /&gt;
accidental buffer overflows to crop up.&lt;br /&gt;
&lt;br /&gt;
First off, what's missing?  These functions support all ANSI C&lt;br /&gt;
conversion specifiers and selected ones from ISO 9x, with the&lt;br /&gt;
exception of all floating-point conversions.  The floating-point&lt;br /&gt;
conversions are tricky, and will likely be dependent on the&lt;br /&gt;
representation of a floating-point number on a particular&lt;br /&gt;
architecture.  While that representation is likely to conform to some&lt;br /&gt;
standard, it is not currently used in ircu, so seemed like a good&lt;br /&gt;
thing to omit, given the difficulty of implementing it.&lt;br /&gt;
&lt;br /&gt;
There are two more things missing from this implementation that would&lt;br /&gt;
be required by ANSI; the first is support for multibyte character&lt;br /&gt;
strings, and the second is support for locales, neither of which have&lt;br /&gt;
any relevance for ircu, so again omission seemed to be a good policy.&lt;br /&gt;
Additionally, %#x always causes '0x' (or '0X') to be printed, even if&lt;br /&gt;
the number is zero.&lt;br /&gt;
&lt;br /&gt;
These functions also have some extensions not seen in a&lt;br /&gt;
standards-compliant implementation; technically, the ISO 9x extensions&lt;br /&gt;
fall into this category, for instance.  The ISO 9x extensions&lt;br /&gt;
supported are type extensions--%ju, %tu, and %zu, for instance; %qu&lt;br /&gt;
and %hhu are also supported.  The extensions added for use in ircu are&lt;br /&gt;
%Tu, which takes a time_t, and the new %C conversion, which inserts&lt;br /&gt;
either a numeric or a nick, dependent on the &amp;lt;dest&amp;gt; parameter.  The&lt;br /&gt;
GNU %m extension, which inserts the strerror() string corresponding to&lt;br /&gt;
the current value of errno, is also supported, as is a special %v&lt;br /&gt;
extension, which essentially does a recursive call to ircd_snprintf.&lt;br /&gt;
&lt;br /&gt;
The following description is descended from the Linux man page for the&lt;br /&gt;
printf family of functions.&lt;br /&gt;
&lt;br /&gt;
The format string is composed of zero or more directives: ordinary&lt;br /&gt;
characters (not %), which are copied unchanged to the output stream;&lt;br /&gt;
and conversion specifications, each of which results in fetching zero&lt;br /&gt;
or more subsequent arguments.  Each conversion specification is&lt;br /&gt;
introduced by the character %.  The arguments must correspond properly&lt;br /&gt;
(after type promotion) with the conversion specifier.  After the %,&lt;br /&gt;
the following appear in sequence:&lt;br /&gt;
&lt;br /&gt;
* Zero or more of the following flags:&lt;br /&gt;
&lt;br /&gt;
  #	specifying that the value should be converted to an &amp;quot;alternate&lt;br /&gt;
	form.&amp;quot;  For c, d, i, n, p, s, and u conversions, this option&lt;br /&gt;
	has no effect.  For o conversions, the precision of the number&lt;br /&gt;
	is increased to force the first character of the output string&lt;br /&gt;
	to a zero (except if a zero value is printed with an explicit&lt;br /&gt;
	precision of zero).  For x and X conversions, the string '0x'&lt;br /&gt;
	(or '0X' for X conversions) is prepended to it.  For e, E, f,&lt;br /&gt;
	g, and G conversions, the result will always contain a decimal&lt;br /&gt;
	point, even if no digits follow it (normally, a decimal point&lt;br /&gt;
	appears in the results of those conversions only if a digit&lt;br /&gt;
	follows).  For g and G conversions, trailing zeros are not&lt;br /&gt;
	removed from the result as they would otherwise be.  For C&lt;br /&gt;
	conversions, if the destination is local and the origin is a&lt;br /&gt;
	user, the nick!user@host form is used.&lt;br /&gt;
&lt;br /&gt;
  0	specifying zero padding.  For all conversions except n, the&lt;br /&gt;
	converted value is padded on the left with zeros rather than&lt;br /&gt;
	blanks.  If a precision is given with a numeric conversion (d,&lt;br /&gt;
	i, o, u, i, x, and X), the 0 flag is ignored.&lt;br /&gt;
&lt;br /&gt;
  -	(a negative field width flag) indicates the converted value is&lt;br /&gt;
	to be left adjusted on the field boundary.  Except for n&lt;br /&gt;
	conversions, the converted value is padded on the right with&lt;br /&gt;
	blanks, rather than on the left with blanks or zeros.  A -&lt;br /&gt;
	overrides a 0 if both are given.&lt;br /&gt;
&lt;br /&gt;
 ' '	(a space) specifying that a blank should be left before a&lt;br /&gt;
	positive number produced by a signed conversion (d, e, E, f,&lt;br /&gt;
	g, G, or i).&lt;br /&gt;
&lt;br /&gt;
  +	specifying that a sign always be placed before a number&lt;br /&gt;
	produced by a signed conversion.  A + overrides a space if&lt;br /&gt;
	both are used.&lt;br /&gt;
&lt;br /&gt;
  :	specifying that a struct Client name should be preceded by a&lt;br /&gt;
	':' character if the destination is a user&lt;br /&gt;
&lt;br /&gt;
* An optional decimal digit string specifying a minimum field width.&lt;br /&gt;
  If the converted value has fewer characters than the field width, it&lt;br /&gt;
  will be padded with spaces on the left (or right, if the&lt;br /&gt;
  left-adjustment flag has been given) to fill out the field width.&lt;br /&gt;
&lt;br /&gt;
* An optional precision, in the form of a period (`.') followed by an&lt;br /&gt;
  optional digit string.  If the digit string is omitted, the&lt;br /&gt;
  precision is taken as zero.  This gives the minimum number of digits&lt;br /&gt;
  to appear for d, i, o, u, x, and X conversions, the number of digits&lt;br /&gt;
  to appear after the decimal-point for e, E, and f conversions, the&lt;br /&gt;
  maximum number of significant digits for g and G conversions, or the&lt;br /&gt;
  maximum number of characters to be printed from a string for s&lt;br /&gt;
  conversions.&lt;br /&gt;
&lt;br /&gt;
* The optional character h, specifying that a following d, i, o, u, x,&lt;br /&gt;
  or X conversion corresponds to a short int or unsigned short int&lt;br /&gt;
  argument, or that a following n conversion corresponds to a pointer&lt;br /&gt;
  to a short int argument.  If the h character is given again, char is&lt;br /&gt;
  used instead of short int.&lt;br /&gt;
&lt;br /&gt;
* The optional character l (ell) specifying that a following d, i, o,&lt;br /&gt;
  u, x, or X conversion applies to a pointer to a long int or unsigned&lt;br /&gt;
  long int argument, or that a following n conversion corresponds to a&lt;br /&gt;
  pointer to a long int argument.&lt;br /&gt;
&lt;br /&gt;
* The character L specifying that a following e, E, f, g, or G&lt;br /&gt;
  conversion corresponds to a long double argument, or a following d,&lt;br /&gt;
  i, o, u, x, or X conversion corresponds to a long long argument.&lt;br /&gt;
  Note that long long is not specified in ANSI C and therefore not&lt;br /&gt;
  portable to all architectures.&lt;br /&gt;
&lt;br /&gt;
* The optional character q.  This is equivalent to L.&lt;br /&gt;
&lt;br /&gt;
* A j character specifying that the following integer (d, i, o, u, x,&lt;br /&gt;
  or X) conversion corresponds to an intmax_t argument.&lt;br /&gt;
&lt;br /&gt;
* A t character specifying that the following integer (d, i, o, u, x,&lt;br /&gt;
  or X) conversion corresponds to a ptrdiff_t argument.&lt;br /&gt;
&lt;br /&gt;
* A z character specifying that the following integer (d, i, o, u, x,&lt;br /&gt;
  or X) conversion corresponds to a size_t argument.&lt;br /&gt;
&lt;br /&gt;
* A T character specifying that the following integer (d, i, o, u, x,&lt;br /&gt;
  or X) conversion corresponds to a time_t argument.&lt;br /&gt;
&lt;br /&gt;
* A character that specifies the type of conversion to be applied.&lt;br /&gt;
&lt;br /&gt;
A field width or precision, or both, may be indicated by an asterisk&lt;br /&gt;
`*' instead of a digit string.  In this case, an int argument supplies&lt;br /&gt;
the field width or precision.  A negative field width is treated as a&lt;br /&gt;
left adjustment flag followed by a positive field width; a negative&lt;br /&gt;
precision is treated as though it were missing.&lt;br /&gt;
&lt;br /&gt;
The conversion specifiers and their meanings are:&lt;br /&gt;
&lt;br /&gt;
  diouxX	The int (or appropriate variant) argument is converted&lt;br /&gt;
		to signed decimal (d and i), unsigned octal (o),&lt;br /&gt;
		unsigned decimal (u), or unsigned hexadecimal (x and&lt;br /&gt;
		X) notation.  The letters abcdef are used for x&lt;br /&gt;
		conversions; the letters ABCDEF are used for X&lt;br /&gt;
		conversions.  The precision, if any, gives the minimum&lt;br /&gt;
		number of digits that must appear; if the converted&lt;br /&gt;
		value requires fewer digits, it is padded on the left&lt;br /&gt;
		with zeros.&lt;br /&gt;
&lt;br /&gt;
  eE		[NOT IMPLEMENTED] The double argument is rounded and&lt;br /&gt;
		converted in the style [-]d.dddedd where there is one&lt;br /&gt;
		digit before the decimal-point character and the&lt;br /&gt;
		number of digits after it is equal to the precision;&lt;br /&gt;
		if the precision is missing, it is taken as 6; if the&lt;br /&gt;
		precision is zero, no decimal-point character&lt;br /&gt;
		appears.  An E conversion uses the letter E (rather&lt;br /&gt;
		than e) to introduce the exponent.  The exponent&lt;br /&gt;
		always contains at least two digits; if the value is&lt;br /&gt;
		zero, the exponent is 00.&lt;br /&gt;
&lt;br /&gt;
  f		[NOT IMPLEMENTED] The double argument is rounded and&lt;br /&gt;
		converted to  decimal notation in the style&lt;br /&gt;
		[-]ddd.ddd, where the number of digits after the&lt;br /&gt;
		decimal-point character is equal to the precision&lt;br /&gt;
		specification.  If the precision is missing, it is&lt;br /&gt;
		taken as 6; if the precision is explicitly zero, no&lt;br /&gt;
		decimal-point character appears.  If a decimal point&lt;br /&gt;
		appears, at least one digit appears before it.&lt;br /&gt;
&lt;br /&gt;
  g		[NOT IMPLEMENTED] The double argument is converted in&lt;br /&gt;
		style f or e (or E for G conversions).  The precision&lt;br /&gt;
		specifies the number of significant digits.  If the&lt;br /&gt;
		precision is missing, 6 digits are given; if the&lt;br /&gt;
		precision is zero, it is treated as 1.  Style e is&lt;br /&gt;
		used if the exponent from its conversion is less than&lt;br /&gt;
		-4 or greater than or equal to the precision.&lt;br /&gt;
		Trailing zeros are removed from the fractional part of&lt;br /&gt;
		the result; a decimal point appears only if it is&lt;br /&gt;
		followed by at least one digit.&lt;br /&gt;
&lt;br /&gt;
  c		The int argument is converted to an unsigned char, and&lt;br /&gt;
		the resulting character is written.&lt;br /&gt;
&lt;br /&gt;
  s		The &amp;quot;char *&amp;quot; argument is expected to be a pointer to&lt;br /&gt;
		an array of character type (pointer to a string).&lt;br /&gt;
		Characters from the array are written up to (but not&lt;br /&gt;
		including) a terminating NUL character; if a precision&lt;br /&gt;
		is specified, no more than the number specified are&lt;br /&gt;
		written.  If a precision is given, no null character&lt;br /&gt;
		need be present; if the precision is not specified, or&lt;br /&gt;
		is greater than the size of the array, the array must&lt;br /&gt;
		contain a terminating NUL character.&lt;br /&gt;
&lt;br /&gt;
  p		The &amp;quot;void *&amp;quot; pointer argument is printed in&lt;br /&gt;
		hexadecimal (as if by %#x or %#lx).&lt;br /&gt;
&lt;br /&gt;
  n		The number of characters written so far is stored into&lt;br /&gt;
		the integer indicated by the ``int *'' (or variant)&lt;br /&gt;
		pointer argument.  No argument is converted.&lt;br /&gt;
&lt;br /&gt;
  m		The error message associated with the current value of&lt;br /&gt;
		errno is printed as if by %s.&lt;br /&gt;
&lt;br /&gt;
  C		The client argument identifier is printed under the&lt;br /&gt;
		control of the &amp;lt;dest&amp;gt; argument; if &amp;lt;dest&amp;gt; is NULL or&lt;br /&gt;
		is a user, the client's name (nickname or server name)&lt;br /&gt;
		is printed; otherwise, the client's network numeric is&lt;br /&gt;
		printed.&lt;br /&gt;
&lt;br /&gt;
  H		The channel argument identifier (channel name) is&lt;br /&gt;
		printed.&lt;br /&gt;
&lt;br /&gt;
  v		The argument given must be a pointer to a struct&lt;br /&gt;
		VarData with vd_format and vd_args must be initialized&lt;br /&gt;
		appropriately.  On return, vd_chars will contain the&lt;br /&gt;
		number of characters added to the buffer, and&lt;br /&gt;
		vd_overflow will contain the number of characters that&lt;br /&gt;
		could not be added due to buffer overflow or due to a&lt;br /&gt;
		precision.&lt;br /&gt;
&lt;br /&gt;
  %		A `%' is written.  No argument is converted.  The&lt;br /&gt;
		complete conversion specification is `%%'.&lt;br /&gt;
&lt;br /&gt;
In no case does a non-existent or small field width cause truncation&lt;br /&gt;
of a field; if the result of a conversion is wider than the field&lt;br /&gt;
width, the field is expanded to contain the conversion result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;struct&amp;gt;&lt;br /&gt;
struct VarData {&lt;br /&gt;
  size_t	vd_chars;	/* number of characters inserted */&lt;br /&gt;
  size_t	vd_overflow;	/* number of characters that couldn't be */&lt;br /&gt;
  const char   *vd_format;	/* format string */&lt;br /&gt;
  va_list	vd_args;	/* arguments for %v */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
This structure is used by the %v conversion specification.  The&lt;br /&gt;
_vd_format_ element must contain a format string, and the _vd_args_&lt;br /&gt;
element must be a variable argument list.  Upon return from&lt;br /&gt;
ircd_snprintf() or ircd_vsnprintf(), the _vd_chars_ element will&lt;br /&gt;
contain the number of characters that were able to be inserted, and&lt;br /&gt;
the _vd_overflow_ element will contain the number of characters that&lt;br /&gt;
could not be inserted.&lt;br /&gt;
&amp;lt;/struct&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len,&lt;br /&gt;
		  const char *format, ...);&lt;br /&gt;
&lt;br /&gt;
This formats the argument list, under control of the _format_, into&lt;br /&gt;
the buffer specified by _buf_, the size of which is specified by&lt;br /&gt;
_buf_len_.  The _dest_ parameter is used to determine whether to use a&lt;br /&gt;
numeric or a nickname for %C conversions.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;function&amp;gt;&lt;br /&gt;
int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len,&lt;br /&gt;
		   const char *format, va_list args);&lt;br /&gt;
&lt;br /&gt;
This function is identical to the ircd_snprintf() function except for&lt;br /&gt;
the variable argument list given by _args_.&lt;br /&gt;
&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;authors&amp;gt;&lt;br /&gt;
Kev &amp;lt;klmitch@mit.edu&amp;gt;&lt;br /&gt;
&amp;lt;/authors&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;changelog&amp;gt;&lt;br /&gt;
[2001-6-15 Kev] Initial documentation of the ircd_snprintf family of&lt;br /&gt;
functions.&lt;br /&gt;
&amp;lt;/changelog&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:IRCu API|IRCD]]&lt;/div&gt;</summary>
		<author><name>Secretagent</name></author>	</entry>

	</feed>