ehrlich@psuvax1.psu.edu (Dan Ehrlich) (09/17/87)
After being serverley chastised for my mods to syslogd.c to fix logging ftpd after a chroot. I submit the following for you amusement. This is probably they way it should have been done to begin with. In lib/libc/gen/syslog.c openlog will do a "connect" as well as creating the socket when LOG_NDELAY is specified. There was also the same problem with chroot for /dev/console as for /dev/log so that should now work also. --Dan Ehrlich RCS file: RCS/syslog.c,v retrieving revision 1.1 diff -c -r1.1 syslog.c *** /tmp/,RCSt1008669 Wed Sep 16 18:37:56 1987 --- syslog.c Wed Sep 16 18:27:40 1987 *************** *** 6,11 **** --- 6,12 ---- #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)syslog.c 5.9 (Berkeley) 5/7/86"; + static char RCSsrc[] = "$Source: /usr/src/lib/libc/gen/RCS/syslog.c,v $"; #endif LIBC_SCCS and not lint /* *************** *** 44,49 **** --- 45,51 ---- static char ctty[] = "/dev/console"; static int LogFile = -1; /* fd for log */ + static int ConsFD = -1; /* fd for console */ static int LogStat = 0; /* status bits, set by openlog() */ static char *LogTag = "syslog"; /* string to tag the entry with */ static int LogMask = 0xff; /* mask of priorities to be logged */ *************** *** 63,71 **** register int c; long now; int pid, olderrno = errno; /* see if we should just throw out this message */ ! if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) return; if (LogFile < 0) openlog(LogTag, LogStat | LOG_NDELAY, 0); --- 65,74 ---- register int c; long now; int pid, olderrno = errno; + int oldh_errno = h_errno; /* see if we should just throw out this message */ ! if (pri <= LOG_EMERG || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0) return; if (LogFile < 0) openlog(LogTag, LogStat | LOG_NDELAY, 0); *************** *** 101,115 **** *b++ = c; continue; } ! if ((c = *f++) != 'm') { *b++ = '%'; *b++ = c; continue; } ! if ((unsigned)olderrno > sys_nerr) ! sprintf(b, "error %d", olderrno); ! else ! strcpy(b, sys_errlist[olderrno]); b += strlen(b); } *b++ = '\n'; --- 104,131 ---- *b++ = c; continue; } ! if (((c = *f++) != 'm') && (c != 'h')) { *b++ = '%'; *b++ = c; continue; } ! /* ! * Handle %m and %h formats. ! * %m prints text associated with errno ! * %h prints text associated with h_errno. ! */ ! switch (c) { ! case 'm': if ((unsigned)olderrno > sys_nerr) ! sprintf(b, "error %d", olderrno); ! else ! strcpy(b, sys_errlist[olderrno]); ! break; ! case 'h': if ((unsigned)oldh_errno > sys_nherr) ! sprintf(b, "herror %d", oldh_errno); ! else ! strcpy(b, sys_herrlist[oldh_errno]); ! break; ! } b += strlen(b); } *b++ = '\n'; *************** *** 120,127 **** c = MAXLINE; /* output the message to the local logger */ ! if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0) return; if (!(LogStat & LOG_CONS)) return; --- 136,145 ---- c = MAXLINE; /* output the message to the local logger */ ! if (send(LogFile, outline, c, 0) >= 0) return; + else + perror("syslog: send"); if (!(LogStat & LOG_CONS)) return; *************** *** 130,146 **** if (pid == -1) return; if (pid == 0) { ! int fd; ! ! signal(SIGALRM, SIG_DFL); ! sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); ! alarm(5); ! fd = open(ctty, O_WRONLY); ! alarm(0); strcat(o, "\r"); o = index(outline, '>') + 1; ! write(fd, o, c + 1 - (o - outline)); ! close(fd); _exit(0); } if (!(LogStat & LOG_NOWAIT)) --- 148,162 ---- if (pid == -1) return; if (pid == 0) { ! /* ! * Open console if not already. ! */ ! if (ConsFD == -1) ! ConsFD = open(ctty, O_WRONLY | O_NDELAY); strcat(o, "\r"); o = index(outline, '>') + 1; ! write(ConsFD, o, c + 1 - (o - outline)); ! close(ConsFD); _exit(0); } if (!(LogStat & LOG_NOWAIT)) *************** *** 166,173 **** --- 182,198 ---- SyslogAddr.sa_family = AF_UNIX; strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data); if (LogStat & LOG_NDELAY) { + /* + * If LOG_NDELAY, connect to the socket and grab a + * descriptor for /dev/console (if LOG_CONS), in + * case the user wants to chroot. + */ LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); fcntl(LogFile, F_SETFD, 1); + if (connect(LogFile, &SyslogAddr, sizeof SyslogAddr) < 0) + perror("openlog: connect"); + if (LogStat & LOG_CONS) + ConsFD = open(ctty, O_WRONLY | O_NDELAY); } }
chris@mimsy.UUCP (Chris Torek) (09/21/87)
There is a problem with these patches. According to syslog(3), LOG_CONS `... is safe to use in daemon processes that have no controlling terminal since syslog will fork before opening the console'. This version of syslog() does not do that. My own solution is simply to allow syslog() with LOG_CONS to fail if the connect() fails and the program using syslog does a chdir(). This is not right either, but does not attach the program to the console. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris