utxdb.c revision 202778
1/*-
2 * Copyright (c) 2010 Ed Schouten <ed@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/lib/libc/gen/utxdb.c 202778 2010-01-22 04:53:08Z ed $");
29
30#include "namespace.h"
31#include <sys/endian.h>
32#include <sys/param.h>
33#include <stdlib.h>
34#include <string.h>
35#include <utmpx.h>
36#include "utxdb.h"
37#include "un-namespace.h"
38
39#define	UTOF_STRING(ut, fu, field) do { \
40	strncpy((fu)->fu_ ## field, (ut)->ut_ ## field,		\
41	    MIN(sizeof (fu)->fu_ ## field, sizeof (ut)->ut_ ## field));	\
42} while (0)
43#define	UTOF_ID(ut, fu) do { \
44	memcpy((fu)->fu_id, (ut)->ut_id,				\
45	    MIN(sizeof (fu)->fu_id, sizeof (ut)->ut_id));		\
46} while (0)
47#define	UTOF_PID(ut, fu) do { \
48	(fu)->fu_pid = htobe32((ut)->ut_pid);				\
49} while (0)
50#define	UTOF_TYPE(ut, fu) do { \
51	(fu)->fu_type = (ut)->ut_type;					\
52} while (0)
53#define	UTOF_TV(ut, fu) do { \
54	(fu)->fu_tv = htobe64((uint64_t)(ut)->ut_tv.tv_sec * 1000000 +	\
55	    (uint64_t)(ut)->ut_tv.tv_usec);				\
56} while (0)
57
58void
59utx_to_futx(const struct utmpx *ut, struct futx *fu)
60{
61
62	memset(fu, 0, sizeof *fu);
63
64	switch (ut->ut_type) {
65	case BOOT_TIME:
66	case OLD_TIME:
67	case NEW_TIME:
68	/* Extension: shutdown time. */
69	case SHUTDOWN_TIME:
70		break;
71	case USER_PROCESS:
72		UTOF_ID(ut, fu);
73		UTOF_STRING(ut, fu, user);
74		UTOF_STRING(ut, fu, line);
75		/* Extension: host name. */
76		UTOF_STRING(ut, fu, host);
77		UTOF_PID(ut, fu);
78		break;
79	case INIT_PROCESS:
80		UTOF_ID(ut, fu);
81		UTOF_PID(ut, fu);
82		break;
83	case LOGIN_PROCESS:
84		UTOF_ID(ut, fu);
85		UTOF_STRING(ut, fu, user);
86		UTOF_STRING(ut, fu, line);
87		UTOF_PID(ut, fu);
88		break;
89	case DEAD_PROCESS:
90		UTOF_ID(ut, fu);
91		UTOF_PID(ut, fu);
92		break;
93	default:
94		fu->fu_type = EMPTY;
95		return;
96	}
97
98	UTOF_TYPE(ut, fu);
99	UTOF_TV(ut, fu);
100}
101
102#define	FTOU_STRING(fu, ut, field) do { \
103	strncpy((ut)->ut_ ## field, (fu)->fu_ ## field,		\
104	    MIN(sizeof (ut)->ut_ ## field - 1, sizeof (fu)->fu_ ## field)); \
105} while (0)
106#define	FTOU_ID(fu, ut) do { \
107	memcpy((ut)->ut_id, (fu)->fu_id,				\
108	    MIN(sizeof (ut)->ut_id, sizeof (fu)->fu_id));		\
109} while (0)
110#define	FTOU_PID(fu, ut) do { \
111	(ut)->ut_pid = be32toh((fu)->fu_pid);				\
112} while (0)
113#define	FTOU_TYPE(fu, ut) do { \
114	(ut)->ut_type = (fu)->fu_type;					\
115} while (0)
116#define	FTOU_TV(fu, ut) do { \
117	uint64_t t;							\
118	t = be64toh((fu)->fu_tv);					\
119	(ut)->ut_tv.tv_sec = t / 1000000;				\
120	(ut)->ut_tv.tv_usec = t % 1000000;				\
121} while (0)
122
123struct utmpx *
124futx_to_utx(const struct futx *fu)
125{
126	static struct utmpx *ut;
127
128	if (ut == NULL) {
129		ut = calloc(1, sizeof *ut);
130		if (ut == NULL)
131			return (NULL);
132	} else {
133		memset(ut, 0, sizeof *ut);
134	}
135
136	switch (fu->fu_type) {
137	case BOOT_TIME:
138	case OLD_TIME:
139	case NEW_TIME:
140	/* Extension: shutdown time. */
141	case SHUTDOWN_TIME:
142		break;
143	case USER_PROCESS:
144		FTOU_ID(fu, ut);
145		FTOU_STRING(fu, ut, user);
146		FTOU_STRING(fu, ut, line);
147		/* Extension: host name. */
148		FTOU_STRING(fu, ut, host);
149		FTOU_PID(fu, ut);
150		break;
151	case INIT_PROCESS:
152		FTOU_ID(fu, ut);
153		FTOU_PID(fu, ut);
154		break;
155	case LOGIN_PROCESS:
156		FTOU_ID(fu, ut);
157		FTOU_STRING(fu, ut, user);
158		FTOU_STRING(fu, ut, line);
159		FTOU_PID(fu, ut);
160		break;
161	case DEAD_PROCESS:
162		FTOU_ID(fu, ut);
163		FTOU_PID(fu, ut);
164		break;
165	default:
166		ut->ut_type = EMPTY;
167		return (ut);
168	}
169
170	FTOU_TYPE(fu, ut);
171	FTOU_TV(fu, ut);
172	return (ut);
173}
174