Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <sys/select.h>
- #include <errno.h>
- #define BUFL 4096
- int fater(char *mes){
- printf("ERROR: %s\n",mes);
- exit(1);
- }
- void *small(int s){
- void *ret = malloc(s);
- if(!ret)fater("malloc");
- return ret;
- }
- void write_message(int file,char *mes,int len){
- int written,pos;
- for(pos=0;pos<len;pos+=written){
- written=write(file,mes,len);
- if(written==-1)fater("writing");
- }
- }
- struct peers{
- int sock;
- struct sockaddr addr;
- socklen_t addrlen;
- struct peers *next;
- };
- int prepfdset(fd_set *set,struct peers *p,int lstn){
- struct peers *pitr;
- int max=lstn;
- FD_ZERO(set);
- FD_SET(lstn,set);
- for(pitr=p;pitr;pitr=pitr->next){
- FD_SET(pitr->sock,set);
- max=(p->sock>max)?p->sock:max;
- }
- return max+1;
- }
- int main(int argc,char **argv){
- struct addrinfo hints,*res,*itr;
- int lstn;
- int psock;
- int nfds;
- int fd_changes;
- struct peers *p,*pend,*pitr;
- fd_set rfds;
- unsigned char BUF[BUFL];
- size_t recvd,written;
- char hello[]="ECHO: ";
- /*do lots of busywork*/
- p=NULL;
- pend=NULL;
- pitr=NULL;
- lstn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
- if(lstn==-1)fater("making socket");
- int zero=0;
- if(setsockopt(lstn,SOL_SOCKET,SO_REUSEADDR,&zero,sizeof(int)))fater("setsockopt");
- memset(&hints,0,sizeof(struct addrinfo));
- hints.ai_family=AF_INET;
- hints.ai_socktype=SOCK_STREAM;
- if(getaddrinfo(NULL,"3310",&hints,&res))fater("getaddrinfo");
- for(itr=res;itr;itr=itr->ai_next)
- if(!bind(lstn,itr->ai_addr,itr->ai_addrlen))
- break;
- if(!itr)fater("binding");
- freeaddrinfo(res);
- itr=NULL;
- if(listen(lstn,256))fater("HEY, listen!");
- /*get busy*/
- while(1){
- nfds=prepfdset(&rfds,p,lstn);
- fd_changes=select(nfds,&rfds,NULL,NULL,NULL);
- if(!fd_changes) continue;
- if(fd_changes==-1)
- switch(errno){
- /*when a socket is closed, do we handle it here?*/
- default:fater(strerror(errno));
- }
- /*check the listener for incoming connections*/
- if(FD_ISSET(lstn,&rfds)){
- /*linked list of peer management*/
- if(!pend){
- p=small(sizeof(struct peers));
- pend=p;
- } else {
- pend->next=small(sizeof(struct peers));
- pend=pend->next;
- }
- pend->sock=accept(lstn,&(pend->addr),&(pend->addrlen));
- if(pend->sock==-1)fater("accepting");
- /*is that all the fd_set changes?*/
- if(!--fd_changes) continue;
- }
- /*check peers for incoming messages*/
- for(pitr=p;pitr;pitr=pitr->next){
- if(FD_ISSET(pitr->sock,&rfds)){
- recvd=read(pitr->sock,BUF,BUFL);
- /*do we check for closed sockets here, or in select or wot?*/
- if(recvd==-1)fater("reading socket");
- /*HANDLE input - this changes to make an IRC server*/
- write_message(pitr->sock,hello,strlen(hello));
- write_message(pitr->sock,BUF,recvd);
- /*is that all the fd_set changes?*/
- if(!--fd_changes) break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement