]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
5d5c5d0d A |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. |
3 | * | |
6601e61a | 4 | * @APPLE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
6601e61a A |
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. | |
8f6c56a5 | 11 | * |
6601e61a A |
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 | |
8f6c56a5 A |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
6601e61a A |
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. | |
8f6c56a5 | 19 | * |
6601e61a | 20 | * @APPLE_LICENSE_HEADER_END@ |
1c79356b A |
21 | */ |
22 | /* | |
23 | * Copyright (c) 1995-1998 Apple Computer, Inc. | |
24 | * | |
25 | * Change Log: | |
26 | * Created February 20, 1995 by Tuyen Nguyen | |
27 | * Modified for MP, 1996 by Tuyen Nguyen | |
28 | * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. | |
29 | */ | |
30 | #include <sys/errno.h> | |
31 | #include <sys/types.h> | |
32 | #include <sys/param.h> | |
33 | #include <machine/spl.h> | |
34 | #include <sys/systm.h> | |
35 | #include <sys/kernel.h> | |
91447636 | 36 | #include <sys/proc_internal.h> /* for p_fd in fdflags */ |
1c79356b A |
37 | #include <sys/filedesc.h> |
38 | #include <sys/fcntl.h> | |
39 | #include <sys/mbuf.h> | |
40 | #include <sys/malloc.h> | |
91447636 | 41 | #include <sys/file_internal.h> |
1c79356b A |
42 | #include <sys/socket.h> |
43 | #include <sys/socketvar.h> | |
91447636 A |
44 | #include <sys/sysproto.h> |
45 | #include <sys/kdebug.h> | |
1c79356b A |
46 | #include <net/if_var.h> |
47 | ||
48 | #include <netat/sysglue.h> | |
49 | #include <netat/appletalk.h> | |
50 | #include <netat/at_var.h> | |
51 | #include <netat/at_pcb.h> | |
52 | #include <netat/debug.h> | |
53 | ||
1c79356b A |
54 | |
55 | extern at_state_t at_state; /* global state of AT network */ | |
56 | extern at_ifaddr_t *ifID_home; /* default interface */ | |
91447636 A |
57 | extern lck_mtx_t * atalk_mutex; |
58 | ||
59 | #define f_flag f_fglob->fg_flag | |
60 | #define f_type f_fglob->fg_type | |
61 | #define f_msgcount f_fglob->fg_msgcount | |
62 | #define f_cred f_fglob->fg_cred | |
63 | #define f_ops f_fglob->fg_ops | |
64 | #define f_offset f_fglob->fg_offset | |
65 | #define f_data f_fglob->fg_data | |
1c79356b | 66 | |
0c530ab8 A |
67 | extern int _ATsocket(int, int *, void *); |
68 | extern int _ATgetmsg(int, strbuf_t *, strbuf_t *, int *, int *, void *); | |
69 | extern int _ATputmsg(); | |
70 | extern int _ATPsndreq(), _ATPsndrsp(), _ATPgetreq(), _ATPgetrsp(); | |
71 | ||
72 | ||
1c79356b | 73 | int ATsocket(proc, uap, retval) |
91447636 | 74 | struct proc *proc; |
55e303ae | 75 | struct ATsocket_args *uap; |
1c79356b A |
76 | int *retval; |
77 | { | |
78 | int err; | |
91447636 | 79 | atalk_lock(); |
0c530ab8 | 80 | if (_ATsocket) { |
1c79356b A |
81 | /* required check for all AppleTalk system calls */ |
82 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
83 | *retval = -1; | |
84 | err = ENOTREADY; | |
85 | } else { | |
0c530ab8 | 86 | *retval = _ATsocket((int)uap->proto, (int *)&err, (void *)proc); |
1c79356b A |
87 | } |
88 | } else { | |
89 | *retval = -1; | |
90 | err = ENXIO; | |
91 | } | |
91447636 | 92 | atalk_unlock(); |
1c79356b A |
93 | return err; |
94 | } | |
95 | ||
96 | int ATgetmsg(proc, uap, retval) | |
91447636 | 97 | struct proc *proc; |
55e303ae | 98 | struct ATgetmsg_args *uap; |
1c79356b A |
99 | int *retval; |
100 | { | |
101 | int err; | |
102 | ||
91447636 | 103 | atalk_lock(); |
0c530ab8 | 104 | if (_ATgetmsg) { |
1c79356b A |
105 | /* required check for all AppleTalk system calls */ |
106 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
107 | *retval = -1; | |
108 | err = ENOTREADY; | |
109 | } else { | |
110 | *retval = | |
0c530ab8 | 111 | (*_ATgetmsg)(uap->fd, uap->ctlptr, uap->datptr, |
1c79356b A |
112 | uap->flags, &err, proc); |
113 | } | |
114 | } else { | |
115 | *retval = -1; | |
116 | err = ENXIO; | |
117 | } | |
91447636 | 118 | atalk_unlock(); |
1c79356b A |
119 | return err; |
120 | } | |
121 | ||
55e303ae | 122 | int ATputmsg(proc, uap, retval) |
91447636 | 123 | struct proc *proc; |
55e303ae | 124 | struct ATputmsg_args *uap; |
1c79356b A |
125 | int *retval; |
126 | { | |
127 | int err; | |
128 | ||
91447636 | 129 | atalk_lock(); |
0c530ab8 | 130 | if (_ATputmsg) { |
1c79356b A |
131 | /* required check for all AppleTalk system calls */ |
132 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
133 | *retval = -1; | |
134 | err = ENOTREADY; | |
135 | } else { | |
136 | *retval = | |
0c530ab8 | 137 | _ATputmsg(uap->fd, uap->ctlptr, uap->datptr, |
1c79356b A |
138 | uap->flags, &err, proc); |
139 | } | |
140 | } else { | |
141 | *retval = -1; | |
142 | err = ENXIO; | |
143 | } | |
91447636 | 144 | atalk_unlock(); |
1c79356b A |
145 | return err; |
146 | } | |
147 | ||
148 | int ATPsndreq(proc, uap, retval) | |
91447636 | 149 | struct proc *proc; |
55e303ae | 150 | struct ATPsndreq_args *uap; |
1c79356b A |
151 | int *retval; |
152 | { | |
153 | int err; | |
154 | ||
91447636 | 155 | atalk_lock(); |
0c530ab8 | 156 | if (_ATPsndreq) { |
1c79356b A |
157 | /* required check for all AppleTalk system calls */ |
158 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
159 | *retval = -1; | |
160 | err = ENOTREADY; | |
161 | } else { | |
162 | *retval = | |
0c530ab8 | 163 | _ATPsndreq(uap->fd, uap->buf, uap->len, |
1c79356b A |
164 | uap->nowait, &err, proc); |
165 | } | |
166 | } else { | |
167 | *retval = -1; | |
168 | err= ENXIO; | |
169 | } | |
91447636 | 170 | atalk_unlock(); |
1c79356b A |
171 | return err; |
172 | } | |
173 | ||
55e303ae | 174 | int ATPsndrsp(proc, uap, retval) |
91447636 | 175 | struct proc *proc; |
55e303ae | 176 | struct ATPsndrsp_args *uap; |
1c79356b A |
177 | int *retval; |
178 | { | |
179 | int err; | |
180 | ||
91447636 | 181 | atalk_lock(); |
0c530ab8 | 182 | if (_ATPsndrsp) { |
1c79356b A |
183 | /* required check for all AppleTalk system calls */ |
184 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
185 | *retval = -1; | |
186 | err = ENOTREADY; | |
187 | } else { | |
188 | *retval = | |
0c530ab8 | 189 | _ATPsndrsp(uap->fd, uap->respbuff, |
1c79356b A |
190 | uap->resplen, uap->datalen, &err, proc); |
191 | } | |
192 | } else { | |
193 | *retval = -1; | |
194 | err = ENXIO; | |
195 | } | |
91447636 | 196 | atalk_unlock(); |
1c79356b A |
197 | return err; |
198 | } | |
199 | ||
55e303ae | 200 | int ATPgetreq(proc, uap, retval) |
91447636 | 201 | struct proc *proc; |
55e303ae | 202 | struct ATPgetreq_args *uap; |
1c79356b A |
203 | int *retval; |
204 | { | |
205 | int err; | |
206 | ||
91447636 | 207 | atalk_lock(); |
0c530ab8 | 208 | if (_ATPgetreq) { |
1c79356b A |
209 | /* required check for all AppleTalk system calls */ |
210 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
211 | *retval = -1; | |
212 | err = ENOTREADY; | |
213 | } else { | |
214 | *retval = | |
0c530ab8 | 215 | _ATPgetreq(uap->fd, uap->buf, uap->buflen, |
1c79356b A |
216 | &err, proc); |
217 | } | |
218 | } else { | |
219 | *retval = -1; | |
220 | err = ENXIO; | |
221 | } | |
91447636 | 222 | atalk_unlock(); |
1c79356b A |
223 | return err; |
224 | } | |
225 | ||
55e303ae | 226 | int ATPgetrsp(proc, uap, retval) |
91447636 | 227 | struct proc *proc; |
55e303ae | 228 | struct ATPgetrsp_args *uap; |
1c79356b A |
229 | int *retval; |
230 | { | |
231 | int err = 0; | |
232 | ||
91447636 | 233 | atalk_lock(); |
0c530ab8 | 234 | if (_ATPgetrsp) { |
1c79356b A |
235 | /* required check for all AppleTalk system calls */ |
236 | if (!(at_state.flags & AT_ST_STARTED) || !ifID_home) { | |
237 | *retval = -1; | |
238 | err = ENOTREADY; | |
239 | } else { | |
240 | *retval = | |
0c530ab8 | 241 | _ATPgetrsp(uap->fd, uap->bdsp, &err, proc); |
1c79356b A |
242 | } |
243 | } else { | |
244 | *retval = -1; | |
245 | err = ENXIO; | |
246 | } | |
91447636 | 247 | atalk_unlock(); |
1c79356b A |
248 | return err; |
249 | } | |
250 | ||
91447636 A |
251 | int atalk_closeref(fg, grefp) |
252 | struct fileglob *fg; | |
1c79356b A |
253 | gref_t **grefp; |
254 | { | |
91447636 A |
255 | if ((*grefp = (gref_t *)fg->fg_data)) { |
256 | fg->fg_data = 0; | |
1c79356b A |
257 | return(0); |
258 | } | |
259 | return(EBADF); | |
260 | } | |
261 | ||
262 | int atalk_openref(gref, retfd, proc) | |
263 | gref_t *gref; | |
264 | int *retfd; | |
265 | struct proc *proc; | |
266 | { | |
55e303ae | 267 | extern int _ATread(), _ATwrite(),_ATioctl(), _ATselect(), _ATclose(), _ATkqfilter(); |
1c79356b | 268 | static struct fileops fileops = |
91447636 | 269 | {_ATread, _ATwrite, _ATioctl, _ATselect, _ATclose, _ATkqfilter, 0}; |
1c79356b | 270 | int err, fd; |
91447636 A |
271 | struct fileproc *fp; |
272 | ||
273 | lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED); | |
274 | ||
275 | proc_fdlock(proc); | |
276 | if ((err = falloc_locked(proc, &fp, &fd, 1)) != 0) { | |
277 | proc_fdunlock(proc); | |
1c79356b A |
278 | return err; |
279 | } | |
280 | ||
281 | fp->f_flag = FREAD|FWRITE; | |
282 | /*##### LD 5/7/96 Warning: we don't have a "DTYPE_OTHER" for | |
283 | * MacOSX, so defines DTYPE_ATALK as DTYPE_SOCKET... | |
284 | */ | |
285 | fp->f_type = DTYPE_ATALK+1; | |
286 | fp->f_ops = &fileops; | |
91447636 A |
287 | fp->f_data = (void *)gref; |
288 | ||
6601e61a | 289 | procfdtbl_releasefd(proc, fd, NULL); |
1c79356b | 290 | *retfd = fd; |
91447636 A |
291 | fp_drop(proc, fd, fp, 1); |
292 | proc_fdunlock(proc); | |
1c79356b A |
293 | /* |
294 | kprintf("atalk_openref: fp = 0x%x, gref = 0x%x\n", (u_int)fp, (u_int)gref); | |
295 | */ | |
1c79356b A |
296 | return 0; |
297 | } | |
298 | ||
91447636 A |
299 | /* |
300 | * go from file descriptor to gref, which has been saved in fp->f_data | |
301 | * | |
302 | * This routine returns with an iocount on the fileproc when the fp is null | |
303 | * as it converts fd to fileproc. Callers of this api who pass fp as null | |
304 | * need to drop the iocount when they are done with the fp | |
305 | */ | |
306 | int atalk_getref(fp, fd, grefp, proc, droponerr) | |
307 | struct fileproc *fp; | |
1c79356b A |
308 | int fd; |
309 | gref_t **grefp; | |
310 | struct proc *proc; | |
91447636 | 311 | int droponerr; |
1c79356b | 312 | { |
91447636 | 313 | int error; |
1c79356b | 314 | |
91447636 A |
315 | proc_fdlock(proc); |
316 | error = atalk_getref_locked(fp, fd, grefp, proc, droponerr); | |
317 | proc_fdunlock(proc); | |
318 | return error; | |
319 | } | |
1c79356b | 320 | |
91447636 A |
321 | int atalk_getref_locked(fp, fd, grefp, proc, droponerr) |
322 | struct fileproc *fp; | |
323 | int fd; | |
324 | gref_t **grefp; | |
325 | struct proc *proc; | |
326 | int droponerr; | |
327 | { | |
328 | lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED); | |
329 | if (fp == 0) { | |
330 | int error = fp_lookup(proc, fd, &fp, 1); | |
331 | ||
332 | if (error) { | |
333 | ||
334 | *grefp = (gref_t *) 0; | |
335 | return EBADF; | |
336 | } | |
337 | } | |
338 | *grefp = (gref_t *)fp->f_data; | |
8f6c56a5 | 339 | if (fp->f_type != (DTYPE_ATALK+1) || *grefp == 0 || *grefp == (gref_t *)(-1)) { |
91447636 A |
340 | if (droponerr) |
341 | fp_drop(proc, fd, fp, 1); | |
342 | printf("atalk_getref_locked EBADF f_data: %x\n", fp->f_data); | |
343 | return EBADF; | |
344 | } | |
345 | ||
346 | if ((*grefp)->errno) { | |
347 | if (droponerr) | |
348 | fp_drop(proc, fd, fp, 1); | |
349 | return (int)(*grefp)->errno; | |
350 | } | |
351 | return 0; | |
1c79356b | 352 | } |