1202188Sed/*- 2202188Sed * Copyright (c) 2010 Ed Schouten <ed@FreeBSD.org> 3202188Sed * All rights reserved. 4202188Sed * 5202188Sed * Redistribution and use in source and binary forms, with or without 6202188Sed * modification, are permitted provided that the following conditions 7202188Sed * are met: 8202188Sed * 1. Redistributions of source code must retain the above copyright 9202188Sed * notice, this list of conditions and the following disclaimer. 10202188Sed * 2. Redistributions in binary form must reproduce the above copyright 11202188Sed * notice, this list of conditions and the following disclaimer in the 12202188Sed * documentation and/or other materials provided with the distribution. 13202188Sed * 14202188Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15202188Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16202188Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17202188Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18202188Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19202188Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20202188Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21202188Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22202188Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23202188Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24202188Sed * SUCH DAMAGE. 25202188Sed */ 26202188Sed 27202188Sed#include <sys/cdefs.h> 28202188Sed__FBSDID("$FreeBSD$"); 29202188Sed 30202188Sed#include "namespace.h" 31202188Sed#include <sys/endian.h> 32202188Sed#include <sys/param.h> 33202876Sed#include <sys/time.h> 34202530Sed#include <stdlib.h> 35202188Sed#include <string.h> 36202188Sed#include <utmpx.h> 37202188Sed#include "utxdb.h" 38202188Sed#include "un-namespace.h" 39202188Sed 40202188Sed#define UTOF_STRING(ut, fu, field) do { \ 41202188Sed strncpy((fu)->fu_ ## field, (ut)->ut_ ## field, \ 42202188Sed MIN(sizeof (fu)->fu_ ## field, sizeof (ut)->ut_ ## field)); \ 43202188Sed} while (0) 44202188Sed#define UTOF_ID(ut, fu) do { \ 45202188Sed memcpy((fu)->fu_id, (ut)->ut_id, \ 46202188Sed MIN(sizeof (fu)->fu_id, sizeof (ut)->ut_id)); \ 47202188Sed} while (0) 48202188Sed#define UTOF_PID(ut, fu) do { \ 49202188Sed (fu)->fu_pid = htobe32((ut)->ut_pid); \ 50202188Sed} while (0) 51202188Sed#define UTOF_TYPE(ut, fu) do { \ 52202188Sed (fu)->fu_type = (ut)->ut_type; \ 53202188Sed} while (0) 54202876Sed#define UTOF_TV(fu) do { \ 55202876Sed struct timeval tv; \ 56202876Sed gettimeofday(&tv, NULL); \ 57202876Sed (fu)->fu_tv = htobe64((uint64_t)tv.tv_sec * 1000000 + \ 58202876Sed (uint64_t)tv.tv_usec); \ 59202188Sed} while (0) 60202188Sed 61202188Sedvoid 62202188Sedutx_to_futx(const struct utmpx *ut, struct futx *fu) 63202188Sed{ 64202188Sed 65202188Sed memset(fu, 0, sizeof *fu); 66202188Sed 67202188Sed switch (ut->ut_type) { 68202188Sed case BOOT_TIME: 69202188Sed case OLD_TIME: 70202188Sed case NEW_TIME: 71202188Sed /* Extension: shutdown time. */ 72202188Sed case SHUTDOWN_TIME: 73202188Sed break; 74202188Sed case USER_PROCESS: 75202188Sed UTOF_ID(ut, fu); 76202188Sed UTOF_STRING(ut, fu, user); 77202188Sed UTOF_STRING(ut, fu, line); 78202188Sed /* Extension: host name. */ 79202188Sed UTOF_STRING(ut, fu, host); 80202188Sed UTOF_PID(ut, fu); 81202188Sed break; 82202188Sed case INIT_PROCESS: 83202188Sed UTOF_ID(ut, fu); 84202188Sed UTOF_PID(ut, fu); 85202188Sed break; 86202188Sed case LOGIN_PROCESS: 87202188Sed UTOF_ID(ut, fu); 88202188Sed UTOF_STRING(ut, fu, user); 89202530Sed UTOF_STRING(ut, fu, line); 90202188Sed UTOF_PID(ut, fu); 91202188Sed break; 92202188Sed case DEAD_PROCESS: 93202188Sed UTOF_ID(ut, fu); 94202188Sed UTOF_PID(ut, fu); 95202188Sed break; 96202188Sed default: 97202188Sed fu->fu_type = EMPTY; 98202188Sed return; 99202188Sed } 100202188Sed 101202188Sed UTOF_TYPE(ut, fu); 102202876Sed UTOF_TV(fu); 103202188Sed} 104202188Sed 105202188Sed#define FTOU_STRING(fu, ut, field) do { \ 106202188Sed strncpy((ut)->ut_ ## field, (fu)->fu_ ## field, \ 107202188Sed MIN(sizeof (ut)->ut_ ## field - 1, sizeof (fu)->fu_ ## field)); \ 108202188Sed} while (0) 109202188Sed#define FTOU_ID(fu, ut) do { \ 110202188Sed memcpy((ut)->ut_id, (fu)->fu_id, \ 111202188Sed MIN(sizeof (ut)->ut_id, sizeof (fu)->fu_id)); \ 112202188Sed} while (0) 113202188Sed#define FTOU_PID(fu, ut) do { \ 114202188Sed (ut)->ut_pid = be32toh((fu)->fu_pid); \ 115202188Sed} while (0) 116202188Sed#define FTOU_TYPE(fu, ut) do { \ 117202188Sed (ut)->ut_type = (fu)->fu_type; \ 118202188Sed} while (0) 119202188Sed#define FTOU_TV(fu, ut) do { \ 120202188Sed uint64_t t; \ 121202188Sed t = be64toh((fu)->fu_tv); \ 122202188Sed (ut)->ut_tv.tv_sec = t / 1000000; \ 123202188Sed (ut)->ut_tv.tv_usec = t % 1000000; \ 124202188Sed} while (0) 125202188Sed 126202530Sedstruct utmpx * 127202530Sedfutx_to_utx(const struct futx *fu) 128202188Sed{ 129202530Sed static struct utmpx *ut; 130202188Sed 131202530Sed if (ut == NULL) { 132202530Sed ut = calloc(1, sizeof *ut); 133202530Sed if (ut == NULL) 134202530Sed return (NULL); 135218846Sed } else 136202530Sed memset(ut, 0, sizeof *ut); 137202188Sed 138202188Sed switch (fu->fu_type) { 139202188Sed case BOOT_TIME: 140202188Sed case OLD_TIME: 141202188Sed case NEW_TIME: 142202188Sed /* Extension: shutdown time. */ 143202188Sed case SHUTDOWN_TIME: 144202188Sed break; 145202188Sed case USER_PROCESS: 146202188Sed FTOU_ID(fu, ut); 147202188Sed FTOU_STRING(fu, ut, user); 148202188Sed FTOU_STRING(fu, ut, line); 149202188Sed /* Extension: host name. */ 150202188Sed FTOU_STRING(fu, ut, host); 151202188Sed FTOU_PID(fu, ut); 152202188Sed break; 153202188Sed case INIT_PROCESS: 154202188Sed FTOU_ID(fu, ut); 155202188Sed FTOU_PID(fu, ut); 156202188Sed break; 157202188Sed case LOGIN_PROCESS: 158202188Sed FTOU_ID(fu, ut); 159202188Sed FTOU_STRING(fu, ut, user); 160202530Sed FTOU_STRING(fu, ut, line); 161202188Sed FTOU_PID(fu, ut); 162202188Sed break; 163202188Sed case DEAD_PROCESS: 164202188Sed FTOU_ID(fu, ut); 165202188Sed FTOU_PID(fu, ut); 166202188Sed break; 167202188Sed default: 168202188Sed ut->ut_type = EMPTY; 169202530Sed return (ut); 170202188Sed } 171202188Sed 172202188Sed FTOU_TYPE(fu, ut); 173202188Sed FTOU_TV(fu, ut); 174202530Sed return (ut); 175202188Sed} 176