/* * SCOPY.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. * * COPY SERVER * * The current version only accepts one connection at a time. This server * handles uploading/downloading of data. * * Receive: * 'W' NLEN NAME FILELEN -receive file * 'X' NLEN NAME 0 -create and CD into directory * 'Y' 0 0 -restore previous directory * 'C' NLEN NAME 0 -set destination directory * * length in 68000 longword format. */ #include #include #include "servers.h" int Enable_Abort; char Buf[1024]; typedef struct FileInfoBlock FIB; typedef struct Process PROC; extern struct MsgPort *DListen(); extern PROC *FindTask(); extern char *AllocMem(); _main() { struct MsgPort *port; PROC *myproc = FindTask(NULL); long chan; long savedir; long mask, rmask; Enable_Abort = 0; port = DListen(PORT_FILECOPY); WaitPort(&myproc->pr_MsgPort); ReplyMsg(GetMsg(&myproc->pr_MsgPort)); savedir = Lock("", SHARED_LOCK); /* duplicate current dir */ if (!savedir) _exit(1); savedir = CurrentDir(savedir); /* CD dup, returns original */ mask = SIGBREAKF_CTRL_C|(1 << port->mp_SigBit); for (;;) { rmask = Wait(mask); if (rmask & SIGBREAKF_CTRL_C) break; while (chan = DAccept(port)) { fflush(stdout); putdir(chan, ""); DClose(chan); } } UnLock(CurrentDir(savedir)); DUnListen(port); } static char Name[128]; putdir(chan, dirname) char *dirname; { FIB *fib; long lock; long oldlock; long len; int ret = -1; unsigned char co, nl, rc; fib = (FIB *)AllocMem(sizeof(FIB), MEMF_PUBLIC); if ((lock = Lock(dirname, SHARED_LOCK)) == NULL) { if (lock = CreateDir(dirname)) { UnLock(lock); lock = Lock(dirname, SHARED_LOCK); } } if (lock == NULL || !Examine(lock,fib) || fib->fib_DirEntryType < 0) { if (lock) UnLock(lock); rc = 'N'; DWrite(chan, &rc, 1); FreeMem(fib, sizeof(FIB)); return(1); } rc = 'Y'; DWrite(chan, &rc, 1); oldlock = CurrentDir(lock); while (DRead(chan, &co, 1) == 1) { if (DRead(chan, &nl, 1) != 1 || DRead(chan, Name, nl) != nl) break; if (DRead(chan, &len, 4) != 4) break; switch(co) { case 'C': { char co = 'N'; long lock = Lock(Name, SHARED_LOCK); /* CD to dir */ if (!lock) { if (lock = CreateDir(Name)) { /* or create */ UnLock(lock); lock = Lock(Name, SHARED_LOCK); } } if (lock) { co = 'Y'; UnLock(CurrentDir(lock)); } DWrite(chan, &co, 1); } break; case 'W': if (putfile(chan, Name, len) < 0) { ret = -1; goto fail; } break; case 'X': if (putdir(chan, Name) < 0) { ret = -1; goto fail; } break; case 'Y': ret = 1; co = 'Y'; DWrite(chan, &co, 1); goto fail; default: co = 'N'; DWrite(chan, &co, 1); break; } } fail: UnLock(CurrentDir(oldlock)); FreeMem(fib, sizeof(FIB)); return(ret); } putfile(chan, name, len) char *name; { long fh = Open(name, 1006); long n, r; char rc; if (fh == NULL) { rc = 'N'; DWrite(chan, &rc, 1); return(0); } rc = 'Y'; DWrite(chan, &rc, 1); while (len) { r = (len > sizeof(Buf)) ? sizeof(Buf) : len; n = DRead(chan, Buf, r); if (n != r) break; if (Write(fh, Buf, n) != n) break; len -= n; } Close(fh); if (len) { unlink(name); return(-1); } rc = 'Y'; DWrite(chan, &rc, 1); return(0); }