1. Cross platform system information
- Posted by Michael J. Sabal <m_sabal at yahoo.co?> Jul 05, 2007
- 572 views
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
- Posted by Michael J. Sabal <m_sabal at yahoo.co?> Jul 06, 2007
- 562 views
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