Close a tcl server after file copy is complete - network-programming

I am running a tcl server in VM and a client in windows machine to copy a file from client to vm. The problem is I want the server to close automatically after the task is done. Currently it is not doing it , because "vwait" is set to "forever" .I don't have much knowledge about tcl network programming ,so I can't figure out how to implement it.
My server code
##server side
set destination_directory /home/media
set service_port 9900
proc receive_file {channel_name client_address client_port} {
fconfigure $channel_name -translation binary
gets $channel_name line
foreach {name size} $line {}
set fully_qualified_filename [file join $::destination_directory $name]
set fp [open $fully_qualified_filename w]
fconfigure $fp -translation binary
fcopy $channel_name $fp -size $size
close $channel_name
close $fp
}
socket -server receive_file $service_port
vwait forever
and my client code:
##client side
set service_port 9900
set service_host 192.168.164.161
proc send_one_file name {
set size [file size $name]
set fp [open $name]
fconfigure $fp -translation binary
set channel [socket $::service_host $::service_port]
fconfigure $channel -translation binary
puts $channel [list $name $size]
fcopy $fp $channel -size $size
close $fp
close $channel
}
send_one_file "sample.pdf"
Please guide.

Add one more line to the receive_file proc after you close the handles:
set ::forever true ;# or any other value at all

If you want the Tcl script to terminate after the transfer is done, you can just exit after the close.
set destination_directory /home/media
set service_port 9900
proc receive_file {channel_name client_address client_port} {
fconfigure $channel_name -translation binary
gets $channel_name line
foreach {name size} $line {}
set fully_qualified_filename [file join $::destination_directory $name]
set fp [open $fully_qualified_filename w]
fconfigure $fp -translation binary
fcopy $channel_name $fp -size $size
close $channel_name
close $fp
exit ; #### All done with this process
}
socket -server receive_file $service_port
vwait forever
However, it is probably better to use the asynchronous form of fcopy (I've added a bunch of other Tcl 8.5-isms in here too):
set destination_directory /home/media
set service_port 9900
proc receive_file {channel client_address client_port} {
global destination_directory
lassign [gets $channel] name size
fconfigure $channel -translation binary
if {[catch {
set fp [open [file join $destination_directory $name] "wb"]
fcopy $channel $fp -size $size -command [list done_transfer $channel $fp]
}]} exit
}
proc done_transfer {from_channel to_channel bytes {errorMessage ""}} {
close $from_channel
close $to_channel
exit
}
socket -server receive_file $service_port
vwait forever
A production version of this would probably have code in there to guard against bad filenames, do logging, and possibly to allow multiple connections to be made and for those connections to all finish before the server script finishes. All that makes the code quite a bit longer…

Related

How can I access a memory mapped device, synthesized on fpga, with a Lauterbach script?

on a ZCU106 board with MPSoC Zynq Ultrascale+, I have developed a simple test application that performs reads and writes to a memory-mapped device register. The device in question is a GPIO peripheral, synthesized to fpga and accessed in memory with address (0xA0010000) configured via Vivado tool. The application does not use MMU. If I try to launch and run my application from the Vitis debugger, everything works correctly, with no problems. However, I need to launch the application from Lauterbach's Trace32. By doing the launch with a practice script (Lauterbach's scripting language), the application loads correctly, but upon reading or writing to the memory address where the synthesized device is mapped to fpga, a "debug port fail" type problem is returned. I therefore analyzed the tcl script automatically generated by Vitis to see if there are any hardware configurations that are made in tcl, but which I do not predict with the practice script (Lauterbach). My suspicion is that there are special instructions to enable the mapping of memory addresses that a processor can access. I attach the tcl script generated by Vitis, perhaps the "offending" instruction is the 'loadhw -hw'? Thanks in advance to anyone who can help me.
# In Vitis IDE create a Single Application Debug launch configuration,
# change the debug type to 'Attach to running target' and provide this
# tcl script in 'Execute Script' option.
# Path of this script: /home/daniele/vitis_workspace/interr_measurement_test_system/_ide/scripts/debugger_interr_measurement_test-default.tcl
#
#
# Usage with xsct:
# To debug using xsct, launch xsct and run below command
# source /home/daniele/vitis_workspace/interr_measurement_test_system/_ide/scripts/debugger_interr_measurement_test-default.tcl
#
connect -url tcp:127.0.0.1:3121
source /tools/Xilinx/Vitis/2021.2/scripts/vitis/util/zynqmp_utils.tcl
targets -set -nocase -filter {name =~"APU*"}
rst -system
after 3000
targets -set -filter {jtag_cable_name =~ "Xilinx HW-FTDI-TEST FT232H 49619" && level==0 && jtag_device_ctx=="jsn-HW-FTDI-TEST FT232H-49619-14730093-0"}
fpga -file /home/daniele/vitis_workspace/interr_measurement_test/_ide/bitstream/zcu106_int_meas_plat_wrapper.bit
targets -set -nocase -filter {name =~"APU*"}
loadhw -hw /home/daniele/vitis_workspace/zcu106_int_meas_plat_wrapper/export/zcu106_int_meas_pp
lat_wrapper/hw/zcu106_int_meas_plat_wrapper.xsa -mem-ranges [list {0x80000000 0xbfffffff} {0x400000000 0x5ffffffff} {0x1000000000 0x7fffffffff}] -regs
configparams force-mem-access 1
targets -set -nocase -filter {name =~"APU*"}
set mode [expr [mrd -value 0xFF5E0200] & 0xf]
targets -set -nocase -filter {name =~ "*A53*#0"}
rst -processor
dow /home/daniele/vitis_workspace/zcu106_int_meas_plat_wrapper/export/zcu106_int_meas_plat_wrapper/sw/zcu106_int_meas_plat_wrapper/boot/fsbl.elf
set bp_30_4_fsbl_bp [bpadd -addr &XFsbl_Exit]
con -block -timeout 60
bpremove $bp_30_4_fsbl_bp
targets -set -nocase -filter {name =~ "*A53*#0"}
rst -processor
dow /home/daniele/vitis_workspace/interr_measurement_test/Debug/interr_measurement_test.elf
configparams force-mem-access 0
bpadd -addr &main

Timeout Command under Expect not Working as Expected

I'm new to this community as well as programming. I'm currently working on a an simple Expect script that that reads a file with a list of DNS names, SSH into a Cisco router, and does a simple "show ip int brief".
This list contains some hosts that are not reachable at the moment, so I'm trying to get the script to timeout that unreachable device but to continue with the rest of devices.
When I run the script, it is able to SSH to the first device and execute the "show" command. However, when it reaches the second device (which is unreachable), it hangs there for about 30 seconds and then terminates the script. I'm not sure what I'm doing wrong. Any assistance would be greatly appreciated.
#!/usr/bin/expect
#
#
set workingdir cisco/rtr
puts stdout "Enter TACACS Username:"
gets stdin tacuserid
system stty -echo
puts stdout "Enter TACACS password:"
gets stdin tacpswd
puts stdout "\nEnter enable password:"
gets stdin enabpswd
system stty echo
#
set RTR [open "$workingdir/IP-List.txt" r]
set timestamp [timestamp -format %Y-%m-%d_%H:%M]
#
while {[gets $RTR dnsname] != -1} {
if {[ string range $dnsname 0 0 ] != "#"} {
send_user "The value of the router name is $dnsname\n"
set timeout 10
set count 0
log_file -a -noappend $workingdir/session_$dnsname\_$timestamp.log
send_log "### /START-SSH-SESSION/ IP: $dnsname # [exec date] ###\n"
spawn ssh -o StrictHostKeyChecking=no -l $tacuserid $dnsname
expect {
"TACACS Password: " {send "$tacpswd\r"}
timeout {puts "$dnsname - failed to login"; wait;close;exp_continue}
}
expect {
{>} {send "enable\r"; send_user "on the second expect\n"}
}
expect {
{assword: } {send "$enabpswd\r"}
}
#
expect {
"#" {send "show ip int brief\r"}
}
#expect "#"
send "exit\r"
send_log "\n"
send_log "### /END-SSH-SESSION/ IP: $dnsname # [exec date] ###\n"
log_file
}
}
exit
Your first expect is doing
expect {...
timeout {puts "..."; wait; close; exp_continue}
}
This will match when the ssh takes over 10 seconds to connect to a host.
When this matches it inevitably exits with an error (spawn id ... not open). This is because you wait for the command to end, close the spawn connection, then restart the same expect command.
You probably meant to use continue rather than exp_continue, in order to continue with the enclosing while loop.

CMD - get MAC address of iPhone

Im trying to get the MAC address of my iPhone from my windows machine.
GETMAC /s 10.30.114.14
And it returns:
ERROR: The RPC server is unavailable
But if I try to get a MAC address of any other device (laptops and what not), I get a good address within milliseconds.
So Im asking: Is there a way to get a MAC address of an iDevice from CMD?
**I know I can look at the device settings, but that is realy not what I'm after.
ping it and then grab the MAC from the arp cache:
#echo off
set IP=10.30.114.14
ping -n 1 %IP% >nul
for /f "tokens=2" %%a in ('arp -a ^| find "%IP%"') do set MAC=%%a
echo MAC: %MAC%
pause
Suppose that you a have the inputfile with computers or ip address list, you can give a try with batch file :
#echo off
Title Get IP and MAC address for remote PCs over the network using batch
Set "Copyright=by Hackoo 2021"
Title %~nx0 %Copyright%
Mode con cols=90 lines=12
cls & color 0A & echo.
echo ********************************************************************************
echo Get IP and MAC address for remote PCs over the network by %Copyright%
echo ********************************************************************************
echo(
if _%1_==_Main_ goto :Main
:getadmin
echo %~nx0 : self elevating
set vbs=%temp%\getadmin.vbs
(
echo Set UAC = CreateObject^("Shell.Application"^)
echo UAC.ShellExecute "%~s0", "Main %~sdp0 %*", "", "runas", 1
)> "%vbs%"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
goto :eof
::-------------------------------------------------------------------------------------
:Main
set "InputFile=%~dp0Hosts.txt"
set "OutPutFile=%~dp0IP-MAC.txt"
If Exist "%OutPutFile%" Del "%OutPutFile%"
If Not Exist "%InputFile%" (
color 0C & echo "%InputFile%" does not exist. Please check it first !
Timeout /T 8 /NoBreak>nul & Exit
)
Netsh interface ip delete arpcache >nul 2>&1
#for /f "tokens=* delims=" %%H in ('Type "%InputFile%"') do (
Ping -n 1 %%H>nul
#for /f "tokens=2" %%M in ('arp -a %%H ^| find "%%H"') do (
echo %%H : %%M
echo %%H : %%M>>"%OutPutFile%"
)
)
If Exist "%OutPutFile%" Start "" "%OutPutFile%" & Timeout /T 1 /NoBreak>nul & Exit

How to execute a CMD file in remote computer

I am looking to execute a command in remote machine using invoke but the .cmd file will call for additional .vbs script. So i guess i may have to mention CScript if so how do i mention both cmd/c and cscript in the below command
Invoke-Command -computername blrscrv01 -ScriptBlock { param($path, $command ) cmd /c $path $command } -args '"C:\windows\system32\cscript.exe"','"/?"'
Your example worked for me when I removed the extra level of quoting.
Invoke-Command -computername blrscrv01 -ScriptBlock { param($path, $command ) cmd /c $path $command } -args 'C:\windows\system32\cscript.exe','/?'
Troubleshooting
Enter a remote session and poke around.
Enter-PSSession -computername blrscrv01
Verify that the target script exists and is accessible.
dir \\lcsap027\deploy\c2.cmd
dir \\lcsap027\deploy
type \\lcsap027\deploy\c2.cmd
Attempt to run the script interactively.
\\lcsap027\deploy\c2.cmd
or
cmd /c \\lcsap027\deploy\c2.cmd
Alternative
Another thing you might try is not invoking a cmd script remotely, but issuing the commands remotely. New-PSSession will return a handle you can use to deal interactively with the remote machine. You can repeatedly issue commands with Invoke-Command and get the results (as primitive data types and generic objects, though, not the actual objects themselves).
Altered Script
Here's an altered version of the script you put in your comment. I've removed the nested Invoke-Command (I don't know why it was necessary, you're already running commands on the remote machine). Since the line breaks got lost in the comment, I don't know if there were any statement separator problems (I'll just assume there weren't, though in its "formatted" form as a one-liner, it would have died horribly because PoSH wouldn't have known where one statement ended and the next began).
param(
[string]$ComputerName,
[string]$User,
[string]$pass
)
Get-PSSEssion | Remove-PSSession
$session = New-PSSession -ComputerName $ComputerName
Invoke-Command -Session $session -ScriptBlock {
param(
[string]$ComputerName,
[string]$Username,
[string]$Password
)
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("x:", "\\machinename\sharename", $false, $Username, $Password)
cmd.exe /c "x:\c2.cmd"
$net.RemoveNetworkDrive("x:")
} -args $ComputerName, $User, $pass
This at least got the remote script to run and produced the expected output. (I emitted the computer name, user name, and file location.)
Bear in mind that this method doesn't employ any transport-/application-layer encryption, so the password is sent cleartext over the network.

I can't send some command line parameters via Autohotkey to VLC

I can't figure out how to get my audio extractor script working via commandline arguments on ahk. I know the command line argument is correct, as I'm able to get it working through a batch file, but I keep getting the error below. I think I'm probably doing something wrong syntactically but I just can't figure out what.
I'd really appreciate any help. Thanks.
Error: the following variable name contains an illegal character"
channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%A_LoopField%.mp3"}
Code:
fileselectfile, File_Name, M3
SplitPath, File_Name, name
Loop, parse, name, `n
if a_index = 2
{
msgbox, %A_LoopField%
Run, "C:\Program Files\VideoLAN\VLC\vlc.exe" "-I dummy -v %File_Name% :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%A_LoopField%.mp3"}"
}
Here is the original batch code if you're curious about the audio extraction function I was talking about
#ECHO OFF
REM Loop through files (Recurse subfolders)
REM Syntax
REM FOR /R [[drive:]path] %%parameter IN (set) DO command
REM
REM Key
REM drive:path : The folder tree where the files are located.
REM
REM set : A set of one or more files. Wildcards must be used.
REM If (set) is a period character (.) then FOR will
REM loop through every folder.
REM
REM command : The command(s) to carry out, including any
REM command-line parameters.
REM
REM %%parameter : A replaceable parameter:
REM in a batch file use %%G (on the command line %G)
FOR /R %%G IN (*.mp3) DO (CALL :SUB_VLC "%%G")
FOR /R %%G IN (*.mp3.mp*) DO (CALL :SUB_RENAME "%%G")
GOTO :eof
:SUB_VLC
SET _firstbit=%1
SET _qt="
CALL SET _newnm=%%_firstbit:%_qt%=%%
SET _commanm=%_newnm:,=_COMMA_%
REM echo %_commanm%
ECHO Transcoding %1
REM Here's where the actual transcoding/conversion happens. The next line
REM fires off a command to VLC.exe with the relevant arguments:
CALL "C:\Program Files\VideoLAN\VLC\vlc" -I dummy -v %1 :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%_commanm%.mp3"} vlc://quit
REM Having no SLEEP-esque command, we have to trick DOS/Windows into pausing
REM for a bit between encode ops - To give the host OS a chance to do what it
REM needs to - Via clever use of the PING utility:
REM (Thanks to http://www.computing.net/answers/programming/dos-command-for-wait-5-seconds/11192.html for the tip! :-)
PING -n 1 -w 10000 1.1.1.1 > NUL
GOTO :eof
:SUB_RENAME
SET _origfnm=%1
SET _endbit=%_origfnm:*.mp3=%
CALL SET _newfilenm=%%_origfnm:.mp3%_endbit%=.mp3%%
SET _newfilenm=%_newfilenm:_COMMA_=,%
COPY %1 %_newfilenm%
GOTO :eof
:eof
REM My own little addition to prevent the batch window from "vanishing" without
REM trace at the end of execution, as if a critical error had occurred.
PAUSE
Have you tried without the SplitPath, File_Name, name? I got rid of the error like this, but I don't know if it produces the result you want in the end.
I found the answer. I was making syntatical errors I just didn't have the knowledge to fix myself. The new RUN statement works perfectly.
Here is the newly revised script
fileselectfile, File_Name, M3
SplitPath, File_Name, name, dir, ext, name_no_ext, drive
StringReplace, File_Name, File_Name,`n, \
Loop, parse, name, `n
{if a_index = 2
msgbox, %A_LoopField%
Run % "C:\Program Files\VideoLAN\VLC\vlc.exe -I dummy -v """ File_Name """ :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access=""file"",mux=dummy,dst=""" A_LoopField ".mp3""} "
}

Resources