FreeNOS
ListFiles.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <dirent.h>
21#include <string.h>
22#include <errno.h>
23#include <unistd.h>
24#include <sys/stat.h>
25#include <limits.h>
26#include <libgen.h>
27#include <TerminalCodes.h>
28#include "ListFiles.h"
29
30ListFiles::ListFiles(int argc, char **argv)
31 : POSIXApplication(argc, argv)
32{
33 parser().setDescription("List files on the filesystem");
34 parser().registerPositional("FILE", "Target file to list", 0);
35 parser().registerFlag('l', "long", "List files in long output format");
36 parser().registerFlag('a', "all", "List all files on the filesystem");
37 parser().registerFlag('n', "no-color", "Set to disable terminal color output");
38}
39
43
45{
46 const Vector<Argument *> & positionals = arguments().getPositionals();
47 Result result = Success, ret = Success;
48
49 // List files provided on the command-line, if any
50 if (positionals.count() > 0)
51 {
52 for (Size i = 0; i < positionals.count(); i++)
53 {
54 result = printFiles(positionals[i]->getValue());
55
56 // Update the return result
57 if (result != Success)
58 {
59 ret = result;
60 }
61 }
62 }
63 // Otherwise, list the current directory
64 else
65 {
66 char path[PATH_MAX];
67 getcwd(path, sizeof(path));
68
69 ret = printFiles(path);
70 }
71
72 // Done
73 return ret;
74}
75
77{
78 struct dirent *dent;
79 struct stat st;
80 char tmp[PATH_MAX];
81 String out;
82 DIR *d;
83 Result r = Success;
84
85 // Retrieve file status
86 if (stat(*path, &st) != 0)
87 {
88 ERROR("failed to stat '" << *path << "': " << strerror(errno));
89 return IOError;
90 }
91
92 // Is the given file a directory?
93 if (S_ISDIR(st.st_mode))
94 {
95 // Attempt to open the directory
96 if (!(d = opendir(*path)))
97 {
98 ERROR("failed to open '" << *path << "': " << strerror(errno));
99 return IOError;
100 }
101
102 // Read directory
103 while ((dent = readdir(d)))
104 {
105 // Construct full path
106 snprintf(tmp, sizeof(tmp),
107 "%s/%s", *path, dent->d_name);
108
109 if ((r = printSingleFile(tmp, out)) != Success)
110 break;
111 }
112 // Close it
113 closedir(d);
114 }
115 // The given file is not a directory
116 else
117 {
118 r = printSingleFile(path, out);
119 }
120
121 // Final newline
122 if (!arguments().get("long"))
123 out << "\r\n";
124
125 // Write to standard output
126 write(1, *out, out.length());
127
128 // Success
129 return r;
130}
131
133{
134 const bool color = arguments().get("no-color") == ZERO;
135 struct stat st;
136
137 // Retrieve file status
138 if (stat(*path, &st) != 0)
139 {
140 ERROR("failed to stat '" << *path << "': " << strerror(errno));
141 return IOError;
142 }
143
144 // Apply long output
145 if (arguments().get("long"))
146 {
147 if (color)
148 {
149 out << WHITE;
150 }
151 out << (st.st_mode & S_IRUSR ? "r" : "-");
152 out << (st.st_mode & S_IWUSR ? "w" : "-");
153 out << (st.st_mode & S_IXUSR ? "x" : "-");
154 out << (st.st_mode & S_IRGRP ? "r" : "-");
155 out << (st.st_mode & S_IWGRP ? "w" : "-");
156 out << (st.st_mode & S_IXGRP ? "x" : "-");
157 out << (st.st_mode & S_IROTH ? "r" : "-");
158 out << (st.st_mode & S_IWOTH ? "w" : "-");
159 out << (st.st_mode & S_IXOTH ? "x" : "-");
160
161 out << " uid:" << st.st_uid << " ";
162 out.pad(23);
163
164 out << " gid:" << st.st_gid << " ";
165 out.pad(33);
166
167 out << " " << st.st_size << " ";
168 out.pad(43);
169 }
170
171 // Apply coloring
172 if (color)
173 {
174 if (S_ISDIR(st.st_mode))
175 out << BLUE;
176
177 else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
178 out << YELLOW;
179
180 // Is the file executable?
181 else if (st.st_mode & 0100)
182 out << GREEN;
183 else
184 out << WHITE;
185 }
186
187 out << basename((char *) *path) << " ";
188
189 if (color)
190 {
191 out << WHITE;
192 }
193
194 // Long output needs a newline
195 if (arguments().get("long"))
196 out << "\r\n";
197
198 // Done
199 return Success;
200}
Result
Result codes.
Definition Application.h:54
const ArgumentContainer & arguments() const
Get program arguments.
ArgumentParser & parser()
Get program arguments parser.
const Vector< Argument * > & getPositionals() const
Get positional arguments.
const char * get(const char *name) const
Get argument by name.
void setDescription(const String &desc)
Set program description.
Result registerPositional(const char *name, const char *description, Size count=1)
Register a positional argument.
Result registerFlag(char arg, const char *name, const char *description)
Register a flag Argument.
Result printSingleFile(const String &path, String &out) const
List single file on the filesystem.
ListFiles(int argc, char **argv)
Constructor.
Definition ListFiles.cpp:30
virtual Result exec()
Execute the application.
Definition ListFiles.cpp:44
virtual ~ListFiles()
Destructor.
Definition ListFiles.cpp:40
Result printFiles(const String &path) const
List files on the filesystem.
Definition ListFiles.cpp:76
POSIX-compatible application.
Abstraction of strings.
Definition String.h:42
Size length() const
Same as count().
Definition String.cpp:105
String & pad(const Size length)
Pad line with trailing whitespace.
Definition String.cpp:332
Vectors are dynamically resizeable Arrays.
Definition Vector.h:42
virtual Size count() const
Returns the number of items inside the Vector.
Definition Vector.h:204
#define S_IXGRP
Execute/search permission, group.
Definition stat.h:118
#define S_IROTH
Read permission, others.
Definition stat.h:124
C struct dirent * readdir(DIR *dirp)
Read a directory.
Definition readdir.cpp:21
#define S_IXOTH
Execute/search permission, others.
Definition stat.h:130
#define S_IRGRP
Read permission, group.
Definition stat.h:112
C char * strerror(int errnum)
The strerror function maps the number in errnum to a message string.
Definition strerror.cpp:20
#define S_IWOTH
Write permission, others.
Definition stat.h:127
C int errno
The lvalue errno is used by many functions to return error values.
#define S_ISDIR(m)
Test for a directory.
Definition stat.h:155
#define S_ISBLK(m)
Test for a block special file.
Definition stat.h:149
#define S_ISCHR(m)
Test for a character special file.
Definition stat.h:152
C char * basename(char *path)
Return the last component of a pathname.
Definition basename.cpp:21
#define S_IRUSR
Read permission, owner.
Definition stat.h:100
C DIR * opendir(const char *dirname)
Open directory associated with file descriptor.
Definition opendir.cpp:27
C ssize_t write(int fildes, const void *buf, size_t nbyte)
Write on a file.
Definition write.cpp:22
C char * getcwd(char *buf, size_t size)
Get the pathname of the current working directory.
Definition getcwd.cpp:24
C int snprintf(char *buffer, unsigned int size, const char *fmt,...)
Write a formatted string into a buffer.
Definition snprintf.cpp:22
#define S_IWUSR
Write permission, owner.
Definition stat.h:103
#define S_IWGRP
Write permission, group.
Definition stat.h:115
#define PATH_MAX
Maximum file path length.
Definition limits.h:37
#define S_IXUSR
Execute/search permission, owner.
Definition stat.h:106
C int closedir(DIR *dirp)
Close a directory stream.
Definition closedir.cpp:22
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
#define BLUE
#define WHITE
#define YELLOW
#define GREEN
A type representing a directory stream.
Definition dirent.h:95
Represents a directory entry.
Definition dirent.h:65
char d_name[DIRLEN]
Name of entry.
Definition dirent.h:67
The <sys/stat.h> header shall define the stat structure.
Definition stat.h:177
off_t st_size
For regular files, the file size in bytes.
Definition stat.h:226
uid_t st_uid
User ID of file.
Definition stat.h:209
mode_t st_mode
Mode of file.
Definition stat.h:203
gid_t st_gid
Group ID of file.
Definition stat.h:212