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