hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

utmpx.c (5524B)


      1 /*
      2  * Copyright (c) 2004 Gunnar Ritter
      3  *
      4  * This software is provided 'as-is', without any express or implied
      5  * warranty. In no event will the authors be held liable for any damages
      6  * arising from the use of this software.
      7  *
      8  * Permission is granted to anyone to use this software for any purpose,
      9  * including commercial applications, and to alter it and redistribute
     10  * it freely, subject to the following restrictions:
     11  *
     12  * 1. The origin of this software must not be misrepresented; you must not
     13  *    claim that you wrote the original software. If you use this software
     14  *    in a product, an acknowledgment in the product documentation would be
     15  *    appreciated but is not required.
     16  *
     17  * 2. Altered source versions must be plainly marked as such, and must not be
     18  *    misrepresented as being the original software.
     19  *
     20  * 3. This notice may not be removed or altered from any source distribution.
     21  */
     22 /*	Sccsid @(#)utmpx.c	1.13 (gritter) 12/16/07	*/
     23 
     24 #include <stdio.h>
     25 
     26 #if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \
     27 	defined (__UCLIBC__) || defined (__OpenBSD__) || \
     28 	defined (__DragonFly__) || \
     29 	defined (__APPLE__) && \
     30 		(__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_OS_X_VERSION_10_5)
     31 #include <sys/types.h>
     32 #include <sys/time.h>
     33 #include <utmp.h>
     34 #include <string.h>
     35 
     36 #include "utmpx.h"
     37 
     38 static FILE	*utfp;
     39 static struct utmpx	utx;
     40 static const char	*utmpfile = _PATH_UTMP;
     41 
     42 static FILE *
     43 init(void)
     44 {
     45 	if (utfp == NULL && (utfp = fopen(utmpfile, "r+")) == NULL)
     46 		if ((utfp = fopen(utmpfile, "r")) == NULL)
     47 			return NULL;
     48 	return utfp;
     49 }
     50 
     51 static struct utmpx *
     52 utmp2utmpx(struct utmpx *ux, const struct utmp *up)
     53 {
     54 #ifndef	__dietlibc__
     55 	memset(ux, 0, sizeof *ux);
     56 	ux->ut_tv.tv_sec = up->ut_time;
     57 	memcpy(ux->ut_line, up->ut_line, UT_LINESIZE);
     58 	memcpy(ux->ut_user, up->ut_name, UT_NAMESIZE);
     59 	memcpy(ux->ut_host, up->ut_host, UT_HOSTSIZE);
     60 	if (strcmp(up->ut_line, "~") == 0)
     61 		ux->ut_type = BOOT_TIME;
     62 	else if (strcmp(up->ut_line, "|") == 0)
     63 		ux->ut_type = OLD_TIME;
     64 	else if (strcmp(up->ut_line, "}") == 0)
     65 		ux->ut_type = NEW_TIME;
     66 	else if (*up->ut_name == 0)
     67 		ux->ut_type = DEAD_PROCESS;
     68 	else
     69 		ux->ut_type = USER_PROCESS;
     70 #else	/* __dietlibc__ */
     71 	*ux = *up;
     72 #endif	/* __dietlibc__ */
     73 	return ux;
     74 }
     75 
     76 static struct utmp *
     77 utmpx2utmp(struct utmp *up, const struct utmpx *ux)
     78 {
     79 #ifndef	__dietlibc__
     80 	memset(up, 0, sizeof *up);
     81 	up->ut_time = ux->ut_tv.tv_sec;
     82 	switch (ux->ut_type) {
     83 	case DEAD_PROCESS:
     84 		memcpy(up->ut_line, ux->ut_line, UT_LINESIZE);
     85 		break;
     86 	default:
     87 	case EMPTY:
     88 	case INIT_PROCESS:
     89 	case LOGIN_PROCESS:
     90 	case RUN_LVL:
     91 	case ACCOUNTING:
     92 		return NULL;
     93 	case BOOT_TIME:
     94 		strcpy(up->ut_name, "reboot");
     95 		strcpy(up->ut_line, "~");
     96 		break;
     97 	case OLD_TIME:
     98 		strcpy(up->ut_name, "date");
     99 		strcpy(up->ut_line, "|");
    100 		break;
    101 	case NEW_TIME:
    102 		strcpy(up->ut_name, "date");
    103 		strcpy(up->ut_line, "{");
    104 		break;
    105 	case USER_PROCESS:
    106 		memcpy(up->ut_line, ux->ut_line, UT_LINESIZE);
    107 		memcpy(up->ut_name, ux->ut_user, UT_NAMESIZE);
    108 		memcpy(up->ut_host, ux->ut_host, UT_HOSTSIZE);
    109 	}
    110 #else	/* __dietlibc__ */
    111 	*up = *ux;
    112 #endif	/* __dietlibc__ */
    113 	return up;
    114 }
    115 
    116 struct utmpx *
    117 getutxent(void)
    118 {
    119 	static struct utmp	zero;
    120 	struct utmp	ut;
    121 
    122 	if (init() == NULL)
    123 		return NULL;
    124 	do {
    125 		if (fread(&ut, sizeof ut, 1, utfp) != 1)
    126 			return NULL;
    127 	} while (memcmp(&ut, &zero, sizeof ut) == 0);
    128 	return utmp2utmpx(&utx, &ut);
    129 }
    130 
    131 struct utmpx *
    132 getutxline(const struct utmpx *ux)
    133 {
    134 	struct utmp	ut;
    135 
    136 	if (init() == NULL)
    137 		return NULL;
    138 	fseek(utfp, 0, SEEK_SET);
    139 	while (fread(&ut, sizeof ut, 1, utfp) == 1) {
    140 		utmp2utmpx(&utx, &ut);
    141 		if ((utx.ut_type == LOGIN_PROCESS ||
    142 					utx.ut_type == USER_PROCESS) &&
    143 				strcmp(ut.ut_line, utx.ut_line) == 0)
    144 			return &utx;
    145 	}
    146 	return NULL;
    147 }
    148 
    149 struct utmpx *
    150 getutxid(const struct utmpx *ux)
    151 {
    152 #ifdef	__dietlibc__
    153 	struct utmp	ut;
    154 #endif
    155 
    156 	if (init() == NULL)
    157 		return NULL;
    158 #ifdef	__dietlibc__
    159 	fseek(utfp, 0, SEEK_SET);
    160 	while (fread(&ut, sizeof ut, 1, utfp) == 1) {
    161 		utmp2utmpx(&utx, &ut);
    162 		switch (ux->ut_type) {
    163 		case BOOT_TIME:
    164 		case OLD_TIME:
    165 		case NEW_TIME:
    166 			if (ux->ut_type == utx.ut_type)
    167 				return &utx;
    168 			break;
    169 		case INIT_PROCESS:
    170 		case LOGIN_PROCESS:
    171 		case USER_PROCESS:
    172 		case DEAD_PROCESS:
    173 			if (ux->ut_type == utx.ut_type &&
    174 					ux->ut_id == utx.ut_id)
    175 				return &utx;
    176 			break;
    177 		}
    178 	}
    179 #endif	/* __dietlibc__ */
    180 	return NULL;
    181 }
    182 
    183 void
    184 setutxent(void)
    185 {
    186 	if (init() == NULL)
    187 		return;
    188 	fseek(utfp, 0, SEEK_SET);
    189 }
    190 
    191 void
    192 endutxent(void)
    193 {
    194 	FILE	*fp;
    195 
    196 	if (init() == NULL)
    197 		return;
    198 	fp = utfp;
    199 	utfp = NULL;
    200 	fclose(fp);
    201 }
    202 
    203 int
    204 utmpxname(const char *name)
    205 {
    206 	utmpfile = strdup(name);
    207 	return 0;
    208 }
    209 
    210 extern struct utmpx *
    211 pututxline(const struct utmpx *up)
    212 {
    213 	struct utmp	ut;
    214 	struct utmpx	*rp;
    215 
    216 	if (init() == NULL)
    217 		return NULL;
    218 	/*
    219 	 * Cannot use getutxid() because there is no id field. Use
    220 	 * the equivalent of getutxline() instead.
    221 	 */
    222 	while (fread(&ut, sizeof ut, 1, utfp) == 1) {
    223 		if (strncmp(ut.ut_line, up->ut_line, UT_LINESIZE) == 0) {
    224 			fseek(utfp, -sizeof ut, SEEK_CUR);
    225 			break;
    226 		}
    227 	}
    228 	fflush(utfp);
    229 	if (utmpx2utmp(&ut, up) == NULL)
    230 		rp = NULL;
    231 	else if (fwrite(&ut, sizeof ut, 1, utfp) == 1) {
    232 		utx = *up;
    233 		rp = &utx;
    234 	} else
    235 		rp = NULL;
    236 	fflush(utfp);
    237 	return rp;
    238 }
    239 
    240 extern void
    241 updwtmpx(const char *name, const struct utmpx *up)
    242 {
    243 	FILE	*fp;
    244 
    245 	if ((fp = fopen(name, "a")) == NULL)
    246 		return;
    247 	fwrite(up, sizeof *up, 1, fp);
    248 	fclose(fp);
    249 }
    250 
    251 #endif	/* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ ||
    252 	 	__OpenBSD__ || __DragonFly__ || __APPLE__ */