|
From: Araki K. <j00...@ip...> - 2002-02-19 08:15:24
|
荒木です:-)
Subject: [Mlterm-dev-ja] utmp support for linux glibc
From: MINAMI Hirokazu <mi...@ch...>
Message-ID: <200...@ch...>
Date: Tue, 19 Feb 2002 15:09:26 +0900
> utemper を使わない linux (glibc2) のための utmp 対応を実装してみました。
> # 要するに for Debian...
>
> autoconf 周りのパッチ + kik_utmp_glibc.c(添付) です。
> sysv では動かないはずなので、ファイル名は変えました。
ありがとうございます _o_
ところで、わたしも今まで気づかなかったんですが、手元の NetBSD の libutil
にも同様の login,logout,logwtmp 関数が入ってるみたいです。
# 面倒なことせずに、はじめからこれを使っておけばよかったという...^_^;
ですので、このまま configure ; make すると、手元でも kik_utmp_glibc.c が
選択されるのですが、
1. *BSD には、setutent がない
2. utmp 構造体のメンバが ut_user でなく、ut_name
3. login() 呼びだしの前に、ut_line を埋めておかねばならない
ため、コンパイルエラーがでてしまいまして、その修正が必要でした。
また、*BSD にも login 等はあるようですので、 glibc という名前はちょっと
不適切かなとも思いまして、すべて、login で統一してみました。
kik_utmp_delete() で、free( utmp) ; が必要?という点と、 kik_utmp_new() の
error にて、free( &ut) になっている個所は、free( utmp) の間違い? の二点、
および、手元ではコンパイル時に warning が出ましたので、いくつか #include
を追加しております。
それから、*BSD では、 logout,logwtmp を使用する前に、
kik_priv_restore_e[ug]id()
を呼ばねばならないので、それも追加しております。
最後に、linux の glibc2 にも、logwtmp があるようですので、logwtmp も
追加してみました。
結果、添付のパッチのようになりました。
wtmp 以外は、HAVE_SETUTENT マクロで切りわけて、BSD 特化なコードを追加し
ただけですので、多分大丈夫かな、と思いますが、Linux でも正常に動作する
か試してみてください。
では
--
kiken
j00...@ip...
Index: kiklib/autoconf/configure.in
===================================================================
RCS file: /home/ken/cvsroot/kiklib/autoconf/configure.in,v
retrieving revision 1.31
diff -u -r1.31 configure.in
--- kiklib/autoconf/configure.in 2002/02/14 08:22:27 1.31
+++ kiklib/autoconf/configure.in 2002/02/19 06:46:04
@@ -84,6 +84,13 @@
AC_DEFINE(HAVE_UTMPER)
])
+AC_CHECK_LIB(util,logout,
+[
+LOGIN_LIBS="-lutil"
+AC_SUBST(LOGIN_LIBS)
+AC_DEFINE(HAVE_LOGIN)
+])
+
AC_MSG_CHECKING(for pty/tty type)
AC_CACHE_VAL(kik_cv_pty,[
if test -c /dev/ptmx ; then
Index: kiklib/src/Makefile.in
===================================================================
RCS file: /home/ken/cvsroot/kiklib/src/Makefile.in,v
retrieving revision 1.18
diff -u -r1.18 Makefile.in
--- kiklib/src/Makefile.in 2002/02/13 14:10:01 1.18
+++ kiklib/src/Makefile.in 2002/02/19 06:54:12
@@ -17,7 +17,7 @@
LIBTOOL = @LIBTOOL@
CFLAGS = $(CFLAGS_LOCAL) @DEB_CFLAGS@ @CFLAGS@
-LIBS = $(LIBS_LOCAL) @XPG4_LIBS@ @UTMPER_LIBS@
+LIBS = $(LIBS_LOCAL) @XPG4_LIBS@ @UTMPER_LIBS@ @LOGIN_LIBS@
OBJ = kik_debug.o kik_map.o kik_args.o kik_dlfcn.o kik_mem.o kik_conf.o kik_file.o kik_path.o \
kik_conf_io.o kik_str.o kik_cycle_index.o kik_langinfo.o kik_time.o kik_locale.o \
Index: kiklib/src/kik_config.h.in
===================================================================
RCS file: /home/ken/cvsroot/kiklib/src/kik_config.h.in,v
retrieving revision 1.13
diff -u -r1.13 kik_config.h.in
--- kiklib/src/kik_config.h.in 2002/02/13 14:19:49 1.13
+++ kiklib/src/kik_config.h.in 2002/02/19 06:50:38
@@ -42,6 +42,8 @@
#undef HAVE_UTMPER
+#undef HAVE_LOGIN
+
#undef PTY_STREAMS
#undef PTY_BSD
Index: kiklib/src/kik_utmp.c
===================================================================
RCS file: /home/ken/cvsroot/kiklib/src/kik_utmp.c,v
retrieving revision 1.3
diff -u -r1.3 kik_utmp.c
--- kiklib/src/kik_utmp.c 2002/02/13 14:10:01 1.3
+++ kiklib/src/kik_utmp.c 2002/02/19 07:02:18
@@ -9,6 +9,10 @@
#include "kik_utmp_utmper.c"
+#elif defined(HAVE_LOGIN)
+
+#include "kik_utmp_login.c"
+
#elif defined(HAVE_SETUTENT)
#include "kik_utmp_sysv.c"
Index: kiklib/src/kik_utmp_login.c
===================================================================
RCS file: kik_utmp_login.c
diff -N kik_utmp_login.c
--- /dev/null Tue Feb 19 16:55:30 2002
+++ kik_utmp_login.c Tue Feb 19 16:50:41 2002
@@ -0,0 +1,128 @@
+/*
+ * $Id: kik_utmp_sysv.c,v 1.2 2002/02/13 14:41:31 arakiken Exp $
+ */
+
+#include "kik_utmp.h"
+
+#include <stdio.h> /* NULL */
+#include <pwd.h>
+#include <sys/types.h>
+#include <util.h> /* login/logout */
+#include <utmp.h> /* you have to link libutil*/
+#include <unistd.h> /* getuid */
+#include <string.h> /* strncmp */
+#include <time.h> /* time */
+
+#include "kik_util.h" /* K_MIN */
+#include "kik_mem.h" /* malloc/free */
+#include "kik_config.h" /* HAVE_SETUTENT */
+#include "kik_privilege.h"
+
+struct kik_utmp
+{
+ char ut_line[UT_LINESIZE] ;
+} ;
+
+/* --- global functions --- */
+
+kik_utmp_t
+kik_utmp_new(
+ char * tty ,
+ char * host ,
+ int pty_fd
+ )
+{
+ kik_utmp_t utmp ;
+ struct utmp ut;
+ struct passwd * pwent;
+ char * pw_name;
+
+ if( ( utmp = malloc( sizeof( *utmp))) == NULL)
+ {
+ return NULL ;
+ }
+#ifdef HAVE_SETUTENT
+ setutent();
+#endif
+ memset( &ut , 0 , sizeof( ut)) ;
+ if( ( pwent = getpwuid( getuid())) == NULL || pwent->pw_name == NULL)
+ {
+ pw_name = "?" ;
+ }
+ else
+ {
+ pw_name = pwent->pw_name ;
+ }
+#ifdef HAVE_SETUTENT
+ /* sysv style */
+ strncpy( ut.ut_user , pw_name , K_MIN(sizeof( ut.ut_user),strlen(pw_name))) ;
+#else
+ /* bsd style */
+ strncpy( ut.ut_name , pw_name , K_MIN(sizeof( ut.ut_name),strlen(pw_name))) ;
+#endif
+ if( strncmp( tty, "/dev/", K_MIN(5,strlen(tty))) == 0)
+ {
+ /* skip /dev/ prefix */
+ tty += 5 ;
+ }
+
+ if( strncmp( tty, "pts", K_MIN(3,strlen(tty))) != 0 &&
+ strncmp( tty, "pty", K_MIN(3,strlen(tty))) != 0 &&
+ strncmp( tty, "tty", K_MIN(3,strlen(tty))) != 0)
+ {
+ goto error ;
+ }
+
+#ifndef HAVE_SETUTENT
+ /* bsd */
+ memcpy( ut.ut_line , tty , K_MIN(sizeof(ut.ut_line),strlen(tty))) ;
+#endif
+
+ ut.ut_time = time(NULL);
+ memcpy( ut.ut_host , host , K_MIN(sizeof( ut.ut_host),strlen(host)));
+ kik_priv_restore_euid() ;/* useless? */
+ kik_priv_restore_egid() ;
+
+ login(&ut); /* fills ut.ut_line, ut.ut_type, ut.ut_pid on sysv. */
+ /* login does not give us error information... */
+ kik_priv_change_euid( getuid()) ;
+ kik_priv_change_egid( getgid()) ;
+ memcpy(utmp->ut_line , ut.ut_line , sizeof( utmp->ut_line)) ;
+
+ return utmp;
+ error:
+ kik_priv_change_euid( getuid()) ;
+ kik_priv_change_egid( getgid()) ;
+ free(utmp);
+ return NULL;
+}
+
+int
+kik_utmp_delete(
+ kik_utmp_t utmp
+ )
+{
+#ifndef HAVE_SETUTENT
+ /* bsd */
+ kik_priv_restore_euid() ;
+ kik_priv_restore_egid() ;
+#endif
+
+ logout(utmp->ut_line);
+ logwtmp(utmp->ut_line,"","") ;
+
+#ifndef HAVE_SETUTENT
+ /* bsd */
+ kik_priv_change_euid( getuid()) ;
+ kik_priv_change_egid( getgid()) ;
+#endif
+
+#ifdef HAVE_SETUTENT
+ endutent();
+#endif
+
+ free(utmp) ;
+
+ return 1 ;
+}
+
|