config.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* $Id$
  2. *
  3. * isync - IMAP4 to maildir mailbox synchronizer
  4. * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
  5. * Copyright (C) 2002-2003 Oswald Buddenhagen <ossi@users.sf.net>
  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 of the License, or
  10. * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * As a special exception, isync may be linked with the OpenSSL library,
  22. * despite that library's more restrictive license.
  23. */
  24. #include "isync.h"
  25. #include <unistd.h>
  26. #include <limits.h>
  27. #include <errno.h>
  28. #include <pwd.h>
  29. #include <sys/types.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. config_t *boxes = 0;
  34. /* set defaults from the global configuration section */
  35. static void
  36. config_defaults (config_t * conf)
  37. {
  38. memcpy (conf, &global, sizeof (config_t));
  39. }
  40. static char *
  41. my_strndup (const char *s, size_t nchars)
  42. {
  43. char *r = malloc (sizeof (char) * (nchars + 1));
  44. if (r)
  45. {
  46. memcpy (r, s, nchars);
  47. r[nchars] = 0;
  48. }
  49. return r;
  50. }
  51. char *
  52. expand_strdup (const char *s)
  53. {
  54. char path[_POSIX_PATH_MAX];
  55. struct passwd *pw;
  56. const char *p;
  57. if (*s == '~')
  58. {
  59. s++;
  60. if (*s == '/')
  61. {
  62. /* current user */
  63. pw = getpwuid (getuid ());
  64. p = s + 1;
  65. }
  66. else
  67. {
  68. char *user;
  69. p = strchr (s, '/');
  70. if (p)
  71. {
  72. user = my_strndup (s, (int)(p - s));
  73. p++;
  74. }
  75. else
  76. user = strdup (s);
  77. pw = getpwnam (user);
  78. free (user);
  79. }
  80. if (!pw)
  81. return 0;
  82. snprintf (path, sizeof (path), "%s/%s", pw->pw_dir, p ? p : "");
  83. s = path;
  84. }
  85. else if (*s != '/')
  86. {
  87. snprintf (path, sizeof (path), "%s/%s",
  88. global.maildir ? global.maildir : "", s);
  89. s = path;
  90. }
  91. return strdup (s);
  92. }
  93. static int
  94. is_true (const char *val)
  95. {
  96. return
  97. !strcasecmp (val, "yes") ||
  98. !strcasecmp (val, "true") ||
  99. !strcasecmp (val, "on") ||
  100. !strcmp (val, "1");
  101. }
  102. void
  103. load_config (const char *where, int *o2o)
  104. {
  105. char path[_POSIX_PATH_MAX];
  106. char buf[1024];
  107. struct passwd *pw;
  108. config_t **stor = &boxes, *cfg;
  109. int line = 0;
  110. FILE *fp;
  111. char *p, *cmd, *val;
  112. if (!where)
  113. {
  114. pw = getpwuid (getuid ());
  115. snprintf (path, sizeof (path), "%s/.isyncrc", pw->pw_dir);
  116. where = path;
  117. }
  118. info ("Reading configuration file %s\n", where);
  119. fp = fopen (where, "r");
  120. if (!fp)
  121. {
  122. if (errno != ENOENT)
  123. perror ("fopen");
  124. return;
  125. }
  126. buf[sizeof buf - 1] = 0;
  127. cfg = &global;
  128. while ((fgets (buf, sizeof (buf) - 1, fp)))
  129. {
  130. p = buf;
  131. cmd = next_arg (&p);
  132. val = next_arg (&p);
  133. line++;
  134. if (!cmd || *cmd == '#')
  135. continue;
  136. if (!val) {
  137. fprintf (stderr, "%s:%d: parameter missing\n", path, line);
  138. continue;
  139. }
  140. if (!strcasecmp ("mailbox", cmd))
  141. {
  142. if (*o2o)
  143. break;
  144. cfg = *stor = malloc (sizeof (config_t));
  145. stor = &cfg->next;
  146. config_defaults (cfg);
  147. /* not expanded at this point */
  148. cfg->path = strdup (val);
  149. }
  150. else if (!strcasecmp ("OneToOne", cmd))
  151. {
  152. if (boxes) {
  153. forbid:
  154. fprintf (stderr,
  155. "%s:%d: keyword '%s' allowed only in global section\n",
  156. path, line, cmd);
  157. continue;
  158. }
  159. *o2o = is_true (val);
  160. }
  161. else if (!strcasecmp ("maildir", cmd))
  162. {
  163. if (boxes)
  164. goto forbid;
  165. /* this only affects the global setting */
  166. global.maildir = expand_strdup (val);
  167. }
  168. else if (!strcasecmp ("folder", cmd))
  169. {
  170. if (boxes)
  171. goto forbid;
  172. /* this only affects the global setting */
  173. global.folder = strdup (val);
  174. }
  175. else if (!strcasecmp ("inbox", cmd))
  176. {
  177. if (boxes)
  178. goto forbid;
  179. /* this only affects the global setting */
  180. global.inbox = strdup (val);
  181. }
  182. else if (!strcasecmp ("host", cmd))
  183. {
  184. #if HAVE_LIBSSL
  185. if (!strncasecmp ("imaps:", val, 6))
  186. {
  187. val += 6;
  188. cfg->use_imaps = 1;
  189. cfg->port = 993;
  190. cfg->use_sslv2 = 1;
  191. cfg->use_sslv3 = 1;
  192. }
  193. #endif
  194. cfg->host = strdup (val);
  195. }
  196. else if (!strcasecmp ("user", cmd))
  197. cfg->user = strdup (val);
  198. else if (!strcasecmp ("pass", cmd))
  199. cfg->pass = strdup (val);
  200. else if (!strcasecmp ("port", cmd))
  201. cfg->port = atoi (val);
  202. else if (!strcasecmp ("box", cmd))
  203. cfg->box = strdup (val);
  204. else if (!strcasecmp ("alias", cmd))
  205. {
  206. if (!boxes) {
  207. fprintf (stderr,
  208. "%s:%d: keyword 'alias' allowed only in mailbox specification\n",
  209. path, line);
  210. continue;
  211. }
  212. cfg->alias = strdup (val);
  213. }
  214. else if (!strcasecmp ("maxsize", cmd))
  215. cfg->max_size = atol (val);
  216. else if (!strcasecmp ("MaxMessages", cmd))
  217. cfg->max_messages = atol (val);
  218. else if (!strcasecmp ("UseNamespace", cmd))
  219. cfg->use_namespace = is_true (val);
  220. else if (!strcasecmp ("CopyDeletedTo", cmd))
  221. cfg->copy_deleted_to = strdup (val);
  222. else if (!strcasecmp ("Tunnel", cmd))
  223. cfg->tunnel = strdup (val);
  224. else if (!strcasecmp ("Expunge", cmd))
  225. cfg->expunge = is_true (val);
  226. else if (!strcasecmp ("Delete", cmd))
  227. cfg->delete = is_true (val);
  228. #if HAVE_LIBSSL
  229. else if (!strcasecmp ("CertificateFile", cmd))
  230. cfg->cert_file = expand_strdup (val);
  231. else if (!strcasecmp ("RequireSSL", cmd))
  232. cfg->require_ssl = is_true (val);
  233. else if (!strcasecmp ("UseSSLv2", cmd))
  234. cfg->use_sslv2 = is_true (val);
  235. else if (!strcasecmp ("UseSSLv3", cmd))
  236. cfg->use_sslv3 = is_true (val);
  237. else if (!strcasecmp ("UseTLSv1", cmd))
  238. cfg->use_tlsv1 = is_true (val);
  239. else if (!strcasecmp ("RequireCRAM", cmd))
  240. cfg->require_cram = is_true (val);
  241. #endif
  242. else if (buf[0])
  243. fprintf (stderr, "%s:%d: unknown keyword '%s'\n", path, line, cmd);
  244. }
  245. fclose (fp);
  246. }
  247. config_t *
  248. find_box (const char *s)
  249. {
  250. config_t *p = boxes;
  251. for (; p; p = p->next)
  252. {
  253. if (!strcmp (s, p->path) || (p->alias && !strcmp (s, p->alias)))
  254. return p;
  255. else
  256. {
  257. /* check to see if the full pathname was specified on the
  258. * command line.
  259. */
  260. char *t = expand_strdup (p->path);
  261. if (!strcmp (s, t))
  262. {
  263. free (t);
  264. return p;
  265. }
  266. free (t);
  267. }
  268. }
  269. return 0;
  270. }