3

mb_api.c

  1. #include "mb_api.h"
  2. #include "mb_sio.h"
  3.  
  4. #include "mbdef.h"
  5.  
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8.  
  9. #if defined( LINUX ) || defined(HPUX)
  10. #else
  11. #include <sys/select.h>
  12. #endif
  13.  
  14. #include <sys/param.h>
  15.  
  16. #include <unistd.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #if defined( SUN ) || defined( LINUX )
  22. #include <netinet/in.h>
  23. #endif
  24. #include <netdb.h>
  25.  
  26. #include <errno.h>
  27. #if !defined( LINUX )
  28. extern char *sys_errlist[];
  29. #endif
  30.  
  31. #ifndef MIN
  32. #define MIN(x, y) ((x) < (y) ? (x) : (y))
  33. #endif
  34. #ifndef MAX
  35. #define MAX(x, y) ((x) < (y) ? (y) : (x))
  36. #endif
  37.  
  38. static int pagesize = MB_PAGESIZE;
  39.  
  40. int mb_getpagesize( ) {
  41.     return pagesize;
  42. }
  43.  
  44. int mb_setpagesize( int size ) {
  45.     if ( size > 0 )
  46.         pagesize = size;
  47.  
  48.     return pagesize;
  49. }
  50.  
  51. int mb_send( int socket, char *peer, int msg_type, int msg_id, int msg_len, u_char *msg ) {
  52.     u_char str[ 128 ];
  53.     int cnt;
  54.     int n, w;               /* write status */
  55.  
  56.     n = sprintf( (char *)str, "%c%c%s%c%u%c%u%c", MB_STAMP, msg_type, peer, 0, msg_id, 0, msg_len, 0 );
  57.     if ( s_write( socket, str, n ) < 0 )
  58.         return -1;
  59.  
  60.     if ( msg_len > 0 ) {    /* write msg */
  61.         cnt = 0;
  62.         do {
  63.             n = MIN( msg_len, pagesize );
  64.             w = s_write( socket, msg + cnt, n );
  65.             if ( w < 0 )
  66.                 return -1;
  67.  
  68.             cnt += w;
  69.         }
  70.         while ( msg_len -= w );
  71.     }
  72.  
  73.     return 0;
  74. }
  75.  
  76. int mb_reply( int socket, int msg_id, int msg_len, u_char *msg ) {
  77.     u_char str[ 128 ];
  78.     int n, w;
  79.  
  80.     n = sprintf( (char *)str, "%c%c%u%c%u%c", MB_STAMP, MB_REPLY, msg_id, 0, msg_len, 0 );
  81.  
  82.     w = s_write( socket, str, n );
  83.     if ( w < 0 )
  84.         return -1;
  85.  
  86.     if ( msg_len > 0 ) {    /* write msg */
  87.         int cnt = 0;
  88.         n = MIN( msg_len, pagesize );
  89.         do {
  90.             w = s_write( socket, msg + cnt, n );
  91.             if ( w < 0 )
  92.                 return -1;
  93.  
  94.             cnt += w;
  95.         }
  96.         while ( msg_len -= w );
  97.     }
  98.  
  99.     return 0;
  100. }
  101.  
  102. int mb_reply_nobody( int socket, int msg_id ) {
  103.     u_char str[ 128 ];
  104.     int n;
  105.  
  106.     n = sprintf( (char *)str, "%c%c%u%c", MB_STAMP, MB_NOBODY, msg_id, 0 );
  107.  
  108.     return s_write( socket, str, n );
  109. }
  110.  
  111. int mb_reply_timeout( int socket, int msg_id ) {
  112.     u_char str[ 128 ];
  113.     int n;
  114.  
  115.     n = sprintf( (char *)str, "%c%c%u%c", MB_STAMP, MB_TIMEOUT, msg_id, 0 );
  116.  
  117.     return s_write( socket, str, n );
  118. }
  119.  
  120. int mb_register( int socket, int msg_id, char *app_name, int sync ) {
  121.     u_char str[ 128 ];
  122.     int n;
  123.  
  124.     n = sprintf( (char *)str, "%c%c%u%c%s%c", MB_STAMP, MB_REGISTER, msg_id, 0, app_name, 0 );
  125.  
  126.     if ( s_write( socket, str, n ) == -1 )
  127.         return -1;
  128.  
  129.     if ( sync ) {
  130.         int msg_id, msg_len;
  131.         u_char *msg;
  132.  
  133.         if ( mb_receive( socket, &msg_id, &msg_len, &msg ) == -1 )
  134.             return -1;
  135.  
  136.         n = atoi( (const char *)msg );
  137.         free( msg );
  138.  
  139.         return n;
  140.     }
  141.     return 0;
  142. }
  143.  
  144. int mb_probe( int socket, int msg_id, char *app_name, int sync ) {
  145.     u_char str[ 128 ];
  146.     int n;
  147.  
  148.     n = sprintf( (char *)str, "%c%c%u%c%s%c", MB_STAMP, MB_PROBE, msg_id, 0, app_name, 0 );
  149.  
  150.     if ( s_write( socket, str, n ) == -1 )
  151.         return -1;
  152.  
  153.     if ( sync ) {
  154.         int msg_id, msg_len;
  155.         u_char *msg;
  156.  
  157.         if ( mb_receive( socket, &msg_id, &msg_len, &msg ) == -1 )
  158.             return -1;
  159.  
  160.         n = atoi( (const char *)msg );
  161.         free( msg );
  162.  
  163.         return n;
  164.     }
  165.     return 0;
  166. }
  167.  
  168. int mb_receive( int socket, int *msg_id, int *msg_len, u_char **msg ) {
  169.     int msg_type;
  170.     int c, r;
  171.  
  172. #if 0
  173.     fd_set read_fds;
  174.     int n_fds = FD_SETSIZE;
  175.  
  176.     struct timeval time_out;
  177.  
  178.     FD_ZERO( &read_fds );
  179.     FD_SET( socket, &read_fds );
  180.  
  181.     time_out.tv_sec = 0L;
  182.     time_out.tv_usec = 0L;
  183.  
  184.     /* peek socket */
  185.     if ( select( n_fds, &read_fds, 0, 0, &time_out ) == 0 )
  186.         return 0;
  187. #endif
  188.  
  189.     if ( (c = s_getc( socket )) == MB_STAMP ) {
  190.         msg_type = s_getc( socket );
  191.         switch ( msg_type ) {
  192.         case MB_ONEWAY:
  193.         case MB_TWOWAY:
  194.         case MB_MULTIWAY:
  195.         case MB_REPLY:
  196.         case MB_NOBODY:
  197.         case MB_TIMEOUT:
  198.         case MB_REGISTER:
  199.         case MB_PROBE:
  200.             if ( (*msg_id = s_getuint( socket )) < 0 )
  201.                 return -1;
  202.  
  203.             if ( msg_type == MB_NOBODY || msg_type == MB_TIMEOUT )
  204.                 return msg_type;
  205.  
  206.             if ( (*msg_len = s_getuint( socket )) < 0 )
  207.                 return -1;
  208.            
  209.             if ( *msg_len > 0 ) {
  210.                 int cnt = 0;
  211.                 int len = *msg_len;
  212.                 *msg = (u_char *)malloc( len );
  213.  
  214.                 if ( !*msg )    /* just cautious */
  215.                     break;
  216.  
  217.                 do {
  218.                     r = s_read( socket, *msg + cnt, MIN( len, pagesize ));
  219.                     if ( r < 0 ) {
  220.                         free( *msg );
  221.                         return -1;
  222.                     }
  223.                     cnt += r;
  224.                 }
  225.                 while ( len -= r );
  226.             }
  227.             else
  228.                 *msg = 0;
  229.  
  230.             return msg_type;
  231.  
  232.         default:
  233.             /* error */
  234.             break;
  235.         }
  236.     }
  237.     /* protocol error */
  238.     close( socket );
  239.     return -1;
  240. }
  241.  
  242. static int bind_unix( char *name ) {
  243.     int sd;
  244.     struct sockaddr sd_address;
  245.     char pathname[ MAXPATHLEN ];
  246.  
  247.     if ( (sd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1 )
  248.         return -1;
  249.  
  250.     sd_address.sa_family = AF_UNIX;
  251.     sprintf( pathname, "%s/%s", MB_UNIX, name == 0 ? MB_INET : name );
  252.     (void)strcpy( sd_address.sa_data, pathname );
  253.  
  254.     if ( connect( sd, &sd_address, sizeof( struct sockaddr )) == -1 ) {
  255.         close( sd );
  256.         return -1;
  257.     }
  258.  
  259.     return sd;
  260. }
  261.  
  262. static int bind_inet( char *host, char *port_name ) {
  263.     int sd;
  264.     struct hostent *hp;
  265.     struct sockaddr_in sd_address;
  266.     struct servent *serv;
  267.  
  268.     if ( (hp = gethostbyname( host )) == 0 )
  269.         return -3;
  270.     endhostent();
  271.  
  272.     if ( (serv = getservbyname( port_name == 0 ? MB_INET : port_name, "tcp" )) == 0 )
  273.         return -2;
  274.     endservent();
  275.  
  276.     if ( (sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 )
  277.         return -1;
  278.  
  279.     sd_address.sin_family = AF_INET;
  280.     sd_address.sin_addr.s_addr = *((u_long *)hp->h_addr);
  281.     sd_address.sin_port = serv->s_port;
  282.  
  283.     if ( connect( sd, (struct sockaddr *)&sd_address, sizeof( struct sockaddr_in )) == -1 ) {
  284.         close( sd );
  285.         return -1;
  286.     }
  287.  
  288.     return sd;
  289. }
  290.  
  291. int mb_bind( char *host, char *port_name ) {
  292.     return host ? bind_inet( host, port_name ) : bind_unix( port_name );
  293. }
  294.  
  295. int mb_unbind( int socket ) {
  296.     return close( socket );
  297. }

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].