diff --git a/src/kits/network/Jamfile b/src/kits/network/Jamfile index 0e7da44e9e..c82eb9ba94 100644 --- a/src/kits/network/Jamfile +++ b/src/kits/network/Jamfile @@ -2,6 +2,9 @@ SubDir HAIKU_TOP src kits network ; UsePrivateHeaders libroot net ; +AddFileDataResource libnetwork.so : CSTR:201:services : + [ FDirName $(SUBDIR) dns defaults services ] ; + SharedLibrary libnetwork.so : init.cpp interfaces.cpp diff --git a/src/kits/network/dns/Jamfile b/src/kits/network/dns/Jamfile index 0febb0f0c2..d992a98196 100644 --- a/src/kits/network/dns/Jamfile +++ b/src/kits/network/dns/Jamfile @@ -24,7 +24,6 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) resolv ] ; SubDirC++Flags $(defines) ; } - MergeObject dns_dst.o : dst_api.c hmac_link.c @@ -89,7 +88,7 @@ MergeObject dns_irs.o : lcl_ng.c lcl_nw.c lcl_pr.c - lcl_sv.c + lcl_sv.cpp nis.c nul_ng.c util.c diff --git a/src/kits/network/dns/defaults/services b/src/kits/network/dns/defaults/services new file mode 100644 index 0000000000..6a8cf5e480 --- /dev/null +++ b/src/kits/network/dns/defaults/services @@ -0,0 +1,47 @@ +# Copyright 2006, Haiku, Inc. All Rights Reserved. +# Licensed under the terms of the MIT license. +# +# This file only includes ports in the well known port range, and +# is also not complete - it only includes commonly used ports +# See RFC 1700 for a full list. +# +tcpmux 1/tcp +echo 7/tcp +echo 7/udp +discard 9/tcp sink null +discard 9/udp sink null +daytime 13/tcp +daytime 13/udp +ftp-data 20/tcp +ftp 21/tcp +ssh 22/tcp +telnet 23/tcp +smtp 25/tcp mail +time 37/tcp timserver +time 37/udp timserver +name 42/udp nameserver +whois 43/tcp nicname +domain 53/tcp +domain 53/udp +bootps 67/udp dhcps +bootpc 68/udp dhcpc +tftp 69/udp +finger 79/tcp +http 80/tcp www www-http +kerberos 88/tcp kdc +kerberos 88/udp kdc +pop3 110/tcp +nntp 119/tcp +ntp 123/tcp +ntp 123/udp +netbios-ns 137/tcp +netbios-ns 137/udp +netbios-dgm 138/tcp +netbios-dgm 138/udp +netbios-ssn 139/tcp +netbios-ssn 139/udp +imap 143/tcp imap2 imap4 +irc 194/tcp +ldap 389/tcp +ldap 389/udp +https 443/tcp diff --git a/src/kits/network/dns/headers/irs.h b/src/kits/network/dns/headers/irs.h index 86b49bd3f7..4242953d18 100644 --- a/src/kits/network/dns/headers/irs.h +++ b/src/kits/network/dns/headers/irs.h @@ -14,11 +14,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/* - * $Id$ - */ - #ifndef _IRS_H_INCLUDED #define _IRS_H_INCLUDED @@ -31,6 +26,11 @@ #include #include +#ifdef __cplusplus +extern "C" { +# define private private_data +#endif + /* * This is the group map class. */ @@ -342,4 +342,9 @@ extern struct servent *getservbyport_p __P((int, const char *, extern void setservent_p __P((int, struct net_data *)); extern void endservent_p __P((struct net_data *)); +#ifdef __cplusplus +# undef private +} +#endif + #endif /*_IRS_H_INCLUDED*/ diff --git a/src/kits/network/dns/headers/isc/memcluster.h b/src/kits/network/dns/headers/isc/memcluster.h index 11e1fa381d..2cceb3626e 100644 --- a/src/kits/network/dns/headers/isc/memcluster.h +++ b/src/kits/network/dns/headers/isc/memcluster.h @@ -36,6 +36,10 @@ #define memstats __memstats #define memactive __memactive +#ifdef __cplusplus +extern "C" { +#endif + int meminit(size_t, size_t); void * __memget(size_t); void __memput(void *, size_t); @@ -46,4 +50,8 @@ void __memput_record(void *, size_t, const char *, int); void memstats(FILE *); int memactive(void); +#ifdef __cplusplus +} +#endif + #endif /* MEMCLUSTER_H */ diff --git a/src/kits/network/dns/irs/irs_p.h b/src/kits/network/dns/irs/irs_p.h index d380b0f688..7b83b82831 100644 --- a/src/kits/network/dns/irs/irs_p.h +++ b/src/kits/network/dns/irs/irs_p.h @@ -14,36 +14,30 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/* - * $Id$ - */ - #ifndef _IRS_P_H_INCLUDED #define _IRS_P_H_INCLUDED -#include #include "pathnames.h" -#define IRS_SV_MAXALIASES 35 +#include -struct lcl_sv { - FILE * fp; - char line[BUFSIZ+1]; - struct servent serv; - char * serv_aliases[IRS_SV_MAXALIASES]; -}; + +#ifdef __cplusplus +extern "C" { +#endif #define irs_nul_ng __irs_nul_ng #define map_v4v6_address __map_v4v6_address #define make_group_list __make_group_list -#define irs_lclsv_fnxt __irs_lclsv_fnxt extern void map_v4v6_address(const char *src, char *dst); extern int make_group_list(struct irs_gr *, const char *, gid_t, gid_t *, int *); extern struct irs_ng * irs_nul_ng(struct irs_acc *); -extern struct servent * irs_lclsv_fnxt(struct lcl_sv *); +#ifdef __cplusplus +} #endif + +#endif /* _IRS_P_H_INCLUDED */ diff --git a/src/kits/network/dns/irs/lcl_p.h b/src/kits/network/dns/irs/lcl_p.h index c7b05d966a..b3d7f79d0d 100644 --- a/src/kits/network/dns/irs/lcl_p.h +++ b/src/kits/network/dns/irs/lcl_p.h @@ -14,30 +14,33 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _LCL_P_H_INCLUDED +#define _LCL_P_H_INCLUDED -/* - * $Id$ - */ /* * lcl_p.h - private include file for the local accessor functions. */ -#ifndef _LCL_P_H_INCLUDED -#define _LCL_P_H_INCLUDED +#include + /* * Object state. */ struct lcl_p { struct __res_state * res; - void (*free_res) __P((void *)); + void (*free_res)(void *); }; /* * Externs. */ +#ifdef __cplusplus +extern "C" { +#endif + extern struct irs_acc * irs_lcl_acc __P((const char *)); extern struct irs_gr * irs_lcl_gr __P((struct irs_acc *)); extern struct irs_pw * irs_lcl_pw __P((struct irs_acc *)); @@ -47,4 +50,8 @@ extern struct irs_ho * irs_lcl_ho __P((struct irs_acc *)); extern struct irs_nw * irs_lcl_nw __P((struct irs_acc *)); extern struct irs_ng * irs_lcl_ng __P((struct irs_acc *)); +#ifdef __cplusplus +} +#endif + #endif /*_LCL_P_H_INCLUDED*/ diff --git a/src/kits/network/dns/irs/lcl_sv.c b/src/kits/network/dns/irs/lcl_sv.c deleted file mode 100644 index 8586de984e..0000000000 --- a/src/kits/network/dns/irs/lcl_sv.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 1989, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; -#endif /* LIBC_SCCS and not lint */ - -/* extern */ - -#include "port_before.h" - -#include -#include -#include -#include -#include - -#ifdef IRS_LCL_SV_DB -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "port_after.h" - -#include "irs_p.h" -#include "lcl_p.h" - -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif - -/* Types */ - -struct pvt { -#ifdef IRS_LCL_SV_DB - DB * dbh; - int dbf; -#endif - struct lcl_sv sv; -}; - -/* Forward */ - -static void sv_close(struct irs_sv*); -static struct servent * sv_next(struct irs_sv *); -static struct servent * sv_byname(struct irs_sv *, const char *, - const char *); -static struct servent * sv_byport(struct irs_sv *, int, const char *); -static void sv_rewind(struct irs_sv *); -static void sv_minimize(struct irs_sv *); -/*global*/ struct servent * irs_lclsv_fnxt(struct lcl_sv *); -#ifdef IRS_LCL_SV_DB -static struct servent * sv_db_rec(struct lcl_sv *, DBT *, DBT *); -#endif - -/* Portability */ - -#ifndef SEEK_SET -# define SEEK_SET 0 -#endif - -/* Public */ - -struct irs_sv * -irs_lcl_sv(struct irs_acc *this) { - struct irs_sv *sv; - struct pvt *pvt; - - UNUSED(this); - - if ((sv = memget(sizeof *sv)) == NULL) { - errno = ENOMEM; - return (NULL); - } - memset(sv, 0x5e, sizeof *sv); - if ((pvt = memget(sizeof *pvt)) == NULL) { - memput(sv, sizeof *sv); - errno = ENOMEM; - return (NULL); - } - memset(pvt, 0, sizeof *pvt); - sv->private = pvt; - sv->close = sv_close; - sv->next = sv_next; - sv->byname = sv_byname; - sv->byport = sv_byport; - sv->rewind = sv_rewind; - sv->minimize = sv_minimize; - sv->res_get = NULL; - sv->res_set = NULL; -#ifdef IRS_LCL_SV_DB - pvt->dbf = R_FIRST; -#endif - return (sv); -} - -/* Methods */ - -static void -sv_close(struct irs_sv *this) { - struct pvt *pvt = (struct pvt *)this->private; - -#ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) - (*pvt->dbh->close)(pvt->dbh); -#endif - if (pvt->sv.fp) - fclose(pvt->sv.fp); - memput(pvt, sizeof *pvt); - memput(this, sizeof *this); -} - -static struct servent * -sv_byname(struct irs_sv *this, const char *name, const char *proto) { -#ifdef IRS_LCL_SV_DB - struct pvt *pvt = (struct pvt *)this->private; -#endif - struct servent *p; - char **cp; - - sv_rewind(this); -#ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) { - DBT key, data; - - /* Note that (sizeof "/") == 2. */ - if ((strlen(name) + sizeof "/" + proto ? strlen(proto) : 0) - > sizeof pvt->sv.line) - goto try_local; - key.data = pvt->sv.line; - key.size = SPRINTF((pvt->sv.line, "%s/%s", name, - proto ? proto : "")) + 1; - if (proto != NULL) { - if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0) - return (NULL); - } else if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR) - != 0) - return (NULL); - return (sv_db_rec(&pvt->sv, &key, &data)); - } - try_local: -#endif - - while ((p = sv_next(this))) { - if (strcmp(name, p->s_name) == 0) - goto gotname; - for (cp = p->s_aliases; *cp; cp++) - if (strcmp(name, *cp) == 0) - goto gotname; - continue; - gotname: - if (proto == NULL || strcmp(p->s_proto, proto) == 0) - break; - } - return (p); -} - -static struct servent * -sv_byport(struct irs_sv *this, int port, const char *proto) { -#ifdef IRS_LCL_SV_DB - struct pvt *pvt = (struct pvt *)this->private; -#endif - struct servent *p; - - sv_rewind(this); -#ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) { - DBT key, data; - u_short *ports; - - ports = (u_short *)pvt->sv.line; - ports[0] = 0; - ports[1] = port; - key.data = ports; - key.size = sizeof(u_short) * 2; - if (proto && *proto) { - strncpy((char *)ports + key.size, proto, - BUFSIZ - key.size); - key.size += strlen((char *)ports + key.size) + 1; - if ((*pvt->dbh->get)(pvt->dbh, &key, &data, 0) != 0) - return (NULL); - } else { - if ((*pvt->dbh->seq)(pvt->dbh, &key, &data, R_CURSOR) - != 0) - return (NULL); - } - return (sv_db_rec(&pvt->sv, &key, &data)); - } -#endif - while ((p = sv_next(this))) { - if (p->s_port != port) - continue; - if (proto == NULL || strcmp(p->s_proto, proto) == 0) - break; - } - return (p); -} - -static void -sv_rewind(struct irs_sv *this) { - struct pvt *pvt = (struct pvt *)this->private; - - if (pvt->sv.fp) { - if (fseek(pvt->sv.fp, 0L, SEEK_SET) == 0) - return; - (void)fclose(pvt->sv.fp); - pvt->sv.fp = NULL; - } -#ifdef IRS_LCL_SV_DB - pvt->dbf = R_FIRST; - if (pvt->dbh != NULL) - return; - pvt->dbh = dbopen(_PATH_SERVICES_DB, O_RDONLY,O_RDONLY,DB_BTREE, NULL); - if (pvt->dbh != NULL) { - if (fcntl((*pvt->dbh->fd)(pvt->dbh), F_SETFD, 1) < 0) { - (*pvt->dbh->close)(pvt->dbh); - pvt->dbh = NULL; - } - return; - } -#endif - if ((pvt->sv.fp = fopen(_PATH_SERVICES, "r")) == NULL) - return; - if (fcntl(fileno(pvt->sv.fp), F_SETFD, 1) < 0) { - (void)fclose(pvt->sv.fp); - pvt->sv.fp = NULL; - } -} - -static struct servent * -sv_next(struct irs_sv *this) { - struct pvt *pvt = (struct pvt *)this->private; - -#ifdef IRS_LCL_SV_DB - if (pvt->dbh == NULL && pvt->sv.fp == NULL) -#else - if (pvt->sv.fp == NULL) -#endif - sv_rewind(this); - -#ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) { - DBT key, data; - - while ((*pvt->dbh->seq)(pvt->dbh, &key, &data, pvt->dbf) == 0){ - pvt->dbf = R_NEXT; - if (((char *)key.data)[0]) - continue; - return (sv_db_rec(&pvt->sv, &key, &data)); - } - } -#endif - - if (pvt->sv.fp == NULL) - return (NULL); - return (irs_lclsv_fnxt(&pvt->sv)); -} - -static void -sv_minimize(struct irs_sv *this) { - struct pvt *pvt = (struct pvt *)this->private; - -#ifdef IRS_LCL_SV_DB - if (pvt->dbh != NULL) { - (*pvt->dbh->close)(pvt->dbh); - pvt->dbh = NULL; - } -#endif - if (pvt->sv.fp != NULL) { - (void)fclose(pvt->sv.fp); - pvt->sv.fp = NULL; - } -} - -/* Quasipublic. */ - -struct servent * -irs_lclsv_fnxt(struct lcl_sv *sv) { - char *p, *cp, **q; - - again: - if ((p = fgets(sv->line, BUFSIZ, sv->fp)) == NULL) - return (NULL); - if (*p == '#') - goto again; - sv->serv.s_name = p; - while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') - ++p; - if (*p == '\0' || *p == '#' || *p == '\n') - goto again; - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - p++; - if (*p == '\0' || *p == '#' || *p == '\n') - goto again; - sv->serv.s_port = htons((u_short)strtol(p, &cp, 10)); - if (cp == p || (*cp != '/' && *cp != ',')) - goto again; - p = cp + 1; - sv->serv.s_proto = p; - - q = sv->serv.s_aliases = sv->serv_aliases; - - while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') - ++p; - - while (*p == ' ' || *p == '\t') { - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - ++p; - if (*p == '\0' || *p == '#' || *p == '\n') - break; - if (q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1]) - *q++ = p; - while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') - ++p; - } - - *p = '\0'; - *q = NULL; - return (&sv->serv); -} - -/* Private. */ - -#ifdef IRS_LCL_SV_DB -static struct servent * -sv_db_rec(struct lcl_sv *sv, DBT *key, DBT *data) { - char *p, **q; - int n; - - p = data->data; - p[data->size - 1] = '\0'; /* should be, but we depend on it */ - - if (((char *)key->data)[0] == '\0') { - if (key->size < sizeof(u_short)*2 || data->size < 2) - return (NULL); - sv->serv.s_port = ((u_short *)key->data)[1]; - n = strlen(p) + 1; - if ((size_t)n > sizeof(sv->line)) { - n = sizeof(sv->line); - } - memcpy(sv->line, p, n); - sv->serv.s_name = sv->line; - if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL) - *(sv->serv.s_proto)++ = '\0'; - p += n; - data->size -= n; - } else { - if (data->size < sizeof(u_short) + 1) - return (NULL); - if (key->size > sizeof(sv->line)) - key->size = sizeof(sv->line); - ((char *)key->data)[key->size - 1] = '\0'; - memcpy(sv->line, key->data, key->size); - sv->serv.s_name = sv->line; - if ((sv->serv.s_proto = strchr(sv->line, '/')) != NULL) - *(sv->serv.s_proto)++ = '\0'; - sv->serv.s_port = *(u_short *)data->data; - p += sizeof(u_short); - data->size -= sizeof(u_short); - } - q = sv->serv.s_aliases = sv->serv_aliases; - while (data->size > 0 && q < &sv->serv_aliases[IRS_SV_MAXALIASES - 1]) { - - *q++ = p; - n = strlen(p) + 1; - data->size -= n; - p += n; - } - *q = NULL; - return (&sv->serv); -} -#endif diff --git a/src/kits/network/dns/irs/lcl_sv.cpp b/src/kits/network/dns/irs/lcl_sv.cpp new file mode 100644 index 0000000000..dc25f36986 --- /dev/null +++ b/src/kits/network/dns/irs/lcl_sv.cpp @@ -0,0 +1,355 @@ +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + +/* + * Copyright (c) 1989, 1993, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "port_before.h" + +#include "irs_p.h" +#include "lcl_p.h" + +#include + +#include "port_after.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#define IRS_SV_MAXALIASES 35 + +struct service_private { + FILE* file; + char line[BUFSIZ+1]; + char* resource_file; + char* resource_end; + char* resource_line; + struct servent servent; + char* aliases[IRS_SV_MAXALIASES]; +}; + + +static status_t +find_own_image(image_info* _info) +{ + int32 cookie = 0; + image_info info; + while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { + if (((uint32)info.text <= (uint32)find_own_image + && (uint32)info.text + (uint32)info.text_size > (uint32)find_own_image)) { + // found us + *_info = info; + return B_OK; + } + } + + return B_ENTRY_NOT_FOUND; +} + + +char * +get_next_line(struct service_private* service) +{ + if (service->file != NULL) + return fgets(service->line, BUFSIZ, service->file); + if (service->resource_file == NULL) + return NULL; + + char* line = service->resource_line; + while (line < service->resource_end + && line[0] + && line[0] != '\n') + line++; + + if (service->resource_line >= service->resource_end + || service->resource_line == line) + return NULL; + + strlcpy(service->line, service->resource_line, + min_c(line + 1 - service->resource_line, BUFSIZ)); + service->resource_line = line + 1; + + return service->line; +} + + +// #pragma mark - + + +static void +sv_close(struct irs_sv *sv) +{ + struct service_private *service = (struct service_private *)sv->private_data; + + if (service->file) + fclose(service->file); + + free(service->resource_file); + memput(service, sizeof *service); + memput(sv, sizeof *sv); +} + + +static void +sv_rewind(struct irs_sv *sv) +{ + struct service_private *service = (struct service_private *)sv->private_data; + + if (service->file) { + if (fseek(service->file, 0L, SEEK_SET) == 0) + return; + fclose(service->file); + service->file = NULL; + } + + if ((service->file = fopen(_PATH_SERVICES, "r")) != NULL) { + if (fcntl(fileno(service->file), F_SETFD, 1) == 0) + return; + + fclose(service->file); + service->file = NULL; + } + + // opening the standard file has file has failed, use resources + + if (service->resource_file != NULL) { + service->resource_line = service->resource_file; + return; + } + + image_info info; + if (find_own_image(&info) < B_OK) + return; + + BFile file; + if (file.SetTo(info.name, B_READ_ONLY) < B_OK) + return; + + BResources resources(&file); + if (resources.InitCheck() < B_OK) + return; + + size_t size; + const void* data = resources.LoadResource(B_STRING_TYPE, "services", &size); + if (data == NULL) + return; + + service->resource_file = (char *)malloc(size); + if (service->resource_file == NULL) + return; + + memcpy(service->resource_file, data, size); + service->resource_line = service->resource_file; + service->resource_end = service->resource_file + size; +} + + +static struct servent * +sv_next(struct irs_sv *sv) +{ + struct service_private *service = (struct service_private *)sv->private_data; + char *p, *cp, **q; + + if (service->file == NULL && service->resource_file == NULL) + sv_rewind(sv); + + if (service->file == NULL && service->resource_file == NULL) + return NULL; + +again: + if ((p = get_next_line(service)) == NULL) + return NULL; + + if (*p == '#') + goto again; + + service->servent.s_name = p; + while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') + ++p; + if (*p == '\0' || *p == '#' || *p == '\n') + goto again; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + if (*p == '\0' || *p == '#' || *p == '\n') + goto again; + service->servent.s_port = htons((u_short)strtol(p, &cp, 10)); + if (cp == p || (*cp != '/' && *cp != ',')) + goto again; + p = cp + 1; + service->servent.s_proto = p; + + q = service->servent.s_aliases = service->aliases; + + while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') + ++p; + + while (*p == ' ' || *p == '\t') { + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + ++p; + if (*p == '\0' || *p == '#' || *p == '\n') + break; + if (q < &service->aliases[IRS_SV_MAXALIASES - 1]) + *q++ = p; + while (*p && *p != '\n' && *p != ' ' && *p != '\t' && *p != '#') + ++p; + } + + *p = '\0'; + *q = NULL; + return &service->servent; +} + + +static struct servent * +sv_byname(struct irs_sv *sv, const char *name, const char *protocol) +{ + struct servent *servent; + + sv_rewind(sv); + + while ((servent = sv_next(sv))) { + char **alias; + + if (!strcmp(name, servent->s_name)) + goto gotname; + for (alias = servent->s_aliases; *alias; alias++) { + if (!strcmp(name, *alias)) + goto gotname; + } + continue; +gotname: + if (protocol == NULL || strcmp(servent->s_proto, protocol) == 0) + break; + } + return servent; +} + + +static struct servent * +sv_byport(struct irs_sv *sv, int port, const char *protocol) +{ + struct servent *servent; + + sv_rewind(sv); + while ((servent = sv_next(sv))) { + if (servent->s_port != port) + continue; + if (protocol == NULL || strcmp(servent->s_proto, protocol) == 0) + break; + } + return servent; +} + + +static void +sv_minimize(struct irs_sv *sv) +{ + struct service_private *service = (struct service_private *)sv->private_data; + + if (service->file != NULL) { + fclose(service->file); + service->file = NULL; + } +} + + +// #pragma mark - + + +extern "C" struct irs_sv * +irs_lcl_sv(struct irs_acc */*acc*/) +{ + struct service_private *service; + struct irs_sv *sv; + + if ((sv = (irs_sv *)memget(sizeof *sv)) == NULL) { + errno = ENOMEM; + return NULL; + } + if ((service = (service_private *)memget(sizeof *service)) == NULL) { + memput(sv, sizeof *sv); + errno = ENOMEM; + return NULL; + } + + memset(service, 0, sizeof *service); + + sv->private_data = service; + sv->close = sv_close; + sv->next = sv_next; + sv->byname = sv_byname; + sv->byport = sv_byport; + sv->rewind = sv_rewind; + sv->minimize = sv_minimize; + sv->res_get = NULL; + sv->res_set = NULL; + + return sv; +}