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