+
+ /*
+ * Read in first few bytes of file for segment sizes, ux_mag:
+ * 407 = plain executable
+ * 410 = RO text
+ * 413 = demand paged RO text
+ * Also an ASCII line beginning with #! is
+ * the file name of a ``shell'' and arguments may be prepended
+ * to the argument list if given here.
+ *
+ * SHELL NAMES ARE LIMITED IN LENGTH.
+ *
+ * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
+ * THE ASCII LINE.
+ */
+ u.u_base = (caddr_t)&u.u_exdata;
+ u.u_count = sizeof(u.u_exdata);
+ u.u_offset = 0;
+ u.u_segflg = 1;
+ readi(ip);
+ u.u_segflg = 0;
+ if (u.u_error)
+ goto bad;
+ if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) &&
+ u.u_exdata.ux_shell[0] != '#') {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ switch (u.u_exdata.ux_mag) {
+
+ case 0407:
+ u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
+ u.u_exdata.ux_tsize = 0;
+ break;
+
+ case 0413:
+ case 0410:
+ if (u.u_exdata.ux_tsize == 0) {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ break;
+
+ default:
+ if (u.u_exdata.ux_shell[0] != '#' ||
+ u.u_exdata.ux_shell[1] != '!' ||
+ indir) {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ cp = &u.u_exdata.ux_shell[2]; /* skip "#!" */
+ while (cp < &u.u_exdata.ux_shell[SHSIZE]) {
+ if (*cp == '\t')
+ *cp = ' ';
+ else if (*cp == '\n') {
+ *cp = '\0';
+ break;
+ }
+ cp++;
+ }
+ if (*cp != '\0') {
+ u.u_error = ENOEXEC;
+ goto bad;
+ }
+ cp = &u.u_exdata.ux_shell[2];
+ while (*cp == ' ')
+ cp++;
+ u.u_dirp = cp;
+ while (*cp && *cp != ' ')
+ cp++;
+ sharg = NULL;
+ if (*cp) {
+ *cp++ = '\0';
+ while (*cp == ' ')
+ cp++;
+ if (*cp) {
+ bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
+ sharg = cfarg;
+ }
+ }
+ bcopy((caddr_t)u.u_dbuf, (caddr_t)cfname, DIRSIZ);
+ indir = 1;
+ iput(ip);
+ ip = namei(schar, 0, 1);
+ if (ip == NULL)
+ return;
+ goto again;
+ }
+