~ubuntu-branches/ubuntu/trusty/libnss-db/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/030-no_internal_libc.patch/src/db-XXX.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-10-05 00:29:58 UTC
  • Revision ID: package-import@ubuntu.com-20121005002958-krtscomqp8o3a3bp
Tags: 2.2.3pre1-5
* QA upload.
* Remove old debian/packages file, unused since conversion from yada.
* Convert to source format 3.0 (quilt) (closes: #679676).  Add po/Makevars
  to 080-translations.patch.  Refresh all patches.
* Use dh_installman to install makedb.1.
* Add debhelper token to libnss-db.postinst.
* Link to a versioned copy of the GPL in debian/copyright.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Common code for DB-based databases in nss_db module.
 
2
   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
3
   This file is part of the GNU C Library.
 
4
 
 
5
   The GNU C Library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public License as
 
7
   published by the Free Software Foundation; either version 2 of the
 
8
   License, or (at your option) any later version.
 
9
 
 
10
   The GNU C Library is distributed in the hope that it will be useful,
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   Library General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Library General Public
 
16
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
 
17
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
   Boston, MA 02111-1307, USA.  */
 
19
 
 
20
#include <alloca.h>
 
21
#include <ctype.h>
 
22
#include <db.h>
 
23
#include <netdb.h>
 
24
#include <stdio.h>
 
25
#include <string.h>
 
26
 
 
27
#include <bits/libc-lock.h>
 
28
 
 
29
#include "nss_db.h"
 
30
 
 
31
/* These symbols are defined by the including source file:
 
32
 
 
33
   ENTNAME -- database name of the structure and functions (hostent, pwent).
 
34
   STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
 
35
   DATABASE -- database file name, ("hosts", "passwd")
 
36
 
 
37
   NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
 
38
*/
 
39
 
 
40
#define ENTNAME_r       CONCAT(ENTNAME,_r)
 
41
 
 
42
#include <paths.h>
 
43
#define DBFILE          _PATH_VARDB DATABASE ".db"
 
44
 
 
45
#ifdef NEED_H_ERRNO
 
46
#define H_ERRNO_PROTO   , int *herrnop
 
47
#define H_ERRNO_ARG     , herrnop
 
48
#define H_ERRNO_SET(val) (*herrnop = (val))
 
49
#else
 
50
#define H_ERRNO_PROTO
 
51
#define H_ERRNO_ARG
 
52
#define H_ERRNO_SET(val) ((void) 0)
 
53
#endif
 
54
 
 
55
/* Locks the static variables in this file.  */
 
56
__libc_lock_define_initialized (static, lock)
 
57
 
 
58
/* Maintenance of the shared handle open on the database.  */
 
59
 
 
60
static DB *db;
 
61
static int keep_db;
 
62
static int entidx;
 
63
 
 
64
 
 
65
/* Open the database.  */
 
66
enum nss_status
 
67
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
 
68
{
 
69
  enum nss_status status;
 
70
 
 
71
  __libc_lock_lock (lock);
 
72
 
 
73
  status = internal_setent (DBFILE, &db);
 
74
 
 
75
  /* Remember STAYOPEN flag.  */
 
76
  if (db != NULL)
 
77
    keep_db |= stayopen;
 
78
  /* Reset the sequential index.  */
 
79
  entidx = 0;
 
80
 
 
81
  __libc_lock_unlock (lock);
 
82
 
 
83
  return status;
 
84
}
 
85
 
 
86
 
 
87
/* Close it again.  */
 
88
enum nss_status
 
89
CONCAT(_nss_db_end,ENTNAME) (void)
 
90
{
 
91
  __libc_lock_lock (lock);
 
92
 
 
93
  internal_endent (&db);
 
94
 
 
95
  /* Reset STAYOPEN flag.  */
 
96
  keep_db = 0;
 
97
 
 
98
  __libc_lock_unlock (lock);
 
99
 
 
100
  return NSS_STATUS_SUCCESS;
 
101
}
 
102
 
 
103
/* Do a database lookup for KEY.  */
 
104
static enum nss_status
 
105
lookup (DBT *key, struct STRUCTURE *result,
 
106
        void *buffer, size_t buflen, int *errnop H_ERRNO_PROTO EXTRA_ARGS_DECL)
 
107
{
 
108
  char *p;
 
109
  enum nss_status status;
 
110
  int err;
 
111
  DBT value;
 
112
 
 
113
  /* Open the database.  */
 
114
  if (db == NULL)
 
115
    {
 
116
      status = internal_setent (DBFILE, &db);
 
117
      if (status != NSS_STATUS_SUCCESS)
 
118
        {
 
119
          *errnop = errno;
 
120
          H_ERRNO_SET (NETDB_INTERNAL);
 
121
          return status;
 
122
        }
 
123
    }
 
124
 
 
125
  /* Succeed iff it matches a value that parses correctly.  */
 
126
  value.flags = 0;
 
127
  err = db->get (db, NULL, key, &value, 0);
 
128
  if (err)
 
129
    {
 
130
      if (err > 0)
 
131
        {
 
132
          *errnop = err;
 
133
          H_ERRNO_SET (NETDB_INTERNAL);
 
134
          status = NSS_STATUS_UNAVAIL;
 
135
        }
 
136
      else
 
137
        {
 
138
          switch (err)
 
139
            {
 
140
            case DB_NOTFOUND:
 
141
              H_ERRNO_SET (HOST_NOT_FOUND);
 
142
              status = NSS_STATUS_NOTFOUND;
 
143
              break;
 
144
 
 
145
            default:
 
146
              H_ERRNO_SET (NO_RECOVERY);
 
147
              status = NSS_STATUS_UNAVAIL;
 
148
              break;
 
149
            }
 
150
        }
 
151
    }
 
152
  else if (buflen < value.size)
 
153
    {
 
154
      /* No room to copy the data to.  */
 
155
      *errnop = ERANGE;
 
156
      H_ERRNO_SET (NETDB_INTERNAL);
 
157
      status = NSS_STATUS_TRYAGAIN;
 
158
    }
 
159
  else
 
160
    {
 
161
      /* Copy the result to a safe place.  */
 
162
      p = (char *) memcpy (buffer, value.data, value.size);
 
163
 
 
164
      /* Skip leading blanks.  */
 
165
      while (isspace (*p))
 
166
        ++p;
 
167
 
 
168
      err = parse_line (p, result, buffer, buflen, errnop EXTRA_ARGS);
 
169
 
 
170
      if (err == 0)
 
171
        {
 
172
          /* If the key begins with '0' we are trying to get the next
 
173
             entry.  We want to ignore unparsable lines in this case.  */
 
174
          if (((char *) key->data)[0] == '0')
 
175
            {
 
176
              /* Super magical return value.  We need to tell our caller
 
177
                 that it should continue looping.  This value cannot
 
178
                 happen in other cases.  */
 
179
              status = NSS_STATUS_RETURN;
 
180
            }
 
181
          else
 
182
            {
 
183
              H_ERRNO_SET (HOST_NOT_FOUND);
 
184
              status = NSS_STATUS_NOTFOUND;
 
185
            }
 
186
        }
 
187
      else if (err < 0)
 
188
        {
 
189
          H_ERRNO_SET (NETDB_INTERNAL);
 
190
          status = NSS_STATUS_TRYAGAIN;
 
191
        }
 
192
      else
 
193
        status = NSS_STATUS_SUCCESS;
 
194
    }
 
195
 
 
196
  if (! keep_db)
 
197
    internal_endent (&db);
 
198
 
 
199
  return status;
 
200
}
 
201
 
 
202
 
 
203
/* Macro for defining lookup functions for this DB-based database.
 
204
 
 
205
   NAME is the name of the lookup; e.g. `pwnam'.
 
206
 
 
207
   KEYPATTERN gives `printf' args to construct a key string;
 
208
   e.g. `(".%s", name)'.
 
209
 
 
210
   KEYSIZE gives the allocation size of a buffer to construct it in;
 
211
   e.g. `1 + strlen (name)'.
 
212
 
 
213
   PROTO describes the arguments for the lookup key;
 
214
   e.g. `const char *name'.
 
215
 
 
216
   BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c.  */
 
217
 
 
218
#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)        \
 
219
enum nss_status                                                               \
 
220
_nss_db_get##name##_r (proto,                                                 \
 
221
                       struct STRUCTURE *result,                              \
 
222
                       char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)\
 
223
{                                                                             \
 
224
  DBT key;                                                                    \
 
225
  enum nss_status status;                                                     \
 
226
  const size_t size = (keysize) + 1;                                          \
 
227
  key.data = alloca (size);                                                   \
 
228
  key.size = KEYPRINTF keypattern;                                            \
 
229
  key.flags = 0;                                                              \
 
230
  __libc_lock_lock (lock);                                                    \
 
231
  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG           \
 
232
                   EXTRA_ARGS_VALUE);                                         \
 
233
  __libc_lock_unlock (lock);                                                  \
 
234
  return status;                                                              \
 
235
}
 
236
 
 
237
#define KEYPRINTF(pattern, args...) snprintf (key.data, size, pattern ,##args)
 
238
 
 
239
 
 
240
 
 
241
 
 
242
/* Return the next entry from the database file, doing locking.  */
 
243
enum nss_status
 
244
CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
 
245
                               size_t buflen, int *errnop H_ERRNO_PROTO)
 
246
{
 
247
  /* Return next entry in host file.  */
 
248
  enum nss_status status;
 
249
  char buf[20];
 
250
  DBT key;
 
251
 
 
252
  __libc_lock_lock (lock);
 
253
 
 
254
  /* Loop until we find a valid entry or hit EOF.  See above for the
 
255
     special meaning of the status value.  */
 
256
  do
 
257
    {
 
258
      key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
 
259
      key.flags = 0;
 
260
      status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG
 
261
                       EXTRA_ARGS_VALUE);
 
262
      if (status == NSS_STATUS_TRYAGAIN
 
263
#ifdef NEED_H_ERRNO
 
264
          && *herrnop == NETDB_INTERNAL
 
265
#endif
 
266
          && *errnop == ERANGE)
 
267
        /* Give the user a chance to get the same entry with a larger
 
268
           buffer.  */
 
269
        --entidx;
 
270
    }
 
271
  while (status == NSS_STATUS_RETURN);
 
272
 
 
273
  __libc_lock_unlock (lock);
 
274
 
 
275
  return status;
 
276
}