X-Git-Url: https://git.saurik.com/apple/launchd.git/blobdiff_plain/fc89531ea805ae0e7e8a4fae3760a7c53ac21da7..ed34e3c3e5fb80e0702ac7fb92f189862089d820:/launchd/src/ConsoleMessage.c?ds=inline diff --git a/launchd/src/ConsoleMessage.c b/launchd/src/ConsoleMessage.c deleted file mode 100644 index 30f1cf6..0000000 --- a/launchd/src/ConsoleMessage.c +++ /dev/null @@ -1,327 +0,0 @@ -/** - * ConsoleMessage.c - ConsoleMessage main - * Wilfredo Sanchez | wsanchez@opensource.apple.com - * Kevin Van Vechten | kevinvv@uclink4.berkeley.edu - * $Apple$ - ** - * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.1 (the "License"). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. - * - * The Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - ** - * The ConsoleMessage utility sends an IPC message to SystemStarter - * containing the message specified on the command line. SystemStarter - * will perform the localization. The message is also printed to - * the system log. - **/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "SystemStarterIPC.h" - -static CFDataRef sendIPCMessage(CFStringRef aPortName, CFDataRef aData, CFStringRef aRunLoopMode); - -static void usage() __attribute__((__noreturn__)); -static void -usage() -{ - /* char* aProgram = **_NSGetArgv(); */ - fprintf(stderr, "usage:\n" - "\tConsoleMessage [-v] \n" - "\tConsoleMessage [-v] -S\n" - "\tConsoleMessage [-v] -F\n" - "\tConsoleMessage [-v] -s \n" - "\tConsoleMessage [-v] -f \n" - "\tConsoleMessage [-v] -q \n" - "\tConsoleMessage [-v] -b \n" - "\tConsoleMessage [-v] -u\n" - "\noptions:\n" - "\t-v: verbose (prints errors to stdout)\n" - "\t-S: mark all services as successful\n" - "\t-F: mark all services as failed\n" - "\t-s: mark a specific service as successful\n" - "\t-f: mark a specific service as failed\n" - "\t-q: query a configuration setting\n" - "\t-b: (ignored)\n" - "\t-u: (ignored)\n"); - exit(1); -} - -enum { - kActionConsoleMessage, - kActionSuccess, - kActionFailure, - kActionQuery, -}; - -int -main(int argc, char *argv[]) -{ - int anExitCode = 0; - int aVerboseFlag = 0; - int anAction = kActionConsoleMessage; - char *aProgram = argv[0]; - char *anArgCStr = NULL; - char c; - pid_t w4lw_pid = 0; - FILE *w4lw_f; - - /** - * Handle command line. - **/ - while ((c = getopt(argc, argv, "?vSFs:f:q:b:u")) != -1) { - switch (c) { - case '?': - usage(); - break; - case 'v': - aVerboseFlag = 1; - break; - case 'S': - anAction = kActionSuccess; - anArgCStr = NULL; - break; - case 'F': - anAction = kActionFailure; - anArgCStr = NULL; - break; - case 's': - anAction = kActionSuccess; - anArgCStr = optarg; - break; - case 'f': - anAction = kActionFailure; - anArgCStr = optarg; - break; - case 'q': - anAction = kActionQuery; - anArgCStr = optarg; - break; - case 'b': - exit(EXIT_SUCCESS); - break; - case 'u': - w4lw_f = fopen("/var/run/waiting4loginwindow.pid", "r"); - if (w4lw_f) { - fscanf(w4lw_f, "%d\n", &w4lw_pid); - if (w4lw_pid) - kill(w4lw_pid, SIGTERM); - } - exit(EXIT_SUCCESS); - break; - default: - fprintf(stderr, "ignoring unknown option '-%c'\n", c); - break; - } - } - argc -= optind; - argv += optind; - - if ((anAction == kActionConsoleMessage && argc != 1) || - (anAction == kActionSuccess && argc != 0) || - (anAction == kActionFailure && argc != 0) || - (anAction == kActionQuery && argc != 0)) { - usage(); - } - if (getuid() != 0) { - fprintf(stderr, "you must be root to run %s\n", aProgram); - exit(1); - } else { - CFMutableDictionaryRef anIPCMessage = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - if (anIPCMessage) { - CFStringRef anArg = NULL; - CFIndex aPID = getppid(); - CFNumberRef aPIDNumber = CFNumberCreate(NULL, kCFNumberCFIndexType, &aPID); - - /* - * Parent process id is the process id of the startup - * item that called ConsoleMessage. - */ - CFDictionarySetValue(anIPCMessage, kIPCProcessIDKey, aPIDNumber); - CFRelease(aPIDNumber); - - if (anArgCStr) { - anArg = CFStringCreateWithCString(NULL, anArgCStr, kCFStringEncodingUTF8); - } - if (anAction == kActionSuccess || anAction == kActionFailure) { - CFBooleanRef aStatus = (anAction == kActionSuccess) ? kCFBooleanTrue : kCFBooleanFalse; - CFDictionarySetValue(anIPCMessage, kIPCMessageKey, kIPCStatusMessage); - CFDictionarySetValue(anIPCMessage, kIPCStatusKey, aStatus); - if (anArg) - CFDictionarySetValue(anIPCMessage, kIPCServiceNameKey, anArg); - } else if (anAction == kActionQuery && anArg) { - CFDictionarySetValue(anIPCMessage, kIPCMessageKey, kIPCQueryMessage); - CFDictionarySetValue(anIPCMessage, kIPCConfigSettingKey, anArg); - } else if (anAction == kActionConsoleMessage) { - char *aConsoleMessageCStr = argv[0]; - CFStringRef aConsoleMessage = CFStringCreateWithCString(NULL, aConsoleMessageCStr, kCFStringEncodingUTF8); - - syslog(LOG_INFO, "%s", aConsoleMessageCStr); - - CFDictionarySetValue(anIPCMessage, kIPCMessageKey, kIPCConsoleMessage); - CFDictionarySetValue(anIPCMessage, kIPCConsoleMessageKey, aConsoleMessage); - CFRelease(aConsoleMessage); - } - if (anArg) - CFRelease(anArg); - - { - CFDataRef aData = CFPropertyListCreateXMLData(NULL, anIPCMessage); - if (aData) { - CFDataRef aResultData = sendIPCMessage(CFSTR(kSystemStarterMessagePort), aData, kCFRunLoopDefaultMode); - - /* aResultData should be ASCIZ */ - if (aResultData) { - fprintf(stdout, "%s", CFDataGetBytePtr(aResultData)); - CFRelease(aResultData); - } else { - char *aConsoleMessageCStr = argv[0]; - fprintf(stdout, "%s\n", aConsoleMessageCStr); - - if (aVerboseFlag) - fprintf(stderr, "%s could not connect to SystemStarter.\n", aProgram); - anExitCode = 0; - } - CFRelease(aData); - } else { - if (aVerboseFlag) - fprintf(stderr, "%s: not enough memory to create IPC message.\n", aProgram); - anExitCode = 1; - } - } - } else { - if (aVerboseFlag) - fprintf(stderr, "%s: not enough memory to create IPC message.\n", aProgram); - anExitCode = 1; - } - } - exit(anExitCode); -} - - -static void -dummyCallback(void) -{ -} - -static void replyCallback(CFMachPortRef port __attribute__((unused)), void *aPtr, CFIndex aSize __attribute__((unused)), CFDataRef * aReply) { - SystemStarterIPCMessage *aMessage = (SystemStarterIPCMessage *) aPtr; - - if (aReply != NULL && - aMessage->aProtocol == kIPCProtocolVersion && - aMessage->aByteLength >= 0) { - *aReply = CFDataCreate(NULL, (UInt8 *) aMessage + aMessage->aByteLength, aMessage->aByteLength); - } else if (aReply != NULL) { - *aReply = NULL; - } -} - - -static CFDataRef -sendIPCMessage(CFStringRef aPortName, CFDataRef aData, CFStringRef aRunLoopMode) -{ - SystemStarterIPCMessage *aMessage = NULL; - CFRunLoopSourceRef aSource = NULL; - CFMachPortRef aMachPort = NULL, aReplyPort = NULL; - CFMachPortContext aContext; - kern_return_t aKernReturn = KERN_FAILURE; - mach_port_t aBootstrapPort, aNativePort; - char *aPortNameUTF8String; - CFDataRef aReply = NULL; - SInt32 aStrLen; - - aContext.version = 0; - aContext.info = (void *) NULL; - aContext.retain = 0; - aContext.release = 0; - aContext.copyDescription = 0; - - /* Look up the remote port by name */ - - aStrLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(aPortName) + 1, kCFStringEncodingUTF8); - aPortNameUTF8String = malloc(aStrLen); - if (aPortNameUTF8String) { - CFStringGetCString(aPortName, aPortNameUTF8String, aStrLen, kCFStringEncodingUTF8); - task_get_bootstrap_port(mach_task_self(), &aBootstrapPort); - aKernReturn = bootstrap_look_up(aBootstrapPort, aPortNameUTF8String, &aNativePort); - aMachPort = (KERN_SUCCESS == aKernReturn) ? CFMachPortCreateWithPort(NULL, aNativePort, (CFMachPortCallBack) dummyCallback, &aContext, NULL) : NULL; - free(aPortNameUTF8String); - } - /* Create a reply port and associated run loop source */ - aContext.info = &aReply; - aReplyPort = CFMachPortCreate(NULL, (CFMachPortCallBack) replyCallback, &aContext, NULL); - if (aReplyPort) { - aSource = CFMachPortCreateRunLoopSource(NULL, aReplyPort, 0); - if (aSource) { - CFRunLoopAddSource(CFRunLoopGetCurrent(), aSource, aRunLoopMode); - } - } - /* Allocate a buffer for the message */ - if (aData && aMachPort && aReplyPort) { - SInt32 aSize = (sizeof(SystemStarterIPCMessage) + (CFDataGetLength(aData) + 3)) & ~0x3; - aMessage = (SystemStarterIPCMessage *) malloc(aSize); - if (aMessage) { - aMessage->aHeader.msgh_id = 1; - aMessage->aHeader.msgh_size = aSize; - aMessage->aHeader.msgh_remote_port = CFMachPortGetPort(aMachPort); - aMessage->aHeader.msgh_local_port = CFMachPortGetPort(aReplyPort); - aMessage->aHeader.msgh_reserved = 0; - aMessage->aHeader.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); - aMessage->aBody.msgh_descriptor_count = 0; - aMessage->aProtocol = kIPCProtocolVersion; - aMessage->aByteLength = CFDataGetLength(aData); - memmove((uint8_t *) aMessage + sizeof(SystemStarterIPCMessage), - CFDataGetBytePtr(aData), - CFDataGetLength(aData)); - } - } - /* Wait up to 1 second to send the message */ - if (aMessage) { - aKernReturn = mach_msg((mach_msg_header_t *) aMessage, MACH_SEND_MSG | MACH_SEND_TIMEOUT, aMessage->aHeader.msgh_size, 0, MACH_PORT_NULL, 1000.0, MACH_PORT_NULL); - free(aMessage); - } - /* Wait up to 30 seconds for the reply */ - if (aSource && aKernReturn == MACH_MSG_SUCCESS) { - CFRetain(aReplyPort); - CFRunLoopRunInMode(aRunLoopMode, 30.0, true); - /* - * aReplyPort's replyCallback will set the local aReply - * variable - */ - CFRelease(aReplyPort); - } - if (aMachPort) - CFRelease(aMachPort); - if (aReplyPort) - CFRelease(aReplyPort); - if (aSource) { - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), aSource, aRunLoopMode); - CFRelease(aSource); - } - return aReply; -}