AbstractFSProvider::status_t ZIPProvider::makeDirRecursive(const FileName & url) { if(isDir(url)) { return AbstractFSProvider::OK; } std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); const std::string path = file.getPath(); // Split path into directory components size_t pos = 0; while(pos != path.size()) { pos = path.find('/', pos); if(pos == std::string::npos) { break; } const std::string subPath = path.substr(0, pos + 1); ++pos; if(makeDir(FileName(archiveFileName + '$' + subPath)) != AbstractFSProvider::OK) { return AbstractFSProvider::FAILURE; } } return AbstractFSProvider::OK; }
AbstractFSProvider::status_t ZIPProvider::writeFile(const FileName & url, const std::vector<uint8_t> & data, bool overwrite) { std::lock_guard<std::mutex> lock(handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName, true); if (handle == nullptr) { return FAILURE; } return handle->writeFile(file, data, overwrite); }
AbstractFSProvider::status_t ZIPProvider::makeDir(const FileName & url) { if(isDir(url)) { return AbstractFSProvider::OK; } std::lock_guard<std::mutex> lock(handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName, true); if (handle == nullptr) { return FAILURE; } return handle->makeDir(file); }
AbstractFSProvider::status_t ZIPProvider::makeDir(const FileName & url) { if(isDir(url)) { return AbstractFSProvider::OK; } auto lock = Concurrency::createLock(*handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName, true); if (handle == nullptr) { return FAILURE; } return handle->makeDir(file); }
size_t ZIPProvider::fileSize(const FileName & url) { std::lock_guard<std::mutex> lock(handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName); if (handle == nullptr) { return 0; } // Make sure all data has been written. if (handle->isChanged()) { delete handle; openHandles.erase(archiveFileName); handle = getZIPHandle(archiveFileName); } return handle->fileSize(file); }
AbstractFSProvider::status_t ZIPProvider::readFile(const FileName & url, std::vector<uint8_t> & data) { std::lock_guard<std::mutex> lock(handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName); if (handle == nullptr) { return FAILURE; } // Make sure all data has been written. if (handle->isChanged()) { delete handle; openHandles.erase(archiveFileName); handle = getZIPHandle(archiveFileName); } return handle->readFile(file, data); }
AbstractFSProvider::status_t ZIPProvider::remove(const FileName & url) { auto lock = Concurrency::createLock(*handlesMutex); std::string archiveFileName; FileName file; decomposeURL(url, archiveFileName, file); ZIPHandle * handle = getZIPHandle(archiveFileName); if (handle == nullptr) { return FAILURE; } // Make sure all data has been written. if (handle->isChanged()) { delete handle; openHandles.erase(archiveFileName); handle = getZIPHandle(archiveFileName); } return handle->removeDir(file); }
AbstractFSProvider::status_t ZIPProvider::dir(const FileName & url, std::list< FileName> & result, uint8_t flags) { std::lock_guard<std::mutex> lock(handlesMutex); std::string archiveFileName; FileName localPath; decomposeURL(url, archiveFileName, localPath); ZIPHandle * handle = getZIPHandle(archiveFileName); if (handle == nullptr) { return FAILURE; } // Make sure all data has been written. if (handle->isChanged()) { delete handle; openHandles.erase(archiveFileName); handle = getZIPHandle(archiveFileName); } if (handle == nullptr) { return OK; } return handle->dir(localPath.getDir(), result, flags); }
void createConnection (URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext) { closeSocket(); uint32 timeOutTime = Time::getMillisecondCounter(); if (timeOutMs == 0) timeOutTime += 60000; else if (timeOutMs < 0) timeOutTime = 0xffffffff; else timeOutTime += timeOutMs; String hostName, hostPath; int hostPort; if (! decomposeURL (address, hostName, hostPath, hostPort)) return; String serverName, proxyName, proxyPath; int proxyPort = 0; int port = 0; const String proxyURL (getenv ("http_proxy")); if (proxyURL.startsWithIgnoreCase ("http://")) { if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort)) return; serverName = proxyName; port = proxyPort; } else { serverName = hostName; port = hostPort; } struct addrinfo hints = { 0 }; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; struct addrinfo* result = nullptr; if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == 0) return; socketHandle = socket (result->ai_family, result->ai_socktype, 0); if (socketHandle == -1) { freeaddrinfo (result); return; } int receiveBufferSize = 16384; setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize)); setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0); #if JUCE_MAC setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0); #endif if (connect (socketHandle, result->ai_addr, result->ai_addrlen) == -1) { closeSocket(); freeaddrinfo (result); return; } freeaddrinfo (result); { const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort, proxyName, proxyPort, hostPath, address, headers, postData, isPost)); if (! sendHeader (socketHandle, requestHeader, timeOutTime, progressCallback, progressCallbackContext)) { closeSocket(); return; } } String responseHeader (readResponse (socketHandle, timeOutTime)); if (responseHeader.isNotEmpty()) { headerLines.clear(); headerLines.addLines (responseHeader); const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false) .substring (0, 3).getIntValue(); //int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue(); //bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked"); String location (findHeaderItem (headerLines, "Location:")); if (statusCode >= 300 && statusCode < 400 && location.isNotEmpty()) { if (! location.startsWithIgnoreCase ("http://")) location = "http://" + location; if (++levelsOfRedirection <= 3) { address = location; createConnection (progressCallback, progressCallbackContext); return; } } else { levelsOfRedirection = 0; return; } } closeSocket(); }
static int FtpURLAndTempFile(const char *url,FILE **to,FILE *from) { struct sockaddr_in addr, data_addr; char *host, *filename, *username, *password; int port; FILE *ret; char buffer[300]; int soc, data; int datalen, len; char *databuf, *cmd; if ( from==NULL ) { snprintf(buffer,sizeof(buffer),_("Downloading from %s"), url); *to = NULL; } else snprintf(buffer,sizeof(buffer),_("Uploading to %s"), url); if ( strncasecmp(url,"ftp://",6)!=0 ) { ff_post_error(_("Could not parse URL"),_("Got something else when expecting an ftp URL")); return( false ); } filename = decomposeURL(url, &host, &port, &username, &password); ff_progress_start_indicator(0,_("Font Download..."),buffer, _("Resolving host"),1,1); ff_progress_enable_stop(false); ff_progress_allow_events(); ff_progress_allow_events(); if ( !findFTPhost(&addr, host, port)) { ff_progress_end_indicator(); ff_post_error(_("Could not find host"),_("Could not find \"%s\"\nAre you connected to the internet?"), host ); free( host ); free( filename ); return( false ); } soc = makeConnection(&addr); if ( soc==-1 ) { ff_progress_end_indicator(); ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host ); free( host ); free( filename ); return( false ); } datalen = 8*8*1024; databuf = malloc(datalen+1); cmd = databuf; ChangeLine2_8(_("Logging in...")); if ( getresponse(soc,databuf,datalen) == -1 ) { /* ftp servers say "Hi" when then connect */ ff_progress_end_indicator(); ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host ); free( host ); free( filename ); free(username); free(password); close( soc ); return( false ); } free( host ); if ( username==NULL ) { username=copy("anonymous"); if ( password==NULL ) password=copy("FontForge"); } else if ( password==NULL ) password = copy(""); sprintf(cmd,"USER %s\r\n", username); if ( ftpsendr(soc,cmd,databuf,datalen)== -1 ) { ff_progress_end_indicator(); close( soc ); free(filename); free(databuf); free(username); free(password); return( false ); } sprintf(cmd,"PASS %s\r\n", password); free(username); free(password); if ( ftpsendr(soc,cmd,databuf,datalen)<=0 ) { ff_progress_end_indicator(); LogError(_("Bad Username/Password\n")); close( soc ); free(filename); free(databuf); return( false ); } if ( ftpsendr(soc,"TYPE I\r\n",databuf,datalen)==-1 ) { /* Binary */ ff_progress_end_indicator(); close( soc ); free(filename); free(databuf); return( false ); } if ( from==NULL ) ChangeLine2_8(_("Requesting font...")); else ChangeLine2_8(_("Transmitting font...")); if ( ftpsendpassive(soc,&data_addr,databuf,datalen)<= 0 ) { ff_progress_end_indicator(); close( soc ); free(filename); free(databuf); return( false ); } if (( data = socket(PF_INET,SOCK_STREAM,0))==-1 || connect(data,(struct sockaddr *) &data_addr,sizeof(data_addr))== -1 ) { ff_progress_end_indicator(); if ( data!=-1 ) close(data); close( soc ); free(filename); free(databuf); LogError(_("FTP passive Data Connect failed\n")); return( 0 ); } if ( from==NULL ) { sprintf(cmd,"RETR %s\r\n", filename); if ( ftpsendr(soc,cmd, databuf, datalen)<=0 ) { ff_progress_end_indicator(); ff_post_error(_("Could not download data"),_("Could not find file.") ); close(data); close( soc ); free(filename); free(databuf); return( false ); } ChangeLine2_8(_("Downloading font...")); ret = tmpfile(); while ((len = read(data,databuf,datalen))>0 ) { fwrite(databuf,1,len,ret); } *to = ret; rewind(ret); } else { sprintf(cmd,"STOR %s\r\n", filename); if ( ftpsendr(soc,cmd, databuf, datalen)<=0 ) { ff_progress_end_indicator(); ff_post_error(_("Could not download data"),_("Could not find file.") ); close(data); close( soc ); free(filename); free(databuf); return( false ); } ChangeLine2_8(_("Uploading font...")); rewind(from); while ((len = fread(databuf,1,datalen,from))>0 ) { if ( (len = write(data,databuf,len))<0 ) break; } ret = NULL; } ff_progress_end_indicator(); close( soc ); close( data ); free( databuf ); free( filename ); if ( len==-1 ) { ff_post_error(_("Could not transmit data"),_("Could not transmit data.") ); if ( ret!=NULL ) fclose(ret); return( false ); } return( true ); }
static FILE *HttpURLToTempFile(const char *url, void *_lock) { pthread_mutex_t *lock = _lock; struct sockaddr_in addr; char *pt, *host, *filename, *username, *password; int port; FILE *ret; char buffer[300]; int first, code; int soc; int datalen, len; char *databuf; snprintf(buffer,sizeof(buffer),_("Downloading from %s"), url); if ( strncasecmp(url,"http://",7)!=0 ) { if ( lock!=NULL ) pthread_mutex_lock(lock); ff_post_error(_("Could not parse URL"),_("Got something else when expecting an http URL")); if ( lock!=NULL ) pthread_mutex_unlock(lock); return( NULL ); } if ( lock!=NULL ) pthread_mutex_lock(lock); filename = decomposeURL(url, &host, &port, &username, &password); /* I don't support username/passwords for http */ free( username ); free( password ); if ( lock!=NULL ) pthread_mutex_unlock(lock); if ( lock==NULL ) { ff_progress_start_indicator(0,_("Font Download..."),buffer, _("Resolving host"),1,1); ff_progress_enable_stop(false); ff_progress_allow_events(); ff_progress_allow_events(); } /* This routine contains it's own lock */ if ( !findHTTPhost(&addr, host, port)) { if ( lock==NULL ) ff_progress_end_indicator(); else pthread_mutex_lock(lock); ff_post_error(_("Could not find host"),_("Could not find \"%s\"\nAre you connected to the internet?"), host ); free( host ); free( filename ); if ( lock!=NULL ) pthread_mutex_unlock(lock); return( false ); } soc = makeConnection(&addr); if ( soc==-1 ) { if ( lock==NULL ) ff_progress_end_indicator(); else pthread_mutex_lock(lock); ff_post_error(_("Could not connect to host"),_("Could not connect to \"%s\"."), host ); free( host ); free( filename ); if ( lock!=NULL ) pthread_mutex_unlock(lock); return( false ); } if ( lock!=NULL ) pthread_mutex_lock(lock); datalen = 8*8*1024; databuf = malloc(datalen+1); if ( lock!=NULL ) pthread_mutex_unlock(lock); else ChangeLine2_8(_("Requesting font...")); sprintf( databuf,"GET %s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: FontForge\r\n" "Connection: close\r\n\r\n", filename, host ); if ( write(soc,databuf,strlen(databuf))==-1 ) { if ( lock==NULL ) ff_progress_end_indicator(); if ( lock!=NULL ) pthread_mutex_lock(lock); ff_post_error(_("Could not send request"),_("Could not send request to \"%s\"."), host ); close( soc ); free( databuf ); free( host ); free( filename ); free( host ); free( filename ); if ( lock!=NULL ) pthread_mutex_unlock(lock); return( NULL ); } if ( lock==NULL ) ChangeLine2_8(_("Downloading font...")); if ( lock!=NULL ) pthread_mutex_lock(lock); ret = tmpfile(); if ( lock!=NULL ) pthread_mutex_unlock(lock); first = 1; code = 404; while ((len = read(soc,databuf,datalen))>0 ) { if ( first ) { databuf[len] = '\0'; sscanf(databuf,"HTTP/%*f %d", &code ); first = 0; /* check for redirects */ if ( code>=300 && code<399 && (pt=strstr(databuf,"Location: "))!=NULL ) { char *newurl = pt + strlen("Location: "); pt = strchr(newurl,'\r'); if ( *pt ) *pt = '\0'; close( soc ); if ( lock!=NULL ) pthread_mutex_lock(lock); fclose(ret); free(host); free( filename ); free(databuf); if ( lock!=NULL ) pthread_mutex_unlock(lock); ret = URLToTempFile(newurl,lock); return( ret ); } pt = strstr(databuf,"Content-Length: "); if ( lock==NULL && pt!=NULL ) { pt += strlen( "Content-Length: "); ff_progress_change_total(strtol(pt,NULL,10)); } pt = strstr(databuf,"\r\n\r\n"); if ( pt!=NULL ) { pt += strlen("\r\n\r\n"); fwrite(pt,1,len-(pt-databuf),ret); if ( lock==NULL ) ff_progress_increment(len-(pt-databuf)); } } else { fwrite(databuf,1,len,ret); if ( lock==NULL ) ff_progress_increment(len); } } if ( lock==NULL ) ff_progress_end_indicator(); close( soc ); free( databuf ); if ( lock!=NULL ) pthread_mutex_lock(lock); free( host ); free( filename ); if ( len==-1 ) { ff_post_error(_("Could not download data"),_("Could not download data.") ); fclose(ret); ret = NULL; } else if ( code<200 || code>299 ) { ff_post_error(_("Could not download data"),_("HTTP return code: %d."), code ); fclose(ret); ret = NULL; } else rewind(ret); if ( lock!=NULL ) pthread_mutex_unlock(lock); return( ret ); }