From acbc714acbaf253bf121a217a755089c74c7f01b Mon Sep 17 00:00:00 2001 From: Jay Freeman Date: Wed, 22 Apr 2009 01:03:34 +0000 Subject: The beginning of the future: futzing with APT. git-svn-id: http://svn.telesphoreo.org/trunk@601 514c082c-b64e-11dc-b46d-3d985efe055d --- data/apt/cfnetwork.diff | 655 ------------------------------------------------ 1 file changed, 655 deletions(-) delete mode 100644 data/apt/cfnetwork.diff (limited to 'data/apt/cfnetwork.diff') diff --git a/data/apt/cfnetwork.diff b/data/apt/cfnetwork.diff deleted file mode 100644 index 7da0635a0..000000000 --- a/data/apt/cfnetwork.diff +++ /dev/null @@ -1,655 +0,0 @@ -diff -ru apt-0.7.20.2/methods/http.cc apt-0.7.20.2+iPhone/methods/http.cc ---- apt-0.7.20.2/methods/http.cc 2009-02-07 15:09:35.000000000 +0000 -+++ apt-0.7.20.2+iPhone/methods/http.cc 2009-04-14 16:34:31.000000000 +0000 -@@ -30,6 +30,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -40,9 +41,16 @@ - #include - #include - #include -+#include - - // Internet stuff - #include -+#include -+ -+#include -+#include -+#include -+#include - - #include "config.h" - #include "connect.h" -@@ -52,6 +60,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; -@@ -632,6 +685,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(arg) = 1; -+ CFRunLoopStop(CFRunLoopGetCurrent()); -+ break; -+ -+ case kCFStreamEventErrorOccurred: -+ *reinterpret_cast(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 */ -@@ -1043,6 +1141,8 @@ - signal(SIGINT,SigTerm); - - Server = 0; -+ -+ std::set cached; - - int FailCounter = 0; - while (1) -@@ -1063,173 +1163,313 @@ - 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; - -- // 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; -- } -- }; -+ 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); -+ } -+ -+ 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 the server is sending back sizeless responses then fill in -- the size now */ -+ 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(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); -+ -+ 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; -+ } -+ -+ dt += sz; -+ rd -= sz; -+ } -+ -+ rd = CFReadStreamRead(rs, data, sizeof(data)); -+ goto read; -+ } -+ } -+ -+ goto done; -+ done_: -+ CFRelease(hm); -+ done: -+ CFReadStreamClose(rs); -+ CFRelease(rs); -+ free(url); - -- // 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; -- } -- -- default: -- Fail(_("Internal error")); -- break; -- } -- - FailCounter = 0; - } - -@@ -1242,6 +1482,34 @@ - setlocale(LC_ALL, ""); - - 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 (void *lockdown = lockdown_connect()) { -+ UniqueID_ = lockdown_copy_value(lockdown, NULL, kLockdownUniqueDeviceIDKey); -+ lockdown_disconnect(lockdown); -+ } - - return Mth.Loop(); - } -diff -ru apt-0.7.20.2/methods/makefile apt-0.7.20.2+iPhone/methods/makefile ---- apt-0.7.20.2/methods/makefile 2009-02-07 15:09:35.000000000 +0000 -+++ apt-0.7.20.2+iPhone/methods/makefile 2009-04-14 16:18:18.000000000 +0000 -@@ -47,7 +47,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) -- cgit v1.2.3