This is like rprintf, but it also tries to print some * representation of the error code. Normally errcode = errno. * * Unlike rprintf, this always adds a newline and there should not be * one in the format string. * * Note that since strerror might involve dynamically loading a * message catalog we need to call it once before chroot-ing. */
| 451 | * Note that since strerror might involve dynamically loading a |
| 452 | * message catalog we need to call it once before chroot-ing. */ |
| 453 | void rsyserr(enum logcode code, int errcode, const char *format, ...) |
| 454 | { |
| 455 | va_list ap; |
| 456 | char buf[BIGPATHBUFLEN]; |
| 457 | size_t len; |
| 458 | |
| 459 | /* snprintf returns the would-have-been length on truncation, so |
| 460 | * each cumulative call must be guarded; if not, sizeof buf - len |
| 461 | * can underflow when promoted to size_t and the next call writes |
| 462 | * past the buffer. */ |
| 463 | len = snprintf(buf, sizeof buf, RSYNC_NAME ": [%s] ", who_am_i()); |
| 464 | |
| 465 | if (len < sizeof buf) { |
| 466 | va_start(ap, format); |
| 467 | len += vsnprintf(buf + len, sizeof buf - len, format, ap); |
| 468 | va_end(ap); |
| 469 | } |
| 470 | |
| 471 | if (len < sizeof buf) { |
| 472 | len += snprintf(buf + len, sizeof buf - len, |
| 473 | ": %s (%d)\n", strerror(errcode), errcode); |
| 474 | } |
| 475 | if (len >= sizeof buf) |
| 476 | exit_cleanup(RERR_MESSAGEIO); |
| 477 | |
| 478 | rwrite(code, buf, len, 0); |
| 479 | } |
| 480 | |
| 481 | void rflush(enum logcode code) |
| 482 | { |
no test coverage detected