#include /* Needed only for _O_RDWR definition */ #include #include #include #include #include #include #include #include //#include "main.h" #include #include "typedefs.h" #include "deci2.h" #include "deci2hlp.h" void MakeDeci2Hdr(DECI2_HDR *hdr, u_short l, u_short p, u_char s, u_char d); #include "rfp.h" #include "rfp-srv.h" int rfp_verbose=1; static char *hostname=NULL; typedef struct { char *name; u_int fd; int free; } file_entry; #define MAX_OPEN_FILES 20 file_entry file_table[MAX_OPEN_FILES]; int isActualFileSlot(file_entry*fe) { return (fe>=&file_table[0]) && (fe<&file_table[MAX_OPEN_FILES]); } void SetFileSlot(file_entry*fe, char *filename, int fd) { fe->fd = fd; fe->name = strdup(filename); fe->free = FALSE; } void FreeFileSlot(file_entry*fe) { fe->fd = (u_int)-1; free(fe->name); fe->name = NULL; fe->free = TRUE; } void InitFileTable(void) { int i; for(i=0; i> 1; if((flags & DRFP_OPEN_RDWR) == DRFP_OPEN_RDWR) { converted_flags &= ~ _O_WRONLY; converted_flags |= _O_RDWR; } converted_flags |= _O_BINARY; /* store files open for writing in a separate directory */ /* this directory must exist ! */ if((flags & DRFP_OPEN_WRONLY) && hostname) { strcpy(full_filename, hostname); strcat(full_filename, "/"); strcat(full_filename, barefilename); } else strcpy(full_filename, barefilename); fd = _open (full_filename, converted_flags, _S_IREAD | _S_IWRITE); if( fd != -1) { int i; i = FindFreeFileSlot(); SetFileSlot(&file_table[i], barefilename, fd); return (int)(&file_table[i]); } else { if(rfp_verbose) perror("file open failed:"); return -1; } } int DoCloseFile(int fd) { int ret; file_entry*fe; ret = -1; fe=(file_entry*)fd; if(!fe->free) { int r; r = _close(fe->fd); if(r==0) { FreeFileSlot(fe); ret = 0; } else { } } else { ; } return ret; } int DoReadFile(int fd, unsigned int bytes, char *buffer) { int ret; file_entry*fe; ret = -1; fe=(file_entry*)fd; if(isActualFileSlot(fe) && !fe->free) { ret = _read(fe->fd, buffer, bytes); if(ret<0) if(rfp_verbose) perror( "Problem reading file" ); } return ret; } int DoWriteFile(int fd, unsigned int bytes, char *buffer) { int ret; file_entry*fe; ret = -1; fe=(file_entry*)fd; if(isActualFileSlot(fe) && !fe->free) { // TrackFileWrittenTo(fe->name); ret = _write(fe->fd, buffer, bytes); if(ret<0) if(rfp_verbose) perror( "Problem writing file" ); } else errno = EBADF; return ret; } long DoSeekFile(int fd, int pos, int base) { long ret; int converted_base; file_entry*fe; converted_base = 0; switch(base) { case 0: converted_base = SEEK_SET; break; case 1: converted_base = SEEK_CUR; break; case 2: converted_base = SEEK_END; break; } ret = -1L; fe=(file_entry*)fd; if(isActualFileSlot(fe) && !fe->free) { ret = _lseek(fe->fd, pos, converted_base); if(ret<0) if(rfp_verbose) perror( "Problem seeking pos in file" ); } else errno = EBADF; return ret; } void *RfpHandleOpen(DRFP_HDR *hdr) { int r; struct _pkt { DECI2_HDR deci2; DRFP_HDR drfp; DRFP_OPEN_R_BLOCK openR; } *pkt; DRFP_OPEN_BLOCK *blk = (DRFP_OPEN_BLOCK *)(hdr + 1); M_bswapself32(blk->flag); if(rfp_verbose) printf("open file %s with flags %08x\n", blk->filename, blk->flag); r = DoOpenFile(blk->filename, blk->flag); if ((pkt=(struct _pkt *)GetBlock(sizeof(struct _pkt))) == NULL) return NULL; MakeDeci2Hdr(&pkt->deci2, sizeof(struct _pkt), DECI2_PROTO_DRFP0, DECI2_NODE_HOST, DECI2_NODE_IOP); pkt->drfp.requestOrReplyCode = DRFP_CODE_OPENR; pkt->drfp.requestSequenceNumber = hdr->requestSequenceNumber; if(r!=-1) { // success pkt->openR.fd = r; pkt->openR.result = DRFP_OPENR_OKAY; } else { // failure : don't distinguish ... pkt->openR.fd = -1; pkt->openR.result = DRFP_OPENR_ENOENT; } M_bswapself32(pkt->drfp.requestOrReplyCode); M_bswapself32(pkt->drfp.requestSequenceNumber); M_bswapself32(pkt->openR.fd); M_bswapself32(pkt->openR.result); return pkt; } void *RfpHandleClose(DRFP_HDR *hdr) { int r; struct _pkt { DECI2_HDR deci2; DRFP_HDR drfp; DRFP_CLOSE_R_BLOCK closeR; } *pkt; DRFP_CLOSE_BLOCK *blk = (DRFP_CLOSE_BLOCK *)(hdr + 1); M_bswapself32(blk->fd); if(rfp_verbose) printf("close file descriptor %08x\n", blk->fd); r = DoCloseFile(blk->fd); if ((pkt=(struct _pkt *)GetBlock(sizeof(struct _pkt))) == NULL) return NULL; MakeDeci2Hdr(&pkt->deci2, sizeof(struct _pkt), DECI2_PROTO_DRFP0, DECI2_NODE_HOST, DECI2_NODE_IOP); pkt->drfp.requestOrReplyCode = DRFP_CODE_CLOSER; pkt->drfp.requestSequenceNumber = hdr->requestSequenceNumber; if(r==0) { // success pkt->closeR.result = DRFP_CLOSER_OKAY; } else { // failure : don't distinguish ... pkt->closeR.result = DRFP_CLOSER_EBADF; } M_bswapself32(pkt->drfp.requestOrReplyCode); M_bswapself32(pkt->drfp.requestSequenceNumber); M_bswapself32(pkt->closeR.result); return pkt; } void *RfpHandleRead(DRFP_HDR *hdr) { int r; int hdrsize; int response_size; struct _pkt { DECI2_HDR deci2; DRFP_HDR drfp; DRFP_READ_R_BLOCK readR; } *pkt; DRFP_READ_BLOCK *blk = (DRFP_READ_BLOCK *)(hdr + 1); M_bswapself32(blk->fd); M_bswapself32(blk->numBytes); if(rfp_verbose) printf("read %d bytes from fd %08x\n", blk->numBytes, blk->fd); /* allocate max possible packet for response */ hdrsize = sizeof(struct _pkt) /*- 1*/; response_size = sizeof(struct _pkt) /*- 1*/ + blk->numBytes ; assert(response_size <= DECI2_MAX_LEN); if ((pkt=(struct _pkt *)GetBlock(response_size)) == NULL) return NULL; r = DoReadFile(blk->fd, blk->numBytes, pkt->readR.data); /* now that we now how much we read, set correct packet size in deci2 header */ MakeDeci2Hdr(&pkt->deci2, r!=-1 ? (sizeof(struct _pkt) /*- 1*/ + r) : (sizeof(struct _pkt) /*- 1*/), DECI2_PROTO_DRFP0, DECI2_NODE_HOST, DECI2_NODE_IOP); pkt->drfp.requestOrReplyCode = DRFP_CODE_READR; pkt->drfp.requestSequenceNumber = hdr->requestSequenceNumber; if(r!=-1) {// success pkt->readR.result = DRFP_READR_OKAY; pkt->readR.numBytes = r; } else { // failure : don't distinguish pkt->readR.result = DRFP_READR_EIO; pkt->readR.numBytes = 0; } M_bswapself32(pkt->drfp.requestOrReplyCode); M_bswapself32(pkt->drfp.requestSequenceNumber); M_bswapself32(pkt->readR.result); M_bswapself32(pkt->readR.numBytes); return pkt; } void *RfpHandleWrite(DRFP_HDR *hdr) { int r; struct _pkt { DECI2_HDR deci2; DRFP_HDR drfp; DRFP_WRITE_R_BLOCK writeR; } *pkt; DRFP_WRITE_BLOCK *blk = (DRFP_WRITE_BLOCK *)(hdr + 1); M_bswapself32(blk->fd); M_bswapself32(blk->numBytes); if(rfp_verbose) printf("write %d bytes from fd %08x\n", blk->numBytes, blk->fd); r = DoWriteFile(blk->fd, blk->numBytes, blk->data); if ((pkt=(struct _pkt *)GetBlock(sizeof(struct _pkt))) == NULL) return NULL; MakeDeci2Hdr(&pkt->deci2, sizeof(struct _pkt), DECI2_PROTO_DRFP0, DECI2_NODE_HOST, DECI2_NODE_IOP); pkt->drfp.requestOrReplyCode = DRFP_CODE_WRITER; pkt->drfp.requestSequenceNumber = hdr->requestSequenceNumber; if(!(r<0)) { // success pkt->writeR.result = DRFP_WRITER_OKAY; pkt->writeR.numBytes = r; } else { // failure switch(errno) { case EBADF: pkt->writeR.result = DRFP_WRITER_EBADF; break; case ENOSPC: pkt->writeR.result = DRFP_WRITER_ENOSPC; break; default: pkt->writeR.result = DRFP_WRITER_EIO; break; } pkt->writeR.numBytes = 0; } M_bswapself32(pkt->drfp.requestOrReplyCode); M_bswapself32(pkt->drfp.requestSequenceNumber); M_bswapself32(pkt->writeR.numBytes); return pkt; } void *RfpHandleSeek(DRFP_HDR *hdr) { int r; struct _pkt { DECI2_HDR deci2; DRFP_HDR drfp; DRFP_SEEK_R_BLOCK seekR; } *pkt; DRFP_SEEK_BLOCK *blk = (DRFP_SEEK_BLOCK *)(hdr + 1); M_bswapself32(blk->base); M_bswapself32(blk->fd); M_bswapself32(blk->offset); if(rfp_verbose) printf("seek pos %d/%d for fd %08x\n", blk->offset, blk->base, blk->fd); r = DoSeekFile(blk->fd, blk->offset, blk->base); if ((pkt=(struct _pkt *)GetBlock(sizeof(struct _pkt))) == NULL) return NULL; MakeDeci2Hdr(&pkt->deci2, sizeof(struct _pkt), DECI2_PROTO_DRFP0, DECI2_NODE_HOST, DECI2_NODE_IOP); pkt->drfp.requestOrReplyCode = DRFP_CODE_SEEKR; pkt->drfp.requestSequenceNumber = hdr->requestSequenceNumber; if(r!=-1L) { // success pkt->seekR.result = DRFP_SEEKR_OKAY; pkt->seekR.filePos = r; } else { // failure : don't distinguish ... pkt->seekR.result = DRFP_SEEKR_EBADF; pkt->seekR.filePos = 0; } M_bswapself32(pkt->drfp.requestOrReplyCode); M_bswapself32(pkt->drfp.requestSequenceNumber); M_bswapself32(pkt->seekR.result); M_bswapself32(pkt->seekR.filePos); return pkt; } void * RfpHandler(char *buf) { void *response; DRFP_HDR *hdr = (DRFP_HDR *)buf; M_bswapself32(hdr->requestOrReplyCode) ; M_bswapself32(hdr->requestSequenceNumber) ; switch(hdr->requestOrReplyCode) { case DRFP_CODE_OPEN: response = RfpHandleOpen(hdr); break; case DRFP_CODE_CLOSE: response = RfpHandleClose(hdr); break; case DRFP_CODE_READ: response = RfpHandleRead(hdr); break; case DRFP_CODE_WRITE: response = RfpHandleWrite(hdr); break; case DRFP_CODE_SEEK: response = RfpHandleSeek(hdr); break; default: response = NULL; printf("not ready for RFP message %d\n", hdr->requestOrReplyCode); } return response; } int CreateOutputDirectory(char *dirname) { int r; if(dirname) { r=_mkdir(dirname); return 0; } else return -1; } void InitRFPClient(char *_hostname) { InitFileTable(); hostname = _hostname; CreateOutputDirectory(hostname); } void ExitRFPClient(void) { ExitFileTable(); }