#include "afs/auth.h"
#include "afs/cellconfig.h"
#include "afs/vice.h"
-#include "afs/kauth.h"
-#include "afs/kautils.h"
#include "afs/afsutil.h"
+#include "afs/afs_bypasscache.h"
#include "rx/rx_globals.h"
#include "afsd/afsd.h"
afs_lock_t osi_flplock;
afs_lock_t osi_fsplock;
-#ifndef NETSCAPE_NSAPI
-
/*
* Mutex and condition variable used to implement sleep
*/
pthread_mutex_t usr_sleep_mutex;
pthread_cond_t usr_sleep_cond;
-#endif /* !NETSCAPE_NSAPI */
-
int call_syscall(long, long, long, long, long, long);
int fork_syscall(long, long, long, long, long, long);
* Every user is a super user
*/
int
-afs_osi_suser(void *credp)
+afs_osi_suser(afs_ucred_t *credp)
{
return 1;
}
int
-afs_suser(void *credp)
+afs_suser(afs_ucred_t *credp)
{
return 1;
}
* These are no-ops in user space
*/
-void
-afs_osi_SetTime(osi_timeval_t * atv)
-{
- return;
-}
-
/*
* xflock should never fall through, the only files we know
* about are AFS files
{
struct usr_ucred *newcredp;
- newcredp = (struct usr_ucred *)afs_osi_Alloc(sizeof(struct usr_ucred));
+ newcredp = afs_osi_Alloc(sizeof(struct usr_ucred));
*newcredp = *credp;
newcredp->cr_ref = 1;
return newcredp;
{
struct usr_ucred *newcredp;
- newcredp = (struct usr_ucred *)afs_osi_Alloc(sizeof(struct usr_ucred));
+ newcredp = afs_osi_Alloc(sizeof(struct usr_ucred));
newcredp->cr_ref = 1;
return newcredp;
}
* allocate the data block, so pthread_finish can free the buffer
* when this thread terminates.
*/
- uptr =
- (struct usr_user *)malloc(sizeof(struct usr_user) +
- sizeof(struct usr_ucred));
+ uptr = malloc(sizeof(struct usr_user) + sizeof(struct usr_ucred));
usr_assert(uptr != NULL);
uptr->u_error = 0;
uptr->u_prio = 0;
{
struct usr_user *uptr;
int st;
- st = usr_getspecific(afs_global_u_key, (void **)&uptr);
+
+ st = usr_getspecific(afs_global_u_key, &uptr);
usr_assert(st == 0);
if (uptr == NULL) {
uafs_InitThread();
- st = usr_getspecific(afs_global_u_key, (void **)&uptr);
+ st = usr_getspecific(afs_global_u_key, &uptr);
usr_assert(st == 0);
usr_assert(uptr != NULL);
}
}
index = WAITHASH(x);
if (osi_waithash_avail == NULL) {
- waitp = (osi_wait_t *) afs_osi_Alloc(sizeof(osi_wait_t));
+ waitp = afs_osi_Alloc(sizeof(osi_wait_t));
usr_cond_init(&waitp->cond);
} else {
waitp = osi_waithash_avail;
}
index = WAITHASH((caddr_t) handle);
if (osi_waithash_avail == NULL) {
- waitp = (osi_wait_t *) afs_osi_Alloc(sizeof(osi_wait_t));
+ waitp = afs_osi_Alloc(sizeof(osi_wait_t));
usr_cond_init(&waitp->cond);
} else {
waitp = osi_waithash_avail;
AFS_ASSERT_GLOCK();
AFS_GUNLOCK();
- fp = (struct osi_file *)afs_osi_Alloc(sizeof(struct osi_file));
+ fp = afs_osi_Alloc(sizeof(struct osi_file));
usr_assert(fp != NULL);
usr_assert(ino->ufs);
}
int
-osi_GetTime(struct timeval *tv)
-{
- gettimeofday(tv, NULL);
- return 0;
-}
-
-int
-osi_SetTime(struct timeval *tv)
-{
- return 0;
-}
-
-int
osi_Active(struct vcache *avc)
{
AFS_STATCNT(osi_Active);
afs_global_procp->p_ppid = (pid_t) 1;
afs_global_procp->p_ucred = afs_global_ucredp;
-#ifndef NETSCAPE_NSAPI
/*
* Initialize the mutex and condition variable used to implement
* time sleeps.
*/
pthread_mutex_init(&usr_sleep_mutex, NULL);
pthread_cond_init(&usr_sleep_cond, NULL);
-#endif /* !NETSCAPE_NSAPI */
/*
* Initialize the hash table used for sleep/wakeup
usr_assert(code == 0);
}
+/**
+ * Calculate the cacheMountDir used for a specified dir.
+ *
+ * @param[in] dir Desired mount dir
+ * @param[out] mountdir On success, contains the literal string that should
+ * be used as the cache mount dir.
+ * @param[in] size The number of bytes allocated in mountdir
+ *
+ * @post On success, mountdir begins with a slash, and does not contain two
+ * slashes adjacent to each other
+ *
+ * @return operation status
+ * @retval 0 success
+ * @retval ENAMETOOLONG the specified dir is too long to fix in the given
+ * mountdir buffer
+ * @retval EINVAL the specified dir does not actually specify any meaningful
+ * mount directory
+ */
+static int
+calcMountDir(const char *dir, char *mountdir, size_t size)
+{
+ char buf[1024];
+ char lastchar;
+ char *p;
+ int len;
+
+ if (dir && strlen(dir) > size-1) {
+ return ENAMETOOLONG;
+ }
+
+ /*
+ * Initialize the AFS mount point, default is '/afs'.
+ * Strip duplicate/trailing slashes from mount point string.
+ * afs_mountDirLen is set to strlen(afs_mountDir).
+ */
+ if (!dir) {
+ dir = "afs";
+ }
+ sprintf(buf, "%s", dir);
+
+ mountdir[0] = '/';
+ len = 1;
+ for (lastchar = '/', p = &buf[0]; *p != '\0'; p++) {
+ if (lastchar != '/' || *p != '/') {
+ mountdir[len++] = lastchar = *p;
+ }
+ }
+ if (lastchar == '/' && len > 1)
+ len--;
+ mountdir[len] = '\0';
+ if (len <= 1) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
void
uafs_mount(void) {
int rc;
return;
}
+void
+uafs_setMountDir(const char *dir)
+{
+ if (dir) {
+ int rc;
+ char tmp_mountDir[1024];
+
+ rc = calcMountDir(dir, tmp_mountDir, sizeof(tmp_mountDir));
+ if (rc) {
+ afs_warn("Invalid mount dir specification (error %d): %s\n", rc, dir);
+ } else {
+ if (strcmp(tmp_mountDir, afs_mountDir) != 0) {
+ /* mount dir changed */
+ strcpy(afs_mountDir, tmp_mountDir);
+ afs_mountDirLen = strlen(afs_mountDir);
+ }
+ }
+ }
+}
+
int
uafs_statvfs(struct statvfs *buf)
{
long param4;
};
-#ifdef NETSCAPE_NSAPI
-void
-syscallThread(void *argp)
-#else /* NETSCAPE_NSAPI */
void *
syscallThread(void *argp)
-#endif /* NETSCAPE_NSAPI */
{
int i;
struct usr_ucred *crp;
int
uafs_Setup(const char *mount)
{
- char buf[1024];
- char lastchar;
- char *p;
+ int rc;
static int inited = 0;
if (inited) {
}
inited = 1;
- if (mount && strlen(mount) > 1023) {
- return ENAMETOOLONG;
- }
-
- /*
- * Initialize the AFS mount point, default is '/afs'.
- * Strip duplicate/trailing slashes from mount point string.
- * afs_mountDirLen is set to strlen(afs_mountDir).
- */
- if (!mount) {
- mount = "afs";
- }
- sprintf(buf, "%s", mount);
-
- afs_mountDir[0] = '/';
- afs_mountDirLen = 1;
- for (lastchar = '/', p = &buf[0]; *p != '\0'; p++) {
- if (lastchar != '/' || *p != '/') {
- afs_mountDir[afs_mountDirLen++] = lastchar = *p;
- }
- }
- if (lastchar == '/' && afs_mountDirLen > 1)
- afs_mountDirLen--;
- afs_mountDir[afs_mountDirLen] = '\0';
- if (afs_mountDirLen <= 1) {
- return EINVAL;
+ rc = calcMountDir(mount, afs_mountDir, sizeof(afs_mountDir));
+ if (rc) {
+ return rc;
}
+ afs_mountDirLen = strlen(afs_mountDir);
/* initialize global vars and such */
osi_Init();
}
/*
+ * Lookup the target of a symbolic link
+ * Call VN_HOLD on the output vnode if successful.
+ * Returns zero on success, error code on failure.
+ * If provided, use a path for confirming we are not linked to ourself.
+ *
+ * Note: Caller must hold the AFS global lock.
+ */
+static int
+uafs_LookupLinkPath(struct usr_vnode *vp, struct usr_vnode *parentVp,
+ char *ppathP, struct usr_vnode **vpp)
+{
+ int code;
+ int len;
+ char *pathP;
+ struct usr_vnode *linkVp;
+ struct usr_uio uio;
+ struct iovec iov[1];
+
+ AFS_ASSERT_GLOCK();
+
+ pathP = afs_osi_Alloc(MAX_OSI_PATH + 1);
+ usr_assert(pathP != NULL);
+
+ /*
+ * set up the uio buffer
+ */
+ iov[0].iov_base = pathP;
+ iov[0].iov_len = MAX_OSI_PATH + 1;
+ uio.uio_iov = &iov[0];
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_segflg = 0;
+ uio.uio_fmode = FREAD;
+ uio.uio_resid = MAX_OSI_PATH + 1;
+
+ /*
+ * Read the link data
+ */
+ code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
+ if (code) {
+ afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+ return code;
+ }
+ len = MAX_OSI_PATH + 1 - uio.uio_resid;
+ pathP[len] = '\0';
+
+ /* are we linked to ourname or ./ourname? ELOOP */
+ if (ppathP) {
+ if ((strcmp(pathP, ppathP) == 0) ||
+ ((pathP[0] == '.') &&
+ (pathP[1] == '/') &&
+ (strcmp(&(pathP[2]), ppathP) == 0))) {
+ return ELOOP;
+ }
+ }
+
+ /*
+ * Find the target of the symbolic link
+ */
+ code = uafs_LookupName(pathP, parentVp, &linkVp, 1, 0);
+ if (code) {
+ afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+ return code;
+ }
+
+ afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+ *vpp = linkVp;
+ return 0;
+}
+
+/*
* Lookup a file or directory given its path.
* Call VN_HOLD on the output vnode if successful.
* Returns zero on success, error code on failure.
*/
nextVc = NULL;
nextVp = NULL;
-#ifdef AFS_WEB_ENHANCEMENTS
if ((nextPathP != NULL && *nextPathP != '\0') || !no_eval_mtpt)
code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
else
code =
afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred,
AFS_LOOKUP_NOEVAL);
-#else
- code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
-#endif /* AFS_WEB_ENHANCEMENTS */
if (nextVc)
nextVp=AFSTOV(nextVc);
if (code != 0) {
afs_osi_Free(tmpPath, strlen(path) + 1);
return code;
}
- code = uafs_LookupLink(nextVp, vp, &linkVp);
+ code = uafs_LookupLinkPath(nextVp, vp, NULL, &linkVp);
if (code) {
VN_RELE(vp);
VN_RELE(nextVp);
return 0;
}
-/*
- * Lookup the target of a symbolic link
- * Call VN_HOLD on the output vnode if successful.
- * Returns zero on success, error code on failure.
- *
- * Note: Caller must hold the AFS global lock.
- */
int
uafs_LookupLink(struct usr_vnode *vp, struct usr_vnode *parentVp,
struct usr_vnode **vpp)
{
- int code;
- int len;
- char *pathP;
- struct usr_vnode *linkVp;
- struct usr_uio uio;
- struct iovec iov[1];
-
- AFS_ASSERT_GLOCK();
-
- pathP = afs_osi_Alloc(MAX_OSI_PATH + 1);
- usr_assert(pathP != NULL);
-
- /*
- * set up the uio buffer
- */
- iov[0].iov_base = pathP;
- iov[0].iov_len = MAX_OSI_PATH + 1;
- uio.uio_iov = &iov[0];
- uio.uio_iovcnt = 1;
- uio.uio_offset = 0;
- uio.uio_segflg = 0;
- uio.uio_fmode = FREAD;
- uio.uio_resid = MAX_OSI_PATH + 1;
-
- /*
- * Read the link data
- */
- code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
- if (code) {
- afs_osi_Free(pathP, MAX_OSI_PATH + 1);
- return code;
- }
- len = MAX_OSI_PATH + 1 - uio.uio_resid;
- pathP[len] = '\0';
-
- /*
- * Find the target of the symbolic link
- */
- code = uafs_LookupName(pathP, parentVp, &linkVp, 1, 0);
- if (code) {
- afs_osi_Free(pathP, MAX_OSI_PATH + 1);
- return code;
- }
-
- afs_osi_Free(pathP, MAX_OSI_PATH + 1);
- *vpp = linkVp;
- return 0;
+ return uafs_LookupLinkPath(vp, parentVp, NULL, vpp);
}
/*
}
int
+uafs_pread_nocache(int fd, char *buf, int len, off_t offset)
+{
+ int retval;
+ AFS_GLOCK();
+ retval = uafs_pread_nocache_r(fd, buf, len, offset);
+ AFS_GUNLOCK();
+ return retval;
+}
+
+int
+uafs_pread_nocache_r(int fd, char *buf, int len, off_t offset)
+{
+ int code;
+ struct iovec iov[1];
+ struct usr_vnode *fileP;
+ struct nocache_read_request *bparms;
+ struct usr_uio uio;
+
+ /*
+ * Make sure this is an open file
+ */
+ fileP = afs_FileTable[fd];
+ if (fileP == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /* these get freed in PrefetchNoCache, so... */
+ bparms = afs_osi_Alloc(sizeof(struct nocache_read_request));
+
+ code = afs_CreateReq(&bparms->areq, get_user_struct()->u_cred);
+ if (code) {
+ afs_DestroyReq(bparms->areq);
+ afs_osi_Free(bparms, sizeof(struct nocache_read_request));
+ errno = code;
+ return -1;
+ }
+
+ bparms->auio = &uio;
+ bparms->offset = offset;
+ bparms->length = len;
+
+ /*
+ * set up the uio buffer
+ */
+ iov[0].iov_base = buf;
+ iov[0].iov_len = len;
+ uio.uio_iov = &iov[0];
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = offset;
+ uio.uio_segflg = 0;
+ uio.uio_fmode = FREAD;
+ uio.uio_resid = len;
+
+ /*
+ * do the read
+ */
+ code = afs_PrefetchNoCache(VTOAFS(fileP), get_user_struct()->u_cred,
+ bparms);
+
+ if (code) {
+ errno = code;
+ return -1;
+ }
+
+ afs_FileOffsets[fd] = uio.uio_offset;
+ return (len - uio.uio_resid);
+}
+
+int
uafs_pread(int fd, char *buf, int len, off_t offset)
{
int retval;
struct usr_uio uio;
struct iovec iov[1];
struct usr_vnode *fileP;
- struct usr_buf *bufP;
/*
* Make sure this is an open file
/*
* do the read
*/
- code = afs_read(VTOAFS(fileP), &uio, get_user_struct()->u_cred, 0, &bufP, 0);
+ code = afs_read(VTOAFS(fileP), &uio, get_user_struct()->u_cred, 0);
if (code) {
errno = code;
return -1;
stats->st_atime = attrs.va_atime.tv_sec;
stats->st_mtime = attrs.va_mtime.tv_sec;
stats->st_ctime = attrs.va_ctime.tv_sec;
+ /* preserve dv if possible */
+#if defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
+ stats->st_atimespec.tv_nsec = attrs.va_atime.tv_usec * 1000;
+ stats->st_mtimespec.tv_nsec = attrs.va_mtime.tv_usec * 1000;
+ stats->st_ctimespec.tv_nsec = attrs.va_ctime.tv_usec * 1000;
+#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
+ stats->st_atimensec = attrs.va_atime.tv_usec * 1000;
+ stats->st_mtimensec = attrs.va_mtime.tv_usec * 1000;
+ stats->st_ctimensec = attrs.va_ctime.tv_usec * 1000;
+#endif
stats->st_blksize = attrs.va_blocksize;
stats->st_blocks = attrs.va_blocks;
attrs.va_mode = 0777;
attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
- code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, get_user_struct()->u_cred);
+ code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, NULL,
+ get_user_struct()->u_cred);
VN_RELE(dirP);
if (code != 0) {
errno = code;
/*
* Set up the directory structures
*/
- dirp =
- (usr_DIR *) afs_osi_Alloc(sizeof(usr_DIR) + USR_DIRSIZE +
- sizeof(struct usr_dirent));
+ dirp = afs_osi_Alloc(sizeof(usr_DIR) + USR_DIRSIZE +
+ sizeof(struct usr_dirent));
usr_assert(dirp != NULL);
dirp->dd_buf = (char *)(dirp + 1);
dirp->dd_fd = fd;
}
/*
- * Do AFS authentication
- */
-int
-uafs_klog(char *user, char *cell, char *passwd, char **reason)
-{
- int code;
- afs_int32 password_expires = -1;
-
- usr_mutex_lock(&osi_authenticate_lock);
- code =
- ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION +
- KA_USERAUTH_DOSETPAG2, user, NULL, cell,
- passwd, 0, &password_expires, 0, reason);
- usr_mutex_unlock(&osi_authenticate_lock);
- return code;
-}
-
-int
-uafs_klog_r(char *user, char *cell, char *passwd, char **reason)
-{
- int retval;
- AFS_GUNLOCK();
- retval = uafs_klog(user, cell, passwd, reason);
- AFS_GLOCK();
- return retval;
-}
-
-/*
* Destroy AFS credentials from the kernel cache
*/
int
return NULL;
}
-#ifdef AFS_WEB_ENHANCEMENTS
-/*
- * uafs_klog_nopag
- * klog but don't allocate a new pag
- */
-int
-uafs_klog_nopag(char *user, char *cell, char *passwd, char **reason)
-{
- int code;
- afs_int32 password_expires = -1;
-
- usr_mutex_lock(&osi_authenticate_lock);
- code = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION
- /*+KA_USERAUTH_DOSETPAG2 */ , user,
- NULL, cell, passwd, 0,
- &password_expires, 0, reason);
- usr_mutex_unlock(&osi_authenticate_lock);
- return code;
-}
-
/*
* uafs_getcellstatus
* get the cell status
{
int rc;
struct afs_ioctl iob;
- VolumeStatus *status;
- char buf[1024];
+ VolumeStatus status;
iob.in = 0;
iob.in_size = 0;
- iob.out = buf;
- iob.out_size = 1024;
+ iob.out = (char *)&status;
+ iob.out_size = sizeof status;
rc = call_syscall(AFSCALL_PIOCTL, (long)path, _VICEIOCTL(4), (long)&iob,
0, 0);
return -1;
}
- status = (VolumeStatus *) buf;
- *BlocksInUse = status->BlocksInUse;
- *MaxQuota = status->MaxQuota;
+ *BlocksInUse = status.BlocksInUse;
+ *MaxQuota = status.MaxQuota;
return 0;
}
{
int rc;
struct afs_ioctl iob;
- VolumeStatus *status;
- char buf[1024];
+ VolumeStatus status = { 0 };
- iob.in = buf;
- iob.in_size = 1024;
+ iob.in = (char *)&status;
+ iob.in_size = sizeof status;
iob.out = 0;
iob.out_size = 0;
- memset(buf, 0, sizeof(VolumeStatus));
- status = (VolumeStatus *) buf;
- status->MaxQuota = MaxQuota;
- status->MinQuota = -1;
+ status.MaxQuota = MaxQuota;
+ status.MinQuota = -1;
rc = call_syscall(AFSCALL_PIOCTL, (long)path, _VICEIOCTL(5), (long)&iob,
0, 0);
* Get a list of rights for the current user on path.
*/
int
+uafs_access(char *path, int flags)
+{
+ int code;
+ struct vnode *vp;
+ int fileMode = 0;
+
+ if (flags & R_OK) {
+ fileMode |= VREAD;
+ }
+ if (flags & W_OK) {
+ fileMode |= VWRITE;
+ }
+ if (flags & X_OK) {
+ fileMode |= VEXEC;
+ }
+
+ AFS_GLOCK();
+ code = uafs_LookupName(path, afs_CurrentDir, &vp, 1, 0);
+ if (code != 0) {
+ errno = code;
+ AFS_GUNLOCK();
+ return -1;
+ }
+
+ code = afs_access(VTOAFS(vp), fileMode, get_user_struct()->u_cred);
+ VN_RELE(vp);
+
+ if (code != 0)
+ errno = code;
+
+ AFS_GUNLOCK();
+ return code ? -1 : 0;
+}
+
+/*
+ * uafs_getRights
+ * Get a list of rights for the current user on path.
+ */
+int
uafs_getRights(char *path)
{
int code;
AFS_GUNLOCK();
return afs_rights;
}
-#endif /* AFS_WEB_ENHANCEMENTS */
-
#endif /* UKERNEL */