2002-12-20 02:25:55 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2002-12-20 02:25:55 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2002-12-20 02:25:55 +03:00
*/
# include "lib.h"
# include "lvm-string.h"
2006-08-21 16:54:53 +04:00
# include <ctype.h>
2003-09-18 00:35:57 +04:00
int emit_to_buffer ( char * * buffer , size_t * size , const char * fmt , . . . )
{
int n ;
va_list ap ;
va_start ( ap , fmt ) ;
n = vsnprintf ( * buffer , * size , fmt , ap ) ;
va_end ( ap ) ;
2010-09-20 18:25:27 +04:00
/*
* Revert to old glibc behaviour ( version < = 2.0 .6 ) where snprintf
* returned - 1 if buffer was too small . From glibc 2.1 it returns number
* of chars that would have been written had there been room .
*/
if ( n < 0 | | ( ( unsigned ) n + 1 > * size ) )
n = - 1 ;
2007-08-22 18:38:18 +04:00
if ( n < 0 | | ( ( size_t ) n = = * size ) )
2003-09-18 00:35:57 +04:00
return 0 ;
* buffer + = n ;
* size - = n ;
return 1 ;
}
2004-02-13 17:43:35 +03:00
2010-11-17 13:19:29 +03:00
/*
* A - Za - z0 - 9. _ - + / = ! : & #
*/
int validate_tag ( const char * n )
{
register char c ;
2012-02-08 16:57:15 +04:00
/* int len = 0; */
2010-11-17 13:19:29 +03:00
if ( ! n | | ! * n )
return 0 ;
2012-02-08 16:57:15 +04:00
/* FIXME: Is unlimited tag size support needed ? */
while ( ( /* len++, */ c = * n + + ) )
2010-11-17 13:19:29 +03:00
if ( ! isalnum ( c ) & & c ! = ' . ' & & c ! = ' _ ' & & c ! = ' - ' & & c ! = ' + ' & & c ! = ' / '
& & c ! = ' = ' & & c ! = ' ! ' & & c ! = ' : ' & & c ! = ' & ' & & c ! = ' # ' )
return 0 ;
return 1 ;
}
2013-09-26 20:37:40 +04:00
static int _validate_name ( const char * n )
2006-04-19 19:33:07 +04:00
{
register char c ;
register int len = 0 ;
if ( ! n | | ! * n )
2013-09-26 20:37:40 +04:00
return - 1 ;
2006-04-19 19:33:07 +04:00
/* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
if ( * n = = ' - ' )
2013-09-26 20:37:40 +04:00
return - 2 ;
2006-04-19 19:33:07 +04:00
2012-12-14 17:03:58 +04:00
if ( ( * n = = ' . ' ) & & ( ! n [ 1 ] | | ( n [ 1 ] = = ' . ' & & ! n [ 2 ] ) ) ) /* ".", ".." */
2013-09-26 20:37:40 +04:00
return - 3 ;
2006-04-19 19:33:07 +04:00
while ( ( len + + , c = * n + + ) )
if ( ! isalnum ( c ) & & c ! = ' . ' & & c ! = ' _ ' & & c ! = ' - ' & & c ! = ' + ' )
2013-09-26 20:37:40 +04:00
return - 4 ;
2006-04-19 19:33:07 +04:00
if ( len > NAME_LEN )
2013-09-26 20:37:40 +04:00
return - 5 ;
2006-04-19 19:33:07 +04:00
2013-09-26 20:37:40 +04:00
return 0 ;
}
/*
* Device layer names are all of the form < vg > - < lv > - < layer > , any
* other hyphens that appear in these names are quoted with yet
* another hyphen . The top layer of any device has no layer
* name . eg , vg0 - lvol0 .
*/
int validate_name ( const char * n )
{
return ( _validate_name ( n ) < 0 ? 0 : 1 ) ;
2006-04-19 19:33:07 +04:00
}
2010-04-23 18:16:32 +04:00
int apply_lvname_restrictions ( const char * name )
{
2012-12-14 17:03:58 +04:00
static const char * const _reserved_prefixes [ ] = {
2011-09-06 19:38:44 +04:00
" snapshot " ,
" pvmove " ,
NULL
} ;
2012-12-14 17:03:58 +04:00
static const char * const _reserved_strings [ ] = {
2011-09-06 19:38:44 +04:00
" _mlog " ,
" _mimage " ,
2013-07-05 19:10:47 +04:00
" _pmspare " ,
2011-09-06 19:38:44 +04:00
" _rimage " ,
" _rmeta " ,
" _vorigin " ,
2011-11-03 18:38:36 +04:00
" _tdata " ,
2011-09-06 19:38:44 +04:00
" _tmeta " ,
NULL
} ;
unsigned i ;
const char * s ;
2012-12-14 17:03:58 +04:00
for ( i = 0 ; ( s = _reserved_prefixes [ i ] ) ; i + + ) {
2011-09-06 19:38:44 +04:00
if ( ! strncmp ( name , s , strlen ( s ) ) ) {
log_error ( " Names starting \" %s \" are reserved. "
" Please choose a different LV name. " , s ) ;
return 0 ;
}
2011-09-06 04:26:42 +04:00
}
2012-12-14 17:03:58 +04:00
for ( i = 0 ; ( s = _reserved_strings [ i ] ) ; i + + ) {
2011-09-06 19:38:44 +04:00
if ( strstr ( name , s ) ) {
log_error ( " Names including \" %s \" are reserved. "
" Please choose a different LV name. " , s ) ;
return 0 ;
}
2011-09-06 04:26:42 +04:00
}
2010-04-23 18:16:32 +04:00
return 1 ;
}
2013-09-26 20:37:40 +04:00
/*
* Validates name and returns an emunerated reason for name validataion failure .
*/
name_error_t validate_name_detailed ( const char * name )
{
return _validate_name ( name ) ;
}
2010-04-23 18:16:32 +04:00
int is_reserved_lvname ( const char * name )
{
int rc , old_suppress ;
old_suppress = log_suppress ( 2 ) ;
rc = ! apply_lvname_restrictions ( name ) ;
log_suppress ( old_suppress ) ;
return rc ;
}
2011-08-30 18:55:15 +04:00
char * build_dm_uuid ( struct dm_pool * mem , const char * lvid ,
const char * layer )
{
return dm_build_dm_uuid ( mem , UUID_PREFIX , lvid , layer ) ;
}