utxdb.c revision 202530
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 202530 2010-01-17 21:40:05Z 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 /* XXX: bug in the specification? Needed for getutxline(). */ 87 UTOF_STRING(ut, fu, line); 88 UTOF_PID(ut, fu); 89 break; 90 case DEAD_PROCESS: 91 UTOF_ID(ut, fu); 92 UTOF_PID(ut, fu); 93 break; 94 default: 95 fu->fu_type = EMPTY; 96 return; 97 } 98 99 UTOF_TYPE(ut, fu); 100 UTOF_TV(ut, fu); 101} 102 103#define FTOU_STRING(fu, ut, field) do { \ 104 strncpy((ut)->ut_ ## field, (fu)->fu_ ## field, \ 105 MIN(sizeof (ut)->ut_ ## field - 1, sizeof (fu)->fu_ ## field)); \ 106} while (0) 107#define FTOU_ID(fu, ut) do { \ 108 memcpy((ut)->ut_id, (fu)->fu_id, \ 109 MIN(sizeof (ut)->ut_id, sizeof (fu)->fu_id)); \ 110} while (0) 111#define FTOU_PID(fu, ut) do { \ 112 (ut)->ut_pid = be32toh((fu)->fu_pid); \ 113} while (0) 114#define FTOU_TYPE(fu, ut) do { \ 115 (ut)->ut_type = (fu)->fu_type; \ 116} while (0) 117#define FTOU_TV(fu, ut) do { \ 118 uint64_t t; \ 119 t = be64toh((fu)->fu_tv); \ 120 (ut)->ut_tv.tv_sec = t / 1000000; \ 121 (ut)->ut_tv.tv_usec = t % 1000000; \ 122} while (0) 123 124struct utmpx * 125futx_to_utx(const struct futx *fu) 126{ 127 static struct utmpx *ut; 128 129 if (ut == NULL) { 130 ut = calloc(1, sizeof *ut); 131 if (ut == NULL) 132 return (NULL); 133 } else { 134 memset(ut, 0, sizeof *ut); 135 } 136 137 switch (fu->fu_type) { 138 case BOOT_TIME: 139 case OLD_TIME: 140 case NEW_TIME: 141 /* Extension: shutdown time. */ 142 case SHUTDOWN_TIME: 143 break; 144 case USER_PROCESS: 145 FTOU_ID(fu, ut); 146 FTOU_STRING(fu, ut, user); 147 FTOU_STRING(fu, ut, line); 148 /* Extension: host name. */ 149 FTOU_STRING(fu, ut, host); 150 FTOU_PID(fu, ut); 151 break; 152 case INIT_PROCESS: 153 FTOU_ID(fu, ut); 154 FTOU_PID(fu, ut); 155 break; 156 case LOGIN_PROCESS: 157 FTOU_ID(fu, ut); 158 FTOU_STRING(fu, ut, user); 159 /* XXX: bug in the specification? Needed for getutxline(). */ 160 FTOU_STRING(fu, ut, line); 161 FTOU_PID(fu, ut); 162 break; 163 case DEAD_PROCESS: 164 FTOU_ID(fu, ut); 165 FTOU_PID(fu, ut); 166 break; 167 default: 168 ut->ut_type = EMPTY; 169 return (ut); 170 } 171 172 FTOU_TYPE(fu, ut); 173 FTOU_TV(fu, ut); 174 return (ut); 175} 176