Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2014
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.10 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netdb.h>
  7. #include <sys/select.h>
  8. #include <errno.h>
  9.  
  10. #define BUFL 4096
  11. int fater(char *mes){
  12. printf("ERROR: %s\n",mes);
  13. exit(1);
  14. }
  15.  
  16. void *small(int s){
  17. void *ret = malloc(s);
  18. if(!ret)fater("malloc");
  19. return ret;
  20. }
  21. void write_message(int file,char *mes,int len){
  22. int written,pos;
  23. for(pos=0;pos<len;pos+=written){
  24. written=write(file,mes,len);
  25. if(written==-1)fater("writing");
  26. }
  27. }
  28. struct peers{
  29. int sock;
  30. struct sockaddr addr;
  31. socklen_t addrlen;
  32. struct peers *next;
  33. };
  34.  
  35. int prepfdset(fd_set *set,struct peers *p,int lstn){
  36. struct peers *pitr;
  37. int max=lstn;
  38. FD_ZERO(set);
  39. FD_SET(lstn,set);
  40. for(pitr=p;pitr;pitr=pitr->next){
  41. FD_SET(pitr->sock,set);
  42. max=(p->sock>max)?p->sock:max;
  43. }
  44. return max+1;
  45. }
  46.  
  47. int main(int argc,char **argv){
  48. struct addrinfo hints,*res,*itr;
  49. int lstn;
  50. int psock;
  51. int nfds;
  52. int fd_changes;
  53. struct peers *p,*pend,*pitr;
  54. fd_set rfds;
  55. unsigned char BUF[BUFL];
  56. size_t recvd,written;
  57. char hello[]="ECHO: ";
  58.  
  59. /*do lots of busywork*/
  60. p=NULL;
  61. pend=NULL;
  62. pitr=NULL;
  63.  
  64.  
  65. lstn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  66. if(lstn==-1)fater("making socket");
  67. int zero=0;
  68. if(setsockopt(lstn,SOL_SOCKET,SO_REUSEADDR,&zero,sizeof(int)))fater("setsockopt");
  69.  
  70. memset(&hints,0,sizeof(struct addrinfo));
  71. hints.ai_family=AF_INET;
  72. hints.ai_socktype=SOCK_STREAM;
  73. if(getaddrinfo(NULL,"3310",&hints,&res))fater("getaddrinfo");
  74.  
  75. for(itr=res;itr;itr=itr->ai_next)
  76. if(!bind(lstn,itr->ai_addr,itr->ai_addrlen))
  77. break;
  78. if(!itr)fater("binding");
  79.  
  80. freeaddrinfo(res);
  81. itr=NULL;
  82.  
  83. if(listen(lstn,256))fater("HEY, listen!");
  84.  
  85. /*get busy*/
  86. while(1){
  87. nfds=prepfdset(&rfds,p,lstn);
  88. fd_changes=select(nfds,&rfds,NULL,NULL,NULL);
  89. if(!fd_changes) continue;
  90. if(fd_changes==-1)
  91. switch(errno){
  92. /*when a socket is closed, do we handle it here?*/
  93. default:fater(strerror(errno));
  94. }
  95.  
  96. /*check the listener for incoming connections*/
  97. if(FD_ISSET(lstn,&rfds)){
  98. /*linked list of peer management*/
  99. if(!pend){
  100. p=small(sizeof(struct peers));
  101. pend=p;
  102. } else {
  103. pend->next=small(sizeof(struct peers));
  104. pend=pend->next;
  105. }
  106. pend->sock=accept(lstn,&(pend->addr),&(pend->addrlen));
  107. if(pend->sock==-1)fater("accepting");
  108. /*is that all the fd_set changes?*/
  109. if(!--fd_changes) continue;
  110. }
  111. /*check peers for incoming messages*/
  112. for(pitr=p;pitr;pitr=pitr->next){
  113. if(FD_ISSET(pitr->sock,&rfds)){
  114. recvd=read(pitr->sock,BUF,BUFL);
  115. /*do we check for closed sockets here, or in select or wot?*/
  116. if(recvd==-1)fater("reading socket");
  117. /*HANDLE input - this changes to make an IRC server*/
  118. write_message(pitr->sock,hello,strlen(hello));
  119. write_message(pitr->sock,BUF,recvd);
  120. /*is that all the fd_set changes?*/
  121. if(!--fd_changes) break;
  122. }
  123. }
  124. }
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement