]>
git.saurik.com Git - apple/libc.git/blob - gen/NetBSD/utmpx.c
1 /* $NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $ */
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
38 #include <sys/cdefs.h>
40 #if defined(LIBC_SCCS) && !defined(lint)
41 __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09/06 16:42:10 wiz Exp $");
42 #endif /* LIBC_SCCS and not lint */
44 #include "namespace.h"
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/socket.h>
61 /* don't define earlier, has side effects in fcntl.h */
62 #define __LIBC12_SOURCE__
66 __warn_references(getlastlogx
,
67 "warning: reference to compatibility getlastlogx(); include <utmpx.h> for correct reference")
68 __warn_references(lastlogxname
,
69 "warning: reference to deprecated lastlogxname()")
72 static int readonly
= 0;
73 static struct utmpx ut
;
74 static char utfile
[MAXPATHLEN
] = _PATH_UTMPX
;
75 static char llfile
[MAXPATHLEN
] = _PATH_LASTLOGX
;
77 static struct utmpx
*utmp_update(const struct utmpx
*);
79 static const char vers
[] = "utmpx-1.00";
85 (void)memset(&ut
, 0, sizeof(ut
));
88 (void)fseeko(fp
, (off_t
)sizeof(ut
), SEEK_SET
);
96 (void)memset(&ut
, 0, sizeof(ut
));
112 if ((fp
= fopen(utfile
, "r+")) == NULL
)
113 if ((fp
= fopen(utfile
, "w+")) == NULL
) {
114 if ((fp
= fopen(utfile
, "r")) == NULL
)
121 /* get file size in order to check if new file */
122 if (fstat(fileno(fp
), &st
) == -1)
125 if (st
.st_size
== 0) {
126 /* new file, add signature record */
127 (void)memset(&ut
, 0, sizeof(ut
));
128 ut
.ut_type
= SIGNATURE
;
129 (void)memcpy(ut
.ut_user
, vers
, sizeof(vers
));
130 if (fwrite(&ut
, sizeof(ut
), 1, fp
) != 1)
133 /* old file, read signature record */
134 if (fread(&ut
, sizeof(ut
), 1, fp
) != 1)
136 if (memcmp(ut
.ut_user
, vers
, sizeof(vers
)) != 0 ||
137 ut
.ut_type
!= SIGNATURE
)
142 if (fread(&ut
, sizeof(ut
), 1, fp
) != 1)
149 (void)memset(&ut
, 0, sizeof(ut
));
155 getutxid(const struct utmpx
*utx
)
158 _DIAGASSERT(utx
!= NULL
);
160 if (utx
->ut_type
== EMPTY
)
164 if (ut
.ut_type
== EMPTY
)
166 switch (utx
->ut_type
) {
173 if (ut
.ut_type
== utx
->ut_type
)
180 switch (ut
.ut_type
) {
185 if (memcmp(ut
.ut_id
, utx
->ut_id
,
186 sizeof(ut
.ut_id
)) == 0)
196 } while (getutxent() != NULL
);
202 getutxline(const struct utmpx
*utx
)
205 _DIAGASSERT(utx
!= NULL
);
208 switch (ut
.ut_type
) {
213 if (strncmp(ut
.ut_line
, utx
->ut_line
,
214 sizeof(ut
.ut_line
)) == 0)
220 } while (getutxent() != NULL
);
226 pututxline(const struct utmpx
*utx
)
228 struct utmpx temp
, *u
= NULL
;
231 _DIAGASSERT(utx
!= NULL
);
236 if (strcmp(_PATH_UTMPX
, utfile
) == 0)
237 if ((fp
!= NULL
&& readonly
) || (fp
== NULL
&& geteuid() != 0))
238 return utmp_update(utx
);
241 (void)memcpy(&temp
, utx
, sizeof(temp
));
245 if (fp
== NULL
|| readonly
)
249 if (getutxid(&temp
) == NULL
) {
251 if (getutxid(&temp
) == NULL
) {
252 if (lockf(fileno(fp
), F_LOCK
, (off_t
)0) == -1)
255 if (fseeko(fp
, (off_t
)0, SEEK_END
) == -1)
261 /* we are not appending */
262 if (fseeko(fp
, -(off_t
)sizeof(ut
), SEEK_CUR
) == -1)
266 if (fwrite(&temp
, sizeof (temp
), 1, fp
) != 1)
269 if (fflush(fp
) == -1)
272 u
= memcpy(&ut
, &temp
, sizeof(ut
));
275 if (lockf(fileno(fp
), F_ULOCK
, (off_t
)0) == -1)
282 static struct utmpx
*
283 utmp_update(const struct utmpx
*utx
)
285 char buf
[sizeof(*utx
) * 4 + 1];
289 _DIAGASSERT(utx
!= NULL
);
291 (void)strvisx(buf
, (const char *)(const void *)utx
, sizeof(*utx
),
293 switch (pid
= fork()) {
295 (void)execl(_PATH_UTMP_UPDATE
,
296 strrchr(_PATH_UTMP_UPDATE
, '/') + 1, buf
, NULL
);
302 if (waitpid(pid
, &status
, 0) == -1)
304 if (WIFEXITED(status
) && WEXITSTATUS(status
) == 0)
305 return memcpy(&ut
, utx
, sizeof(ut
));
312 * The following are extensions and not part of the X/Open spec.
315 updwtmpx(const char *file
, const struct utmpx
*utx
)
320 _DIAGASSERT(file
!= NULL
);
321 _DIAGASSERT(utx
!= NULL
);
323 fd
= open(file
, O_WRONLY
|O_APPEND
|O_SHLOCK
);
326 if ((fd
= open(file
, O_CREAT
|O_WRONLY
|O_EXLOCK
, 0644)) == -1)
328 (void)memset(&ut
, 0, sizeof(ut
));
329 ut
.ut_type
= SIGNATURE
;
330 (void)memcpy(ut
.ut_user
, vers
, sizeof(vers
));
331 if (write(fd
, &ut
, sizeof(ut
)) == -1)
334 if (write(fd
, utx
, sizeof(*utx
)) == -1)
349 utmpxname(const char *fname
)
353 _DIAGASSERT(fname
!= NULL
);
357 if (len
>= sizeof(utfile
))
361 if (fname
[len
- 1] != 'x')
364 (void)strlcpy(utfile
, fname
, sizeof(utfile
));
371 getutmp(const struct utmpx
*ux
, struct utmp
*u
)
374 _DIAGASSERT(ux
!= NULL
);
375 _DIAGASSERT(u
!= NULL
);
377 (void)memcpy(u
->ut_name
, ux
->ut_name
, sizeof(u
->ut_name
));
378 (void)memcpy(u
->ut_line
, ux
->ut_line
, sizeof(u
->ut_line
));
379 (void)memcpy(u
->ut_host
, ux
->ut_host
, sizeof(u
->ut_host
));
380 u
->ut_time
= ux
->ut_tv
.tv_sec
;
384 getutmpx(const struct utmp
*u
, struct utmpx
*ux
)
387 _DIAGASSERT(ux
!= NULL
);
388 _DIAGASSERT(u
!= NULL
);
390 (void)memcpy(ux
->ut_name
, u
->ut_name
, sizeof(u
->ut_name
));
391 (void)memcpy(ux
->ut_line
, u
->ut_line
, sizeof(u
->ut_line
));
392 (void)memcpy(ux
->ut_host
, u
->ut_host
, sizeof(u
->ut_host
));
393 ux
->ut_tv
.tv_sec
= u
->ut_time
;
394 ux
->ut_tv
.tv_usec
= 0;
395 (void)memset(&ux
->ut_ss
, 0, sizeof(ux
->ut_ss
));
397 ux
->ut_type
= USER_PROCESS
;
399 ux
->ut_exit
.e_termination
= 0;
400 ux
->ut_exit
.e_exit
= 0;
404 lastlogxname(const char *fname
)
408 _DIAGASSERT(fname
!= NULL
);
412 if (len
>= sizeof(llfile
))
416 if (fname
[len
- 1] != 'x')
419 (void)strlcpy(llfile
, fname
, sizeof(llfile
));
424 getlastlogx(uid_t uid
, struct lastlogx
*ll
)
427 return __getlastlogx13(_PATH_LASTLOGX
, uid
, ll
);
431 __getlastlogx13(const char *fname
, uid_t uid
, struct lastlogx
*ll
)
436 _DIAGASSERT(fname
!= NULL
);
437 _DIAGASSERT(ll
!= NULL
);
439 db
= dbopen(fname
, O_RDONLY
|O_SHLOCK
, 0, DB_HASH
, NULL
);
445 key
.size
= sizeof(uid
);
447 if ((db
->get
)(db
, &key
, &data
, 0) != 0)
450 if (data
.size
!= sizeof(*ll
)) {
456 if ((ll
= malloc(sizeof(*ll
))) == NULL
)
459 (void)memcpy(ll
, data
.data
, sizeof(*ll
));
469 updlastlogx(const char *fname
, uid_t uid
, struct lastlogx
*ll
)
475 _DIAGASSERT(fname
!= NULL
);
476 _DIAGASSERT(ll
!= NULL
);
478 db
= dbopen(fname
, O_RDWR
|O_CREAT
|O_EXLOCK
, 0, DB_HASH
, NULL
);
484 key
.size
= sizeof(uid
);
486 data
.size
= sizeof(*ll
);
487 if ((db
->put
)(db
, &key
, &data
, 0) != 0)