Hello community, here is the log from the commit of package mingetty checked in at Wed May 30 01:15:28 CEST 2007. -------- --- mingetty/mingetty.changes 2006-05-24 17:16:46.000000000 +0200 +++ /mounts/work_src_done/STABLE/mingetty/mingetty.changes 2007-05-29 17:26:14.174970000 +0200 @@ -1,0 +2,6 @@ +Tue May 29 16:55:52 CEST 2007 - werner@suse.de + +- Adopt autologin and other new feature of the other mingetty + at sourceforge. + +------------------------------------------------------------------- Old: ---- mingetty-0.9.6s.dif mingetty-0.9.6s.tar.bz2 New: ---- mingetty-1.0.7s.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mingetty.spec ++++++ --- /var/tmp/diff_new_pack.r32719/_old 2007-05-30 01:14:57.000000000 +0200 +++ /var/tmp/diff_new_pack.r32719/_new 2007-05-30 01:14:57.000000000 +0200 @@ -1,7 +1,7 @@ # -# spec file for package mingetty (Version 0.9.6s) +# spec file for package mingetty (Version 1.0.7s) # -# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine # package are under the same license as the package itself. # @@ -11,16 +11,16 @@ # norootforbuild Name: mingetty -License: GPL +License: GNU General Public License (GPL) Group: System/Base Autoreqprov: on -Version: 0.9.6s -Release: 88 +Version: 1.0.7s +Release: 1 Summary: Minimal Getty for Virtual Consoles Only Provides: sysvinit:/sbin/mingetty BuildRoot: %{_tmppath}/%{name}-%{version}-build -Source: mingetty-0.9.6s.tar.bz2 -Patch: mingetty-0.9.6s.dif +Source: mingetty-1.0.7s.tar.bz2 +#Patch: mingetty-1.0.7s.dif %description The mingetty program is a lightweight, minimalist getty program for use @@ -37,10 +37,15 @@ %prep %setup -q -%patch +#%patch %build -make RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -D_FILE_OFFSET_BITS=64" DEFTERM=linux +%ifarch s390 s390x +DEFTERM=dump +%else +DEFTERM=linux +%endif +make RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -D_FILE_OFFSET_BITS=64" DEFTERM=${DEFTERM} %install mkdir -p ${RPM_BUILD_ROOT}{/sbin,%{_mandir}/man8} @@ -51,7 +56,10 @@ /sbin/mingetty %doc %{_mandir}/man8/mingetty.8.gz -%changelog -n mingetty +%changelog +* Tue May 29 2007 - werner@suse.de +- Adopt autologin and other new feature of the other mingetty + at sourceforge. * Wed May 24 2006 - schwab@suse.de - Don't strip binaries. * Wed Jan 25 2006 - mls@suse.de ++++++ mingetty-0.9.6s.tar.bz2 -> mingetty-1.0.7s.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/CHANGES new/mingetty-1.0.7s/CHANGES --- old/mingetty-0.9.6s/CHANGES 2002-11-13 18:14:17.000000000 +0100 +++ new/mingetty-1.0.7s/CHANGES 2007-05-29 17:23:36.000000000 +0200 @@ -30,3 +30,12 @@ Add an old option for avoiding vcs/vcsa hangup, terminal reset, and the usage of the glibc for updating wtmp. Cleanup the source and the manual page. + +* 04/03/30, Werner Fink <werner@suse.de> + More about UTF-8: enable the kernel to erease UTF-8 multi byte + characters. Therefore add workaround if glibc bits/termios.h + is missing the IUTF8 input flag. + +* 07/05/29, Werner Fink <werner@suse.de> + Adopt autologin and other new feature of the other mingetty + at sourceforge. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/Makefile new/mingetty-1.0.7s/Makefile --- old/mingetty-0.9.6s/Makefile 2002-11-14 13:29:44.000000000 +0100 +++ new/mingetty-1.0.7s/Makefile 2007-05-29 16:49:01.000000000 +0200 @@ -2,23 +2,27 @@ # # DEFTERM = linux -VERSION = mingetty-0.9.6s +VERSION = mingetty-1.0.7s # DEFINES = -DRESET_TTY=1 -DDEFAULT_TERM=\"$(DEFTERM)\" -DVERSION=\"$(VERSION)\" -CFLAGS = -Wall -O2 -pipe -D_GNU_SOURCE -D_BSD_SOURCE $(DEFINES) +CFLAGS = -Wall $(RPM_OPT_FLAGS) -pipe -D_GNU_SOURCE -D_BSD_SOURCE $(DEFINES) # -LDFLAGS = -Wl,-warn-common -s +LDFLAGS = -Wl,-warn-common CC = gcc +DESTDIR = +MANDIR = /usr/share/man +SBINDIR = /sbin + all: mingetty size mingetty install: all - install -s mingetty /sbin/ - install -m 644 mingetty.8 /usr/share/man/man8/ + install mingetty $(DESTDIR)$(SBINDIR) + install -m 644 mingetty.8 $(DESTDIR)$(MANDIR)/man8/ -mingetty: mingetty.o sigfholder.o -mingetty.o: mingetty.c +mingetty: mingetty.o revoke.o +mingetty.o: mingetty.c revoke.c revoke.h clean: rm -f *.o mingetty diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/mingetty.8 new/mingetty-1.0.7s/mingetty.8 --- old/mingetty-0.9.6s/mingetty.8 2002-11-13 18:05:22.000000000 +0100 +++ new/mingetty-1.0.7s/mingetty.8 2007-05-29 17:14:24.000000000 +0200 @@ -1,12 +1,24 @@ .\" -.TH MINGETTY 8 "12 June 1999" "SuSE" "Linux Programmer's Manual" +.TH MINGETTY 8 "29 May 2007" "SuSE" "Linux Programmer's Manual" .SH NAME mingetty \- minimal getty for consoles .SH SYNOPSIS .B /sbin/mingetty -.RB [ \-\-noclear ]\ [ \-\-noreset ]\ [ \-\-long\-hostname ] -.RB [ \-\-no-hostname ]\ [ \-\-login\ \fIlogin_binary\fP ]\ [ \-\-old ] +.RB [ \-\-noclear ] +.RB [ \-\-nonewline ] +.RB [ \-\-noissue ] +.RB [ \-\-nohangup ] +.RB [ \-\-noreset ] +.RB [ \-\-no\-hostname ] +.RB [ \-\-long-hostname ] +.RB [ \-\-login\ \fIlogin_binary\fP ] .RB [ \-\-logopts\ \fI"login_options"\fP ] +.RB [ \-\-nice\ \fInumber\fP ] +.RB [ \-\-delay\ \fInumber\fP ] +.RB [ \-\-chdir\ \fI/home\fP ] +.RB [ \-\-chroot\ \fI/chroot\fP ] +.RB [ \-\-autologin\ \fIuser\fP ] +.RB [ \-\-old ] .I tty .RI [ term ] .PP @@ -17,7 +29,7 @@ .BR agetty (8), .B mingetty is not suitable for serial lines. -For this purpose the usage +For this purpose the usage of .BR mgetty (8) is recommend. .PP @@ -32,14 +44,24 @@ sane default values. With this option the terminal settings will not be changed. .TP -.B \-\-long\-hostname -By default the hostname is only printed until the first dot. -With this option enabled, the full text from gethostname() is shown. +.B \-\-nonewline +Do not print a newline before writing out /etc/issue. +.TP +.B \-\-noissue +Do not output /etc/issue. +.TP +.B \-\-nohangup +Do not call vhangup() to disable writing to this tty by +other applications. .TP .B \-\-no\-hostname By default the hostname will be printed. With this option enabled, no hostname at all will be shown. .TP +.B \-\-long\-hostname +By default the hostname is only printed until the first dot. +With this option enabled, the full text from gethostname() is shown. +.TP .B \-\-login \fIlogin_binary\fP Use the \fIlogin_binary\fP to log in instead of the default .IR /bin/login . @@ -52,6 +74,24 @@ .IR /bin/login . Please read the SECURITY NOTICE below if you want to use this. .TP +.B \-\-nice 10 +Change the priority by calling nice(). +.TP +.B \-\-delay 5 +Sleep this many seconds after startup of mingetty. +.TP +.B \-\-chdir /home +Change into this directory before calling the login prog. +.TP +.B \-\-chroot /chroot +Call chroot() with this directory name. +.TP +.B \-\-autologin username +Log the specified user automatically in without asking for +a login name and password. Check the \-f option from +.B /bin/login +for this. +.TP .B \-\-old Do not reset the terminal line to standard settings and do not hangup the diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/mingetty.c new/mingetty-1.0.7s/mingetty.c --- old/mingetty-0.9.6s/mingetty.c 2002-11-14 13:32:03.000000000 +0100 +++ new/mingetty-1.0.7s/mingetty.c 2007-05-29 17:06:50.000000000 +0200 @@ -65,78 +65,59 @@ * Add an old option for avoiding vcs/vcsa hangup, terminal * reset, and the usage of the glibc for updating wtmp. * Cleanup the source and the manual page. + * + * Tue Mar 30 13:53:48 CEST 2004 - werner@suse.de + * More about UTF-8: enable the kernel to erease UTF-8 multi byte + * characters. Therefore add workaround if glibc bits/termios.h + * is missing the IUTF8 input flag. + * + * Tue May 29 16:55:52 CEST 2007 - Werner Fink <werner@suse.de> + * Adopt autologin and other new feature of the other mingetty + * at sourceforge. */ #ifndef VERSION -# define VERSION "mingetty-0.9.6s" +# define VERSION "mingetty-1.0.7s" #endif #ifndef DEFAULT_TERM # define DEFAULT_TERM "linux" #endif -#ifndef DEBUG_THIS -# define DEBUG_THIS 0 -#endif - #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <sys/syscall.h> -extern int sigfholder(const char *path, int sig); +#include <termios.h> #include <string.h> -#include <grp.h> #include <sys/ioctl.h> #include <errno.h> -#include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> -#if defined __GLIBC__ && __GLIBC__ >= 2 -# include <signal.h> -#else -# include <sys/signal.h> -#endif +#include <signal.h> #include <fcntl.h> #include <stdarg.h> #include <ctype.h> #include <utmp.h> #include <getopt.h> - -#ifdef RESET_TTY -# if defined __GLIBC__ && __GLIBC__ >= 2 -# include <termios.h> -# else -# include <sys/termios.h> -# endif -# include <sys/ttydefaults.h> -#endif - -#if defined(_BSD_SOURCE) -# define strerror(errno) sys_errlist[(errno)] -#else -# define strerror(errno) strerror((errno)) -#endif - -#ifdef linux #include <sys/param.h> -#define USE_SYSLOG -#endif +#include <syslog.h> +#include <sys/utsname.h> +#include <time.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <grp.h> +#include <locale.h> +#include <iconv.h> +#include <wctype.h> +#include <sys/kd.h> +#include "revoke.h" - /* If USE_SYSLOG is undefined all diagnostics go directly to /dev/console. */ -#ifdef USE_SYSLOG -# if defined __GLIBC__ && __GLIBC__ >= 2 -# include <sys/syslog.h> -# else -# include <syslog.h> -# endif +#ifndef IUTF8 +# error IUTF8 input flag not defined #endif #define ISSUE "/etc/issue" /* displayed before the login prompt */ -#include <sys/utsname.h> -#include <time.h> - #define LOGIN "login: " /* login prompt */ - #ifndef _PATH_LOGIN #define _PATH_LOGIN "/bin/login" #endif @@ -150,58 +131,54 @@ static struct utsname uts; /* the hostname */ static char hn[MAXHOSTNAMELEN + 1]; -/* process ID of this program */ -static pid_t pid; -/* session ID of this program */ -static pid_t sid; -/* current time */ -static time_t cur_time; -/* do not send a reset string to the terminal ? */ +/* process and session ID of this program */ +static pid_t pid, sid; +/* login program invoked */ +static char *loginprog = _PATH_LOGIN; +/* Do not send a reset string to the terminal. */ static int noclear = 0; +/* Do not print a newline. */ +static int nonewline = 0; +/* Do not print /etc/issue. */ +static int noissue = 0; +/* Do not call vhangup() on the tty. */ +static int nohangup = 0; +/* Do not print any hostname. */ +static int nohostname = 0; /* Print the whole string of gethostname() instead of just until the next "." */ static int longhostname = 0; -/* Do not print the hostname at all */ -static int nohostname = 0; +/* time to wait, seconds */ +static int delay = 0; +/* chroot directory */ +static char *ch_root = NULL; +/* working directory to change into */ +static char *ch_dir = NULL; +/* 'nice' level of the program */ +static int priority = 0; +/* automatic login with this user */ +static char *autologin = NULL; /* do not reset the terminal ? */ static int noreset = 0; -/* login program */ -static char* loginprog; -/* use old behaviour */ +/* current time */ static int old = 0; +/* current time */ +static int mode = K_RAW; /* * output warn/error messages */ static void _vlogger (int priority, const char *fmt, va_list va_alist) { - char buf[256], *bp; -#ifndef USE_SYSLOG - int fd; -#endif + char buf[256] = {'\0'}, *bp = &buf[0]; -#ifdef USE_SYSLOG - buf[0] = '\0'; - bp = buf; -#else strncpy (buf, progname, sizeof(buf) - 4); buf[sizeof(buf) - 5] = '\0'; strcat (buf, ": "); bp = buf + strlen (buf); -#endif - vsnprintf (bp, sizeof(buf)-strlen(buf), fmt, va_alist); - -#ifdef USE_SYSLOG openlog (progname, LOG_PID, LOG_AUTH); syslog (priority, "%s", buf); closelog (); -#else - strcat (bp, "\r\n"); - if ((fd = open ("/dev/console", 1)) >= 0) { - write (fd, buf, strlen (buf)); - close (fd); - } -#endif } /* @@ -240,14 +217,6 @@ return; } -/* - * cry if wtmp can not be locked - */ -static void sigalrm_handler(int signum) -{ - alert("Lock failed on wtmp"); -} - static void sigquit_handler (int signum) { struct sigaction act; sigset_t set; @@ -269,128 +238,6 @@ abort(); } -#ifdef linux -/* - * - */ -static void vcshangup(const gid_t gid) -{ - struct stat st; - char buf[PATH_MAX+1]; - - if (!vcline) - goto skip; - - /* Set up new virtual console text capture devices */ - strncpy (buf, "/dev/vcs", PATH_MAX); - strncat (buf, vcline, PATH_MAX - strlen(buf)); - - if (stat(buf, &st) < 0) { - if (errno != ENOENT) - error ("%s: %s", buf, strerror(errno)); - goto skip; - } - if (chown (buf, 0, gid) || chmod (buf, (gid ? 0660 : 0600))) { - if (errno == EROFS) - warn("%s: %s", buf, strerror(errno)); - else - error ("%s: %s", buf, strerror(errno)); - } -# ifdef __NR_revoke - _syscall(int, revoke, const char*, buf); -# else - if (sigfholder(buf, SIGHUP)) { /* Be nice, send SIGHUP */ - sleep (2); - if (sigfholder(buf, SIGKILL)) /* Hey, go away */ - sigfholder(buf, SIGCONT); - } -# endif /* __NR_revoke */ - - /* Set up new virtual console text/attribute capture devices */ - strncpy (buf, "/dev/vcsa", PATH_MAX); - strncat (buf, vcline, PATH_MAX - strlen(buf)); - - if (stat(buf, &st) < 0) { - if (errno != ENOENT) - error ("%s: %s", buf, strerror(errno)); - goto skip; - } - if (chown (buf, 0, gid) || chmod (buf, (gid ? 0660 : 0600))) { - if (errno == EROFS) - warn("%s: %s", buf, strerror(errno)); - else - error ("%s: %s", buf, strerror(errno)); - } -# ifdef __NR_revoke - _syscall(int, revoke, const char*, buf); -# else - if (sigfholder(buf, SIGHUP)) { /* Be nice, send SIGHUP */ - sleep (2); - if (sigfholder(buf, SIGKILL)) /* Hey, go away */ - sigfholder(buf, SIGCONT); - } -# endif /* __NR_revoke */ -skip: - return; -} - -# ifdef RESET_TTY -static void reset_stdin() -{ - struct termios termios; - /* The above reset only puts the output things into a sane state. - * The input state is not reset. - */ - memset (&termios, 0, sizeof termios); - if (tcgetattr (0, &termios)) - warn ("tcgetattr problem: %s", strerror(errno)); - - /* Use defaults of <sys/ttydefaults.h> for base settings */ - termios.c_iflag |= TTYDEF_IFLAG; - termios.c_oflag |= TTYDEF_OFLAG; - termios.c_lflag |= TTYDEF_LFLAG; - termios.c_cflag |= (TTYDEF_SPEED | TTYDEF_CFLAG); - - /* Sane setting, allow eight bit characters, no carriage return delay - * the same result as `stty sane cr0 pass8' - */ - termios.c_iflag |= (BRKINT | ICRNL | IMAXBEL); - termios.c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP); - termios.c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); - termios.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\ - NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); - termios.c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE); - termios.c_lflag &= ~(ECHONL | NOFLSH | XCASE | TOSTOP | ECHOPRT); - termios.c_cflag |= (CREAD | CS8 | B38400); - termios.c_cflag &= ~(PARENB); - - /* VTIME and VMIN can overlap with VEOF and VEOL since they are - * only used for non-canonical mode. We just set the at the - * beginning, so nothing bad should happen. - */ - termios.c_cc[VTIME] = 0; - termios.c_cc[VMIN] = 1; - termios.c_cc[VINTR] = CINTR; - termios.c_cc[VQUIT] = CQUIT; - termios.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ - termios.c_cc[VKILL] = CKILL; - termios.c_cc[VEOF] = CEOF; - termios.c_cc[VSWTC] = _POSIX_VDISABLE; - termios.c_cc[VSTART] = CSTART; - termios.c_cc[VSTOP] = CSTOP; - termios.c_cc[VSUSP] = CSUSP; - termios.c_cc[VEOL] = _POSIX_VDISABLE; - termios.c_cc[VREPRINT] = CREPRINT; - termios.c_cc[VDISCARD] = CDISCARD; - termios.c_cc[VWERASE] = CWERASE; - termios.c_cc[VLNEXT] = CLNEXT; - termios.c_cc[VEOL2] = _POSIX_VDISABLE; - if (tcsetattr (0, TCSADRAIN, &termios)) - warn ("tcsetattr problem: %s", strerror(errno)); -} -# endif /* RESET_TTY */ -#endif /* linux */ - /* * update_utmp - update our utmp entry * @@ -404,8 +251,8 @@ static void update_utmp (void) { struct utmp ut; - int ut_fd; struct utmp *utp; + time_t cur_time; utmpname (_PATH_UTMP); setutent (); @@ -417,7 +264,6 @@ memcpy (&ut, utp, sizeof (ut)); } else { /* some inits don't initialize utmp... */ - /* XXX we should print out a warning message */ memset (&ut, 0, sizeof (ut)); if (vcline) /* Standard virtual console devices */ @@ -432,55 +278,42 @@ strncpy (ut.ut_id, ptr, sizeof (ut.ut_id)); } } - endutent (); strncpy (ut.ut_user, "LOGIN", sizeof (ut.ut_user)); strncpy (ut.ut_line, tty, sizeof (ut.ut_line)); + + time (&cur_time); ut.ut_time = cur_time; ut.ut_type = LOGIN_PROCESS; ut.ut_pid = pid; ut.ut_session = sid; - setutent (); pututline (&ut); endutent (); - if (!old) { - /* Default case: Use glibc for updating /var/log/wtmp */ - updwtmp(_PATH_WTMP, &ut); - - } else if ((ut_fd = open (_PATH_WTMP, O_APPEND | O_WRONLY)) >= 0) { - /* Old behaviour */ - (void)signal(SIGALRM, sigalrm_handler); - (void)alarm(3); - flock (ut_fd, LOCK_EX); - (void)alarm(0); - (void)signal(SIGALRM, SIG_DFL); - write (ut_fd, &ut, sizeof (ut)); - flock (ut_fd, LOCK_UN); - close (ut_fd); - } + updwtmp (_PATH_WTMP, &ut); } /* open_tty - set up tty as standard { input, output, error } */ static void open_tty (void) { - struct sigaction sa; + struct sigaction sa, sa_old; sigset_t set; - /* Was `char buf[20];' but there is more than /dev/tty<number> */ char buf[PATH_MAX+1]; - int fd; + int fd, len; gid_t gid = 0; struct group *gr = NULL; - /* Use tty group is available */ + /* Use tty group if available */ if ((gr = getgrnam("tty"))) gid = gr->gr_gid; /* Set up new standard input. */ - if (snprintf(buf, sizeof(buf), "/dev/%s", tty) < 0) { + if (((len = snprintf(buf, sizeof(buf), "/dev/%s", tty)) >= sizeof(buf)) || (len < 0)) error ("%s: %s", buf, strerror(EOVERFLOW)); - } + + /* There is always a race between this reset and the call to + vhangup() that s.o. can use to get access to your tty. */ if (chown (buf, 0, gid) || chmod (buf, (gid ? 0660 : 0600))) { if (errno == EROFS) warn("%s: %s", buf, strerror(errno)); @@ -491,29 +324,31 @@ sa.sa_handler = SIG_IGN; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); - sigaction (SIGHUP, &sa, NULL); + sigaction (SIGHUP, &sa, &sa_old); sa.sa_handler = sigquit_handler; sigaction (SIGQUIT, &sa, NULL); - /* vhangup() will replace all open file descriptors that point to our - controlling tty by a dummy that will deny further reading/writing - to our device. It will also reset the tty to sane defaults, so we - don't have to modify the tty device for sane settings. - We also get a SIGHUP/SIGCONT. + /* vhangup() will replace all open file descriptors in the kernel + that point to our controlling tty by a dummy that will deny + further reading/writing to our device. It will also reset the + tty to sane defaults, so we don't have to modify the tty device + for sane settings. We also get a SIGHUP/SIGCONT. */ if ((fd = open (buf, O_RDWR, 0)) < 0) error ("%s: cannot open tty: %s", buf, strerror(errno)); if (!isatty (fd)) error ("%s: not a tty", buf); - if (vhangup ()) - error ("vhangup() failed"); - /* Get rid of the present stdout/stderr. */ - close (2); - close (1); - close (0); - if (fd > 2) - close (fd); + if (nohangup == 0) { + if (vhangup ()) + error ("%s: vhangup() failed", tty); + /* Get rid of the present stdout/stderr. */ + close (2); + close (1); + close (0); + if (fd > 2) + close (fd); + } if ((fd = open (buf, O_RDWR, 0)) < 0) error ("%s: cannot open tty: %s", buf, strerror(errno)); @@ -532,42 +367,43 @@ if (fd > 2) close (fd); +#ifdef IUTF8 + /* Detect mode of current keyboard setup, e.g. for UTF-8 */ + if (ioctl(0, KDGKBMODE, &mode) < 0) + mode = K_RAW; +#endif + /* Write a reset string to the terminal. This is very linux-specific and should be checked for other systems. */ - if (!noclear) - write (0, "\033c", 2); + if (noclear == 0) + /* don't write a full reset (ESC c) because this leaves the + unicode mode again if the terminal was in unicode mode + and also undos the ESC sequences in CONSOLE_MAGIC which + are needed for some languages/console-fonts. + Just put the cursor to the home position (ESC [ H), + erase everything below the cursor (ESC [ J), and set the + scrolling region to the full window (ESC [ r) */ + write (0, "\033[r\033[H\033[J", 9); -#ifdef linux /* * Only for the standard virtual console devices */ if (!old && vcline) - vcshangup(gid); -#endif + vcshangup(gid, vcline); -#ifdef RESET_TTY /* * The above reset only puts the output things into a sane state. * The input state is not reset. */ if (!noreset && !old) - reset_stdin(); -#endif + reset_stdin(mode); - sa.sa_handler = SIG_DFL; - sa.sa_flags = 0; - sigemptyset (&sa.sa_mask); - sigaction (SIGHUP, &sa, NULL); + sigaction (SIGHUP, &sa_old, NULL); /* Unmask SIGHUP if inherited */ sigemptyset (&set); sigaddset (&set, SIGHUP); sigprocmask (SIG_UNBLOCK, &set, NULL); - -#if DEBUG_THIS - printf ("session=%d, pid=%d, pgid=%d\n", getsid (0), getpid (), - getpgid (0)); -#endif } static void output_special_char (unsigned char c) @@ -589,27 +425,22 @@ printf ("%s", uts.machine); break; case 'o': -#ifdef __USE_GNU printf ("%s", uts.domainname); -#else - printf ("%s", uts.__domainname); -#endif break; case 'd': case 't': { - time_t now; + time_t cur_time; struct tm *tm; - time (&now); - tm = localtime (&now); - if (c == 'd') - /* ISO 8601 */ + time (&cur_time); + tm = localtime (&cur_time); + if (c == 'd') /* ISO 8601 */ printf ("%d-%02d-%02d", 1900 + tm->tm_year, - tm->tm_mon+1, tm->tm_mday); - else - printf ("%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); + tm->tm_mon + 1, tm->tm_mday); + else + printf ("%02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); break; } case 'l': @@ -636,72 +467,104 @@ } /* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ -static void do_prompt (void) +static void do_prompt (int showlogin) { -#if ! OLD FILE *fd; -#else - int fd; -#endif int c; - write (1, "\n", 1); /* start a new line */ -#if ! OLD - if ((fd = fopen (ISSUE, "r"))) { + if (nonewline == 0) + putchar ('\n'); + if (noissue == 0 && (fd = fopen (ISSUE, "r"))) { while ((c = getc (fd)) != EOF) { if (c == '\\') - output_special_char (getc(fd)); + output_special_char (getc (fd)); else putchar (c); } - fflush (stdout); fclose (fd); } -#else - if ((fd = open (ISSUE, O_RDONLY)) >= 0) { - close (fd); - } -#endif - if (!nohostname) { - write (1, hn, strlen (hn)); - write (1, " ", 1); - } - write (1, LOGIN, sizeof (LOGIN) - 1); + if (nohostname == 0) + printf ("%s ", hn); + if (showlogin) + printf ("%s", LOGIN); + fflush (stdout); } /* get_logname - get user name, establish speed, erase, kill, eol */ static char *get_logname (void) { - static char logname[40]; + static char logname[4*UT_NAMESIZE]; char *bp; unsigned char c; + int ascii; + iconv_t ic; - /* flush pending input */ -#if defined __GLIBC__ && __GLIBC__ >= 2 - tcflush(0, TCIFLUSH); -#else - ioctl (0, TCFLSH, 0); + tcflush (0, TCIFLUSH); /* flush pending input */ + +#ifdef IUTF8 + /* Check for UTF-8 mode */ + switch(mode) { + case K_UNICODE: + ascii = 0; + setlocale(LC_CTYPE, "en_US.UTF-8"); + break; + case K_RAW: + case K_MEDIUMRAW: + case K_XLATE: + default: + ascii = 1; + setlocale(LC_CTYPE, "POSIX"); + break; + } #endif for (*logname = 0; *logname == 0;) { - do_prompt (); + do_prompt (1); for (bp = logname;;) { if (read (0, &c, 1) < 1) { - if (errno == EINTR || errno == EIO - || errno == ENOENT) - exit (0); - error ("%s: read: %s", tty, strerror(errno)); + if (errno == EINTR || errno == EAGAIN) { + usleep(1000); + continue; + } + if (errno == EIO || errno == ENOENT) + exit (EXIT_SUCCESS); + error ("%s: read: %s", tty, strerror (errno)); } + if (c == '\n' || c == '\r') { *bp = 0; break; - } else if (!isprint (c)) - error ("%s: invalid character for login name", - tty); - else if (bp - logname >= sizeof (logname) - 1) + } + + if (ascii && !isprint (c)) + error ("%s: invalid character 0x%x in login name", tty, c); + + if ((size_t)(bp - logname) >= sizeof (logname) - 1) error ("%s: too long login name", tty); - else - *bp++ = c; + + *bp++ = c; + } + } + + if (!ascii && (ic = iconv_open("WCHAR_T", "UTF-8"))) { + char tmpbuf[4*sizeof(logname)], *op, *lp; + size_t len = bp - logname; + size_t out = sizeof(tmpbuf) - 1; + size_t wcl; + wint_t *wcp; + + op = tmpbuf; + lp = logname; + if ((wcl = iconv(ic , &lp, &len, &op, &out)) == (size_t)-1) + error ("%s: invalid character conversion for login name", tty); + iconv_close(ic); + + wcp = (wint_t*)tmpbuf; + wcp[wcl] = (wint_t)0; + while (*wcp) { + const wint_t wc = *wcp++; + if (!iswprint(wc)) + error ("%s: invalid character 0x%x in login name", tty, wc); } } return logname; @@ -709,82 +572,35 @@ static void usage (void) { - error ("%s: usage: '%s [--noclear] [--noreset] [--long-hostname] [--no-hostname] [--login program] [--logopts \"loginprg opts\"] tty [term]' with e.g. tty=tty1", VERSION, progname); + error ("%s: usage: '%s [--noclear] [--nonewline] [--noissue]" + " [--nohangup] [--noreset] [--no-hostname] [--long-hostname]" + " [--login program] [--logopts \"loginprg opts\"] [--nice 10]" + " [--delay 10] [--chdir /home] [--chroot /chroot] [--autologin user]" + " [--old] tty [term]' with e.g. tty=tty1", VERSION, progname); } static struct option const long_options[] = { - { "noclear", no_argument, &noclear, 1}, - { "long-hostname", no_argument, &longhostname, 1}, - { "no-hostname", no_argument, &nohostname, 1}, - { "noreset", no_argument, &noreset, 1}, - { "login", required_argument, 0, 2}, - { "logopts", required_argument, 0, 3}, - { "old", no_argument, &old, 1}, + { "autologin", required_argument, NULL, 'a' }, + { "chdir", required_argument, NULL, 'w' }, + { "chroot", required_argument, NULL, 'r' }, + { "delay", required_argument, NULL, 'd' }, + { "noclear", no_argument, &noclear, 1 }, + { "nonewline", no_argument, &nonewline, 1 }, + { "noissue", no_argument, &noissue, 1 }, + { "nohangup", no_argument, &nohangup, 1 }, + { "noreset", no_argument, &noreset, 1 }, + { "no-hostname", no_argument, &nohostname, 1 }, + { "nohostname", no_argument, &nohostname, 1 }, /* compat option */ + { "login", required_argument, NULL, 'l' }, + { "loginprog", required_argument, NULL, 'l' }, /* compat option */ + { "loginopts", required_argument, NULL, 'o' }, + { "logopts", required_argument, NULL, 'o' }, + { "long-hostname", no_argument, &longhostname, 1 }, + { "nice", required_argument, NULL, 'n' }, + { "old", no_argument, &old, 1 }, { 0, 0, 0, 0 } }; -/* Don't allow the user to pass an option as a user name */ -/* To be more safe: Use -- to make sure the rest is interpreted - * as non-options by the program, if it supports it */ -static void checkname (char* nm) -{ - char *p = nm; - if (!nm) - goto err; - if (strlen (nm) > 42) - goto err; - while (isspace (*p)) - p++; - if (*p == '-') - goto err; - return; -err: - error ("checkname: %s", strerror(EPERM)); -} - -static void replacename (char** arr, char* nm) -{ - char *p, *tmp; - while ((p = *arr)) { - char *p1 = p; - while (*p1) { - if (memcmp (p1, "\\u", 2) == 0) - { - tmp = malloc (strlen (p) + strlen (nm)); - if (!tmp) - error ("replacename: %s", strerror(errno)); - if (p1 != p) - memcpy (tmp, p, (p1-p)); - *(tmp + (p1-p)) = 0; - strcat (tmp, nm); - strcat (tmp, p1+2); - *arr = tmp; - } - p1++; - } - arr++; - } -} - -#define ARRAY_SIZE_MAX 16 -static void mkarray (char** arr, char* str) -{ - char* p = str; char* start = p; - int i = 0; - while (*p && i < (ARRAY_SIZE_MAX - 2)) - { - if (isspace (*p)) - { - *p = 0; - while (isspace (*++p)); - if (*p) { arr[i++] = start; start = p; }; - } - else - p++; - }; - arr[i++] = start; arr[i++] = 0; -} - /* * main program */ @@ -795,40 +611,66 @@ char *logoptstr; char logcmd[NAME_MAX+1]; char *logarr[ARRAY_SIZE_MAX]; - loginprog = _PATH_LOGIN; logoptstr = "-- \\u"; progname = basename(argv[0]); + if (!progname) + progname = "mingetty"; + uname (&uts); gethostname (hn, MAXHOSTNAMELEN); + hn[MAXHOSTNAMELEN] = '\0'; pid = getpid (); sid = getsid (0); - time (&cur_time); - while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) + while ((c = getopt_long (argc, argv, "a:d:l:n:w:r:", long_options, (int *) 0)) != EOF) { switch (c) { - case 0: - break; - case 2: - loginprog = optarg; break; - case 3: - logoptstr = optarg; break; - default: - usage (); + case 0: + break; + case 'a': + if (!optarg) usage (); + autologin = optarg; + break; + case 'd': + if (!optarg) usage (); + delay = atoi (optarg); + break; + case 'l': + if (!optarg) usage (); + loginprog = optarg; + break; + case 'o': + if (!optarg) usage (); + logoptstr = optarg; + break; + case 'n': + if (!optarg) usage (); + priority = atoi (optarg); + break; + case 'r': + if (!optarg) usage (); + ch_root = optarg; + break; + case 'w': + if (!optarg) usage (); + ch_dir = optarg; + break; + default: + usage (); } } - if (!longhostname && (s = strchr(hn, '.'))) + if (longhostname == 0 && (s = strchr (hn, '.'))) *s = '\0'; tty = argv[optind++]; if (!tty) usage (); - /* Skip the "/dev/", we may add it later */ + /* Skip the "/dev/", we add it later */ if (strncmp (tty, "/dev/", 5) == 0) tty += 5; - /* On virtual console remeber the line which is used for */ + /* On virtual console remember the line which is used for */ if (strncmp(tty, "tty", 3) == 0 && strspn(tty + 3, "0123456789") == strlen(tty+3)) vcline = tty+3; @@ -839,30 +681,40 @@ setenv("TERM", DEFAULT_TERM, 1); update_utmp (); + if (delay) + sleep (delay); open_tty (); /* flush input and output queues, important for modems */ -#if defined __GLIBC__ && __GLIBC__ >= 2 tcflush(0, TCIOFLUSH); -#else - ioctl (0, TCFLSH, 2); -#endif - while ((logname = get_logname ()) == 0); + if (autologin) { + do_prompt (0); + printf ("%s%s (automatic login)\n", LOGIN, autologin); + logname = autologin; + logoptstr = "-f \\u"; + } else { + while ((logname = get_logname ()) == 0) + /* do nothing */ ; + } + strncpy (logcmd, loginprog, NAME_MAX); strncat (logcmd, " ", NAME_MAX - strlen(logcmd)); strncat (logcmd, logoptstr, NAME_MAX - strlen(logcmd)); - mkarray (logarr, logcmd); checkname (logname); + mkarray (logarr, logcmd); replacename (logarr, logname); -#if DEBUG_THIS - printf ("About to execute %s", logcmd); - c = 1; while (logarr[c]) printf (" `%s'", logarr[c++]); - printf ("\n"); sleep (1); -#endif + if (ch_root) + chroot (ch_root); + if (ch_dir) + chdir (ch_dir); + if (priority) + nice (priority); + execv (loginprog, logarr); - error ("%s: can't exec %s: %s", tty, loginprog, strerror(errno)); - sleep (1); exit (0); + error ("%s: can't exec %s: %s", tty, loginprog, strerror (errno)); + sleep (1); + exit (EXIT_FAILURE); } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/revoke.c new/mingetty-1.0.7s/revoke.c --- old/mingetty-0.9.6s/revoke.c 1970-01-01 01:00:00.000000000 +0100 +++ new/mingetty-1.0.7s/revoke.c 2007-05-29 16:51:29.000000000 +0200 @@ -0,0 +1,310 @@ +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <termios.h> +#include <unistd.h> +#include <sys/kd.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include "revoke.h" +static int sigfholder(const char *path, int sig); + +#ifdef TEST +#define error(fmt,args...) syslog(LOG_ERR,fmt,args);exit(1) +#define warn(fmt,args...) syslog(LOG_WARN,fmt,args) +#else +extern void error (const char *fmt, ...); +extern void warn (const char *fmt, ...); +#endif + +#ifndef IUTF8 +# error IUTF8 input flag not defined +#endif + +/* + * Hang up any vcs terminal line + */ +void vcshangup(const gid_t gid, const char * const vcline) +{ + struct stat st; + char buf[PATH_MAX+1]; + + if (!vcline) + goto skip; + + /* Set up new virtual console text capture devices */ + strncpy (buf, "/dev/vcs", PATH_MAX); + strncat (buf, vcline, PATH_MAX - strlen(buf)); + + if (stat(buf, &st) < 0) { + if (errno != ENOENT) + error ("%s: %s", buf, strerror(errno)); + goto skip; + } + if (chown (buf, 0, gid) || chmod (buf, (gid ? 0660 : 0600))) { + if (errno == EROFS) + warn("%s: %s", buf, strerror(errno)); + else + error ("%s: %s", buf, strerror(errno)); + } +# ifdef __NR_revoke + _syscall(int, revoke, const char*, buf); +# else + if (sigfholder(buf, SIGHUP)) { /* Be nice, send SIGHUP */ + sleep (2); + if (sigfholder(buf, SIGKILL)) /* Hey, go away */ + sigfholder(buf, SIGCONT); + } +# endif /* __NR_revoke */ + + /* Set up new virtual console text/attribute capture devices */ + strncpy (buf, "/dev/vcsa", PATH_MAX); + strncat (buf, vcline, PATH_MAX - strlen(buf)); + + if (stat(buf, &st) < 0) { + if (errno != ENOENT) + error ("%s: %s", buf, strerror(errno)); + goto skip; + } + if (chown (buf, 0, gid) || chmod (buf, (gid ? 0660 : 0600))) { + if (errno == EROFS) + warn("%s: %s", buf, strerror(errno)); + else + error ("%s: %s", buf, strerror(errno)); + } +# ifdef __NR_revoke + _syscall(int, revoke, const char*, buf); +# else + if (sigfholder(buf, SIGHUP)) { /* Be nice, send SIGHUP */ + sleep (2); + if (sigfholder(buf, SIGKILL)) /* Hey, go away */ + sigfholder(buf, SIGCONT); + } +# endif /* __NR_revoke */ +skip: + return; +} + +/* + * Reset terminal on stdin + */ +void reset_stdin(const int mode) +{ + struct termios termios; + /* The above reset only puts the output things into a sane state. + * The input state is not reset. + */ + memset (&termios, 0, sizeof termios); + if (tcgetattr (0, &termios)) + warn ("tcgetattr problem: %s", strerror(errno)); + + /* Use defaults of <sys/ttydefaults.h> for base settings */ + termios.c_iflag |= TTYDEF_IFLAG; + termios.c_oflag |= TTYDEF_OFLAG; + termios.c_lflag |= TTYDEF_LFLAG; + termios.c_cflag |= (TTYDEF_SPEED | TTYDEF_CFLAG); + + /* Sane setting, allow eight bit characters, no carriage return delay + * the same result as `stty sane cr0 pass8' + */ + termios.c_iflag |= (BRKINT | ICRNL | IMAXBEL); + termios.c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP); + termios.c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); + termios.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\ + NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + termios.c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE); + termios.c_lflag &= ~(ECHONL | NOFLSH | XCASE | TOSTOP | ECHOPRT); + termios.c_cflag |= (CREAD | CS8 | B38400); + termios.c_cflag &= ~(PARENB); +#ifdef IUTF8 + /* Set UTF-8 input flag */ + switch(mode) { + case K_UNICODE: + termios.c_iflag |= IUTF8; + break; + case K_RAW: + case K_MEDIUMRAW: + case K_XLATE: + default: + termios.c_iflag &= ~IUTF8; + break; + } +#endif + /* VTIME and VMIN can overlap with VEOF and VEOL since they are + * only used for non-canonical mode. We just set the at the + * beginning, so nothing bad should happen. + */ + termios.c_cc[VTIME] = 0; + termios.c_cc[VMIN] = 1; + termios.c_cc[VINTR] = CINTR; + termios.c_cc[VQUIT] = CQUIT; + termios.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */ + termios.c_cc[VKILL] = CKILL; + termios.c_cc[VEOF] = CEOF; + termios.c_cc[VSWTC] = _POSIX_VDISABLE; + termios.c_cc[VSTART] = CSTART; + termios.c_cc[VSTOP] = CSTOP; + termios.c_cc[VSUSP] = CSUSP; + termios.c_cc[VEOL] = _POSIX_VDISABLE; + termios.c_cc[VREPRINT] = CREPRINT; + termios.c_cc[VDISCARD] = CDISCARD; + termios.c_cc[VWERASE] = CWERASE; + termios.c_cc[VLNEXT] = CLNEXT; + termios.c_cc[VEOL2] = _POSIX_VDISABLE; + if (tcsetattr (0, TCSADRAIN, &termios)) + warn ("tcsetattr problem: %s", strerror(errno)); +} + +/* + * Don't allow the user to pass an option as a user name + * To be more safe: Use -- to make sure the rest is interpreted + * as non-options by the program, if it supports it + */ +void checkname (const char* nm) +{ + const char *p = nm; + if (!nm) + goto err; + if (strlen (nm) > 42) + goto err; + while (isspace (*p)) + p++; + if (*p == '-') + goto err; + return; +err: + error ("checkname: %s", strerror(EPERM)); +} + +void replacename (char** arr, const char* nm) +{ + const char *p; + char *tmp; + while ((p = *arr)) { + const char *p1 = p; + while (*p1) { + if (memcmp (p1, "\\u", 2) == 0) { + tmp = malloc (strlen (p) + strlen (nm)); + if (!tmp) + error ("replacename: %s", strerror(errno)); + if (p1 != p) + memcpy (tmp, p, (p1-p)); + *(tmp + (p1-p)) = 0; + strcat (tmp, nm); + strcat (tmp, p1+2); + *arr = tmp; + } + p1++; + } + arr++; +} +} + +void mkarray (char** arr, char* str) +{ + char* p = str; + char* start = p; + int i = 0; + + while (*p && i < (ARRAY_SIZE_MAX - 2)) { + if (isspace (*p)) { + *p = 0; + while (isspace (*++p)) + ; + if (*p) { + arr[i++] = start; + start = p; + } + } else + p++; + } + arr[i++] = start; + arr[i++] = (char*)0; +} + +static int sigfholder(const char *path, int sig) +{ + char buf[MAXNAMLEN], *ptr; + pid_t pid; + DIR *proc, *fds; + struct dirent *task, *fd; + FILE *fp; + struct stat st, lnk; + int cnt = 0; + + if ((proc = opendir("/proc")) == (DIR *)0) { + error("cannot opendir(/proc): %s\n", strerror(errno)); + } + + if (stat(path, &st) < 0) { + error("cannot stat %s: %s\n", path, strerror(errno)); + } + + while((task = readdir(proc)) != (struct dirent *)0) { + pid = (pid_t)atoi(task->d_name); + + if (pid == 0 || pid == getpid() || pid == getppid()) + continue; + + (void) strcpy(buf,"/proc/"); + (void) strcat(strcat(buf, task->d_name), "/maps"); + if ((fp = fopen(buf,"r")) == (FILE*)0) { + if (errno != ENOENT) + warn("cannot open(%s): %s\n", buf, strerror(errno)); + continue; + } + while ((fgets(buf, MAXNAMLEN, fp))) { + ptr = strrchr(buf, ' '); + if (*(++ptr) == '/' && strncmp(path, ptr, strlen(ptr)-1) == 0) { + kill(pid, sig); + cnt++; + goto out_maps; + } + } + out_maps: + fclose(fp); + + (void) strcpy(buf,"/proc/"); + (void) strcat(strcat(buf, task->d_name), "/fd"); + if ((fds = opendir(buf)) == (DIR *)0) { + if (errno != ENOENT && errno != EPERM) + warn("cannot opendir(%s): %s\n", buf, strerror(errno)); + continue; + } + ptr = strcat(buf, "/"); + ptr = ptr + strlen(buf); + while ((fd = readdir(fds)) != (struct dirent *)0) { + if (*fd->d_name == '.') + continue; + (void) strcpy(ptr, fd->d_name); + if (stat(buf, &lnk) < 0) { + continue; + } + if (st.st_dev == lnk.st_dev && st.st_ino == lnk.st_ino) { + kill(pid, sig); + cnt++; + goto out_fds; + } + } + out_fds: + closedir(fds); + } + closedir(proc); + return cnt; +} + +#ifdef TEST +int main (int argc, char * argv[]) +{ + if (++argv && *argv && (*argv)[0] != '\0') + printf("%d\n", sigfholder(*argv, SIGHUP)); + return 0; +} +#endif diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/revoke.h new/mingetty-1.0.7s/revoke.h --- old/mingetty-0.9.6s/revoke.h 1970-01-01 01:00:00.000000000 +0100 +++ new/mingetty-1.0.7s/revoke.h 2007-05-29 16:51:10.000000000 +0200 @@ -0,0 +1,16 @@ +#ifndef _SIGFHOLDER_H +#define _SIGFHOLDER_H +extern void vcshangup(const gid_t gid, const char * const vcline); +extern void reset_stdin(const int mode); +extern void checkname (const char* nm); +extern void replacename (char** arr, const char* nm); +#define ARRAY_SIZE_MAX 16 +extern void mkarray (char** arr, char* str); +#ifndef IUTF8 +# ifndef ASM_IUTF8 +# error IUTF8 input flag not defined +# else +# define IUTF8 ASM_IUTF8 +# endif +#endif +#endif /* _SIGFHOLDER_H */ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/mingetty-0.9.6s/sigfholder.c new/mingetty-1.0.7s/sigfholder.c --- old/mingetty-0.9.6s/sigfholder.c 2002-03-27 10:57:06.000000000 +0100 +++ new/mingetty-1.0.7s/sigfholder.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,103 +0,0 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <signal.h> -#include <dirent.h> -#include <syslog.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> - -#ifdef TEST -#define error(fmt,args...) syslog(LOG_ERR,fmt,args);exit(1) -#define warn(fmt,args...) syslog(LOG_WARN,fmt,args) -#else -extern void error (const char *fmt, ...); -extern void warn (const char *fmt, ...); -#endif - -#ifdef TEST -static int sigfholder(const char *path, int sig) -#else -int sigfholder(const char *path, int sig) -#endif -{ - char buf[MAXNAMLEN], *ptr; - pid_t pid; - DIR *proc, *fds; - struct dirent *task, *fd; - FILE *fp; - struct stat st, lnk; - int cnt = 0; - - if ((proc = opendir("/proc")) == (DIR *)0) { - error("cannot opendir(/proc): %s\n", strerror(errno)); - } - - if (stat(path, &st) < 0) { - error("cannot stat %s: %s\n", path, strerror(errno)); - } - - while((task = readdir(proc)) != (struct dirent *)0) { - pid = (pid_t)atoi(task->d_name); - - if (pid == 0 || pid == getpid() || pid == getppid()) - continue; - - (void) strcpy(buf,"/proc/"); - (void) strcat(strcat(buf, task->d_name), "/maps"); - if ((fp = fopen(buf,"r")) == (FILE*)0) { - if (errno != ENOENT) - warn("cannot open(%s): %s\n", buf, strerror(errno)); - continue; - } - while ((fgets(buf, MAXNAMLEN, fp))) { - ptr = strrchr(buf, ' '); - if (*(++ptr) == '/' && strncmp(path, ptr, strlen(ptr)-1) == 0) { - kill(pid, sig); - cnt++; - goto out_maps; - } - } - out_maps: - fclose(fp); - - (void) strcpy(buf,"/proc/"); - (void) strcat(strcat(buf, task->d_name), "/fd"); - if ((fds = opendir(buf)) == (DIR *)0) { - if (errno != ENOENT && errno != EPERM) - warn("cannot opendir(%s): %s\n", buf, strerror(errno)); - continue; - } - ptr = strcat(buf, "/"); - ptr = ptr + strlen(buf); - while ((fd = readdir(fds)) != (struct dirent *)0) { - if (*fd->d_name == '.') - continue; - (void) strcpy(ptr, fd->d_name); - if (stat(buf, &lnk) < 0) { - continue; - } - if (st.st_dev == lnk.st_dev && st.st_ino == lnk.st_ino) { - kill(pid, sig); - cnt++; - goto out_fds; - } - } - out_fds: - closedir(fds); - } - closedir(proc); - return cnt; -} - -#ifdef TEST -int main (int argc, char * argv[]) -{ - if (++argv && *argv && (*argv)[0] != '\0') - printf("%d\n", sigfholder(*argv, SIGHUP)); - return 0; -} -#endif ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@Hilbert.suse.de