$treeview $search $mathjax $extrastylesheet
librsync
2.0.2
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- library for network deltas 00004 * 00005 * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@sourcefrog.net> 00006 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org> 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation; either version 2.1 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 00023 #include "config.h" 00024 00025 #include <assert.h> 00026 #include <stdlib.h> 00027 #ifdef HAVE_UNISTD_H 00028 # include <unistd.h> 00029 #endif 00030 #include <stdio.h> 00031 #ifdef HAVE_FCNTL_H 00032 # include <fcntl.h> 00033 #endif 00034 #ifdef HAVE_SYS_FILE_H 00035 # include <sys/file.h> 00036 #endif 00037 #ifdef HAVE_SYS_STAT_H 00038 # include <sys/stat.h> 00039 #endif 00040 #include <string.h> 00041 #include <errno.h> 00042 00043 #include "librsync.h" 00044 #include "fileutil.h" 00045 #include "trace.h" 00046 00047 /* Use fseeko64, _fseeki64, or fseeko for long files if they exist. */ 00048 #if defined(HAVE_FSEEKO64) && (SIZEOF_OFF_T < 8) 00049 # define fopen(f, m) fopen64((f), (m)) 00050 # define fseek(f, o, w) fseeko64((f), (o), (w)) 00051 #elif defined(HAVE__FSEEKI64) 00052 # define fseek(f, o, w) _fseeki64((f), (o), (w)) 00053 #elif defined(HAVE_FSEEKO) 00054 # define fseek(f, o, w) fseeko((f), (o), (w)) 00055 #endif 00056 00057 /* Use fstat64 or _fstati64 for long file fstat if they exist. */ 00058 #if defined(HAVE_FSTAT64) && (SIZEOF_OFF_T < 8) 00059 # define stat stat64 00060 # define fstat(f,s) fstat64((f), (s)) 00061 #elif defined(HAVE__FSTATI64) 00062 # define stat _stati64 00063 # define fstat(f,s) _fstati64((f), (s)) 00064 #endif 00065 00066 /* Make sure S_ISREG is defined. */ 00067 #ifndef S_ISREG 00068 # define S_ISREG(x) ((x) & _S_IFREG) 00069 #endif 00070 00071 /* Use _fileno if it exists and fileno doesn't. */ 00072 #if !defined(HAVE_FILENO) && defined(HAVE__FILENO) 00073 # define fileno(f) _fileno((f)) 00074 #endif 00075 00076 /** Open a file with special handling for '-' or unspecified filenames. 00077 * 00078 * \param filename - The filename to open. 00079 * 00080 * \param mode - fopen style mode string. 00081 * 00082 * \param force - bool to force overwriting of existing files. */ 00083 FILE *rs_file_open(char const *filename, char const *mode, int force) 00084 { 00085 FILE *f; 00086 int is_write; 00087 00088 is_write = mode[0] == 'w'; 00089 00090 if (!filename || !strcmp("-", filename)) { 00091 if (is_write) { 00092 #if _WIN32 00093 _setmode(_fileno(stdout), _O_BINARY); 00094 #endif 00095 return stdout; 00096 } else { 00097 #if _WIN32 00098 _setmode(_fileno(stdin), _O_BINARY); 00099 #endif 00100 return stdin; 00101 } 00102 } 00103 00104 if (!force && is_write) { 00105 if ((f = fopen(filename, "rb"))) { 00106 // File exists 00107 rs_error("File exists \"%s\", aborting!", filename); 00108 fclose(f); 00109 exit(RS_IO_ERROR); 00110 } 00111 } 00112 00113 if (!(f = fopen(filename, mode))) { 00114 rs_error("Error opening \"%s\" for %s: %s", filename, 00115 is_write ? "write" : "read", strerror(errno)); 00116 exit(RS_IO_ERROR); 00117 } 00118 00119 return f; 00120 } 00121 00122 int rs_file_close(FILE *f) 00123 { 00124 if ((f == stdin) || (f == stdout)) 00125 return 0; 00126 return fclose(f); 00127 } 00128 00129 void rs_get_filesize(FILE *f, rs_long_t *size) 00130 { 00131 struct stat st; 00132 if (size && (fstat(fileno(f), &st) == 0) && (S_ISREG(st.st_mode))) { 00133 *size = st.st_size; 00134 } 00135 } 00136 00137 rs_result rs_file_copy_cb(void *arg, rs_long_t pos, size_t *len, void **buf) 00138 { 00139 int got; 00140 FILE *f = (FILE *)arg; 00141 00142 if (fseek(f, pos, SEEK_SET)) { 00143 rs_error("seek failed: %s", strerror(errno)); 00144 return RS_IO_ERROR; 00145 } 00146 00147 got = fread(*buf, 1, *len, f); 00148 if (got == -1) { 00149 rs_error("read error: %s", strerror(errno)); 00150 return RS_IO_ERROR; 00151 } else if (got == 0) { 00152 rs_error("unexpected eof on fd%d", fileno(f)); 00153 return RS_INPUT_ENDED; 00154 } else { 00155 *len = got; 00156 return RS_DONE; 00157 } 00158 }