int getbootline(char *kernel, char *bootstrap) { int rc = 1; char *ptr; char *kargs = kern_prog.args; char *bargs = boot_prog.args; for (;;) { if (com_enabled) flush_char(); printf("\nboot: "); gets(ptr = boot_line); if (!*ptr) rc = 0; while (*ptr == ' ') ptr++; if (*ptr == '?') { usage(); continue; } #ifdef DEBUG if (*ptr == '~') { debug = !debug; continue; } #endif ptr = copyword(ptr, kernel); while (*kargs++ = *kernel) kernel++; while (*ptr == '-') { if (*(ptr+1) == '-') { ptr += 2; while (*ptr == ' ') ptr++; break; } ptr = copyargs(ptr, &kargs); } kern_prog.args_size = kargs - kern_prog.args; ptr = copyword(ptr, bootstrap); while (*bargs++ = *bootstrap) bootstrap++; while (*ptr) ptr = copyargs(ptr, &bargs); boot_prog.args_size = bargs - boot_prog.args; return(rc); } }
/* * copy arguments onto the stack in the normal way, then copy out * any ELF-like AUX entries used by the dynamic loading scheme. */ int osf1_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp) { struct osf1_exec_emul_arg *emul_arg = pack->ep_emul_arg; struct osf1_auxv ai[OSF1_MAX_AUX_ENTRIES], *a; char *prognameloc, *loadernameloc; size_t len; int error; if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) goto out; a = ai; memset(ai, 0, sizeof ai); prognameloc = *stackp + sizeof ai; if ((error = copyoutstr(emul_arg->exec_name, prognameloc, MAXPATHLEN + 1, NULL)) != 0) goto out; a->a_type = OSF1_AT_EXEC_FILENAME; a->a_un.a_ptr = prognameloc; a++; /* * if there's a loader, push additional auxv entries on the stack. */ if (emul_arg->flags & OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER) { loadernameloc = prognameloc + MAXPATHLEN + 1; if ((error = copyoutstr(emul_arg->loader_name, loadernameloc, MAXPATHLEN + 1, NULL)) != 0) goto out; a->a_type = OSF1_AT_EXEC_LOADER_FILENAME; a->a_un.a_ptr = loadernameloc; a++; a->a_type = OSF1_AT_EXEC_LOADER_FLAGS; a->a_un.a_val = 0; if (pack->ep_vap->va_mode & S_ISUID) a->a_un.a_val |= OSF1_LDR_EXEC_SETUID_F; if (pack->ep_vap->va_mode & S_ISGID) a->a_un.a_val |= OSF1_LDR_EXEC_SETGID_F; if (l->l_proc->p_slflag & PSL_TRACED) a->a_un.a_val |= OSF1_LDR_EXEC_PTRACE_F; a++; } a->a_type = OSF1_AT_NULL; a->a_un.a_val = 0; a++; len = (a - ai) * sizeof(struct osf1_auxv); if ((error = copyout(ai, *stackp, len)) != 0) goto out; *stackp += len; out: exec_free_emul_arg(pack); return error; }
static char * copyword(char *p, char *copy) { if (*p == 0 || *p == '-') return p; return copyargs(p, ©); }
VOID setargs(STRING argi[]) { /* count args */ REG STRING *argp=argi; REG INT argn=0; WHILE Rcheat(*argp++)!=ENDARGS DO argn++ OD /* free old ones unless on for loop chain */ freeargs(dolh); dolh=(DOLPTR)copyargs(argi,argn); /* sets dolv */ assnum(&dolladr,dolc=argn-1); }
void setargs(const char *argi[]) { /* count args */ register const char **argp = argi; register int argn = 0; while (((intptr_t)(*argp++)) != ENDARGS) argn++; /* free old ones unless on for loop chain */ freeargs(dolh); dolh = (DOLPTR) copyargs(argi, argn); /* sets dolv */ assnum(&dolladr, dolc = argn - 1); }
/* * sets up positional parameters */ void setargs(unsigned char *argi[]) { unsigned char **argp = argi; /* count args */ int argn = 0; while (*argp++ != (unsigned char *)ENDARGS) argn++; /* * free old ones unless on for loop chain */ freedolh(); dolh = copyargs(argi, argn); dolc = argn - 1; }
/* * Copy arguments onto the stack in the normal way, but add some * space for extra information in case of dynamic binding. */ void * ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, void *stack, void *argp) { stack = copyargs(pack, arginfo, stack, argp); if (!stack) return (NULL); /* * Push space for extra arguments on the stack needed by * dynamically linked binaries. */ if (pack->ep_interp != NULL) { pack->ep_emul_argp = stack; stack += ELF_AUX_ENTRIES * sizeof (AuxInfo); } return (stack); }
int pecoff_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp) { int len = sizeof(struct pecoff_args); struct pecoff_args *ap; int error; if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) return error; ap = (struct pecoff_args *)pack->ep_emul_arg; if ((error = copyout(ap, *stackp, len)) != 0) return error; #if 0 /* kern_exec.c? */ free(ap, M_TEMP); pack->ep_emul_arg = 0; #endif *stackp += len; return error; }
int main (int argc, char **argv) { int index; struct passwd *pw; struct servent *sp; sigset_t sigs, osigs; int asrsh, rem; pid_t pid = 0; uid_t uid; char *args, *host; set_program_name (argv[0]); asrsh = 0; host = user = NULL; /* If called as something other than "rsh", use it as the host name */ { char *p = strrchr (argv[0], '/'); if (p) ++p; else p = argv[0]; if (strcmp (p, "rsh")) host = p; else asrsh = 1; } /* Parse command line */ iu_argp_init ("rsh", default_program_authors); argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &index, NULL); if (index < argc) host = argv[index++]; /* To few args. */ if (!host) error (EXIT_FAILURE, 0, "host not specified"); /* If no further arguments, must have been called as rlogin. */ if (!argv[index]) { if (asrsh) *argv = (char *) "rlogin"; seteuid (getuid ()); setuid (getuid ()); execv (PATH_RLOGIN, argv); error (EXIT_FAILURE, errno, "cannot execute %s", PATH_RLOGIN); } argc -= index; argv += index; /* We must be setuid root. */ if (geteuid ()) error (EXIT_FAILURE, 0, "must be setuid root.\n"); if (!(pw = getpwuid (uid = getuid ()))) error (EXIT_FAILURE, 0, "unknown user id"); /* Accept user1@host format, though "-l user2" overrides user1 */ { char *p = strchr (host, '@'); if (p) { *p = '\0'; if (!user && p > host) user = host; host = p + 1; if (*host == '\0') error (EXIT_FAILURE, 0, "empty host name"); } } #if defined KERBEROS || defined SHISHI # ifdef ENCRYPTION /* -x turns off -n */ if (doencrypt) null_input_option = 0; # endif #endif args = copyargs (argv); sp = NULL; #ifdef KERBEROS if (use_kerberos) { sp = getservbyname ((doencrypt ? "ekshell" : "kshell"), "tcp"); if (sp == NULL) { use_kerberos = 0; warning ("can't get entry for %s/tcp service", doencrypt ? "ekshell" : "kshell"); } } #elif defined(SHISHI) if (use_kerberos) { sp = getservbyname ("kshell", "tcp"); if (sp == NULL) { use_kerberos = 0; warning ("can't get entry for %s/tcp service", "kshell"); } } #endif if (sp == NULL) sp = getservbyname ("shell", "tcp"); if (sp == NULL) error (EXIT_FAILURE, 0, "shell/tcp: unknown service"); #if defined KERBEROS || defined SHISHI try_connect: if (use_kerberos) { struct hostent *hp; /* fully qualify hostname (needed for krb_realmofhost) */ hp = gethostbyname (host); if (hp != NULL && !(host = strdup (hp->h_name))) error (EXIT_FAILURE, errno, "strdup"); # if defined KERBEROS rem = KSUCCESS; errno = 0; if (dest_realm == NULL) dest_realm = krb_realmofhost (host); # elif defined (SHISHI) rem = SHISHI_OK; errno = 0; # endif # ifdef ENCRYPTION if (doencrypt) # if defined SHISHI { int i; char *term; term = xmalloc (strlen (args) + 4); strcpy (term, "-x "); strcat (term, args); rem = krcmd_mutual (&h, &host, sp->s_port, &user, term, &rfd2, dest_realm, &enckey); if (rem > 0) { keytype = shishi_key_type (enckey); keylen = shishi_cipher_blocksize (keytype); ivtab[0] = &iv1; ivtab[1] = &iv2; ivtab[2] = &iv3; ivtab[3] = &iv4; for (i = 0; i < 4; i++) { ivtab[i]->ivlen = keylen; switch (keytype) { case SHISHI_DES_CBC_CRC: case SHISHI_DES_CBC_MD4: case SHISHI_DES_CBC_MD5: case SHISHI_DES_CBC_NONE: case SHISHI_DES3_CBC_HMAC_SHA1_KD: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, 2 * i + 1 * (i < 2) - 4 * (i >= 2), ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), ivtab[i]->iv, ivtab[i]->ivlen); break; case SHISHI_ARCFOUR_HMAC: case SHISHI_ARCFOUR_HMAC_EXP: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i; ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), NULL, 0); break; default: ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i; ivtab[i]->iv = malloc (ivtab[i]->ivlen); memset (ivtab[i]->iv, 0, ivtab[i]->ivlen); ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey), ivtab[i]->iv, ivtab[i]->ivlen); } } } free (term); } else # else rem = krcmd_mutual (&host, sp->s_port, user, args, &rfd2, dest_realm, &cred, schedule); else # endif # endif rem = krcmd ( # if defined SHISHI &h, &host, sp->s_port, &user, args, &rfd2, dest_realm); # else &host, sp->s_port, user, args, &rfd2, dest_realm); # endif if (rem < 0) { use_kerberos = 0; sp = getservbyname ("shell", "tcp"); if (sp == NULL) error (EXIT_FAILURE, 0, "shell/tcp: unknown service"); if (errno == ECONNREFUSED) warning ("remote host doesn't support Kerberos"); if (errno == ENOENT) warning ("can't provide Kerberos auth data"); goto try_connect; } }
int main(int argc, char **argv) { struct passwd const *pw; struct servent const *sp; long omask; int argoff, asrsh, ch, dflag, nflag, one, rem; pid_t pid = 0; uid_t uid; char *args, *host, *p, *user; int timeout = 0; argoff = asrsh = dflag = nflag = 0; one = 1; host = user = NULL; /* if called as something other than "rsh", use it as the host name */ if ((p = strrchr(argv[0], '/'))) ++p; else p = argv[0]; if (strcmp(p, "rsh")) host = p; else asrsh = 1; /* handle "rsh host flags" */ if (!host && argc > 2 && argv[1][0] != '-') { host = argv[1]; argoff = 1; } #define OPTIONS "468Lde:l:nt:w" while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1) switch(ch) { case '4': family = PF_INET; break; case '6': family = PF_INET6; break; case 'L': /* -8Lew are ignored to allow rlogin aliases */ case 'e': case 'w': case '8': break; case 'd': dflag = 1; break; case 'l': user = optarg; break; case 'n': nflag = 1; break; case 't': timeout = atoi(optarg); break; case '?': default: usage(); } optind += argoff; /* if haven't gotten a host yet, do so */ if (!host && !(host = argv[optind++])) usage(); /* if no further arguments, must have been called as rlogin. */ if (!argv[optind]) { if (asrsh) *argv = rlogin; execv(_PATH_RLOGIN, argv); err(1, "can't exec %s", _PATH_RLOGIN); } argc -= optind; argv += optind; if (!(pw = getpwuid(uid = getuid()))) errx(1, "unknown user id"); if (!user) user = pw->pw_name; args = copyargs(argv); sp = NULL; if (sp == NULL) sp = getservbyname("shell", "tcp"); if (sp == NULL) errx(1, "shell/tcp: unknown service"); if (timeout) { signal(SIGALRM, connect_timeout); alarm(timeout); } rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2, family); if (timeout) { signal(SIGALRM, SIG_DFL); alarm(0); } if (rem < 0) exit(1); if (rfd2 < 0) errx(1, "can't establish stderr"); if (dflag) { if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0) warn("setsockopt"); if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0) warn("setsockopt"); } setuid(uid); omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, sendsig); if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, sendsig); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, sendsig); if (!nflag) { pid = fork(); if (pid < 0) err(1, "fork"); } else shutdown(rem, SHUT_WR); ioctl(rfd2, FIONBIO, &one); ioctl(rem, FIONBIO, &one); talk(nflag, omask, pid, rem, timeout); if (!nflag) kill(pid, SIGKILL); exit(0); }
void boot(int drive) { int addr; int top; int kern_entry; int boot_start; int boot_region_desc; int boot_thread_state; unsigned int size; int env_start; int env_size = 0; char *p; char *env = 0; char *defaults = 0; int defaults_size = 0; int i; int idt[2]; delayprompt = 10; /* default to 10s at the prompt */ switch(drive) { case BIOS_DEV_FLOPPY: dev = DEV_FLOPPY; break; case BIOS_FAKE_WD: dev = DEV_WD; break; case BIOS_DEV_WIN: default: dev = DEV_HD; break; } cnvmem = memsize(0); extmem = memsize(1); printf("\n>> Secondary Mach boot %s\n>> %d/%dk (? for help, ^C for intr)\n", VERSIONDATE, cnvmem, extmem); #ifdef DEBUG printf("end x%x data 0x%x\n",end,edata); #endif /* sanity check: */ if ((int)end > KALLOC_OFFSET || (int)end > (BOOTSTACK-0x300)) { printf("Size problem: 0x%x > 0x%x\n",end, ((int)end > KALLOC_OFFSET)?KALLOC_OFFSET:BOOTSTACK-0x300); } #if DEBUG if (debug) { printf("dev = %x\n", dev); printf("unit = %x\n", unit); printf("part = %x\n", part); } #endif #if 0 dev = DEV_HD; unit = 0; part = 0; #endif reset_pic(); /* Lilo breaks PIC, BIOS disk ints fail */ calibrate_delay(); /* adjust delay for i/o operation */ gateA20(); if (dev == DEV_FLOPPY && devfs()) { printf("No fd FS, using hd\n"); dev = DEV_HD; part = 0; } bcopy(MACH_KERNEL, kern_prog.name, sizeof(MACH_KERNEL)); bcopy(BOOTSTRAP, boot_prog.name, sizeof(BOOTSTRAP)); bcopy(MACH_BOOT_ENV, env_prog.name, sizeof(MACH_BOOT_ENV)); reload_env_file: if (openrd(env_prog.name, NULL) == 0 && fsize() != 0) { const char *value; /* * Read mach_boot environment file if exists */ printf("Reading defaults from %s:\n",env_prog.name); defaults_size = fsize()+1; if (defaults != (char *)0) free(defaults); defaults = (char *)malloc(defaults_size); read(defaults, defaults_size-1); *(defaults+defaults_size-1) = 0; printf("%s", defaults); for (p = defaults; p < defaults + defaults_size; p++) if (*p == '\n') *p = '\0'; value = get_env("CONSOLE", defaults, defaults_size); if (strcmp(value, "vga") == 0 || strcmp(value, "VGA") == 0) com_enabled = 0; /* WARNING: do not enable the remote console based * on the latter argument in an environment file, since * now, remote console enabling is decided by the primary * boot ONLY and passed along through secondary's. */ if (*get_env("PROMPT", defaults, defaults_size) == '1') prompt = 1; if (com_enabled && (value = get_env("COM1_SETUP", defaults, defaults_size))) com_setup(value); if (value = get_env("DELAYPROMPT", defaults, defaults_size)) { delayprompt = atoi(value); /* don't allow stupid values */ if (delayprompt < 3) delayprompt = 3; } } for (;;) { if ((!getbootline(kern_prog.name, boot_prog.name)) && defaults ) { /* * Get defaults from /mach_boot.env if any. */ const char *value; if (value = get_env("KERNEL_NAME", defaults, defaults_size)) { strcpy(kern_prog.name, (char *)value); strcpy(kern_prog.args, (char *)value); kern_prog.args_size = strlen(value)+1; } if (value = get_env("KERNEL_ARGS", defaults, defaults_size)) { char *args; args = kern_prog.args + kern_prog.args_size; while (*value) value = copyargs((char *)value, &args); kern_prog.args_size = args - kern_prog.args; } if (value = get_env("BOOTSTRAP_NAME", defaults, defaults_size)) { strcpy(boot_prog.name, (char *)value); strcpy(boot_prog.args, (char *)value); boot_prog.args_size = strlen(value)+1; } if (value = get_env("BOOTSTRAP_ARGS", defaults, defaults_size)) { char *args; args = boot_prog.args + boot_prog.args_size; while (*value) value = copyargs((char *)value, &args); boot_prog.args_size = args - boot_prog.args; } } if (cons_is_com) { printf("console is COM1\n"); /* check if we already enabled remote console? */ p = kern_prog.args + kern_prog.args_size; *p++ = '-'; *p++ = 'r'; *p++ = 0; kern_prog.args_size += 3; } addr = KERNEL_BOOT_ADDR; if (loadtext(&addr, &kern_prog)) { strcpy(env_prog.name, kern_prog.name); goto reload_env_file; } else if (loadprog(&addr, &kern_prog)) { printf("Can't load %s\n", kern_prog.name); usage(); continue; } kern_entry = entry; if (dev == DEV_WD) net_get_root_device(); env_start = addr; if (openrd("/mach_servers/environment", NULL) == 0 && fsize() != 0) { unsigned int total = fsize()+1; printf("Loading environment from /mach_servers/environment\n"); env = (char *)malloc(total); read(env, total-1); *(env+total-1) = 0; for (p = env; p < env + total; p++) if (*p == '\n') *p = '\0'; pcpy(env, (void *)addr, total); addr += total; env_size += total; free(env); } env = (char *)malloc(BOOT_LINE_LENGTH); #if BOOT_ENV_COMPAT /* should go away when all kernels are converted to use BOOT_DEVICE */ p = env; strcpy(p, "BOOTOFFSET="); p = itoa(p + strlen(p), boff) + 1; strcpy(p, "BOOTDEV=hd"); p += strlen(p)+1; *(p-3) = dev; strcpy(p, "BOOTUNIT="); p = itoa(p + strlen(p), unit) + 1; strcpy(p, "BOOTPART="); p = itoa(p + strlen(p), part) + 1; size = p - env; pcpy(env, (void *)addr, size); addr += size; env_size += size; #endif /* BOOT_ENV_COMPAT */ p = env; strcpy(p, "BOOT_DEVICE=hd"); p += strlen(p); *(p-2) = dev; p = itoa(p, unit); *p++ = 'a'+part; size = p - env; pcpy(env, (void *)addr, size); addr += size; env_size += size; free(env); if (strncmp("none",boot_prog.name,sizeof("none"))==0 ||strncmp("null",boot_prog.name,sizeof("null"))==0) { boot_start = 0; boot_region_desc = 0; boot_prog.sym_start = 0; boot_prog.sym_size = 0; boot_prog.args_start = 0; boot_prog.args_size = 0; region_count = 0; boot_thread_state = 0; top = page_align(addr); goto boot_kernel_only; } boot_start = addr = page_align(addr); if (loadprog(&addr, &boot_prog)) { printf("Can't load %s\n", boot_prog.name); usage(); continue; } boot_region_desc = addr; addr = boot_region_desc + (region_count * sizeof(regions[0])); pcpy(regions, (void *) boot_region_desc, addr - boot_region_desc); boot_thread_state = addr; addr += sizeof(thread_state); pcpy(&thread_state, (void *) boot_thread_state, addr - boot_thread_state); top = page_align(addr); boot_kernel_only: #ifdef DEBUG if (debug) { printf("startprog(\n"); printf(" entry 0x%x,\n", kern_entry); printf(" -1,\n"); printf(" extmem 0x%x,\n", extmem); printf(" cnvmem 0x%x,\n", cnvmem); printf(" kern_sym_start 0x%x,\n", kern_prog.sym_start); printf(" kern_sym_size 0x%x,\n", kern_prog.sym_size); printf(" kern_args_start 0x%x,\n", kern_prog.args_start); printf(" kern_args_size 0x%x,\n", kern_prog.args_size); for (p = kern_prog.args; p < &kern_prog.args[kern_prog.args_size]; p += strlen(p)+1) printf("<%s>", p); printf("\n"); printf(" boot_sym_start 0x%x,\n", boot_prog.sym_start); printf(" boot_sym_size 0x%x,\n", boot_prog.sym_size); printf(" boot_args_start 0x%x,\n", boot_prog.args_start); printf(" boot_args_size 0x%x,\n", boot_prog.args_size); for (p = boot_prog.args; p < &boot_prog.args[boot_prog.args_size]; p += strlen(p)+1) printf("<%s>", p); printf("\n"); printf(" boot_start 0x%x,\n", boot_start); printf(" boot_size 0x%x,\n", boot_prog.sym_start - boot_start); printf(" boot_region_desc 0x%x,\n", boot_region_desc); printf(" boot_region_count 0x%x,\n", region_count); printf(" boot_thread_state_flavor %d,\n", THREAD_SYSCALL_STATE); printf(" boot_thread_state 0x%x (eip 0x%x, esp 0x%x),\n", boot_thread_state, thread_state.eip, thread_state.esp); printf(" boot_thread_state_count %d,\n", (int) i386_THREAD_SYSCALL_STATE_COUNT); printf(" env_start 0x%x,\n", env_start); printf(" env_size 0x%x,\n", env_size); printf(" top 0x%x)\n", (int) top); getchar(); continue; } #endif /* DEBUG */ /* * New calling convention * * %esp -> -1 * size of extended memory (K) * size of conventional memory (K) * kern_sym_start * kern_sym_size * kern_args_start * kern_args_size * boot_sym_start * boot_sym_size * boot_args_start * boot_args_size * boot_start * boot_size * boot_region_desc * boot_region_count * boot_thread_state_flavor * boot_thread_state * boot_thread_state_count * env_start * env_size * top of loaded memory */ startprog( kern_entry, -1, extmem, cnvmem, kern_prog.sym_start, kern_prog.sym_size, kern_prog.args_start, kern_prog.args_size, boot_prog.sym_start, boot_prog.sym_size, boot_prog.args_start, boot_prog.args_size, boot_start, boot_prog.sym_start - boot_start, boot_region_desc, region_count, THREAD_SYSCALL_STATE, boot_thread_state, i386_THREAD_SYSCALL_STATE_COUNT, env_start, env_size, top); } }
int ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp) { struct linux_extra_stack_data64 *esdp, esd; struct elf_args *ap; struct vattr *vap; Elf_Ehdr *eh; Elf_Phdr *ph; u_long phsize; Elf_Addr phdr = 0; int error; int i; if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) return error; /* * Push extra arguments on the stack needed by dynamically * linked binaries and static binaries as well. */ memset(&esd, 0, sizeof(esd)); esdp = (struct linux_extra_stack_data64 *)(*stackp); ap = (struct elf_args *)pack->ep_emul_arg; vap = pack->ep_vap; eh = (Elf_Ehdr *)pack->ep_hdr; /* * We forgot this, so we need to reload it now. XXX keep track of it? */ if (ap == NULL) { phsize = eh->e_phnum * sizeof(Elf_Phdr); ph = (Elf_Phdr *)kmem_alloc(phsize, KM_SLEEP); error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize); if (error != 0) { for (i = 0; i < eh->e_phnum; i++) { if (ph[i].p_type == PT_PHDR) { phdr = ph[i].p_vaddr; break; } } } kmem_free(ph, phsize); } /* * The exec_package doesn't have a proc pointer and it's not * exactly trivial to add one since the credentials are * changing. XXX Linux uses curlwp's credentials. * Why can't we use them too? */ i = 0; esd.ai[i].a_type = LINUX_AT_HWCAP; esd.ai[i++].a_v = rcr4(); esd.ai[i].a_type = AT_PAGESZ; esd.ai[i++].a_v = PAGE_SIZE; esd.ai[i].a_type = LINUX_AT_CLKTCK; esd.ai[i++].a_v = hz; esd.ai[i].a_type = AT_PHDR; esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr); esd.ai[i].a_type = AT_PHENT; esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize); esd.ai[i].a_type = AT_PHNUM; esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum); esd.ai[i].a_type = AT_BASE; esd.ai[i++].a_v = (ap ? ap->arg_interp : 0); esd.ai[i].a_type = AT_FLAGS; esd.ai[i++].a_v = 0; esd.ai[i].a_type = AT_ENTRY; esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry); esd.ai[i].a_type = LINUX_AT_EGID; esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ? vap->va_gid : kauth_cred_getegid(l->l_cred)); esd.ai[i].a_type = LINUX_AT_GID; esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred); esd.ai[i].a_type = LINUX_AT_EUID; esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? vap->va_uid : kauth_cred_geteuid(l->l_cred)); esd.ai[i].a_type = LINUX_AT_UID; esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred); esd.ai[i].a_type = LINUX_AT_SECURE; esd.ai[i++].a_v = 0; esd.ai[i].a_type = LINUX_AT_PLATFORM; esd.ai[i++].a_v = (Elf_Addr)&esdp->hw_platform[0]; esd.ai[i].a_type = AT_NULL; esd.ai[i++].a_v = 0; #ifdef DEBUG_LINUX if (i != LINUX_ELF_AUX_ENTRIES) { printf("linux_elf64_copyargs: %d Aux entries\n", i); return EINVAL; } #endif strcpy(esd.hw_platform, LINUX_PLATFORM); exec_free_emul_arg(pack); /* * Copy out the ELF auxiliary table and hw platform name */ if ((error = copyout(&esd, esdp, sizeof(esd))) != 0) return error; *stackp += sizeof(esd); return 0; }
//------------------------------------ // The parse method: Way too long. // Note that flag args are pushed // onto the stack, then the regular // args are appended, sorting them // to the rear the way getopt() does. //------------------------------------ Boolean getoopt::parse( int argc, char** argv) { Optarg o; int cat; const flagspec* fs; Arg_List nonflagargs; enum States {START, ARGEXPECTED}; States state = START; for (unsigned int i = 1; i < (unsigned int)argc; i++) { unsigned int endsize = static_cast<unsigned int>(strlen(argv[i])); switch (state) { case START: cat = catagorize(argv[i]); switch (cat) { case 0: // non-flag command line argument addarg(nonflagargs, "", Optarg::REGULAR, argv[i]); break; case 1: // short (1-character) flag { if(endsize == 1) { MessageLoaderParms parms( "getoopt.getoopt.MISSING_OPTION", "Missing required option for $0", argv[i]); addError(MessageLoader::getMessage(parms)); break; } unsigned int argpos = 1; while (argpos < endsize) { char c = argv[i][argpos]; fs = getFlagspec(c); // Short flag String temp = argv[i]; String name = temp.subString(argpos, 1); // See if we recognize it if (!fs) { MessageLoaderParms parms( "getoopt.getoopt.UNKNOWN_FLAG", "Unknown flag $0$1", "-", name); addError(MessageLoader::getMessage(parms)); argpos++; } else { // Should this flag be bound? if (fs->argtype == NOARG) { // NO addarg(_args, name, Optarg::FLAG, ""); argpos++; } else { // YES -- the value is here or in the next arg optargFromShortOpt(o, &argv[i][argpos]); if (o.Value() == "") { // No value yet state = ARGEXPECTED; } else { addarg(_args, o); } argpos = endsize; } } } break; } // end subcase 1 case 2: // long (--xyz) flag { String arg = &(argv[i][2]); optargFromLongOpt(o, arg); fs = getFlagspec(o.getName()); // see if we recognize this flag if (!fs) { MessageLoaderParms parms( "getoopt.getoopt.UNKNOWN_FLAG", "Unknown flag $0$1", "", o.getName()); addError(MessageLoader::getMessage(parms)); } else { // this is a long flag we know about if (o.optarg() != "" || fs->argtype != MUSTHAVEARG) { addarg(_args, o); state = START; // we have a completed long flag } else { // no value yet, and we expect one if (fs->argtype == MUSTHAVEARG) { state = ARGEXPECTED; } } } break; } // end subcase 2 } // end switch catagorize() break; // end of case START case ARGEXPECTED: if (argv[i][0] == '-') { MessageLoaderParms parms( "getoopt.getoopt.MISSING_VALUE_FOR_FLAG", "Missing required value for flag $0", o.getopt()); addError(MessageLoader::getMessage(parms)); i--; } else { o.setValue(argv[i]); } addarg(_args, o); state = START; break; } // end switch } // end for if (state != START) { MessageLoaderParms parms( "getoopt.getoopt.MISSING_VALUE_FOR_FLAG", "Missing required value for flag $0", o.getName()); addError(MessageLoader::getMessage(parms)); } copyargs(_args, nonflagargs); return !_errorStrings.size(); }
/* * Copy arguments onto the stack in the normal way, but add some * extra information in case of dynamic binding. */ int ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp) { size_t len; AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a; struct elf_args *ap; int error; struct vattr *vap; if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) return error; a = ai; /* * Push extra arguments used by glibc on the stack. */ a->a_type = AT_PAGESZ; a->a_v = PAGE_SIZE; a++; if ((ap = (struct elf_args *)pack->ep_emul_arg)) { a->a_type = AT_PHDR; a->a_v = ap->arg_phaddr; a++; a->a_type = AT_PHENT; a->a_v = ap->arg_phentsize; a++; a->a_type = AT_PHNUM; a->a_v = ap->arg_phnum; a++; a->a_type = AT_BASE; a->a_v = ap->arg_interp; a++; a->a_type = AT_FLAGS; a->a_v = 0; a++; a->a_type = AT_ENTRY; a->a_v = ap->arg_entry; a++; exec_free_emul_arg(pack); } /* Linux-specific items */ a->a_type = LINUX_AT_CLKTCK; a->a_v = hz; a++; vap = pack->ep_vap; a->a_type = LINUX_AT_UID; a->a_v = kauth_cred_getuid(l->l_cred); a++; a->a_type = LINUX_AT_EUID; if (vap->va_mode & S_ISUID) a->a_v = vap->va_uid; else a->a_v = kauth_cred_geteuid(l->l_cred); a++; a->a_type = LINUX_AT_GID; a->a_v = kauth_cred_getgid(l->l_cred); a++; a->a_type = LINUX_AT_EGID; if (vap->va_mode & S_ISGID) a->a_v = vap->va_gid; else a->a_v = kauth_cred_getegid(l->l_cred); a++; a->a_type = AT_NULL; a->a_v = 0; a++; len = (a - ai) * sizeof(AuxInfo); if ((error = copyout(ai, *stackp, len)) != 0) return error; *stackp += len; return 0; }