vrele(fdvp);
vrele(fvp);
#else
-#ifdef notdef
if (error == EXDEV) {
- /* The idea would be to have a userspace handler like afsdb to
- * run mv as the user, thus:
- */
- printf("su %d -c /bin/mv /afs/.:mount/%d:%d:%d:%d/%s /afs/.:mount/%d:%d:%d:%d/%s\n",
- afs_cr_uid(cn_cred(tcnp)), fvc->f.fid.Cell, fvc->f.fid.Fid.Volume,
- fvc->f.fid.Fid.Vnode, fvc->f.fid.Fid.Unique, fname,
- tvc->f.fid.Cell, tvc->f.fid.Fid.Volume, tvc->f.fid.Fid.Vnode,
- tvc->f.fid.Fid.Unique, tname);
+ struct brequest *tb;
+ struct afs_uspc_param mvReq;
+ struct vcache *tvc;
+ struct vcache *fvc = VTOAFS(fdvp);
+ int code = 0;
+ struct afs_fakestat_state fakestate;
+ int fakestatdone = 0;
+
+ tvc = VTOAFS(tdvp);
+
+ /* unrewritten mount point? */
+ if (tvc->mvstat == 1) {
+ if (tvc->mvid && (tvc->f.states & CMValid)) {
+ struct vrequest treq;
+
+ afs_InitFakeStat(&fakestate);
+ code = afs_InitReq(&treq, vop_cred);
+ if (!code) {
+ fakestatdone = 1;
+ code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
+ } else
+ afs_PutFakeStat(&fakestate);
+ }
+ }
+
+ if (!code) {
+ /* at some point in the future we should allow other types */
+ mvReq.reqtype = AFS_USPC_UMV;
+ mvReq.req.umv.id = afs_cr_uid(cn_cred(tcnp));
+ mvReq.req.umv.idtype = IDTYPE_UID;
+ mvReq.req.umv.sCell = fvc->f.fid.Cell;
+ mvReq.req.umv.sVolume = fvc->f.fid.Fid.Volume;
+ mvReq.req.umv.sVnode = fvc->f.fid.Fid.Vnode;
+ mvReq.req.umv.sUnique = fvc->f.fid.Fid.Unique;
+ mvReq.req.umv.dCell = tvc->f.fid.Cell;
+ mvReq.req.umv.dVolume = tvc->f.fid.Fid.Volume;
+ mvReq.req.umv.dVnode = tvc->f.fid.Fid.Vnode;
+ mvReq.req.umv.dUnique = tvc->f.fid.Fid.Unique;
+
+ /*
+ * su %d -c mv /afs/.:mount/%d:%d:%d:%d/%s
+ * /afs/.:mount/%d:%d:%d:%d/%s where:
+ * mvReq.req.umv.id, fvc->f.fid.Cell, fvc->f.fid.Fid.Volume,
+ * fvc->f.fid.Fid.Vnode, fvc->f.fid.Fid.Unique, fname,
+ * tvc->f.fid.Cell, tvc->f.fid.Fid.Volume, tvc->f.fid.Fid.Vnode,
+ * tvc->f.fid.Fid.Unique, tname
+ */
+
+ tb = afs_BQueue(BOP_MOVE, NULL, 0, 1, cn_cred(tcnp),
+ 0L, 0L, &mvReq, fname, tname);
+ /* wait to collect result */
+ while ((tb->flags & BUVALID) == 0) {
+ tb->flags |= BUWAIT;
+ afs_osi_Sleep(tb);
+ }
+ /* if we succeeded, clear the error. otherwise, EXDEV */
+ if (mvReq.retval == 0)
+ error = 0;
+
+ afs_BRelease(tb);
+ }
+
+ if (fakestatdone)
+ afs_PutFakeStat(&fakestate);
}
-#endif
AFS_GUNLOCK();
cache_purge(fdvp);
static int
EvalMountData(char type, char *data, afs_uint32 states, afs_uint32 cellnum,
struct volume **avolpp, register struct vrequest *areq,
- afs_uint32 *acellidxp, afs_uint32 *avolnump, afs_uint32 *avnoidp)
+ afs_uint32 *acellidxp, afs_uint32 *avolnump,
+ afs_uint32 *avnoidp, afs_uint32 *auniqp)
{
struct volume *tvp = 0;
struct VenusFid tfid;
struct cell *tcell;
- char *cpos, *volnamep, *x;
- char *buf;
+ char *cpos, *volnamep;
+ char *buf, *endptr;
afs_int32 prefetch; /* 1=>None 2=>RO 3=>BK */
afs_int32 mtptCell, assocCell = 0, hac = 0;
afs_int32 samecell, roname, len;
- afs_uint32 volid, cellidx, vnoid = 0;
+ afs_uint32 volid = 0, cellidx, vnoid = 0, uniq = 0;
+ /* Start by figuring out and finding the cell */
cpos = afs_strchr(data, ':'); /* if cell name present */
if (cpos) {
- cellnum = 0;
volnamep = cpos + 1;
*cpos = 0;
- for (x = data; *x >= '0' && *x <= '9'; x++)
- cellnum = (cellnum * 10) + (*x - '0');
- if (cellnum && !*x)
+ if ((afs_strtoi_r(data, &endptr, &cellnum) == 0) &&
+ (endptr == cpos))
tcell = afs_GetCell(cellnum, READ_LOCK);
else {
tcell = afs_GetCellByName(data, READ_LOCK);
volnamep = data;
tcell = afs_GetCell(cellnum, READ_LOCK);
} else {
- /*printf("No cellname %s , or cellnum %d , returning ENODEV\n",
- data, cellnum);*/
+ /* No cellname or cellnum; return ENODEV */
return ENODEV;
}
if (!tcell) {
- /*printf("Lookup failed, returning ENODEV\n");*/
+ /* no cell found; return ENODEV */
return ENODEV;
}
}
afs_PutCell(tcell, READ_LOCK);
- cpos = afs_strrchr(volnamep, ':'); /* if vno present */
- if (cpos)
+ /* If there's nothing to look up, we can't proceed */
+ if (!*volnamep)
+ return ENODEV;
+
+ /* cell found. figure out volume */
+ cpos = afs_strchr(volnamep, ':');
+ if (cpos)
*cpos = 0;
+
/* Look for an all-numeric volume ID */
- volid = 0;
- for (x = volnamep; *x >= '0' && *x <= '9'; x++)
- volid = (volid * 10) + (*x - '0');
- if (cpos) {
- *cpos = ':';
- vnoid = 0;
- if (*x == *cpos) /* allow vno with numeric volid only */
- for (x = (cpos + 1); *x >= '0' && *x <= '9'; x++)
- vnoid = (vnoid * 10) + (*x - '0');
- if (*x)
- vnoid = 0;
- }
+ if ((afs_strtoi_r(volnamep, &endptr, &volid) == 0) &&
+ ((endptr == cpos) || (!*endptr)))
+ {
+ /* Ok. Is there a vnode and uniq? */
+ if (cpos) {
+ char *vnodep = (char *)(cpos + 1);
+ char *uniqp = NULL;
+ if ((!*vnodep) /* no vnode after colon */
+ || !(uniqp = afs_strchr(vnodep, ':')) /* no colon for uniq */
+ || (!*(++uniqp)) /* no uniq after colon */
+ || (afs_strtoi_r(vnodep, &endptr, &vnoid) != 0) /* bad vno */
+ || (*endptr != ':') /* bad vnode field */
+ || (afs_strtoi_r(uniqp, &endptr, &uniq) != 0) /* bad uniq */
+ || (*endptr)) /* anything after uniq */
+ {
+ *cpos = ':';
+ /* sorry. vnode and uniq, or nothing */
+ return ENODEV;
+ }
+ }
+ } else
+ volid = 0;
/*
* If the volume ID was all-numeric, and they didn't ask for a
* as-is. This is currently only used for handling name lookups
* in the dynamic mount directory.
*/
- if (!*x && !avolpp) {
- if (acellidxp)
- *acellidxp = cellidx;
- if (avolnump)
- *avolnump = volid;
- if (avnoidp)
- *avnoidp = vnoid;
- return 0;
+ if (volid && !avolpp) {
+ if (*cpos)
+ *cpos = ':';
+ goto done;
}
/*
* and don't second-guess them by forcing use of a RW volume when
* they gave the ID of something else.
*/
- if (!*x && type == '%') {
+ if (volid && type == '%') {
tfid.Fid.Volume = volid; /* remember BK volume */
tfid.Cell = mtptCell;
tvp = afs_GetVolume(&tfid, areq, WRITE_LOCK); /* get the new one */
- if (!tvp) {
- /*printf("afs_GetVolume failed - returning ENODEV");*/
- return ENODEV; /* oops, can't do it */
- }
+ if (cpos) /* one way or another we're done */
+ *cpos = ':';
+ if (!tvp)
+ return ENODEV; /* afs_GetVolume failed; return ENODEV */
goto done;
}
* The RO volume will be prefetched if requested (but not returned).
* Set up to use volname first.
*/
- cpos = afs_strchr(volnamep, ':'); /* if vno present */
- if (cpos)
- *cpos = 0;
-
- /*printf("Calling GetVolumeByName\n");*/
tvp = afs_GetVolumeByName(volnamep, mtptCell, prefetch, areq, WRITE_LOCK);
/* If no volume was found in this cell, try the associated linked cell */
/* done with volname */
if (cpos)
*cpos = ':';
-
- if (!tvp) {
- /*printf("Couldn't find the volume\n");*/
+ if (!tvp)
return ENODEV; /* Couldn't find the volume */
- }
/* Don't cross mountpoint from a BK to a BK volume */
if ((states & CBackup) && (tvp->states & VBackup)) {
*avolnump = tvp->volume;
if (avnoidp)
*avnoidp = vnoid;
+ if (auniqp)
+ *auniqp = uniq;
if (avolpp)
*avolpp = tvp;
- else
+ else if (tvp)
afs_PutVolume(tvp, WRITE_LOCK);
return 0;
}
struct volume **avolpp, register struct vrequest *areq)
{
afs_int32 code;
- afs_uint32 avnoid;
+ afs_uint32 avnoid, auniq;
AFS_STATCNT(EvalMountPoint);
#ifdef notdef
/* Determine which cell and volume the mointpoint goes to */
code = EvalMountData(avc->linkData[0], avc->linkData + 1,
avc->f.states, avc->f.fid.Cell, avolpp, areq, 0, 0,
- &avnoid);
+ &avnoid, &auniq);
if (code) return code;
if (!avnoid)
avnoid = 1;
+ if (!auniq)
+ auniq = 1;
+
if (avc->mvid == 0)
avc->mvid =
(struct VenusFid *)osi_AllocSmallSpace(sizeof(struct VenusFid));
avc->mvid->Cell = (*avolpp)->cell;
avc->mvid->Fid.Volume = (*avolpp)->volume;
avc->mvid->Fid.Vnode = avnoid;
- avc->mvid->Fid.Unique = 1;
+ avc->mvid->Fid.Unique = auniq;
avc->f.states |= CMValid;
/* Used to: if the mount point is stored within a backup volume,
*/
if (afs_IsDynrootMount(adp)) {
struct VenusFid tfid;
- afs_uint32 cellidx, volid, vnoid;
+ afs_uint32 cellidx, volid, vnoid, uniq;
- code = EvalMountData('%', aname, 0, 0, NULL, &treq, &cellidx, &volid, &vnoid);
+ code = EvalMountData('%', aname, 0, 0, NULL, &treq, &cellidx, &volid, &vnoid, &uniq);
if (code)
goto done;
- afs_GetDynrootMountFid(&tfid);
- tfid.Fid.Vnode = VNUM_FROM_TYPEID(VN_TYPE_MOUNT, cellidx << 2);
- tfid.Fid.Unique = volid;
+ /* If a vnode was returned, it's not a real mount point */
+ if (vnoid > 1) {
+ struct cell *tcell = afs_GetCellByIndex(cellidx, READ_LOCK);
+ tfid.Cell = tcell->cellNum;
+ afs_PutCell(tcell, READ_LOCK);
+ tfid.Fid.Vnode = vnoid;
+ tfid.Fid.Volume = volid;
+ tfid.Fid.Unique = uniq;
+ } else {
+ afs_GetDynrootMountFid(&tfid);
+ tfid.Fid.Vnode = VNUM_FROM_TYPEID(VN_TYPE_MOUNT, cellidx << 2);
+ tfid.Fid.Unique = volid;
+ }
*avcp = tvc = afs_GetVCache(&tfid, &treq, NULL, NULL);
+ code = (tvc ? 0 : ENOENT);
hit = 1;
goto done;
}
#if defined(AFS_CACHE_BYPASS)
#define BOP_FETCH_NOCACHE 4 /* parms are: vnode ptr, offset, segment ptr, addr, cred ptr */
#endif
+#ifdef AFS_DARWIN_ENV
+#define BOP_MOVE 5 /* ptr1 afs_uspc_param ptr2 sname ptr3 dname */
+#endif
#define B_DONTWAIT 1 /* On failure return; don't wait */
thread_terminate(current_thread());
break;
case AFSOP_START_BKG:
- AFS_GLOCK();
- wakeup(arg);
- while (afs_initState < AFSOP_START_BKG)
- afs_osi_Sleep(&afs_initState);
- if (afs_initState < AFSOP_GO) {
- afs_initState = AFSOP_GO;
- afs_osi_Wakeup(&afs_initState);
- }
- afs_BackgroundDaemon();
- AFS_GUNLOCK();
+ printf("Install matching afsd! Old background daemons not supported.\n");
thread_terminate(current_thread());
break;
case AFSOP_START_TRUNCDAEMON:
put_vfs_context();
#endif
#if ((defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS)) || defined(AFS_DARWIN80_ENV)) && !defined(UKERNEL)
+#if defined(AFS_DARWIN80_ENV)
+ if (parm == AFSOP_BKG_HANDLER) {
+ /* if afs_uspc_param grows this should be checked */
+ struct afs_uspc_param *mvParam = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
+ void *param2;
+ void *param1;
+ int namebufsz;
+
+ AFS_COPYIN(AFSKPTR(parm2), (caddr_t)mvParam,
+ sizeof(struct afs_uspc_param), code);
+ namebufsz = mvParam->bufSz;
+ param1 = afs_osi_Alloc(namebufsz);
+ param2 = afs_osi_Alloc(namebufsz);
+
+ while (afs_initState < AFSOP_START_BKG)
+ afs_osi_Sleep(&afs_initState);
+ if (afs_initState < AFSOP_GO) {
+ afs_initState = AFSOP_GO;
+ afs_osi_Wakeup(&afs_initState);
+ }
+
+ code = afs_BackgroundDaemon(mvParam, param1, param2);
+
+ if (!code) {
+ mvParam->retval = 0;
+ /* for reqs where pointers are strings: */
+ if (mvParam->reqtype == AFS_USPC_UMV) {
+ /* don't copy out random kernel memory */
+ AFS_COPYOUT(param2, AFSKPTR(parm4),
+ MIN(namebufsz, strlen((char *)param2)+1), code);
+ AFS_COPYOUT(param1, AFSKPTR(parm3),
+ MIN(namebufsz, strlen((char *)param1)+1), code);
+ }
+ AFS_COPYOUT((caddr_t)mvParam, AFSKPTR(parm2),
+ sizeof(struct afs_uspc_param), code);
+ }
+
+ afs_osi_Free(param1, namebufsz);
+ afs_osi_Free(param2, namebufsz);
+ osi_FreeSmallSpace(mvParam);
+ } else
+#endif /* DARWIN80 */
if (parm < AFSOP_ADDCELL || parm == AFSOP_RXEVENT_DAEMON
|| parm == AFSOP_RXLISTENER_DAEMON) {
afs_DaemonOp(parm, parm2, parm3, parm4, parm5, parm6);
AFS_GUNLOCK();
exit(CLD_EXITED, 0);
#endif /* AFS_SGI_ENV */
+#ifndef AFS_DARWIN80_ENV
} else if (parm == AFSOP_START_BKG) {
while (afs_initState < AFSOP_START_BKG)
afs_osi_Sleep(&afs_initState);
}
/* start the bkg daemon */
afs_osi_Invisible();
-#ifdef AFS_AIX32_ENV
+# ifdef AFS_AIX32_ENV
if (parm2)
afs_BioDaemon(parm2);
else
-#endif /* AFS_AIX32_ENV */
+# endif /* AFS_AIX32_ENV */
afs_BackgroundDaemon();
afs_osi_Visible();
-#ifdef AFS_SGI_ENV
+# ifdef AFS_SGI_ENV
AFS_GUNLOCK();
exit(CLD_EXITED, 0);
-#endif /* AFS_SGI_ENV */
+# endif /* AFS_SGI_ENV */
+#endif /* ! AFS_DARWIN80_ENV */
} else if (parm == AFSOP_START_TRUNCDAEMON) {
while (afs_initState < AFSOP_GO)
afs_osi_Sleep(&afs_initState);
afs_BRelease(tb); /* this grabs and releases afs_xbrs lock */
}
+#ifdef AFS_DARWIN80_ENV
+int
+afs_BackgroundDaemon(struct afs_uspc_param *uspc, void *param1, void *param2)
+#else
void
afs_BackgroundDaemon(void)
+#endif
{
struct brequest *tb;
int i, foundAny;
/* Irix with "short stack" exits */
afs_BackgroundDaemon_once();
- afs_nbrs++;
+#ifdef AFS_DARWIN80_ENV
+ /* If it's a re-entering syscall, complete the request and release */
+ if (uspc->ts > -1) {
+ tb = afs_brs;
+ for (i = 0; i < NBRS; i++, tb++) {
+ if (tb->ts == uspc->ts) {
+ /* copy the userspace status back in */
+ ((struct afs_uspc_param *) tb->ptr_parm[0])->retval =
+ uspc->retval;
+ /* mark it valid and notify our caller */
+ tb->flags |= BUVALID;
+ if (tb->flags & BUWAIT) {
+ tb->flags &= ~BUWAIT;
+ afs_osi_Wakeup(tb);
+ }
+ brequest_release(tb);
+ break;
+ }
+ }
+ } else {
+ afs_osi_MaskUserLoop();
+#endif
+ /* Otherwise it's a new one */
+ afs_nbrs++;
+#ifdef AFS_DARWIN80_ENV
+ }
+#endif
ObtainWriteLock(&afs_xbrs, 302);
while (1) {
afs_termState = AFSOP_STOP_TRUNCDAEMON;
ReleaseWriteLock(&afs_xbrs);
afs_osi_Wakeup(&afs_termState);
+#ifdef AFS_DARWIN80_ENV
+ return -2;
+#else
return;
+#endif
}
/* find a request */
BStore(tb);
else if (tb->opcode == BOP_PATH)
BPath(tb);
+#ifdef AFS_DARWIN80_ENV
+ else if (tb->opcode == BOP_MOVE) {
+ memcpy(uspc, (struct afs_uspc_param *) tb->ptr_parm[0],
+ sizeof(struct afs_uspc_param));
+ uspc->ts = tb->ts;
+ /* string lengths capped in move vop; copy NUL tho */
+ memcpy(param1, (char *)tb->ptr_parm[1],
+ strlen(tb->ptr_parm[1])+1);
+ memcpy(param2, (char *)tb->ptr_parm[2],
+ strlen(tb->ptr_parm[2])+1);
+ return 0;
+ }
+#endif
else
panic("background bop");
brequest_release(tb);
afs_brsDaemons--;
}
}
+#ifdef AFS_DARWIN80_ENV
+ return -2;
+#endif
}
extern void afs_BRelease(register struct brequest *ab);
extern int afs_BBusy(void);
extern int afs_BioDaemon(afs_int32 nbiods);
+#ifdef AFS_DARWIN80_ENV
+extern int afs_BackgroundDaemon(struct afs_uspc_param *uspc, void *param1, void *param2);
+#else
extern void afs_BackgroundDaemon(void);
+#endif
extern void shutdown_daemons(void);
extern int afs_sgidaemon(void);
/* afs_util.c */
+extern afs_int32 afs_strtoi_r(const char *str, char **endptr, afs_uint32 *ret);
extern afs_int32 afs_calc_inum (afs_int32 volume, afs_int32 vnode);
#ifndef afs_cv2string
extern char *afs_cv2string(char *ttp, afs_uint32 aval);
} /*afs_cv2string */
#endif
+/* not a generic strtoul replacement. for vol/vno/uniq, portable */
+
+afs_int32
+afs_strtoi_r(const char *str, char **endptr, afs_uint32 *ret)
+{
+ char *x;
+
+ *ret = 0;
+ *endptr = (char *)str;
+
+ if (!str)
+ return ERANGE;
+
+ for (x = (char *)str; *x >= '0' && *x <= '9'; x++) {
+ /* Check for impending overflow */
+ if (*ret > 429496729) { /* ULONG_MAX/10 */
+ *ret = 0;
+ *endptr = (char *)str;
+ return EINVAL;
+ }
+
+ *ret = (*ret * 10) + (*x - '0');
+ }
+
+ *endptr = x;
+ return 0;
+}
+
#ifndef afs_strcasecmp
int
afs_strcasecmp(char *s1, char *s2)
{
if (afsd_debug) {
printf("%s: Current directory entry:\n", rn);
-#ifdef AFS_SGI62_ENV
+#if defined(AFS_SGI62_ENV) || defined(AFS_DARWIN90_ENV)
printf("\tinode=%" AFS_INT64_FMT ", reclen=%d, name='%s'\n", currp->d_ino,
currp->d_reclen, currp->d_name);
#elif defined(AFS_DFBSD_ENV)
exit(1);
}
-#ifdef mac2
-#include <sys/ioctl.h>
-#endif /* mac2 */
+#ifdef AFS_DARWIN_ENV
+static void
+BkgHandler(void)
+{
+ afs_int32 code;
+ struct afs_uspc_param *uspc;
+ char srcName[256];
+ char dstName[256];
+
+ uspc = (struct afs_uspc_param *)malloc(sizeof(struct afs_uspc_param));
+ memset(uspc, 0, sizeof(struct afs_uspc_param));
+ memset(srcName, 0, sizeof(srcName));
+ memset(dstName, 0, sizeof(dstName));
+
+ /* brscount starts at 0 */
+ uspc->ts = -1;
+
+ while (1) {
+ pid_t child = 0;
+ int status;
+ char srcpath[BUFSIZ];
+ char dstpath[BUFSIZ];
+
+ /* pushing in a buffer this large */
+ uspc->bufSz = 256;
+
+ code = call_syscall(AFSOP_BKG_HANDLER, uspc, srcName, dstName);
+ if (code) { /* Something is wrong? */
+ if (code == -2) /* shutting down */
+ break;
+
+ sleep(1);
+ uspc->retval = -1;
+ continue;
+ }
+
+ switch (uspc->reqtype) {
+ case AFS_USPC_UMV:
+ snprintf(srcpath, BUFSIZ, "/afs/.:mount/%d:%d:%d:%d/%s",
+ uspc->req.umv.sCell, uspc->req.umv.sVolume,
+ uspc->req.umv.sVnode, uspc->req.umv.sUnique, srcName);
+ snprintf(dstpath, BUFSIZ, "/afs/.:mount/%d:%d:%d:%d/%s",
+ uspc->req.umv.dCell, uspc->req.umv.dVolume,
+ uspc->req.umv.dVnode, uspc->req.umv.dUnique, dstName);
+ if ((child = fork()) == 0) {
+ /* first child does cp; second, rm. mv would re-enter. */
+
+ switch (uspc->req.umv.idtype) {
+ case IDTYPE_UID:
+ if (setuid(uspc->req.umv.id) != 0) {
+ exit(-1);
+ }
+ break;
+ default:
+ exit(-1);
+ break; /* notreached */
+ }
+ execl("/bin/cp", "(afsd EXDEV helper)", "-PRp", "--", srcpath,
+ dstpath, (char *) NULL);
+ }
+ if (child == (pid_t) -1) {
+ uspc->retval = -1;
+ continue;
+ }
+
+ if (waitpid(child, &status, 0) == -1)
+ uspc->retval = EIO;
+ else if (WIFEXITED(status) != 0 && WEXITSTATUS(status) == 0) {
+ if ((child = fork()) == 0) {
+ switch (uspc->req.umv.idtype) {
+ case IDTYPE_UID:
+ if (setuid(uspc->req.umv.id) != 0) {
+ exit(-1);
+ }
+ break;
+ default:
+ exit(-1);
+ break; /* notreached */
+ }
+ execl("/bin/rm", "(afsd EXDEV helper)", "-rf", "--",
+ srcpath, (char *) NULL);
+ }
+ if (child == (pid_t) -1) {
+ uspc->retval = -1;
+ continue;
+ }
+ if (waitpid(child, &status, 0) == -1)
+ uspc->retval = EIO;
+ else if (WIFEXITED(status) != 0) {
+ /* rm exit status */
+ uspc->retval = WEXITSTATUS(status);
+ } else {
+ /* rm signal status */
+ uspc->retval = -(WTERMSIG(status));
+ }
+ } else {
+ /* error from cp: exit or signal status */
+ uspc->retval = (WIFEXITED(status) != 0) ?
+ WEXITSTATUS(status) : -(WTERMSIG(status));
+ }
+ memset(srcName, 0, sizeof(srcName));
+ memset(dstName, 0, sizeof(dstName));
+ break;
+
+ default:
+ /* unknown req type */
+ uspc->retval = -1;
+ break;
+ }
+ }
+ exit(1);
+}
+#endif
#ifdef AFS_SGI65_ENV
#define SET_RTPRI(P) { \
for (i = 0; i < nDaemons; i++) {
code = fork();
if (code == 0) {
- /* Child */
-#ifdef AFS_AIX32_ENV
+#ifdef AFS_DARWIN80_ENV
+ /* Since the background daemon runs as a user process,
+ * need to drop the controlling TTY, etc.
+ */
+ if (daemon(0, 0) == -1) {
+ printf("Error starting background daemon: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ BkgHandler();
+#elif defined(AFS_AIX32_ENV)
call_syscall(AFSOP_START_BKG, 0);
#else
call_syscall(AFSOP_START_BKG);
#define AFSOP_SET_RXPCK 38 /* set rx_extraPackets*/
#define AFSOP_BUCKETPCT 39 /* bucket percentage */
#define AFSOP_SET_RXMAXMTU 40 /* set rx_MyMaxSendSize,rx_maxReceiveSizeUser,rx_maxReceiveSize */
+#define AFSOP_BKG_HANDLER 41 /* userspace-capable Bkg daemon */
/* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
#define AFSCALL_PIOCTL 20
#endif
/* arguments passed by afsd */
+#define IDTYPE_UID 0
+
+/* We don't necessarily have VenusFid here */
+struct afs_umv_param {
+ afs_int32 id;
+ afs_int32 idtype;
+ afs_int32 sCell;
+ afs_int32 sVolume;
+ afs_int32 sVnode;
+ afs_int32 sUnique;
+ afs_int32 dCell;
+ afs_int32 dVolume;
+ afs_int32 dVnode;
+ afs_int32 dUnique;
+};
+
+#define AFS_USPC_UMV 1
+
+struct afs_uspc_param {
+ afs_int32 retval;
+ afs_int32 ts; /* brequest ts - always unique */
+ afs_int32 bufSz;
+ afs_int32 reqtype;
+ union {
+ struct afs_umv_param umv;
+ } req;
+};
+
struct afs_cacheParams {
afs_int32 cacheScaches;
afs_int32 cacheFiles;