+ if ( ! check_cpu_subtype(mach_header->cpusubtype) ) {
+ error = EBADARCH;
+ goto bad;
+ }
+
+ if (mach_header->magic == MH_CIGAM) {
+
+ int classicBinaryLen = nd.ni_cnd.cn_namelen;
+ if (classicBinaryLen > MAXCOMLEN)
+ classicBinaryLen = MAXCOMLEN;
+ bcopy((caddr_t)nd.ni_cnd.cn_nameptr,
+ (caddr_t)binaryWithClassicName,
+ (unsigned)classicBinaryLen);
+ binaryWithClassicName[classicBinaryLen] = '\0';
+ executingClassic = 1;
+
+ vput(vp); /* cleanup? */
+ nd.ni_cnd.cn_nameiop = LOOKUP;
+
+ nd.ni_cnd.cn_flags = (nd.ni_cnd.cn_flags & HASBUF) |
+ /* (FOLLOW | LOCKLEAF | SAVENAME) */
+ (LOCKLEAF | SAVENAME);
+ nd.ni_segflg = UIO_SYSSPACE;
+
+ nd.ni_dirp = classichandler;
+ if ((error = namei(&nd)) != 0) {
+ error = EBADARCH;
+ goto bad1;
+ }
+ vp = nd.ni_vp;
+
+ VOP_LEASE(vp,p,cred,LEASE_READ);
+ if ((error = VOP_GETATTR(vp,&vattr,p->p_ucred,p))) {
+ goto bad;
+ }
+ goto again;
+ }
+
+ if (uap->argp != NULL) {
+ /* geez -- why would argp ever be NULL, and why would we proceed? */
+
+ /* First, handle any argument massaging */
+ if (executingInterpreter && executingClassic) {
+ error = copyArgument(classichandler,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ if (error) goto bad;
+
+ /* Now name the interpreter. */
+ error = copyArgument(savedpath,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ if (error) goto bad;
+
+ /*
+ * if we're running an interpreter, as we'd be passing the
+ * command line executable as an argument to the interpreter already.
+ * Doing "execve("myShellScript","bogusName",arg1,arg2,...)
+ * probably shouldn't ever let bogusName be seen by the shell
+ * script.
+ */
+
+ if (cfarg[0]) {
+ error = copyArgument(cfarg,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ if (error) goto bad;
+ }
+
+ char* originalExecutable = uap->fname;
+ error = copyArgument(originalExecutable,UIO_USERSPACE,&nc,&cp,&cc);
+ na++;
+ /* remove argv[0] b/c we've already placed it at */
+ /* this point */
+ uap->argp++;
+ if (error) goto bad;
+
+ /* and continue with rest of the arguments. */
+ } else if (executingClassic) {
+ error = copyArgument(classichandler,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ if (error) goto bad;
+
+ char* originalExecutable = uap->fname;
+ error = copyArgument(originalExecutable,UIO_USERSPACE,&nc,&cp,&cc);
+ if (error) goto bad;
+ uap->argp++;
+ na++;
+
+ /* and rest of arguments continue as before. */
+ } else if (executingInterpreter) {
+ char *actualExecutable = nd.ni_cnd.cn_nameptr;
+ error = copyArgument(actualExecutable,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ /* remove argv[0] b/c we just placed it in the arg list. */
+ uap->argp++;
+ if (error) goto bad;
+ /* Copy the argument in the interpreter first line if there
+ * was one.
+ */
+ if (cfarg[0]) {
+ error = copyArgument(cfarg,UIO_SYSSPACE,&nc,&cp,&cc);
+ na++;
+ if (error) goto bad;
+ }
+
+ /* copy the name of the file being interpreted, gotten from
+ * the structures passed in to execve.
+ */
+ error = copyArgument(uap->fname,UIO_USERSPACE,&nc,&cp,&cc);
+ na++;
+ }
+ /* Now, get rest of arguments */
+ while (uap->argp != NULL) {
+ char* userArgument = (char*)fuword((caddr_t) uap->argp);
+ uap->argp++;
+ if (userArgument == NULL) {
+ break;
+ } else if ((int)userArgument == -1) {
+ /* Um... why would it be -1? */
+ error = EFAULT;
+ goto bad;
+ }
+ error = copyArgument(userArgument, UIO_USERSPACE,&nc,&cp,&cc);
+ if (error) goto bad;
+ na++;
+ }
+ /* Now, get the environment */
+ while (uap->envp != NULL) {
+ char *userEnv = (char*) fuword((caddr_t) uap->envp);
+ uap->envp++;
+ if (userEnv == NULL) {
+ break;
+ } else if ((int)userEnv == -1) {
+ error = EFAULT;
+ goto bad;
+ }
+ error = copyArgument(userEnv,UIO_USERSPACE,&nc,&cp,&cc);
+ if (error) goto bad;
+ na++;
+ ne++;
+ }
+ }
+
+ /* make sure there are nulls are the end!! */
+ {
+ int cnt = 3;
+ char *mp = cp;
+
+ while ( cnt-- )
+ *mp++ = '\0';
+ }
+
+ /* and round up count of bytes written to next word. */
+ nc = (nc + NBPW-1) & ~(NBPW-1);
+
+ if (vattr.va_fsid == classichandler_fsid &&
+ vattr.va_fileid == classichandler_fileid) {
+ executingClassic = 1;
+ }
+