home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff294.lzh
/
DNet
/
unix
/
server
/
sgcopy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-11
|
5KB
|
330 lines
/*
* SGCOPY.C V1.1
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
* GET-COPY SERVER (NEW COPY SERVER)
*
* The current version only accepts one connection at a time. This server
* will send requested files to the remote machine.
*
* length in 68000 longword format.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/resource.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include "servers.h"
typedef struct {
char Cmd;
char Str[64];
long Val;
} HDR;
typedef unsigned char ubyte;
char *getnamepart();
char *getdirpart();
char Buf[4096];
int Chan;
chandler()
{
union wait stat;
struct rusage rus;
while (wait3(&stat, WNOHANG, &rus) > 0);
}
main(ac,av)
char *av[];
{
long chann = DListen(PORT_GFILECOPY);
int fd;
int n;
char buf[256];
extern int errno;
if (av[1])
chdir(av[1]);
signal(SIGCHLD, chandler);
signal(SIGPIPE, SIG_IGN);
for (;;) {
fd = DAccept(chann);
if (fd < 0) {
if (errno == EINTR)
continue;
break;
}
if (fork() == NULL) {
SGCopy(fd);
_exit(1);
}
close(fd);
}
perror("SCOPY");
}
SGCopy(fd)
int fd;
{
short error = 0;
static HDR Hdr;
Chan = fd;
error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
if (error)
return(error);
switch(ReadHeader(&Hdr)) {
default:
case -1:
error = 1;
return(error);
case 'H':
break;
}
while (!error) {
switch(ReadHeader(&Hdr)) {
case 'G':
{
char svdir[1024];
getwd(svdir);
if (chdir(getdirpart(Hdr.Str)) < 0) {
error = WriteHeader('N', "Unable to cd to dir", 0);
} else {
error = PutObject(getnamepart(Hdr.Str));
}
chdir(svdir);
}
break;
case 'E':
goto done;
case 'P': /* put-files, not implemented */
default:
error = 1;
break;
}
}
done:
;
}
PutObject(str)
char *str;
{
struct stat stat;
short error = 0;
if (lstat(str, &stat) < 0) {
error = WriteHeader('N', "Unable to find object", 0);
return(0);
}
if (stat.st_mode & S_IFDIR) {
error = PutDir(str);
} else {
error = PutFile(str);
}
return(0);
}
PutDir(name)
char *name;
{
struct stat stat;
char svdir[1024];
static HDR Hdr;
short error = 0;
char *fn = getnamepart(name);
DIR *dir;
struct direct *de;
if (lstat(name, &stat) < 0 || !(dir = opendir(name))) {
WriteHeader('N', "Possible Disk Error", 0);
error = 1;
goto done;
}
if (error = WriteHeader('D', fn, 0))
goto done;
switch(ReadHeader(&Hdr)) {
case 'Y':
break;
case 'S':
goto done;
case 'N':
error = 1;
break;
default:
error = 1;
break;
}
if (error)
goto done;
getwd(svdir);
if (chdir(name) < 0) {
error = 1;
WriteHeader('N', "unable to chdir", 0);
}
if (error)
goto done;
while (de = readdir(dir)) {
if (strcmp(de->d_name, ".") == 0)
continue;
if (strcmp(de->d_name, "..") == 0)
continue;
if (lstat(de->d_name, &stat) < 0) {
continue;
}
if (stat.st_mode & S_IFDIR) {
error = PutDir(de->d_name);
} else {
error = PutFile(de->d_name);
}
if (error)
break;
}
WriteHeader('E', NULL, 0);
chdir(svdir);
done:
return(error);
}
PutFile(name)
char *name;
{
int fd = -1;
static HDR Hdr;
long len;
short error = 0;
char *fn = getnamepart(name);
fd = open(fn, O_RDONLY, 0);
if (fd < 0) { /* don't do anything if unable to open it */
WriteHeader('N', "file not readable", 0);
goto done;
}
len = lseek(fd, 0L, 2);
if (error = WriteHeader('F', fn, len))
goto done;
switch(ReadHeader(&Hdr)) {
case 'Y':
lseek(fd, Hdr.Val, 0); /* start pos. */
len -= Hdr.Val;
if (len < 0)
len = 0;
break;
case 'S':
goto done;
case 'N':
error = 1;
break;
default:
error = 1;
break;
}
if (error)
goto done;
while (len) {
register long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
if (read(fd, Buf, n) != n) { /* read failed! */
error = 10;
goto done;
}
if (gwrite(Chan, Buf, n) != n) {
error = 10;
goto done;
}
len -= n;
}
done:
if (fd >= 0)
close(fd);
return(error);
}
WriteHeader(c, str, len)
char c;
char *str;
long len;
{
ubyte sl;
if (str == NULL)
str = "";
sl = strlen(str);
if (gwrite(Chan, &c, 1) < 0)
return(1);
if (gwrite(Chan, &sl,1) < 0)
return(1);
if (gwrite(Chan, str, sl) != sl)
return(1);
len = htonl68(len);
if (gwrite(Chan, &len, 4) != 4)
return(1);
return(0);
}
ReadHeader(hdr)
HDR *hdr;
{
ubyte sl;
ubyte cmd;
hdr->Cmd = -1;
if (ggread(Chan, &cmd, 1) != 1)
return(-1);
if (ggread(Chan, &sl, 1) != 1)
return(-1);
if (sl >= sizeof(hdr->Str)) {
return(-1);
}
if (ggread(Chan, hdr->Str, sl) != sl)
return(-1);
hdr->Str[sl] = 0;
if (ggread(Chan, &hdr->Val, 4) != 4)
return(-1);
hdr->Val = ntohl68(hdr->Val);
hdr->Cmd = cmd;
return(hdr->Cmd);
}
char *
getnamepart(str)
char *str;
{
register char *ptr = str + strlen(str);
while (ptr >= str) {
if (*ptr == '/')
break;
--ptr;
}
return(ptr+1);
}
char *
getdirpart(str)
char *str;
{
static char buf[1024];
strcpy(buf, str);
getnamepart(buf)[0] = 0;
if (buf[0] == 0)
return(".");
return(buf);
}