1 /* Copyright (C) 2008-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
17
18 #include <sys/types.h>
19 #include <utmp.h>
20 #include <errno.h>
21 #include <stdlib.h>
22
23 #include "utmp32.h"
24 #include "utmp-convert.h"
25
26 /* Allocate a static buffer to be returned to the caller. As well as
27 with the existing version of these functions the caller has to be
28 aware that the contents of this buffer will change with subsequent
29 calls. */
30 #define ALLOCATE_UTMP32_OUT(OUT) \
31 static struct utmp32 *OUT = NULL; \
32 \
33 if (OUT == NULL) \
34 { \
35 OUT = malloc (sizeof (struct utmp32)); \
36 if (OUT == NULL) \
37 return NULL; \
38 }
39
40 /* Perform a lookup for a utmp entry matching FIELD using function
41 FUNC. FIELD is converted to a 64 bit utmp and the result is
42 converted back to 32 bit utmp. */
43 #define ACCESS_UTMP_ENTRY(FUNC, FIELD) \
44 struct utmp in64; \
45 struct utmp *out64; \
46 ALLOCATE_UTMP32_OUT (out32); \
47 \
48 utmp_convert32to64 (FIELD, &in64); \
49 out64 = FUNC (&in64); \
50 \
51 if (out64 == NULL) \
52 return NULL; \
53 \
54 utmp_convert64to32 (out64, out32); \
55 \
56 return out32;
57
58 /* Search forward from the current point in the utmp file until the
59 next entry with a ut_type matching ID->ut_type. */
60 struct utmp32 *
getutid32(const struct utmp32 * id)61 getutid32 (const struct utmp32 *id)
62 {
63 ACCESS_UTMP_ENTRY (__getutid, id)
64 }
65 symbol_version (getutid32, getutid, GLIBC_2.0);
66
67 /* Search forward from the current point in the utmp file until the
68 next entry with a ut_line matching LINE->ut_line. */
69 struct utmp32 *
getutline32(const struct utmp32 * line)70 getutline32 (const struct utmp32 *line)
71 {
72 ACCESS_UTMP_ENTRY (__getutline, line)
73 }
74 symbol_version (getutline32, getutline, GLIBC_2.0);
75
76 /* Write out entry pointed to by UTMP_PTR into the utmp file. */
77 struct utmp32 *
pututline32(const struct utmp32 * utmp_ptr)78 pututline32 (const struct utmp32 *utmp_ptr)
79 {
80 ACCESS_UTMP_ENTRY (__pututline, utmp_ptr)
81 }
82 symbol_version (pututline32, pututline, GLIBC_2.0);
83
84 /* Read next entry from a utmp-like file. */
85 struct utmp32 *
getutent32(void)86 getutent32 (void)
87 {
88 struct utmp *out64;
89 ALLOCATE_UTMP32_OUT (out32);
90
91 out64 = __getutent ();
92 if (!out64)
93 return NULL;
94
95 utmp_convert64to32 (out64, out32);
96 return out32;
97 }
98 symbol_version (getutent32, getutent, GLIBC_2.0);
99
100 /* Reentrant versions of the file for handling utmp files. */
101
102 int
getutent32_r(struct utmp32 * buffer,struct utmp32 ** result)103 getutent32_r (struct utmp32 *buffer, struct utmp32 **result)
104 {
105 struct utmp out64;
106 struct utmp *out64p;
107 int ret;
108
109 ret = __getutent_r (&out64, &out64p);
110 if (ret == -1)
111 {
112 *result = NULL;
113 return -1;
114 }
115
116 utmp_convert64to32 (out64p, buffer);
117 *result = buffer;
118
119 return 0;
120 }
121 symbol_version (getutent32_r, getutent_r, GLIBC_2.0);
122
123 int
getutid32_r(const struct utmp32 * id,struct utmp32 * buffer,struct utmp32 ** result)124 getutid32_r (const struct utmp32 *id, struct utmp32 *buffer,
125 struct utmp32 **result)
126 {
127 struct utmp in64;
128 struct utmp out64;
129 struct utmp *out64p;
130 int ret;
131
132 utmp_convert32to64 (id, &in64);
133
134 ret = __getutid_r (&in64, &out64, &out64p);
135 if (ret == -1)
136 {
137 *result = NULL;
138 return -1;
139 }
140
141 utmp_convert64to32 (out64p, buffer);
142 *result = buffer;
143
144 return 0;
145 }
146 symbol_version (getutid32_r, getutid_r, GLIBC_2.0);
147
148 int
getutline32_r(const struct utmp32 * line,struct utmp32 * buffer,struct utmp32 ** result)149 getutline32_r (const struct utmp32 *line,
150 struct utmp32 *buffer, struct utmp32 **result)
151 {
152 struct utmp in64;
153 struct utmp out64;
154 struct utmp *out64p;
155 int ret;
156
157 utmp_convert32to64 (line, &in64);
158
159 ret = __getutline_r (&in64, &out64, &out64p);
160 if (ret == -1)
161 {
162 *result = NULL;
163 return -1;
164 }
165
166 utmp_convert64to32 (out64p, buffer);
167 *result = buffer;
168
169 return 0;
170
171 }
172 symbol_version (getutline32_r, getutline_r, GLIBC_2.0);
173
174 /* Append entry UTMP to the wtmp-like file WTMP_FILE. */
175 void
updwtmp32(const char * wtmp_file,const struct utmp32 * utmp)176 updwtmp32 (const char *wtmp_file, const struct utmp32 *utmp)
177 {
178 struct utmp in32;
179
180 utmp_convert32to64 (utmp, &in32);
181 __updwtmp (wtmp_file, &in32);
182 }
183 symbol_version (updwtmp32, updwtmp, GLIBC_2.0);
184