PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/zuluCrypt-cli/utility/socket/socket.c

https://gitlab.com/m.schmidt/zuluCrypt
C | 852 lines | 705 code | 129 blank | 18 comment | 151 complexity | a5669caad3f1df055daae4eb7e05050e MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, BSD-2-Clause
  1. /*
  2. *
  3. * Copyright (c) 2012-2015
  4. * name : Francis Banyikwa
  5. * email: mhogomchungu@gmail.com
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "socket.h"
  20. #ifndef _GNU_SOURCE
  21. #define _GNU_SOURCE
  22. #endif
  23. #include <sys/socket.h>
  24. #include <unistd.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <sys/un.h>
  29. #include <netinet/in.h>
  30. #include <arpa/inet.h>
  31. #include <sys/select.h>
  32. #include <netdb.h>
  33. #include <sys/time.h>
  34. #include <fcntl.h>
  35. #include <errno.h>
  36. #include <sys/socket.h>
  37. #include <netdb.h>
  38. struct SocketType_t
  39. {
  40. int socket_server ;
  41. int type ;
  42. int protocol ;
  43. int cmax ;
  44. int domain ;
  45. socklen_t size ;
  46. int fd ;
  47. void * socket ;
  48. char * inetAddress ;
  49. };
  50. static void ( *_fcn_ )( void ) = NULL ;
  51. void SocketExitOnMemoryExaustion( void ( *f )( void ) )
  52. {
  53. _fcn_ = f ;
  54. }
  55. static socket_t _SocketError( void )
  56. {
  57. if( _fcn_ != NULL ){
  58. _fcn_() ;
  59. }
  60. return SocketVoid ;
  61. }
  62. static inline socket_t _SocketLocal( void )
  63. {
  64. socket_t s = malloc( sizeof( struct SocketType_t ) ) ;
  65. struct sockaddr_un * e ;
  66. if( s == NULL ){
  67. return SocketVoid ;
  68. }else{
  69. memset( s,'\0',sizeof( struct SocketType_t ) ) ;
  70. s->socket = malloc( sizeof( struct sockaddr_un ) ) ;
  71. if( s->socket == NULL ){
  72. free( s ) ;
  73. return _SocketError() ;
  74. }else{
  75. s->size = sizeof( struct sockaddr_un ) ;
  76. memset( s->socket,'\0',s->size ) ;
  77. e = s->socket ;
  78. e->sun_family = AF_UNIX ;
  79. return s ;
  80. }
  81. }
  82. }
  83. static inline socket_t _SocketNet( void )
  84. {
  85. socket_t s = malloc( sizeof( struct SocketType_t ) ) ;
  86. struct sockaddr_in * e ;
  87. if( s == NULL ){
  88. return SocketVoid ;
  89. }else{
  90. memset( s,'\0',sizeof( struct SocketType_t ) ) ;
  91. s->socket = malloc( sizeof( struct sockaddr_in ) ) ;
  92. if( s->socket == NULL ){
  93. free( s ) ;
  94. return _SocketError() ;
  95. }else{
  96. s->inetAddress = NULL ;
  97. s->size = sizeof( struct sockaddr_in ) ;
  98. memset( s->socket,'\0',s->size ) ;
  99. e = s->socket ;
  100. e->sin_family = AF_INET ;
  101. return s ;
  102. }
  103. }
  104. }
  105. static inline socket_t _SocketNet6( void )
  106. {
  107. socket_t s = malloc( sizeof( struct SocketType_t ) ) ;
  108. struct sockaddr_in6 * e ;
  109. if( s == NULL ){
  110. return SocketVoid ;
  111. }else{
  112. memset( s,'\0',sizeof( struct SocketType_t ) ) ;
  113. s->socket = malloc( sizeof( struct sockaddr_in6 ) ) ;
  114. if( s->socket == NULL ){
  115. free( s ) ;
  116. return _SocketError() ;
  117. }else{
  118. s->inetAddress = NULL ;
  119. s->size = sizeof( struct sockaddr_in6 ) ;
  120. memset( s->socket,'\0',s->size ) ;
  121. e = s->socket ;
  122. e->sin6_family = AF_INET6 ;
  123. return s ;
  124. }
  125. }
  126. }
  127. socket_t Socket( int domain,int type,int protocol )
  128. {
  129. socket_t s = SocketVoid ;
  130. int fd ;
  131. if( domain != AF_UNIX && domain != AF_INET && domain != AF_INET6 ){
  132. return SocketVoid ;
  133. }
  134. fd = socket( domain,type,protocol ) ;
  135. if( fd == -1 ){
  136. return SocketVoid ;
  137. }
  138. fcntl( fd,F_SETFD,FD_CLOEXEC ) ;
  139. switch( domain ){
  140. case AF_UNIX : s = _SocketLocal() ; break ;
  141. case AF_INET : s = _SocketNet() ; break ;
  142. case AF_INET6: s = _SocketNet6() ; break ;
  143. }
  144. if( s == SocketVoid ){
  145. close( fd ) ;
  146. return SocketVoid ;
  147. }else{
  148. s->domain = domain ;
  149. s->type = type ;
  150. s->protocol = protocol ;
  151. s->cmax = 1 ;
  152. s->socket_server = 0 ;
  153. s->fd = fd ;
  154. return s ;
  155. }
  156. }
  157. int SocketFileDescriptor( socket_t s )
  158. {
  159. if( s == SocketVoid ){
  160. return -1 ;
  161. }else{
  162. return s->fd ;
  163. }
  164. }
  165. socket_t SocketLocalWithOptions( const char * address,int type,int protocol )
  166. {
  167. socket_t s = Socket( AF_UNIX,type,protocol ) ;
  168. struct sockaddr_un * e ;
  169. size_t l = sizeof( e->sun_path ) ;
  170. if( s != SocketVoid ){
  171. e = s->socket ;
  172. strncpy( e->sun_path,address,l ) ;
  173. }
  174. return s ;
  175. }
  176. socket_t SocketLocal( const char * address )
  177. {
  178. return SocketLocalWithOptions( address,SOCK_STREAM,0 ) ;
  179. }
  180. socket_t SocketNetWithOptions( const char * address,int port,int type,int protocol )
  181. {
  182. socket_t s = SocketVoid ;
  183. struct addrinfo * info ;
  184. struct addrinfo hint ;
  185. struct sockaddr_in * e ;
  186. memset( &hint,'\0',sizeof( hint ) ) ;
  187. hint.ai_family = AF_INET ;
  188. hint.ai_socktype = type ;
  189. hint.ai_protocol = protocol ;
  190. if( getaddrinfo( address,NULL,&hint,&info) == 0 ){
  191. s = Socket( AF_INET,type,protocol ) ;
  192. if( s != SocketVoid ){
  193. e = s->socket ;
  194. memcpy( e,info->ai_addr,info->ai_addrlen ) ;
  195. e->sin_port = htons( port ) ;
  196. }
  197. freeaddrinfo( info ) ;
  198. }
  199. return s ;
  200. }
  201. socket_t SocketNet( const char * address,int port )
  202. {
  203. return SocketNetWithOptions( address,port,SOCK_STREAM,0 ) ;
  204. }
  205. socket_t SocketNetWithOptions6( const char * address,int port,int type,int protocol )
  206. {
  207. socket_t s = SocketVoid ;
  208. struct addrinfo hint ;
  209. struct addrinfo * info ;
  210. struct sockaddr_in6 * e ;
  211. memset( &hint,'\0',sizeof( struct addrinfo ) ) ;
  212. hint.ai_family = AF_INET6 ;
  213. hint.ai_socktype = type ;
  214. hint.ai_protocol = protocol ;
  215. if( getaddrinfo( address,NULL,&hint,&info ) == 0 ){
  216. s = Socket( AF_INET6,type,protocol ) ;
  217. if( s != SocketVoid ){
  218. e = s->socket ;
  219. memcpy( e,info->ai_addr,info->ai_addrlen ) ;
  220. e->sin6_port = htons( port ) ;
  221. }
  222. freeaddrinfo( info ) ;
  223. }
  224. return s ;
  225. }
  226. socket_t SocketNet6( const char * address,int port )
  227. {
  228. return SocketNetWithOptions6( address,port,SOCK_STREAM,0 ) ;
  229. }
  230. static inline const char * _SocketNetAddress( socket_t s )
  231. {
  232. const char * c ;
  233. struct sockaddr_in * e = s->socket ;
  234. if( s->inetAddress == NULL ){
  235. s->inetAddress = malloc( sizeof( char ) * INET_ADDRSTRLEN ) ;
  236. if( s->inetAddress == NULL ){
  237. _SocketError() ;
  238. return NULL ;
  239. }
  240. c = inet_ntop( AF_INET,&e->sin_addr,s->inetAddress,INET_ADDRSTRLEN ) ;
  241. if( c == NULL ){
  242. free( s->inetAddress ) ;
  243. s->inetAddress = NULL ;
  244. return NULL ;
  245. }
  246. }
  247. return s->inetAddress ;
  248. }
  249. static inline const char * _SocketNetAddress6( socket_t s )
  250. {
  251. const char * c ;
  252. struct sockaddr_in6 * e = s->socket ;
  253. if( s->inetAddress == NULL ){
  254. s->inetAddress = malloc( sizeof( char ) * INET6_ADDRSTRLEN ) ;
  255. if( s->inetAddress == NULL ){
  256. _SocketError() ;
  257. return NULL ;
  258. }
  259. c = inet_ntop( AF_INET6,&e->sin6_addr,s->inetAddress,INET6_ADDRSTRLEN ) ;
  260. if( c == NULL ){
  261. free( s->inetAddress ) ;
  262. s->inetAddress = NULL ;
  263. return NULL ;
  264. }
  265. }
  266. return s->inetAddress ;
  267. }
  268. static inline const char * _SocketLocalAddress( socket_t s )
  269. {
  270. struct sockaddr_un * e = s->socket ;
  271. return e->sun_path ;
  272. }
  273. const char * SocketAddress( socket_t s )
  274. {
  275. if( s == SocketVoid ){
  276. return NULL ;
  277. }else{
  278. switch( s->domain ){
  279. case AF_UNIX : return _SocketLocalAddress( s ) ;
  280. case AF_INET : return _SocketNetAddress( s ) ;
  281. case AF_INET6: return _SocketNetAddress6( s ) ;
  282. default : return NULL ;
  283. }
  284. }
  285. }
  286. int SocketBind( socket_t s )
  287. {
  288. struct sockaddr * e ;
  289. struct sockaddr_un * f ;
  290. char buffer[ sizeof( f->sun_path ) + 1 ] ;
  291. if( s == SocketVoid ){
  292. return 0 ;
  293. }
  294. e = s->socket ;
  295. if( s->domain == AF_UNIX ){
  296. s->socket_server = 1 ;
  297. f = s->socket ;
  298. strncpy( buffer,f->sun_path,sizeof( f->sun_path ) ) ;
  299. *( buffer + sizeof( f->sun_path ) ) = '\0' ;
  300. unlink( buffer ) ;
  301. return bind( s->fd,e,s->size ) == 0 ;
  302. }else if( s->domain == AF_INET ){
  303. return bind( s->fd,e,s->size ) == 0 ;
  304. }else if (s->domain == AF_INET6 ){
  305. return bind( s->fd,e,s->size ) == 0 ;
  306. }else{
  307. return 0 ;
  308. }
  309. }
  310. static inline socket_t _SocketAcceptLocal( socket_t s )
  311. {
  312. struct sockaddr_un * e ;
  313. struct sockaddr_un * z ;
  314. struct sockaddr * f ;
  315. size_t size = sizeof( struct sockaddr_un ) ;
  316. socket_t x = malloc( sizeof( struct SocketType_t ) ) ;
  317. if( x == NULL ){
  318. return _SocketError() ;
  319. }else{
  320. memset( x,'\0',sizeof( struct SocketType_t ) ) ;
  321. x->socket = malloc( size ) ;
  322. if( x->socket == NULL ){
  323. free( x ) ;
  324. x = _SocketError() ;
  325. }else{
  326. x->size = size ;
  327. memset( x->socket,'\0',size ) ;
  328. f = x->socket ;
  329. x->fd = accept( s->fd,f,&x->size ) ;
  330. if( x->fd == -1 ){
  331. free( x->socket ) ;
  332. free( x ) ;
  333. x = SocketVoid ;
  334. }else{
  335. e = s->socket ;
  336. z = x->socket ;
  337. strncpy( z->sun_path,e->sun_path,sizeof( e->sun_path ) ) ;
  338. x->inetAddress = NULL ;
  339. x->domain = s->domain ;
  340. x->type = s->type ;
  341. x->protocol = s->protocol ;
  342. x->cmax = 1 ;
  343. x->socket_server = 0 ;
  344. }
  345. }
  346. return x ;
  347. }
  348. }
  349. static inline socket_t _SocketAcceptNet( socket_t s )
  350. {
  351. struct sockaddr * f ;
  352. size_t size = sizeof( struct sockaddr_in ) ;
  353. socket_t x = ( socket_t ) malloc( sizeof( struct SocketType_t ) ) ;
  354. if( x == NULL ){
  355. return _SocketError() ;
  356. }else{
  357. memset( x,'\0',sizeof( struct SocketType_t ) ) ;
  358. x->socket = malloc( size ) ;
  359. if( x->socket == NULL ){
  360. free( x ) ;
  361. x = _SocketError() ;
  362. }else{
  363. x->size = size ;
  364. memset( x->socket,'\0',size ) ;
  365. f = x->socket ;
  366. x->fd = accept( s->fd,f,&x->size ) ;
  367. if( x->fd == -1 ){
  368. free( x->socket ) ;
  369. free( x ) ;
  370. x = SocketVoid ;
  371. }else{
  372. x->inetAddress = NULL ;
  373. x->domain = s->domain ;
  374. x->type = s->type ;
  375. x->protocol = s->protocol ;
  376. x->cmax = 1 ;
  377. x->socket_server = 0 ;
  378. }
  379. }
  380. return x ;
  381. }
  382. }
  383. static inline socket_t _SocketAcceptNet6( socket_t s )
  384. {
  385. struct sockaddr * f ;
  386. size_t size = sizeof( struct sockaddr_in6 ) ;
  387. socket_t x = malloc( sizeof( struct SocketType_t ) ) ;
  388. if( x == NULL ){
  389. return _SocketError() ;
  390. }else{
  391. memset( x,'\0',sizeof( struct SocketType_t ) ) ;
  392. x->socket = malloc( size ) ;
  393. if( x->socket == NULL ){
  394. free( x ) ;
  395. x = _SocketError() ;
  396. }else{
  397. x->size = size ;
  398. memset( x->socket,'\0',size ) ;
  399. f = x->socket ;
  400. x->fd = accept( s->fd,f,&x->size ) ;
  401. if( x->fd == -1 ){
  402. free( x->socket ) ;
  403. free( x ) ;
  404. x = SocketVoid ;
  405. }else{
  406. x->inetAddress = NULL ;
  407. x->domain = s->domain ;
  408. x->type = s->type ;
  409. x->protocol = s->protocol ;
  410. x->cmax = 1 ;
  411. x->socket_server = 0 ;
  412. }
  413. }
  414. return x ;
  415. }
  416. }
  417. socket_t SocketAccept( socket_t s )
  418. {
  419. switch( s->domain ){
  420. case AF_UNIX : return _SocketAcceptLocal( s ) ;
  421. case AF_INET : return _SocketAcceptNet( s ) ;
  422. case AF_INET6: return _SocketAcceptNet6( s ) ;
  423. default : return SocketVoid ;
  424. }
  425. }
  426. int SocketIsBlocking( socket_t s )
  427. {
  428. int flags ;
  429. if( s == SocketVoid ){
  430. return -1 ;
  431. }else{
  432. flags = fcntl( s->fd,F_GETFL,0 ) ;
  433. return flags != ( flags | O_NONBLOCK ) ;
  434. }
  435. }
  436. #define READ 1
  437. #define WRITE 0
  438. static inline int _SocketNotTimedOut( socket_t s,time_t time,int mode )
  439. {
  440. int fd = s->fd ;
  441. fd_set fdset ;
  442. struct timeval interval ;
  443. memset( &interval,'\0',sizeof( struct timeval ) ) ;
  444. interval.tv_sec = time ;
  445. interval.tv_usec = 0 ;
  446. FD_ZERO( &fdset ) ;
  447. FD_SET( fd,&fdset ) ;
  448. if( mode == READ ){
  449. select( fd + 1,&fdset,NULL,NULL,&interval ) ;
  450. return FD_ISSET( fd,&fdset ) ;
  451. }else{
  452. select( fd + 1,NULL,&fdset,NULL,&interval ) ;
  453. return FD_ISSET( fd,&fdset ) ;
  454. }
  455. }
  456. socket_t SocketAcceptWithTimeOut( socket_t s,time_t time )
  457. {
  458. if( _SocketNotTimedOut( s,time,READ ) ){
  459. return SocketAccept( s ) ;
  460. }else{
  461. return SocketVoid ;
  462. }
  463. }
  464. static inline void _SocketClose( socket_t * p )
  465. {
  466. socket_t s = *p ;
  467. int fd = s->fd ;
  468. struct sockaddr_un * e ;
  469. *p = SocketVoid ;
  470. shutdown( fd,SHUT_RDWR ) ;
  471. close( fd ) ;
  472. if( s->domain == AF_UNIX ) {
  473. if( s->socket_server ){
  474. e = s->socket ;
  475. unlink( e->sun_path ) ;
  476. }
  477. }
  478. free( s->socket ) ;
  479. free( s->inetAddress ) ;
  480. free( s ) ;
  481. }
  482. void SocketClose( socket_t * p )
  483. {
  484. if( p != NULL && *p != SocketVoid ){
  485. _SocketClose( p ) ;
  486. }
  487. }
  488. void SocketCloseWriteChannel( socket_t s )
  489. {
  490. if( s != NULL ){
  491. shutdown( s->fd,SHUT_WR ) ;
  492. }
  493. }
  494. void SocketCloseReadChannel( socket_t s )
  495. {
  496. if( s != NULL ){
  497. shutdown( s->fd,SHUT_RD ) ;
  498. }
  499. }
  500. static inline int _SocketConnect( socket_t s )
  501. {
  502. return connect( s->fd,s->socket,s->size ) == 0 ;
  503. }
  504. int SocketConnect( socket_t * s )
  505. {
  506. if( s == NULL || *s == SocketVoid ){
  507. return 0 ;
  508. }
  509. if( _SocketConnect( *s ) ){
  510. return 1 ;
  511. }else{
  512. _SocketClose( s ) ;
  513. return 0 ;
  514. }
  515. }
  516. void SocketSetListenMaximum( socket_t s,int m )
  517. {
  518. if( s != SocketVoid ){
  519. s->cmax = m ;
  520. }
  521. }
  522. int SocketSetDoNotBlock( socket_t s )
  523. {
  524. int flags ;
  525. if( s == SocketVoid ){
  526. return -1 ;
  527. }else{
  528. flags = fcntl( s->fd,F_GETFL,0 );
  529. if( flags == -1 ){
  530. return -1 ;
  531. }else{
  532. return fcntl( s->fd,F_SETFL,flags | O_NONBLOCK ) ;
  533. }
  534. }
  535. }
  536. int SocketSetBlock( socket_t s )
  537. {
  538. int flags ;
  539. if( s == SocketVoid ){
  540. return -1 ;
  541. }else{
  542. flags = fcntl( s->fd,F_GETFL,0 );
  543. if( flags == -1 ){
  544. return -1 ;
  545. }else{
  546. return fcntl( s->fd,F_SETFL,flags & ~O_NONBLOCK ) ;
  547. }
  548. }
  549. }
  550. int SocketListen( socket_t s )
  551. {
  552. if( s == SocketVoid ){
  553. return 0 ;
  554. }else{
  555. return listen( s->fd,s->cmax ) == 0 ;
  556. }
  557. }
  558. ssize_t SocketGetData_2( socket_t s,char * buffer,size_t len )
  559. {
  560. ssize_t e ;
  561. if( s == SocketVoid ){
  562. return -1 ;
  563. }else{
  564. len = len - 1 ;
  565. e = read( s->fd,buffer,len ) ;
  566. if( e >= 0 ){
  567. buffer[ e ] = '\0' ;
  568. }
  569. return e ;
  570. }
  571. }
  572. ssize_t SocketGetData_3( socket_t s,char * buffer,size_t len,int timeout )
  573. {
  574. if( _SocketNotTimedOut( s,( time_t )timeout,READ ) ){
  575. return SocketGetData_2( s,buffer,len ) ;
  576. }else{
  577. return -1 ;
  578. }
  579. }
  580. #define BUFFSIZE 32
  581. #define BUFFERINIT 64
  582. #define FACTOR 2
  583. static inline char * __expandBuffer( char * buffer,size_t new_size,size_t * buff_size )
  584. {
  585. char * e ;
  586. if( new_size >= *buff_size ){
  587. *buff_size = *buff_size * FACTOR ;
  588. e = realloc( buffer,*buff_size ) ;
  589. if( e == NULL ){
  590. free( buffer ) ;
  591. _SocketError() ;
  592. return NULL ;
  593. }else{
  594. return e ;
  595. }
  596. }else{
  597. return buffer ;
  598. }
  599. }
  600. ssize_t SocketGetData( socket_t s,char ** e )
  601. {
  602. int fd ;
  603. ssize_t result ;
  604. size_t total = 0 ;
  605. size_t buff_size = BUFFERINIT ;
  606. char buffer[ BUFFSIZE ] ;
  607. char * d ;
  608. char * f ;
  609. if( s == SocketVoid ){
  610. return -1 ;
  611. }
  612. f = malloc( sizeof( char ) * buff_size ) ;
  613. if( f == NULL ){
  614. _SocketError() ;
  615. return -1 ;
  616. }else{
  617. fd = s->fd ;
  618. while( 1 ){
  619. result = read( fd,buffer,BUFFSIZE ) ;
  620. if( result <= 0 ){
  621. if( total ){
  622. break ;
  623. }else{
  624. free( f ) ;
  625. return -1 ;
  626. }
  627. }else{
  628. d = __expandBuffer( f,total + result,&buff_size ) ;
  629. if( d == NULL ){
  630. free( f ) ;
  631. _SocketError() ;
  632. return -1 ;
  633. }else{
  634. f = d ;
  635. memcpy( f + total,buffer,result ) ;
  636. total = total + result ;
  637. }
  638. }
  639. }
  640. if( total ){
  641. d = ( char * ) realloc( f,total + 1 ) ;
  642. if( d == NULL ){
  643. free( f ) ;
  644. _SocketError() ;
  645. return -1 ;
  646. }else{
  647. d[ total ] = '\0' ;
  648. *e = d ;
  649. }
  650. }else{
  651. free( f ) ;
  652. }
  653. return total ;
  654. }
  655. }
  656. ssize_t SocketGetData_1( socket_t s,char ** e,size_t len )
  657. {
  658. int fd ;
  659. ssize_t result ;
  660. size_t total = 0 ;
  661. size_t buff_size = BUFFERINIT ;
  662. char buffer[ BUFFSIZE ] ;
  663. char * d ;
  664. char * f ;
  665. if( s == SocketVoid ){
  666. return -1 ;
  667. }
  668. f = malloc( sizeof( char ) * buff_size ) ;
  669. if( f == NULL ){
  670. _SocketError() ;
  671. return -1 ;
  672. }else{
  673. fd = s->fd ;
  674. while( 1 ){
  675. result = read( fd,buffer,BUFFSIZE ) ;
  676. if( result <= 0 ){
  677. if( total ){
  678. break ;
  679. }else{
  680. free( f ) ;
  681. return -1 ;
  682. }
  683. }else{
  684. d = __expandBuffer( f,total + result,&buff_size ) ;
  685. if( d == NULL ){
  686. free( f ) ;
  687. _SocketError() ;
  688. return -1 ;
  689. }else{
  690. f = d ;
  691. memcpy( f + total,buffer,result ) ;
  692. total = total + result ;
  693. if( total >= len ){
  694. total = len ;
  695. break ;
  696. }
  697. }
  698. }
  699. }
  700. if( total ){
  701. d = realloc( f,total + 1 ) ;
  702. if( d == NULL ){
  703. free( f ) ;
  704. _SocketError() ;
  705. return 0 ;
  706. }else{
  707. d[ total ] = '\0' ;
  708. *e = d ;
  709. }
  710. }else{
  711. free( f ) ;
  712. }
  713. return total ;
  714. }
  715. }
  716. ssize_t SocketSendData( socket_t s,const char * buffer,size_t len )
  717. {
  718. if( s == SocketVoid || buffer == NULL || len == 0 ){
  719. return -1 ;
  720. }else{
  721. return write( s->fd,buffer,len ) ;
  722. }
  723. }