static gboolean package_write (xmms_vis_client_t *c, int32_t id, struct timeval *time, int channels, int size, short *buf) { if (c->type == VIS_UNIXSHM) { return write_shm (&c->transport.shm, c, id, time, channels, size, buf); } else if (c->type == VIS_UDP) { return write_udp (&c->transport.udp, c, id, time, channels, size, buf, vis->socket); } return FALSE; }
/* Make writes even "more" of a race condition */ void slowwrite(medium_s *medium, void *buf, size_t size) { size_t i; medium->size = 0; for(i = 0; i < size; i++) { write_shm(medium, buf+i, sizeof(char)); medium->size++; } }
main ( int argc, char **argv) { struct sockaddr_in sa; struct sockaddr_in caller; int ssd, csd, length, flag = 1 ; char cnt_name[ 20 ] ; int i, n, key, savesig ; pid_t pid, loop_pid ; struct client_ds *c_data ; struct sigaction usr2act ; sigset_t usr2mask, savemask, zeromask ; if ( argc != 2 ) err_quit ( "Usage: %s <port>", argv[0] ) ; if ( signal ( SIGUSR1, SIG_IGN ) == SIG_ERR ) err_sys ( "signal error" ) ; if ( signal ( SIGINT, sig_term ) == SIG_ERR ) err_sys ( "signal error" ) ; usr2act.sa_handler = sigusr2 ; usr2act.sa_flags = SA_NOMASK ; if ( sigaction ( SIGUSR2, &usr2act, NULL ) == -1 ) err_sys ( "sigaction error" ) ; sigemptyset ( &zeromask ) ; sigemptyset ( &usr2mask ) ; sigaddset ( &usr2mask, SIGUSR2 ) ; atexit ( end_func ) ; key = p_key = atoi(argv[1]) ; sa.sin_family= AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port= htons((u_short)atoi(argv[1])) ; if ((ssd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_sys ("socket error"); if (bind(ssd, (struct sockaddr *)&sa, sizeof sa) < 0) err_sys ("bind error"); if ( ( p_semid = semget ( p_key, 1, IPC_CREAT | 0700 ) ) == -1 ) err_sys ( "semget error" ) ; init ( p_semid, 0 ) ; if ( ( p_shmid = shmget ( p_key, 8192, IPC_CREAT | 0700 ) ) == -1 ) err_sys ( "shmget" ) ; write_shm ( p_semid, p_shmid, "No Data" ) ; if ( listen (ssd, MAXCLIENT) ) err_quit ( "listen error" ) ; length = sizeof(sa); L_Client = MakeEmpty ( L_Client ) ; i = 0 ; while ( flag ) { sigsetjmp ( s_env, savesig ) ; printf ( "Waiting for Connection...\n" ) ; if ((csd = accept(ssd, (struct sockaddr *)&caller, &length)) < 0) err_sys ( "acccept" ) ; if ( sigprocmask ( SIG_BLOCK, &usr2mask, &savemask ) < 0 ) err_quit ( "sigprocmask error" ) ; if ( c_count == MAXCLIENT ) { send ( csd, "server is too busy!!!\n", 23, MSG_DONTWAIT ) ; if ( sigprocmask ( SIG_SETMASK, &savemask, NULL ) < 0 ) err_quit ( "sigprocmask error" ) ; close( csd ) ; siglongjmp ( s_env, 0 ) ; } c_data = malloc ( sizeof ( struct client_ds ) ) ; if ( ( n = recv ( csd, cnt_name, sizeof(cnt_name), 0 ) ) < 0 ) err_sys ( "read error" ) ; if ( cnt_name[ n-1 ] == '\n' ) cnt_name[ n-1 ] = 0 ; cnt_name[ n ] = 0 ; strcpy ( c_data->c_name, cnt_name ) ; if ( ( c_data->c_semid = semget ( ++key, 1, IPC_CREAT | 0700 ) ) == -1 ) err_sys ( "semget error" ) ; init ( c_data->c_semid, 0 ) ; if ( ( c_data->c_shmid = shmget ( key, 8192, IPC_CREAT | 0700 ) ) == -1 ) err_sys ( "shmget" ) ; write_shm ( c_data->c_semid, c_data->c_shmid, "No Data" ) ; c_data->c_fd = csd ; c_data->c_pid = 0 ; printf ( "Client is connected %d\n", csd ) ; if ( ( pid = fork ( ) ) == -1 ) err_sys ( "fork error" ) ; else if ( pid == 0 ) { close( ssd ) ; if ( handle_client ( c_data ) != 0 ) err_sys ( "error handling client" ) ; printf ( "Exiting\n" ) ; exit ( 0 ) ; } c_data->c_pid = pid ; if ( waitpid ( pid, NULL, WNOHANG ) == -1 ) err_sys ( "waitpid error" ); Insert ( c_data, L_Client, L_Client ) ; c_count++ ; if ( sigprocmask ( SIG_SETMASK, &savemask, NULL ) < 0 ) err_quit ( "sigprocmask error" ) ; } close(ssd); printf ( "Removing Public Shared memory\n" ) ; semdel ( p_semid ) ; shmdel ( p_shmid ) ; exit(0); }
void send_private( int sno ) { int i ; Position Pos, TmpPos; char touser[ NAMSIZ ], Buf[ MAXBUF ], Tmp[ MAXBUF ] ; Pos = L_Client->Next ; while ( Pos != NULL ) { if (sempid(Pos->Element->c_semid, 0)==Pos->Element->c_pid) { read_shm ( Pos->Element->c_semid, Pos->Element->c_shmid, Buf ) ; printf ( "Message Got :%s:\n", Buf ) ; if ( strcmp ( Buf, "Quit" ) == 0 ) { write_shm ( Pos->Element->c_semid, Pos->Element->c_shmid, "Finished" ) ; if ( waitpid ( Pos->Element->c_pid, NULL, 0 ) == -1 ) err_sys ( "waitpid error" ) ; semdel ( Pos->Element->c_semid ) ; shmdel ( Pos->Element->c_shmid ) ; close ( Pos->Element->c_fd ) ; printf ( "Removing the user from List >>%s<<\n", Pos->Element->c_name ) ; Delete ( Pos->Element->c_name, L_Client ) ; c_count-- ; printf ( "Client Process Removed\n" ) ; return ; } else if ( strcmp ( Buf, "list" ) == 0 ) { printf ( "Got Message from %s To List Users\n", Pos->Element->c_name ) ; TmpPos = L_Client->Next ; while ( TmpPos != NULL ) { sprintf ( Tmp, "%s\n", TmpPos->Element->c_name ) ; send ( Pos->Element->c_fd, Tmp, strlen ( Tmp ), MSG_DONTWAIT ) ; TmpPos = TmpPos->Next ; } send( Pos->Element->c_fd, prompt[0], strlen(prompt[0]), MSG_DONTWAIT); write_shm ( Pos->Element->c_semid, Pos->Element->c_shmid, "No Data" ) ; return ; } else { touser[ 0 ] = '\0' ; for ( i = 1; Buf[ i ] != '>'; i++ ) touser[ i-1 ] = Buf[ i ]; touser[ i-1 ] = '\0' ; printf ( "Searching For User %s\n", touser ) ; TmpPos = Find ( touser, L_Client ) ; if ( TmpPos == NULL ) { printf ( "%s: User Not Available\n", touser ) ; sprintf ( Tmp, "%s: User Not Available\n>>", touser ) ; send ( Pos->Element->c_fd, Tmp, strlen ( Tmp ), MSG_DONTWAIT ) ; write_shm ( Pos->Element->c_semid, Pos->Element->c_shmid, "No Data" ) ; return ; } printf ( "%s: User Available\n", touser ) ; sprintf ( Tmp, "PRIVATE Message From %s: %s\n>>", Pos->Element->c_name, &Buf[ i+1 ] ) ; printf ( "PRIVATE Message From %s: %s\n", Pos->Element->c_name, &Buf[ i+1 ] ) ; send ( TmpPos->Element->c_fd, Tmp, strlen ( Tmp ), MSG_DONTWAIT ) ; sprintf ( Tmp, "Message Has been recevied by %s\n>>", touser ) ; printf ( "Message Has been recevied by %s\n", touser ) ; send ( Pos->Element->c_fd, Tmp, strlen ( Tmp ), MSG_DONTWAIT ) ; write_shm ( Pos->Element->c_semid, Pos->Element->c_shmid, "No Data" ) ; } } Pos = Pos->Next ; } }
int handle_client ( struct client_ds *cds ) { int retval ; int action = -1 ; int savesig ; char tmp[MAXBUF], buf[MAXBUF], touser[ NAMSIZ ] ; struct sigaction act; int csd ; csd = cds->c_fd ; if ( signal ( SIGUSR1, sigusr ) == SIG_ERR ) err_sys ( "signal error" ) ; sprintf ( buf, "Client Name: %s\n", cds->c_name ) ; send(csd, buf, strlen(buf), MSG_DONTWAIT); send( csd, prompt[1], strlen(prompt[1]), MSG_DONTWAIT ); if ( sigsetjmp ( c_env, savesig ) == 1 ) { read_shm ( p_semid, p_shmid, buf ) ; send(csd, buf, strlen(buf), MSG_DONTWAIT); send( csd, prompt[0], strlen(prompt[0]), MSG_DONTWAIT ); } while(action != 2){ if((retval = recv(csd, buf, sizeof(buf), 0) ) < 0) err_sys("Reading stream message\n"); buf[retval]='\0'; if (strcmp(buf,"help\n")==0) action=0; if (strcmp(buf,"list\n")==0) action=7; if (strcmp(buf,"pub\n")==0) action=1; if (strcmp(buf,"quit\n")==0 || retval==0) action=2; if (strcmp(buf,"pri\n")==0) action=1; if (strcmp(buf,"\n")==0) action=3; switch (action) { case 0: send(csd, prompt[1], strlen(prompt[1]), MSG_DONTWAIT); action=-1; break; case 1: if (strcmp(buf,"pri\n")==0) { send(csd, prompt[4], strlen(prompt[4]), MSG_DONTWAIT); action = 5 ; } else { send(csd, prompt[2], strlen(prompt[2]), MSG_DONTWAIT); action = 4 ; } break; case 2: write_shm ( cds->c_semid, cds->c_shmid, "Quit" ) ; kill ( getppid( ), SIGUSR2 ) ; while ( sempid( cds->c_semid, 0 ) == getpid () ) sleep ( 1 ) ; printf("\nEnding connection ...\n"); return 0 ; break; case 3: send(csd, prompt[3], strlen(prompt[3]), MSG_DONTWAIT); action=-1; break; case 4: printf ( "server recevied: %s\n", buf ) ; sprintf ( tmp, "Message From %s: %s\n", cds->c_name, buf ) ; write_shm ( p_semid, p_shmid, tmp ) ; kill ( 0, SIGUSR1 ) ; action=3; break ; case 5: buf[ strlen( buf ) - 1 ] = '\0' ; printf ( "getting private message for %s\n", buf ) ; sprintf ( touser, "%s", buf ) ; send(csd, prompt[2], strlen(prompt[2]), MSG_DONTWAIT); action=6; break; case 6: sprintf ( tmp, "<%s>%s", touser, buf ) ; write_shm ( cds->c_semid, cds->c_shmid, tmp ) ; kill ( getppid( ), SIGUSR2 ) ; action=3; break ; case 7: write_shm ( cds->c_semid, cds->c_shmid, "list" ) ; kill ( getppid( ), SIGUSR2 ) ; action=3; break ; default: send(csd, prompt[3], strlen(prompt[3]), MSG_DONTWAIT); } } close(csd); return 1 ; }