static int do_card_label(struct state *cur, int argc, char **argv) { struct sc_pkcs15_card *p15card = cur->profile->p15_spec; return setstr(&p15card->label, argv[0]); }
static void checkTimeoutCommand (long int *timeout, char **command, const char *msgCommandWithoutTimeout, const char *msgTimeoutWithoutCommand) { if (*timeout == -1) { /* invalid timeout value was specified */ *timeout = 0; *command = setstr(*command, NULL); } if (*timeout == 0 && *command) { message (LOG_ERR, msgCommandWithoutTimeout); *command = setstr(*command, NULL); } if (*timeout && *command == NULL) { message (LOG_ERR, msgTimeoutWithoutCommand); *timeout = 0; } }
static int do_card_manufacturer(struct state *cur, int argc, char **argv) { struct sc_pkcs15_card *p15card = cur->profile->p15_spec; return setstr(&p15card->manufacturer_id, argv[0]); }
void TRunCommandDialog::handleEvent(TEvent& event) { TDialog::handleEvent(event); if (event.what==evCommand) { switch (event.message.command) { case cmRunBrowse: { TFileDialog *fo=new TFileDialog("*.*", "Open file", "~F~ile name", fdOpenButton, hhRunFile); fo->helpCtx = hcFileDlgCommon; int res = owner->execView(fo)==cmFileOpen; if (res) { char exename[QS_MAXPATH+1]; fo->getData(exename); setstr(r_cmdline,exename); } destroy(fo); clearEvent(event); break; } case cmRunExecute: { char *cmd = getstr(r_cmdline); if (cmd&&*cmd) opts_run(cmd,r_opts->mark(0),r_opts->mark(1)); clearEvent(event); break; } } } }
void DataFeed::setUrl ( char *name, long nameLen ) { if (!name || nameLen == 0) return; if (nameLen < 11 || strncasecmp(name, "datafeed://", 11) != 0) { char tempUrl[MAX_USERNAMELEN+1]; setstr(tempUrl, MAX_USERNAMELEN-12, name, nameLen); m_urlLen = sprintf(m_url, "datafeed://%s/", tempUrl); } else m_urlLen = setstr(m_url, MAX_USERNAMELEN, name, nameLen); // base name long i; for (i = 0; m_url[i+11] != '/'; i++) m_baseName[i] = m_url[i+11]; m_baseName[i] = '\0'; m_baseNameLen = i; }
char *getstr(char *ident, int *status) { varentry_t *var = lookupvar(ident, string); char *out; *status = ERROR_NONE; if(var == NULL) { out = setstr(ident, "", status); } else { out = var->val.string; } return out; }
/* set variable to integer */ void setint(struct tbl *vq, mksh_ari_t n) { if (!(vq->flag&INTEGER)) { vtemp->flag = (ISSET|INTEGER); vtemp->type = 0; vtemp->areap = ATEMP; vtemp->val.i = n; /* setstr can't fail here */ setstr(vq, str_val(vtemp), KSH_RETURN_ERROR); } else vq->val.i = n; vq->flag |= ISSET; if ((vq->flag&SPECIAL)) setspec(vq); }
void DataFeed::set ( long creationTime, char *dataFeedUrl, long dataFeedUrlLen, char *passcode, long passcodeLen, bool isActive, bool isLocked ) { setUrl(dataFeedUrl, dataFeedUrlLen); m_passcodeLen = setstr(m_passcode, MAX_PASSCODELEN, passcode, passcodeLen); // flags m_isActive = isActive; m_isLocked = isLocked; // creation time m_creationTime = creationTime; }
void writePidFile (char *pidfile) { FILE *fp; if (args.pidfile) unlink (args.pidfile); args.pidfile = setstr(args.pidfile, pidfile); if (args.pidfile) { fp = fopen(pidfile, "w"); if (fp) { fprintf (fp, "%d", getpid()); fclose (fp); } else message (LOG_ERR, "can't write pidfile %s\n", pidfile); } }
int text_dialog_kbrd(const char *message, char** answer, int flags) { htsmsg_t *m; rstr_t *r; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "textDialogKbrd"); prop_set_string_ex(prop_create(p, "message"), NULL, message, flags & MESSAGE_POPUP_RICH_TEXT ? PROP_STR_RICH : PROP_STR_UTF8); prop_t *string = prop_create(p, "input"); if(flags & MESSAGE_POPUP_CANCEL) prop_set_int(prop_create(p, "cancel"), 1); if(flags & MESSAGE_POPUP_OK) prop_set_int(prop_create(p, "ok"), 1); event_t *e = popup_display_kbrd(p, string); if (event_is_action(e, ACTION_OK)) { m = htsmsg_create_map(); r = prop_get_string(string); htsmsg_add_str(m, "input", r ? rstr_get(r) : ""); rstr_release(r); htsmsg_get_str(m, "input"); setstr(answer, m, "input"); } prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)){ event_release(e); return -1; } event_release(e); return 0; }
static void mprintit(mbox_t *mbp) { struct tbl *vp; #if 0 /* * I doubt this $_ overloading is bad in /bin/sh mode. Anyhow, we * crash as the code looks now if we do not set vp. Now, this is * easy to fix too, but I'd like to see what POSIX says before doing * a change like that. */ if (!Flag(FSH)) #endif /* Ignore setstr errors here (arbitrary) */ setstr((vp = local("_", false)), mbp->mb_path, KSH_RETURN_ERROR); shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0)); unset(vp, 0); }
int c_read(char **wp) { int c = 0; int expand = 1, history = 0; int expanding; int ecode = 0; char *cp; int fd = 0; struct shf *shf; int optc; const char *emsg; XString cs, xs; struct tbl *vp; char *xp = NULL; while ((optc = ksh_getopt(wp, &builtin_opt, "prsu,")) != -1) switch (optc) { case 'p': if ((fd = coproc_getfd(R_OK, &emsg)) < 0) { bi_errorf("-p: %s", emsg); return 1; } break; case 'r': expand = 0; break; case 's': history = 1; break; case 'u': if (!*(cp = builtin_opt.optarg)) fd = 0; else if ((fd = check_fd(cp, R_OK, &emsg)) < 0) { bi_errorf("-u: %s: %s", cp, emsg); return 1; } break; case '?': return 1; } wp += builtin_opt.optind; if (*wp == NULL) *--wp = "REPLY"; /* Since we can't necessarily seek backwards on non-regular files, * don't buffer them so we can't read too much. */ shf = shf_reopen(fd, SHF_RD | SHF_INTERRUPT | can_seek(fd), shl_spare); if ((cp = strchr(*wp, '?')) != NULL) { *cp = 0; if (isatty(fd)) { /* at&t ksh says it prints prompt on fd if it's open * for writing and is a tty, but it doesn't do it * (it also doesn't check the interactive flag, * as is indicated in the Kornshell book). */ shellf("%s", cp+1); } } /* If we are reading from the co-process for the first time, * make sure the other side of the pipe is closed first. This allows * the detection of eof. * * This is not compatible with at&t ksh... the fd is kept so another * coproc can be started with same output, however, this means eof * can't be detected... This is why it is closed here. * If this call is removed, remove the eof check below, too. * coproc_readw_close(fd); */ if (history) Xinit(xs, xp, 128, ATEMP); expanding = 0; Xinit(cs, cp, 128, ATEMP); for (; *wp != NULL; wp++) { for (cp = Xstring(cs, cp); ; ) { if (c == '\n' || c == EOF) break; while (1) { c = shf_getc(shf); if (c == '\0') continue; if (c == EOF && shf_error(shf) && shf_errno(shf) == EINTR) { /* Was the offending signal one that * would normally kill a process? * If so, pretend the read was killed. */ ecode = fatal_trap_check(); /* non fatal (eg, CHLD), carry on */ if (!ecode) { shf_clearerr(shf); continue; } } break; } if (history) { Xcheck(xs, xp); Xput(xs, xp, c); } Xcheck(cs, cp); if (expanding) { expanding = 0; if (c == '\n') { c = 0; if (Flag(FTALKING_I) && isatty(fd)) { /* set prompt in case this is * called from .profile or $ENV */ set_prompt(PS2, NULL); pprompt(prompt, 0); } } else if (c != EOF) Xput(cs, cp, c); continue; } if (expand && c == '\\') { expanding = 1; continue; } if (c == '\n' || c == EOF) break; if (ctype(c, C_IFS)) { if (Xlength(cs, cp) == 0 && ctype(c, C_IFSWS)) continue; if (wp[1]) break; } Xput(cs, cp, c); } /* strip trailing IFS white space from last variable */ if (!wp[1]) while (Xlength(cs, cp) && ctype(cp[-1], C_IFS) && ctype(cp[-1], C_IFSWS)) cp--; Xput(cs, cp, '\0'); vp = global(*wp); /* Must be done before setting export. */ if (vp->flag & RDONLY) { shf_flush(shf); bi_errorf("%s is read only", *wp); return 1; } if (Flag(FEXPORT)) typeset(*wp, EXPORT, 0, 0, 0); if (!setstr(vp, Xstring(cs, cp), KSH_RETURN_ERROR)) { shf_flush(shf); return 1; } } shf_flush(shf); if (history) { Xput(xs, xp, '\0'); source->line++; histsave(source->line, Xstring(xs, xp), 1); Xfree(xs, xp); } /* if this is the co-process fd, close the file descriptor * (can get eof if and only if all processes are have died, ie, * coproc.njobs is 0 and the pipe is closed). */ if (c == EOF && !ecode) coproc_read_close(fd); return ecode ? ecode : c == EOF; }
static int main_init(int argc, const char *argv[], Source **sp, struct block **lp) { int argi, i; Source *s = NULL; struct block *l; unsigned char restricted_shell, errexit, utf_flag; char *cp; const char *ccp, **wp; struct tbl *vp; struct stat s_stdin; #if !defined(_PATH_DEFPATH) && defined(_CS_PATH) ssize_t k; #endif #if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC) ebcdic_init(); #endif set_ifs(TC_IFSWS); #ifdef __OS2__ os2_init(&argc, &argv); #endif /* do things like getpgrp() et al. */ chvt_reinit(); /* make sure argv[] is sane, for weird OSes */ if (!*argv) { argv = empty_argv; argc = 1; } kshname = argv[0]; /* initialise permanent Area */ ainit(&aperm); /* max. name length: -2147483648 = 11 (+ NUL) */ vtemp = alloc(offsetof(struct tbl, name[0]) + 12, APERM); /* set up base environment */ env.type = E_NONE; ainit(&env.area); /* set up global l->vars and l->funs */ newblock(); /* Do this first so output routines (eg, errorf, shellf) can work */ initio(); /* determine the basename (without '-' or path) of the executable */ ccp = kshname; goto begin_parsing_kshname; while ((i = ccp[argi++])) { if (mksh_cdirsep(i)) { ccp += argi; begin_parsing_kshname: argi = 0; if (*ccp == '-') ++ccp; } } if (!*ccp) ccp = empty_argv[0]; /* * Turn on nohup by default. (AT&T ksh does not have a nohup * option - it always sends the hup). */ Flag(FNOHUP) = 1; /* * Turn on brace expansion by default. AT&T kshs that have * alternation always have it on. */ Flag(FBRACEEXPAND) = 1; /* * Turn on "set -x" inheritance by default. */ Flag(FXTRACEREC) = 1; /* define built-in commands and see if we were called as one */ ktinit(APERM, &builtins, /* currently up to 54 builtins: 75% of 128 = 2^7 */ 7); for (i = 0; mkshbuiltins[i].name != NULL; i++) if (!strcmp(ccp, builtin(mkshbuiltins[i].name, mkshbuiltins[i].func))) Flag(FAS_BUILTIN) = 1; if (!Flag(FAS_BUILTIN)) { /* check for -T option early */ argi = parse_args(argv, OF_FIRSTTIME, NULL); if (argi < 0) return (1); #if defined(MKSH_BINSHPOSIX) || defined(MKSH_BINSHREDUCED) /* are we called as -sh or /bin/sh or so? */ if (!strcmp(ccp, "sh" MKSH_EXE_EXT)) { /* either also turns off braceexpand */ #ifdef MKSH_BINSHPOSIX /* enable better POSIX conformance */ change_flag(FPOSIX, OF_FIRSTTIME, true); #endif #ifdef MKSH_BINSHREDUCED /* enable kludge/compat mode */ change_flag(FSH, OF_FIRSTTIME, true); #endif } #endif } initvar(); inittraps(); coproc_init(); /* set up variable and command dictionaries */ ktinit(APERM, &taliases, 0); ktinit(APERM, &aliases, 0); #ifndef MKSH_NOPWNAM ktinit(APERM, &homedirs, 0); #endif /* define shell keywords */ initkeywords(); init_histvec(); /* initialise tty size before importing environment */ change_winsz(); #ifdef _PATH_DEFPATH def_path = _PATH_DEFPATH; #else #ifdef _CS_PATH if ((k = confstr(_CS_PATH, NULL, 0)) > 0 && confstr(_CS_PATH, cp = alloc(k + 1, APERM), k + 1) == k + 1) def_path = cp; else #endif /* * this is uniform across all OSes unless it * breaks somewhere hard; don't try to optimise, * e.g. add stuff for Interix or remove /usr * for HURD, because e.g. Debian GNU/HURD is * "keeping a regular /usr"; this is supposed * to be a sane 'basic' default PATH */ def_path = MKSH_UNIXROOT "/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/bin" MKSH_PATHSEPS MKSH_UNIXROOT "/sbin" MKSH_PATHSEPS MKSH_UNIXROOT "/usr/sbin"; #endif /* * Set PATH to def_path (will set the path global variable). * (import of environment below will probably change this setting). */ vp = global(TPATH); /* setstr can't fail here */ setstr(vp, def_path, KSH_RETURN_ERROR); #ifndef MKSH_NO_CMDLINE_EDITING /* * Set edit mode to emacs by default, may be overridden * by the environment or the user. Also, we want tab completion * on in vi by default. */ change_flag(FEMACS, OF_SPECIAL, true); #if !MKSH_S_NOVI Flag(FVITABCOMPLETE) = 1; #endif #endif /* import environment */ init_environ(); /* override default PATH regardless of environment */ #ifdef MKSH_DEFPATH_OVERRIDE vp = global(TPATH); setstr(vp, MKSH_DEFPATH_OVERRIDE, KSH_RETURN_ERROR); #endif /* for security */ typeset(TinitIFS, 0, 0, 0, 0); /* assign default shell variable values */ typeset("PATHSEP=" MKSH_PATHSEPS, 0, 0, 0, 0); substitute(initsubs, 0); /* Figure out the current working directory and set $PWD */ vp = global(TPWD); cp = str_val(vp); /* Try to use existing $PWD if it is valid */ set_current_wd((mksh_abspath(cp) && test_eval(NULL, TO_FILEQ, cp, Tdot, true)) ? cp : NULL); if (current_wd[0]) simplify_path(current_wd); /* Only set pwd if we know where we are or if it had a bogus value */ if (current_wd[0] || *cp) /* setstr can't fail here */ setstr(vp, current_wd, KSH_RETURN_ERROR); for (wp = initcoms; *wp != NULL; wp++) { c_builtin(wp); while (*wp != NULL) wp++; } setint_n(global("OPTIND"), 1, 10); kshuid = getuid(); kshgid = getgid(); kshegid = getegid(); safe_prompt = ksheuid ? "$ " : "# "; vp = global("PS1"); /* Set PS1 if unset or we are root and prompt doesn't contain a # */ if (!(vp->flag & ISSET) || (!ksheuid && !strchr(str_val(vp), '#'))) /* setstr can't fail here */ setstr(vp, safe_prompt, KSH_RETURN_ERROR); setint_n((vp = global("BASHPID")), 0, 10); vp->flag |= INT_U; setint_n((vp = global("PGRP")), (mksh_uari_t)kshpgrp, 10); vp->flag |= INT_U; setint_n((vp = global("PPID")), (mksh_uari_t)kshppid, 10); vp->flag |= INT_U; setint_n((vp = global("USER_ID")), (mksh_uari_t)ksheuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHUID")), (mksh_uari_t)kshuid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHEGID")), (mksh_uari_t)kshegid, 10); vp->flag |= INT_U; setint_n((vp = global("KSHGID")), (mksh_uari_t)kshgid, 10); vp->flag |= INT_U; setint_n((vp = global("RANDOM")), rndsetup(), 10); vp->flag |= INT_U; setint_n((vp_pipest = global("PIPESTATUS")), 0, 10); /* Set this before parsing arguments */ Flag(FPRIVILEGED) = (kshuid != ksheuid || kshgid != kshegid) ? 2 : 0; /* this to note if monitor is set on command line (see below) */ #ifndef MKSH_UNEMPLOYED Flag(FMONITOR) = 127; #endif /* this to note if utf-8 mode is set on command line (see below) */ UTFMODE = 2; if (!Flag(FAS_BUILTIN)) { argi = parse_args(argv, OF_CMDLINE, NULL); if (argi < 0) return (1); } /* process this later only, default to off (hysterical raisins) */ utf_flag = UTFMODE; UTFMODE = 0; if (Flag(FAS_BUILTIN)) { /* auto-detect from environment variables, always */ utf_flag = 3; } else if (Flag(FCOMMAND)) { s = pushs(SSTRINGCMDLINE, ATEMP); if (!(s->start = s->str = argv[argi++])) errorf(Tf_optfoo, "", "", 'c', Treq_arg); while (*s->str) { if (ctype(*s->str, C_QUOTE)) break; s->str++; } if (!*s->str) s->flags |= SF_MAYEXEC; s->str = s->start; #ifdef MKSH_MIDNIGHTBSD01ASH_COMPAT /* compatibility to MidnightBSD 0.1 /bin/sh (kludge) */ if (Flag(FSH) && argv[argi] && !strcmp(argv[argi], "--")) ++argi; #endif if (argv[argi]) kshname = argv[argi++]; } else if (argi < argc && !Flag(FSTDIN)) { s = pushs(SFILE, ATEMP); #ifdef __OS2__ /* * A bug in OS/2 extproc (like shebang) handling makes * it not pass the full pathname of a script, so we need * to search for it. This changes the behaviour of a * simple "mksh foo", but can't be helped. */ s->file = argv[argi++]; if (search_access(s->file, X_OK) != 0) s->file = search_path(s->file, path, X_OK, NULL); if (!s->file || !*s->file) s->file = argv[argi - 1]; #else s->file = argv[argi++]; #endif s->u.shf = shf_open(s->file, O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); if (s->u.shf == NULL) { shl_stdout_ok = false; warningf(true, Tf_sD_s, s->file, cstrerror(errno)); /* mandated by SUSv4 */ exstat = 127; unwind(LERROR); } kshname = s->file; } else { Flag(FSTDIN) = 1; s = pushs(SSTDIN, ATEMP); s->file = "<stdin>"; s->u.shf = shf_fdopen(0, SHF_RD | can_seek(0), NULL); if (isatty(0) && isatty(2)) { Flag(FTALKING) = Flag(FTALKING_I) = 1; /* The following only if isatty(0) */ s->flags |= SF_TTY; s->u.shf->flags |= SHF_INTERRUPT; s->file = NULL; } } /* this bizarreness is mandated by POSIX */ if (fstat(0, &s_stdin) >= 0 && S_ISCHR(s_stdin.st_mode) && Flag(FTALKING)) reset_nonblock(0); /* initialise job control */ j_init(); /* do this after j_init() which calls tty_init_state() */ if (Flag(FTALKING)) { if (utf_flag == 2) { #ifndef MKSH_ASSUME_UTF8 /* auto-detect from locale or environment */ utf_flag = 4; #else /* this may not be an #elif */ #if MKSH_ASSUME_UTF8 utf_flag = 1; #else /* always disable UTF-8 (for interactive) */ utf_flag = 0; #endif #endif } #ifndef MKSH_NO_CMDLINE_EDITING x_init(); #endif } #ifdef SIGWINCH sigtraps[SIGWINCH].flags |= TF_SHELL_USES; setsig(&sigtraps[SIGWINCH], x_sigwinch, SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); #endif l = e->loc; if (Flag(FAS_BUILTIN)) { l->argc = argc; l->argv = argv; l->argv[0] = ccp; } else { l->argc = argc - argi; /* * allocate a new array because otherwise, when we modify * it in-place, ps(1) output changes; the meaning of argc * here is slightly different as it excludes kshname, and * we add a trailing NULL sentinel as well */ l->argv = alloc2(l->argc + 2, sizeof(void *), APERM); l->argv[0] = kshname; memcpy(&l->argv[1], &argv[argi], l->argc * sizeof(void *)); l->argv[l->argc + 1] = NULL; getopts_reset(1); } /* divine the initial state of the utf8-mode Flag */ ccp = null; switch (utf_flag) { /* auto-detect from locale or environment */ case 4: #if HAVE_SETLOCALE_CTYPE ccp = setlocale(LC_CTYPE, ""); #if HAVE_LANGINFO_CODESET if (!isuc(ccp)) ccp = nl_langinfo(CODESET); #endif if (!isuc(ccp)) ccp = null; #endif /* FALLTHROUGH */ /* auto-detect from environment */ case 3: /* these were imported from environ earlier */ if (ccp == null) ccp = str_val(global("LC_ALL")); if (ccp == null) ccp = str_val(global("LC_CTYPE")); if (ccp == null) ccp = str_val(global("LANG")); UTFMODE = isuc(ccp); break; /* not set on command line, not FTALKING */ case 2: /* unknown values */ default: utf_flag = 0; /* FALLTHROUGH */ /* known values */ case 1: case 0: UTFMODE = utf_flag; break; } /* Disable during .profile/ENV reading */ restricted_shell = Flag(FRESTRICTED); Flag(FRESTRICTED) = 0; errexit = Flag(FERREXIT); Flag(FERREXIT) = 0; /* * Do this before profile/$ENV so that if it causes problems in them, * user will know why things broke. */ if (!current_wd[0] && Flag(FTALKING)) warningf(false, "can't determine current directory"); if (Flag(FLOGIN)) include(MKSH_SYSTEM_PROFILE, 0, NULL, true); if (!Flag(FPRIVILEGED)) { if (Flag(FLOGIN)) include(substitute("$HOME/.profile", 0), 0, NULL, true); if (Flag(FTALKING)) { cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE); if (cp[0] != '\0') include(cp, 0, NULL, true); } } else { include(MKSH_SUID_PROFILE, 0, NULL, true); /* turn off -p if not set explicitly */ if (Flag(FPRIVILEGED) != 1) change_flag(FPRIVILEGED, OF_INTERNAL, false); } if (restricted_shell) { c_builtin(restr_com); /* After typeset command... */ Flag(FRESTRICTED) = 1; } Flag(FERREXIT) = errexit; if (Flag(FTALKING) && s) hist_init(s); else /* set after ENV */ Flag(FTRACKALL) = 1; alarm_init(); *sp = s; *lp = l; return (0); }
Tchar getch(void) { int k; Tchar i, j; g0: if (ch) { i = ch; if (cbits(i) == '\n') nlflg++; ch = 0; return(i); } if (nlflg) return('\n'); i = getch0(); if (ismot(i)) return(i); k = cbits(i); if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0) /* nothing special */ return(i); if (k != ESC) { if (k == '\n') { nlflg++; if (ip == 0) numtabp[CD].val++; /* line number */ return(k); } if (k == FLSS) { copyf++; raw++; i = getch0(); if (!fi) flss = i; copyf--; raw--; goto g0; } if (k == RPT) { setrpt(); goto g0; } if (!copyf) { if (k == 'f' && lg && !lgf) { i = getlg(i); return(i); } if (k == fc || k == tabch || k == ldrch) { if ((i = setfield(k)) == 0) goto g0; else return(i); } if (k == '\b') { i = makem(-width(' ' | chbits)); return(i); } } return(i); } k = cbits(j = getch0()); if (ismot(j)) return(j); switch (k) { case 'n': /* number register */ setn(); goto g0; case '$': /* argument indicator */ seta(); goto g0; case '*': /* string indicator */ setstr(); goto g0; case '{': /* LEFT */ i = LEFT; goto gx; case '}': /* RIGHT */ i = RIGHT; goto gx; case '"': /* comment */ while (cbits(i = getch0()) != '\n') ; if (ip == 0) numtabp[CD].val++; /* line number */ nlflg++; return(i); /* experiment: put it here instead of copy mode */ case '(': /* special char name \(xx */ case 'C': /* \C'...' */ if ((i = setch(k)) == 0) goto g0; goto gx; case ESC: /* double backslash */ i = eschar; goto gx; case 'e': /* printable version of current eschar */ i = PRESC; goto gx; case '\n': /* concealed newline */ numtabp[CD].val++; goto g0; case ' ': /* unpaddable space */ i = UNPAD; goto gx; case '\'': /* \(aa */ i = ACUTE; goto gx; case '`': /* \(ga */ i = GRAVE; goto gx; case '_': /* \(ul */ i = UNDERLINE; goto gx; case '-': /* current font minus */ i = MINUS; goto gx; case '&': /* filler */ i = FILLER; goto gx; case 'c': /* to be continued */ i = CONT; goto gx; case '!': /* transparent indicator */ i = XPAR; goto gx; case 't': /* tab */ i = '\t'; return(i); case 'a': /* leader (SOH) */ /* old: *pbp++ = LEADER; goto g0; */ i = LEADER; return i; case '%': /* ohc */ i = OHC; return(i); case 'g': /* return format of a number register */ setaf(); /* should this really be in copy mode??? */ goto g0; case '.': /* . */ i = '.'; gx: setsfbits(i, sfbits(j)); return(i); } if (copyf) { *pbp++ = j; return(eschar); } switch (k) { case 'f': /* font indicator */ setfont(0); goto g0; case 's': /* size indicator */ setps(); goto g0; case 'v': /* vert mot */ numerr.type = numerr.escarg = 0; numerr.esc = k; if (i = vmot()) { return(i); } goto g0; case 'h': /* horiz mot */ numerr.type = numerr.escarg = 0; numerr.esc = k; if (i = hmot()) return(i); goto g0; case '|': /* narrow space */ if (NROFF) goto g0; return(makem((int)(EM)/6)); case '^': /* half narrow space */ if (NROFF) goto g0; return(makem((int)(EM)/12)); case 'w': /* width function */ setwd(); goto g0; case 'p': /* spread */ spread++; goto g0; case 'N': /* absolute character number */ numerr.type = numerr.escarg = 0; numerr.esc = k; if ((i = setabs()) == 0) goto g0; return i; case 'H': /* character height */ numerr.type = numerr.escarg = 0; numerr.esc = k; return(setht()); case 'S': /* slant */ numerr.type = numerr.escarg = 0; numerr.esc = k; return(setslant()); case 'z': /* zero with char */ return(setz()); case 'l': /* hor line */ numerr.type = numerr.escarg = 0; numerr.esc = k; setline(); goto g0; case 'L': /* vert line */ numerr.type = numerr.escarg = 0; numerr.esc = k; setvline(); goto g0; case 'D': /* drawing function */ numerr.type = numerr.escarg = 0; numerr.esc = k; setdraw(); goto g0; case 'X': /* \X'...' for copy through */ setxon(); goto g0; case 'b': /* bracket */ setbra(); goto g0; case 'o': /* overstrike */ setov(); goto g0; case 'k': /* mark hor place */ if ((k = findr(getsn())) != -1) { numtabp[k].val = numtabp[HP].val; } goto g0; case '0': /* number space */ return(makem(width('0' | chbits))); case 'x': /* extra line space */ numerr.type = numerr.escarg = 0; numerr.esc = k; if (i = xlss()) return(i); goto g0; case 'u': /* half em up */ case 'r': /* full em up */ case 'd': /* half em down */ return(sethl(k)); default: return(j); } /* NOTREACHED */ }
event_t * popup_display_kbrd(prop_t *p, prop_t *string) { prop_courier_t *pc = prop_courier_create_waitable(); event_t *e = NULL; prop_t *r = prop_create(p, "eventSink"); prop_sub_t *s = prop_subscribe(0, PROP_TAG_CALLBACK, eventsink, &e, PROP_TAG_ROOT, r, PROP_TAG_COURIER, pc, NULL); /* Will show the popup */ if(prop_set_parent(p, prop_create(prop_get_global(), "popups"))) { /* popuproot is a zombie, this is an error */ abort(); } while (e == NULL || (!event_is_action(e, ACTION_OK) && !event_is_action(e, ACTION_CANCEL))) { while(e == NULL) prop_courier_wait_and_dispatch(pc); if (!event_is_action(e, ACTION_OK) && !event_is_action(e, ACTION_CANCEL)) { char *tmpInput; htsmsg_t *m; rstr_t *r; m = htsmsg_create_map(); r = prop_get_string(string); htsmsg_add_str(m, "input", r ? rstr_get(r) : ""); rstr_release(r); htsmsg_get_str(m, "input"); setstr(&tmpInput, m, "input"); if (event_is_action(e, ACTION_KBRD_A)) strcat(tmpInput, "a"); else if (event_is_action(e, ACTION_KBRD_B)) strcat(tmpInput, "b"); else if (event_is_action(e, ACTION_KBRD_C)) strcat(tmpInput, "c"); else if (event_is_action(e, ACTION_KBRD_D)) strcat(tmpInput, "d"); else if (event_is_action(e, ACTION_KBRD_E)) strcat(tmpInput, "e"); else if (event_is_action(e, ACTION_KBRD_F)) strcat(tmpInput, "f"); else if (event_is_action(e, ACTION_KBRD_G)) strcat(tmpInput, "g"); else if (event_is_action(e, ACTION_KBRD_H)) strcat(tmpInput, "h"); else if (event_is_action(e, ACTION_KBRD_I)) strcat(tmpInput, "i"); else if (event_is_action(e, ACTION_KBRD_J)) strcat(tmpInput, "j"); else if (event_is_action(e, ACTION_KBRD_K)) strcat(tmpInput, "k"); else if (event_is_action(e, ACTION_KBRD_L)) strcat(tmpInput, "l"); else if (event_is_action(e, ACTION_KBRD_M)) strcat(tmpInput, "m"); else if (event_is_action(e, ACTION_KBRD_N)) strcat(tmpInput, "n"); else if (event_is_action(e, ACTION_KBRD_O)) strcat(tmpInput, "o"); else if (event_is_action(e, ACTION_KBRD_P)) strcat(tmpInput, "p"); else if (event_is_action(e, ACTION_KBRD_Q)) strcat(tmpInput, "q"); else if (event_is_action(e, ACTION_KBRD_R)) strcat(tmpInput, "r"); else if (event_is_action(e, ACTION_KBRD_S)) strcat(tmpInput, "s"); else if (event_is_action(e, ACTION_KBRD_T)) strcat(tmpInput, "t"); else if (event_is_action(e, ACTION_KBRD_U)) strcat(tmpInput, "u"); else if (event_is_action(e, ACTION_KBRD_V)) strcat(tmpInput, "v"); else if (event_is_action(e, ACTION_KBRD_W)) strcat(tmpInput, "w"); else if (event_is_action(e, ACTION_KBRD_X)) strcat(tmpInput, "x"); else if (event_is_action(e, ACTION_KBRD_Y)) strcat(tmpInput, "y"); else if (event_is_action(e, ACTION_KBRD_Z)) strcat(tmpInput, "z"); else if (event_is_action(e, ACTION_KBRD_0)) strcat(tmpInput, "0"); else if (event_is_action(e, ACTION_KBRD_1)) strcat(tmpInput, "1"); else if (event_is_action(e, ACTION_KBRD_2)) strcat(tmpInput, "2"); else if (event_is_action(e, ACTION_KBRD_3)) strcat(tmpInput, "3"); else if (event_is_action(e, ACTION_KBRD_4)) strcat(tmpInput, "4"); else if (event_is_action(e, ACTION_KBRD_5)) strcat(tmpInput, "5"); else if (event_is_action(e, ACTION_KBRD_6)) strcat(tmpInput, "6"); else if (event_is_action(e, ACTION_KBRD_7)) strcat(tmpInput, "7"); else if (event_is_action(e, ACTION_KBRD_8)) strcat(tmpInput, "8"); else if (event_is_action(e, ACTION_KBRD_9)) strcat(tmpInput, "9"); else if (event_is_action(e, ACTION_KBRD_COMMA)) strcat(tmpInput, ","); else if (event_is_action(e, ACTION_KBRD_DOT)) strcat(tmpInput, "."); else if (event_is_action(e, ACTION_KBRD_SPACE)) strcat(tmpInput, " "); else if (event_is_action(e, ACTION_BS)) { if (strlen(tmpInput) > 0) { strncpy(tmpInput, tmpInput, strlen(tmpInput) - 1); tmpInput[strlen(tmpInput) - 1] = '\0'; } } prop_set_string(string, tmpInput); e = NULL; } } prop_unsubscribe(s); return e; }
static int comexec(struct op *t, struct tbl * volatile tp, const char **ap, volatile int flags, volatile int *xerrok) { int i; volatile int rv = 0; const char *cp; const char **lastp; /* Must be static (XXX but why?) */ static struct op texec; int type_flags; bool resetspec; int fcflags = FC_BI|FC_FUNC|FC_PATH; struct block *l_expand, *l_assign; int optc; const char *exec_argv0 = NULL; bool exec_clrenv = false; /* snag the last argument for $_ */ if (Flag(FTALKING) && *(lastp = ap)) { /* * XXX not the same as AT&T ksh, which only seems to set $_ * after a newline (but not in functions/dot scripts, but in * interactive and script) - perhaps save last arg here and * set it in shell()?. */ while (*++lastp) ; /* setstr() can't fail here */ setstr(typeset("_", LOCAL, 0, INTEGER, 0), *--lastp, KSH_RETURN_ERROR); } /** * Deal with the shell builtins builtin, exec and command since * they can be followed by other commands. This must be done before * we know if we should create a local block which must be done * before we can do a path search (in case the assignments change * PATH). * Odd cases: * FOO=bar exec >/dev/null FOO is kept but not exported * FOO=bar exec foobar FOO is exported * FOO=bar command exec >/dev/null FOO is neither kept nor exported * FOO=bar command FOO is neither kept nor exported * PATH=... foobar use new PATH in foobar search */ resetspec = false; while (tp && tp->type == CSHELL) { /* undo effects of command */ fcflags = FC_BI|FC_FUNC|FC_PATH; if (tp->val.f == c_builtin) { if ((cp = *++ap) == NULL || (!strcmp(cp, "--") && (cp = *++ap) == NULL)) { tp = NULL; break; } if ((tp = findcom(cp, FC_BI)) == NULL) errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin"); if (tp->type == CSHELL && (tp->val.f == c_cat #ifdef MKSH_PRINTF_BUILTIN || tp->val.f == c_printf #endif )) break; continue; } else if (tp->val.f == c_exec) { if (ap[1] == NULL) break; ksh_getopt_reset(&builtin_opt, GF_ERROR); while ((optc = ksh_getopt(ap, &builtin_opt, "a:c")) != -1) switch (optc) { case 'a': exec_argv0 = builtin_opt.optarg; break; case 'c': exec_clrenv = true; /* ensure we can actually do this */ resetspec = true; break; default: rv = 2; goto Leave; } ap += builtin_opt.optind; flags |= XEXEC; } else if (tp->val.f == c_command) { bool saw_p = false; /* * Ugly dealing with options in two places (here * and in c_command(), but such is life) */ ksh_getopt_reset(&builtin_opt, 0); while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p') saw_p = true; if (optc != -1) /* command -vV or something */ break; /* don't look for functions */ fcflags = FC_BI|FC_PATH; if (saw_p) { if (Flag(FRESTRICTED)) { warningf(true, "%s: %s", "command -p", "restricted"); rv = 1; goto Leave; } fcflags |= FC_DEFPATH; } ap += builtin_opt.optind; /* * POSIX says special builtins lose their status * if accessed using command. */ resetspec = true; if (!ap[0]) { /* ensure command with no args exits with 0 */ subst_exstat = 0; break; } } else if (tp->val.f == c_cat) { /* if we have any flags, do not use the builtin */ if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' && /* argument, begins with -, is not - or -- */ (ap[1][1] != '-' || ap[1][2] != '\0')) { struct tbl *ext_cat; ext_cat = findcom(Tcat, FC_PATH | FC_FUNC); if (ext_cat && (ext_cat->type != CTALIAS || (ext_cat->flag & ISSET))) tp = ext_cat; } break; #ifdef MKSH_PRINTF_BUILTIN } else if (tp->val.f == c_printf) { struct tbl *ext_printf; ext_printf = findcom(Tprintf, FC_PATH | FC_FUNC); if (ext_printf && (ext_printf->type != CTALIAS || (ext_printf->flag & ISSET))) tp = ext_printf; break; #endif } else if (tp->val.f == c_trap) { t->u.evalflags &= ~DOTCOMEXEC; break; } else break; tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC)); } if (t->u.evalflags & DOTCOMEXEC) flags |= XEXEC; l_expand = e->loc; if (!resetspec && (!ap[0] || (tp && (tp->flag & KEEPASN)))) type_flags = 0; else { /* create new variable/function block */ newblock(); /* ksh functions don't keep assignments, POSIX functions do. */ if (!resetspec && tp && tp->type == CFUNC && !(tp->flag & FKSH)) type_flags = EXPORT; else type_flags = LOCAL|LOCAL_COPY|EXPORT; } l_assign = e->loc; if (exec_clrenv) l_assign->flags |= BF_STOPENV; if (Flag(FEXPORT)) type_flags |= EXPORT; if (Flag(FXTRACE)) change_xtrace(2, false); for (i = 0; t->vars[i]; i++) { /* do NOT lookup in the new var/fn block just created */ e->loc = l_expand; cp = evalstr(t->vars[i], DOASNTILDE | DOSCALAR); e->loc = l_assign; if (Flag(FXTRACE)) { const char *ccp; ccp = skip_varname(cp, true); if (*ccp == '+') ++ccp; if (*ccp == '=') ++ccp; shf_write(cp, ccp - cp, shl_xtrace); print_value_quoted(shl_xtrace, ccp); shf_putc(' ', shl_xtrace); } /* but assign in there as usual */ typeset(cp, type_flags, 0, 0, 0); } if (Flag(FXTRACE)) { change_xtrace(2, false); if (ap[rv = 0]) { xtrace_ap_loop: print_value_quoted(shl_xtrace, ap[rv]); if (ap[++rv]) { shf_putc(' ', shl_xtrace); goto xtrace_ap_loop; } } change_xtrace(1, false); } if ((cp = *ap) == NULL) { rv = subst_exstat; goto Leave; } else if (!tp) { if (Flag(FRESTRICTED) && vstrchr(cp, '/')) { warningf(true, "%s: %s", cp, "restricted"); rv = 1; goto Leave; } tp = findcom(cp, fcflags); } switch (tp->type) { /* shell built-in */ case CSHELL: do_call_builtin: rv = call_builtin(tp, (const char **)ap, null, resetspec); if (resetspec && tp->val.f == c_shift) { l_expand->argc = l_assign->argc; l_expand->argv = l_assign->argv; } break; /* function call */ case CFUNC: { volatile uint32_t old_inuse; const char * volatile old_kshname; volatile uint8_t old_flags[FNFLAGS]; if (!(tp->flag & ISSET)) { struct tbl *ftp; if (!tp->u.fpath) { rv = (tp->u2.errnov == ENOENT) ? 127 : 126; warningf(true, "%s: %s %s: %s", cp, "can't find", "function definition file", cstrerror(tp->u2.errnov)); break; } if (include(tp->u.fpath, 0, NULL, false) < 0) { if (!strcmp(cp, Tcat)) { no_cat_in_FPATH: tp = findcom(Tcat, FC_BI); goto do_call_builtin; } #ifdef MKSH_PRINTF_BUILTIN if (!strcmp(cp, Tprintf)) { no_printf_in_FPATH: tp = findcom(Tprintf, FC_BI); goto do_call_builtin; } #endif warningf(true, "%s: %s %s %s: %s", cp, "can't open", "function definition file", tp->u.fpath, cstrerror(errno)); rv = 127; break; } if (!(ftp = findfunc(cp, hash(cp), false)) || !(ftp->flag & ISSET)) { if (!strcmp(cp, Tcat)) goto no_cat_in_FPATH; #ifdef MKSH_PRINTF_BUILTIN if (!strcmp(cp, Tprintf)) goto no_printf_in_FPATH; #endif warningf(true, "%s: %s %s", cp, "function not defined by", tp->u.fpath); rv = 127; break; } tp = ftp; } /* * ksh functions set $0 to function name, POSIX * functions leave $0 unchanged. */ old_kshname = kshname; if (tp->flag & FKSH) kshname = ap[0]; else ap[0] = kshname; e->loc->argv = ap; for (i = 0; *ap++ != NULL; i++) ; e->loc->argc = i - 1; /* * ksh-style functions handle getopts sanely, * Bourne/POSIX functions are insane... */ if (tp->flag & FKSH) { e->loc->flags |= BF_DOGETOPTS; e->loc->getopts_state = user_opt; getopts_reset(1); } for (type_flags = 0; type_flags < FNFLAGS; ++type_flags) old_flags[type_flags] = shell_flags[type_flags]; change_xtrace((Flag(FXTRACEREC) ? Flag(FXTRACE) : 0) | ((tp->flag & TRACE) ? 1 : 0), false); old_inuse = tp->flag & FINUSE; tp->flag |= FINUSE; e->type = E_FUNC; if (!(i = kshsetjmp(e->jbuf))) { execute(tp->val.t, flags & XERROK, NULL); i = LRETURN; } kshname = old_kshname; change_xtrace(old_flags[(int)FXTRACE], false); #ifndef MKSH_LEGACY_MODE if (tp->flag & FKSH) { /* Korn style functions restore Flags on return */ old_flags[(int)FXTRACE] = Flag(FXTRACE); for (type_flags = 0; type_flags < FNFLAGS; ++type_flags) shell_flags[type_flags] = old_flags[type_flags]; } #endif tp->flag = (tp->flag & ~FINUSE) | old_inuse; /* * Were we deleted while executing? If so, free the * execution tree. */ if ((tp->flag & (FDELETE|FINUSE)) == FDELETE) { if (tp->flag & ALLOC) { tp->flag &= ~ALLOC; tfree(tp->val.t, tp->areap); } tp->flag = 0; } switch (i) { case LRETURN: case LERROR: rv = exstat & 0xFF; break; case LINTR: case LEXIT: case LLEAVE: case LSHELL: quitenv(NULL); unwind(i); /* NOTREACHED */ default: quitenv(NULL); internal_errorf("%s %d", "CFUNC", i); } break; } /* executable command */ case CEXEC: /* tracked alias */ case CTALIAS: if (!(tp->flag&ISSET)) { if (tp->u2.errnov == ENOENT) { rv = 127; warningf(true, "%s: %s", cp, "not found"); } else { rv = 126; warningf(true, "%s: %s: %s", cp, "can't execute", cstrerror(tp->u2.errnov)); } break; } /* set $_ to program's full path */ /* setstr() can't fail here */ setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0), tp->val.s, KSH_RETURN_ERROR); /* to fork, we set up a TEXEC node and call execute */ texec.type = TEXEC; /* for vistree/dumptree */ texec.left = t; texec.str = tp->val.s; texec.args = ap; /* in this case we do not fork, of course */ if (flags & XEXEC) { if (exec_argv0) texec.args[0] = exec_argv0; j_exit(); if (!(flags & XBGND) #ifndef MKSH_UNEMPLOYED || Flag(FMONITOR) #endif ) { setexecsig(&sigtraps[SIGINT], SS_RESTORE_ORIG); setexecsig(&sigtraps[SIGQUIT], SS_RESTORE_ORIG); } } rv = exchild(&texec, flags, xerrok, -1); break; } Leave: if (flags & XEXEC) { exstat = rv & 0xFF; unwind(LLEAVE); } return (rv); }
static int comexec(struct op *t, struct tbl * volatile tp, const char **ap, volatile int flags, volatile int *xerrok) { int i; volatile int rv = 0; const char *cp; const char **lastp; /* Must be static (XXX but why?) */ static struct op texec; int type_flags; bool keepasn_ok; int fcflags = FC_BI|FC_FUNC|FC_PATH; bool bourne_function_call = false; struct block *l_expand, *l_assign; /* * snag the last argument for $_ XXX not the same as AT&T ksh, * which only seems to set $_ after a newline (but not in * functions/dot scripts, but in interactive and script) - * perhaps save last arg here and set it in shell()?. */ if (Flag(FTALKING) && *(lastp = ap)) { while (*++lastp) ; /* setstr() can't fail here */ setstr(typeset("_", LOCAL, 0, INTEGER, 0), *--lastp, KSH_RETURN_ERROR); } /** * Deal with the shell builtins builtin, exec and command since * they can be followed by other commands. This must be done before * we know if we should create a local block which must be done * before we can do a path search (in case the assignments change * PATH). * Odd cases: * FOO=bar exec >/dev/null FOO is kept but not exported * FOO=bar exec foobar FOO is exported * FOO=bar command exec >/dev/null FOO is neither kept nor exported * FOO=bar command FOO is neither kept nor exported * PATH=... foobar use new PATH in foobar search */ keepasn_ok = true; while (tp && tp->type == CSHELL) { /* undo effects of command */ fcflags = FC_BI|FC_FUNC|FC_PATH; if (tp->val.f == c_builtin) { if ((cp = *++ap) == NULL || (!strcmp(cp, "--") && (cp = *++ap) == NULL)) { tp = NULL; break; } if ((tp = findcom(cp, FC_BI)) == NULL) errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin"); continue; } else if (tp->val.f == c_exec) { if (ap[1] == NULL) break; ap++; flags |= XEXEC; } else if (tp->val.f == c_command) { int optc, saw_p = 0; /* * Ugly dealing with options in two places (here * and in c_command(), but such is life) */ ksh_getopt_reset(&builtin_opt, 0); while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p') saw_p = 1; if (optc != EOF) /* command -vV or something */ break; /* don't look for functions */ fcflags = FC_BI|FC_PATH; if (saw_p) { if (Flag(FRESTRICTED)) { warningf(true, "%s: %s", "command -p", "restricted"); rv = 1; goto Leave; } fcflags |= FC_DEFPATH; } ap += builtin_opt.optind; /* * POSIX says special builtins lose their status * if accessed using command. */ keepasn_ok = false; if (!ap[0]) { /* ensure command with no args exits with 0 */ subst_exstat = 0; break; } #ifndef MKSH_NO_EXTERNAL_CAT } else if (tp->val.f == c_cat) { /* * if we have any flags, do not use the builtin * in theory, we could allow -u, but that would * mean to use ksh_getopt here and possibly ad- * ded complexity and more code and isn't worth * additional hassle (and the builtin must call * ksh_getopt already but can't come back here) */ if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' && /* argument, begins with -, is not - or -- */ (ap[1][1] != '-' || ap[1][2] != '\0')) /* don't look for builtins or functions */ fcflags = FC_PATH; else /* go on, use the builtin */ break; #endif #if !defined(MKSH_SMALL) } else if (tp->val.f == c_trap) { t->u.evalflags &= ~DOTCOMEXEC; break; #endif } else break; tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC)); } #if !defined(MKSH_SMALL) if (t->u.evalflags & DOTCOMEXEC) flags |= XEXEC; #endif l_expand = e->loc; if (keepasn_ok && (!ap[0] || (tp && (tp->flag & KEEPASN)))) type_flags = 0; else { /* create new variable/function block */ newblock(); /* ksh functions don't keep assignments, POSIX functions do. */ if (keepasn_ok && tp && tp->type == CFUNC && !(tp->flag & FKSH)) { bourne_function_call = true; type_flags = EXPORT; } else type_flags = LOCAL|LOCAL_COPY|EXPORT; } l_assign = e->loc; if (Flag(FEXPORT)) type_flags |= EXPORT; for (i = 0; t->vars[i]; i++) { /* do NOT lookup in the new var/fn block just created */ e->loc = l_expand; cp = evalstr(t->vars[i], DOASNTILDE); e->loc = l_assign; /* but assign in there as usual */ if (Flag(FXTRACE)) { if (i == 0) shf_puts(substitute(str_val(global("PS4")), 0), shl_out); shf_fprintf(shl_out, "%s%c", cp, t->vars[i + 1] ? ' ' : '\n'); if (!t->vars[i + 1]) shf_flush(shl_out); } typeset(cp, type_flags, 0, 0, 0); if (bourne_function_call && !(type_flags & EXPORT)) typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0); } if ((cp = *ap) == NULL) { rv = subst_exstat; goto Leave; } else if (!tp) { if (Flag(FRESTRICTED) && vstrchr(cp, '/')) { warningf(true, "%s: %s", cp, "restricted"); rv = 1; goto Leave; } tp = findcom(cp, fcflags); } switch (tp->type) { /* shell built-in */ case CSHELL: rv = call_builtin(tp, (const char **)ap, null); if (!keepasn_ok && tp->val.f == c_shift) { l_expand->argc = l_assign->argc; l_expand->argv = l_assign->argv; } break; /* function call */ case CFUNC: { volatile unsigned char old_xflag; volatile uint32_t old_inuse; const char * volatile old_kshname; if (!(tp->flag & ISSET)) { struct tbl *ftp; if (!tp->u.fpath) { rv = (tp->u2.errnov == ENOENT) ? 127 : 126; warningf(true, "%s: %s %s: %s", cp, "can't find", "function definition file", cstrerror(tp->u2.errnov)); break; } if (include(tp->u.fpath, 0, NULL, false) < 0) { rv = errno; warningf(true, "%s: %s %s %s: %s", cp, "can't open", "function definition file", tp->u.fpath, cstrerror(rv)); rv = 127; break; } if (!(ftp = findfunc(cp, hash(cp), false)) || !(ftp->flag & ISSET)) { warningf(true, "%s: %s %s", cp, "function not defined by", tp->u.fpath); rv = 127; break; } tp = ftp; } /* * ksh functions set $0 to function name, POSIX * functions leave $0 unchanged. */ old_kshname = kshname; if (tp->flag & FKSH) kshname = ap[0]; else ap[0] = kshname; e->loc->argv = ap; for (i = 0; *ap++ != NULL; i++) ; e->loc->argc = i - 1; /* * ksh-style functions handle getopts sanely, * Bourne/POSIX functions are insane... */ if (tp->flag & FKSH) { e->loc->flags |= BF_DOGETOPTS; e->loc->getopts_state = user_opt; getopts_reset(1); } old_xflag = Flag(FXTRACE); Flag(FXTRACE) |= tp->flag & TRACE ? 1 : 0; old_inuse = tp->flag & FINUSE; tp->flag |= FINUSE; e->type = E_FUNC; if (!(i = kshsetjmp(e->jbuf))) { execute(tp->val.t, flags & XERROK, NULL); i = LRETURN; } kshname = old_kshname; Flag(FXTRACE) = old_xflag; tp->flag = (tp->flag & ~FINUSE) | old_inuse; /* * Were we deleted while executing? If so, free the * execution tree. TODO: Unfortunately, the table entry * is never re-used until the lookup table is expanded. */ if ((tp->flag & (FDELETE|FINUSE)) == FDELETE) { if (tp->flag & ALLOC) { tp->flag &= ~ALLOC; tfree(tp->val.t, tp->areap); } tp->flag = 0; } switch (i) { case LRETURN: case LERROR: rv = exstat & 0xFF; break; case LINTR: case LEXIT: case LLEAVE: case LSHELL: quitenv(NULL); unwind(i); /* NOTREACHED */ default: quitenv(NULL); internal_errorf("%s %d", "CFUNC", i); } break; } /* executable command */ case CEXEC: /* tracked alias */ case CTALIAS: if (!(tp->flag&ISSET)) { if (tp->u2.errnov == ENOENT) { rv = 127; warningf(true, "%s: %s", cp, "not found"); } else { rv = 126; warningf(true, "%s: %s: %s", cp, "can't execute", cstrerror(tp->u2.errnov)); } break; } /* set $_ to programme's full path */ /* setstr() can't fail here */ setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), tp->val.s, KSH_RETURN_ERROR); if (flags&XEXEC) { j_exit(); if (!(flags&XBGND) #ifndef MKSH_UNEMPLOYED || Flag(FMONITOR) #endif ) { setexecsig(&sigtraps[SIGINT], SS_RESTORE_ORIG); setexecsig(&sigtraps[SIGQUIT], SS_RESTORE_ORIG); } } /* to fork we set up a TEXEC node and call execute */ texec.type = TEXEC; /* for tprint */ texec.left = t; texec.str = tp->val.s; texec.args = ap; rv = exchild(&texec, flags, xerrok, -1); break; } Leave: if (flags & XEXEC) { exstat = rv & 0xFF; unwind(LLEAVE); } return (rv); }
int c_cd(const char **wp) { int optc, rv, phys_path; bool physical = tobool(Flag(FPHYSICAL)); /* was a node from cdpath added in? */ int cdnode; /* show where we went?, error for $PWD */ bool printpath = false, eflag = false; struct tbl *pwd_s, *oldpwd_s; XString xs; char *dir, *allocd = NULL, *tryp, *pwd, *cdpath; while ((optc = ksh_getopt(wp, &builtin_opt, "eLP")) != -1) switch (optc) { case 'e': eflag = true; break; case 'L': physical = false; break; case 'P': physical = true; break; case '?': return (2); } wp += builtin_opt.optind; if (Flag(FRESTRICTED)) { bi_errorf("restricted shell - can't cd"); return (2); } pwd_s = global("PWD"); oldpwd_s = global("OLDPWD"); if (!wp[0]) { /* No arguments - go home */ if ((dir = str_val(global("HOME"))) == null) { bi_errorf("no home directory (HOME not set)"); return (2); } } else if (!wp[1]) { /* One argument: - or dir */ strdupx(allocd, wp[0], ATEMP); if (ksh_isdash((dir = allocd))) { afree(allocd, ATEMP); allocd = NULL; dir = str_val(oldpwd_s); if (dir == null) { bi_errorf("no OLDPWD"); return (2); } printpath = true; } } else if (!wp[2]) { /* Two arguments - substitute arg1 in PWD for arg2 */ size_t ilen, olen, nlen, elen; char *cp; if (!current_wd[0]) { bi_errorf("can't determine current directory"); return (2); } /* * substitute arg1 for arg2 in current path. * if the first substitution fails because the cd fails * we could try to find another substitution. For now * we don't */ if ((cp = strstr(current_wd, wp[0])) == NULL) { bi_errorf("bad substitution"); return (2); } /*- * ilen = part of current_wd before wp[0] * elen = part of current_wd after wp[0] * because current_wd and wp[1] need to be in memory at the * same time beforehand the addition can stay unchecked */ ilen = cp - current_wd; olen = strlen(wp[0]); nlen = strlen(wp[1]); elen = strlen(current_wd + ilen + olen) + 1; dir = allocd = alloc(ilen + nlen + elen, ATEMP); memcpy(dir, current_wd, ilen); memcpy(dir + ilen, wp[1], nlen); memcpy(dir + ilen + nlen, current_wd + ilen + olen, elen); printpath = true; } else { bi_errorf("too many arguments"); return (2); } #ifdef MKSH__NO_PATH_MAX /* only a first guess; make_path will enlarge xs if necessary */ XinitN(xs, 1024, ATEMP); #else XinitN(xs, PATH_MAX, ATEMP); #endif cdpath = str_val(global("CDPATH")); do { cdnode = make_path(current_wd, dir, &cdpath, &xs, &phys_path); if (physical) rv = chdir(tryp = Xstring(xs, xp) + phys_path); else { simplify_path(Xstring(xs, xp)); rv = chdir(tryp = Xstring(xs, xp)); } } while (rv < 0 && cdpath != NULL); if (rv < 0) { if (cdnode) bi_errorf("%s: %s", dir, "bad directory"); else bi_errorf("%s: %s", tryp, cstrerror(errno)); afree(allocd, ATEMP); Xfree(xs, xp); return (2); } rv = 0; /* allocd (above) => dir, which is no longer used */ afree(allocd, ATEMP); allocd = NULL; /* Clear out tracked aliases with relative paths */ flushcom(false); /* * Set OLDPWD (note: unsetting OLDPWD does not disable this * setting in AT&T ksh) */ if (current_wd[0]) /* Ignore failure (happens if readonly or integer) */ setstr(oldpwd_s, current_wd, KSH_RETURN_ERROR); if (!mksh_abspath(Xstring(xs, xp))) { pwd = NULL; } else if (!physical) { goto norealpath_PWD; } else if ((pwd = allocd = do_realpath(Xstring(xs, xp))) == NULL) { if (eflag) rv = 1; norealpath_PWD: pwd = Xstring(xs, xp); } /* Set PWD */ if (pwd) { char *ptmp = pwd; set_current_wd(ptmp); /* Ignore failure (happens if readonly or integer) */ setstr(pwd_s, ptmp, KSH_RETURN_ERROR); } else { set_current_wd(null); pwd = Xstring(xs, xp); /* XXX unset $PWD? */ if (eflag) rv = 1; } if (printpath || cdnode) shprintf("%s\n", pwd); afree(allocd, ATEMP); Xfree(xs, xp); return (rv); }
static void parseArgs (int argc, char * const *argv) { int c, i; args.argc = argc; args.argv = argv; args.progname = basename(*argv); args.verbose = 0; args.daemon = 0; args.allowsleepcommand = setstr(args.allowsleepcommand, NULL); args.cantsleepcommand = setstr(args.cantsleepcommand, NULL); args.sleepcommand = setstr(args.sleepcommand, NULL); args.wakeupcommand = setstr(args.wakeupcommand, NULL); args.displaydimcommand = setstr(args.displaydimcommand, NULL); args.displayundimcommand = setstr(args.displayundimcommand, NULL); args.displaysleepcommand = setstr(args.displaysleepcommand, NULL); args.displaywakeupcommand = setstr(args.displaywakeupcommand, NULL); args.idletimeout = 0; args.idlecommand = setstr(args.idlecommand, NULL); args.idleresume = 0; args.idleresumecommand = setstr(args.idleresumecommand, NULL); args.breaklength = 0; args.resumecommand = setstr(args.resumecommand, NULL); args.plugcommand = setstr(args.plugcommand, NULL); args.unplugcommand = setstr(args.unplugcommand, NULL); writePidFile (NULL); if (argc == 1) usage (); optreset = optind = 1; while ((c = getopt_long(argc, argv, GETOPT_STRING, longopts, &i)) != -1) setOption (c, optarg); if (argc != optind) message (LOG_ERR, "superfluous arguments ignored: \"%s ...\"\n", argv[optind]); checkTimeoutCommand (&args.idletimeout, &args.idlecommand, "idlecommand without timeout ignored\n", "timeout without idlecommand ignored\n"); checkTimeoutCommand (&args.breaklength, &args.resumecommand, "resumecommand without break ignored\n", "break without resumecommand ignored\n"); if (! args.idlecommand && args.idleresumecommand) message (LOG_ERR, "idleresumecommand without idlecommand ignored\n"); if (! args.allowsleepcommand && ! args.cantsleepcommand && ! args.sleepcommand && ! args.wakeupcommand && ! args.displaydimcommand && ! args.displayundimcommand && ! args.displaysleepcommand && ! args.displaywakeupcommand && ! args.idlecommand && ! args.resumecommand && ! args.plugcommand && ! args.unplugcommand) message (LOG_ERR, "no useful options set\n"); }
/* search for variable; if not found, return NULL or create globally */ struct tbl * isglobal(const char *n, bool docreate) { struct tbl *vp; union mksh_cchack vname; struct block *l = e->loc; int c; bool array; uint32_t h, val; /* * check to see if this is an array; * dereference namerefs; must come first */ vn = array_index_calc(n, &array, &val); h = hash(vn); c = (unsigned char)vn[0]; if (!ctype(c, C_ALPHX)) { if (array) errorf(Tbadsubst); vp = vtemp; vp->flag = DEFINED; vp->type = 0; vp->areap = ATEMP; if (ctype(c, C_DIGIT)) { if (getn(vn, &c)) { /* main.c:main_init() says 12 */ shf_snprintf(vp->name, 12, Tf_d, c); if (c <= l->argc) { /* setstr can't fail here */ setstr(vp, l->argv[c], KSH_RETURN_ERROR); } } else vp->name[0] = '\0'; vp->flag |= RDONLY; goto out; } vp->name[0] = c; vp->name[1] = '\0'; vp->flag |= RDONLY; if (vn[1] != '\0') goto out; vp->flag |= ISSET|INTEGER; switch (c) { case '$': vp->val.i = kshpid; break; case '!': /* if no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; case '?': vp->val.i = exstat & 0xFF; break; case '#': vp->val.i = l->argc; break; case '-': vp->flag &= ~INTEGER; vp->val.s = getoptions(); break; default: vp->flag &= ~(ISSET|INTEGER); } goto out; } l = varsearch(e->loc, &vp, vn, h); if (vp == NULL && docreate) vp = ktenter(&l->vars, vn, h); else docreate = false; if (vp != NULL) { if (array) vp = arraysearch(vp, val); if (docreate) { vp->flag |= DEFINED; if (special(vn)) vp->flag |= SPECIAL; } } out: last_lookup_was_array = array; if (vn != n) afree(vname.rw, ATEMP); return (vp); }
static void getspec(struct tbl *vp) { mksh_ari_u num; int st; struct timeval tv; switch ((st = special(vp->name))) { case V_COLUMNS: case V_LINES: /* * Do NOT export COLUMNS/LINES. Many applications * check COLUMNS/LINES before checking ws.ws_col/row, * so if the app is started with C/L in the environ * and the window is then resized, the app won't * see the change cause the environ doesn't change. */ if (got_winch) change_winsz(); break; } switch (st) { case V_BASHPID: num.u = (mksh_uari_t)procpid; break; case V_COLUMNS: num.i = x_cols; break; case V_HISTSIZE: num.i = histsize; break; case V_LINENO: num.u = (mksh_uari_t)current_lineno + user_lineno; break; case V_LINES: num.i = x_lins; break; case V_EPOCHREALTIME: { /* 10(%u) + 1(.) + 6 + NUL */ char buf[18]; vp->flag &= ~SPECIAL; mksh_TIME(tv); shf_snprintf(buf, sizeof(buf), "%u.%06u", (unsigned)tv.tv_sec, (unsigned)tv.tv_usec); setstr(vp, buf, KSH_RETURN_ERROR | 0x4); vp->flag |= SPECIAL; return; } case V_OPTIND: num.i = user_opt.uoptind; break; case V_RANDOM: num.i = rndget(); break; case V_SECONDS: /* * On start up the value of SECONDS is used before * it has been set - don't do anything in this case * (see initcoms[] in main.c). */ if (vp->flag & ISSET) { mksh_TIME(tv); num.i = tv.tv_sec - seconds; } else return; break; default: /* do nothing, do not touch vp at all */ return; } vp->flag &= ~SPECIAL; setint_n(vp, num.i, 0); vp->flag |= SPECIAL; }
int keyring_lookup(const char *id, char **username, char **password, char **domain, int *remember_me, const char *source, const char *reason, int flags) { htsmsg_t *m; rstr_t *r; int remember = !!(flags & KEYRING_REMEMBER_ME_SET); hts_mutex_lock(&keyring_mutex); if(flags & KEYRING_QUERY_USER) { htsmsg_t *parent; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "auth"); prop_set_string(prop_create(p, "id"), id); prop_set_string(prop_create(p, "source"), source); prop_set_string(prop_create(p, "reason"), reason); prop_set_int(prop_create(p, "disableUsername"), username == NULL); prop_set_int(prop_create(p, "canRemember"), !!(flags & KEYRING_SHOW_REMEMBER_ME)); prop_t *rememberMe = prop_create(p, "rememberMe"); prop_set_int(rememberMe, remember); prop_sub_t *remember_sub = prop_subscribe(0, PROP_TAG_CALLBACK_INT, set_remember, &remember, PROP_TAG_ROOT, rememberMe, NULL); prop_t *user = prop_create(p, "username"); prop_t *pass = prop_create(p, "password"); TRACE(TRACE_INFO, "keyring", "Requesting credentials for %s : %s : %s", id, source, reason); event_t *e = popup_display(p); prop_unsubscribe(remember_sub); if(flags & KEYRING_ONE_SHOT) parent = NULL; else if(remember) parent = persistent_keyring; else parent = temporary_keyring; if(parent != NULL) htsmsg_delete_field(parent, id); if(event_is_action(e, ACTION_OK)) { /* OK */ m = htsmsg_create_map(); if(username != NULL) { r = prop_get_string(user); htsmsg_add_str(m, "username", r ? rstr_get(r) : ""); *username = strdup(r ? rstr_get(r) : ""); rstr_release(r); } r = prop_get_string(pass); htsmsg_add_str(m, "password", r ? rstr_get(r) : ""); *password = strdup(r ? rstr_get(r) : ""); rstr_release(r); if(parent != NULL) { htsmsg_add_msg(parent, id, m); if(parent == persistent_keyring) keyring_store(); } } else { /* CANCEL */ if(parent == persistent_keyring) keyring_store(); } if(remember_me != NULL) *remember_me = remember; prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)) { /* return CANCEL to caller */ hts_mutex_unlock(&keyring_mutex); event_release(e); return -1; } event_release(e); } else { if((m = htsmsg_get_map(temporary_keyring, id)) == NULL && (m = htsmsg_get_map(persistent_keyring, id)) == NULL) { hts_mutex_unlock(&keyring_mutex); return 1; } setstr(username, m, "username"); setstr(password, m, "password"); setstr(domain, m, "domain"); } hts_mutex_unlock(&keyring_mutex); return 0; }
int keyring_lookup(const char *id, char **username, char **password, char **domain, int query, const char *source, const char *reason, int force_temporary) { htsmsg_t *m; rstr_t *r; hts_mutex_lock(&keyring_mutex); if(query) { htsmsg_t *parent; prop_t *p = prop_create_root(NULL); prop_set_string(prop_create(p, "type"), "auth"); prop_set_string(prop_create(p, "id"), id); prop_set_string(prop_create(p, "source"), source); prop_set_string(prop_create(p, "reason"), reason); int remember = !force_temporary; prop_set_int(prop_create(p, "canRemember"), remember); prop_t *rememberMe = prop_create(p, "rememberMe"); prop_set_int(rememberMe, remember); prop_sub_t *remember_sub = prop_subscribe(0, PROP_TAG_CALLBACK_INT, set_remember, &remember, PROP_TAG_ROOT, rememberMe, NULL); prop_t *user = prop_create(p, "username"); prop_t *pass = prop_create(p, "password"); TRACE(TRACE_INFO, "keyring", "Requesting credentials for %s : %s : %s", id, source, reason); event_t *e = popup_display(p); prop_unsubscribe(remember_sub); if(remember) parent = persistent_keyring; else parent = temporary_keyring; htsmsg_delete_field(parent, id); if(event_is_action(e, ACTION_OK)) { /* OK */ m = htsmsg_create_map(); r = prop_get_string(user); htsmsg_add_str(m, "username", r ? rstr_get(r) : ""); rstr_release(r); r = prop_get_string(pass); htsmsg_add_str(m, "password", r ? rstr_get(r) : ""); rstr_release(r); htsmsg_add_msg(parent, id, m); if(parent == persistent_keyring) keyring_store(); } else { /* CANCEL, store without adding anything */ keyring_store(); } prop_destroy(p); if(event_is_action(e, ACTION_CANCEL)) { /* return CANCEL to caller */ hts_mutex_unlock(&keyring_mutex); event_release(e); return -1; } event_release(e); } if((m = htsmsg_get_map(temporary_keyring, id)) == NULL && (m = htsmsg_get_map(persistent_keyring, id)) == NULL) { hts_mutex_unlock(&keyring_mutex); return 1; } setstr(username, m, "username"); setstr(password, m, "password"); setstr(domain, m, "domain"); hts_mutex_unlock(&keyring_mutex); return 0; }
void set_val(const std::string& section, const std::string& key, const T& val) { string_appender<> oss; oss << val; setstr(section, key, oss.str()); }
/* * execute command tree */ int execute(struct op * volatile t, /* if XEXEC don't fork */ volatile int flags, volatile int * volatile xerrok) { int i; volatile int rv = 0, dummy = 0; int pv[2]; const char ** volatile ap = NULL; char ** volatile up; const char *s, *ccp; struct ioword **iowp; struct tbl *tp = NULL; char *cp; if (t == NULL) return (0); /* Caller doesn't care if XERROK should propagate. */ if (xerrok == NULL) xerrok = &dummy; if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE) /* run in sub-process */ return (exchild(t, flags & ~XTIME, xerrok, -1)); newenv(E_EXEC); if (trap) runtraps(0); /* we want to run an executable, do some variance checks */ if (t->type == TCOM) { /* check if this is 'var=<<EOF' */ if ( /* we have zero arguments, i.e. no programme to run */ t->args[0] == NULL && /* we have exactly one variable assignment */ t->vars[0] != NULL && t->vars[1] == NULL && /* we have exactly one I/O redirection */ t->ioact != NULL && t->ioact[0] != NULL && t->ioact[1] == NULL && /* of type "here document" (or "here string") */ (t->ioact[0]->flag & IOTYPE) == IOHERE && /* the variable assignment begins with a valid varname */ (ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] && /* and has no right-hand side (i.e. "varname=") */ ccp[0] == CHAR && ccp[1] == '=' && ccp[2] == EOS && /* plus we can have a here document content */ herein(t->ioact[0], &cp) == 0 && cp && *cp) { char *sp = cp, *dp; size_t n = ccp - t->vars[0] + 2, z; /* drop redirection (will be garbage collected) */ t->ioact = NULL; /* set variable to its expanded value */ z = strlen(cp) + 1; if (notoktomul(z, 2) || notoktoadd(z * 2, n)) internal_errorf(Toomem, (unsigned long)-1); dp = alloc(z * 2 + n, ATEMP); memcpy(dp, t->vars[0], n); t->vars[0] = dp; dp += n; while (*sp) { *dp++ = QCHAR; *dp++ = *sp++; } *dp = EOS; /* free the expanded value */ afree(cp, APERM); } /* * Clear subst_exstat before argument expansion. Used by * null commands (see comexec() and c_eval()) and by c_set(). */ subst_exstat = 0; /* for $LINENO */ current_lineno = t->lineno; /* * POSIX says expand command words first, then redirections, * and assignments last.. */ up = eval(t->args, t->u.evalflags | DOBLANK | DOGLOB | DOTILDE); if (flags & XTIME) /* Allow option parsing (bizarre, but POSIX) */ timex_hook(t, &up); ap = (const char **)up; if (Flag(FXTRACE) && ap[0]) { shf_puts(substitute(str_val(global("PS4")), 0), shl_out); for (i = 0; ap[i]; i++) shf_fprintf(shl_out, "%s%c", ap[i], ap[i + 1] ? ' ' : '\n'); shf_flush(shl_out); } if (ap[0]) tp = findcom(ap[0], FC_BI|FC_FUNC); } flags &= ~XTIME; if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) { e->savefd = alloc2(NUFILE, sizeof(short), ATEMP); /* initialise to not redirected */ memset(e->savefd, 0, NUFILE * sizeof(short)); } /* mark for replacement later (unless TPIPE) */ vp_pipest->flag |= INT_L; /* do redirection, to be restored in quitenv() */ if (t->ioact != NULL) for (iowp = t->ioact; *iowp != NULL; iowp++) { if (iosetup(*iowp, tp) < 0) { exstat = rv = 1; /* * Redirection failures for special commands * cause (non-interactive) shell to exit. */ if (tp && tp->type == CSHELL && (tp->flag & SPEC_BI)) errorfz(); /* Deal with FERREXIT, quitenv(), etc. */ goto Break; } } switch (t->type) { case TCOM: rv = comexec(t, tp, (const char **)ap, flags, xerrok); break; case TPAREN: rv = execute(t->left, flags | XFORK, xerrok); break; case TPIPE: flags |= XFORK; flags &= ~XEXEC; e->savefd[0] = savefd(0); e->savefd[1] = savefd(1); while (t->type == TPIPE) { openpipe(pv); /* stdout of curr */ ksh_dup2(pv[1], 1, false); /** * Let exchild() close pv[0] in child * (if this isn't done, commands like * (: ; cat /etc/termcap) | sleep 1 * will hang forever). */ exchild(t->left, flags | XPIPEO | XCCLOSE, NULL, pv[0]); /* stdin of next */ ksh_dup2(pv[0], 0, false); closepipe(pv); flags |= XPIPEI; t = t->right; } /* stdout of last */ restfd(1, e->savefd[1]); /* no need to re-restore this */ e->savefd[1] = 0; /* Let exchild() close 0 in parent, after fork, before wait */ i = exchild(t, flags | XPCLOSE | XPIPEST, xerrok, 0); if (!(flags&XBGND) && !(flags&XXCOM)) rv = i; break; case TLIST: while (t->type == TLIST) { execute(t->left, flags & XERROK, NULL); t = t->right; } rv = execute(t, flags & XERROK, xerrok); break; case TCOPROC: { #ifndef MKSH_NOPROSPECTOFWORK sigset_t omask; /* * Block sigchild as we are using things changed in the * signal handler */ sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); e->type = E_ERRH; if ((i = kshsetjmp(e->jbuf))) { sigprocmask(SIG_SETMASK, &omask, NULL); quitenv(NULL); unwind(i); /* NOTREACHED */ } #endif /* Already have a (live) co-process? */ if (coproc.job && coproc.write >= 0) errorf("coprocess already exists"); /* Can we re-use the existing co-process pipe? */ coproc_cleanup(true); /* do this before opening pipes, in case these fail */ e->savefd[0] = savefd(0); e->savefd[1] = savefd(1); openpipe(pv); if (pv[0] != 0) { ksh_dup2(pv[0], 0, false); close(pv[0]); } coproc.write = pv[1]; coproc.job = NULL; if (coproc.readw >= 0) ksh_dup2(coproc.readw, 1, false); else { openpipe(pv); coproc.read = pv[0]; ksh_dup2(pv[1], 1, false); /* closed before first read */ coproc.readw = pv[1]; coproc.njobs = 0; /* create new coprocess id */ ++coproc.id; } #ifndef MKSH_NOPROSPECTOFWORK sigprocmask(SIG_SETMASK, &omask, NULL); /* no more need for error handler */ e->type = E_EXEC; #endif /* * exchild() closes coproc.* in child after fork, * will also increment coproc.njobs when the * job is actually created. */ flags &= ~XEXEC; exchild(t->left, flags | XBGND | XFORK | XCOPROC | XCCLOSE, NULL, coproc.readw); break; } case TASYNC: /* * XXX non-optimal, I think - "(foo &)", forks for (), * forks again for async... parent should optimise * this to "foo &"... */ rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK, xerrok); break; case TOR: case TAND: rv = execute(t->left, XERROK, xerrok); if ((rv == 0) == (t->type == TAND)) rv = execute(t->right, XERROK, xerrok); flags |= XERROK; if (xerrok) *xerrok = 1; break; case TBANG: rv = !execute(t->right, XERROK, xerrok); flags |= XERROK; if (xerrok) *xerrok = 1; break; case TDBRACKET: { Test_env te; te.flags = TEF_DBRACKET; te.pos.wp = t->args; te.isa = dbteste_isa; te.getopnd = dbteste_getopnd; te.eval = test_eval; te.error = dbteste_error; rv = test_parse(&te); break; } case TFOR: case TSELECT: { volatile bool is_first = true; ap = (t->vars == NULL) ? e->loc->argv + 1 : (const char **)eval((const char **)t->vars, DOBLANK | DOGLOB | DOTILDE); e->type = E_LOOP; while ((i = kshsetjmp(e->jbuf))) { if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { quitenv(NULL); unwind(i); } else if (i == LBREAK) { rv = 0; goto Break; } } /* in case of a continue */ rv = 0; if (t->type == TFOR) { while (*ap != NULL) { setstr(global(t->str), *ap++, KSH_UNWIND_ERROR); rv = execute(t->left, flags & XERROK, xerrok); } } else { /* TSELECT */ for (;;) { if (!(ccp = do_selectargs(ap, is_first))) { rv = 1; break; } is_first = false; setstr(global(t->str), ccp, KSH_UNWIND_ERROR); execute(t->left, flags & XERROK, xerrok); } } break; } case TWHILE: case TUNTIL: e->type = E_LOOP; while ((i = kshsetjmp(e->jbuf))) { if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { quitenv(NULL); unwind(i); } else if (i == LBREAK) { rv = 0; goto Break; } } /* in case of a continue */ rv = 0; while ((execute(t->left, XERROK, NULL) == 0) == (t->type == TWHILE)) rv = execute(t->right, flags & XERROK, xerrok); break; case TIF: case TELIF: if (t->right == NULL) /* should be error */ break; rv = execute(t->left, XERROK, NULL) == 0 ? execute(t->right->left, flags & XERROK, xerrok) : execute(t->right->right, flags & XERROK, xerrok); break; case TCASE: i = 0; ccp = evalstr(t->str, DOTILDE); for (t = t->left; t != NULL && t->type == TPAT; t = t->right) { for (ap = (const char **)t->vars; *ap; ap++) { if (i || ((s = evalstr(*ap, DOTILDE|DOPAT)) && gmatchx(ccp, s, false))) { rv = execute(t->left, flags & XERROK, xerrok); i = 0; switch (t->u.charflag) { case '&': i = 1; /* FALLTHROUGH */ case '|': goto TCASE_next; } goto TCASE_out; } } i = 0; TCASE_next: /* empty */; } TCASE_out: break; case TBRACE: rv = execute(t->left, flags & XERROK, xerrok); break; case TFUNCT: rv = define(t->str, t); break; case TTIME: /* * Clear XEXEC so nested execute() call doesn't exit * (allows "ls -l | time grep foo"). */ rv = timex(t, flags & ~XEXEC, xerrok); break; case TEXEC: /* an eval'd TCOM */ s = t->args[0]; up = makenv(); restoresigs(); cleanup_proc_env(); { union mksh_ccphack cargs; cargs.ro = t->args; execve(t->str, cargs.rw, up); rv = errno; } if (rv == ENOEXEC) scriptexec(t, (const char **)up); else errorf("%s: %s", s, cstrerror(rv)); } Break: exstat = rv & 0xFF; if (vp_pipest->flag & INT_L) { unset(vp_pipest, 1); vp_pipest->flag = DEFINED | ISSET | INTEGER | RDONLY | ARRAY | INT_U; vp_pipest->val.i = rv; } /* restores IO */ quitenv(NULL); if ((flags&XEXEC)) /* exit child */ unwind(LEXIT); if (rv != 0 && !(flags & XERROK) && (xerrok == NULL || !*xerrok)) { if (Flag(FERREXIT) & 0x80) { /* inside eval */ Flag(FERREXIT) = 0; } else { trapsig(ksh_SIGERR); if (Flag(FERREXIT)) unwind(LERROR); } } return (rv); }
/* * Search for variable, if not found create globally. */ struct tbl * global(const char *n) { struct block *l = e->loc; struct tbl *vp; int c; unsigned int h; bool array; int val; /* Check to see if this is an array */ n = array_index_calc(n, &array, &val); h = hash(n); c = n[0]; if (!letter(c)) { if (array) errorf("bad substitution"); vp = &vtemp; vp->flag = DEFINED; vp->type = 0; vp->areap = ATEMP; *vp->name = c; if (digit(c)) { for (c = 0; digit(*n); n++) c = c*10 + *n-'0'; if (c <= l->argc) /* setstr can't fail here */ setstr(vp, l->argv[c], KSH_RETURN_ERROR); vp->flag |= RDONLY; return vp; } vp->flag |= RDONLY; if (n[1] != '\0') return vp; vp->flag |= ISSET|INTEGER; switch (c) { case '$': vp->val.i = kshpid; break; case '!': /* If no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; case '?': vp->val.i = exstat; break; case '#': vp->val.i = l->argc; break; case '-': vp->flag &= ~INTEGER; vp->val.s = getoptions(); break; default: vp->flag &= ~(ISSET|INTEGER); } return vp; } for (l = e->loc; ; l = l->next) { vp = ktsearch(&l->vars, n, h); if (vp != NULL) { if (array) return arraysearch(vp, val); else return vp; } if (l->next == NULL) break; } vp = ktenter(&l->vars, n, h); if (array) vp = arraysearch(vp, val); vp->flag |= DEFINED; if (special(n)) vp->flag |= SPECIAL; return vp; }
/* * Search for variable, if not found create globally. */ struct tbl * global(const char *n) { struct block *l = e->loc; struct tbl *vp; int c; bool array; uint32_t h, val; /* * check to see if this is an array; * dereference namerefs; must come first */ n = array_index_calc(n, &array, &val); h = hash(n); c = (unsigned char)n[0]; if (!ksh_isalphx(c)) { if (array) errorf("bad substitution"); vp = &vtemp; vp->flag = DEFINED; vp->type = 0; vp->areap = ATEMP; *vp->name = c; if (ksh_isdigit(c)) { if (getn(n, &c) && (c <= l->argc)) /* setstr can't fail here */ setstr(vp, l->argv[c], KSH_RETURN_ERROR); vp->flag |= RDONLY; return (vp); } vp->flag |= RDONLY; if (n[1] != '\0') return (vp); vp->flag |= ISSET|INTEGER; switch (c) { case '$': vp->val.i = kshpid; break; case '!': /* if no job, expand to nothing */ if ((vp->val.i = j_async()) == 0) vp->flag &= ~(ISSET|INTEGER); break; case '?': vp->val.i = exstat & 0xFF; break; case '#': vp->val.i = l->argc; break; case '-': vp->flag &= ~INTEGER; vp->val.s = getoptions(); break; default: vp->flag &= ~(ISSET|INTEGER); } return (vp); } l = varsearch(e->loc, &vp, n, h); if (vp != NULL) return (array ? arraysearch(vp, val) : vp); vp = ktenter(&l->vars, n, h); if (array) vp = arraysearch(vp, val); vp->flag |= DEFINED; if (special(n)) vp->flag |= SPECIAL; return (vp); }
/** * main: * @argc: Number of arguments given to program * @argv: Arguments given to program * * Returns: Return code * * Main entry point */ int main (int argc, char *argv[]) { int ret; DBusError error; char buf[512]; char *nbuf; int dmipipe[2]; int nullfd; FILE *f; int dmiparser_state = DMIPARSER_STATE_IGNORE; /* on some system chassis pops up several times, * so only take the first entry for each */ int dmiparser_done_bios = FALSE; int dmiparser_done_system = FALSE; int dmiparser_done_chassis = FALSE; uint i; struct stat s; const char *path = NULL; const char *possible_paths[] = { "/usr/sbin/dmidecode", "/bin/dmidecode", "/sbin/dmidecode", "/usr/local/sbin/dmidecode", }; /* assume failure */ ret = 1; setup_logger (); dbus_error_init (&error); udi = getenv ("UDI"); if (udi == NULL) { HAL_ERROR (("UDI not set")); goto out; } if ((ctx = libhal_ctx_init_direct (&error)) == NULL) { HAL_ERROR (("ctx init failed")); goto out; } /* find the path to dmidecode */ for (i = 0; i < sizeof (possible_paths) / sizeof (char *); i++) { if (stat (possible_paths[i], &s) == 0 && S_ISREG (s.st_mode)) { path = possible_paths[i]; break; } } if (path == NULL) { HAL_ERROR(("Could not find dmidecode, exit!")); exit(1); } if(pipe (dmipipe) == -1) { HAL_ERROR(("Could not create pipe (error: '%s'), exit!", strerror(errno))); exit(1); } if ((f = fdopen (dmipipe[0], "r")) == NULL) { HAL_ERROR(("Could not open file (error: '%s'), exit!", strerror(errno))); exit(1); } if ((nullfd = open ("/dev/null", O_RDONLY)) == -1){ HAL_ERROR(("Could not open /dev/null (error: '%s'), exit!", strerror(errno))); exit(1); } /* fork the child process */ switch (fork ()) { case 0: /* child */ dup2 (nullfd, STDIN_FILENO); dup2 (dmipipe[1], STDOUT_FILENO); close (dmipipe[0]); close (dmipipe[1]); /* execute the child */ execl (path, path, NULL); /* throw an error if we ever reach this point */ HAL_ERROR (("Failed to execute dmidecode!")); exit (1); break; case -1: HAL_ERROR (("Cannot fork!")); goto out; } /* parent continues from here */ /* close unused descriptor */ close (dmipipe[1]); /* read the output of the child */ while(fgets (buf, sizeof(buf), f) != NULL) { int j; unsigned int len; unsigned int tabs = 0; /* trim whitespace */ len = strlen (buf); /* check that will fit in buffer */ if (len >= sizeof (buf)) continue; /* not big enough for data, and protects us from underflow */ if (len < 3) { dmiparser_state = DMIPARSER_STATE_IGNORE; continue; } /* find out number of leading tabs */ if (buf[0] == '\t' && buf[1] == '\t') tabs = 2; /* this is list data */ else if (buf[0] == '\t') tabs = 1; /* this is data, 0 is section type */ if (tabs == 2) /* we do not proccess data at depth 2 */ continue; /* set the section type */ if (tabs == 0) { if (!dmiparser_done_bios && strbegin (buf, "BIOS Information")) dmiparser_state = DMIPARSER_STATE_BIOS; else if (!dmiparser_done_system && strbegin (buf, "System Information")) dmiparser_state = DMIPARSER_STATE_SYSTEM; else if (!dmiparser_done_chassis && strbegin (buf, "Chassis Information")) dmiparser_state = DMIPARSER_STATE_CHASSIS; else if (!dmiparser_done_chassis && strbegin (buf, "Base Board Information")) dmiparser_state = DMIPARSER_STATE_BOARD; else /* * We do not match the other sections, * or sections we have processed before */ dmiparser_state = DMIPARSER_STATE_IGNORE; continue; /* next line */ } /* we are not in a section we know, no point continueing */ if (dmiparser_state == DMIPARSER_STATE_IGNORE) continue; /* return success only if there was something usefull to parse */ ret = 0; /* removes the leading tab */ nbuf = &buf[1]; /* removes the trailing spaces */ for (j = len - 2; isspace (nbuf[j]) && j >= 0; --j) nbuf[j] = '\0'; if (dmiparser_state == DMIPARSER_STATE_BIOS) { setstr (nbuf, "Vendor:", "system.firmware.vendor"); setstr (nbuf, "Version:", "system.firmware.version"); setstr (nbuf, "Release Date:", "system.firmware.release_date"); dmiparser_done_bios = TRUE; } else if (dmiparser_state == DMIPARSER_STATE_SYSTEM) { setstr (nbuf, "Manufacturer:", "system.hardware.vendor"); setstr (nbuf, "Product Name:", "system.hardware.product"); setstr (nbuf, "Version:", "system.hardware.version"); setstr (nbuf, "Serial Number:", "system.hardware.serial"); setstr (nbuf, "UUID:", "system.hardware.uuid"); dmiparser_done_system = TRUE; } else if (dmiparser_state == DMIPARSER_STATE_CHASSIS) { setstr (nbuf, "Manufacturer:", "system.chassis.manufacturer"); setstr (nbuf, "Type:", "system.chassis.type"); dmiparser_done_chassis = TRUE; } else if (dmiparser_state == DMIPARSER_STATE_BOARD) { setstr (nbuf, "Manufacturer:", "system.board.vendor"); setstr (nbuf, "Product Name:", "system.board.product"); setstr (nbuf, "Version:", "system.board.version"); setstr (nbuf, "Serial Number:", "system.board.serial"); dmiparser_done_system = TRUE; } } /* as read to EOF, close */ fclose (f); out: LIBHAL_FREE_DBUS_ERROR (&error); /* free ctx */ if (ctx != NULL) { libhal_ctx_shutdown (ctx, &error); LIBHAL_FREE_DBUS_ERROR (&error); libhal_ctx_free (ctx); } return ret; }
void DataFeed::parse ( char *dataFeedPage, long dataFeedPageLen ) { // use Xml Class to parse up the page Xml xml; xml.set ( csUTF8, dataFeedPage, dataFeedPageLen, false, 0, false, TITLEREC_CURRENT_VERSION ); // get the nodes long numNodes = xml.getNumNodes(); XmlNode *nodes = xml.getNodes(); // to count the tiers, result levels, and level costs long currTier = 0; long currResultLevel = 0; long currLevelCost = 0; // pull out the keywords for the data feed for (long i = 0; i < numNodes; i++) { // skip if this isn't a meta tag, shouldn't happen if (nodes[i].m_nodeId != 68) continue; // get the meta tag name //long tagLen; //char *tag = xml.getString(i, "name", &tagLen); long ucTagLen; char *ucTag = xml.getString(i, "name", &ucTagLen); char tag[256]; long tagLen = utf16ToLatin1 ( tag, 256, (UChar*)ucTag, ucTagLen>>1 ); // skip if empty if (!tag || tagLen <= 0) continue; // get the content long ucConLen; char *ucCon = xml.getString(i, "content", &ucConLen); char con[1024]; long conLen = utf16ToLatin1 ( con, 1024, (UChar*)ucCon, ucConLen>>1 ); if (!con || conLen <= 0) continue; // match the meta tag to its local var and copy content if (tagLen == 10 && strncasecmp(tag, "customerid", 10) == 0) m_customerId = atoll(con); else if (tagLen == 11 && strncasecmp(tag, "datafeedurl", 11) == 0) setUrl(con, conLen); else if (tagLen == 8 && strncasecmp(tag, "passcode", 8) == 0) m_passcodeLen = setstr(m_passcode, MAX_PASSCODELEN, con, conLen); else if (tagLen == 6 && strncasecmp(tag, "status", 6) == 0) m_isActive = (bool)atoi(con); else if (tagLen == 6 && strncasecmp(tag, "locked", 6) == 0) m_isLocked = (bool)atoi(con); else if (tagLen == 14 && strncasecmp(tag, "dfcreationtime", 14) == 0) m_creationTime = atol(con); else if (tagLen == 8 && strncasecmp(tag, "numtiers", 8) == 0) m_priceTable.m_numTiers = atol(con); else if (tagLen == 15 && strncasecmp(tag, "numresultlevels", 15) == 0) m_priceTable.m_numResultLevels = atol(con); else if (tagLen == 10 && strncasecmp(tag, "monthlyfee", 10) == 0) m_priceTable.m_monthlyFee = atol(con); else if (tagLen == 7 && strncasecmp(tag, "tiermax", 7) == 0) { m_priceTable.m_tierMax[currTier] = (unsigned long)atol(con); currTier++; } else if (tagLen == 11 && strncasecmp(tag, "resultlevel", 11) == 0) { m_priceTable.m_resultLevels[currResultLevel] = (unsigned long)atol(con); currResultLevel++; } else if (tagLen == 9 && strncasecmp(tag, "levelcost", 9) == 0) { m_priceTable.m_levelCosts[currLevelCost] = (unsigned long)atol(con); currLevelCost++; } else log(LOG_INFO, "datafeed: Invalid Meta Tag Parsed [%li]:" " %s", tagLen, tag); } }
/* * lookup variable (according to (set&LOCAL)), set its attributes * (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, LCASEV, * UCASEV_AL), and optionally set its value if an assignment. */ struct tbl * typeset(const char *var, uint32_t set, uint32_t clr, int field, int base) { struct tbl *vp; struct tbl *vpbase, *t; char *tvar; const char *val; size_t len; bool vappend = false; enum namerefflag new_refflag = SRF_NOP; if ((set & (ARRAY | ASSOC)) == ASSOC) { new_refflag = SRF_ENABLE; set &= ~(ARRAY | ASSOC); } if ((clr & (ARRAY | ASSOC)) == ASSOC) { new_refflag = SRF_DISABLE; clr &= ~(ARRAY | ASSOC); } /* check for valid variable name, search for value */ val = skip_varname(var, false); if (val == var) { /* no variable name given */ return (NULL); } if (*val == '[') { if (new_refflag != SRF_NOP) errorf("%s: %s", var, "reference variable can't be an array"); len = array_ref_len(val); if (len == 0) return (NULL); /* * IMPORT is only used when the shell starts up and is * setting up its environment. Allow only simple array * references at this time since parameter/command * substitution is performed on the [expression] which * would be a major security hole. */ if (set & IMPORT) { size_t i; for (i = 1; i < len - 1; i++) if (!ksh_isdigit(val[i])) return (NULL); } val += len; } if (val[0] == '=') { strndupx(tvar, var, val - var, ATEMP); ++val; } else if (set & IMPORT) { /* environment invalid variable name or no assignment */ return (NULL); } else if (val[0] == '+' && val[1] == '=') { strndupx(tvar, var, val - var, ATEMP); val += 2; vappend = true; } else if (val[0] != '\0') { /* other invalid variable names (not from environment) */ return (NULL); } else { /* just varname with no value part nor equals sign */ strdupx(tvar, var, ATEMP); val = NULL; /* handle foo[*] => foo (whole array) mapping for R39b */ len = strlen(tvar); if (len > 3 && tvar[len - 3] == '[' && tvar[len - 2] == '*' && tvar[len - 1] == ']') tvar[len - 3] = '\0'; } if (new_refflag == SRF_ENABLE) { const char *qval, *ccp; /* bail out on 'nameref foo+=bar' */ if (vappend) errorf("appending not allowed for nameref"); /* find value if variable already exists */ if ((qval = val) == NULL) { varsearch(e->loc, &vp, tvar, hash(tvar)); if (vp == NULL) goto nameref_empty; qval = str_val(vp); } /* check target value for being a valid variable name */ ccp = skip_varname(qval, false); if (ccp == qval) { if (ksh_isdigit(qval[0])) { int c; if (getn(qval, &c)) goto nameref_rhs_checked; } else if (qval[1] == '\0') switch (qval[0]) { case '$': case '!': case '?': case '#': case '-': goto nameref_rhs_checked; } nameref_empty: errorf("%s: %s", var, "empty nameref target"); } len = (*ccp == '[') ? array_ref_len(ccp) : 0; if (ccp[len]) { /* * works for cases "no array", "valid array with * junk after it" and "invalid array"; in the * latter case, len is also 0 and points to '[' */ errorf("%s: %s", qval, "nameref target not a valid parameter name"); } nameref_rhs_checked: /* prevent nameref loops */ while (qval) { if (!strcmp(qval, tvar)) errorf("%s: %s", qval, "expression recurses on parameter"); varsearch(e->loc, &vp, qval, hash(qval)); qval = NULL; if (vp && ((vp->flag & (ARRAY | ASSOC)) == ASSOC)) qval = str_val(vp); } } /* prevent typeset from creating a local PATH/ENV/SHELL */ if (Flag(FRESTRICTED) && (strcmp(tvar, "PATH") == 0 || strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0)) errorf("%s: %s", tvar, "restricted"); innermost_refflag = new_refflag; vp = (set & LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) : global(tvar); if (new_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC) vp->flag &= ~ASSOC; else if (new_refflag == SRF_ENABLE) { if (vp->flag & ARRAY) { struct tbl *a, *tmp; /* free up entire array */ for (a = vp->u.array; a; ) { tmp = a; a = a->u.array; if (tmp->flag & ALLOC) afree(tmp->val.s, tmp->areap); afree(tmp, tmp->areap); } vp->u.array = NULL; vp->flag &= ~ARRAY; } vp->flag |= ASSOC; } set &= ~(LOCAL|LOCAL_COPY); vpbase = (vp->flag & ARRAY) ? global(arrayname(tvar)) : vp; /* * only allow export flag to be set; AT&T ksh allows any * attribute to be changed which means it can be truncated or * modified (-L/-R/-Z/-i) */ if ((vpbase->flag & RDONLY) && (val || clr || (set & ~EXPORT))) /* XXX check calls - is error here ok by POSIX? */ errorfx(2, "read-only: %s", tvar); afree(tvar, ATEMP); /* most calls are with set/clr == 0 */ if (set | clr) { bool ok = true; /* * XXX if x[0] isn't set, there will be problems: need * to have one copy of attributes for arrays... */ for (t = vpbase; t; t = t->u.array) { bool fake_assign; char *s = NULL; char *free_me = NULL; fake_assign = (t->flag & ISSET) && (!val || t != vp) && ((set & (UCASEV_AL|LCASEV|LJUST|RJUST|ZEROFIL)) || ((t->flag & INTEGER) && (clr & INTEGER)) || (!(t->flag & INTEGER) && (set & INTEGER))); if (fake_assign) { if (t->flag & INTEGER) { s = str_val(t); free_me = NULL; } else { s = t->val.s + t->type; free_me = (t->flag & ALLOC) ? t->val.s : NULL; } t->flag &= ~ALLOC; } if (!(t->flag & INTEGER) && (set & INTEGER)) { t->type = 0; t->flag &= ~ALLOC; } t->flag = (t->flag | set) & ~clr; /* * Don't change base if assignment is to be * done, in case assignment fails. */ if ((set & INTEGER) && base > 0 && (!val || t != vp)) t->type = base; if (set & (LJUST|RJUST|ZEROFIL)) t->u2.field = field; if (fake_assign) { if (!setstr(t, s, KSH_RETURN_ERROR)) { /* * Somewhat arbitrary action * here: zap contents of * variable, but keep the flag * settings. */ ok = false; if (t->flag & INTEGER) t->flag &= ~ISSET; else { if (t->flag & ALLOC) afree(t->val.s, t->areap); t->flag &= ~(ISSET|ALLOC); t->type = 0; } } if (free_me) afree(free_me, t->areap); } } if (!ok) errorfz(); } if (val != NULL) { char *tval; if (vappend) { tval = shf_smprintf("%s%s", str_val(vp), val); val = tval; } else tval = NULL; if (vp->flag&INTEGER) { /* do not zero base before assignment */ setstr(vp, val, KSH_UNWIND_ERROR | 0x4); /* done after assignment to override default */ if (base > 0) vp->type = base; } else /* setstr can't fail (readonly check already done) */ setstr(vp, val, KSH_RETURN_ERROR | 0x4); if (tval != NULL) afree(tval, ATEMP); } /* only x[0] is ever exported, so use vpbase */ if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) && vpbase->type == 0) exportprep(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null); return (vp); }