PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/user/snort/src/snprintf.c

https://bitbucket.org/thelearninglabs/uclinux-distro-tll-public
C | 507 lines | 374 code | 35 blank | 98 comment | 54 complexity | 584f11cc582ec6788c9c76f91f8b6f18 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-3.0, Unlicense, GPL-2.0, GPL-3.0, CC-BY-SA-3.0, AGPL-1.0, ISC, MIT, 0BSD, LGPL-2.0
  1. /* $Id$ */
  2. /*
  3. ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
  4. **
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation; either version 2 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. /*
  20. ** This file contains various routines which we shamelessly steal from other
  21. ** opensource products :-P (I love code reuseability idea)
  22. ** fygrave@tigerteam.net
  23. */
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27. #ifndef HAVE_SNPRINTF
  28. #include "snprintf.h"
  29. /* snprintf() and all supporting routines were taken from sendmail, hence the
  30. * copyleft message
  31. */
  32. /*
  33. * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
  34. * Copyright (c) 1997 Eric P. Allman. All rights reserved.
  35. * Copyright (c) 1988, 1993
  36. * The Regents of the University of California. All rights reserved.
  37. *
  38. * By using this file, you agree to the terms and conditions set
  39. * forth in the LICENSE file which can be found at the top level of
  40. * the sendmail distribution.
  41. *
  42. */
  43. /*
  44. ** SNPRINTF, VSNPRINT -- counted versions of printf
  45. **
  46. ** These versions have been grabbed off the net. They have been
  47. ** cleaned up to compile properly and support for .precision and
  48. ** %lx has been added.
  49. */
  50. /**************************************************************
  51. * Original:
  52. * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
  53. * A bombproof version of doprnt (sm_dopr) included.
  54. * Sigh. This sort of thing is always nasty do deal with. Note that
  55. * the version here does not include floating point...
  56. *
  57. * snprintf() is used instead of sprintf() as it does limit checks
  58. * for string length. This covers a nasty loophole.
  59. *
  60. * The other functions are there to prevent NULL pointers from
  61. * causing nast effects.
  62. **************************************************************/
  63. void sm_dopr();
  64. char *DoprEnd;
  65. int SnprfOverflow;
  66. #ifndef HAVE_SNPRINTF
  67. /* VARARGS3 */
  68. int
  69. #ifdef __STDC__
  70. snprintf(char *str, size_t count, const char *fmt, ...)
  71. #else
  72. snprintf(str, count, fmt, va_alist)
  73. char *str;
  74. size_t count;
  75. const char *fmt;
  76. va_dcl
  77. #endif
  78. {
  79. int len;
  80. VA_LOCAL_DECL
  81. VA_START(fmt);
  82. len = vsnprintf(str, count, fmt, ap);
  83. VA_END;
  84. return len;
  85. }
  86. #ifndef luna2
  87. #ifndef HAVE_VSNPRINTF
  88. int
  89. vsnprintf(str, count, fmt, args)
  90. char *str;
  91. size_t count;
  92. const char *fmt;
  93. va_list args;
  94. {
  95. str[0] = 0;
  96. DoprEnd = str + count - 1;
  97. SnprfOverflow = 0;
  98. sm_dopr( str, fmt, args );
  99. if(count > 0)
  100. DoprEnd[0] = 0;
  101. if(SnprfOverflow && tTd(57, 2))
  102. printf("\nvsnprintf overflow, len = %ld, str = %s",
  103. (long) count, shortenstring(str, MAXSHORTSTR));
  104. return strlen((const char *)str);
  105. }
  106. #endif /* !HAVE_VSNPRINTF */
  107. #endif /* !luna2 */
  108. #endif /* !HASSNPRINTF */
  109. /*
  110. * sm_dopr(): poor man's version of doprintf
  111. */
  112. void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
  113. void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad));
  114. void dostr __P(( char * , int ));
  115. char *output;
  116. void dopr_outch __P(( int c ));
  117. int SyslogErrno;
  118. void
  119. sm_dopr( buffer, format, args )
  120. char *buffer;
  121. const char *format;
  122. va_list args;
  123. {
  124. int ch;
  125. long value;
  126. int longflag = 0;
  127. int pointflag = 0;
  128. int maxwidth = 0;
  129. char *strvalue;
  130. int ljust;
  131. int len;
  132. int zpad;
  133. #if !HAVE_STRERROR && !defined(ERRLIST_PREDEFINED)
  134. extern char *sys_errlist[];
  135. extern int sys_nerr;
  136. #endif
  137. output = buffer;
  138. while((ch = *format++) != '\0')
  139. {
  140. switch(ch)
  141. {
  142. case '%':
  143. ljust = len = zpad = maxwidth = 0;
  144. longflag = pointflag = 0;
  145. nextch:
  146. ch = *format++;
  147. switch(ch)
  148. {
  149. case 0:
  150. dostr( "**end of format**" , 0);
  151. return;
  152. case '-': ljust = 1; goto nextch;
  153. case '0': /* set zero padding if len not set */
  154. if(len==0 && !pointflag) zpad = '0';
  155. case '1':
  156. case '2':
  157. case '3':
  158. case '4':
  159. case '5':
  160. case '6':
  161. case '7':
  162. case '8':
  163. case '9':
  164. if(pointflag)
  165. maxwidth = maxwidth*10 + ch - '0';
  166. else
  167. len = len*10 + ch - '0';
  168. goto nextch;
  169. case '*':
  170. if(pointflag)
  171. maxwidth = va_arg( args, int );
  172. else
  173. len = va_arg( args, int );
  174. goto nextch;
  175. case '.': pointflag = 1; goto nextch;
  176. case 'l': longflag = 1; goto nextch;
  177. case 'u':
  178. case 'U':
  179. /*fmtnum(value,base,dosign,ljust,len,zpad) */
  180. if(longflag)
  181. {
  182. value = va_arg( args, long );
  183. }
  184. else
  185. {
  186. value = va_arg( args, int );
  187. }
  188. fmtnum( value, 10,0, ljust, len, zpad ); break;
  189. case 'o':
  190. case 'O':
  191. /*fmtnum(value,base,dosign,ljust,len,zpad) */
  192. if(longflag)
  193. {
  194. value = va_arg( args, long );
  195. }
  196. else
  197. {
  198. value = va_arg( args, int );
  199. }
  200. fmtnum( value, 8,0, ljust, len, zpad ); break;
  201. case 'd':
  202. case 'D':
  203. if(longflag)
  204. {
  205. value = va_arg( args, long );
  206. }
  207. else
  208. {
  209. value = va_arg( args, int );
  210. }
  211. fmtnum( value, 10,1, ljust, len, zpad ); break;
  212. case 'x':
  213. if(longflag)
  214. {
  215. value = va_arg( args, long );
  216. }
  217. else
  218. {
  219. value = va_arg( args, int );
  220. }
  221. fmtnum( value, 16,0, ljust, len, zpad ); break;
  222. case 'X':
  223. if(longflag)
  224. {
  225. value = va_arg( args, long );
  226. }
  227. else
  228. {
  229. value = va_arg( args, int );
  230. }
  231. fmtnum( value,-16,0, ljust, len, zpad ); break;
  232. case 's':
  233. strvalue = va_arg( args, char *);
  234. if(maxwidth > 0 || !pointflag)
  235. {
  236. if(pointflag && len > maxwidth)
  237. len = maxwidth; /* Adjust padding */
  238. fmtstr( strvalue,ljust,len,zpad, maxwidth);
  239. }
  240. break;
  241. case 'c':
  242. ch = va_arg( args, int );
  243. dopr_outch( ch ); break;
  244. case 'm':
  245. #if HAVE_STRERROR
  246. dostr(strerror(SyslogErrno), 0);
  247. #else
  248. if(SyslogErrno < 0 || SyslogErrno >= sys_nerr)
  249. {
  250. dostr("Error ", 0);
  251. fmtnum(SyslogErrno, 10, 0, 0, 0, 0);
  252. }
  253. else
  254. dostr((char *)sys_errlist[SyslogErrno], 0);
  255. #endif
  256. break;
  257. case '%': dopr_outch( ch ); continue;
  258. default:
  259. dostr( "???????" , 0);
  260. }
  261. break;
  262. default:
  263. dopr_outch( ch );
  264. break;
  265. }
  266. }
  267. *output = 0;
  268. }
  269. void
  270. fmtstr( value, ljust, len, zpad, maxwidth )
  271. char *value;
  272. int ljust, len, zpad, maxwidth;
  273. {
  274. int padlen, strlen; /* amount to pad */
  275. if(value == 0)
  276. {
  277. value = "<NULL>";
  278. }
  279. for(strlen = 0; value[strlen]; ++ strlen); /* strlen */
  280. if(strlen > maxwidth && maxwidth)
  281. strlen = maxwidth;
  282. padlen = len - strlen;
  283. if(padlen < 0) padlen = 0;
  284. if(ljust) padlen = -padlen;
  285. while(padlen > 0)
  286. {
  287. dopr_outch( ' ' );
  288. --padlen;
  289. }
  290. dostr( value, maxwidth );
  291. while(padlen < 0)
  292. {
  293. dopr_outch( ' ' );
  294. ++padlen;
  295. }
  296. }
  297. void
  298. fmtnum( value, base, dosign, ljust, len, zpad )
  299. long value;
  300. int base, dosign, ljust, len, zpad;
  301. {
  302. int signvalue = 0;
  303. unsigned long uvalue;
  304. char convert[20];
  305. int place = 0;
  306. int padlen = 0; /* amount to pad */
  307. int caps = 0;
  308. /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
  309. value, base, dosign, ljust, len, zpad )); */
  310. uvalue = value;
  311. if(dosign)
  312. {
  313. if(value < 0)
  314. {
  315. signvalue = '-';
  316. uvalue = -value;
  317. }
  318. }
  319. if(base < 0)
  320. {
  321. caps = 1;
  322. base = -base;
  323. }
  324. do
  325. {
  326. convert[place++] =
  327. (caps? "0123456789ABCDEF":"0123456789abcdef")
  328. [uvalue % (unsigned)base ];
  329. uvalue = (uvalue / (unsigned)base );
  330. }while(uvalue);
  331. convert[place] = 0;
  332. padlen = len - place;
  333. if(padlen < 0) padlen = 0;
  334. if(ljust) padlen = -padlen;
  335. /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
  336. convert,place,signvalue,padlen)); */
  337. if(zpad && padlen > 0)
  338. {
  339. if(signvalue)
  340. {
  341. dopr_outch( signvalue );
  342. --padlen;
  343. signvalue = 0;
  344. }
  345. while(padlen > 0)
  346. {
  347. dopr_outch( zpad );
  348. --padlen;
  349. }
  350. }
  351. while(padlen > 0)
  352. {
  353. dopr_outch( ' ' );
  354. --padlen;
  355. }
  356. if(signvalue) dopr_outch( signvalue );
  357. while(place > 0) dopr_outch( convert[--place] );
  358. while(padlen < 0)
  359. {
  360. dopr_outch( ' ' );
  361. ++padlen;
  362. }
  363. }
  364. void
  365. dostr( str , cut)
  366. char *str;
  367. int cut;
  368. {
  369. if(cut)
  370. {
  371. while(*str && cut-- > 0) dopr_outch(*str++);
  372. }
  373. else
  374. {
  375. while(*str) dopr_outch(*str++);
  376. }
  377. }
  378. void
  379. dopr_outch( c )
  380. int c;
  381. {
  382. #if 0
  383. if(iscntrl(c) && c != '\n' && c != '\t')
  384. {
  385. c = '@' + (c & 0x1F);
  386. if(DoprEnd == 0 || output < DoprEnd)
  387. *output++ = '^';
  388. }
  389. #endif
  390. if(DoprEnd == 0 || output < DoprEnd)
  391. *output++ = c;
  392. else
  393. SnprfOverflow++;
  394. }
  395. /*
  396. ** QUAD_TO_STRING -- Convert a quad type to a string.
  397. **
  398. ** Convert a quad type to a string. This must be done
  399. ** separately as %lld/%qd are not supported by snprint()
  400. ** and adding support would slow down systems which only
  401. ** emulate the data type.
  402. **
  403. ** Parameters:
  404. ** value -- number to convert to a string.
  405. **
  406. ** Returns:
  407. ** pointer to a string.
  408. */
  409. char *
  410. quad_to_string(value)
  411. QUAD_T value;
  412. {
  413. char *fmtstr;
  414. static char buf[64];
  415. /*
  416. ** Use sprintf() instead of snprintf() since snprintf()
  417. ** does not support %qu or %llu. The buffer is large enough
  418. ** to hold the string so there is no danger of buffer
  419. ** overflow.
  420. */
  421. #if NEED_PERCENTQ
  422. fmtstr = "%qu";
  423. #else
  424. fmtstr = "%llu";
  425. #endif
  426. sprintf(buf, fmtstr, value);
  427. return buf;
  428. }
  429. /*
  430. ** SHORTENSTRING -- return short version of a string
  431. **
  432. ** If the string is already short, just return it. If it is too
  433. ** long, return the head and tail of the string.
  434. **
  435. ** Parameters:
  436. ** s -- the string to shorten.
  437. ** m -- the max length of the string.
  438. **
  439. ** Returns:
  440. ** Either s or a short version of s.
  441. */
  442. char *
  443. shortenstring(s, m)
  444. register const char *s;
  445. int m;
  446. {
  447. int l;
  448. static char buf[MAXSHORTSTR + 1];
  449. l = strlen(s);
  450. if(l < m)
  451. return(char *) s;
  452. if(m > MAXSHORTSTR)
  453. m = MAXSHORTSTR;
  454. else if(m < 10)
  455. {
  456. if(m < 5)
  457. {
  458. strncpy(buf, s, m);
  459. buf[m] = '\0';
  460. return buf;
  461. }
  462. strncpy(buf, s, m - 3);
  463. strcpy(buf + m - 3, "...");
  464. return buf;
  465. }
  466. m = (m - 3) / 2;
  467. strncpy(buf, s, m);
  468. strcpy(buf + m, "...");
  469. strcpy(buf + m + 3, s + l - m);
  470. return buf;
  471. }
  472. #endif