/*
- * "$Id: main.c 7925 2008-09-10 17:47:26Z mike $"
+ * "$Id: main.c 11721 2014-03-21 18:18:56Z msweet $"
*
- * Main loop for the CUPS scheduler.
+ * Main loop for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Main entry for the CUPS scheduler.
- * cupsdAddString() - Copy and add a string to an array.
- * cupsdCheckProcess() - Tell the main loop to check for dead children.
- * cupsdClearString() - Clear a string.
- * cupsdFreeStrings() - Free an array of strings.
- * cupsdHoldSignals() - Hold child and termination signals.
- * cupsdReleaseSignals() - Release signals for delivery.
- * cupsdSetString() - Set a string value.
- * cupsdSetStringf() - Set a formatted string value.
- * launchd_checkin() - Check-in with launchd and collect the listening
- * fds.
- * launchd_checkout() - Update the launchd KeepAlive file as needed.
- * parent_handler() - Catch USR1/CHLD signals...
- * process_children() - Process all dead children...
- * select_timeout() - Calculate the select timeout value.
- * sigchld_handler() - Handle 'child' signals from old processes.
- * sighup_handler() - Handle 'hangup' signals to reconfigure the
- * scheduler.
- * sigterm_handler() - Handle 'terminate' signals that stop the scheduler.
- * usage() - Show scheduler usage.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
# include <malloc.h>
#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+
#ifdef HAVE_NOTIFY_H
# include <notify.h>
#endif /* HAVE_NOTIFY_H */
+#ifdef HAVE_DBUS
+# include <dbus/dbus.h>
+#endif /* HAVE_DBUS */
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
/*
* Local functions...
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-#ifdef __sgi
- cups_file_t *fp; /* Fake lpsched lock file */
- struct stat statbuf; /* Needed for checking lpsched FIFO */
-#endif /* __sgi */
int run_as_child = 0;
/* Needed for background fork/exec */
#ifdef __APPLE__
int launchd_idle_exit;
/* Idle exit on select timeout? */
#endif /* HAVE_LAUNCHD */
-#ifdef HAVE_AVAHI
- cupsd_timeout_t *tmo; /* Next scheduled timed callback */
- long tmo_delay; /* Time before it must be called */
-#endif /* HAVE_AVAHI */
#ifdef HAVE_GETEUID
char *current; /* Current directory */
-
/*
* Allocate a buffer for the current working directory to
* reduce run-time stack usage; this approximates the
UseProfiles = 0;
break;
+ case 's' : /* Set cups-files.conf location */
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, _("cupsd: Expected cups-files.conf "
+ "filename after \"-s\" option."));
+ usage(1);
+ }
+
+ if (argv[i][0] != '/')
+ {
+ /*
+ * Relative filename not allowed...
+ */
+
+ _cupsLangPuts(stderr, _("cupsd: Relative cups-files.conf "
+ "filename not allowed."));
+ usage(1);
+ }
+
+ cupsdSetString(&CupsFilesFile, argv[i]);
+ break;
+
#ifdef __APPLE__
case 'S' : /* Disable system management functions */
fputs("cupsd: -S (disable system management) for internal "
if (!ConfigurationFile)
cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");
+ if (!CupsFilesFile)
+ {
+ char *filename, /* Copy of cupsd.conf filename */
+ *slash; /* Final slash in cupsd.conf filename */
+ size_t len; /* Size of buffer */
+
+ len = strlen(ConfigurationFile) + 15;
+ if ((filename = malloc(len)) == NULL)
+ {
+ _cupsLangPrintf(stderr,
+ _("cupsd: Unable to get path to "
+ "cups-files.conf file."));
+ return (1);
+ }
+
+ strlcpy(filename, ConfigurationFile, len);
+ if ((slash = strrchr(filename, '/')) == NULL)
+ {
+ _cupsLangPrintf(stderr,
+ _("cupsd: Unable to get path to "
+ "cups-files.conf file."));
+ return (1);
+ }
+
+ strlcpy(slash, "/cups-files.conf", len - (slash - filename));
+ cupsdSetString(&CupsFilesFile, filename);
+ free(filename);
+ }
+
/*
* If the user hasn't specified "-f", run in the background...
*/
}
}
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) && OpenBSD < 201211
/*
* Call _thread_sys_closefrom() so the child process doesn't reset the
* parent's file descriptors to be blocking. This is a workaround for a
- * limitation of userland libpthread on OpenBSD.
+ * limitation of userland libpthread on older versions of OpenBSD.
*/
_thread_sys_closefrom(0);
-#endif /* __OpenBSD__ */
+#endif /* __OpenBSD__ && OpenBSD < 201211 */
/*
* Since CoreFoundation and DBUS both create fork-unsafe data on execution of
setlocale(LC_TIME, "");
#endif /* LC_TIME */
+#ifdef HAVE_DBUS_THREADS_INIT
+ /*
+ * Enable threading support for D-BUS...
+ */
+
+ dbus_threads_init_default();
+#endif /* HAVE_DBUS_THREADS_INIT */
+
/*
* Set the maximum number of files...
*/
*/
if (!cupsdReadConfiguration())
- {
- if (TestConfigFile)
- printf("%s contains errors\n", ConfigurationFile);
- else
- syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
- ConfigurationFile);
return (1);
- }
else if (TestConfigFile)
{
- printf("%s is OK\n", ConfigurationFile);
+ printf("\"%s\" is OK.\n", CupsFilesFile);
+ printf("\"%s\" is OK.\n", ConfigurationFile);
return (0);
}
signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */
-#ifdef __sgi
- /*
- * Try to create a fake lpsched lock file if one is not already there.
- * Some Adobe applications need it under IRIX in order to enable
- * printing...
- */
-
- if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
- {
- syslog(LOG_LPR, "Unable to create fake lpsched lock file "
- "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
- strerror(errno));
- }
- else
- {
- fchmod(cupsFileNumber(fp), 0644);
- fchown(cupsFileNumber(fp), User, Group);
-
- cupsFileClose(fp);
- }
-#endif /* __sgi */
-
/*
* Initialize authentication certificates...
*/
* Got an error from select!
*/
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
cupsd_printer_t *p; /* Current printer */
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
if (errno == EINTR) /* Just interrupted by a signal */
job->print_pipes[0], job->print_pipes[1],
job->back_pipes[0], job->back_pipes[1]);
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name,
p->reg_name ? p->reg_name : "(null)");
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
break;
}
}
#endif /* __APPLE__ */
-#ifdef HAVE_AVAHI
- /*
- * If a timed callback is due, run it.
- */
-
- tmo = cupsdNextTimeout(&tmo_delay);
- if (tmo && tmo_delay == 0)
- cupsdRunTimeout(tmo);
-#endif /* HAVE_AVAHI */
-
#ifndef __APPLE__
/*
* Update the network interfaces once a minute...
*/
cupsdDeleteCert(0);
- cupsdAddCert(0, "root", NULL);
+ cupsdAddCert(0, "root", cupsdDefaultAuthType());
}
#endif /* !HAVE_AUTHORIZATION_H */
cupsdStopSystemMonitor();
#endif /* __APPLE__ */
-#ifdef HAVE_GSSAPI
- /*
- * Free the scheduler's Kerberos context...
- */
-
-# ifdef __APPLE__
- /*
- * If the weak-linked GSSAPI/Kerberos library is not present, don't try
- * to use it...
- */
-
- if (krb5_init_context != NULL)
-# endif /* __APPLE__ */
- if (KerberosContext)
- krb5_free_context(KerberosContext);
-#endif /* HAVE_GSSAPI */
-
-#ifdef __sgi
- /*
- * Remove the fake IRIX lpsched lock file, but only if the existing
- * file is not a FIFO which indicates that the real IRIX lpsched is
- * running...
- */
-
- if (!stat("/var/spool/lp/FIFO", &statbuf))
- if (!S_ISFIFO(statbuf.st_mode))
- unlink("/var/spool/lp/SCHEDLOCK");
-#endif /* __sgi */
-
cupsdStopSelect();
return (!stop_scheduler);
const char *f, /* I - Printf-style format string */
...) /* I - Additional args as needed */
{
- char v[4096]; /* Formatting string value */
+ char v[65536 + 64]; /* Formatting string value */
va_list ap; /* Argument pointer */
char *olds; /* Old string */
lis->fd = fd;
# ifdef HAVE_SSL
- if (_httpAddrPort(&(lis->address)) == 443)
+ if (httpAddrPort(&(lis->address)) == 443)
lis->encryption = HTTP_ENCRYPT_ALWAYS;
# endif /* HAVE_SSL */
}
}
if (status && status != SIGTERM && status != SIGKILL &&
- status != SIGPIPE && job->status >= 0)
+ status != SIGPIPE)
{
/*
* An error occurred; save the exit status so we know to stop
*
* A negative status indicates that the backend failed and the
* printer needs to be stopped.
+ *
+ * In order to preserve the most serious status, we always log
+ * when a process dies due to a signal (e.g. SIGABRT, SIGSEGV,
+ * and SIGBUS) and prefer to log the backend exit status over a
+ * filter's.
*/
- if (job->filters[i])
- job->status = status; /* Filter failed */
- else
- job->status = -status; /* Backend failed */
+ int old_status = abs(job->status);
+
+ if (WIFSIGNALED(status) || /* This process crashed, or */
+ !job->status || /* No process had a status, or */
+ (!job->filters[i] && WIFEXITED(old_status)))
+ { /* Backend and filter didn't crash */
+ if (job->filters[i])
+ job->status = status; /* Filter failed */
+ else
+ job->status = -status; /* Backend failed */
+ }
if (job->state_value == IPP_JOB_PROCESSING &&
job->status_level > CUPSD_LOG_ERROR &&
cupsd_job_t *job; /* Job information */
cupsd_subscription_t *sub; /* Subscription information */
const char *why; /* Debugging aid */
-#ifdef HAVE_AVAHI
- cupsd_timeout_t *tmo; /* Timed callback */
- long tmo_delay; /* Seconds before calling it */
-#endif /* HAVE_AVAHI */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: JobHistoryUpdate=%ld",
}
#endif /* __APPLE__ */
-#ifdef HAVE_AVAHI
- /*
- * See if there are any scheduled timed callbacks to run.
- */
-
- if ((tmo = cupsdNextTimeout(&tmo_delay)) != NULL &&
- (now + tmo_delay) < timeout)
- {
- timeout = tmo_delay;
- why = "run a timed callback";
- }
-#endif /* HAVE_AVAHI */
-
/*
* Check whether we are accepting new connections...
*/
_cupsLangPuts(fp, _("Usage: cupsd [options]"));
_cupsLangPuts(fp, _("Options:"));
- _cupsLangPuts(fp, _(" -c config-file Load alternate configuration "
- "file."));
+ _cupsLangPuts(fp, _(" -c cupsd.conf Set cupsd.conf file to use."));
_cupsLangPuts(fp, _(" -f Run in the foreground."));
_cupsLangPuts(fp, _(" -F Run in the foreground but "
"detach from console."));
/*
- * End of "$Id: main.c 7925 2008-09-10 17:47:26Z mike $".
+ * End of "$Id: main.c 11721 2014-03-21 18:18:56Z msweet $".
*/