1 | /* Copyright (C) 2008-2024 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 * |
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 * |
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 * |
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 * |
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 (from: out64, to: 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 |
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 (from: out64p, to: buffer); |
117 | *result = buffer; |
118 | |
119 | return 0; |
120 | } |
121 | symbol_version (getutent32_r, getutent_r, GLIBC_2.0); |
122 | |
123 | int |
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 (from: id, to: &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 (from: out64p, to: buffer); |
142 | *result = buffer; |
143 | |
144 | return 0; |
145 | } |
146 | symbol_version (getutid32_r, getutid_r, GLIBC_2.0); |
147 | |
148 | int |
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 (from: line, to: &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 (from: out64p, to: 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 |
176 | updwtmp32 (const char *wtmp_file, const struct utmp32 *utmp) |
177 | { |
178 | struct utmp in32; |
179 | |
180 | utmp_convert32to64 (from: utmp, to: &in32); |
181 | __updwtmp (wtmp_file, &in32); |
182 | } |
183 | symbol_version (updwtmp32, updwtmp, GLIBC_2.0); |
184 | |