]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/listen.c
3b565bf35b9a28fcb5a72d84ea32c167ccbb9a5a
[thirdparty/cups.git] / scheduler / listen.c
1 /*
2 * "$Id: listen.c,v 1.9.2.2 2001/12/26 16:52:54 mike Exp $"
3 *
4 * Server listening routines for the Common UNIX Printing System (CUPS)
5 * scheduler.
6 *
7 * Copyright 1997-2001 by Easy Software Products, all rights reserved.
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
18 * 44141 Airport View Drive, Suite 204
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 *
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...
31 */
32
33 /*
34 * Include necessary headers...
35 */
36
37 #include "cupsd.h"
38
39
40 /*
41 * 'PauseListening()' - Clear input polling on all listening sockets...
42 */
43
44 void
45 PauseListening(void)
46 {
47 int i; /* Looping var */
48 listener_t *lis; /* Current listening socket */
49
50
51 if (!FD_ISSET(Listeners[0].fd, &InputSet))
52 return;
53
54 if (NumClients == MaxClients)
55 LogMessage(L_WARN, "Max clients reached, holding new connections...");
56
57 LogMessage(L_DEBUG, "PauseListening: clearing input bits...");
58
59 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
60 FD_CLR(lis->fd, &InputSet);
61 }
62
63
64 /*
65 * 'ResumeListening()' - Set input polling on all listening sockets...
66 */
67
68 void
69 ResumeListening(void)
70 {
71 int i; /* Looping var */
72 listener_t *lis; /* Current listening socket */
73
74
75 if (FD_ISSET(Listeners[0].fd, &InputSet))
76 return;
77
78 if (NumClients >= (MaxClients - 1))
79 LogMessage(L_WARN, "Resuming new connection processing...");
80
81 LogMessage(L_DEBUG, "ResumeListening: setting input bits...");
82
83 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
84 FD_SET(lis->fd, &InputSet);
85 }
86
87
88 /*
89 * 'StartListening()' - Create all listening sockets...
90 */
91
92 void
93 StartListening(void)
94 {
95 int i, /* Looping var */
96 val; /* Parameter value */
97 listener_t *lis; /* Current listening socket */
98 struct hostent *host; /* Host entry for server address */
99 char s[256]; /* String addresss */
100
101
102 LogMessage(L_DEBUG, "StartListening: NumListeners=%d", NumListeners);
103
104 /*
105 * Get the server's IP address...
106 */
107
108 memset(&ServerAddr, 0, sizeof(ServerAddr));
109
110 if ((host = httpGetHostByName(ServerName)) != NULL)
111 {
112 /*
113 * Found the server's address!
114 */
115
116 httpAddrLoad(host, 0, 0, &ServerAddr);
117 }
118 else
119 {
120 /*
121 * Didn't find it! Use an address of 0...
122 */
123
124 LogMessage(L_ERROR, "StartListening: Unable to find IP address for server name \"%s\"!\n",
125 ServerName);
126
127 ServerAddr.ipv4.sin_family = AF_INET;
128 }
129
130 /*
131 * Setup socket listeners...
132 */
133
134 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
135 {
136 httpAddrString(&(lis->address), s, sizeof(s));
137
138 #ifdef AF_INET6
139 if (lis->address.addr.sa_family == AF_INET6)
140 LogMessage(L_DEBUG, "StartListening: address=%s port=%d (IPv6)", s,
141 ntohs(lis->address.ipv6.sin6_port));
142 else
143 #endif /* AF_INET6 */
144 LogMessage(L_DEBUG, "StartListening: address=%s port=%d", s,
145 ntohs(lis->address.ipv4.sin_port));
146
147 if ((lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0)) == -1)
148 {
149 LogMessage(L_ERROR, "StartListening: Unable to open listen socket - %s.",
150 strerror(errno));
151 exit(errno);
152 }
153
154 fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
155
156 /*
157 * Set things up to reuse the local address for this port.
158 */
159
160 val = 1;
161 #ifdef __sun
162 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
163 #else
164 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
165 #endif /* __sun */
166
167 /*
168 * Bind to the port we found...
169 */
170
171 if (bind(lis->fd, (struct sockaddr *)&(lis->address), sizeof(lis->address)) < 0)
172 {
173 LogMessage(L_ERROR, "StartListening: Unable to bind socket - %s.",
174 strerror(errno));
175 exit(errno);
176 }
177
178 /*
179 * Listen for new clients.
180 */
181
182 if (listen(lis->fd, ListenBackLog) < 0)
183 {
184 LogMessage(L_ERROR, "StartListening: Unable to listen for clients - %s.",
185 strerror(errno));
186 exit(errno);
187 }
188 }
189
190 ResumeListening();
191 }
192
193
194 /*
195 * 'StopListening()' - Close all listening sockets...
196 */
197
198 void
199 StopListening(void)
200 {
201 int i; /* Looping var */
202 listener_t *lis; /* Current listening socket */
203
204
205 LogMessage(L_DEBUG, "StopListening: closing all listen sockets.");
206
207 PauseListening();
208
209 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
210 #if defined(WIN32) || defined(__EMX__)
211 closesocket(lis->fd);
212 #else
213 close(lis->fd);
214 #endif /* WIN32 || __EMX__ */
215 }
216
217
218 /*
219 * End of "$Id: listen.c,v 1.9.2.2 2001/12/26 16:52:54 mike Exp $".
220 */