--****************************************************************************** --* * --* File: TkSocket_00.lua Revision: 1.0 * --* * --* Purpose: performs a DNS lookup * --* * --* Creation: 09.03.2002 Last Modification: 09.03.2002 * --* * --* Platform: IBM-compatible PC running Windows 98SE * --* * --* Environment: Lua 4.0, TkLua 4.0 * --* * --* Author: Andreas Rozek Phone: ++49 (711) 6770682 * --* Kirschblütenweg 15 Fax: - * --* D-70569 Stuttgart EMail: Andreas.Rozek@T-Online.De * --* Germany * --* * --* URL: http://www.Andreas-Rozek.de/ * --* * --* Copyright: the software is published under the "GNU Lesser General Pub- * --* lic License" (see "http://www.fsf.org/copyleft/lesser.html" * --* for additional information) * --* * --* Comments: this is the first experiment with LuaSockets under TkLua 4.0 * --* * --****************************************************************************** dofile("Lua_02_Lib.lua"); -- provides an extended 'tostring' function etc. dofile("TkLua_00_Lib.lua"); -- provides a simple Tk Console local Icon = "./Lua.gif";-- specifying the file name is already sufficient local Title = "TkSocket_00"; local Subtitle = "performs a DNS lookup"; Status = "enter an IP address or a Host Name and press \"Resolve\""; --****************************************************************************** --* * --* doLookup callback function which performs the actual DNS lookup * --* * --****************************************************************************** function doLookup () local Candidate = CandidateEntry.current; Candidate = gsub(Candidate, "^%s*", ""); -- removes leading white char.s Candidate = gsub(Candidate, "%s*$", ""); -- removes trailing white char.s if (Candidate == "") then tkmessagebox{ title=%Title..": Input Error", message="No Host Name or IP Address given", icon="error", type="ok", default="ok" }; setFields(); -- clears all relevant fields of the user interface return nil; -- 'return' without 'nil' produces an error!? end; --**** now perform the lookup **** local MessageWindow = tktoplevel{ tklabel{image="./Info.gif", anchor="ne", width=16, height=16}, tkmessage{ "DNS Lookup running\nPlease wait..."; width="20c", anchor="nw", font="-*-helvetica-bold-r-*--12" }; side="left" -- common layout attribute for all inner widgets }; MessageWindow:title(%Title..": DNS Lookup running"); MessageWindow:transient(MainWindow.tkname); -- register window dependencies MessageWindow:show(); -- also triggers a window layout MessageWindow:resizable(0,0); -- disables window size changes MessageWindow:raise(); -- brings the window into the foreground --**** center this window within the main window (for user's convenience) **** -- tkeval("update idletasks"); -- guarantee actual window display tkeval("update"); -- "update idletasks" doesn't seem to be enough local MainGeometry = MainWindow:geometry(); local _,_,MainW,MainH,MainX,MainY = strfind(MainGeometry[1],"^(%d+)x(%d+)([+-]?%d+)([+-]?%d+)"); local MessageGeometry = MessageWindow:geometry(); local _,_,MsgW,MsgH,MsgX,MsgY = strfind(MessageGeometry[1],"^(%d+)x(%d+)([+-]?%d+)([+-]?%d+)"); MsgX = max(0,floor(MainX+(MainW-MsgW)/2)); MsgY = max(0,floor(MainY+(MainH-MsgH)/2)); MessageWindow:geometry("+"..MsgX.."+"..MsgY); --**** prevent window from being closed by the user **** MessageWindow:protocol("WM_DELETE_WINDOW", ""); --**** make this window "modal" **** MessageWindow:focus(); MessageWindow:grab(); -- tkeval("update idletasks"); -- guarantee actual window display tkeval("update"); -- "update idletasks" doesn't seem to be enough --**** it's now time to perform the DNS lookup **** local Address,HostInfo = toip(Candidate); MainWindow:grab(); -- releases the grab on "MessageWindow" MessageWindow:withdraw(); -- removes the window if (Address == nil) then tkmessagebox{ title=%Title..": DNS Lookup Error", message="DNS Lookup failed\nReason: \""..tostring(HostInfo).."\"", icon="error", type="ok", default="ok" }; setFields(Candidate,nil,nil,nil,"DNS Lookup failed, reason: \""..tostring(HostInfo).."\""); return nil; -- 'return' without 'nil' produces an error!? end; --**** analyse any results **** local AliasList = ""; if (HostInfo.alias ~= nil) and (getn(HostInfo.alias) > 0) then -- 2nd case is important! local AliasCount = getn(HostInfo.alias); for i = 1,AliasCount do AliasList = AliasList..HostInfo.alias[i]; if (i < AliasCount) then AliasList = AliasList..", "; end; end; end; local AddressList = ""; if (HostInfo.ip ~= nil) and (getn(HostInfo.ip) > 0) then -- 2nd case is important! local AddressCount = getn(HostInfo.ip); for i = 1,AddressCount do AddressList = AddressList..HostInfo.ip[i]; if (i < AddressCount) then AddressList = AddressList..", "; end; end; end; setFields(Candidate, HostInfo.name, AliasList, AddressList, Status); end; --****************************************************************************** --* * --* setFields (re)loads relevant fields of the graphical user interface * --* * --****************************************************************************** function setFields (Candidate, CanonicalName, AliasList, AddressList, Message) CandidateEntry.current = Candidate or ""; CanonicalView.state = "normal"; CanonicalView.current = CanonicalName or ""; CanonicalView.state = "disabled"; AliasView.state = "normal"; AliasView.current = AliasList or ""; AliasView.state = "disabled"; AddressView.state = "normal"; AddressView.current = AddressList or ""; AddressView.state = "disabled"; StatusBar.text = Message or Status; end; --****************************************************************************** --* * --* main program * --* * --****************************************************************************** --**** define window components **** local LabelFont = "-*-helvetica-bold-r-*--12"; -- just an abbreviation local IconLabel = tklabel{image=Icon, anchor="center", width=32, height=32}; local TitleLabel = tklabel{Title; anchor="e", font="-*-helvetica-bold-o-*--16"}; local SubtitleLabel = tklabel{Subtitle; anchor="e", font="-*-helvetica-bold-r-*--12"}; local UpperSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local CandidateLabel = tklabel{"Input:"; font=LabelFont}; CandidateEntry = tkentry{width=30}; local DNSButton = tkbutton{"Resolve"; font=LabelFont, command="doLookup()"}; local InputSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; local CanonicalLabel = tklabel{"Canonical Name:"; font=LabelFont}; CanonicalView = tkentry{state="disabled", background="SystemButtonFace"}; local AliasLabel = tklabel{"Alias List:"; font=LabelFont}; AliasView = tkentry{state="disabled", background="SystemButtonFace"}; local AddressLabel = tklabel{"Address List:"; font=LabelFont}; AddressView = tkentry{state="disabled", background="SystemButtonFace"}; local LowerSeparator = tkframe{relief="sunken", borderwidth=2, height=2}; StatusBar = tklabel{Status; width=40, anchor="w", font="-*-helvetica-medium-r-*--11"}; --**** construct application window **** MainWindow = tkmain{ tkframe{ IconLabel, {side="left"}, TitleLabel, {side="top", fill="x"}, SubtitleLabel, {side="top", fill="x"} }, {side="top", fill="x"}, UpperSeparator, {side="top", fill="x"}, tkframe{ -- see below for some "fine-tuning" of this frame CandidateLabel, CandidateEntry, DNSButton, "/", InputSeparator, "/", CanonicalLabel, CanonicalView, "/", AliasLabel, AliasView, "/", AddressLabel, AddressView; geoman="grid" }, {side="top", fill="both", expand=1}, LowerSeparator, {side="top", fill="x"}, StatusBar, {side="top", fill="x"} }; --**** provide a default for 'CandidateEntry' **** CandidateEntry.current="localhost"; --**** display application window **** MainWindow:title(Title.." - "..Subtitle); MainWindow:show(); -- also triggers a window layout --MainWindow:resizable(0,0); -- disables window size changes --MainWindow:raise(); -- brings the window into the foreground --**** it's now time to fine-tune the display **** tkeval('grid configure '..CandidateLabel.tkname..' -sticky "e" -pady 2'); tkeval('grid configure '..CandidateEntry.tkname..' -padx 2 -pady 2'); tkeval('grid configure '..DNSButton.tkname..' -padx 2 -pady 2'); tkeval('grid configure '..InputSeparator.tkname..' -columnspan 3 -sticky "ew"'); tkeval('grid configure '..CanonicalLabel.tkname..' -sticky "e"'); tkeval('grid configure '..CanonicalView.tkname..' -columnspan 2 -sticky "ew" -padx 2 -pady 2'); tkeval('grid configure '..AliasLabel.tkname..' -sticky "e"'); tkeval('grid configure '..AliasView.tkname..' -columnspan 2 -sticky "ew" -padx 2'); tkeval('grid configure '..AddressLabel.tkname..' -sticky "e"'); tkeval('grid configure '..AddressView.tkname..' -columnspan 2 -sticky "ew" -padx 2 -pady 2'); --**** provide an explicit method to terminate this program! **** MainWindow:protocol("WM_DELETE_WINDOW", "print('done...'); tkexit()");