|
import subprocess |
|
import os |
|
import re |
|
import requests |
|
from bs4 import BeautifulSoup |
|
|
|
def run_command(command): |
|
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) |
|
return result.stdout, result.stderr, result.returncode |
|
|
|
def get_missing_shared_object(binary): |
|
_, stderr, _ = run_command(f"./{binary}") |
|
match = re.search(r"error while loading shared libraries: (.*): cannot open shared object file", stderr) |
|
if match: |
|
return match.group(1) |
|
return None |
|
|
|
def find_package_for_shared_object(shared_object): |
|
base_url = "https://packages.debian.org/search" |
|
params = { |
|
'mode': 'path', |
|
'suite': 'sid', |
|
'section': 'all', |
|
'arch': 'amd64', |
|
'searchon': 'contents', |
|
'keywords': shared_object |
|
} |
|
|
|
response = requests.get(base_url, params=params) |
|
if response.status_code != 200: |
|
print(f"Failed to retrieve data from {base_url}") |
|
return None |
|
|
|
soup = BeautifulSoup(response.text, 'html.parser') |
|
results = soup.find_all('tr') |
|
|
|
for result in results: |
|
file_td = result.find('td', class_='file') |
|
if file_td and shared_object in file_td.text: |
|
package_td = result.find('a') |
|
if package_td: |
|
package_name = package_td.text.strip() |
|
return [package_name] |
|
|
|
return None |
|
|
|
def download_and_extract_deb(package): |
|
stdout, _, _ = run_command(f"apt-cache show {package}") |
|
match = re.search(r"Filename: (\S+)", stdout) |
|
if not match: |
|
raise Exception(f"Could not find a downloadable URL for package: {package}") |
|
|
|
deb_url = f"http://archive.ubuntu.com/ubuntu/{match.group(1)}" |
|
deb_file = deb_url.split('/')[-1] |
|
|
|
run_command(f"wget {deb_url}") |
|
run_command(f"dpkg-deb -x {deb_file} ./{package}_extracted") |
|
return f"./{package}_extracted" |
|
|
|
def find_shared_object_in_extracted_dir(directory, shared_object): |
|
for root, _, files in os.walk(directory): |
|
if shared_object in files: |
|
return os.path.join(root, shared_object) |
|
return None |
|
|
|
def create_symlink(shared_object_path): |
|
link_name = os.path.expanduser(f"~/.local/lib/auto-download/{os.path.basename(shared_object_path)}") |
|
os.makedirs(os.path.dirname(link_name), exist_ok=True) |
|
if not os.path.exists(link_name): |
|
os.symlink(os.path.realpath(shared_object_path), link_name) |
|
print(f"Created symlink: {link_name} -> {shared_object_path}") |
|
else: |
|
print(f"Symlink already exists: {link_name}") |
|
|
|
def main(binary): |
|
while True: |
|
shared_object = get_missing_shared_object(binary) |
|
if not shared_object: |
|
print("No missing shared object found.") |
|
break |
|
|
|
print(f"Missing shared object: {shared_object}") |
|
packages = find_package_for_shared_object(shared_object) |
|
if not packages: |
|
print(f"No package found for {shared_object}") |
|
break |
|
|
|
for package in packages: |
|
print(f"Trying to download and extract package: {package}") |
|
extracted_dir = download_and_extract_deb(package) |
|
shared_object_path = find_shared_object_in_extracted_dir(extracted_dir, shared_object) |
|
if shared_object_path: |
|
create_symlink(shared_object_path) |
|
break |
|
else: |
|
print(f"Could not find {shared_object} in any of the packages.") |
|
break |
|
|
|
if __name__ == "__main__": |
|
binary_name = "code" |
|
main(binary_name) |