files.c (21813B)
1 /* Copyright (c) 2003-2004, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file files.h 8 * 9 * \brief Wrappers for reading and writing data to files on disk. 10 **/ 11 12 #ifdef _WIN32 13 #include <windows.h> 14 #endif 15 16 #include "lib/fs/files.h" 17 #include "lib/fs/path.h" 18 #include "lib/container/smartlist.h" 19 #include "lib/log/log.h" 20 #include "lib/log/util_bug.h" 21 #include "lib/log/escape.h" 22 #include "lib/err/torerr.h" 23 #include "lib/malloc/malloc.h" 24 #include "lib/sandbox/sandbox.h" 25 #include "lib/string/printf.h" 26 #include "lib/string/util_string.h" 27 #include "lib/fdio/fdio.h" 28 29 #ifdef HAVE_SYS_TYPES_H 30 #include <sys/types.h> 31 #endif 32 #ifdef HAVE_SYS_STAT_H 33 #include <sys/stat.h> 34 #endif 35 #ifdef HAVE_UTIME_H 36 #include <utime.h> 37 #endif 38 #ifdef HAVE_SYS_TIME_H 39 #include <sys/time.h> 40 #endif 41 #ifdef HAVE_FCNTL_H 42 #include <fcntl.h> 43 #endif 44 #ifdef HAVE_UNISTD_H 45 #include <unistd.h> 46 #endif 47 #include <errno.h> 48 #include <stdio.h> 49 #include <string.h> 50 51 /** As open(path, flags, mode), but return an fd with the close-on-exec mode 52 * set. */ 53 int 54 tor_open_cloexec(const char *path, int flags, unsigned mode) 55 { 56 int fd; 57 const char *p = sandbox_intern_string(path); 58 #ifdef O_CLOEXEC 59 fd = open(p, flags|O_CLOEXEC, mode); 60 if (fd >= 0) 61 return fd; 62 /* If we got an error, see if it is EINVAL. EINVAL might indicate that, 63 * even though we were built on a system with O_CLOEXEC support, we 64 * are running on one without. */ 65 if (errno != EINVAL) 66 return -1; 67 #endif /* defined(O_CLOEXEC) */ 68 69 log_debug(LD_FS, "Opening %s with flags %x", p, flags); 70 fd = open(p, flags, mode); 71 #ifdef FD_CLOEXEC 72 if (fd >= 0) { 73 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { 74 log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno)); 75 close(fd); 76 return -1; 77 } 78 } 79 #endif /* defined(FD_CLOEXEC) */ 80 return fd; 81 } 82 83 /** As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the 84 * underlying file handle. */ 85 FILE * 86 tor_fopen_cloexec(const char *path, const char *mode) 87 { 88 const char *p = sandbox_intern_string(path); 89 FILE *result = fopen(p, mode); 90 #ifdef FD_CLOEXEC 91 if (result != NULL) { 92 if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) { 93 log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno)); 94 fclose(result); 95 return NULL; 96 } 97 } 98 #endif /* defined(FD_CLOEXEC) */ 99 return result; 100 } 101 102 /** As rename(), but work correctly with the sandbox. */ 103 int 104 tor_rename(const char *path_old, const char *path_new) 105 { 106 log_debug(LD_FS, "Renaming %s to %s", path_old, path_new); 107 return rename(sandbox_intern_string(path_old), 108 sandbox_intern_string(path_new)); 109 } 110 111 /** 112 * Rename the file <b>from</b> to the file <b>to</b>. On Unix, this is 113 * the same as rename(2). On windows, this removes <b>to</b> first if 114 * it already exists. 115 * Returns 0 on success. Returns -1 and sets errno on failure. 116 */ 117 int 118 replace_file(const char *from, const char *to) 119 { 120 #ifndef _WIN32 121 return tor_rename(from, to); 122 #else 123 switch (file_status(to)) 124 { 125 case FN_NOENT: 126 break; 127 case FN_FILE: 128 case FN_EMPTY: 129 if (unlink(to)) return -1; 130 break; 131 case FN_ERROR: 132 return -1; 133 case FN_DIR: 134 errno = EISDIR; 135 return -1; 136 } 137 return tor_rename(from,to); 138 #endif /* !defined(_WIN32) */ 139 } 140 141 /** Change <b>fname</b>'s modification time to now. */ 142 int 143 touch_file(const char *fname) 144 { 145 if (utime(fname, NULL)!=0) 146 return -1; 147 return 0; 148 } 149 150 /** Wrapper for unlink() to make it mockable for the test suite; returns 0 151 * if unlinking the file succeeded, -1 and sets errno if unlinking fails. 152 */ 153 154 MOCK_IMPL(int, 155 tor_unlink,(const char *pathname)) 156 { 157 return unlink(pathname); 158 } 159 160 /** Write <b>count</b> bytes from <b>buf</b> to <b>fd</b>. Return the number 161 * of bytes written, or -1 on error. Only use if fd is a blocking fd. */ 162 ssize_t 163 write_all_to_fd(int fd, const char *buf, size_t count) 164 { 165 size_t written = 0; 166 ssize_t result; 167 raw_assert(count < SSIZE_MAX); 168 169 while (written != count) { 170 result = write(fd, buf+written, count-written); 171 if (result<0) 172 return -1; 173 written += result; 174 } 175 return (ssize_t)count; 176 } 177 178 /** Read from <b>fd</b> to <b>buf</b>, until we get <b>count</b> bytes or 179 * reach the end of the file. Return the number of bytes read, or -1 on 180 * error. Only use if fd is a blocking fd. */ 181 ssize_t 182 read_all_from_fd(int fd, char *buf, size_t count) 183 { 184 size_t numread = 0; 185 ssize_t result; 186 187 if (count > SIZE_T_CEILING || count > SSIZE_MAX) { 188 errno = EINVAL; 189 return -1; 190 } 191 192 while (numread < count) { 193 result = read(fd, buf+numread, count-numread); 194 if (result<0) 195 return -1; 196 else if (result == 0) 197 break; 198 numread += result; 199 } 200 return (ssize_t)numread; 201 } 202 203 /** Return: 204 * FN_ERROR if filename can't be read, is NULL, or is zero-length, 205 * FN_NOENT if it doesn't exist, 206 * FN_FILE if it is a non-empty regular file, or a FIFO on unix-like systems, 207 * FN_EMPTY for zero-byte regular files, 208 * FN_DIR if it's a directory, and 209 * FN_ERROR for any other file type. 210 * On FN_ERROR and FN_NOENT, sets errno. (errno is not set when FN_ERROR 211 * is returned due to an unhandled file type.) */ 212 file_status_t 213 file_status(const char *fname) 214 { 215 struct stat st; 216 char *f; 217 int r; 218 if (!fname || strlen(fname) == 0) { 219 return FN_ERROR; 220 } 221 f = tor_strdup(fname); 222 clean_fname_for_stat(f); 223 log_debug(LD_FS, "stat()ing %s", f); 224 r = stat(sandbox_intern_string(f), &st); 225 tor_free(f); 226 if (r) { 227 if (errno == ENOENT) { 228 return FN_NOENT; 229 } 230 return FN_ERROR; 231 } 232 if (st.st_mode & S_IFDIR) { 233 return FN_DIR; 234 } else if (st.st_mode & S_IFREG) { 235 if (st.st_size > 0) { 236 return FN_FILE; 237 } else if (st.st_size == 0) { 238 return FN_EMPTY; 239 } else { 240 return FN_ERROR; 241 } 242 #ifndef _WIN32 243 } else if (st.st_mode & S_IFIFO) { 244 return FN_FILE; 245 #endif 246 } else { 247 return FN_ERROR; 248 } 249 } 250 251 /** Returns true if <b>file_type</b> represents an existing file (even if 252 * empty). Returns false otherwise. */ 253 bool 254 is_file(file_status_t file_type) 255 { 256 return file_type != FN_ERROR && file_type != FN_NOENT && file_type != FN_DIR; 257 } 258 259 /** Returns true if <b>file_type</b> represents an existing directory. Returns 260 * false otherwise. */ 261 bool 262 is_dir(file_status_t file_type) 263 { 264 return file_type == FN_DIR; 265 } 266 267 /** Create a file named <b>fname</b> with the contents <b>str</b>. Overwrite 268 * the previous <b>fname</b> if possible. Return 0 on success, -1 on failure. 269 * 270 * This function replaces the old file atomically, if possible. This 271 * function, and all other functions in util.c that create files, create them 272 * with mode 0600. 273 */ 274 MOCK_IMPL(int, 275 write_str_to_file,(const char *fname, const char *str, int bin)) 276 { 277 #ifdef _WIN32 278 if (!bin && strchr(str, '\r')) { 279 log_warn(LD_BUG, 280 "We're writing a text string that already contains a CR to %s", 281 escaped(fname)); 282 } 283 #endif /* defined(_WIN32) */ 284 return write_bytes_to_file(fname, str, strlen(str), bin); 285 } 286 287 /** Represents a file that we're writing to, with support for atomic commit: 288 * we can write into a temporary file, and either remove the file on 289 * failure, or replace the original file on success. */ 290 struct open_file_t { 291 char *tempname; /**< Name of the temporary file. */ 292 char *filename; /**< Name of the original file. */ 293 unsigned rename_on_close:1; /**< Are we using the temporary file or not? */ 294 unsigned binary:1; /**< Did we open in binary mode? */ 295 int fd; /**< fd for the open file. */ 296 FILE *stdio_file; /**< stdio wrapper for <b>fd</b>. */ 297 }; 298 299 /** Try to start writing to the file in <b>fname</b>, passing the flags 300 * <b>open_flags</b> to the open() syscall, creating the file (if needed) with 301 * access value <b>mode</b>. If the O_APPEND flag is set, we append to the 302 * original file. Otherwise, we open a new temporary file in the same 303 * directory, and either replace the original or remove the temporary file 304 * when we're done. 305 * 306 * Return the fd for the newly opened file, and store working data in 307 * *<b>data_out</b>. The caller should not close the fd manually: 308 * instead, call finish_writing_to_file() or abort_writing_to_file(). 309 * Returns -1 on failure. 310 * 311 * NOTE: When not appending, the flags O_CREAT and O_TRUNC are treated 312 * as true and the flag O_EXCL is treated as false. 313 * 314 * NOTE: Ordinarily, O_APPEND means "seek to the end of the file before each 315 * write()". We don't do that. 316 */ 317 int 318 start_writing_to_file(const char *fname, int open_flags, int mode, 319 open_file_t **data_out) 320 { 321 open_file_t *new_file = tor_malloc_zero(sizeof(open_file_t)); 322 const char *open_name; 323 int append = 0; 324 325 tor_assert(fname); 326 tor_assert(data_out); 327 #if (O_BINARY != 0 && O_TEXT != 0) 328 tor_assert((open_flags & (O_BINARY|O_TEXT)) != 0); 329 #endif 330 new_file->fd = -1; 331 new_file->filename = tor_strdup(fname); 332 if (open_flags & O_APPEND) { 333 open_name = fname; 334 new_file->rename_on_close = 0; 335 append = 1; 336 open_flags &= ~O_APPEND; 337 } else { 338 tor_asprintf(&new_file->tempname, "%s.tmp", fname); 339 open_name = new_file->tempname; 340 /* We always replace an existing temporary file if there is one. */ 341 open_flags |= O_CREAT|O_TRUNC; 342 open_flags &= ~O_EXCL; 343 new_file->rename_on_close = 1; 344 } 345 #if O_BINARY != 0 346 if (open_flags & O_BINARY) 347 new_file->binary = 1; 348 #endif 349 350 new_file->fd = tor_open_cloexec(open_name, open_flags, mode); 351 if (new_file->fd < 0) { 352 log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s", 353 open_name, fname, strerror(errno)); 354 goto err; 355 } 356 if (append) { 357 if (tor_fd_seekend(new_file->fd) < 0) { 358 log_warn(LD_FS, "Couldn't seek to end of file \"%s\": %s", open_name, 359 strerror(errno)); 360 goto err; 361 } 362 } 363 364 *data_out = new_file; 365 366 return new_file->fd; 367 368 err: 369 if (new_file->fd >= 0) 370 close(new_file->fd); 371 *data_out = NULL; 372 tor_free(new_file->filename); 373 tor_free(new_file->tempname); 374 tor_free(new_file); 375 return -1; 376 } 377 378 /** Given <b>file_data</b> from start_writing_to_file(), return a stdio FILE* 379 * that can be used to write to the same file. The caller should not mix 380 * stdio calls with non-stdio calls. */ 381 FILE * 382 fdopen_file(open_file_t *file_data) 383 { 384 tor_assert(file_data); 385 if (file_data->stdio_file) 386 return file_data->stdio_file; 387 tor_assert(file_data->fd >= 0); 388 if (!(file_data->stdio_file = fdopen(file_data->fd, 389 file_data->binary?"ab":"a"))) { 390 log_warn(LD_FS, "Couldn't fdopen \"%s\" [%d]: %s", file_data->filename, 391 file_data->fd, strerror(errno)); 392 } 393 return file_data->stdio_file; 394 } 395 396 /** Combines start_writing_to_file with fdopen_file(): arguments are as 397 * for start_writing_to_file, but */ 398 FILE * 399 start_writing_to_stdio_file(const char *fname, int open_flags, int mode, 400 open_file_t **data_out) 401 { 402 FILE *res; 403 if (start_writing_to_file(fname, open_flags, mode, data_out)<0) 404 return NULL; 405 if (!(res = fdopen_file(*data_out))) { 406 abort_writing_to_file(*data_out); 407 *data_out = NULL; 408 } 409 return res; 410 } 411 412 /** Helper function: close and free the underlying file and memory in 413 * <b>file_data</b>. If we were writing into a temporary file, then delete 414 * that file (if abort_write is true) or replaces the target file with 415 * the temporary file (if abort_write is false). */ 416 static int 417 finish_writing_to_file_impl(open_file_t *file_data, int abort_write) 418 { 419 int r = 0; 420 421 tor_assert(file_data && file_data->filename); 422 if (file_data->stdio_file) { 423 if (fclose(file_data->stdio_file)) { 424 log_warn(LD_FS, "Error closing \"%s\": %s", file_data->filename, 425 strerror(errno)); 426 abort_write = r = -1; 427 } 428 } else if (file_data->fd >= 0 && close(file_data->fd) < 0) { 429 log_warn(LD_FS, "Error flushing \"%s\": %s", file_data->filename, 430 strerror(errno)); 431 abort_write = r = -1; 432 } 433 434 if (file_data->rename_on_close) { 435 tor_assert(file_data->tempname && file_data->filename); 436 if (!abort_write) { 437 tor_assert(strcmp(file_data->filename, file_data->tempname)); 438 if (replace_file(file_data->tempname, file_data->filename)) { 439 log_warn(LD_FS, "Error replacing \"%s\": %s", file_data->filename, 440 strerror(errno)); 441 abort_write = r = -1; 442 } 443 } 444 if (abort_write) { 445 int res = unlink(file_data->tempname); 446 if (res != 0) { 447 /* We couldn't unlink and we'll leave a mess behind */ 448 log_warn(LD_FS, "Failed to unlink %s: %s", 449 file_data->tempname, strerror(errno)); 450 r = -1; 451 } 452 } 453 } 454 455 tor_free(file_data->filename); 456 tor_free(file_data->tempname); 457 tor_free(file_data); 458 459 return r; 460 } 461 462 /** Finish writing to <b>file_data</b>: close the file handle, free memory as 463 * needed, and if using a temporary file, replace the original file with 464 * the temporary file. */ 465 int 466 finish_writing_to_file(open_file_t *file_data) 467 { 468 return finish_writing_to_file_impl(file_data, 0); 469 } 470 471 /** Finish writing to <b>file_data</b>: close the file handle, free memory as 472 * needed, and if using a temporary file, delete it. */ 473 int 474 abort_writing_to_file(open_file_t *file_data) 475 { 476 return finish_writing_to_file_impl(file_data, 1); 477 } 478 479 /** Helper: given a set of flags as passed to open(2), open the file 480 * <b>fname</b> and write all the sized_chunk_t structs in <b>chunks</b> to 481 * the file. Do so as atomically as possible e.g. by opening temp files and 482 * renaming. */ 483 static int 484 write_chunks_to_file_impl(const char *fname, const smartlist_t *chunks, 485 int open_flags) 486 { 487 open_file_t *file = NULL; 488 int fd; 489 ssize_t result; 490 fd = start_writing_to_file(fname, open_flags, 0600, &file); 491 if (fd<0) 492 return -1; 493 SMARTLIST_FOREACH(chunks, sized_chunk_t *, chunk, 494 { 495 result = write_all_to_fd(fd, chunk->bytes, chunk->len); 496 if (result < 0) { 497 log_warn(LD_FS, "Error writing to \"%s\": %s", fname, 498 strerror(errno)); 499 goto err; 500 } 501 tor_assert((size_t)result == chunk->len); 502 }); 503 504 return finish_writing_to_file(file); 505 err: 506 abort_writing_to_file(file); 507 return -1; 508 } 509 510 /** Given a smartlist of sized_chunk_t, write them to a file 511 * <b>fname</b>, overwriting or creating the file as necessary. 512 * If <b>no_tempfile</b> is 0 then the file will be written 513 * atomically. */ 514 int 515 write_chunks_to_file(const char *fname, const smartlist_t *chunks, int bin, 516 int no_tempfile) 517 { 518 int flags = OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT); 519 520 if (no_tempfile) { 521 /* O_APPEND stops write_chunks_to_file from using tempfiles */ 522 flags |= O_APPEND; 523 } 524 return write_chunks_to_file_impl(fname, chunks, flags); 525 } 526 527 /** Write <b>len</b> bytes, starting at <b>str</b>, to <b>fname</b> 528 using the open() flags passed in <b>flags</b>. */ 529 static int 530 write_bytes_to_file_impl(const char *fname, const char *str, size_t len, 531 int flags) 532 { 533 int r; 534 sized_chunk_t c = { str, len }; 535 smartlist_t *chunks = smartlist_new(); 536 smartlist_add(chunks, &c); 537 r = write_chunks_to_file_impl(fname, chunks, flags); 538 smartlist_free(chunks); 539 return r; 540 } 541 542 /** As write_str_to_file, but does not assume a NUL-terminated 543 * string. Instead, we write <b>len</b> bytes, starting at <b>str</b>. */ 544 MOCK_IMPL(int, 545 write_bytes_to_file,(const char *fname, const char *str, size_t len, 546 int bin)) 547 { 548 return write_bytes_to_file_impl(fname, str, len, 549 OPEN_FLAGS_REPLACE|(bin?O_BINARY:O_TEXT)); 550 } 551 552 /** As write_bytes_to_file, but if the file already exists, append the bytes 553 * to the end of the file instead of overwriting it. */ 554 int 555 append_bytes_to_file(const char *fname, const char *str, size_t len, 556 int bin) 557 { 558 return write_bytes_to_file_impl(fname, str, len, 559 OPEN_FLAGS_APPEND|(bin?O_BINARY:O_TEXT)); 560 } 561 562 /** Like write_str_to_file(), but also return -1 if there was a file 563 already residing in <b>fname</b>. */ 564 int 565 write_bytes_to_new_file(const char *fname, const char *str, size_t len, 566 int bin) 567 { 568 return write_bytes_to_file_impl(fname, str, len, 569 OPEN_FLAGS_DONT_REPLACE| 570 (bin?O_BINARY:O_TEXT)); 571 } 572 573 /** 574 * Read the contents of the open file <b>fd</b> presuming it is a FIFO 575 * (or similar) file descriptor for which the size of the file isn't 576 * known ahead of time. 577 * Return NULL on failure, and a NUL-terminated string on success. 578 * On success, set <b>sz_out</b> to the number of bytes read (not including 579 * the final NULL, which wasn't read from <b>fd</b>). 580 */ 581 char * 582 read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) 583 { 584 ssize_t r; 585 size_t pos = 0; 586 char *string = NULL; 587 size_t string_max = 0; 588 589 if (max_bytes_to_read+1 >= SIZE_T_CEILING) { 590 errno = EINVAL; 591 return NULL; 592 } 593 594 do { 595 /* XXXX This "add 1K" approach is a little goofy; if we care about 596 * performance here, we should be doubling. But in practice we shouldn't 597 * be using this function on big files anyway. */ 598 string_max = pos + 1024; 599 if (string_max > max_bytes_to_read) 600 string_max = max_bytes_to_read + 1; 601 string = tor_realloc(string, string_max); 602 r = read(fd, string + pos, string_max - pos - 1); 603 if (r < 0) { 604 int save_errno = errno; 605 tor_free(string); 606 errno = save_errno; 607 return NULL; 608 } 609 610 pos += r; 611 } while (r > 0 && pos < max_bytes_to_read); 612 613 tor_assert(pos < string_max); 614 *sz_out = pos; 615 string[pos] = '\0'; 616 return string; 617 } 618 619 /** Read the contents of <b>filename</b> into a newly allocated 620 * string; return the string on success or NULL on failure. 621 * 622 * If <b>stat_out</b> is provided, store the result of stat()ing the 623 * file into <b>stat_out</b>. 624 * 625 * If <b>flags</b> & RFTS_BIN, open the file in binary mode. 626 * If <b>flags</b> & RFTS_IGNORE_MISSING, don't warn if the file 627 * doesn't exist. 628 * 629 * Unless the RFTS_BIN flag is set in <b>flags</b>, this function will strip 630 * any CR characters in the return value on all platforms. 631 */ 632 /* 633 * This function <em>may</em> return an erroneous result if the file 634 * is modified while it is running, but must not crash or overflow. 635 * Right now, the error case occurs when the file length grows between 636 * the call to stat and the call to read_all: the resulting string will 637 * be truncated. 638 */ 639 MOCK_IMPL(char *, 640 read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) 641 { 642 int fd; /* router file */ 643 struct stat statbuf; 644 char *string; 645 ssize_t r; 646 int bin = flags & RFTS_BIN; 647 648 tor_assert(filename); 649 650 fd = tor_open_cloexec(filename,O_RDONLY|(bin?O_BINARY:O_TEXT),0); 651 if (fd<0) { 652 int severity = LOG_WARN; 653 int save_errno = errno; 654 if (errno == ENOENT && (flags & RFTS_IGNORE_MISSING)) 655 severity = LOG_INFO; 656 log_fn(severity, LD_FS,"Could not open \"%s\": %s",filename, 657 strerror(errno)); 658 errno = save_errno; 659 return NULL; 660 } 661 662 if (fstat(fd, &statbuf)<0) { 663 int save_errno = errno; 664 close(fd); 665 log_warn(LD_FS,"Could not fstat \"%s\".",filename); 666 errno = save_errno; 667 return NULL; 668 } 669 670 #ifndef _WIN32 671 /** When we detect that we're reading from a FIFO, don't read more than 672 * this many bytes. It's insane overkill for most uses. */ 673 #define FIFO_READ_MAX (1024*1024) 674 if (S_ISFIFO(statbuf.st_mode)) { 675 size_t sz = 0; 676 string = read_file_to_str_until_eof(fd, FIFO_READ_MAX, &sz); 677 int save_errno = errno; 678 if (string && stat_out) { 679 statbuf.st_size = sz; 680 memcpy(stat_out, &statbuf, sizeof(struct stat)); 681 } 682 close(fd); 683 if (!string) 684 errno = save_errno; 685 return string; 686 } 687 #endif /* !defined(_WIN32) */ 688 689 if ((uint64_t)(statbuf.st_size)+1 >= SIZE_T_CEILING) { 690 close(fd); 691 errno = EINVAL; 692 return NULL; 693 } 694 695 string = tor_malloc((size_t)(statbuf.st_size+1)); 696 697 r = read_all_from_fd(fd,string,(size_t)statbuf.st_size); 698 if (r<0) { 699 int save_errno = errno; 700 log_warn(LD_FS,"Error reading from file \"%s\": %s", filename, 701 strerror(errno)); 702 tor_free(string); 703 close(fd); 704 errno = save_errno; 705 return NULL; 706 } 707 string[r] = '\0'; /* NUL-terminate the result. */ 708 709 if (!bin && strchr(string, '\r')) { 710 log_debug(LD_FS, "We didn't convert CRLF to LF as well as we hoped " 711 "when reading %s. Coping.", 712 filename); 713 tor_strstrip(string, "\r"); 714 r = strlen(string); 715 } 716 if (!bin) { 717 statbuf.st_size = (size_t) r; 718 } else { 719 if (r != statbuf.st_size) { 720 /* Unless we're using text mode on win32, we'd better have an exact 721 * match for size. */ 722 int save_errno = errno; 723 log_warn(LD_FS,"Could read only %d of %ld bytes of file \"%s\".", 724 (int)r, (long)statbuf.st_size,filename); 725 tor_free(string); 726 close(fd); 727 errno = save_errno; 728 return NULL; 729 } 730 } 731 close(fd); 732 if (stat_out) { 733 memcpy(stat_out, &statbuf, sizeof(struct stat)); 734 } 735 736 return string; 737 } 738 739 /** Attempt to read a file <b>fname</b>. If the file's contents is 740 * equal to the string <b>str</b>, return 0. Otherwise, attempt to 741 * overwrite the file with the contents of <b>str</b> and return 742 * the value of write_str_to_file(). 743 */ 744 int 745 write_str_to_file_if_not_equal(const char *fname, const char *str) 746 { 747 char *fstr = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL); 748 int rv; 749 750 if (!fstr || strcmp(str, fstr)) { 751 rv = write_str_to_file(fname, str, 0); 752 } else { 753 rv = 0; 754 } 755 tor_free(fstr); 756 return rv; 757 } 758 759 #if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS) 760 #include "ext/getdelim.c" 761 #endif