Ruby: can you send a socket as a parameter? [closed] - ruby

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a long ruby script running on a machine and I thought of re-organizing it by dividing it into small functions and sending the socket as a parameter:
#!/usr/bin/env ruby
def prepare data, my_socket
# some calculations
my_socket.write data
end
# execution starts here
tcpsocket = TCPSocket.open host, port
data = "xxx"
prepare(data, tcpsocket)
Unfortunately I can't test.
EDIT: Now that I understood that I shouldn't do that (I will read on the subject later), this is what I did:
#!/usr/bin/env ruby
def prepare data
my_array = []
# some calculations
my_array << data
end
# execution starts here
tcpsocket = TCPSocket.open host, port
data = "xxx"
my_array = prepare data
my_array.each do |m|
my_socket.write m
end

tcpsocket is a local identifier (file descriptor) for a given socket-endpoint.
You would not achieve anything by sending the file descriptor of one host to another host. Without the kernel (or process) hosting the file-descriptor, tcpsocket means nothing. Typically, the kernel would have a mapping of file-descriptor and the socket structure. If you send the tcpsocket file-descriptor to the other side, the other side would not have the corresponding socket structure.
Accordingly, operations on the passed file-descriptor would fail with a bad file-descriptor error. In the worst case, if the process on the remote host has another file-descriptor with the same value, then this would cause unexpected things!

Related

is there an API to check if Mac's Microphone or video camera is in use? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Yes, I realize I can just look at the green-light when the video camera is on. That's not the point.
I'd like to write a little utility that notices when the mic or video camera is in use. I don't have any interest in knowing what app is using it. I just want to know if the mic / camera on or off.
This is for me as a parent. I was thinking I could get one of those color changing LED lights, and then when the camera/mic is on, my app could detect it, then send a signal to the light to change color. Then when one of my kids walks in, they'd see the light is "red" (meaning, do not disturb) and they'd know I'm on a conference call.
I have pretty much the exact same problem to solve. This is my prototype solution. It monitors the number of threads of the AppleCamera process. On the test macbook, the base number of threads seems to be 3. When an application uses the camera, the count increases to 4. I plan to implement microphone checking as well. I'm sure my code could be more compact and I could get the shell commands down to a one-liner but I prefer readability.
import subprocess
import pywemo
DEVICE_NAME = "BatSignal"
def count_camera_threads():
command = ["pgrep", "AppleCamera"]
process = subprocess.run(command, capture_output=True, text=True)
pid = process.stdout.replace("\n", "")
command = ["ps", "M", pid]
process = subprocess.run(command, capture_output=True, text=True)
lines = process.stdout
count = len(lines.splitlines()) - 2
return count
def get_device(name):
devices = pywemo.discover_devices()
for device in devices:
if device.name == name:
return device
return None
if __name__ == "__main__":
device = get_device(DEVICE_NAME)
if device is None:
exit(f"Unable to find '{DEVICE_NAME}' on network")
while True:
if count_camera_threads() > 3:
device.on()
else:
device.off()
time.sleep(1)

TFTP packet example?

I'm writing a TFTP server in Ruby and I don't understand a couple things.
First, I read through the entire RFC and I understand the TFTP part of the packet (2 bytes opcode, etc), but I don't know where the TID's go. Also, I've never done anything in Ruby at a byte level. I don't know how to create a variable that's 2 bytes this and then 1 byte that and then whatever.
If someone could show me an example of how to construct a read request packet in ruby, that'd be sweet. Say I'm on the client side and I select port #20000 (for my local TID) and I want to read the file named /Users/pachun/documents/hello.txt on the server which has a TID of 69 right now because it's the first request. How would I construct that packet in Ruby?
Check out this project:
https://github.com/spiceworks/net-tftp
The code there should answer your questions regarding how to construct byte sequences for communicating with tftp protocol.

Streaming JSON Algorithm - WITHOUT STACK

Is it possible to design a streaming JSON algorithm that writes JSON directly to a socket with the following properties:
* can only write to, but cannot delete or seek within the stream
* does not use either an IMPLICIT or explicit stack
* uses only a constant amount of memory stack depth no matter how deep the object nesting within the json
{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{"1":{...}}}}}}}}}}}}}}}}}
Short answer: No.
Slightly longer: At least not in the general case. If you could guarantee that the nesting has no branching, you could use a simple counter to close the braces at the end.
No, because you could use such a program to compress infinite amounts of memory into a finite space.
Encoding implementation:
input = read('LIBRARY_OF_CONGRESS.tar.bz2')
input_binary = convert_to_binary(input)
json_opening = replace({'0':'[', '1':'{'}, input_binary)
your_program <INPUTPIPE >/dev/null
INPUTPIPE << json_opening
Execute the above program then clone virtual machine it is running on. That is your finite-space compressed version of the infinitely-large input data set. Then to decode...
Decoding implementation:
set_output_pipe(your_program, OUTPUTPIPE)
INPUTPIPE << EOL
json_closing << OUTPUTPIPE
output_binary = replace({']':'0', '}':'1'}, reverse(json_closing))
output = convert_from_binary(output_binary)
write(output, 'LIBRARY_OF_CONGRESS-copy.tar.bz2')
And of course, all good code should have a test case...
Test case:
bc 'LIBRARY_OF_CONGRESS.tar.bz2' 'LIBRARY_OF_CONGRESS-copy.tar.bz2'

A simple TCP messaging protocol?

I want to send messages between Ruby processes via TCP without using ending chars that could restrict the potential message content. That rules out the naïve socket.puts/gets approach.
Is there a basic TCP message implementation somewhere in the standard libs?.
(I'd like to avoid Drb to keep everything simple.)
It seems like there is no canonical, reusable solution.
So here's a basic implementation for the archives:
module Messaging
# Assumes 'msg' is single-byte encoded
# and not larger than 4,3 GB ((2**(4*8)-1) bytes)
def dispatch(msg)
write([msg.length].pack('N') + msg)
end
def receive
if (message_size = read(4)) # sizeof (N)
message_size = message_size.unpack('N')[0]
read(message_size)
end
end
end
# usage
message_hub = TCPSocket.new('localhost', 1234).extend(Messaging)
The usual way to send strings in that situation is to send an integer (encoded however you like) for the size of the string, followed by that many bytes. You can save space but still allow arbitrary sizes by using a UTF-8-like scheme for that integer.

ruby socket issue

i'm still kind of newbie to ruby, but i became used on using ruby sockets, cause i used the 'Socket' class many times, and so i having full control to my sockets and their options.
the thing is i'm trying to make it a little easy for me, so i'm trying to use the 'TCPSocket' class ,witch (i guess) doesn't give u much control as the 'Socket' class.
my script looks like this:
require 'socket'
client = TCPSocket.open('5.5.5.5', '5555')
client.send("msg", 0) # 0 means standard packet
client.close
the question is, what is suppose to be instead of the '0' on the send line ?? and if '0' means standard packet, what other than standard can exist there, is it some control over the TCP packet ?? if so, then it will be much easier for me than writing the whole socket by hand using the 'Socket' class.
The second parameter to send is the flags parameter. It gets passed onto the the send system call. You'll normally want to leave this at 0.
On my system, according to the man page, the other possible flags are:
#define MSG_OOB 0x1 /* process out-of-band data */
#define MSG_DONTROUTE 0x4 /* bypass routing, use direct interface */

Resources