]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/helper/helper_comm.c
configd-293.4.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / helper / helper_comm.c
1 /*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <sys/types.h>
25 #include <sys/uio.h>
26 #include <unistd.h>
27 #include <CoreFoundation/CoreFoundation.h>
28 #include "helper_comm.h"
29
30 #include <SystemConfiguration/SCPrivate.h>
31
32
33 static ssize_t
34 readn(int ref, void *data, size_t len)
35 {
36 size_t left = len;
37 ssize_t n;
38 void *p = data;
39
40 while (left > 0) {
41 if ((n = read(ref, p, left)) == -1) {
42 if (errno != EINTR) {
43 return -1;
44 }
45 n = 0;
46 } else if (n == 0) {
47 break; /* EOF */
48 }
49
50 left -= n;
51 p += n;
52 }
53 return (len - left);
54 }
55
56
57 static ssize_t
58 writen(int ref, const void *data, size_t len)
59 {
60 size_t left = len;
61 ssize_t n;
62 const void *p = data;
63
64 while (left > 0) {
65 if ((n = write(ref, p, left)) == -1) {
66 if (errno != EINTR) {
67 return -1;
68 }
69 n = 0;
70 }
71 left -= n;
72 p += n;
73 }
74 return len;
75 }
76
77
78 Boolean
79 __SCHelper_txMessage(int fd, uint32_t msgID, CFDataRef data)
80 {
81 ssize_t n_written;
82 uint32_t header[2];
83
84 header[0] = msgID;
85 header[1] = (data != NULL) ? CFDataGetLength(data) : 0;
86
87 n_written = writen(fd, header, sizeof(header));
88 if (n_written != sizeof(header)) {
89 if ((n_written == -1) && (errno != EPIPE)) {
90 perror("write() failed while sending msgID");
91 }
92 return FALSE;
93 }
94
95 if (header[1] == 0) {
96 // if no data to send
97 return TRUE;
98 }
99
100 n_written = writen(fd, CFDataGetBytePtr(data), header[1]);
101 if (n_written != header[1]) {
102 if ((n_written == -1) && (errno != EPIPE)) {
103 perror("write() failed while sending data");
104 }
105 return FALSE;
106 }
107
108 return TRUE;
109 }
110
111 Boolean
112 __SCHelper_rxMessage(int fd, uint32_t *msgID, CFDataRef *data)
113 {
114 void *bytes;
115 size_t n_read;
116 uint32_t header[2];
117
118 n_read = readn(fd, header, sizeof(header));
119 if (n_read != sizeof(header)) {
120 if (n_read == -1) {
121 perror("read() failed while reading msgID");
122 }
123 return FALSE;
124 }
125
126 if (msgID != NULL) {
127 *msgID = header[0];
128 }
129
130 if (header[1] == 0) {
131 if (data != NULL) {
132 *data = NULL;
133 }
134 return TRUE;
135 } else if ((int32_t)header[1] < 0) {
136 perror("read() failed, invalid data length");
137 return FALSE;
138 }
139
140 bytes = CFAllocatorAllocate(NULL, header[1], 0);
141 n_read = readn(fd, bytes, header[1]);
142 if (n_read != header[1]) {
143 if (n_read == -1) {
144 perror("read() failed while reading data");
145 }
146 CFAllocatorDeallocate(NULL, bytes);
147 return FALSE;
148 }
149
150 if (data != NULL) {
151 *data = CFDataCreateWithBytesNoCopy(NULL, bytes, header[1], NULL);
152 } else {
153 // toss reply data
154 CFAllocatorDeallocate(NULL, bytes);
155 }
156
157 return TRUE;
158 }
159
160
161 Boolean
162 _SCHelperExec(int fd, uint32_t msgID, CFDataRef data, uint32_t *status, CFDataRef *reply)
163 {
164 Boolean ok;
165
166 ok = __SCHelper_txMessage(fd, msgID, data);
167 if (!ok) {
168 return FALSE;
169 }
170
171 if ((status == NULL) && (reply == NULL)) {
172 // if no reply expected (one way)
173 return TRUE;
174 }
175
176 ok = __SCHelper_rxMessage(fd, status, reply);
177 if (!ok) {
178 return FALSE;
179 }
180
181 return TRUE;
182 }