|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*
27: * Copyright (c) 1989, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * This code is derived from software contributed to Berkeley by
31: * Rick Macklem at The University of Guelph.
32: *
33: * Redistribution and use in source and binary forms, with or without
34: * modification, are permitted provided that the following conditions
35: * are met:
36: * 1. Redistributions of source code must retain the above copyright
37: * notice, this list of conditions and the following disclaimer.
38: * 2. Redistributions in binary form must reproduce the above copyright
39: * notice, this list of conditions and the following disclaimer in the
40: * documentation and/or other materials provided with the distribution.
41: * 3. All advertising materials mentioning features or use of this software
42: * must display the following acknowledgement:
43: * This product includes software developed by the University of
44: * California, Berkeley and its contributors.
45: * 4. Neither the name of the University nor the names of its contributors
46: * may be used to endorse or promote products derived from this software
47: * without specific prior written permission.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59: * SUCH DAMAGE.
60: *
61: * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95
62: * FreeBSD-Id: nfsm_subs.h,v 1.13 1997/07/16 09:06:30 dfr Exp $
63: */
64:
65:
66: #ifndef _NFS_NFSM_SUBS_H_
67: #define _NFS_NFSM_SUBS_H_
68:
69:
70: /*
71: * These macros do strange and peculiar things to mbuf chains for
72: * the assistance of the nfs code. To attempt to use them for any
73: * other purpose will be dangerous. (they make weird assumptions)
74: */
75:
76: /*
77: * First define what the actual subs. return
78: */
79: struct mbuf *nfsm_reqh __P((struct vnode *vp, u_long procid, int hsiz,
80: caddr_t *bposp));
81: struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid,
82: int auth_type, int auth_len, char *auth_str,
83: int verf_len, char *verf_str,
84: struct mbuf *mrest, int mrest_len,
85: struct mbuf **mbp, u_long *xidp));
86:
87: #define M_HASCL(m) ((m)->m_flags & M_EXT)
88: #define NFSMINOFF(m) \
89: if (M_HASCL(m)) \
90: (m)->m_data = (m)->m_ext.ext_buf; \
91: else if ((m)->m_flags & M_PKTHDR) \
92: (m)->m_data = (m)->m_pktdat; \
93: else \
94: (m)->m_data = (m)->m_dat
95: #define NFSMADV(m, s) (m)->m_data += (s)
96: #define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \
97: (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN))
98:
99: /*
100: * Now for the macros that do the simple stuff and call the functions
101: * for the hard stuff.
102: * These macros use several vars. declared in nfsm_reqhead and these
103: * vars. must not be used elsewhere unless you are careful not to corrupt
104: * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries
105: * that may be used so long as the value is not expected to retained
106: * after a macro.
107: * I know, this is kind of dorkey, but it makes the actual op functions
108: * fairly clean and deals with the mess caused by the xdr discriminating
109: * unions.
110: */
111:
112: #define nfsm_build(a,c,s) \
113: { if ((s) > M_TRAILINGSPACE(mb)) { \
114: MGET(mb2, M_WAIT, MT_DATA); \
115: if ((s) > MLEN) \
116: panic("build > MLEN"); \
117: mb->m_next = mb2; \
118: mb = mb2; \
119: mb->m_len = 0; \
120: bpos = mtod(mb, caddr_t); \
121: } \
122: (a) = (c)(bpos); \
123: mb->m_len += (s); \
124: bpos += (s); }
125:
126: #define nfsm_dissect(a, c, s) \
127: { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
128: if (t1 >= (s)) { \
129: (a) = (c)(dpos); \
130: dpos += (s); \
131: } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2))) { \
132: error = t1; \
133: m_freem(mrep); \
134: goto nfsmout; \
135: } else { \
136: (a) = (c)cp2; \
137: } }
138:
139: #define nfsm_fhtom(v, v3) \
140: { if (v3) { \
141: t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \
142: if (t2 <= M_TRAILINGSPACE(mb)) { \
143: nfsm_build(tl, u_long *, t2); \
144: *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \
145: *(tl + ((t2>>2) - 2)) = 0; \
146: bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \
147: VTONFS(v)->n_fhsize); \
148: } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \
149: (caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize))) { \
150: error = t2; \
151: m_freem(mreq); \
152: goto nfsmout; \
153: } \
154: } else { \
155: nfsm_build(cp, caddr_t, NFSX_V2FH); \
156: bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \
157: } }
158:
159: #define nfsm_srvfhtom(f, v3) \
160: { if (v3) { \
161: nfsm_build(tl, u_long *, NFSX_UNSIGNED + NFSX_V3FH); \
162: *tl++ = txdr_unsigned(NFSX_V3FH); \
163: bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
164: } else { \
165: nfsm_build(cp, caddr_t, NFSX_V2FH); \
166: bcopy((caddr_t)(f), cp, NFSX_V2FH); \
167: } }
168:
169: #define nfsm_srvpostop_fh(f) \
170: { nfsm_build(tl, u_long *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
171: *tl++ = nfs_true; \
172: *tl++ = txdr_unsigned(NFSX_V3FH); \
173: bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
174: }
175:
176: #define nfsm_mtofh(d, v, v3, f) \
177: { struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \
178: if (v3) { \
179: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
180: (f) = fxdr_unsigned(int, *tl); \
181: } else \
182: (f) = 1; \
183: if (f) { \
184: nfsm_getfh(ttfhp, ttfhsize, (v3)); \
185: if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \
186: &ttnp))) { \
187: error = t1; \
188: m_freem(mrep); \
189: goto nfsmout; \
190: } \
191: (v) = NFSTOV(ttnp); \
192: } \
193: if (v3) { \
194: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
195: if (f) \
196: (f) = fxdr_unsigned(int, *tl); \
197: else if (fxdr_unsigned(int, *tl)) \
198: nfsm_adv(NFSX_V3FATTR); \
199: } \
200: if (f) \
201: nfsm_loadattr((v), (struct vattr *)0); \
202: }
203:
204: #define nfsm_getfh(f, s, v3) \
205: { if (v3) { \
206: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
207: if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \
208: (s) > NFSX_V3FHMAX) { \
209: m_freem(mrep); \
210: error = EBADRPC; \
211: goto nfsmout; \
212: } \
213: } else \
214: (s) = NFSX_V2FH; \
215: nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); }
216:
217: #define nfsm_loadattr(v, a) \
218: { struct vnode *ttvp = (v); \
219: if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a)))) { \
220: error = t1; \
221: m_freem(mrep); \
222: goto nfsmout; \
223: } \
224: (v) = ttvp; }
225:
226: #define nfsm_postop_attr(v, f) \
227: { struct vnode *ttvp = (v); \
228: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
229: if (((f) = fxdr_unsigned(int, *tl))) { \
230: if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \
231: (struct vattr *)0))) { \
232: error = t1; \
233: (f) = 0; \
234: m_freem(mrep); \
235: goto nfsmout; \
236: } \
237: (v) = ttvp; \
238: } }
239:
240: /* Used as (f) for nfsm_wcc_data() */
241: #define NFSV3_WCCRATTR 0
242: #define NFSV3_WCCCHK 1
243:
244: #define nfsm_wcc_data(v, f) \
245: { int ttattrf, ttretf = 0; \
246: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
247: if (*tl == nfs_true) { \
248: nfsm_dissect(tl, u_long *, 6 * NFSX_UNSIGNED); \
249: if (f) \
250: ttretf = (VTONFS(v)->n_mtime == \
251: fxdr_unsigned(u_long, *(tl + 2))); \
252: } \
253: nfsm_postop_attr((v), ttattrf); \
254: if (f) { \
255: (f) = ttretf; \
256: } else { \
257: (f) = ttattrf; \
258: } }
259:
260: #define nfsm_v3sattr(s, a, u, g) \
261: { (s)->sa_modetrue = nfs_true; \
262: (s)->sa_mode = vtonfsv3_mode((a)->va_mode); \
263: (s)->sa_uidtrue = nfs_true; \
264: (s)->sa_uid = txdr_unsigned(u); \
265: (s)->sa_gidtrue = nfs_true; \
266: (s)->sa_gid = txdr_unsigned(g); \
267: (s)->sa_sizefalse = nfs_false; \
268: (s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
269: (s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \
270: }
271:
272: #define nfsm_strsiz(s,m) \
273: { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
274: if (((s) = fxdr_unsigned(long,*tl)) > (m)) { \
275: m_freem(mrep); \
276: error = EBADRPC; \
277: goto nfsmout; \
278: } }
279:
280: #define nfsm_srvstrsiz(s,m) \
281: { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
282: if (((s) = fxdr_unsigned(long,*tl)) > (m) || (s) <= 0) { \
283: error = EBADRPC; \
284: nfsm_reply(0); \
285: } }
286:
287: #define nfsm_srvnamesiz(s) \
288: { nfsm_dissect(tl,u_long *,NFSX_UNSIGNED); \
289: if (((s) = fxdr_unsigned(long,*tl)) > NFS_MAXNAMLEN) \
290: error = NFSERR_NAMETOL; \
291: if ((s) <= 0) \
292: error = EBADRPC; \
293: if (error) \
294: nfsm_reply(0); \
295: }
296:
297: #define nfsm_mtouio(p,s) \
298: if ((s) > 0 && \
299: (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \
300: error = t1; \
301: m_freem(mrep); \
302: goto nfsmout; \
303: }
304:
305: #define nfsm_uiotom(p,s) \
306: if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos))) { \
307: error = t1; \
308: m_freem(mreq); \
309: goto nfsmout; \
310: }
311:
312: #define nfsm_reqhead(v,a,s) \
313: mb = mreq = nfsm_reqh((v),(a),(s),&bpos)
314:
315: #define nfsm_reqdone m_freem(mrep); \
316: nfsmout:
317:
318: #define nfsm_rndup(a) (((a)+3)&(~0x3))
319:
320: #define nfsm_request(v, t, p, c) \
321: if ((error = nfs_request((v), mreq, (t), (p), \
322: (c), &mrep, &md, &dpos))) { \
323: if (error & NFSERR_RETERR) \
324: error &= ~NFSERR_RETERR; \
325: else \
326: goto nfsmout; \
327: }
328:
329: #define nfsm_strtom(a,s,m) \
330: if ((s) > (m)) { \
331: m_freem(mreq); \
332: error = ENAMETOOLONG; \
333: goto nfsmout; \
334: } \
335: t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \
336: if (t2 <= M_TRAILINGSPACE(mb)) { \
337: nfsm_build(tl,u_long *,t2); \
338: *tl++ = txdr_unsigned(s); \
339: *(tl+((t2>>2)-2)) = 0; \
340: bcopy((caddr_t)(a), (caddr_t)tl, (s)); \
341: } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s)))) { \
342: error = t2; \
343: m_freem(mreq); \
344: goto nfsmout; \
345: }
346:
347: #define nfsm_srvdone \
348: nfsmout: \
349: return(error)
350:
351: #define nfsm_reply(s) \
352: { \
353: nfsd->nd_repstat = error; \
354: if (error && !(nfsd->nd_flag & ND_NFSV3)) \
355: (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
356: mrq, &mb, &bpos); \
357: else \
358: (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
359: mrq, &mb, &bpos); \
360: m_freem(mrep); \
361: mreq = *mrq; \
362: if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
363: error == EBADRPC)) \
364: return(0); \
365: }
366:
367: #define nfsm_writereply(s, v3) \
368: { \
369: nfsd->nd_repstat = error; \
370: if (error && !(v3)) \
371: (void) nfs_rephead(0, nfsd, slp, error, cache, &frev, \
372: &mreq, &mb, &bpos); \
373: else \
374: (void) nfs_rephead((s), nfsd, slp, error, cache, &frev, \
375: &mreq, &mb, &bpos); \
376: }
377:
378: #define nfsm_adv(s) \
379: { t1 = mtod(md, caddr_t)+md->m_len-dpos; \
380: if (t1 >= (s)) { \
381: dpos += (s); \
382: } else if ((t1 = nfs_adv(&md, &dpos, (s), t1))) { \
383: error = t1; \
384: m_freem(mrep); \
385: goto nfsmout; \
386: } }
387:
388: #define nfsm_srvmtofh(f) \
389: { if (nfsd->nd_flag & ND_NFSV3) { \
390: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
391: if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \
392: error = EBADRPC; \
393: nfsm_reply(0); \
394: } \
395: } \
396: nfsm_dissect(tl, u_long *, NFSX_V3FH); \
397: bcopy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
398: if ((nfsd->nd_flag & ND_NFSV3) == 0) \
399: nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
400: }
401:
402: #define nfsm_clget \
403: if (bp >= be) { \
404: if (mp == mb) \
405: mp->m_len += bp-bpos; \
406: MGET(mp, M_WAIT, MT_DATA); \
407: MCLGET(mp, M_WAIT); \
408: mp->m_len = NFSMSIZ(mp); \
409: mp2->m_next = mp; \
410: mp2 = mp; \
411: bp = mtod(mp, caddr_t); \
412: be = bp+mp->m_len; \
413: } \
414: tl = (u_long *)bp
415:
416: #define nfsm_srvfillattr(a, f) \
417: nfsm_srvfattr(nfsd, (a), (f))
418:
419: #define nfsm_srvwcc_data(br, b, ar, a) \
420: nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos)
421:
422: #define nfsm_srvpostop_attr(r, a) \
423: nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos)
424:
425: #define nfsm_srvsattr(a) \
426: { nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
427: if (*tl == nfs_true) { \
428: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
429: (a)->va_mode = nfstov_mode(*tl); \
430: } \
431: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
432: if (*tl == nfs_true) { \
433: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
434: (a)->va_uid = fxdr_unsigned(uid_t, *tl); \
435: } \
436: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
437: if (*tl == nfs_true) { \
438: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
439: (a)->va_gid = fxdr_unsigned(gid_t, *tl); \
440: } \
441: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
442: if (*tl == nfs_true) { \
443: nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
444: fxdr_hyper(tl, &(a)->va_size); \
445: } \
446: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
447: switch (fxdr_unsigned(int, *tl)) { \
448: case NFSV3SATTRTIME_TOCLIENT: \
449: nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
450: fxdr_nfsv3time(tl, &(a)->va_atime); \
451: break; \
452: case NFSV3SATTRTIME_TOSERVER: \
453: (a)->va_atime.tv_sec = time.tv_sec; \
454: (a)->va_atime.tv_nsec = time.tv_usec * 1000; \
455: break; \
456: }; \
457: nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \
458: switch (fxdr_unsigned(int, *tl)) { \
459: case NFSV3SATTRTIME_TOCLIENT: \
460: nfsm_dissect(tl, u_long *, 2 * NFSX_UNSIGNED); \
461: fxdr_nfsv3time(tl, &(a)->va_mtime); \
462: break; \
463: case NFSV3SATTRTIME_TOSERVER: \
464: (a)->va_mtime.tv_sec = time.tv_sec; \
465: (a)->va_mtime.tv_nsec = time.tv_usec * 1000; \
466: break; \
467: }; }
468:
469: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.