home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
tcp
/
Networking
/
TCP
/
Server
/
wu-ftpd
/
src
/
amitcp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-15
|
4KB
|
196 lines
/*
* This module contains __open() and fstat() from AmiTCP 3.0 beta 2
* which will be recompiled with our redefined getumask(), geteuid()
* and getegid() functions from config.h so that we don't need to open
* usergroup.library if multiuser.library is installed.
*
* Author is Jarno Rajahalme <Jarno.Rajahalme@hut.fi>.
*
* Copyright © 1993,1994 AmiTCP/IP Group, <amitcp-group@hut.fi>
* Helsinki University of Technology, Finland.
* All rights reserved.
*/
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <dos.h>
#include <ios1.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <bsdsocket.h>
#include "AmiTCP:src/netlib/netlib.h"
#include "AmiTCP:src/netlib/fibex.h"
#include "config.h"
int fstat(int fd, struct stat *st)
{
struct UFB *ufb = chkufb(fd);
if (st == NULL || ((1 & (long)st) == 1)) {
errno = EFAULT;
return -1;
}
if (ufb == NULL || ufb->ufbflg == 0) {
errno = EBADF;
return -1;
}
if (ufb->ufbflg & UFB_SOCK) { /* a socket */
long value;
long size = sizeof(value);
bzero(st, sizeof(*st));
/* st->st_dev = ??? */
st->st_mode = S_IFSOCK | S_IRUSR | S_IWUSR;
st->st_uid = geteuid();
st->st_gid = getegid();
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &size) == 0)
st->st_blksize = value;
return 0;
} else { /* ordinal file */
if (ExamineFH(ufb->ufbfh, __dostat_fib)) {
__dostat(__dostat_fib, st);
st->st_dev = (dev_t)((struct FileHandle *)BADDR(ufb->ufbfh))->fh_Type;
return 0;
} else {
errno = EIO;
return -1;
}
}
}
extern int (*__closefunc)(int);
__stdargs int
__open(const char *name, int mode, ...)
{
struct UFB *ufb;
int fd;
int flags;
char newfile = TRUE;
BPTR file;
/*
* Set up __closefunc (which is used at cleanup)
*/
__closefunc = __close;
/*
* Check for the break signals
*/
__chkabort();
/*
* find first free ufb
*/
ufb = __allocufb(&fd);
if (ufb == NULL)
return -1; /* errno is set by the __allocufb() */
/*
* malloc space for the name & copy it
*/
if ((ufb->ufbfn = malloc(strlen(name)+1)) == NULL) {
SET_OSERR(ERROR_NO_FREE_STORE);
errno = ENOMEM;
return -1;
}
strcpy(ufb->ufbfn, name);
/*
* Translate mode to ufb flags
*/
switch (mode & (O_WRONLY | O_RDWR)) {
case O_RDONLY:
if (mode & (O_APPEND | O_CREAT | O_TRUNC | O_EXCL)) {
errno = EINVAL;
return -1;
}
flags = UFB_RA;
break;
case O_WRONLY:
flags = UFB_WA;
break;
case O_RDWR:
flags = UFB_RA | UFB_WA;
break;
default:
errno = EINVAL;
return -1;
}
if (mode & O_APPEND)
flags |= UFB_APP;
if (mode & O_XLATE)
flags |= UFB_XLAT;
if (mode & O_TEMP)
flags |= UFB_TEMP;
if (mode & O_CREAT) {
BPTR lock;
if (lock = Lock((char *)name, SHARED_LOCK)) {
if (mode & O_EXCL) {
UnLock(lock);
errno = EEXIST;
free(ufb->ufbfn);
return -1;
}
if (mode & O_TRUNC)
newfile = FALSE;
else
mode &= ~O_CREAT;
UnLock(lock);
}
}
if (mode & O_CREAT) {
if ((file = Open((char *)name, MODE_NEWFILE)) == NULL)
goto osfail;
if (newfile) {
va_list va;
int cmode;
va_start(va, mode);
cmode = va_arg(va, int) & ~getumask();
chmod((char *)name, cmode); /* hope this doesn't fail :-) */
}
}
else {
if ((file = Open((char *)name,
(flags & UFB_WA && mode & O_LOCK) ?
MODE_READWRITE : MODE_OLDFILE)) == NULL)
goto osfail;
}
/*
* All done! Setting the ufb->ufbflg field to non-zero value marks
* this ufb used.
*/
ufb->ufbflg = flags;
ufb->ufbfh = (long)file;
return fd;
osfail:
{
int code = IoErr();
if (ufb->ufbfn)
free(ufb->ufbfn);
set_errno(code);
}
return -1;
}