util.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * isync - mbsync wrapper: IMAP4 to maildir mailbox synchronizer
  3. * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
  4. * Copyright (C) 2002-2004 Oswald Buddenhagen <ossi@users.sf.net>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "isync.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <string.h>
  24. #include <pwd.h>
  25. #include <ctype.h>
  26. void
  27. sys_error( const char *msg, ... )
  28. {
  29. va_list va;
  30. char buf[1024];
  31. va_start( va, msg );
  32. if ((unsigned)vsnprintf( buf, sizeof(buf), msg, va ) >= sizeof(buf))
  33. oob();
  34. va_end( va );
  35. perror( buf );
  36. }
  37. char *
  38. next_arg( char **s )
  39. {
  40. char *ret;
  41. if (!s || !*s)
  42. return 0;
  43. while (isspace( (unsigned char) **s ))
  44. (*s)++;
  45. if (!**s) {
  46. *s = 0;
  47. return 0;
  48. }
  49. if (**s == '"') {
  50. ++*s;
  51. ret = *s;
  52. *s = strchr( *s, '"' );
  53. } else {
  54. ret = *s;
  55. while (**s && !isspace( (unsigned char) **s ))
  56. (*s)++;
  57. }
  58. if (*s) {
  59. if (**s)
  60. *(*s)++ = 0;
  61. if (!**s)
  62. *s = 0;
  63. }
  64. return ret;
  65. }
  66. #ifndef HAVE_VASPRINTF
  67. static int
  68. vasprintf( char **strp, const char *fmt, va_list ap )
  69. {
  70. int len;
  71. char tmp[1024];
  72. if ((len = vsnprintf( tmp, sizeof(tmp), fmt, ap )) < 0 || !(*strp = malloc( len + 1 )))
  73. return -1;
  74. if (len >= (int)sizeof(tmp))
  75. vsprintf( *strp, fmt, ap );
  76. else
  77. memcpy( *strp, tmp, len + 1 );
  78. return len;
  79. }
  80. #endif
  81. #ifndef HAVE_MEMRCHR
  82. void *
  83. memrchr( const void *s, int c, size_t n )
  84. {
  85. u_char *b = (u_char *)s, *e = b + n;
  86. while (--e >= b)
  87. if (*e == c)
  88. return (void *)e;
  89. return 0;
  90. }
  91. #endif
  92. #ifndef HAVE_STRNLEN
  93. int
  94. strnlen( const char *str, size_t maxlen )
  95. {
  96. size_t len;
  97. /* It's tempting to use memchr(), but it's allowed to read past the end of the actual string. */
  98. for (len = 0; len < maxlen && str[len]; len++) {}
  99. return len;
  100. }
  101. #endif
  102. int
  103. starts_with( const char *str, int strl, const char *cmp, int cmpl )
  104. {
  105. if (strl < 0)
  106. strl = strnlen( str, cmpl + 1 );
  107. return (strl >= cmpl) && !memcmp( str, cmp, cmpl );
  108. }
  109. int
  110. equals( const char *str, int strl, const char *cmp, int cmpl )
  111. {
  112. if (strl < 0)
  113. strl = strnlen( str, cmpl + 1 );
  114. return (strl == cmpl) && !memcmp( str, cmp, cmpl );
  115. }
  116. void
  117. oob( void )
  118. {
  119. fputs( "Fatal: buffer too small. Please report a bug.\n", stderr );
  120. abort();
  121. }
  122. int
  123. nfsnprintf( char *buf, int blen, const char *fmt, ... )
  124. {
  125. int ret;
  126. va_list va;
  127. va_start( va, fmt );
  128. if (blen <= 0 || (unsigned)(ret = vsnprintf( buf, blen, fmt, va )) >= (unsigned)blen)
  129. oob();
  130. va_end( va );
  131. return ret;
  132. }
  133. static void ATTR_NORETURN
  134. oom( void )
  135. {
  136. fputs( "Fatal: Out of memory\n", stderr );
  137. abort();
  138. }
  139. void *
  140. nfmalloc( size_t sz )
  141. {
  142. void *ret;
  143. if (!(ret = malloc( sz )))
  144. oom();
  145. return ret;
  146. }
  147. void *
  148. nfrealloc( void *mem, size_t sz )
  149. {
  150. char *ret;
  151. if (!(ret = realloc( mem, sz )) && sz)
  152. oom();
  153. return ret;
  154. }
  155. char *
  156. nfstrdup( const char *str )
  157. {
  158. char *ret;
  159. if (!(ret = strdup( str )))
  160. oom();
  161. return ret;
  162. }
  163. int
  164. nfvasprintf( char **str, const char *fmt, va_list va )
  165. {
  166. int ret = vasprintf( str, fmt, va );
  167. if (ret < 0)
  168. oom();
  169. return ret;
  170. }
  171. int
  172. nfasprintf( char **str, const char *fmt, ... )
  173. {
  174. int ret;
  175. va_list va;
  176. va_start( va, fmt );
  177. ret = nfvasprintf( str, fmt, va );
  178. va_end( va );
  179. return ret;
  180. }