1 #define _GNU_SOURCE
2 
3 #ifdef HAVE_CONFIG_H
4 #include "../config.h" //this should be conditional for win builds.
5 #endif
6 
7 #ifdef _MSC_VER
8 #	include "../src/bsd/getopt.h"
9 #else
10 #	include <getopt.h>
11 #endif
12 
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16 #include <stdlib.h>
17 #include <string.h>
18 #include <limits.h>
19 #ifndef PATH_MAX
20 #define PATH_MAX 4096
21 #endif
22 
23 #include <libetpan/libetpan.h>
24 
25 #include "option-parser.h"
26 
27 /*
28   options
29 
30   --driver (pop3|imap|nntp|mbox|mh|maildir)  -d
31 
32   default driver is mbox
33 
34   --server {server-name} -s
35   --port {port-number}   -p
36   --tls                  -t
37   --starttls             -x
38   --user {login}         -u
39   --password {password}  -v
40   --path {mailbox}       -l
41   --apop                 -a
42   --cache {directory}    -c
43   --flags {directory}    -f
44 */
45 
46 struct storage_name {
47   int id;
48   char * name;
49 };
50 
51 static struct storage_name storage_tab[] = {
52   {POP3_STORAGE, "pop3"},
53   {IMAP_STORAGE, "imap"},
54   {NNTP_STORAGE, "nntp"},
55   {MBOX_STORAGE, "mbox"},
56   {MH_STORAGE, "mh"},
57   {MAILDIR_STORAGE, "maildir"},
58   {FEED_STORAGE, "feed"},
59 };
60 
get_driver(char * name)61 static int get_driver(char * name)
62 {
63   int driver_type;
64   unsigned int i;
65 
66   driver_type = -1;
67   for(i = 0 ; i < sizeof(storage_tab) / sizeof(struct storage_name) ; i++) {
68     if (strcasecmp(name, storage_tab[i].name) == 0) {
69       driver_type = i;
70       break;
71     }
72   }
73 
74   return driver_type;
75 }
76 
parse_options(int argc,char ** argv,int * driver,char ** server,int * port,int * connection_type,char ** user,char ** password,int * auth_type,bool * xoauth2,char ** path,char ** cache_directory,char ** flags_directory)77 int parse_options(int argc, char ** argv,
78     int * driver,
79     char ** server, int * port, int * connection_type,
80     char ** user, char ** password, int * auth_type, bool * xoauth2,
81     char ** path, char ** cache_directory,
82     char ** flags_directory)
83 {
84   int indx;
85 #if HAVE_GETOPT_LONG
86   static struct option long_options[] = {
87     {"driver",   1, 0, 'd'},
88     {"server",   1, 0, 's'},
89     {"port",     1, 0, 'p'},
90     {"tls",      0, 0, 't'},
91     {"starttls", 0, 0, 'x'},
92     {"user",     1, 0, 'u'},
93     {"password", 1, 0, 'v'},
94     {"path",     1, 0, 'l'},
95     {"apop",     0, 0, 'a'},
96     {"oauth",    0, 0, 'o'},
97     {"cache",    1, 0, 'c'},
98     {"flags",    1, 0, 'f'},
99 	{"debug-stream", 0, 0, 'D'},
100     {NULL,       0, 0, 0},
101   };
102 #endif
103   int r;
104   char location[PATH_MAX];
105   char * env_user;
106 
107   indx = 0;
108 
109   * driver = MBOX_STORAGE;
110   * server = NULL;
111   * port = 0;
112   * connection_type = CONNECTION_TYPE_PLAIN;
113   * user = NULL;
114   * password = NULL;
115   * auth_type = POP3_AUTH_TYPE_PLAIN;
116   env_user = getenv("USER");
117   if (env_user != NULL) {
118     snprintf(location, PATH_MAX, "/var/mail/%s", env_user);
119     * path = strdup(location);
120   }
121   else
122     * path = NULL;
123   * cache_directory = NULL;
124   * flags_directory = NULL;
125 
126   while (1) {
127 #if HAVE_GETOPT_LONG
128     r = getopt_long(argc, argv, "d:s:p:txu:v:l:aoc:f:D", long_options, &indx);
129 #else
130     r = getopt(argc, argv, "d:s:p:txu:v:l:aoc:f:D");
131 #endif
132 
133     if (r == -1)
134       break;
135 
136     switch (r) {
137     case 'd':
138       * driver = get_driver(optarg);
139       break;
140     case 's':
141       if (* server != NULL)
142         free(* server);
143       * server = strdup(optarg);
144       break;
145     case 'p':
146       * port = strtoul(optarg, NULL, 10);
147       break;
148     case 't':
149       * connection_type = CONNECTION_TYPE_TLS;
150       break;
151     case 'x':
152       * connection_type = CONNECTION_TYPE_STARTTLS;
153         break;
154     case 'u':
155       if (* user != NULL)
156         free(* user);
157       * user = strdup(optarg);
158       break;
159     case 'v':
160       if (* password != NULL)
161         free(* password);
162       * password = strdup(optarg);
163       break;
164     case 'l':
165       if (* path != NULL)
166         free(* path);
167       * path = strdup(optarg);
168       break;
169     case 'a':
170       * auth_type = POP3_AUTH_TYPE_APOP;
171       break;
172     case 'o':
173       * xoauth2 = true;
174       break;
175     case 'c':
176       if (* cache_directory != NULL)
177         free(* cache_directory);
178       * cache_directory = strdup(optarg);
179       break;
180     case 'f':
181       if (* flags_directory != NULL)
182         free(* flags_directory);
183       * flags_directory = strdup(optarg);
184       break;
185 	case 'D':
186 		mailstream_debug = 1;
187 		break;
188     }
189   }
190 
191   return 0;
192 }
193 
init_storage(struct mailstorage * storage,int driver,const char * server,int port,int connection_type,const char * user,const char * password,int auth_type,bool xoauth2,const char * path,const char * cache_directory,const char * flags_directory)194 int init_storage(struct mailstorage * storage,
195     int driver, const char * server, int port,
196     int connection_type, const char * user, const char * password, int auth_type, bool xoauth2,
197     const char * path, const char * cache_directory, const char * flags_directory)
198 {
199   int r;
200   int cached;
201 
202   cached = (cache_directory != NULL);
203 
204   switch (driver) {
205   case POP3_STORAGE:
206     r = pop3_mailstorage_init(storage, server, port, NULL, connection_type,
207         auth_type, user, password, cached, cache_directory,
208         flags_directory);
209     if (r != MAIL_NO_ERROR) {
210       printf("error initializing POP3 storage\n");
211       goto err;
212     }
213     break;
214 
215   case IMAP_STORAGE:
216     if (xoauth2) {
217       r = imap_mailstorage_init_sasl(storage, server, port, NULL, connection_type,
218           "xoauth2", NULL, NULL, NULL, NULL, user, password, NULL, cached, cache_directory);
219     } else {
220       r = imap_mailstorage_init(storage, server, port, NULL, connection_type,
221           IMAP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory);
222     }
223     if (r != MAIL_NO_ERROR) {
224       printf("error initializing IMAP storage\n");
225       goto err;
226     }
227     break;
228 
229   case NNTP_STORAGE:
230     r = nntp_mailstorage_init(storage, server, port, NULL, connection_type,
231         NNTP_AUTH_TYPE_PLAIN, user, password, cached, cache_directory,
232         flags_directory);
233     if (r != MAIL_NO_ERROR) {
234       printf("error initializing NNTP storage\n");
235       goto err;
236     }
237     break;
238 
239   case MBOX_STORAGE:
240     r = mbox_mailstorage_init(storage, path, cached, cache_directory,
241         flags_directory);
242     if (r != MAIL_NO_ERROR) {
243       printf("error initializing mbox storage\n");
244       goto err;
245     }
246     break;
247 
248   case MH_STORAGE:
249     r = mh_mailstorage_init(storage, path, cached, cache_directory,
250         flags_directory);
251     if (r != MAIL_NO_ERROR) {
252       printf("error initializing MH storage\n");
253       goto err;
254     }
255     break;
256   case MAILDIR_STORAGE:
257     r = maildir_mailstorage_init(storage, path, cached, cache_directory,
258         flags_directory);
259     if (r != MAIL_NO_ERROR) {
260       printf("error initializing maildir storage\n");
261       goto err;
262     }
263     break;
264   case FEED_STORAGE:
265     r = feed_mailstorage_init(storage, path, cached, cache_directory,
266         flags_directory);
267     if (r != MAIL_NO_ERROR) {
268       printf("error initializing feed storage\n");
269       goto err;
270     }
271     break;
272   }
273 
274   return MAIL_NO_ERROR;
275 
276  err:
277   return r;
278 }
279 
280