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 ; +} + |