From ac0cc9792460d5fd0c58f783f1842b9b7883e196 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Wed, 2 Mar 2005 12:57:56 +0000 Subject: [PATCH] - Added atoll(), ffs(), ftw(), nftw(), lstat() and uname() code contributed by Peter Bengtsson. Thank you very much! git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14848 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 12 +- library/GNUmakefile.os4 | 12 +- library/changes | 3 + library/ftw_ftw.c | 238 ++++++++++++++++++++++++ library/ftw_headers.h | 47 +++++ library/ftw_nftw.c | 334 ++++++++++++++++++++++++++++++++++ library/include/ftw.h | 102 +++++++++++ library/include/stdlib.h | 5 +- library/include/strings.h | 5 +- library/include/sys/utsname.h | 74 ++++++++ library/smakefile | 9 +- library/stat_lstat.c | 258 +++++++++++++++++++++++++- library/stdlib_atoll.c | 76 ++++++++ library/strings_ffs.c | 71 ++++++++ library/utsname_uname.c | 168 +++++++++++++++++ 15 files changed, 1395 insertions(+), 19 deletions(-) create mode 100644 library/ftw_ftw.c create mode 100644 library/ftw_headers.h create mode 100644 library/ftw_nftw.c create mode 100644 library/include/ftw.h create mode 100644 library/include/sys/utsname.h create mode 100644 library/stdlib_atoll.c create mode 100644 library/strings_ffs.c create mode 100644 library/utsname_uname.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 87c180e..e17234a 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.32 2005-02-28 13:22:53 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.33 2005-03-02 12:57:53 obarthel Exp $ # # :ts=8 # @@ -148,6 +148,8 @@ C_LIB = \ fcntl_open.o \ fcntl_read.o \ fcntl_write.o \ + ftw_ftw.o \ + ftw_nftw.o \ libgen_basename.o \ libgen_dirname.o \ locale_init_exit.o \ @@ -269,6 +271,7 @@ C_LIB = \ stdlib_atexit.o \ stdlib_atoi.o \ stdlib_atol.o \ + stdlib_atoll.o \ stdlib_bsearch.o \ stdlib_calloc.o \ stdlib_checkdetach.o \ @@ -344,6 +347,7 @@ C_LIB = \ stdlib_umodsi3.o \ stdlib_unsetenv.o \ stdlib_wildcard_expand.o \ + strings_ffs.o \ strings_strcasecmp.o \ strings_strncasecmp.o \ string_bcmp.o \ @@ -427,7 +431,8 @@ C_LIB = \ unistd_truncate.o \ unistd_unlink.o \ unistd_usleep.o \ - utime_utime.o + utime_utime.o \ + utsname_uname.o UNIX_LIB = \ unix.lib_rev.o \ @@ -653,7 +658,8 @@ NET_LIB = \ usergroup_setregid.o \ usergroup_setreuid.o \ usergroup_setsid.o \ - usergroup_setuid.o + usergroup_setuid.o \ + utsname_uname.o DEBUG_LIB = \ debug.lib_rev.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 11ac75d..8ecce5a 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.32 2005-02-28 13:22:53 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.33 2005-03-02 12:57:53 obarthel Exp $ # # :ts=8 # @@ -152,6 +152,8 @@ C_LIB = \ fcntl_open.o \ fcntl_read.o \ fcntl_write.o \ + ftw_ftw.o \ + ftw_nftw.o \ libgen_basename.o \ libgen_dirname.o \ locale_init_exit.o \ @@ -273,6 +275,7 @@ C_LIB = \ stdlib_atexit.o \ stdlib_atoi.o \ stdlib_atol.o \ + stdlib_atoll.o \ stdlib_bsearch.o \ stdlib_calloc.o \ stdlib_checkdetach.o \ @@ -348,6 +351,7 @@ C_LIB = \ stdlib_umodsi3.o \ stdlib_unsetenv.o \ stdlib_wildcard_expand.o \ + strings_ffs.o \ strings_strcasecmp.o \ strings_strncasecmp.o \ string_bcmp.o \ @@ -431,7 +435,8 @@ C_LIB = \ unistd_truncate.o \ unistd_unlink.o \ unistd_usleep.o \ - utime_utime.o + utime_utime.o \ + utsname_uname.o # All objects files which make up libunix.a UNIX_LIB = \ @@ -620,7 +625,8 @@ NET_LIB = \ usergroup_setregid.o \ usergroup_setreuid.o \ usergroup_setsid.o \ - usergroup_setuid.o + usergroup_setuid.o \ + utsname_uname.o # All objects files which make up libdebug.a DEBUG_LIB = \ diff --git a/library/changes b/library/changes index 800af66..b5a7b17 100644 --- a/library/changes +++ b/library/changes @@ -80,6 +80,9 @@ absolute Amiga path names passed to it and will use them without changing them. +- Added atoll(), ffs(), ftw(), nftw(), lstat() and uname() code + contributed by Peter Bengtsson. Thank you very much! + c.lib 1.188 (7.2.2005) diff --git a/library/ftw_ftw.c b/library/ftw_ftw.c new file mode 100644 index 0000000..3ea43b5 --- /dev/null +++ b/library/ftw_ftw.c @@ -0,0 +1,238 @@ +/* + * $Id: ftw_ftw.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +/* + * This ftw() implementation builds heavily on existing functionality and could certainly + * be made more efficient (e.g. by combining walk & stat using ExAll()/ExNext()) but this + * way the Unix pathname translation is free. + */ + +/****************************************************************************/ + +#include +#include +#include +#include +#include + +/****************************************************************************/ + +#ifndef _DEBUG_H +#include "debug.h" +#endif /* _DEBUG_H */ + +#ifndef _FTW_HEADERS_H +#include "ftw_headers.h" +#endif /* _FTW_HEADERS_H */ + +#ifndef _STDLIB_PROTOS_H +#include "stdlib_protos.h" /* get/set errno. */ +#endif /* _STDLIB_PROTOS_H */ + +/****************************************************************************/ + +static int +walk(const char *path,int (*func)(const char *,const struct stat *,int),int depth,int level) +{ + int result = 0; + DIR *dp; + struct dirent *de; + struct stat st; + char *next_name; + int type; + int old_length; + int errtmp; + + ENTER(); + + SHOWSTRING(path); + SHOWPOINTER(func); + SHOWVALUE(depth); + SHOWVALUE(level); + + if(__check_abort_enabled) + __check_abort(); + + if(level > depth) + goto out; + + if(stat(path,&st) == OK) + { + if (S_ISDIR(st.st_mode)) + { + if(FLAG_IS_SET(st.st_mode,S_IRUSR)) + type = FTW_D; /* Directory */ + else + type = FTW_DNR; /* Directory No Read-permission */ + } + else if (S_ISREG(st.st_mode)) + { + type = FTW_F; /* File */ + } + else + { + /* Skip */ + goto out; + } + } + else + { + type = FTW_NS; /* No Stat */ + } + + result = (*func)(path,&st,type); + if(result != 0) + goto out; + + if(type == FTW_D) + { + dp = opendir(path); /* Also takes care of Unix->Amiga pathname conversion. */ + if(dp == NULL) + { + result = -1; /* Pass errno from opendir() */ + goto out; + } + + old_length = strlen(path); + + next_name = malloc(old_length + NAME_MAX + 2); /* Allocate new for each recursive step to handle extremely long path names. */ + if(next_name == NULL) + { + __set_errno(ENOMEM); + + result = -1; + goto out; + } + + strcpy(next_name,path); + + if(old_length > 0 && next_name[old_length - 1] != ':' && next_name[old_length-1] != '/') + next_name[old_length++] = '/'; + + while((result == 0) && (de = readdir(dp)) != NULL) + { + strlcpy(&next_name[old_length],de->d_name,NAME_MAX + 2); + + result = walk(next_name,func,depth,level+1); + } + + errtmp = __get_errno(); + + closedir(dp); + free(next_name); + + __set_errno(errtmp); + } + + out: + + RETURN(result); + return(result); +} + +int +ftw(const char *path,int (*func)(const char *,const struct stat *,int),int depth) +{ + int result = -1; + char *base; + int len; + + ENTER(); + + SHOWSTRING(path); + SHOWPOINTER(func); + SHOWVALUE(depth); + + if(path == NULL) + { + SHOWMSG("NULL pathname to ftw()."); + + __set_errno(EFAULT); + goto out; + } + + if(func == NULL) + { + SHOWMSG("No function supplied."); + + __set_errno(EFAULT); + goto out; + } + + if(depth < 0) + { + SHOWMSG("Invalid depth.\n"); + + __set_errno(EINVAL); + goto out; + } + + /* Make sure the path never ends with '/' unless used to indicate parent directory. */ + len = strlen(path); + if(len > 1 && path[len - 1] == '/' && path[len - 2] != '/') + { + int error; + + base = strdup(path); + if(base == NULL) + { + __set_errno(ENOMEM); + goto out; + } + + base[len - 1] = '\0'; + + result = walk(base,func,depth,0); + + error = __get_errno(); + + free(base); + + __set_errno(error); + } + else + { + result = walk(path,func,depth,0); + } + + out: + + RETURN(result); + return(result); +} diff --git a/library/ftw_headers.h b/library/ftw_headers.h new file mode 100644 index 0000000..3ab9ab5 --- /dev/null +++ b/library/ftw_headers.h @@ -0,0 +1,47 @@ +/* + * $Id: ftw_headers.h,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FTW_HEADERS_H +#define _FTW_HEADERS_H + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#include "macros.h" + +/****************************************************************************/ + +#endif /* _FTW_HEADERS_H */ diff --git a/library/ftw_nftw.c b/library/ftw_nftw.c new file mode 100644 index 0000000..1881e9e --- /dev/null +++ b/library/ftw_nftw.c @@ -0,0 +1,334 @@ +/* + * $Id: ftw_nftw.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +/* + * This nftw() implementation builds heavily on existing functionality and could certainly + * be made more efficient. + */ + +/****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/****************************************************************************/ + +#ifndef _DEBUG_H +#include "debug.h" +#endif /* _DEBUG_H */ + +#ifndef _FTW_HEADERS_H +#include "ftw_headers.h" +#endif /* _FTW_HEADERS_H */ + +#ifndef _STDLIB_PROTOS_H +#include "stdlib_protos.h" /* get/set errno. */ +#endif /* _STDLIB_PROTOS_H */ + +/****************************************************************************/ + +static int +walk(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),const int depth,int level,const int flags,const int base,int * const prune) +{ + int result = 0; + DIR *dp; + struct dirent *de; + struct stat st; + char *next_name; + char *old_cwd = 0; + int type; + int old_length; + int errtmp; + struct FTW extra_info; + int stat_result; + + ENTER(); + + SHOWSTRING(path); + SHOWPOINTER(func); + SHOWVALUE(depth); + SHOWVALUE(level); + SHOWVALUE(flags); + + if(__check_abort_enabled) + __check_abort(); + + if(level > depth) + goto out; + + if(FLAG_IS_SET(flags,FTW_PHYS)) + stat_result = lstat(path,&st); + else + stat_result = stat(path,&st); + + if(stat_result == OK) + { + if (S_ISLNK(st.st_mode)) /* Should only be possible if lstat() is used. */ + { + type = FTW_SL; + } + else if (S_ISDIR(st.st_mode)) + { + if(FLAG_IS_SET(st.st_mode,S_IRUSR)) + type = FTW_D; /* Directory */ + else + type = FTW_DNR; /* Directory No Read-permission */ + } + else if (S_ISREG(st.st_mode)) + { + type = FTW_F; /* File */ + } + else + { + /* Skip */ + goto out; + } + } + else + { + if(FLAG_IS_CLEAR(flags,FTW_PHYS) && lstat(path,&st) == OK) + type = FTW_SLN; /* Broken link. */ + else + type = FTW_NS; /* No Stat */ + } + + extra_info.quit = 0; + extra_info.base = base; + extra_info.level = level; + + if(type == FTW_D) + { + old_length = strlen(path); + + if(FLAG_IS_CLEAR(flags,FTW_DEPTH)) + result = (*func)(path,&st,type,&extra_info); + + if(extra_info.quit == 0) + { + dp = opendir(path); /* Also takes care of Unix->Amiga pathname conversion. */ + if(dp == NULL) + { + result = -1; + goto out; + } + + if(FLAG_IS_SET(flags,FTW_CHDIR)) /* Change to directory before traversing. */ + { + old_cwd = malloc(old_length + NAME_MAX); + if(old_cwd == NULL) + { + __set_errno(ENOMEM); + + result = -1; + goto out; + } + + getcwd(old_cwd,old_length + NAME_MAX); + chdir(path); + } + + next_name = malloc(old_length + NAME_MAX + 2); /* Allocate new for each recursive step to handle extremely long path names. */ + if(next_name == NULL) + { + __set_errno(ENOMEM); + + result = -1; + goto out; + } + + strcpy(next_name,path); + if(old_length > 0 && next_name[old_length - 1] != ':' && next_name[old_length - 1] != '/') + next_name[old_length++] = '/'; + + while((result == 0) && (de = readdir(dp)) != NULL) + { + strlcpy(&next_name[old_length],de->d_name,NAME_MAX + 2); + + result = walk(next_name,func,depth,level + 1,flags,old_length,prune); + if((*prune) != 0) + { + (*prune) = 0; + break; + } + } + + errtmp = __get_errno(); + + closedir(dp); + + __set_errno(errtmp); + + free(next_name); + + if((result == 0) && FLAG_IS_SET(flags,FTW_DEPTH)) + result = (*func)(path,&st,FTW_DP,&extra_info); + } + + if(extra_info.quit == FTW_PRUNE) /* Abort traversal of current directory. */ + (*prune) = 1; + } + else + { + result = (*func)(path,&st,type,&extra_info); + } + + out: + + if(old_cwd != NULL) + { + errtmp = __get_errno(); + + chdir(old_cwd); /* Restore (pop) old directory. */ + free(old_cwd); + + __set_errno(errtmp); + } + + RETURN(result); + return(result); +} + +/****************************************************************/ + +static int +index_of_end_part(const char *path) +{ + int result = 0; + int i; + + i = strlen(path) - 1; + while(i-- > 0) + { + if(path[i] == '/' || path[i] == ':') + { + result = i + 1; + break; + } + } + + return(result); +} + +/****************************************************************/ + +int +nftw(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),int depth,int flags) +{ + char *base; + int len; + int base_index; + int prune = 0; + int result = -1; + + ENTER(); + + SHOWSTRING(path); + SHOWPOINTER(func); + SHOWVALUE(depth); + SHOWVALUE(flags); + + if(path == NULL) + { + SHOWMSG("NULL pathname to nftw()."); + __set_errno(EFAULT); + goto out; + } + + if(func == NULL) + { + SHOWMSG("No function supplied."); + __set_errno(EFAULT); + goto out; + } + + if(depth < 0) + { + SHOWMSG("Invalid depth.\n"); + __set_errno(EINVAL); + goto out; + } + + if((flags & ~FTW_ALL_FLAGS) != 0) + { + SHOWMSG("Bogus flags."); + + __set_errno(EINVAL); + goto out; + } + + /* Make sure the path never ends with '/' unless used to indicate parent directory. */ + + len = strlen(path); + if(len > 1 && path[len - 1] == '/' && path[len - 2] != '/') + { + int error; + + base = strdup(path); + if(base == NULL) + { + __set_errno(ENOMEM); + goto out; + } + + base[len - 1] = '\0'; + + base_index = index_of_end_part(base); + + result = walk(base,func,depth,0,flags,base_index,&prune); + + error = __get_errno(); + free(base); + __set_errno(error); + } + else + { + base_index = index_of_end_part(path); + + result = walk(path,func,depth,0,flags,base_index,&prune); + } + + out: + + RETURN(result); + return(result); +} diff --git a/library/include/ftw.h b/library/include/ftw.h new file mode 100644 index 0000000..fcfba01 --- /dev/null +++ b/library/include/ftw.h @@ -0,0 +1,102 @@ +/* + * $Id: ftw.h,v 1.1 2005-03-02 12:57:56 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FTW_H +#define _FTW_H + +/****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +/* Values passed to the user function (argument #3). */ +enum +{ + FTW_F, /* Regular file. */ + FTW_D, /* Directory. */ + FTW_DP, /* Directory, already visited. (nftw() only) */ + FTW_SL, /* Symlink. (nftw() only) */ + FTW_SLN, /* Broken Symlink. (does not point to an existing file, nftw() only) */ + FTW_DNR, /* Directory which can not be read (e.g. not enough permissions) */ + FTW_NS /* Stat failed. */ +}; + +/****************************************************************************/ + +/* Flags for FTW.quit */ +#define FTW_SKD (1L<<0) /* Skip directory. */ +#define FTW_PRUNE (1L<<1) /* Prune traversal. (skip up) */ + +/****************************************************************************/ + +/* Flags for nftw() */ +#define FTW_PHYS (1L<<0) +#define FTW_MOUNT (1L<<1) /* Currently unsupported. */ +#define FTW_DEPTH (1L<<2) +#define FTW_CHDIR (1L<<3) +#define FTW_ALL_FLAGS (0x0000000f) + +/****************************************************************************/ + +struct FTW +{ + int quit; /* Flags passed out from the user function to ftw()/nftw() */ + int base; /* Index of current item from start of string. e.g. 4 for "foo/bar" */ + int level; /* Current depth. (counted from 0) */ +}; + +/****************************************************************************/ + +extern int ftw(const char *path,int (*func)(const char *,const struct stat *,int),int depth); +extern int nftw(const char *path,int (*func)(const char *,const struct stat *,int,struct FTW *),int depth,int flags); + +/****************************************************************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/****************************************************************************/ + +#endif /* _FTW_H */ diff --git a/library/include/stdlib.h b/library/include/stdlib.h index abe5945..29040f8 100644 --- a/library/include/stdlib.h +++ b/library/include/stdlib.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib.h,v 1.7 2005-02-27 18:09:12 obarthel Exp $ + * $Id: stdlib.h,v 1.8 2005-03-02 12:57:56 obarthel Exp $ * * :ts=4 * @@ -153,11 +153,12 @@ extern int rand_r(unsigned int * seed); /****************************************************************************/ -/* These two functions are unavailable under SAS/C for lack of a +/* These functions are unavailable under SAS/C for lack of a "long long" data type. */ #if ! defined(__SASC) extern long long strtoll(const char *str, char **ptr, int base); extern unsigned long long strtoull(const char *str, char **ptr, int base); +extern long long atoll(const char *str); #endif /* __SASC */ /****************************************************************************/ diff --git a/library/include/strings.h b/library/include/strings.h index 49ce1fd..5fa8b64 100644 --- a/library/include/strings.h +++ b/library/include/strings.h @@ -1,5 +1,5 @@ /* - * $Id: strings.h,v 1.3 2005-01-02 09:07:21 obarthel Exp $ + * $Id: strings.h,v 1.4 2005-03-02 12:57:56 obarthel Exp $ * * :ts=4 * @@ -52,9 +52,10 @@ extern "C" { /****************************************************************************/ -/* These two come from 4.4BSD. */ +/* These come from 4.4BSD. */ extern int strcasecmp(const char *s1, const char *s2); extern int strncasecmp(const char *s1, const char *s2, size_t len); +extern int ffs(int i); /****************************************************************************/ diff --git a/library/include/sys/utsname.h b/library/include/sys/utsname.h new file mode 100644 index 0000000..8ab1fb9 --- /dev/null +++ b/library/include/sys/utsname.h @@ -0,0 +1,74 @@ +/* + * $Id: utsname.h,v 1.1 2005-03-02 12:57:56 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +/****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +#define SYS_NMLN 32 + +/****************************************************************************/ + +struct utsname +{ + char sysname[SYS_NMLN]; /* OS Name ("AmigaOS") */ + char nodename[SYS_NMLN]; /* Usually Hostname, but there appears to be no standard. */ + char release[SYS_NMLN]; /* Release e.g. "51.1" (The Version of version.library) */ + char version[SYS_NMLN]; /* Version e.h. "4.0" (OS Version) */ + char machine[SYS_NMLN]; /* Machine e.g. "m68k" or "ppc" */ +}; + +/****************************************************************************/ + +extern int uname(struct utsname *); + +/****************************************************************************/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/****************************************************************************/ + +#endif /* _SYS_UTSNAME_H */ diff --git a/library/smakefile b/library/smakefile index aeedb0b..1663281 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ _# -# $Id: smakefile,v 1.26 2005-02-28 13:22:53 obarthel Exp $ +# $Id: smakefile,v 1.27 2005-03-02 12:57:53 obarthel Exp $ # # :ts=8 # @@ -380,6 +380,7 @@ STDLIB_OBJ = \ stdlib_atof.o \ stdlib_atoi.o \ stdlib_atol.o \ + stdlib_atoll.o \ stdlib_bsearch.o \ stdlib_calloc.o \ stdlib_checkdetach.o \ @@ -483,6 +484,7 @@ STRING_OBJ = \ string_strxfrm.o STRINGS_OBJ = \ + strings_ffs.o \ strings_strcasecmp.o \ strings_strncasecmp.o @@ -510,6 +512,8 @@ TIME_OBJ = \ time_weekday.o UNISTD_OBJ = \ + ftw_ftw.o \ + ftw_nftw.o \ unistd_access.o \ unistd_chdir.o \ unistd_chdir_exit.o \ @@ -546,7 +550,8 @@ UNISTD_OBJ = \ unistd_truncate.o \ unistd_unix_path_semantics.o \ unistd_unlink.o \ - unistd_usleep.o + unistd_usleep.o \ + utsname_uname.o # \ # unistd_wildcard_expand.o diff --git a/library/stat_lstat.c b/library/stat_lstat.c index 2ae2fc8..aebe9ef 100644 --- a/library/stat_lstat.c +++ b/library/stat_lstat.c @@ -1,5 +1,5 @@ /* - * $Id: stat_lstat.c,v 1.5 2005-02-28 10:07:30 obarthel Exp $ + * $Id: stat_lstat.c,v 1.6 2005-03-02 12:57:53 obarthel Exp $ * * :ts=4 * @@ -41,30 +41,174 @@ #include "stat_headers.h" #endif /* _STAT_HEADERS_H */ +#ifndef _LOCALE_HEADERS_H +#include "locale_headers.h" +#endif /* _LOCALE_HEADERS_H */ + +#ifndef _TIME_HEADERS_H +#include "time_headers.h" +#endif /* _TIME_HEADERS_H */ + /****************************************************************************/ /* The following is not part of the ISO 'C' (1994) standard. */ /****************************************************************************/ -int -lstat(const char * path_name, struct stat * buffer) +/* + * lstat_lock(): An implementation of Lock() which remembers whether or + * not it resolved soft links. + * + * Unfortunately is is limited to 255 character names. + */ + +static BPTR +lstat_lock(const char *name,const int mode,int *link_length) { + D_S(struct bcpl_name,bname); + const size_t name_size = sizeof(bname->name); + char * new_name = NULL; + struct DevProc * dvp = NULL; + LONG link_count = 16; + BPTR lock = ZERO; + size_t name_len; + LONG error; + + name_len = strlen(name); + if(name_len >= name_size) + { + SetIoErr(ERROR_LINE_TOO_LONG); + goto out; + } + + /* Convert the name into a BCPL string. */ + bname->name[0] = name_len; + memmove(&bname->name[1],name,name_len); + + while(TRUE) + { + /* Get a handle on the device, volume or assignment name in the path. */ + dvp = GetDeviceProc(name,dvp); + if(dvp == NULL) + goto out; + + /* Try to obtain a lock on the object. */ + lock = DoPkt(dvp->dvp_Port,ACTION_LOCATE_OBJECT,dvp->dvp_Lock,MKBADDR(bname),mode,0,0); + if(lock != ZERO) + break; + + error = IoErr(); + + if(error == ERROR_OBJECT_NOT_FOUND) + { + /* If this is part of a multi-volume assignment, try the next part. */ + if(FLAG_IS_SET(dvp->dvp_Flags,DVPF_ASSIGN)) + continue; + + /* Not much we can do here... */ + break; + } + else if (error == ERROR_IS_SOFT_LINK) + { + LONG result; + + /* Should we give the soft link resolution another try? */ + link_count--; + if(link_count == 0) + { + /* Nope, we already spent too much time trying to + resolve nested links. */ + SetIoErr(ERROR_TOO_MANY_LEVELS); + goto out; + } + + /* For soft link resolution we need a temporary buffer to + let the file system store the resolved path name in. */ + if(new_name == NULL) + { + new_name = malloc(name_size); + if(new_name == NULL) + { + SetIoErr(ERROR_NO_FREE_STORE); + goto out; + } + + strcpy(new_name,name); + name = new_name; + } + + /* Now ask the file system to resolve the entire path. */ + result = ReadLink(dvp->dvp_Port,dvp->dvp_Lock,name,name,name_size); + if(result < 0) + { + /* This will return either -1 (resolution error) or -2 + (buffer too small). We regard both as trouble. */ + SetIoErr(ERROR_INVALID_COMPONENT_NAME); + goto out; + } + + /* Remember the length of the link name. */ + if(result > 0) + (*link_length) = result; + + /* We now have a new name to resolve. */ + name_len = strlen(name); + + bname->name[0] = name_len; + memmove(&bname->name[1],name,name_len); + } + else + { + /* Some other error; ask if the user wants to have another go at it. */ + if(ErrorReport(error,REPORT_LOCK,dvp->dvp_Lock,dp->dvp_Port) != 0) + break; + } + + /* Retry the lookup. */ + FreeDeviceProc(dvp); + dvp = NULL; + } + + out: + + error = IoErr(); + + if(new_name != NULL) + free(new_name); + + FreeDeviceProc(dvp); + + SetIoErr(error); + + return(lock); +} + +int +lstat(const char * path_name, struct stat * st) +{ + #if defined(UNIX_PATH_SEMANTICS) + struct name_translation_info path_name_nti; + #endif /* UNIX_PATH_SEMANTICS */ + D_S(struct FileInfoBlock,fib); + struct FileLock * fl; int result = -1; + LONG status; + BPTR file_lock = ZERO; + int link_length = 0; ENTER(); SHOWSTRING(path_name); - SHOWPOINTER(buffer); + SHOWPOINTER(st); - assert( path_name != NULL && buffer != NULL ); + assert( path_name != NULL && st != NULL ); if(__check_abort_enabled) __check_abort(); #if defined(CHECK_FOR_NULL_POINTERS) { - if(path_name == NULL || buffer == NULL) + if(path_name == NULL || st == NULL) { SHOWMSG("invalid parameters"); @@ -74,10 +218,110 @@ lstat(const char * path_name, struct stat * buffer) } #endif /* CHECK_FOR_NULL_POINTERS */ - result = stat(path_name,buffer); + #if defined(UNIX_PATH_SEMANTICS) + { + if(__unix_path_semantics) + { + if(__translate_unix_to_amiga_path_name(&path_name,&path_name_nti) != 0) + goto out; + + /* The pseudo root directory is a very special case indeed. + We make up some pseudo data for it. */ + if(path_name_nti.is_root) + { + struct DateStamp ds; + time_t mtime; + + SHOWMSG("setting up the root directory info"); + + memset(st,0,sizeof(*st)); + + PROFILE_OFF(); + DateStamp(&ds); + PROFILE_ON(); + + mtime = __convert_datestamp_to_time(&ds); + + st->st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + st->st_mtime = mtime; + st->st_atime = mtime; + st->st_ctime = mtime; + st->st_nlink = 2; + st->st_blksize = 512; + + result = 0; + goto out; + } + } + } + #endif /* UNIX_PATH_SEMANTICS */ + + D(("trying to get a lock on '%s'",path_name)); + + PROFILE_OFF(); + file_lock = lstat_lock(path_name,SHARED_LOCK,&link_length); + PROFILE_ON(); + + if(file_lock == ZERO) + { + SHOWMSG("that didn't work"); + + __set_errno(__translate_access_io_error_to_errno(IoErr())); + goto out; + } + + if(link_length > 0) + { + struct DateStamp ds; + time_t mtime; + + /* Build a dummy stat for the link. */ + + SHOWMSG("Creating stat info for link."); + + memset(st,0,sizeof(*st)); + + PROFILE_OFF(); + DateStamp(&ds); + PROFILE_ON(); + + mtime = __convert_datestamp_to_time(&ds); + + st->st_mode = S_IFLNK | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + st->st_dev = DeviceProc(path_name); + st->st_size = link_length; + st->st_mtime = mtime; + st->st_atime = mtime; + st->st_ctime = mtime; + st->st_nlink = 1; + } + else + { + PROFILE_OFF(); + status = Examine(file_lock,fib); + PROFILE_ON(); + + if(status == DOSFALSE) + { + SHOWMSG("couldn't examine it"); + + __set_errno(__translate_io_error_to_errno(IoErr())); + goto out; + } + + fl = BADDR(file_lock); + + __convert_file_info_to_stat(fl->fl_Task,fib,st); + } + + result = 0; out: + PROFILE_OFF(); + UnLock(file_lock); + PROFILE_ON(); + RETURN(result); return(result); } diff --git a/library/stdlib_atoll.c b/library/stdlib_atoll.c new file mode 100644 index 0000000..4489c1b --- /dev/null +++ b/library/stdlib_atoll.c @@ -0,0 +1,76 @@ +/* + * $Id: stdlib_atoll.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDLIB_NULL_POINTER_CHECK_H +#include "stdlib_null_pointer_check.h" +#endif /* _STDLIB_NULL_POINTER_CHECK_H */ + +/****************************************************************************/ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +#if defined(USE_64_BIT_INTS) + +/****************************************************************************/ + +long long +atoll(const char *str) +{ + long long result = 0; + + assert( str != NULL ); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(str == NULL) + { + errno = EFAULT; + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + result = strtoll(str, (char **)NULL, 10); + + out: + + return(result); +} + +/****************************************************************************/ + +#endif /* USE_64_BIT_INTS */ diff --git a/library/strings_ffs.c b/library/strings_ffs.c new file mode 100644 index 0000000..f286514 --- /dev/null +++ b/library/strings_ffs.c @@ -0,0 +1,71 @@ +/* + * $Id: strings_ffs.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDLIB_NULL_POINTER_CHECK_H +#include "stdlib_null_pointer_check.h" +#endif /* _STDLIB_NULL_POINTER_CHECK_H */ + +/****************************************************************************/ + +#ifndef _STRINGS_HEADERS_H +#include "strings_headers.h" +#endif /* _STRINGS_HEADERS_H */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +/* Return the index of the lowest set bit. (Counted from one) */ +int +ffs(int i) +{ + int result = 0; + + if(i != 0) + { + int x; + + x = (i & (-i)) - 1; + x -= ((x >> 1) & 0x55555555); + x = ((x >> 2) & 0x33333333) + (x & 0x33333333); + x = ((x >> 4) + x) & 0x0f0f0f0f; + x += (x >> 8); + x += (x >> 16); + + result = 1 + (x & 0x3f); /* The first bit has index 1. */ + } + + return(result); +} diff --git a/library/utsname_uname.c b/library/utsname_uname.c new file mode 100644 index 0000000..b146611 --- /dev/null +++ b/library/utsname_uname.c @@ -0,0 +1,168 @@ +/* + * $Id: utsname_uname.c,v 1.1 2005-03-02 12:57:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************/ + +/* The following is not part of the ISO 'C' (1994) standard. */ + +/****************************************************************************/ + +#include + +/****************************************************************************/ + +#if defined(SOCKET_SUPPORT) && !defined(_SOCKET_HEADERS_H) +#include "socket_headers.h" +#endif /* SOCKET_SUPPORT && !_SOCKET_HEADERS_H */ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +#ifndef _DEBUG_H +#include "debug.h" +#endif /* _DEBUG_H */ + +/****************************************************************************/ + +#define OSNAME "AmigaOS" + +/****************************************************************************/ + +#ifdef __amigaos4__ +#define ARCH "ppc" +#else +#define ARCH "m68k" /* XXX: How should Coldfire accelerators be handled? */ +#endif /* __amigaos4__ */ + +/****************************************************************************/ + +int +uname(struct utsname *info) +{ + struct Library * VersionBase; + int Version,Revision; + char * version_string; + int result = -1; + + ENTER(); + + SHOWPOINTER(info); + + if(info == NULL) + { + __set_errno(EFAULT); + goto out; + } + + strlcpy(info->sysname,OSNAME,sizeof(info->sysname)); + +#if defined(SOCKET_SUPPORT) + __gethostname((STRPTR)info->nodename,sizeof(info->nodename)); +#else + strlcpy(info->nodename,"localhost",sizeof(info->nodename)); +#endif /* SOCKET_SUPPORT */ + + VersionBase = OpenLibrary("version.library",0L); + if(VersionBase != NULL) + { + Version = VersionBase->lib_Version; + Revision = VersionBase->lib_Revision; + + CloseLibrary(VersionBase); + } + else + { + Version = 0; + Revision = 0; + } + + snprintf(info->release,sizeof(info->release),"%d.%d",Version,Revision); + + /* This is mostly a stab in the dark. Is there any "official" way of finding out the OS version? + * Also, this could be more detailed e.g. "3.9-BB2" instead of just "3.9". + * For the curious: + * + * V.R OS Version + * + * 30.x 1.0 (Never released) + * 31.x 1.1 (NTSC) + * 32.x 1.1 (PAL) + * 33.x 1.2 + * 34.x 1.3 + * 35.x 1.3 (with A2024 support) + * 36.x 2.0-2.02 + * 37.x 2.04-2.05 + * 38.x 2.1 + * 39.x 3.0 + * 40.x 3.1 + * 43.x 3.2 (Never released) + * 44.2 3.5 + * 44.4 3.5-BB1 + * 44.5 3.5-BB2 + * 45.1 3.9 + * 45.2 3.9-BB1 + * 45.3 3.9-BB2 + * + */ + + if (Version >= 46) + version_string = "4.0"; + else if (Version == 45) + version_string = "3.9"; + else if (Version >= 44) + version_string = "3.5"; + else if (Version >= 40) + version_string = 3.1"; + else if (Version >= 39) + version_string = "3.0"; + else + version_string = "unknown"; + + strlcpy(info->version,version_string,sizeof(info->version)); + + strlcpy(info->machine,ARCH,sizeof(info->machine)); + + SHOWSTRING(info->sysname); + SHOWSTRING(info->nodename); + SHOWSTRING(info->release); + SHOWSTRING(info->version); + SHOWSTRING(info->machine); + + result = 0; + +out: + + RETURN(result); + return(result); +}