-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9346929
Showing
18 changed files
with
1,788 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
*~ | ||
lib | ||
pkgs | ||
bottle | ||
bin | ||
curlprog | ||
tarball_incremental | ||
scan | ||
minibrew.tar.xz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
all: minibrew.tar.xz | ||
|
||
SOURCES := dl.pl extract.pl genlib.pl genbin.pl rebase.pl deploy.pl $(wildcard *.json) curlprog tarball_incremental scan mod/Ujsonin.pm | ||
EMPTY_FOLDERS := bin pkgs lib bottle | ||
|
||
minibrew.tar.xz: $(SOURCES) | ||
tar --no-recursion -cJf minibrew.tar.xz $(SOURCES) $(EMPTY_FOLDERS) | ||
|
||
scan: scan.c | ||
clang -arch x86_64 -arch arm64 -o scan scan.c | ||
codesign --sign - scan | ||
|
||
tarball_incremental: tarball_incremental.c | ||
clang -arch x86_64 -arch arm64 -o tarball_incremental tarball_incremental.c -I/usr/local/opt/libarchive/include -ldl | ||
codesign --sign - tarball_incremental | ||
|
||
curlprog: curlprog.m | ||
clang -arch x86_64 -arch arm64 -fobjc-arc -o curlprog curlprog.m -ldl -framework Foundation | ||
codesign --sign - curlprog | ||
|
||
clean: | ||
rm scan curlprog tarball_incremental minibrew.tar.xz |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <dlfcn.h> | ||
#include <curl/curl.h> | ||
#import <sys/sysctl.h> | ||
#include <unistd.h> | ||
#import <Foundation/Foundation.h> | ||
|
||
// Define a structure to hold function pointers for the libcurl functions we need | ||
struct curl_functions { | ||
CURL* (*easy_init )(void); | ||
CURLcode (*easy_setopt )(CURL *curl, CURLoption option, ...); | ||
CURLcode (*easy_perform )(CURL *curl); | ||
void (*easy_cleanup )(CURL *curl); | ||
const char* (*easy_strerror )(CURLcode); | ||
struct curl_slist* (*slist_append )(struct curl_slist *, const char *); | ||
void (*slist_free_all)(struct curl_slist *); | ||
const char* (*version )(void); | ||
}; | ||
|
||
// Callback function for writing received data to a file | ||
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { | ||
FILE *writehere = (FILE *)userp; | ||
return fwrite(buffer, size, nmemb, writehere); | ||
} | ||
|
||
// Progress callback function | ||
int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { | ||
static double last_dl = 0; | ||
if (dlnow - last_dl > 20480) { // 20KB | ||
printf("%.0f\n", dlnow-last_dl); | ||
last_dl = dlnow; | ||
} | ||
return 0; | ||
} | ||
|
||
// Header callback function to print each header line | ||
size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) { | ||
fwrite(buffer, size, nitems, (FILE *)userdata); | ||
return nitems * size; | ||
} | ||
|
||
int main( int argc, char **argv ) { | ||
void *libcurl; | ||
struct curl_functions curl; | ||
CURL *handle; | ||
CURLcode res; | ||
|
||
if( argc < 3 ) { | ||
printf("Usage: %s [url] [save location]\n\n", argv[0] ); | ||
return 1; | ||
} | ||
|
||
// Load the libcurl shared library | ||
libcurl = dlopen("/usr/lib/libcurl.dylib", RTLD_LAZY); | ||
if (!libcurl) { | ||
fprintf(stderr, "Error loading libcurl: %s\n", dlerror()); | ||
return 1; | ||
} | ||
|
||
// Load function symbols | ||
curl.easy_init = dlsym(libcurl, "curl_easy_init"); | ||
curl.easy_setopt = dlsym(libcurl, "curl_easy_setopt"); | ||
curl.easy_perform = dlsym(libcurl, "curl_easy_perform"); | ||
curl.easy_cleanup = dlsym(libcurl, "curl_easy_cleanup"); | ||
curl.easy_strerror = dlsym(libcurl, "curl_easy_strerror"); | ||
curl.slist_append = dlsym(libcurl, "curl_slist_append"); | ||
curl.slist_free_all = dlsym(libcurl, "curl_slist_free_all"); | ||
curl.version = dlsym(libcurl, "curl_version"); | ||
|
||
if (!curl.easy_init || !curl.easy_setopt || !curl.easy_perform || !curl.easy_cleanup || | ||
!curl.easy_strerror || !curl.slist_append || !curl.slist_free_all || !curl.version) { | ||
fprintf(stderr, "Error loading functions: %s\n", dlerror()); | ||
dlclose(libcurl); | ||
return 1; | ||
} | ||
|
||
char *curlVersion = strdup( curl.version() ); | ||
for( int i=0;i<strlen( curlVersion ); i++ ) { | ||
if( curlVersion[i] == ' ' ) { | ||
curlVersion[i] = 0x00; | ||
break; | ||
} | ||
} | ||
//printf("Curl version: %s\n", version ); | ||
//libcurl/8.4.0 SecureTransport (LibreSSL/3.3.6) zlib/1.2.11 nghttp2/1.51.0 | ||
|
||
char *version = NULL; | ||
@autoreleasepool { | ||
NSProcessInfo *processInfo = [NSProcessInfo processInfo]; | ||
NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion]; | ||
NSString *versionString = [NSString stringWithFormat:@"Mac OS X %ld.%ld.%ld", | ||
osVersion.majorVersion, | ||
osVersion.minorVersion, | ||
osVersion.patchVersion]; | ||
version = strdup( [versionString UTF8String] ); | ||
} | ||
|
||
const char hwMachine[] = "hw.machine"; | ||
size_t size; | ||
sysctlbyname(hwMachine, NULL, &size, NULL, 0); | ||
char *value = malloc(size); | ||
sysctlbyname(hwMachine, value, &size, NULL, 0); | ||
|
||
//printf("Arch:%s\n", value ); | ||
|
||
const char archIntel[] = "Intel"; | ||
const char archArm[] = "Arm"; | ||
char *arch = NULL; | ||
if( !strncmp( value, "x86_64", 6 ) ) { | ||
arch = strdup( archIntel ); | ||
free( value ); | ||
value = NULL; | ||
} | ||
else if( !strncmp( value, "arm64", 5 ) ) { | ||
arch = strdup( archArm ); | ||
free( value ); | ||
value = NULL; | ||
} | ||
else { | ||
arch = value; | ||
value = NULL; | ||
} | ||
|
||
// Initialize a libcurl easy session | ||
handle = curl.easy_init(); | ||
if (handle) { | ||
//FILE *fp = fopen("openssl.tar.gz", "wb"); | ||
FILE *fp = fopen( argv[2], "wb"); | ||
|
||
if (!fp) { | ||
perror("File opening failed"); | ||
return EXIT_FAILURE; | ||
} | ||
|
||
// Set URL | ||
//curl.easy_setopt(handle, CURLOPT_URL, "https://ghcr.io/v2/homebrew/core/openssl/3/blobs/sha256:28be258776e175a8c29a19be5312b885574a98324d7b03c7ec12f2d7eadcbce1"); | ||
curl.easy_setopt(handle, CURLOPT_URL, argv[1] ); | ||
|
||
// Set progress function and enable it | ||
curl.easy_setopt(handle, CURLOPT_NOPROGRESS, 0L); | ||
curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); | ||
curl.easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, progress_callback); | ||
// Set headers | ||
struct curl_slist *headers = NULL; | ||
char ua[300]; | ||
snprintf( ua, 300, "User-Agent: Minibrew/0.0.1 (Macintosh; %s %s) %s", arch, version, curlVersion ); | ||
|
||
headers = curl.slist_append(headers, ua); | ||
headers = curl.slist_append(headers, "Accept-Language: en"); | ||
headers = curl.slist_append(headers, "Authorization: Bearer QQ=="); | ||
curl.easy_setopt(handle, CURLOPT_HTTPHEADER, headers); | ||
// Set write function | ||
curl.easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data); | ||
curl.easy_setopt(handle, CURLOPT_WRITEDATA, fp); | ||
|
||
//curl.easy_setopt(handle, CURLOPT_HEADERFUNCTION, header_callback); | ||
//curl.easy_setopt(handle, CURLOPT_HEADERDATA, stdout); | ||
|
||
// Perform the request | ||
res = curl.easy_perform(handle); | ||
if (res != CURLE_OK) { | ||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl.easy_strerror(res)); | ||
} | ||
|
||
// Cleanup | ||
curl.easy_cleanup(handle); | ||
curl.slist_free_all(headers); | ||
fclose(fp); | ||
} | ||
|
||
dlclose(libcurl); | ||
|
||
if( arch ) free( arch ); | ||
if( version ) free( version ); | ||
if( curlVersion ) free( curlVersion ); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/usr/bin/perl -w | ||
use strict; | ||
|
||
system("./dl.pl"); | ||
system("./extract.pl"); | ||
system("./genlib.pl"); | ||
system("./genbin.pl"); | ||
system("./rebase.pl"); | ||
print "DONE\n"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
#!/usr/bin/perl -w | ||
# Copyright (c) 2024 Dry Ark LLC | ||
use strict; | ||
use lib 'mod'; | ||
use Ujsonin; | ||
use Data::Dumper; | ||
|
||
my $arch = `uname -m`; | ||
$arch =~ s/\n//; | ||
|
||
my $macosVersion = `sw_vers -productVersion`; | ||
my $major = $macosVersion; | ||
$major =~ s/\..+//; | ||
|
||
my $plat = "";#"ventura"; | ||
if( $arch eq 'arm64' ) { | ||
$plat = "arm64_"; | ||
} | ||
|
||
|
||
if( $major == 12 ) { $plat .= "monterey"; } | ||
elsif( $major == 13 ) { $plat .= "ventura"; } | ||
elsif( $major == 14 ) { $plat .= "sonoma"; } | ||
else { | ||
print "MacOS older than monterey(12) or newer than sonoma(14)\n"; | ||
exit; | ||
} | ||
|
||
my $doneSize = 0; | ||
my $totSize = 0; | ||
my $dlTot = 0; | ||
|
||
my $lastPercent = -1; | ||
|
||
if( ! -e "/usr/bin/install_name_tool" ) { | ||
if( ! -e "./install_name_tool.tar.xz" ) { | ||
`curl --progress-bar --location https://github.com/dryark/cctools-port/releases/download/986/install_name_tool.tar.xz -o install_name_tool.tar.xz`; | ||
} | ||
if( ! -e "./install_name_tool" ) { | ||
`tar -xf install_name_tool.tar.xz`; | ||
} | ||
} | ||
|
||
download_plat( $plat ); | ||
|
||
sub download_plat { | ||
my $plat = shift; | ||
Ujsonin::init(); | ||
my $data = read_file("dlinfo.json"); | ||
my $data2 = read_file("dlsize.json"); | ||
my $root = Ujsonin::parse( $data, 0 ); | ||
my $root2 = Ujsonin::parse( $data2, 0 ); | ||
#print Dumper( $root ); | ||
|
||
my $curlVersion = get_curl_version(); | ||
|
||
my $pkgs = $root->{pkgs}; | ||
my $shas = $root2->{sha256}; | ||
|
||
#my $totSize = 0; | ||
for my $pkg ( @$pkgs ) { | ||
my $plats = $pkg->{platforms}; | ||
my $sha = $plats->{ $plat } || $plats->{all}; | ||
#print "$name - $sha\n"; | ||
my $size = $shas->{ $sha }; | ||
if( !$size ) { | ||
print "Could not find size for $sha\n"; | ||
} | ||
$totSize += $size; | ||
} | ||
print "Total size of packages to download: $totSize\n"; | ||
print "Downloading raw brew packages...\n"; | ||
print_progress( 0 ); | ||
|
||
#exit; | ||
|
||
for my $pkg ( @$pkgs ) { | ||
my $name = $pkg->{name}; | ||
my $url = $pkg->{url}; | ||
my $plats = $pkg->{platforms}; | ||
my $sha = $plats->{ $plat } || $plats->{all}; | ||
my $size = $shas->{ $sha }; | ||
#print "$name - $sha\n"; | ||
$dlTot += $size; | ||
ghcr_dl( "$url$sha", "bottle/$name.tar.gz", $curlVersion, $size ); | ||
#delete $plats->{_parent}; | ||
#print Dumper( $plats ); | ||
} | ||
print "\n"; | ||
#print "\nDl tot: $dlTot\n"; | ||
} | ||
|
||
sub get_curl_version { | ||
my $curlInfo = `curl --version`; | ||
my @curlLines = split("\n",$curlInfo); | ||
my $curlVersion = "8.4.0"; | ||
if( $curlLines[0] =~ m/curl ([0-9\.]+)/ ) { | ||
$curlVersion = $1; | ||
} | ||
return $curlVersion; | ||
} | ||
|
||
sub ghcr_dl { | ||
my ( $url, $out, $curlVersion, $size ) = @_; | ||
#my $ua = '--user-agent "Homebrew/4.2.20 (Macintosh; Intel Mac OS X 13.6.4) curl/'.$curlVersion.'"'; | ||
#my $lang = '--header Accept-Language:\\ en'; | ||
#my $auth = '--header "Authorization: Bearer QQ=="'; | ||
#my $fixed = "--disable --cookie /dev/null --globoff --show-error $ua $lang --fail --retry 3 $auth --remote-time"; | ||
|
||
if( ! -e "$out" ) { | ||
#`curl $fixed --location $url -o $out`; | ||
#print " curl $fixed --location $url -o $out\n"; | ||
|
||
#my $fileDone = 0; | ||
#for( my $i=0;$i<5000;$i++ ) { | ||
# $fileDone += 20000; | ||
# last if( $fileDone >= $size ); | ||
# $doneSize += 20000; | ||
# print_progress( int( ($doneSize/$totSize)*100 ) ); | ||
# select(undef, undef, undef, 0.001); | ||
#} | ||
|
||
my $cmd = "./curlprog \"$url\" \"$out\""; | ||
open my $cmdfh, '-|', $cmd; | ||
while( my $line = <$cmdfh> ) { | ||
my $bytes = int( $line ); | ||
if( $bytes ) { | ||
$doneSize += $bytes; | ||
print_progress( int( ($doneSize/$totSize)*100 ) ); | ||
} | ||
else { | ||
print "Line: $line\n"; | ||
} | ||
} | ||
} | ||
} | ||
|
||
sub print_progress { | ||
my ($percent) = @_; | ||
return if( $percent == $lastPercent ); | ||
$percent *= 1.08; | ||
$percent = 100 if( $percent > 100 ); | ||
my $num_blocks = int($percent / 2); | ||
my $bar = '[' . '=' x $num_blocks . ' ' x (50 - $num_blocks) . ']'; | ||
printf("\r%s %3d%%", $bar, $percent); | ||
STDOUT->flush(); # Flush the output buffer to update the display immediately | ||
$lastPercent = $percent; | ||
} | ||
|
||
sub read_file { | ||
my $fn = shift; | ||
open my $fh, '<', $fn or return ""; | ||
my $data = do { local $/; <$fh> }; | ||
close( $fh ); | ||
return $data; | ||
} |
Oops, something went wrong.