librsync  2.3.3
fileutil.c
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- library for network deltas
4 *
5 * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@sourcefrog.net>
6 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "config.h"
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include <errno.h>
28#ifdef HAVE_UNISTD_H
29# include <unistd.h>
30#endif
31#ifdef HAVE_FCNTL_H
32# include <fcntl.h>
33#endif
34#ifdef HAVE_SYS_TYPES_H
35# include <sys/types.h>
36#endif
37#ifdef HAVE_SYS_FILE_H
38# include <sys/file.h>
39#endif
40#ifdef HAVE_SYS_STAT_H
41# include <sys/stat.h>
42#endif
43#ifdef HAVE_IO_H
44# include <io.h>
45#endif
46#include "librsync.h"
47#include "trace.h"
48
49/* Use fseeko64, _fseeki64, or fseeko for long files if they exist. */
50#if defined(HAVE_FSEEKO64) && (SIZEOF_OFF_T < 8)
51# define fopen(f, m) fopen64((f), (m))
52# define fseek(f, o, w) fseeko64((f), (o), (w))
53#elif defined(HAVE__FSEEKI64)
54# define fseek(f, o, w) _fseeki64((f), (o), (w))
55#elif defined(HAVE_FSEEKO)
56# define fseek(f, o, w) fseeko((f), (o), (w))
57#endif
58
59/* Use fstat64 or _fstati64 for long file fstat if they exist. */
60#if defined(HAVE_FSTAT64) && (SIZEOF_OFF_T < 8)
61# define stat stat64
62# define fstat(f,s) fstat64((f), (s))
63#elif defined(HAVE__FSTATI64)
64# define stat _stati64
65# define fstat(f,s) _fstati64((f), (s))
66#endif
67
68/* Make sure S_ISREG is defined. */
69#ifndef S_ISREG
70# define S_ISREG(x) ((x) & _S_IFREG)
71#endif
72
73/* Use and prefer _fileno if it exists. */
74#ifdef HAVE__FILENO
75# define fileno(f) _fileno((f))
76#endif
77
78FILE *rs_file_open(char const *filename, char const *mode, int force)
79{
80 FILE *f;
81 int is_write;
82
83 is_write = mode[0] == 'w';
84
85 if (!filename || !strcmp("-", filename)) {
86 if (is_write) {
87#if _WIN32
88 _setmode(_fileno(stdout), _O_BINARY);
89#endif
90 return stdout;
91 } else {
92#if _WIN32
93 _setmode(_fileno(stdin), _O_BINARY);
94#endif
95 return stdin;
96 }
97 }
98
99 if (!force && is_write) {
100 if ((f = fopen(filename, "rb"))) {
101 // File exists
102 rs_error("File exists \"%s\", aborting!", filename);
103 fclose(f);
104 exit(RS_IO_ERROR);
105 }
106 }
107
108 if (!(f = fopen(filename, mode))) {
109 rs_error("Error opening \"%s\" for %s: %s", filename,
110 is_write ? "write" : "read", strerror(errno));
111 exit(RS_IO_ERROR);
112 }
113
114 return f;
115}
116
117int rs_file_close(FILE *f)
118{
119 if ((f == stdin) || (f == stdout))
120 return 0;
121 return fclose(f);
122}
123
124rs_long_t rs_file_size(FILE *f)
125{
126 struct stat st;
127 if ((fstat(fileno(f), &st) == 0) && (S_ISREG(st.st_mode)))
128 return st.st_size;
129 return -1;
130}
131
132rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf)
133{
134 FILE *f = (FILE *)arg;
135
136 if (fseek(f, pos, SEEK_SET)) {
137 rs_error("seek failed: %s", strerror(errno));
138 return RS_IO_ERROR;
139 }
140 *len = fread(*buf, 1, *len, f);
141 if (*len) {
142 return RS_DONE;
143 } else if (ferror(f)) {
144 rs_error("read error: %s", strerror(errno));
145 return RS_IO_ERROR;
146 } else {
147 rs_error("unexpected eof on fd%d", fileno(f));
148 return RS_INPUT_ENDED;
149 }
150}
Public header for librsync.
rs_result
Return codes from nonblocking rsync operations.
Definition: librsync.h:180
@ RS_DONE
Completed successfully.
Definition: librsync.h:181
@ RS_INPUT_ENDED
Unexpected end of input file, perhaps due to a truncated file or dropped network connection.
Definition: librsync.h:190
@ RS_IO_ERROR
Error in file or network IO.
Definition: librsync.h:187
logging functions.