home *** CD-ROM | disk | FTP | other *** search
- /*
- * Amiga support routines for wuarchive ftp daemon
- * © 1994 Blaz Zupan, <blaz.zupan@uni-mb.si
- * All Rights Reserved
- *
- * Contains: fchown(), chroot(), IsInRoot(), chdir(), getcwd()
- *
- */
-
- #include <exec/memory.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <string.h>
- #include <stdlib.h>
- #include <errno.h>
- #include "/src/config.h"
-
- #if 0
- #include <proto/usergroup.h>
- #include <ios1.h>
-
- /* This is a terrible hack. First we try to find the UFB with
- * a SAS specific function and extract the Amiga filehandle from
- * it. Then we close the file (by using the Amiga filehandle) and
- * set the owner of it and then reopen it (and hope that the
- * reopening succeeds).
- *
- * This will stay a hack as long as C= doesn't provide us with
- * a SetOwner() that can operate on filehandles and locks.
- */
-
- int fchown(int fd, int uid, int gid)
- {
- int ret = -1;
- struct UFB *ufb;
-
- if (ufb = chkufb (fd)) /* SAS specific! */
- {
- Close((BPTR)ufb->ufbfh);
- if (SetOwner(ufb->ufbfn, (uid << 16) + gid))
- ret = 0;
- ufb->ufbfh = Open(ufb->ufbfn, MODE_READWRITE);
- }
- return (ret);
- }
- #else
- int fchown(int fd, int uid, int gid)
- {
- return 0;
- }
- #endif
-
-
- /*
- * This routine is an attempt to emulate the Unix chroot()
- * function. It only saves the name supplied in the global
- * AmigaRootDir. Everything else must be done by the suppord
- * routines (IsInRoot(), chdir() and getcwd()).
- */
- extern int anonymous, guest;
- char AmigaRootDir[MAXPATHLEN + 2] = "";
-
- int
- chroot (char *dir)
- {
- BPTR lock;
-
- if (lock = Lock (dir, SHARED_LOCK))
- {
- NameFromLock (lock, AmigaRootDir, MAXPATHLEN);
- UnLock (lock);
- return 0;
- }
- return -1;
- }
-
- /* Checks to see if file is located under users
- * home directory structure (but only for anonymous and guest users!).
- */
- int
- IsInRoot (char *dir)
- {
- int ret = 0;
- BPTR lock;
-
- if (!anonymous && !guest)
- return 1;
-
- if (lock = Lock (dir, SHARED_LOCK))
- {
- char name[MAXPATHLEN];
-
- if (NameFromLock (lock, name, MAXPATHLEN))
- {
- if (strlen (AmigaRootDir) <= strlen (name))
- {
- if (!strncmp (AmigaRootDir, name, strlen (AmigaRootDir)))
- ret = 1;
- }
- }
- UnLock (lock);
- }
- return ret;
- }
-
- /* chdir() replacement that enables use of chroot() */
- int
- chdir (const char *path)
- {
- BPTR lock;
- int err = ENOENT;
- char newpath[MAXPATHLEN];
-
- if (anonymous || guest)
- {
- if (path[0] == '/')
- {
- strcpy(newpath, AmigaRootDir);
- AddPart(newpath, (void *)&path[1], MAXPATHLEN);
- }
- else
- strcpy(newpath, path);
- }
- else
- strcpy(newpath, path);
-
- {
- char tmppath[MAXPATHLEN];
-
- adjustpath(newpath, tmppath, MAXPATHLEN); /* unix<->amiga path conversion */
- strcpy(newpath, tmppath);
- }
-
- if (IsInRoot (newpath))
- {
- if (lock = Lock (newpath, SHARED_LOCK))
- {
- UnLock (CurrentDir (lock));
- err = 0;
- }
- }
- errno = err;
- return err ? -1 : 0;
- }
-
- /* getcwd() replacement that returns a fake directory under
- * users home directory
- */
- char *
- getcwd (char *buf, int size)
- {
- if (!buf)
- buf = malloc (MAXPATHLEN);
-
- if (buf)
- {
- BPTR lock;
-
- if (lock = Lock ("", SHARED_LOCK))
- {
- if (NameFromLock (lock, buf, size))
- {
- if (anonymous || guest)
- {
- if (*(buf + strlen(AmigaRootDir)) == '/')
- strcpy (buf, buf + strlen (AmigaRootDir));
- else
- {
- strcpy (buf + 1, buf + strlen (AmigaRootDir));
- buf[0] = '/';
- }
- }
- }
- else
- errno = ENOMEM;
- UnLock (lock);
- }
- else
- errno = ENOENT;
- }
- else
- errno = ENOMEM;
- return buf;
- }
-