Szanowni Państwo,

bardzo proszę o pomoc w dorobieniu kodu do zapytania:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

#define MAXLOGIN 65
#define MAXCLIENTS 100

/*
1. Zakaz multilogowania - wylogować poprzedniego klienta
2. /receiver * - broadcast
3. informacje do użytkowników niezalogowanych są buforowane na serwerze (np. utworzyć na serwerze plik z nazwą klienta i po zalogowaniu dostaje wszystkie wiadomości)
*/

struct svc_arg *tab[MAXCLIENTS] = { NULL };

// przerabiamy tak aby każdy user mógł zobaczyć kto jest zalogowany
struct svc_arg 
{
	int sock;
	char login[MAXLOGIN];
	char receiver[MAXLOGIN];
	FILE *in;
	FILE *out;
};

int nclients = 0;

void *service(void *arg)
{
    int i, poz;
    int exitflag = 0;
    struct svc_arg *a = (struct svc_arg *) arg;
    
    if(nclients == MAXCLIENTS)
	{
		shutdown(a->sock, SHUT_RDWR); // żeby na niektórych wersjach nc działało
		close(a->sock);
		free(a);
		return;
	}
	
	for(poz = 0; poz < MAXCLIENTS; poz++)
	{
		if(tab[poz] == NULL)
		{
			tab[poz] = a;
			nclients++;
			break;
		}
	}

	pthread_detach(pthread_self());
    //FILE *in = fdopen(a->sock, "r"); // wprowadzamy strumienie danych otwarty do odczytu
    //FILE *out = fdopen(a->sock, "w"); // zapis
	a->in = fdopen(a->sock, "r"); // wprowadzamy strumienie danych otwarty do odczytu
    a->out = fdopen(a->sock, "w"); // zapis
    setlinebuf(a->in);
    setlinebuf(a->out);
    //printf("%d\n", a->sock);
    fprintf(a->out, "Welcome\n");
    //fflush(out); // setlinebuf wysyła na bufor po zakończeniu linii
	for(;;) // będziemy czytać łańcuch znaków
    {
    	char buf[1024];
     	char cmd[1024];
      	char par[1024];
      	char text[1024];
      	int czyDoszlo;
      
      	if(!fgets(buf, sizeof(buf), a->in))
			break;

	    int n = strlen(buf);
      	while(--n >= 0)
      	{
			if(buf[n] == '\n' || buf[n] == '\r')
	  			buf[n] = 0;
			else
	  			break;
      	}
		//if(buf[0] == 'q') // wyłączenie serwera po wpisaniu q
		//break;
      
		switch(buf[0])
      	{
			case 0:
		  		break;
			case '/':
			 	// polecenie
			  	par[0] = 0;
			  	sscanf(buf + 1, "%s %s", cmd, par);
			  	if(!strcmp(cmd, "quit"))
			  	{
					exitflag = 1;
					break;
		  		}
		  		if(!strcmp(cmd, "ver"))
		  		{
					fprintf(a->out, "Ver 0.1\n");
					break;
		  		}
				if(!strcmp(cmd, "login"))
				{
					for (i = 0; i < MAXCLIENTS; i++)
					{
						if (tab[i] != NULL && strcmp(tab[i]->login, a->login) && !strcmp(tab[i]->login, par))
						{
							shutdown(tab[i]->sock, SHUT_RDWR); // żeby na niektórych wersjach nc działało
							close(tab[i]->sock);
						//	free
							tab[i] = NULL;
						//	nclients--;
							break;
						}
						//break;
					}
				
					strcpy(a->login, par);
					
					char name[1024];
					sprintf(name, "cache/%s", a->login);
					FILE *f = fopen(name, "r");
					if(f != NULL)
					{
						char buf[1024];
						while(fgets(buf, 1024, f))
						{
							//fputs(buf, a->out);
							fprintf(a->out, "%s", buf);
						}
						fclose(f);
						unlink(name);
					}

					
					break;
				}
				if(!strcmp(cmd, "receiver"))
				{
					strcpy(a->receiver, par);
					break;					
					
				}
				if(!strcmp(cmd, "list"))
				{
					fprintf(a->out, "Liczba połączonych klientów: %d\n", nclients);
					for(i = 0; i < MAXCLIENTS; i++)
					{
						if(tab[i] != NULL)
						{
							fprintf(a->out, "%3d %-17s %-17s\n", tab[i]->sock, tab[i]->login, tab[i]->receiver);
						}
					}
					break;
				}
				if(!strcmp(cmd, "sendto"))
				{	
					czyDoszlo = 0;
					for(i = 0; i < MAXCLIENTS; i++)
	  				{
	  					if(tab[i] == NULL)
	  						continue;
	  				
	  					if(!strcmp(tab[i]->login, par))
	  					{
	  						strcpy(text, &buf[strlen(cmd) + strlen(par) + 3]);
							fprintf(tab[i]->out, "%s > %s\n", a->login, text);
							czyDoszlo = 1;
						}
					}
					
					if(!czyDoszlo)
	  				{
	  					fprintf(a->out, "Wiadomość niedostarczona\n");
	  				}
					
					break;
				}
				if(!strcmp(cmd, "broadcast"))
				{
					for(i = 0; i < MAXCLIENTS; i++)
		  			{
	  					if(tab[i] == NULL)
	  						continue;
	  		
	  					strcpy(text, &buf[strlen(cmd) + 2]);
						fprintf(tab[i]->out, "%s > %s\n", a->login, text);
					}
					break;
				}
		  		fprintf(a->out, "ERRCMD %s\n", cmd);
		  		break;
			default:
	  			// dane
	  			fprintf(a->out, "%s > %s\n", a->login, buf);
			  	//for (i = 0; buf[i] != 0; i++)
	  			//{
	    		//	printf("%d ", buf[i]);
	  			//}
	  			czyDoszlo = 0;
  				for(i = 0; i < MAXCLIENTS; i++)
  				{
  					if(tab[i] == NULL)
  						continue;
  						
  					if((!strcmp(a->receiver, "*") && strcmp(tab[i]->login, a->login)) || !strcmp(tab[i]->login, a->receiver))
  					{
  						fprintf(tab[i]->out, "%s > %s\n", a->login, buf);
  						czyDoszlo = 1;
		  			}
		  			
				}  				
  				
  				if(!czyDoszlo)
  				{
  					fprintf(a->out, "Wiadomość będzie dostarczona jak sie zaloguje\n");
					char name[1024];
						sprintf(name, "cache/%s", a->receiver);
						FILE *f = fopen(name, "a");
						if(f != NULL)
						{
							fputs(buf, f);
							fputs("\n", f);
							fclose(f);
						}
  				}
	  			break;
      	}
      	
      	if(exitflag)
			break;
    }
    shutdown(a->sock, SHUT_RDWR); // żeby na niektórych wersjach nc działało
    close(a->sock);
    //free(arg);
	tab[poz] = NULL;
	free(a);
	nclients--;
    return NULL;
}

main()
{
    struct sockaddr_in server;
    int sock, opt;
    struct svc_arg *a;
    pthread_t tid;
    sock = socket(AF_INET, SOCK_STREAM, 0); // funckja socket która działa strumieniowo to jest opcja gdzie nie trzeba czekać minuty na ponowne połączenie
    opt = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    memset(&server, 0, sizeof(server)); // zeruje strukturę
    server.sin_family = AF_INET; // w sieci internet
    server.sin_port = htons(10917); // port
    if (bind(sock, (struct sockaddr *) &server, // funckja nie wywoła się jeśli port jest zajęty lub port jest mniejszy lub równy 1024 (tylko dla admina)
             sizeof(server))) {
        perror("bind");
        exit(1);
    }
    listen(sock, 5); // gdniazdko jest nasłuchowe - 5 - mówi że kolejka oczekujących klientów może być 5 (większość nowych systemów olewa ten parametr)
    for (;;) 
	{
        //a = (struct svc_arg *) malloc(sizeof(struct svc_arg)); // alokuje miejsce na strukturę serwera svc_arg to nasza struktura
		a = (struct svc_arg *) calloc(1, sizeof(struct svc_arg));
        a->sock = accept(sock, NULL, NULL);
        pthread_create(&tid, NULL, service, a); // serwis obsługuje klienta
    }
} 

generalnie chodzi o dorobienie blokowania kowalskiego (od blokowanego nie dochodzi wiadomość do mnie )
dodatkowo chciałbym aby zablokowany otrzymywał informację, że jest zablokowany.

Będę wdzięczny za bardzo szybką pomoc.