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 >
C/C++ Source or Header  |  2012-01-23  |  6KB  |  244 lines

  1. /*
  2.  * $Id: utils.c,v 1.14 2009-03-18 21:22:28 heas Exp $
  3.  *
  4.  * Copyright (c) 1995-1998 by Cisco systems, Inc.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software for
  7.  * any purpose and without fee is hereby granted, provided that this
  8.  * copyright and permission notice appear on all copies of the
  9.  * software and supporting documentation, the name of Cisco Systems,
  10.  * Inc. not be used in advertising or publicity pertaining to
  11.  * distribution of the program without specific prior permission, and
  12.  * notice be given in supporting documentation that modification,
  13.  * copying and distribution is by permission of Cisco Systems, Inc.
  14.  *
  15.  * Cisco Systems, Inc. makes no representations about the suitability
  16.  * of this software for any purpose.  THIS SOFTWARE IS PROVIDED ``AS
  17.  * IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
  18.  * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  19.  * FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #include "tac_plus.h"
  23.  
  24. char *
  25. tac_malloc(int size)
  26. {
  27.     char *p;
  28.  
  29.     /* some mallocs don't like requests for zero length */
  30.     if (size == 0) {
  31.     size++;
  32.     }
  33.  
  34.     p = (char *)malloc(size);
  35.  
  36.     if (p == NULL) {
  37.     report(LOG_ERR, "malloc %d failure: %s", size, strerror(errno));
  38.     tac_exit(1);
  39.     }
  40.     return(p);
  41. }
  42.  
  43. char *
  44. tac_realloc(char *ptr, int size)
  45. {
  46.     char *p;
  47.  
  48.     if (ptr == NULL) {
  49.     /* realloc(0, size) is not portable */
  50.     p = tac_malloc(size);
  51.     } else {
  52.     p = (char *)realloc(ptr, size);
  53.     }
  54.  
  55.     if (p == NULL) {
  56.     report(LOG_ERR, "realloc %d failure", size);
  57.     tac_exit(1);
  58.     }
  59.     return(p);
  60. }
  61.  
  62. RETSIGTYPE
  63. tac_exit(int status)
  64. {
  65.     if (debug & DEBUG_FORK_FLAG)
  66.     report(LOG_DEBUG, "exit status=%d", status);
  67.     exit(status);
  68. }
  69.  
  70. char *
  71. tac_strdup(char *p)
  72. {
  73.     char *n = strdup(p);
  74.  
  75.     if (n == NULL) {
  76.     report(LOG_ERR, "strdup allocation failure");
  77.     tac_exit(1);
  78.     }
  79.     return(n);
  80. }
  81.  
  82. char *
  83. tac_make_string(u_char *p, int len)
  84. {
  85.     char *string;
  86.     int new_len = len;
  87.  
  88.     /*
  89.      * Add space for a null terminator if needed. Also, no telling
  90.      * what various mallocs will do when asked for a length of zero.
  91.      */
  92.     if (len == 0 || p[len - 1])
  93.     new_len++;
  94.  
  95.     string = (char *)tac_malloc(new_len);
  96.  
  97.     memset(string, 0, new_len);
  98.     memcpy(string, p, len);
  99.     return(string);
  100. }
  101.  
  102. /*
  103.  * return a pointer to the end of substring in string, or NULL. Substring
  104.  * must begin at start of string.
  105.  */
  106. char *
  107. tac_find_substring(char *substring, char *string)
  108. {
  109.     int len;
  110.  
  111.     if (!(substring && string)) {
  112.     return(NULL);
  113.     }
  114.  
  115.     len = strlen(substring);
  116.  
  117.     if (len > (int)strlen(string)) {
  118.     return(NULL);
  119.     }
  120.  
  121.     if (strncmp(substring, string, len)) {
  122.     /* no match */
  123.     return(NULL);
  124.     }
  125.     return(string + len);
  126. }
  127.  
  128. /*
  129.  * Lock a file descriptor using fcntl. Returns 1 on successfully
  130.  * acquiring the lock. The lock disappears when we close the file.
  131.  *
  132.  * Note that if the locked file is on an NFS-mounted partition, you
  133.  * are at the mercy of NFS server's lockd, which is probably a bad idea.
  134.  */
  135. int
  136. tac_lockfd(char *filename, int lockfd)
  137. {
  138.     int tries;
  139.     struct flock flock;
  140.     int status;
  141.  
  142.     flock.l_type   = F_WRLCK;
  143.     flock.l_whence = SEEK_SET; /* relative to bof */
  144.     flock.l_start  = 0L; /* from offset zero */
  145.     flock.l_len    = 0L; /* lock to eof */
  146.  
  147.     if (debug & DEBUG_LOCK_FLAG) {
  148.     syslog(LOG_ERR, "Attempting to lock %s fd %d", filename, lockfd);
  149.     }
  150.  
  151.     for (tries = 0; tries < 10; tries++) {
  152.     errno = 0;
  153.     status = fcntl(lockfd, F_SETLK, &flock);
  154.     if (status == -1) {
  155.         if (errno == EACCES || errno == EAGAIN) {
  156.         sleep(1);
  157.         continue;
  158.         } else {
  159.         syslog(LOG_ERR, "fcntl lock error status %d on %s %d %s",
  160.                status, filename, lockfd, strerror(errno));
  161.         return(0);
  162.         }
  163.     }
  164.     /* successful lock */
  165.     break;
  166.     }
  167.  
  168.     if (errno != 0) {
  169.     syslog(LOG_ERR, "Cannot lock %s fd %d in %d tries %s",
  170.            filename, lockfd, tries+1, strerror(errno));
  171.  
  172.     /* who is hogging this lock */
  173.     flock.l_type   = F_WRLCK;
  174.     flock.l_whence = SEEK_SET; /* relative to bof */
  175.     flock.l_start  = 0L; /* from offset zero */
  176.     flock.l_len    = 0L; /* lock to eof */
  177. #ifdef HAS_FLOCK_SYSID
  178.     flock.l_sysid  = 0L;
  179. #endif
  180.     flock.l_pid    = 0;
  181.  
  182.     status = fcntl(lockfd, F_GETLK, &flock);
  183.     if ((status == -1) || (flock.l_type == F_UNLCK)) {
  184.         syslog(LOG_ERR, "Cannot determine %s lockholder status=%d type=%d",
  185.            filename, status, flock.l_type);
  186.         return(0);
  187.     }
  188.  
  189.     if (debug & DEBUG_LOCK_FLAG) {
  190.         syslog(LOG_ERR, "Lock on %s is being held by sys=%u pid=%d",
  191.            filename,
  192. #ifdef HAS_FLOCK_SYSID
  193.            flock.l_sysid,
  194. #else
  195.            0,
  196. #endif
  197.            (int)flock.l_pid);
  198.     }
  199.     return(0);
  200.     }
  201.  
  202.     if (debug & DEBUG_LOCK_FLAG) {
  203.     syslog(LOG_ERR, "Successfully locked %s fd %d after %d tries",
  204.            filename, lockfd, tries+1);
  205.     }
  206.     return(1);
  207. }
  208.  
  209. /*
  210.  * Unlock a file descriptor using fcntl. Returns 1 on successfully
  211.  * releasing a lock. The lock dies when we close the file.
  212.  *
  213.  * Note that if the locked file is on an NFS-mounted partition, you
  214.  * are at the mercy of SUN's lockd, which is probably a bad idea.
  215.  */
  216. int
  217. tac_unlockfd(char *filename, int lockfd)
  218. {
  219.     struct flock flock;
  220.     int status;
  221.  
  222.     flock.l_type   = F_WRLCK;
  223.     flock.l_whence = SEEK_SET; /* relative to bof */
  224.     flock.l_start  = 0L; /* from offset zero */
  225.     flock.l_len    = 0L; /* lock to eof */
  226.  
  227.     if (debug & DEBUG_LOCK_FLAG) {
  228.     syslog(LOG_ERR, "Attempting to unlock %s fd %d", filename, lockfd);
  229.     }
  230.  
  231.     status = fcntl(lockfd, F_UNLCK, &flock);
  232.     if (status == -1) {
  233.     syslog(LOG_ERR, "fcntl unlock error status %d on %s %d %s",
  234.            status, filename, lockfd, strerror(errno));
  235.     return(1);
  236.     }
  237.  
  238.     if (debug & DEBUG_LOCK_FLAG) {
  239.     syslog(LOG_ERR, "Successfully unlocked %s fd %d",
  240.            filename, lockfd);
  241.     }
  242.     return(0);
  243. }
  244.