librsync  2.3.2
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 <assert.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #ifdef HAVE_FCNTL_H
33 # include <fcntl.h>
34 #endif
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38 #ifdef HAVE_SYS_FILE_H
39 # include <sys/file.h>
40 #endif
41 #ifdef HAVE_SYS_STAT_H
42 # include <sys/stat.h>
43 #endif
44 #ifdef HAVE_IO_H
45 # include <io.h>
46 #endif
47 #include "librsync.h"
48 #include "trace.h"
49 
50 /* Use fseeko64, _fseeki64, or fseeko for long files if they exist. */
51 #if defined(HAVE_FSEEKO64) && (SIZEOF_OFF_T < 8)
52 # define fopen(f, m) fopen64((f), (m))
53 # define fseek(f, o, w) fseeko64((f), (o), (w))
54 #elif defined(HAVE__FSEEKI64)
55 # define fseek(f, o, w) _fseeki64((f), (o), (w))
56 #elif defined(HAVE_FSEEKO)
57 # define fseek(f, o, w) fseeko((f), (o), (w))
58 #endif
59 
60 /* Use fstat64 or _fstati64 for long file fstat if they exist. */
61 #if defined(HAVE_FSTAT64) && (SIZEOF_OFF_T < 8)
62 # define stat stat64
63 # define fstat(f,s) fstat64((f), (s))
64 #elif defined(HAVE__FSTATI64)
65 # define stat _stati64
66 # define fstat(f,s) _fstati64((f), (s))
67 #endif
68 
69 /* Make sure S_ISREG is defined. */
70 #ifndef S_ISREG
71 # define S_ISREG(x) ((x) & _S_IFREG)
72 #endif
73 
74 /* Use and prefer _fileno if it exists. */
75 #ifdef HAVE__FILENO
76 # define fileno(f) _fileno((f))
77 #endif
78 
79 FILE *rs_file_open(char const *filename, char const *mode, int force)
80 {
81  FILE *f;
82  int is_write;
83 
84  is_write = mode[0] == 'w';
85 
86  if (!filename || !strcmp("-", filename)) {
87  if (is_write) {
88 #if _WIN32
89  _setmode(_fileno(stdout), _O_BINARY);
90 #endif
91  return stdout;
92  } else {
93 #if _WIN32
94  _setmode(_fileno(stdin), _O_BINARY);
95 #endif
96  return stdin;
97  }
98  }
99 
100  if (!force && is_write) {
101  if ((f = fopen(filename, "rb"))) {
102  // File exists
103  rs_error("File exists \"%s\", aborting!", filename);
104  fclose(f);
105  exit(RS_IO_ERROR);
106  }
107  }
108 
109  if (!(f = fopen(filename, mode))) {
110  rs_error("Error opening \"%s\" for %s: %s", filename,
111  is_write ? "write" : "read", strerror(errno));
112  exit(RS_IO_ERROR);
113  }
114 
115  return f;
116 }
117 
118 int rs_file_close(FILE *f)
119 {
120  if ((f == stdin) || (f == stdout))
121  return 0;
122  return fclose(f);
123 }
124 
125 rs_long_t rs_file_size(FILE *f)
126 {
127  struct stat st;
128  if ((fstat(fileno(f), &st) == 0) && (S_ISREG(st.st_mode)))
129  return st.st_size;
130  return -1;
131 }
132 
133 rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf)
134 {
135  FILE *f = (FILE *)arg;
136 
137  if (fseek(f, pos, SEEK_SET)) {
138  rs_error("seek failed: %s", strerror(errno));
139  return RS_IO_ERROR;
140  }
141  *len = fread(*buf, 1, *len, f);
142  if (*len) {
143  return RS_DONE;
144  } else if (ferror(f)) {
145  rs_error("read error: %s", strerror(errno));
146  return RS_IO_ERROR;
147  } else {
148  rs_error("unexpected eof on fd%d", fileno(f));
149  return RS_INPUT_ENDED;
150  }
151 }
Public header for librsync.
LIBRSYNC_EXPORT int rs_file_close(FILE *file)
Close a file with special handling for stdin or stdout.
Definition: fileutil.c:118
LIBRSYNC_EXPORT rs_long_t rs_file_size(FILE *file)
Get the size of a file.
Definition: fileutil.c:125
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
LIBRSYNC_EXPORT rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf)
rs_copy_cb that reads from a stdio file.
Definition: fileutil.c:133
LIBRSYNC_EXPORT FILE * rs_file_open(char const *filename, char const *mode, int force)
Open a file with special handling for stdin or stdout.
Definition: fileutil.c:79
logging functions.