/* ActiveGS, Copyright 2004-2016 Olivier Goguel, https://github.com/ogoguel/ActiveGS Based on Kegs, Copyright 2004 Kent Dickey, https://kegs.sourceforge.net This code is covered by the GNU GPL licence */ #include "../Common.osx/cemulatorctrlmac.h" #include "ActiveDownload.h" #include #include #include "../Common/ki.h" #include "../kegs/Src/sim65816.h" #ifdef DRIVER_IOS #include #include #include #endif #ifdef _DEBUG #define new DEBUG_NEW #endif #define ACTIVEGSDOMAIN kUserDomain MyString homePath; extern const char * activegsdownloaddir; extern const char * activegspersistentdir; #define MAX_PATH 1024 bool CDownload::GetFile( const char *url, const char *filename) { bool bSuccess=false; CFStringRef rawCFString=NULL; CFStringRef normalizedCFString=NULL; CFStringRef escapedCFString=NULL; CFURLRef urlRef=NULL; CFHTTPMessageRef messageRef = NULL; CFReadStreamRef readStreamRef = NULL; #define HTTPBUFLEN 4096 UInt8 httpbuff[HTTPBUFLEN]; CFIndex numbytes ; FILE* f = NULL; int nbread=0; int dwLength = 0 ; int pourcent=0; MyString str; if (filename) showProgress(url,0); if ( strlen( url ) < 12 ) goto Bail; rawCFString = CFStringCreateWithCString( NULL, url, CFStringGetSystemEncoding() ); if ( rawCFString == NULL ) goto Bail; normalizedCFString = CFURLCreateStringByReplacingPercentEscapes( NULL, rawCFString, CFSTR("") ); if ( normalizedCFString == NULL ) goto Bail; escapedCFString = CFURLCreateStringByAddingPercentEscapes( NULL, normalizedCFString, NULL, NULL, kCFStringEncodingUTF8 ); if ( escapedCFString == NULL ) goto Bail; urlRef= CFURLCreateWithString( kCFAllocatorDefault, escapedCFString, NULL ); CFRelease( rawCFString ); CFRelease( normalizedCFString ); CFRelease( escapedCFString ); if ( urlRef == NULL ) { goto Bail; } messageRef = CFHTTPMessageCreateRequest( kCFAllocatorDefault, CFSTR("GET"), urlRef, kCFHTTPVersion1_1 ); if ( messageRef == NULL ) goto Bail; CFRelease(urlRef); urlRef = NULL; // Create the stream for the request. readStreamRef = CFReadStreamCreateForHTTPRequest( kCFAllocatorDefault, messageRef ); if ( readStreamRef == NULL ) goto Bail; if (!CFReadStreamOpen(readStreamRef)) goto Bail; /* tr = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStreamRef, kCFStreamPropertyHTTPResponseHeader); if (tr) { sizeStr = CFHTTPMessageCopyHeaderFieldValue (tr, CFSTR("Content-Length")); if (sizeStr) str = CFStringGetCStringPtr(sizeStr,CFStringGetSystemEncoding()); } */ if (filename) { f =fopen(filename,"wb"); if (!f) { printf("cannot write file %s\n",filename); goto Bail; } } while ( (numbytes = CFReadStreamRead (readStreamRef,httpbuff,HTTPBUFLEN ) ) != 0 ) { /* tr = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStreamRef, kCFStreamPropertyHTTPResponseHeader); if (tr) { dic = CFHTTPMessageCopyAllHeaderFields (tr); char *the_pcKeys[50],*the_pcValues[50]; CFDictionaryGetKeysAndValues(dic, (const void **)&the_pcKeys, (const void **)&the_pcValues); sizeStr = CFHTTPMessageCopyHeaderFieldValue (tr, CFSTR("Content-Length")); if (sizeStr) str = CFStringGetCStringPtr(sizeStr,CFStringGetSystemEncoding()); } */ if (numbytes<0) { // CFErrorRef err = CFReadStreamCopyError (readStreamRef); goto Bail; } nbread+=numbytes; if (f) fwrite(httpbuff,1,numbytes,f); if (dwLength) pourcent = (nbread*100)/dwLength; else pourcent = -nbread ; //(pourcent+5)%100; if (filename) showProgress(url,pourcent); if (r_sim65816.should_emulator_terminate()) { outputInfo("Download aborted (%s)\n",url); goto Bail; } //usleep(2000); } if (nbread) bSuccess=true; { Bail: { if (f) fclose(f); if (filename && !bSuccess) deleteFile(filename); if ( messageRef != NULL ) CFRelease( messageRef ); if ( readStreamRef != NULL ) { //CFReadStreamSetClient( readStreamRef, kCFStreamEventNone, NULL, NULL ); //CFReadStreamUnscheduleFromRunLoop( readStreamRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes ); CFReadStreamClose( readStreamRef ); CFRelease( readStreamRef ); } if ( urlRef != NULL ) CFRelease( urlRef ); } } #ifdef DRIVER_IOS if (!bSuccess && bNotifyDownloadFailure) { extern void x_notify_download_failure(const char*); x_notify_download_failure(url); } #endif return bSuccess; } bool CDownload::retrievePersistentZippedFile(const char* url,int _order,MyString& _path, MyString& _short) { MyString dir = getPersistentDir(url); DIR* pdir = opendir(dir.c_str()); if (!pdir) return false; struct dirent* dp; MyString search; search.Format("%d_",_order); while( (dp=readdir(pdir)) != NULL ) { if (strstr(dp->d_name,search.c_str())==dp->d_name) { _path = dir; _path += ACTIVEGS_DIRECTORY_SEPARATOR ; _path += dp->d_name ; _short = dp->d_name; closedir(pdir); return true; } } closedir(pdir); return false; } void CDownload::deleteFile(const char* _dir) { remove(_dir); } void CDownload::deleteDirectory(const char* _dir,int keepdir) { DIR* pdir = opendir(_dir); if (!pdir) return ; struct dirent* dp; while( (dp=readdir(pdir)) != NULL ) { MyString name=_dir; name+=ACTIVEGS_DIRECTORY_SEPARATOR; name+=dp->d_name; printf("delete file:%s\n",name.c_str()); deleteFile(name.c_str()); } closedir(pdir); if (!keepdir) rmdir(_dir); } void CDownload::createDirectory(const char *_subdir) { #ifdef DRIVER_IOS // rend le chemin absolu if (strstr(_subdir,homePath.c_str())==_subdir) _subdir += homePath.length()+1; MyString fullpath(homePath.c_str()); fullpath+='/'; fullpath+=_subdir; if (mkdir(fullpath.c_str(),0777)) { // printf("cannot create %s\n",fullpath.c_str()); } #else UniChar nameData[1024]; OSStatus err; FSRef domain; // élimine le chemin absolu if (strstr(_subdir,homePath.c_str())==_subdir) _subdir += homePath.length()+1; err = FSFindFolder(kUserDomain, kDomainTopLevelFolderType ,kDontCreateFolder, &domain); const char* file = getfile(_subdir); // cherche le chemin parent if (file!=_subdir) { MyString dir; UniChar ename[1024]; FSRef subdomain; getdir(_subdir,dir); CFStringRef ed = __CFStringMakeConstantString(dir.c_str()); int l = CFStringGetLength(ed); CFStringGetCharacters(ed, CFRangeMake(0, l), ename); err = FSMakeFSRefUnicode (&domain, l, (const UniChar*)ename,0,&subdomain); domain = subdomain; _subdir = file; } CFStringRef sd = __CFStringMakeConstantString(_subdir); int lend = CFStringGetLength(sd); CFStringGetCharacters(sd, CFRangeMake(0, lend), nameData); err = FSCreateDirectoryUnicode(&domain, lend, nameData, 0, NULL, NULL, NULL, NULL); if (err !=0) printf("cannot create %s\n",_subdir); else printf("%s created\n",_subdir); #endif } void CDownload::initPersistentSystemPath(MyString& path) { extern void x_init_persistent_path(MyString& hp); x_init_persistent_path(homePath); if (homePath.GetAt(homePath.GetLength()-1)=='/') { MyString tmp (homePath.Left(homePath.GetLength()-1)); homePath = tmp; } path = homePath; /* CDownload::createDirectory(activegspersistentdir); MyString c; c = activegspersistentdir; c +='/'; c += activegsdownloaddir ; CDownload::createDirectory(c.c_str()); persistentPath = homePath.c_str() ; persistentPath += '/'; persistentPath += activegspersistentdir; printf("mac persistent directory :%s\n",persistentPath.c_str()); // CDownload::setPersistentPath(persistentPath.c_str()); */ } #ifndef DRIVER_IOS void x_init_persistent_path(MyString& hp) { OSStatus err; FSRef homeDir; err = FSFindFolder(ACTIVEGSDOMAIN, kDomainTopLevelFolderType,kDontCreateFolder, &homeDir); CFURLRef url = CFURLCreateFromFSRef (NULL,&homeDir); CFStringRef fullpath = CFURLCopyFileSystemPath (url,kCFURLPOSIXPathStyle); hp = CFStringGetCStringPtr(fullpath,CFStringGetSystemEncoding()); } #endif