1 #ifndef INCLUDED_ircd_snprintf_h 2 #define INCLUDED_ircd_snprintf_h 3 /* 4 * IRC - Internet Relay Chat, include/ircd_snprintf.h 5 * Copyright (C) 2000 Kevin L. Mitchell <klmitch@mit.edu> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 /** @file 22 * @brief IRC-specific printf() clone interface. 23 * @version $Id$ 24 */ 25 #ifndef INCLUDED_sys_types_h 26 #include <sys/types.h> 27 #define INCLUDED_sys_types_h 28 #endif 29 #ifndef INCLUDED_stdarg_h 30 #include <stdarg.h> 31 #define INCLUDED_stdarg_h 32 #endif 33 34 struct Client; 35 36 /** structure passed as argument for %v conversion */ 37 struct VarData { 38 size_t vd_chars; /**< number of characters inserted */ 39 size_t vd_overflow; /**< number of characters that couldn't be */ 40 const char *vd_format; /**< format string */ 41 va_list vd_args; /**< arguments for %v */ 42 }; 43 44 #ifndef HAVE_VA_COPY 45 #if HAVE___VA_COPY 46 #define va_copy(DEST, SRC) __va_copy(DEST, SRC) 47 #else 48 /** Fallback macro to copy to \a DEST from \a SRC. */ 49 #define va_copy(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof(DEST)) 50 #endif 51 #endif 52 53 extern int ircd_snprintf(struct Client *dest, char *buf, size_t buf_len, 54 const char *format, ...); 55 extern int ircd_vsnprintf(struct Client *dest, char *buf, size_t buf_len, 56 const char *format, va_list args); 57 58 /** @fn int ircd_snprintf(struct Client *dest, char *buf, size_t 59 buf_len, const char *format, ...) 60 ** 61 ** These functions are intended to be a complete replacement for 62 ** sprintf and sprintf_irc. They are a (nearly) complete 63 ** reimplementation, and of course they're snprintf clones, making it 64 ** more difficult for accidental buffer overflows to crop up. 65 ** 66 ** First off, what's missing? These functions support all ANSI C 67 ** conversion specifiers and selected ones from ISO 9x, with the 68 ** exception of all floating-point conversions. The floating-point 69 ** conversions are tricky, and will likely be dependent on the 70 ** representation of a floating-point number on a particular 71 ** architecture. While that representation is likely to conform to 72 ** some standard, it is not currently used in ircu, so seemed like a 73 ** good thing to omit, given the difficulty of implementing it. 74 ** 75 ** There are two more things missing from this implementation that 76 ** would be required by ANSI; the first is support for multibyte 77 ** character strings, and the second is support for locales, neither 78 ** of which have any relevance for ircu, so again omission seemed to 79 ** be a good policy. Additionally, %#x always causes '0x' (or '0X') 80 ** to be printed, even if the number is zero. 81 ** 82 ** These functions also have some extensions not seen in a 83 ** standards-compliant implementation; technically, the ISO 9x 84 ** extensions fall into this category, for instance. The ISO 9x 85 ** extensions supported are type extensions--%ju, %tu, and %zu, for 86 ** instance; %qu and %hhu are also supported. The extensions added 87 ** for use in ircu are %Tu, which takes a time_t, and the new %C 88 ** conversion, which inserts either a numeric or a nick, dependant on 89 ** the <dest> parameter. The GNU %m extension, which inserts the 90 ** strerror() string corresponding to the current value of errno, is 91 ** also supported, as is a special %v extension, which essentially 92 ** does a recursive call to ircd_snprintf. 93 ** 94 ** The following description is descended from the Linux manpage for 95 ** the printf family of functions. 96 ** 97 ** The format string is composed of zero or more directives: 98 ** ordinary characters (not %), which are copied unchanged to the 99 ** output stream; and conversion specifications, each of which results 100 ** in fetching zero or more subsequent arguments. Each conversion 101 ** specification is introduced by the character %. The arguments must 102 ** correspond properly (after type promotion) with the conversion 103 ** specifier. After the %, the following appear in sequence: 104 ** 105 ** <ul><li>Zero or more of the following flags:<dl> 106 ** 107 ** <dt>#</dt> 108 ** <dd>specifying that the value should be converted to an 109 ** "alternate form." For c, d, i, n, p, s, and u conversions, 110 ** this option has no effect. For o conversions, the precision 111 ** of the number is increased to force the first character of the 112 ** output string to a zero (except if a zero value is printed 113 ** with an explicit precision of zero). For x and X conversions, 114 ** the string '0x' (or '0X' for X conversions) is prepended to 115 ** it. For e, E, f, g, and G conversions, the result will always 116 ** contain a decimal point, even if no digits follow it 117 ** (normally, a decimal point appears in the results of those 118 ** conversions only if a digit follows). For g and G 119 ** conversions, trailing zeros are not removed from the result as 120 ** they would otherwise be. For C conversions, if the 121 ** destination is local and the origin is a user, the 122 ** nick!user\@host form is used.</dd> 123 ** 124 ** <dt>0</dt> 125 ** <dd> specifying zero padding. For all conversions except n, the 126 ** converted value is padded on the left with zeros rather than 127 ** blanks. If a precision is given with a numeric conversion (d, 128 ** i, o, u, i, x, and X), the 0 flag is ignored.</dd> 129 ** 130 ** <dt>-</dt> 131 ** <dd>(a negative field width flag) indicates the converted value is 132 ** to be left adjusted on the field boundary. Except for n 133 ** conversions, the converted value is padded on the right with 134 ** blanks, rather than on the left with blanks or zeros. A - 135 ** overrides a 0 if both are given.</dd> 136 ** 137 ** <dt>' ' (a space)</dt> 138 ** <dd>specifying that a blank should be left before a 139 ** positive number produced by a signed conversion (d, e, E, f, 140 ** g, G, or i).</dd> 141 ** 142 ** <dt>+</dt> 143 ** <dd>specifying that a sign always be placed before a number 144 ** produced by a signed conversion. A + overrides a space if 145 ** both are used.</dd> 146 ** 147 ** <dt>:</dt> 148 ** <dd>specifying that a struct Client name should be preceded by a 149 ** ':' character if the destination is a user.</dd> 150 ** </dl></li> 151 ** 152 ** <li>An optional decimal digit string specifying a minimum field 153 ** width. If the converted value has fewer characters than the 154 ** field width, it will be padded with spaces on the left (or right, 155 ** if the left-adjustment flag has been given) to fill out the field 156 ** width.</li> 157 ** 158 ** <li>An optional precision, in the form of a period (`.') followed by 159 ** an optional digit string. If the digit string is omitted, the 160 ** precision is taken as zero. This gives the minimum number of 161 ** digits to appear for d, i, o, u, x, and X conversions, the number 162 ** of digits to appear after the decimal-point for e, E, and f 163 ** conversions, the maximum number of significant digits for g and G 164 ** conversions, or the maximum number of characters to be printed 165 ** from a string for s conversions.</li> 166 ** 167 ** <li>The optional character h, specifying that a following d, i, o, u, 168 ** x, or X conversion corresponds to a short int or unsigned short 169 ** int argument, or that a following n conversion corresponds to a 170 ** pointer to a short int argument. If the h character is given 171 ** again, char is used instead of short int.</li> 172 ** 173 ** <li>The optional character l (ell) specifying that a following d, i, 174 ** o, u, x, or X conversion applies to a pointer to a long int or 175 ** unsigned long int argument, or that a following n conversion 176 ** corresponds to a pointer to a long int argument.</li> 177 ** 178 ** <li>The character L specifying that a following e, E, f, g, or G 179 ** conversion corresponds to a long double argument, or a following 180 ** d, i, o, u, x, or X conversion corresponds to a long long 181 ** argument. Note that long long is not specified in ANSI C and 182 ** therefore not portable to all architectures.</li> 183 ** 184 ** <li>The optional character q. This is equivalent to L.</li> 185 ** 186 ** <li>A j character specifying that the following integer (d, i, o, u, 187 ** x, or X) conversion corresponds to an intmax_t argument.</li> 188 ** 189 ** <li>A t character specifying that the following integer (d, i, o, u, 190 ** x, or X) conversion corresponds to a ptrdiff_t argument.</li> 191 ** 192 ** <li>A z character specifying that the following integer (d, i, o, u, 193 ** x, or X) conversion corresponds to a size_t argument.</li> 194 ** 195 ** <li>A T character specifying that the following integer (d, i, o, u, 196 ** x, or X) conversion corresponds to a time_t argument.</li> 197 ** 198 ** <li>A character that specifies the type of conversion to be applied.</li> 199 ** </ul> 200 ** 201 ** A field width or precision, or both, may be indicated by an 202 ** asterisk `*' instead of a digit string. In this case, an int 203 ** argument supplies the field width or precision. A negative field 204 ** width is treated as a left adjustment flag followed by a positive 205 ** field width; a negative precision is treated as though it were 206 ** missing. 207 ** 208 ** The conversion specifiers and their meanings are: 209 ** 210 ** <dl> 211 ** <dt>diouxX</dt> 212 ** <dd>The int (or appropriate variant) argument is converted 213 ** to signed decimal (d and i), unsigned octal (o), 214 ** unsigned decimal (u), or unsigned hexadecimal (x and 215 ** X) notation. The letters abcdef are used for x 216 ** conversions; the letters ABCDEF are used for X 217 ** conversions. The precision, if any, gives the minimum 218 ** number of digits that must appear; if the converted 219 ** value requires fewer digits, it is padded on the left 220 ** with zeros.</dd> 221 ** 222 ** <dt>eE [NOT IMPLEMENTED]</dt> 223 ** <dd>The double argument is rounded and 224 ** converted in the style [-]d.dddedd where there is one 225 ** digit before the decimal-point character and the 226 ** number of digits after it is equal to the precision; 227 ** if the precision is missing, it is taken as 6; if the 228 ** precision is zero, no decimal-point character appears. 229 ** An E conversion uses the letter E (rather than e) to 230 ** introduce the exponent. The exponent always contains 231 ** at least two digits; if the value is zero, the 232 ** exponent is 00.</dd> 233 ** 234 ** <dt>f [NOT IMPLEMENTED]</dt> 235 ** <dd>The double argument is rounded and 236 ** converted to decimal notation in the style 237 ** [-]ddd.ddd, where the number of digits after the 238 ** decimal-point character is equal to the precision 239 ** specification. If the precision is missing, it is 240 ** taken as 6; if the precision is explicitly zero, no 241 ** decimal-point character appears. If a decimal point 242 ** appears, at least one digit appears before it.</dd> 243 ** 244 ** <dt>g [NOT IMPLEMENTED]</dt> 245 ** <dd>The double argument is converted in 246 ** style f or e (or E for G conversions). The precision 247 ** specifies the number of significant digits. If the 248 ** precision is missing, 6 digits are given; if the 249 ** precision is zero, it is treated as 1. Style e is 250 ** used if the exponent from its conversion is less than 251 ** -4 or greater than or equal to the precision. 252 ** Trailing zeros are removed from the fractional part of 253 ** the result; a decimal point appears only if it is 254 ** followed by at least one digit.</dd> 255 ** 256 ** <dt>c</dt> 257 ** <dd>The int argument is converted to an unsigned char, and 258 ** the resulting character is written.</dd> 259 ** 260 ** <dt>s</dt> 261 ** <dd>The "char *" argument is expected to be a pointer to 262 ** an array of character type (pointer to a string). 263 ** Characters from the array are written up to (but not 264 ** including) a terminating NUL character; if a precision 265 ** is specified, no more than the number specified are 266 ** written. If a precision is given, no null character 267 ** need be present; if the precision is not specified, or 268 ** is greater than the size of the array, the array must 269 ** contain a terminating NUL character.</dd> 270 ** 271 ** <dt>p</dt> 272 ** <dd>The "void *" pointer argument is printed in 273 ** hexadecimal (as if by %#x or %#lx).</dd> 274 ** 275 ** <dt>n</dt> 276 ** <dd>The number of characters written so far is stored into 277 ** the integer indicated by the ``int *'' (or variant) 278 ** pointer argument. No argument is converted.</dd> 279 ** 280 ** <dt>m</dt> 281 ** <dd>The error message associated with the current value of 282 ** errno is printed as if by %s.</dd> 283 ** 284 ** <dt>C</dt> 285 ** <dd>The client argument identifier is printed under the 286 ** control of the <dest> argument; if <dest> is NULL or 287 ** is a user, the client's name (nickname or server name) 288 ** is printed; otherwise, the client's network numeric is 289 ** printed.</dd> 290 ** 291 ** <dt>H</dt> 292 ** <dd>The channel argument identifier (channel name) is 293 ** printed.</dd> 294 ** 295 ** <dt>v</dt> 296 ** <dd>The argument given must be a pointer to a struct 297 ** VarData with vd_format and vd_args must be initialized 298 ** appropriately. On return, vd_chars will contain the 299 ** number of characters added to the buffer, and 300 ** vd_overflow will contain the number of characters that 301 ** could not be added due to buffer overflow or due to a 302 ** precision.</dd> 303 ** 304 ** <dt>%<dt> 305 ** <dd>A `%' is written. No argument is converted. The 306 ** complete conversion specification is `%%'.</dd> 307 ** </dl> 308 ** 309 ** In no case does a non-existent or small field width cause 310 ** truncation of a field; if the result of a conversion is wider than 311 ** the field width, the field is expanded to contain the conversion 312 ** result. 313 ** 314 ** @param[in] dest Client receiving of message. 315 ** @param[out] buf Output buffer for formatted message. 316 ** @param[in] buf_len Number of bytes that can be written to \a buf. 317 ** @param[in] format Format string for message. 318 ** @return Number of bytes that would be written to \a buf without truncation. 319 */ 320 321 #endif /* INCLUDED_ircd_snprintf_h */ 322