1. Cross platform system information
I have an application that I'm working on that needs to be cross-platform,
and needs to be able to detect which version of an OS it's running on
(Windows 98, XP, or Vista, or Linux 2.4.x or 2.6.x). It also needs to be
able to detect the logged in username if possible. I know I can write a
fairly lengthy function using platform() and lots of if's to do this; but
it might be nice if uname(), a fairly standard C function, were built in as
a machine_func. Any ideas?
Mike Sabal
2. Re: Cross platform system information
Anyway, here's the long code to do it. I have no idea how DOS would return
anything meaningful, unless it were from a Watcom call to uname().
-- Returns a sequence (empty if there's an error):
-- {sequence SYSNAME,
-- sequence NODENAME,
-- sequence RELEASE,
-- sequence VERSION,
-- sequence MACHINE,
-- sequence USERNAME}
include machine.e
include dll.e
include misc.e
object dll_, uname_
if platform()=DOS32 then
dll_ = -1
uname_ = -1
elsif platform()=WIN32 then
dll_ = open_dll("kernel32.dll")
uname_ = define_c_func(dll_,"GetVersionExA",{C_POINTER},C_UINT)
elsif platform()=LINUX then
dll_ = open_dll("libc.so")
uname_ = define_c_func(dll_,"uname",{C_POINTER},C_UINT)
end if
function get_string(atom lpsz)
atom ptr, c
sequence s
s = ""
if lpsz = 0 then
return s
end if
ptr = 0
c = peek(lpsz+ptr)
while c != 0 do
s = s & c
ptr = ptr + 1
c = peek(lpsz+ptr)
end while
return s
end function
function windows_username()
sequence username
atom advapi_, getusername_
atom user_struct, status
advapi_ = open_dll("advapi32.dll")
getusername_ =
define_c_func(advapi_,"GetUserNameA",{C_POINTER,C_POINTER},C_INT)
user_struct = allocate(261)
poke4(user_struct,256)
status = c_func(getusername_,{user_struct+4,user_struct})
if not status then
free(user_struct)
return ""
end if
username = get_string(user_struct+4)
free(user_struct)
return username
end function
function linux_username()
sequence username
atom uid, pwptr, pwptr1
atom getuid_, getpwuid_
getuid_ = define_c_func(dll_,"getuid",{},C_UINT)
getpwuid_ = define_c_func(dll_,"getpwuid",{C_UINT},C_POINTER)
uid = c_func(getuid_,{})
pwptr = c_func(getpwuid_,{uid})
if pwptr > 0 then
pwptr1 = peek4u(pwptr)
-- Linux 2.4: pwptr = {username, password_hash, uid, gid, Real name, home
dir, shell}
username = get_string(pwptr1+0)
free(pwptr1)
return username
end if
return ""
end function
global function uname()
atom utsname, getcompname_
atom compnameptr
sequence compname
integer status
sequence rtn
atom sizeof_utsnamestr
if platform()=DOS32 then
elsif platform()=WIN32 then
getcompname_ =
define_c_proc(dll_,"GetComputerNameExA",{C_UINT,C_POINTER,C_POINTER})
compnameptr = allocate(261)
poke4(compnameptr,256)
c_proc(getcompname_,{1,compnameptr+4,compnameptr})
compname = get_string(compnameptr+4)
free(compnameptr)
utsname = allocate((5*4)+128+8)
poke4(utsname,156)
status = c_func(uname_,{utsname})
if status = 0 then
poke4(utsname,148)
status = c_func(uname_,{utsname})
if status = 0 then
return {}
end if
end if
rtn = {"Microsoft Windows",
compname, -- hostname
sprintf("%d.%d.%d.%d",{peek4u(utsname+4),peek4u(utsname+8),peek(utsname+148)+(peek(utsname+149)*256),
peek(utsname+150)+(peek(utsname+151)*256)}),
sprintf("Build %d",peek4u(utsname+12)),
sprintf("%d",peek4u(utsname+16)),
windows_username()}
free(utsname)
return rtn
elsif platform()=LINUX then
sizeof_utsnamestr=65
utsname = allocate(sizeof_utsnamestr*6)
status = c_func(uname_,{utsname})
if status < 0 then
return {}
end if
rtn = {get_string(utsname+0),
get_string(utsname+(sizeof_utsnamestr*1)),
get_string(utsname+(sizeof_utsnamestr*2)),
get_string(utsname+(sizeof_utsnamestr*3)),
get_string(utsname+(sizeof_utsnamestr*4)),
linux_username()}
free(utsname)
return rtn
end if
return {}
end function