diff options
author | Sam Bingner <sam@bingner.com> | 2018-12-07 13:01:05 -1000 |
---|---|---|
committer | Sam Bingner <sam@bingner.com> | 2018-12-07 13:01:05 -1000 |
commit | dabe8669a56fca398da9a7dd117eb74f874cddc0 (patch) | |
tree | 1e9f41f484e72a02652b600498a7b09aee62b7e6 /data/_apt7/cfnetwork.diff | |
parent | bae6eae573376ebc0e942e88c4f6eaea9b0f1574 (diff) |
Update to use libapt instead of apt7-lib for apt1.4+ and add apt-rdepends
Diffstat (limited to 'data/_apt7/cfnetwork.diff')
-rw-r--r-- | data/_apt7/cfnetwork.diff | 703 |
1 files changed, 703 insertions, 0 deletions
diff --git a/data/_apt7/cfnetwork.diff b/data/_apt7/cfnetwork.diff new file mode 100644 index 000000000..f6d609521 --- /dev/null +++ b/data/_apt7/cfnetwork.diff @@ -0,0 +1,703 @@ +diff -ru apt-0.7.25.3/methods/http.cc apt-0.7.25.3+iPhone/methods/http.cc +--- apt-0.7.25.3/methods/http.cc 2010-02-01 19:44:41.000000000 +0000 ++++ apt-0.7.25.3+iPhone/methods/http.cc 2010-02-22 20:20:42.000000000 +0000 +@@ -31,6 +31,7 @@ + #include <apt-pkg/hashes.h> + #include <apt-pkg/netrc.h> + ++#include <sys/sysctl.h> + #include <sys/stat.h> + #include <sys/time.h> + #include <utime.h> +@@ -41,11 +42,20 @@ + #include <string.h> + #include <iostream> + #include <map> ++#include <set> + #include <apti18n.h> + + + // Internet stuff + #include <netdb.h> ++#include <arpa/inet.h> ++ ++#include <dlfcn.h> ++#include <lockdown.h> ++#include <CoreFoundation/CoreFoundation.h> ++#include <CoreServices/CoreServices.h> ++#include <CFNetwork/CFNetwork.h> ++#include <SystemConfiguration/SystemConfiguration.h> + + #include "config.h" + #include "connect.h" +@@ -54,6 +62,51 @@ + /*}}}*/ + using namespace std; + ++CFStringRef Firmware_; ++const char *Machine_; ++CFStringRef UniqueID_; ++ ++void CfrsError(const char *name, CFReadStreamRef rs) { ++ CFStreamError se = CFReadStreamGetError(rs); ++ ++ if (se.domain == kCFStreamErrorDomainCustom) { ++ } else if (se.domain == kCFStreamErrorDomainPOSIX) { ++ _error->Error("POSIX: %s", strerror(se.error)); ++ } else if (se.domain == kCFStreamErrorDomainMacOSStatus) { ++ _error->Error("MacOSStatus: %ld", se.error); ++ } else if (se.domain == kCFStreamErrorDomainNetDB) { ++ _error->Error("NetDB: %s %s", name, gai_strerror(se.error)); ++ } else if (se.domain == kCFStreamErrorDomainMach) { ++ _error->Error("Mach: %ld", se.error); ++ } else if (se.domain == kCFStreamErrorDomainHTTP) { ++ switch (se.error) { ++ case kCFStreamErrorHTTPParseFailure: ++ _error->Error("Parse failure"); ++ break; ++ ++ case kCFStreamErrorHTTPRedirectionLoop: ++ _error->Error("Redirection loop"); ++ break; ++ ++ case kCFStreamErrorHTTPBadURL: ++ _error->Error("Bad URL"); ++ break; ++ ++ default: ++ _error->Error("Unknown HTTP error: %ld", se.error); ++ break; ++ } ++ } else if (se.domain == kCFStreamErrorDomainSOCKS) { ++ _error->Error("SOCKS: %ld", se.error); ++ } else if (se.domain == kCFStreamErrorDomainSystemConfiguration) { ++ _error->Error("SystemConfiguration: %ld", se.error); ++ } else if (se.domain == kCFStreamErrorDomainSSL) { ++ _error->Error("SSL: %ld", se.error); ++ } else { ++ _error->Error("Domain #%ld: %ld", se.domain, se.error); ++ } ++} ++ + string HttpMethod::FailFile; + int HttpMethod::FailFd = -1; + time_t HttpMethod::FailTime = 0; +@@ -646,6 +699,51 @@ + } + /*}}}*/ + ++static const CFOptionFlags kNetworkEvents = ++ kCFStreamEventOpenCompleted | ++ kCFStreamEventHasBytesAvailable | ++ kCFStreamEventEndEncountered | ++ kCFStreamEventErrorOccurred | ++0; ++ ++static void CFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType event, void *arg) { ++ switch (event) { ++ case kCFStreamEventOpenCompleted: ++ break; ++ ++ case kCFStreamEventHasBytesAvailable: ++ case kCFStreamEventEndEncountered: ++ *reinterpret_cast<int *>(arg) = 1; ++ CFRunLoopStop(CFRunLoopGetCurrent()); ++ break; ++ ++ case kCFStreamEventErrorOccurred: ++ *reinterpret_cast<int *>(arg) = -1; ++ CFRunLoopStop(CFRunLoopGetCurrent()); ++ break; ++ } ++} ++ ++/* http://lists.apple.com/archives/Macnetworkprog/2006/Apr/msg00014.html */ ++int CFReadStreamOpen(CFReadStreamRef stream, double timeout) { ++ CFStreamClientContext context; ++ int value(0); ++ ++ memset(&context, 0, sizeof(context)); ++ context.info = &value; ++ ++ if (CFReadStreamSetClient(stream, kNetworkEvents, CFReadStreamCallback, &context)) { ++ CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); ++ if (CFReadStreamOpen(stream)) ++ CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeout, false); ++ else ++ value = -1; ++ CFReadStreamSetClient(stream, kCFStreamEventNone, NULL, NULL); ++ } ++ ++ return value; ++} ++ + // HttpMethod::SendReq - Send the HTTP request /*{{{*/ + // --------------------------------------------------------------------- + /* This places the http request in the outbound buffer */ +@@ -1088,6 +1186,8 @@ + signal(SIGINT,SigTerm); + + Server = 0; ++ ++ std::set<std::string> cached; + + int FailCounter = 0; + while (1) +@@ -1107,214 +1207,314 @@ + + if (Queue == 0) + continue; +- +- // Connect to the server +- if (Server == 0 || Server->Comp(Queue->Uri) == false) +- { +- delete Server; +- Server = new ServerState(Queue->Uri,this); +- } +- /* If the server has explicitly said this is the last connection +- then we pre-emptively shut down the pipeline and tear down +- the connection. This will speed up HTTP/1.0 servers a tad +- since we don't have to wait for the close sequence to +- complete */ +- if (Server->Persistent == false) +- Server->Close(); +- +- // Reset the pipeline +- if (Server->ServerFd == -1) +- QueueBack = Queue; +- +- // Connnect to the host +- if (Server->Open() == false) +- { +- Fail(true); +- delete Server; +- Server = 0; +- continue; ++ ++ CFStringEncoding se = kCFStringEncodingUTF8; ++ ++ char *url = strdup(Queue->Uri.c_str()); ++ url: ++ URI uri = std::string(url); ++ std::string hs = uri.Host; ++ ++ if (cached.find(hs) != cached.end()) { ++ _error->Error("Cached Failure"); ++ Fail(true); ++ free(url); ++ FailCounter = 0; ++ continue; ++ } ++ ++ std::string urs = uri; ++ ++ for (;;) { ++ size_t bad = urs.find_first_of("+"); ++ if (bad == std::string::npos) ++ break; ++ // XXX: generalize ++ urs = urs.substr(0, bad) + "%2b" + urs.substr(bad + 1); + } + +- // Fill the pipeline. +- Fetch(0); +- +- // Fetch the next URL header data from the server. +- switch (Server->RunHeaders()) +- { +- case 0: +- break; +- +- // The header data is bad +- case 2: +- { +- _error->Error(_("Bad header data")); +- Fail(true); +- RotateDNS(); +- continue; +- } +- +- // The server closed a connection during the header get.. +- default: +- case 1: +- { +- FailCounter++; +- _error->Discard(); +- Server->Close(); +- Server->Pipeline = false; +- +- if (FailCounter >= 2) +- { +- Fail(_("Connection failed"),true); +- FailCounter = 0; +- } +- +- RotateDNS(); +- continue; +- } +- }; ++ CFStringRef sr = CFStringCreateWithCString(kCFAllocatorDefault, urs.c_str(), se); ++ CFURLRef ur = CFURLCreateWithString(kCFAllocatorDefault, sr, NULL); ++ CFRelease(sr); ++ CFHTTPMessageRef hm = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), ur, kCFHTTPVersion1_1); ++ CFRelease(ur); ++ ++ struct stat SBuf; ++ if (stat(Queue->DestFile.c_str(), &SBuf) >= 0 && SBuf.st_size > 0) { ++ sr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("bytes=%li-"), (long) SBuf.st_size - 1); ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Range"), sr); ++ CFRelease(sr); ++ ++ sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(SBuf.st_mtime).c_str(), se); ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Range"), sr); ++ CFRelease(sr); ++ ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("no-cache")); ++ } else if (Queue->LastModified != 0) { ++ sr = CFStringCreateWithCString(kCFAllocatorDefault, TimeRFC1123(Queue->LastModified).c_str(), se); ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("If-Modified-Since"), sr); ++ CFRelease(sr); ++ ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("no-cache")); ++ } else ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("Cache-Control"), CFSTR("max-age=0")); ++ ++ if (Firmware_ != NULL) ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Firmware"), Firmware_); ++ ++ sr = CFStringCreateWithCString(kCFAllocatorDefault, Machine_, se); ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Machine"), sr); ++ CFRelease(sr); ++ ++ if (UniqueID_ != NULL) ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Unique-ID"), UniqueID_); ++ ++ CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.592")); ++ ++ CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); ++ CFRelease(hm); ++ ++#define _kCFStreamPropertyReadTimeout CFSTR("_kCFStreamPropertyReadTimeout") ++#define _kCFStreamPropertyWriteTimeout CFSTR("_kCFStreamPropertyWriteTimeout") ++#define _kCFStreamPropertySocketImmediateBufferTimeOut CFSTR("_kCFStreamPropertySocketImmediateBufferTimeOut") ++ ++ /*SInt32 to(TimeOut); ++ CFNumberRef nm(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &to));*/ ++ double to(TimeOut); ++ CFNumberRef nm(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &to)); ++ ++ CFReadStreamSetProperty(rs, _kCFStreamPropertyReadTimeout, nm); ++ CFReadStreamSetProperty(rs, _kCFStreamPropertyWriteTimeout, nm); ++ CFReadStreamSetProperty(rs, _kCFStreamPropertySocketImmediateBufferTimeOut, nm); ++ CFRelease(nm); ++ ++ CFDictionaryRef dr = SCDynamicStoreCopyProxies(NULL); ++ CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPProxy, dr); ++ CFRelease(dr); ++ ++ //CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue); ++ CFReadStreamSetProperty(rs, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); + +- // Decide what to do. + FetchResult Res; ++ CFIndex rd; ++ UInt32 sc; ++ ++ uint8_t data[10240]; ++ size_t offset = 0; ++ ++ Status("Connecting to %s", hs.c_str()); ++ ++ switch (CFReadStreamOpen(rs, to)) { ++ case -1: ++ CfrsError("Open", rs); ++ goto fail; ++ ++ case 0: ++ _error->Error("Host Unreachable"); ++ cached.insert(hs); ++ goto fail; ++ ++ case 1: ++ /* success */ ++ break; ++ ++ fail: ++ Fail(true); ++ goto done; ++ } ++ ++ rd = CFReadStreamRead(rs, data, sizeof(data)); ++ ++ if (rd == -1) { ++ CfrsError(uri.Host.c_str(), rs); ++ cached.insert(hs); ++ Fail(true); ++ goto done; ++ } ++ + Res.Filename = Queue->DestFile; +- switch (DealWithHeaders(Res,Server)) +- { +- // Ok, the file is Open +- case 0: +- { +- URIStart(Res); + +- // Run the data +- bool Result = Server->RunData(); ++ hm = (CFHTTPMessageRef) CFReadStreamCopyProperty(rs, kCFStreamPropertyHTTPResponseHeader); ++ sc = CFHTTPMessageGetResponseStatusCode(hm); ++ ++ if (sc == 301 || sc == 302) { ++ sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Location")); ++ if (sr == NULL) { ++ Fail(); ++ goto done_; ++ } else { ++ size_t ln = CFStringGetLength(sr) + 1; ++ free(url); ++ url = static_cast<char *>(malloc(ln)); ++ ++ if (!CFStringGetCString(sr, url, ln, se)) { ++ Fail(); ++ goto done_; ++ } ++ ++ CFRelease(sr); ++ goto url; ++ } ++ } ++ ++ sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Range")); ++ if (sr != NULL) { ++ size_t ln = CFStringGetLength(sr) + 1; ++ char cr[ln]; ++ ++ if (!CFStringGetCString(sr, cr, ln, se)) { ++ Fail(); ++ goto done_; ++ } ++ ++ CFRelease(sr); ++ ++ if (sscanf(cr, "bytes %lu-%*u/%lu", &offset, &Res.Size) != 2) { ++ _error->Error(_("The HTTP server sent an invalid Content-Range header")); ++ Fail(); ++ goto done_; ++ } ++ ++ if (offset > Res.Size) { ++ _error->Error(_("This HTTP server has broken range support")); ++ Fail(); ++ goto done_; ++ } ++ } else { ++ sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Content-Length")); ++ if (sr != NULL) { ++ Res.Size = CFStringGetIntValue(sr); ++ CFRelease(sr); ++ } ++ } ++ ++ time(&Res.LastModified); ++ ++ sr = CFHTTPMessageCopyHeaderFieldValue(hm, CFSTR("Last-Modified")); ++ if (sr != NULL) { ++ size_t ln = CFStringGetLength(sr) + 1; ++ char cr[ln]; ++ ++ if (!CFStringGetCString(sr, cr, ln, se)) { ++ Fail(); ++ goto done_; ++ } ++ ++ CFRelease(sr); ++ ++ if (!StrToTime(cr, Res.LastModified)) { ++ _error->Error(_("Unknown date format")); ++ Fail(); ++ goto done_; ++ } ++ } ++ ++ if (sc < 200 || sc >= 300 && sc != 304) { ++ sr = CFHTTPMessageCopyResponseStatusLine(hm); + +- /* If the server is sending back sizeless responses then fill in +- the size now */ ++ size_t ln = CFStringGetLength(sr) + 1; ++ char cr[ln]; ++ ++ if (!CFStringGetCString(sr, cr, ln, se)) { ++ Fail(); ++ goto done; ++ } ++ ++ CFRelease(sr); ++ ++ _error->Error("%s", cr); ++ ++ Fail(); ++ goto done_; ++ } ++ ++ CFRelease(hm); ++ ++ if (sc == 304) { ++ unlink(Queue->DestFile.c_str()); ++ Res.IMSHit = true; ++ Res.LastModified = Queue->LastModified; ++ URIDone(Res); ++ } else { ++ Hashes hash; ++ ++ File = new FileFd(Queue->DestFile, FileFd::WriteAny); ++ if (_error->PendingError() == true) { ++ delete File; ++ File = NULL; ++ Fail(); ++ goto done; ++ } ++ ++ FailFile = Queue->DestFile; ++ FailFile.c_str(); // Make sure we dont do a malloc in the signal handler ++ FailFd = File->Fd(); ++ FailTime = Res.LastModified; ++ ++ Res.ResumePoint = offset; ++ ftruncate(File->Fd(), offset); ++ ++ if (offset != 0) { ++ lseek(File->Fd(), 0, SEEK_SET); ++ if (!hash.AddFD(File->Fd(), offset)) { ++ _error->Errno("read", _("Problem hashing file")); ++ delete File; ++ File = NULL; ++ Fail(); ++ goto done; ++ } ++ } ++ ++ lseek(File->Fd(), 0, SEEK_END); ++ ++ URIStart(Res); ++ ++ read: if (rd == -1) { ++ CfrsError("rd", rs); ++ Fail(true); ++ } else if (rd == 0) { + if (Res.Size == 0) + Res.Size = File->Size(); +- +- // Close the file, destroy the FD object and timestamp it +- FailFd = -1; +- delete File; +- File = 0; +- +- // Timestamp ++ + struct utimbuf UBuf; + time(&UBuf.actime); +- UBuf.actime = Server->Date; +- UBuf.modtime = Server->Date; +- utime(Queue->DestFile.c_str(),&UBuf); ++ UBuf.actime = Res.LastModified; ++ UBuf.modtime = Res.LastModified; ++ utime(Queue->DestFile.c_str(), &UBuf); + +- // Send status to APT +- if (Result == true) +- { +- Res.TakeHashes(*Server->In.Hash); +- URIDone(Res); +- } +- else +- { +- if (Server->ServerFd == -1) +- { +- FailCounter++; +- _error->Discard(); +- Server->Close(); +- +- if (FailCounter >= 2) +- { +- Fail(_("Connection failed"),true); +- FailCounter = 0; +- } +- +- QueueBack = Queue; +- } +- else +- Fail(true); +- } +- break; +- } +- +- // IMS hit +- case 1: +- { ++ Res.TakeHashes(hash); + URIDone(Res); +- break; +- } +- +- // Hard server error, not found or something +- case 3: +- { +- Fail(); +- break; +- } +- +- // Hard internal error, kill the connection and fail +- case 5: +- { +- delete File; +- File = 0; ++ } else { ++ hash.Add(data, rd); + +- Fail(); +- RotateDNS(); +- Server->Close(); +- break; +- } ++ uint8_t *dt = data; ++ while (rd != 0) { ++ int sz = write(File->Fd(), dt, rd); ++ ++ if (sz == -1) { ++ delete File; ++ File = NULL; ++ Fail(); ++ goto done; ++ } + +- // We need to flush the data, the header is like a 404 w/ error text +- case 4: +- { +- Fail(); +- +- // Send to content to dev/null +- File = new FileFd("/dev/null",FileFd::WriteExists); +- Server->RunData(); +- delete File; +- File = 0; +- break; +- } +- +- // Try again with a new URL +- case 6: +- { +- // Clear rest of response if there is content +- if (Server->HaveContent) +- { +- File = new FileFd("/dev/null",FileFd::WriteExists); +- Server->RunData(); +- delete File; +- File = 0; ++ dt += sz; ++ rd -= sz; + } + +- /* Detect redirect loops. No more redirects are allowed +- after the same URI is seen twice in a queue item. */ +- StringVector &R = Redirected[Queue->DestFile]; +- bool StopRedirects = false; +- if (R.size() == 0) +- R.push_back(Queue->Uri); +- else if (R[0] == "STOP" || R.size() > 10) +- StopRedirects = true; +- else +- { +- for (StringVectorIterator I = R.begin(); I != R.end(); I++) +- if (Queue->Uri == *I) +- { +- R[0] = "STOP"; +- break; +- } +- +- R.push_back(Queue->Uri); +- } +- +- if (StopRedirects == false) +- Redirect(NextURI); +- else +- Fail(); +- +- break; ++ rd = CFReadStreamRead(rs, data, sizeof(data)); ++ goto read; + } +- +- default: +- Fail(_("Internal error")); +- break; + } +- ++ ++ goto done; ++ done_: ++ CFRelease(hm); ++ done: ++ CFReadStreamClose(rs); ++ CFRelease(rs); ++ free(url); ++ + FailCounter = 0; + } + +@@ -1330,6 +1530,41 @@ + signal(SIGPIPE, SIG_IGN); + + HttpMethod Mth; ++ ++ size_t size; ++ sysctlbyname("hw.machine", NULL, &size, NULL, 0); ++ char *machine = new char[size]; ++ sysctlbyname("hw.machine", machine, &size, NULL, 0); ++ Machine_ = machine; ++ ++ const char *path = "/System/Library/CoreServices/SystemVersion.plist"; ++ CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (uint8_t *) path, strlen(path), false); ++ ++ CFPropertyListRef plist; { ++ CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); ++ CFReadStreamOpen(stream); ++ plist = CFPropertyListCreateFromStream(kCFAllocatorDefault, stream, 0, kCFPropertyListImmutable, NULL, NULL); ++ CFReadStreamClose(stream); ++ } ++ ++ CFRelease(url); ++ ++ if (plist != NULL) { ++ Firmware_ = (CFStringRef) CFRetain(CFDictionaryGetValue((CFDictionaryRef) plist, CFSTR("ProductVersion"))); ++ CFRelease(plist); ++ } ++ ++ if (UniqueID_ == NULL) ++ if (void *libMobileGestalt = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_GLOBAL | RTLD_LAZY)) ++ if (CFStringRef (*$MGCopyAnswer)(CFStringRef) = (CFStringRef (*)(CFStringRef)) dlsym(libMobileGestalt, "MGCopyAnswer")) ++ UniqueID_ = $MGCopyAnswer(CFSTR("UniqueDeviceID")); ++ ++ if (UniqueID_ == NULL) ++ if (void *lockdown = lockdown_connect()) { ++ UniqueID_ = (CFStringRef)lockdown_copy_value(lockdown, NULL, kLockdownUniqueDeviceIDKey); ++ lockdown_disconnect(lockdown); ++ } ++ + return Mth.Loop(); + } + +diff -ru apt-0.7.25.3/methods/makefile apt-0.7.25.3+iPhone/methods/makefile +--- apt-0.7.25.3/methods/makefile 2010-02-01 19:44:41.000000000 +0000 ++++ apt-0.7.25.3+iPhone/methods/makefile 2010-02-22 20:14:29.000000000 +0000 +@@ -46,7 +46,7 @@ + + # The http method + PROGRAM=http +-SLIBS = -lapt-pkg $(SOCKETLIBS) $(INTLLIBS) ++SLIBS = -lapt-pkg $(SOCKETLIBS) $(INTLLIBS) -framework CoreFoundation -framework CFNetwork -framework SystemConfiguration -framework IOKit -llockdown + LIB_MAKES = apt-pkg/makefile + SOURCE = http.cc rfc2553emu.cc connect.cc + include $(PROGRAM_H) |