aboutsummaryrefslogblamecommitdiff
path: root/wakedlg.go
blob: 53fd3e56ca09522e3f88334470a8c0deccf55a1a (plain) (tree)



























































































































































                                                                                                                                                                                                                                                                 
package main

import (
	"fmt"
	"net"
	"regexp"

	"github.com/lxn/walk"
	"github.com/lxn/walk/declarative"
	"github.com/mdlayher/wol"
)

// WakeOnLAN struct type for wake on lan
type WakeOnLAN struct {
	SleepHost, SleepPass, SleepMac string
	SleepPort                      int
}

func runWakeOnLanDg(owner walk.Form, dfgAddr, mactgadd string) (int, error) {
	const regexSingle = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"

	var wakeClientguiwindow struct {
		dlgWakeOnLan       *walk.Dialog
		dbindersshx        *walk.DataBinder
		acceptPB, cancelPB *walk.PushButton
		macLine, addrLine  *walk.LineEdit
	}

	wakestatset := &WakeOnLAN{
		SleepHost: dfgAddr,
		SleepMac:  mactgadd,
		SleepPort: 7,
	}
	return declarative.Dialog{
		AssignTo:      &wakeClientguiwindow.dlgWakeOnLan,
		FixedSize:     true,
		Title:         "Wake On LAN Client",
		DefaultButton: &wakeClientguiwindow.acceptPB,
		CancelButton:  &wakeClientguiwindow.cancelPB,
		DataBinder: declarative.DataBinder{
			AssignTo:       &wakeClientguiwindow.dbindersshx,
			Name:           "wakeClient",
			DataSource:     wakestatset,
			ErrorPresenter: declarative.ToolTipErrorPresenter{},
		},
		MinSize: declarative.Size{Width: 320, Height: 300},
		Layout:  declarative.VBox{},
		Children: []declarative.Widget{
			declarative.GroupBox{
				Title:  "Wake On Lan Options",
				Layout: declarative.HBox{},
				Children: []declarative.Widget{
					declarative.Composite{
						Layout: declarative.Grid{Columns: 1},
						Children: []declarative.Widget{
							declarative.GroupBox{
								Title:  "Host Address To Wake",
								Layout: declarative.Grid{Columns: 3},
								Children: []declarative.Widget{
									declarative.LineEdit{
										AssignTo:    &wakeClientguiwindow.addrLine,
										ToolTipText: "format: IP Address",
										CueBanner:   "IPv4 Address...",
										Text:        declarative.Bind("SleepHost"),
									},

									declarative.NumberEdit{
										ToolTipText: "port number",
										MaxSize:     declarative.Size{Width: 40},
										MinSize:     declarative.Size{Width: 40},
										Value:       declarative.Bind("SleepPort"),
										MinValue:    1,
										MaxValue:    65535,
									},
								},
							},
							declarative.GroupBox{
								Title:  "Host MAC Address",
								Layout: declarative.Grid{Columns: 1},
								Children: []declarative.Widget{
									declarative.LineEdit{
										AssignTo:  &wakeClientguiwindow.macLine,
										CueBanner: "Mac Address...",
										Text:      declarative.Bind("SleepMac"),
									},
								},
							},
							declarative.GroupBox{
								Title:  "Optional Wake Up Password",
								Layout: declarative.VBox{},
								Children: []declarative.Widget{
									declarative.LineEdit{
										CueBanner:    "Optional Password...",
										PasswordMode: true,
										Text:         declarative.Bind("SleepPass"),
									},
								},
							},
						},
					},
				},
			},
			declarative.Composite{
				Layout: declarative.HBox{},
				Children: []declarative.Widget{
					declarative.HSpacer{},
					declarative.PushButton{
						AssignTo: &wakeClientguiwindow.acceptPB,
						Text:     "Wake Up",
						OnClicked: func() {
							if err := wakeClientguiwindow.dbindersshx.Submit(); err != nil {
								return
							}
							if wakestatset.SleepHost == "" {
								wakeClientguiwindow.addrLine.Focused()
								return
							}
							if wakestatset.SleepMac == "" {
								wakeClientguiwindow.macLine.Focused()
								return
							}
							if match, _ := regexp.MatchString(regexSingle, wakestatset.SleepHost); !match {
								walk.MsgBox(wakeClientguiwindow.dlgWakeOnLan, "Host syntax error", "Invalid IPv4 address, Example: 192.168.1.1", walk.MsgBoxIconError)
								return
							}
							digMacAddr, err := net.ParseMAC(wakestatset.SleepMac)
							if err != nil {
								walk.MsgBox(wakeClientguiwindow.dlgWakeOnLan, "Mac syntax error", fmt.Sprint(err), walk.MsgBoxIconError)
								return
							}
							if err := wakeMachineUp(fmt.Sprintf("%v:%v", wakestatset.SleepHost, wakestatset.SleepPort), digMacAddr, []byte(wakestatset.SleepPass)); err != nil {
								walk.MsgBox(wakeClientguiwindow.dlgWakeOnLan, "Wake on error", fmt.Sprint(err), walk.MsgBoxIconError)
								return
							}
							walk.MsgBox(wakeClientguiwindow.dlgWakeOnLan, "Wake on lan", fmt.Sprintf("sent UDP Wake-on-LAN magic packet using \n%s to %s", wakestatset.SleepHost, wakestatset.SleepMac), walk.MsgBoxIconInformation)
						},
					},
					declarative.PushButton{
						AssignTo:  &wakeClientguiwindow.cancelPB,
						Text:      "Cancel",
						OnClicked: func() { wakeClientguiwindow.dlgWakeOnLan.Cancel() },
					},
				},
			},
		},
	}.Run(owner)
}

func wakeMachineUp(ipaddr string, macaddr net.HardwareAddr, password []byte) error {
	machine, err := wol.NewClient()
	if err != nil {
		return err
	}
	defer machine.Close()
	return machine.WakePassword(ipaddr, macaddr, password)
}

Snix LLC Git Repository Holder Copyright(C) 2022 All Rights Reserved Email To Snix.IR