Change the sync example to perform a 'ls -l' on an NFS URL
[deb_libnfs.git] / examples / nfsclient-sync.c
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 /* Example program using the highlevel sync interface
22 */
23 #ifdef WIN32
24 #include "win32_compat.h"
25 #else
26 #include <string.h>
27 #include <fcntl.h>
28 #include <sys/stat.h>
29 #include <sys/statvfs.h>
30 #endif
31
32
33 #if defined(WIN32)
34 #pragma comment(lib, "ws2_32.lib")
35 WSADATA wsaData;
36 #else
37 #include <sys/statvfs.h>
38 #include <unistd.h>
39 #endif
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <stdint.h>
44 #include <inttypes.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include <fcntl.h>
48 #include "libnfs-zdr.h"
49 #include "libnfs.h"
50 #include <rpc/rpc.h> /* for authunix_create() */
51 #include <popt.h>
52 #include "libnfs-raw.h"
53 #include "libnfs-raw-mount.h"
54
55 struct client {
56 char *server;
57 char *export;
58 uint32_t mount_port;
59 int is_finished;
60 };
61
62
63 char buf[3*1024*1024+337];
64
65 void print_usage(void)
66 {
67 fprintf(stderr, "Usage: nfsclient-sync [-?|--help] [--usage] <url>\n");
68 }
69
70 void print_help(void)
71 {
72 fprintf(stderr, "Usage: nfsclient-sync [OPTION...] <url>\n");
73 fprintf(stderr, "\n");
74 fprintf(stderr, "Help options:\n");
75 fprintf(stderr, " -?, --help Show this help message\n");
76 fprintf(stderr, " --usage Display brief usage message\n");
77 fprintf(stderr, "\n");
78 fprintf(stderr, "NFS URL format : nfs://<server>/<export-path>\n");
79 fprintf(stderr, "\n");
80 fprintf(stderr, "<host> is either of:\n");
81 fprintf(stderr, " \"hostname\" nfs.example\n");
82 fprintf(stderr, " \"ipv4-address\" 10.1.1.27\n");
83 fprintf(stderr, " \"ipv6-address\" [fce0::1]\n");
84 }
85
86 int main(int argc, char *argv[])
87 {
88 struct nfs_context *nfs = NULL;
89 int i, ret, res;
90 uint64_t offset;
91 struct client client;
92 struct stat st;
93 struct nfsfh *nfsfh;
94 struct nfsdir *nfsdir;
95 struct nfsdirent *nfsdirent;
96 struct statvfs svfs;
97 exports export, tmp;
98 int show_help = 0, show_usage = 0;
99 poptContext pc;
100 const char **extra_argv;
101 int extra_argc = 0;
102 const char *url = NULL;
103 char *server = NULL, *path = NULL, *strp;
104
105 struct poptOption popt_options[] = {
106 { "help", '?', POPT_ARG_NONE, &show_help, 0, "Show this help message", NULL },
107 { "usage", 0, POPT_ARG_NONE, &show_usage, 0, "Display brief usage message", NULL },
108 POPT_TABLEEND
109 };
110
111 #if defined(WIN32)
112 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
113 printf("Failed to start Winsock2\n");
114 exit(10);
115 }
116 #endif
117
118 pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_POSIXMEHARDER);
119 if ((res = poptGetNextOpt(pc)) < -1) {
120 fprintf(stderr, "Failed to parse option : %s %s\n",
121 poptBadOption(pc, 0), poptStrerror(res));
122 exit(10);
123 }
124 extra_argv = poptGetArgs(pc);
125 if (extra_argv) {
126 url = *extra_argv;
127 extra_argv++;
128 while (extra_argv[extra_argc]) {
129 extra_argc++;
130 }
131 }
132 poptFreeContext(pc);
133
134 if (show_help != 0) {
135 print_help();
136 exit(0);
137 }
138
139 if (show_usage != 0) {
140 print_usage();
141 exit(0);
142 }
143
144 if (url == NULL) {
145 fprintf(stderr, "No URL specified.\n");
146 print_usage();
147 exit(0);
148 }
149
150 if (strncmp(url, "nfs://", 6)) {
151 fprintf(stderr, "Invalid URL specified.\n");
152 print_usage();
153 exit(0);
154 }
155
156 server = strdup(url + 6);
157 if (server == NULL) {
158 fprintf(stderr, "Failed to strdup server string\n");
159 exit(10);
160 }
161 if (server[0] == '/' || server[0] == '\0') {
162 fprintf(stderr, "Invalid server string.\n");
163 free(server);
164 exit(10);
165 }
166 strp = strchr(server, '/');
167 if (strp == NULL) {
168 fprintf(stderr, "Invalid URL specified.\n");
169 print_usage();
170 free(server);
171 exit(0);
172 }
173 path = strdup(strp);
174 if (path == NULL) {
175 fprintf(stderr, "Failed to strdup server string\n");
176 free(server);
177 exit(10);
178 }
179 if (path[0] != '/') {
180 fprintf(stderr, "Invalid path.\n");
181 free(server);
182 free(path);
183 exit(10);
184 }
185 *strp = 0;
186
187 client.server = server;
188 client.export = path;
189 client.is_finished = 0;
190
191
192 nfs = nfs_init_context();
193 if (nfs == NULL) {
194 printf("failed to init context\n");
195 goto finished;
196 }
197
198 ret = nfs_mount(nfs, client.server, client.export);
199 if (ret != 0) {
200 printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs));
201 goto finished;
202 }
203
204
205 ret = nfs_opendir(nfs, "/", &nfsdir);
206 if (ret != 0) {
207 printf("Failed to opendir(\"/\")\n", nfs_get_error(nfs));
208 exit(10);
209 }
210 while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) {
211 char path[1024];
212
213 if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) {
214 continue;
215 }
216
217 snprintf(path, 1024, "%s/%s", "/", nfsdirent->name);
218 ret = nfs_stat(nfs, path, &st);
219 if (ret != 0) {
220 fprintf(stderr, "Failed to stat(%s) %s\n", path, nfs_get_error(nfs));
221 continue;
222 }
223
224 switch (st.st_mode & S_IFMT) {
225 case S_IFLNK:
226 case S_IFREG:
227 printf("-");
228 break;
229 case S_IFDIR:
230 printf("d");
231 break;
232 case S_IFCHR:
233 printf("c");
234 break;
235 case S_IFBLK:
236 printf("b");
237 break;
238 }
239 printf("%c%c%c",
240 "-r"[!!(st.st_mode & S_IRUSR)],
241 "-w"[!!(st.st_mode & S_IWUSR)],
242 "-x"[!!(st.st_mode & S_IXUSR)]
243 );
244 printf("%c%c%c",
245 "-r"[!!(st.st_mode & S_IRGRP)],
246 "-w"[!!(st.st_mode & S_IWGRP)],
247 "-x"[!!(st.st_mode & S_IXGRP)]
248 );
249 printf("%c%c%c",
250 "-r"[!!(st.st_mode & S_IROTH)],
251 "-w"[!!(st.st_mode & S_IWOTH)],
252 "-x"[!!(st.st_mode & S_IXOTH)]
253 );
254 printf(" %2d", st.st_nlink);
255 printf(" %5d", st.st_uid);
256 printf(" %5d", st.st_gid);
257 printf(" %12" PRId64, st.st_size);
258
259 printf(" %s\n", nfsdirent->name);
260 }
261 nfs_closedir(nfs, nfsdir);
262
263
264 finished:
265 free(server);
266 free(path);
267 if (nfs != NULL) {
268 nfs_destroy_context(nfs);
269 }
270 printf("nfsclient finished\n");
271 return 0;
272 }
273