"""Detection d'une cible ssh (user/host/port) tapee a la main dans un terminal. Sert a proposer le SFTP sur l'hote d'une commande `ssh ...` sans avoir a creer un favori au prealable. """ from __future__ import annotations import re # Repere une commande ssh tapee a la main dans un terminal. SSH_COMMAND_RE = re.compile(r"\bssh\s+(?P[^\r\n|;&]+)") # options ssh qui consomment la valeur suivante (a ne pas confondre avec l'hote) SSH_VALUE_OPTIONS = { "-p", "-i", "-l", "-o", "-F", "-J", "-b", "-c", "-D", "-L", "-R", "-W", "-e", "-m", "-Q", } HOST_RE = re.compile(r"^[A-Za-z0-9][\w.\-]*$") def _parse_ssh_args(args: str) -> dict | None: tokens = args.split() user, host, port = "", "", 22 index = 0 while index < len(tokens): token = tokens[index] if token.startswith("-"): if token in SSH_VALUE_OPTIONS: value = tokens[index + 1] if index + 1 < len(tokens) else "" if token == "-p" and value.isdigit(): port = int(value) if token == "-l" and value: user = value index += 2 continue if token.startswith("-p") and token[2:].isdigit(): # forme collee : -p2222 port = int(token[2:]) index += 1 continue if not host: candidate = token if "@" in candidate: user, _, candidate = candidate.partition("@") if HOST_RE.match(candidate): host = candidate index += 1 return {"user": user, "host": host, "port": port} if host else None def detect_ssh_target(text: str) -> dict | None: """Renvoie la derniere cible ssh trouvee dans le texte d'un terminal.""" result = None for match in SSH_COMMAND_RE.finditer(text): parsed = _parse_ssh_args(match.group("args")) if parsed: result = parsed return result