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

« back to all changes in this revision

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