]> 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/*
e673c4b4 2 * "$Id: listen.c,v 1.9.2.12 2004/02/24 21:36:59 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
e673c4b4 143 for (i = NumListeners, lis = Listeners, LocalPort = 0; i > 0; i --, lis ++)
e82646f2 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
e673c4b4 161 if (!LocalPort &&
162 (httpAddrLocalhost(&(lis->address)) ||
163 httpAddrAny(&(lis->address))))
0f71c41e 164 {
165#ifdef AF_INET6
166 if (lis->address.addr.sa_family == AF_INET6)
167 LocalPort = ntohs(lis->address.ipv6.sin6_port);
168 else
169#endif /* AF_INET6 */
170 LocalPort = ntohs(lis->address.ipv4.sin_port);
171 }
172
173 /*
174 * Create a socket for listening...
175 */
176
99de6da0 177 if ((lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0)) == -1)
e82646f2 178 {
676cde07 179 LogMessage(L_ERROR, "StartListening: Unable to open listen socket - %s.",
e82646f2 180 strerror(errno));
181 exit(errno);
182 }
183
18fe941f 184 LogMessage(L_DEBUG2, "StartListening: fd=%d", lis->fd);
185
e82646f2 186 fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
187
188 /*
189 * Set things up to reuse the local address for this port.
190 */
191
192 val = 1;
193#ifdef __sun
194 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
195#else
196 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
197#endif /* __sun */
198
199 /*
200 * Bind to the port we found...
201 */
202
a09840c5 203#ifdef AF_INET6
204 if (bind(lis->fd, (struct sockaddr *)&(lis->address),
205 lis->address.addr.sa_family == AF_INET ?
206 sizeof(lis->address.ipv4) :
207 sizeof(lis->address.ipv6)) < 0)
208#else
209 if (bind(lis->fd, (struct sockaddr *)&(lis->address),
210 sizeof(lis->address.ipv4)) < 0)
211#endif
e82646f2 212 {
99de6da0 213 LogMessage(L_ERROR, "StartListening: Unable to bind socket - %s.",
214 strerror(errno));
e82646f2 215 exit(errno);
216 }
217
218 /*
219 * Listen for new clients.
220 */
221
27eba2dd 222 if (listen(lis->fd, ListenBackLog) < 0)
e82646f2 223 {
676cde07 224 LogMessage(L_ERROR, "StartListening: Unable to listen for clients - %s.",
e82646f2 225 strerror(errno));
226 exit(errno);
227 }
e82646f2 228 }
229
e673c4b4 230 /*
231 * Make sure that we are listening on localhost!
232 */
233
234 if (!LocalPort)
235 {
236 LogMessage(L_EMERG, "No Listen or Port lines were found to allow access via localhost!");
237
238 /*
239 * Commit suicide...
240 */
241
242 kill(getpid(), SIGTERM);
243 }
244
d236cb49 245 ResumeListening();
e82646f2 246}
247
248
249/*
250 * 'StopListening()' - Close all listening sockets...
251 */
252
253void
254StopListening(void)
255{
256 int i; /* Looping var */
257 listener_t *lis; /* Current listening socket */
258
259
676cde07 260 LogMessage(L_DEBUG, "StopListening: closing all listen sockets.");
d236cb49 261
262 PauseListening();
263
e82646f2 264 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
c3026ddc 265#ifdef WIN32
e82646f2 266 closesocket(lis->fd);
267#else
268 close(lis->fd);
c3026ddc 269#endif /* WIN32 */
e82646f2 270}
271
272
273/*
e673c4b4 274 * End of "$Id: listen.c,v 1.9.2.12 2004/02/24 21:36:59 mike Exp $".
e82646f2 275 */