home-backup/home_backup/sys_service/utils.py

48 lines
1.6 KiB
Python

import asyncio
import functools
import json
import struct
async def get_user_home(name:str):
# Check args
if not isinstance(name, str):
raise TypeError("name have to be a string.")
# Find home
proc = await asyncio.create_subprocess_exec(b"getent", b"passwd", name.encode(), stdout=asyncio.subprocess.PIPE)
proc_data = proc.communicate()
if not isinstance(proc_data, tuple):
raise RuntimeError("Internal value isn't the expected type.")
if proc.returncode != 0:
raise RuntimeError("getent didn't work.")
return proc_data[0].split(":")[6]
async def run_access_socket(path:str, async_callback):
async def run_func(read, write):
# Get user id
socket = write.get_extra_info("socket")
tmp = socket.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize('3i'))
tmp = struct.unpack('3i', tmp)[1]
uid = str(tmp)
# Run callback
await async_callback(read, write, uid)
await (await asyncio.start_unix_server(run_func, path=path)).serve_forever()
_format_length = struct.Struct(">I")
def rpc_callback(async_func):
@functools.wraps(async_func)
async def wrap_func(read, write, uid):
while not read.at_eof():
# Read data
size = _format_length.unpack(await read.readexactly(_format_length.size))
data = json.loads((await read.readexactly(size)).decode("UTF-8"))
# Callback and return result
result = json.dumps(await async_func(data, uid)).encode("UTF-8")
write.write(_format_length.pack(len(result)))
write.write(result)
return wrap_func