* Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF
* Add helper program fstab-decode to make it easier to handle /etc/mtab content. Patch by Miloslav Trmac and Fedora. * Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD. * Add fix for Debian bug #374038 - Make it clear that shutdown -c can only cancel a waiting shutdown, not an active one. * Add not to pidof manual page about the use of readlink(2). Patch by Bill Nottingham and Fedora. * Add changes for Debian bug #68621 - Add PAM support for programs spawned by init on the console like sulogin. Based on patch by Topi Miettinen.
This commit is contained in:
		| @@ -57,6 +57,16 @@ sysvinit (2.88dsf) UNRELEASED; urgency=low | ||||
|   * sulogin - add the possibility to reset the terminal io | ||||
|   * Fix some minor problems | ||||
|   * init - enable is_selinux_enabled() to detect selinuxfs | ||||
|   * Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF | ||||
|   * Add helper program fstab-decode to make it easier to handle | ||||
|     /etc/mtab content. Patch by Miloslav Trmac and Fedora. | ||||
|   * Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD. | ||||
|   * Add fix for Debian bug #374038 - Make it clear that shutdown -c can | ||||
|     only cancel a waiting shutdown, not an active one. | ||||
|   * Add not to pidof manual page about the use of readlink(2). Patch by | ||||
|     Bill Nottingham and Fedora. | ||||
|   * Add changes for Debian bug #68621 - Add PAM support for programs spawned | ||||
|     by init on the console like sulogin. Based on patch by Topi Miettinen. | ||||
|  | ||||
|  -- Petter Reinholdtsen <pere@hungry.com>  Sun, 12 Jul 2009 19:58:10 +0200 | ||||
|  | ||||
|   | ||||
							
								
								
									
										45
									
								
								man/fstab-decode.8
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								man/fstab-decode.8
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| .\" A man page for fstab-decode(8). | ||||
| .\" | ||||
| .\" Copyright (C) 2006 Red Hat, Inc. All rights reserved. | ||||
| .\" | ||||
| .\" This copyrighted material is made available to anyone wishing to use, | ||||
| .\" modify, copy, or redistribute it subject to the terms and conditions of the | ||||
| .\" GNU General Public License v.2. | ||||
| .\" | ||||
| .\" This program is distributed in the hope that it will be useful, but WITHOUT | ||||
| .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
| .\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||||
| .\" more details. | ||||
| .\" | ||||
| .\" You should have received a copy of the GNU General Public License along | ||||
| .\" with this program; if not, write to the Free Software Foundation, Inc., | ||||
| .\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
| .\" | ||||
| .\" Author: Miloslav Trmac <mitr@redhat.com> | ||||
| .TH fstab-decode 8 "May 2006" | ||||
|  | ||||
| .SH NAME | ||||
| fstab-decode \- run a command with fstab-encoded arguments | ||||
|  | ||||
| .SH SYNOPSIS | ||||
| \fB fstab-decode\fR \fICOMMAND\fR [\fIARGUMENT\fR]... | ||||
|  | ||||
| .SH DESCRIPTION | ||||
| .B fstab-decode | ||||
| decodes escapes in the specified \FIARGUMENT\fRs | ||||
| and uses them to run \fICOMMAND\fR. | ||||
| The argument escaping uses the same rules as path escaping in | ||||
| \fB/etc/fstab\fR, | ||||
| .B /etc/mtab | ||||
| and \fB/proc/mtab\fR. | ||||
|  | ||||
| .SH EXIT STATUS | ||||
| .B fstab-decode | ||||
| exits with status 127 if | ||||
| .I COMMAND | ||||
| can't be run. | ||||
| Otherwise it exits with the status returned by \fICOMMAND\fR. | ||||
|  | ||||
| .SH EXAMPLES | ||||
|  | ||||
| .B fstab-decode umount $(awk '$3 == "vfat" { print $2 }' /etc/fstab) | ||||
| @@ -77,7 +77,11 @@ the program behaves according to the name under which it is called. | ||||
| When \fIpidof\fP is invoked with a full pathname to the program it | ||||
| should find the pid of, it is reasonably safe. Otherwise it is possible | ||||
| that it returns pids of running programs that happen to have the same name | ||||
| as the program you're after but are actually other programs. | ||||
| as the program you're after but are actually other programs. Note that | ||||
| that the executable name of running processes is calculated with | ||||
| .BR readlink (2), | ||||
| so symbolic links to executables will also match. | ||||
|  | ||||
| .SH SEE ALSO | ||||
| .BR shutdown (8), | ||||
| .BR init (8), | ||||
|   | ||||
| @@ -93,9 +93,10 @@ you'd expect. | ||||
| .\"}}} | ||||
| .\"{{{  -c | ||||
| .IP \fB\-c\fP | ||||
| Cancel an already running shutdown. With this option it is of course | ||||
| not possible to give the \fBtime\fP argument, but you can enter a | ||||
| explanatory message on the command line that will be sent to all users. | ||||
| Cancel a waiting shutdown. ("shutdown now" is no longer waiting.) With | ||||
| this option it is of course not possible to give the time argument, but | ||||
| you can enter explanatory message arguments on the command line that | ||||
| will be sent to all users. | ||||
| .\"}}} | ||||
| .\"{{{  -t sec | ||||
| .IP "\fB\-t\fP \fIsec\fP" | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/Makefile
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/Makefile
									
									
									
									
									
								
							| @@ -8,19 +8,20 @@ | ||||
| # Version:	@(#)Makefile  2.85-13  23-Mar-2004  miquels@cistron.nl | ||||
| # | ||||
|  | ||||
| CPPFLAGS = -DUSE_PAM | ||||
| CFLAGS	?= -ansi -O2 -fomit-frame-pointer | ||||
| CFLAGS	+= -W -Wall -D_GNU_SOURCE | ||||
| override CFLAGS += -W -Wall -D_GNU_SOURCE | ||||
| STATIC	= | ||||
|  | ||||
| # For some known distributions we do not build all programs, otherwise we do. | ||||
| BIN	= | ||||
| SBIN	= init halt shutdown runlevel killall5 | ||||
| SBIN	= init halt shutdown runlevel killall5 fstab-decode | ||||
| USRBIN	= last mesg | ||||
|  | ||||
| MAN1	= last.1 lastb.1 mesg.1 | ||||
| MAN5	= initscript.5 inittab.5 | ||||
| MAN8	= halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8 | ||||
| MAN8	+= shutdown.8 telinit.8 | ||||
| MAN8	+= shutdown.8 telinit.8 fstab-decode.8 | ||||
|  | ||||
| ifeq ($(DISTRO),) | ||||
| BIN	+= mountpoint | ||||
| @@ -31,6 +32,7 @@ MAN8	+= sulogin.8 bootlogd.8 | ||||
| endif | ||||
|  | ||||
| ifeq ($(DISTRO),Debian) | ||||
| CPPFLAGS+= -DACCTON_OFF | ||||
| BIN	+= mountpoint | ||||
| SBIN	+= sulogin bootlogd | ||||
| MAN1	+= mountpoint.1 | ||||
| @@ -43,6 +45,7 @@ MAN1	+= wall.1 | ||||
| endif | ||||
|  | ||||
| ifeq ($(DISTRO),SuSE) | ||||
| CPPFLAGS+= -DUSE_SYSFS -DSANE_TIO -DSIGINT_ONLYONCE | ||||
| BIN	+= mountpoint | ||||
| SBIN	+= sulogin | ||||
| USRBIN	+= utmpdump | ||||
| @@ -50,28 +53,39 @@ MAN1	+= utmpdump.1 mountpoint.1 | ||||
| MAN8	+= sulogin.8 | ||||
| endif | ||||
|  | ||||
| ID		= $(shell id -u) | ||||
| BIN_OWNER	= root | ||||
| BIN_GROUP	= root | ||||
| BIN_COMBO	= $(BIN_OWNER):$(BIN_GROUP) | ||||
| STRIP		= strip -s -R .comment | ||||
| INSTALL_EXEC	= install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 755 | ||||
| INSTALL_DATA	= install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 644 | ||||
| ifeq ($(ID),0) | ||||
|   INSTALL_EXEC	= install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 755 | ||||
|   INSTALL_DATA	= install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 644 | ||||
| else | ||||
|   INSTALL_EXEC	= install -m 755 | ||||
|   INSTALL_DATA	= install -m 644 | ||||
| endif | ||||
| INSTALL_DIR	= install -m 755 -d | ||||
| MANDIR		= /usr/share/man | ||||
|  | ||||
| ifeq ($(WITH_SELINUX),yes) | ||||
|   SELINUX_DEF=-DWITH_SELINUX | ||||
|   INIT_SELIBS=-lsepol -lselinux | ||||
|   SULOGIN_SELIBS=-lselinux	 | ||||
|   SELINUX_DEF	=  -DWITH_SELINUX | ||||
|   INITLIBS	+= -lsepol -lselinux | ||||
|   SULOGINLIBS	= -lselinux	 | ||||
| else | ||||
|   SELINUX_DEF= | ||||
|   INIT_SELIBS= | ||||
|   SULOGIN_SELIBS= | ||||
|   SELINUX_DEF	= | ||||
|   INITLIBS	= | ||||
|   SULOGINLIBS	= | ||||
| endif | ||||
|  | ||||
| # Additional libs for GNU libc. | ||||
| ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),) | ||||
|   INITLIBS	+= -lpam -lpam_misc | ||||
| endif | ||||
|  | ||||
| # Additional libs for GNU libc. | ||||
| ifneq ($(wildcard /usr/lib*/libcrypt.a),) | ||||
| LCRYPT		= -lcrypt | ||||
|   SULOGINLIBS	+= -lcrypt | ||||
| endif | ||||
|  | ||||
| all:		$(BIN) $(SBIN) $(USRBIN) | ||||
| @@ -81,7 +95,7 @@ all:		$(BIN) $(SBIN) $(USRBIN) | ||||
| #%.o: %.c | ||||
| #	$(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@ | ||||
|  | ||||
| init:		LDLIBS += $(INIT_SELIBS) $(STATIC) | ||||
| init:		LDLIBS += $(INITLIBS) $(STATIC) | ||||
| init:		init.o init_utmp.o | ||||
|  | ||||
| halt:		halt.o ifdown.o hddown.o utmp.o reboot.h | ||||
| @@ -96,7 +110,7 @@ utmpdump:	utmpdump.o | ||||
|  | ||||
| runlevel:	runlevel.o | ||||
|  | ||||
| sulogin:	LDLIBS += $(LCRYPT) $(SULOGIN_SELIBS) $(STATIC) | ||||
| sulogin:	LDLIBS += $(SULOGINLIBS) $(STATIC) | ||||
| sulogin:	sulogin.o | ||||
|  | ||||
| wall:		dowall.o wall.o | ||||
|   | ||||
| @@ -263,6 +263,9 @@ int consolename(char *res, int rlen) | ||||
| 	} | ||||
|  | ||||
| #ifdef TIOCGDEV | ||||
| # ifndef  ENOIOCTLCMD | ||||
| #  define ENOIOCTLCMD	515 | ||||
| # endif | ||||
| 	if (ioctl(0, TIOCGDEV, &kdev) == 0) { | ||||
| 		int r = findtty(res, "/dev", rlen, (dev_t)kdev); | ||||
| 		if (0 != r) | ||||
|   | ||||
							
								
								
									
										86
									
								
								src/fstab-decode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/fstab-decode.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* fstab-decode(8). | ||||
|  | ||||
| Copyright (c) 2006 Red Hat, Inc. All rights reserved. | ||||
|  | ||||
| This copyrighted material is made available to anyone wishing to use, modify, | ||||
| copy, or redistribute it subject to the terms and conditions of the GNU General | ||||
| Public License v.2. | ||||
|  | ||||
| This program is distributed in the hope that it will be useful, but WITHOUT ANY | ||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||||
| PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||||
|  | ||||
| You should have received a copy of the GNU General Public License along with | ||||
| this program; if not, write to the Free Software Foundation, Inc., 51 Franklin | ||||
| Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
|  | ||||
| Author: Miloslav Trmac <mitr@redhat.com> */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| /* Decode the fstab-encoded string in place. */ | ||||
| static void | ||||
| decode(char *s) | ||||
| { | ||||
| 	const char *src; | ||||
| 	char *dest; | ||||
|  | ||||
| 	src = s; | ||||
| 	dest = s; | ||||
| 	while (*src != '\0') { | ||||
| 		if (*src != '\\') | ||||
| 			*dest = *src++; | ||||
| 		else { | ||||
| 			static const struct repl { | ||||
| 				char orig[4]; | ||||
| 				size_t len; | ||||
| 				char new; | ||||
| 			} repls[] = { | ||||
| #define R(X, Y) { X, sizeof(X) - 1, Y } | ||||
| 				R("\\", '\\'), | ||||
| 				R("011", '\t'), | ||||
| 				R("012", '\n'), | ||||
| 				R("040", ' '), | ||||
| 				R("134", '\\') | ||||
| #undef R | ||||
| 			}; | ||||
|  | ||||
| 			size_t i; | ||||
|  | ||||
| 			for (i = 0; i < sizeof (repls) / sizeof (repls[0]); | ||||
| 			     i++) { | ||||
| 				if (memcmp(src + 1, repls[i].orig, | ||||
| 					   repls[i].len) == 0) { | ||||
| 					*dest = repls[i].new; | ||||
| 					src += 1 + repls[i].len; | ||||
| 					goto found; | ||||
| 				} | ||||
| 			} | ||||
| 			*dest = *src++; | ||||
| 		found: | ||||
| 			; | ||||
| 		} | ||||
| 		dest++; | ||||
| 	} | ||||
| 	*dest = '\0'; | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int argc, char *argv[]) | ||||
| { | ||||
| 	size_t i; | ||||
|  | ||||
| 	if (argc < 2) { | ||||
| 		fprintf(stderr, "Usage: fstab-decode command [arguments]\n"); | ||||
| 		return EXIT_FAILURE; | ||||
| 	} | ||||
| 	for (i = 2; i < (size_t)argc; i++) | ||||
| 		decode(argv[i]); | ||||
| 	execvp(argv[1], argv + 1); | ||||
| 	fprintf(stderr, "fstab-decode: %s: %s\n", argv[1], strerror(errno)); | ||||
| 	return 127; | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/ifdown.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/ifdown.c
									
									
									
									
									
								
							| @@ -77,15 +77,33 @@ int ifdown(void) | ||||
| 				continue; | ||||
| 			if (strchr(ifr[i].ifr_name, ':') != NULL) | ||||
| 				continue; | ||||
| 			ifr[i].ifr_flags &= ~(IFF_UP); | ||||
| 			if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) { | ||||
|  | ||||
| 			/* Read interface flags */ | ||||
| 			if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) < 0) { | ||||
| 				fprintf(stderr, "ifdown: shutdown "); | ||||
| 				perror(ifr[i].ifr_name); | ||||
| 				continue; | ||||
| 			} | ||||
| 			/* | ||||
| 			 * Expected in <net/if.h> according to | ||||
| 			 * "UNIX Network Programming". | ||||
| 			 */ | ||||
| #ifdef ifr_flags | ||||
| # define IRFFLAGS	ifr_flags | ||||
| #else	/* Present on kFreeBSD */ | ||||
| # define IRFFLAGS	ifr_flagshigh | ||||
| #endif | ||||
| 			if (ifr[i].IRFFLAGS & IFF_UP) { | ||||
| 				ifr[i].IRFFLAGS &= ~(IFF_UP); | ||||
| 				if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) { | ||||
| 					fprintf(stderr, "ifdown: shutdown "); | ||||
| 					perror(ifr[i].ifr_name); | ||||
| 				} | ||||
| 			} | ||||
| #undef IRFFLAGS | ||||
| 		} | ||||
| 	} | ||||
| 	close(fd); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/init.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/init.c
									
									
									
									
									
								
							| @@ -53,11 +53,10 @@ | ||||
| #include <sys/time.h> | ||||
|  | ||||
| #ifdef WITH_SELINUX | ||||
| #include <selinux/selinux.h> | ||||
| #include <sys/mount.h> | ||||
| #  include <selinux/selinux.h> | ||||
| #  include <sys/mount.h> | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef __i386__ | ||||
| #  ifdef __GLIBC__ | ||||
|      /* GNU libc 2.x */ | ||||
| @@ -71,6 +70,11 @@ | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_PAM | ||||
| #  include <security/pam_appl.h> | ||||
| #  include <security/pam_misc.h> | ||||
| #endif | ||||
|  | ||||
| #include "init.h" | ||||
| #include "initreq.h" | ||||
| #include "paths.h" | ||||
| @@ -746,6 +750,16 @@ void console_stty(void) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| #ifdef __FreeBSD_kernel__ | ||||
| 	/* | ||||
| 	 * The kernel of FreeBSD expects userland to set TERM.  Usually, we want | ||||
| 	 * "cons25".  Later, gettys might disagree on this (i.e. we're not using | ||||
| 	 * syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still | ||||
| 	 * need a non-dumb terminal. | ||||
| 	 */ | ||||
| 	putenv ("TERM=cons25"); | ||||
| #endif | ||||
|  | ||||
| 	(void) tcgetattr(fd, &tty); | ||||
|  | ||||
| 	tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; | ||||
| @@ -902,6 +916,20 @@ void init_freeenv(char **e) | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef USE_PAM | ||||
| static pam_handle_t *pamh = NULL; | ||||
| static const struct pam_conv conv = { misc_conv, NULL }; | ||||
| # define PAM_FAIL_CHECK(func, args...)	\ | ||||
| 	{ \ | ||||
| 		const int __ret = (func)(args); \ | ||||
| 		if (__ret != PAM_SUCCESS) { \ | ||||
| 			initlog(L_VB, "%s", pam_strerror(pamh, __ret)); \ | ||||
| 			pam_end(pamh, __ret); \ | ||||
| 			exit(1); \ | ||||
| 		} \ | ||||
| 	} | ||||
| #endif /* USE_PAM */ | ||||
|  | ||||
| /* | ||||
|  *	Fork and execute. | ||||
|  * | ||||
| @@ -1031,6 +1059,14 @@ int spawn(CHILD *ch, int *res) | ||||
|  | ||||
|   		sigprocmask(SIG_SETMASK, &omask, NULL); | ||||
|  | ||||
| #ifdef USE_PAM | ||||
| 		PAM_FAIL_CHECK(pam_start, "init", "root" , &conv, &pamh); | ||||
| 		PAM_FAIL_CHECK(pam_set_item, pamh, PAM_TTY, console_dev); | ||||
| 		PAM_FAIL_CHECK(pam_acct_mgmt, pamh, PAM_SILENT); | ||||
| 		PAM_FAIL_CHECK(pam_open_session, pamh, PAM_SILENT); | ||||
| 		PAM_FAIL_CHECK(pam_setcred, pamh, PAM_ESTABLISH_CRED|PAM_SILENT); | ||||
| #endif | ||||
|  | ||||
| 		/* | ||||
| 		 * Update utmp/wtmp file prior to starting | ||||
| 		 * any child.  This MUST be done right here in | ||||
|   | ||||
| @@ -32,11 +32,18 @@ | ||||
|  *		along with this program; if not, write to the Free Software | ||||
|  *		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  */ | ||||
| #ifndef _GNU_SOURCE | ||||
| # define _GNU_SOURCE	/* otherwise `extern char **environ' is missed */ | ||||
| #endif | ||||
| #ifndef ACCTON_OFF | ||||
| # define ACCTON_OFF	0 | ||||
| #endif | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/wait.h> | ||||
| #include <time.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <stdlib.h> | ||||
| @@ -330,7 +337,7 @@ void fastdown() | ||||
|  | ||||
| 	/* First idle init. */ | ||||
| 	if (kill(1, SIGTSTP) < 0) { | ||||
| 		fprintf(stderr, "shutdown: can't idle init.\r\n"); | ||||
| 		fprintf(stderr, "shutdown: can't idle init: %s.\r\n", strerror(errno)); | ||||
| 		exit(1); | ||||
| 	} | ||||
|  | ||||
| @@ -357,7 +364,17 @@ void fastdown() | ||||
| 	write_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); | ||||
|  | ||||
| 	/* This is for those who have quota installed. */ | ||||
| #if defined(ACCTON_OFF) | ||||
| # if (ACCTON_OFF > 1) && (_BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)) | ||||
| 	/* This is an alternative way to disable accounting, saving a fork() */ | ||||
| 	if (acct(NULL)) | ||||
| 		fprintf(stderr, "shutdown: can not stop process accounting: %s.\r\n", strerror(errno)); | ||||
| # elif (ACCTON_OFF > 0) | ||||
| 	spawn(1, "accton", "off", NULL); | ||||
| # else | ||||
| 	spawn(1, "accton", NULL); | ||||
| # endif | ||||
| #endif | ||||
| 	spawn(1, "quotaoff", "-a", NULL); | ||||
|  | ||||
| 	sync(); | ||||
|   | ||||
| @@ -200,7 +200,11 @@ gettok(char *line, char *dest, int size, int eatspace) | ||||
| } | ||||
|  | ||||
| void | ||||
| # ifdef __GNUC__ | ||||
| undump(FILE *fp, int forever __attribute__((unused)), int oldfmt) | ||||
| #else | ||||
| undump(FILE *fp, int forever, int oldfmt) | ||||
| #endif | ||||
| { | ||||
| 	struct utmp ut; | ||||
| 	struct oldutmp uto; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user