33 #include <libFreeWRL.h>
34 #include <resources.h>
52 #define getcwd _getcwd
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"
67 #endif //INCLUDE_STL_FILES
69 #define UNUSED(v) ((void) v)
72 void append_openned_file(
s_list_t *list,
const char *filename,
int fd,
char *text);
74 int inputFileType = IS_TYPE_UNKNOWN;
75 int inputFileVersion[3] = {0,0,0};
78 int fw_mkdir(
const char* path){
82 return mkdir(path,0755);
89 char* 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);
128 char* remove_filename_from_path(
const char *path)
133 slash = strrchr(path,
'/');
136 printf (
"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,
'/');
141 printf (
"remove_filename_from_path, returning :%s:\n",rv);
143 rv = STRNDUP(path, (
size_t)slash - (
size_t)path + 1);
149 char *strBackslash2fore(
char *str)
153 for( jj=0;jj<(int)strlen(str);jj++)
154 if(str[jj] ==
'\\' ) str[jj] =
'/';
159 char *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) ;
192 bool do_file_exists(
const char *filename)
195 if (stat(filename, &ss) == 0) {
204 bool do_file_readable(
const char *filename)
206 if (access(filename, R_OK) == 0) {
216 bool do_dir_exists(
const char *dir)
220 #if defined(_MSC_VER)
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 ?
"..." :
""));
254 static 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)
289 static 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);
411 OLDCODEstatic
openned_file_t* load_file_read_old(
const char *filename)
413 OLDCODE
struct stat ss;
415 OLDCODE
unsigned char *text, *current;
416 OLDCODE
int left2read;
417 OLDCODE#ifdef _MSC_VER
418 OLDCODE
size_t blocksz, readsz;
420 OLDCODE ssize_t blocksz, readsz;
423 OLDCODE
if (stat(filename, &ss) < 0) {
424 OLDCODE PERROR_MSG(
"load_file_read: could not stat: %s\n", filename);
427 OLDCODE#ifdef _MSC_VER
428 OLDCODE fd = open(filename, O_RDONLY | O_BINARY);
430 OLDCODE fd = open(filename, O_RDONLY | O_NONBLOCK);
432 OLDCODE
if (fd < 0) {
433 OLDCODE PERROR_MSG(
"load_file_read: could not open: %s\n", filename);
436 OLDCODE
if (!ss.st_size) {
437 OLDCODE ERROR_MSG(
"load_file_read: file is empty %s\n", filename);
442 OLDCODE text = current = MALLOC(
unsigned char *, ss.st_size +1);
444 OLDCODE ERROR_MSG(
"load_file_read: cannot allocate memory to read file %s\n", filename);
449 OLDCODE
if (ss.st_size > SSIZE_MAX) {
451 OLDCODE blocksz = SSIZE_MAX;
453 OLDCODE blocksz = ss.st_size+1;
456 OLDCODE left2read = ss.st_size;
459 OLDCODE
while (left2read > 0) {
460 OLDCODE readsz = read(fd, current, blocksz);
461 OLDCODE
if (readsz > 0) {
463 OLDCODE current += blocksz;
464 OLDCODE left2read -= blocksz;
467 OLDCODE
if (readsz == 0) {
472 OLDCODE PERROR_MSG(
"load_file_read: error reading file %s\n", filename);
481 OLDCODE text[ss.st_size] =
'\0';
484 OLDCODE
return create_openned_file(filename, fd, ss.st_size+1, text,0,0,FALSE);
491 char *fwg_frontEndWantsFileName() {
return NULL;}
492 void 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)));
536 int 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) {
574 #endif //INCLUDE_NON_WEB3D_FORMATS
577 if (strncmp((
const char*)buffer,
"#VRML V2.0 utf8",15) == 0) {
578 inputFileVersion[0] = 2;
582 if (strncmp ((
const char*)buffer,
"#X3D",4) == 0) {
583 inputFileVersion[0] = 3;
586 if (strncmp ((
const char*)buffer,
"#X3D V3.0 utf8",14) == 0) {
589 if (strncmp ((
const char*)buffer,
"#X3D V3.1 utf8",14) == 0) {
590 inputFileVersion[1] = 1;
593 if (strncmp ((
const char*)buffer,
"#X3D V3.2 utf8",14) == 0) {
594 inputFileVersion[1] = 2;
597 if (strncmp ((
const char*)buffer,
"#X3D V3.3 utf8",14) == 0) {
598 inputFileVersion[1] = 3;
601 if (strncmp ((
const char*)buffer,
"#X3D V3.4 utf8",14) == 0) {
602 inputFileVersion[1] = 4;
609 if (strncmp((
const char*)buffer,
"#VRML V1.0 asc",10) == 0) {
610 return IS_TYPE_VRML1;
617 while(rv && *rv !=
'\0'){
618 if(*rv ==
'<')
return IS_TYPE_XML_X3D;
619 if (*rv ==
'{')
return IS_TYPE_VRML;
623 #if defined (INCLUDE_STL_FILES)
624 return stlDTFT(buffer,len);
625 #endif //INCLUDE_STL_FILES
627 return IS_TYPE_UNKNOWN;
636 #if !defined( _MSC_VER) && !defined(_ANDROID) && !defined(ANDROIDNDK) && !defined(IOS)
637 int freewrlSystem (
const char *sysline)
643 #define MAXEXECPARAMS 10
644 #define EXECBUFSIZE 2000
645 char *paramline[MAXEXECPARAMS];
646 char buf[EXECBUFSIZE];
657 memset(paramline, 0,
sizeof(paramline));
660 haveXmessage = !strncmp(sysline, FREEWRL_MESSAGE_WRAPPER, strlen(FREEWRL_MESSAGE_WRAPPER));
665 if (strlen(sysline)>=EXECBUFSIZE)
return FALSE;
666 strcpy (buf,sysline);
673 paramline[0] = FREEWRL_MESSAGE_WRAPPER;
674 paramline[1] = strchr(internbuf,
' ');
678 while (internbuf != NULL) {
680 paramline[count] = internbuf;
681 internbuf = strchr(internbuf,
' ');
682 if (internbuf != NULL) {
688 if (count >= MAXEXECPARAMS)
return -1;
701 waitForChild = FALSE;
704 if (strncmp(paramline[count],
"&",strlen(paramline[count])) == 0) {
706 paramline[count] =
'\0';
725 Xrv = execl((
const char *)paramline[0],
726 (
const char *)paramline[0],paramline[1], paramline[2],
727 paramline[3],paramline[4],paramline[5],
728 paramline[6],paramline[7], NULL);
729 printf (
"FreeWRL: Fatal problem execing %s\n",paramline[0]);
746 waitpid(child, &pidStatus, 0);
756 return (WIFEXITED(pidStatus) == TRUE);
758 printf (
"System call failed :%s:\n",sysline);
770 static TCHAR *singleDot = L
".";
771 static TCHAR *doubleDot = L
"..";
772 static TCHAR *backslash = L
"\\";
773 static TCHAR *star = L
"*";
776 static TCHAR *singleDot =
".";
777 static TCHAR *doubleDot =
"..";
778 static TCHAR *backslash =
"\\";
779 static TCHAR *star =
"*";
783 BOOL IsDots(
const TCHAR* str) {
784 if(_tcscmp(str,singleDot) && _tcscmp(str,doubleDot))
788 BOOL DeleteDirectory0(
const TCHAR* sPath) {
790 WIN32_FIND_DATA FindFileData;
791 TCHAR DirPath[MAX_PATH];
792 TCHAR FileName[MAX_PATH];
795 _tcscpy(DirPath,sPath);
796 _tcscat(DirPath,backslash);
797 _tcscat(DirPath,star);
798 _tcscpy(FileName,sPath);
799 _tcscat(FileName,backslash);
802 hFind = FindFirstFileEx(DirPath, FindExInfoStandard, &FindFileData, FindExSearchNameMatch, NULL, 0);
805 hFind = FindFirstFile(DirPath,&FindFileData);
807 if(hFind == INVALID_HANDLE_VALUE)
809 _tcscpy(DirPath,FileName);
813 if(FindNextFile(hFind,&FindFileData)) {
814 if(IsDots(FindFileData.cFileName))
continue;
815 _tcscat(FileName,FindFileData.cFileName);
816 if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
818 if(!DeleteDirectory0(FileName)) {
822 RemoveDirectory(FileName);
823 _tcscpy(FileName,DirPath);
826 if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
827 _tchmod(FileName, 777);
828 if(!DeleteFile(FileName)) {
843 _tcscpy(FileName,DirPath);
847 if(GetLastError() == ERROR_NO_MORE_FILES)
857 return RemoveDirectory(sPath);
860 BOOL tdirectory_remove_all(TCHAR *sPath){
862 retval = DeleteDirectory0(sPath);
865 void tremove_file_or_folder(TCHAR *path){
870 WIN32_FILE_ATTRIBUTE_DATA fad;
871 finfo = GetFileAttributesEx(path, GetFileExInfoStandard, &fad);
874 err = GetLastError();
876 ConsoleMessage(
"GetFileAttribuesEx err=%d maxpath%d pathlen%d", (
int)err,MAX_PATH,_tcslen(path));
877 isDir = ! _tcsstr(path, singleDot);
880 isDir = finfo && (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
884 finfo = GetFileAttributes(path);
885 isDir = FILE_ATTRIBUTE_DIRECTORY & finfo;
888 tdirectory_remove_all(path);
892 void remove_file_or_folder(
const char *path){
898 size_t convertedChars = 0;
899 TCHAR wcstring[MAX_PATH];
900 char fname2[MAX_PATH];
903 origsize = strlen(path) + 1;
905 for(jj=0;jj<(int)strlen(fname2);jj++)
906 if(fname2[jj] ==
'/' ) fname2[jj] =
'\\';
910 mbstowcs_s(&convertedChars, wcstring, origsize, fname2, _TRUNCATE);
912 mbstowcs(wcstring, fname2, MB_CUR_MAX);
915 _tcscpy(wcstring,fname2);
917 tremove_file_or_folder(wcstring);
919 #else // POSIX and OSX - WARNING UNTESTED as of Sept 7, 2013
922 int directory_remove_all(
const char *path)
924 DIR *d = opendir(path);
925 size_t path_len = strlen(path);
933 while (!r && (p=readdir(d)))
940 if (!strcmp(p->d_name,
".") || !strcmp(p->d_name,
".."))
944 len = path_len + strlen(p->d_name) + 2;
945 buf = MALLOC(
void *, len);
949 snprintf(buf, len,
"%s/%s", path, p->d_name);
950 if (!stat(buf, &statbuf))
952 if (S_ISDIR(statbuf.st_mode))
954 r2 = directory_remove_all(buf);
973 void remove_file_or_folder(
const char * path){
975 if (!stat(path, &statbuf))
980 if (S_ISDIR(statbuf.st_mode))
982 r2 = directory_remove_all(path);
997 #define WRITEBUFFERSIZE (8192)
1000 int unzip_archive_to_temp_folder(
const char *zipfilename,
const char* tempfolderpath)
1003 const char *filename_to_extract=NULL;
1005 const char *dirname=NULL;
1007 char *fullpath = NULL;
1010 uf = unzOpen(zipfilename);
1013 printf(
"Cannot open %s \n",zipfilename);
1016 printf(
"%s opened\n",zipfilename);
1019 fw_mkdir(tempfolderpath);
1028 err = unzGetGlobalInfo(uf,&gi);
1030 printf(
"error %d with zipfile in unzGetGlobalInfo \n",err);
1034 for (i=0;i<gi.number_entry;i++)
1037 char filename_inzip[256];
1038 char* filename_withoutpath;
1047 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,
sizeof(filename_inzip),NULL,0,NULL,0);
1051 printf(
"error %d with zipfile in unzGetCurrentFileInfo\n",err);
1055 size_buf = WRITEBUFFERSIZE;
1056 buf = (
void*)MALLOC(
void *, size_buf);
1059 printf(
"Error allocating memory\n");
1060 return UNZ_INTERNALERROR;
1063 p = filename_withoutpath = filename_inzip;
1064 while ((*p) !=
'\0')
1066 if (((*p)==
'/') || ((*p)==
'\\'))
1067 filename_withoutpath = p+1;
1071 if ((*filename_withoutpath)==
'\0')
1073 printf(
"creating directory: %s\n",filename_inzip);
1074 strcpy(temppath,tempfolderpath);
1075 strcat(temppath,
"/");
1076 strcat(temppath,filename_inzip);
1082 const char* write_filename;
1085 write_filename = filename_inzip;
1087 err = unzOpenCurrentFile(uf);
1090 printf(
"error %d with zipfile in unzOpenCurrentFile\n",err);
1095 strcpy(temppath,tempfolderpath);
1096 strcat(temppath,
"/");
1097 strcat(temppath,write_filename);
1099 fout=fopen(temppath,
"wb");
1104 printf(
" extracting: %s\n",write_filename);
1108 err = unzReadCurrentFile(uf,buf,size_buf);
1111 printf(
"error %d with zipfile in unzReadCurrentFile\n",err);
1115 if (fwrite(buf,err,1,fout)!=1)
1117 printf(
"error in writing extracted file\n");
1130 err = unzCloseCurrentFile (uf);
1133 printf(
"error %d with zipfile in unzCloseCurrentFile\n",err);
1137 unzCloseCurrentFile(uf);
1144 if ((i+1)<gi.number_entry)
1146 err = unzGoToNextFile(uf);
1149 printf(
"error %d with zipfile in unzGoToNextFile\n",err);
1161 char* remove_filename_from_path(
const char *path);
1162 char *strBackslash2fore(
char *str);
1163 void resitem_enqueue(
s_list_t *item);
1167 char* tempfolderpath;
1169 tempfolderpath = tempnam(gglobal()->Mainloop.tmpFileLocation,
"freewrl_download_XXXXXXXX");
1172 tempfolderpath = STRDUP(res->URLrequest);
1173 tempfolderpath = strBackslash2fore(tempfolderpath);
1174 tempfolderpath = remove_filename_from_path(tempfolderpath);
1175 tempfolderpath = tempnam(tempfolderpath,
"freewrl_download_XXXXXXXX");
1177 err = unzip_archive_to_temp_folder(res->actual_file, tempfolderpath);
1181 strcpy(request,tempfolderpath);
1182 strcat(request,
"/doc.x3d");
1183 docx3d = resource_create_single(request);
1184 docx3d->parent = NULL;
1185 docx3d->type = rest_file;
1186 docx3d->media_type = resm_x3d;
1187 docx3d->treat_as_root = 1;
1189 resitem_enqueue(ml_new(docx3d));
1191 res->cached_files = ml_append(res->cached_files,ml_new(tempfolderpath));
1192 ConsoleMessage(
"unzip folder:%s\n", tempfolderpath);
1195 ConsoleMessage(
"unzip failed to folder:%s\n", tempfolderpath);
1207 file2blob_task_chain,
1208 file2blob_task_spawn,
1209 file2blob_task_enqueue,
1210 } file2blob_task_tactic;
1212 void resource_remove_cached_file(
s_list_t *cfe);
1220 if(res->media_type != resm_x3z){
1221 cf = (
s_list_t *)res->cached_files;
1223 ml_foreach(cf, resource_remove_cached_file(__l));
1225 ml_foreach(cf, ml_free(__l));
1226 res->cached_files = NULL;
1231 int file2blob(
void *resp){
1236 if(res->media_type == resm_image){
1238 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1240 retval = imagery_load(res);
1241 }
else if(res->media_type == resm_movie){
1242 retval = movie_load(res);
1244 retval = resource_load(res);
1246 delete_temp_file(res);
1249 int async_thread_count = 0;
1250 static void *thread_load_async (
void *args){
1253 async_thread_count++;
1254 printf(
"[%d]",async_thread_count);
1255 loaded = file2blob(res);
1258 resitem_enqueue_tg(ml_new(res),res->tg);
1259 async_thread_count--;
1263 if(!res->_loadThread) res->_loadThread = malloc(
sizeof(pthread_t));
1264 pthread_create ((pthread_t*)res->_loadThread, NULL,&thread_load_async, (
void *)res);
1266 void file2blob_task(
s_list_t *item){
1269 int tactic = file2blob_task_enqueue;
1270 if(tactic == file2blob_task_chain){
1272 if(res->media_type == resm_image){
1274 printf(
"FREEWRL LOADING IMAGERY: %s", res->actual_file);
1281 delete_temp_file(res);
1282 resitem_enqueue(item);
1283 }
else if(tactic == file2blob_task_enqueue){
1286 res->_loadFunc = (int(*)(
void*))file2blob;
1289 resitem_enqueue(item);
1290 }
else if(tactic == file2blob_task_spawn){