2003-07-19 07:08:00 +04:00
/*
2003-12-20 05:29:10 +03:00
* sysfs_utils . c
2003-07-19 07:08:00 +04:00
*
* System utility functions for libsysfs
*
2003-10-21 12:19:14 +04:00
* Copyright ( C ) IBM Corp . 2003
2003-07-19 07:08:00 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library 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
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
2004-10-20 15:15:26 +04:00
# include "libsysfs.h"
2003-07-19 07:08:00 +04:00
# include "sysfs.h"
2004-01-15 09:21:38 +03:00
/**
* sysfs_remove_trailing_slash : Removes any trailing ' / ' in the given path
* @ path : Path to look for the trailing ' / '
* Returns 0 on success 1 on error
*/
2004-03-12 11:57:30 +03:00
int sysfs_remove_trailing_slash ( char * path )
2004-01-15 09:21:38 +03:00
{
2005-03-27 03:09:05 +04:00
size_t len ;
2004-01-15 09:21:38 +03:00
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2004-01-15 09:21:38 +03:00
errno = EINVAL ;
return 1 ;
}
2005-03-27 03:09:05 +04:00
len = strlen ( path ) ;
while ( len > 0 & & path [ len - 1 ] = = ' / ' )
path [ - - len ] = ' \0 ' ;
2004-01-15 09:21:38 +03:00
return 0 ;
}
2003-07-19 07:08:00 +04:00
/*
* sysfs_get_mnt_path : Gets the sysfs mount point .
* @ mnt_path : place to put " sysfs " mount point
* @ len : size of mnt_path
* returns 0 with success and - 1 with error .
*/
2004-03-12 11:57:30 +03:00
int sysfs_get_mnt_path ( char * mnt_path , size_t len )
2003-07-19 07:08:00 +04:00
{
2005-02-23 14:21:39 +03:00
static char sysfs_path [ SYSFS_PATH_MAX ] = " " ;
const char * sysfs_path_env ;
/* evaluate only at the first call */
if ( sysfs_path [ 0 ] = = ' \0 ' ) {
/* possible overrride of real mount path */
sysfs_path_env = getenv ( SYSFS_PATH_ENV ) ;
if ( sysfs_path_env ! = NULL ) {
safestrcpymax ( mnt_path , sysfs_path_env , len ) ;
2005-03-27 03:09:05 +04:00
sysfs_remove_trailing_slash ( mnt_path ) ;
2005-02-23 14:21:39 +03:00
return 0 ;
}
safestrcpymax ( mnt_path , SYSFS_MNT_PATH , len ) ;
2003-11-12 16:37:24 +03:00
}
2003-07-19 07:08:00 +04:00
2005-02-23 14:21:39 +03:00
return 0 ;
2003-07-19 07:08:00 +04:00
}
/**
* sysfs_get_name_from_path : returns last name from a " / " delimited path
* @ path : path to get name from
* @ name : where to put name
* @ len : size of name
*/
2004-03-12 11:57:30 +03:00
int sysfs_get_name_from_path ( const char * path , char * name , size_t len )
2003-07-19 07:08:00 +04:00
{
2004-03-12 11:57:30 +03:00
char tmp [ SYSFS_PATH_MAX ] ;
char * n = NULL ;
2005-02-23 14:21:39 +03:00
if ( ! path | | ! name | | len = = 0 ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
return - 1 ;
}
2003-11-25 10:47:43 +03:00
memset ( tmp , 0 , SYSFS_PATH_MAX ) ;
2004-03-12 11:57:30 +03:00
safestrcpy ( tmp , path ) ;
2003-11-25 10:47:43 +03:00
n = strrchr ( tmp , ' / ' ) ;
2003-07-19 07:08:00 +04:00
if ( n = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
2003-12-20 05:29:10 +03:00
if ( * ( n + 1 ) = = ' \0 ' ) {
* n = ' \0 ' ;
n = strrchr ( tmp , ' / ' ) ;
if ( n = = NULL ) {
errno = EINVAL ;
return - 1 ;
}
}
2003-07-19 07:08:00 +04:00
n + + ;
[PATCH] more Libsysfs updates
On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote:
> On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote:
> > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote:
> > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote:
> > >
> > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1)
> > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1)
> > >
> > > These strings are not terminated with '\0' if from is longer than
> > > the sizeof to.
> >
> > Did not do it on purpose as the "to" elements are either calloc'd or memset to
> > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :)
>
> Ahh, sounds good.
>
> > > > +#define safestrncpy(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncpy(to, from, maxsize-1); \
> > > > +} while (0)
> > > > +
> > > > +#define safestrncat(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncat(to, from, maxsize - strlen(to)-1); \
> > > > +} while (0)
> > >
> > > We all expect a similar behavior like strncat/strncpy according to the
> > > names, but these macros are limiting by the target size and do not limit
> > > the count of chars copied.
> > > This is confusing I think and suggest using a different name like
> > > 'safestrcopymax()' or something.
> >
> > Good point.. will make the change
>
> Nice. I've had these *n* names too and I forgot about the logic and only
> 10 days later I introduced a ugly bug cause I can't limit the count of
> copied chars :)
Inlined is the patch for this... applies on the earlier _BIG_ patch.
2004-03-12 11:57:36 +03:00
safestrcpymax ( name , n , len ) ;
2003-07-19 07:08:00 +04:00
return 0 ;
}
2005-02-23 14:21:39 +03:00
2003-07-19 07:08:00 +04:00
/**
* sysfs_get_link : returns link source
* @ path : symbolic link ' s path
* @ target : where to put name
* @ len : size of name
*/
2004-03-12 11:57:30 +03:00
int sysfs_get_link ( const char * path , char * target , size_t len )
2003-07-19 07:08:00 +04:00
{
2004-03-12 11:57:30 +03:00
char devdir [ SYSFS_PATH_MAX ] ;
char linkpath [ SYSFS_PATH_MAX ] ;
char temp_path [ SYSFS_PATH_MAX ] ;
char * d = NULL , * s = NULL ;
2003-11-12 16:37:24 +03:00
int slashes = 0 , count = 0 ;
2003-07-19 07:08:00 +04:00
2005-02-23 14:21:39 +03:00
if ( ! path | | ! target | | len = = 0 ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
return - 1 ;
}
memset ( devdir , 0 , SYSFS_PATH_MAX ) ;
memset ( linkpath , 0 , SYSFS_PATH_MAX ) ;
2004-03-12 11:57:30 +03:00
memset ( temp_path , 0 , SYSFS_PATH_MAX ) ;
safestrcpy ( devdir , path ) ;
2003-07-19 07:08:00 +04:00
if ( ( readlink ( path , linkpath , SYSFS_PATH_MAX ) ) < 0 ) {
return - 1 ;
}
d = linkpath ;
2005-02-23 14:21:39 +03:00
/*
2004-01-15 09:21:38 +03:00
* Three cases here :
* 1. relative path = > format . . / . .
* 2. absolute path = > format / abcd / efgh
* 3. relative path _from_ this dir = > format abcd / efgh
2005-02-23 14:21:39 +03:00
*/
2004-01-15 09:21:38 +03:00
switch ( * d ) {
case ' . ' :
2005-02-23 14:21:39 +03:00
/*
2004-01-15 09:21:38 +03:00
* handle the case where link is of type . / abcd / xxx
*/
2004-03-12 11:57:30 +03:00
safestrcpy ( temp_path , devdir ) ;
2004-01-15 09:21:38 +03:00
if ( * ( d + 1 ) = = ' / ' )
d + = 2 ;
else if ( * ( d + 1 ) = = ' . ' )
goto parse_path ;
2004-03-12 11:57:30 +03:00
s = strrchr ( temp_path , ' / ' ) ;
2004-01-15 09:21:38 +03:00
if ( s ! = NULL ) {
* ( s + 1 ) = ' \0 ' ;
2004-03-12 11:57:30 +03:00
safestrcat ( temp_path , d ) ;
2004-01-15 09:21:38 +03:00
} else {
2004-03-12 11:57:30 +03:00
safestrcpy ( temp_path , d ) ;
2004-01-15 09:21:38 +03:00
}
[PATCH] more Libsysfs updates
On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote:
> On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote:
> > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote:
> > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote:
> > >
> > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1)
> > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1)
> > >
> > > These strings are not terminated with '\0' if from is longer than
> > > the sizeof to.
> >
> > Did not do it on purpose as the "to" elements are either calloc'd or memset to
> > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :)
>
> Ahh, sounds good.
>
> > > > +#define safestrncpy(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncpy(to, from, maxsize-1); \
> > > > +} while (0)
> > > > +
> > > > +#define safestrncat(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncat(to, from, maxsize - strlen(to)-1); \
> > > > +} while (0)
> > >
> > > We all expect a similar behavior like strncat/strncpy according to the
> > > names, but these macros are limiting by the target size and do not limit
> > > the count of chars copied.
> > > This is confusing I think and suggest using a different name like
> > > 'safestrcopymax()' or something.
> >
> > Good point.. will make the change
>
> Nice. I've had these *n* names too and I forgot about the logic and only
> 10 days later I introduced a ugly bug cause I can't limit the count of
> copied chars :)
Inlined is the patch for this... applies on the earlier _BIG_ patch.
2004-03-12 11:57:36 +03:00
safestrcpymax ( target , temp_path , len ) ;
2004-01-15 09:21:38 +03:00
break ;
2005-02-23 14:21:39 +03:00
/*
* relative path , getting rid of leading " ../.. "
2004-01-15 09:21:38 +03:00
*/
parse_path :
while ( * d = = ' / ' | | * d = = ' . ' ) {
if ( * d = = ' / ' )
slashes + + ;
d + + ;
}
d - - ;
s = & devdir [ strlen ( devdir ) - 1 ] ;
while ( s ! = NULL & & count ! = ( slashes + 1 ) ) {
s - - ;
if ( * s = = ' / ' )
count + + ;
}
[PATCH] more Libsysfs updates
On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote:
> On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote:
> > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote:
> > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote:
> > >
> > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1)
> > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1)
> > >
> > > These strings are not terminated with '\0' if from is longer than
> > > the sizeof to.
> >
> > Did not do it on purpose as the "to" elements are either calloc'd or memset to
> > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :)
>
> Ahh, sounds good.
>
> > > > +#define safestrncpy(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncpy(to, from, maxsize-1); \
> > > > +} while (0)
> > > > +
> > > > +#define safestrncat(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncat(to, from, maxsize - strlen(to)-1); \
> > > > +} while (0)
> > >
> > > We all expect a similar behavior like strncat/strncpy according to the
> > > names, but these macros are limiting by the target size and do not limit
> > > the count of chars copied.
> > > This is confusing I think and suggest using a different name like
> > > 'safestrcopymax()' or something.
> >
> > Good point.. will make the change
>
> Nice. I've had these *n* names too and I forgot about the logic and only
> 10 days later I introduced a ugly bug cause I can't limit the count of
> copied chars :)
Inlined is the patch for this... applies on the earlier _BIG_ patch.
2004-03-12 11:57:36 +03:00
safestrcpymax ( s , d , ( SYSFS_PATH_MAX - strlen ( devdir ) ) ) ;
safestrcpymax ( target , devdir , len ) ;
2004-01-15 09:21:38 +03:00
break ;
case ' / ' :
/* absolute path - copy as is */
[PATCH] more Libsysfs updates
On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote:
> On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote:
> > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote:
> > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote:
> > >
> > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1)
> > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1)
> > >
> > > These strings are not terminated with '\0' if from is longer than
> > > the sizeof to.
> >
> > Did not do it on purpose as the "to" elements are either calloc'd or memset to
> > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :)
>
> Ahh, sounds good.
>
> > > > +#define safestrncpy(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncpy(to, from, maxsize-1); \
> > > > +} while (0)
> > > > +
> > > > +#define safestrncat(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncat(to, from, maxsize - strlen(to)-1); \
> > > > +} while (0)
> > >
> > > We all expect a similar behavior like strncat/strncpy according to the
> > > names, but these macros are limiting by the target size and do not limit
> > > the count of chars copied.
> > > This is confusing I think and suggest using a different name like
> > > 'safestrcopymax()' or something.
> >
> > Good point.. will make the change
>
> Nice. I've had these *n* names too and I forgot about the logic and only
> 10 days later I introduced a ugly bug cause I can't limit the count of
> copied chars :)
Inlined is the patch for this... applies on the earlier _BIG_ patch.
2004-03-12 11:57:36 +03:00
safestrcpymax ( target , linkpath , len ) ;
2004-01-15 09:21:38 +03:00
break ;
default :
/* relative path from this directory */
2004-03-12 11:57:30 +03:00
safestrcpy ( temp_path , devdir ) ;
s = strrchr ( temp_path , ' / ' ) ;
2004-01-15 09:21:38 +03:00
if ( s ! = NULL ) {
* ( s + 1 ) = ' \0 ' ;
2004-03-12 11:57:30 +03:00
safestrcat ( temp_path , linkpath ) ;
2004-01-15 09:21:38 +03:00
} else {
2004-03-12 11:57:30 +03:00
safestrcpy ( temp_path , linkpath ) ;
}
[PATCH] more Libsysfs updates
On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote:
> On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote:
> > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote:
> > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote:
> > >
> > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1)
> > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1)
> > >
> > > These strings are not terminated with '\0' if from is longer than
> > > the sizeof to.
> >
> > Did not do it on purpose as the "to" elements are either calloc'd or memset to
> > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :)
>
> Ahh, sounds good.
>
> > > > +#define safestrncpy(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncpy(to, from, maxsize-1); \
> > > > +} while (0)
> > > > +
> > > > +#define safestrncat(to, from, maxsize) \
> > > > +do { \
> > > > + to[maxsize-1] = '\0'; \
> > > > + strncat(to, from, maxsize - strlen(to)-1); \
> > > > +} while (0)
> > >
> > > We all expect a similar behavior like strncat/strncpy according to the
> > > names, but these macros are limiting by the target size and do not limit
> > > the count of chars copied.
> > > This is confusing I think and suggest using a different name like
> > > 'safestrcopymax()' or something.
> >
> > Good point.. will make the change
>
> Nice. I've had these *n* names too and I forgot about the logic and only
> 10 days later I introduced a ugly bug cause I can't limit the count of
> copied chars :)
Inlined is the patch for this... applies on the earlier _BIG_ patch.
2004-03-12 11:57:36 +03:00
safestrcpymax ( target , temp_path , len ) ;
2003-11-12 16:37:24 +03:00
}
2003-07-19 07:08:00 +04:00
return 0 ;
}
2003-10-21 12:19:14 +04:00
/**
* sysfs_close_list : generic list free routine
* @ list : dlist to free
* Returns nothing
*/
void sysfs_close_list ( struct dlist * list )
{
2005-02-23 14:21:39 +03:00
if ( list )
2003-10-21 12:19:14 +04:00
dlist_destroy ( list ) ;
}
/**
2005-02-23 14:21:39 +03:00
* sysfs_open_directory_list : gets a list of all directories under " path "
* @ path : path to read
* Returns a dlist of supported names or NULL no directories ( errno is set
* in case of error
*/
struct dlist * sysfs_open_directory_list ( const char * path )
2003-10-21 12:19:14 +04:00
{
2005-02-23 14:21:39 +03:00
if ( ! path )
2003-10-21 12:19:14 +04:00
return NULL ;
2005-02-23 14:21:39 +03:00
return ( read_dir_subdirs ( path ) ) ;
2003-10-21 12:19:14 +04:00
}
2003-12-16 08:53:28 +03:00
/**
* sysfs_path_is_dir : Check if the path supplied points to a directory
* @ path : path to validate
* Returns 0 if path points to dir , 1 otherwise
*/
2004-03-12 11:57:30 +03:00
int sysfs_path_is_dir ( const char * path )
2003-12-16 08:53:28 +03:00
{
struct stat astats ;
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
return 1 ;
}
if ( ( lstat ( path , & astats ) ) ! = 0 ) {
dprintf ( " stat() failed \n " ) ;
return 1 ;
}
if ( S_ISDIR ( astats . st_mode ) )
return 0 ;
2005-02-23 14:21:39 +03:00
2003-12-16 08:53:28 +03:00
return 1 ;
}
/**
* sysfs_path_is_link : Check if the path supplied points to a link
* @ path : path to validate
* Returns 0 if path points to link , 1 otherwise
*/
2004-03-12 11:57:30 +03:00
int sysfs_path_is_link ( const char * path )
2003-12-16 08:53:28 +03:00
{
struct stat astats ;
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
return 1 ;
}
if ( ( lstat ( path , & astats ) ) ! = 0 ) {
2004-10-20 15:15:26 +04:00
dprintf ( " stat() failed \n " ) ;
2003-12-16 08:53:28 +03:00
return 1 ;
}
if ( S_ISLNK ( astats . st_mode ) )
return 0 ;
2005-02-23 14:21:39 +03:00
2003-12-16 08:53:28 +03:00
return 1 ;
}
/**
* sysfs_path_is_file : Check if the path supplied points to a file
* @ path : path to validate
* Returns 0 if path points to file , 1 otherwise
*/
2004-03-12 11:57:30 +03:00
int sysfs_path_is_file ( const char * path )
2003-12-16 08:53:28 +03:00
{
struct stat astats ;
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
return 1 ;
}
if ( ( lstat ( path , & astats ) ) ! = 0 ) {
2004-10-20 15:15:26 +04:00
dprintf ( " stat() failed \n " ) ;
2003-12-16 08:53:28 +03:00
return 1 ;
}
if ( S_ISREG ( astats . st_mode ) )
return 0 ;
2005-02-23 14:21:39 +03:00
2003-12-16 08:53:28 +03:00
return 1 ;
}