isdn4k-utils/lib/libtools.c

754 lines
14 KiB
C

/* $Id: libtools.c,v 1.11 2004/08/25 21:22:14 tobiasb Exp $
* ISDN accounting for isdn4linux.
*
* Copyright 1996 by Stefan Luethje (luethje@sl-gw.lake.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: libtools.c,v $
* Revision 1.11 2004/08/25 21:22:14 tobiasb
* Minor fixes, required by gcc-3.4: Label at end of block, double function
* declaration. Revealed by Andreas Jochens as Debian bug #266523.
*
* Revision 1.10 1999/11/03 16:13:36 paul
* Added { } to suppress egcs warnings.
*
* Revision 1.9 1998/10/18 20:13:51 luethje
* isdnlog: Added the switch -K
*
* Revision 1.8 1998/10/13 22:17:22 luethje
* isdnlog: evaluate the variable PATH for program starts.
*
* Revision 1.7 1998/10/13 21:53:36 luethje
* isdnrep and lib: bugfixes
*
* Revision 1.6 1997/05/09 23:31:09 luethje
* isdnlog: new switch -O
* isdnrep: new format %S
* bugfix in handle_runfiles()
*
* Revision 1.5 1997/04/15 00:20:18 luethje
* replace variables: some bugfixes, README comleted
*
* Revision 1.4 1997/04/10 23:32:35 luethje
* Added the feature, that environment variables are allowed in the config files.
*
* Revision 1.3 1997/03/20 00:28:02 luethje
* Inserted lines into the files for the revision tool.
*
*/
#define _LIB_TOOLS_C_
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <fnmatch.h>
#include <ctype.h>
#include <unistd.h>
#include "libtools.h"
/****************************************************************************/
#define SET_BEGIN_VAR 1
/****************************************************************************/
static int (*print_msg)(const char *, ...) = printf;
/****************************************************************************/
void set_print_fct_for_libtools(int (*new_print_msg)(const char *, ...))
{
print_msg = new_print_msg;
}
/****************************************************************************/
char *Not_Space(char *String)
{
while (isspace(*String)) String++;
if (*String == '\0')
String = NULL;
return String;
}
/****************************************************************************/
char *To_Upper (char *String)
{
char *Ptr = String;
while (*Ptr != '\0')
{
*Ptr = toupper(*Ptr);
Ptr++;
}
return String;
}
/****************************************************************************/
char *Kill_Blanks(char *String)
{
int Cnt1 = 0, Cnt2 = 0;
while (String[Cnt1] != '\0')
{
if (!isspace(String[Cnt1]))
String[Cnt2++] = String[Cnt1];
Cnt1++;
}
String[Cnt2] = '\0';
return String;
}
/****************************************************************************/
char *FGets(char *String, int StringLen, FILE *fp, int *Line)
{
int Len;
char *RetCode = NULL;
char *Ptr = NULL;
char *Help = NULL;
if ((Help = (char*) alloca(StringLen*sizeof(char))) == NULL)
return NULL;
*String ='\0';
while ((RetCode = fgets(Help, StringLen - strlen(String), fp)) != NULL)
{
(*Line)++;
if ((Len = strlen(Help)) > 0 && Help[Len-1] == '\n' )
Help[Len-1] = '\0';
if ((Ptr = Check_Quote(Help,S_COMMENT,QUOTE_DELETE)) != NULL)
*Ptr = '\0';
strcat(String,Help);
if ((Len = strlen(String)) > 0 && String[Len-1] == C_QUOTE_CHAR )
String[Len-1] = '\0';
else
break;
}
Ptr = String;
while (isspace(*Ptr)) Ptr++;
if (*Ptr =='\0' && RetCode != NULL)
RetCode = FGets(String,StringLen,fp,Line);
else
{
strcpy(Help,Ptr);
strcpy(String,Help);
}
return RetCode;
}
/****************************************************************************/
char *Check_Quote(char *String, char *Quote, int Flag)
{
char *Ptr = String;
char *Ptr2;
if (Ptr == NULL)
return NULL;
while ((Ptr = Strpbrk(Ptr,Quote)) != NULL)
{
if (Ptr != String && *(Ptr - 1) == C_QUOTE_CHAR)
{
if (Flag == QUOTE_IGNORE)
{
Ptr++;
}
else
if (Flag == QUOTE_DELETE)
{
Ptr2 = Ptr - 1;
do
*Ptr2 = *(Ptr2 + 1);
while(*Ptr2++ != '\0');
}
else
return NULL;
}
else
break;
}
return Ptr;
}
/****************************************************************************/
const char* Quote_Chars(char *string)
{
int i;
int Index = 0;
static char *Ptr = NULL;
char *Help = NULL;
if (Ptr != NULL)
free(Ptr);
Ptr = strdup(string);
if (string == NULL)
{
print_msg("%s!\n","Got a NULL string!\n");
return "";
}
while((Help = Strpbrk(Ptr+Index,S_COMMENT)) != NULL)
{
Index = Help - Ptr;
if ((Ptr = (char*) realloc(Ptr,(strlen(Ptr)+2)*sizeof(char))) == NULL)
{
print_msg("%s!\n","Can not alllocate memory!\n");
return "";
}
for (i = strlen(Ptr); i >= Index; i--)
Ptr[i+1] = Ptr[i];
Ptr[Index] = C_QUOTE_CHAR;
Index += 2;
}
return Ptr;
}
/****************************************************************************/
/* Als Workaround fuer strpbrk(): seltsame Abstuerze ;-( */
char *Strpbrk( const char* Str, const char* Accept )
{
int i;
int len;
int first = -1;
int helpfirst = -1;
int pos = -1;
char *RetCode = NULL;
if (Str == NULL || Accept == NULL)
return NULL;
len = strlen(Accept);
for (i = 0; i < len; i++)
{
if ((RetCode = strchr(Str,Accept[i])) != NULL)
{
if ((helpfirst = RetCode - Str) < first || first == -1)
{
pos = i;
first = helpfirst;
}
}
}
if (pos == -1)
return NULL;
else
RetCode = (char*) (Str + first);
/* Alte Zeile
while (*Accept != '\0' && (RetCode = strchr(Str,*Accept++)) == NULL);
*/
return RetCode;
}
/****************************************************************************/
char **String_to_Array(char* String, char Trenn)
{
char *Ptr = String;
char **RetCode = NULL;
char *Ptr1 = NULL;
char *Ptr2 = NULL;
int Cnt = 2;
if (*String == '\0')
return NULL;
while((Ptr = strchr(Ptr,Trenn)) != NULL)
{
Cnt++;
Ptr++;
}
RetCode = (char**) calloc(Cnt,sizeof(char*));
Ptr = strdup(String);
if (RetCode == NULL || Ptr == NULL)
return NULL;
Cnt = 0;
Ptr1 = Ptr;
do
{
Ptr2 = strchr(Ptr1,Trenn);
if (Ptr2)
*Ptr2++ = '\0';
RetCode[Cnt] = (char*) calloc(strlen(Ptr1)+1,sizeof(char));
if (RetCode == NULL)
return RetCode;
strcpy(RetCode[Cnt++],Ptr1);
Ptr1 = Ptr2;
}
while (Ptr1 != NULL);
free(Ptr);
return RetCode;
}
/****************************************************************************/
void del_Array(char **Ptr)
{
int Cnt = 0;
if (Ptr)
{
while (Ptr[Cnt])
free(Ptr[Cnt++]);
free (Ptr);
}
}
/****************************************************************************/
int _append_element(void ***elem, void *ins)
{
int num = 2;
void **Ptr = *elem;
if (Ptr != NULL)
while(*Ptr != NULL)
num++,Ptr++;
if ((*elem = (void**) realloc(*elem,sizeof(void*)*num)) == NULL)
{
print_msg("Can not alloc memory!\n");
return -1;
}
(*elem)[num-2] = ins;
(*elem)[num-1] = NULL;
return 0;
}
/****************************************************************************/
int _delete_element(void ***elem, int deep)
{
void **Ptr = *elem;
if (deep < 0)
return -1;
if (Ptr == NULL)
return 0;
if (deep != 0)
while(*Ptr != NULL)
delete_element(Ptr++,deep-1);
free(*elem);
*elem = NULL;
return 0;
}
/****************************************************************************/
int match(register char *p, register char *s, int flags)
{
char *ptr1;
char *ptr2;
if ((flags & F_IGNORE_CASE) || (flags & F_NO_HOLE_WORD))
{
if ((flags & F_IGNORE_CASE) && !(flags & F_NO_HOLE_WORD) &&
!strcasecmp(p,s) )
return 0;
if ((ptr1 = (char*) alloca((strlen(p)+3)*sizeof(char))) == NULL)
return -1;
if ((ptr2 = (char*) alloca((strlen(s)+3)*sizeof(char))) == NULL)
return -1;
strcpy(ptr1,p);
strcpy(ptr2,s);
if (flags & F_IGNORE_CASE)
{
To_Upper(ptr1);
To_Upper(ptr2);
}
if (flags & F_NO_HOLE_WORD)
{
char string[SHORT_STRING_SIZE];
sprintf(string,"*%s*",ptr1);
strcpy(ptr1,string);
}
flags &= ~F_IGNORE_CASE;
flags &= ~F_NO_HOLE_WORD;
p = ptr1;
s = ptr2;
}
else
if (!strcmp(p,s))
return 0;
#ifdef OWN_MATCH
return _match(p,s);
#else
return fnmatch(p,s,flags);
#endif
} /* match */
/****************************************************************************/
#ifdef OWN_MATCH
int _match(char* p,char* s)
{
register int sc, pcc;
if (!*s || !*p)
return(-1);
while ((pcc = *p++ & QCMASK)) {
sc = *s++ & QMASK;
switch (pcc) {
case '[' : if (!(p = cclass(p, sc)))
return(-1);
break;
case '?' : if (!sc)
return(-1);
break;
case '*' : s--;
do {
if (!*p || !_match(p, s))
return(0);
} while (*s++);
return(-1);
default : if (sc != (pcc &~QUOTE))
return(-1);
}
}
return(*s);
} /* _match */
#endif
/****************************************************************************/
int is_double (char *string, double *value)
{
double dummy2 = 0;
char* dummy;
if (*string == '\0')
return 1;
dummy = (char*) alloca((strlen(string)+1)*sizeof(char));
if (value == NULL)
value = &dummy2;
return (sscanf(string,"%lf%s",value,dummy) == 1);
}
/****************************************************************************/
int is_integer (char *string, long int *value)
{
long int dummy2 = 0;
char* dummy;
if (*string == '\0')
return 1;
dummy = (char*) alloca((strlen(string)+1)*sizeof(char));
if (value == NULL)
value = &dummy2;
return (sscanf(string,"%ld%s",value,dummy) == 1);
}
/****************************************************************************/
char *Replace_Variable(char *String)
{
static char *RetCode = NULL;
char *Begin = NULL;
char *Var = NULL;
char *End = NULL;
char *Value = NULL;
char *Ptr = String;
int cnt = 0;
int num = 0;
while ((Ptr = strchr(Ptr,C_BEGIN_VAR)) != NULL)
{
cnt++;
Ptr++;
}
if (!cnt)
return String;
if (RetCode != NULL)
free(RetCode);
if ((RetCode = strdup(String)) == NULL ||
(Var = strdup(RetCode)) == NULL ||
(End = strdup(RetCode)) == NULL )
{
print_msg("%s!\n","Error: Can not allocate memory!\n");
return NULL;
}
while ((Ptr = strchr(RetCode,C_BEGIN_VAR)) != NULL)
{
if (Ptr != RetCode && Ptr[-1] == C_QUOTE_CHAR)
{
*Ptr = SET_BEGIN_VAR;
memmove(Ptr-1,Ptr,strlen(RetCode)-(Ptr-RetCode-1));
cnt--;
}
else
if ((num = sscanf(Ptr+1,"%[0-9a-zA-Z]%[^\n]",Var,End)) >= 1 ||
(num = sscanf(Ptr+1,"{%[0-9a-zA-Z]}%[^\n]",Var,End)) >= 1 )
{
if ((Value = getenv(Var)) != NULL)
{
free(Begin);
if ((Begin = strdup(RetCode)) == NULL)
{
print_msg("%s!\n","Error: Can not allocate memory!\n");
return NULL;
}
Begin[Ptr-RetCode] = '\0';
if ((RetCode = (char*) realloc(RetCode,sizeof(char)*strlen(RetCode)+strlen(Value)-strlen(Var))) == NULL)
{
print_msg("%s!\n","Error: Can not allocate memory!\n");
return NULL;
}
if (num == 1)
*End = '\0';
sprintf(RetCode,"%s%s%s",Begin,Value,End);
free(Var);
free(End);
if ((Var = strdup(RetCode)) == NULL ||
(End = strdup(RetCode)) == NULL )
{
print_msg("%s!\n","Error: Can not allocate memory!\n");
return NULL;
}
cnt--;
}
else
{
*Ptr = SET_BEGIN_VAR;
cnt--;
print_msg("Warning: Unknown variable `%s'!\n",Var);
}
}
else
*Ptr = SET_BEGIN_VAR;
}
if (cnt)
print_msg("Warning: Invalid token in string `%s'!\n",String);
free(Begin);
free(Var);
free(End);
if ((Ptr = RetCode) != NULL)
{
while (*Ptr != '\0')
{
if (*Ptr == SET_BEGIN_VAR)
*Ptr = C_BEGIN_VAR;
Ptr++;
}
}
return RetCode;
}
/****************************************************************************/
#define MAX_PREC 9
char *int2str(int value, int prec)
{
static char RetCode[MAX_PREC+1];
if (prec < 0 || prec > MAX_PREC)
{
print_msg("Error: precision %d is out of range (0-%d)!\n",prec,MAX_PREC);
*RetCode = '\0';
}
else
sprintf(RetCode,"%*d",prec,value);
return RetCode;
}
/****************************************************************************/
char *Strncat(char *dest, const char *src, int len)
{
int destlen = strlen(dest);
return Strncpy(dest+destlen,src,len-destlen);
}
/****************************************************************************/
char *Strncpy(char *dest, const char *src, int len)
{
int l = strlen(src);
if (l > len - 1)
l = len - 1;
strncpy(dest,src,l);
dest[l] = '\0';
return dest;
}
/****************************************************************************/
const char *Pathfind(const char *path, const char *name, char *mode)
{
static char file[PATH_MAX];
char _path[PATH_MAX];
int _mode = 0;
char *ptr = _path;
if (name == NULL)
return NULL;
if (mode != NULL)
while (*mode)
{
switch(*mode++)
{
case 'x': _mode |= X_OK;
break;
case 'w': _mode |= W_OK;
break;
case 'r': _mode |= R_OK;
break;
default : ;
}
}
if (strchr(name,C_SLASH) != NULL)
{
if (!access(name,_mode))
return name;
else
return NULL;
}
if (path == NULL)
{
if ((ptr = getenv(PATH_ENV)) == NULL)
return NULL;
Strncpy(_path,ptr,PATH_MAX);
ptr = _path;
_mode |= X_OK;
}
else
Strncpy(_path,path,PATH_MAX);
while((ptr = strtok(ptr,":")) != NULL)
{
snprintf(file,PATH_MAX-1,"%s/%s",ptr,name);
if (!access(file,_mode))
return file;
ptr = NULL;
}
return NULL;
}
/****************************************************************************/