예제 #1
0
int cmd_mv(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *oldpath;
  char *newpath;
  int ret;

  /* Get the full path to the old and new file paths */

  oldpath = nsh_getfullpath(vtbl, argv[1]);
  if (!oldpath)
    {
      return ERROR;
    }

  newpath = nsh_getfullpath(vtbl, argv[2]);
  if (!newpath)
    {
      nsh_freefullpath(newpath);
      return ERROR;
    }

  /* Perform the mount */

  ret = rename(oldpath, newpath);
  if (ret < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "rename", NSH_ERRNO);
    }

  /* Free the file paths */

  nsh_freefullpath(oldpath);
  nsh_freefullpath(newpath);
  return ret;
}
예제 #2
0
int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *fullpath;
  int i;
  int ret = OK;

  /* Loop for each file name on the command line */

  for (i = 1; i < argc && ret == OK; i++)
    {
      /* Get the fullpath to the file */

      fullpath = nsh_getfullpath(vtbl, argv[i]);
      if (!fullpath)
        {
          ret = ERROR;
        }
      else
        {
          /* Dump the file to the console */

          ret = cat_common(vtbl, argv[0], fullpath);

          /* Free the allocated full path */

          nsh_freefullpath(fullpath);
        }
    }

  return ret;
}
예제 #3
0
int nsh_script(FAR struct nsh_vtbl_s *vtbl, const char *cmd, const char *path)
{
  char *fullpath;
  FILE *stream;
  char *buffer;
  char *pret;
  int ret = ERROR;

  /* The path to the script may be relative to the current working directory */

  fullpath = nsh_getfullpath(vtbl, path);
  if (!fullpath)
    {
      return ERROR;
    }

  /* Get a reference to the common input buffer */

  buffer = nsh_linebuffer(vtbl);
  if (buffer)
    {
      /* Open the file containing the script */

      stream = fopen(fullpath, "r");
      if (!stream)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "fopen", NSH_ERRNO);
          nsh_freefullpath(fullpath);
          return ERROR;
        }

      /* Loop, processing each command line in the script file (or
       * until an error occurs)
       */

      do
        {
          /* Get the next line of input from the file */

          fflush(stdout);
          pret = fgets(buffer, CONFIG_NSH_LINELEN, stream);
          if (pret)
            {
              /* Parse process the command.  NOTE:  this is recursive...
               * we got to cmd_sh via a call to nsh_parse.  So some
               * considerable amount of stack may be used.
               */

              ret = nsh_parse(vtbl, buffer);
            }
        }
      while (pret && ret == OK);
      fclose(stream);
    }

  nsh_freefullpath(fullpath);
  return ret;
}
예제 #4
0
int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  const char *path = argv[1];
  char *alloc = NULL;
  char *fullpath = NULL;
  int ret = OK;

  /* Check for special arguments */

  if (argc < 2 || strcmp(path, "~") == 0)
    {
      path = g_home;
    }
  else if (strcmp(path, "-") == 0)
    {
      alloc = strdup(nsh_getwd(g_oldpwd));
      path  = alloc;
    }
  else if (strcmp(path, "..") == 0)
    {
      alloc = strdup(nsh_getcwd());
      path  = dirname(alloc);
    }
  else
    {
      fullpath = nsh_getfullpath(vtbl, path);
      path     = fullpath;
    }

  /* Set the new workding directory */

  ret = chdir(path);
  if (ret != 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "chdir", NSH_ERRNO);
      ret = ERROR;
    }

  /* Free any memory that was allocated */

  if (alloc)
    {
      free(alloc);
    }

  if (fullpath)
    {
      nsh_freefullpath(fullpath);
    }
  return ret;
}
예제 #5
0
int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *fullpath = nsh_getfullpath(vtbl, argv[1]);
  int ret = ERROR;

  if (fullpath)
    {
      ret = mkfifo(fullpath, 0777);
      if (ret < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfifo", NSH_ERRNO);
        }
      nsh_freefullpath(fullpath);
    }
  return ret;
}
예제 #6
0
int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  struct fat_format_s fmt = FAT_FORMAT_INITIALIZER;
  char *fullpath = nsh_getfullpath(vtbl, argv[1]);
  int ret = ERROR;

  if (fullpath)
    {  
      ret = mkfatfs(fullpath, &fmt);
      if (ret < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfatfs", NSH_ERRNO);
        }
      nsh_freefullpath(fullpath);
    }
  return ret;
}
예제 #7
0
int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *fullpath = nsh_getfullpath(vtbl, argv[1]);
  int ret = ERROR;

  if (fullpath)
    {
      /* Perform the umount */

      ret = umount(fullpath);
      if (ret < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "umount", NSH_ERRNO);
        }
      nsh_freefullpath(fullpath);
    }
  return ret;
}
예제 #8
0
파일: nsh_fscmds.c 프로젝트: bartyam/NuttX
int cmd_mksmartfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *fullpath = nsh_getfullpath(vtbl, argv[1]);
  int ret = ERROR;
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
  int nrootdirs = 1;
#endif

  if (fullpath)
    {
      /* Test if number of root directories was supplied */

#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
      if (argc == 3)
        {
          nrootdirs = atoi(argv[2]);
        }

      if (nrootdirs > 8 || nrootdirs < 1)
        {
          nsh_output(vtbl, "Invalid number of root directories specified\n");
        }
      else
#endif
        {
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
          ret = mksmartfs(fullpath, nrootdirs);
#else
          ret = mksmartfs(fullpath);
#endif
          if (ret < 0)
            {
              nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mksmartfs", NSH_ERRNO);
            }
        }

      nsh_freefullpath(fullpath);
    }

  return ret;
}
예제 #9
0
파일: nsh_fscmds.c 프로젝트: bartyam/NuttX
int cmd_cmp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
    char *path1 = NULL;
    char *path2 = NULL;
    int fd1 = -1, fd2 = -1;
    int ret = ERROR;
    unsigned total_read = 0;
    
    /* Get the full path to the two files */
    
    path1 = nsh_getfullpath(vtbl, argv[1]);
    if (!path1)
    {
        goto errout;
    }
    
    path2 = nsh_getfullpath(vtbl, argv[2]);
    if (!path2)
    {
        goto errout;
    }
    
    /* Open the files for reading */
    fd1 = open(path1, O_RDONLY);
    if (fd1 < 0)
    {
        nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
        goto errout;
    }
    
    fd2 = open(path2, O_RDONLY);
    if (fd2 < 0)
    {
        nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
        goto errout;
    }
    
    for (;;)
    {
        char buf1[128];
        char buf2[128];
        
        int nbytesread1 = read(fd1, buf1, sizeof(buf1));
        int nbytesread2 = read(fd2, buf2, sizeof(buf2));
        
        if (nbytesread1 < 0)
        {
            nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
            goto errout;
        }
        
        if (nbytesread2 < 0)
        {
            nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
            goto errout;
        }
        
        total_read += nbytesread1>nbytesread2?nbytesread2:nbytesread1;
        
        if (nbytesread1 != nbytesread2 || memcmp(buf1, buf2, nbytesread1) != 0)
        {
            nsh_output(vtbl, "files differ: byte %u\n", total_read);
            goto errout;
        }
        
        if (nbytesread1 < sizeof(buf1)) break;
    }
    
    ret = OK;
    
errout:
    if (fd1 != -1) close(fd1);
    if (fd2 != -1) close(fd2);
    return ret;
}
예제 #10
0
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  FAR const char *source;
  FAR char *fullsource;
  FAR const char *target;
  FAR char *fulltarget;
  FAR const char *filesystem = NULL;
  bool badarg = false;
  int option;
  int ret;

  /* The mount command behaves differently if no parameters are provided */

#ifndef CONFIG_NUTTX_KERNEL
  if (argc < 2)
    {
      return mount_show(vtbl, argv[0]);
    }
#endif

  /* Get the mount options.  NOTE: getopt() is not thread safe nor re-entrant.
   * To keep its state proper for the next usage, it is necessary to parse to
   * the end of the line even if an error occurs.  If an error occurs, this
   * logic just sets 'badarg' and continues.
   */

  while ((option = getopt(argc, argv, ":t:")) != ERROR)
    {
      switch (option)
        {
          case 't':
            filesystem = optarg;
            break;

          case ':':
            nsh_output(vtbl, g_fmtargrequired, argv[0]);
            badarg = true;
            break;

          case '?':
          default:
            nsh_output(vtbl, g_fmtarginvalid, argv[0]);
            badarg = true;
            break;
        }
    }

  /* If a bad argument was encountered, then return without processing the
   * command.
   */

  if (badarg)
    {
      return ERROR;
    }

  /* There may be one or two required arguments after the options: the source
   * and target paths.  Some file systems do not require the source parameter
   * so if there is only one parameter left, it must be the target.
   */

  if (optind >= argc)
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      return ERROR;
    }

  source = NULL;
  target = argv[optind];
  optind++;
  
  if (optind < argc)
    {
      source = target;
      target = argv[optind];
      optind++;

      if (optind < argc)
        {
          nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
          return ERROR;
        }
    }

  /* While the above parsing for the -t argument looks nice, the -t argument
   * not really optional.
   */

  if (!filesystem)
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      return ERROR;
    }

  /* The source and target paths might be relative to the current
   * working directory.
   */

  fullsource = NULL;
  fulltarget = NULL;

  if (source)
    {
      fullsource = nsh_getfullpath(vtbl, source);
      if (!fullsource)
        {
          return ERROR;
        }
    }

  fulltarget = nsh_getfullpath(vtbl, target);
  if (!fulltarget)
    {
      ret = ERROR;
      goto errout;
    }

  /* Perform the mount */

  ret = mount(fullsource, fulltarget, filesystem, 0, NULL);
  if (ret < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
    }

errout:
  if (fullsource)
    {
      nsh_freefullpath(fullsource);
    }

  if (fulltarget)
    {
      nsh_freefullpath(fulltarget);
    }

  return ret;
}
예제 #11
0
int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  struct nfs_args data;
  FAR char *address;
  FAR char *lpath;
  FAR char *rpath;
  bool badarg = false;
#ifdef CONFIG_NET_IPv6
  FAR struct sockaddr_in6 *sin;
  struct in6_addr inaddr;
#else
  FAR struct sockaddr_in *sin;
  struct in_addr inaddr;
#endif
  int ret;

  /* If a bad argument was encountered, then return without processing the
   * command.
   */

  if (badarg)
    {
      return ERROR;
    }

  /* The fist argument on the command line should be the NFS server IP address
   * in standard IPv4 (or IPv6) dot format.
   */

  address = argv[1];
  if (!address)
    {
      return ERROR;
    }

  /* The local mount point path (lpath) might be relative to the current working
   * directory.
   */

  lpath = nsh_getfullpath(vtbl, argv[2]);
  if (!lpath)
    {
      return ERROR;
    }

  /* Get the remote mount point path */

  rpath = argv[3];

   /* Convert the IP address string into its binary form */

#ifdef CONFIG_NET_IPv6
  ret = inet_pton(AF_INET6, address, &inaddr);
#else
  ret = inet_pton(AF_INET, address, &inaddr);
#endif
  if (ret != 1)
    {
      nsh_freefullpath(lpath);
      return ERROR;
    }

  /* Place all of the NFS arguements into the nfs_args structure */

  memset(&data, 0, sizeof(data));

#ifdef CONFIG_NET_IPv6
  sin                  = (FAR struct sockaddr_in6 *)&data.addr;
  sin->sin_family      = AF_INET6;
  sin->sin_port        = htons(NFS_PMAPPORT);
  memcpy(&sin->sin6_addr, &inaddr, sizeof(struct in6_addr));
  data.addrlen         = sizeof(struct sockaddr_in6);
#else
  sin                  = (FAR struct sockaddr_in *)&data.addr;
  sin->sin_family      = AF_INET;
  sin->sin_port        = htons(NFS_PMAPPORT);
  sin->sin_addr        = inaddr;
  data.addrlen         = sizeof(struct sockaddr_in);
#endif

  data.sotype          = SOCK_DGRAM;
  data.path            = rpath;
  data.flags           = 0;       /* 0=Use all defaults */

  /* Perform the mount */

  ret = mount(NULL, lpath, "nfs", 0, (FAR void *)&data);
  if (ret < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
    }

  /* We no longer need the allocated mount point path */

  nsh_freefullpath(lpath);
  return ret;
}
예제 #12
0
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
    struct dd_s dd;
    char *infile = NULL;
    char *outfile = NULL;
    int ret = ERROR;
    int i;

    /* Initialize the dd structure */

    memset(&dd, 0, sizeof(struct dd_s));
    dd.vtbl      = vtbl;              /* For nsh_output */
    dd.sectsize  = DEFAULT_SECTSIZE;  /* Sector size if 'bs=' not provided */
    dd.nsectors  = 0xffffffff;        /* MAX_UINT32 */

    /* If no IF= option is provided on the command line, then read
     * from stdin.
     */

#ifdef CAN_PIPE_FROM_STD
    DD_INFD      = 0;       /* stdin */
#ifndef CONFIG_NSH_DISABLE_DD
    dd.infread   = readch;  /* Character oriented read */
    dd.infclose  = noclose; /* Don't close stdin */
#endif
#endif
    /* If no OF= option is provided on the command line, then write
     * to stdout.
     */

#ifdef CAN_PIPE_FROM_STD
    DD_OUTDF     = 1;       /* stdout */
#ifndef CONFIG_NSH_DISABLE_DD
    dd.outfwrite = writech; /* Character oriented write */
    dd.outfclose = noclose; /* Don't close stdout */
#endif
#endif

    /* Parse command line parameters */

    for (i = 1; i < argc; i++)
    {
        if (strncmp(argv[i], "if=", 3) == 0)
        {
            infile = nsh_getfullpath(vtbl, &argv[i][3]);
        }
        else if (strncmp(argv[i], "of=", 3) == 0)
        {
            outfile = nsh_getfullpath(vtbl, &argv[i][3]);
        }
        else if (strncmp(argv[i], "bs=", 3) == 0)
        {
            dd.sectsize = atoi(&argv[i][3]);
        }
        else if (strncmp(argv[i], "count=", 6) == 0)
        {
            dd.nsectors = atoi(&argv[i][6]);
        }
        else if (strncmp(argv[i], "skip=", 5) == 0)
        {
            dd.skip = atoi(&argv[i][5]);
        }
    }

#ifndef CAN_PIPE_FROM_STD
    if (!infile || !outfile)
    {
        nsh_output(vtbl, g_fmtargrequired, g_dd);
        goto errout_with_paths;
    }
#endif

    /* Allocate the I/O buffer */

    dd.buffer = malloc(dd.sectsize);
    if (!dd.buffer)
    {
        nsh_output(vtbl, g_fmtcmdoutofmemory, g_dd);
        goto errout_with_paths;
    }

    /* Open the input file */

    ret = dd_infopen(infile, &dd);
    if (ret < 0)
    {
        goto errout_with_paths;
    }

    /* Open the output file */

    ret = dd_outfopen(outfile, &dd);
    if (ret < 0)
    {
        goto errout_with_inf;
    }

    /* Then perform the data transfer */

    dd.sector = 0;
    while (!dd.eof && dd.nsectors > 0)
    {
        /* Read one sector from from the input */

        ret = DD_READ(&dd);
        if (ret < 0)
        {
            goto errout_with_outf;
        }

        /* Has the incoming data stream ended? */

        if (!dd.eof)
        {
            /* Pad with zero if necessary (at the end of file only) */

            for (i = dd.nbytes; i < dd.sectsize; i++)
            {
                dd.buffer[i] = 0;
            }

            /* Write one sector to the output file */

            if (dd.sector >= dd.skip)
            {
                ret = DD_WRITE(&dd);
                if (ret < 0)
                {
                    goto errout_with_outf;
                }

                /* Decrement to show that a sector was written */

                dd.nsectors--;
            }

            /* Increment the sector number */

            dd.sector++;
        }
    }
    ret = OK;

errout_with_outf:
    DD_INCLOSE(&dd);
errout_with_inf:
    DD_OUTCLOSE(&dd);
    free(dd.buffer);
errout_with_paths:
    if (infile)
    {
        free(infile);
    }
    if (outfile)
    {
        free(outfile);
    }
    return ret;
}
예제 #13
0
int cmd_cmp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  FAR char *path1 = NULL;
  FAR char *path2 = NULL;
  off_t total_read = 0;
  int fd1 = -1;
  int fd2 = -1;
  int ret = ERROR;

  /* Get the full path to the two files */

  path1 = nsh_getfullpath(vtbl, argv[1]);
  if (!path1)
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      goto errout;
    }

  path2 = nsh_getfullpath(vtbl, argv[2]);
  if (!path2)
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      goto errout_with_path1;
    }

  /* Open the files for reading */

  fd1 = open(path1, O_RDONLY);
  if (fd1 < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
      goto errout_with_path2;
    }

  fd2 = open(path2, O_RDONLY);
  if (fd2 < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
      goto errout_with_fd1;
    }

  /* The loop until we hit the end of file or find a difference in the two
   * files.
   */

  for (;;)
    {
      char buf1[128];
      char buf2[128];

      /* Read the file data */

      ssize_t nbytesread1 = read(fd1, buf1, sizeof(buf1));
      ssize_t nbytesread2 = read(fd2, buf2, sizeof(buf2));

      if (nbytesread1 < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
          goto errout_with_fd2;
        }

      if (nbytesread2 < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
          goto errout_with_fd2;
        }

      total_read += nbytesread1 > nbytesread2 ? nbytesread2 : nbytesread1;

      /* Compare the file data */

      if (nbytesread1 != nbytesread2 ||
          memcmp(buf1, buf2, nbytesread1) != 0)
        {
          nsh_output(vtbl, "files differ: byte %u\n", total_read);
          goto errout_with_fd2;
        }

      /* A partial read indicates the end of file (usually) */

      if (nbytesread1 < (size_t)sizeof(buf1))
        {
          break;
        }
    }

  /* The files are the same, i.e., the end of file was encountered
   * without finding any differences.
   */

  ret = OK;

errout_with_fd2:
  close(fd2);
errout_with_fd1:
  close(fd1);
errout_with_path2:
  nsh_freefullpath(path2);
errout_with_path1:
  nsh_freefullpath(path1);
errout:
  return ret;
}
예제 #14
0
int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char buffer[IOBUFFERSIZE];
  char *fullpath;
  int fd;
  int i;
  int ret = OK;

  /* Loop for each file name on the command line */

  for (i = 1; i < argc && ret == OK; i++)
    {
      /* Get the fullpath to the file */

      fullpath = nsh_getfullpath(vtbl, argv[i]);
      if (fullpath)
        {
          /* Open the file for reading */

          fd = open(fullpath, O_RDONLY);
          if (fd < 0)
            {
             nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
            }
          else
            {
              /* And just dump it byte for byte into stdout */

              for (;;)
                {
                  int nbytesread = read(fd, buffer, IOBUFFERSIZE);

                  /* Check for read errors */

                  if (nbytesread < 0)
                    {
                      /* EINTR is not an error (but will stop stop the cat) */

#ifndef CONFIG_DISABLE_SIGNALS
                      if (errno == EINTR)
                        {
                          nsh_output(vtbl, g_fmtsignalrecvd, argv[0]);
                        }
                      else
#endif
                        {
                          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
                        }

                      ret = ERROR;
                      break;
                    }

                  /* Check for data successfully read */

                  else if (nbytesread > 0)
                    {
                      int nbyteswritten = 0;

                      while (nbyteswritten < nbytesread)
                        {
                          ssize_t n = nsh_write(vtbl, buffer, nbytesread);
                          if (n < 0)
                            {
                              /* EINTR is not an error (but will stop stop the cat) */

 #ifndef CONFIG_DISABLE_SIGNALS
                              if (errno == EINTR)
                                {
                                  nsh_output(vtbl, g_fmtsignalrecvd, argv[0]);
                                }
                              else
#endif
                                {
                                  nsh_output(vtbl, g_fmtcmdfailed, argv[0], "write", NSH_ERRNO);
                                }
                              ret = ERROR;
                              break;
                            }
                          else
                            {
                              nbyteswritten += n;
                            }
                        }
                    }

                  /* Otherwise, it is the end of file */

                  else
                    {
                      break;
                    }
                }

              (void)close(fd);
            }

          /* Free the allocated full path */

          nsh_freefullpath(fullpath);
        }
    }
  return ret;
}
예제 #15
0
int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  const char *relpath;
  unsigned int lsflags = 0;
  char *fullpath;
  bool badarg = false;
  int ret;

  /* Get the ls options */

  int option;
  while ((option = getopt(argc, argv, "lRs")) != ERROR)
    {
      switch (option)
        {
          case 'l':
            lsflags |= (LSFLAGS_SIZE|LSFLAGS_LONG);
            break;

          case 'R':
            lsflags |= LSFLAGS_RECURSIVE;
            break;

          case 's':
            lsflags |= LSFLAGS_SIZE;
            break;

          case '?':
          default:
            nsh_output(vtbl, g_fmtarginvalid, argv[0]);
            badarg = true;
            break;
        }
    }

  /* If a bad argument was encountered, then return without processing the command */

  if (badarg)
    {
      return ERROR;
    }

  /* There may be one argument after the options */

  if (optind + 1 < argc)
    {
      nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
      return ERROR;
    }
  else if (optind >= argc)
    {
#ifndef CONFIG_DISABLE_ENVIRON
      relpath = nsh_getcwd();
#else
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      return ERROR;
#endif
    }
  else
    {
      relpath = argv[optind];
    }

  /* Get the fullpath to the directory */

  fullpath = nsh_getfullpath(vtbl, relpath);
  if (!fullpath)
    {
      return ERROR;
    }

  /* List the directory contents */

  nsh_output(vtbl, "%s:\n", fullpath);
  ret = foreach_direntry(vtbl, "ls", fullpath, ls_handler, (void*)lsflags);
  if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
    {
      /* Then recurse to list each directory within the directory */

      ret = foreach_direntry(vtbl, "ls", fullpath, ls_recursive, (void*)lsflags);
    }
  nsh_freefullpath(fullpath);
  return ret;
}
예제 #16
0
int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  struct stat buf;
  char *srcpath  = NULL;
  char *destpath = NULL;
  char *allocpath = NULL;
  int oflags = O_WRONLY|O_CREAT|O_TRUNC;
  int rdfd;
  int wrfd;
  int ret = ERROR;

  /* Get the full path to the source file */

  srcpath = nsh_getfullpath(vtbl, argv[1]);
  if (!srcpath)
    {
      goto errout;
    }

  /* Open the source file for reading */

  rdfd = open(srcpath, O_RDONLY);
  if (rdfd < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
      goto errout_with_srcpath;
    }

  /* Get the full path to the destination file or directory */

  destpath = nsh_getfullpath(vtbl, argv[2]);
  if (!destpath)
    {
      goto errout_with_rdfd;
    }

  /* Check if the destination is a directory */

  ret = stat(destpath, &buf);
  if (ret == 0)
    {
      /* Something exists here... is it a directory? */

      if (S_ISDIR(buf.st_mode))
        {
          /* Yes, it is a directory. Remove any trailing '/' characters from the path */

          trim_dir(argv[2]);

          /* Construct the full path to the new file */

          allocpath = nsh_getdirpath(argv[2], basename(argv[1]) );
          if (!allocpath)
            {
              nsh_output(vtbl, g_fmtcmdoutofmemory, argv[0]);
              goto errout_with_destpath;
            }

          /* Open then dest for writing */

          nsh_freefullpath(destpath);
          destpath = allocpath;
        }
      else if (!S_ISREG(buf.st_mode))
        {
          /* Maybe it is a driver? */

          oflags = O_WRONLY;
        }
    }

  /* Now open the destination */

  wrfd = open(destpath, oflags, 0666);
  if (wrfd < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
      goto errout_with_allocpath;
    }

  /* Now copy the file */

  for (;;)
    {
      int nbytesread;
      int nbyteswritten;

      do
        {
          nbytesread = read(rdfd, g_iobuffer, IOBUFFERSIZE);
          if (nbytesread == 0)
            {
              /* End of file */

              ret = OK;
              goto errout_with_wrfd;
            }
          else if (nbytesread < 0)
            {
              /* EINTR is not an error (but will still stop the copy) */

#ifndef CONFIG_DISABLE_SIGNALS
              if (errno == EINTR)
                {
                  nsh_output(vtbl, g_fmtsignalrecvd, argv[0]);
                }
              else
#endif
                {
                  /* Read error */

                  nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
                }
              goto errout_with_wrfd;
            }
        }
      while (nbytesread <= 0);

      do
        {
          nbyteswritten = write(wrfd, g_iobuffer, nbytesread);
          if (nbyteswritten >= 0)
            {
              nbytesread -= nbyteswritten;
            }
          else
            {
              /* EINTR is not an error (but will still stop the copy) */

#ifndef CONFIG_DISABLE_SIGNALS
              if (errno == EINTR)
                {
                  nsh_output(vtbl, g_fmtsignalrecvd, argv[0]);
                }
              else
#endif
                {
                 /* Read error */

                  nsh_output(vtbl, g_fmtcmdfailed, argv[0], "write", NSH_ERRNO);
                }
              goto errout_with_wrfd;
            }
        }
      while (nbytesread > 0);
    }

errout_with_wrfd:
  close(wrfd);

errout_with_allocpath:
  if (allocpath)
    {
      free(allocpath);
    }

errout_with_destpath:
  if (destpath && !allocpath)
    {
      nsh_freefullpath(destpath);
    }

errout_with_rdfd:
  close(rdfd);

errout_with_srcpath:
  if (srcpath)
    {
      nsh_freefullpath(srcpath);
    }
errout:
  return ret;
}
int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
{
  FAR char *argv[MAX_ARGV_ENTRIES];
  FAR char *saveptr;
  FAR char *cmd;
#if CONFIG_NFILE_STREAMS > 0
  FAR char *redirfile = NULL;
  int       oflags = 0;
  int       fd = -1;
#endif
  int       argc;
  int       ret;

  /* Initialize parser state */

  memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
#ifndef CONFIG_NSH_DISABLEBG
  vtbl->np.np_bg       = false;
#endif
#if CONFIG_NFILE_STREAMS > 0
  vtbl->np.np_redirect = false;
#endif

  /* Parse out the command at the beginning of the line */

  saveptr = cmdline;
  cmd = nsh_argument(vtbl, &saveptr);

  /* Handler if-then-else-fi */

#ifndef CONFIG_NSH_DISABLESCRIPT
  if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0)
    {
      goto errout;
    }
#endif

  /* Handle nice */

#ifndef CONFIG_NSH_DISABLEBG
  if (nsh_nice(vtbl, &cmd, &saveptr) != 0)
    {
      goto errout;
    }
#endif

  /* Check if any command was provided -OR- if command processing is
   * currently disabled.
   */

#ifndef CONFIG_NSH_DISABLESCRIPT
  if (!cmd || !nsh_cmdenabled(vtbl))
#else
  if (!cmd)
#endif
    {
      /* An empty line is not an error and an unprocessed command cannot
       * generate an error, but neither should they change the last
       * command status.
       */

      return OK;
    }

  /* Parse all of the arguments following the command name.  The form
   * of argv is:
   *
   *   argv[0]:      The command name.
   *   argv[1]:      The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
   *   argv[argc-3]: Possibly '>' or '>>'
   *   argv[argc-2]: Possibly <file>
   *   argv[argc-1]: Possibly '&'
   *   argv[argc]:   NULL terminating pointer
   *
   * Maximum size is CONFIG_NSH_MAXARGUMENTS+5
   */

  argv[0] = cmd;
  for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
    {
      argv[argc] = nsh_argument(vtbl, &saveptr);
      if (!argv[argc])
        {
          break;
        }
    }

  argv[argc] = NULL;

  /* Check if the command should run in background */

#ifndef CONFIG_NSH_DISABLEBG
  if (argc > 1 && strcmp(argv[argc-1], "&") == 0)
    {
      vtbl->np.np_bg = true;
      argv[argc-1] = NULL;
      argc--;
    }
#endif

#if CONFIG_NFILE_STREAMS > 0
  /* Check if the output was re-directed using > or >> */

  if (argc > 2)
    {
      /* Check for redirection to a new file */

      if (strcmp(argv[argc-2], g_redirect1) == 0)
        {
          vtbl->np.np_redirect = true;
          oflags               = O_WRONLY|O_CREAT|O_TRUNC;
          redirfile            = nsh_getfullpath(vtbl, argv[argc-1]);
          argc                -= 2;
        }

      /* Check for redirection by appending to an existing file */

      else if (strcmp(argv[argc-2], g_redirect2) == 0)
        {
          vtbl->np.np_redirect = true;
          oflags               = O_WRONLY|O_CREAT|O_APPEND;
          redirfile            = nsh_getfullpath(vtbl, argv[argc-1]);
          argc                -= 2;
        }
    }
#endif

  /* Check if the maximum number of arguments was exceeded */

  if (argc > CONFIG_NSH_MAXARGUMENTS)
    {
      nsh_output(vtbl, g_fmttoomanyargs, cmd);
    }

  /* Does this command correspond to an application filename?
   * nsh_fileapp() returns:
   *
   *   -1 (ERROR)  if the application task corresponding to 'argv[0]' could not
   *               be started (possibly because it doesn not exist).
   *    0 (OK)     if the application task corresponding to 'argv[0]' was
   *               and successfully started.  If CONFIG_SCHED_WAITPID is
   *               defined, this return value also indicates that the
   *               application returned successful status (EXIT_SUCCESS)
   *    1          If CONFIG_SCHED_WAITPID is defined, then this return value
   *               indicates that the application task was spawned successfully
   *               but returned failure exit status.
   *
   * Note the priority if not effected by nice-ness.
   */

#ifdef CONFIG_NSH_FILE_APPS
  ret = nsh_fileapp(vtbl, argv[0], argv, redirfile, oflags);
  if (ret >= 0)
    {
      /* nsh_fileapp() returned 0 or 1.  This means that the builtin
       * command was successfully started (although it may not have ran
       * successfully).  So certainly it is not an NSH command.
       */

      /* Free the redirected output file path */

      if (redirfile)
        {
          nsh_freefullpath(redirfile);
        }

      /* Save the result:  success if 0; failure if 1 */

      return nsh_saveresult(vtbl, ret != OK);
    }

  /* No, not a built in command (or, at least, we were unable to start a
   * builtin command of that name).  Treat it like an NSH command.
   */

#endif

  /* Does this command correspond to a builtin command?
   * nsh_builtin() returns:
   *
   *   -1 (ERROR)  if the application task corresponding to 'argv[0]' could not
   *               be started (possibly because it doesn not exist).
   *    0 (OK)     if the application task corresponding to 'argv[0]' was
   *               and successfully started.  If CONFIG_SCHED_WAITPID is
   *               defined, this return value also indicates that the
   *               application returned successful status (EXIT_SUCCESS)
   *    1          If CONFIG_SCHED_WAITPID is defined, then this return value
   *               indicates that the application task was spawned successfully
   *               but returned failure exit status.
   *
   * Note the priority if not effected by nice-ness.
   */

#if defined(CONFIG_NSH_BUILTIN_APPS) && (!defined(CONFIG_NSH_FILE_APPS) || !defined(CONFIG_FS_BINFS))
#if CONFIG_NFILE_STREAMS > 0
  ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags);
#else
  ret = nsh_builtin(vtbl, argv[0], argv, NULL, 0);
#endif
  if (ret >= 0)
    {
      /* nsh_builtin() returned 0 or 1.  This means that the builtin
       * command was successfully started (although it may not have ran
       * successfully).  So certainly it is not an NSH command.
       */

#if CONFIG_NFILE_STREAMS > 0
      /* Free the redirected output file path */

      if (redirfile)
        {
          nsh_freefullpath(redirfile);
        }
#endif

      /* Save the result:  success if 0; failure if 1 */

      return nsh_saveresult(vtbl, ret != OK);
    }

  /* No, not a built in command (or, at least, we were unable to start a
   * builtin command of that name).  Treat it like an NSH command.
   */

#endif

#if CONFIG_NFILE_STREAMS > 0
  /* Redirected output? */

  if (vtbl->np.np_redirect)
    {
      /* Open the redirection file.  This file will eventually
       * be closed by a call to either nsh_release (if the command
       * is executed in the background) or by nsh_undirect if the
       * command is executed in the foreground.
       */

      fd = open(redirfile, oflags, 0666);
      nsh_freefullpath(redirfile);
      redirfile = NULL;

      if (fd < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
          goto errout;
        }
    }
#endif

  /* Handle the case where the command is executed in background.
   * However is app is to be started as builtin new process will
   * be created anyway, so skip this step.
   */

#ifndef CONFIG_NSH_DISABLEBG
  if (vtbl->np.np_bg)
    {
      struct sched_param param;
      struct nsh_vtbl_s *bkgvtbl;
      struct cmdarg_s *args;
      pthread_attr_t attr;
      pthread_t thread;

      /* Get a cloned copy of the vtbl with reference count=1.
       * after the command has been processed, the nsh_release() call
       * at the end of nsh_child() will destroy the clone.
       */

      bkgvtbl = nsh_clone(vtbl);
      if (!bkgvtbl)
        {
          goto errout_with_redirect;
        }

      /* Create a container for the command arguments */

      args = nsh_cloneargs(bkgvtbl, fd, argc, argv);
      if (!args)
        {
          nsh_release(bkgvtbl);
          goto errout_with_redirect;
        }

#if CONFIG_NFILE_STREAMS > 0
      /* Handle redirection of output via a file descriptor */

      if (vtbl->np.np_redirect)
        {
          (void)nsh_redirect(bkgvtbl, fd, NULL);
        }
#endif

      /* Get the execution priority of this task */

      ret = sched_getparam(0, &param);
      if (ret != 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO);
          nsh_releaseargs(args);
          nsh_release(bkgvtbl);
          goto errout;
        }

      /* Determine the priority to execute the command */

      if (vtbl->np.np_nice != 0)
        {
          int priority = param.sched_priority - vtbl->np.np_nice;
          if (vtbl->np.np_nice < 0)
            {
              int max_priority = sched_get_priority_max(SCHED_NSH);
              if (priority > max_priority)
                {
                  priority = max_priority;
                }
            }
          else
            {
              int min_priority = sched_get_priority_min(SCHED_NSH);
              if (priority < min_priority)
                {
                  priority = min_priority;
                }
            }

          param.sched_priority = priority;
        }

      /* Set up the thread attributes */

      (void)pthread_attr_init(&attr);
      (void)pthread_attr_setschedpolicy(&attr, SCHED_NSH);
      (void)pthread_attr_setschedparam(&attr, &param);

      /* Execute the command as a separate thread at the appropriate priority */

      ret = pthread_create(&thread, &attr, nsh_child, (pthread_addr_t)args);
      if (ret != 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", NSH_ERRNO_OF(ret));
          nsh_releaseargs(args);
          nsh_release(bkgvtbl);
          goto errout;
        }

      /* Detach from the pthread since we are not going to join with it.
       * Otherwise, we would have a memory leak.
       */

      (void)pthread_detach(thread);

      nsh_output(vtbl, "%s [%d:%d]\n", cmd, thread, param.sched_priority);
    }
  else
#endif
    {
#if CONFIG_NFILE_STREAMS > 0
      uint8_t save[SAVE_SIZE];

      /* Handle redirection of output via a file descriptor */

      if (vtbl->np.np_redirect)
        {
          nsh_redirect(vtbl, fd, save);
        }
#endif

      /* Then execute the command in "foreground" -- i.e., while the user waits
       * for the next prompt.  nsh_execute will return:
       *
       * -1 (ERRROR) if the command was unsuccessful
       *  0 (OK)     if the command was successful
       */

      ret = nsh_execute(vtbl, argc, argv);

#if CONFIG_NFILE_STREAMS > 0
      /* Restore the original output.  Undirect will close the redirection
       * file descriptor.
       */

      if (vtbl->np.np_redirect)
        {
          nsh_undirect(vtbl, save);
        }
#endif

      /* Mark errors so that it is possible to test for non-zero return values
       * in nsh scripts.
       */

      if (ret < 0)
        {
          goto errout;
        }
    }

  /* Return success if the command succeeded (or at least, starting of the
   * command task succeeded).
   */

  return nsh_saveresult(vtbl, false);

#ifndef CONFIG_NSH_DISABLEBG
errout_with_redirect:
#if CONFIG_NFILE_STREAMS > 0
  if (vtbl->np.np_redirect)
    {
      close(fd);
    }
#endif
#endif

errout:
  return nsh_saveresult(vtbl, true);
}
예제 #18
0
int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *loopdev  = NULL;
  char *filepath = NULL;
  bool  teardown = false;
  bool  readonly = false;
  off_t offset   = 0;
  bool  badarg   = false;
  int   ret      = ERROR;
  int   option;

  /* Get the losetup options:  Two forms are supported:
   *
   *   losetup -d <loop-device>
   *   losetup [-o <offset>] [-r] <loop-device> <filename>
   *
   * NOTE that the -o and -r options are accepted with the -d option, but
   * will be ignored.
   */

  while ((option = getopt(argc, argv, "d:o:r")) != ERROR)
    {
      switch (option)
        {
        case 'd':
          loopdev  = nsh_getfullpath(vtbl, optarg);
          teardown = true;
          break;

        case 'o':
          offset = atoi(optarg);
          break;

        case 'r':
          readonly = true;
          break;

        case '?':
        default:
          nsh_output(vtbl, g_fmtarginvalid, argv[0]);
          badarg = true;
          break;
        }
    }

  /* If a bad argument was encountered, then return without processing the command */

  if (badarg)
    {
      goto errout_with_paths;
    }

  /* If this is not a tear down operation, then additional command line
   * parameters are required.
   */

  if (!teardown)
    {
      /* There must be two arguments on the command line after the options */

      if (optind + 1 < argc)
        {
          loopdev = nsh_getfullpath(vtbl, argv[optind]);
          optind++;

          filepath = nsh_getfullpath(vtbl, argv[optind]);
          optind++;
        }
      else
        {
          nsh_output(vtbl, g_fmtargrequired, argv[0]);
          goto errout_with_paths;
        }
    }

  /* There should be nothing else on the command line */

  if (optind < argc)
   {
     nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
     goto errout_with_paths;
   }

  /* Perform the teardown operation */

  if (teardown)
    {
      /* Tear down the loop device. */

      ret = loteardown(loopdev);
      if (ret < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "loteardown", NSH_ERRNO_OF(-ret));
          goto errout_with_paths;
        }
    }
  else
    {
      /* Set up the loop device */

      ret = losetup(loopdev, filepath, 512, offset, readonly);
      if (ret < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "losetup", NSH_ERRNO_OF(-ret));
          goto errout_with_paths;
        }
    }

  /* Free memory */

errout_with_paths:
  if (loopdev)
    {
      free(loopdev);
    }

  if (filepath)
    {
      free(filepath);
    }
  return ret;
}
예제 #19
0
static inline int unaryexpression(FAR struct nsh_vtbl_s *vtbl, char **argv)
{
  struct stat buf;
  char *fullpath;
  int   ret;

  /* -n STRING */

  if (strcmp(argv[0], "-n") == 0)
    {
      /* Return true if the length of the string is non-zero */

      return strlen(argv[1]) != 0 ? TEST_TRUE : TEST_FALSE;
    }

  /* -z STRING */

  if (strcmp(argv[0], "-z") == 0)
    {
      /* Return true if the length of the string is zero */

      return strlen(argv[1]) == 0 ? TEST_TRUE : TEST_FALSE;
    }

  /* All of the remaining assume that the following argument is the
   * path to a file.
   */

  fullpath = nsh_getfullpath(vtbl, argv[1]);
  if (!fullpath)
    {
       return TEST_FALSE;
    }

  ret = stat(fullpath, &buf);
  nsh_freefullpath(fullpath);

  if (ret != 0)
    {
       /* The file does not exist (or another error occurred) -- return FALSE */

       return TEST_FALSE;
    }

  /* -b FILE */

  if (strcmp(argv[0], "-b") == 0)
    {
      /* Return true if the path is a block device */

      return S_ISBLK(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
    }

  /* -c FILE */

  if (strcmp(argv[0], "-c") == 0)
    {
      /* Return true if the path is a character device */

      return S_ISCHR(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
    }

  /* -d FILE */

  if (strcmp(argv[0], "-d") == 0)
    {
      /* Return true if the path is a directory */

      return S_ISDIR(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
    }

  /* -e FILE */

  if (strcmp(argv[0], "-e") == 0)
    {
      /* Return true if the file exists */

      return TEST_TRUE;
    }

  /* -f FILE */

  if (strcmp(argv[0], "-f") == 0)
    {
      /* Return true if the path refers to a regular file */

      return S_ISREG(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
    }

  /* -r FILE */

  if (strcmp(argv[0], "-r") == 0)
    {
      /* Return true if the file is readable */

      return (buf.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)) != 0 ? TEST_TRUE : TEST_FALSE;
    }

  /* -s FILE */

  if (strcmp(argv[0], "-s") == 0)
    {
      /* Return true if the size of the file is greater than zero */

      return buf.st_size > 0 ? TEST_TRUE : TEST_FALSE;
    }

  /* -w FILE */

  if (strcmp(argv[0], "-w") == 0)
    {
      /* Return true if the file is write-able */

      return (buf.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0 ? TEST_TRUE : TEST_FALSE;
    }

  /* Unrecognized operator */

  return TEST_ERROR;
}
예제 #20
0
static int cmd_codecs_proc(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv,
                           uint8_t mode, codec_callback_t func)
{
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
  static const unsigned char hex_chars[] = "0123456789abcdef";
  MD5_CTX ctx;
  unsigned char mac[16];
  char *pSrc;
  char *pDest;
#endif

  char *localfile = NULL;
  char *src_buffer = NULL;
  char *buffer = NULL;
  char *fullpath = NULL;
  const char *fmt;
  char *s_data;
  bool badarg = false;
  bool is_file = false;
  bool is_websafe=false;
  int option;
  int fd = -1;
  int buff_len = 0;
  int src_buff_len = 0;
  int i = 0;
  int ret = OK;

  /* Get the command options */

  while ((option = getopt(argc, argv, ":fw")) != ERROR)
    {
      switch (option)
        {
          case 'f':
            is_file = true;
            break;

#ifdef CONFIG_CODECS_BASE64
          case 'w':
            is_websafe = true;

            if (!(mode == CODEC_MODE_BASE64ENC || mode == CODEC_MODE_BASE64DEC))
              {
                badarg = true;
              }
            break;
#endif
          case ':':
            nsh_output(vtbl, g_fmtargrequired, argv[0]);
            badarg = true;
            break;

          case '?':
          default:
            nsh_output(vtbl, g_fmtarginvalid, argv[0]);
            badarg = true;
            break;
        }
    }

  /* If a bad argument was encountered, then return without processing the command */

  if (badarg)
    {
      return ERROR;
    }

  /* There should be exactly on parameter left on the command-line */

  if (optind == argc-1)
    {
      s_data = argv[optind];
    }
  else if (optind >= argc)
    {
      fmt = g_fmttoomanyargs;
      goto errout;
    }
  else
    {
      fmt = g_fmtargrequired;
      goto errout;
    }

#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
  if (mode == CODEC_MODE_HASH_MD5)
    {
      MD5Init(&ctx);
    }
#endif

  if (is_file)
    {
      /* Get the local file name */

      localfile = s_data;

      /* Get the full path to the local file */

      fullpath = nsh_getfullpath(vtbl, localfile);

      /* Open the local file for writing */

      fd = open(fullpath, O_RDONLY|O_TRUNC, 0644);
      if (fd < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
          ret = ERROR;
          goto exit;
        }

      src_buffer = malloc(CONFIG_NSH_CODECS_BUFSIZE+2);
#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
      if (mode == CODEC_MODE_BASE64ENC)
        {
          src_buff_len = CONFIG_NSH_CODECS_BUFSIZE / 3 * 3;
        }
      else
#endif
        {
          src_buff_len = CONFIG_NSH_CODECS_BUFSIZE;
        }

      buff_len = calc_codec_buffsize(src_buff_len+2, mode);
      buffer = malloc(buff_len);
      while(true)
        {
          memset(src_buffer, 0, src_buff_len+2);
          ret=read(fd, src_buffer, src_buff_len);
          if (ret < 0)
            {
              nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
              ret = ERROR;
              goto exit;
            }
          else if(ret==0)
            {
              break;
            }

#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
          if (mode == CODEC_MODE_URLDECODE)
            {
              if (src_buffer[src_buff_len-1]=='%')
                {
                  ret += read(fd,&src_buffer[src_buff_len],2);
                }
              else if (src_buffer[src_buff_len-2]=='%')
                {
                  ret += read(fd,&src_buffer[src_buff_len],1);
                }
            }
#endif
          memset(buffer, 0, buff_len);
          if (func)
            {
#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
              if (mode == CODEC_MODE_HASH_MD5)
                {
                  func(src_buffer, ret, (char *)&ctx, &buff_len,0);
                }
              else
#endif
                {
                  func(src_buffer, ret, buffer, &buff_len,(is_websafe)?1:0);
                  nsh_output(vtbl, "%s", buffer);
                }
            }

          buff_len = calc_codec_buffsize(src_buff_len+2, mode);
        }

#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
      if (mode == CODEC_MODE_HASH_MD5)
        {
          MD5Final(mac, &ctx);
          pSrc = (char *)&mac;
          pDest = buffer;
          for(i=0;i<16;i++,pSrc++)
            {
              *pDest++ = hex_chars[(*pSrc) >> 4];
              *pDest++ = hex_chars[(*pSrc) & 0x0f];
            }

          *pDest='\0';
          nsh_output(vtbl, "%s\n", buffer);
        }
#endif
      ret = OK;
      goto exit;
    }
예제 #21
0
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  char *source;
  char *target;
  char *filesystem = 0;
  bool badarg = false;
  int ret;

  /* Get the mount options */

  int option;
  while ((option = getopt(argc, argv, ":t:")) != ERROR)
    {
      switch (option)
        {
          case 't':
            filesystem = optarg;
            break;

          case ':':
            nsh_output(vtbl, g_fmtargrequired, argv[0]);
            badarg = true;
            break;

          case '?':
          default:
            nsh_output(vtbl, g_fmtarginvalid, argv[0]);
            badarg = true;
            break;
        }
    }

  /* If a bad argument was encountered, then return without processing the command */

  if (badarg)
    {
      return ERROR;
    }

  /* There are two required arguments after the options */

  if (optind + 2 < argc)
    {
      nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
      return ERROR;
    }
  else if (optind + 2 > argc)
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      return ERROR;
    }

  /* The source and target paths might be relative to the current
   * working directory.
   */

  source = nsh_getfullpath(vtbl, argv[optind]);
  if (!source)
    {
      return ERROR;
    }

  target = nsh_getfullpath(vtbl, argv[optind+1]);
  if (!target)
    {
      nsh_freefullpath(source);
      return ERROR;
    }

  /* Perform the mount */

  ret = mount(source, target, filesystem, 0, NULL);
  if (ret < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
    }

  nsh_freefullpath(source);
  nsh_freefullpath(target);
  return ret;
}
예제 #22
0
int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
{
  FAR char *argv[MAX_ARGV_ENTRIES];
  FAR char *saveptr;
  FAR char *cmd;
  FAR char *redirfile = NULL;
  int       fd = -1;
  int       oflags = 0;
  int       argc;
  int       ret;

  /* Initialize parser state */

  memset(argv, 0, MAX_ARGV_ENTRIES*sizeof(FAR char *));
#ifndef CONFIG_NSH_DISABLEBG
  vtbl->np.np_bg       = false;
#endif
  vtbl->np.np_redirect = false;

  /* Parse out the command at the beginning of the line */

  saveptr = cmdline;
  cmd = nsh_argument(vtbl, &saveptr);

  /* Handler if-then-else-fi */

#ifndef CONFIG_NSH_DISABLESCRIPT
  if (nsh_ifthenelse(vtbl, &cmd, &saveptr) != 0)
    {
      goto errout;
    }
#endif

  /* Handle nice */

#ifndef CONFIG_NSH_DISABLEBG
  if (nsh_nice(vtbl, &cmd, &saveptr) != 0)
    {
      goto errout;
    }
#endif

  /* Check if any command was provided -OR- if command processing is
   * currently disabled.
   */

#ifndef CONFIG_NSH_DISABLESCRIPT
  if (!cmd || !nsh_cmdenabled(vtbl))
#else
  if (!cmd)
#endif
    {
      /* An empty line is not an error and an unprocessed command cannot
       * generate an error, but neither should they change the last
       * command status.
       */

      return OK;
    }

  /* Parse all of the arguments following the command name.  The form
   * of argv is:
   *
   *   argv[0]:      The command name. 
   *   argv[1]:      The beginning of argument (up to NSH_MAX_ARGUMENTS)
   *   argv[argc-3]: Possibly '>' or '>>'
   *   argv[argc-2]: Possibly <file>
   *   argv[argc-1]: Possibly '&'
   *   argv[argc]:   NULL terminating pointer
   *
   * Maximum size is NSH_MAX_ARGUMENTS+5
   */

  argv[0] = cmd;
  for (argc = 1; argc < MAX_ARGV_ENTRIES-1; argc++)
    {
      argv[argc] = nsh_argument(vtbl, &saveptr);
      if (!argv[argc])
        {
          break;
        }
    }

  argv[argc] = NULL;

  /* Check if the command should run in background */

#ifndef CONFIG_NSH_DISABLEBG
  if (argc > 1 && strcmp(argv[argc-1], "&") == 0)
    {
      vtbl->np.np_bg = true;
      argv[argc-1] = NULL;
      argc--;
    }
#endif

  /* Check if the output was re-directed using > or >> */

  if (argc > 2)
    {
      /* Check for redirection to a new file */

      if (strcmp(argv[argc-2], g_redirect1) == 0)
        {
          vtbl->np.np_redirect = true;
          oflags               = O_WRONLY|O_CREAT|O_TRUNC;
          redirfile            = nsh_getfullpath(vtbl, argv[argc-1]);
          argc                -= 2;
        }

      /* Check for redirection by appending to an existing file */

      else if (strcmp(argv[argc-2], g_redirect2) == 0)
        {
          vtbl->np.np_redirect = true;
          oflags               = O_WRONLY|O_CREAT|O_APPEND;
          redirfile            = nsh_getfullpath(vtbl, argv[argc-1]);
          argc                -= 2;
        }
    }

  /* Redirected output? */

  if (vtbl->np.np_redirect)
    {
      /* Open the redirection file.  This file will eventually
       * be closed by a call to either nsh_release (if the command
       * is executed in the background) or by nsh_undirect if the
       * command is executed in the foreground.
       */

      fd = open(redirfile, oflags, 0666);
      nsh_freefullpath(redirfile);
      redirfile = NULL;

      if (fd < 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "open", NSH_ERRNO);
          goto errout;
        }
    }

  /* Check if the maximum number of arguments was exceeded */

  if (argc > NSH_MAX_ARGUMENTS)
    {
      nsh_output(vtbl, g_fmttoomanyargs, cmd);
    }

  /* Handle the case where the command is executed in background.
   * However is app is to be started as namedapp new process will
   * be created anyway, so skip this step. */

#ifndef CONFIG_NSH_DISABLEBG
  if (vtbl->np.np_bg
#ifdef CONFIG_NSH_BUILTIN_APPS
      && namedapp_isavail(argv[0]) < 0     
#endif
  )
    {
      struct sched_param param;
      struct nsh_vtbl_s *bkgvtbl;
      struct cmdarg_s *args;
      pthread_attr_t attr;
      pthread_t thread;

      /* Get a cloned copy of the vtbl with reference count=1.
       * after the command has been processed, the nsh_release() call
       * at the end of nsh_child() will destroy the clone.
       */

      bkgvtbl = nsh_clone(vtbl);
      if (!bkgvtbl)
        {
          goto errout_with_redirect;
        }

      /* Create a container for the command arguments */

      args = nsh_cloneargs(bkgvtbl, fd, argc, argv);
      if (!args)
        {
          nsh_release(bkgvtbl);
          goto errout_with_redirect;
        }

      /* Handle redirection of output via a file descriptor */

      if (vtbl->np.np_redirect)
        {
          (void)nsh_redirect(bkgvtbl, fd, NULL);
        }

      /* Get the execution priority of this task */

      ret = sched_getparam(0, &param);
      if (ret != 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "sched_getparm", NSH_ERRNO);
          nsh_releaseargs(args);
          nsh_release(bkgvtbl);
          goto errout;
        }

      /* Determine the priority to execute the command */

      if (vtbl->np.np_nice != 0)
        {
          int priority = param.sched_priority - vtbl->np.np_nice;
          if (vtbl->np.np_nice < 0)
            {
              int max_priority = sched_get_priority_max(SCHED_NSH);
              if (priority > max_priority)
                {
                  priority = max_priority;
                }
            }
          else
            {
              int min_priority = sched_get_priority_min(SCHED_NSH);
              if (priority < min_priority)
                {
                  priority = min_priority;
                }
            }
          param.sched_priority = priority;
        }

      /* Set up the thread attributes */

      (void)pthread_attr_init(&attr);
      (void)pthread_attr_setschedpolicy(&attr, SCHED_NSH);
      (void)pthread_attr_setschedparam(&attr, &param);

      /* Execute the command as a separate thread at the appropriate priority */

      ret = pthread_create(&thread, &attr, nsh_child, (pthread_addr_t)args);
      if (ret != 0)
        {
          nsh_output(vtbl, g_fmtcmdfailed, cmd, "pthread_create", NSH_ERRNO_OF(ret));
          nsh_releaseargs(args);
          nsh_release(bkgvtbl);
          goto errout;
        }

      nsh_output(vtbl, "%s [%d:%d]\n", cmd, thread, param.sched_priority);
    }
  else
#endif
    {
      uint8_t save[SAVE_SIZE];

      /* Handle redirection of output via a file descriptor */

      if (vtbl->np.np_redirect)
        {
          nsh_redirect(vtbl, fd, save);
        }

      /* Then execute the command in "foreground" -- i.e., while the user waits
       * for the next prompt.  nsh_execute will return:
       *
       * -1 (ERRROR) if the command was unsuccessful
       *  0 (OK)     if the command was successful
       *  1          if an application task was spawned successfully, but
       *             returned failure exit status.
       */

      ret = nsh_execute(vtbl, argc, argv);

      /* Restore the original output.  Undirect will close the redirection
       * file descriptor.
       */

      if (vtbl->np.np_redirect)
        {
          nsh_undirect(vtbl, save);
        }

      /* Treat both errors and non-zero return codes as "errors" so that
       * it is possible to test for non-zero returns in nsh scripts.
       */

      if (ret != OK)
        {
          goto errout;
        }
    }

  /* Return success if the command succeeded (or at least, starting of the
   * command task succeeded).
   */

  return nsh_saveresult(vtbl, false);

#ifndef CONFIG_NSH_DISABLEBG
errout_with_redirect:
  if (vtbl->np.np_redirect)
    {
      close(fd);
    }
#endif
errout:
  return nsh_saveresult(vtbl, true);
}
예제 #23
0
int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
  struct fat_format_s fmt = FAT_FORMAT_INITIALIZER;
  FAR char *fullpath;
  bool badarg;
  int option;
  int ret = ERROR;

  /* mkfatfs [-F <fatsize>] <block-driver> */

  badarg = false;
  while ((option = getopt(argc, argv, ":F:")) != ERROR)
    {
      switch (option)
        {
          case 'F':
            fmt.ff_fattype = atoi(optarg);
            if (fmt.ff_fattype != 0  && fmt.ff_fattype != 12 &&
                fmt.ff_fattype != 16 && fmt.ff_fattype != 32)
              {
                nsh_output(vtbl, g_fmtargrange, argv[0]);
                badarg = true;
              }
            break;

         case ':':
            nsh_output(vtbl, g_fmtargrequired, argv[0]);
            badarg = true;
            break;

          case '?':
          default:
            nsh_output(vtbl, g_fmtarginvalid, argv[0]);
            badarg = true;
            break;
        }
    }

  /* If a bad argument was encountered, then return without processing the command */

  if (badarg)
    {
      return ERROR;
    }

  /* There should be exactly one parameter left on the command-line */

  if (optind == argc-1)
    {
      fullpath = nsh_getfullpath(vtbl, argv[optind]);
      if (!fullpath)
        {
          nsh_output(vtbl, g_fmtcmdfailed, argv[0], "nsh_getfullpath",
                     NSH_ERRNO);
          return ERROR;
        }
    }
  else if (optind >= argc)
    {
      nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
      return ERROR;
    }
  else
    {
      nsh_output(vtbl, g_fmtargrequired, argv[0]);
      return ERROR;
    }

  /* Now format the FAT file system */

  ret = mkfatfs(fullpath, &fmt);
  if (ret < 0)
    {
      nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mkfatfs", NSH_ERRNO);
    }

  nsh_freefullpath(fullpath);
  return ret;
}