5762785 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056/tools]$ cat -n file_sync.c
  1 #include "compat.h"
  2 #include "md4.h"
  3 #include "net.h"
  4 
  5 #ifndef O_LARGEFILE
  6 #define O_LARGEFILE 0
  7 #endif
  8 
  9 uint64_t net_bytesout = 0;
 10 uint64_t net_bytesin = 0;
 11 
 12 extern char *optarg;
 13 extern int optind, opterr, optopt;
 14 
 15 static int print_help(int ret) {
 16     fprintf(stderr, "Usage: file_sync -t <host> <port> <file>\n");
 17     fprintf(stderr, "Usage: file_sync -r <port> <file>\n");
 18     return(ret);
 19 }
 20 
 21 #if 0
 22 static void print_hash(FILE *fp, const unsigned char *hash) {
 23     int i;
 24 
 25     for (i = 0; i < 16; i++) {
 26         fprintf(fp, "%x", hash[i] >> 4);
 27         fprintf(fp, "%x", hash[i] & 0xf);
 28     }
 29 
 30     return;
 31 }
 32 #endif
 33 
 34 static ssize_t read_large(int fd, char *buf, size_t count) {
 35     size_t bytestoread;
 36     ssize_t read_ret;
 37     ssize_t retval = 0;
 38 
 39     while (count) {
 40         bytestoread = count;
 41 
 42         if (bytestoread >= INT_MAX) {
 43             bytestoread = INT_MAX - 1;
 44         }
 45 
 46         read_ret = read(fd, buf, bytestoread);
 47         if (read_ret < 0) {
 48             /*
 49              * Only indicate an error if we have not read anything
 50              * into the buffer.  Subsequent calls to read() should
 51              * generate the error again.  Hopefully.
 52              */
 53             if (retval == 0) {
 54                 retval = -1;
 55             }
 56             break;
 57         }
 58 
 59         if (read_ret == 0) {
 60             break;
 61         }
 62 
 63         count -= read_ret;
 64         buf += read_ret;
 65         retval += read_ret;
 66     }
 67 
 68     return(retval);
 69 }
 70 
 71 static ssize_t write_large(int fd, char *buf, size_t count) {
 72     size_t bytestowrite;
 73     ssize_t write_ret;
 74     ssize_t retval = 0;
 75 
 76     while (count) {
 77         bytestowrite = count;
 78 
 79         if (bytestowrite >= INT_MAX) {
 80             bytestowrite = INT_MAX - 1;
 81         }
 82 
 83         write_ret = write(fd, buf, bytestowrite);
 84         if (write_ret < 0) {
 85             retval = -1;
 86             break;
 87         }
 88 
 89         if (write_ret == 0) {
 90             break;
 91         }
 92 
 93         count -= write_ret;
 94         buf += write_ret;
 95         retval += write_ret;
 96     }
 97 
 98     return(retval);
 99 }
100 
101 static ssize_t read_net(int fd, void *buf, size_t count) {
102     ssize_t retval;
103 
104     retval = read(fd, buf, count);
105 
106     if (retval > 0) {
107         net_bytesin += retval;
108     }
109 
110     return(retval);
111 }
112 
113 static ssize_t write_net(int fd, void *buf, size_t count) {
114     ssize_t retval;
115 
116     retval = write(fd, buf, count);
117     if (retval > 0) {
118         net_bytesout += retval;
119     }
120 
121     return(retval);
122 }
123 
124 static ssize_t read_large_net(int fd, void *buf, size_t count) {
125     ssize_t retval;
126 
127     retval = read_large(fd, buf, count);
128 
129     if (retval > 0) {
130         net_bytesin += retval;
131     }
132 
133     return(retval);
134 }
135 
136 static ssize_t write_large_net(int fd, void *buf, size_t count) {
137     ssize_t retval;
138 
139     retval = write_large(fd, buf, count);
140     if (retval > 0) {
141         net_bytesout += retval;
142     }
143 
144     return(retval);
145 }
146 
147 int sync_transmit(const char *host, int port, const char *file) {
148     rsaref_MD4_CTX mdctx;
149     unsigned char md4buf[16];
150     uint64_t filesize;
151     uint32_t blocksize;
152     uint8_t blockok;
153     ssize_t read_ret, write_ret;
154     char *buf;
155     off_t lseek_ret;
156     int retval = 0;
157     int sockfd;
158     int fd;
159 
160     fd = open(file, O_RDONLY | O_LARGEFILE);
161     if (fd < 0) {
162         CHECKPOINT;
163         return(-1);
164 
165     }
166 
167     lseek_ret = lseek(fd, 0, SEEK_END);
168     if (lseek_ret < 0) {
169         close(fd);
170         CHECKPOINT;
171         return(-1);
172     }
173 
174     filesize = lseek_ret;
175 
176     lseek(fd, 0, SEEK_SET);
177 
178     sockfd = net_connect_tcp(host, port);
179     if (sockfd < 0) {
180         close(fd);
181         CHECKPOINT;
182         return(-1);
183     }
184 
185     blocksize = (128 * 1024);
186 
187     buf = calloc(blocksize, 1);
188     if (!buf) {
189         close(fd);
190         close(sockfd);
191         CHECKPOINT;
192         return(-1);
193     }
194 
195     filesize = htonll(filesize);
196     blocksize = htonl(blocksize);
197 
198     write_ret = write_net(sockfd, &filesize, sizeof(filesize));
199     if (write_ret != sizeof(filesize)) {
200         close(fd);
201         close(sockfd);
202         CHECKPOINT;
203         return(-1);
204     }
205 
206     write_ret = write_net(sockfd, &blocksize, sizeof(blocksize));
207     if (write_ret != sizeof(blocksize)) {
208         close(fd);
209         close(sockfd);
210         CHECKPOINT;
211         return(-1);
212     }
213 
214     blocksize = ntohl(blocksize);
215 
216     while (1) {
217         read_ret = read_large(fd, buf, blocksize);
218         if (read_ret < 0) {
219             retval = -1;
220             CHECKPOINT;
221             break;
222         }
223 
224         if (read_ret == 0) {
225             CHECKPOINT;
226             break;
227         }
228 
229         rsaref_MD4Init(&mdctx);
230         rsaref_MD4Update(&mdctx, buf, read_ret);
231         rsaref_MD4Final(md4buf, &mdctx);
232 
233         write_ret = write_net(sockfd, md4buf, sizeof(md4buf));
234         if (write_ret != sizeof(md4buf)) {
235             retval = -1;
236             CHECKPOINT;
237             break;
238         }
239 
240         read_ret = read_net(sockfd, &blockok, sizeof(blockok));
241         if (read_ret != sizeof(blockok)) {
242             retval = -1;
243             CHECKPOINT;
244             break;
245         }
246 
247         if (!blockok) {
248             write_ret = write_large_net(sockfd, buf, blocksize);
249             if (write_ret != blocksize) {
250                 retval = -1;
251                 CHECKPOINT;
252                 break;
253             }
254         }
255     }
256 
257     close(fd);
258     close(sockfd);
259 
260     return(retval);
261 }
262 
263 int sync_receive(int port, const char *file) {
264     rsaref_MD4_CTX mdctx;
265     unsigned char md4buf[16], check_md4buf[16];
266     uint64_t filesize;
267     uint32_t blocksize;
268     uint8_t blockok;
269     ssize_t cur_read_ret, read_ret, write_ret;
270     size_t bytestowrite;
271     off_t lseek_ret;
272     char *buf;
273     int sockfd, master_sockfd;
274     int retval = 0;
275     int fd;
276     int skipbytes;
277 
278     fd = open(file, O_RDWR | O_CREAT | O_LARGEFILE, 0600);
279     if (fd < 0) {
280         CHECKPOINT;
281         return(-1);
282     }
283 
284     master_sockfd = net_listen(port);
285     if (master_sockfd < 0) {
286         close(fd);
287         CHECKPOINT;
288         return(-1);
289     }
290 
291     sockfd = accept(master_sockfd, NULL, 0);
292     if (sockfd < 0) {
293         close(fd);
294         close(master_sockfd);
295         CHECKPOINT;
296         return(-1);
297     }
298 
299     read_ret = read_net(sockfd, &filesize, sizeof(filesize));
300     if (read_ret != sizeof(filesize)) {
301         close(fd);
302         close(sockfd);
303         close(master_sockfd);
304         CHECKPOINT;
305         return(-1);
306     }
307 
308     read_ret = read_net(sockfd, &blocksize, sizeof(blocksize));
309     if (read_ret != sizeof(blocksize)) {
310         close(fd);
311         close(sockfd);
312         close(master_sockfd);
313         CHECKPOINT;
314         return(-1);
315     }
316 
317     filesize = ntohll(filesize);
318     blocksize = ntohl(blocksize);
319 
320     buf = calloc(blocksize, 1);
321     if (!buf) {
322         close(fd);
323         close(sockfd);
324         close(master_sockfd);
325         CHECKPOINT;
326         return(-1);
327     }
328 
329     while (filesize) {
330         cur_read_ret = read_ret = read_large(fd, buf, blocksize);
331         if (read_ret < 0) {
332             retval = -1;
333             CHECKPOINT;
334             break;
335         }
336 
337         bytestowrite = blocksize;
338         if (bytestowrite > filesize) {
339             bytestowrite = filesize;
340         }
341 
342         if (read_ret != blocksize) {
343             memset(buf, '\0', bytestowrite);
344             read_ret = bytestowrite;
345             skipbytes = bytestowrite;
346         } else {
347             skipbytes = 0;
348         }
349 
350         rsaref_MD4Init(&mdctx);
351         rsaref_MD4Update(&mdctx, buf, read_ret);
352         rsaref_MD4Final(md4buf, &mdctx);
353 
354         read_ret = read_net(sockfd, check_md4buf, sizeof(check_md4buf));
355         if (read_ret != sizeof(check_md4buf)) {
356             retval = -1;
357             CHECKPOINT;
358             break;
359         }
360 
361         if (memcmp(check_md4buf, md4buf, sizeof(md4buf)) == 0) {
362             blockok = 1;
363         } else {
364             blockok = 0;
365         }
366 
367         write_ret = write_net(sockfd, &blockok, sizeof(blockok));
368         if (write_ret != sizeof(blockok)) {
369             retval = -1;
370             CHECKPOINT;
371             break;
372         }
373 
374         if (blockok && skipbytes > 0) {
375             lseek_ret = lseek(fd, skipbytes, SEEK_CUR);
376             if (lseek_ret < 0) {
377                 retval = -1;
378                 CHECKPOINT;
379                 break;
380             }
381         }
382 
383         if (!blockok) {
384             read_ret = read_large_net(sockfd, buf, blocksize);
385             if (read_ret != blocksize) {
386                 retval = -1;
387                 CHECKPOINT;
388                 break;
389             }
390 
391             if (cur_read_ret) {
392                 lseek_ret = lseek(fd, ((off_t) cur_read_ret) * -1, SEEK_CUR);
393                 if (lseek_ret < 0) {
394                     retval = -1;
395                     CHECKPOINT;
396                     break;
397                 }
398             }
399 
400             write_ret = write(fd, buf, bytestowrite);
401             if (write_ret != bytestowrite) {
402                 retval = -1;
403                 CHECKPOINT;
404                 break;
405             }
406         }
407 
408         filesize -= bytestowrite;
409     }
410 
411     close(fd);
412     close(sockfd);
413     close(master_sockfd);
414 
415     return(retval);
416 }
417 
418 int main(int argc, char **argv) {
419     char *mode, *host, *port_str, *file;
420     int func_ret;
421     int retval = EXIT_SUCCESS;
422     int port;
423 
424     if (argc < 2) {
425         return(print_help(EXIT_FAILURE));
426     }
427 
428     
429 
430     mode = argv[1];
431     if (strcmp(mode, "-t") == 0) {
432         if (argc != 5) {
433             return(print_help(EXIT_FAILURE));
434         }
435 
436         host = argv[2];
437         port_str = argv[3];
438         file = argv[4];
439 
440         port = strtoul(port_str, NULL, 10);
441 
442         func_ret = sync_transmit(host, port, file); 
443         if (func_ret < 0) {
444             fprintf(stderr, "Failed.\n");
445             retval = 1;
446         }
447     } else if (strcmp(mode, "-r") == 0) {
448         if (argc != 4) {
449             return(print_help(EXIT_FAILURE));
450         }
451 
452         port_str = argv[2];
453         file = argv[3];
454 
455         port = strtoul(port_str, NULL, 10);
456 
457         func_ret = sync_receive(port, file);
458         if (func_ret < 0) {
459             fprintf(stderr, "Failed.\n");
460             retval = 1;
461         }
462     } else {
463         return(print_help(EXIT_FAILURE));
464     }
465 
466     printf("Bytes In: %llu, Bytes Out: %llu\n", net_bytesin, net_bytesout);
467 
468     return(retval);
469 }
5762786 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056/tools]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2006-01-17 16:27:20