1c39934eaSBrian Somers /*- 2*1de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*1de7b4b8SPedro F. Giffuni * 4c39934eaSBrian Somers * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 5c39934eaSBrian Somers * All rights reserved. 6c39934eaSBrian Somers * 7c39934eaSBrian Somers * Redistribution and use in source and binary forms, with or without 8c39934eaSBrian Somers * modification, are permitted provided that the following conditions 9c39934eaSBrian Somers * are met: 10c39934eaSBrian Somers * 1. Redistributions of source code must retain the above copyright 11c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer. 12c39934eaSBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 13c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer in the 14c39934eaSBrian Somers * documentation and/or other materials provided with the distribution. 15c39934eaSBrian Somers * 16c39934eaSBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17c39934eaSBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c39934eaSBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c39934eaSBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20c39934eaSBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21c39934eaSBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22c39934eaSBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23c39934eaSBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24c39934eaSBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25c39934eaSBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26c39934eaSBrian Somers * SUCH DAMAGE. 27c39934eaSBrian Somers * 2897d92980SPeter Wemm * $FreeBSD$ 2975240ed1SBrian Somers */ 3075240ed1SBrian Somers 3174457d3dSBrian Somers #include <sys/param.h> 3274457d3dSBrian Somers 334ef16f24SBrian Somers #include <sys/socket.h> 344ef16f24SBrian Somers #include <netinet/in.h> 351fa665f5SBrian Somers #include <sys/un.h> 3675240ed1SBrian Somers 374ef16f24SBrian Somers #include <errno.h> 386eafd353SBrian Somers #include <stdarg.h> 3975240ed1SBrian Somers #include <stdio.h> 4075240ed1SBrian Somers #include <string.h> 4175240ed1SBrian Somers #include <sys/stat.h> 4285b542cfSBrian Somers #include <termios.h> 434ef16f24SBrian Somers #include <unistd.h> 4475240ed1SBrian Somers 454ef16f24SBrian Somers #include "log.h" 4677ff88adSBrian Somers #include "descriptor.h" 474ef16f24SBrian Somers #include "server.h" 4885b542cfSBrian Somers #include "prompt.h" 4930949fd4SBrian Somers #include "ncpaddr.h" 501a2b4e4aSBrian Somers #include "probe.h" 514ef16f24SBrian Somers 5277ff88adSBrian Somers static int 53f013f33eSBrian Somers server_UpdateSet(struct fdescriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) 5477ff88adSBrian Somers { 5577ff88adSBrian Somers struct server *s = descriptor2server(d); 560f2f3eb3SBrian Somers struct prompt *p; 570f2f3eb3SBrian Somers int sets; 5875240ed1SBrian Somers 590f2f3eb3SBrian Somers sets = 0; 60b6dec9f0SBrian Somers if (r && s->fd >= 0) { 6177ff88adSBrian Somers if (*n < s->fd + 1) 6277ff88adSBrian Somers *n = s->fd + 1; 6385b542cfSBrian Somers FD_SET(s->fd, r); 6424989c68SBrian Somers log_Printf(LogTIMER, "server: fdset(r) %d\n", s->fd); 650f2f3eb3SBrian Somers sets++; 6677ff88adSBrian Somers } 670f2f3eb3SBrian Somers 680f2f3eb3SBrian Somers for (p = log_PromptList(); p; p = p->next) 690f2f3eb3SBrian Somers sets += descriptor_UpdateSet(&p->desc, r, w, e, n); 700f2f3eb3SBrian Somers 710f2f3eb3SBrian Somers return sets; 7277ff88adSBrian Somers } 7377ff88adSBrian Somers 7477ff88adSBrian Somers static int 75f013f33eSBrian Somers server_IsSet(struct fdescriptor *d, const fd_set *fdset) 7677ff88adSBrian Somers { 7777ff88adSBrian Somers struct server *s = descriptor2server(d); 780f2f3eb3SBrian Somers struct prompt *p; 790f2f3eb3SBrian Somers 800f2f3eb3SBrian Somers if (s->fd >= 0 && FD_ISSET(s->fd, fdset)) 810f2f3eb3SBrian Somers return 1; 820f2f3eb3SBrian Somers 830f2f3eb3SBrian Somers for (p = log_PromptList(); p; p = p->next) 840f2f3eb3SBrian Somers if (descriptor_IsSet(&p->desc, fdset)) 850f2f3eb3SBrian Somers return 1; 860f2f3eb3SBrian Somers 870f2f3eb3SBrian Somers return 0; 8877ff88adSBrian Somers } 8977ff88adSBrian Somers 9077ff88adSBrian Somers static void 91f013f33eSBrian Somers server_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset) 9277ff88adSBrian Somers { 9377ff88adSBrian Somers struct server *s = descriptor2server(d); 9430949fd4SBrian Somers struct sockaddr_storage ss; 9530949fd4SBrian Somers struct sockaddr *sa = (struct sockaddr *)&ss; 9630949fd4SBrian Somers struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 9730949fd4SBrian Somers #ifndef NOINET6 9830949fd4SBrian Somers struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 9930949fd4SBrian Somers #endif 10030949fd4SBrian Somers int ssize = sizeof ss, wfd; 101b6217683SBrian Somers struct prompt *p; 10230949fd4SBrian Somers struct ncpaddr addr; 10377ff88adSBrian Somers 1040f2f3eb3SBrian Somers if (s->fd >= 0 && FD_ISSET(s->fd, fdset)) { 10577ff88adSBrian Somers wfd = accept(s->fd, sa, &ssize); 1060f2f3eb3SBrian Somers if (wfd < 0) 107dd7e2610SBrian Somers log_Printf(LogERROR, "server_Read: accept(): %s\n", strerror(errno)); 1086d110b1bSBrian Somers else if (sa->sa_len == 0) { 1096d110b1bSBrian Somers close(wfd); 1106d110b1bSBrian Somers wfd = -1; 1116d110b1bSBrian Somers } 1120f2f3eb3SBrian Somers } else 1130f2f3eb3SBrian Somers wfd = -1; 11477ff88adSBrian Somers 1150f2f3eb3SBrian Somers if (wfd >= 0) 11677ff88adSBrian Somers switch (sa->sa_family) { 11777ff88adSBrian Somers case AF_LOCAL: 118dd7e2610SBrian Somers log_Printf(LogPHASE, "Connected to local client.\n"); 11977ff88adSBrian Somers break; 12077ff88adSBrian Somers 12177ff88adSBrian Somers case AF_INET: 12230949fd4SBrian Somers ncpaddr_setsa(&addr, sa); 12330949fd4SBrian Somers if (ntohs(sin->sin_port) < 1024) { 124dd7e2610SBrian Somers log_Printf(LogALERT, "Rejected client connection from %s:%u" 12577ff88adSBrian Somers "(invalid port number) !\n", 12630949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin->sin_port)); 12777ff88adSBrian Somers close(wfd); 1280f2f3eb3SBrian Somers wfd = -1; 1290f2f3eb3SBrian Somers break; 13077ff88adSBrian Somers } 131dd7e2610SBrian Somers log_Printf(LogPHASE, "Connected to client from %s:%u\n", 13230949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin->sin_port)); 13377ff88adSBrian Somers break; 13477ff88adSBrian Somers 13530949fd4SBrian Somers #ifndef NOINET6 13630949fd4SBrian Somers case AF_INET6: 13730949fd4SBrian Somers ncpaddr_setsa(&addr, sa); 13830949fd4SBrian Somers if (ntohs(sin6->sin6_port) < 1024) { 13930949fd4SBrian Somers log_Printf(LogALERT, "Rejected client connection from %s:%u" 14030949fd4SBrian Somers "(invalid port number) !\n", 14130949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin6->sin6_port)); 14230949fd4SBrian Somers close(wfd); 14330949fd4SBrian Somers wfd = -1; 14430949fd4SBrian Somers break; 14530949fd4SBrian Somers } 14630949fd4SBrian Somers log_Printf(LogPHASE, "Connected to client from %s:%u\n", 14730949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin6->sin6_port)); 14830949fd4SBrian Somers break; 14930949fd4SBrian Somers #endif 15030949fd4SBrian Somers 15177ff88adSBrian Somers default: 15277ff88adSBrian Somers write(wfd, "Unrecognised access !\n", 22); 15377ff88adSBrian Somers close(wfd); 1540f2f3eb3SBrian Somers wfd = -1; 1550f2f3eb3SBrian Somers break; 15677ff88adSBrian Somers } 15777ff88adSBrian Somers 1580f2f3eb3SBrian Somers if (wfd >= 0) { 159b6217683SBrian Somers if ((p = prompt_Create(s, bundle, wfd)) == NULL) { 160b6217683SBrian Somers write(wfd, "Connection refused.\n", 20); 16177ff88adSBrian Somers close(wfd); 16277ff88adSBrian Somers } else { 163b6217683SBrian Somers switch (sa->sa_family) { 164b6217683SBrian Somers case AF_LOCAL: 165565e35e5SBrian Somers p->src.type = "local"; 16674457d3dSBrian Somers strncpy(p->src.from, s->cfg.sockname, sizeof p->src.from - 1); 167565e35e5SBrian Somers p->src.from[sizeof p->src.from - 1] = '\0'; 168b6217683SBrian Somers break; 169b6217683SBrian Somers case AF_INET: 17030949fd4SBrian Somers p->src.type = "ip"; 171565e35e5SBrian Somers snprintf(p->src.from, sizeof p->src.from, "%s:%u", 17230949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin->sin_port)); 173b6217683SBrian Somers break; 17430949fd4SBrian Somers #ifndef NOINET6 17530949fd4SBrian Somers case AF_INET6: 17630949fd4SBrian Somers p->src.type = "ip6"; 17730949fd4SBrian Somers snprintf(p->src.from, sizeof p->src.from, "%s:%u", 17830949fd4SBrian Somers ncpaddr_ntoa(&addr), ntohs(sin6->sin6_port)); 17930949fd4SBrian Somers break; 18030949fd4SBrian Somers #endif 181b6217683SBrian Somers } 182b6217683SBrian Somers prompt_TtyCommandMode(p); 183b6217683SBrian Somers prompt_Required(p); 18477ff88adSBrian Somers } 18577ff88adSBrian Somers } 18677ff88adSBrian Somers 1870bdcbcbeSBrian Somers log_PromptListChanged = 0; 1880f2f3eb3SBrian Somers for (p = log_PromptList(); p; p = p->next) 1890bdcbcbeSBrian Somers if (descriptor_IsSet(&p->desc, fdset)) { 1900f2f3eb3SBrian Somers descriptor_Read(&p->desc, bundle, fdset); 1910bdcbcbeSBrian Somers if (log_PromptListChanged) 1920bdcbcbeSBrian Somers break; 1930bdcbcbeSBrian Somers } 1940f2f3eb3SBrian Somers } 1950f2f3eb3SBrian Somers 1961af29a6eSBrian Somers static int 197057f1760SBrian Somers server_Write(struct fdescriptor *d __unused, struct bundle *bundle __unused, 198057f1760SBrian Somers const fd_set *fdset __unused) 19977ff88adSBrian Somers { 20077ff88adSBrian Somers /* We never want to write here ! */ 201a33b2ef7SBrian Somers log_Printf(LogALERT, "server_Write: Internal error: Bad call !\n"); 2021af29a6eSBrian Somers return 0; 20377ff88adSBrian Somers } 20477ff88adSBrian Somers 20577ff88adSBrian Somers struct server server = { 20677ff88adSBrian Somers { 20777ff88adSBrian Somers SERVER_DESCRIPTOR, 20877ff88adSBrian Somers server_UpdateSet, 20977ff88adSBrian Somers server_IsSet, 21077ff88adSBrian Somers server_Read, 21177ff88adSBrian Somers server_Write 21277ff88adSBrian Somers }, 213057f1760SBrian Somers -1, 214057f1760SBrian Somers { "", "", 0, 0 } 21577ff88adSBrian Somers }; 2164ef16f24SBrian Somers 21774457d3dSBrian Somers enum server_stat 21874457d3dSBrian Somers server_Reopen(struct bundle *bundle) 21974457d3dSBrian Somers { 22074457d3dSBrian Somers char name[sizeof server.cfg.sockname]; 22137b8a5c7SBrian Somers struct stat st; 22274457d3dSBrian Somers u_short port; 22374457d3dSBrian Somers mode_t mask; 22474457d3dSBrian Somers enum server_stat ret; 22574457d3dSBrian Somers 22674457d3dSBrian Somers if (server.cfg.sockname[0] != '\0') { 22774457d3dSBrian Somers strcpy(name, server.cfg.sockname); 22874457d3dSBrian Somers mask = server.cfg.mask; 22974457d3dSBrian Somers server_Close(bundle); 23037b8a5c7SBrian Somers if (server.cfg.sockname[0] != '\0' && stat(server.cfg.sockname, &st) == 0) 23137b8a5c7SBrian Somers if (!(st.st_mode & S_IFSOCK) || unlink(server.cfg.sockname) != 0) 23237b8a5c7SBrian Somers return SERVER_FAILED; 23374457d3dSBrian Somers ret = server_LocalOpen(bundle, name, mask); 23474457d3dSBrian Somers } else if (server.cfg.port != 0) { 23574457d3dSBrian Somers port = server.cfg.port; 23674457d3dSBrian Somers server_Close(bundle); 23774457d3dSBrian Somers ret = server_TcpOpen(bundle, port); 23874457d3dSBrian Somers } else 23974457d3dSBrian Somers ret = SERVER_UNSET; 24074457d3dSBrian Somers 24174457d3dSBrian Somers return ret; 24274457d3dSBrian Somers } 24374457d3dSBrian Somers 24474457d3dSBrian Somers enum server_stat 245dd7e2610SBrian Somers server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask) 2464ef16f24SBrian Somers { 24774457d3dSBrian Somers struct sockaddr_un ifsun; 24874457d3dSBrian Somers mode_t oldmask; 2494ef16f24SBrian Somers int s; 2504ef16f24SBrian Somers 25174457d3dSBrian Somers oldmask = (mode_t)-1; /* Silence compiler */ 252683cef3cSBrian Somers 2539304cfd0SDimitry Andric if (server.cfg.sockname[0] != '\0' && !strcmp(server.cfg.sockname, name)) 25474457d3dSBrian Somers server_Close(bundle); 25574457d3dSBrian Somers 25674457d3dSBrian Somers memset(&ifsun, '\0', sizeof ifsun); 25774457d3dSBrian Somers ifsun.sun_len = strlen(name); 25874457d3dSBrian Somers if (ifsun.sun_len > sizeof ifsun.sun_path - 1) { 259dd7e2610SBrian Somers log_Printf(LogERROR, "Local: %s: Path too long\n", name); 26074457d3dSBrian Somers return SERVER_INVALID; 2614ef16f24SBrian Somers } 26274457d3dSBrian Somers ifsun.sun_family = AF_LOCAL; 26374457d3dSBrian Somers strcpy(ifsun.sun_path, name); 2644ef16f24SBrian Somers 26563c6cac9SBrian Somers s = socket(PF_LOCAL, SOCK_STREAM, 0); 2664ef16f24SBrian Somers if (s < 0) { 267dd7e2610SBrian Somers log_Printf(LogERROR, "Local: socket: %s\n", strerror(errno)); 26874457d3dSBrian Somers goto failed; 2694ef16f24SBrian Somers } 2704ef16f24SBrian Somers setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 2718ea8442cSBrian Somers if (mask != (mode_t)-1) 27274457d3dSBrian Somers oldmask = umask(mask); 27374457d3dSBrian Somers if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) { 2748ea8442cSBrian Somers if (mask != (mode_t)-1) 27574457d3dSBrian Somers umask(oldmask); 276dd7e2610SBrian Somers log_Printf(LogWARN, "Local: bind: %s\n", strerror(errno)); 2774ef16f24SBrian Somers close(s); 27874457d3dSBrian Somers goto failed; 2794ef16f24SBrian Somers } 2808ea8442cSBrian Somers if (mask != (mode_t)-1) 28174457d3dSBrian Somers umask(oldmask); 2824ef16f24SBrian Somers if (listen(s, 5) != 0) { 2839b996792SBrian Somers log_Printf(LogERROR, "Local: Unable to listen to socket -" 2849b996792SBrian Somers " BUNDLE overload?\n"); 2854ef16f24SBrian Somers close(s); 28674457d3dSBrian Somers unlink(name); 28774457d3dSBrian Somers goto failed; 2884ef16f24SBrian Somers } 289661a0e90SBrian Somers server_Close(bundle); 29077ff88adSBrian Somers server.fd = s; 29174457d3dSBrian Somers server.cfg.port = 0; 29274457d3dSBrian Somers strncpy(server.cfg.sockname, ifsun.sun_path, sizeof server.cfg.sockname - 1); 29374457d3dSBrian Somers server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0'; 29474457d3dSBrian Somers server.cfg.mask = mask; 295dd7e2610SBrian Somers log_Printf(LogPHASE, "Listening at local socket %s.\n", name); 29674457d3dSBrian Somers 29774457d3dSBrian Somers return SERVER_OK; 29874457d3dSBrian Somers 29974457d3dSBrian Somers failed: 30074457d3dSBrian Somers if (server.fd == -1) { 30174457d3dSBrian Somers server.fd = -1; 30274457d3dSBrian Somers server.cfg.port = 0; 30374457d3dSBrian Somers strncpy(server.cfg.sockname, ifsun.sun_path, 30474457d3dSBrian Somers sizeof server.cfg.sockname - 1); 30574457d3dSBrian Somers server.cfg.sockname[sizeof server.cfg.sockname - 1] = '\0'; 30674457d3dSBrian Somers server.cfg.mask = mask; 30774457d3dSBrian Somers } 30874457d3dSBrian Somers return SERVER_FAILED; 3094ef16f24SBrian Somers } 3104ef16f24SBrian Somers 31174457d3dSBrian Somers enum server_stat 31274457d3dSBrian Somers server_TcpOpen(struct bundle *bundle, u_short port) 3134ef16f24SBrian Somers { 31430949fd4SBrian Somers struct sockaddr_storage ss; 31530949fd4SBrian Somers struct sockaddr_in *sin = (struct sockaddr_in *)&ss; 3161a2b4e4aSBrian Somers #ifndef NOINET6 31730949fd4SBrian Somers struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; 31830949fd4SBrian Somers #endif 31930949fd4SBrian Somers int s, sz; 3204ef16f24SBrian Somers 32174457d3dSBrian Somers if (server.cfg.port == port) 32274457d3dSBrian Somers server_Close(bundle); 323d40f8a5aSBrian Somers 32474457d3dSBrian Somers if (port == 0) 32574457d3dSBrian Somers return SERVER_INVALID; 32674457d3dSBrian Somers 32730949fd4SBrian Somers memset(&ss, '\0', sizeof ss); 3281a2b4e4aSBrian Somers #ifndef NOINET6 3291a2b4e4aSBrian Somers if (probe.ipv6_available) { 3301a2b4e4aSBrian Somers sin6->sin6_family = AF_INET6; 3311a2b4e4aSBrian Somers sin6->sin6_port = htons(port); 332260799afSBrian Somers sin6->sin6_len = (u_int8_t)sizeof ss; 3331a2b4e4aSBrian Somers sz = sizeof *sin6; 33463c6cac9SBrian Somers s = socket(PF_INET6, SOCK_STREAM, 0); 3351a2b4e4aSBrian Somers } else 3361a2b4e4aSBrian Somers #endif 3371a2b4e4aSBrian Somers { 33830949fd4SBrian Somers sin->sin_family = AF_INET; 33930949fd4SBrian Somers sin->sin_port = htons(port); 340260799afSBrian Somers sin->sin_len = (u_int8_t)sizeof ss; 34130949fd4SBrian Somers sin->sin_addr.s_addr = INADDR_ANY; 34230949fd4SBrian Somers sz = sizeof *sin; 34363c6cac9SBrian Somers s = socket(PF_INET, SOCK_STREAM, 0); 3441a2b4e4aSBrian Somers } 3451a2b4e4aSBrian Somers 3464ef16f24SBrian Somers if (s < 0) { 347dd7e2610SBrian Somers log_Printf(LogERROR, "Tcp: socket: %s\n", strerror(errno)); 34874457d3dSBrian Somers goto failed; 3494ef16f24SBrian Somers } 35030949fd4SBrian Somers 351bba6dc1dSHajimu UMEMOTO #ifndef NOINET6 352bba6dc1dSHajimu UMEMOTO if (probe.ipv6_available) { 353bba6dc1dSHajimu UMEMOTO int off = 0; 354bba6dc1dSHajimu UMEMOTO setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off)); 355bba6dc1dSHajimu UMEMOTO } 356bba6dc1dSHajimu UMEMOTO #endif 357bba6dc1dSHajimu UMEMOTO 3584ef16f24SBrian Somers setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s); 35930949fd4SBrian Somers if (bind(s, (struct sockaddr *)&ss, sz) < 0) { 360dd7e2610SBrian Somers log_Printf(LogWARN, "Tcp: bind: %s\n", strerror(errno)); 3614ef16f24SBrian Somers close(s); 36274457d3dSBrian Somers goto failed; 3634ef16f24SBrian Somers } 3644ef16f24SBrian Somers if (listen(s, 5) != 0) { 365661a0e90SBrian Somers log_Printf(LogERROR, "Tcp: Unable to listen to socket: %s\n", 366661a0e90SBrian Somers strerror(errno)); 3674ef16f24SBrian Somers close(s); 36874457d3dSBrian Somers goto failed; 3694ef16f24SBrian Somers } 370dd7e2610SBrian Somers server_Close(bundle); 37177ff88adSBrian Somers server.fd = s; 37274457d3dSBrian Somers server.cfg.port = port; 37374457d3dSBrian Somers *server.cfg.sockname = '\0'; 37474457d3dSBrian Somers server.cfg.mask = 0; 375dd7e2610SBrian Somers log_Printf(LogPHASE, "Listening at port %d.\n", port); 37674457d3dSBrian Somers return SERVER_OK; 37774457d3dSBrian Somers 37874457d3dSBrian Somers failed: 37974457d3dSBrian Somers if (server.fd == -1) { 38074457d3dSBrian Somers server.fd = -1; 38174457d3dSBrian Somers server.cfg.port = port; 38274457d3dSBrian Somers *server.cfg.sockname = '\0'; 38374457d3dSBrian Somers server.cfg.mask = 0; 38474457d3dSBrian Somers } 38574457d3dSBrian Somers return SERVER_FAILED; 3864ef16f24SBrian Somers } 3874ef16f24SBrian Somers 38877ff88adSBrian Somers int 389057f1760SBrian Somers server_Close(struct bundle *bundle __unused) 3904ef16f24SBrian Somers { 39177ff88adSBrian Somers if (server.fd >= 0) { 39274457d3dSBrian Somers if (*server.cfg.sockname != '\0') { 393661a0e90SBrian Somers struct sockaddr_un un; 394661a0e90SBrian Somers int sz = sizeof un; 395661a0e90SBrian Somers 396661a0e90SBrian Somers if (getsockname(server.fd, (struct sockaddr *)&un, &sz) == 0 && 397661a0e90SBrian Somers un.sun_family == AF_LOCAL && sz == sizeof un) 39874457d3dSBrian Somers unlink(un.sun_path); 3994ef16f24SBrian Somers } 400661a0e90SBrian Somers close(server.fd); 40177ff88adSBrian Somers server.fd = -1; 402b6217683SBrian Somers /* Drop associated prompts */ 4030f2f3eb3SBrian Somers log_DestroyPrompts(&server); 40474457d3dSBrian Somers 40577ff88adSBrian Somers return 1; 4064ef16f24SBrian Somers } 40774457d3dSBrian Somers 40877ff88adSBrian Somers return 0; 4094ef16f24SBrian Somers } 41074457d3dSBrian Somers 41174457d3dSBrian Somers int 41274457d3dSBrian Somers server_Clear(struct bundle *bundle) 41374457d3dSBrian Somers { 41474457d3dSBrian Somers int ret; 41574457d3dSBrian Somers 41674457d3dSBrian Somers ret = server_Close(bundle); 41774457d3dSBrian Somers 41874457d3dSBrian Somers server.fd = -1; 41974457d3dSBrian Somers server.cfg.port = 0; 42074457d3dSBrian Somers *server.cfg.sockname = '\0'; 42174457d3dSBrian Somers server.cfg.mask = 0; 42274457d3dSBrian Somers 42374457d3dSBrian Somers return ret; 42474457d3dSBrian Somers } 425