@@ -1,973 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: Common utilities
*
*****************************************************************************
* Copyright (C) 1997-2004
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS 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.
*
* MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************/
# include "../config.h"
# include "../lib/libs.h"
# include "../lib/mberrors.h"
# include <sys/un.h>
# include "common.h"
pid_t mypid ; /* Original parent pid if child */
unsigned long lcrc = 0 , tcrc = 1 ; /* CRC value of logstring */
int lcnt = 0 ; /* Same message counter */
static char * pbuff = NULL ;
static int sock = - 1 ; /* TCP/IP socket */
int ttyfd ; /* Filedescriptor for raw mode */
struct termios tbufs , tbufsavs ; /* Structure for raw mode */
struct sockaddr_un clntaddr ; /* Client socket address */
struct sockaddr_un servaddr ; /* Server socket address */
struct sockaddr_un from ; /* From socket address */
int fromlen ;
static char spath [ PATH_MAX ] ; /* Server socket path */
static char cpath [ PATH_MAX ] ; /* Client socket path */
extern int lines , columns ;
void InitClient ( char * user )
{
sprintf ( cpath , " %s/tmp/mbmon%d " , getenv ( " MBSE_ROOT " ) , getpid ( ) ) ;
sprintf ( spath , " %s/tmp/mbtask " , getenv ( " MBSE_ROOT " ) ) ;
/*
* Store my pid in case a child process is forked and wants to do
* some communications with the mbsed server.
*/
mypid = getpid ( ) ;
if ( socket_connect ( user ) = = - 1 ) {
printf ( " PANIC: cannot access socket \n " ) ;
exit ( MBERR_INIT_ERROR ) ;
}
}
void ExitClient ( int errcode )
{
if ( socket_shutdown ( mypid ) = = - 1 )
printf ( " PANIC: unable to shutdown socket \n " ) ;
fflush ( stdout ) ;
fflush ( stdin ) ;
if ( pbuff )
free ( pbuff ) ;
unlink ( cpath ) ;
exit ( errcode ) ;
}
void SockS ( const char * format , . . . )
{
char * out ;
va_list va_ptr ;
out = calloc ( 2048 , sizeof ( char ) ) ;
va_start ( va_ptr , format ) ;
vsprintf ( out , format , va_ptr ) ;
va_end ( va_ptr ) ;
if ( socket_send ( out ) = = 0 )
socket_receive ( ) ;
free ( out ) ;
}
char * SockR ( const char * format , . . . )
{
static char buf [ SS_BUFSIZE ] ;
char * out ;
va_list va_ptr ;
memset ( & buf , 0 , SS_BUFSIZE ) ;
out = calloc ( 2048 , sizeof ( char ) ) ;
va_start ( va_ptr , format ) ;
vsprintf ( out , format , va_ptr ) ;
va_end ( va_ptr ) ;
if ( socket_send ( out ) = = 0 )
sprintf ( buf , " %s " , socket_receive ( ) ) ;
free ( out ) ;
return buf ;
}
void Syslog ( int level , const char * format , . . . )
{
char * outstr ;
va_list va_ptr ;
int i ;
outstr = calloc ( 2048 , sizeof ( char ) ) ;
va_start ( va_ptr , format ) ;
vsprintf ( outstr , format , va_ptr ) ;
va_end ( va_ptr ) ;
for ( i = 0 ; i < strlen ( outstr ) ; i + + )
if ( outstr [ i ] = = ' \r ' | | outstr [ i ] = = ' \n ' )
outstr [ i ] = ' ' ;
tcrc = StringCRC32 ( outstr ) ;
if ( tcrc = = lcrc ) {
lcnt + + ;
free ( outstr ) ;
return ;
} else {
lcrc = tcrc ;
if ( lcnt ) {
lcnt + + ;
SockS ( " ALOG:5,mbmon.log,mbmon,%d,+,Last message repeated %d times; " , mypid , lcnt ) ;
}
lcnt = 0 ;
}
SockS ( " ALOG:5,mbmon.log,mbmon,%d,+,%s; " , mypid , outstr ) ;
free ( outstr ) ;
}
void IsDoing ( const char * format , . . . )
{
char * outputstr ;
va_list va_ptr ;
outputstr = calloc ( 64 , sizeof ( char ) ) ;
va_start ( va_ptr , format ) ;
vsprintf ( outputstr , format , va_ptr ) ;
va_end ( va_ptr ) ;
SockS ( " ADOI:2,%d,%s; " , mypid , outputstr ) ;
free ( outputstr ) ;
}
static time_t nop = 0 ;
/*
* This function can be called very often but will only send once a minute
* a NOP to the server. This is a simple solution to keep server trafic low.
*/
void Nopper ( void )
{
time_t now ;
now = time ( NULL ) ;
if ( ( ( time_t ) now - ( time_t ) nop ) > 60 ) {
nop = now ;
SockS ( " GNOP:1,%d; " , mypid ) ;
}
}
/************************************************************************
*
* Connect to Unix Datagram socket, return -1 if error or socket no.
*/
int socket_connect ( char * user )
{
int s ;
static char buf [ SS_BUFSIZE ] , tty [ 18 ] ;
if ( ( s = socket ( AF_UNIX , SOCK_DGRAM , 0 ) ) = = - 1 ) {
perror ( " mbmon " ) ;
printf ( " Unable to create Unix Datagram socket \n " ) ;
return - 1 ;
}
memset ( & clntaddr , 0 , sizeof ( clntaddr ) ) ;
clntaddr . sun_family = AF_UNIX ;
strcpy ( clntaddr . sun_path , cpath ) ;
if ( bind ( s , ( struct sockaddr * ) & clntaddr , sizeof ( clntaddr ) ) < 0 ) {
close ( s ) ;
perror ( " mbmon " ) ;
printf ( " Can't bind socket %s \n " , cpath ) ;
return - 1 ;
}
memset ( & servaddr , 0 , sizeof ( servaddr ) ) ;
servaddr . sun_family = AF_UNIX ;
sprintf ( servaddr . sun_path , " %s " , ( char * ) spath ) ;
/*
* Now that we have an connection, we gather
* information to tell the server who we are.
*/
if ( isatty ( 1 ) & & ( ttyname ( 1 ) ! = NULL ) ) {
strcpy ( tty , ttyname ( 1 ) ) ;
if ( strchr ( tty , ' p ' ) )
memccpy ( tty , index ( tty , ' p ' ) , ' \0 ' , strlen ( tty ) ) ;
else if ( strchr ( tty , ' t ' ) )
memccpy ( tty , index ( tty , ' t ' ) , ' \0 ' , strlen ( tty ) ) ;
else if ( strchr ( tty , ' c ' ) )
memccpy ( tty , index ( tty , ' c ' ) , ' \0 ' , strlen ( tty ) ) ;
} else {
strcpy ( tty , " - " ) ;
}
sock = s ;
/*
* Send the information to the server.
*/
sprintf ( buf , " AINI:5,%d,%s,%s,mbmon,localhost; " , getpid ( ) , tty , user ) ;
if ( socket_send ( buf ) ! = 0 ) {
sock = - 1 ;
return - 1 ;
}
strcpy ( buf , socket_receive ( ) ) ;
if ( strncmp ( buf , " 100:0; " , 6 ) ! = 0 ) {
printf ( " AINI not acknowledged by the server \n " ) ;
sock = - 1 ;
return - 1 ;
}
return s ;
}
/*
* Send data via Unix Datagram socket
*/
int socket_send ( char * buf )
{
if ( sock = = - 1 )
return - 1 ;
if ( sendto ( sock , buf , strlen ( buf ) , 0 , ( struct sockaddr * ) & servaddr , sizeof ( servaddr ) ) ! = strlen ( buf ) ) {
printf ( " Socket send failed error %d \n " , errno ) ;
return - 1 ;
}
return 0 ;
}
/*
* Return an empty buffer if somthing went wrong, else the complete
* dataline is returned.
*/
char * socket_receive ( void )
{
static char buf [ SS_BUFSIZE ] ;
int rlen ;
memset ( ( char * ) & buf , 0 , SS_BUFSIZE ) ;
fromlen = sizeof ( from ) ;
rlen = recvfrom ( sock , buf , SS_BUFSIZE , 0 , & from , & fromlen ) ;
if ( rlen = = - 1 ) {
perror ( " recv " ) ;
printf ( " Error reading socket \n " ) ;
memset ( ( char * ) & buf , 0 , SS_BUFSIZE ) ;
return buf ;
}
return buf ;
}
/***************************************************************************
*
* Shutdown the socket, first send the server the close command so this
* application will be removed from the servers active clients list.
* There must be a parameter with the pid so that client applications
* where the shutdown will be done by a child process is able to give
* the parent pid as an identifier.
*/
int socket_shutdown ( pid_t pid )
{
static char buf [ SS_BUFSIZE ] ;
if ( sock = = - 1 )
return 0 ;
sprintf ( buf , " ACLO:1,%d; " , pid ) ;
if ( socket_send ( buf ) = = 0 ) {
strcpy ( buf , socket_receive ( ) ) ;
if ( strncmp ( buf , " 107:0; " , 6 ) ! = 0 ) {
printf ( " Shutdown not acknowledged by the server \n " ) ;
printf ( " Got \" %s \" \n " , buf ) ;
}
}
if ( shutdown ( sock , 1 ) = = - 1 ) {
perror ( " mbmon " ) ;
printf ( " Cannot shutdown socket \n " ) ;
return - 1 ;
}
sock = - 1 ;
return 0 ;
}
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
unsigned long crc32tab [ ] = { /* CRC polynomial 0xedb88320 */
0x00000000 , 0x77073096 , 0xee0e612c , 0x990951ba , 0x076dc419 , 0x706af48f , 0xe963a535 , 0x9e6495a3 ,
0x0edb8832 , 0x79dcb8a4 , 0xe0d5e91e , 0x97d2d988 , 0x09b64c2b , 0x7eb17cbd , 0xe7b82d07 , 0x90bf1d91 ,
0x1db71064 , 0x6ab020f2 , 0xf3b97148 , 0x84be41de , 0x1adad47d , 0x6ddde4eb , 0xf4d4b551 , 0x83d385c7 ,
0x136c9856 , 0x646ba8c0 , 0xfd62f97a , 0x8a65c9ec , 0x14015c4f , 0x63066cd9 , 0xfa0f3d63 , 0x8d080df5 ,
0x3b6e20c8 , 0x4c69105e , 0xd56041e4 , 0xa2677172 , 0x3c03e4d1 , 0x4b04d447 , 0xd20d85fd , 0xa50ab56b ,
0x35b5a8fa , 0x42b2986c , 0xdbbbc9d6 , 0xacbcf940 , 0x32d86ce3 , 0x45df5c75 , 0xdcd60dcf , 0xabd13d59 ,
0x26d930ac , 0x51de003a , 0xc8d75180 , 0xbfd06116 , 0x21b4f4b5 , 0x56b3c423 , 0xcfba9599 , 0xb8bda50f ,
0x2802b89e , 0x5f058808 , 0xc60cd9b2 , 0xb10be924 , 0x2f6f7c87 , 0x58684c11 , 0xc1611dab , 0xb6662d3d ,
0x76dc4190 , 0x01db7106 , 0x98d220bc , 0xefd5102a , 0x71b18589 , 0x06b6b51f , 0x9fbfe4a5 , 0xe8b8d433 ,
0x7807c9a2 , 0x0f00f934 , 0x9609a88e , 0xe10e9818 , 0x7f6a0dbb , 0x086d3d2d , 0x91646c97 , 0xe6635c01 ,
0x6b6b51f4 , 0x1c6c6162 , 0x856530d8 , 0xf262004e , 0x6c0695ed , 0x1b01a57b , 0x8208f4c1 , 0xf50fc457 ,
0x65b0d9c6 , 0x12b7e950 , 0x8bbeb8ea , 0xfcb9887c , 0x62dd1ddf , 0x15da2d49 , 0x8cd37cf3 , 0xfbd44c65 ,
0x4db26158 , 0x3ab551ce , 0xa3bc0074 , 0xd4bb30e2 , 0x4adfa541 , 0x3dd895d7 , 0xa4d1c46d , 0xd3d6f4fb ,
0x4369e96a , 0x346ed9fc , 0xad678846 , 0xda60b8d0 , 0x44042d73 , 0x33031de5 , 0xaa0a4c5f , 0xdd0d7cc9 ,
0x5005713c , 0x270241aa , 0xbe0b1010 , 0xc90c2086 , 0x5768b525 , 0x206f85b3 , 0xb966d409 , 0xce61e49f ,
0x5edef90e , 0x29d9c998 , 0xb0d09822 , 0xc7d7a8b4 , 0x59b33d17 , 0x2eb40d81 , 0xb7bd5c3b , 0xc0ba6cad ,
0xedb88320 , 0x9abfb3b6 , 0x03b6e20c , 0x74b1d29a , 0xead54739 , 0x9dd277af , 0x04db2615 , 0x73dc1683 ,
0xe3630b12 , 0x94643b84 , 0x0d6d6a3e , 0x7a6a5aa8 , 0xe40ecf0b , 0x9309ff9d , 0x0a00ae27 , 0x7d079eb1 ,
0xf00f9344 , 0x8708a3d2 , 0x1e01f268 , 0x6906c2fe , 0xf762575d , 0x806567cb , 0x196c3671 , 0x6e6b06e7 ,
0xfed41b76 , 0x89d32be0 , 0x10da7a5a , 0x67dd4acc , 0xf9b9df6f , 0x8ebeeff9 , 0x17b7be43 , 0x60b08ed5 ,
0xd6d6a3e8 , 0xa1d1937e , 0x38d8c2c4 , 0x4fdff252 , 0xd1bb67f1 , 0xa6bc5767 , 0x3fb506dd , 0x48b2364b ,
0xd80d2bda , 0xaf0a1b4c , 0x36034af6 , 0x41047a60 , 0xdf60efc3 , 0xa867df55 , 0x316e8eef , 0x4669be79 ,
0xcb61b38c , 0xbc66831a , 0x256fd2a0 , 0x5268e236 , 0xcc0c7795 , 0xbb0b4703 , 0x220216b9 , 0x5505262f ,
0xc5ba3bbe , 0xb2bd0b28 , 0x2bb45a92 , 0x5cb36a04 , 0xc2d7ffa7 , 0xb5d0cf31 , 0x2cd99e8b , 0x5bdeae1d ,
0x9b64c2b0 , 0xec63f226 , 0x756aa39c , 0x026d930a , 0x9c0906a9 , 0xeb0e363f , 0x72076785 , 0x05005713 ,
0x95bf4a82 , 0xe2b87a14 , 0x7bb12bae , 0x0cb61b38 , 0x92d28e9b , 0xe5d5be0d , 0x7cdcefb7 , 0x0bdbdf21 ,
0x86d3d2d4 , 0xf1d4e242 , 0x68ddb3f8 , 0x1fda836e , 0x81be16cd , 0xf6b9265b , 0x6fb077e1 , 0x18b74777 ,
0x88085ae6 , 0xff0f6a70 , 0x66063bca , 0x11010b5c , 0x8f659eff , 0xf862ae69 , 0x616bffd3 , 0x166ccf45 ,
0xa00ae278 , 0xd70dd2ee , 0x4e048354 , 0x3903b3c2 , 0xa7672661 , 0xd06016f7 , 0x4969474d , 0x3e6e77db ,
0xaed16a4a , 0xd9d65adc , 0x40df0b66 , 0x37d83bf0 , 0xa9bcae53 , 0xdebb9ec5 , 0x47b2cf7f , 0x30b5ffe9 ,
0xbdbdf21c , 0xcabac28a , 0x53b39330 , 0x24b4a3a6 , 0xbad03605 , 0xcdd70693 , 0x54de5729 , 0x23d967bf ,
0xb3667a2e , 0xc4614ab8 , 0x5d681b02 , 0x2a6f2b94 , 0xb40bbe37 , 0xc30c8ea1 , 0x5a05df1b , 0x2d02ef8d
} ;
/* Calculate the CRC of a string. */
unsigned long str_crc32 ( char * str )
{
unsigned long crc ;
for ( crc = 0L ; * str ; str + + )
crc = crc32tab [ ( ( int ) crc ^ ( * str ) ) & 0xff ] ^ ( ( crc > > 8 ) & 0x00ffffff ) ;
return crc ;
}
unsigned long StringCRC32 ( char * str )
{
unsigned long crc ;
for ( crc = 0xffffffff ; * str ; str + + )
crc = crc32tab [ ( ( int ) crc ^ ( * str ) ) & 0xff ] ^ ( ( crc > > 8 ) & 0x00ffffff ) ;
return crc ;
}
int rawset = FALSE ;
/*
* Sets raw mode and saves the terminal setup
*/
void Setraw ( )
{
int rc ;
if ( ( rc = tcgetattr ( ttyfd , & tbufs ) ) ) {
perror ( " " ) ;
printf ( " $tcgetattr(0, save) return %d \n " , rc ) ;
exit ( MBERR_TTYIO_ERROR ) ;
}
tbufsavs = tbufs ;
tbufs . c_iflag & = ~ ( INLCR | ICRNL | ISTRIP | IXON ) ;
/*
* Map CRNL modes strip control characters and flow control
*/
tbufs . c_oflag & = ~ OPOST ; /* Don't do ouput character translation */
tbufs . c_lflag & = ~ ( ICANON | ECHO ) ; /* No canonical input and no echo */
tbufs . c_cc [ VMIN ] = 1 ; /* Receive 1 character at a time */
tbufs . c_cc [ VTIME ] = 0 ; /* No time limit per character */
if ( ( rc = tcsetattr ( ttyfd , TCSADRAIN , & tbufs ) ) ) {
perror ( " " ) ;
printf ( " $tcsetattr(%d, TCSADRAIN, raw) return %d \n " , ttyfd , rc ) ;
exit ( MBERR_TTYIO_ERROR ) ;
}
rawset = TRUE ;
}
/*
* Unsets raw mode and returns state of terminal
*/
void Unsetraw ( )
{
int rc ;
/*
* Only unset the mode if it is set to raw mode
*/
if ( rawset = = TRUE ) {
if ( ( rc = tcsetattr ( ttyfd , TCSAFLUSH , & tbufsavs ) ) ) {
perror ( " " ) ;
printf ( " $tcsetattr(%d, TCSAFLUSH, save) return %d \n " , ttyfd , rc ) ;
exit ( MBERR_TTYIO_ERROR ) ;
}
}
rawset = FALSE ;
}
/*
* Wait for a character for a maximum of wtime * 10 mSec.
*/
int Waitchar ( unsigned char * ch , int wtime )
{
int i , rc = - 1 ;
for ( i = 0 ; i < wtime ; i + + ) {
rc = read ( ttyfd , ch , 1 ) ;
if ( rc = = 1 )
return rc ;
msleep ( 10 ) ;
}
return rc ;
}
int Escapechar ( unsigned char * ch )
{
int rc ;
unsigned char c ;
/*
* Escape character, if nothing follows within
* 50 mSec, the user really pressed <esc>.
*/
if ( ( rc = Waitchar ( ch , 5 ) ) = = - 1 )
return rc ;
if ( * ch = = ' [ ' ) {
/*
* Start of CSI sequence. If nothing follows,
* return immediatly.
*/
if ( ( rc = Waitchar ( ch , 5 ) ) = = - 1 )
return rc ;
/*
* Test for the most important keys. Note
* that only the cursor movement keys are
* guaranteed to work with PC-clients.
*/
c = * ch ;
if ( c = = ' A ' )
c = KEY_UP ;
if ( c = = ' B ' )
c = KEY_DOWN ;
if ( c = = ' C ' )
c = KEY_RIGHT ;
if ( c = = ' D ' )
c = KEY_LEFT ;
if ( ( c = = ' 1 ' ) | | ( c = = ' H ' ) | | ( c = = 0 ) )
c = KEY_HOME ;
if ( ( c = = ' 4 ' ) | | ( c = = ' K ' ) | | ( c = = 101 ) | | ( c = = 144 ) )
c = KEY_END ;
if ( c = = ' 2 ' )
c = KEY_INS ;
if ( c = = ' 3 ' )
c = KEY_DEL ;
if ( c = = ' 5 ' )
c = KEY_PGUP ;
if ( c = = ' 6 ' )
c = KEY_PGDN ;
memcpy ( ch , & c , sizeof ( unsigned char ) ) ;
return rc ;
}
return - 1 ;
}
/*
* Returns the offset from your location to UTC. So in the MET timezone
* this returns -60 (wintertime). People in the USA get positive results.
*/
long gmt_offset ( time_t now )
{
struct tm ptm ;
struct tm gtm ;
long offset ;
if ( ! now )
now = time ( NULL ) ;
ptm = * localtime ( & now ) ;
/*
* To get the timezone, compare localtime with GMT.
*/
gtm = * gmtime ( & now ) ;
/*
* Assume we are never more than 24 hours away.
*/
offset = gtm . tm_yday - ptm . tm_yday ;
if ( offset > 1 )
offset = - 24 ;
else if ( offset < - 1 )
offset = 24 ;
else
offset * = 24 ;
/*
* Scale in the hours and minutes; ignore seconds.
*/
offset + = gtm . tm_hour - ptm . tm_hour ;
offset * = 60 ;
offset + = gtm . tm_min - ptm . tm_min ;
return offset ;
}
/*
* Returns the TZUTC string, note that the sign is opposite from the
* function above.
*/
char * gmtoffset ( time_t now )
{
static char buf [ 6 ] = " +0000 " ;
char sign ;
int hr , min ;
long offset ;
offset = gmt_offset ( now ) ;
if ( offset < = 0 ) {
sign = ' + ' ;
offset = - offset ;
} else
sign = ' - ' ;
hr = offset / 60L ;
min = offset % 60L ;
if ( sign = = ' - ' )
sprintf ( buf , " %c%02d%02d " , sign , hr , min ) ;
else
sprintf ( buf , " %02d%02d " , hr , min ) ;
return ( buf ) ;
}
char * str_time ( time_t total )
{
static char buf [ 10 ] ;
int h , m ;
memset ( & buf , 0 , sizeof ( buf ) ) ;
/*
* 0 .. 59 seconds
*/
if ( total < ( time_t ) 60 ) {
sprintf ( buf , " %2d.00s " , ( int ) total ) ;
return buf ;
}
/*
* 1:00 .. 59:59 minutes:seconds
*/
if ( total < ( time_t ) 3600 ) {
h = total / 60 ;
m = total % 60 ;
sprintf ( buf , " %2d:%02d " , h , m ) ;
return buf ;
}
/*
* 1:00 .. 23:59 hours:minutes
*/
if ( total < ( time_t ) 86400 ) {
h = ( total / 60 ) / 60 ;
m = ( total / 60 ) % 60 ;
sprintf ( buf , " %2d:%02dm " , h , m ) ;
return buf ;
}
/*
* 1/00 .. 30/23 days/hours
*/
if ( total < ( time_t ) 2592000 ) {
h = ( total / 3600 ) / 24 ;
m = ( total / 3600 ) % 24 ;
sprintf ( buf , " %2d/%02dh " , h , m ) ;
return buf ;
}
sprintf ( buf , " N/A " ) ;
return buf ;
}
char * t_elapsed ( time_t start , time_t end )
{
return str_time ( end - start ) ;
}
char * xstrcpy ( char * src )
{
char * tmp ;
if ( src = = NULL )
return ( NULL ) ;
tmp = malloc ( strlen ( src ) + 1 ) ;
strcpy ( tmp , src ) ;
return tmp ;
}
char * xstrcat ( char * src , char * add )
{
char * tmp ;
size_t size = 0 ;
if ( ( add = = NULL ) | | ( strlen ( add ) = = 0 ) )
return src ;
if ( src )
size = strlen ( src ) ;
size + = strlen ( add ) ;
tmp = malloc ( size + 1 ) ;
* tmp = ' \0 ' ;
if ( src ) {
strcpy ( tmp , src ) ;
free ( src ) ;
}
strcat ( tmp , add ) ;
return tmp ;
}
char * padleft ( char * str , int size , char pad )
{
static char stri [ 256 ] ;
static char temp [ 256 ] ;
strcpy ( stri , str ) ;
memset ( temp , pad , ( long ) size ) ;
temp [ size ] = ' \0 ' ;
if ( strlen ( stri ) < = size )
memmove ( temp , stri , ( long ) strlen ( stri ) ) ;
else
memmove ( temp , stri , ( long ) size ) ;
return temp ;
}
void Striplf ( char * String )
{
int i ;
for ( i = 0 ; i < strlen ( String ) ; i + + ) {
if ( * ( String + i ) = = ' \0 ' )
break ;
if ( * ( String + i ) = = ' \n ' )
* ( String + i ) = ' \0 ' ;
}
}
/*
* Changes ansi background and foreground color
*/
void colour ( int fg , int bg )
{
int att = 0 , fore = 37 , back = 40 ;
if ( fg < 0 | | fg > 31 | | bg < 0 | | bg > 7 ) {
printf ( " ANSI: Illegal colour specified: %i, %i \n " , fg , bg ) ;
return ;
}
printf ( " [" ) ;
if ( fg > 15 ) {
printf ( " 5; " ) ;
fg - = 16 ;
}
if ( fg > 7 ) {
att = 1 ;
fg = fg - 8 ;
}
if ( fg = = 0 ) fore = 30 ;
else if ( fg = = 1 ) fore = 34 ;
else if ( fg = = 2 ) fore = 32 ;
else if ( fg = = 3 ) fore = 36 ;
else if ( fg = = 4 ) fore = 31 ;
else if ( fg = = 5 ) fore = 35 ;
else if ( fg = = 6 ) fore = 33 ;
else fore = 37 ;
if ( bg = = 1 ) back = 44 ;
else if ( bg = = 2 ) back = 42 ;
else if ( bg = = 3 ) back = 46 ;
else if ( bg = = 4 ) back = 41 ;
else if ( bg = = 5 ) back = 45 ;
else if ( bg = = 6 ) back = 43 ;
else if ( bg = = 7 ) back = 47 ;
else back = 40 ;
printf ( " %d;%d;%dm " , att , fore , back ) ;
}
void clear ( )
{
colour ( LIGHTGRAY , BLACK ) ;
printf ( ANSI_HOME ) ;
printf ( ANSI_CLEAR ) ;
}
/*
* Moves cursor to specified position
*/
void locate ( int y , int x )
{
if ( y > lines | | x > columns ) {
printf ( " ANSI: Invalid screen coordinates: %i, %i \n " , y , x ) ;
return ;
}
printf ( " \x1B [%i;%iH " , y , x ) ;
}
/*
* curses compatible functions
*/
void mvprintw ( int y , int x , const char * format , . . . )
{
char * outputstr ;
va_list va_ptr ;
outputstr = calloc ( 2048 , sizeof ( char ) ) ;
va_start ( va_ptr , format ) ;
vsprintf ( outputstr , format , va_ptr ) ;
va_end ( va_ptr ) ;
locate ( y , x ) ;
printf ( outputstr ) ;
free ( outputstr ) ;
}
/*
* * Milliseconds timer, returns 0 on success.
* */
int msleep ( int msecs )
{
int rc ;
struct timespec req , rem ;
rem . tv_sec = 0 ;
rem . tv_nsec = 0 ;
req . tv_sec = msecs / 1000 ;
req . tv_nsec = ( msecs % 1000 ) * 1000000 ;
while ( TRUE ) {
rc = nanosleep ( & req , & rem ) ;
if ( rc = = 0 )
break ;
if ( ( errno = = EINVAL ) | | ( errno = = EFAULT ) ) {
Syslog ( ' ? ' , " $msleep(%d) " , msecs ) ;
break ;
}
/*
* Error was EINTR, run timer again to complete.
*/
req . tv_sec = rem . tv_sec ;
req . tv_nsec = rem . tv_nsec ;
rem . tv_sec = 0 ;
rem . tv_nsec = 0 ;
}
return rc ;
}
/*
* Signal handler signal names.
*/
# ifdef __i386__
char SigName [ 32 ] [ 16 ] = { " NOSIGNAL " ,
" SIGHUP " , " SIGINT " , " SIGQUIT " , " SIGILL " ,
" SIGTRAP " , " SIGIOT " , " SIGBUS " , " SIGFPE " ,
" SIGKILL " , " SIGUSR1 " , " SIGSEGV " , " SIGUSR2 " ,
" SIGPIPE " , " SIGALRM " , " SIGTERM " , " SIGSTKFLT " ,
" SIGCHLD " , " SIGCONT " , " SIGSTOP " , " SIGTSTP " ,
" SIGTTIN " , " SIGTTOU " , " SIGURG " , " SIGXCPU " ,
" SIGXFSZ " , " SIGVTALRM " , " SIGPROF " , " SIGWINCH " ,
" SIGIO " , " SIGPWR " , " SIGUNUSED " } ;
# endif
# ifdef __PPC__
char SigName [ 32 ] [ 16 ] = { " NOSIGNAL " ,
" SIGHUP " , " SIGINT " , " SIGQUIT " , " SIGILL " ,
" SIGTRAP " , " SIGIOT " , " SIGBUS " , " SIGFPE " ,
" SIGKILL " , " SIGUSR1 " , " SIGSEGV " , " SIGUSR2 " ,
" SIGPIPE " , " SIGALRM " , " SIGTERM " , " SIGSTKFLT " ,
" SIGCHLD " , " SIGCONT " , " SIGSTOP " , " SIGTSTP " ,
" SIGTTIN " , " SIGTTOU " , " SIGURG " , " SIGXCPU " ,
" SIGXFSZ " , " SIGVTALRM " , " SIGPROF " , " SIGWINCH " ,
" SIGIO " , " SIGPWR " , " SIGUNUSED " } ;
# endif
# ifdef __sparc__
char SigName [ 32 ] [ 16 ] = { " NOSIGNAL " ,
" SIGHUP " , " SIGINT " , " SIGQUIT " , " SIGILL " ,
" SIGTRAP " , " SIGIOT " , " SIGEMT " , " SIGFPE " ,
" SIGKILL " , " SIGBUS " , " SIGSEGV " , " SIGSYS " ,
" SIGPIPE " , " SIGALRM " , " SIGTERM " , " SIGURG " ,
" SIGSTOP " , " SIGTSTP " , " SIGCONT " , " SIGCHLD " ,
" SIGTTIN " , " SIGTTOU " , " SIGIO " , " SIGXCPU " ,
" SIGXFSZ " , " SIGVTALRM " , " SIGPROF " , " SIGWINCH " ,
" SIGLOST " , " SIGUSR1 " , " SIGUSR2 " } ;
# endif
# ifdef __alpha__
char SigName [ 32 ] [ 16 ] = { " NOSIGNAL " ,
" SIGHUP " , " SIGINT " , " SIGQUIT " , " SIGILL " ,
" SIGTRAP " , " SIGABRT " , " SIGEMT " , " SIGFPE " ,
" SIGKILL " , " SIGBUS " , " SIGSEGV " , " SIGSYS " ,
" SIGPIPE " , " SIGALRM " , " SIGTERM " , " SIGURG " ,
" SIGSTOP " , " SIGTSTP " , " SIGCONT " , " SIGCHLD " ,
" SIGTTIN " , " SIGTTOU " , " SIGIO " , " SIGXCPU " ,
" SIGXFSZ " , " SIGVTALRM " , " SIGPROF " , " SIGWINCH " ,
" SIGINFO " , " SIGUSR1 " , " SIGUSR2 " } ;
# endif
# ifdef __hppa__
char SigName [ 32 ] [ 16 ] = { " NOSIGNAL " ,
" SIGHUP " , " SIGINT " , " SIGQUIT " , " SIGILL " ,
" SIGTRAP " , " SIGABRT " , " SIGEMT " , " SIGFPE " ,
" SIGKILL " , " SIGBUS " , " SIGSEGV " , " SIGSYS " ,
" SIGPIPE " , " SIGALRM " , " SIGTERM " , " SIGUSR1 " ,
" SIGUSR2 " , " SIGCHLD " , " SIGPWR " , " SIGVTALRM " ,
" SIGPROF " , " SIGIO " , " SIGWINCH " , " SIGSTOP " ,
" SIGTSTP " , " SIGCONT " , " SIGTTIN " , " SIGTTOU " ,
" SIGURG " , " SIGLOST " , " SIGUNUSED " } ;
# endif