2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2013
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.
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.
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/>.
18 #define _FILE_OFFSET_BITS 64
26 #include "aros_compat.h"
31 #include "win32_compat.h"
32 #pragma comment(lib, "ws2_32.lib")
50 #include <sys/types.h>
52 #include "libnfs-zdr.h"
54 #include "libnfs-raw.h"
55 #include "libnfs-raw-mount.h"
60 struct nfs_context
*nfs
;
66 fprintf(stderr
, "Usage: nfs-cp <src> <dst>\n");
67 fprintf(stderr
, "<src>,<dst> can either be a local file or "
73 free_file_context(struct file_context
*file_context
)
75 if (file_context
->fd
!= -1) {
76 close(file_context
->fd
);
78 if (file_context
->nfsfh
!= NULL
) {
79 nfs_close(file_context
->nfs
, file_context
->nfsfh
);
81 if (file_context
->nfs
!= NULL
) {
82 nfs_destroy_context(file_context
->nfs
);
88 fstat_file(struct file_context
*fc
, struct stat
*st
)
90 if (fc
->is_nfs
== 0) {
91 return fstat(fc
->fd
, st
);
93 return nfs_fstat(fc
->nfs
, fc
->nfsfh
, st
);
98 file_pread(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
100 if (fc
->is_nfs
== 0) {
101 lseek(fc
->fd
, off
, SEEK_SET
);
102 return read(fc
->fd
, buf
, count
);
104 return nfs_pread(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
109 file_pwrite(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
111 if (fc
->is_nfs
== 0) {
112 lseek(fc
->fd
, off
, SEEK_SET
);
113 return write(fc
->fd
, buf
, count
);
115 return nfs_pwrite(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
119 static struct file_context
*
120 open_file(const char *url
, int flags
)
122 struct file_context
*file_context
;
123 char *server
= NULL
, *path
= NULL
, *file
= NULL
, *strp
;
125 file_context
= malloc(sizeof(struct file_context
));
126 if (file_context
== NULL
) {
127 fprintf(stderr
, "Failed to malloc file_context\n");
130 file_context
->is_nfs
= 0;
131 file_context
->fd
= -1;
132 file_context
->nfs
= NULL
;
133 file_context
->nfsfh
= NULL
;
136 if (strncmp(url
, "nfs://", 6)) {
137 file_context
->is_nfs
= 0;
138 file_context
->fd
= open(url
, flags
, 0660);
139 if (file_context
->fd
== -1) {
140 fprintf(stderr
, "Failed to open %s\n", url
);
141 free_file_context(file_context
);
147 file_context
->is_nfs
= 1;
149 file_context
->nfs
= nfs_init_context();
150 if (file_context
->nfs
== NULL
) {
151 fprintf(stderr
, "failed to init context\n");
152 free_file_context(file_context
);
156 server
= strdup(url
+ 6);
157 if (server
== NULL
) {
158 fprintf(stderr
, "Failed to strdup server string\n");
159 free_file_context(file_context
);
162 if (server
[0] == '/' || server
[0] == '\0') {
163 fprintf(stderr
, "Invalid server string.\n");
165 free_file_context(file_context
);
168 strp
= strchr(server
, '/');
172 fprintf(stderr
, "Invalid URL specified.\n");
174 free_file_context(file_context
);
178 strp
= strrchr(path
, '/');
180 fprintf(stderr
, "Invalid URL specified.\n");
183 free_file_context(file_context
);
189 if (nfs_mount(file_context
->nfs
, server
, path
) != 0) {
190 fprintf(stderr
, "Failed to mount nfs share : %s\n",
191 nfs_get_error(file_context
->nfs
));
195 free_file_context(file_context
);
199 if (flags
== O_RDONLY
) {
200 if (nfs_open(file_context
->nfs
, file
, flags
,
201 &file_context
->nfsfh
) != 0) {
202 fprintf(stderr
, "Failed to open file : %s\n",
203 nfs_get_error(file_context
->nfs
));
207 free_file_context(file_context
);
211 if (nfs_creat(file_context
->nfs
, file
, 0660,
212 &file_context
->nfsfh
) != 0) {
213 fprintf(stderr
, "Failed to creat file %s %s\n", file
,
214 nfs_get_error(file_context
->nfs
));
218 free_file_context(file_context
);
230 #define BUFSIZE 1024*1024
231 static char buf
[BUFSIZE
];
233 int main(int argc
, char *argv
[])
237 struct file_context
*src
;
238 struct file_context
*dst
;
243 if (WSAStartup(MAKEWORD(2,2), &wsaData
) != 0) {
244 printf("Failed to start Winsock2\n");
257 src
= open_file(argv
[1], O_RDONLY
);
259 fprintf(stderr
, "Failed to open %s\n", argv
[1]);
263 dst
= open_file(argv
[2], O_WRONLY
|O_CREAT
|O_TRUNC
);
265 fprintf(stderr
, "Failed to open %s\n", argv
[2]);
266 free_file_context(src
);
270 if (fstat_file(src
, &st
) != 0) {
271 fprintf(stderr
, "Failed to fstat source file\n");
272 free_file_context(src
);
273 free_file_context(dst
);
278 while (off
< st
.st_size
) {
279 count
= st
.st_size
- off
;
280 if (count
> BUFSIZE
) {
283 count
= file_pread(src
, buf
, count
, off
);
285 fprintf(stderr
, "Failed to read from source file\n");
286 free_file_context(src
);
287 free_file_context(dst
);
290 count
= file_pwrite(dst
, buf
, count
, off
);
292 fprintf(stderr
, "Failed to write to dest file\n");
293 free_file_context(src
);
294 free_file_context(dst
);
300 printf("copied %d bytes\n", (int)count
);
302 free_file_context(src
);
303 free_file_context(dst
);