+++ /dev/null
-/*
- * Copyright (c) 2003-2004,2006-2007,2009-2010,2012-2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * authz.c
- */
-
-#include <getopt.h>
-#include <stdio.h>
-#include <Security/AuthorizationPriv.h>
-#include <utilities/SecCFRelease.h>
-
-#include "authz.h"
-#include "security_tool.h"
-
-// AEWP?
-
-static AuthorizationRef
-read_auth_ref_from_stdin()
-{
- AuthorizationRef auth_ref = NULL;
- AuthorizationExternalForm extform;
- ssize_t bytes_read;
-
- while (kAuthorizationExternalFormLength != (bytes_read = read(STDIN_FILENO, &extform, kAuthorizationExternalFormLength)))
- {
- if ((bytes_read == -1) && ((errno != EAGAIN) || (errno != EINTR)))
- break;
- }
- if (bytes_read != kAuthorizationExternalFormLength)
- fprintf(stderr, "ERR: Failed to read authref\n");
- else
- if (AuthorizationCreateFromExternalForm(&extform, &auth_ref))
- fprintf(stderr, "ERR: Failed to internalize authref\n");
-
- close(0);
-
- return auth_ref;
-}
-
-static int
-write_auth_ref_to_stdout(AuthorizationRef auth_ref)
-{
- AuthorizationExternalForm extform;
- ssize_t bytes_written;
-
- if (AuthorizationMakeExternalForm(auth_ref, &extform))
- return -1;
-
- while (kAuthorizationExternalFormLength != (bytes_written = write(STDOUT_FILENO, &extform, kAuthorizationExternalFormLength)))
- {
- if ((bytes_written == -1) && ((errno != EAGAIN) || (errno != EINTR)))
- break;
- }
-
- if (bytes_written == kAuthorizationExternalFormLength)
- return 0;
-
- return -1;
-}
-
-static void
-write_dict_to_stdout(CFDictionaryRef dict)
-{
- if (!dict)
- return;
-
- CFDataRef right_definition_xml = CFPropertyListCreateXMLData(NULL, dict);
-
- if (!right_definition_xml)
- return;
-
- write(STDOUT_FILENO, CFDataGetBytePtr(right_definition_xml), CFDataGetLength(right_definition_xml));
- CFRelease(right_definition_xml);
-}
-
-static CFDictionaryRef CF_RETURNS_RETAINED
-read_dict_from_stdin()
-{
- ssize_t bytes_read = 0;
- uint8_t buffer[4096];
- CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
- CFErrorRef err = NULL;
-
- if (!data)
- return NULL;
-
- while ((bytes_read = read(STDIN_FILENO, (void *)buffer, sizeof(buffer))))
- {
- if (bytes_read == -1)
- break;
- else
- CFDataAppendBytes(data, buffer, bytes_read);
- }
-
- CFDictionaryRef right_dict = (CFDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, &err);
- CFRelease(data);
-
- if (NULL == right_dict) {
- CFShow(err);
- return NULL;
- }
-
- if (CFGetTypeID(right_dict) != CFDictionaryGetTypeID())
- {
- fprintf(stderr, "This is not a dictionary.\n");
- CFRelease(right_dict);
- return NULL;
- }
- return right_dict;
-}
-
-static CFPropertyListRef CF_RETURNS_RETAINED
-read_plist_from_file(CFStringRef filePath)
-{
- CFTypeRef property = NULL;
- CFPropertyListRef propertyList = NULL;
- CFURLRef fileURL = NULL;
- CFErrorRef errorString = NULL;
- CFDataRef resourceData = NULL;
- Boolean status = FALSE;
- SInt32 errorCode = -1;
-
- // Convert the path to a URL.
- fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath, kCFURLPOSIXPathStyle, false);
- if (NULL == fileURL) {
- goto bail;
- }
- property = CFURLCreatePropertyFromResource(kCFAllocatorDefault, fileURL, kCFURLFileExists, NULL);
- if (NULL == property) {
- goto bail;
- }
- status = CFBooleanGetValue(property);
- if (!status) {
- fprintf(stderr, "The file does not exist.\n");
- goto bail;
- }
-
- // Read the XML file.
- status = CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode);
- if (!status) {
- fprintf(stderr, "Error (%d) reading the file.\n", (int)errorCode);
- goto bail;
- }
-
- // Reconstitute the dictionary using the XML data.
- propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, resourceData, kCFPropertyListImmutable, NULL, &errorString);
- if (NULL == propertyList) {
- CFShow(errorString);
- goto bail;
- }
-
- // Some error checking.
- if (!CFPropertyListIsValid(propertyList, kCFPropertyListXMLFormat_v1_0) || CFGetTypeID(propertyList) != CFDictionaryGetTypeID()) {
- fprintf(stderr, "The file is invalid.\n");
- CFRelease(propertyList);
- propertyList = NULL;
- goto bail;
- }
-
-bail:
- if (NULL != fileURL)
- CFRelease(fileURL);
- if (NULL != property)
- CFRelease(property);
- if (NULL != resourceData)
- CFRelease(resourceData);
-
- return propertyList;
-}
-
-static Boolean
-write_plist_to_file(CFPropertyListRef propertyList, CFStringRef filePath)
-{
- CFTypeRef property = NULL;
- CFURLRef fileURL = NULL;
- CFDataRef xmlData = NULL;
- Boolean status = FALSE;
- SInt32 errorCode = -1;
- CFErrorRef errorRef = NULL;
-
- // Convert the path to a URL.
- fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath, kCFURLPOSIXPathStyle, false);
- if (NULL == fileURL) {
- goto bail;
- }
- property = CFURLCreatePropertyFromResource(kCFAllocatorDefault, fileURL, kCFURLFileExists, NULL);
- if (NULL == property) {
- goto bail;
- }
- if (!CFBooleanGetValue(property)) {
- fprintf(stderr, "The file does not exist.\n");
- goto bail;
- }
-
- // Convert the property list into XML data.
- xmlData = CFPropertyListCreateData(kCFAllocatorDefault, propertyList, kCFPropertyListXMLFormat_v1_0, 0, &errorRef);
- if (errorRef) {
- fprintf(stderr, "The file could not be written.\n");
- goto bail;
- }
-
- // Write the XML data to the file.
- if (!CFURLWriteDataAndPropertiesToResource(fileURL, xmlData, NULL, &errorCode)) {
- fprintf(stderr, "The file could not be written.\n");
- goto bail;
- }
-
- status = TRUE;
-bail:
- CFReleaseNull(property);
- if (NULL != xmlData)
- CFRelease(xmlData);
- if (NULL != fileURL)
- CFRelease(fileURL);
-
- return status;
-}
-
-static void merge_dictionaries(const void *key, const void *value, void *mergeDict)
-{
- CFDictionarySetValue(mergeDict, key, value);
-}
-
-int
-authorizationdb(int argc, char * const * argv)
-{
- AuthorizationRef auth_ref = NULL;
- int ch;
- while ((ch = getopt(argc, argv, "i")) != -1)
- {
- switch (ch)
- {
- case 'i':
- auth_ref = read_auth_ref_from_stdin();
- break;
- case '?':
- default:
- return SHOW_USAGE_MESSAGE;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- return SHOW_USAGE_MESSAGE; // required right parameter(s)
-
- OSStatus status;
-
- if (argc > 1)
- {
- if (!auth_ref && AuthorizationCreate(NULL, NULL, 0, &auth_ref))
- return -1;
-
- if (!strcmp("read", argv[0]))
- {
- CFDictionaryRef right_definition;
- status = AuthorizationRightGet(argv[1], &right_definition);
- if (!status)
- {
- write_dict_to_stdout(right_definition);
- CFRelease(right_definition);
- }
- }
- else if (!strcmp("write", argv[0]))
- {
- if (argc == 2)
- {
- CFDictionaryRef right_definition = read_dict_from_stdin();
- if (!right_definition)
- return -1;
- status = AuthorizationRightSet(auth_ref, argv[1], right_definition, NULL, NULL, NULL);
- CFRelease(right_definition);
- }
- else if (argc == 3)
- {
- // argv[2] is shortcut string
- CFStringRef shortcut_definition = CFStringCreateWithCStringNoCopy(NULL, argv[2], kCFStringEncodingUTF8, kCFAllocatorNull);
- if (!shortcut_definition)
- return -1;
- status = AuthorizationRightSet(auth_ref, argv[1], shortcut_definition, NULL, NULL, NULL);
- CFRelease(shortcut_definition);
- }
- else
- return SHOW_USAGE_MESSAGE; // take one optional argument - no more
-
- }
- else if (!strcmp("remove", argv[0]))
- {
- status = AuthorizationRightRemove(auth_ref, argv[1]);
- }
- else if (!strcmp("smartcard", argv[0]))
- {
- if (argc == 2)
- {
- if(!strcmp("status", argv[1]))
- {
- const CFStringRef SMARTCARD_LINE = CFSTR("builtin:smartcard-sniffer,privileged");
- const CFStringRef MECHANISMS = CFSTR("mechanisms");
- const CFStringRef BUILTIN_LINE = CFSTR("builtin:policy-banner");
- const char* SYSTEM_LOGIN_CONSOLE = "system.login.console";
- const char* AUTHENTICATE = "authenticate";
-
- CFIndex requiredLine1 = -1;
- CFIndex requiredLine2 = -1;
-
- CFDictionaryRef right_definition;
- status = AuthorizationRightGet(SYSTEM_LOGIN_CONSOLE, &right_definition);
- if(!status)
- {
- CFArrayRef mechanisms;
-
- Boolean res = CFDictionaryGetValueIfPresent(right_definition, MECHANISMS, (void*)&mechanisms);
- if(res)
- {
- // now parse all array elements until "builtin:policy-banner" is found
- CFIndex c = CFArrayGetCount(mechanisms);
- CFStringRef mechanismName;
-
- for (CFIndex i = 0; i < c; ++i)
- {
- mechanismName = CFArrayGetValueAtIndex(mechanisms, i);
- if(CFStringCompare(mechanismName, BUILTIN_LINE, 0) == kCFCompareEqualTo)
- {
- if(i + 1 < c)
- {
- mechanismName = CFArrayGetValueAtIndex(mechanisms, i + 1);
- if(CFStringCompare(mechanismName, SMARTCARD_LINE, 0) == kCFCompareEqualTo)
- {
- requiredLine1 = i + 1;
- }
- break;
- }
- }
- }
- }
- CFRelease(right_definition);
- }
- status = AuthorizationRightGet(AUTHENTICATE, &right_definition);
- if(!status)
- {
- CFArrayRef mechanisms;
-
- Boolean res = CFDictionaryGetValueIfPresent(right_definition, MECHANISMS, (void*)&mechanisms);
- if(res)
- {
- // now parse all array elements until "builtin:policy-banner" is found
- CFIndex c = CFArrayGetCount(mechanisms);
- CFStringRef mechanismName;
-
- if(c > 0)
- {
- mechanismName = CFArrayGetValueAtIndex(mechanisms, 0);
- if(CFStringCompare(mechanismName, SMARTCARD_LINE, 0) == kCFCompareEqualTo)
- {
- requiredLine2 = 0;
- }
- }
- }
- CFRelease(right_definition);
- }
- printf("Current smartcard login state: %s (system.login.console %s, authentication rule %s)\n", requiredLine1 != -1 && requiredLine2 != -1 ?"enabled":"disabled", requiredLine1 != -1 ? "enabled":"disabled", requiredLine2 != -1 ? "enabled":"disabled");
-
- }
- else if(!strcmp("disable", argv[1]))
- status = AuthorizationEnableSmartCard(auth_ref, FALSE);
- else if(!strcmp("enable", argv[1]))
- status = AuthorizationEnableSmartCard(auth_ref, TRUE);
- else
- return SHOW_USAGE_MESSAGE; // unrecognized parameter
- }
- else
- return SHOW_USAGE_MESSAGE; // required parameter missing
- }
- else if (!strcmp("merge", argv[0])) {
- status = 1;
- CFStringRef sourcePath = NULL;
- CFStringRef destPath = NULL;
- CFPropertyListRef sourcePlist = NULL;
- CFPropertyListRef destPlist = NULL;
- CFDictionaryRef sourceRights = NULL;
- CFDictionaryRef sourceRules = NULL;
- CFDictionaryRef destRights = NULL;
- CFDictionaryRef destRules = NULL;
- CFIndex rightsCount = 0;
- CFIndex rulesCount = 0;
- CFMutableDictionaryRef mergeRights = NULL;
- CFMutableDictionaryRef mergeRules = NULL;
- CFMutableDictionaryRef outDict = NULL;
-
- if (argc < 2 || argc > 3)
- return SHOW_USAGE_MESSAGE;
-
- if (!strcmp("-", argv[1])) {
- // Merging from <STDIN>.
- sourcePlist = read_dict_from_stdin();
- } else {
- sourcePath = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
- if (NULL == sourcePath) {
- goto bail;
- }
- sourcePlist = read_plist_from_file(sourcePath);
- }
- if (NULL == sourcePlist)
- goto bail;
- if (argc == 2) {
- // Merging to /etc/authorization.
- destPath = CFStringCreateWithCString(kCFAllocatorDefault, "/etc/authorization", kCFStringEncodingUTF8);
- } else {
- destPath = CFStringCreateWithCString(kCFAllocatorDefault, argv[2], kCFStringEncodingUTF8);
- }
- if (NULL == destPath) {
- goto bail;
- }
- destPlist = read_plist_from_file(destPath);
- if (NULL == destPlist)
- goto bail;
-
- sourceRights = CFDictionaryGetValue(sourcePlist, CFSTR("rights"));
- sourceRules = CFDictionaryGetValue(sourcePlist, CFSTR("rules"));
- destRights = CFDictionaryGetValue(destPlist, CFSTR("rights"));
- destRules = CFDictionaryGetValue(destPlist, CFSTR("rules"));
- if (sourceRights)
- rightsCount += CFDictionaryGetCount(sourceRights);
- if (destRights)
- rightsCount += CFDictionaryGetCount(destRights);
- mergeRights = CFDictionaryCreateMutable(NULL, rightsCount, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (NULL == mergeRights) {
- goto bail;
- }
- if (sourceRules)
- rulesCount += CFDictionaryGetCount(sourceRules);
- if (destRules)
- rulesCount += CFDictionaryGetCount(destRules);
- mergeRules = CFDictionaryCreateMutable(NULL, rulesCount, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (NULL == mergeRules) {
- goto bail;
- }
-
- if (destRights)
- CFDictionaryApplyFunction(destRights, merge_dictionaries, mergeRights);
- if (destRules)
- CFDictionaryApplyFunction(destRules, merge_dictionaries, mergeRules);
- if (sourceRights)
- CFDictionaryApplyFunction(sourceRights, merge_dictionaries, mergeRights);
- if (sourceRules)
- CFDictionaryApplyFunction(sourceRules, merge_dictionaries, mergeRules);
-
- outDict = CFDictionaryCreateMutable(NULL, 3, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- if (NULL == outDict) {
- goto bail;
- }
- if (CFDictionaryContainsKey(sourcePlist, CFSTR("comment")))
- CFDictionaryAddValue(outDict, CFSTR("comment"), CFDictionaryGetValue(sourcePlist, CFSTR("comment")));
- else if (CFDictionaryContainsKey(destPlist, CFSTR("comment")))
- CFDictionaryAddValue(outDict, CFSTR("comment"), CFDictionaryGetValue(destPlist, CFSTR("comment")));
- CFDictionaryAddValue(outDict, CFSTR("rights"), mergeRights);
- CFDictionaryAddValue(outDict, CFSTR("rules"), mergeRules);
- if (!write_plist_to_file(outDict, destPath))
- goto bail;
-
- status = noErr;
-bail:
- if (sourcePath)
- CFRelease(sourcePath);
- if (destPath)
- CFRelease(destPath);
- if (sourcePlist)
- CFRelease(sourcePlist);
- if (destPlist)
- CFRelease(destPlist);
- if (outDict)
- CFRelease(outDict);
- }
- else
- return SHOW_USAGE_MESSAGE;
- }
- else
- return SHOW_USAGE_MESSAGE;
-
- if (auth_ref)
- AuthorizationFree(auth_ref, 0);
-
- if (!do_quiet)
- fprintf(stderr, "%s (%d)\n", status ? "NO" : "YES", (int)status);
-
- return (status ? -1 : 0);
-}
-
-int
-authorize(int argc, char * const *argv)
-{
- int ch;
- int retval = 1;
- OSStatus status;
-
- Boolean user_interaction_allowed = FALSE, extend_rights = TRUE;
- Boolean partial_rights = FALSE, destroy_rights = FALSE;
- Boolean pre_authorize = FALSE, internalize = FALSE, externalize = FALSE;
- Boolean wait = FALSE, explicit_credentials = FALSE;
- Boolean isolate_explicit_credentials = FALSE, least_privileged = FALSE;
- char *login = NULL;
-
- while ((ch = getopt(argc, argv, "ucC:EpdPieqwxl")) != -1)
- {
- switch (ch)
- {
- case 'u':
- user_interaction_allowed = TRUE;
- break;
- case 'c':
- explicit_credentials = TRUE;
- break;
- case 'C':
- explicit_credentials = TRUE;
- login = optarg;
- break;
- case 'e':
- externalize = TRUE;
- break;
- case 'E':
- extend_rights = FALSE;
- break;
- case 'p':
- partial_rights = TRUE;
- break;
- case 'd':
- destroy_rights = TRUE;
- break;
- case 'P':
- pre_authorize = TRUE;
- break;
- case 'i':
- internalize = TRUE;
- break;
- case 'w':
- wait = TRUE;
- externalize = TRUE;
- break;
- case 'x':
- isolate_explicit_credentials = TRUE;
- break;
- case 'l':
- least_privileged = TRUE;
- break;
- case '?':
- default:
- return SHOW_USAGE_MESSAGE;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- return SHOW_USAGE_MESSAGE; // required right parameter(s)
-
-// set up AuthorizationFlags
- AuthorizationFlags flags = kAuthorizationFlagDefaults |
- (user_interaction_allowed ? kAuthorizationFlagInteractionAllowed : 0) |
- (extend_rights ? kAuthorizationFlagExtendRights : 0) |
- (partial_rights ? kAuthorizationFlagPartialRights : 0) |
- (pre_authorize ? kAuthorizationFlagPreAuthorize : 0) |
- (least_privileged ? kAuthorizationFlagLeastPrivileged : 0);
-
-// set up AuthorizationRightSet
- AuthorizationItem *rights = malloc(argc * sizeof(AuthorizationItem));
- if (!rights) {
- fprintf(stderr, "Out of memory\n");
- retval = 1;
- goto bail;
- }
- memset(rights, '\0', argc * sizeof(AuthorizationItem));
- AuthorizationItemSet rightset = { argc, rights };
- while (argc > 0)
- rights[--argc].name = *argv++;
-
- AuthorizationRef auth_ref = NULL;
-
-// internalize AuthorizationRef
- if (internalize)
- {
- auth_ref = read_auth_ref_from_stdin();
- if (!auth_ref) {
- retval = 1;
- goto bail;
- }
- }
-
- if (!auth_ref && AuthorizationCreate(NULL, NULL,
- (least_privileged ? kAuthorizationFlagLeastPrivileged : 0),
- &auth_ref)) {
- retval = -1;
- goto bail;
- }
-
-// prepare environment if needed
- AuthorizationEnvironment *envp = NULL;
- if (explicit_credentials) {
- if (!login)
- login = getlogin();
- char *pass = getpass("Password:");
- if (!(login && pass)) {
- retval = 1;
- goto bail;
- }
- static AuthorizationItem authenv[] = {
- { kAuthorizationEnvironmentUsername },
- { kAuthorizationEnvironmentPassword },
- { kAuthorizationEnvironmentShared } // optional (see below)
- };
- static AuthorizationEnvironment env = { 0, authenv };
- authenv[0].valueLength = strlen(login);
- authenv[0].value = login;
- authenv[1].valueLength = strlen(pass);
- authenv[1].value = pass;
- if (isolate_explicit_credentials)
- env.count = 2; // do not send kAuthorizationEnvironmentShared
- else
- env.count = 3; // do send kAuthorizationEnvironmentShared
- envp = &env;
- }
-
-// perform Authorization
- AuthorizationRights *granted_rights = NULL;
- status = AuthorizationCopyRights(auth_ref, &rightset, envp, flags, &granted_rights);
-
-// externalize AuthorizationRef
- if (externalize)
- write_auth_ref_to_stdout(auth_ref);
-
- if (!do_quiet)
- fprintf(stderr, "%s (%d) ", status ? "NO" : "YES", (int)status);
-
- if (!do_quiet && !status && granted_rights)
- {
- uint32_t index;
- fprintf(stderr, "{ %d: ", (int)granted_rights->count);
- for (index = 0; index < granted_rights->count; index++)
- {
- fprintf(stderr, "\"%s\"%s %c ", granted_rights->items[index].name,
- (kAuthorizationFlagCanNotPreAuthorize & granted_rights->items[index].flags) ? " (cannot-preauthorize)" : "",
- (index+1 != granted_rights->count) ? ',' : '}');
- }
- AuthorizationFreeItemSet(granted_rights);
- }
-
- if (!do_quiet)
- fprintf(stderr, "\n");
-
-// wait for client to pick up AuthorizationRef
- if (externalize && wait)
- while (-1 != write(STDOUT_FILENO, NULL, 0))
- usleep(100);
-
-// drop AuthorizationRef
- if (auth_ref)
- AuthorizationFree(auth_ref, destroy_rights ? kAuthorizationFlagDestroyRights : 0);
-
- retval = (status ? -1 : 0);
-bail:
- if (rights)
- free(rights);
-
- return retval;
-}
-
-
-int
-execute_with_privileges(int argc, char * const *argv)
-{
- AuthorizationRef auth_ref = NULL;
- int ch;
- while ((ch = getopt(argc, argv, "i")) != -1)
- {
- switch (ch)
- {
- case 'i':
- auth_ref = read_auth_ref_from_stdin();
- break;
- case '?':
- default:
- return SHOW_USAGE_MESSAGE;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc == 0)
- return SHOW_USAGE_MESSAGE; // required tool parameter(s)
-
- OSStatus status;
-
- if (!auth_ref && AuthorizationCreate(NULL, NULL, 0, &auth_ref))
- return -1;
-
- FILE *communications_pipe = NULL;
-
- status = AuthorizationExecuteWithPrivileges(auth_ref,argv[0], 0, (argc > 1) ? &argv[1] : NULL, &communications_pipe);
-
- if (!do_quiet)
- fprintf(stderr, "%s (%d) ", status ? "NO" : "YES", (int)status);
-
- if (!status)
- {
- ssize_t bytes_read = 0;
- uint8_t buffer[4096];
-
- while ((bytes_read = read(STDIN_FILENO, &buffer, sizeof(buffer))))
- {
- if ((bytes_read == -1) && ((errno != EAGAIN) || (errno != EINTR)))
- break;
- else
- while ((-1 == write(fileno(communications_pipe), buffer, bytes_read)) &&
- ((errno == EAGAIN) || (errno == EINTR)))
- usleep(100);
- }
- }
-
- return (status ? -1 : 0);
-}
-