s7.c (>gcc -i s7.c server)
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/time.h>
extern errno;
#define PORT 22222
#define MAX_CLIENT 5
static char buf[BUFSIZ];
//follow "c7.c"
//-1 non command
//1 clear screen
//2 send file
//3 get own id
int WhichCommand(char usercmd[])
{
char tbuf[201];
char tbuf1[101];
char tbuf2[101];
char tbuf3[101];
int i;
//convert to upper case
strncpy(tbuf,usercmd,200);
for (i=0; i<strlen(tbuf); i++) tbuf[i]=toupper(tbuf[i]);
//extract command
//CLEAR
if (strcmp(tbuf,"/CLEAR\n")==0) return 1;
//SEND
sscanf(tbuf,"%s",tbuf1);
if (strcmp(tbuf1,"/SEND")==0) return 2;
//OWNID
sscanf(tbuf,"%s",tbuf1);
if (strcmp(tbuf1,"/OWNID")==0) return 3;
return 0;
}
///////////////////////////////////////////////
//extract the client number to send to
//return client number if successful,
//0 or negative number returned if unsuccessful
int GetReceiverClientNo(char *msg)
{
char t1[100],t2[100];
//less than 2 words in message
if (sscanf(msg,"%s %s",t1,t2)<2) return -1;
return atoi(t2);
}
///////////////////////////////////////////////
int getuser(char *input)
{
int i,count=0;
char ctemp[50];
if(!isdigit(input[1]))
return 0;
while(!isdigit(input[count]))count++;
i=0;
while(isdigit(input[count]))
{
ctemp[i++]=input[count++];
}
ctemp[i]='\0';
return atoi(ctemp);
}
///////////////////////////////////////////////
void set_unblock(int sock)
{
if(fcntl(sock,F_SETFL,FNDELAY)<0)
{
perror("File control");
exit(2);
}
}
///////////////////////////////////////////////
void form_message(int i,char *input,char *result)
{
char temp[100];
strcpy(temp,"Client");
strcat(temp,ltoa(((long)i+1)));
strcat(temp," > ");
strcat(temp,input);
write(fileno(stdout),temp,strlen(temp));
strcpy(result,temp);
}
///////////////////////////////////////////////
void disp_time(int fd)
{
struct tm *tm_ptr;
time_t atime;
(void) time(&atime);
tm_ptr = localtime(&atime);
if (tm_ptr->tm_hour>=10)
{
write(fd, ltoa(tm_ptr->tm_hour), strlen(ltoa(tm_ptr->tm_hour)));
}
else
{
write(fd, "0", 1);
write(fd, ltoa(tm_ptr->tm_hour), strlen(ltoa(tm_ptr->tm_hour)));
}
write(fd,":",1);
if (tm_ptr->tm_min>=10)
{
write(fd, ltoa(tm_ptr->tm_min), strlen(ltoa(tm_ptr->tm_min)));
}
else
{
write(fd, "0", 1);
write(fd, ltoa(tm_ptr->tm_min), strlen(ltoa(tm_ptr->tm_min)));
}
write(fd,":",1);
if (tm_ptr->tm_sec>=10)
{
write(fd, ltoa(tm_ptr->tm_sec), strlen(ltoa(tm_ptr->tm_sec)));
}
else
{
write(fd, "0", 1);
write(fd, ltoa(tm_ptr->tm_sec), strlen(ltoa(tm_ptr->tm_sec)));
}
}
///////////////////////////////////////////////
void store(char* data, int fd)
{
disp_time(fd);
write(fd," : ",3) ;
write(fd,data,strlen(data));
}
///////////////////////////////////////////////
main(void)
{
int tlen,fd,orig_sock,new_sock,clnt_len,len,i,count,loop_count;
int sock[MAX_CLIENT][2],receiver;
char cbuf[100];
struct sockaddr_in serv_adr,com_adr,clnt_adr;
int reserve[BUFSIZ];
int reserve_pt;
int tmp;
int goback=0;
int t1;
char tbuf1[100],tbuf2[100],tbuf3[100],tbuf4[100];
for (tmp=0;tmp<BUFSIZ;tmp++) reserve[tmp]=-1;
reserve_pt=0;
tmp=0;
count=0;
tlen=strlen(ltoa(time(NULL)));
if((fd=open("logdata",O_WRONLY|O_APPEND|O_CREAT,0644))==-1)
{
write(fileno(stdout),"Log file error",14);
exit(1);
}
lseek(fd,(off_t)0,SEEK_END);
if((orig_sock=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("Server socket");
exit(1);
}
set_unblock(orig_sock);
memset(&serv_adr,0,sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(PORT);
if(bind(orig_sock,(struct sockaddr *)&serv_adr,sizeof(serv_adr))<0)
{
perror("Server bind");
exit(3);
}
if(listen(orig_sock,5)<0)
{
perror("listen error");
exit(4);
}
do
{
do
{
memset(&buf,0,BUFSIZ);
for(i=0;i<count;i++)
if((len=read(sock[i][1],buf,BUFSIZ))>0)
{
form_message(i,buf,cbuf);
store(cbuf,fd);
if(buf[0]=='Q')
for(loop_count=0;loop_count<count;loop_count++)
{
if(loop_count!=i)
{
write(sock[loop_count][1],cbuf,strlen(cbuf));
}
}
else
if(buf[0]=='A')
{
if((receiver=getuser(buf))>0)
{
write(sock[receiver-1][1],cbuf,strlen(cbuf));
}
}
else
if(buf[0]=='.')
{
if (count==tmp)
{
count--;
}
else
{
reserve[reserve_pt]=i;
reserve_pt++;
}
printf("Client %d left ...\n",i+1);
printf("%d client(s) right now !\n",count-reserve_pt);
write(fd,"Client ",7);
write(fd,ltoa(i+1),strlen(ltoa(i+1)));
write(fd," left server at time ",21);
disp_time(fd);
write(fd,"\n",1);
if(reserve_pt==count)
{
count=0;
reserve_pt=0;
printf("No clients left on server now !\n");
disp_time(fd);
write(fd," : No clients left in server !",30);
write(fd,"\n",1);
}
}
//send file
else if (WhichCommand(buf)==2)
{
//check it is not sending to itself
sscanf(buf,"%s %s",tbuf1,tbuf3);
if (i+1==atoi(tbuf3))
{
sprintf(cbuf,"Error : sending to ownself\n");
write(sock[i][1],cbuf,strlen(cbuf));
}
else
{
strcpy(cbuf,"/getdirectory");
write(sock[i][1],cbuf,strlen(cbuf));
//store sender's directory in tbuf1
while ((len=read(sock[i][1],tbuf1,BUFSIZ))<=0) sleep(1);
strcpy(cbuf,"/getdirectory");
write(sock[atoi(tbuf3)-1][1],cbuf,strlen(cbuf));
//store receiver's directory in tbuf2
while ((len=read(sock[atoi(tbuf3)-1][1],tbuf2,BUFSIZ))<=0) sleep(1);
//ask client to copy file
sscanf(buf,"%s %s %s",cbuf,tbuf4,tbuf3);//tbuf3 has filename
sprintf(cbuf,"/copy %s%s %s%s",tbuf1,tbuf3,tbuf2,tbuf3);
write(sock[i][1],cbuf,strlen(cbuf));
}
}
//ownid
else if (WhichCommand(buf)==3)
{
sprintf(cbuf,"%s %d","/ownid :",i+1);
write(sock[i][1],cbuf,strlen(cbuf));
}
}
}while((new_sock=accept(orig_sock,(struct sockaddr*)&clnt_adr,&clnt_len))<0);
if ((count==MAX_CLIENT)&&(reserve_pt==0))
{
write(new_sock," Server overload! Unable to connect! ",37);
close(new_sock);
goback=1;
}
if (goback==0)
{
if (reserve_pt>0)
{
tmp=reserve[reserve_pt-1];
reserve[reserve_pt-1]=-1;
reserve_pt--;
}
else
{
tmp=count;
count++;
}
printf("Client %d joined server ...\n",tmp+1);
write(fd,"Client ",7);
write(fd,ltoa(tmp+1),strlen(ltoa(tmp+1)));
write(fd," joined server at time ",23);
disp_time(fd);
write(fd,"\n",1);
if(socketpair(AF_UNIX,SOCK_STREAM,0,sock[tmp])<0)
{
perror("Socket pair generation error");
close(orig_sock);
exit(6);
}
for(i=0;i<2;i++)
set_unblock(sock[tmp][i]);
if(fork()==0)
{
close(sock[tmp][1]);
set_unblock(new_sock);
do
{
memset(&buf,0,BUFSIZ);
if((len=read(new_sock,buf,BUFSIZ))>0)
{
if(buf[0]=='.')
{
if (count==tmp)
{
count--;
}
else
{
reserve[reserve_pt]=i;
reserve_pt++;
}
close(new_sock);
//write(sock[count][0],buf,len);
write(sock[tmp][0],buf,len);
exit(9);
}
write(sock[tmp][0],buf,len);
//write(sock[count][0],buf,len);
}
if((len=read(sock[tmp][0],buf,BUFSIZ))>0)
{
write(new_sock,buf,len);
}
}while(1);
}else close(new_sock);
close(sock[tmp][0]);
}
goback=0;
}while(1);
close(fd);
}