// // This is called from our userinput.c if the type of object is unregistered // int reg_userinput( lion_t *handle, void *user_data, int status, int size, char *line) { object_t *node = (object_t *) user_data; // Get our object struct // We should _always_ have a object node here, since we are only called // from userinput.c if we did have one. But, for sanity.... if (!node) return 0; // Check which event we got and process... switch( status ) { case LION_CONNECTION_LOST: printf("Connection '%p' (%s) was lost: %d:%s\n", handle, node->username, size, line); say_all("%s connection lost: %d:%s\r\n", node->username, size, line); node->handle = NULL; object_free( node ); break; case LION_CONNECTION_CLOSED: printf("Connection '%p' (%s) was gracefully closed.\n", handle, node->username); say_all("%s disconnected.\r\n", node->username); node->handle = NULL; object_free( node ); break; // We have a new connection, send the greeting: // This isn't called here. We leave it for debugging reasons. case LION_CONNECTION_CONNECTED: break; case LION_BUFFER_USED: break; case LION_BUFFER_EMPTY: break; case LION_INPUT: if (!strncasecmp("quit", line, 4)) { lion_close(handle); break; } if (!strncasecmp("who", line, 4)) { command_who(node); break; } say_all("<%s> %s\r\n", node->username, line); break; case LION_BINARY: break; } return 0; }
int main(int argc, char * argv[]) { int maxfd, listenfd, connfd, sockfd; int len,i,nready,size; int clientsNumber = 0, groupsNumber = 0; Usuario client[FD_SETSIZE]; Grupo grupo[FD_SETSIZE]; fd_set rset, allset; char buf[MAXLINE]; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; int serv_port; if (argc==2) { serv_port = atoi(argv[1]); } else { fprintf(stderr, "usage: ./server port\n"); exit(1); } if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); return 1; } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(serv_port); /* SO_REUSEADDR */ /*int activate = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &activate, sizeof(activate));*/ if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { perror("bind error"); close(listenfd); return 1; } if (listen(listenfd, LISTENQ) < 0) { perror("listen error"); close(listenfd); return 1; } maxfd = listenfd; for(i = 0; i < FD_SETSIZE; i++) { client[i].userfd = -1; client[i].name[0] = '\0'; grupo[i].name[0] = '\0'; inicializa(&(grupo[i].membros)); } FD_ZERO(&allset); if (listenfd >= FD_SETSIZE || listenfd < 0) { perror("FD_SET error (invalid listenfd)"); exit(1); } FD_SET(listenfd, &allset); for ( ; ; ) { rset = allset; /* structure assignment */ if ((nready = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0){ perror("select error"); exit(1); } if (FD_ISSET(listenfd, &rset)) { /* new client connection */ clilen = sizeof(cliaddr); if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) { perror("accept error"); exit(1); } if ((len = recv(connfd, buf, MAXLINE, 0)) < 0) { perror("recv name error"); exit(1); } printf("New Connection!\n"); for(i = 0; i < clientsNumber; i++) { if(strcmp(client[i].name, buf) == 0) { printf("Old User!\n"); break; } } if (i == FD_SETSIZE) { perror("too many clients"); exit(1); } if (client[i].userfd < 0) { client[i].userfd = connfd; /* save descriptor */ if(i == clientsNumber) { clientsNumber++; strcpy(client[i].name, buf); printf("New client registered!\n"); } else { printf("Welcome back %s\n", client[i].name); } FD_SET(connfd, &allset); /* add new descriptor to set */ if (connfd > maxfd) maxfd = connfd; /* for select */ if (send(connfd, buf, len, 0) < 0) { perror("send confirm name"); exit(1); } } else { close(connfd); //already connected } if (connfd >= FD_SETSIZE || connfd < 0) { perror("FD_SET error (invalid connfd)"); exit(1); } if (--nready <= 0) continue; /* no more readable descriptors */ } for (i = 0; i <= clientsNumber; i++) { /* check all clients for data */ if ( (sockfd = client[i].userfd) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if ( (len = read(sockfd, buf, MAXLINE)) == 0) { /* connection closed by client */ close(sockfd); printf("Client %s logout!\n", client[i].name); if (sockfd >= FD_SETSIZE || sockfd < 0) { perror("FD_CLR error"); exit(1); } FD_CLR(sockfd, &allset); client[i].userfd = -1; } else { if((size = strlen(buf)) < len - 2) { } else { if(strncmp(buf, "WHO", 3) == 0) { printf("WHO\n"); command_who(client, clientsNumber, sockfd); } else if (strncmp(buf, "CREATEG ", 8) == 0) { printf("CREATEG\n"); command_create_group(&groupsNumber, sockfd, i, buf+8, grupo); } else if (strncmp(buf, "JOING ", 6) == 0) { printf("JOING\n"); command_join_group(groupsNumber, sockfd, i, buf+6, grupo); } else if (strncmp(buf, "SEND ", 5) == 0) { printf("SEND\n"); command_send(client[i].name, buf, clientsNumber, client); } else if (strncmp(buf, "SENDG ", 6) == 0) { printf("SENDG\n"); command_send_group(); } } //send(sockfd, buf, len, 0); } if (--nready <= 0) break; /* no more readable descriptors */ } } } }