2001-10-12 14:32:06 +04:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
2001-10-31 15:47:01 +03:00
* This file is released under the LGPL .
2001-10-12 14:32:06 +04:00
*/
# include "uuid.h"
# include "log.h"
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
2002-01-04 19:55:14 +03:00
# include <assert.h>
2001-10-12 14:32:06 +04:00
static unsigned char _c [ ] =
" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ " ;
2001-12-11 14:40:34 +03:00
static int _built_inverse ;
static unsigned char _inverse_c [ 256 ] ;
2001-10-12 14:32:06 +04:00
int id_create ( struct id * id )
{
int random , i , len = sizeof ( id - > uuid ) ;
memset ( id - > uuid , 0 , len ) ;
if ( ( random = open ( " /dev/urandom " , O_RDONLY ) ) < 0 ) {
log_sys_error ( " open " , " id_create " ) ;
return 0 ;
}
if ( read ( random , id - > uuid , len ) ! = len ) {
log_sys_error ( " read " , " id_create " ) ;
2002-01-08 01:25:57 +03:00
close ( random ) ;
2001-10-12 14:32:06 +04:00
return 0 ;
}
close ( random ) ;
for ( i = 0 ; i < len ; i + + )
id - > uuid [ i ] = _c [ id - > uuid [ i ] % ( sizeof ( _c ) - 1 ) ] ;
return 1 ;
}
2001-12-11 14:40:34 +03:00
/*
* The only validity check we have is that
* the uuid just contains characters from
* ' _c ' . A checksum would have been nice : (
*/
void _build_inverse ( void )
{
char * ptr ;
if ( _built_inverse )
return ;
memset ( _inverse_c , 0 , sizeof ( _inverse_c ) ) ;
for ( ptr = _c ; * ptr ; ptr + + )
_inverse_c [ ( int ) * ptr ] = ( char ) 0x1 ;
}
2001-10-12 14:32:06 +04:00
int id_valid ( struct id * id )
{
2001-12-11 14:40:34 +03:00
int i ;
_build_inverse ( ) ;
for ( i = 0 ; i < ID_LEN ; i + + )
if ( ! _inverse_c [ id - > uuid [ i ] ] ) {
log_err ( " UUID contains invalid character " ) ;
return 0 ;
}
2001-10-12 14:32:06 +04:00
return 1 ;
}
int id_cmp ( struct id * lhs , struct id * rhs )
{
return memcmp ( lhs - > uuid , rhs - > uuid , sizeof ( lhs - > uuid ) ) ;
}
2001-12-11 14:40:34 +03:00
# define GROUPS (ID_LEN / 4)
2001-12-20 19:05:14 +03:00
2001-12-20 14:52:54 +03:00
int id_write_format ( struct id * id , char * buffer , size_t size )
2001-12-11 14:40:34 +03:00
{
2002-01-04 19:55:14 +03:00
int i , tot ;
static int group_size [ ] = { 6 , 4 , 4 , 4 , 4 , 4 , 6 } ;
2001-12-11 14:40:34 +03:00
2002-01-04 19:55:14 +03:00
assert ( ID_LEN = = 32 ) ;
/* split into groups seperated by dashes */
if ( size < ( 32 + 6 + 1 ) ) {
log_err ( " Couldn't write uuid, buffer too small. " ) ;
2001-12-11 14:40:34 +03:00
return 0 ;
2002-01-04 19:55:14 +03:00
}
2001-12-11 14:40:34 +03:00
2002-01-04 19:55:14 +03:00
for ( i = 0 , tot = 0 ; i < 7 ; i + + ) {
memcpy ( buffer , id - > uuid + tot , group_size [ i ] ) ;
buffer + = group_size [ i ] ;
tot + = group_size [ i ] ;
* buffer + + = ' - ' ;
2001-12-11 14:40:34 +03:00
}
2002-01-04 19:55:14 +03:00
* - - buffer = ' \0 ' ;
2001-12-11 14:40:34 +03:00
return 1 ;
}
int id_read_format ( struct id * id , char * buffer )
{
2002-01-04 19:55:14 +03:00
int out = 0 ;
2001-12-12 19:22:38 +03:00
2002-01-04 19:55:14 +03:00
/* just strip out any dashes */
while ( * buffer ) {
if ( * buffer = = ' - ' ) {
buffer + + ;
continue ;
}
if ( out > = ID_LEN ) {
log_err ( " Too many characters to be uuid. " ) ;
return 0 ;
}
id - > uuid [ out + + ] = * buffer + + ;
2001-12-11 14:40:34 +03:00
}
2002-01-04 19:55:14 +03:00
if ( out ! = ID_LEN ) {
log_err ( " Couldn't read uuid, incorrect number of characters. " ) ;
return 0 ;
}
2001-12-11 14:40:34 +03:00
return id_valid ( id ) ;
}