utils.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Portions of this source code were derived from Berkeley
* under license from the Regents of the University of
* California.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* DESCRIPTION: This file contains various functions used by more than one NIS
* components. A lot of this code started off in ypxfr and then
* got used by other components. Some of it has become a little
* 'quirky' and should probably be re-worked.
*/
#include <unistd.h>
#include <syslog.h>
#include <sys/mman.h>
#include <thread.h>
#include <synch.h>
#include <stdarg.h>
#include <ndbm.h>
#include "../ypsym.h"
#include "../ypdefs.h"
#include "shim.h"
USE_DBM
/*
* Globals
*/
/*
* DESCRIPTION : Utility functions used by everything.
*/
bool check_map_existence(char *);
void logprintf2(char *format, ...);
/*
* This checks to see if the source map files exist, then renames them to the
* target names. This is a boolean function. The file names from.pag and
* from.dir will be changed to to.pag and to.dir in the success case.
*
* Note: If the second of the two renames fails, yprename_map will try to
* un-rename the first pair, and leave the world in the state it was on entry.
* This might fail, too, though...
*
* GIVEN : Name of map to copy from
* Name of map to copy to
* Flag indicating if map is secure.
*/
bool
rename_map(from, to, secure_map)
char *from;
char *to;
bool_t secure_map;
{
char fromfile[MAXNAMLEN + 1];
char tofile[MAXNAMLEN + 1];
char savefile[MAXNAMLEN + 1];
if (!from || !to) {
return (FALSE);
}
if (!check_map_existence(from)) {
return (FALSE);
}
(void) strcpy(fromfile, from);
(void) strcat(fromfile, dbm_pag);
(void) strcpy(tofile, to);
(void) strcat(tofile, dbm_pag);
if (rename(fromfile, tofile)) {
logprintf2("Can't mv %s to %s.\n", fromfile,
tofile);
return (FALSE);
}
(void) strcpy(savefile, tofile);
(void) strcpy(fromfile, from);
(void) strcat(fromfile, dbm_dir);
(void) strcpy(tofile, to);
(void) strcat(tofile, dbm_dir);
if (rename(fromfile, tofile)) {
logprintf2("Can't mv %s to %s.\n", fromfile,
tofile);
(void) strcpy(fromfile, from);
(void) strcat(fromfile, dbm_pag);
(void) strcpy(tofile, to);
(void) strcat(tofile, dbm_pag);
if (rename(tofile, fromfile)) {
logprintf2(
"Can't recover from rename failure.\n");
return (FALSE);
}
return (FALSE);
}
if (!secure_map) {
chmod(savefile, 0644);
chmod(tofile, 0644);
}
return (TRUE);
}
/*
* Function : delete_map()
*
* Description: Deletes a map
*
* Given : Map name
*
* Return : TRUE = Map deleted
* FALSE = Map not completly deleted
*/
bool
delete_map(name)
char *name;
{
char fromfile[MAXNAMLEN + 1];
if (!name) {
return (FALSE);
}
if (!check_map_existence(name)) {
/* Already gone */
return (TRUE);
}
(void) strcpy(fromfile, name);
(void) strcat(fromfile, dbm_pag);
if (unlink(fromfile)) {
logprintf2("Can't unlink %s.\n", fromfile);
return (FALSE);
}
(void) strcpy(fromfile, name);
(void) strcat(fromfile, dbm_dir);
if (unlink(fromfile)) {
logprintf2("Can't unlink %s.\n", fromfile);
return (FALSE);
}
return (TRUE);
}
/*
* This performs an existence check on the dbm data base files <pname>.pag and
* <pname>.dir.
*/
bool
check_map_existence(pname)
char *pname;
{
char dbfile[MAXNAMLEN + 1];
struct stat filestat;
int len;
if (!pname || ((len = strlen(pname)) == 0) ||
(len + 5) > (MAXNAMLEN + 1)) {
return (FALSE);
}
errno = 0;
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, dbm_dir);
if (stat(dbfile, &filestat) != -1) {
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, dbm_pag);
if (stat(dbfile, &filestat) != -1) {
return (TRUE);
} else {
if (errno != ENOENT) {
logprintf2(
"Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
} else {
if (errno != ENOENT) {
logprintf2(
"Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
}
/*
* FUNCTION : logprintf2()
*
* DESCRIPTION: The functions in this file were oringinaly shared between
* ypxfr and ypserv. On error they called logprintf().
* Unfortunatly this had been implemented differently in the two
* sources and not at all in some of the NIS components required
* for N2L.
*
* This function is simplified version of logprinf() as/when
* possible the other error calls should be migrated to use this
* common version. If a common set of functionality can be found
* this versions should be modified to support it.
*/
void
logprintf2(char *format, ...)
{
va_list ap;
va_start(ap, format);
syslog(LOG_ERR, format, ap);
va_end(ap);
}
/*
* This performs an existence check on the dbm data base files <name>.pag and
* <name>.dir. pname is a ptr to the filename. This should be an absolute
* path.
* Returns TRUE if the map exists and is accessable; else FALSE.
*
* Note: The file name should be a "base" form, without a file "extension" of
* .dir or .pag appended. See ypmkfilename for a function which will generate
* the name correctly. Errors in the stat call will be reported at this level,
* however, the non-existence of a file is not considered an error, and so will
* not be reported.
*/
bool
ypcheck_map_existence(char *pname)
{
char dbfile[MAXNAMLEN + sizeof (TTL_POSTFIX) + 1];
struct stat filestat;
int len;
if (!pname || ((len = (int)strlen(pname)) == 0) ||
(len + sizeof (dbm_pag)) > (MAXNAMLEN + 1)) {
return (FALSE);
}
errno = 0;
/* Check for existance of .dir file */
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, dbm_dir);
if (stat(dbfile, &filestat) == -1) {
if (errno != ENOENT) {
(void) fprintf(stderr,
"ypserv: Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
/* Check for existance of .pag file */
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, dbm_pag);
if (stat(dbfile, &filestat) == -1) {
if (errno != ENOENT) {
(void) fprintf(stderr,
"ypserv: Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
if (yptol_mode) {
/* Check for existance of TTL .dir file */
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, TTL_POSTFIX);
(void) strcat(dbfile, dbm_dir);
if (stat(dbfile, &filestat) == -1) {
if (errno != ENOENT) {
(void) fprintf(stderr,
"ypserv: Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
/* Check for existance of TTL .pag file */
(void) strcpy(dbfile, pname);
(void) strcat(dbfile, TTL_POSTFIX);
(void) strcat(dbfile, dbm_pag);
if (stat(dbfile, &filestat) == -1) {
if (errno != ENOENT) {
(void) fprintf(stderr,
"ypserv: Stat error on map file %s.\n",
dbfile);
}
return (FALSE);
}
}
return (TRUE);
}