]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/listen.c
Import cups.org releases
[thirdparty/cups.git] / scheduler / listen.c
1 /*
2 * "$Id$"
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 {
61 LogMessage(L_DEBUG2, "PauseListening: Removing fd %d from InputSet...",
62 lis->fd);
63
64 FD_CLR(lis->fd, &InputSet);
65 }
66 }
67
68
69 /*
70 * 'ResumeListening()' - Set input polling on all listening sockets...
71 */
72
73 void
74 ResumeListening(void)
75 {
76 int i; /* Looping var */
77 listener_t *lis; /* Current listening socket */
78
79
80 if (FD_ISSET(Listeners[0].fd, &InputSet))
81 return;
82
83 if (NumClients >= (MaxClients - 1))
84 LogMessage(L_WARN, "Resuming new connection processing...");
85
86 LogMessage(L_DEBUG, "ResumeListening: setting input bits...");
87
88 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
89 {
90 LogMessage(L_DEBUG2, "ResumeListening: Adding fd %d to InputSet...",
91 lis->fd);
92
93 FD_SET(lis->fd, &InputSet);
94 }
95 }
96
97
98 /*
99 * 'StartListening()' - Create all listening sockets...
100 */
101
102 void
103 StartListening(void)
104 {
105 int i, /* Looping var */
106 val; /* Parameter value */
107 listener_t *lis; /* Current listening socket */
108 struct hostent *host; /* Host entry for server address */
109
110
111 LogMessage(L_DEBUG, "StartListening: NumListeners=%d", NumListeners);
112
113 /*
114 * Get the server's IP address...
115 */
116
117 memset(&ServerAddr, 0, sizeof(ServerAddr));
118
119 if ((host = gethostbyname(ServerName)) != NULL)
120 {
121 /*
122 * Found the server's address!
123 */
124
125 memcpy((char *)&(ServerAddr.sin_addr), host->h_addr, host->h_length);
126 ServerAddr.sin_family = host->h_addrtype;
127 }
128 else
129 {
130 /*
131 * Didn't find it! Use an address of 0...
132 */
133
134 LogMessage(L_ERROR, "StartListening: Unable to find IP address for server name \"%s\"!\n",
135 ServerName);
136
137 ServerAddr.sin_family = AF_INET;
138 }
139
140 /*
141 * Setup socket listeners...
142 */
143
144 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
145 {
146 LogMessage(L_DEBUG, "StartListening: address=%08x port=%d",
147 ntohl(lis->address.sin_addr.s_addr),
148 ntohs(lis->address.sin_port));
149
150 if ((lis->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
151 {
152 LogMessage(L_ERROR, "StartListening: Unable to open listen socket - %s.",
153 strerror(errno));
154 exit(errno);
155 }
156
157 fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
158
159 /*
160 * Set things up to reuse the local address for this port.
161 */
162
163 val = 1;
164 #ifdef __sun
165 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
166 #else
167 setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
168 #endif /* __sun */
169
170 /*
171 * Bind to the port we found...
172 */
173
174 if (bind(lis->fd, (struct sockaddr *)&(lis->address), sizeof(lis->address)) < 0)
175 {
176 LogMessage(L_ERROR, "StartListening: Unable to bind socket - %s.", strerror(errno));
177 exit(errno);
178 }
179
180 /*
181 * Listen for new clients.
182 */
183
184 if (listen(lis->fd, ListenBackLog) < 0)
185 {
186 LogMessage(L_ERROR, "StartListening: Unable to listen for clients - %s.",
187 strerror(errno));
188 exit(errno);
189 }
190 }
191
192 ResumeListening();
193 }
194
195
196 /*
197 * 'StopListening()' - Close all listening sockets...
198 */
199
200 void
201 StopListening(void)
202 {
203 int i; /* Looping var */
204 listener_t *lis; /* Current listening socket */
205
206
207 LogMessage(L_DEBUG, "StopListening: closing all listen sockets.");
208
209 PauseListening();
210
211 for (i = NumListeners, lis = Listeners; i > 0; i --, lis ++)
212 #if defined(WIN32) || defined(__EMX__)
213 closesocket(lis->fd);
214 #else
215 close(lis->fd);
216 #endif /* WIN32 || __EMX__ */
217 }
218
219
220 /*
221 * End of "$Id$".
222 */