Untitled

 avatar
unknown
python
2 years ago
4.5 kB
17
Indexable
def __send(sock, data:bytes) -> int:
	pos = 0
	while pos<len(data):
		sent = sock.send(data[pos:])
		if sent==0:  print(f'\x1b[91mFAIL  \x1b[31m{__file__}\x1b[91m:\x1b[32m{sys._getframe().f_code.co_name}\x1b[0m()\x1b[91m:\x1b[34m{sys._getframe().f_lineno}  \x1b[0msocket broken'); return 0
		pos += sent
	return 1

def __recv(sock, bdim:int) -> bytes:
	data = io.BytesIO()
	pos  = 0
	while pos<bdim:
		datum = sock.recv(min(bdim-pos, 0x1000))  # won't accept packets greater than this many bytes
		if datum==b'':
			if pos!=0:  print(f'\x1b[91mFAIL  \x1b[31m{__file__}\x1b[91m:\x1b[32m{sys._getframe().f_code.co_name}\x1b[0m()\x1b[91m:\x1b[34m{sys._getframe().f_lineno}  \x1b[0msocket broken  \x1b[0m{pos} {datum}')
			return data.getvalue()
		data.write(datum)
		pos += len(datum)
	return data.getvalue()

def fssend(sock, opcode:int,bdim:int=0,data:bytes=b''):  # @meta  pack an fs packet into byte
	packet = io.BytesIO()
	packet.write(SFID)
	packet.write(opcode.to_bytes(1,'little'))
	packet.write(bdim.to_bytes(8,'little'))
	if   opcode==OPACK  or opcode==OPEXIT:                   pass
	elif opcode==OPPASS or opcode==OPCMD or opcode==OPFILE:  packet.write(data)
	__send(sock,packet.getvalue())

# @meta  tries its best to recv a full fs packet. unpack the fs packet from bytes
# @ret   [opcode,bdim,data]
def fsrecv(sock):
	hdr = __recv(sock,SFHDRBDIM)  # recv the hdr

	id = hdr[0:8]
	if id!=SFID:
		if len(hdr)!=0:  print(f'\x1b[91mFAIL  \x1b[31m{__file__}\x1b[91m:\x1b[32m{sys._getframe().f_code.co_name}\x1b[0m()\x1b[91m:\x1b[34m{sys._getframe().f_lineno}  \x1b[0mpacket')
		return OPFAIL,0,b''

	opcode = int.from_bytes(hdr[8:9],'little')
	if   opcode==OPACK  or opcode==OPEXIT:  return opcode,0,b''
	elif opcode==OPPASS or opcode==OPCMD or opcode==OPFILE:
		bdim = int.from_bytes(hdr[9:17],'little')  # x.to_bytes(8,'little')
		data = __recv(sock,bdim)
		return opcode,bdim,data
	else:  print(f'\x1b[91mFAIL  \x1b[31m{__file__}\x1b[91m:\x1b[32m{sys._getframe().f_code.co_name}\x1b[0m()\x1b[91m:\x1b[34m{sys._getframe().f_lineno}  \x1b[0mpacket');  return OPFAIL,0,b''

# @meta  show an fs packet
def fsshow(opcode,bdim,data):
	print(f"\x1b[31m{opcode} \x1b[32m{bdim:,} \x1b[0m{data.decode('utf-8')}")

# -----------------------------------------------------------------------------------------------------------------------------------------# @blk1  srv: server
def srv():
	srv = socket.socket()
	srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

	host = socket.gethostname()
	srv.bind((host,SFPORT))
	srv.listen(4)  # how many clts the srv can listen to simultaneously
	print(f'\x1b[33mlisten \x1b[91m:\x1b[34m{SFPORT}\x1b[0m')

	def connection(clt,addr):
		m.print(f'\x1b[91mhi \x1b[34m{addr}\x1b[0m')
		opcode,bdim,data = fsrecv(clt)
		if opcode!=OPPASS or data!=SFPASS:  print(f'\x1b[91mFAIL  \x1b[31m{__file__}\x1b[91m:\x1b[32m{sys._getframe().f_code.co_name}\x1b[0m()\x1b[91m:\x1b[34m{sys._getframe().f_lineno}  \x1b[0mpass'); fssend(clt, OPFAIL); clt.close(); return
		fssend(clt, OPACK)

		while 1:
			print(f'\n{m.datestr(rgb=1)} recv')
			opcode,bdim,req = fsrecv(clt);  fsshow(opcode,bdim,req)
			if opcode==OPEXIT or opcode==OPFAIL:  break
			elif opcode==OPCMD:
				reply = subprocess.run(req, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
				reply = reply.stdout if reply.stdout else reply.stderr
				fssend(clt, OPCMD,len(reply),reply)

		m.print(f'\x1b[92mbye \x1b[34m{addr}\x1b[0m')
		clt.close()

	while 1:
		clt,addr = srv.accept()  # accept new clt conn
		thr = m.Thread(target=connection, args=[clt,addr], autokill=1)
		thr.start()

	srv.shutdown()
	srv.close()

# -----------------------------------------------------------------------------------------------------------------------------------------# @blk1  clt: client
def clt(host=SFHOST):
	print(f'ip \x1b[92m{host}\x1b[0m\n')
	clt = socket.socket()
	clt.connect((host,SFPORT))

	fssend(clt, OPPASS,len(SFPASS),SFPASS)
	opcode,bdim,data = fsrecv(clt)  # fsshow(opcode,bdim,data)
	if opcode==OPEXIT or opcode==OPFAIL:  	clt.shutdown(socket.SHUT_RDWR); clt.close(); return

	while 1:
		req = input('\x1b[92m$\x1b[0m ')
		if req[:4]=='exit':  fssend(clt, OPEXIT)
		else:                fssend(clt, OPCMD,len(req),req.encode('utf-8'))

		opcode,bdim,reply = fsrecv(clt)  # print(f'\x1b[31m{opcode} \x1b[32m{bdim:,}\x1b[0m')
		print(reply.decode('utf-8'))
		if opcode==OPEXIT or opcode==OPFAIL:  break

	clt.shutdown(socket.SHUT_RDWR)
	clt.close()