]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/listen.c
Mirror 1.1.x changes.
[thirdparty/cups.git] / scheduler / listen.c
CommitLineData
e82646f2 1/*
0f71c41e 2 * "$Id: listen.c,v 1.9.2.11 2003/07/20 03:13:10 mike Exp $"
e82646f2 3 *
4 * Server listening routines for the Common UNIX Printing System (CUPS)
5 * scheduler.
6 *
1d9595ab 7 * Copyright 1997-2003 by Easy Software Products, all rights reserved.
e82646f2 8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Easy Software Products and are protected by Federal
11 * copyright law. Distribution and use rights are outlined in the file
12 * "LICENSE.txt" which should have been included with this file. If this
13 * file is missing or damaged please contact Easy Software Products
14 * at:
15 *
16 * Attn: CUPS Licensing Information
17 * Easy Software Products
8784b6a6 18 * 44141 Airport View Drive, Suite 204
e82646f2 19 * Hollywood, Maryland 20636-3111 USA
20 *
21 * Voice: (301) 373-9603
22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
24 *
25 * Contents:
26 *
d236cb49 27 * PauseListening() - Clear input polling on all listening sockets...
28 * ResumeListening() - Set input polling on all listening sockets...
29 * StartListening() - Create all listening sockets...
30 * StopListening() - Close all listening sockets...
e82646f2 31 */
32
33/*
34 * Include necessary headers...
35 */
36
37#include "cupsd.h"
38
39
d236cb49 40/*
41 * 'PauseListening()' - Clear input polling on all listening sockets...
42 */
43
44void
45PauseListening(void)
46{
47 int i; /* Looping var */
48 listener_t *lis; /* Current listening socket */
49
50
5073e3f8 51 if (NumListeners < 1 || !FD_ISSET(Listeners[0].fd, InputSet))
d236cb49 52 return;
53
676cde07 54 if (NumClients == MaxClients)
55 LogMessage(L_WARN, "Max clients reached, holding new connections...");
56
18fe941f 57 LogMessage(L_DEBUG, "PauseListening: Clearing input bits...");
d236cb49 58
59 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
18fe941f 60 {
61 LogMessage(L_DEBUG2, "PauseListening: Removing fd %d from InputSet...",
62 lis->fd);
63
f3bc1068 64 FD_CLR(lis->fd, InputSet);
18fe941f 65 }
d236cb49 66}
67
68
69/*
70 * 'ResumeListening()' - Set input polling on all listening sockets...
71 */
72
73void
74ResumeListening(void)
75{
76 int i; /* Looping var */
77 listener_t *lis; /* Current listening socket */
78
79
5073e3f8 80 if (NumListeners < 1 || FD_ISSET(Listeners[0].fd, InputSet))
d236cb49 81 return;
82
676cde07 83 if (NumClients >= (MaxClients - 1))
84 LogMessage(L_WARN, "Resuming new connection processing...");
85
18fe941f 86 LogMessage(L_DEBUG, "ResumeListening: Setting input bits...");
d236cb49 87
88 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
18fe941f 89 {
90 LogMessage(L_DEBUG2, "ResumeListening: Adding fd %d to InputSet...",
91 lis->fd);
f3bc1068 92 FD_SET(lis->fd, InputSet);
18fe941f 93 }
d236cb49 94}
95
96
e82646f2 97/*
98 * 'StartListening()' - Create all listening sockets...
99 */
100
101void
102StartListening(void)
103{
104 int i, /* Looping var */
105 val; /* Parameter value */
106 listener_t *lis; /* Current listening socket */
2bdd1992 107 struct hostent *host; /* Host entry for server address */
99de6da0 108 char s[256]; /* String addresss */
e82646f2 109
110
676cde07 111 LogMessage(L_DEBUG, "StartListening: NumListeners=%d", NumListeners);
d236cb49 112
2bdd1992 113 /*
114 * Get the server's IP address...
115 */
116
117 memset(&ServerAddr, 0, sizeof(ServerAddr));
118
753453e4 119 if ((host = httpGetHostByName(ServerName)) != NULL)
2bdd1992 120 {
121 /*
122 * Found the server's address!
123 */
124
99de6da0 125 httpAddrLoad(host, 0, 0, &ServerAddr);
2bdd1992 126 }
127 else
128 {
129 /*
130 * Didn't find it! Use an address of 0...
131 */
132
7e3ba0af 133 LogMessage(L_ERROR, "StartListening: Unable to find IP address for server name \"%s\" - %s\n",
134 ServerName, hstrerror(h_errno));
2bdd1992 135
99de6da0 136 ServerAddr.ipv4.sin_family = AF_INET;
2bdd1992 137 }
138
e82646f2 139 /*
140 * Setup socket listeners...
141 */
142
143 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
144 {
99de6da0 145 httpAddrString(&(lis->address), s, sizeof(s));
146
147#ifdef AF_INET6
148 if (lis->address.addr.sa_family == AF_INET6)
149 LogMessage(L_DEBUG, "StartListening: address=%s port=%d (IPv6)", s,
150 ntohs(lis->address.ipv6.sin6_port));
151 else
152#endif /* AF_INET6 */
153 LogMessage(L_DEBUG, "StartListening: address=%s port=%d", s,
154 ntohs(lis->address.ipv4.sin_port));
155
0f71c41e 156 /*
157 * Save the first port that is bound to the local loopback or
158 * "any" address...
159 */
160
161 if (httpAddrLocalhost(&(lis->address)) ||
162 httpAddrAny(&(lis->address)))
163 {
164#ifdef AF_INET6
165 if (lis->address.addr.sa_family == AF_INET6)
166 LocalPort = ntohs(lis->address.ipv6.sin6_port);
167 else
168#endif /* AF_INET6 */
169 LocalPort = ntohs(lis->address.ipv4.sin_port);
170 }
171
172 /*
173 * Create a socket for listening...
174 */
175
99de6da0 176 if ((lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0)) == -1)
e82646f2 177 {
676cde07 178 LogMessage(L_ERROR, "StartListening: Unable to open listen socket - %s.",
e82646f2 179 strerror(errno));
180 exit(errno);
181 }
182
18fe941f 183 LogMessage(L_DEBUG2, "StartListening: fd=%d", lis->fd);
184
e82646f2 185 fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
186
187 /*
188 * Set things up to reuse the local address for this port.
189 */
190
191 val = 1;
192#ifdef __sun
193 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
194#else
195 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
196#endif /* __sun */
197
198 /*
199 * Bind to the port we found...
200 */
201
a09840c5 202#ifdef AF_INET6
203 if (bind(lis->fd, (struct sockaddr *)&(lis->address),
204 lis->address.addr.sa_family == AF_INET ?
205 sizeof(lis->address.ipv4) :
206 sizeof(lis->address.ipv6)) < 0)
207#else
208 if (bind(lis->fd, (struct sockaddr *)&(lis->address),
209 sizeof(lis->address.ipv4)) < 0)
210#endif
e82646f2 211 {
99de6da0 212 LogMessage(L_ERROR, "StartListening: Unable to bind socket - %s.",
213 strerror(errno));
e82646f2 214 exit(errno);
215 }
216
217 /*
218 * Listen for new clients.
219 */
220
27eba2dd 221 if (listen(lis->fd, ListenBackLog) < 0)
e82646f2 222 {
676cde07 223 LogMessage(L_ERROR, "StartListening: Unable to listen for clients - %s.",
e82646f2 224 strerror(errno));
225 exit(errno);
226 }
e82646f2 227 }
228
d236cb49 229 ResumeListening();
e82646f2 230}
231
232
233/*
234 * 'StopListening()' - Close all listening sockets...
235 */
236
237void
238StopListening(void)
239{
240 int i; /* Looping var */
241 listener_t *lis; /* Current listening socket */
242
243
676cde07 244 LogMessage(L_DEBUG, "StopListening: closing all listen sockets.");
d236cb49 245
246 PauseListening();
247
e82646f2 248 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
c3026ddc 249#ifdef WIN32
e82646f2 250 closesocket(lis->fd);
251#else
252 close(lis->fd);
c3026ddc 253#endif /* WIN32 */
e82646f2 254}
255
256
257/*
0f71c41e 258 * End of "$Id: listen.c,v 1.9.2.11 2003/07/20 03:13:10 mike Exp $".
e82646f2 259 */