void create_client(int sockfd, struct sockaddr_in *addr, socklen_t *addrlen) { char addrstr[INET6_ADDRSTRLEN]; client_t *client; if(sockfd > fd_client_index_limit) { fprintf(stderr, "cannot create any more clients (sockfd > _SO_OPEN_MAX)!\n"); return; } if(fd_client_index[sockfd]) { fprintf(stderr, "FD/client index inconsistent (already set)!\n"); return; } client = calloc(1, sizeof(client_t)); if(client == NULL) { perror("calloc()"); close(sockfd); return; } if(inet_ntop(AF_INET, &(addr->sin_addr), addrstr, INET6_ADDRSTRLEN) == NULL) { perror("inet_ntop()"); kill_client(client); return; } fprintf(stderr, "client connected from %s:%d\n", addrstr, ntohs(addr->sin_port)); client->sockfd = sockfd; client->socklen = addrlen; if((client->addr = calloc(1, *client->socklen)) == NULL) { perror("calloc()"); kill_client(client); return; } memcpy(client->addr, addr, *addrlen); client->is_sender = 1; client->message = first_message; client->last_message = NULL; client_list_add(client); fd_client_index[sockfd] = client; }
void srv_sigchld_handler(int sig){ pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG)) != -1){ kill_client(pid); } }
char * message_client(Client *c, IxpMsg *m) { char *s; int i; s = getword(m); switch(getsym(s)) { case LKILL: kill_client(c); break; case LURGENT: i = gettoggle(m); if(i == -1) return Ebadusage; set_urgent(c, i, True); break; case LFULLSCREEN: i = gettoggle(m); if(i == -1) return Ebadusage; fullscreen(c, i); break; default: return Ebadcmd; } return nil; }
void prepare_msg(char *nick, char *msg, int cs1, t_list **list) { char result[4096]; int i; sprintf(result, "From %s: %s", nick, msg); i = write(cs1, result, strlen(result)); if (i <= 0) kill_client(list, cs1); }
void server_polling(int listener) { int i, fd, res_num; ssize_t n; uint64_t tag; nfds_t pfd_num = MAX_CLIENTS + 1; // + 1 for listener itself struct pollfd pfd[pfd_num]; client = pfd; struct sockaddr cliaddr; socklen_t cliaddrlen; for (i = 0; i < pfd_num; i++) pfd[i].fd = -1; pfd[0].fd = listener; pfd[0].events = POLLIN; while (1) { Log(LOG_DEBUG, "polling......."); if ((res_num = poll(pfd, pfd_num, 10000)) < 0) Log_die(DIE_FAILURE, LOG_ERR, "poll() failed"); if (pfd[0].revents & POLLIN) { // acceptable cliaddrlen = sizeof(struct sockaddr); if ((fd = accept(listener, &cliaddr, &cliaddrlen)) < 0) Log_die(DIE_FAILURE, LOG_ERR, "accept() failed"); for (i = 1; i < pfd_num; i++) if (pfd[i].fd < 0) { pfd[i].fd = fd; //set_nonblock(pfd[i].fd); break; } if (i == pfd_num) Log(LOG_WARNING, "client number over upper limit %d", MAX_CLIENTS); else { pfd[i].events = POLLIN; Log(LOG_NOTICE, "client[%d] connected", i); } if (--res_num <= 0) continue; } for (i = 1; i < pfd_num; i++) { if ((fd = pfd[i].fd) < 0) continue; if (pfd[i].revents & (POLLIN | POLLERR)) { tag = read_tag(fd, NULL); //read_tag(fd, &tag, sizeof(tag), NULL); if ((n < 0 && errno == ECONNRESET) || n == 0) { Log(LOG_NOTICE, "client[%d] reseted/closed connection", i); kill_client(pfd, i); } else if (n < 0) Log_die(DIE_FAILURE, LOG_ERR, "read from client[i] failed", i); else { client_idx = i; tag_switch(tag, fd); } } if (--res_num <= 0) break; } } // end for while(1) .. }
void time_out(int signo) { Log(LOG_DEBUG, "@time_out()"); kill_client(client, client_idx); }
void client_read(client_t *client) { ssize_t read_sz; if(client->rbuf == NULL) { client->rbuf_idx = 0; client->rbuf_sz = BUF_SIZE; client->rbuf = malloc(client->rbuf_sz); if(client->rbuf == NULL) { perror("malloc()"); kill_client(client); pthread_exit((void *) 0); } } while((read_sz = recv(client->sockfd, client->rbuf + client->rbuf_idx, client->rbuf_sz - client->rbuf_idx, MSG_DONTWAIT | MSG_NOSIGNAL)) > 0) { fprintf(stderr, "received %lu+%lu bytes from client %p\n", read_sz, client->rbuf_idx, (void *) client); client->rbuf_idx += read_sz; /* is buffer full */ if(client->rbuf_idx == client->rbuf_sz) { client->rbuf_sz *= 2; if(client->rbuf_sz > BUF_MAX) { fprintf(stderr, "buffer overflow, discarding message\n"); free(client->rbuf); return; } /*fprintf(stderr, "increasing message buffer size to %lu\n", buf_sz);*/ client->rbuf = realloc(client->rbuf, client->rbuf_sz); if(client->rbuf == NULL) { perror("realloc()"); return; } continue; } /* message is complete */ if(client->is_sender) { message_t *message = create_message(client->rbuf, client->rbuf_idx); if(message) fprintf(stderr, "created new message %p (length: %lu) from client %p\n", (void *) message, message->len, (void *) client); } else { fprintf(stderr, "client is not allowed to send messages!\n"); } client->rbuf_idx = 0; } if(read_sz == -1 && errno == EAGAIN) return; if(read_sz == -1) { perror("read()"); kill_client(client); pthread_exit((void *) 0); } }
int send_pending_messages(client_t *client) { message_t *message = client->message; int count = 0; /* fprintf(stderr, "checking for pending message to client %p\n", (void *) client); */ if(message == NULL && client->last_message) { if(client->last_message->next == NULL) return count; message = client->last_message->next; client->mstr_idx = 0; } if(message == NULL) { message = first_message; client->mstr_idx = 0; } while(message) { size_t write_sz = 0; fprintf(stderr, "sending message %p to client\n", (void *)message); client->message = message; while(client->mstr_idx < message->len) { write_sz = send(client->sockfd, message->str + client->mstr_idx, message->len - client->mstr_idx, MSG_DONTWAIT | MSG_NOSIGNAL); if(write_sz == -1) break; fprintf(stderr, "wrote %lu+%lu/%lu bytes of message %p to client %p\n", client->mstr_idx, write_sz, message->len, (void *) message, (void *) client); client->mstr_idx += write_sz; if(client->mstr_idx >= message->len) break; } if(write_sz == -1 && errno == EAGAIN) break; if(write_sz == -1) { perror("send()"); kill_client(client); pthread_exit((void *) 0); return count; } client->last_message = message; client->message = message = message->next; client->mstr_idx = 0; count++; } return count; }
int main(){ setLogDebugLevel( dbgLevel ); setLogFile( logFile ); setLogSilentMode(1); writeLog( 0, "Starting remoteAdv Master Client - Version: %s", version ); // Gets a hostent struct containing data about the given host struct hostent *server = gethostbyname( server_ip ); if(server == NULL) { herror("ERROR: Host lookup failed"); exit(1); } // Create a TCP socket and return a file descriptor for accessing it int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1) { perror("ERROR: Open socket failed"); exit(1); } // Create and initialize a sock_addr struct contianing info about the server to connect to struct sockaddr_in server_addr; memset( &server_addr , 0 , sizeof(server_addr)); // Denotes an internet socket server_addr.sin_family = AF_INET; // Copies several values from the server hostent struct into this one memcpy( &server_addr.sin_addr.s_addr, server->h_addr, server->h_length ); // Sets the server port to the one passed in server_addr.sin_port = server_port; // Connect to the server int connectResult = connect(sockfd,(struct sockaddr*)&server_addr, sizeof(server_addr)); if(connectResult == -1) { perror("ERROR: Connection to server failed"); exit(1); } int auth_result = authenticate( sockfd ); if( auth_result == -1 ) { writeLog( -1, "Server authentication failed" ); exit(1); } else { writeLog( 2, "Server connection successful" ); writeLog( 3, "Connected to server at '%s:%d'", server_ip, server_port ); } int end = 0; // Wait to send commands while( !end ) { printMenu(); // Display options to allow user to see options. int input = 0; scanf( "%d", &input ); switch( input ) { case sel_list_slaves: system( "clear" ); // Clear works on unix like enviorments, this will throw an error on windows. list_slaves( sockfd ); break; case sel_claim_client: system( "clear" ); claim_client( sockfd ); break; case sel_release_client: release_client( sockfd ); break; case sel_set_debug_level: set_debug_level( sockfd ); break; case sel_kill_client: kill_client( sockfd ); break; case sel_close: end = 1; default: break; } fflush( stdout ); system( "clear" ); } // Close the connection to the server close( sockfd ); return 0; }