stdc.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499
  1. #include <stdio.h>
  2. #include <dirent.h>
  3. #if _WIN32
  4. #define _USE_32BIT_TIME_T
  5. #endif
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #if _WIN32
  9. #include <time.h>
  10. #include <direct.h>
  11. #define WIN32_LEAN_AND_MEAN
  12. #include <winsock2.h>
  13. #include <windows.h>
  14. #include <ws2tcpip.h>
  15. #include <utime.h>
  16. extern int bmx_inet_pton(int af, const char *src, void *dst);
  17. #define inet_pton bmx_inet_pton
  18. extern int _bbusew;
  19. #else
  20. #include <time.h>
  21. #include <unistd.h>
  22. #include <limits.h> //PATH_MAX
  23. #include <sys/time.h>
  24. #include <netinet/in.h>
  25. #include <sys/socket.h>
  26. #include <netdb.h>
  27. #include <arpa/inet.h>
  28. #include <utime.h>
  29. #endif
  30. #if __APPLE__
  31. #include <TargetConditionals.h>
  32. #endif
  33. #include <brl.mod/blitz.mod/blitz.h>
  34. FILE* stdin_;
  35. FILE* stdout_;
  36. FILE* stderr_;
  37. extern BBObject * pub_stdc_TAddrInfo__Create(struct addrinfo * info, int owner);
  38. extern BBArray * pub_stdc_TAddrInfo__CreateArray(int count);
  39. extern void pub_stdc_TAddrInfo__SetAtIndex(BBArray * arr, BBObject * info, int index);
  40. #if _WIN32
  41. int getchar_(){
  42. if( _bbusew ) return getwchar();
  43. return getchar();
  44. }
  45. int puts_( BBString *str ){
  46. if( _bbusew ) {
  47. BBChar *p=bbStringToWString( str );
  48. int res = _putws( p );
  49. bbMemFree(p);
  50. return res;
  51. }
  52. char *p=bbStringToCString( str );
  53. int res = puts( p );
  54. bbMemFree(p);
  55. return res;
  56. }
  57. int putenv_( BBString *str ){
  58. if( _bbusew ) {
  59. BBChar *p=bbStringToWString( str );
  60. int res = _wputenv( p );
  61. bbMemFree(p);
  62. return res;
  63. }
  64. char *p=bbStringToCString( str );
  65. int res = putenv( p );
  66. bbMemFree(p);
  67. return res;
  68. }
  69. BBString *getenv_( BBString *str ){
  70. if( _bbusew ) {
  71. BBChar *p=bbStringToWString( str );
  72. BBString * res = bbStringFromWString( _wgetenv( p ) );
  73. bbMemFree(p);
  74. return res;
  75. }
  76. char *p=bbStringToCString( str );
  77. BBString * res = bbStringFromCString( getenv( p ) );
  78. bbMemFree(res);
  79. return res;
  80. }
  81. int fputs_( BBString *str,FILE* file ){
  82. if( _bbusew ) {
  83. BBChar *p=bbStringToWString( str );
  84. int res = fputws( p,file );
  85. bbMemFree(p);
  86. return res;
  87. }
  88. char *p=bbStringToCString( str );
  89. int res = fputs( p,file );
  90. bbMemFree(p);
  91. return res;
  92. }
  93. int chdir_( BBString *path ){
  94. if( _bbusew ) {
  95. BBChar *p=bbStringToWString( path );
  96. int res = _wchdir( p );
  97. bbMemFree(p);
  98. return res;
  99. }
  100. char *p=bbStringToCString( path );
  101. int res = _chdir( p );
  102. bbMemFree(p);
  103. return res;
  104. }
  105. FILE* fopen_( BBString *file,BBString *mode ){
  106. if( _bbusew ) {
  107. BBChar *f=bbStringToWString( file );
  108. BBChar *m=bbStringToWString( mode );
  109. FILE * res = _wfopen( f, m );
  110. bbMemFree(m);
  111. bbMemFree(f);
  112. return res;
  113. }
  114. char *f=bbStringToCString( file );
  115. char *m=bbStringToCString( mode );
  116. FILE * res = fopen( f, m );
  117. bbMemFree(m);
  118. bbMemFree(f);
  119. return res;
  120. }
  121. BBString *getcwd_(){
  122. if( _bbusew ){
  123. wchar_t buf[MAX_PATH];
  124. _wgetcwd( buf,MAX_PATH );
  125. return bbStringFromWString( buf );
  126. }else{
  127. char buf[MAX_PATH];
  128. _getcwd( buf,MAX_PATH );
  129. return bbStringFromCString( buf );
  130. }
  131. return &bbEmptyString;
  132. }
  133. int chmod_( BBString *path,int mode ){
  134. if( _bbusew ) {
  135. BBChar *p=bbStringToWString( path );
  136. int res = _wchmod( p,mode );
  137. bbMemFree(p);
  138. return res;
  139. }
  140. char *p=bbStringToCString( path );
  141. int res = _chmod( p,mode );
  142. bbMemFree(p);
  143. return res;
  144. }
  145. int mkdir_( BBString *path,int mode ){
  146. if( _bbusew ) {
  147. BBChar *p=bbStringToWString( path );
  148. int res = _wmkdir( p );
  149. bbMemFree(p);
  150. return res;
  151. }
  152. char *p=bbStringToCString( path );
  153. int res = _mkdir( p );
  154. bbMemFree(p);
  155. return res;
  156. }
  157. int rmdir_( BBString *path ){
  158. if( _bbusew ) {
  159. BBChar *p=bbStringToWString( path );
  160. int res = _wrmdir( p );
  161. bbMemFree(p);
  162. return res;
  163. }
  164. char *p=bbStringToCString( path );
  165. int res = _rmdir( p );
  166. bbMemFree(p);
  167. return res;
  168. }
  169. int rename_( BBString *src,BBString *dst ){
  170. if( _bbusew ) {
  171. BBChar *s=bbStringToWString( src );
  172. BBChar *d=bbStringToWString( dst );
  173. int res = _wrename( s, d );
  174. bbMemFree(d);
  175. bbMemFree(s);
  176. return res;
  177. }
  178. char *s=bbStringToCString( src );
  179. char *d=bbStringToCString( dst );
  180. int res = rename( s, d );
  181. bbMemFree(d);
  182. bbMemFree(s);
  183. return res;
  184. }
  185. void remove_( BBString *path ){
  186. chmod_( path,0x1b6 );
  187. if( _bbusew ){
  188. BBChar *p=bbStringToWString( path );
  189. _wremove( p );
  190. bbMemFree(p);
  191. }else{
  192. char *p=bbStringToCString( path );
  193. remove( p );
  194. bbMemFree(p);
  195. }
  196. }
  197. void* opendir_( BBString *path ){
  198. if( _bbusew ) {
  199. BBChar *p=bbStringToWString( path );
  200. void * res = _wopendir( p );
  201. bbMemFree(p);
  202. return res;
  203. }
  204. char *p=bbStringToCString( path );
  205. void * res = opendir( p );
  206. bbMemFree(p);
  207. return res;
  208. }
  209. int closedir_( void* dir ){
  210. if( _bbusew ) return _wclosedir( (_WDIR*)dir );
  211. return closedir( (DIR*)dir );
  212. }
  213. BBString *readdir_( void* dir ){
  214. if( _bbusew ){
  215. struct _wdirent *t=_wreaddir( (_WDIR*)dir );
  216. return t ? bbStringFromWString( t->d_name ) : &bbEmptyString;
  217. }
  218. struct dirent *t=readdir( (DIR*)dir );
  219. return t ? bbStringFromCString( t->d_name ) : &bbEmptyString;
  220. }
  221. int stat_( BBString *path,int *t_mode,BBLONG *t_size,int *t_mtime,int *t_ctime,int *t_atime ){
  222. int i;
  223. struct _stati64 st;
  224. for( i=0;i<path->length;++i ){
  225. if( path->buf[i]=='<' || path->buf[i]=='>' ) return -1;
  226. }
  227. if( _bbusew ){
  228. BBChar *p = bbStringToWString(path);
  229. if( _wstati64( p,&st ) ) {
  230. bbMemFree(p);
  231. return -1;
  232. }
  233. bbMemFree(p);
  234. }else{
  235. char *p = bbStringToCString(path);
  236. if( _stati64( p,&st ) ) {
  237. bbMemFree(p);
  238. return -1;
  239. }
  240. bbMemFree(p);
  241. }
  242. *t_mode=st.st_mode;
  243. *t_size=st.st_size;
  244. *t_mtime=st.st_mtime;
  245. *t_ctime=st.st_ctime;
  246. *t_atime=st.st_atime;
  247. return 0;
  248. }
  249. int stat64_( BBString *path,int *t_mode,BBLONG *t_size,BBLONG *t_mtime,BBLONG *t_ctime,BBLONG *t_atime ){
  250. int i;
  251. struct _stati64 st;
  252. for( i=0;i<path->length;++i ){
  253. if( path->buf[i]=='<' || path->buf[i]=='>' ) return -1;
  254. }
  255. if( _bbusew ){
  256. BBChar *p = bbStringToWString(path);
  257. if( _wstati64( p,&st ) ) {
  258. bbMemFree(p);
  259. return -1;
  260. }
  261. bbMemFree(p);
  262. }else{
  263. char *p = bbStringToCString(path);
  264. if( _stati64( p,&st ) ) {
  265. bbMemFree(p);
  266. return -1;
  267. }
  268. bbMemFree(p);
  269. }
  270. *t_mode=st.st_mode;
  271. *t_size=st.st_size;
  272. *t_mtime=st.st_mtime;
  273. *t_ctime=st.st_ctime;
  274. *t_atime=st.st_atime;
  275. return 0;
  276. }
  277. int system_( BBString *cmd ){
  278. int res;
  279. PROCESS_INFORMATION pi={0};
  280. if( _bbusew ){
  281. STARTUPINFOW si={sizeof(si)};
  282. wchar_t *tmp = bbStringToWString(cmd);
  283. if( CreateProcessW( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){
  284. WaitForSingleObject( pi.hProcess,INFINITE );
  285. res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1;
  286. CloseHandle( pi.hProcess );
  287. CloseHandle( pi.hThread );
  288. }else{
  289. res=GetLastError();
  290. }
  291. bbMemFree(tmp);
  292. } else {
  293. STARTUPINFO si={sizeof(si)};
  294. char *tmp = bbStringToCString(cmd);
  295. if( CreateProcessA( 0,tmp,0,0,1,CREATE_DEFAULT_ERROR_MODE,0,0,&si,&pi ) ){
  296. WaitForSingleObject( pi.hProcess,INFINITE );
  297. res=GetExitCodeProcess( pi.hProcess,(DWORD*)&res ) ? res : -1;
  298. CloseHandle( pi.hProcess );
  299. CloseHandle( pi.hThread );
  300. }else{
  301. res=GetLastError();
  302. }
  303. bbMemFree(tmp);
  304. }
  305. return res;
  306. }
  307. int fseek_( FILE* stream, BBLONG offset, int origin ) {
  308. return (_fseeki64(stream, offset, origin) == 0) ? 0 : 1;
  309. }
  310. BBLONG ftell_( FILE* stream ) {
  311. return _ftelli64(stream);
  312. }
  313. int ftruncate_(FILE* stream, BBLONG size) {
  314. return _chsize_s(fileno(stream), size);
  315. }
  316. int clock_gettime_(int id, struct timespec * spec) {
  317. __int64 ftime;
  318. union {
  319. unsigned __int64 ftime;
  320. FILETIME ft;
  321. } ft;
  322. GetSystemTimeAsFileTime(&ft.ft);
  323. ftime = ft.ftime - 116444736000000000LL;
  324. spec->tv_sec = ftime / 10000000LL;
  325. spec->tv_nsec = ((int)(ftime % 10000000LL)) *100;
  326. return 0;
  327. }
  328. int utime_( BBString *path, int type, BBLONG time){
  329. struct _utimbuf times = {0,0};
  330. if ( type == 0 ) {
  331. times.modtime = time;
  332. } else if ( type == 2 ) {
  333. times.actime = time;
  334. } else {
  335. return -1;
  336. }
  337. wchar_t *p = bbStringToWString(path);
  338. int res = _wutime( p, &times);
  339. bbMemFree(p);
  340. return res == 0 ? 0 : -1;
  341. }
  342. #else
  343. int getchar_(){
  344. return getchar();
  345. }
  346. int puts_( BBString *str ){
  347. char *p = bbStringToUTF8String( str );
  348. int res = puts( p );
  349. bbMemFree(p);
  350. return res;
  351. }
  352. int putenv_( BBString *str ){
  353. char *t=bbStringToUTF8String( str );
  354. char *p=(char*)malloc( strlen(t)+1 );
  355. strcpy( p,t );
  356. bbMemFree(t);
  357. return putenv( p );
  358. }
  359. BBString *getenv_( BBString *str ){
  360. char *p = bbStringToUTF8String( str );
  361. BBString * res = bbStringFromUTF8String( getenv( p ) );
  362. bbMemFree(p);
  363. return res;
  364. }
  365. FILE* fopen_( BBString *file,BBString *mode ){
  366. char *f = bbStringToUTF8String( file );
  367. char *m = bbStringToUTF8String( mode );
  368. FILE * res = fopen( f, m );
  369. bbMemFree(m);
  370. bbMemFree(f);
  371. return res;
  372. }
  373. int fputs_( BBString *str,FILE* file ){
  374. char *p = bbStringToUTF8String( str );
  375. int res = fputs( p,file );
  376. bbMemFree(p);
  377. return res;
  378. }
  379. int chdir_( BBString *path ){
  380. char *p = bbStringToUTF8String( path );
  381. int res = chdir( p );
  382. bbMemFree(p);
  383. return res;
  384. }
  385. BBString *getcwd_(){
  386. char buf[PATH_MAX];
  387. getcwd( buf,PATH_MAX );
  388. return bbStringFromUTF8String( buf );
  389. }
  390. int chmod_( BBString *path,int mode ){
  391. char *p = bbStringToUTF8String( path );
  392. int res = chmod( p, mode );
  393. bbMemFree(p);
  394. return res;
  395. }
  396. int mkdir_( BBString *path,int mode ){
  397. char *p = bbStringToUTF8String( path );
  398. int res = mkdir( p, mode );
  399. bbMemFree(p);
  400. return res;
  401. }
  402. int rmdir_( BBString *path ){
  403. char *p = bbStringToUTF8String( path );
  404. int res = rmdir( p );
  405. bbMemFree(p);
  406. return res;
  407. }
  408. int rename_( BBString *src,BBString *dst ){
  409. char *s = bbStringToUTF8String( src );
  410. char *d = bbStringToUTF8String( dst );
  411. int res = rename( s, d );
  412. bbMemFree(d);
  413. bbMemFree(s);
  414. return res;
  415. }
  416. int remove_( BBString *path ){
  417. char *p = bbStringToUTF8String( path );
  418. int res = remove( p );
  419. bbMemFree(p);
  420. return res;
  421. }
  422. DIR* opendir_( BBString *path ){
  423. char *p = bbStringToUTF8String( path );
  424. DIR * res = opendir( p );
  425. bbMemFree(p);
  426. return res;
  427. }
  428. BBString *readdir_( DIR* dir ){
  429. struct dirent *t=readdir( dir );
  430. return t ? bbStringFromUTF8String( t->d_name ) : &bbEmptyString;
  431. }
  432. int closedir_( DIR* dir ){
  433. return closedir( dir );
  434. }
  435. int stat_( BBString *path,int *t_mode,BBLONG *t_size,int *t_mtime,int *t_ctime,int *t_atime ){
  436. struct stat st;
  437. char *p = bbStringToUTF8String( path );
  438. if( stat( p,&st ) ) {
  439. bbMemFree(p);
  440. return -1;
  441. }
  442. bbMemFree(p);
  443. *t_mode=st.st_mode;
  444. *t_size=st.st_size;
  445. *t_mtime=st.st_mtime;
  446. *t_ctime=st.st_ctime;
  447. *t_atime=st.st_atime;
  448. return 0;
  449. }
  450. int stat64_( BBString *path,int *t_mode,BBLONG *t_size,BBLONG *t_mtime,BBLONG *t_ctime,BBLONG *t_atime ){
  451. struct stat st;
  452. char *p = bbStringToUTF8String( path );
  453. if( stat( p,&st ) ) {
  454. bbMemFree(p);
  455. return -1;
  456. }
  457. bbMemFree(p);
  458. *t_mode=st.st_mode;
  459. *t_size=st.st_size;
  460. *t_mtime=st.st_mtime;
  461. *t_ctime=st.st_ctime;
  462. *t_atime=st.st_atime;
  463. return 0;
  464. }
  465. int utime_( BBString *path, int type, BBLONG time){
  466. struct utimbuf times = {0,0};
  467. if ( type == 0 ) {
  468. times.modtime = time;
  469. } else if ( type == 2 ) {
  470. times.actime = time;
  471. } else {
  472. return -1;
  473. }
  474. char *p = (char*)bbStringToUTF8String( path );
  475. int res = utime( p, &times);
  476. bbMemFree(p);
  477. return res == 0 ? 0 : -1;
  478. }
  479. int system_( BBString *cmd ){
  480. #if TARGET_OS_IPHONE || TARGET_OS_TV
  481. bbExThrowCString("Not available on iOS");
  482. return -1;
  483. #elif defined(__ANDROID__)
  484. bbExThrowCString("Not available on Android");
  485. return -1;
  486. #else
  487. char *p = bbStringToUTF8String( cmd );
  488. int res = system( p );
  489. bbMemFree(p);
  490. return res;
  491. #endif
  492. }
  493. int fseek_( FILE* stream, BBLONG offset, int origin ) {
  494. return fseeko(stream, offset, origin);
  495. }
  496. BBLONG ftell_( FILE* stream ) {
  497. return ftello(stream);
  498. }
  499. int ftruncate_(FILE* stream, BBLONG size) {
  500. return ftruncate(fileno(stream), size);
  501. }
  502. #ifndef __APPLE__
  503. int clock_gettime_(int id, struct timespec * spec) {
  504. return clock_gettime(id, spec);
  505. }
  506. #endif
  507. #endif
  508. #ifdef __APPLE__
  509. #include <mach/mach_time.h>
  510. BBULONG mach_absolute_time_ns() {
  511. static mach_timebase_info_data_t s_timebase_info;
  512. static int inited = 0;
  513. if (!inited) {
  514. mach_timebase_info(&s_timebase_info);
  515. };
  516. return (mach_absolute_time() * s_timebase_info.numer) / s_timebase_info.denom;
  517. }
  518. #endif
  519. int fclose_( FILE* stream ) {
  520. return fclose(stream);
  521. }
  522. int feof_(FILE* stream) {
  523. return feof(stream);
  524. }
  525. int fflush_( FILE* stream ) {
  526. return fflush(stream);
  527. }
  528. int htons_( int n ){
  529. return htons( n );
  530. }
  531. int ntohs_( int n ){
  532. return ntohs( n );
  533. }
  534. int htonl_( int n ){
  535. return htonl( n );
  536. }
  537. int ntohl_( int n ){
  538. return ntohl( n );
  539. }
  540. #if _WIN32
  541. SOCKET socket_( int addr_type,int comm_type,int protocol ){
  542. return socket( addr_type,comm_type,protocol );
  543. #else
  544. int socket_( int addr_type,int comm_type,int protocol ){
  545. return socket( addr_type,comm_type,protocol );
  546. #endif
  547. }
  548. #if _WIN32
  549. void closesocket_( SOCKET s ){
  550. closesocket( s );
  551. #else
  552. void closesocket_( int s ){
  553. close( s );
  554. #endif
  555. }
  556. int bmx_stdc_convertAFFamily(int family) {
  557. switch (family) {
  558. case 2:
  559. return AF_INET;
  560. case 10:
  561. return AF_INET6;
  562. }
  563. // unmapped
  564. return family;
  565. }
  566. #if _WIN32
  567. int bind_( SOCKET socket,int addr_type,int port ){
  568. #else
  569. int bind_( int socket,int addr_type,int port ){
  570. #endif
  571. int r;
  572. // if ( addr_type!=AF_INET ) return -1;
  573. switch(addr_type) {
  574. case AF_INET:
  575. {
  576. struct sockaddr_in sa;
  577. memset( &sa,0,sizeof(sa) );
  578. sa.sin_family= bmx_stdc_convertAFFamily(addr_type);
  579. sa.sin_addr.s_addr=htonl(INADDR_ANY);
  580. sa.sin_port=htons( port );
  581. return bind( socket,(void*)&sa,sizeof(sa) );
  582. }
  583. case AF_INET6:
  584. {
  585. struct sockaddr_in6 sa;
  586. memset( &sa,0,sizeof(sa) );
  587. sa.sin6_family= bmx_stdc_convertAFFamily(addr_type);
  588. sa.sin6_addr=in6addr_any;
  589. sa.sin6_port=htons( port );
  590. return bind( socket,(void*)&sa,sizeof(sa) );
  591. }
  592. default:
  593. return -1;
  594. }
  595. }
  596. #if _WIN32
  597. int bmx_stdc_bind_info(SOCKET socket, struct addrinfo * info) {
  598. #else
  599. int bmx_stdc_bind_info(int socket, struct addrinfo * info) {
  600. #endif
  601. return bind(socket, info->ai_addr, info->ai_addrlen);
  602. }
  603. char *gethostbyaddr_( void *addr,int addr_len,int addr_type ){
  604. return NULL;
  605. //struct hostent *e=gethostbyaddr( addr,addr_len,addr_type );
  606. //return e ? e->h_name : 0;
  607. }
  608. BBARRAY getaddrinfo_hints(BBString *name, BBString *service, struct addrinfo * hints) {
  609. struct addrinfo * info;
  610. struct addrinfo * ip;
  611. char * n = bbStringToUTF8String(name);
  612. char * s = 0;
  613. if (service != &bbEmptyString) {
  614. s = bbStringToUTF8String(service);
  615. }
  616. int res = getaddrinfo(n, s, hints, &info);
  617. bbMemFree(s);
  618. bbMemFree(n);
  619. if (res != 0) {
  620. return &bbEmptyArray;
  621. }
  622. int count = 0;
  623. for (ip = info; ip != NULL; ip = ip->ai_next) {
  624. count++;
  625. }
  626. BBArray * arr = pub_stdc_TAddrInfo__CreateArray(count);
  627. count = 0;
  628. for (ip = info; ip != NULL; ip = ip->ai_next) {
  629. BBObject * obj = pub_stdc_TAddrInfo__Create(ip, count == 0);
  630. pub_stdc_TAddrInfo__SetAtIndex(arr, obj, count);
  631. count++;
  632. }
  633. return arr;
  634. }
  635. BBARRAY getaddrinfo_(BBString *name, BBString *service, int family) {
  636. struct addrinfo hints;
  637. memset(&hints, 0, sizeof(struct addrinfo));
  638. hints.ai_family = bmx_stdc_convertAFFamily(family);
  639. return getaddrinfo_hints(name, service, &hints);
  640. }
  641. struct addrinfo * bmx_stdc_addrinfo_new() {
  642. return (struct addrinfo *)calloc(1, sizeof(struct addrinfo));
  643. }
  644. void freeaddrinfo_(struct addrinfo * info ) {
  645. freeaddrinfo(info);
  646. }
  647. #if _WIN32
  648. int connect_( SOCKET socket, struct addrinfo * info ){
  649. #else
  650. int connect_( int socket, struct addrinfo * info ){
  651. #endif
  652. return connect( socket, info->ai_addr, info->ai_addrlen);
  653. }
  654. #if _WIN32
  655. int listen_( SOCKET socket,int backlog ){
  656. #else
  657. int listen_( int socket,int backlog ){
  658. #endif
  659. return listen( socket,backlog );
  660. }
  661. #if _WIN32
  662. int accept_( SOCKET socket,const char *addr,unsigned int *addr_len ){
  663. #else
  664. int accept_( int socket,const char *addr,unsigned int *addr_len ){
  665. #endif
  666. return accept( socket,(void*)addr,addr_len );
  667. }
  668. #if _WIN32
  669. int bmx_stdc_accept_(SOCKET socket, struct sockaddr_storage * storage) {
  670. #else
  671. int bmx_stdc_accept_(int socket, struct sockaddr_storage * storage) {
  672. #endif
  673. if (storage) {
  674. int size = sizeof(struct sockaddr_storage );
  675. return accept(socket, (struct sockaddr *)storage, &size);
  676. } else {
  677. return accept(socket, NULL, NULL);
  678. }
  679. }
  680. #if _WIN32
  681. int select_( int n_read,SOCKET *r_socks,int n_write,SOCKET *w_socks,int n_except,SOCKET *e_socks,int millis ){
  682. #else
  683. int select_( int n_read,int *r_socks,int n_write,int *w_socks,int n_except,int *e_socks,int millis ){
  684. #endif
  685. int i,n,r;
  686. struct timeval tv,*tvp;
  687. fd_set r_set,w_set,e_set;
  688. n=-1;
  689. FD_ZERO( &r_set );
  690. for( i=0;i<n_read;++i ){
  691. FD_SET( r_socks[i],&r_set );
  692. if( r_socks[i]>n ) n=r_socks[i];
  693. }
  694. FD_ZERO( &w_set );
  695. for( i=0;i<n_write;++i ){
  696. FD_SET( w_socks[i],&w_set );
  697. if( w_socks[i]>n ) n=w_socks[i];
  698. }
  699. FD_ZERO( &e_set );
  700. for( i=0;i<n_except;++i ){
  701. FD_SET( e_socks[i],&e_set );
  702. if( e_socks[i]>n ) n=e_socks[i];
  703. }
  704. if( millis<0 ){
  705. tvp=0;
  706. }else{
  707. tv.tv_sec=millis/1000;
  708. tv.tv_usec=(millis%1000)*1000;
  709. tvp=&tv;
  710. }
  711. r=select( n+1,&r_set,&w_set,&e_set,tvp );
  712. if( r<0 ) return r;
  713. for( i=0;i<n_read;++i ){
  714. if( !FD_ISSET(r_socks[i],&r_set) ) r_socks[i]=0;
  715. }
  716. for( i=0;i<n_write;++i ){
  717. if( !FD_ISSET(w_socks[i],&w_set) ) w_socks[i]=0;
  718. }
  719. for( i=0;i<n_except;++i ){
  720. if( !FD_ISSET(e_socks[i],&e_set) ) e_socks[i]=0;
  721. }
  722. return r;
  723. }
  724. #if _WIN32
  725. ssize_t send_( SOCKET socket,const char *buf,size_t size,int flags ){
  726. #else
  727. ssize_t send_( int socket,const char *buf,size_t size,int flags ){
  728. #endif
  729. return send( socket,buf,size,flags );
  730. }
  731. #if _WIN32
  732. int sendto_( SOCKET socket,const char *buf,int size,int flags,const char * dest_ip,int dest_port, int addr_type ){
  733. #else
  734. int sendto_( int socket,const char *buf,int size,int flags,const char * dest_ip,int dest_port, int addr_type ){
  735. #endif
  736. addr_type = bmx_stdc_convertAFFamily(addr_type);
  737. switch (addr_type) {
  738. case AF_INET:
  739. {
  740. struct sockaddr_in sa;
  741. memset( &sa,0,sizeof(sa) );
  742. sa.sin_family=AF_INET;
  743. #ifdef _WIN32
  744. sa.sin_addr.s_addr=inet_addr( dest_ip );
  745. #else
  746. inet_pton(AF_INET, dest_ip, &(sa.sin_addr));
  747. #endif
  748. // memcpy( &sa.sin_addr,dest_ip,4 );
  749. sa.sin_port=htons( dest_port );
  750. return sendto( socket,buf,size,flags,(void*)&sa,sizeof(sa));
  751. }
  752. case AF_INET6:
  753. {
  754. struct sockaddr_in6 sa;
  755. memset( &sa,0,sizeof(sa) );
  756. sa.sin6_family=AF_INET6;
  757. sa.sin6_port=htons( dest_port );
  758. memcpy( &sa.sin6_addr, dest_ip,16 );
  759. return sendto( socket,buf,size,flags,(void*)&sa,sizeof(sa));
  760. }
  761. }
  762. return 0;
  763. }
  764. #if _WIN32
  765. ssize_t recv_( SOCKET socket,char *buf,size_t size,int flags ){
  766. #else
  767. ssize_t recv_( int socket,char *buf,size_t size,int flags ){
  768. #endif
  769. return recv( socket,buf,size,flags );
  770. }
  771. #if _WIN32
  772. int recvfrom_( SOCKET socket,char *buf,int size,int flags,int *_ip,int *_port){
  773. #else
  774. int recvfrom_( int socket,char *buf,int size,int flags,int *_ip,int *_port){
  775. #endif
  776. struct sockaddr_in sa;
  777. int sasize;
  778. int count;
  779. memset( &sa,0,sizeof(sa) );
  780. sasize=sizeof(sa);
  781. count=recvfrom(socket,buf,size,flags,(void*)&sa,&sasize);
  782. *_ip=ntohl_(sa.sin_addr.s_addr);
  783. *_port=ntohs_(sa.sin_port);
  784. return count;
  785. }
  786. #if _WIN32
  787. int setsockopt_( SOCKET socket,int level,int optname,const void *optval,int count){
  788. #else
  789. int setsockopt_( int socket,int level,int optname,const void *optval,int count){
  790. #endif
  791. return setsockopt( socket,level,optname,optval,count);
  792. }
  793. #if _WIN32
  794. int getsockopt_( SOCKET socket,int level,int optname,void *optval,int *count){
  795. #else
  796. int getsockopt_( int socket,int level,int optname,void *optval,int *count){
  797. #endif
  798. return getsockopt( socket,level,optname,optval,count);
  799. }
  800. #if _WIN32
  801. int shutdown_( SOCKET socket,int how ){
  802. #else
  803. int shutdown_( int socket,int how ){
  804. #endif
  805. return shutdown( socket,how );
  806. }
  807. #if _WIN32
  808. int getsockname_( SOCKET socket,void *addr,int *len ){
  809. #else
  810. int getsockname_( int socket,void *addr,int *len ){
  811. #endif
  812. return getsockname( socket,addr,len );
  813. }
  814. #if _WIN32
  815. int getpeername_( SOCKET socket,void *addr,int *len ){
  816. #else
  817. int getpeername_( int socket,void *addr,int *len ){
  818. #endif
  819. return getpeername( socket,addr,len );
  820. }
  821. typedef struct {
  822. int year;
  823. int month;
  824. int day;
  825. int hour;
  826. int minute;
  827. int second;
  828. int millisecond;
  829. int utc;
  830. int offset;
  831. int dst;
  832. } SDateTime;
  833. #ifdef __WIN32__
  834. int bmx_calc_timeoffset_mins(SDateTime * dt) {
  835. TIME_ZONE_INFORMATION tz;
  836. DWORD rc = GetTimeZoneInformation(&tz);
  837. int offset_minutes = tz.Bias + (TIME_ZONE_ID_DAYLIGHT != rc ? tz.StandardBias : tz.DaylightBias);
  838. dt->dst = (rc == TIME_ZONE_ID_DAYLIGHT) ? 1 : 0;
  839. return offset_minutes;
  840. }
  841. void bmx_current_datetime(SDateTime * dt, int utc) {
  842. SYSTEMTIME systemTime;
  843. if (utc) {
  844. GetSystemTime(&systemTime);
  845. } else {
  846. GetLocalTime(&systemTime);
  847. }
  848. dt->year = systemTime.wYear;
  849. dt->month = systemTime.wMonth;
  850. dt->day = systemTime.wDay;
  851. dt->hour = systemTime.wHour;
  852. dt->minute = systemTime.wMinute;
  853. dt->second = systemTime.wSecond;
  854. dt->millisecond = systemTime.wMilliseconds;
  855. dt->utc = utc;
  856. dt->offset = utc ? 0 : bmx_calc_timeoffset_mins(dt);
  857. }
  858. #else
  859. int bmx_calc_timeoffset_mins() {
  860. time_t rawtime;
  861. struct tm local_tm, utc_tm;
  862. time(&rawtime);
  863. localtime_r(&rawtime, &local_tm);
  864. gmtime_r(&rawtime, &utc_tm);
  865. // Calculate the time difference in minutes
  866. int diff_minutes = (local_tm.tm_hour - utc_tm.tm_hour) * 60 + (local_tm.tm_min - utc_tm.tm_min);
  867. // Adjust the difference if crossing a day boundary
  868. if (local_tm.tm_yday < utc_tm.tm_yday) {
  869. diff_minutes -= 24 * 60;
  870. } else if (local_tm.tm_yday > utc_tm.tm_yday) {
  871. diff_minutes += 24 * 60;
  872. }
  873. return diff_minutes;
  874. }
  875. void bmx_current_datetime(SDateTime * dt, int utc) {
  876. struct timespec ts;
  877. struct tm tm;
  878. clock_gettime(CLOCK_REALTIME, &ts);
  879. if (utc) {
  880. gmtime_r(&ts.tv_sec, &tm);
  881. dt->dst = 0;
  882. } else {
  883. localtime_r(&ts.tv_sec, &tm);
  884. dt->dst = tm.tm_isdst > 0 ? 1 : 0;
  885. }
  886. dt->year = tm.tm_year + 1900;
  887. dt->month = tm.tm_mon + 1;
  888. dt->day = tm.tm_mday;
  889. dt->hour = tm.tm_hour;
  890. dt->minute = tm.tm_min;
  891. dt->second = tm.tm_sec;
  892. dt->millisecond = ts.tv_nsec / 1000000;
  893. dt->utc = utc;
  894. dt->offset = utc ? 0 : bmx_calc_timeoffset_mins();
  895. }
  896. #endif
  897. int bmx_datetime_from_local_epoch(BBLONG epoch, SDateTime* dt) {
  898. struct tm* local;
  899. #if defined(__linux__) || defined(__APPLE__)
  900. struct tm result;
  901. local = localtime_r(&epoch, &result);
  902. #elif defined(_WIN32) || defined(_WIN64)
  903. local = localtime(&epoch);
  904. #else
  905. return -1; // Platform not supported
  906. #endif
  907. if (!local) {
  908. return -1;
  909. }
  910. dt->year = local->tm_year + 1900;
  911. dt->month = local->tm_mon + 1;
  912. dt->day = local->tm_mday;
  913. dt->hour = local->tm_hour;
  914. dt->minute = local->tm_min;
  915. dt->second = local->tm_sec;
  916. dt->millisecond = 0;
  917. dt->utc = 0; // This is local time
  918. #if defined(__linux__) || defined(__APPLE__)
  919. dt->offset = local->tm_gmtoff / 60; // 'tm_gmtoff' holds seconds east of UTC
  920. dt->dst = local->tm_isdst;
  921. #elif defined(_WIN32) || defined(_WIN64)
  922. dt->offset = -bmx_calc_timeoffset_mins(dt); // - is because Windows returns minutes west of UTC
  923. #endif
  924. return 0;
  925. }
  926. SDateTime bmx_datetime_from_epoch(BBLONG epochTimeSecs, BBLONG fracNanoseconds, int isLocalTime) {
  927. SDateTime dt;
  928. if (isLocalTime) {
  929. int res = bmx_datetime_from_local_epoch(epochTimeSecs, &dt);
  930. if (res == 0) {
  931. dt.millisecond = fracNanoseconds / 1000000;
  932. }
  933. return dt;
  934. }
  935. struct tm timeinfo;
  936. #if defined(_WIN32) || defined(_WIN64)
  937. gmtime_s(&timeinfo, &epochTimeSecs);
  938. #else
  939. gmtime_r(&epochTimeSecs, &timeinfo);
  940. #endif
  941. dt.year = timeinfo.tm_year + 1900;
  942. dt.month = timeinfo.tm_mon + 1;
  943. dt.day = timeinfo.tm_mday;
  944. dt.hour = timeinfo.tm_hour;
  945. dt.minute = timeinfo.tm_min;
  946. dt.second = timeinfo.tm_sec;
  947. dt.millisecond = fracNanoseconds / 1000000;
  948. dt.utc = 1;
  949. dt.offset = 0;
  950. dt.dst = 0;
  951. return dt;
  952. }
  953. time_t bmx_datetime_to_time_t(SDateTime * dt) {
  954. struct tm t;
  955. t.tm_year = dt->year - 1900;
  956. t.tm_mon = dt->month - 1;
  957. t.tm_mday = dt->day;
  958. t.tm_hour = dt->hour;
  959. t.tm_min = dt->minute;
  960. t.tm_sec = dt->second;
  961. t.tm_isdst = -1; // timegm and _mkgmtime do not use this field
  962. if (!dt->utc) {
  963. // Convert the offset to seconds
  964. int offsetSeconds = dt->offset * 60;
  965. if (dt->dst == 1) {
  966. offsetSeconds += 3600;
  967. }
  968. // Convert struct tm to time_t as if it was UTC
  969. time_t ts;
  970. #if defined(_WIN32) || defined(_WIN64)
  971. ts = _mkgmtime(&t);
  972. #else
  973. ts = timegm(&t);
  974. #endif
  975. if (ts == -1) {
  976. return -1;
  977. }
  978. // Apply the offset
  979. ts -= offsetSeconds;
  980. return (BBLONG)ts;
  981. } else {
  982. // Convert struct tm to time_t as UTC
  983. time_t ts;
  984. #if defined(_WIN32) || defined(_WIN64)
  985. ts = _mkgmtime(&t);
  986. #else
  987. ts = timegm(&t);
  988. #endif
  989. if (ts == -1) {
  990. return -1;
  991. }
  992. return ts;
  993. }
  994. }
  995. BBLONG bmx_datetime_to_epoch(SDateTime * dt) {
  996. if (dt->utc) {
  997. return (BBLONG)bmx_datetime_to_time_t(dt);
  998. }
  999. struct tm t;
  1000. t.tm_year = dt->year - 1900;
  1001. t.tm_mon = dt->month - 1;
  1002. t.tm_mday = dt->day;
  1003. t.tm_hour = dt->hour;
  1004. t.tm_min = dt->minute;
  1005. t.tm_sec = dt->second;
  1006. t.tm_isdst = dt->dst;
  1007. return (BBLONG)mktime(&t);
  1008. }
  1009. int bmx_datetime_convert_to_utc(const SDateTime* dt, SDateTime* dt_utc) {
  1010. if (!dt || !dt_utc)
  1011. return -1; // Return error if either pointer is NULL
  1012. if (dt->utc == 1) {
  1013. *dt_utc = *dt;
  1014. return 0;
  1015. }
  1016. time_t ts = bmx_datetime_to_time_t(dt);
  1017. if (ts == -1) {
  1018. return -1;
  1019. }
  1020. struct tm utc;
  1021. #if defined(_WIN32) || defined(_WIN64)
  1022. gmtime_s(&timeinfo, &epochTimeSecs);
  1023. #else
  1024. gmtime_r(&ts, &utc);
  1025. #endif
  1026. dt_utc->year = utc.tm_year + 1900;
  1027. dt_utc->month = utc.tm_mon + 1;
  1028. dt_utc->day = utc.tm_mday;
  1029. dt_utc->hour = utc.tm_hour;
  1030. dt_utc->minute = utc.tm_min;
  1031. dt_utc->second = utc.tm_sec;
  1032. dt_utc->millisecond = dt->millisecond;
  1033. dt_utc->utc = 1;
  1034. dt_utc->offset = 0;
  1035. dt_utc->dst = 0;
  1036. return 0;
  1037. }
  1038. BBString * bmx_current_datetime_format(BBString * format) {
  1039. struct tm tm;
  1040. time_t rawtime;
  1041. char buf[256];
  1042. unsigned char * f = bbStringToUTF8String(format);
  1043. time(&rawtime);
  1044. #if defined(_WIN32) || defined(_WIN64)
  1045. localtime_s(&tm, &rawtime);
  1046. #else
  1047. localtime_r(&rawtime, &tm);
  1048. #endif
  1049. strftime(buf, sizeof(buf), f, &tm);
  1050. BBString * res = bbStringFromUTF8String(buf);
  1051. bbMemFree(f);
  1052. return res;
  1053. }
  1054. BBString * bmx_datetime_iso8601(const SDateTime *dt, int showMillis) {
  1055. char buf[32];
  1056. if (dt->utc) {
  1057. if (showMillis) {
  1058. snprintf(buf, 32, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
  1059. dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second, dt->millisecond);
  1060. } else {
  1061. snprintf(buf, 32, "%04d-%02d-%02dT%02d:%02d:%02dZ",
  1062. dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second);
  1063. }
  1064. } else {
  1065. int offset = dt->dst == 1 ? dt->offset + 60 : dt->offset;
  1066. int offset_sign = dt->offset >= 0 ? 1 : -1;
  1067. int offset_hours = offset / 60;
  1068. int offset_minutes = offset % 60 * offset_sign;
  1069. if (showMillis) {
  1070. snprintf(buf, 32, "%04d-%02d-%02dT%02d:%02d:%02d.%03d%+03d:%02d",
  1071. dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second, dt->millisecond,
  1072. offset_hours, offset_minutes);
  1073. } else {
  1074. snprintf(buf, 32, "%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d",
  1075. dt->year, dt->month, dt->day, dt->hour, dt->minute, dt->second,
  1076. offset_hours, offset_minutes);
  1077. }
  1078. }
  1079. return bbStringFromCString(buf);
  1080. }
  1081. int time_( void *ttime ){
  1082. return (int)time( (time_t*)ttime );
  1083. }
  1084. void *localtime_( void *ttime ){
  1085. return localtime( (time_t*)ttime );
  1086. }
  1087. int strftime_( char *buf,int size,BBString *fmt,void *ttime ){
  1088. char *p = bbStringToCString( fmt );
  1089. int res = strftime( buf,size,p,ttime );
  1090. bbMemFree(p);
  1091. return res;
  1092. }
  1093. int bmx_stdc_addrinfo_flags(struct addrinfo * info) {
  1094. return info->ai_flags;
  1095. }
  1096. int bmx_stdc_addrinfo_family(struct addrinfo * info) {
  1097. return info->ai_family;
  1098. }
  1099. int bmx_stdc_addrinfo_socktype(struct addrinfo * info) {
  1100. return info->ai_socktype;
  1101. }
  1102. int bmx_stdc_addrinfo_protocol(struct addrinfo * info) {
  1103. return info->ai_protocol;
  1104. }
  1105. int bmx_stdc_addrinfo_addrlen(struct addrinfo * info) {
  1106. return info->ai_addrlen;
  1107. }
  1108. struct sockaddr * bmx_stdc_addrinfo_addr(struct addrinfo * info) {
  1109. return info->ai_addr;
  1110. }
  1111. BBString * bmx_stdc_addrinfo_canonname(struct addrinfo * info) {
  1112. return bbStringFromUTF8String(info->ai_canonname);
  1113. }
  1114. void bmx_stdc_addrinfo_setflags(struct addrinfo * info, int flags) {
  1115. info->ai_flags = flags;
  1116. }
  1117. void bmx_stdc_addrinfo_setfamily(struct addrinfo * info, int family) {
  1118. info->ai_family = bmx_stdc_convertAFFamily(family);
  1119. }
  1120. void bmx_stdc_addrinfo_setsocktype(struct addrinfo * info, int sockType) {
  1121. info->ai_socktype = sockType;
  1122. }
  1123. void bmx_stdc_addrinfo_setprotocol(struct addrinfo * info, int protocol) {
  1124. info->ai_protocol = protocol;
  1125. }
  1126. int bmx_stdc_convertNIFlags(int flags) {
  1127. int niFlags = 0;
  1128. if (flags & 0x0001) {
  1129. niFlags |= NI_DGRAM;
  1130. }
  1131. if (flags & 0x0002) {
  1132. niFlags |= NI_NAMEREQD;
  1133. }
  1134. if (flags & 0x0004) {
  1135. niFlags |= NI_NOFQDN;
  1136. }
  1137. if (flags & 0x0008) {
  1138. niFlags |= NI_NUMERICHOST;
  1139. }
  1140. if (flags & 0x0010) {
  1141. niFlags |= NI_NUMERICSERV;
  1142. }
  1143. return niFlags;
  1144. }
  1145. BBString * bmx_stdc_addrinfo_hostname(struct addrinfo * info, int flags) {
  1146. char host[256];
  1147. int res = getnameinfo(info->ai_addr, info->ai_addrlen, host, 256, 0, 0, bmx_stdc_convertNIFlags(flags));
  1148. if (res != 0) {
  1149. return &bbEmptyString;
  1150. }
  1151. return bbStringFromUTF8String(host);
  1152. }
  1153. int inet_pton_(int family, BBString * src, void * dst) {
  1154. char * s = bbStringToCString(src);
  1155. int res = inet_pton(bmx_stdc_convertAFFamily(family), s, dst);
  1156. bbMemFree(s);
  1157. return res;
  1158. }
  1159. struct sockaddr_storage * bmx_stdc_sockaddrestorage_new() {
  1160. return calloc(1, sizeof(struct sockaddr_storage));
  1161. }
  1162. BBString * bmx_stdc_sockaddrestorage_address(struct sockaddr_storage * storage) {
  1163. BBString * address = &bbEmptyString;
  1164. #if _WIN32
  1165. TCHAR add[256];
  1166. typedef LPTSTR (__stdcall RTLIPV6ADDRESSTOSTRING)(const IN6_ADDR*, PTSTR);
  1167. typedef LPTSTR (__stdcall RTLIPV4ADDRESSTOSTRING)(const IN_ADDR*, PTSTR);
  1168. HMODULE ntdll = GetModuleHandle("NTDLL.DLL");
  1169. if (storage->ss_family == AF_INET) {
  1170. RTLIPV4ADDRESSTOSTRING* RtlIpv4AddressToStringFunc = (RTLIPV4ADDRESSTOSTRING*)GetProcAddress(ntdll, "RtlIpv4AddressToStringW");
  1171. RtlIpv4AddressToStringFunc(&((struct sockaddr_in*)storage)->sin_addr, add);
  1172. } else {
  1173. RTLIPV6ADDRESSTOSTRING* RtlIpv6AddressToStringFunc = (RTLIPV6ADDRESSTOSTRING*)GetProcAddress(ntdll, "RtlIpv6AddressToStringW");
  1174. RtlIpv6AddressToStringFunc(&((struct sockaddr_in6*)storage)->sin6_addr, add);
  1175. }
  1176. address = bbStringFromWString((BBChar*)add);
  1177. #else
  1178. char add[256];
  1179. if (storage->ss_family == AF_INET) {
  1180. inet_ntop(storage->ss_family, &((struct sockaddr_in*)storage)->sin_addr, add, sizeof(add));
  1181. } else {
  1182. inet_ntop(storage->ss_family, &((struct sockaddr_in6*)storage)->sin6_addr, add, sizeof(add));
  1183. }
  1184. address = bbStringFromCString(add);
  1185. #endif
  1186. return address;
  1187. }
  1188. #if _WIN32
  1189. int bmx_stdc_getsockname(SOCKET socket, int * port, BBSTRING * address) {
  1190. #else
  1191. int bmx_stdc_getsockname(int socket, int * port, BBSTRING * address) {
  1192. #endif
  1193. struct sockaddr_storage storage;
  1194. int len = sizeof(struct sockaddr_storage);
  1195. int res = getsockname(socket, (struct sockaddr *)&storage, &len);
  1196. if (res >= 0) {
  1197. if (storage.ss_family == AF_INET) {
  1198. *port = ntohs(((struct sockaddr_in*)&storage)->sin_port);
  1199. } else {
  1200. *port = ntohs(((struct sockaddr_in6*)&storage)->sin6_port);
  1201. }
  1202. *address = bmx_stdc_sockaddrestorage_address(&storage);
  1203. }
  1204. return res;
  1205. }
  1206. #if _WIN32
  1207. int bmx_stdc_getpeername(SOCKET socket, int * port, BBSTRING * address) {
  1208. #else
  1209. int bmx_stdc_getpeername(int socket, int * port, BBSTRING * address) {
  1210. #endif
  1211. struct sockaddr_storage storage;
  1212. int len = sizeof(struct sockaddr_storage);
  1213. int res = getpeername(socket, (struct sockaddr *)&storage, &len);
  1214. if (res >= 0) {
  1215. if (storage.ss_family == AF_INET) {
  1216. *port = ntohs(((struct sockaddr_in*)&storage)->sin_port);
  1217. } else {
  1218. *port = ntohs(((struct sockaddr_in6*)&storage)->sin6_port);
  1219. }
  1220. *address = bmx_stdc_sockaddrestorage_address(&storage);
  1221. }
  1222. return res;
  1223. }
  1224. #if _WIN32
  1225. static void CleanupWSA(){
  1226. WSACleanup();
  1227. }
  1228. #endif
  1229. void bb_stdc_Startup(){
  1230. #if _WIN32
  1231. WSADATA ws;
  1232. WSAStartup( MAKEWORD(2, 2),&ws );
  1233. atexit( CleanupWSA );
  1234. #endif
  1235. stdin_=stdin;
  1236. stdout_=stdout;
  1237. stderr_=stderr;
  1238. }