config.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* $Id$
  2. *
  3. * isync - IMAP4 to maildir mailbox synchronizer
  4. * Copyright (C) 2000-1 Michael R. Elkins <me@mutt.org>
  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. #define _GNU_SOURCE 1
  21. #include <unistd.h>
  22. #include <limits.h>
  23. #include <errno.h>
  24. #include <pwd.h>
  25. #include <sys/types.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include "isync.h"
  30. config_t *boxes = 0;
  31. /* set defaults from the global configuration section */
  32. static void
  33. config_defaults (config_t * conf)
  34. {
  35. memcpy (conf, &global, sizeof (config_t));
  36. }
  37. #ifndef HAVE_STRNDUP
  38. static char *
  39. strndup (const char *s, size_t nchars)
  40. {
  41. char *r = malloc (sizeof (char) * (nchars + 1));
  42. strncpy (r, s, nchars);
  43. r[nchars] = 0;
  44. return r;
  45. }
  46. #endif /* ! HAVE_STRNDUP */
  47. char *
  48. expand_strdup (const char *s)
  49. {
  50. char path[_POSIX_PATH_MAX];
  51. struct passwd *pw;
  52. const char *p;
  53. if (*s == '~')
  54. {
  55. s++;
  56. if (*s == '/')
  57. {
  58. /* current user */
  59. pw = getpwuid (getuid ());
  60. p = s + 1;
  61. }
  62. else
  63. {
  64. char *user;
  65. p = strchr (s, '/');
  66. if (p)
  67. {
  68. user = strndup (s, (int)(p - s));
  69. p++;
  70. }
  71. else
  72. user = strdup (s);
  73. pw = getpwnam (user);
  74. free (user);
  75. }
  76. if (!pw)
  77. return 0;
  78. snprintf (path, sizeof (path), "%s/%s", pw->pw_dir, p ? p : "");
  79. s = path;
  80. }
  81. else if (*s != '/')
  82. {
  83. snprintf (path, sizeof (path), "%s/%s",
  84. global.maildir ? global.maildir : "", s);
  85. s = path;
  86. }
  87. return strdup (s);
  88. }
  89. void
  90. load_config (const char *where)
  91. {
  92. char path[_POSIX_PATH_MAX];
  93. char buf[1024];
  94. struct passwd *pw;
  95. config_t **cur = &boxes;
  96. int line = 0;
  97. FILE *fp;
  98. char *p, *cmd, *val;
  99. if (!where)
  100. {
  101. pw = getpwuid (getuid ());
  102. snprintf (path, sizeof (path), "%s/.isyncrc", pw->pw_dir);
  103. where = path;
  104. }
  105. printf ("Reading %s\n", where);
  106. fp = fopen (where, "r");
  107. if (!fp)
  108. {
  109. if (errno != ENOENT)
  110. perror ("fopen");
  111. return;
  112. }
  113. buf[sizeof buf - 1] = 0;
  114. while ((fgets (buf, sizeof (buf) - 1, fp)))
  115. {
  116. p = buf;
  117. cmd = next_arg (&p);
  118. val = next_arg (&p);
  119. line++;
  120. if (!cmd || *cmd == '#')
  121. continue;
  122. if (!strcasecmp ("mailbox", cmd))
  123. {
  124. if (*cur)
  125. cur = &(*cur)->next;
  126. *cur = calloc (1, sizeof (config_t));
  127. config_defaults (*cur);
  128. /* not expanded at this point */
  129. (*cur)->path = strdup (val);
  130. }
  131. else if (!strcasecmp ("maildir", cmd))
  132. {
  133. /* this only affects the global setting */
  134. free (global.maildir);
  135. global.maildir = expand_strdup (val);
  136. }
  137. else if (!strcasecmp ("host", cmd))
  138. {
  139. #if HAVE_LIBSSL
  140. if (!strncasecmp ("imaps:", val, 6))
  141. {
  142. val += 6;
  143. if (*cur)
  144. {
  145. (*cur)->use_imaps = 1;
  146. (*cur)->port = 993;
  147. (*cur)->use_sslv2 = 1;
  148. (*cur)->use_sslv3 = 1;
  149. }
  150. else
  151. {
  152. global.use_imaps = 1;
  153. global.port = 993;
  154. global.use_sslv2 = 1;
  155. global.use_sslv3 = 1;
  156. }
  157. }
  158. #endif
  159. if (*cur)
  160. (*cur)->host = strdup (val);
  161. else
  162. global.host = strdup (val);
  163. }
  164. else if (!strcasecmp ("user", cmd))
  165. {
  166. if (*cur)
  167. (*cur)->user = strdup (val);
  168. else
  169. global.user = strdup (val);
  170. }
  171. else if (!strcasecmp ("pass", cmd))
  172. {
  173. if (*cur)
  174. (*cur)->pass = strdup (val);
  175. else
  176. global.pass = strdup (val);
  177. }
  178. else if (!strcasecmp ("port", cmd))
  179. {
  180. if (*cur)
  181. (*cur)->port = atoi (val);
  182. else
  183. global.port = atoi (val);
  184. }
  185. else if (!strcasecmp ("box", cmd))
  186. {
  187. if (*cur)
  188. (*cur)->box = strdup (val);
  189. else
  190. global.box = strdup (val);
  191. }
  192. else if (!strcasecmp ("alias", cmd))
  193. {
  194. if (*cur)
  195. (*cur)->alias = strdup (val);
  196. }
  197. else if (!strcasecmp ("maxsize", cmd))
  198. {
  199. if (*cur)
  200. (*cur)->max_size = atol (val);
  201. else
  202. global.max_size = atol (val);
  203. }
  204. else if (!strcasecmp ("MaxMessages", cmd))
  205. {
  206. if (*cur)
  207. (*cur)->max_messages = atol (val);
  208. else
  209. global.max_messages = atol (val);
  210. }
  211. else if (!strcasecmp ("UseNamespace", cmd))
  212. {
  213. if (*cur)
  214. (*cur)->use_namespace = (strcasecmp (val, "yes") == 0);
  215. else
  216. global.use_namespace = (strcasecmp (val, "yes") == 0);
  217. }
  218. else if (!strcasecmp ("CopyDeletedTo", cmd))
  219. {
  220. if (*cur)
  221. (*cur)->copy_deleted_to = strdup (val);
  222. else
  223. global.copy_deleted_to = strdup (val);
  224. }
  225. else if (!strcasecmp ("Expunge", cmd))
  226. {
  227. if (*cur)
  228. (*cur)->expunge = (strcasecmp (val, "yes") == 0);
  229. else
  230. global.expunge = (strcasecmp (val, "yes") == 0);
  231. }
  232. else if (!strcasecmp ("Delete", cmd))
  233. {
  234. if (*cur)
  235. (*cur)->delete = (strcasecmp (val, "yes") == 0);
  236. else
  237. global.delete = (strcasecmp (val, "yes") == 0);
  238. }
  239. #if HAVE_LIBSSL
  240. else if (!strcasecmp ("CertificateFile", cmd))
  241. {
  242. if (*cur)
  243. (*cur)->cert_file = expand_strdup (val);
  244. else
  245. global.cert_file = expand_strdup (val);
  246. }
  247. else if (!strcasecmp ("RequireSSL", cmd))
  248. {
  249. if (*cur)
  250. (*cur)->require_ssl = (strcasecmp (val, "yes") == 0);
  251. else
  252. global.require_ssl = (strcasecmp (val, "yes") == 0);
  253. }
  254. else if (!strcasecmp ("UseSSLv2", cmd))
  255. {
  256. if (*cur)
  257. (*cur)->use_sslv2 = (strcasecmp (val, "yes") == 0);
  258. else
  259. global.use_sslv2 = (strcasecmp (val, "yes") == 0);
  260. }
  261. else if (!strcasecmp ("UseSSLv3", cmd))
  262. {
  263. if (*cur)
  264. (*cur)->use_sslv3 = (strcasecmp (val, "yes") == 0);
  265. else
  266. global.use_sslv3 = (strcasecmp (val, "yes") == 0);
  267. }
  268. else if (!strcasecmp ("UseTLSv1", cmd))
  269. {
  270. if (*cur)
  271. (*cur)->use_tlsv1 = (strcasecmp (val, "yes") == 0);
  272. else
  273. global.use_tlsv1 = (strcasecmp (val, "yes") == 0);
  274. }
  275. else if (!strcasecmp ("RequireCRAM", cmd))
  276. {
  277. if (*cur)
  278. (*cur)->require_cram = (strcasecmp (val, "yes") == 0);
  279. else
  280. global.require_cram = (strcasecmp (val, "yes") == 0);
  281. }
  282. #endif
  283. else if (buf[0])
  284. printf ("%s:%d:unknown keyword:%s\n", path, line, cmd);
  285. }
  286. fclose (fp);
  287. }
  288. config_t *
  289. find_box (const char *s)
  290. {
  291. config_t *p = boxes;
  292. for (; p; p = p->next)
  293. {
  294. if (!strcmp (s, p->path) || (p->alias && !strcmp (s, p->alias)))
  295. return p;
  296. else
  297. {
  298. /* check to see if the full pathname was specified on the
  299. * command line.
  300. */
  301. char *t = expand_strdup (p->path);
  302. if (!strcmp (s, t))
  303. {
  304. free (t);
  305. return p;
  306. }
  307. free (t);
  308. }
  309. }
  310. return 0;
  311. }