Esempio n. 1
0
int
path_absolute(const char* path, stralloc* sa) {
  int ret = 0;
  stralloc_zero(sa);

  if(!path_isabs(path)) {
    path_getcwd(sa);
    stralloc_catc(sa, PATHSEP_C);
    stralloc_cats(sa, path);
    return 1;
  }

  stralloc_copys(sa, path);
  return 0;
}
Esempio n. 2
0
int parse_subst(struct parser *p) {
  char c;
  
  if(source_next(&c) <= 0)
    return -1;
  
  if(c == '(') {
    return parse_bquoted(p);
  } else if(parse_isparam(c) || c == '{') {
    return parse_param(p);
  }
  
  stralloc_catc(&p->sa, '$');
  return 0;
}
Esempio n. 3
0
/* set a variable value
 * ----------------------------------------------------------------------- */
const char *var_setvint(const char *v, int i, int flags) {
  struct var *var;

  var = var_create(v, flags);
  
  var->flags |= flags;

  if(var->sa.a == 0)
    var->sa.s = NULL;
  
  stralloc_copyb(&var->sa, v, var->len);
  stralloc_catc(&var->sa, '=');
  stralloc_catlong(&var->sa, i);
  stralloc_nul(&var->sa);
  var->offset = var->len + 1;
  return var->sa.s;
}
Esempio n. 4
0
int
list_dir_internal(stralloc* dir, char type) {
  size_t l;
  struct dir_s d;
  stralloc pre;
  int dtype;
  int is_dir, is_symlink;
  size_t len;
#if !WINDOWS_NATIVE
  struct stat st;
  static dev_t root_dev;
#endif
  char *name, *s;
  (void)type;
  while(dir->len > 1 && IS_DIRSEP(dir->s[dir->len - 1])) dir->len--;
  stralloc_nul(dir);
#if !WINDOWS_NATIVE
  if(root_dev == 0) {
    if(stat(dir->s, &st) != -1) {
      root_dev = st.st_dev;
    }
  }
#endif
  if(dir_open(&d, dir->s) != 0) {
    buffer_puts(buffer_2, "ERROR: Opening directory ");
    buffer_putsa(buffer_2, dir);
    buffer_puts(buffer_2, " failed!\n");
    buffer_flush(buffer_2);
    goto end;
  }
  if(dir->s[dir->len - 1] != DIRSEP_C)
    stralloc_cats(dir, DIRSEP_S);
  l = dir->len;
  while((name = dir_read(&d))) {
    unsigned int mode = 0, nlink = 0, uid = 0, gid = 0;
    uint64 size = 0, mtime = 0;
    dtype = dir_type(&d);
    dir->len = l;
    if(str_equal(name, "") || str_equal(name, ".") || str_equal(name, "..")) {
      continue;
    }
    stralloc_readyplus(dir, str_len(name) + 1);
    str_copy(dir->s + dir->len, name);
    dir->len += str_len(name);
    is_symlink = !!(dtype & D_SYMLINK);
#if !WINDOWS_NATIVE
    if(!opt_deref && lstat(dir->s, &st) != -1) {
      if(root_dev && st.st_dev) {
        if(st.st_dev != root_dev) {
          continue;
        }
      }
    }
#endif
#if !WINDOWS_NATIVE
    if(S_ISLNK(st.st_mode)) {
      stat(dir->s, &st);
    }
    mode = st.st_mode;
#endif
    if(dtype) {
      is_dir = !!(dtype & D_DIRECTORY);
    } else {
#if WINDOWS_NATIVE
      is_dir = 0;
#else
      is_dir = !!S_ISDIR(mode);
#endif
    }
    if(dtype & D_SYMLINK)
      is_symlink = 1;
#if !WINDOWS_NATIVE
    nlink = st.st_nlink;
    uid = st.st_uid;
    gid = st.st_gid;
    size = st.st_size;
    mtime = st.st_mtime;
#else
    mode = (is_dir ? 0040000 : 0100000) | (is_symlink ? 0120000 : 0);
#if USE_READDIR
    if(!is_dir) {
      size = dir_size(&d); /* dir_INTERNAL(&d)->dir_entry->d_name); */
      mtime = dir_time(&d);
    } else {
      mtime = 0;
      size = 0;
    }
#else
    size = dir_size(&d);
    mtime = dir_time(&d, D_TIME_MODIFICATION);
#endif
#endif
    if(opt_list && size >= opt_minsize) {
      stralloc_init(&pre);
      /* Mode string */
      mode_str(&pre, mode);
      stralloc_catb(&pre, " ", 1);
      /* num links */
      make_num(&pre, nlink, 3);
      stralloc_catb(&pre, " ", 1);
      /* uid */
      make_num(&pre, uid, 0);
      stralloc_catb(&pre, " ", 1);
      /* gid */
      make_num(&pre, gid, 0);
      stralloc_catb(&pre, " ", 1);
      /* size */
      make_num(&pre, size, 6);
      stralloc_catb(&pre, " ", 1);
      /* time */
      make_num(&pre, mtime, 0);
      /*     make_time(&pre, mtime, 10); */
      stralloc_catb(&pre, " ", 1);
    }
    /* fprintf(stderr, "%d %08x\n", is_dir, dir_ATTRS(&d)); */
    if(is_dir)
      stralloc_catc(dir, opt_separator);
    if(dir->len > MAX_PATH) {
      buffer_puts(buffer_2, "ERROR: Directory ");
      buffer_putsa(buffer_2, dir);
      buffer_puts(buffer_2, " longer than MAX_PATH (" STRINGIFY(MAX_PATH) ")!\n");
      /*buffer_putulong(buffer_2, MAX_PATH);
      buffer_puts(buffer_2, ")!\n");*/
      buffer_flush(buffer_2);
      goto end;
    }
    s = dir->s;
    len = dir->len;
    if(len >= 2 && s[0] == '.' && IS_DIRSEP(s[1])) {
      len -= 2;
      s += 2;
    }
    if(opt_list && size >= opt_minsize)
      buffer_putsa(buffer_1, &pre);

    if(opt_relative_to) {
      size_t sz = str_len(opt_relative_to);
      if(str_diffn(s, opt_relative_to, sz) == 0) {
        s += sz;
        len -= sz;
        while(*s == '\\' || *s == '/') {
          s++;
          len--;
        }
      }
    }

    if(size >= opt_minsize) {
      buffer_put(buffer_1, s, len);
      buffer_put(buffer_1, "\n", 1);
      buffer_flush(buffer_1);
    }

    if(is_dir && (opt_deref || !is_symlink)) {
      dir->len--;
      list_dir_internal(dir, 0);
    }
  }
end:
  dir_close(&d);
  return 0;
}
Esempio n. 5
0
union node*
expand_param(struct nargparam* param, union node** nptr, struct vartab* varstack, char* argv[], int exitcode, int flags) {
  union node* n = *nptr;
  stralloc value;
  char* str = NULL;
  const char *v = NULL;
  unsigned long argc, vlen = 0;

        for(argc = 0; argv[argc]; ++argc)
          ;
  stralloc_init(&value);

  /* treat special arguments */
  if(param->flag & S_SPECIAL) {
    switch(param->flag & S_SPECIAL) {
      /* $# substitution */
      case S_ARGC: {
        stralloc_catulong0(&value, argc, 0);
        break;
      }

      /* $* substitution */
      case S_ARGV: {
        char** s;

        for(s = argv; *s;) {
          stralloc_cats(&n->narg.stra, *s);
          if(*++s) stralloc_catc(&n->narg.stra, ' ');
        }
        break;
      }

      /* $@ substitution */
      case S_ARGVS: {
        unsigned int i = 0;

        while(i < argc) {
          param->flag &= ~S_SPECIAL;
          param->flag |= S_ARG;
          param->numb = 1 + i;

          n = expand_param(param, nptr, varstack, argv, exitcode,flags);

          if(++i < argc) nptr = &n->list.next;
        }

        return n;
      }

        /* $? substitution */
      case S_EXITCODE: {
        stralloc_catulong0(&value, exitcode, 0);
        break;
      }

      /* $- substitution */
      case S_FLAGS: break;

      /* $! substitution */
      case S_BGEXCODE:
        break;

        /* $[0-9] arg subst */
      case S_ARG: {
        if(param->numb == 0) {
        /*  stralloc_cats(&value, sh_argv0); */
        } else if(param->numb - 1 < argc) {
          stralloc_cats(&value, argv[param->numb - 1]);
        }
        break;
      }

        /* $$ arg subst */
      case S_PID: {
        stralloc_catulong0(&value, getpid(), 0);
        break;
      }
    }

    /* special parameters are always set */
    if(value.len) {
      stralloc_nul(&value);
      v = value.s;
    }

    vlen = value.len;
  }
  /* ..and variable substitutions */
  else {
    size_t offset;

    /* look for the variable.
       if the S_NULL flag is set and we have a var which is null
       set v to NULL */
    if((v = var_get(varstack, param->name, &offset))) {
      if(v[offset] == '\0' && (param->flag & S_NULL)) {
        v = NULL;
        vlen = 0;
      } else {
        v = &v[offset];
        vlen = str_len(v);
      }
    }
  }

  /* check for S_STRLEN substitution */
  if(param->flag & S_STRLEN) {
    char lstr[FMT_ULONG];

    n = expand_cat(lstr, fmt_ulong(lstr, vlen), nptr, varstack, flags);

    stralloc_free(&value);

    return n;
  }

  str = str_ndup(v, vlen);

  /* otherwise expand the apropriate variable/word subst */
  switch(param->flag & S_VAR) {
    /* return word if parameter unset (or null) */
    case S_DEFAULT: {
      if(v) n = expand_cat(v, vlen, nptr, varstack, flags);
      /* unset, substitute */
      else
        n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags);
      break;
    }
    /* if parameter unset (or null) then expand word to it
       and substitute paramter */
    case S_ASGNDEF: {
      if(v)
        n = expand_cat(v, vlen, nptr, varstack, flags);
      else {
        n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags | X_NOSPLIT);
        var_setvsa(param->name, /* BUG */ &n->narg.stra, V_DEFAULT);
      }
      break;
    }

    /* indicate error if null or unset */
    case S_ERRNULL: {
      if(v)
        n = expand_cat(v, vlen, nptr, varstack, flags);
      else {
        union node* tmpnode = NULL;

        n = expand_arg(&param->word->narg, &tmpnode, varstack, argv, exitcode, flags);
       errmsg_warn((n && n->narg.stra.s) ? n->narg.stra.s : "parameter null or not set", 0);
        if(tmpnode) tree_free(tmpnode);
      }
      break;
    }

      /* if parameter unset (or null) then substitute null,
         otherwise substitute word */
    case S_ALTERNAT: {
      if(v) n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags);
      break;

        /* remove smallest matching suffix */
      case S_RSSFX: {
        int i;
        stralloc sa;

        if(v && vlen) {
          expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
          stralloc_nul(&sa);

          for(i = vlen - 1; i >= 0; i--)
            if(fnmatch(sa.s, str + i, FNM_PERIOD) == 0) break;

          n = expand_cat(v, (i < 0 ? vlen : i), nptr, varstack, flags);
        }
        break;
      }
    }

      /* remove largest matching suffix */
    case S_RLSFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = 0; i <= vlen; i++)
          if(fnmatch(sa.s,  str + i,  FNM_PERIOD) == 0) break;

        n = expand_cat(v, (i > vlen ? vlen : i), nptr, varstack, flags);
      }

      break;
    }

      /* remove smallest matching prefix */
    case S_RSPFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = 1; i <= vlen; i++) {
          str_copyn(str, v, i);
          if(fnmatch(sa.s, (char*)v, FNM_PERIOD) == 0) break;
        }

        if(i > vlen) i = 0;

        n = expand_cat(v + i, vlen - i, nptr, varstack, flags);
        str_copy(str, v);
      }
      break;
    }

      /* remove largest matching prefix */
    case S_RLPFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = vlen; i > 0; i--) {
          str_copyn(str, v, i);
          if(fnmatch(sa.s, (char*)v, FNM_PERIOD) == 0) break;
        }

        if(i == 0) i = vlen;

        n = expand_cat(v + i, vlen - i, nptr, varstack, flags);
        str_copy(str, v);
      }
      break;
    }
  }

  free(str);

  stralloc_free(&value);
  return n;
}
Esempio n. 6
0
/* main loop, parse lines into trees and execute them
 * ----------------------------------------------------------------------- */
void sh_loop(void) {
  struct parser p;
  union node *list;
  stralloc cmd;

  /* if we're in interactive mode some 
     additional stuff is to be initialized */
  if(source->mode & SOURCE_IACTIVE)
    history_load();
  
  stralloc_init(&cmd);

  parse_init(&p, P_DEFAULT);
  
  while(!(parse_gettok(&p, P_DEFAULT) & T_EOF)) {
    p.pushback++;
    parse_lineno = source->line;

    var_setvint("LINENO", parse_lineno, V_DEFAULT);
    
    /* launch the parser to get a complete command */
    if((list = parse_list(&p)))
    {
      struct eval e;
      
      if(source->mode & SOURCE_IACTIVE)
      {
        tree_printlist(list, &cmd, NULL);
        stralloc_catc(&cmd, '\n');
        stralloc_nul(&cmd);
        history_set(cmd.s);
        cmd.s = NULL;
        history_advance();
      }

#ifdef DEBUG
/*      debug_list(list, 0);
      buffer_putnlflush(fd_err->w);*/
#endif /* DEBUG */
      eval_push(&e, E_JCTL);
      eval_tree(&e, list, E_ROOT|E_LIST);
      sh->exitcode = eval_pop(&e);
      
      stralloc_zero(&cmd);

      tree_free(list);
    } else if(!(p.tok & (T_NL | T_SEMI | T_BGND))) {
      /* we have a parse error */
      if(p.tok != T_EOF)
        parse_error(&p, 0);

      /* exit if not interactive */
      if(!(source->mode & SOURCE_IACTIVE))
        sh_exit(1);

      /* ..otherwise discard the input buffer */
      source_flush();
      p.pushback = 0;
    }
    
    if(p.tok & (T_NL|T_SEMI|T_BGND))
      p.pushback = 0;

    /* reset prompt */
    prompt_number = 0;
  }
}