Exemple #1
0
int
sln(const char* path) {
  stralloc s, d;
  char* to;
  ssize_t i;
  stralloc_init(&s);
  stralloc_copys(&s, path);

  stralloc_init(&d);
  stralloc_copy(&d, &s);

  while(reduce(&d)) {

    buffer_puts(buffer_2, "'");
    buffer_putsa(buffer_2, &d);
    buffer_puts(buffer_2, "' -> '");
    buffer_putsa(buffer_2, &s);
    buffer_puts(buffer_2, "'\n");
    buffer_flush(buffer_2);

    stralloc_nul(&s);
    stralloc_nul(&d);

    if(mklink_sa(&s, &d) == -1) {
      errmsg_warnsys("symlink failed", NULL);
      exit(2);
    }
    stralloc_copy(&s, &d);
  }

  return 0;
}
Exemple #2
0
/* evaluate case conditional construct (3.9.4.3)
 * ----------------------------------------------------------------------- */
int eval_case(struct eval *e, struct ncase *ncase) {
  union node *node;
  union node *pat;
  int ret = 0;
  stralloc word;
  stralloc pattern;
  stralloc_init(&word);
  stralloc_init(&pattern);

  if(ncase->word)
    expand_catsa(ncase->word, &word, X_NOSPLIT);
  
  stralloc_nul(&word);

  for(node = ncase->list; node; node = node->list.next) {
    for(pat = node->ncasenode.pats; pat; pat = pat->list.next) {
      expand_catsa(pat, &pattern, X_NOSPLIT);
      stralloc_nul(&pattern);
      
      if(shell_fnmatch(pattern.s, pattern.len, word.s, word.len, SH_FNM_PERIOD) == 0) {
        ret = eval_tree(e, node->ncasenode.cmds, E_LIST);
        goto end;
      }
      
      stralloc_zero(&pattern);
    }
  }

end:  
  stralloc_free(&pattern);
  stralloc_free(&word);

  return ret;
}
Exemple #3
0
/* process all here-docs
 * 
 * nredir->data is set to the next here-doc redirection by redir_addhere()
 * after processing it is set to the content of the here-doc (an narg node)
 * ----------------------------------------------------------------------- */
void redir_source(void) {
  struct parser p;
  stralloc delim;
  int r;
    
  parse_init(&p, P_HERE);
      
  stralloc_init(&delim);
  
  for(; redir_list; redir_list = &redir_list->data->nredir) {
    /* expand the delimiter */
    stralloc_init(&delim);
    expand_catsa((union node *)redir_list, &delim, 0);
    
    /* when any character of the delimiter has been escaped
       then treat the whole here-doc as non-expanded word */
    r = parse_here(&p, &delim, (redir_list->list->nargstr.flag & S_ESCAPED));
    
    tree_free(redir_list->list);
    redir_list->list = parse_getarg(&p);
    
    /* free expanded delimiters */
    stralloc_free(&delim);
  }
}
Exemple #4
0
/* evaluates backquoted command list, while writing stdout to a stralloc 
 */
union node*
expand_command(struct nargcmd *cmd, union node **nptr, struct vartab* varstack, int flags) {
  union node *n = *nptr;
  stralloc sa;
  stralloc_init(&sa);

  /* make the output buffer write to the stralloc */
  buffer_tosa(buffer_1, &sa); 

  /* evaluate the command tree in a subshell */
  /*sh_push(&sh);
  sh_subshell(cmd->list, E_EXIT);
  sh_pop(&sh);*/

  /* split trailing newlines */
  while(sa.len && sa.s[sa.len - 1] == '\n')
    sa.len--;

  /* expand the output of the command 
   
     FIXME: we could do this much nicer by doing an
            expand_write() which is set as buffer op 
            on the output fd.
   
            so we won't have to alloc all the stuff twice!
   */
  n = expand_cat(sa.s, sa.len, nptr, varstack, flags);
  stralloc_free(&sa);

  return n;
}
Exemple #5
0
/* expands the prompt if necessary
 * ----------------------------------------------------------------------- */
void prompt_expand(void) {
  /* expand PS1 only */
  if(prompt_number != 1)
    return;

  /* expand prompt tree if present */
  if(prompt_node) {
    stralloc sa;

    /* escape prompt */
    stralloc_init(&sa);
#ifdef DEBUG
/*    debug_list(prompt_node, 0);      */
#endif    
    expand_catsa(prompt_node, &sa, 0);
    stralloc_nul(&sa);
    stralloc_zero(&prompt_expansion);
    prompt_escape(sa.s, &prompt_expansion);
    stralloc_nul(&prompt_expansion);

#ifdef DEBUG
/*    debug_stralloc("prompt", &sa, 0);*/
#endif      
    
  }
}
Exemple #6
0
void
http_init(http* h, const char* host, uint16 port) {
  byte_zero(h, sizeof(http));
  h->sock = -1;
  stralloc_init(&h->host);
  stralloc_copys(&h->host, host);
  h->port = port;
  h->request = NULL;
}
Exemple #7
0
int main() {
  stralloc sa;
  buffer b;
  stralloc line;

  stralloc_init(&sa);
  stralloc_init(&line);
  stralloc_copys(&sa,"this is a test\nline 2\n");
  buffer_fromsa(&b,&sa);

  while (buffer_getline_sa(&b,&line)==0) {
    buffer_puts(buffer_1,"got line: \"");
    if (stralloc_chop(&line)!='\n') break;
    buffer_putsa(buffer_1,&line);
    buffer_putsflush(buffer_1,"\"\n");
    stralloc_copys(&line,"");
  }
  return 0;
}
Exemple #8
0
static int
pls_reader(playlist* pl) {
  int ret;
    static playlist_entry entry;
  buffer* inbuf = pl->ptr;
  stralloc line;
  stralloc_init(&line);
  if(( ret = buffer_getline_sa(inbuf, &line))) {
    size_t index2, index;
    index2 = index = 0;
    while(line.len > 1 &&
          (line.s[line.len - 1] == '\r' || line.s[line.len - 1] == '\n'))
      line.len--;
    stralloc_0(&line);
    if(!str_diffn(&line.s[index], "Number", 6)) {
    } else if(line.s[index] == '[') {
    } else if((index2 = str_chr(&line.s[index], '=')) > 0) {
      unsigned long trackno = 0;
      index = index2;
      index2++;
      do { index--; } while(isdigit(line.s[index]) && index > 0);
      scan_ulong(&line.s[index], &trackno);
      if(!str_diffn(&line.s[index], "File", 4)) {
        stralloc_copys(&entry.path, &line.s[index2]);
        stralloc_0(&entry.path);
      } else if(!str_diffn(&line.s[index], "Title", 5)) {
        stralloc_copys(&entry.title, &line.s[index2]);
        stralloc_0(&entry.title);
      } else if(!str_diffn(&line.s[index], "Length", 6)) {
        unsigned long len;
        scan_ulong(&line.s[index2], &len);
        entry.length = len;
      }
      /*
      uint32 index = 8;
      index += scan_ulong(&line.s[index], &len);
      entry.length = len;
      index++;
      stralloc_copys(&entry.title, &line.s[index]);
      stralloc_0(&entry.title);
      */
    } else {
      /*
      stralloc_copy(&entry.path, &line);
      stralloc_0(&entry.path);
      if(pl->callback) {
      pl->callback(pl, &entry.title, &entry.path, entry.length);
      }*/
    }
  }
  return ret;
}
Exemple #9
0
int main() {
  stralloc sa;
  int res;

  stralloc_init(&sa);
  res=buffer_get_token_sa_pred(buffer_0,&sa,ishttp);
  buffer_puts(buffer_1,"buffer_get_token_sa_pred returned ");
  buffer_putlong(buffer_1,res);
  buffer_putsflush(buffer_1,".\n\n");
  buffer_putsa(buffer_1,&sa);
  buffer_flush(buffer_1);
  return 0;
}
Exemple #10
0
/* evaluates backquoted command list, while writing stdout to a stralloc 
 * ----------------------------------------------------------------------- */
union node *expand_command(struct nargcmd *cmd, union node **nptr, int flags) {
  union node *n = *nptr;
  struct vartab vars;
  struct fd fd;
  struct fdstack fdst;
  struct env sh;
  stralloc sa;
  stralloc_init(&sa);

  /* do this in a new i/o context so we can redirect stdout */
  vartab_push(&vars);
  
  /* make the output buffer write to the stralloc */
  fdstack_push(&fdst);
  fd_push(&fd, STDOUT_FILENO, FD_WRITE);
  fd_subst(&fd, &sa);

  /* evaluate the command tree in a subshell */
  sh_push(&sh);
  sh_subshell(cmd->list, E_EXIT);
  sh_pop(&sh);

  fdstack_pop(&fdst);

  vartab_pop(&vars);

  /* split trailing newlines */
  while(sa.len && sa.s[sa.len - 1] == '\n')
    sa.len--;

  /* expand the output of the command 
   
     FIXME: we could do this much nicer by doing an
            expand_write() which is set as buffer op 
            on the output fd.
   
            so we won't have to alloc all the stuff twice!
   */
  n = expand_cat(sa.s, sa.len, nptr, flags);
  stralloc_free(&sa);

  return n;
}
Exemple #11
0
/* set a variable
 * ----------------------------------------------------------------------- */
struct var *var_set(char *v, int flags) {
  struct var *var;
  
  /* find/create the variable */
  if((var = var_create(v, flags)) == NULL)
    return var;
  
  /* free if it was a previously allocated string */
  if(var->sa.a)
    stralloc_free(&var->sa);
    
  stralloc_init(&var->sa);
  
  var->sa.s = v;
  var->sa.len = str_len(v);
  var->offset = var->len;
  
  if(var->len < var->sa.len)
    var->offset++;
  
  return var;
}
Exemple #12
0
char *whirlpool_digest(const char *str)
{
	whirlpool_t ctx;
	stralloc_t sa;
	char *buf;
	uint8_t digest[DIGESTBYTES];
	int i;

	whirlpool_init(&ctx);
	whirlpool_add(&ctx, (const unsigned char * const) str, str_len(str)*8);
	whirlpool_finalize(&ctx, digest);

	stralloc_init(&sa);

	for (i = 0; i < DIGESTBYTES; i++)
		stralloc_catf(&sa, "%02X", digest[i]);

	buf = stralloc_finalize(&sa);

	stralloc_free(&sa);

	return buf;
}
Exemple #13
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;
}
Exemple #14
0
int
dir_type(struct dir_s* d) {
  int r = 0;
#if !USE_READDIR && (defined(_WIN32) || defined(_WIN32) || defined(__MSYS__))
  if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
    r |= D_SYMLINK;
  else if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & 0x10)
    r |= D_DIRECTORY;
  else if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & 0x20)
    r |= D_FILE;
#else
#ifndef DT_DIR
#define DT_DIR 4
#endif

#ifndef DT_REG
#define DT_REG 8
#endif

#ifndef DT_LNK
#define DT_LNK 10
#endif

#if defined(_DIRENT_HAVE_D_TYPE) || (!defined(__MSYS__) && !defined(__CYGWIN__))
  switch((dir_TYPE(d))) {
    case DT_DIR: {
      r |= D_DIRECTORY;
      break;
    }
    case DT_REG: {
      r |= D_FILE;
      break;
    }
    case DT_LNK: {
      r |= D_SYMLINK;
      break;
    }
    case 0:
    default: { break; }
  }
#else
  {
    stralloc sa;
    struct stat st;
    DIR* dh = dir_INTERNAL(d)->dir_handle;

    stralloc_init(&sa);
        dir_path(d, &sa);
    stralloc_nul(&sa);

    if(lstat(sa.s, &st) != -1) {
      if(S_ISLNK(st.st_mode))
        r |= D_SYMLINK;
      else if(S_ISDIR(st.st_mode))
        r |= D_DIRECTORY;
      else if(S_ISREG(st.st_mode))
        r |= D_FILE;
    }

#ifdef DEBUG_OUTPUT
    buffer_puts(buffer_2, "dir_type path: ");
    buffer_putsa(buffer_2, &sa);
    buffer_putnlflush(buffer_2);
#endif


//      printf("dh: %p __d_dirname: %s\n", dh, dh->__d_dirname);

    stralloc_free(&sa);
  }
//#error No dirent type method
#endif

#endif
  return r;
}
Exemple #15
0
int
main(int argc, char* argv[]) {
  int index = 0, c;
  static const struct longopt opts[] = {{"help", 0, NULL, 'h'}, {"verbose", 0, 0, 'v'}, {0}};

  errmsg_iam(argv[0]);

  for(;;) {
    c = getopt_long(argc, argv, "hv", opts, &index);
    if(c == -1)
      break;
    if(c == '\0')
      continue;

    switch(c) {
      case 'h': usage(argv[0]); return 0;
      case 'v': verbose = 1; break;
      default: {
        usage(argv[0]);
        return 1;
      }
    }
  }

  while(optind < argc) {
    const char* a = argv[optind++];
    int i = str_rchr(a, '.');

    if(str_equal(&a[i], ".list")) {
      buffer in;
      if(!buffer_mmapread(&in, a)) {
        stralloc target, link;
        ssize_t ret;
        stralloc_init(&target);
        stralloc_init(&link);

        for(;;) {
          if((ret = buffer_get_new_token_sa(&in, &target, " \t\v", 2)) < 0)
            break;

          if(ret == 0 || target.s[0] == '\0')
            break;
          if(target.len > 0)
            --target.len;

          if((ret = buffer_get_new_token_sa(&in, &link, "\r\n", 2)) < 0)
            break;

          if(ret == 0 || link.s[0] == '\0')
            break;
          stralloc_chomp(&link);

          mklink_sa(&target, &link);

          if(!stralloc_endb(&link, ".so", 3)) {
            if(sln(link.s))
              return 1;
          }
        }

        buffer_close(&in);
      }
    } else {
      if(sln(argv[i]))
        return 1;
    }
  }
}
Exemple #16
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;
}
Exemple #17
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;
  }
}
Exemple #18
0
/* change working directory
 * ----------------------------------------------------------------------- */
int builtin_cd(int argc, char **argv) {
  int c;
  int ok = 0;
  int symbolic = 1;
  const char *arg;
  unsigned long len;
  unsigned long n;
  stralloc newcwd;
  
  /* check options, -L for symlink, -P for physical path */
  while((c = shell_getopt(argc, argv, "LP")) > 0) {
    switch(c) {
      case 'L': symbolic = 1; break;
      case 'P': symbolic = 0; break;
      default: builtin_invopt(argv); return 1;
    }
  }
  
  arg = argv[shell_optind];
  stralloc_init(&newcwd);

  /* empty argument means chdir(HOME) */
  if(arg == NULL) {
    arg = var_value("HOME", &len);

    if(arg[0] == '\0') {
      sh_msg("HOME variable not set!");
      return 1;
    }
  }

  len = str_len(arg);
  
  /* when it isn't an absolute path we have to check CDPATH */
  if(arg[0] != '/') {
    char path[PATH_MAX + 1];
    const char *cdpath;

    /* loop through colon-separated CDPATH variable */
    cdpath = var_value("CDPATH", NULL);

    do {
      /* too much, too much :) */
      if((n = str_chr(cdpath, ':')) + len + 1 > PATH_MAX) {
        /* set error code and print the longer string in the error msg */
        errno = ENAMETOOLONG;
        return builtin_errmsgn(argv, (n > len ? cdpath : arg),
                               (n > len ? n : len), strerror(errno));
      }
      
      /* copy path prefix from cdpath if present */
      if(n) {
        byte_copy(path, n, cdpath);
        cdpath += n;
        path[n++] = '/';
      }
      
      /* copy the argument and canonicalize */
      str_copy(&path[n], arg);

      ok = shell_realpath(path, &newcwd, symbolic, &sh->cwd);

      /* skip the colon */
      if(*cdpath == ':')
        cdpath++;
    } while(*cdpath && !ok);

  }
  /* absolute path */
  else {
    /* last cdpath length set to 0, because we're not using cdpath here */
    n = 0;
    ok = shell_canonicalize(arg, &newcwd, symbolic);
  }
  
  stralloc_nul(&newcwd);

  /* try to chdir() if everything's ok */
  if(ok && chdir(newcwd.s) == 0) {
    /* print path if prefix was taken from cdpath */
    if(n) {
      buffer_putsa(fd_out->w, &newcwd);
      buffer_putnlflush(fd_out->w);
    }
    
    /* set the path */
    stralloc_move(&sh->cwd, &newcwd);

    /* if the path has symlinks then set sh->cwdsym */
    sh->cwdsym = (ok > 1);

    return 0;
  }
  
  /* we failed */
  builtin_error(argv, newcwd.s);
  stralloc_free(&newcwd);
  return 1;
}
Exemple #19
0
void
xml_read_callback(xmlreader* r, xml_read_callback_fn* fn) {
  ssize_t n;
  buffer* b = r->b;
  stralloc tag, attr, val;
  stralloc_init(&tag);
  stralloc_init(&attr);
  stralloc_init(&val);
  hmap_init(XML_HMAP_BUCKETS, &r->attrmap);

  while((n = buffer_skip_until(b, "<", 1)) > 0) {
    const char* s;
    stralloc_zero(&tag);
    r->self_closing = r->closing = 0;
    s = buffer_peek(b);

    if(*s == '/') {
      r->closing = 1;
      buffer_skipc(b);
    } else if(*s == '?') {
      r->self_closing = 1;
    } else if(*s == '!') {
      if(buffer_skip_until(b, ">", 1) <= 0)
        return;
      continue;
    }
    if((n = buffer_gettok_sa(b, &tag, " \n\t\r\v/>", 7)) < 0)
      return;
    stralloc_nul(&tag);
    buffer_skipspace(b);

    while((s = buffer_peek(b)) && isalpha(*s)) {
      char ch;
      int quoted = 0;
      const char* charset;
      stralloc_zero(&attr);
      stralloc_zero(&val);
      if((n = buffer_gettok_sa(b, &attr, "=", 1)) < 0)
        break;
      if(buffer_skipc(b) < 0)
        return;

      if(*buffer_peek(b) == '"') {
        if(buffer_skipc(b) < 0)
          return;
        quoted = 1;
      }
      charset = quoted ? "\"" : "/> \t\r\n\v";
      if((n = buffer_gettok_sa(b, &val, charset, str_len(charset))) < 0)
        break;
      if(quoted && buffer_skipc(b) < 0)
        return;
      stralloc_nul(&attr);
      stralloc_nul(&val);
      hmap_set(&r->attrmap, attr.s, attr.len, val.s, val.len + 1);
      if(!fn(r, XML_ATTRIBUTE, &attr, &val, NULL))
        return;
      buffer_skipspace(b);
    }
    buffer_skipspace(b);

    if((s = buffer_peek(b)) && str_chr("/?", *s) < 2) {
      r->self_closing = 1;
      r->closing = 0;
      buffer_skipc(b);
    }
    buffer_skipspace(b);
    if((s = buffer_peek(b)) && *s == '>')
      buffer_skipc(b);
    if(!fn(r, XML_ELEMENT, &tag, NULL, &r->attrmap))
      return;

    if(r->attrmap) {
      hmap_destroy(&r->attrmap);
      r->attrmap = NULL;
    }
    hmap_init(XML_HMAP_BUCKETS, &r->attrmap);
    stralloc_zero(&tag);
    if((n = buffer_gettok_sa(b, &tag, "<", 1)) < 0)
      return;
    s = buffer_peek(b);

    if(!is_whitespace(tag.s, tag.len)) {
      if(!fn(r, XML_TEXT, NULL, &tag, NULL))
        return;
    }
  }
}