~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to uspace/app/bdsh/cmds/modules/ls/ls.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
 
2
 * All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 * Redistributions of source code must retain the above copyright notice, this
 
8
 * list of conditions and the following disclaimer.
 
9
 *
 
10
 * Redistributions in binary form must reproduce the above copyright notice,
 
11
 * this list of conditions and the following disclaimer in the documentation
 
12
 * and/or other materials provided with the distribution.
 
13
 *
 
14
 * Neither the name of the original program's authors nor the names of its
 
15
 * contributors may be used to endorse or promote products derived from this
 
16
 * software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
28
 * POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
 
 
31
/* NOTE:
 
32
 * This is a bit of an ugly hack, working around the absence of fstat / etc.
 
33
 * As more stuff is completed and exposed in libc, this will improve */
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <unistd.h>
 
38
#include <dirent.h>
 
39
#include <fcntl.h>
 
40
#include <sys/types.h>
 
41
#include <sys/stat.h>
 
42
#include <string.h>
 
43
 
 
44
#include "errors.h"
 
45
#include "config.h"
 
46
#include "util.h"
 
47
#include "entry.h"
 
48
#include "ls.h"
 
49
#include "cmds.h"
 
50
 
 
51
static char *cmdname = "ls";
 
52
 
 
53
static void ls_scan_dir(const char *d, DIR *dirp)
 
54
{
 
55
        struct dirent *dp;
 
56
        char *buff;
 
57
 
 
58
        if (! dirp)
 
59
                return;
 
60
 
 
61
        buff = (char *)malloc(PATH_MAX);
 
62
        if (NULL == buff) {
 
63
                cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
 
64
                return;
 
65
        }
 
66
 
 
67
        while ((dp = readdir(dirp))) {
 
68
                memset(buff, 0, sizeof(buff));
 
69
                /* Don't worry if inserting a double slash, this will be fixed by
 
70
                 * absolutize() later with subsequent calls to open() or readdir() */
 
71
                snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
 
72
                ls_print(dp->d_name, buff);
 
73
        }
 
74
 
 
75
        free(buff);
 
76
 
 
77
        return;
 
78
}
 
79
 
 
80
/* ls_print currently does nothing more than print the entry.
 
81
 * in the future, we will likely pass the absolute path, and
 
82
 * some sort of ls_options structure that controls how each
 
83
 * entry is printed and what is printed about it.
 
84
 *
 
85
 * Now we just print basic DOS style lists */
 
86
 
 
87
static void ls_print(const char *name, const char *pathname)
 
88
{
 
89
        struct stat s;
 
90
        int rc;
 
91
 
 
92
        rc = stat(pathname, &s);
 
93
        if (rc != 0) {
 
94
                /* Odd chance it was deleted from the time readdir() found it */
 
95
                printf("ls: skipping bogus node %s\n", pathname);
 
96
                printf("rc=%d\n", rc);
 
97
                return;
 
98
        }
 
99
        
 
100
        if (s.is_file)
 
101
                printf("%-40s\t%llu\n", name, (long long) s.size);
 
102
        else
 
103
                printf("%-40s\n", name);
 
104
 
 
105
        return;
 
106
}
 
107
 
 
108
void help_cmd_ls(unsigned int level)
 
109
{
 
110
        if (level == HELP_SHORT) {
 
111
                printf("`%s' lists files and directories.\n", cmdname);
 
112
        } else {
 
113
                help_cmd_ls(HELP_SHORT);
 
114
                printf("  `%s' [path], if no path is given the current "
 
115
                                "working directory is used.\n", cmdname);
 
116
        }
 
117
 
 
118
        return;
 
119
}
 
120
 
 
121
int cmd_ls(char **argv)
 
122
{
 
123
        unsigned int argc;
 
124
        struct stat s;
 
125
        char *buff;
 
126
        DIR *dirp;
 
127
 
 
128
        argc = cli_count_args(argv);
 
129
 
 
130
        buff = (char *) malloc(PATH_MAX);
 
131
        if (NULL == buff) {
 
132
                cli_error(CL_ENOMEM, "%s: ", cmdname);
 
133
                return CMD_FAILURE;
 
134
        }
 
135
        memset(buff, 0, sizeof(buff));
 
136
 
 
137
        if (argc == 1)
 
138
                getcwd(buff, PATH_MAX);
 
139
        else
 
140
                str_cpy(buff, PATH_MAX, argv[1]);
 
141
 
 
142
        if (stat(buff, &s)) {
 
143
                cli_error(CL_ENOENT, buff);
 
144
                free(buff);
 
145
                return CMD_FAILURE;
 
146
        }
 
147
 
 
148
        if (s.is_file) {
 
149
                ls_print(buff, buff);
 
150
        } else {
 
151
                dirp = opendir(buff);
 
152
                if (!dirp) {
 
153
                        /* May have been deleted between scoping it and opening it */
 
154
                        cli_error(CL_EFAIL, "Could not stat %s", buff);
 
155
                        free(buff);
 
156
                        return CMD_FAILURE;
 
157
                }
 
158
                ls_scan_dir(buff, dirp);
 
159
                closedir(dirp);
 
160
        }
 
161
 
 
162
        free(buff);
 
163
 
 
164
        return CMD_SUCCESS;
 
165
}
 
166