aboutsummaryrefslogtreecommitdiff
path: root/nis/nis_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/nis_cache.c')
-rw-r--r--nis/nis_cache.c307
1 files changed, 0 insertions, 307 deletions
diff --git a/nis/nis_cache.c b/nis/nis_cache.c
deleted file mode 100644
index e10b8c0..0000000
--- a/nis/nis_cache.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <rpcsvc/nis.h>
-#include <rpcsvc/nis_cache.h>
-#include <bits/libc-lock.h>
-
-#include "nis_intern.h"
-
-static struct timeval TIMEOUT = {10, 0};
-
-#define HEADER_MAGIC 0x07021971
-#define SPACER_MAGIC 0x07654321
-
-#define CACHE_VERSION 0x00000001
-
-struct cache_header
-{
- u_long magic; /* Magic number */
- u_long vers; /* Cache file format version */
- u_short tcp_port; /* tcp port of nis_cachemgr */
- u_short udp_port; /* udp port of nis_cachemgr */
- u_long entries; /* Number of cached objs. */
- off_t used; /* How many space are used ? */
-};
-typedef struct cache_header cache_header;
-
-struct cache_spacer
-{
- u_long magic; /* Magic number */
- u_long hashval;
- time_t ctime; /* time we have created this object */
- time_t ttl; /* time to life of this object */
- off_t next_offset;
-};
-typedef struct cache_spacer cache_spacer;
-
-static int cache_fd = -1;
-static int clnt_sock;
-static caddr_t maddr = NULL;
-static size_t msize;
-static CLIENT *cache_clnt = NULL;
-
-/* If there is no cachemgr, we shouldn't use NIS_SHARED_DIRCACHE, if
- there is no NIS_SHARED_DIRCACHE, we couldn't use nis_cachemgr.
- So, if the clnt_call to nis_cachemgr fails, we also close the cache file.
- But another thread could read the cache => lock the cache_fd and cache_clnt
- variables with the same lock */
-__libc_lock_define_initialized (static, mgrlock)
-
-/* close file handles and nis_cachemgr connection */
-static void
-__cache_close (void)
-{
- if (cache_fd != -1)
- {
- close (cache_fd);
- cache_fd = -1;
- }
- if (cache_clnt != NULL)
- {
- clnt_destroy (cache_clnt);
- close (clnt_sock);
- cache_clnt = NULL;
- }
-}
-
-/* open the cache file and connect to nis_cachemgr */
-static bool_t
-__cache_open (void)
-{
- struct sockaddr_in sin;
- cache_header hptr;
-
- if ((cache_fd = open (CACHEFILE, O_RDONLY)) == -1)
- return FALSE;
-
- if (read (cache_fd, &hptr, sizeof (cache_header)) == -1
- || lseek (cache_fd, 0, SEEK_SET) < 0)
- {
- close (cache_fd);
- cache_fd = -1;
- return FALSE;
- }
- if (hptr.magic != HEADER_MAGIC)
- {
- close (cache_fd);
- cache_fd = -1;
- syslog (LOG_ERR, _("NIS+: cache file is corrupt!"));
- return FALSE;
- }
-
- memset (&sin, '\0', sizeof (sin));
- sin.sin_family = AF_INET;
- clnt_sock = RPC_ANYSOCK;
- sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- sin.sin_port = htons (hptr.tcp_port);
- cache_clnt = clnttcp_create (&sin, CACHEPROG, CACHE_VER_1, &clnt_sock, 0, 0);
- if (cache_clnt == NULL)
- {
- close (cache_fd);
- cache_fd = -1;
- return FALSE;
- }
- /* If the program exists, close the socket */
- if (fcntl (clnt_sock, F_SETFD, FD_CLOEXEC) == -1)
- perror (_("fcntl: F_SETFD"));
- return TRUE;
-}
-
-/* Ask the cache manager to update directory 'name'
- for us (because the ttl has expired). */
-static nis_error
-__cache_refresh (nis_name name)
-{
- char clnt_res = 0;
- nis_error result = NIS_SUCCESS;
-
- __libc_lock_lock (mgrlock);
-
- if (cache_clnt == NULL)
- result = NIS_FAIL;
- else if (clnt_call (cache_clnt, NIS_CACHE_REFRESH_ENTRY,
- (xdrproc_t) xdr_wrapstring, (caddr_t) &name,
- (xdrproc_t) xdr_void, &clnt_res, TIMEOUT)
- != RPC_SUCCESS)
- {
- __cache_close ();
- result = NIS_FAIL;
- }
-
- __libc_lock_unlock (mgrlock);
-
- return result;
-}
-
-static nis_error
-__cache_find (const_nis_name name, directory_obj **obj)
-{
- unsigned long hash;
- struct cache_header *hptr;
- struct cache_spacer *cs;
- struct directory_obj *dir;
- XDR xdrs;
- caddr_t addr, ptr;
- time_t now = time (NULL);
-
- if (maddr == NULL)
- return NIS_FAIL;
-
- hash = __nis_hash (name, strlen(name));
- hptr = (cache_header *)maddr;
- if ((hptr->magic != HEADER_MAGIC) || (hptr->vers != CACHE_VERSION))
- {
- syslog (LOG_ERR, _("NIS+: cache file is corrupt!"));
- return NIS_SYSTEMERROR;
- }
- cs = (cache_spacer *)(maddr + sizeof (cache_header));
- while (cs->next_offset)
- {
- if (cs->magic != SPACER_MAGIC)
- {
- syslog (LOG_ERR, _("NIS+: cache file is corrupt!"));
- return NIS_SYSTEMERROR;
- }
- if (cs->hashval == hash)
- {
- if ((now - cs->ctime) > cs->ttl)
- return NIS_CACHEEXPIRED;
- dir = calloc (1, sizeof (directory_obj));
- addr = (caddr_t)cs + sizeof (cache_spacer);
- xdrmem_create (&xdrs, addr, cs->next_offset, XDR_DECODE);
- xdr_directory_obj (&xdrs, dir);
- xdr_destroy (&xdrs);
- *obj = dir;
- return NIS_SUCCESS;
- }
- ptr = (caddr_t)cs;
- ptr += cs->next_offset + sizeof (struct cache_spacer);
- cs = (struct cache_spacer *)ptr;
- }
- return NIS_NOTFOUND;
-}
-
-static directory_obj *
-internal_cache_search (const_nis_name name)
-{
- directory_obj *dir;
- nis_error res;
- int second_refresh = 0;
- struct stat s;
-
- if (cache_fd == -1)
- if (__cache_open () == FALSE)
- return NULL;
-
- again:
- /* This lock is for nis_cachemgr, so it couldn't write a new cache
- file if we reading it */
- if (__nis_lock_cache () == -1)
- return NULL;
-
- if (maddr != NULL)
- munmap (maddr, msize);
- if (fstat (cache_fd, &s) < 0)
- maddr = MAP_FAILED;
- else
- {
- msize = s.st_size;
- maddr = mmap (0, msize, PROT_READ, MAP_SHARED, cache_fd, 0);
- }
- if (maddr == MAP_FAILED)
- {
- __nis_unlock_cache ();
- return NULL;
- }
-
- res = __cache_find (name, &dir);
-
- munmap (maddr, msize);
- maddr = NULL;
- /* Allow nis_cachemgr to write a new cachefile */
- __nis_unlock_cache ();
-
- switch(res)
- {
- case NIS_CACHEEXPIRED:
- if (second_refresh)
- {
- __cache_close ();
- syslog (LOG_WARNING,
- _("NIS+: nis_cachemgr failed to refresh object for us"));
- return NULL;
- }
- ++second_refresh;
- if (__cache_refresh ((char *) name) != NIS_SUCCESS)
- return NULL;
- goto again;
- break;
- case NIS_SUCCESS:
- return dir;
- default:
- return NULL;
- }
-}
-
-directory_obj *
-__cache_search (const_nis_name name)
-{
- directory_obj *dir;
-
- __libc_lock_lock (mgrlock);
-
- dir = internal_cache_search (name);
-
- __libc_lock_unlock (mgrlock);
-
- return dir;
-}
-
-nis_error
-__cache_add (fd_result *fd)
-{
- char clnt_res = 0;
- nis_error result = NIS_SUCCESS;
-
- __libc_lock_lock (mgrlock);
-
- if (cache_clnt == NULL)
- if (__cache_open () == FALSE)
- result = NIS_FAIL;
-
- if (cache_clnt != NULL &&
- (clnt_call (cache_clnt, NIS_CACHE_ADD_ENTRY, (xdrproc_t) xdr_fd_result,
- (caddr_t)fd, (xdrproc_t) xdr_void, &clnt_res, TIMEOUT)
- != RPC_SUCCESS))
- {
- __cache_close ();
- result = NIS_RPCERROR;
- }
-
- __libc_lock_unlock (mgrlock);
-
- return result;
-}