home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.shrubbery.net
/
2015-02-07.ftp.shrubbery.net.tar
/
ftp.shrubbery.net
/
pub
/
tac_plus
/
tacacs+-F4.0.4.27a.tar.gz
/
tacacs+-F4.0.4.27a.tar
/
tacacs+-F4.0.4.27a
/
utils.c
< prev
next >
Wrap
C/C++ Source or Header
|
2012-01-23
|
6KB
|
244 lines
/*
* $Id: utils.c,v 1.14 2009-03-18 21:22:28 heas Exp $
*
* Copyright (c) 1995-1998 by Cisco systems, Inc.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies of the
* software and supporting documentation, the name of Cisco Systems,
* Inc. not be used in advertising or publicity pertaining to
* distribution of the program without specific prior permission, and
* notice be given in supporting documentation that modification,
* copying and distribution is by permission of Cisco Systems, Inc.
*
* Cisco Systems, Inc. makes no representations about the suitability
* of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
* IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "tac_plus.h"
char *
tac_malloc(int size)
{
char *p;
/* some mallocs don't like requests for zero length */
if (size == 0) {
size++;
}
p = (char *)malloc(size);
if (p == NULL) {
report(LOG_ERR, "malloc %d failure: %s", size, strerror(errno));
tac_exit(1);
}
return(p);
}
char *
tac_realloc(char *ptr, int size)
{
char *p;
if (ptr == NULL) {
/* realloc(0, size) is not portable */
p = tac_malloc(size);
} else {
p = (char *)realloc(ptr, size);
}
if (p == NULL) {
report(LOG_ERR, "realloc %d failure", size);
tac_exit(1);
}
return(p);
}
RETSIGTYPE
tac_exit(int status)
{
if (debug & DEBUG_FORK_FLAG)
report(LOG_DEBUG, "exit status=%d", status);
exit(status);
}
char *
tac_strdup(char *p)
{
char *n = strdup(p);
if (n == NULL) {
report(LOG_ERR, "strdup allocation failure");
tac_exit(1);
}
return(n);
}
char *
tac_make_string(u_char *p, int len)
{
char *string;
int new_len = len;
/*
* Add space for a null terminator if needed. Also, no telling
* what various mallocs will do when asked for a length of zero.
*/
if (len == 0 || p[len - 1])
new_len++;
string = (char *)tac_malloc(new_len);
memset(string, 0, new_len);
memcpy(string, p, len);
return(string);
}
/*
* return a pointer to the end of substring in string, or NULL. Substring
* must begin at start of string.
*/
char *
tac_find_substring(char *substring, char *string)
{
int len;
if (!(substring && string)) {
return(NULL);
}
len = strlen(substring);
if (len > (int)strlen(string)) {
return(NULL);
}
if (strncmp(substring, string, len)) {
/* no match */
return(NULL);
}
return(string + len);
}
/*
* Lock a file descriptor using fcntl. Returns 1 on successfully
* acquiring the lock. The lock disappears when we close the file.
*
* Note that if the locked file is on an NFS-mounted partition, you
* are at the mercy of NFS server's lockd, which is probably a bad idea.
*/
int
tac_lockfd(char *filename, int lockfd)
{
int tries;
struct flock flock;
int status;
flock.l_type = F_WRLCK;
flock.l_whence = SEEK_SET; /* relative to bof */
flock.l_start = 0L; /* from offset zero */
flock.l_len = 0L; /* lock to eof */
if (debug & DEBUG_LOCK_FLAG) {
syslog(LOG_ERR, "Attempting to lock %s fd %d", filename, lockfd);
}
for (tries = 0; tries < 10; tries++) {
errno = 0;
status = fcntl(lockfd, F_SETLK, &flock);
if (status == -1) {
if (errno == EACCES || errno == EAGAIN) {
sleep(1);
continue;
} else {
syslog(LOG_ERR, "fcntl lock error status %d on %s %d %s",
status, filename, lockfd, strerror(errno));
return(0);
}
}
/* successful lock */
break;
}
if (errno != 0) {
syslog(LOG_ERR, "Cannot lock %s fd %d in %d tries %s",
filename, lockfd, tries+1, strerror(errno));
/* who is hogging this lock */
flock.l_type = F_WRLCK;
flock.l_whence = SEEK_SET; /* relative to bof */
flock.l_start = 0L; /* from offset zero */
flock.l_len = 0L; /* lock to eof */
#ifdef HAS_FLOCK_SYSID
flock.l_sysid = 0L;
#endif
flock.l_pid = 0;
status = fcntl(lockfd, F_GETLK, &flock);
if ((status == -1) || (flock.l_type == F_UNLCK)) {
syslog(LOG_ERR, "Cannot determine %s lockholder status=%d type=%d",
filename, status, flock.l_type);
return(0);
}
if (debug & DEBUG_LOCK_FLAG) {
syslog(LOG_ERR, "Lock on %s is being held by sys=%u pid=%d",
filename,
#ifdef HAS_FLOCK_SYSID
flock.l_sysid,
#else
0,
#endif
(int)flock.l_pid);
}
return(0);
}
if (debug & DEBUG_LOCK_FLAG) {
syslog(LOG_ERR, "Successfully locked %s fd %d after %d tries",
filename, lockfd, tries+1);
}
return(1);
}
/*
* Unlock a file descriptor using fcntl. Returns 1 on successfully
* releasing a lock. The lock dies when we close the file.
*
* Note that if the locked file is on an NFS-mounted partition, you
* are at the mercy of SUN's lockd, which is probably a bad idea.
*/
int
tac_unlockfd(char *filename, int lockfd)
{
struct flock flock;
int status;
flock.l_type = F_WRLCK;
flock.l_whence = SEEK_SET; /* relative to bof */
flock.l_start = 0L; /* from offset zero */
flock.l_len = 0L; /* lock to eof */
if (debug & DEBUG_LOCK_FLAG) {
syslog(LOG_ERR, "Attempting to unlock %s fd %d", filename, lockfd);
}
status = fcntl(lockfd, F_UNLCK, &flock);
if (status == -1) {
syslog(LOG_ERR, "fcntl unlock error status %d on %s %d %s",
status, filename, lockfd, strerror(errno));
return(1);
}
if (debug & DEBUG_LOCK_FLAG) {
syslog(LOG_ERR, "Successfully unlocked %s fd %d",
filename, lockfd);
}
return(0);
}