]>
Commit | Line | Data |
---|---|---|
26761c28 | 1 | /* Mail alias file parser in nss_db module. |
9a6450d5 | 2 | Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. |
26761c28 UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
26761c28 UD |
10 | |
11 | The GNU C Library 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 GNU | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
26761c28 | 15 | |
41bdb6e2 AJ |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with the GNU C Library; if not, write to the Free | |
18 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
19 | 02111-1307 USA. */ | |
26761c28 UD |
20 | |
21 | #include <aliases.h> | |
22 | #include <alloca.h> | |
23 | #include <ctype.h> | |
9a6450d5 | 24 | #include <dlfcn.h> |
26761c28 | 25 | #include <errno.h> |
5107cf1d | 26 | #include <bits/libc-lock.h> |
26761c28 UD |
27 | #include <paths.h> |
28 | #include <string.h> | |
29 | ||
30 | #include "nsswitch.h" | |
9a6450d5 | 31 | #include "nss_db.h" |
26761c28 UD |
32 | |
33 | /* Locks the static variables in this file. */ | |
34 | __libc_lock_define_initialized (static, lock) | |
35 | \f | |
36 | /* Maintenance of the shared handle open on the database. */ | |
37 | ||
9a6450d5 | 38 | static NSS_DB *db; |
26761c28 UD |
39 | static int keep_db; |
40 | static unsigned int entidx; /* Index for `getaliasent_r'. */ | |
41 | ||
b5701890 | 42 | |
9a6450d5 | 43 | /* Open database. */ |
26761c28 UD |
44 | enum nss_status |
45 | _nss_db_setaliasent (int stayopen) | |
46 | { | |
47 | enum nss_status status; | |
48 | ||
49 | __libc_lock_lock (lock); | |
50 | ||
9a6450d5 UD |
51 | status = internal_setent (_PATH_VARDB "aliases.db", &db); |
52 | ||
53 | /* Remember STAYOPEN flag. */ | |
54 | if (db != NULL) | |
55 | keep_db |= stayopen; | |
26761c28 UD |
56 | |
57 | /* Reset the sequential index. */ | |
58 | entidx = 0; | |
59 | ||
60 | __libc_lock_unlock (lock); | |
61 | ||
62 | return status; | |
63 | } | |
64 | ||
65 | ||
9a6450d5 | 66 | /* Close it again. */ |
26761c28 UD |
67 | enum nss_status |
68 | _nss_db_endaliasent (void) | |
69 | { | |
70 | __libc_lock_lock (lock); | |
71 | ||
9a6450d5 | 72 | internal_endent (&db); |
26761c28 UD |
73 | |
74 | /* Reset STAYOPEN flag. */ | |
75 | keep_db = 0; | |
76 | ||
77 | __libc_lock_unlock (lock); | |
78 | ||
79 | return NSS_STATUS_SUCCESS; | |
80 | } | |
81 | \f | |
82 | /* We provide the parse function here. The parser in libnss_files | |
83 | cannot be used. The generation of the db file already resolved all | |
84 | :include: statements so we simply have to parse the list and store | |
85 | the result. */ | |
86 | static enum nss_status | |
5148d49f | 87 | lookup (DBT *key, struct aliasent *result, char *buffer, |
d71b808a | 88 | size_t buflen, int *errnop) |
26761c28 UD |
89 | { |
90 | enum nss_status status; | |
91 | DBT value; | |
92 | ||
93 | /* Open the database. */ | |
9a6450d5 | 94 | if (db == NULL) |
5148d49f | 95 | { |
9a6450d5 UD |
96 | status = internal_setent (_PATH_VARDB "aliases.db", &db); |
97 | if (status != NSS_STATUS_SUCCESS) | |
98 | { | |
99 | *errnop = errno; | |
100 | return status; | |
101 | } | |
5148d49f | 102 | } |
26761c28 | 103 | |
5148d49f | 104 | value.flags = 0; |
9a6450d5 | 105 | if (DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0)) == 0) |
26761c28 UD |
106 | { |
107 | const char *src = value.data; | |
9a6450d5 UD |
108 | char *cp; |
109 | size_t cnt; | |
26761c28 UD |
110 | |
111 | result->alias_members_len = 0; | |
112 | ||
113 | /* We now have to fill the BUFFER with all the information. */ | |
114 | if (buflen < key->size + 1) | |
115 | { | |
116 | no_more_room: | |
d71b808a | 117 | *errnop = ERANGE; |
26761c28 UD |
118 | return NSS_STATUS_TRYAGAIN; |
119 | } | |
120 | ||
9a6450d5 UD |
121 | buffer = stpncpy (buffer, key->data, key->size) + 1; |
122 | buflen -= key->size + 1; | |
123 | ||
124 | while (*src != '\0') | |
26761c28 | 125 | { |
9a6450d5 UD |
126 | const char *end, *upto; |
127 | while (isspace (*src)) | |
128 | ++src; | |
26761c28 | 129 | |
9a6450d5 UD |
130 | end = strchr (src, ','); |
131 | if (end == NULL) | |
132 | end = strchr (src, '\0'); | |
133 | for (upto = end; upto > src && isspace (upto[-1]); --upto); | |
26761c28 | 134 | |
9a6450d5 | 135 | if (upto != src) |
26761c28 | 136 | { |
9a6450d5 UD |
137 | if ((upto - src) + __alignof__ (char *) > buflen) |
138 | goto no_more_room; | |
139 | buffer = stpncpy (buffer, src, upto - src) + 1; | |
140 | buflen -= (upto - src) + __alignof (char *); | |
141 | ++result->alias_members_len; | |
26761c28 | 142 | } |
9a6450d5 UD |
143 | src = end + (*end != '\0'); |
144 | } | |
26761c28 | 145 | |
9a6450d5 UD |
146 | /* Now prepare the return. Provide string pointers for the |
147 | currently selected aliases. */ | |
26761c28 | 148 | |
9a6450d5 UD |
149 | /* Adjust the pointer so it is aligned for storing pointers. */ |
150 | buffer += __alignof__ (char *) - 1; | |
151 | buffer -= ((buffer - (char *) 0) % __alignof__ (char *)); | |
152 | result->alias_members = (char **) buffer; | |
26761c28 | 153 | |
9a6450d5 UD |
154 | /* Compute addresses of alias entry strings. */ |
155 | cp = result->alias_name; | |
156 | for (cnt = 0; cnt < result->alias_members_len; ++cnt) | |
157 | { | |
158 | cp = strchr (cp, '\0') + 1; | |
159 | result->alias_members[cnt] = cp; | |
26761c28 | 160 | } |
9a6450d5 UD |
161 | |
162 | status = (result->alias_members_len == 0 | |
163 | ? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS); | |
26761c28 UD |
164 | } |
165 | else | |
166 | status = NSS_STATUS_NOTFOUND; | |
167 | ||
168 | if (! keep_db) | |
9a6450d5 | 169 | internal_endent (&db); |
26761c28 UD |
170 | |
171 | return status; | |
172 | } | |
173 | \f | |
174 | enum nss_status | |
d71b808a UD |
175 | _nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen, |
176 | int *errnop) | |
26761c28 | 177 | { |
74015205 | 178 | /* Return next entry in alias file. */ |
26761c28 UD |
179 | enum nss_status status; |
180 | char buf[20]; | |
181 | DBT key; | |
182 | ||
183 | __libc_lock_lock (lock); | |
74015205 | 184 | key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++); |
5148d49f | 185 | key.flags = 0; |
d71b808a | 186 | status = lookup (&key, result, buffer, buflen, errnop); |
5148d49f UD |
187 | if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) |
188 | /* Give the user a chance to get the same entry with a larger buffer. */ | |
189 | --entidx; | |
26761c28 UD |
190 | __libc_lock_unlock (lock); |
191 | ||
192 | return status; | |
193 | } | |
194 | ||
195 | ||
196 | enum nss_status | |
197 | _nss_db_getaliasbyname_r (const char *name, struct aliasent *result, | |
d71b808a | 198 | char *buffer, size_t buflen, int *errnop) |
26761c28 UD |
199 | { |
200 | DBT key; | |
201 | enum nss_status status; | |
202 | ||
203 | key.size = 1 + strlen (name); | |
204 | ||
205 | key.data = __alloca (key.size); | |
206 | ((char *) key.data)[0] = '.'; | |
207 | memcpy (&((char *) key.data)[1], name, key.size - 1); | |
5148d49f | 208 | key.flags = 0; |
26761c28 UD |
209 | |
210 | __libc_lock_lock (lock); | |
d71b808a | 211 | status = lookup (&key, result, buffer, buflen, errnop); |
26761c28 UD |
212 | __libc_lock_unlock (lock); |
213 | ||
214 | return status; | |
215 | } |