void safe_vproc_transaction_end(void) { if (vproc_transaction_end) { if (transaction) { vproc_transaction_end(NULL, transaction); transaction = NULL; } else LogMsg("safe_vproc_transaction_end: No current transaction"); } }
void cupsdSetBusyState(void) { int newbusy; /* New busy state */ static int busy = 0; /* Current busy state */ static const char * const busy_text[] = { /* Text for busy states */ "Not busy", "Dirty files", "Printing jobs", "Printing jobs and dirty files", "Active clients", "Active clients and dirty files", "Active clients and printing jobs", "Active clients, printing jobs, and dirty files" }; #ifdef HAVE_VPROC_TRANSACTION_BEGIN static vproc_transaction_t vtran = 0; /* Current busy transaction */ #endif /* HAVE_VPROC_TRANSACTION_BEGIN */ newbusy = (DirtyCleanTime ? 1 : 0) | (cupsArrayCount(PrintingJobs) ? 2 : 0) | (cupsArrayCount(ActiveClients) ? 4 : 0); if (newbusy != busy) { busy = newbusy; #ifdef HAVE_VPROC_TRANSACTION_BEGIN if (busy && !vtran) vtran = vproc_transaction_begin(NULL); else if (!busy && vtran) { vproc_transaction_end(NULL, vtran); vtran = 0; } #endif /* HAVE_VPROC_TRANSACTION_BEGIN */ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetBusyState: %s", busy_text[busy]); } }
void cupsdSetBusyState(void) { int i; /* Looping var */ cupsd_job_t *job; /* Current job */ cupsd_printer_t *p; /* Current printer */ int newbusy; /* New busy state */ static int busy = 0; /* Current busy state */ static const char * const busy_text[] = { /* Text for busy states */ "Not busy", "Dirty files", "Printing jobs", "Printing jobs and dirty files", "Active clients", "Active clients and dirty files", "Active clients and printing jobs", "Active clients, printing jobs, and dirty files" }; #ifdef __APPLE__ static vproc_transaction_t vtran = 0; /* Current busy transaction */ static IOPMAssertionID keep_awake = 0;/* Keep the system awake while printing */ #endif /* __APPLE__ */ /* * Figure out how busy we are... */ newbusy = (DirtyCleanTime ? 1 : 0) | (cupsArrayCount(ActiveClients) ? 4 : 0); for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs); job; job = (cupsd_job_t *)cupsArrayNext(PrintingJobs)) { if ((p = job->printer) != NULL) { for (i = 0; i < p->num_reasons; i ++) if (!strcmp(p->reasons[i], "connecting-to-device")) break; if (!p->num_reasons || i >= p->num_reasons) break; } } if (job) newbusy |= 2; cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetBusyState: newbusy=\"%s\", busy=\"%s\"", busy_text[newbusy], busy_text[busy]); /* * Manage state changes... */ if (newbusy != busy) { busy = newbusy; #ifdef __APPLE__ if (busy && !vtran) vtran = vproc_transaction_begin(NULL); else if (!busy && vtran) { vproc_transaction_end(NULL, vtran); vtran = 0; } #endif /* __APPLE__ */ } #ifdef __APPLE__ if (cupsArrayCount(PrintingJobs) > 0 && !keep_awake) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting NetworkClientActive."); IOPMAssertionCreateWithName(kIOPMAssertNetworkClientActive, kIOPMAssertionLevelOn, CFSTR("org.cups.cupsd"), &keep_awake); } else if (cupsArrayCount(PrintingJobs) == 0 && keep_awake) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing power assertion."); IOPMAssertionRelease(keep_awake); keep_awake = 0; } #endif /* __APPLE__ */ }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ int num_defaults; /* Number of default options */ cups_option_t *defaults; /* Default options */ char line[256], /* Command string */ command, /* Command code */ *dest, /* Pointer to destination */ *list, /* Pointer to list */ *agent, /* Pointer to user */ status; /* Status for client */ socklen_t hostlen; /* Size of client address */ http_addr_t hostaddr; /* Address of client */ char hostname[256], /* Name of client */ hostip[256], /* IP address */ *hostfamily; /* Address family */ int hostlookups; /* Do hostname lookups? */ #ifdef __APPLE__ vproc_transaction_t vtran = vproc_transaction_begin(NULL); #endif /* __APPLE__ */ /* * Don't buffer the output... */ setbuf(stdout, NULL); /* * Log things using the "cups-lpd" name... */ openlog("cups-lpd", LOG_PID, LOG_LPR); /* * Scan the command-line for options... */ num_defaults = 0; defaults = NULL; hostlookups = 1; for (i = 1; i < argc; i ++) if (argv[i][0] == '-') { switch (argv[i][1]) { case 'h' : /* -h hostname[:port] */ if (argv[i][2]) cupsSetServer(argv[i] + 2); else { i ++; if (i < argc) cupsSetServer(argv[i]); else syslog(LOG_WARNING, "Expected hostname string after -h option!"); } break; case 'o' : /* Option */ if (argv[i][2]) num_defaults = cupsParseOptions(argv[i] + 2, num_defaults, &defaults); else { i ++; if (i < argc) num_defaults = cupsParseOptions(argv[i], num_defaults, &defaults); else syslog(LOG_WARNING, "Expected option string after -o option!"); } break; case 'n' : /* Don't do hostname lookups */ hostlookups = 0; break; default : syslog(LOG_WARNING, "Unknown option \"%c\" ignored!", argv[i][1]); break; } } else syslog(LOG_WARNING, "Unknown command-line option \"%s\" ignored!", argv[i]); /* * Get the address of the client... */ hostlen = sizeof(hostaddr); if (getpeername(0, (struct sockaddr *)&hostaddr, &hostlen)) { syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno)); strlcpy(hostname, "unknown", sizeof(hostname)); } else { httpAddrString(&hostaddr, hostip, sizeof(hostip)); if (hostlookups) httpAddrLookup(&hostaddr, hostname, sizeof(hostname)); else strlcpy(hostname, hostip, sizeof(hostname)); #ifdef AF_INET6 if (hostaddr.addr.sa_family == AF_INET6) hostfamily = "IPv6"; else #endif /* AF_INET6 */ hostfamily = "IPv4"; syslog(LOG_INFO, "Connection from %s (%s %s)", hostname, hostfamily, hostip); } num_defaults = cupsAddOption("job-originating-host-name", hostname, num_defaults, &defaults); /* * RFC1179 specifies that only 1 daemon command can be received for * every connection. */ if (smart_gets(line, sizeof(line), stdin) == NULL) { /* * Unable to get command from client! Send an error status and return. */ syslog(LOG_ERR, "Unable to get command line from client!"); putchar(1); #ifdef __APPLE__ vproc_transaction_end(NULL, vtran); #endif /* __APPLE__ */ return (1); } /* * The first byte is the command byte. After that will be the queue name, * resource list, and/or user name. */ if ((command = line[0]) == '\0') dest = line; else dest = line + 1; if (command == 0x02) list = NULL; else { for (list = dest; *list && !isspace(*list & 255); list ++); while (isspace(*list & 255)) *list++ = '\0'; } /* * Do the command... */ switch (command) { default : /* Unknown command */ syslog(LOG_ERR, "Unknown LPD command 0x%02X!", command); syslog(LOG_ERR, "Command line = %s", line + 1); putchar(1); status = 1; break; case 0x01 : /* Print any waiting jobs */ syslog(LOG_INFO, "Print waiting jobs (no-op)"); putchar(0); status = 0; break; case 0x02 : /* Receive a printer job */ syslog(LOG_INFO, "Receive print job for %s", dest); /* recv_print_job() sends initial status byte */ status = (char)recv_print_job(dest, num_defaults, defaults); break; case 0x03 : /* Send queue state (short) */ syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list); /* no status byte for this command */ status = (char)send_state(dest, list, 0); break; case 0x04 : /* Send queue state (long) */ syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list); /* no status byte for this command */ status = (char)send_state(dest, list, 1); break; case 0x05 : /* Remove jobs */ if (list) { /* * Grab the agent and skip to the list of users and/or jobs. */ agent = list; for (; *list && !isspace(*list & 255); list ++); while (isspace(*list & 255)) *list++ = '\0'; syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent); status = (char)remove_jobs(dest, agent, list); } else status = 1; putchar(status); break; } syslog(LOG_INFO, "Closing connection"); closelog(); #ifdef __APPLE__ vproc_transaction_end(NULL, vtran); #endif /* __APPLE__ */ return (status); }
int main(int argc, char *argv[]) { register char **sptr = server; register char **cptr = client; register char **ptr; int pid; int client_given = 0, server_given = 0; int client_args_given = 0, server_args_given = 0; int start_of_client_args, start_of_server_args; struct sigaction sa, si; #ifdef __APPLE__ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 vproc_transaction_t vt; #endif #endif program = *argv++; argc--; /* * copy the client args. */ if (argc == 0 || (**argv != '/' && **argv != '.')) { for (ptr = default_client; *ptr; ) *cptr++ = *ptr++; } else { client_given = 1; } start_of_client_args = (cptr - client); while (argc && strcmp(*argv, "--")) { client_args_given++; *cptr++ = *argv++; argc--; } *cptr = NULL; if (argc) { argv++; argc--; } /* * Copy the server args. */ if (argc == 0 || (**argv != '/' && **argv != '.')) { *sptr++ = default_server; } else { server_given = 1; *sptr++ = *argv++; argc--; } if (argc > 0 && (argv[0][0] == ':' && isdigit(argv[0][1]))) displayNum = *argv; else displayNum = *sptr++ = default_display; start_of_server_args = (sptr - server); while (--argc >= 0) { server_args_given++; *sptr++ = *argv++; } *sptr = NULL; /* * if no client arguments given, check for a startup file and copy * that into the argument list */ if (!client_given) { char *cp; Bool required = False; xinitrcbuf[0] = '\0'; if ((cp = getenv("XINITRC")) != NULL) { snprintf(xinitrcbuf, sizeof(xinitrcbuf), "%s", cp); required = True; } else if ((cp = getenv("HOME")) != NULL) { snprintf(xinitrcbuf, sizeof(xinitrcbuf), "%s/%s", cp, XINITRC); } if (xinitrcbuf[0]) { if (access(xinitrcbuf, F_OK) == 0) { client += start_of_client_args - 1; client[0] = xinitrcbuf; } else if (required) { Error("warning, no client init file \"%s\"", xinitrcbuf); } } } /* * if no server arguments given, check for a startup file and copy * that into the argument list */ if (!server_given) { char *cp; Bool required = False; xserverrcbuf[0] = '\0'; if ((cp = getenv("XSERVERRC")) != NULL) { snprintf(xserverrcbuf, sizeof(xserverrcbuf), "%s", cp); required = True; } else if ((cp = getenv("HOME")) != NULL) { snprintf(xserverrcbuf, sizeof(xserverrcbuf), "%s/%s", cp, XSERVERRC); } if (xserverrcbuf[0]) { if (access(xserverrcbuf, F_OK) == 0) { server += start_of_server_args - 1; server[0] = xserverrcbuf; } else if (required) { Error("warning, no server init file \"%s\"", xserverrcbuf); } } } /* * Start the server and client. */ signal(SIGCHLD, SIG_DFL); /* Insurance */ /* Let those signal interrupt the wait() call in the main loop */ memset(&sa, 0, sizeof sa); sa.sa_handler = sigCatch; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* do not set SA_RESTART */ sigaction(SIGTERM, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); memset(&si, 0, sizeof(si)); si.sa_handler = sigIgnore; sigemptyset(&si.sa_mask); si.sa_flags = SA_RESTART; sigaction(SIGALRM, &si, NULL); sigaction(SIGUSR1, &si, NULL); #ifdef __APPLE__ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 vt = vproc_transaction_begin(NULL); #endif #endif if (startServer(server) > 0 && startClient(client) > 0) { pid = -1; while (pid != clientpid && pid != serverpid && gotSignal == 0 ) pid = wait(NULL); } #ifdef __APPLE__ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 vproc_transaction_end(NULL, vt); #endif #endif signal(SIGTERM, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); shutdown(); if (gotSignal != 0) { Errorx("unexpected signal %d", gotSignal); exit(EXIT_FAILURE); } if (serverpid < 0) Fatalx("server error"); if (clientpid < 0) Fatalx("client error"); exit(EXIT_SUCCESS); }
int main(int ac, char *av[]) { char *p = NULL; kern_return_t kr = KERN_FAILURE; long n; int ch; mach_msg_header_t hdr; while ((ch = getopt(ac, av, "dt:")) != -1) switch (ch) { case 'd': opt_debug = 1; break; case 't': n = strtol(optarg, &p, 0); if ('\0' == optarg[0] || '\0' != *p || n > LONG_MAX || n < 0) { fprintf(stderr, "Invalid idle timeout: %s\n", optarg); exit(EXIT_FAILURE); } maxidle = n; break; case '?': default: fprintf(stderr, "Usage: mDNSResponderHelper [-d] [-t maxidle]\n"); exit(EXIT_FAILURE); } ac -= optind; av += optind; initialize_logging(); helplog(ASL_LEVEL_INFO, "Starting"); initialize_id(); #ifndef NO_SECURITYFRAMEWORK // We should normally be running as a system daemon. However, that might not be the case in some scenarios (e.g. debugging). // Explicitly ensure that our Keychain operations utilize the system domain. if (opt_debug) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); #endif gPort = register_service(kmDNSHelperServiceName); if (!gPort) exit(EXIT_FAILURE); if (maxidle) actualidle = maxidle; signal(SIGTERM, handle_sigterm); // We use BeginTransactionAtShutdown in the plist that ensures that we will // receive a SIGTERM during shutdown rather than a SIGKILL. But launchd (due to some // limitation) currently requires us to still start and end the transaction for // its proper initialization. vproc_transaction_t vt = vproc_transaction_begin(NULL); if (vt) vproc_transaction_end(NULL, vt); if (initialize_timer()) exit(EXIT_FAILURE); for (n=0; n<100000; n++) if (!gRunLoop) usleep(100); if (!gRunLoop) { helplog(ASL_LEVEL_ERR, "gRunLoop not set after waiting"); exit(EXIT_FAILURE); } for(;;) { hdr.msgh_bits = 0; hdr.msgh_local_port = gPort; hdr.msgh_remote_port = MACH_PORT_NULL; hdr.msgh_size = sizeof(hdr); hdr.msgh_id = 0; kr = mach_msg(&hdr, MACH_RCV_LARGE | MACH_RCV_MSG, 0, hdr.msgh_size, gPort, 0, 0); if (MACH_RCV_TOO_LARGE != kr) helplog(ASL_LEVEL_ERR, "main MACH_RCV_MSG error: %d %X %s", kr, kr, mach_error_string(kr)); kr = mach_msg_server_once(helper_server, MAX_MSG_SIZE, gPort, MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)); if (KERN_SUCCESS != kr) { helplog(ASL_LEVEL_ERR, "mach_msg_server: %d %X %s", kr, kr, mach_error_string(kr)); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }