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"
48 #include <sys/types.h>
50 #include "libnfs-zdr.h"
52 #include "libnfs-raw.h"
53 #include "libnfs-raw-mount.h"
58 struct nfs_context
*nfs
;
64 fprintf(stderr
, "Usage: nfs-cp <src> <dst>\n");
65 fprintf(stderr
, "<src>,<dst> can either be a local file or "
71 free_file_context(struct file_context
*file_context
)
73 if (file_context
->fd
!= -1) {
74 close(file_context
->fd
);
76 if (file_context
->nfsfh
!= NULL
) {
77 nfs_close(file_context
->nfs
, file_context
->nfsfh
);
79 if (file_context
->nfs
!= NULL
) {
80 nfs_destroy_context(file_context
->nfs
);
86 fstat_file(struct file_context
*fc
, struct stat
*st
)
88 if (fc
->is_nfs
== 0) {
89 return fstat(fc
->fd
, st
);
91 return nfs_fstat(fc
->nfs
, fc
->nfsfh
, st
);
96 file_pread(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
98 if (fc
->is_nfs
== 0) {
99 return pread(fc
->fd
, buf
, count
, off
);
101 return nfs_pread(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
106 file_pwrite(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
108 if (fc
->is_nfs
== 0) {
109 return pwrite(fc
->fd
, buf
, count
, off
);
111 return nfs_pwrite(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
115 static struct file_context
*
116 open_file(const char *url
, int flags
)
118 struct file_context
*file_context
;
119 char *server
= NULL
, *path
= NULL
, *file
= NULL
, *strp
;
121 file_context
= malloc(sizeof(struct file_context
));
122 if (file_context
== NULL
) {
123 fprintf(stderr
, "Failed to malloc file_context\n");
126 file_context
->is_nfs
= 0;
127 file_context
->fd
= -1;
128 file_context
->nfs
= NULL
;
129 file_context
->nfsfh
= NULL
;
132 if (strncmp(url
, "nfs://", 6)) {
133 file_context
->is_nfs
= 0;
134 file_context
->fd
= open(url
, flags
, 0660);
135 if (file_context
->fd
== -1) {
136 fprintf(stderr
, "Failed to open %s\n", url
);
137 free_file_context(file_context
);
143 file_context
->is_nfs
= 1;
145 file_context
->nfs
= nfs_init_context();
146 if (file_context
->nfs
== NULL
) {
147 fprintf(stderr
, "failed to init context\n");
148 free_file_context(file_context
);
152 server
= strdup(url
+ 6);
153 if (server
== NULL
) {
154 fprintf(stderr
, "Failed to strdup server string\n");
155 free_file_context(file_context
);
158 if (server
[0] == '/' || server
[0] == '\0') {
159 fprintf(stderr
, "Invalid server string.\n");
161 free_file_context(file_context
);
164 strp
= strchr(server
, '/');
168 fprintf(stderr
, "Invalid URL specified.\n");
170 free_file_context(file_context
);
174 strp
= strrchr(path
, '/');
176 fprintf(stderr
, "Invalid URL specified.\n");
179 free_file_context(file_context
);
185 if (nfs_mount(file_context
->nfs
, server
, path
) != 0) {
186 fprintf(stderr
, "Failed to mount nfs share : %s\n",
187 nfs_get_error(file_context
->nfs
));
191 free_file_context(file_context
);
195 if (flags
== O_RDONLY
) {
196 if (nfs_open(file_context
->nfs
, file
, flags
,
197 &file_context
->nfsfh
) != 0) {
198 fprintf(stderr
, "Failed to open file : %s\n",
199 nfs_get_error(file_context
->nfs
));
203 free_file_context(file_context
);
207 if (nfs_creat(file_context
->nfs
, file
, 0660,
208 &file_context
->nfsfh
) != 0) {
209 fprintf(stderr
, "Failed to creat file %s %s\n", file
,
210 nfs_get_error(file_context
->nfs
));
214 free_file_context(file_context
);
226 #define BUFSIZE 1024*1024
227 static char buf
[BUFSIZE
];
229 int main(int argc
, char *argv
[])
233 struct file_context
*src
;
234 struct file_context
*dst
;
239 if (WSAStartup(MAKEWORD(2,2), &wsaData
) != 0) {
240 printf("Failed to start Winsock2\n");
253 src
= open_file(argv
[1], O_RDONLY
);
255 fprintf(stderr
, "Failed to open %s\n", argv
[1]);
259 dst
= open_file(argv
[2], O_WRONLY
|O_CREAT
|O_TRUNC
);
261 fprintf(stderr
, "Failed to open %s\n", argv
[2]);
262 free_file_context(src
);
266 if (fstat_file(src
, &st
) != 0) {
267 fprintf(stderr
, "Failed to fstat source file\n");
268 free_file_context(src
);
269 free_file_context(dst
);
274 while (off
< st
.st_size
) {
275 count
= st
.st_size
- off
;
276 if (count
> BUFSIZE
) {
279 count
= file_pread(src
, buf
, count
, off
);
281 fprintf(stderr
, "Failed to read from source file\n");
282 free_file_context(src
);
283 free_file_context(dst
);
286 count
= file_pwrite(dst
, buf
, count
, off
);
288 fprintf(stderr
, "Failed to write to dest file\n");
289 free_file_context(src
);
290 free_file_context(dst
);
296 printf("copied %d bytes\n", (int)count
);
298 free_file_context(src
);
299 free_file_context(dst
);