1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <mailutils/sys/mailcap.h>
22 #include <mailutils/iterator.h>
23
24 static int
25 finder_init (mu_mailcap_finder_t finder,
26 int flags,
27 struct mu_mailcap_selector_closure *sc,
28 struct mu_mailcap_error_closure *ec,
29 char **file_names);
30
31 int
mu_mailcap_finder_create(mu_mailcap_finder_t * pfinder,int flags,struct mu_mailcap_selector_closure * sc,struct mu_mailcap_error_closure * ec,char ** file_names)32 mu_mailcap_finder_create (mu_mailcap_finder_t *pfinder, int flags,
33 struct mu_mailcap_selector_closure *sc,
34 struct mu_mailcap_error_closure *ec,
35 char **file_names)
36 {
37 int rc;
38 mu_mailcap_finder_t finder;
39
40 if (!pfinder)
41 return MU_ERR_OUT_PTR_NULL;
42 if (!file_names)
43 return EINVAL;
44 finder = calloc (1, sizeof *finder);
45 if (!finder)
46 return ENOMEM;
47 rc = finder_init (finder, flags, sc, ec, file_names);
48 if (rc)
49 mu_mailcap_finder_destroy (&finder);
50 else
51 *pfinder = finder;
52 return rc;
53 }
54
55 static int
finder_init(mu_mailcap_finder_t finder,int flags,struct mu_mailcap_selector_closure * sc,struct mu_mailcap_error_closure * ec,char ** file_names)56 finder_init (mu_mailcap_finder_t finder,
57 int flags,
58 struct mu_mailcap_selector_closure *sc,
59 struct mu_mailcap_error_closure *ec,
60 char **file_names)
61 {
62 int rc;
63 size_t i;
64
65 rc = mu_mailcap_create (&finder->mcp);
66 if (rc)
67 return rc;
68 mu_mailcap_set_flags (finder->mcp, flags);
69 if (sc)
70 {
71 rc = mu_mailcap_set_selector (finder->mcp, sc);
72 if (rc)
73 return rc;
74 }
75 if (ec)
76 {
77 rc = mu_mailcap_set_error (finder->mcp, ec);
78 if (rc)
79 return rc;
80 }
81
82 for (i = 0; file_names[i]; i++)
83 {
84 if (access (file_names[i], F_OK))
85 continue;
86 mu_mailcap_parse_file (finder->mcp, file_names[i]);
87 }
88
89 return 0;
90 }
91
92 void
mu_mailcap_finder_destroy(mu_mailcap_finder_t * pfinder)93 mu_mailcap_finder_destroy (mu_mailcap_finder_t *pfinder)
94 {
95 if (pfinder && *pfinder)
96 {
97 mu_mailcap_finder_t finder = *pfinder;
98 mu_iterator_destroy (&finder->itr);
99 mu_mailcap_destroy (&finder->mcp);
100 free (finder);
101 *pfinder = NULL;
102 }
103 }
104
105 int
mu_mailcap_finder_next_match(mu_mailcap_finder_t finder,mu_mailcap_entry_t * ret_entry)106 mu_mailcap_finder_next_match (mu_mailcap_finder_t finder,
107 mu_mailcap_entry_t *ret_entry)
108 {
109 int rc;
110
111 if (!finder)
112 return EINVAL;
113 if (!ret_entry)
114 return MU_ERR_OUT_PTR_NULL;
115 if (!finder->itr)
116 {
117 rc = mu_mailcap_get_iterator (finder->mcp, &finder->itr);
118 if (rc == 0)
119 rc = mu_iterator_first (finder->itr);
120 }
121 else
122 rc = mu_iterator_next (finder->itr);
123
124 if (rc)
125 return rc;
126
127 if (mu_iterator_is_done (finder->itr))
128 return MU_ERR_NOENT;
129
130 return mu_iterator_current (finder->itr, (void**) ret_entry);
131 }
132