1 1.3 riastrad /* $NetBSD: output_cdb.c,v 1.3 2023/08/08 10:35:21 riastradh Exp $ */ 2 1.1 joerg 3 1.1 joerg /*- 4 1.1 joerg * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 1.1 joerg * All rights reserved. 6 1.1 joerg * 7 1.1 joerg * This code is derived from software contributed to The NetBSD Foundation 8 1.1 joerg * by Joerg Sonnenberger. 9 1.1 joerg * 10 1.1 joerg * Redistribution and use in source and binary forms, with or without 11 1.1 joerg * modification, are permitted provided that the following conditions 12 1.1 joerg * are met: 13 1.1 joerg * 1. Redistributions of source code must retain the above copyright 14 1.1 joerg * notice, this list of conditions and the following disclaimer. 15 1.1 joerg * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 joerg * notice, this list of conditions and the following disclaimer in the 17 1.1 joerg * documentation and/or other materials provided with the distribution. 18 1.1 joerg * 19 1.1 joerg * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 joerg * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 joerg * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 joerg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 joerg * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 joerg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 joerg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 joerg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 joerg * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 joerg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 joerg * POSSIBILITY OF SUCH DAMAGE. 30 1.1 joerg */ 31 1.1 joerg 32 1.1 joerg 33 1.1 joerg #include <sys/endian.h> 34 1.1 joerg #include <cdbw.h> 35 1.1 joerg #include <err.h> 36 1.1 joerg #include <errno.h> 37 1.1 joerg #include <fcntl.h> 38 1.1 joerg #include <stdlib.h> 39 1.1 joerg #include <string.h> 40 1.1 joerg #include <stringlist.h> 41 1.1 joerg #include <unistd.h> 42 1.1 joerg 43 1.1 joerg #include "extern.h" 44 1.1 joerg 45 1.1 joerg static struct cdbw *cdbw; 46 1.1 joerg static int cdbw_fd = -1; 47 1.1 joerg 48 1.1 joerg int 49 1.1 joerg cdb_open(const char *tname) 50 1.1 joerg { 51 1.1 joerg 52 1.1 joerg if ((cdbw = cdbw_open()) == NULL) 53 1.1 joerg return -1; 54 1.1 joerg 55 1.1 joerg if ((cdbw_fd = open(tname, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) { 56 1.1 joerg cdbw_close(cdbw); 57 1.1 joerg cdbw = NULL; 58 1.1 joerg return -1; 59 1.1 joerg } 60 1.1 joerg return 0; 61 1.1 joerg } 62 1.1 joerg 63 1.1 joerg void 64 1.1 joerg cdb_add(StringList *sl, size_t port, const char *proto, size_t *cnt, 65 1.1 joerg int warndup) 66 1.1 joerg { 67 1.1 joerg uint8_t key[255 * 2 + 2]; 68 1.1 joerg uint8_t *data, *data_iter; 69 1.1 joerg size_t len, protolen, datalen, keylen; 70 1.1 joerg uint32_t idx; 71 1.1 joerg size_t i; 72 1.1 joerg 73 1.1 joerg protolen = strlen(proto); 74 1.1 joerg if (protolen == 0 || protolen > 255) 75 1.1 joerg errx(1, "Invalid protocol ``%s'', entry skipped", proto); 76 1.1 joerg 77 1.1 joerg datalen = 4 + protolen; 78 1.1 joerg for (i = 0; i < sl->sl_cur; ++i) { 79 1.1 joerg len = strlen(sl->sl_str[i]); 80 1.1 joerg if (len == 0 || len > 255) 81 1.1 joerg errx(1, "Service alias ``%s'' invalid", sl->sl_str[i]); 82 1.1 joerg datalen += len + 2; 83 1.1 joerg } 84 1.1 joerg 85 1.1 joerg data = malloc(datalen); 86 1.1 joerg if (data == NULL) 87 1.1 joerg err(1, "malloc failed"); 88 1.1 joerg be16enc(data, port); 89 1.1 joerg data[2] = protolen; 90 1.1 joerg data_iter = data + 3; 91 1.1 joerg memcpy(data_iter, proto, protolen + 1); 92 1.1 joerg data_iter += protolen + 1; 93 1.1 joerg for (i = 0; i < sl->sl_cur; ++i) { 94 1.1 joerg len = strlen(sl->sl_str[i]); 95 1.1 joerg *data_iter++ = len; 96 1.1 joerg memcpy(data_iter, sl->sl_str[i], len + 1); 97 1.1 joerg data_iter += len + 1; 98 1.1 joerg } 99 1.1 joerg 100 1.1 joerg if (cdbw_put_data(cdbw, data, datalen, &idx)) 101 1.1 joerg err(1, "cdbw_put_data failed"); 102 1.1 joerg 103 1.1 joerg free(data); 104 1.1 joerg 105 1.1 joerg key[0] = 0; 106 1.1 joerg key[1] = protolen; 107 1.1 joerg be16enc(key + 2, port); 108 1.1 joerg memcpy(key + 4, proto, protolen); 109 1.1 joerg keylen = 4 + protolen; 110 1.1 joerg if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) 111 1.1 joerg warnx("duplicate service: `%zu/%s'", port, proto); 112 1.1 joerg 113 1.1 joerg key[1] = 0; 114 1.1 joerg keylen = 4; 115 1.1 joerg if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) 116 1.1 joerg warnx("duplicate service: `%zu'", port); 117 1.1 joerg 118 1.1 joerg /* add references for service and all aliases */ 119 1.1 joerg for (i = 0; i < sl->sl_cur; i++) { 120 1.1 joerg len = strlen(sl->sl_str[i]); 121 1.1 joerg key[0] = len; 122 1.1 joerg key[1] = protolen; 123 1.1 joerg memcpy(key + 2, sl->sl_str[i], len); 124 1.1 joerg memcpy(key + 2 + len, proto, protolen); 125 1.1 joerg keylen = 2 + len + protolen; 126 1.1 joerg if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) 127 1.1 joerg warnx("duplicate service: `%s/%s'", sl->sl_str[i], proto); 128 1.1 joerg 129 1.1 joerg key[1] = 0; 130 1.1 joerg keylen = 2 + len; 131 1.1 joerg if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) 132 1.1 joerg warnx("duplicate service: `%s'", sl->sl_str[i]); 133 1.1 joerg } 134 1.1 joerg 135 1.1 joerg sl_free(sl, 1); 136 1.1 joerg } 137 1.1 joerg 138 1.1 joerg int 139 1.1 joerg cdb_close(void) 140 1.1 joerg { 141 1.1 joerg int rv, serrno; 142 1.1 joerg 143 1.1 joerg rv = 0; 144 1.1 joerg serrno = errno; 145 1.1 joerg 146 1.3 riastrad if (cdbw_output(cdbw, cdbw_fd, "services(5)", NULL)) { 147 1.1 joerg rv = -1; 148 1.1 joerg serrno = errno; 149 1.1 joerg } 150 1.1 joerg 151 1.1 joerg cdbw_close(cdbw); 152 1.1 joerg cdbw = NULL; 153 1.1 joerg 154 1.1 joerg if (close(cdbw_fd)) { 155 1.1 joerg if (rv == 0) 156 1.1 joerg serrno = errno; 157 1.1 joerg rv = -1; 158 1.1 joerg } 159 1.1 joerg cdbw_fd = -1; 160 1.1 joerg 161 1.1 joerg errno = serrno; 162 1.1 joerg return rv; 163 1.1 joerg } 164