Startpunkten
This commit is contained in:
364
ftp_layer.c
Normal file
364
ftp_layer.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/* FTP-layer av Daniel W och Anders W för datakommunikation-lab! */
|
||||
|
||||
#include "student.h"
|
||||
#include "signal_prim.h"
|
||||
|
||||
#define FPATH "./ftp_socket"
|
||||
#define LPATH "./link_socket"
|
||||
#define AF 1 /* send AF_Abort_Ind to app with cancel() */
|
||||
#define L 0 /* send L_Abort_Req to linker with cancel()*/
|
||||
#define IsFTP 0x80 /* set the ID-bit to indicate FTP & !chat */
|
||||
#define OPMASK 0x7f /* to mask out the 'operation'-field */
|
||||
#define SIGPACKLEN 3 /* lenght of a sigpacket; primitive or PDU */
|
||||
#define MAXDATALEN 200 /* max datalen to tfr between ftp and linker */
|
||||
#define IDLE 0
|
||||
#define UUUK 1
|
||||
#define UIUK 2
|
||||
#define DATA 3
|
||||
#define UUNK 4
|
||||
#define UINK 5
|
||||
#define TERROR 6 /* the states */
|
||||
#define CR 1
|
||||
#define CA 2
|
||||
#define DR 3
|
||||
#define DA 4
|
||||
#define RR 5
|
||||
#define RA 6
|
||||
#define DT 7 /* the PDU's */
|
||||
/* #define NULL 0 */
|
||||
|
||||
void do_something(void);
|
||||
int Polla(int,int); /* handles error from PollSocket() */
|
||||
void cancel(int); /* sets 'state' to IDLE */
|
||||
void WriteSigToApp(int); /* write a sig and handle error */
|
||||
void WriteSigToLink(int); /* write a sig and handle error */
|
||||
int WriteDataToLink(char*, int); /* cancel(AF/L) if no L_Stat from link */
|
||||
void WriteDataToApp(char*,int);
|
||||
int doSigPacket(int); /* uses WriteDataToLink() */
|
||||
int ConnToLinker(void); /* executes cancel(AF/L) on error */
|
||||
void DiscFromLinker(void); /* executes cancel(L) on error */
|
||||
|
||||
int lSock_fd, fSock_fd, state=IDLE, stderr=2;
|
||||
|
||||
main(int argc,char *argv[]) {
|
||||
|
||||
int temp_fd;
|
||||
printf("FTP_LAYER startat\n");
|
||||
if((fSock_fd=CreateUnixClientSocket(FPATH))<0) {
|
||||
fprintf(stderr,"Can't create client signal socket to application!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("FTP_Layer har startat APP-socket...\n");
|
||||
if((temp_fd=CreateUnixServerSocket(LPATH))<0) {
|
||||
fprintf(stderr,"Can't create server signal socket to linker!\n");
|
||||
exit(2);
|
||||
}
|
||||
printf("FTP_Layer har startat LINK-socket...\n");
|
||||
switch(fork()) {
|
||||
case -1:
|
||||
fprintf(stderr,"Fork failed in FTP-layer!\n");
|
||||
exit(4);
|
||||
case 0:
|
||||
close(fSock_fd);
|
||||
close(temp_fd);
|
||||
execv("./link_layer",argv);
|
||||
exit(0);
|
||||
default:
|
||||
if((lSock_fd=AcceptConnection(temp_fd))<0) {
|
||||
fprintf(stderr,"Can't accept client signal socket from application!\n");
|
||||
exit(3);
|
||||
}
|
||||
do_something();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int Polla(int fd1, int fd2) {
|
||||
int poll;
|
||||
poll=PollSocket(fd1,fd2,NULL);
|
||||
if(poll==-1) {
|
||||
fprintf(stderr,"PollSocket-error in FTP-layer, quitting!\n\n");
|
||||
exit(8);
|
||||
}
|
||||
return poll-1;
|
||||
}
|
||||
|
||||
void do_something() {
|
||||
int sig, poll;
|
||||
char buf[MAXDATALEN+SIGPACKLEN], x;
|
||||
long len;
|
||||
while(1) {
|
||||
poll=Polla(fSock_fd,lSock_fd);
|
||||
if(poll==fSock_fd) { /* signal från applikationen */
|
||||
sig=ReadSignalfromSocket(fSock_fd,SIGPACKLEN);
|
||||
if(sig==AF_Abort_Req)
|
||||
cancel(L);
|
||||
else if(sig==-1) {
|
||||
fprintf(stderr,"ReadSignal-error in FTP-layer, quitting!\n\n");
|
||||
exit(15);
|
||||
}
|
||||
else {
|
||||
switch(state) {
|
||||
case IDLE:
|
||||
if(sig==AF_Con_Req) {
|
||||
if(ConnToLinker())
|
||||
if(doSigPacket(CR)) state=UUUK;
|
||||
}
|
||||
else
|
||||
cancel(AF);
|
||||
break;
|
||||
case UIUK:
|
||||
if(sig==AF_Con_Resp)
|
||||
if(doSigPacket(CA)) state=DATA;
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
case DATA:
|
||||
if(sig==AF_Data_Req) {
|
||||
PollSocket(fSock_fd,fSock_fd,NULL);
|
||||
ReadDatafromSocket(fSock_fd, (char*)&len,sizeof(long));
|
||||
if(len) {
|
||||
PollSocket(fSock_fd,fSock_fd,NULL);
|
||||
while(len>0) {
|
||||
x=ReadDatafromSocket(fSock_fd,buf+3,len>MAXDATALEN?MAXDATALEN:len);
|
||||
if(x>0) {
|
||||
buf[0]=x+2;
|
||||
buf[1]=x;
|
||||
buf[2]=IsFTP | DT;
|
||||
if(!WriteDataToLink(buf,x+SIGPACKLEN)) break;
|
||||
len-=x;
|
||||
}
|
||||
else if(x==-1) {
|
||||
fprintf(stderr,"Readerror in FTP-layer, quitting!\n\n");
|
||||
exit(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(sig==AF_Disc_Req)
|
||||
if(doSigPacket(DR)) state=UUNK;
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
case UINK:
|
||||
if(sig==AF_Disc_Resp) {
|
||||
if(doSigPacket(DA)) {
|
||||
state=IDLE;
|
||||
DiscFromLinker();
|
||||
}
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
case TERROR:
|
||||
if(sig==AF_Rej_Resp)
|
||||
if(doSigPacket(RA)) state=IDLE;
|
||||
else
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
break;
|
||||
default: /* I UUUK & UUNK ska man inte få signaler från app */
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(poll==lSock_fd) { /* signal från linkern */
|
||||
sig=ReadSignalfromSocket(lSock_fd,SIGPACKLEN);
|
||||
if(sig==L_Abort_Ind)
|
||||
cancel(AF);
|
||||
else if(sig==L_Data_Ind)
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
else if(sig==-1) {
|
||||
fprintf(stderr,"ReadSignal-error in FTP-layer, quitting!\n\n");
|
||||
exit(15);
|
||||
}
|
||||
else {
|
||||
switch(state) {
|
||||
case IDLE:
|
||||
if(sig==L_Con_Ind) {
|
||||
WriteSigToLink(L_Con_Resp);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)==L_Data_Req) {
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
ReadDatafromSocket(lSock_fd,buf,1);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||
if(buf[1] & IsFTP) {
|
||||
if((buf[1] & OPMASK)==CR) {
|
||||
WriteSigToApp(AF_Con_Ind);
|
||||
state=UIUK;
|
||||
}
|
||||
else
|
||||
cancel(L);
|
||||
}
|
||||
}
|
||||
else
|
||||
cancel(L);
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
case UUUK:
|
||||
if(sig==L_Data_Ind) {
|
||||
ReadDatafromSocket(lSock_fd,buf,1);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||
if(buf[1] & IsFTP) {
|
||||
if((buf[1] & OPMASK)==CA) {
|
||||
WriteSigToApp(AF_Con_Conf);
|
||||
state=DATA;
|
||||
}
|
||||
else if((buf[1] & OPMASK)==RR) {
|
||||
WriteSigToApp(AF_Rej_Ind);
|
||||
state=TERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
cancel(AF);
|
||||
break;
|
||||
case DATA:
|
||||
if(sig==L_Data_Ind) {
|
||||
ReadDatafromSocket(lSock_fd,buf,1);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||
if(buf[1] & IsFTP) {
|
||||
if((buf[1] & OPMASK)==DT) {
|
||||
len=buf[0];
|
||||
WriteDataToApp((char*)&len,sizeof(long));
|
||||
WriteDataToApp(buf+2,len);
|
||||
}
|
||||
else if((buf[1] & OPMASK)==DR) {
|
||||
WriteSigToApp(AF_Disc_Ind);
|
||||
state=UINK;
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
case UUNK:
|
||||
if(sig==L_Data_Ind) {
|
||||
ReadDatafromSocket(lSock_fd,buf,1);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
ReadDatafromSocket(lSock_fd,buf,buf[0]);
|
||||
if(buf[1] & IsFTP) {
|
||||
if((buf[1] & OPMASK)==DA) {
|
||||
WriteSigToApp(AF_Disc_Conf);
|
||||
state=IDLE;
|
||||
DiscFromLinker();
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
break;
|
||||
default: /* i UIUK, UINK & TERROR ska man inte få sig. från linker */
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cancel(int af_abort) {
|
||||
if(af_abort)
|
||||
WriteSigToApp(AF_Abort_Ind);
|
||||
else
|
||||
WriteSigToLink(L_Abort_Req);
|
||||
state=IDLE;
|
||||
}
|
||||
|
||||
void WriteSigToLink(int flag) {
|
||||
if(WriteSignaltoSocket(lSock_fd,flag,SIGPACKLEN)==-1) {
|
||||
fprintf(stderr,"Write-error to linker, quitting!\n\n");
|
||||
exit(10);
|
||||
} }
|
||||
|
||||
void WriteSigToApp(int flag) {
|
||||
if(WriteSignaltoSocket(fSock_fd,flag,SIGPACKLEN)==-1) {
|
||||
fprintf(stderr,"Write-error to application, quitting!\n\n");
|
||||
exit(11);
|
||||
} }
|
||||
|
||||
int WriteDataToLink(char* buf,int len) {
|
||||
int x;
|
||||
WriteSigToLink(L_Data_Req);
|
||||
PollSocket(lSock_fd,lSock_fd,NULL);
|
||||
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)!=L_Status) {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
return 0;
|
||||
}
|
||||
if((x=WriteDatatoSocket(lSock_fd,buf,len))==-1) {
|
||||
fprintf(stderr,"Write-error to linker, quitting!\n\n");
|
||||
exit(13);
|
||||
}
|
||||
else
|
||||
while(x<len) x+=WriteDatatoSocket(lSock_fd,buf+x,len-x);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WriteDataToApp(char* buf,int len) {
|
||||
int x;
|
||||
WriteSigToApp(AF_Data_Ind);
|
||||
if((x=WriteDatatoSocket(fSock_fd,buf,len))==-1) {
|
||||
fprintf(stderr,"Write-error to application, quitting!\n\n");
|
||||
exit(13);
|
||||
}
|
||||
else
|
||||
while(x<len) x+=WriteDatatoSocket(lSock_fd,buf+x,len-x);
|
||||
}
|
||||
|
||||
int doSigPacket(int flag) {
|
||||
char head[3];
|
||||
head[0]=2;
|
||||
head[1]=0;
|
||||
head[2]=IsFTP | flag;
|
||||
return WriteDataToLink(head,SIGPACKLEN);
|
||||
}
|
||||
|
||||
int ConnToLinker() {
|
||||
WriteSigToLink(L_Con_Req);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
switch(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)) {
|
||||
case L_Con_Conf:
|
||||
return 1;
|
||||
case L_Abort_Ind:
|
||||
cancel(AF);
|
||||
return 0;
|
||||
default:
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
return 0;
|
||||
} }
|
||||
|
||||
void DiscFromLinker() {
|
||||
WriteSigToLink(L_Disc_Req);
|
||||
Polla(lSock_fd,lSock_fd);
|
||||
if(ReadSignalfromSocket(lSock_fd,SIGPACKLEN)!=L_Disc_Conf) {
|
||||
cancel(AF);
|
||||
cancel(L);
|
||||
} }
|
||||
Reference in New Issue
Block a user