diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-10-18 15:16:22 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-10-18 15:16:22 +0000 |
commit | 67479a700e3bd2e52980c00ac35c888589ac0a36 (patch) | |
tree | 2a13dea0fbd27ba19d0b19d5849699128d495806 /nscd/nscd_getgr_r.c | |
parent | 6cde0c6047769a661b8cf7e4f93842914a4bb54f (diff) | |
download | glibc-67479a700e3bd2e52980c00ac35c888589ac0a36.tar.gz glibc-67479a700e3bd2e52980c00ac35c888589ac0a36.tar.xz glibc-67479a700e3bd2e52980c00ac35c888589ac0a36.zip |
Update.
1998-10-18 Ulrich Drepper <drepper@cygnus.com> * resolv/nss_dns/dns-host.c: Add missing errnop parameter to the NSS functions. * resolv/nss_dns/dns-network.c: Likewise. * grp/Makefile: Don't search for linuxhtreads in add-ons, use have-thread-library to determine whether threads are available. * pwd/Makefile: Remove wrong comment. * inet/Makefile: Define CFLAGS-gethstbyad_r.c, CFLAGS-gethstbynm_r.c, and CFLAGS-gethstbynm2_r.c to -DUSE_NSCD=1. * locale/C-messages.c: Define default strings for YESTR and NOSTR. * nss/Versions: Add __nss_hosts_lookup. * nss/getXXbyYY.c: Remove unneeded assignment. * nss/getXXbyYY_r.c: Include nscd/nscd_proto.h only if needed. Almost complete rewrite of the NSCD to make it smaller, faster, add more functionnality and make it easier to extend. * nscd/Makfile (routines): Add nscd_gethst_r. (nscd-modules): Add hstcache, gethstbyad_r, gethstbynm2_r, and cache. * nscd/cache.c: New file. * nscd/gethstbyad_r.c: New file. * nscd/gethstbynm2_r.c: New file. * nscd/hstcache.c: New file. * nscd/nscd_gethst_r.c: New file. * nscd/connections.c: Rewritten. Don't start new thread for every new connection. Use a fixed set of threads which handle all connections and also the cache cleanup. * nscd/grpcache.c: Rewritten to use generic cache handling functions in cache.c. * nscd/nscd.c: Recognize new parameter nthreads. Adjust initialization for rewrite. Remove handle_requests function. * nscd/nscd.h (NSCD_VERSION): Bump to 2. Define new data structure for the new unified cache and the host database entries. * nscd/nscd_conf.c: Rewrite parsing partly to allow adding of more databases easily. Recognize check-files and threads definitions. * nscd/nscd.conf: Add definition of enable-cache and check-files to passwd and group definitions. Add new set of definitions for hosts. * nscd/nscd_getgr_r.c: Rewrite for new protocol. * nscd/nscd_getpw_r.c: Likewise. * nscd/nscd_proto.h: Add prototype for host database functions. * nscd/nscd_stat.c: Rewrite to simplify printing of information for many databases. * nscd/dbg_log.c: Remove unnecessary variable initializations. Global variable debug_flag is renamed to dbg_level. * nscd/dbg_log.h: Declare set_logfile.
Diffstat (limited to 'nscd/nscd_getgr_r.c')
-rw-r--r-- | nscd/nscd_getgr_r.c | 186 |
1 files changed, 70 insertions, 116 deletions
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c index ec4f5a1297..f27da02569 100644 --- a/nscd/nscd_getgr_r.c +++ b/nscd/nscd_getgr_r.c @@ -32,41 +32,36 @@ int __nss_not_use_nscd_group; -static int __nscd_getgr_r (const char *key, request_type type, - struct group *resultbuf, char *buffer, - size_t buflen); +static int nscd_getgr_r (const char *key, size_t keylen, request_type type, + struct group *resultbuf, char *buffer, + size_t buflen); + int __nscd_getgrnam_r (const char *name, struct group *resultbuf, char *buffer, size_t buflen) { - if (name == NULL) - return 1; - - return __nscd_getgr_r (name, GETGRBYNAME, resultbuf, buffer, buflen); + return nscd_getgr_r (name, strlen (name) + 1, GETGRBYNAME, resultbuf, + buffer, buflen); } + int __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer, size_t buflen) { - char *p = buffer; - int plen; + char buf[12]; + size_t n; - plen = __snprintf (buffer, buflen, "%d", gid); - if (plen == -1) - { - __set_errno (ERANGE); - return -1; - } - p = buffer + plen + 1; + n = __snprintf (buf, sizeof (buf), "%d", gid) + 1; - return __nscd_getgr_r (buffer, GETGRBYGID, resultbuf, p, buflen - plen -1); + return nscd_getgr_r (buf, n, GETGRBYGID, resultbuf, buffer, buflen); } + /* Create a socket connected to a name. */ static int -nscd_open_socket (void) +open_socket (void) { struct sockaddr_un addr; int sock; @@ -91,16 +86,16 @@ nscd_open_socket (void) return sock; } + static int -__nscd_getgr_r (const char *key, request_type type, struct group *resultbuf, - char *buffer, size_t buflen) +nscd_getgr_r (const char *key, size_t keylen, request_type type, + struct group *resultbuf, char *buffer, size_t buflen) { - int sock = nscd_open_socket (); + int sock = open_socket (); request_header req; gr_response_header gr_resp; ssize_t nbytes; - size_t maxiov; - size_t sum; + struct iovec vec[2]; if (sock == -1) { @@ -110,16 +105,14 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf, req.version = NSCD_VERSION; req.type = type; - req.key_len = strlen (key); - nbytes = __write (sock, &req, sizeof (request_header)); - if (nbytes != sizeof (request_header)) - { - __close (sock); - return 1; - } + req.key_len = keylen; + + vec[0].iov_base = &req; + vec[0].iov_len = sizeof (request_header); + vec[1].iov_base = (void *) key; + vec[1].iov_len = keylen; - nbytes = __write (sock, key, req.key_len); - if (nbytes != req.key_len) + if (__writev (sock, vec, 2) != sizeof (request_header) + keylen) { __close (sock); return 1; @@ -142,118 +135,79 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf, if (gr_resp.found == 1) { - struct iovec *vec; size_t *len; char *p = buffer; - int nblocks; size_t total_len; uintptr_t align; + size_t cnt; - /* A first check whether the buffer is sufficently large is possible. */ - if (buflen < gr_resp.gr_name_len + 1 + gr_resp.gr_passwd_len + 1) + /* Now allocate the buffer the array for the group members. We must + align the pointer. */ + align = ((__alignof__ (char *) - (p - ((char *) 0))) + & (__alignof__ (char *) - 1)); + if (buflen < (align + (1 + gr_resp.gr_mem_cnt) * sizeof (char *) + + gr_resp.gr_name_len + gr_resp.gr_passwd_len)) { + no_room: __set_errno (ERANGE); __close (sock); return -1; } - /* Allocate the IOVEC. */ - vec = alloca ((2 + gr_resp.gr_mem_len) * sizeof (struct iovec)); - len = alloca (gr_resp.gr_mem_len * sizeof (size_t)); + p += align; + resultbuf->gr_mem = (char **) p; + p += (1 + gr_resp.gr_mem_cnt) * sizeof (char *); + buflen -= align + (1 + gr_resp.gr_mem_cnt) * sizeof (char *); - vec[0].iov_base = resultbuf->gr_name = p; - vec[0].iov_len = gr_resp.gr_name_len; - total_len = gr_resp.gr_name_len; - p += gr_resp.gr_name_len + 1; + /* Set pointers for strings. */ + resultbuf->gr_name = p; + p += gr_resp.gr_name_len; + resultbuf->gr_passwd = p; + p += gr_resp.gr_passwd_len; - vec[1].iov_base = resultbuf->gr_passwd = p; - vec[1].iov_len = gr_resp.gr_passwd_len; - total_len += gr_resp.gr_passwd_len; - p += gr_resp.gr_passwd_len + 1; - buflen -= total_len; - nblocks = 2; + /* Fill in what we know now. */ + resultbuf->gr_gid = gr_resp.gr_gid; - if (gr_resp.gr_mem_len > 0) - { - vec[2].iov_base = len; - vec[2].iov_len = gr_resp.gr_mem_len * sizeof (size_t); - total_len += gr_resp.gr_mem_len * sizeof (size_t); - nblocks = 3; - } + /* Allocate array to store lengths. */ + len = alloca (gr_resp.gr_mem_cnt * sizeof (size_t)); + + total_len = gr_resp.gr_mem_cnt * sizeof (size_t); + vec[0].iov_base = len; + vec[0].iov_len = total_len; + vec[1].iov_base = resultbuf->gr_name; + vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + total_len += gr_resp.gr_name_len + gr_resp.gr_passwd_len; + + buflen -= total_len; /* Get this data. */ - if (__readv (sock, vec, nblocks) != total_len) + if (__readv (sock, vec, 2) != total_len) { __close (sock); return 1; } - /* Now we know the sizes. First terminate the strings we just read. */ - resultbuf->gr_name[gr_resp.gr_name_len] = '\0'; - resultbuf->gr_passwd[gr_resp.gr_passwd_len] = '\0'; - - resultbuf->gr_gid = gr_resp.gr_gid; + /* Clear the terminating entry. */ + resultbuf->gr_mem[gr_resp.gr_mem_cnt] = NULL; - /* Now allocate the buffer the array for the group members. We must - align the pointer. */ - align = ((__alignof__ (char *) - (p - ((char *) 0))) - & (__alignof__ (char *) - 1)); - if (align + (1 + gr_resp.gr_mem_len) * sizeof (char *) > buflen) + /* Prepare reading the group members. */ + total_len = 0; + for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt) { - __set_errno (ERANGE); - __close (sock); - return -1; + resultbuf->gr_mem[cnt] = p; + total_len += len[cnt]; + p += len[cnt]; } - p += align; - resultbuf->gr_mem = (char **) p; - p += (1 + gr_resp.gr_mem_len) * sizeof (char *); - buflen -= align + (1 + gr_resp.gr_mem_len) * sizeof (char *); - resultbuf->gr_mem[gr_resp.gr_mem_len] = NULL; + if (total_len > buflen) + goto no_room; - if (gr_resp.gr_mem_len > 0) + if (__read (sock, resultbuf->gr_mem[0], total_len) != total_len) { - /* Prepare reading the group members. */ - size_t i; - - total_len = 0; - for (i = 0; i < gr_resp.gr_mem_len; ++i) - { - if (len[i] >= buflen) - { - __set_errno (ERANGE); - __close (sock); - return -1; - } - - vec[i].iov_base = resultbuf->gr_mem[i] = p; - vec[i].iov_len = len[i]; - total_len += len[i]; - buflen -= len[i]; - p += len[i]; - *p++ = '\0'; - } - -#ifdef UIO_MAXIOV - maxiov = UIO_MAXIOV; -#else - maxiov = sysconf (_SC_UIO_MAXIOV); -#endif - - sum = 0; - while (i > maxiov) - { - sum += __readv (sock, vec, maxiov); - vec += maxiov; - i -= maxiov; - } - - if (sum + __readv (sock, vec, i) != total_len) - { - __close (sock); - return -1; - } + __close (sock); + return -1; } + __close (sock); return 0; } |