📄 nsh_fscmds.c
字号:
/**************************************************************************** * examples/nsh/nsh_fscmds.c * * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#include <sys/types.h>#if CONFIG_NFILE_DESCRIPTORS > 0# include <sys/stat.h># include <fcntl.h>#endif#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0# ifdef CONFIG_FS_FAT /* Need at least one filesytem in configuration */# include <sys/mount.h># endif#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <dirent.h>#include <limits.h>#include <libgen.h>#include <errno.h>#include "nsh.h"/**************************************************************************** * Definitions ****************************************************************************/#define LSFLAGS_SIZE 1#define LSFLAGS_LONG 2#define LSFLAGS_RECURSIVE 4/* The size of the I/O buffer may be specified in the * configs/<board-name>defconfig file -- provided that it is at least as * large as PATH_MAX. */#if CONFIG_NFILE_DESCRIPTORS > 0# ifdef CONFIG_NSH_IOBUFFERSIZE# if CONFIG_NSH_IOBUFFERSIZE > (PATH_MAX + 1)# define IOBUFFERSIZE CONFIG_NSH_IOBUFFERSIZE# else# define IOBUFFERSIZE (PATH_MAX + 1)# endif# else# define IOBUFFERSIZE 1024# endif# else# define IOBUFFERSIZE (PATH_MAX + 1)#endif/**************************************************************************** * Private Types ****************************************************************************/typedef int (*direntry_handler_t)(FAR void *, const char *, struct dirent *, void *);/**************************************************************************** * Private Function Prototypes ****************************************************************************//**************************************************************************** * Private Data ****************************************************************************/static char g_iobuffer[IOBUFFERSIZE];/**************************************************************************** * Public Data ****************************************************************************//**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: trim_dir ****************************************************************************/static void trim_dir(char *arg){ /* Skip any trailing '/' characters (unless it is also the leading '/') */ int len = strlen(arg) - 1; while (len > 0 && arg[len] == '/') { arg[len] = '\0'; len--; }}/**************************************************************************** * Name: getdirpath ****************************************************************************/static char *getdirpath(const char *path, const char *file){ /* Handle the case where all that is left is '/' */ if (strcmp(path, "/") == 0) { sprintf(g_iobuffer, "/%s", file); } else { sprintf(g_iobuffer, "%s/%s", path, file); } g_iobuffer[PATH_MAX] = '\0'; return strdup(g_iobuffer);}/**************************************************************************** * Name: foreach_direntry ****************************************************************************/#if CONFIG_NFILE_DESCRIPTORS > 0static int foreach_direntry(FAR void *handle, const char *cmd, const char *dirpath, direntry_handler_t handler, void *pvarg){ DIR *dirp; int ret = OK; /* Trim trailing '/' from directory names */#ifdef CONFIG_FULL_PATH trim_dir(arg);#endif /* Open the directory */ dirp = opendir(dirpath); if (!dirp) { /* Failed to open the directory */ nsh_output(handle, g_fmtnosuch, cmd, "directory", dirpath); return ERROR; } /* Read each directory entry */ for (;;) { struct dirent *entryp = readdir(dirp); if (!entryp) { /* Finished with this directory */ break; } /* Call the handler with this directory entry */ if (handler(handle, dirpath, entryp, pvarg) < 0) { /* The handler reported a problem */ ret = ERROR; break; } } closedir(dirp); return ret;}#endif/**************************************************************************** * Name: ls_handler ****************************************************************************/#if CONFIG_NFILE_DESCRIPTORS > 0static int ls_handler(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg){ unsigned int lsflags = (unsigned int)pvarg; int ret; /* Check if any options will require that we stat the file */ if ((lsflags & (LSFLAGS_SIZE|LSFLAGS_LONG)) != 0) { struct stat buf; char *fullpath = getdirpath(dirpath, entryp->d_name); /* Yes, stat the file */ ret = stat(fullpath, &buf); free(fullpath); if (ret != 0) { nsh_output(handle, g_fmtcmdfailed, "ls", "stat", NSH_ERRNO); return OK; } if ((lsflags & LSFLAGS_LONG) != 0) { char details[] = "----------"; if (S_ISDIR(buf.st_mode)) { details[0]='d'; } else if (S_ISCHR(buf.st_mode)) { details[0]='c'; } else if (S_ISBLK(buf.st_mode)) { details[0]='b'; } if ((buf.st_mode & S_IRUSR) != 0) { details[1]='r'; } if ((buf.st_mode & S_IWUSR) != 0) { details[2]='w'; } if ((buf.st_mode & S_IXUSR) != 0) { details[3]='x'; } if ((buf.st_mode & S_IRGRP) != 0) { details[4]='r'; } if ((buf.st_mode & S_IWGRP) != 0) { details[5]='w'; } if ((buf.st_mode & S_IXGRP) != 0) { details[6]='x'; } if ((buf.st_mode & S_IROTH) != 0) { details[7]='r'; } if ((buf.st_mode & S_IWOTH) != 0) { details[8]='w'; } if ((buf.st_mode & S_IXOTH) != 0) { details[9]='x'; } nsh_output(handle, " %s", details); } if ((lsflags & LSFLAGS_SIZE) != 0) { nsh_output(handle, "%8d", buf.st_size); } } /* then provide the filename that is common to normal and verbose output */#ifdef CONFIG_FULL_PATH nsh_output(handle, " %s/%s", arg, entryp->d_name);#else nsh_output(handle, " %s", entryp->d_name);#endif if (DIRENT_ISDIRECTORY(entryp->d_type)) { nsh_output(handle, "/\n"); } else { nsh_output(handle, "\n"); } return OK;}#endif/**************************************************************************** * Name: ls_recursive ****************************************************************************/#if CONFIG_NFILE_DESCRIPTORS > 0static int ls_recursive(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg){ /* Is this entry a directory? */ if (DIRENT_ISDIRECTORY(entryp->d_type)) { /* Yes.. */ char *newpath; newpath = getdirpath(dirpath, entryp->d_name); /* List the directory contents */ nsh_output(handle, "%s:\n", newpath); foreach_direntry(handle, "ls", newpath, ls_handler, pvarg); /* Then recurse to list each directory within the directory */ foreach_direntry(handle, "ls", newpath, ls_recursive, pvarg); free(newpath); } return OK;}#endif/**************************************************************************** * Public Functions ****************************************************************************//**************************************************************************** * Name: cmd_cat ****************************************************************************/#if CONFIG_NFILE_DESCRIPTORS > 0void cmd_cat(FAR void *handle, int argc, char **argv){ char buffer[1024]; /* Open the file for reading */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -