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