Package: cron Version: 3.0pl1-100 Tags: patch perror is called after library functions besides the one that failed, and without saving/restoring errno or otherwise referencing the correct value. Some of those problems are introduced by the debian diff.gz and some exist in the upstream distribution.
You can test that this is a real problem with something like: $ strace -e unlink,write -o /dev/stdout crontab -r 2>/dev/full unlink("crontabs/pryzbyj") = -1 EACCES (Permission denied) write(2, "/var/spool/cron/", 16) = -1 ENOSPC (No space left on device) write(2, "crontabs/pryzbyj: No space left "..., 42) = -1 ENOSPC (No space left on device) strace causes crontab to run with EGID=GID instead of GID(crontab), so unlink fails (that strace happens to cause crontab to fail without manually reducing permissions on the cronspools is a happy concidence). When the fprintf(stderr) error handler fails due to ENOSPC (as intended), it upsets errno, and the written perror message corresponds (less usefully) to the 2nd error instead of the first. This is an interdiff against cron-3.0pl1-103 (Debian). diff -u cron-3.0pl1/misc.c cron-3.0pl1/misc.c --- cron-3.0pl1/misc.c +++ cron-3.0pl1/misc.c @@ -203,8 +203,7 @@ fprintf(stderr, "%s: created\n", CRONDIR); stat(CRONDIR, &sb); } else { - fprintf(stderr, "%s: ", CRONDIR); - perror("mkdir"); + fprintf(stderr, "%s: mkdir: %s\n", CRONDIR, strerror(errno)); exit(ERROR_EXIT); } } @@ -214,8 +213,7 @@ exit(ERROR_EXIT); } if (chdir(CRONDIR) < OK) { - fprintf(stderr, "cannot chdir(%s), bailing out.\n", CRONDIR); - perror(CRONDIR); + fprintf(stderr, "%s: chdir: %s\n", strerror(errno)); exit(ERROR_EXIT); } @@ -227,8 +225,7 @@ fprintf(stderr, "%s: created\n", SPOOL_DIR); stat(SPOOL_DIR, &sb); } else { - fprintf(stderr, "%s: ", SPOOL_DIR); - perror("mkdir"); + fprintf(stderr, "%s: mkdir: %s\n", SPOOL_DIR, strerror(errno)); exit(ERROR_EXIT); } } @@ -507,9 +504,8 @@ if (LogFD < OK) { LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600); if (LogFD < OK) { - fprintf(stderr, "%s: can't open log file\n", - ProgramName); - perror(LOG_FILE); + fprintf(stderr, "%s: %s: open: %s\n", + ProgramName, LOG_FILE, strerror(errno)); } else { (void) fcntl(LogFD, F_SETFD, 1); } diff -u cron-3.0pl1/crontab.c cron-3.0pl1/crontab.c --- cron-3.0pl1/crontab.c +++ cron-3.0pl1/crontab.c @@ -326,8 +326,7 @@ if (errno == ENOENT) fprintf(stderr, "no crontab for %s\n", User); else { - fprintf(stderr, "%s/", CRONDIR); - perror(n); + fprintf(stderr, "%s/: fopen: %s\n", n, strerror(errno)); } exit(ERROR_EXIT); } else if ((fd=fileno(f))==-1) { @@ -413,8 +412,7 @@ if (errno == ENOENT) fprintf(stderr, "no crontab for %s\n", User); else { - fprintf(stderr, "%s/", CRONDIR); - perror(n); + fprintf(stderr, "%s/: unlink: %s\n", CRONDIR, strerror(errno)); } exit(ERROR_EXIT); } @@ -583,8 +581,7 @@ (void) snprintf(n, MAX_FNAME, CRON_TAB(User)); if (!(f = fopen(n, "r"))) { if (errno != ENOENT) { - fprintf(stderr, "%s/", CRONDIR); - perror(n); + fprintf(stderr, "%s/: fdopen: %s", n, strerror(errno)); exit(ERROR_EXIT); } fprintf(stderr, "no crontab for %s - using an empty one\n", @@ -875,14 +872,12 @@ um = umask(077); fd = mkstemp(tn); if (fd < 0) { - fprintf(stderr, "%s/", CRONDIR); - perror(tn); + fprintf(stderr, "%s/: mkstemp: %s\n", CRONDIR, strerror(errno)); return(-2); } tmp = fdopen(fd, "w+"); if (!tmp) { - fprintf(stderr, "%s/", CRONDIR); - perror(tn); + fprintf(stderr, "%s/: fdopen: %s\n", CRONDIR, strerror(errno)); return (-2); } (void) umask(um); @@ -903,9 +898,8 @@ putc(ch, tmp); if (ferror(tmp) || fflush(tmp) || fsync(fd)) { - fprintf(stderr, "%s: error while writing new crontab to %s\n", - ProgramName, tn); - perror("Error"); + fprintf(stderr, "%s: %s: %s\n", + ProgramName, tn, strerror(errno)); fclose(tmp); unlink(tn); return (-2); } @@ -969,9 +963,8 @@ } if (rename(tn, n)) { - fprintf(stderr, "%s: error renaming %s to %s\n", - ProgramName, tn, n); - perror("rename"); + fprintf(stderr, "%s: %s: rename: %s\n", + ProgramName, n, strerror(errno)); unlink(tn); return (-2); } @@ -994,16 +987,14 @@ (void) gettimeofday(&tvs[0], &tz); tvs[1] = tvs[0]; if (utimes(SPOOL_DIR, tvs) < OK) { - fprintf(stderr, "crontab: can't update mtime on spooldir\n"); - fprintf(stderr, "%s/", CRONDIR); - perror(SPOOL_DIR); + fprintf(stderr, "%s/: utimes: %s", CRONDIR, strerror(errno)); + fputs("crontab: can't update mtime on spooldir\n", stderr); return; } #else if (utime(SPOOL_DIR, NULL) < OK) { - fprintf(stderr, "crontab: can't update mtime on spooldir\n"); - fprintf(stderr, "%s/", CRONDIR); - perror(SPOOL_DIR); + fprintf(stderr, "%s: utime: %s\n", CRONDIR, strerror(errno)); + fputs(stderr, "crontab: can't update mtime on spooldir\n", stderr); return; } #endif /*USE_UTIMES*/ diff -u cron-3.0pl1/do_command.c cron-3.0pl1/do_command.c --- cron-3.0pl1/do_command.c +++ cron-3.0pl1/do_command.c @@ -342,8 +342,7 @@ } #endif execle(shell, shell, "-c", e->cmd, (char *)0, jobenv); - fprintf(stderr, "execl: couldn't exec `%s'\n", shell); - perror("execl"); + fprintf(stderr, "%s: execle: %s\n", shell, strerror(er)); _exit(ERROR_EXIT); } break; -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]