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
;
67 fprintf(stderr
, "Usage: nfs-cp <src> <dst>\n");
68 fprintf(stderr
, "<src>,<dst> can either be a local file or "
74 free_file_context(struct file_context
*file_context
)
76 if (file_context
->fd
!= -1) {
77 close(file_context
->fd
);
79 if (file_context
->nfsfh
!= NULL
) {
80 nfs_close(file_context
->nfs
, file_context
->nfsfh
);
82 if (file_context
->nfs
!= NULL
) {
83 nfs_destroy_context(file_context
->nfs
);
85 nfs_destroy_url(file_context
->url
);
90 fstat_file(struct file_context
*fc
, struct stat
*st
)
92 if (fc
->is_nfs
== 0) {
93 return fstat(fc
->fd
, st
);
95 return nfs_fstat(fc
->nfs
, fc
->nfsfh
, st
);
100 file_pread(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
102 if (fc
->is_nfs
== 0) {
103 lseek(fc
->fd
, off
, SEEK_SET
);
104 return read(fc
->fd
, buf
, count
);
106 return nfs_pread(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
111 file_pwrite(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
113 if (fc
->is_nfs
== 0) {
114 lseek(fc
->fd
, off
, SEEK_SET
);
115 return write(fc
->fd
, buf
, count
);
117 return nfs_pwrite(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
121 static struct file_context
*
122 open_file(const char *url
, int flags
)
124 struct file_context
*file_context
;
126 file_context
= malloc(sizeof(struct file_context
));
127 if (file_context
== NULL
) {
128 fprintf(stderr
, "Failed to malloc file_context\n");
131 file_context
->is_nfs
= 0;
132 file_context
->fd
= -1;
133 file_context
->nfs
= NULL
;
134 file_context
->nfsfh
= NULL
;
135 file_context
->url
= NULL
;
137 if (strncmp(url
, "nfs://", 6)) {
138 file_context
->is_nfs
= 0;
139 file_context
->fd
= open(url
, flags
, 0660);
140 if (file_context
->fd
== -1) {
141 fprintf(stderr
, "Failed to open %s\n", url
);
142 free_file_context(file_context
);
148 file_context
->is_nfs
= 1;
150 file_context
->nfs
= nfs_init_context();
151 if (file_context
->nfs
== NULL
) {
152 fprintf(stderr
, "failed to init context\n");
153 free_file_context(file_context
);
157 file_context
->url
= nfs_parse_url_full(file_context
->nfs
, url
);
158 if (file_context
->url
== NULL
) {
159 fprintf(stderr
, "%s\n", nfs_get_error(file_context
->nfs
));
160 free_file_context(file_context
);
164 if (nfs_mount(file_context
->nfs
, file_context
->url
->server
,
165 file_context
->url
->path
) != 0) {
166 fprintf(stderr
, "Failed to mount nfs share : %s\n",
167 nfs_get_error(file_context
->nfs
));
168 free_file_context(file_context
);
172 if (flags
== O_RDONLY
) {
173 if (nfs_open(file_context
->nfs
, file_context
->url
->file
, flags
,
174 &file_context
->nfsfh
) != 0) {
175 fprintf(stderr
, "Failed to open file %s: %s\n",
176 file_context
->url
->file
,
177 nfs_get_error(file_context
->nfs
));
178 free_file_context(file_context
);
182 if (nfs_creat(file_context
->nfs
, file_context
->url
->file
, 0660,
183 &file_context
->nfsfh
) != 0) {
184 fprintf(stderr
, "Failed to creat file %s: %s\n",
185 file_context
->url
->file
,
186 nfs_get_error(file_context
->nfs
));
187 free_file_context(file_context
);
194 #define BUFSIZE 1024*1024
195 static char buf
[BUFSIZE
];
197 int main(int argc
, char *argv
[])
201 struct file_context
*src
;
202 struct file_context
*dst
;
207 if (WSAStartup(MAKEWORD(2,2), &wsaData
) != 0) {
208 printf("Failed to start Winsock2\n");
221 src
= open_file(argv
[1], O_RDONLY
);
223 fprintf(stderr
, "Failed to open %s\n", argv
[1]);
227 dst
= open_file(argv
[2], O_WRONLY
|O_CREAT
|O_TRUNC
);
229 fprintf(stderr
, "Failed to open %s\n", argv
[2]);
230 free_file_context(src
);
234 if (fstat_file(src
, &st
) != 0) {
235 fprintf(stderr
, "Failed to fstat source file\n");
236 free_file_context(src
);
237 free_file_context(dst
);
242 while (off
< st
.st_size
) {
243 count
= st
.st_size
- off
;
244 if (count
> BUFSIZE
) {
247 count
= file_pread(src
, buf
, count
, off
);
249 fprintf(stderr
, "Failed to read from source file\n");
250 free_file_context(src
);
251 free_file_context(dst
);
254 count
= file_pwrite(dst
, buf
, count
, off
);
256 fprintf(stderr
, "Failed to write to dest file\n");
257 free_file_context(src
);
258 free_file_context(dst
);
264 printf("copied %d bytes\n", (int)off
);
266 free_file_context(src
);
267 free_file_context(dst
);