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