1/* copy.c 2 Copy one file to another for the UUCP package. 3 4 Copyright (C) 1991, 1992, 1995, 2002 Ian Lance Taylor 5 6 This file is part of the Taylor UUCP package. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of the 11 License, or (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucp.h" 26 27#if USE_RCS_ID 28const char copy_rcsid[] = "$Id: copy.c,v 1.22 2002/03/05 19:10:41 ian Rel $"; 29#endif 30 31#include "uudefs.h" 32#include "system.h" 33#include "sysdep.h" 34 35#include <stdio.h> 36#include <errno.h> 37 38/* Copy one file to another. */ 39 40#if USE_STDIO 41 42boolean 43fcopy_file (zfrom, zto, fpublic, fmkdirs, fsignals) 44 const char *zfrom; 45 const char *zto; 46 boolean fpublic; 47 boolean fmkdirs; 48 boolean fsignals; 49{ 50 FILE *efrom; 51 boolean fret; 52 53 efrom = fopen (zfrom, BINREAD); 54 if (efrom == NULL) 55 { 56 ulog (LOG_ERROR, "fopen (%s): %s", zfrom, strerror (errno)); 57 return FALSE; 58 } 59 60 fret = fcopy_open_file (efrom, zto, fpublic, fmkdirs, fsignals); 61 (void) fclose (efrom); 62 return fret; 63} 64 65boolean 66fcopy_open_file (efrom, zto, fpublic, fmkdirs, fsignals) 67 FILE *efrom; 68 const char *zto; 69 boolean fpublic; 70 boolean fmkdirs; 71 boolean fsignals; 72{ 73 FILE *eto; 74 char ab[8192]; 75 size_t c; 76 77 eto = esysdep_fopen (zto, fpublic, FALSE, fmkdirs); 78 if (eto == NULL) 79 return FALSE; 80 81 while ((c = fread (ab, sizeof (char), sizeof ab, efrom)) != 0) 82 { 83 if (fwrite (ab, sizeof (char), (size_t) c, eto) != c) 84 { 85 ulog (LOG_ERROR, "fwrite: %s", strerror (errno)); 86 (void) fclose (eto); 87 (void) remove (zto); 88 return FALSE; 89 } 90 if (fsignals && FGOT_SIGNAL ()) 91 { 92 /* Log the signal. */ 93 ulog (LOG_ERROR, (const char *) NULL); 94 (void) fclose (eto); 95 (void) remove (zto); 96 return FALSE; 97 } 98 } 99 100 if (! fsysdep_sync (eto, zto)) 101 { 102 (void) fclose (eto); 103 (void) remove (zto); 104 return FALSE; 105 } 106 107 if (fclose (eto) != 0) 108 { 109 ulog (LOG_ERROR, "fclose: %s", strerror (errno)); 110 (void) remove (zto); 111 return FALSE; 112 } 113 114 if (ferror (efrom)) 115 { 116 ulog (LOG_ERROR, "fread: %s", strerror (errno)); 117 (void) remove (zto); 118 return FALSE; 119 } 120 121 return TRUE; 122} 123 124#else /* ! USE_STDIO */ 125 126#if HAVE_FCNTL_H 127#include <fcntl.h> 128#else 129#if HAVE_SYS_FILE_H 130#include <sys/file.h> 131#endif 132#endif 133 134#ifndef O_RDONLY 135#define O_RDONLY 0 136#define O_WRONLY 1 137#define O_RDWR 2 138#endif 139 140#ifndef O_NOCTTY 141#define O_NOCTTY 0 142#endif 143 144boolean 145fcopy_file (zfrom, zto, fpublic, fmkdirs, fsignals) 146 const char *zfrom; 147 const char *zto; 148 boolean fpublic; 149 boolean fmkdirs; 150 boolean fsignals; 151{ 152 int ofrom; 153 boolean fret; 154 155 ofrom = open (zfrom, O_RDONLY | O_NOCTTY, 0); 156 if (ofrom < 0) 157 { 158 ulog (LOG_ERROR, "open (%s): %s", zfrom, strerror (errno)); 159 return FALSE; 160 } 161 162 fret = fcopy_open_file (ofrom, zto, fpublic, fmkdirs, fsignals); 163 (void) close (ofrom); 164 return fret; 165} 166 167boolean 168fcopy_open_file (ofrom, zto, fpublic, fmkdirs, fsignals) 169 int ofrom; 170 const char *zto; 171 boolean fpublic; 172 boolean fmkdirs; 173 boolean fsignals; 174{ 175 int oto; 176 char ab[8192]; 177 int c; 178 179 /* These file mode arguments are from the UNIX version of sysdep.h; 180 each system dependent header file will need their own 181 definitions. */ 182 oto = creat (zto, fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE); 183 if (oto < 0) 184 { 185 if (errno == ENOENT && fmkdirs) 186 { 187 if (! fsysdep_make_dirs (zto, fpublic)) 188 return FALSE; 189 oto = creat (zto, 190 fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE); 191 } 192 if (oto < 0) 193 { 194 ulog (LOG_ERROR, "open (%s): %s", zto, strerror (errno)); 195 return FALSE; 196 } 197 } 198 199 while ((c = read (ofrom, ab, sizeof ab)) > 0) 200 { 201 if (write (oto, ab, (size_t) c) != c) 202 { 203 ulog (LOG_ERROR, "write: %s", strerror (errno)); 204 (void) close (oto); 205 (void) remove (zto); 206 return FALSE; 207 } 208 if (fsignals && FGOT_SIGNAL ()) 209 { 210 /* Log the signal. */ 211 ulog (LOG_ERROR, (const char *) NULL); 212 (void) fclose (eto); 213 (void) remove (zto); 214 return FALSE; 215 } 216 } 217 218 if (! fsysdep_sync (oto, zto)) 219 { 220 (void) close (oto); 221 (void) remove (zto); 222 return FALSE; 223 } 224 225 if (close (oto) < 0) 226 { 227 ulog (LOG_ERROR, "close: %s", strerror (errno)); 228 (void) remove (zto); 229 return FALSE; 230 } 231 232 if (c < 0) 233 { 234 ulog (LOG_ERROR, "read: %s", strerror (errno)); 235 (void) remove (zto); 236 return FALSE; 237 } 238 239 return TRUE; 240} 241 242#endif /* ! USE_STDIO */ 243