Imported Upstream version 1.9.5
[deb_libnfs.git] / utils / nfs-ls.c
CommitLineData
ee872606
RRS
1/*
2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2010
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#define _FILE_OFFSET_BITS 64
19#define _GNU_SOURCE
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#ifdef AROS
26#include "aros_compat.h"
27#endif
28
29#ifdef WIN32
30#include "win32_compat.h"
31#pragma comment(lib, "ws2_32.lib")
32WSADATA wsaData;
33#define PRId64 "ll"
34#else
35#include <inttypes.h>
36#include <string.h>
37#include <sys/stat.h>
38#include <sys/statvfs.h>
39#ifndef AROS
40#include <sys/statvfs.h>
41#endif
42#endif
43
44#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <stdint.h>
51#include <sys/types.h>
52#include <sys/stat.h>
53#include <fcntl.h>
ee872606
RRS
54#include "libnfs.h"
55#include "libnfs-raw.h"
56#include "libnfs-raw-mount.h"
57
58struct client {
59 char *server;
60 char *export;
61 uint32_t mount_port;
62 int is_finished;
63};
64
65int recursive = 0, summary = 0, discovery = 0;
66
67void print_usage(void)
68{
69 fprintf(stderr, "Usage: nfs-ls [-?|--help|--usage] [-R|--recursive] [-s|--summary] [-D|--discovery] <url>\n");
70}
71
72int process_server(const char *server) {
73 struct exportnode *exports;
74 struct exportnode *export;
75
76 exports = mount_getexports(server);
77 if (exports == NULL) {
78 fprintf(stderr, "Failed to get exports for server %s.\n", server);
79 return -1;
80 }
81 for (export=exports; export; export = export->ex_next) {
82 printf("nfs://%s%s\n", server, export->ex_dir);
83 }
84 mount_free_export_list(exports);
85 return 0;
86}
87
88void process_dir(struct nfs_context *nfs, char *dir, int level) {
89 int ret;
90 struct nfsdirent *nfsdirent;
91 struct statvfs svfs;
92 struct nfsdir *nfsdir;
ee872606
RRS
93
94 if (!level) {
95 printf("Recursion detected!\n");
96 exit(10);
97 }
98
99 ret = nfs_opendir(nfs, dir, &nfsdir);
100 if (ret != 0) {
101 printf("Failed to opendir(\"%s\") %s\n", dir, nfs_get_error(nfs));
102 exit(10);
103 }
104 while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) {
105 char path[1024];
106
107 if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) {
108 continue;
109 }
ee872606 110 snprintf(path, 1024, "%s/%s", dir, nfsdirent->name);
ee872606 111
f1f22dbf 112 switch (nfsdirent->mode & S_IFMT) {
ee872606
RRS
113#ifndef WIN32
114 case S_IFLNK:
115 printf("l");
116 break;
117#endif
118 case S_IFREG:
119 printf("-");
120 break;
121 case S_IFDIR:
122 printf("d");
123 break;
124 case S_IFCHR:
125 printf("c");
126 break;
127 case S_IFBLK:
128 printf("b");
129 break;
130 }
131 printf("%c%c%c",
f1f22dbf
RRS
132 "-r"[!!(nfsdirent->mode & S_IRUSR)],
133 "-w"[!!(nfsdirent->mode & S_IWUSR)],
134 "-x"[!!(nfsdirent->mode & S_IXUSR)]
ee872606
RRS
135 );
136 printf("%c%c%c",
f1f22dbf
RRS
137 "-r"[!!(nfsdirent->mode & S_IRGRP)],
138 "-w"[!!(nfsdirent->mode & S_IWGRP)],
139 "-x"[!!(nfsdirent->mode & S_IXGRP)]
ee872606
RRS
140 );
141 printf("%c%c%c",
f1f22dbf
RRS
142 "-r"[!!(nfsdirent->mode & S_IROTH)],
143 "-w"[!!(nfsdirent->mode & S_IWOTH)],
144 "-x"[!!(nfsdirent->mode & S_IXOTH)]
ee872606 145 );
f1f22dbf
RRS
146 printf(" %2d", (int)nfsdirent->nlink);
147 printf(" %5d", (int)nfsdirent->uid);
148 printf(" %5d", (int)nfsdirent->gid);
149 printf(" %12" PRId64, nfsdirent->size);
ee872606
RRS
150
151 printf(" %s\n", path + 1);
152
f1f22dbf 153 if (recursive && (nfsdirent->mode & S_IFMT) == S_IFDIR) {
ee872606
RRS
154 process_dir(nfs, path, level - 1);
155 }
156 }
157 nfs_closedir(nfs, nfsdir);
158}
159
160int main(int argc, char *argv[])
161{
162 struct nfs_context *nfs = NULL;
163 int i, ret = 1, res;
164 uint64_t offset;
165 struct client client;
166 struct statvfs stvfs;
f1f22dbf 167 struct nfs_url *url = NULL;
ee872606
RRS
168 exports export, tmp;
169
170#ifdef WIN32
171 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
172 printf("Failed to start Winsock2\n");
173 exit(10);
174 }
175#endif
176
177#ifdef AROS
178 aros_init_socket();
179#endif
180
181 if (argc < 2) {
182 fprintf(stderr, "No URL specified.\n");
183 goto finished;
184 }
185
186 for (i=1; i < argc -1; i++) {
187 if (!strcmp(argv[i], "-R") || !strcmp(argv[i], "--recursive")) {
188 recursive++;
189 } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--summary")) {
190 summary++;
191 } else if (!strcmp(argv[i], "-D") || !strcmp(argv[i], "--discovery")) {
192 discovery++;
193 } else{
194 goto finished;
195 }
196 }
197
198 nfs = nfs_init_context();
199 if (nfs == NULL) {
200 printf("failed to init context\n");
201 goto finished;
202 }
203
204 if (discovery) {
205 url = nfs_parse_url_incomplete(nfs, argv[argc - 1]);
206 if (url == NULL) {
207 fprintf(stderr, "%s\n", nfs_get_error(nfs));
208 goto finished;
209 }
210 if (!url->server) {
211 struct nfs_server_list *srvrs;
212 struct nfs_server_list *srv;
213
214 srvrs = nfs_find_local_servers();
215 if (srvrs == NULL) {
216 fprintf(stderr, "Failed to find local servers.\n");
217 goto finished;
218 }
219 for (srv=srvrs; srv; srv = srv->next) {
220 if (recursive) {
221 process_server(srv->addr);
222 } else {
223 printf("nfs://%s\n", srv->addr);
224 }
225 }
226 free_nfs_srvr_list(srvrs);
227 ret = 0;
228 goto finished;
229 }
230 if (url->server && !url->path) {
231 ret = process_server(url->server);
232 goto finished;
233 }
234 nfs_destroy_url(url);
235 }
236
237 url = nfs_parse_url_dir(nfs, argv[argc - 1]);
238 if (url == NULL) {
239 fprintf(stderr, "%s\n", nfs_get_error(nfs));
240 goto finished;
241 }
242
243 client.server = url->server;
244 client.export = url->path;
245 client.is_finished = 0;
246
247 if ((ret = nfs_mount(nfs, client.server, client.export)) != 0) {
248 fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs));
249 goto finished;
250 }
251
252 process_dir(nfs, "", 16);
253
254 if (summary) {
255 if (nfs_statvfs(nfs, "", &stvfs) != 0) {
256 goto finished;
257 }
258 printf("\n%12" PRId64 " of %12" PRId64 " bytes free.\n",
259 stvfs.f_frsize * stvfs.f_bfree, stvfs.f_frsize * stvfs.f_blocks);
260 }
261
262 ret = 0;
263finished:
264 if (ret > 0) {
265 print_usage();
266 }
267 nfs_destroy_url(url);
268 if (nfs != NULL) {
269 nfs_destroy_context(nfs);
270 }
271 return ret;
272}