server.c
#include <mine.h>
#include <ncurses.h>
#include <signal.h>
#include <fcntl.h>
void callpeer ();
short int getpeer (char *filename);
void disconnect (int clt);
void handlequit (int sig);
void sendclient (int clt);
void setin ();
void takeclient (int fd);
void terminate ();
short int EAR, IN[10], in=0, maxy, maxx, peers=0, acptsw=1;
char *scktfile, *clearline;
int main (int argc, char *argv[]) {
char buffer[65], *tok;
struct {char mtxt[70];}inbx[10];
short int ch,i,x,I=0, bytes;
struct sockaddr_un tmpSA;
socklen_t tlen=sizeof(tmpSA);
scktfile=ec_malloc(strlen(argv[1]));
strcpy(scktfile,argv[1]);
if ((EAR=loclsckt(scktfile)) < 0) {printf("loclsckt fail in main(): %d", EAR); return -1;}
if ((listen(EAR,10)) !=0) {perror("listen fail in main()"); return -2;}
signal(SIGINT,handlequit);
for (i=0;i<10;i++) {inbx[i].mtxt[0]=0;IN[i]=-1;}
initscr();
getmaxyx(stdscr,maxy,maxx);
clearline=ec_malloc(maxx);
for (i=0;i<maxx;i++) clearline[i]=32;
clearline[maxx]=0;
halfdelay(5);
noecho();
start_color();
init_pair(1, COLOR_MAGENTA,COLOR_BLACK);
init_pair(2, COLOR_BLACK,COLOR_MAGENTA);
init_pair(3, COLOR_MAGENTA,COLOR_WHITE);
init_pair(4, COLOR_GREEN,COLOR_BLACK);
init_pair(5, COLOR_BLACK,COLOR_GREEN);
attron(COLOR_PAIR(3));
printw("local socket server open on %s", scktfile);
attroff(COLOR_PAIR(3));
mvaddstr(1,0,"Ctrl-c to quit");
mvprintw(2,0, "%s", clearline);
refresh();
fcntl(EAR,F_SETFL,O_NONBLOCK);
while (ch=getch()) {
if ((IN[in]=accept(EAR,(struct sockaddr*)&tmpSA,&tlen)) > 0) takeclient(IN[in]);
if (ch=='T') terminate();
if (ch=='C') callpeer();
if ((ch > 47) && (ch < 58)) sendclient(ch-48);
for (i=0;i<10;i++) if (IN[i] > 2) if ((bytes=read(IN[i],buffer,64)) > 0) {
buffer[bytes]=0;
for (x=bytes;x>=0;x--) if (buffer[x]=='\n') buffer[x]=0;
attron(COLOR_PAIR(1));
for (x=1;x<10;x++) {
strcpy(inbx[10-x].mtxt,inbx[9-x].mtxt);
mvprintw((maxy-2)-x,0,"%s",clearline);
mvprintw((maxy-2)-x,0,"%s",inbx[10-x].mtxt);
}
if ((strcmp(buffer,"TERMINATED")) == 0) {disconnect(i);
sprintf(inbx[0].mtxt,"Client %d signed off.",i);
setin();}
else sprintf(inbx[0].mtxt,"fd%d: %s",IN[i],buffer);
mvprintw(maxy-12,0,"%s",clearline);
mvprintw(maxy-12,0,"%s",inbx[0].mtxt);
attroff(COLOR_PAIR(1));
}
mvprintw(1,50,"iteration %d", I); I++;
refresh();
}
endwin();
close(EAR);
unlink(scktfile);
return 0;
}
void callpeer () {
char blank[maxx], spath[70];
short int i, peer;
sprintf(blank,"Socket path");
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
blank[maxx]=0;
mvprintw(5,0,"%s",blank);
mvprintw(5,11,": ");
echo();
getstr(spath);
noecho();
halfdelay(5);
peer=getpeer(spath);
if (peer < 0) {
mvprintw(2,5,"%s",clearline);
attron(COLOR_PAIR(4));
mvprintw(7,5,"%s", clearline);
mvprintw(7,5,"FAILED connect");
attroff(COLOR_PAIR(4));
return;}
IN[in]=peer;
mvprintw(3,0,"%s",clearline);
mvprintw(3,0,"New connection on file descriptor %d",IN[in]);
attron(COLOR_PAIR(2));
mvprintw(maxy-1,in*8+1,"%d: FD%d",in,IN[in]);
attroff(COLOR_PAIR(2));
fcntl(IN[in],F_SETFL,O_NONBLOCK);
setin();
}
void disconnect (int clt) {
close(IN[clt]);
IN[clt]=-1;
mvprintw(maxy-1,clt*8," ");
}
short int getpeer (char *filename) {
char me[108],*ptr;
short int i, cxt, retv;
struct sockaddr_un peer;
size_t size;
strcpy(me,scktfile);
i=strlen(me);
ptr=strrchr(filename,'/');
strcat(me,ptr);
me[i]='-';
unlink(me);
if (strlen(me) > 107) {puts("filename too long"); handlequit(2);}
cxt=loclsckt(me);
peer.sun_family=AF_LOCAL;
strcpy(peer.sun_path,filename);
size=SUN_LEN(&peer);
if ((retv=connect(cxt,(struct sockaddr*)&peer,size)) < 0) return retv;
return cxt;
}
void handlequit (int sig) {
short int pid=getpid(), i;
for (i=0;i<10;i++) if (IN[i]>0) {
write(IN[i],"TERMINATED\n",11);
disconnect(i);}
endwin();
close(EAR);
puts("DONE");
unlink(scktfile);
kill(pid,9);
}
void sendclient (int clt) {
int i;
char messg[64],blank[maxx], *tok;
if (IN[clt] < 0) sprintf(blank,"There is no client %d", clt);
else strcpy(blank,"Message");
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
blank[maxx]=0;
mvprintw(3,0,"%s",blank);
if (IN[clt] < 0) return;
mvprintw(3,7,": ");
echo();
getstr(messg);
noecho();
halfdelay(5);
if ((messg[0] == '\n') || ((write(IN[clt],messg,64)) == -1)) sprintf(blank,"Message NOT delivered.");
else sprintf(blank,"Delivered message.");
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
mvprintw(3,0,"%s",blank);
}
void setin () {
short int i;
for (i=0;i<10;i++) {
if (IN[i] == -1) {
if (i<9 && acptsw==0) {
mvprintw(maxy-1,73," ");
acptsw=1;}
break;}
if (i==8) acptsw = 0;}
in=i;
}
void takeclient (int fd) {
short int i;
char messg[64];
mvprintw(3,0,"%s",clearline);
if (acptsw == 1) {
mvprintw(3,0,"New connection on file descriptor %d",IN[in]);
sprintf(messg, "You are connected.\n");
attron(COLOR_PAIR(2));
mvprintw(maxy-1,in*8+1,"%d: FD%d",in,IN[in]);
attroff(COLOR_PAIR(2));
fcntl(IN[in],F_SETFL,O_NONBLOCK);}
else if (acptsw == 0) {
mvprintw(3,0,"Refused additional connection ");
attron(COLOR_PAIR(5));
mvprintw(maxy-1,73,"%d: FULL",in);
attroff(COLOR_PAIR(5));
sprintf(messg, "TERMINATED\n");
close(IN[in]); IN[in]=-1;
}
write(IN[in],messg,strlen(messg));
setin();
}
void terminate () {
char messg[]="TERMINATED", blank[maxx];
short int who,i;
sprintf(blank,"Terminate who[0-9]");
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
blank[maxx]=0;
mvprintw(5,0,"%s",blank);
mvprintw(5,18,"? ");
nocbreak(); echo();
who=getch();
halfdelay(5); noecho();
who-=48;
if ((who > 9) || (who < 0) || IN[who] < 0) {
sprintf(blank,"%d can't be terminated",who);
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
mvprintw(6,0,"%s",blank);
return;}
write(IN[who],messg,strlen(messg));
disconnect(who);
sprintf(blank,"Socket at FD %d closed.",who);
for(i=strlen(blank);i<maxx;i++) blank[i]=32;
mvprintw(5,0,"%s", blank);
setin();
}
client.c
#include <mine.h>
#include <signal.h>
short int ME;
void handlequit (int sig) {
short int pid=getpid();
if (sig != 133) write(ME,"TERMINATED\n",11);
close(ME);
kill(pid,9);
}
int main(int argc, char *argv[]) {
short int len, pid;
char messg[80];
struct sockaddr_un servr;
size_t size;
if ((ME=socket(PF_LOCAL,SOCK_STREAM,0)) < 0) perror("socket");
signal(SIGINT,handlequit);
servr.sun_family=AF_LOCAL;
strcpy(servr.sun_path,argv[1]);
size=SUN_LEN(&servr);
if ((connect(ME,(struct sockaddr*)&servr,size)) != 0) {
perror("connect fail in main()"); handlequit(2);}
pid=fork();
if (pid == 0) {
while (1) {
char *string=linein(stdin);
write(ME,string,strlen(string));
}
return;
}
while ((len=read(ME,messg,80)) > 0) {
messg[len]=0;
system("echo -en \"\033[1;33m\"");
printf("From server: %s\n",messg);
system("echo -en \"\033[1;00m\"");
fflush(stdout);
if (strncmp(messg,"TERMINATED",11) == 0) break;
}
handlequit(133);
return 0;
}