]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/dirsvc.c
Increased number of serial ports detected under Linux to 100.
[thirdparty/cups.git] / scheduler / dirsvc.c
CommitLineData
a129ddbd 1/*
0c2ea277 2 * "$Id: dirsvc.c,v 1.58 2000/09/07 20:34:41 mike Exp $"
a129ddbd 3 *
d6de4648 4 * Directory services routines for the Common UNIX Printing System (CUPS).
a129ddbd 5 *
71fe22b7 6 * Copyright 1997-2000 by Easy Software Products, all rights reserved.
a129ddbd 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
8784b6a6 17 * 44141 Airport View Drive, Suite 204
a129ddbd 18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
cbbfcc63 26 * StartBrowsing() - Start sending and receiving broadcast information.
27 * StopBrowsing() - Stop sending and receiving broadcast information.
28 * UpdateBrowseList() - Update the browse lists for any new browse data.
29 * SendBrowseList() - Send new browsing information.
03081fd2 30 * StartPolling() - Start polling servers as needed.
31 * StopPolling() - Stop polling servers as needed.
a129ddbd 32 */
33
34/*
35 * Include necessary headers...
36 */
37
fd8b1cf8 38#include "cupsd.h"
39
40
d6de4648 41/*
42 * 'StartBrowsing()' - Start sending and receiving broadcast information.
43 */
44
fd8b1cf8 45void
46StartBrowsing(void)
47{
d6de4648 48 int val; /* Socket option value */
49 struct sockaddr_in addr; /* Broadcast address */
50
51
8828fd5f 52 if (!Browsing)
d6de4648 53 return;
54
55 /*
56 * Create the broadcast socket...
57 */
58
900b10ea 59 if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
d6de4648 60 {
5ea8888e 61 LogMessage(L_ERROR, "StartBrowsing: Unable to create broadcast socket - %s.",
d6de4648 62 strerror(errno));
58218b2c 63 Browsing = 0;
d6de4648 64 return;
65 }
66
67 /*
900b10ea 68 * Set the "broadcast" flag...
d6de4648 69 */
70
71 val = 1;
e9e40963 72 if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
fd3ece61 73 {
5ea8888e 74 LogMessage(L_ERROR, "StartBrowsing: Unable to set broadcast mode - %s.",
fd3ece61 75 strerror(errno));
76
77#if defined(WIN32) || defined(__EMX__)
78 closesocket(BrowseSocket);
79#else
80 close(BrowseSocket);
81#endif /* WIN32 || __EMX__ */
82
83 BrowseSocket = -1;
58218b2c 84 Browsing = 0;
fd3ece61 85 return;
86 }
d6de4648 87
d6de4648 88 /*
89 * Bind the socket to browse port...
90 */
91
d6de4648 92 memset(&addr, 0, sizeof(addr));
93 addr.sin_addr.s_addr = htonl(INADDR_ANY);
94 addr.sin_family = AF_INET;
95 addr.sin_port = htons(BrowsePort);
96
16b0a852 97 if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr)))
d6de4648 98 {
5ea8888e 99 LogMessage(L_ERROR, "StartBrowsing: Unable to bind broadcast socket - %s.",
d6de4648 100 strerror(errno));
101
102#if defined(WIN32) || defined(__EMX__)
103 closesocket(BrowseSocket);
104#else
105 close(BrowseSocket);
106#endif /* WIN32 || __EMX__ */
107
108 BrowseSocket = -1;
58218b2c 109 Browsing = 0;
d6de4648 110 return;
111 }
112
113 /*
114 * Finally, add the socket to the input selection set...
115 */
116
117 FD_SET(BrowseSocket, &InputSet);
fd8b1cf8 118}
119
120
d6de4648 121/*
122 * 'StopBrowsing()' - Stop sending and receiving broadcast information.
123 */
124
fd8b1cf8 125void
126StopBrowsing(void)
127{
8828fd5f 128 if (!Browsing)
d6de4648 129 return;
130
131 /*
132 * Close the socket and remove it from the input selection set.
133 */
134
3c7bb4a2 135 if (BrowseSocket >= 0)
136 {
d6de4648 137#if defined(WIN32) || defined(__EMX__)
3c7bb4a2 138 closesocket(BrowseSocket);
d6de4648 139#else
3c7bb4a2 140 close(BrowseSocket);
d6de4648 141#endif /* WIN32 || __EMX__ */
142
3c7bb4a2 143 FD_CLR(BrowseSocket, &InputSet);
f63a2256 144 BrowseSocket = 0;
3c7bb4a2 145 }
fd8b1cf8 146}
147
148
d6de4648 149/*
150 * 'UpdateBrowseList()' - Update the browse lists for any new browse data.
151 */
152
fd8b1cf8 153void
154UpdateBrowseList(void)
155{
8b43895a 156 int i; /* Looping var */
e5ebb675 157 int auth; /* Authorization status */
eef5ad1b 158 int len, /* Length of name string */
159 offset; /* Offset in name string */
d6de4648 160 int bytes; /* Number of bytes left */
161 char packet[1540]; /* Broadcast packet */
e5ebb675 162 struct sockaddr_in srcaddr; /* Source address */
163 char srcname[1024]; /* Source hostname */
164 unsigned address; /* Source address (host order) */
165 struct hostent *srchost; /* Host entry for source address */
d6de4648 166 cups_ptype_t type; /* Printer type */
167 ipp_pstate_t state; /* Printer state */
168 char uri[HTTP_MAX_URI], /* Printer URI */
169 method[HTTP_MAX_URI], /* Method portion of URI */
170 username[HTTP_MAX_URI], /* Username portion of URI */
171 host[HTTP_MAX_URI], /* Host portion of URI */
a2c6b8b1 172 resource[HTTP_MAX_URI], /* Resource portion of URI */
173 info[IPP_MAX_NAME], /* Information string */
174 location[IPP_MAX_NAME], /* Location string */
175 make_model[IPP_MAX_NAME];/* Make and model string */
d6de4648 176 int port; /* Port portion of URI */
177 char name[IPP_MAX_NAME], /* Name of printer */
8b43895a 178 *hptr, /* Pointer into hostname */
179 *sptr; /* Pointer into ServerName */
180 printer_t *p, /* Printer information */
181 *pclass, /* Printer class */
182 *first; /* First printer in class */
d6de4648 183
184
185 /*
186 * Read a packet from the browse socket...
187 */
188
e5ebb675 189 len = sizeof(srcaddr);
16b0a852 190 if ((bytes = recvfrom(BrowseSocket, packet, sizeof(packet), 0,
e5ebb675 191 (struct sockaddr *)&srcaddr, &len)) <= 0)
18d7d592 192 {
5ea8888e 193 LogMessage(L_ERROR, "Browse recv failed - %s.",
18d7d592 194 strerror(errno));
5ea8888e 195 LogMessage(L_ERROR, "Browsing turned off.");
1a5606a3 196
197 StopBrowsing();
198 Browsing = 0;
18d7d592 199 return;
200 }
201
202 packet[bytes] = '\0';
e5ebb675 203
204 /*
205 * Figure out where it came from...
206 */
207
208 address = ntohl(srcaddr.sin_addr.s_addr);
209
210 if (HostNameLookups)
211#ifndef __sgi
212 srchost = gethostbyaddr((char *)&(srcaddr.sin_addr), sizeof(struct in_addr),
213 AF_INET);
18d7d592 214#else
e5ebb675 215 srchost = gethostbyaddr(&(srcaddr.sin_addr), sizeof(struct in_addr),
216 AF_INET);
217#endif /* !__sgi */
218 else
219 srchost = NULL;
220
221 if (srchost == NULL)
222 sprintf(srcname, "%d.%d.%d.%d", address >> 24, (address >> 16) & 255,
223 (address >> 8) & 255, address & 255);
224 else
f9bacabb 225 {
e5ebb675 226 strncpy(srcname, srchost->h_name, sizeof(srcname) - 1);
227 srcname[sizeof(srcname) - 1] = '\0';
228 }
1a5606a3 229
e5ebb675 230 len = strlen(srcname);
231
232 /*
233 * Do ACL stuff...
234 */
235
236 if (BrowseACL)
237 {
238 if (address == 0x7f000001 || strcasecmp(srcname, "localhost") == 0)
239 {
240 /*
241 * Access from localhost (127.0.0.1) is always allowed...
242 */
243
244 auth = AUTH_ALLOW;
245 }
246 else
247 {
248 /*
249 * Do authorization checks on the domain/address...
250 */
251
d21a7597 252 switch (BrowseACL->order_type)
e5ebb675 253 {
d21a7597 254 default :
255 auth = AUTH_DENY; /* anti-compiler-warning-code */
256 break;
257
e5ebb675 258 case AUTH_ALLOW : /* Order Deny,Allow */
d21a7597 259 auth = AUTH_ALLOW;
260
e5ebb675 261 if (CheckAuth(address, srcname, len,
262 BrowseACL->num_deny, BrowseACL->deny))
263 auth = AUTH_DENY;
264
265 if (CheckAuth(address, srcname, len,
266 BrowseACL->num_allow, BrowseACL->allow))
267 auth = AUTH_ALLOW;
268 break;
269
270 case AUTH_DENY : /* Order Allow,Deny */
d21a7597 271 auth = AUTH_DENY;
272
e5ebb675 273 if (CheckAuth(address, srcname, len,
274 BrowseACL->num_allow, BrowseACL->allow))
275 auth = AUTH_ALLOW;
276
277 if (CheckAuth(address, srcname, len,
278 BrowseACL->num_deny, BrowseACL->deny))
279 auth = AUTH_DENY;
280 break;
281 }
282 }
283 }
284 else
285 auth = AUTH_ALLOW;
286
287 if (auth == AUTH_DENY)
288 {
289 LogMessage(L_DEBUG, "UpdateBrowseList: Refused %d bytes from %s", bytes,
290 srcname);
d6de4648 291 return;
f9bacabb 292 }
d6de4648 293
e5ebb675 294 LogMessage(L_DEBUG, "UpdateBrowseList: (%d bytes from %s) %s", bytes, srcname,
295 packet);
296
297 /*
298 * Parse packet...
299 */
d6de4648 300
a2c6b8b1 301 location[0] = '\0';
302 info[0] = '\0';
303 make_model[0] = '\0';
304
305 if (sscanf(packet,
306 "%x%x%1023s%*[^\"]\"%127[^\"]%*[^\"]\"%127[^\"]%*[^\"]\"%127[^\"]",
d21a7597 307 (unsigned *)&type, (unsigned *)&state, uri, location, info,
308 make_model) < 3)
d6de4648 309 {
5ea8888e 310 LogMessage(L_WARN, "UpdateBrowseList: Garbled browse packet - %s",
d6de4648 311 packet);
312 return;
313 }
314
a2c6b8b1 315 DEBUG_printf(("type=%x, state=%x, uri=\"%s\"\n"
316 "location=\"%s\", info=\"%s\", make_model=\"%s\"\n",
317 type, state, uri, location, info, make_model));
a8b216d5 318
d6de4648 319 /*
320 * Pull the URI apart to see if this is a local or remote printer...
321 */
322
323 httpSeparate(uri, method, username, host, &port, resource);
324
a8b216d5 325 DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName));
326
d6de4648 327 if (strcasecmp(host, ServerName) == 0)
328 return;
329
e5ebb675 330 /*
331 * Do relaying...
332 */
333
334 for (i = 0; i < NumRelays; i ++)
335 if (CheckAuth(address, srcname, len, 1, &(Relays[i].from)))
336 if (sendto(BrowseSocket, packet, bytes, 0,
337 (struct sockaddr *)&(Relays[i].to),
338 sizeof(struct sockaddr_in)) <= 0)
339 {
340 LogMessage(L_ERROR, "UpdateBrowseList: sendto failed for relay %d - %s.",
341 i + 1, strerror(errno));
342 return;
343 }
344
d6de4648 345 /*
346 * OK, this isn't a local printer; see if we already have it listed in
347 * the Printers list, and add it if not...
348 */
349
8b43895a 350 hptr = strchr(host, '.');
351 sptr = strchr(ServerName, '.');
352
9fe0309f 353 if (sptr != NULL && hptr != NULL)
354 {
355 /*
356 * Strip the common domain name components...
357 */
358
359 while (hptr != NULL)
360 {
361 if (strcasecmp(hptr, sptr) == 0)
362 {
363 *hptr = '\0';
364 break;
365 }
366 else
367 hptr = strchr(hptr + 1, '.');
368 }
369 }
d6de4648 370
c7fa9d06 371 if (type & CUPS_PRINTER_CLASS)
d6de4648 372 {
373 /*
c7fa9d06 374 * Remote destination is a class...
d6de4648 375 */
376
c7fa9d06 377 if (strncmp(resource, "/classes/", 9) == 0)
970017a4 378 snprintf(name, sizeof(name), "%s@%s", resource + 9, host);
c7fa9d06 379 else
380 return;
381
d6f1ff9a 382 if ((p = FindClass(name)) == NULL && BrowseShortNames)
0c2ea277 383 {
d6f1ff9a 384 if ((p = FindClass(resource + 9)) != NULL)
385 {
386 if (strcasecmp(p->hostname, host) != 0)
387 {
388 /*
389 * Nope, this isn't the same host; if the hostname isn't the local host,
390 * add it to the other class and then find a class using the full host
391 * name...
392 */
393
394 if (p->type & CUPS_PRINTER_REMOTE)
395 {
396 strcat(p->name, "@");
397 strcat(p->name, p->hostname);
398 SetPrinterAttrs(p);
399 SortPrinters();
400 }
401
402 p = NULL;
403 }
404 }
405 else
406 {
407 strncpy(name, resource + 9, sizeof(name) - 1);
408 name[sizeof(name) - 1] = '\0';
409 }
0c2ea277 410 }
d6f1ff9a 411
412 if (p == NULL)
c7fa9d06 413 {
414 /*
415 * Class doesn't exist; add it...
416 */
d6de4648 417
782359ca 418 p = AddClass(name);
c7fa9d06 419
420 /*
782359ca 421 * Force the URI to point to the real server...
c7fa9d06 422 */
423
5057ad3b 424 p->type = type;
c7fa9d06 425 strcpy(p->uri, uri);
5374d18c 426 strcpy(p->more_info, uri);
c7fa9d06 427 strcpy(p->device_uri, uri);
67a6c918 428 strcpy(p->hostname, host);
a2c6b8b1 429
430 strcpy(p->location, "Location Unknown");
431 strcpy(p->info, "No Information Available");
432 snprintf(p->make_model, sizeof(p->make_model), "Remote Class on %s",
433 host);
434
5057ad3b 435 SetPrinterAttrs(p);
c7fa9d06 436 }
437 }
438 else
439 {
d6de4648 440 /*
c7fa9d06 441 * Remote destination is a printer...
d6de4648 442 */
443
c7fa9d06 444 if (strncmp(resource, "/printers/", 10) == 0)
970017a4 445 snprintf(name, sizeof(name), "%s@%s", resource + 10, host);
c7fa9d06 446 else
447 return;
448
d6f1ff9a 449 if ((p = FindPrinter(name)) == NULL && BrowseShortNames)
0c2ea277 450 {
d6f1ff9a 451 if ((p = FindPrinter(resource + 10)) != NULL)
452 {
453 if (strcasecmp(p->hostname, host) != 0)
454 {
455 /*
456 * Nope, this isn't the same host; if the hostname isn't the local host,
457 * add it to the other printer and then find a printer using the full host
458 * name...
459 */
460
461 if (p->type & CUPS_PRINTER_REMOTE)
462 {
463 strcat(p->name, "@");
464 strcat(p->name, p->hostname);
465 SetPrinterAttrs(p);
466 SortPrinters();
467 }
468
469 p = NULL;
470 }
471 }
472 else
473 {
474 strncpy(name, resource + 10, sizeof(name) - 1);
475 name[sizeof(name) - 1] = '\0';
476 }
0c2ea277 477 }
d6f1ff9a 478
479 if (p == NULL)
c7fa9d06 480 {
481 /*
482 * Printer doesn't exist; add it...
483 */
484
485 p = AddPrinter(name);
486
487 /*
5057ad3b 488 * Force the URI to point to the real server...
c7fa9d06 489 */
490
5057ad3b 491 p->type = type;
c7fa9d06 492 strcpy(p->uri, uri);
5374d18c 493 strcpy(p->more_info, uri);
c7fa9d06 494 strcpy(p->device_uri, uri);
67a6c918 495 strcpy(p->hostname, host);
a2c6b8b1 496
497 strcpy(p->location, "Location Unknown");
498 strcpy(p->info, "No Information Available");
499 snprintf(p->make_model, sizeof(p->make_model), "Remote Printer on %s",
500 host);
501
5057ad3b 502 SetPrinterAttrs(p);
c7fa9d06 503 }
d6de4648 504 }
505
506 /*
507 * Update the state...
508 */
509
f925c8de 510 p->type = type;
d6de4648 511 p->state = state;
0948b55b 512 p->accepting = state != IPP_PRINTER_STOPPED;
d6de4648 513 p->browse_time = time(NULL);
8b43895a 514
a2c6b8b1 515 if (location[0])
516 strcpy(p->location, location);
517 if (info[0])
518 strcpy(p->info, info);
519 if (make_model[0])
520 strcpy(p->make_model, make_model);
521
29a78848 522 /*
523 * If the remote printer is idle, check for local jobs that might need to
524 * go to it...
525 */
526
527 if (p->state == IPP_PRINTER_IDLE)
528 CheckJobs();
529
fb00e262 530 /*
4621b86f 531 * See if we have a default printer... If not, make the first printer the
532 * default.
fb00e262 533 */
534
535 if (DefaultPrinter == NULL && Printers != NULL)
536 DefaultPrinter = Printers;
537
8b43895a 538 /*
539 * Do auto-classing if needed...
540 */
541
542 if (ImplicitClasses)
543 {
544 /*
545 * Loop through all available printers and create classes as needed...
546 */
547
d21a7597 548 for (p = Printers, len = 0, offset = 0, first = NULL;
549 p != NULL;
550 p = p->next)
8b43895a 551 {
552 /*
553 * Skip classes...
554 */
555
556 if (p->type & CUPS_PRINTER_CLASS)
557 {
558 len = 0;
559 continue;
560 }
561
562 /*
563 * If len == 0, get the length of this printer name up to the "@"
564 * sign (if any).
565 */
566
567 if (len > 0 &&
eef5ad1b 568 strncasecmp(p->name, name + offset, len) == 0 &&
8b43895a 569 (p->name[len] == '\0' || p->name[len] == '@'))
570 {
571 /*
572 * We have more than one printer with the same name; see if
573 * we have a class, and if this printer is a member...
574 */
575
a2c6b8b1 576 if ((pclass = FindPrinter(name)) == NULL)
18d7d592 577 {
4139b718 578 /*
579 * Need to add the class...
580 */
581
a2c6b8b1 582 pclass = AddPrinter(name);
4139b718 583 pclass->type |= CUPS_PRINTER_IMPLICIT;
584 pclass->accepting = 1;
585 pclass->state = IPP_PRINTER_IDLE;
586
587 SetPrinterAttrs(pclass);
20da3efb 588
589 DEBUG_printf(("Added new class \"%s\", type = %x\n", name,
590 pclass->type));
18d7d592 591 }
8b43895a 592
593 if (first != NULL)
594 {
595 for (i = 0; i < pclass->num_printers; i ++)
596 if (pclass->printers[i] == first)
597 break;
598
599 if (i >= pclass->num_printers)
600 AddPrinterToClass(pclass, first);
601
602 first = NULL;
603 }
604
605 for (i = 0; i < pclass->num_printers; i ++)
606 if (pclass->printers[i] == p)
607 break;
608
609 if (i >= pclass->num_printers)
610 AddPrinterToClass(pclass, p);
611 }
612 else
613 {
614 /*
615 * First time around; just get name length and mark it as first
616 * in the list...
617 */
618
619 if ((hptr = strchr(p->name, '@')) != NULL)
620 len = hptr - p->name;
621 else
622 len = strlen(p->name);
623
782359ca 624 strncpy(name, p->name, len);
625 name[len] = '\0';
eef5ad1b 626 offset = 0;
782359ca 627
a2c6b8b1 628 if ((pclass = FindPrinter(name)) != NULL &&
629 !(pclass->type & CUPS_PRINTER_IMPLICIT))
782359ca 630 {
631 /*
632 * Can't use same name as printer; add "Any" to the front of the
633 * name...
634 */
635
636 strcpy(name, "Any");
637 strncpy(name + 3, p->name, len);
638 name[len + 3] = '\0';
eef5ad1b 639 offset = 3;
782359ca 640 }
641
8b43895a 642 first = p;
643 }
644 }
645 }
fd8b1cf8 646}
647
648
d6de4648 649/*
650 * 'SendBrowseList()' - Send new browsing information.
651 */
652
fd8b1cf8 653void
654SendBrowseList(void)
655{
d6de4648 656 int i; /* Looping var */
657 printer_t *p, /* Current printer */
658 *np; /* Next printer */
f9d6449d 659 time_t ut, /* Minimum update time */
660 to; /* Timeout time */
d6de4648 661 int bytes; /* Length of packet */
a2c6b8b1 662 char packet[1453];
d6de4648 663 /* Browse data packet */
664
665
03081fd2 666 if (!Browsing || BrowseInterval == 0)
f63a2256 667 return;
668
d6de4648 669 /*
670 * Compute the update time...
671 */
672
f9d6449d 673 ut = time(NULL) - BrowseInterval;
674 to = time(NULL) - BrowseTimeout;
d6de4648 675
676 /*
677 * Loop through all of the printers and send local updates as needed...
678 */
679
680 for (p = Printers; p != NULL; p = np)
681 {
682 np = p->next;
683
684 if (p->type & CUPS_PRINTER_REMOTE)
685 {
686 /*
687 * See if this printer needs to be timed out...
688 */
689
f9d6449d 690 if (p->browse_time < to)
e63d9801 691 {
5ea8888e 692 LogMessage(L_INFO, "Remote destination \"%s\" has timed out; deleting it...",
d62e9bdd 693 p->name);
d6de4648 694 DeletePrinter(p);
e63d9801 695 }
d6de4648 696 }
18d7d592 697 else if (p->browse_time < ut && !(p->type & CUPS_PRINTER_IMPLICIT))
d6de4648 698 {
699 /*
700 * Need to send an update...
701 */
702
703 p->browse_time = time(NULL);
704
a2c6b8b1 705 snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n",
706 p->type | CUPS_PRINTER_REMOTE, p->state, p->uri,
707 p->location, p->info, p->make_model);
708
d6de4648 709 bytes = strlen(packet);
8828fd5f 710 DEBUG_printf(("SendBrowseList: (%d bytes) %s", bytes, packet));
d6de4648 711
712 /*
713 * Send a packet to each browse address...
714 */
715
716 for (i = 0; i < NumBrowsers; i ++)
16b0a852 717 if (sendto(BrowseSocket, packet, bytes, 0,
718 (struct sockaddr *)Browsers + i, sizeof(Browsers[0])) <= 0)
f63a2256 719 {
5ea8888e 720 LogMessage(L_ERROR, "SendBrowseList: sendto failed for browser %d - %s.",
fd3ece61 721 i + 1, strerror(errno));
f63a2256 722 LogMessage(L_ERROR, "Browsing turned off.");
723
724 StopBrowsing();
725 Browsing = 0;
726 return;
727 }
d6de4648 728 }
729 }
fd8b1cf8 730}
a129ddbd 731
732
733/*
03081fd2 734 * 'StartPolling()' - Start polling servers as needed.
735 */
736
737void
738StartPolling(void)
739{
e5ebb675 740 int i; /* Looping var */
741 dirsvc_poll_t *poll; /* Current polling server */
742 int pid; /* New process ID */
743 char sport[10]; /* Server port */
744 char bport[10]; /* Browser port */
745 char interval[10]; /* Poll interval */
746
747
748 sprintf(bport, "%d", BrowsePort);
b1ac1113 749
750 if (BrowseInterval)
751 sprintf(interval, "%d", BrowseInterval);
752 else
753 strcpy(interval, "30");
e5ebb675 754
755 for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++)
756 {
757 sprintf(sport, "%d", poll->port);
758
759 if ((pid = fork()) == 0)
760 {
761 /*
762 * Child...
763 */
764
765 setgid(Group);
766 setuid(User);
767
768 execl(CUPS_SERVERBIN "/daemon/cups-polld", "cups-polld", poll->hostname,
769 sport, interval, bport, NULL);
770 exit(errno);
771 }
772 else if (pid < 0)
773 {
774 LogMessage(L_ERROR, "StartPolling: Unable to fork polling daemon - %s",
775 strerror(errno));
776 poll->pid = 0;
777 break;
778 }
779 else
780 {
781 poll->pid = pid;
782 LogMessage(L_DEBUG, "StartPolling: Started polling daemon for %s:%d, pid = %d",
783 poll->hostname, poll->port, pid);
784 }
785 }
03081fd2 786}
787
788
789/*
790 * 'StopPolling()' - Stop polling servers as needed.
791 */
792
793void
794StopPolling(void)
795{
e5ebb675 796 int i; /* Looping var */
797 dirsvc_poll_t *poll; /* Current polling server */
798
799
800 for (i = 0, poll = Polled; i < NumPolled; i ++, poll ++)
801 if (poll->pid)
802 kill(poll->pid, SIGTERM);
03081fd2 803}
804
805
806/*
0c2ea277 807 * End of "$Id: dirsvc.c,v 1.58 2000/09/07 20:34:41 mike Exp $".
a129ddbd 808 */