]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/moh.c
configd-53.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / moh.c
1 /*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /*
24 * Modification History
25 *
26 * May 29, 2002 Roger Smith <rsmith@apple.com>
27 * - initial revision
28 */
29
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/errno.h>
34 #include <sys/socket.h>
35 #include <sys/un.h>
36 #include <CoreFoundation/CoreFoundation.h>
37
38 #include <SystemConfiguration/SystemConfiguration.h>
39 #include <SystemConfiguration/SCPrivate.h>
40
41 #include "moh.h"
42 #include "moh_msg.h"
43
44 // Note: right now we are not currently using the deviceName. This could be the raw
45 // tty name such as "modem" since this is guaranteed to be unique in the /dev.
46 // We would use this deviceName to differientate between multiple MOH devices
47 // present in the system when we create the socket.
48
49
50 static int
51 readn(int ref, void *data, int len)
52 {
53 int left = len;
54 int n;
55 void *p = data;
56
57 while (left > 0) {
58 if ((n = read(ref, p, left)) < 0) {
59 if (errno != EINTR) {
60 return -1;
61 }
62 n = 0;
63 } else if (n == 0) {
64 break; /* EOF */
65 }
66
67 left -= n;
68 p += n;
69 }
70 return (len - left);
71 }
72
73
74 static int
75 writen(int ref, void *data, int len)
76 {
77 int left = len;
78 int n;
79 void *p = data;
80
81 while (left > 0) {
82 if ((n = write(ref, p, left)) <= 0) {
83 if (errno != EINTR) {
84 return -1;
85 }
86 n = 0;
87 }
88 left -= n;
89 p += n;
90 }
91 return len;
92 }
93
94
95 __private_extern__
96 int
97 MOHInit(int *ref, CFStringRef deviceName)
98 {
99 int sock;
100 int status;
101 struct sockaddr_un sun;
102
103 sock = socket(AF_LOCAL, SOCK_STREAM, 0);
104
105 bzero(&sun, sizeof(sun));
106 sun.sun_family = AF_LOCAL;
107 strncpy(sun.sun_path, MOH_PATH, sizeof(sun.sun_path));
108
109 status = connect(sock, (struct sockaddr *)&sun, sizeof(sun));
110 if (status < 0) {
111 return errno;
112 }
113
114 *ref = sock;
115 return 0;
116 }
117
118
119 __private_extern__
120 int
121 MOHDispose(int ref)
122 {
123 if (close(ref) < 0) {
124 return errno;
125 }
126 return 0;
127 }
128
129
130 __private_extern__
131 int
132 MOHExec(int ref,
133 u_long link,
134 u_int32_t cmd,
135 void *request,
136 u_long requestLen,
137 void **reply,
138 u_long *replyLen)
139 {
140 struct moh_msg_hdr msg;
141 char *buf = NULL;
142 ssize_t n;
143
144 bzero(&msg, sizeof(msg));
145 msg.m_type = cmd;
146 msg.m_link = link;
147 msg.m_len = ((request != NULL) && (requestLen > 0)) ? requestLen : 0;
148
149 // send the command
150 n = writen(ref, &msg, sizeof(msg));
151 if (n == -1) {
152 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: %s"), strerror(errno));
153 return errno;
154 } else if (n != sizeof(msg)) {
155 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: wrote=%d"), n);
156 return -1;
157 }
158
159 if ((request != NULL) && (requestLen > 0)) {
160 n = writen(ref, request, requestLen);
161 if (n == -1) {
162 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: %s"), strerror(errno));
163 return errno;
164 } else if (n != requestLen) {
165 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: wrote=%d"), n);
166 return -1;
167 }
168 }
169
170 // always expect a reply
171 n = readn(ref, &msg, sizeof(msg));
172 if (n == -1) {
173 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: error=%s"), strerror(errno));
174 return errno;
175 } else if (n != sizeof(msg)) {
176 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: insufficent data, read=%d"), n);
177 return -1;
178 }
179
180 if (msg.m_len) {
181 buf = CFAllocatorAllocate(NULL, msg.m_len, 0);
182 if (buf) {
183 // read reply
184 n = readn(ref, buf, msg.m_len);
185 if (n == -1) {
186 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: error=%s"), strerror(errno));
187 CFAllocatorDeallocate(NULL, buf);
188 return errno;
189 } else if (n != msg.m_len) {
190 SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: insufficent data, read=%d"), n);
191 CFAllocatorDeallocate(NULL, buf);
192 return -1;
193 }
194 }
195 }
196
197 if (reply && replyLen) {
198 *reply = buf;
199 *replyLen = msg.m_len;
200 } else if (buf) {
201 // if additional returned data is unwanted
202 CFAllocatorDeallocate(NULL, buf);
203 }
204
205 return msg.m_result;
206 }
207