33#include <libFreeWRL.h>
57#include "main/ProdCon.h"
58#if !defined(IPHONE) && !defined(_ANDROID)
59#include "input/InputFunctions.h"
60#include "plugin/pluginUtils.h"
61#include "plugin/PluginSocket.h"
65#if defined (INCLUDE_STL_FILES)
66#include "input/convertSTL.h"
69#define UNUSED(v) ((void) v)
72void append_openned_file(
s_list_t *list,
const char *filename,
int fd,
char *text);
74int inputFileType = IS_TYPE_UNKNOWN;
75int inputFileVersion[3] = {0,0,0};
78int fw_mkdir(
const char* path){
82 return mkdir(path,0755);
89char* concat_path(
const char *a,
const char *b)
98 tmp = MALLOC(
char *, 2+lb);
99 sprintf(tmp,
"/%s", b);
105 tmp = MALLOC(
char *, la+2);
106 sprintf(tmp,
"%s/", a);
114 if (a[la-1] ==
'/') {
115 tmp = MALLOC(
char *, la + lb + 1);
116 sprintf(tmp,
"%s%s", a, b);
118 tmp = MALLOC(
char *, la + lb + 2);
119 sprintf(tmp,
"%s/%s", a, b);
128char* remove_filename_from_path(
const char *path)
133 slash = strrchr(path,
'/');
136printf (
"remove_filename_from_path going to copy %d\n", ((
int)slash-(
int)path)+1);
137 rv = strndup(path, ((
int)slash-(
int)path)+1);
139 slash = strrchr(rv,
'/');
141printf (
"remove_filename_from_path, returning :%s:\n",rv);
143 rv = STRNDUP(path, (
size_t)slash - (
size_t)path + 1);
149char *strBackslash2fore(
char *str)
153 for( jj=0;jj<(int)strlen(str);jj++)
154 if(str[jj] ==
'\\' ) str[jj] =
'/';
159char *get_current_dir()
162 cwd = MALLOC(
char *, PATH_MAX);
163 retvar = getcwd(cwd, PATH_MAX);
164 if (NULL != retvar) {
167 cwd = strBackslash2fore(cwd);
171 printf(
"Unable to establish current working directory in %s,%d errno=%d",__FILE__,__LINE__,errno) ;
192bool do_file_exists(
const char *filename)
195 if (stat(filename, &ss) == 0) {
204bool do_file_readable(
const char *filename)
206 if (access(filename, R_OK) == 0) {
216bool do_dir_exists(
const char *dir)
224 if (stat(dir, &ss) == 0) {
225 if (access(dir,X_OK) == 0) {
228 WARN_MSG(
"directory '%s' exists but is not accessible\n", dir);
240 static char first_ten[11];
242 int len = of->fileDataSize;
244 memcpy(first_ten, of->fileData, len);
246 printf(
"{%s, %d, %d, %s%s}\n", of->fileFileName, of->fileDescriptor, of->fileDataSize, (of->fileData ? first_ten :
"(null)"), (of->fileData ?
"..." :
""));
254static openned_file_t* create_openned_file(
const char *filename,
int fd,
int dataSize,
char *data,
int imageHeight,
int imageWidth,
bool imageAlpha)
258 char *fileData = NULL;
259 if (dataSize > 0 && data)
261 fileData = MALLOC (
char *, dataSize+1);
262 if (NULL != fileData)
264 memcpy (fileData, data, dataSize);
265 fileData[dataSize] =
'\0';
271 of->fileFileName = filename;
272 of->fileDescriptor = fd;
274 of->fileDataSize = dataSize;
275 of->imageHeight = imageHeight;
276 of->imageWidth = imageWidth;
277 of->imageAlpha = imageAlpha;
288#if defined(FW_USE_MMAP)
289static void* load_file_mmap(
const char *filename)
295 if (stat(filename, &ss) < 0) {
296 PERROR_MSG(
"load_file_mmap: could not stat: %s\n", filename);
299 fd = open(filename, O_RDONLY | O_NONBLOCK);
301 PERROR_MSG(
"load_file_mmap: could not open: %s\n", filename);
305 ERROR_MSG(
"load_file_mmap: file is empty %s\n", filename);
309 text = mmap(NULL, ss.st_size, PROT_READ, MAP_SHARED, fd, 0);
310 if ((text == MAP_FAILED) || (!text)) {
311 PERROR_MSG(
"load_file_mmap: could not mmap: %s\n", filename);
315 return create_openned_file(filename, fd, text,0,0,FALSE);
323 int load_file_blob(
const char *filename,
char **blob,
int *len){
326 char *text, *current;
329 size_t blocksz, readsz;
331 ssize_t blocksz, readsz;
334 if (stat(filename, &ss) < 0) {
335 PERROR_MSG(
"load_file_read: could not stat: %s\n", filename);
339 fd = open(filename, O_RDONLY | O_BINARY);
341 fd = open(filename, O_RDONLY | O_NONBLOCK);
344 PERROR_MSG(
"load_file_read: could not open: %s\n", filename);
348 ERROR_MSG(
"load_file_read: file is empty %s\n", filename);
353 text = current = MALLOC(
char *, ss.st_size +1);
355 ERROR_MSG(
"load_file_read: cannot allocate memory to read file %s\n", filename);
360 if (ss.st_size > SSIZE_MAX) {
364 blocksz = ss.st_size+1;
367 left2read = ss.st_size;
370 while (left2read > 0) {
371 readsz = read(fd, current, blocksz);
375 left2read -= blocksz;
383 PERROR_MSG(
"load_file_read: error reading file %s\n", filename);
392 text[ss.st_size] =
'\0';
404 if( load_file_blob(filename, &blob, &len))
406 retval = create_openned_file(filename, 0, len, blob,0,0,FALSE);
411OLDCODEstatic
openned_file_t* load_file_read_old(
const char *filename)
413OLDCODE
struct stat ss;
415OLDCODE
unsigned char *text, *current;
416OLDCODE
int left2read;
417OLDCODE#ifdef _MSC_VER
418OLDCODE
size_t blocksz, readsz;
420OLDCODE ssize_t blocksz, readsz;
423OLDCODE
if (stat(filename, &ss) < 0) {
424OLDCODE PERROR_MSG(
"load_file_read: could not stat: %s\n", filename);
427OLDCODE#ifdef _MSC_VER
428OLDCODE fd = open(filename, O_RDONLY | O_BINARY);
430OLDCODE fd = open(filename, O_RDONLY | O_NONBLOCK);
433OLDCODE PERROR_MSG(
"load_file_read: could not open: %s\n", filename);
436OLDCODE
if (!ss.st_size) {
437OLDCODE ERROR_MSG(
"load_file_read: file is empty %s\n", filename);
442OLDCODE text = current = MALLOC(
unsigned char *, ss.st_size +1);
444OLDCODE ERROR_MSG(
"load_file_read: cannot allocate memory to read file %s\n", filename);
449OLDCODE
if (ss.st_size > SSIZE_MAX) {
451OLDCODE blocksz = SSIZE_MAX;
453OLDCODE blocksz = ss.st_size+1;
456OLDCODE left2read = ss.st_size;
459OLDCODE
while (left2read > 0) {
460OLDCODE readsz = read(fd, current, blocksz);
461OLDCODE
if (readsz > 0) {
463OLDCODE current += blocksz;
464OLDCODE left2read -= blocksz;
467OLDCODE
if (readsz == 0) {
472OLDCODE PERROR_MSG(
"load_file_read: error reading file %s\n", filename);
481OLDCODE text[ss.st_size] =
'\0';
484OLDCODE
return create_openned_file(filename, fd, ss.st_size+1, text,0,0,FALSE);
491char *fwg_frontEndWantsFileName() {
return NULL;}
492void fwg_frontEndReturningData(
char* fileData,
int length,
int width,
int height,
bool hasAlpha) {}
501 if (NULL == filename) {
511 DEBUG_RES(
"loading file: %s pthread %p\n", filename,pthread_self());
515#if defined(FW_USE_MMAP)
516#if !defined(_MSC_VER)
518 of = load_file_mmap(filename);
521 of = load_file_win32_mmap(filename);
525 of = load_file_read(filename);
527 DEBUG_RES(
"%s loading status: %s\n", filename, BOOL_STR((of!=NULL)));
536int determineFileType(
const char *buffer,
const int len)
540 int foundStart = FALSE;
542 for (count = 0; count < 3; count ++) inputFileVersion[count] = 0;
545 if (strncmp((
const char*)buffer,
"<?xml version",12) == 0){
554 while (!foundStart) {
555 while ((*rv !=
'<') && (*rv !=
'\0')) rv++;
558 if (*rv !=
'!') foundStart = TRUE;
559 }
else if (*rv ==
'\0') foundStart = TRUE;
561 if (strncmp((
const char*)rv,
"X3D",3) == 0) {
563 inputFileVersion[0] = 3;
564 return IS_TYPE_XML_X3D;
567#if defined (INCLUDE_NON_WEB3D_FORMATS)
568 if (strncmp((
const char*)rv,
"COLLADA",7) == 0) {
569 return IS_TYPE_COLLADA;
571 if (strncmp((
const char*)rv,
"kml",3) == 0) {
578 if (strncmp((
const char*)buffer,
"#VRML V2.0 utf8",15) == 0) {
579 inputFileVersion[0] = 2;
583 if (strncmp ((
const char*)buffer,
"#X3D",4) == 0) {
584 inputFileVersion[0] = 3;
587 if (strncmp ((
const char*)buffer,
"#X3D V3.0 utf8",14) == 0) {
588 inputFileVersion[1] = 0;
591 if (strncmp ((
const char*)buffer,
"#X3D V3.1 utf8",14) == 0) {
592 inputFileVersion[1] = 1;
595 if (strncmp ((
const char*)buffer,
"#X3D V3.2 utf8",14) == 0) {
596 inputFileVersion[1] = 2;
599 if (strncmp ((
const char*)buffer,
"#X3D V3.3 utf8",14) == 0) {
600 inputFileVersion[1] = 3;
603 if (strncmp ((
const char*)buffer,
"#X3D V4.0 utf8",14) == 0) {
604 inputFileVersion[0] = 4;
605 inputFileVersion[1] = 0;
612 if (strncmp((
const char*)buffer,
"#VRML V1.0 asc",10) == 0) {
613 return IS_TYPE_VRML1;
620 while(rv && *rv !=
'\0'){
621 if(*rv ==
'<')
return IS_TYPE_XML_X3D;
622 if (*rv ==
'{')
return IS_TYPE_VRML;
626 #if defined (INCLUDE_STL_FILES)
627 return stlDTFT((
const unsigned char*)buffer,len);
630 return IS_TYPE_UNKNOWN;
639#if !defined( _MSC_VER) && !defined(_ANDROID) && !defined(ANDROIDNDK) && !defined(IOS)
640int freewrlSystem (
const char *sysline)
646#define MAXEXECPARAMS 10
647#define EXECBUFSIZE 2000
648 char *paramline[MAXEXECPARAMS];
649 char buf[EXECBUFSIZE];
660 memset(paramline, 0,
sizeof(paramline));
663 haveXmessage = !strncmp(sysline, FREEWRL_MESSAGE_WRAPPER, strlen(FREEWRL_MESSAGE_WRAPPER));
668 if (strlen(sysline)>=EXECBUFSIZE)
return FALSE;
669 strcpy (buf,sysline);
676 paramline[0] = FREEWRL_MESSAGE_WRAPPER;
677 paramline[1] = strchr(internbuf,
' ');
681 while (internbuf != NULL) {
683 paramline[count] = internbuf;
684 internbuf = strchr(internbuf,
' ');
685 if (internbuf != NULL) {
691 if (count >= MAXEXECPARAMS)
return -1;
704 waitForChild = FALSE;
707 if (strncmp(paramline[count],
"&",strlen(paramline[count])) == 0) {
709 paramline[count] =
'\0';
728 Xrv = execl((
const char *)paramline[0],
729 (
const char *)paramline[0],paramline[1], paramline[2],
730 paramline[3],paramline[4],paramline[5],
731 paramline[6],paramline[7], NULL);
732 printf (
"FreeWRL: Fatal problem execing %s\n",paramline[0]);
749 waitpid(child, &pidStatus, 0);
759 return (WIFEXITED(pidStatus) == TRUE);
761 printf (
"System call failed :%s:\n",sysline);
766#elif defined(_MSC_VER)
767int freewrlSystem (
const char *sysline)
769 return system(sysline);
777static TCHAR *singleDot = L
".";
778static TCHAR *doubleDot = L
"..";
779static TCHAR *backslash = L
"\\";
780static TCHAR *star = L
"*";
783static TCHAR *singleDot =
".";
784static TCHAR *doubleDot =
"..";
785static TCHAR *backslash =
"\\";
786static TCHAR *star =
"*";
790BOOL IsDots(
const TCHAR* str) {
791 if(_tcscmp(str,singleDot) && _tcscmp(str,doubleDot))
795BOOL DeleteDirectory0(
const TCHAR* sPath) {
797 WIN32_FIND_DATA FindFileData;
798 TCHAR DirPath[MAX_PATH];
799 TCHAR FileName[MAX_PATH];
802 _tcscpy(DirPath,sPath);
803 _tcscat(DirPath,backslash);
804 _tcscat(DirPath,star);
805 _tcscpy(FileName,sPath);
806 _tcscat(FileName,backslash);
809 hFind = FindFirstFileEx(DirPath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);
812 hFind = FindFirstFile(DirPath,&FindFileData);
814 if(hFind == INVALID_HANDLE_VALUE)
816 _tcscpy(DirPath,FileName);
820 if(FindNextFile(hFind,&FindFileData)) {
821 if(IsDots(FindFileData.cFileName))
continue;
822 _tcscat(FileName,FindFileData.cFileName);
823 if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
825 if(!DeleteDirectory0(FileName)) {
829 RemoveDirectory(FileName);
830 _tcscpy(FileName,DirPath);
833 if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
834 _tchmod(FileName, 777);
835 if(!DeleteFile(FileName)) {
850 _tcscpy(FileName,DirPath);
854 if(GetLastError() == ERROR_NO_MORE_FILES)
864 return RemoveDirectory(sPath);
867BOOL tdirectory_remove_all(TCHAR *sPath){
869 retval = DeleteDirectory0(sPath);
872void tremove_file_or_folder(TCHAR *path){
877 WIN32_FILE_ATTRIBUTE_DATA fad;
878 finfo = GetFileAttributesEx(path, GetFileExInfoStandard, &fad);
881 err = GetLastError();
883 ConsoleMessage(
"GetFileAttribuesEx err=%d maxpath%d pathlen%d", (
int)err,MAX_PATH,_tcslen(path));
884 isDir = ! _tcsstr(path, singleDot);
887 isDir = finfo && (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
891 finfo = GetFileAttributes(path);
892 isDir = FILE_ATTRIBUTE_DIRECTORY & finfo;
895 tdirectory_remove_all(path);
899void remove_file_or_folder(
const char *path){
905 size_t convertedChars = 0;
906 TCHAR wcstring[MAX_PATH];
907 char fname2[MAX_PATH];
910 origsize = strlen(path) + 1;
912 for(jj=0;jj<(int)strlen(fname2);jj++)
913 if(fname2[jj] ==
'/' ) fname2[jj] =
'\\';
917 mbstowcs_s(&convertedChars, wcstring, origsize, fname2, _TRUNCATE);
919 mbstowcs(wcstring, fname2, MB_CUR_MAX);
922 _tcscpy(wcstring,fname2);
924 tremove_file_or_folder(wcstring);
929int directory_remove_all(
const char *path)
931 DIR *d = opendir(path);
932 size_t path_len = strlen(path);
940 while (!r && (p=readdir(d)))
947 if (!strcmp(p->d_name,
".") || !strcmp(p->d_name,
".."))
951 len = path_len + strlen(p->d_name) + 2;
952 buf = MALLOC(
void *, len);
956 snprintf(buf, len,
"%s/%s", path, p->d_name);
957 if (!stat(buf, &statbuf))
959 if (S_ISDIR(statbuf.st_mode))
961 r2 = directory_remove_all(buf);
980void remove_file_or_folder(
const char * path){
982 if (!stat(path, &statbuf))
987 if (S_ISDIR(statbuf.st_mode))
989 r2 = directory_remove_all(path);
1004#define WRITEBUFFERSIZE (8192)
1007int unzip_archive_to_temp_folder(
const char *zipfilename,
const char* tempfolderpath)
1010 const char *filename_to_extract=NULL;
1012 const char *dirname=NULL;
1014 char *fullpath = NULL;
1017 uf = unzOpen(zipfilename);
1020 printf(
"Cannot open %s \n",zipfilename);
1023 printf(
"%s opened\n",zipfilename);
1026 fw_mkdir(tempfolderpath);
1035 err = unzGetGlobalInfo(uf,&gi);
1037 printf(
"error %d with zipfile in unzGetGlobalInfo \n",err);
1041 for (i=0;i<gi.number_entry;i++)
1044 char filename_inzip[256];
1045 char* filename_withoutpath;
1054 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,
sizeof(filename_inzip),NULL,0,NULL,0);
1058 printf(
"error %d with zipfile in unzGetCurrentFileInfo\n",err);
1062 size_buf = WRITEBUFFERSIZE;
1063 buf = (
void*)MALLOC(
void *, size_buf);
1066 printf(
"Error allocating memory\n");
1067 return UNZ_INTERNALERROR;
1070 p = filename_withoutpath = filename_inzip;
1071 while ((*p) !=
'\0')
1073 if (((*p)==
'/') || ((*p)==
'\\'))
1074 filename_withoutpath = p+1;
1078 if ((*filename_withoutpath)==
'\0')
1080 printf(
"creating directory: %s\n",filename_inzip);
1081 strcpy(temppath,tempfolderpath);
1082 strcat(temppath,
"/");
1083 strcat(temppath,filename_inzip);
1089 const char* write_filename;
1092 write_filename = filename_inzip;
1094 err = unzOpenCurrentFile(uf);
1097 printf(
"error %d with zipfile in unzOpenCurrentFile\n",err);
1102 strcpy(temppath,tempfolderpath);
1103 strcat(temppath,
"/");
1104 strcat(temppath,write_filename);
1106 fout=fopen(temppath,
"wb");
1111 printf(
" extracting: %s\n",write_filename);
1115 err = unzReadCurrentFile(uf,buf,size_buf);
1118 printf(
"error %d with zipfile in unzReadCurrentFile\n",err);
1122 if (fwrite(buf,err,1,fout)!=1)
1124 printf(
"error in writing extracted file\n");
1137 err = unzCloseCurrentFile (uf);
1140 printf(
"error %d with zipfile in unzCloseCurrentFile\n",err);
1144 unzCloseCurrentFile(uf);
1151 if ((i+1)<gi.number_entry)
1153 err = unzGoToNextFile(uf);
1156 printf(
"error %d with zipfile in unzGoToNextFile\n",err);
1168char* remove_filename_from_path(
const char *path);
1169char *strBackslash2fore(
char *str);
1170void resitem_enqueue(
s_list_t *item);
1174 char* tempfolderpath;
1176 tempfolderpath = TEMPNAM(gglobal()->Mainloop.tmpFileLocation,
"freewrl_download_XXXXXXXX");
1179 tempfolderpath = STRDUP(res->URLrequest);
1180 tempfolderpath = strBackslash2fore(tempfolderpath);
1181 tempfolderpath = remove_filename_from_path(tempfolderpath);
1182 tempfolderpath = TEMPNAM(tempfolderpath,
"freewrl_download_XXXXXXXX");
1184 err = unzip_archive_to_temp_folder(res->actual_file, tempfolderpath);
1188 strcpy(request,tempfolderpath);
1189 strcat(request,
"/doc.x3d");
1190 docx3d = resource_create_single(request);
1191 docx3d->parent = NULL;
1192 docx3d->type = rest_file;
1193 docx3d->media_type = resm_x3d;
1194 docx3d->treat_as_root = 1;
1196 resitem_enqueue(ml_new(docx3d));
1198 res->cached_files = ml_append(res->cached_files,ml_new(tempfolderpath));
1199 ConsoleMessage(
"unzip folder:%s\n", tempfolderpath);
1202 ConsoleMessage(
"unzip failed to folder:%s\n", tempfolderpath);
1214 file2blob_task_chain,
1215 file2blob_task_spawn,
1216 file2blob_task_enqueue,
1217} file2blob_task_tactic2;
1219void resource_remove_cached_file(
s_list_t *cfe);
1227 if(res->media_type != resm_x3z){
1228 cf = (
s_list_t *)res->cached_files;
1230 ml_foreach(cf, resource_remove_cached_file(__l));
1232 ml_foreach(cf, ml_free(__l));
1233 res->cached_files = NULL;
1238int file2blob(
void *resp){
1243 if(res->media_type == resm_image){
1245 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1247 retval = imagery_load(res);
1248 }
else if(res->media_type == resm_movie){
1249 retval = movie_load(res);
1251 retval = resource_load(res);
1253 delete_temp_file(res);
1256int async_thread_count = 0;
1257static void *thread_load_async (
void *args){
1260 async_thread_count++;
1261 printf(
"[%d]",async_thread_count);
1262 loaded = file2blob(res);
1265 resitem_enqueue_tg(ml_new(res),res->tg);
1266 async_thread_count--;
1270 if(!res->_loadThread) res->_loadThread = malloc(
sizeof(pthread_t));
1271 pthread_create ((pthread_t*)res->_loadThread, NULL,&thread_load_async, (
void *)res);
1273void file2blob_task(
s_list_t *item){
1276 int tactic = file2blob_task_enqueue;
1277 if(tactic == file2blob_task_chain){
1279 if(res->media_type == resm_image){
1281 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1288 delete_temp_file(res);
1289 resitem_enqueue(item);
1290 }
else if(tactic == file2blob_task_enqueue){
1293 res->_loadFunc = (int(*)(
void*))file2blob;
1296 resitem_enqueue(item);
1297 }
else if(tactic == file2blob_task_spawn){