diff -urN cups-1.3.10/scheduler/conf.c cups-1.3.10-xined/scheduler/conf.c --- cups-1.3.10/scheduler/conf.c 2009-04-17 03:32:04.000000000 +0800 +++ cups-1.3.10-xined/scheduler/conf.c 2009-04-27 14:02:29.000000000 +0800 @@ -116,6 +116,7 @@ { "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING }, #endif /* HAVE_GSSAPI */ { "HideImplicitMembers", &HideImplicitMembers, CUPSD_VARTYPE_BOOLEAN }, + { "IdleTimeout", &IdleTimeout, CUPSD_VARTYPE_INTEGER }, { "ImplicitClasses", &ImplicitClasses, CUPSD_VARTYPE_BOOLEAN }, { "ImplicitAnyClasses", &ImplicitAnyClasses, CUPSD_VARTYPE_BOOLEAN }, { "JobRetryLimit", &JobRetryLimit, CUPSD_VARTYPE_INTEGER }, @@ -123,7 +124,7 @@ { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_INTEGER }, { "KeepAlive", &KeepAlive, CUPSD_VARTYPE_BOOLEAN }, #ifdef HAVE_LAUNCHD - { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_INTEGER }, + { "LaunchdTimeout", &IdleTimeout, CUPSD_VARTYPE_INTEGER }, { "LaunchdConf", &LaunchdConf, CUPSD_VARTYPE_STRING }, #endif /* HAVE_LAUNCHD */ { "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER }, @@ -610,9 +611,10 @@ MaxSubscriptionsPerUser = 0; DefaultLeaseDuration = 86400; MaxLeaseDuration = 0; + IdleTimeout = DEFAULT_TIMEOUT + 10; + #ifdef HAVE_LAUNCHD - LaunchdTimeout = DEFAULT_TIMEOUT + 10; cupsdSetString(&LaunchdConf, CUPS_DEFAULT_LAUNCHD_CONF); #endif /* HAVE_LAUNCHD */ diff -urN cups-1.3.10/scheduler/conf.h cups-1.3.10-xined/scheduler/conf.h --- cups-1.3.10/scheduler/conf.h 2009-04-17 03:32:04.000000000 +0800 +++ cups-1.3.10-xined/scheduler/conf.h 2009-04-27 14:02:29.000000000 +0800 @@ -206,9 +206,9 @@ # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ #endif /* HAVE_SSL */ -#ifdef HAVE_LAUNCHD -VAR int LaunchdTimeout VALUE(DEFAULT_TIMEOUT); +VAR int IdleTimeout VALUE(DEFAULT_TIMEOUT); /* Time after which an idle cupsd will exit */ +#ifdef HAVE_LAUNCHD VAR char *LaunchdConf VALUE(NULL); /* launchd(8) configuration file */ #endif /* HAVE_LAUNCHD */ diff -urN cups-1.3.10/scheduler/cupsd.h cups-1.3.10-xined/scheduler/cupsd.h --- cups-1.3.10/scheduler/cupsd.h 2008-02-16 07:26:51.000000000 +0800 +++ cups-1.3.10-xined/scheduler/cupsd.h 2009-04-27 14:02:29.000000000 +0800 @@ -140,6 +140,13 @@ #define RELOAD_ALL 1 /* Reload everything */ #define RELOAD_CUPSD 2 /* Reload only cupsd.conf */ +/* Ondemand types ... + * + */ +#define ONDEMAND_NONE 0 /* Not started ondemand */ +#define ONDEMAND_LAUNCHD 1 /* Started by launchd */ +#define ONDEMAND_XINETD 2 /* Started by xinetd */ + /* * Select callback function type... @@ -165,10 +172,8 @@ /* Kerberos context for credentials */ #endif /* HAVE_GSSAPI */ -#ifdef HAVE_LAUNCH_H -VAR int Launchd VALUE(0); - /* Running from launchd */ -#endif /* HAVE_LAUNCH_H */ +VAR int ondemand VALUE(ONDEMAND_NONE); + /* Running from xinetd or launchd */ #if defined(__APPLE__) && defined(HAVE_DLFCN_H) typedef int (*PSQUpdateQuotaProcPtr)(const char *printer, const char *info, diff -urN cups-1.3.10/scheduler/main.c cups-1.3.10-xined/scheduler/main.c --- cups-1.3.10/scheduler/main.c 2009-01-29 06:12:18.000000000 +0800 +++ cups-1.3.10-xined/scheduler/main.c 2009-04-27 14:02:29.000000000 +0800 @@ -77,7 +77,7 @@ /* * Local functions... */ - +static void xinetd_checkin(void); #ifdef HAVE_LAUNCHD static void launchd_checkin(void); static void launchd_checkout(void); @@ -150,10 +150,8 @@ #else time_t netif_time = 0; /* Time since last network update */ #endif /* __APPLE__ */ -#if HAVE_LAUNCHD - int launchd_idle_exit; + int idle_exit; /* Idle exit on select timeout? */ -#endif /* HAVE_LAUNCHD */ #ifdef HAVE_GETEUID @@ -174,10 +172,17 @@ fg = 0; + if (getenv("CUPSD_XINETD")) + { + ondemand = ONDEMAND_XINETD; + fg = 1; + } + + #ifdef HAVE_LAUNCHD if (getenv("CUPSD_LAUNCHD")) { - Launchd = 1; + ondemand = ONDEMAND_LAUNCHD; fg = 1; } #endif /* HAVE_LAUNCHD */ @@ -260,7 +265,7 @@ case 'l' : /* Started by launchd... */ #ifdef HAVE_LAUNCHD - Launchd = 1; + ondemand = ONDEMAND_LAUNCHD; fg = 1; #else _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled " @@ -275,6 +280,11 @@ fg = 1; break; + case 'x' : /*Started by xinetd */ + ondemand = ONDEMAND_XINETD; + fg = 1; + break; + default : /* Unknown option */ _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - " "aborting!\n"), *opt); @@ -485,8 +495,17 @@ TempDir, strerror(errno)); } + if (ondemand == ONDEMAND_XINETD) + { + /* + * If we were started by xinetd get the listen sockets file descriptors... + */ + xinetd_checkin(); + } + + #if HAVE_LAUNCHD - if (Launchd) + if (ondemand == ONDEMAND_LAUNCHD) { /* * If we were started by launchd get the listen sockets file descriptors... @@ -636,9 +655,12 @@ /* * Send server-started event... */ - + if (ondemand == ONDEMAND_XINETD) + cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, + "Scheduler started via xinetd."); + else #ifdef HAVE_LAUNCHD - if (Launchd) + if (ondemand == ONDEMAND_LAUNCHD) cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started via launchd."); else @@ -741,9 +763,17 @@ ConfigurationFile); break; } + if (ondemand == ONDEMAND_XINETD) + { + /* + * If we were started by xinetd get the listen sockets file descriptors... + */ + xinetd_checkin(); + } + #if HAVE_LAUNCHD - if (Launchd) + if (ondemand == ONDEMAND_LAUNCHD) { /* * If we were started by launchd get the listen sockets file descriptors... @@ -780,26 +810,23 @@ if ((timeout = select_timeout(fds)) > 1 && LastEvent) timeout = 1; -#if HAVE_LAUNCHD /* * If no other work is scheduled and we're being controlled by - * launchd then timeout after 'LaunchdTimeout' seconds of + * launchd then timeout after 'IdleTimeout' seconds of * inactivity... */ - - if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled && + if (timeout == 86400 && ondemand != ONDEMAND_NONE && IdleTimeout && !NumPolled && !cupsArrayCount(ActiveJobs) && (!Browsing || (!BrowseRemoteProtocols && (!NumBrowsers || !BrowseLocalProtocols || cupsArrayCount(Printers) == 0)))) { - timeout = LaunchdTimeout; - launchd_idle_exit = 1; + timeout = IdleTimeout; + idle_exit = 1; } else - launchd_idle_exit = 0; -#endif /* HAVE_LAUNCHD */ + idle_exit = 0; if ((fds = cupsdDoSelect(timeout)) < 0) { @@ -877,13 +904,12 @@ } #endif /* !__APPLE__ */ -#if HAVE_LAUNCHD /* * If no other work was scheduled and we're being controlled by launchd - * then timeout after 'LaunchdTimeout' seconds of inactivity... + * then timeout after 'IdleTimeout' seconds of inactivity... */ - if (!fds && launchd_idle_exit) + if (!fds && idle_exit) { cupsdLogMessage(CUPSD_LOG_INFO, "Printer sharing is off and there are no jobs pending, " @@ -891,7 +917,6 @@ stop_scheduler = 1; break; } -#endif /* HAVE_LAUNCHD */ /* * Resume listening for new connections as needed... @@ -1380,6 +1405,98 @@ _cupsStrFree(olds); } +static void +xinetd_checkin(void) +{ + int portnum; /* Port number */ + cupsd_listener_t *lis; /* Listeners array */ + http_addr_t addr; /* Address variable */ + socklen_t addrlen; /* Length of address */ + int fd; /* File descriptor */ + char s[256]; /* String addresss */ + + cupsdLogMessage(CUPSD_LOG_INFO, "xinetd_checkin: pid=%d", (int)getpid()); + /* + * xinetd passes the socket on stdin/stdout/stderr. + * Set stdout/stderr to something more sensible. + */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + /* + * Get the socket + */ + + fd = 0; + addrlen = sizeof(addr); + if (getsockname(fd, (struct sockaddr *)&addr, &addrlen)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "xinetd_checkin: Unable to get local address - %s", + strerror(errno)); + return; + } + + /* + * Try to match the xinetd socket address to one of the listeners... + */ + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + if (httpAddrEqual(&lis->address, &addr)) + break; + + /* + * Add a new listener If there's no match... + */ + + if (lis) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "xinetd_checkin: Matched existing listener %s with fd %d...", + httpAddrString(&(lis->address), s, sizeof(s)), fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_INFO, + "xinetd_checkin: Adding new listener %s with fd %d...", + httpAddrString(&addr, s, sizeof(s)), fd); + + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "xinetd_checkin: Unable to allocate listener - %s.", + strerror(errno)); + exit(EXIT_FAILURE); + } + + cupsArrayAdd(Listeners, lis); + + memcpy(&lis->address, &addr, sizeof(lis->address)); + } + + lis->fd = fd; + +# ifdef HAVE_SSL + portnum = 0; + +# ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + portnum = ntohs(lis->address.ipv6.sin6_port); + else +# endif /* AF_INET6 */ + if (lis->address.addr.sa_family == AF_INET) + portnum = ntohs(lis->address.ipv4.sin_port); + + if (portnum == 443) + lis->encryption = HTTP_ENCRYPT_ALWAYS; +# endif /* HAVE_SSL */ +} + + + #ifdef HAVE_LAUNCHD /* @@ -2012,7 +2129,9 @@ "-f Run in the foreground\n" "-F Run in the foreground but detach\n" "-h Show this usage message\n" - "-l Run cupsd from launchd(8)\n")); + "-l Run cupsd from launchd(8)\n" + "-x Run cupsd from xinetd(8)\n")); + exit(status); }