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>
53 #include "libnfs-raw.h"
54 #include "libnfs-raw-mount.h"
59 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
);
84 nfs_destroy_url(file_context
->url
);
89 fstat_file(struct file_context
*fc
, struct stat
*st
)
91 if (fc
->is_nfs
== 0) {
92 return fstat(fc
->fd
, st
);
94 return nfs_fstat(fc
->nfs
, fc
->nfsfh
, st
);
99 file_pread(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
101 if (fc
->is_nfs
== 0) {
102 lseek(fc
->fd
, off
, SEEK_SET
);
103 return read(fc
->fd
, buf
, count
);
105 return nfs_pread(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
110 file_pwrite(struct file_context
*fc
, char *buf
, int64_t count
, uint64_t off
)
112 if (fc
->is_nfs
== 0) {
113 lseek(fc
->fd
, off
, SEEK_SET
);
114 return write(fc
->fd
, buf
, count
);
116 return nfs_pwrite(fc
->nfs
, fc
->nfsfh
, off
, count
, buf
);
120 static struct file_context
*
121 open_file(const char *url
, int flags
)
123 struct file_context
*file_context
;
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
;
134 file_context
->url
= 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 file_context
->url
= nfs_parse_url_full(file_context
->nfs
, url
);
157 if (file_context
->url
== NULL
) {
158 fprintf(stderr
, "%s\n", nfs_get_error(file_context
->nfs
));
159 free_file_context(file_context
);
163 if (nfs_mount(file_context
->nfs
, file_context
->url
->server
,
164 file_context
->url
->path
) != 0) {
165 fprintf(stderr
, "Failed to mount nfs share : %s\n",
166 nfs_get_error(file_context
->nfs
));
167 free_file_context(file_context
);
171 if (flags
== O_RDONLY
) {
172 if (nfs_open(file_context
->nfs
, file_context
->url
->file
, flags
,
173 &file_context
->nfsfh
) != 0) {
174 fprintf(stderr
, "Failed to open file %s: %s\n",
175 file_context
->url
->file
,
176 nfs_get_error(file_context
->nfs
));
177 free_file_context(file_context
);
181 if (nfs_creat(file_context
->nfs
, file_context
->url
->file
, 0660,
182 &file_context
->nfsfh
) != 0) {
183 fprintf(stderr
, "Failed to creat file %s: %s\n",
184 file_context
->url
->file
,
185 nfs_get_error(file_context
->nfs
));
186 free_file_context(file_context
);
193 #define BUFSIZE 1024*1024
194 static char buf
[BUFSIZE
];
196 int main(int argc
, char *argv
[])
200 struct file_context
*src
;
201 struct file_context
*dst
;
206 if (WSAStartup(MAKEWORD(2,2), &wsaData
) != 0) {
207 printf("Failed to start Winsock2\n");
220 src
= open_file(argv
[1], O_RDONLY
);
222 fprintf(stderr
, "Failed to open %s\n", argv
[1]);
226 dst
= open_file(argv
[2], O_WRONLY
|O_CREAT
|O_TRUNC
);
228 fprintf(stderr
, "Failed to open %s\n", argv
[2]);
229 free_file_context(src
);
233 if (fstat_file(src
, &st
) != 0) {
234 fprintf(stderr
, "Failed to fstat source file\n");
235 free_file_context(src
);
236 free_file_context(dst
);
241 while (off
< st
.st_size
) {
242 count
= st
.st_size
- off
;
243 if (count
> BUFSIZE
) {
246 count
= file_pread(src
, buf
, count
, off
);
248 fprintf(stderr
, "Failed to read from source file\n");
249 free_file_context(src
);
250 free_file_context(dst
);
253 count
= file_pwrite(dst
, buf
, count
, off
);
255 fprintf(stderr
, "Failed to write to dest file\n");
256 free_file_context(src
);
257 free_file_context(dst
);
263 printf("copied %d bytes\n", (int)off
);
265 free_file_context(src
);
266 free_file_context(dst
);