util.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * mbsync - 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, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * As a special exception, mbsync may be linked with the OpenSSL library,
  21. * despite that library's more restrictive license.
  22. */
  23. #include "isync.h"
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26. #include <fcntl.h>
  27. #include <string.h>
  28. #include <pwd.h>
  29. #include <ctype.h>
  30. int Verbose, Quiet, Debug;
  31. void
  32. debug( const char *msg, ... )
  33. {
  34. va_list va;
  35. if (Debug) {
  36. va_start( va, msg );
  37. vprintf( msg, va );
  38. va_end( va );
  39. fflush( stdout );
  40. }
  41. }
  42. void
  43. info( const char *msg, ... )
  44. {
  45. va_list va;
  46. if (!Quiet) {
  47. va_start( va, msg );
  48. vprintf( msg, va );
  49. va_end( va );
  50. fflush( stdout );
  51. }
  52. }
  53. void
  54. infoc( char c )
  55. {
  56. if (!Quiet) {
  57. putchar( c );
  58. fflush( stdout );
  59. }
  60. }
  61. void
  62. warn( const char *msg, ... )
  63. {
  64. va_list va;
  65. if (Quiet < 2) {
  66. va_start( va, msg );
  67. vfprintf( stderr, msg, va );
  68. va_end( va );
  69. }
  70. }
  71. char *
  72. next_arg( char **s )
  73. {
  74. char *ret;
  75. if (!s || !*s)
  76. return 0;
  77. while (isspace( (unsigned char) **s ))
  78. (*s)++;
  79. if (!**s) {
  80. *s = 0;
  81. return 0;
  82. }
  83. if (**s == '"') {
  84. ++*s;
  85. ret = *s;
  86. *s = strchr( *s, '"' );
  87. } else {
  88. ret = *s;
  89. while (**s && !isspace( (unsigned char) **s ))
  90. (*s)++;
  91. }
  92. if (*s) {
  93. if (**s)
  94. *(*s)++ = 0;
  95. if (!**s)
  96. *s = 0;
  97. }
  98. return ret;
  99. }
  100. void
  101. add_string_list( string_list_t **list, const char *str )
  102. {
  103. string_list_t *elem;
  104. int len;
  105. len = strlen( str );
  106. elem = nfmalloc( sizeof(*elem) + len );
  107. elem->next = *list;
  108. *list = elem;
  109. memcpy( elem->string, str, len + 1 );
  110. }
  111. void
  112. free_string_list( string_list_t *list )
  113. {
  114. string_list_t *tlist;
  115. for (; list; list = tlist) {
  116. tlist = list->next;
  117. free( list );
  118. }
  119. }
  120. void
  121. free_generic_messages( message_t *msgs )
  122. {
  123. message_t *tmsg;
  124. for (; msgs; msgs = tmsg) {
  125. tmsg = msgs->next;
  126. free( msgs );
  127. }
  128. }
  129. void
  130. strip_cr( msg_data_t *msgdata )
  131. {
  132. int i, o;
  133. if (msgdata->crlf) {
  134. for (i = o = 0; i < msgdata->len; i++)
  135. if (msgdata->data[i] != '\r')
  136. msgdata->data[o++] = msgdata->data[i];
  137. msgdata->len = o;
  138. msgdata->crlf = 0;
  139. }
  140. }
  141. #ifndef HAVE_VASPRINTF
  142. static int
  143. vasprintf( char **strp, const char *fmt, va_list ap )
  144. {
  145. int len;
  146. char tmp[1024];
  147. if ((len = vsnprintf( tmp, sizeof(tmp), fmt, ap )) < 0 || !(*strp = malloc( len + 1 )))
  148. return -1;
  149. if (len >= (int)sizeof(tmp))
  150. vsprintf( *strp, fmt, ap );
  151. else
  152. memcpy( *strp, tmp, len + 1 );
  153. return len;
  154. }
  155. #endif
  156. void
  157. oob( void )
  158. {
  159. fputs( "Fatal: buffer too small. Please report a bug.\n", stderr );
  160. abort();
  161. }
  162. int
  163. nfsnprintf( char *buf, int blen, const char *fmt, ... )
  164. {
  165. int ret;
  166. va_list va;
  167. va_start( va, fmt );
  168. if (blen <= 0 || (unsigned)(ret = vsnprintf( buf, blen, fmt, va )) >= (unsigned)blen)
  169. oob();
  170. va_end( va );
  171. return ret;
  172. }
  173. static void ATTR_NORETURN
  174. oom( void )
  175. {
  176. fputs( "Fatal: Out of memory\n", stderr );
  177. abort();
  178. }
  179. void *
  180. nfmalloc( size_t sz )
  181. {
  182. void *ret;
  183. if (!(ret = malloc( sz )))
  184. oom();
  185. return ret;
  186. }
  187. void *
  188. nfcalloc( size_t sz )
  189. {
  190. void *ret;
  191. if (!(ret = calloc( sz, 1 )))
  192. oom();
  193. return ret;
  194. }
  195. void *
  196. nfrealloc( void *mem, size_t sz )
  197. {
  198. char *ret;
  199. if (!(ret = realloc( mem, sz )) && sz)
  200. oom();
  201. return ret;
  202. }
  203. char *
  204. nfstrdup( const char *str )
  205. {
  206. char *ret;
  207. if (!(ret = strdup( str )))
  208. oom();
  209. return ret;
  210. }
  211. int
  212. nfvasprintf( char **str, const char *fmt, va_list va )
  213. {
  214. int ret = vasprintf( str, fmt, va );
  215. if (ret < 0)
  216. oom();
  217. return ret;
  218. }
  219. int
  220. nfasprintf( char **str, const char *fmt, ... )
  221. {
  222. int ret;
  223. va_list va;
  224. va_start( va, fmt );
  225. ret = nfvasprintf( str, fmt, va );
  226. va_end( va );
  227. return ret;
  228. }
  229. /*
  230. static struct passwd *
  231. cur_user( void )
  232. {
  233. char *p;
  234. struct passwd *pw;
  235. uid_t uid;
  236. uid = getuid();
  237. if ((!(p = getenv("LOGNAME")) || !(pw = getpwnam( p )) || pw->pw_uid != uid) &&
  238. (!(p = getenv("USER")) || !(pw = getpwnam( p )) || pw->pw_uid != uid) &&
  239. !(pw = getpwuid( uid )))
  240. {
  241. fputs ("Cannot determinate current user\n", stderr);
  242. return 0;
  243. }
  244. return pw;
  245. }
  246. */
  247. static char *
  248. my_strndup( const char *s, size_t nchars )
  249. {
  250. char *r = nfmalloc( nchars + 1 );
  251. memcpy( r, s, nchars );
  252. r[nchars] = 0;
  253. return r;
  254. }
  255. char *
  256. expand_strdup( const char *s )
  257. {
  258. struct passwd *pw;
  259. const char *p, *q;
  260. char *r;
  261. if (*s == '~') {
  262. s++;
  263. if (!*s) {
  264. p = 0;
  265. q = Home;
  266. } else if (*s == '/') {
  267. p = s;
  268. q = Home;
  269. } else {
  270. if ((p = strchr( s, '/' ))) {
  271. r = my_strndup( s, (int)(p - s) );
  272. pw = getpwnam( r );
  273. free( r );
  274. } else
  275. pw = getpwnam( s );
  276. if (!pw)
  277. return 0;
  278. q = pw->pw_dir;
  279. }
  280. nfasprintf( &r, "%s%s", q, p ? p : "" );
  281. return r;
  282. } else
  283. return nfstrdup( s );
  284. }
  285. static int
  286. compare_ints( const void *l, const void *r )
  287. {
  288. return *(int *)l - *(int *)r;
  289. }
  290. void
  291. sort_ints( int *arr, int len )
  292. {
  293. qsort( arr, len, sizeof(int), compare_ints );
  294. }
  295. static struct {
  296. unsigned char i, j, s[256];
  297. } rs;
  298. void
  299. arc4_init( void )
  300. {
  301. int i, fd;
  302. unsigned char j, si, dat[128];
  303. if ((fd = open( "/dev/urandom", O_RDONLY )) < 0 && (fd = open( "/dev/random", O_RDONLY )) < 0) {
  304. fprintf( stderr, "Fatal: no random number source available.\n" );
  305. exit( 3 );
  306. }
  307. if (read( fd, dat, 128 ) != 128) {
  308. fprintf( stderr, "Fatal: cannot read random number source.\n" );
  309. exit( 3 );
  310. }
  311. close( fd );
  312. for (i = 0; i < 256; i++)
  313. rs.s[i] = i;
  314. for (i = j = 0; i < 256; i++) {
  315. si = rs.s[i];
  316. j += si + dat[i & 127];
  317. rs.s[i] = rs.s[j];
  318. rs.s[j] = si;
  319. }
  320. rs.i = rs.j = 0;
  321. for (i = 0; i < 256; i++)
  322. arc4_getbyte();
  323. }
  324. unsigned char
  325. arc4_getbyte( void )
  326. {
  327. unsigned char si, sj;
  328. rs.i++;
  329. si = rs.s[rs.i];
  330. rs.j += si;
  331. sj = rs.s[rs.j];
  332. rs.s[rs.i] = sj;
  333. rs.s[rs.j] = si;
  334. return rs.s[(si + sj) & 0xff];
  335. }