Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "tinypy.h"
  2. #include <sys/socket.h>
  3.  
  4. #define  GET_STR_ARG() TP_TYPE(TP_STRING).string.val
  5. #define  NET_ERROR(FUNC, MSG)  if(FUNC==-1){ tp_raise_f(tp_None, "%s Error code: %d", MSG , err_code);}
  6.  
  7. static tp_obj inet_pton(TP, const char *buf, int len, unsigned *addr)
  8. {
  9.     char *p = (char *)buf;
  10.     int i = 0;
  11.     unsigned val = 0;
  12.     *addr = 0;
  13.     while (*p && p < buf + len && i < 4){
  14.         if (*p == '.' || !*p){
  15.             if (val > 255)
  16.                 tp_raise(tp_None, tp_string("ValueError: number > 255 in IP address"));
  17.             *addr += (val << ((i++) << 3));
  18.             val = 0;
  19.         }else{
  20.             if (*p < '0' || *p > '9')
  21.                 tp_raise(tp_None, tp_string("ValueError: bad char in IP address, digit expected"));
  22.             val = val * 10 + *p - '0';
  23.         }
  24.         p++;
  25.     }
  26.     if (!*p){
  27.         if (i == 3){
  28.             *addr += (val << ((i++) << 3));
  29.         }else{
  30.             tp_raise_f(tp_None, "ValueError: bad IP address!", tp_None);
  31.         }
  32.     }
  33.  }
  34.  
  35. static tp_obj _close(TP){
  36.     tp_obj socket_info=TP_TYPE(TP_DICT);
  37.     int id = (int)tp_get(tp, socket_info, tp_string("id")).number.val;
  38.     NET_ERROR(close(id), "Unable to close socket!")
  39.     else{
  40.         tp_set(tp, socket_info, tp_string("closed"), tp_True);
  41.     }
  42.     return tp_None;
  43. }
  44.  
  45. static tp_obj _bind(TP)
  46. {
  47.     tp_obj self = TP_TYPE(TP_DICT);
  48.     const char* local_addr = TP_TYPE(TP_STRING).string.val;
  49.     unsigned local_port = PORT((unsigned)TP_NUM());
  50.    
  51.     unsigned addr_n;
  52.     inet_pton(tp, local_addr, strlen(local_addr), &addr_n);
  53.     unsigned family  = (unsigned)tp_get(tp, self, tp_string("domain")).number.val;
  54.     int id = (int)tp_get(tp, self, tp_string("id")).number.val;
  55.     struct sockaddr addr={addr_n, family, local_port,0};    
  56.     NET_ERROR(bind(id, &addr, sizeof(addr)), "Bind error!");
  57.     return tp_None;
  58. }
  59.  
  60. static tp_obj _listen(TP){
  61.     int backlog = (int)TP_NUM();
  62.     tp_obj socket_obj = TP_TYPE(TP_DICT);
  63.     int id = (int)tp_get(tp,socket_obj, tp_string("id")).number.val;
  64.     NET_ERROR(listen(id, backlog), "Listen error!");
  65.     return tp_None;
  66. }
  67.  
  68. static tp_obj _send(TP){
  69.     const char * msg = GET_STR_ARG();
  70.     tp_obj socket_obj = TP_TYPE(TP_DICT);
  71.     int id = (int)tp_get(tp,socket_obj, tp_string("id")).number.val;
  72.     NET_ERROR(send(id, (const void*)msg, strlen(msg), MSG_NOFLAG),"Sending failed!");
  73.     return tp_None;
  74. }
  75.  
  76. static tp_obj _connect(TP)
  77. {
  78.     tp_obj self = TP_TYPE(TP_DICT);
  79.     const char* local_addr = TP_TYPE(TP_STRING).string.val;
  80.     unsigned local_port = PORT((unsigned)TP_NUM());
  81.    
  82.     unsigned addr_n;
  83.     inet_pton(tp, local_addr, strlen(local_addr), &addr_n);
  84.     unsigned family  = (unsigned)tp_get(tp, self, tp_string("domain")).number.val;
  85.     int id = (int)tp_get(tp, self, tp_string("id")).number.val;
  86.     struct sockaddr addr={addr_n, family, local_port,0};    
  87.     NET_ERROR(connect(id, &addr, sizeof(addr)), "Connection failed!");
  88.     return tp_None;
  89. }
  90.  
  91. static tp_obj _socket(TP){
  92.     int domain = (int)TP_NUM();
  93.     int type = (int)TP_NUM();
  94.     int protocol=(int)TP_NUM();
  95.     int id = socket(domain, type, protocol);
  96.     tp_obj socket_info=tp_dict(tp);
  97.     NET_ERROR(id, "Unable to open socket!")
  98.     else{
  99.         tp_set(tp, socket_info, tp_string("id"), tp_number(id));
  100.         tp_set(tp, socket_info, tp_string("domain"), tp_number(domain));
  101.         tp_set(tp, socket_info, tp_string("type"), tp_number(type));
  102.         tp_set(tp, socket_info, tp_string("protocol"), tp_number(protocol));
  103.     }
  104.     tp_set(tp, socket_info, tp_string("connect"), tp_method(tp, socket_info, _connect));
  105.     tp_set(tp, socket_info, tp_string("bind"), tp_method(tp, socket_info, _bind));
  106.     tp_set(tp, socket_info, tp_string("close"), tp_method(tp, socket_info, _close));
  107.     tp_set(tp, socket_info, tp_string("send"), tp_method(tp, socket_info, _send));
  108.     return socket_info;
  109. }
  110.  
  111.  
  112.