wc: Added wc
[mutos-utils.git] / ls.c
blobdb62d455f56387a5b92b6b8feda67ceed98095f6
1 /*
2 Copyright © 2013 Alastair Stuart
4 This program is open source 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.
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.
15 #include <errno.h>
16 #include <stdbool.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
21 #include <dirent.h>
22 #include <getopt.h>
23 #include <sys/types.h>
25 #define VERSION "0.01"
27 struct {
28 bool all;
29 } flags;
31 int string_cmp(const void *a, const void *b)
33 return strcasecmp(*(char* const*) a, *(char* const*) b);
36 int list_dir(char* dirname, bool multiple)
38 DIR *dp = NULL;
39 struct dirent *ep = NULL;
41 size_t number = 0;
43 dp = opendir(dirname);
45 if (dp) {
46 while ((ep = readdir(dp)))
48 number++;
50 closedir(dp);
53 char* entries[number];
55 dp = opendir(dirname);
56 if (dp) {
57 for (size_t i = 0; (ep = readdir(dp)) && i < number; i++)
59 if (ep->d_type == DT_DIR) {
60 entries[i] = strcat(ep->d_name, "/");
61 } else {
62 entries[i] = ep->d_name;
65 closedir(dp);
66 } else {
67 return errno;
70 qsort(entries, number, sizeof(char*), string_cmp);
72 if (multiple) {
73 printf("%s:\n", dirname);
75 for (size_t i = 0; i < number; i++)
77 if (entries[i][0] == '.' && flags.all) {
78 printf("%s\n", entries[i]);
81 if (entries[i][0] != '.') {
82 printf("%s\n", entries[i]);
86 return 0;
89 void usage(char* program)
91 printf("Usage: %s [options]\n", program);
92 printf("Lists directory contents.\n"
93 "\n"
94 " -a, --all Show hidden files also.\n"
95 "\n"
96 " --help Print this message.\n"
97 " --version Show version info.\n");
100 int main(int argc, char* argv[])
102 bool errors = false;
104 flags.all = false;
105 static struct option long_options[] = {
106 {"all", no_argument, NULL, 'a'},
107 {"help", no_argument, NULL, 1},
108 {"version", no_argument, NULL, 2},
109 {NULL, 0, NULL, 0}
112 int c = 0;
113 while ((c = getopt_long(argc, argv, "a",
114 long_options, NULL)) != -1)
116 switch (c)
118 case 'a':
119 flags.all = true;
120 break;
121 case 1:
122 usage(argv[0]);
123 return 0;
124 case 2:
125 printf("ls (mutos) v"VERSION"\n");
126 return 0;
127 default:
128 fprintf(stderr,"Run '%s --help' for usage.\n",
129 argv[0]);
130 return 1;
134 if ((argc - optind) == 0) {
135 if (list_dir("./", false) != 0) {
136 fprintf(stderr, "%s: %s: %s\n",
137 argv[0], strerror(errno), realpath("./", NULL));
138 return 1;
140 } else if ((argc - optind) == 1) {
141 if (list_dir(argv[optind], false) != 0) {
142 fprintf(stderr, "%s: %s: %s\n",
143 argv[0], strerror(errno), realpath("./", NULL));
144 return 1;
148 for (int i = optind; i < argc; i++)
150 if (list_dir(argv[i], true) != 0) {
151 fprintf(stderr, "%s: %s: %s\n",
152 argv[0], strerror(errno), argv[i]);
153 errors = true;
154 } else if (i != argc - 1) {
155 printf("\n");
159 if (errors) {
160 return 1;
161 } else {
162 return 0;